Sign in to follow this  
longjohnsliver

Crashing indexed buffer

Recommended Posts

longjohnsliver    122
I creted a small app to test what I'd learnt about indexed buffers but it crashed. I believe there's something wrong with one of these functions:
WORD indices[] // ... (Index list)
void* IndexPtr;

// Main stuff

// Pass (void*)&indices as IndexList
bool SetIndexBuffer(IDirect3DDevice9 *pDevice, IDirect3DIndexBuffer9 *pIB,
                    DWORD FirstIndex, DWORD NumIndices, void *IndexList)
{
  if(!pGraphics || !IndexList || !pIB)
    return false;

  if(FAILED(pGraphics->CreateIndexBuffer(NumIndices * sizeof(WORD),
            0, D3DFMT_INDEX32, D3DPOOL_MANAGED, &pIB, NULL)))
  return false;

  if(FAILED(pIB.Lock(FirstIndex * sizeof(WORD), NumIndices * sizeof(WORD), (void**)&IndexPtr, 0)))
    return false;

  memcpy(IndexPtr, IndexList, NumIndices * sizeof(WORD));

  if(FAILED(pIB.Unlock()))
    return false;

  return true;
}

bool RenderIndexBuffer(IDirect3DDevice9 *pDevice, IDirect3DIndexBuffer9 *pIB,
                       D3DPRIMITIVETYPE Type, DWORD NumPrimitives,
                       DWORD NumVertices, DWORD FirstIndex)
{
  if(!pDevice || !pIB)
    return false;

  // Now set FVF, set vertices

  if(FAILED(pGraphics->SetIndices(pIB)))
    return flase;
  if(FAILED(pGraphics->DrawIndexedPrimitive(Type, 0,
            FirstIndex, NumVertices(), 0, NumPrimitives)))
    return false;

  return true;
}
Thanks for any help! PS: I hope I didn't make any typos while making some modifications to my source to show it here :S

Share this post


Link to post
Share on other sites
Evil Steve    2017
SetIndexBuffer() only takes a pointer to an IB, when it should take a pointer to a pointer. Otherwise, the index buffer pointer is never saved out of the function, and you'll be trying to render with a fubar pointer.

Share this post


Link to post
Share on other sites
Evil Steve    2017
Your SetIndexBuffer() function takes the address of the pIB parameter and passes it to CreateIndexBuffer(). CreateIndexBuffer() then sets the value of pIB (Which is a pointer). Outside the function, the pointer you pass into SetIndexBuffer() is unaffected, because the pointer is copied. CreateIndexBuffer() "returns" a pointer to a IDirect3DIndexBuffer9, not a real IDirect3DIndexBuffer9 class.

It's kinda hard to explain really... This is why CreateIndexBuffer() takes a pointer to a pointer to an index buffer, not a pointer to an index buffer.

The following version should work (untested):

bool SetIndexBuffer(IDirect3DDevice9 *pDevice, IDirect3DIndexBuffer9 **ppIB,
DWORD FirstIndex, DWORD NumIndices, void *IndexList)
{
if(!pGraphics || !IndexList || !pIB)
return false;

if(FAILED(pGraphics->CreateIndexBuffer(NumIndices * sizeof(WORD),
0, D3DFMT_INDEX32, D3DPOOL_MANAGED, ppIB, NULL)))
return false;

if(FAILED((*ppIB)->Lock(FirstIndex * sizeof(WORD), NumIndices * sizeof(WORD), (void**)&IndexPtr, 0)))
return false;

memcpy(IndexPtr, IndexList, NumIndices * sizeof(WORD));

if(FAILED((*ppIB)->Unlock()))
return false;

return true;
}


It's usually a good idea to use LPDIRECT3DINDEXBUFFER9 instead of IDirect3DIndexBuffer9*, since it helps to remind you (Well, it helps to remind me [smile]) that you can't ever deal with a raw IDirect3DIndexBuffer9 class, only pointers to it.

Share this post


Link to post
Share on other sites
ET3D    810
What kind of crash are you getting? Where does it happen? Does Direct3D print anything when you run it in debug mode? (Saying that a program crashed is all well and good, but doesn't give much to go on.)

What's obviously missing from your code is the setting of the vertex stream, but you might have just cut it out for the posting.

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