Index Buffer - Still Not Resolved...

Started by
8 comments, last by jtmerchant 20 years, 1 month ago
I've been having a bit of trouble with my simple mesh class that allows the programmer to easily use vertex and index buffers. Right now, the problem is that my program bombs out when I try to render indexed primitives. I have tracked down the bug to this function call: (*device)->SetIndices(ib); ib being the pointer to the index buffer. Here is the code dealing with ib:

//Initialize the buffer

(*device)->CreateIndexBuffer(sizeof(short)*maxi,D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&ib,NULL);
//Fill the buffer

short* i;
ib->Lock(0,0,(void**)&i,0);
for(int a=0;a < vl.size();a++)  {
	i[a]=il[a];
}
ib->Unlock();
ibinit=true;
//il is an instance of the class std::vector containing the indices input by the user:

FWRESULT FWMesh::FillList(short index)  {
	il.push_back(index);
	return FW_OK;
}
If I take SetIndices() out, the program works fine without bombing out, that is except for the fact that it doesn't render anything when I call DrawIndexedPrimitive(), as the SetIndices() function is required. EDIT:: Gwahaha! Die forum monster! I win! I posted without you eating half my post! EDIT:: If you need more surrounding code, just say the word "word" and I'll reply with more. EDIT:: Some of this is a bit mucked up because I forgot the source tags and the message board took some of the code as unicode, but I cleaned up as well as I could. EDIT:: I changed the title so people wouldn't say, "Hey, 9 posts, it's probably solved already." [edited by - jtmerchant--GWAAHAHAHAHHAHHAHAHAHAHAHAHAHAHAHAHAHAHHAHAHAHAHAHAHHAHAHAHAHAHAHAHAHAHAHAH! I'm okay. Really. I am.] [edited by - jtmerchant on March 6, 2004 9:50:47 PM] [edited by - jtmerchant on March 6, 2004 9:54:50 PM] [edited by - jtmerchant on March 15, 2004 3:49:19 AM] [edited by - jtmerchant on March 18, 2004 9:26:03 AM]
Advertisement
Is vl.size() the same as maxi?? Also, maybe you should use WORD instead of "short" for your index array. I forget how many bits "short" is defined to have.

neneboricua
vl.size is the number of indices (which amounts to 6 in the case of the 4-pointed rectangle I am testing with). maxi is a value set by the user so they can use the index buffer without knowing how many indices they will use. In my example case, it is 100, just to be sure. If the index buffer can contain more indices than it renders, and just renders the needed indices, it doesn''t really make a difference, does it? And as to the contained variable, I tried WORD without success. I''ve tried short in the past and it has worked fine, my needs not exceeding the given 2 bytes (16 bits), considering I don''t think my vertex buffer has more than 65,000 stored vertices.
Just because commenting that line out allows the program not to crash doesn''t mean that this line is causing the problem. The problem is probably removed by commenting out this line because DirectX is not using index buffers at all without it, and thus some problem with the data in your index buffer, or the format of your buffer, etc., is never becoming an issue. My guess is that you either have bad indices in your buffer, or your DrawIndexedPrimitive has bad parameters.

int main() { return *((int*)0); }
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Actually, Agony, you're probably right, but I only know it bombs out precisely on SetIndices because I put 2 message boxes around SetIndices, 1 right before which is seen, then 1 right after which I never see because it bombs out right before it. I know it's not an intialization error because initialization returns fine. This narrows it down pretty well- it obviously has something to do with filling the buffer or filling the list.

EDIT:: Basically, either of these:
FWRESULT FWMesh::FillList(short index)  {	il.push_back(index);	return FW_OK;}//--------------------------------------------------------short* i;ib->Lock(0,0,(void**)&i,0);for(int a=0;a < il.size();a++)  {	i[a]=il[a];}ib->Unlock();

I reposted these so you didn't have to look through the whole source.

EDIT:: Just fixed the vl.size to il.size.

[edited by - jtmerchant on March 16, 2004 2:11:18 AM]

[edited by - jtmerchant on March 18, 2004 6:48:11 AM]
Is there some sort of function to check if the information in the index buffer is corrupted?

EDIT:: No one replying.... does that mean "no"?

[edited by - jtmerchant on March 18, 2004 1:42:16 AM]
OK, few things:

1) You fill your list with indices from il, yet you fill it up to vl.size() would it not be better to fill it up to il.size()?

2) Get the HRESULTs from your D3D calls and look at them to see whats going on. Especially, get it from the SetIndices() call you think is crashing.

3) Set the debug spew up to maximum in the DX control panel.

Let us know what happens...

-Mezz
1) That was a typo I fixed a while ago. Guess I forgot to repost.
2) Everything returns fine, except for SetIndices(), which doesn't return at all, crashing within the function.
3) Umm... I barely understand debugging, but I know enough of it to narrow down certain problems. However when it comes to things like having to "set the debug spew up to maximum in the DX control panel" I have to say: "WHATCHA MEAN BOY?!" No, jk, but I still have no idea what that means.

EDIT:: Hey hey! Someone actually replied

[edited by - jtmerchant on March 18, 2004 6:45:23 AM]
By debug spew I mean
Control Panel -> DirectX -> Direct3D -> Debug Output Level
and set it all the way to more.

Perhaps a bit more surrounding code would be helpful to diagnose this problem, seeing as I odnt have any more ideas from what you''ve said.
BTW, what SDK are you using?

-Mezz
Ok, upped the DOL and didn''t really help much.
Here is basically the current condition of the relevant code for the DLL class FWMesh, updated to the time this is posted:
// Initialize buffersFWRESULT FWMesh::InitBuffer(IDirect3DDevice9** device,FWBUFFERTYPE bt)  {	if(bt | FWBT_VERTEX)		(*device)->CreateVertexBuffer(sizeof(FWVERTEX)*maxv,D3DUSAGE_WRITEONLY,FVF,D3DPOOL_MANAGED,&vb,NULL);	else if(bt | FWBT_INDEX)  {		if(((*device)->CreateIndexBuffer(sizeof(short)*maxi,D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&ib,NULL)) != D3D_OK)  {			return FWRESULT_ERROR;		}	}	return FW_OK;}//Fill the buffers from the listFWRESULT FWMesh::FillBuffer(FWBUFFERTYPE bt)  {	if(bt | FWBT_VERTEX)  {		FWVERTEX* v;		vb->Lock(0,0,(void**)&v,0);		for(int b=0;b < vl.size();b++)  {			v[b]=vl[b];		}		vb->Unlock();	}	else if(bt | FWBT_INDEX)  {		short* i;		ib->Lock(0,0,(void**)&i,0);		for(int a=0;a < il.size();a++)  {			i[a]=il[a];		}		ib->Unlock();		ibinit=true;	}	return FW_OK;}/*Fill the lists (less complicated, without the void pointer converted to either pointer blah blah blah you don''t care.*/FWRESULT FWMesh::FillList(float x,float y, float z,D3DCOLOR color)  {	vl.push_back(FWVERTEX(x,y,z,color));	return FW_OK;}FWRESULT FWMesh::FillList(short index)  {	il.push_back(index);	return FW_OK;}// The cleaned up rendering function (in reality is different- bunch of commented out code.FWRESULT FWMesh::Render(IDirect3DDevice9** device)  {	(*device)->SetFVF(FVF);	(*device)->SetStreamSource(0,vb,0,sizeof(FWVERTEX));	(*device)->SetIndices(ib);	(*device)->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,vl.size(),0,il.size()/3);

That''s what''s in the mesh part of my engine. Now here''s the actual program code:
// Setup	cube=new FWMesh;	cube->Init();	cube->SetFVF(FWVERTEX::FVF);	cube->FillList(1.0f,-1.0f,-5.0f,0xFF00FFFF);	cube->FillList(1.0f,1.0f,-5.0f,0xFFFFFF00);	cube->FillList(-1.0f,-1.0f,-5.0f,0xFFFFFF00);	cube->FillList(-1.0f,1.0f,-5.0f,0xFFFFFF00);	// The order may look a bit wierd ''cause I haven''t fixed it from tinkering to see what the problem was-	cube->FillList(0);	cube->FillList(1);	cube->FillList(2);	cube->FillList(2);	cube->FillList(1);	cube->FillList(3);	cube->InitBuffer(&device,FWBT_VERTEX);	if((cube->InitBuffer(&device,FWBT_INDEX)) != FW_OK)		MessageBox(NULL,"Index buffer failed to initialize. Darnit!!!!","Error.... Error....",MB_OK);	cube->FillBuffer(FWBT_VERTEX);	cube->FillBuffer(FWBT_INDEX);/* Render (heh, once I get this mesh thing mostly running, it''ll be so easy to render, even though I''ll have to give it carrots) :)*/cube->Render(&device);

This topic is closed to new replies.

Advertisement