This is isn't a progress post as such, it's actually a quick howto for anyone else who's trying to optimise a D3DVertexBuffer and D3DIndexBuffer and is not using D3DX.
The short answer is one has to use D3DX - but it's not as bad as it sounds. The gist of it is too call OptimizeInplace on a ID3DXMesh. The code below shows how to copy an existing vertex buffer and index buffer into the ID3DXMesh, optimise it and then copy them back again.
ID3DXMesh* pXMesh;
void* pvDestIndexBuffer;
void* pvDestVertexBuffer;
void* pvSrcIndexBuffer = The pointer .Lock() gave you;
void* pvSrcVertexBuffer = The pointer .Lock() gave you;
DWORD* pvAdjacency;
D3DXCreateMeshFVF(iNumTriangles, iNumIndicies, D3DXMESH_SYSTEMMEM, Your FVF here, lpD3DDevice, &pXMesh);
iVertSize = pXMesh->GetNumBytesPerVertex();
pXMesh->LockIndexBuffer(D3DLOCK_NO_DIRTY_UPDATE, &pvDestBaseIndexBuffer);
pXMesh->LockVertexBuffer(D3DLOCK_NO_DIRTY_UPDATE, &pvDestVertexBuffer);
memcpy(pvDestVertexBuffer, pvSrcVertexBuffer, iVertexSize * iNumVerticies);
memcpy(pvDestIndexBuffer, pvSrcIndexBuffer, sizeof(WORD) * iNumVerticies);
Start interesting bit here
pvAdjacency = (DWORD*)malloc(iNumTriangles * 3 * sizeof(DWORD));
pXMesh->GenerateAdjacency(0.0f, pvAdjacency);
pXMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE | D3DXMESHOPT_DONOTSPLIT, pvAdjacency, NULL, NULL, NULL);
free(pvAdjacency);
End interesting bit
memcpy(pvSrcIndexBuffer, pvDestIndexBuffer, sizeof(WORD) * iNumVertices);
memcpy(pvSrcVertexBuffer, pvDestVertexBuffer, iVertexSize * iNumVerticies);
.Unlock() your buffers
The bad news is that somewhere in typing that I got confused between the number of vertices and the number of indicies but it's not too difficult to work out which is which. They're all called iNumVerticies here.
Obviously for 32 bit indicies one needs to use sizeof(DWORD) instead of sizeof(WORD).
Later!
The short answer is one has to use D3DX - but it's not as bad as it sounds. The gist of it is too call OptimizeInplace on a ID3DXMesh. The code below shows how to copy an existing vertex buffer and index buffer into the ID3DXMesh, optimise it and then copy them back again.
ID3DXMesh* pXMesh;
void* pvDestIndexBuffer;
void* pvDestVertexBuffer;
void* pvSrcIndexBuffer = The pointer .Lock() gave you;
void* pvSrcVertexBuffer = The pointer .Lock() gave you;
DWORD* pvAdjacency;
D3DXCreateMeshFVF(iNumTriangles, iNumIndicies, D3DXMESH_SYSTEMMEM, Your FVF here, lpD3DDevice, &pXMesh);
iVertSize = pXMesh->GetNumBytesPerVertex();
pXMesh->LockIndexBuffer(D3DLOCK_NO_DIRTY_UPDATE, &pvDestBaseIndexBuffer);
pXMesh->LockVertexBuffer(D3DLOCK_NO_DIRTY_UPDATE, &pvDestVertexBuffer);
memcpy(pvDestVertexBuffer, pvSrcVertexBuffer, iVertexSize * iNumVerticies);
memcpy(pvDestIndexBuffer, pvSrcIndexBuffer, sizeof(WORD) * iNumVerticies);
Start interesting bit here
pvAdjacency = (DWORD*)malloc(iNumTriangles * 3 * sizeof(DWORD));
pXMesh->GenerateAdjacency(0.0f, pvAdjacency);
pXMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE | D3DXMESHOPT_DONOTSPLIT, pvAdjacency, NULL, NULL, NULL);
free(pvAdjacency);
End interesting bit
memcpy(pvSrcIndexBuffer, pvDestIndexBuffer, sizeof(WORD) * iNumVertices);
memcpy(pvSrcVertexBuffer, pvDestVertexBuffer, iVertexSize * iNumVerticies);
.Unlock() your buffers
The bad news is that somewhere in typing that I got confused between the number of vertices and the number of indicies but it's not too difficult to work out which is which. They're all called iNumVerticies here.
Obviously for 32 bit indicies one needs to use sizeof(DWORD) instead of sizeof(WORD).
Later!
4 Comments:
NVTriStrip doesn't do a bad job of optimizing the geometry either ;)
And Dude! it's indices, not indicies; vertices, not verticies.
:D
ps. glad to see you getting down and dirty with this stuff again ;)
By Justin Paver, at 5:59 pm
Looking through my code vertices is variously spelt as: verts, vertexs verticies and vertices ;)
Probably I should kleen it up sometime... maybe... sometime.
By Andrew, at 1:21 pm
how about a hybrid: vertexices :)
By Justin Paver, at 3:48 am
Vertex Ice - Ice Ice Baby!
*smacks self in head wished hadn't thought that*
By Andrew, at 7:38 am
Post a Comment
<< Home