• Create Account

## How many vertices in a teapot?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

17 replies to this topic

### #1Hseptic  Members

146
Like
0Likes
Like

Posted 25 May 2012 - 06:03 PM

Is there any way to access the vertices using the ID3DXMesh interface of a teapot (after using D3DXCreateTeapot)? Is there any way to add a color of type D3DCOLOR to each vertex?

### #2DJTN  Members

207
Like
0Likes
Like

Posted 25 May 2012 - 07:10 PM

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/directx/articles/d3dxmesh.htm

### #3Hseptic  Members

146
Like
0Likes
Like

Posted 25 May 2012 - 07:32 PM

How do I know if I've reached the end of the buffer? i.e. how many verts are in the teapot?

### #4SiCrane  Moderators

11526
Like
0Likes
Like

Posted 25 May 2012 - 08:01 PM

Did you try the ID3DXBaseMesh::GetNumVertices() member function?

### #5Bacterius  Members

13102
Like
0Likes
Like

Posted 26 May 2012 - 01:49 AM

I guess it depends on the teapot. Some have more vertices than others (of course, more is not always better, especially when it comes to teapots).

Ok, I'll leave now!

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

### #6Hseptic  Members

146
Like
0Likes
Like

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.

### #7hupsilardee  Members

491
Like
1Likes
Like

Posted 26 May 2012 - 12:36 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

### #8Hseptic  Members

146
Like
0Likes
Like

Posted 26 May 2012 - 03:20 PM

After locking, how do I insert the colors into the buffer exactly?

### #9Hseptic  Members

146
Like
0Likes
Like

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.

### #10DJTN  Members

207
Like
0Likes
Like

Posted 26 May 2012 - 05:38 PM

You pass in a zero for options, vertex Elements, pointer to your device, and then (out) the new mesh. If it's telling you the VertexColElement is undefined then you need to define (initiate) it. If you've already defined it, debug (step through code) to see what happened to it.

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.

### #11Hseptic  Members

146
Like
0Likes
Like

Posted 26 May 2012 - 07:47 PM

I'm trying to add a color to each vertex in the teapot, though I'm still confused about the steps necessary to do so. I have defined VertexColElements as shown in one of my above posts. It is not a compile or run time error. The coding environment merely shows a squiggly like under "VertexColElements" stating that it is an undefined idenitfier. This leads me to believe that I've missed something. I just don't know what.

### #12belfegor  Members

2833
Like
0Likes
Like

Posted 27 May 2012 - 04:10 AM

So you have vertex struct and declaration, then:
//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.

### #13hupsilardee  Members

491
Like
1Likes
Like

Posted 27 May 2012 - 05:52 AM

You have not actually declared the static declarator member, you have only defined it. In the header fileyou have something like this

// 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


### #14Hseptic  Members

146
Like
0Likes
Like

Posted 28 May 2012 - 02:53 PM

I have defined VertexColElements like so...
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?

### #15hupsilardee  Members

491
Like
0Likes
Like

Posted 29 May 2012 - 04:23 AM

Is VertexColElements defined before the function call? It looks like mTeapot is a member, so can the class with the mTeapot member access it? As a quick workaround you could try copy-pasting that array directly above the call to mTeapot->CloneMesh(), that would work but is not great as a long term solution

### #16DJTN  Members

207
Like
0Likes
Like

Posted 30 May 2012 - 09:17 AM

You have defined a structure but you have not declared a var to hold the struc in memory.

### #17KymikoLoco  Members

195
Like
0Likes
Like

Posted 30 May 2012 - 10:17 AM

You have defined a structure but you have not declared a var to hold the struc in memory.

Not quite correct, since VertexCol::Decl is a static variable. Refer to this:

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().

### #18hupsilardee  Members

491
Like
0Likes
Like

Posted 31 May 2012 - 06:42 PM

You have defined a structure but you have not declared a var to hold the struc in memory.

Not quite correct, since VertexCol::Decl is a static variable. Refer to this:

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.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.