Sign in to follow this  
dpro

Beginner Problems with Index Buffers

Recommended Posts

I am honestly stumped, I fixed my earlier question, however I cannot seem to get this to work. All I am trying to do is render a relatively simple terrain concept. NOTE: testcol = testrow = 4;
...
float boundsx = 20.0;
float boundsz = 20.0;

void fillVerts()
{
	
	//use tilesize as 10.0
	float tileSize = 10.0;
	char stuff[2000];
	int tCount = 0;
	// 20 is the number of tiles we want
	int i = 0;
	D3DXVECTOR3 zerod( 0, 0, 0 );
	for( int in = 0; in < vtxSize; in++ )
	{
		vertices[i].pos = zerod;
	}
	srand( timeGetTime( ) );

	float stepX = (boundsx*2) / testcol;
	float stepZ = (boundsz*2) / testcol;
	float startX = boundsx;
	float startZ = -boundsz;

	DWORD color = D3DCOLOR_ARGB( 255, 255,255,255);	
	float x,y,z;
	z = startZ;
	for( int zind = 0; zind <= 4; zind++ )
	{
		
		x = startX;
	
		for( int xind = 0; xind <= 4; xind++ )
		{
			if( xind == 0 || xind == 4 || zind == 0 || zind == 4 )
			{
				y = 0.0;
			}
			else
			{
				y = (float)( ( rand() % 10 ) + 2 );
			}

			D3DXVECTOR3 posvec( x, y, z );
			vertices[ i ].pos = posvec; 
			vertices[ i ].color = color;
			
			i++;
			
			x -= stepX;
		}
		z += stepZ;
	}
	createIdxBuff();
}


then create the vertexbuffer, of size 5 x 5 testcol = 4, testrow = 4, numInd = 96 then I create an IndexBuffer:
void createIdxBuff()
{
	void * pbuffInd;
	hr = p_dev->CreateIndexBuffer( numInd * sizeof( WORD ), NULL, D3DFMT_INDEX32, D3DPOOL_MANAGED, &idxBuff, NULL );
			
	if( !FAILED( hr ) )
	{
		WORD * pind = new WORD[ numInd ];
		WORD x = 0, z = 0, i = 0;
		WORD ind = 0;
		int counter = 0;
		int wid = testcol + 1;

		for( z = 0; z < testcol; z++ )
		{
			for( x = 0; x < testrow; x++ )
			{
				//first tri
				pind[counter++]	= ind;
				pind[counter++]	= ind + 1;
				pind[counter++]	= ind + wid;
				//second tri
				pind[counter++]	= ind + wid;
				pind[counter++]	= ind + 1;
				pind[counter++]	= ind + wid + 1;

				ind++;
			}
			ind++;
		}
		
		hr = idxBuff->Lock( 0, numInd * sizeof( WORD ), &pbuffInd, 0 );
		if( !FAILED( hr ) )
		{
			if( memcpy( pbuffInd, pind, numInd * sizeof( WORD ) ) )
			{
				idxBuff->Unlock();
			}
		}
		
		delete[] pind;
		pind = NULL;
	}
	else
	{
		char buf[2048];
		sprintf( buf, "Error: %s", DXGetErrorDescription9( hr ) );
	}

}


finally we render
...
hresult = p_dev->SetStreamSource( 0, vtxbuffer, 0, sizeof( vtx ) );

...
p_dev->SetIndices( idxBuff );
hr = p_dev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, totalVerts, 0, numPolys * 2 );


I should get something like a grid, but instead I get messed up triangles. Anyone able to offer help? Or see something I am doing thats dumb? Thanks in advance.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
being half asleep, and not really having used d3d before, and not really reading your code.... are u sure u are meaning to use D3DPT_TRIANGLELIST ? secondly, if u do mean to, then are u sure the the second triangle that creates the other half of the quad has the vertex's submitted in the correct order (clockwise / anti-clockwise... have u rotated what u are drawing to see if the other side is showing what u mean to have on the front side?). just something to think about, but back to delerium for me.

bye from bris-vegas. N-B

Share this post


Link to post
Share on other sites
Thanks for the reply, I am pretty sure I am winding in the correct order, I am following a tutorial fairly closely, and they use trianglelists as well, so I am thinking thats a good thing. As for the quads matching up, thats also something I keep seeing repeated in the tutorials so I am either not understanding or I am just totally off somewhere else. However, right now I am not seeing a lot of benefit, so if someone sees something else for fixing be more than welcome, I just cannot see it right now. Perhaps I am just missing something small.

Share this post


Link to post
Share on other sites
Hopefully this isn't against the rules, but I have new info on this problem.

I do not know why but for whatever reason I moved the vertex buffer creation and locking code into the fillVerts function.

It now works much better than before, but I have no idea why.

old code =

void fillVerts()
{
//use tilesize as 10.0
float tileSize = 10.0;
char stuff[2000];
int tCount = 0;
//float zmax = -10000000.00;
// 20 is the number of tiles we want
/*float xStart = (float)( 0.0 - ( tSize / 2.0 ) );
float xEnd = (float)(( tSize / 2.0 ) );
float zStart = (float)( 0.0 - ( tSize / 2.0 ) );
float zEnd = (float)(( tSize / 2.0 ) );*/

int i = 0;
int ix = 0;
D3DXVECTOR3 zerod( 0, 0, 0 );
for( int in = 0; in < vtxSize; in++ )
{
vertices[i].pos = zerod;
}
srand( timeGetTime( ) );

float stepX = (boundsx*2) / m_cols;
float stepZ = (boundsz*2) / m_rows;
float startX = -boundsx;
float startZ = boundsz;

DWORD color = D3DCOLOR_ARGB( 255, 255,255,255);
float x,y,z;
z = startZ;
for( int zind = 0; zind <= m_rows; zind++ )
{
//z = zf[ zind ];
x = startX;

for( int xind = 0; xind <= m_cols; xind++ )
{
if( xind == 0 || xind == m_cols-1 || zind == 0 || zind == m_rows-1 )
{
y = 0.0;
}
else
{
y = (float)( ( rand() % 10 ) + 2 );
//y = 0.0;
}

D3DXVECTOR3 posvec( x, y, z );
vertices[ i ].pos = posvec;
vertices[ i ].color = color;

i++;

x += stepX;
}
z -= stepZ;
}
}



new code

void fillVerts()
{

//use tilesize as 10.0
float tileSize = 10.0;
char stuff[2000];
int tCount = 0;
// 20 is the number of tiles we want
/*float xStart = (float)( 0.0 - ( tSize / 2.0 ) );
float xEnd = (float)(( tSize / 2.0 ) );
float zStart = (float)( 0.0 - ( tSize / 2.0 ) );
float zEnd = (float)(( tSize / 2.0 ) );*/

int i = 0;
int ix = 0;
D3DXVECTOR3 zerod( 0, 0, 0 );
for( int in = 0; in < vtxSize; in++ )
{
vertices[i].pos = zerod;
}
srand( timeGetTime( ) );

float stepX = (boundsx*2) / m_cols;
float stepZ = (boundsz*2) / m_rows;
float startX = -boundsx;
float startZ = boundsz;

DWORD color = D3DCOLOR_ARGB( 255, 255,255,255);
float x,y,z;
z = startZ;
for( int zind = 0; zind <= m_rows; zind++ )
{
//z = zf[ zind ];
x = startX;

for( int xind = 0; xind <= m_cols; xind++ )
{
if( xind == 0 || xind == m_cols-1 || zind == 0 || zind == m_rows-1 )
{
y = 0.0;
}
else
{
y = (float)( ( rand() % 10 ) + 2 );
//y = 0.0;
}

D3DXVECTOR3 posvec( x, y, z );
vertices[ i ].pos = posvec;
vertices[ i ].color = color;

i++;
x += stepX;
}
z -= stepZ;
}
//MOVED BUFFER CREATION AND LOCKING HERE INSTEAD OF OUTSIDE FUNCTION
hr = p_dev->CreateVertexBuffer( totalVerts * sizeof( vtx ), D3DUSAGE_WRITEONLY, vtxfvf, D3DPOOL_MANAGED,
&vtxbuffer, NULL );

if( FAILED( hr ) )
{
char buf[2048];
sprintf( buf, "Found the error: %s", DXGetErrorDescription9( hr ) );
}
else
{

void *data;
hr = vtxbuffer->Lock( 0, 0, &data, D3DLOCK_DISCARD );
if( !FAILED( hr ) )
{
if( !memcpy( data, vertices, totalVerts * sizeof( vtx ) ) )
{
int pasnfias = 34;
}
}
hr = vtxbuffer->Unlock();
}
}



Suddenly this move of code seems to have largely fixed it. Vertices was a globally defined buffer in the .h file, so I cannot see why this would be any different. Anyone got any ideas on this? This is very very odd to me, but perhaps I have been looking at this too long to see whats wrong. Any ideas would be aweomse, thanks again!

Share this post


Link to post
Share on other sites
Hey dpro hello :)
I'd like to comment on your Index creation method. From the line below:
hr = p_dev->CreateIndexBuffer( numInd * sizeof( WORD ), NULL, D3DFMT_INDEX32, D3DPOOL_MANAGED, &idxBuff, NULL );


I see a big problem.

Unless on your machine your WORD is a 32-bits value (which I doubt ^^) you are creating an index buffer which is actually half the index-count you want. Say you want 100 indices and your WORD is a 2 byte value ( = 16 bits ). You will end up with a 200 bytes Index buffer. But since you created it with D3DFMT_INDEX32, DX will think that you'll fill it with 4 bytes values, and he'll consider your buffer is then a 200 / 4 = 50 indices buffer :) Too bad heh ?

direct quote from the SDK documentation:
Quote:

I notice that 32-bit indices are a supported type; can I use them on all devices?
No. You must check the D3DCAPS9::MaxVertexIndex field to determine the maximum index value that is supported by the device. This value must be greater than 2 to the 16th power -1 (0xffff) in order for index buffers of type D3DFMT_INDEX32 to be supported. In addition, note that some devices may support 32-bit indices but support a maximum index value less than 2 to the 32nd power -1 (0xffffffff); in this case the application must respect the limit reported by the device.


So I suggest you to use 16 bits indices wherever they would fit your needs.

Now another remark, about the way you fill up your index buffer (and maybe your vertex buffer too although I dont know what type of object your "vertices" var is). When you lock a buffer (whether it is an index or vertex buffer matters little), you retrieve a pointer to memory that directx has had ready just for you to write to it :) So why bother allocation a
new WORD[ numInd ];

Go ahead man, lock that buffer like you did:
hr = idxBuff->Lock( 0, numInd * sizeof( WORD ), &pbuffInd, 0 );

or, since you are locking the whole buffer anyway:
hr = idxBuff->Lock( 0, 0, &pbuffInd, 0 );

and use pbuffInd as if you had new'd it (of course do not delete[] it ^^ I think it's obvious heh ? :p)

Well, this is what I cans say so far about your code, try to fix that up a shoot again. Let us know about it is working or not.

And If I said some bullshit, shame on me till the end of time ;)

Share this post


Link to post
Share on other sites
Good points :) Changing those things turned out to be the key!

Also thats an excellent point about using the pointer already created by d3d :)
I always saw it that way and figured that was the only way to do it. No bull from you at all :) good points all around and thanks again, frustration always makes finding a problem harder.

Well I could delete the pointer given to me by D3D, but I don't wanna make it harder on myself :)

Share this post


Link to post
Share on other sites
Quote:
Original post by dpro
Well I could delete the pointer given to me by D3D, but I don't wanna make it harder on myself :)

Yeah go ahead :) And you'll be back here pretty soon :p

Share this post


Link to post
Share on other sites
Quote:
Original post by janta
Quote:
Original post by dpro
Well I could delete the pointer given to me by D3D, but I don't wanna make it harder on myself :)

Yeah go ahead :) And you'll be back here pretty soon :p


Lol I know better than that, I'm not as incompetent as I seem ;) Thanks again for the pointers, I took up D3D a while ago... then dropped it, but I never got far into it as I kept on getting busy with other projects sadly.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this