Retrieving triangles from a vertex buffer. Help needed.

Started by
2 comments, last by George109 18 years, 6 months ago
I'm using the index buffer to get the vertices of the triangles from the vertex buffer. Then with the vertices, I create the triangles. The triangles are stored as a D3DTRIANGLE_LIST in the buffers. I suspect that there is something wrong with the way that I retrieving the vertices from the vertex buffer. Is there any other way to retrieve the position of the vertices from a vertex buffer?


// Get the vertex declaration of the mesh.
D3DVERTEXELEMENT9 vertexDeclaration[MAX_FVF_DECL_SIZE];
pMesh->GetDeclaration( vertexDeclaration );

// Find the offset of the declaration.
DWORD offset = 0;

// Scan the vertex declaration array.
int i = 0;
while( vertexDeclaration.Type != D3DDECLTYPE_UNUSED )
{
	if( vertexDeclaration.Usage == D3DDECLUSAGE_POSITION )
	{
		offset = vertexDeclaration.Offset;
		break;
	}

	i++;
}

// Lock the vertex and index buffer of the mesh.
void* pData = 0;
WORD* pIndexData = 0;
pMesh->LockVertexBuffer( D3DLOCK_READONLY, (void**)&pData );
pMesh->LockIndexBuffer( D3DLOCK_READONLY, (void**)&pIndexData );

// Scan the triangles.
D3DXVECTOR3 vertexPosition[3];
Triangle3 tri;
for( DWORD i = 0, iTriangle = 0; iTriangle < pMeshContainer->MeshData.pMesh->GetNumFaces(); i+=3, iTriangle++ )
{	
	// Get the position.
	memcpy( &vertexPosition[0], &((D3DVERTEXELEMENT9*)pData)[pIndexData] + offset, sizeof(D3DXVECTOR3) );
	memcpy( &vertexPosition[1], &((D3DVERTEXELEMENT9*)pData)[pIndexData[i+1]] + offset, sizeof(D3DXVECTOR3) );
	memcpy( &vertexPosition[2], &((D3DVERTEXELEMENT9*)pData)[pIndexData[i+2]] + offset, sizeof(D3DXVECTOR3) );

	// Build the triangle.
	tri.origin() = vertexPosition[0];
	tri.edge0() = vertexPosition[1] - vertexPosition[0];
	tri.edge1() = vertexPosition[2] - vertexPosition[0];

	// Store it in the triangle list.
	memcpy( pTriangleList[iTriangle].triangle, &tri, sizeof(Triangle3) ); 
}

pMesh->UnlockVertexBuffer();
pMesh->UnlockIndexBuffer();
Advertisement
What is the error/problem you get? Perhaps if you give a problem, you might get a helpful answer?
Scanning through your code, I think that the part where you retreive the actual positions might be a bit off.

Try changing
void* pData = 0;
to this
char* pData = 0; // mainly cuz char is an 8-bit pointer.

Your loop should look like this:
for( DWORD dwFace; dwFace < pMeshContainer->MeshData.pMesh->GetNumFaces(); dwFace++ ){  // Get the position  memcpy( &vertexPosition[0], reinterpret_cast<D3DXVECTOR3*>( pData + (pIndexData[dwFace*3 + 0]*m_pMeshContainer-MeshData.pMesh->GetNumBytesPerVertex()) ), sizeof(D3DXVECTOR3) );  memcpy( &vertexPosition[1], reinterpret_cast<D3DXVECTOR3*>( pData + (pIndexData[dwFace*3 + 1]*m_pMeshContainer-MeshData.pMesh->GetNumBytesPerVertex()) ), sizeof(D3DXVECTOR3) );  memcpy( &vertexPosition[2], reinterpret_cast<D3DXVECTOR3*>( pData + (pIndexData[dwFace*3 + 2]*m_pMeshContainer-MeshData.pMesh->GetNumBytesPerVertex()) ), sizeof(D3DXVECTOR3) );  // Build the triangle.  tri.origin() = vertexPosition[0];  tri.edge0() = vertexPosition[1] - vertexPosition[0];  tri.edge1() = vertexPosition[2] - vertexPosition[0];  // Store it in the triangle list.  memcpy( pTriangleList[iTriangle].triangle, &tri, sizeof(Triangle3) ); }

Notice that since you don't know the exact vertex format, the indexing into the vertex buffer data is more complicated.

The "pIndexData[dwFace*3 + #]" indicates the vertices of a particular triangle. "dwFace" is which triangle in the mesh we're dealing with. You need to multiply by 3 because the index buffer stores the 3 indices of each face consecutively. The "+ #" indicates which vertex of the triangle you refer to.

This value must then be multiplied by the number of bytes per vertex because we don't know what other data each vertex has. It could have a normal vector, texture coordinates, etc... So even though the index buffer tells us logically where in the vertex buffer the actual vertices are, since our vertex buffer pointer isn't of the correct type, we cannot just add this to the vertex buffer pointer. This is why I changed the type of "pData" to char; it lets offset by bytes into the vertex buffer memory.

Once we have the number of bytes into the vertex buffer that the data is located at, we can then copy this data. Notice that I didn't use your "offset" variable. The reason is because I'm assuming that the position of the vertex is always at the start of the vertex; i.e., offset 0. To be technically correct, you should add "offset" to "pData".

Hope this helps,
neneboricua

[Edited by - Coder on October 13, 2005 9:12:28 AM]
That seems to work neneboricua. Thanks for replies!

This topic is closed to new replies.

Advertisement