Sign in to follow this  
bfarah

Vertex color not working

Recommended Posts

bfarah    100
Hi, i know the basics of direct 3D and i have looked every where online and in books to change the vertex color and for some reason its not changing. I tried using FVF, and vertex element decl. here is the struct for my vertex struct TVERTEX { D3DXVECTOR3 vPos; float fU, fV; D3DXVECTOR3 vNormal; DWORD dwColor; TVERTEX( void ) { vPos.x = vPos.y = vPos.z = 0.0f; fU = fV = 0.0f; vNormal.x = vNormal.y = vNormal.z = 0.0f; dwColor = D3DCOLOR_ARGB(255, 255, 255, 255); } }; i set the default vertex color to white D3DVERTEXELEMENT9 decl[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, {0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, {0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END() }; i create and set the vertex element pDevice->CreateVertexDeclaration(decl, &m_ptVertexDecl); pDevice->SetVertexDeclaration( m_ptVertexDecl ); and i draw the object in wire frame and its not all white, half is a blue/teal color and the other half is black.

Share this post


Link to post
Share on other sites
Gage64    1235
Quote:
{0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},


This should be:

{0, 32, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},

Share this post


Link to post
Share on other sites
bfarah    100
Quote:
Original post by Hodgman
What kind of material set-up are you using?


I am using a diffuse material

D3DMATERIAL9 m_tMaterial;

m_tMaterial.Diffuse.r = 1.0f;
m_tMaterial.Diffuse.g = 1.0f;
m_tMaterial.Diffuse.b = 1.0f;

Quote:
{0, 32, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},


i changed it to 32 and now its all black instead of white.

Share this post


Link to post
Share on other sites
Gage64    1235
If you're using lighting, it won't work because the vertex normal is set to zero.

If you don't want to use lighting (i.e., you just want to use vertex colors), you need to disable it:

device->SetRenderState(D3DRS_LIGHTING, false);

Share this post


Link to post
Share on other sites
bfarah    100
Quote:
Original post by Gage64
If you're using lighting, it won't work because the vertex normal is set to zero.

If you don't want to use lighting (i.e., you just want to use vertex colors), you need to disable it:

device->SetRenderState(D3DRS_LIGHTING, false);


The verts do have normals because i have exported the model from Maya. I have disabled lighting and there is not change.

Share this post


Link to post
Share on other sites
Txkun    151
Since you aren't talking about shaders, this is fixed pipeline, right?

If so, well, your verterx format is a bit odd.

You have normals AND a vertex color.
In a fixed pipeline they can't both be used to calculate the final color.
What you would like to see?

If you want lighting you don't need a vertex color on the vertices but you have to:
enable lighting, setup correctly a light, setup material, draw

if you want to see vertex color you don't need normals so just:
disable lighting, draw

Then you should also check what texture are you binding on the texture stage.
A NULL texture, with default parameters should result in a black mesh.
Try to bind a white texture and check the result.

Share this post


Link to post
Share on other sites
bfarah    100
Txkun,

I put the vertex color in there so i can render the bounding box of the object which has texture and will be lit.

I might be doing the rendering of the bounding box differently. Which way is suitable for debug purposes in game so i can change the color of the bounding box to a different color when it detects a collision.

I have been using OpenGL on my last 3D project and switching to Direct3D. it was easy for me using OpenGL.

Thanks

Share this post


Link to post
Share on other sites
Gage64    1235
Post the drawing code, and any other code you think might be relevant.

But please use source tags (see the FAQ for instructions).

Share this post


Link to post
Share on other sites
bfarah    100
Loading the mesh


CMesh *CMesh::LoadMesh( const char *szFile, IDirect3DDevice9 *pDevice, bool bBinaryFile )
{
if( bBinaryFile )
{
// Open File
ifstream fFile( szFile, std::ios_base::binary );
if( fFile.is_open() )
{
size_t uNameLength = 0;
fFile.read( (char *)&uNameLength, sizeof(size_t) );
char *szBuffer = new char[uNameLength];
fFile.read( (char *)szBuffer, uNameLength );
m_szName = szBuffer;
delete [] szBuffer;

// Read how many verts and indices
fFile.read( (char *)&m_uNumVertices, sizeof(size_t) );
fFile.read( (char *)&m_uNumPolygons, sizeof(size_t) );

size_t uNumTextures = 0;
fFile.read( (char *)&uNumTextures, sizeof(size_t) );

// Read in the number of texture names HERE
for( int i = 0; i < uNumTextures; ++i )
{
size_t uTexNameLength = 0;
fFile.read( (char *)&uTexNameLength, sizeof(size_t) );
char *szTexBuffer = new char[uTexNameLength];
fFile.read( (char *)szTexBuffer, uTexNameLength );
//printf(szTexBuffer, "%s/Resources", szTexBuffer);
char *szFilePath = "../Resources/";
char *szFile = new char[strlen(szFilePath) + strlen(szTexBuffer) + 2];

strcpy(szFile, szFilePath);
strcpy(&szFile[strlen(szFilePath)], szTexBuffer);

D3DXCreateTextureFromFile(pDevice, szFile, &m_pTexture);

delete [] szTexBuffer;
delete [] szFile;


}

m_pVertices = new TVERTEX[ m_uNumVertices ];
// Create a Vert array for the size of the verts
for( size_t i = 0; i < m_uNumVertices; ++i )
{
fFile.read( (char *)&m_pVertices[i].vPos.x, sizeof(float) );
fFile.read( (char *)&m_pVertices[i].vPos.y, sizeof(float) );
fFile.read( (char *)&m_pVertices[i].vPos.z, sizeof(float) );

fFile.read( (char *)&m_pVertices[i].vNormal.x, sizeof(float) );
fFile.read( (char *)&m_pVertices[i].vNormal.y, sizeof(float) );
fFile.read( (char *)&m_pVertices[i].vNormal.z, sizeof(float) );

fFile.read( (char *)&m_pVertices[i].fU, sizeof(float) );
fFile.read( (char *)&m_pVertices[i].fV, sizeof(float) );

}
// Create an array for the size of the indices
m_puPolygons = new short[ m_uNumPolygons * 3 ];

for( size_t i = 0; i < (m_uNumPolygons * 3); i += 3 )
{
size_t temp = 0;

fFile.read( (char *)&temp, sizeof( size_t ) );
m_puPolygons[i] = (short)temp;

fFile.read( (char *)&temp, sizeof( size_t ) );
m_puPolygons[i + 1] = (short)temp;

fFile.read( (char *)&temp, sizeof( size_t ) );
m_puPolygons[i + 2] = (short)temp;
}

fFile.close();
}
else
return NULL;

D3DVERTEXELEMENT9 decl[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{0, 32, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
D3DDECL_END()
};

pDevice->CreateVertexDeclaration(decl, &m_ptVertexDecl);
pDevice->SetVertexDeclaration( m_ptVertexDecl );

void *pVBuffer = NULL;

pDevice->CreateVertexBuffer( m_uNumVertices * sizeof(TVERTEX), 0,
0 , D3DPOOL_MANAGED, &m_pVertexBuff, 0);

m_pVertexBuff->Lock(0, 0, (void**)&pVBuffer, 0);
memcpy(pVBuffer, m_pVertices, m_uNumVertices * sizeof(TVERTEX));
m_pVertexBuff->Unlock();

// Setup the index buffer here
pDevice->CreateIndexBuffer( (m_uNumPolygons * 3) * sizeof(short), 0,
D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pIndexBuff, 0 );

void *pIBuffer = NULL;
m_pIndexBuff->Lock( 0, 0, (void**)&pIBuffer, 0 );
memcpy( pIBuffer, m_puPolygons, (m_uNumPolygons * 3) * sizeof( short ) );
m_pIndexBuff->Unlock();


m_tMaterial.Diffuse.r = 1.0f;
m_tMaterial.Diffuse.g = 1.0f;
m_tMaterial.Diffuse.b = 1.0f;


}

return this;
}



Rendering the objects

void CRenderEngine::Render( vector<CBaseObject *> &tObjects )
{
Begin();

DrawHUD();

// Render all game objects here.
for( size_t i = 0; i < tObjects.size(); ++i )
{
CMesh *pMesh = tObjects[i]->GetMesh();
CBoundingVolume *pBV = tObjects[i]->GetBV();
Vec3f tPos = tObjects[i]->GetPos();

D3DXMATRIX transform; // basic transform
D3DXMatrixIdentity(&transform); // set to identity
transform._41 = tPos.x;
transform._42 = tPos.y;
transform._43 = tPos.z;
m_lpDirect3DDevice->SetTransform(D3DTS_WORLD, &transform); // set world transform

// Draw Bounding Box here
if( pBV )
{
CMesh *pBVMesh = pBV->GetBVMesh();

m_lpDirect3DDevice->SetVertexDeclaration( pBVMesh->GetVertexDecl() );
//m_lpDirect3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
m_lpDirect3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
m_lpDirect3DDevice->SetRenderState(D3DRS_LIGHTING, false);
//m_lpDirect3DDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
m_lpDirect3DDevice->SetStreamSource( 0, pBVMesh->GetVertexBuffer(), 0, sizeof( TVERTEX ) );
m_lpDirect3DDevice->SetIndices( pBVMesh->GetIndexBuffer() );

m_lpDirect3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, pBVMesh->GetNumVerts(), 0, pBVMesh->GetNumPolygons() );

}

m_lpDirect3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
m_lpDirect3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );

if( pMesh )
{
m_lpDirect3DDevice->SetVertexDeclaration( pMesh->GetVertexDecl() );
m_lpDirect3DDevice->SetStreamSource( 0, pMesh->GetVertexBuffer(), 0, sizeof( TVERTEX ) );
m_lpDirect3DDevice->SetIndices( pMesh->GetIndexBuffer() );
m_lpDirect3DDevice->SetMaterial( &pMesh->GetMaterial() );
m_lpDirect3DDevice->SetTexture( 0, pMesh->GetTexture() );

m_lpDirect3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, pMesh->GetNumVerts(), 0, pMesh->GetNumPolygons() );
}
}

m_lpDirect3DDevice->SetTransform( D3DTS_VIEW, &m_mViewMatrix );
m_lpDirect3DDevice->SetTransform( D3DTS_PROJECTION, &m_mProjectionMatrix );

End();
}

Share this post


Link to post
Share on other sites
jbb    471
Don't you have to set D3DRS_COLORVERTEX renderstate to true to use vertex colors rather than material colours? It's been a while since I did this so I might be wrong

Share this post


Link to post
Share on other sites
Txkun    151
bfarah, ah ok... thanks for description.

Well I really think it's texture fault then. I worked a little in OpenGL too and IIRC the default in OpenGL for an unbound texture was white, for Direct3D in black. Usually the default is for textures stages is modulate texture and color inputs to get result color (check SetTextureStageState documentation).

p.s.
now that I see your code, I don't see any SetTexture. Does DrawHUD leave something bound?

Share this post


Link to post
Share on other sites
bfarah    100
Quote:
Don't you have to set D3DRS_COLORVERTEX renderstate to true to use vertex colors rather than material colours? It's been a while since I did this so I might be wrong


I would have no clue, the teacher i had didn't teach us at all. all he did was talk about his new born child and wasted thousands of dollars.

Share this post


Link to post
Share on other sites
bfarah    100
its working now, the problem was the vertexelement offset was at 24 and changed it to 32.
The other problem was that hitting F7 wouldn't compile the .h file of the mesh class so when i changed the color vertex to blue or what ever it didn't compile the change. I did a rebuild and ran the program and it did change the color. it still works if it has or doesn't have a texture attached to the object.

Basically i F'd up. You know when people call up technical support and the tech people say is the computer or printer turned on. its like saying before we go in more detail did you do a rebuild of your solution.

Thanks for all your help guys/girls and sorry for my stupid mistake :)

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