Troubles Learning Direct3D 9 Lighting (C++)

Started by
2 comments, last by dist0rted 16 years, 9 months ago
For some reason, when I try to use lighting, my triangle doesn't show up on the screen, just a blank screen really. What I thought it might be is that I'm normalizing the vertices wrong. I'm simply using D3DXVec3Normalize() to do this for me, as shown:

	D3DXVec3Normalize((D3DXVECTOR3*)&Triangle[0].normal, &Triangle[0].pos);
	D3DXVec3Normalize((D3DXVECTOR3*)&Triangle[1].normal, &Triangle[1].pos);
	D3DXVec3Normalize((D3DXVECTOR3*)&Triangle[2].normal, &Triangle[2].pos);
(I use those functions later in the program, after I've already defined the vertices...) Note that my vertices are defined as follows:

struct DGVERTEXNORM
{
	D3DXVECTOR3 pos; // xyz coords
	D3DXVECTOR3 normal; // normal for lighting
	DWORD dwColor; // color
};

DGVERTEXNORM Triangle[] =
{
	{ D3DXVECTOR3(-1.0f, -1.0f, 5.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DCOLOR_XRGB(255, 0, 0) },
	{ D3DXVECTOR3(-1.0f, 1.0f, 5.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DCOLOR_XRGB(0, 255, 0) },
	{ D3DXVECTOR3(1.0f, -1.0f, 5.0f), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DCOLOR_XRGB(0, 0, 255) }
};




Here's the code I use to set the light and the material (before the main loop starts):

	D3DLIGHT9 light;
	ZeroMemory(&light, sizeof(light));
	light.Type = D3DLIGHT_POINT;
	light.Position = D3DXVECTOR3(0.0f, 0.0f, 3.0f);
	light.Diffuse.r = light.Ambient.r = 1.0f;
	light.Diffuse.g = light.Ambient.g = 1.0f;
	light.Diffuse.b = light.Ambient.b = 1.0f;
	light.Range = 1000.0f;
	graphics.EnableLighting();
	graphics.GetDevice()->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(100, 100, 100));
	graphics.GetDevice()->SetLight(0, &light);
	graphics.GetDevice()->LightEnable(0, TRUE);
	D3DMATERIAL9 material;
	material.Diffuse.r = material.Diffuse.g = material.Diffuse.b = material.Diffuse.a = 1.0f;
	material.Ambient.r = material.Ambient.g = material.Ambient.b = material.Ambient.a = 1.0f;
	graphics.GetDevice()->SetMaterial(&material);




(graphics.EnableLighting() is the same as graphics.GetDevice()->SetRenderState(D3DRS_LIGHTING, TRUE)) Yes, my projection/view matrices are setup right and the triangle is being displayed properly otherwise (I know this because whenever I comment out the lighting code and disable lighting, it shows up fine). [Edited by - dist0rted on July 26, 2007 1:13:24 PM]
=============================All knowledge is good; only the way it is put to use is good or evil.
Advertisement
Did I leave out anything that may be causing the problem? I don't know what I'm doing wrong...
=============================All knowledge is good; only the way it is put to use is good or evil.
Things to do:
  • Clear the backbuffer to a colour other than black (E.g. bright blue). That way you can tell if the triangles are visible at all, or if they're just not being lit (in which case they'll show up as black).
  • Disable culling, to see if your triangle vertices are the wrong way around (pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE))
  • Check your matrices (view, projection and world). I find it's easiest to use the D3DX functions to create a perspective projection matrix, a view matrix with the origin at (0, 0, 0) looking at (0, 0, 1), and leave the world matrix as an identity. Then put all the vertices at z=25 or so.
  • Check your clip planes aren't "silly" values. Try setting them to 1.0f and 1000.0f for near and far clip planes respectively (Remember that vertices 1.0f units from the camera or nearer will now be clipped). Make sure the near clip plane isn't 0 (That causes a division by zero and undefined behaviour).
  • Check you're clearing the Z-buffer as well as the render target each frame (If you're using a Z-buffer)
  • Use DrawPrimitiveUP to check if there's a bug with your vertex buffer code.

    That's all I can think of offhand.

    EDIT: Also, probably unrelated but you should either fill in entire structures, or zero them out first. You're setting a material with "random" values for the specular colour and any other members in it.
    Also, your normals have a length of 0, which is usually bad. Set the Z value for your normals to all z = -1.0f
    RE-EDIT: Oh, I missed the bit about D3DXVec3Normalize(). That will use the direction from the origin to the vertex as the vertex normal, which would be fine for a sphere, but probably not what you want for a triangle. I doubt this is the problem really, since even if your normals were totally screwed, the vertices would still be lit by ambient light.
  • Wow, thanks a million dude. It was because I wasn't clearing out my material structure. I first set the Clear() color to green and saw that it wasn't being lit, and then tried everything else you said.

    But, it works now hehehe, thanks.
    =============================All knowledge is good; only the way it is put to use is good or evil.

    This topic is closed to new replies.

    Advertisement