#2 Members - Reputation: 199
Posted 25 May 2012 - 07:10 PM
http://www.mvps.org/directx/articles/d3dxmesh.htm
#6 Members - Reputation: 146
Posted 26 May 2012 - 08:33 AM
Is this a trick question? LOL. You can access the vertex buffer through the mesh interface. To add a color type you may need to create a new vertexformat.
http://www.mvps.org/...es/d3dxmesh.htm
I can create a new vertex, like so...
struct VertexCol
{
VertexCol():pos(0.0f, 0.0f, 0.0f),col(0x00000000){}
VertexCol(float x, float y, float z, D3DCOLOR c):pos(x,y,z), col(c){}
VertexCol(const D3DXVECTOR3& v, D3DCOLOR c):pos(v),col(c){}
D3DXVECTOR3 pos;
D3DCOLOR col;
static IDirect3DVertexDeclaration9* Decl;
};
D3DVERTEXELEMENT9 VertexColElements[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
D3DDECL_END()
};
HR(gd3dDevice->CreateVertexDeclaration(VertexColElements, &VertexCol::Decl));
The question is how do I implement this new format into the teapot?
Edited by Hseptic, 26 May 2012 - 08:33 AM.
#9 Members - Reputation: 146
Posted 26 May 2012 - 04:06 PM
use the ID3DXMesh::CloneMesh function, then lock the vertex buffer and write in all the colors. Make sure not to lock with the overwrite flag otherwise all the positions will be lost
I'm having trouble with the CloneMesh function. What exactly do I put for the second parameter? Right now I have:
mTeapot->CloneMesh(0, VertexColElements, gd3dDevice, &mTeapotClone);However it says that "VertexColElements" is undefined.
#10 Members - Reputation: 199
Posted 26 May 2012 - 05:38 PM
Cloning allows you to create a structure (format) for the vertex buffer to hold the data YOU define.
It might be a good idea to convey what you're trying to accomplish. I think the standard format of a mesh already contains a vertex color section.
#11 Members - Reputation: 146
Posted 26 May 2012 - 07:47 PM
#12 Members - Reputation: 1098
Posted 27 May 2012 - 04:10 AM
//afer CloneMesh
D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
hr = teapotMesh->GetDeclaration(decl);
if(FAILED(hr))
{
...// on failed
}
WORD offsetToPosition = 0;
bool havePos = false;
for(UINT i = 0; i < MAX_FVF_DECL_SIZE; ++i)
{
if(decl[i].Stream == 0xFF || decl[i].Stream != 0)
{
break;
}
if((decl[i].Usage == D3DDECLUSAGE_POSITION) && (decl[i].Type == D3DDECLTYPE_FLOAT3))
{
offsetToPosition = decl[i].Offset;
havePos = true;
continue;
}
}
if(!havePos)
{
...// on failed
}
DWORD numVertices = teapotMesh->GetNumVertices();
DWORD numTri = teapotMesh->GetNumFaces();
DWORD numIndices = teapotMesh->GetNumFaces() * 3;
DWORD bytesPerVertex = teapotMesh->GetNumBytesPerVertex();
USHORT* pNewIndices = nullptr;
USHORT* pTeapotIndices = nullptr;
newMesh->LockIndexBuffer(0, 0, (void**)&pNewIndices, 0);
terrMesh->LockIndexBuffer(0, (void**)&pTeapotIndices);
memcpy(pNewIndices, pTeapotIndices, numIndices);
newMesh->UnlockIndexBuffer();
teapotMesh->UnlockIndexBuffer();
VERTEX* pNewVertices = nullptr;
BYTE* pTeapotVertices = nullptr;
newMesh->LockVertexBuffer(0, 0, (void**)&pNewVertices, 0);
teapotMesh->LockVertexBuffer(0, (void**)&pTeapotVertices);
for(DWORD i = 0; i < numVertices; ++i)
{
pNewVertices[i].position.x = *reinterpret_cast<float*>((i * bytesPerVertex) + pVertices + offsetToPosition);
pNewVertices[i].position.y = *reinterpret_cast<float*>((i * bytesPerVertex) + pVertices + offsetToPosition + sizeof(float));
pNewVertices[i].position.z = *reinterpret_cast<float*>((i * bytesPerVertex) + pVertices + offsetToPosition + sizeof(float) * 2);
pNewVertices[i].color = yourColor;
}
newMesh->UnlockVertexBuffer();
teapotMesh->UnlockVertexBuffer();
Edited by belfegor, 27 May 2012 - 04:11 AM.
#13 Members - Reputation: 442
Posted 27 May 2012 - 05:52 AM
// VertexCol.h
struct VertexCol
{
float x, y, z;
DWORD color;
static IDirect3DVertexDeclaration9* Decl;
};
Then in one of your CPP files you need to type this
// VertexCol.cpp IDirect3DVertexDeclaration9* VertexCol::Decl = NULL;
Unfortunately, static members can be fiddly like this.
Then when this is in place you need to pass in the vertex elements to the CloneMesh function. Making sure that you have initialised VertexCol::Decl:
ID3DXMesh* oldMesh; ID3DXMesh* newMesh; D3DVERTEXELEMENT9 elements[MAX_FVF_DECL_SIZE]; // MAX_FVF_DECL_SIZE is the largest number of elements that any vertex declaration can have VertexCol::Decl->GetDeclaration(elements, NULL); oldMesh->CloneMesh(0, elements, device, &newMesh); // Instead of 0 consider using D3DXMESH_MANAGED as teh first arg // now you have the new mesh with the vertex colors you can release the old one if you no longer need it
#14 Members - Reputation: 146
Posted 28 May 2012 - 02:53 PM
D3DVERTEXELEMENT9 VertexColElements[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
D3DDECL_END()
};
HR(gd3dDevice->CreateVertexDeclaration(VertexColElements, &VertexCol::Decl));
I still don't know why the environment won't recognize VertexColElements when I insert it into the CloneMesh function like this...
mTeapot->CloneMesh(0, VertexColElements, gd3dDevice, &mTeapotClone);
What's wrong?
#15 Members - Reputation: 442
Posted 29 May 2012 - 04:23 AM
#17 Members - Reputation: 195
Posted 30 May 2012 - 10:17 AM
Not quite correct, since VertexCol::Decl is a static variable. Refer to this:You have defined a structure but you have not declared a var to hold the struc in memory.
Making sure that you have initialised VertexCol::Decl
I would go with hupsilardee's advice of copy-pasting the VertexColElements definition directly above the call to CloneMesh().
#18 Members - Reputation: 442
Posted 31 May 2012 - 06:42 PM
Not quite correct, since VertexCol::Decl is a static variable. Refer to this:
You have defined a structure but you have not declared a var to hold the struc in memory.Making sure that you have initialised VertexCol::Decl
I would go with hupsilardee's advice of copy-pasting the VertexColElements definition directly above the call to CloneMesh().
But like I said, not as a long-term solution.






