• Advertisement
Sign in to follow this  

CreateVertexBuffer() is creating a VB with the same value as one that already exists.

This topic is 4429 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

I have found the cause of a bug I've been getting just trying to render 2 coloured quads. My code basically goes like this:
CreateVertexBuffer1()
Lock, copy data, Unlock

CreateVertexBuffer2()
Lock, copy data, Unlock

DrawVertexBuffer1()
DrawVertexBuffer2()





The result I've been getting is that VertexBuffer1 is rendered as a screwed up mess, while VertexBuffer2 comes out fine. So I made a test case that created 2 arrays, holding raw vertex data for both quads, and two function-scope VBs. In the same function I performed the pseudocode above. "Create1, create2, draw1, draw2". Came out fine. If I altered the code to go "create1, draw1, create2, draw2" this also ran fine. I can't tell you how long I spent wondering (incorrectly) why storing the raw data in a vector made any difference. Well, I can, days. Eventually I started looking more closely at Lock(). The 3rd parameter of Lock() is the address of a pointer to a void. A void** even. You have to declare a pointer, then pass the address of that pointer into Lock(). Lock() sticks a value in that pointer, so now your pointer points to the start of the vertex buffer you used to call Lock(). I grabbed the values of both pointers in my test case: 24265984 24332032 Then the bugged case: 13697792 13697792 So that's it. In my test case, Lock() returns a different area of memory for each quad's blob of video memory. In the bugged case, it doesn't, then when I try to draw the first quad, its data has already been messed up by the Lock() and copy to the 2nd quad's memory area. Fantastic. Still.. why? Why is the usage of vectors causing Lock() to return the same address. Why are two different vertex buffer objects giving me the same blob of video memory? Of course, then I actually thought to check the vertex buffer objects themselves. In the test case, these 2 objects are declared with function-scope, but in the bugged code, they are stored in a vector of vectors, elements being pushed onto the back of the vector as needed. When I create the 2nd LPDIRECT3DVERTEXBUFFER9 object, it points to the same IDirect3DVertexBuffer9 interface that the first one did. Again, not in the test case.. not when I declared two function-scope LPDIRECT3DVERTEXBUFFER9 vertex buffers. Each one points to a different place. For some reasons, if you do this:
LPDIRECT3DVERTEXBUFFER9 VB1, VB2;
CreateVertexBuffer(...., &VB1);
CreateVertexBuffer(...., &VB2);




then VB1 != VB2. But if you do this:
ReleaseRenderLayers();
m_VLayersToRender.push_back(RENDERLAYER());
m_VLayersToRender.back().v_PaintingData.push_back(RENDERDATA());
CreateVertexBuffer(..., &(m_VLayersToRender.back().v_PaintingData.back().VB));

m_VLayersToRender.back().v_PaintingData.push_back(RENDERDATA());
CreateVertexBuffer(..., &(m_VLayersToRender.back().v_PaintingData.back().VB));



then m_VLayersToRender.back().v_PaintingData[0].VB == m_VLayersToRender.back().v_PaintingData[1].VB Even though the second element of the v_PaintingData vector, and hence the second VB, doesn't even exist by the time the first one is completely created. Even though both VBs are in different places in memory. For some reason, CreateVertexBuffer() is giving them the same values. Hence the same IDirect3DVertexBuffer9 interface object, hence calling the same Lock() function.. blah blah blah. I still don't know why vectors cause this screwup. DirectX hurrah! The bugged code. >_< [Edited by - Defend on January 3, 2006 8:35:13 AM]

Share this post


Link to post
Share on other sites
Advertisement
Hi,

I've been looking through the code. Is there no chance that ReleaseRenderLayers(); is releasing the VB you create just before calling it (VB #1)?

Also, are both Create functions succeeding? No debug output?

Hope this helps :).

Share this post


Link to post
Share on other sites
Yeah I removed the Error checking lines to try and clear up what was already some lengthy code. I had checked the DirectX function returns many times. Also no chance of ReleaseRenderLayers() doing anything seedy, its only about 5 straightforward lines.

I had tried absolutely everything before coming to the conclusion that the vectors were causing some screwup, so when I got to that point, I had no more ideas at all for how to fix it. You did manage to come up with a new suggestion though (checking ReleaseRenderLayers()), just, that wasn't it. Wish it was.

The problem was the old compiler I was using! >_< Wasted days using broken code. Zeux in #Gamedev tried to find the bug with me, and eventually he and others suggested ditching my old VC++ 6.0. Suggested with Gusto. And that was it; VC++EE 2005, the new PSDK, and alot of converting to LPCTSTR later, the test program was compiling again and the bugged code working fine.

Thanks for having a go though. As you can see, you're the only one, so much appreciation there.
(And a big thanks to Zeux for reaching my level of stuckness enough to suggest it was the compiler.)

Share this post


Link to post
Share on other sites
Ok, I'm stupid, but not in the way I'd like.
The bug is still there, I'm just stupid for forgetting that I had edited my test case to actually run properly before switching compilers and libraries.

So now I'm on VC++EE 2005, with the new PSDK, and the bug is still there. Its irritating to be still dealing with the same bug after more than a week, but I'll write a couple of minimal programs to test the bug as acutely as possible. Until then, any more ideas?

Share this post


Link to post
Share on other sites
This might be a little difficult to test, but I'm a bit worried you might be releasing your VB before you're expecting it to. I see no other way you'd get a new device with the same memory address, and no error/warning.

I get the feeling that the vector interface's push_back() function is destroying your object, after copying it. If you placed any call to Release() on the VB in the objects' destructor (you're using two-tiered vectors, so in either of the two object types), the memory will get released on the push_back() function, I think (I'm really not sure aobut this, the vector class is a big question-mark to me :)).

As a quick test, I'd recommend one of two things:

1) Comment out ANY call to Release on any vertex bufffer.
2) Try using a vector of pointers, instead of a vector of objects. You'll be able to control when the objects are destroyed, and you're more likely to avoid this bug.

I hope I'm accurate on this, but it's still worth a shot :) Good luck, hope this helps.

Share this post


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

  • Advertisement