Jump to content
  • Advertisement
Sign in to follow this  
utilae

Can't get Index Buffer to work

This topic is 4898 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Edit: Go to bottom post about trying to get my index buffer/drawindexedprimitive to work Hi, I am using C++ and Direct3D9. I have a function called AddSquare(). This function adds six vertices to a list, eg
//add six vertices to the list of vertices
// v2---v3|v5  //0.0-----0.0
// |     /|    //|     /  |  
// |   /  |    //|   /    |
// | /    |    //| /      |
//v1|v4---v6   //0.0-----1.0





Then I call a function which fills the vertex buffer (first all vertices are sorted by Z order). In the below image I have nine rects (each rect has a texture). The problem is that some of the textures are distorted. All nine squares together make one big square. The middle square is mean't to be grey, but it is not visible for some reason and one of the corners looks wrong. At this point each of the nine squares have the same z value (all six vertices for one square has the same z value as the vertices from any other square). If I change the vertices of each square to be differnt, then there are no glitches. But then I render another texture on top and the textures distort again. Anyone able to help? [Edited by - utilae on May 24, 2005 3:14:50 AM]

Share this post


Link to post
Share on other sites
Advertisement
What I beleave is happening, is that your polygons are rendering one over the other. That is why, when you mode the vertices slightly, they render correctly.

To solve this, you should probably create 4 vertices, make the indices work for those 4 vertices and render as a triangle list. That creates 2 triangles that share 2 vertices. In general, texture problems like this one are caused by inprecision in floating point values.

Check this thread for more about problems with floating point values :
http://www.gamedev.net/community/forums/topic.asp?topic_id=321103

Here is an example :

// v1-----v2
// |----/-|
// |---/--|
// |--/---|
// v0-----v3

index list :
0-2-1
3-2-0

Share this post


Link to post
Share on other sites
So how do you make indicies work for 4 vertices, cause I don't remember using indicies and I don't know what they are?

Here's my function anyway. I call it whenever I want to add a set of vertices to draw an image (texture):

//Add four vertices to make up a square (that a texture will be within)
void CVertexManager::AddSquare(RECT &recPos,const float &fZOrder,TILE &TilePos)//system null reference
{
if(m_lstVertexList.empty()==true)
m_nPrimitiveCount=0;

//vertices must be sort in order of Z value (0.0 close, 10.0 far). Z values closer to 0 are rendered first.
//Use RECT coordinates to create vertices
VERTEX vrtBottomLeft,vrtTopLeft,vrtTopRight,vrtBottomRight;
vrtTopLeft.x=recPos.left; vrtTopLeft.y=recPos.top; vrtTopLeft.z=fZOrder; vrtTopLeft.tu=TilePos.m_tuLeft; vrtTopLeft.tv=TilePos.m_tvTop;
vrtTopRight.x=recPos.right; vrtTopRight.y=recPos.top; vrtTopRight.z=fZOrder; vrtTopRight.tu=TilePos.m_tuRight; vrtTopRight.tv=TilePos.m_tvTop;
vrtBottomLeft.x=recPos.left; vrtBottomLeft.y=recPos.bottom; vrtBottomLeft.z=fZOrder; vrtBottomLeft.tu=TilePos.m_tuLeft; vrtBottomLeft.tv=TilePos.m_TvBottom;
vrtBottomRight.x=recPos.right; vrtBottomRight.y=recPos.bottom; vrtBottomRight.z=fZOrder; vrtBottomRight.tu=TilePos.m_tuRight; vrtBottomRight.tv=TilePos.m_TvBottom;

//add six vertices to the list of vertices
// v1-----v2 //0.0-----0.0 //tu=horizontal
// |----/-| //| / | //tv=vertical
// |---/--| //| / |
// |--/---| //| / |
// v0-----v3 //0.0-----1.0

m_lstVertexList.push_back(vrtTopLeft);
m_lstVertexList.push_back(vrtTopRight);
m_lstVertexList.push_back(vrtBottomLeft);
m_lstVertexList.push_back(vrtBottomRight);

//add two primitives to the number of primitives to draw
++m_nPrimitiveCount;++m_nPrimitiveCount;
}


Share this post


Link to post
Share on other sites
Basically you create an index buffer and a vertex buffer. the index buffer is created by adding the location of the vertex it wants to reference in the vertex buffer. for instance say,

0---2
| / |
|/ |
1---3

Your vertex buffer would be filled with ( Vertex0, Vertex1, Vertex2, Vertex3 ).
Your INDEX buffer would be filled with( int0, int1, int2, int2, int1, int3 ) CCW.

When you render, you render with DrawIndexedPrimitive(...).


I would search msdn.microsoft.com and lookup the following functions.

CreateIndexBuffer(...) // creates your index buffer
CreateVertexBuffer(...) //prolly know but creates your vertex buffer
SetFVF(...) //Prolly know but sets your vertex format
SetStreamSource(...) //you prolly know, but sets your vertex buffer
SetIndicies(...) //sets your index buffer
DrawIndexedPrimitive(...) //draws from indexing not like DramPrimitive(...)

Share this post


Link to post
Share on other sites
Ok, I am trying to get this drawindexed primitive thing to work, though draw indexed primitive keeps failing because their are too few vertices for the primitives or something.

Here's my code:

Setup vertex and index buffer

//Create a dynamic vertex buffer in system memory
void CVertexManager::SetupVertices(void)
{
g_Log<<"VERTEX SIZE="<<sizeof(VERTEX)<<endl;
g_Log<<"VERTEX BUFFER SIZE="<<(sizeof(VERTEX)*10920)<<endl;

//create d3d9 vertex buffer
HRESULT hr=g_pD3DDevice9->CreateVertexBuffer(sizeof(VERTEX)*10920,D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,g_dwFVF,D3DPOOL_SYSTEMMEM,&g_pVertexBuffer,NULL);
g_Log<<"SetupVertices() Create Vertex Buffer: "<<DXGetErrorString9(hr)<<endl;

//create d3d9 index buffer (size=2 triangles * 3 indicies * sizeof(word))
hr=g_pD3DDevice9->CreateIndexBuffer(6*sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&g_pIndexBuffer,NULL);
g_Log<<"SetupVertices() Create Index Buffer: "<<DXGetErrorString9(hr)<<endl;

//fill index buffer
WORD *usIndices=NULL;
g_pIndexBuffer->Lock(0,0,(void**)&usIndices,0);//lock index buffer
usIndices[0]=0;//index buffer data
usIndices[1]=1;
usIndices[2]=3;
usIndices[3]=3;
usIndices[4]=1;
usIndices[5]=2;
g_pIndexBuffer->Unlock();//unlock index buffer

//set index buffer
g_pD3DDevice9->SetIndices(g_pIndexBuffer);
}



Add all the vertices necesary for a 2d textured square

//Add vertices to make up a square
void CVertexManager::AddSquare(RECT &recPos,const float &fZOrder,TILE &TilePos)
{
if(m_lstVertexList.empty()==true)
{
m_nPrimitiveCount=0;
m_nVertexCount=0;
}

//vertices must be sort in order of Z value (0.0 close, 10.0 far). Z values closer to 10 are rendered first.
//Use RECT coordinates to create vertices
VERTEX vrtBottomLeft,vrtTopLeft,vrtTopRight,vrtBottomRight;
vrtTopLeft.x=recPos.left; vrtTopLeft.y=recPos.top; vrtTopLeft.z=fZOrder; vrtTopLeft.tu=TilePos.m_tuLeft; vrtTopLeft.tv=TilePos.m_tvTop;
vrtTopRight.x=recPos.right; vrtTopRight.y=recPos.top; vrtTopRight.z=fZOrder; vrtTopRight.tu=TilePos.m_tuRight; vrtTopRight.tv=TilePos.m_tvTop;
vrtBottomLeft.x=recPos.left; vrtBottomLeft.y=recPos.bottom; vrtBottomLeft.z=fZOrder; vrtBottomLeft.tu=TilePos.m_tuLeft; vrtBottomLeft.tv=TilePos.m_TvBottom;
vrtBottomRight.x=recPos.right; vrtBottomRight.y=recPos.bottom; vrtBottomRight.z=fZOrder; vrtBottomRight.tu=TilePos.m_tuRight; vrtBottomRight.tv=TilePos.m_TvBottom;

//add six vertices to the list of vertices
// v1-----v2 //0.0-----0.0 //tu=horizontal
// |----/-| //| / | //tv=vertical
// |---/--| //| / |
// |--/---| //| / |
// v0-----v3 //0.0-----1.0
m_lstVertexList.push_back(vrtBottomLeft);
m_lstVertexList.push_back(vrtTopLeft);
m_lstVertexList.push_back(vrtTopRight);
m_lstVertexList.push_back(vrtBottomRight);

//update how many primitives and vertices there are to render
++m_nPrimitiveCount;++m_nPrimitiveCount;
m_nVertexCount+=4;
}



Draw indexed primitive fails

g_pD3DDevice9->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,VertexManager.GetVertexCount(),0,VertexManager.GetPrimitiveCount());

Share this post


Link to post
Share on other sites
Well I went through it nothing big jumped out at me, I would look at your vertex counts then... I do something like (VertexManager.GetVertexCount() / 3). Are your vertex and primitive counts correct? Maybe the original problem was in there...
Another thing I noticed for your vertex buffer, why ya using D3DPOOL_SYSTEMMEM, why not D3DPOOL_MANAGED? Also are you definitly wanting to use a static buffer? D3DUSAGE_WRITEONLY, or dynamic? D3DUSAGE_DYNAMIC.

Also check your format D3DFMT_INDEX16 or D3DFMT_INDEX32? Just some ideas here, also where is the error coming in at?

EDIT:

Heh this may be really stupid but, I dont see where ya load yer vertex buffer? You still need both buffers... just load it like you loaded the index buffer... unless ya just didnt post it, then pardon me...

Share this post


Link to post
Share on other sites
I just didn't show my vertex buffer code, etc. I want my vertex buffer to be dynamic. My program is crashing at the drawindexedprimitive line and it says:
"No valid index stream currently set. DrawIndexedPrimitive failed"

A few other questions:
For every square I want to draw, I add 4 vertices to the vertex buffer, this is two primitives, so I increase the primitive count by 2. Sould I increase the vertex count by 4 or 6?

How many vertices to primitives is required for drawindexedprimitive to work?

I only fill the index buffer once (at load), is this ok (cause I am always going to be drawing squares)?

Share this post


Link to post
Share on other sites
1) DrawIndexedPrimitive () should be able to accept any number of verts.

2) m_pDevice->SetStreamSource () will solve the problem with "No valid index stream currently set. DrawIndexedPrimitive failed"

3) You should increase the vertex count by 4 if you create 4 vertices.

4) If m_pDevice->SetStreamSource () doesn't work, m_pDevice->DrawPrimitiveUP () should work fine for your purposes.

5) You should really get a good book about 3d programming. If you don't know about indices, it is probably a good idea. The books I recommend are "3d Game Engine Programming" by Stephan Zerbst and "Programming Role Playing Games with Direct X" by Jim Adams. Both books have their flaws and are complicated (depending on your abilities), but at the end, you will be much farther than you are right now.

Share this post


Link to post
Share on other sites
I'm already setting my streamsource and FVF:

g_pD3DDevice9->SetFVF(g_dwFVF);
g_pD3DDevice9->SetStreamSource(0,g_pVertexBuffer,0,sizeof(VERTEX));


So I don't know why it thinks the problem is with the stream.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!