Search code examples
c++directxdirectx-9lighting

DirectX 9 vertex colors ingored when lighting is enabled?


Well, the question says it. When I have light disabled (pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);) I get the colors as expected, when I set it to true, I get pure black, even if I set the ambient light, but that's fixed when also setting a material. But the vertex colors are then ignored completely, and I only get the color of the ambient light.

The search so far: The only useful article I have spotted is this vertex lighting tutorial, but it removes the diffuse color from the vertices, and instead adds a normal vector. Also on MSDN, concerning diffuse lighting, it makes no reference as to the color of the vertex. I am beginning to suspect that the color of the vertex, like the RHW value, is normally calculated in runtime, and setting it during declaration just gives color without the need of lighting. Is that it?

lighting-related code:

pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
pd3dDevice->SetRenderState(D3DRS_COLORVERTEX, TRUE); // not sure if needed
pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(22, 255, 255, 255)); // no visible difference on A
pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); // probably not needed yet, can't harm

D3DMATERIAL9 material;

D3DCOLORVALUE zeroColor;
D3DCOLORVALUE oneColor;

zeroColor.a = 0;
zeroColor.r = 0;
zeroColor.g = 0;
zeroColor.b = 0;

oneColor.a = 0; // no perceivable difference between 0 and 1
oneColor.r = 1;
oneColor.g = 1;
oneColor.b = 1;

material.Ambient = oneColor;
material.Diffuse = zeroColor; //setting it to oneColor has no effect
material.Emissive = zeroColor;
material.Power = 0; //no difference if 0 or 1
material.Specular = zeroColor;
pd3dDevice->SetMaterial(&material);

Solution

  • If you want to use the vertex colors as input to the lighting calculation, you need to set the render state D3DRS_AMBIENTMATERIALSOURCE to D3DMCS_COLOR1 (for the diffuse vertex color). The same applies to the other color components.