Hi
I am using DX9 (June 2008 SDK) in VS 2008 using C++.
I have been trying to implement the lighting from the following project
http://www.dhpoware.com/demos/d3dThirdPersonCamera1.html
but unfortunately I am having quite some difficult time with it. Especially adapting the RenderPlayer() and RenderFloor() functions.
RenderFloor()
void RenderFloor()
{
UINT totalPasses;
D3DXHANDLE hTechnique;
D3DXMATRIX identityMatrix;
D3DXMATRIX viewProjMatrix;
D3DXMatrixIdentity(&identityMatrix);
viewProjMatrix = g_camera.getViewMatrix() * g_camera.getProjectionMatrix();
g_pEffect->SetMatrix("worldMatrix", &identityMatrix);
g_pEffect->SetMatrix("worldInverseTransposeMatrix", &identityMatrix);
g_pEffect->SetMatrix("worldViewProjectionMatrix", &viewProjMatrix);
g_pEffect->SetValue("cameraPos", &g_camera.getPosition(), sizeof(D3DXVECTOR3));
g_pEffect->SetValue("globalAmbient", &g_globalAmbient, sizeof(g_globalAmbient));
g_pEffect->SetValue("light.dir", g_light.dir, sizeof(g_light.dir));
g_pEffect->SetValue("light.pos", g_light.pos, sizeof(g_light.pos));
g_pEffect->SetValue("light.ambient", g_light.ambient, sizeof(g_light.ambient));
g_pEffect->SetValue("light.diffuse", g_light.diffuse, sizeof(g_light.diffuse));
g_pEffect->SetValue("light.specular", g_light.specular, sizeof(g_light.specular));
g_pEffect->SetFloat("light.spotInnerCone", g_light.spotInnerCone);
g_pEffect->SetFloat("light.spotOuterCone", g_light.spotOuterCone);
g_pEffect->SetFloat("light.radius", g_light.radius);
g_pEffect->SetValue("material.ambient", g_material.ambient, sizeof(g_material.ambient));
g_pEffect->SetValue("material.diffuse", g_material.diffuse, sizeof(g_material.diffuse));
g_pEffect->SetValue("material.emissive", g_material.emissive, sizeof(g_material.emissive));
g_pEffect->SetValue("material.specular", g_material.specular, sizeof(g_material.specular));
g_pEffect->SetFloat("material.shininess", g_material.shininess);
g_pEffect->SetTexture("colorMapTexture", g_pFloorTexture);
hTechnique = g_pEffect->GetTechniqueByName("PerPixelSpotLighting");
if (SUCCEEDED(g_pEffect->SetTechnique(hTechnique)))
{
g_pDevice->SetVertexDeclaration(g_pVertexDecl);
g_pDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(Vertex));
if (SUCCEEDED(g_pEffect->Begin(&totalPasses, 0)))
{
for (UINT i = 0; i < totalPasses; ++i)
{
if (SUCCEEDED(g_pEffect->BeginPass(i)))
{
g_pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
g_pEffect->EndPass();
}
}
g_pEffect->End();
}
}
}
RenderPlayer()
void RenderPlayer()
{
UINT totalPasses;
D3DXHANDLE hTechnique;
const D3DXMATRIX &worldMatrix = g_player.getWorldMatrix();
const D3DXMATRIX &viewMatrix = g_camera.getViewMatrix();
const D3DXMATRIX &projMatrix = g_camera.getProjectionMatrix();
D3DXMATRIX worldViewProjMatrix = worldMatrix * viewMatrix * projMatrix;
// Since the world matrix here is a rigid-body transformation (i.e., only
// rotations and translations are used) we can simply use the world matrix
// to transform the mesh's normals instead of computing the normal matrix.
// The normal matrix is the transpose of the inverse of the world matrix.
//
// The reason why we don't have to compute the normal matrix is because:
// (a) Rotations are usually orthogonal. This means that the inverse of an
// orthogonal rotation matrix is the same as taking the transpose of
// the orthogonal rotation matrix.
// (b) Translations don't affect the direction of normals.
g_pEffect->SetMatrix("worldMatrix", &worldMatrix);
g_pEffect->SetMatrix("worldInverseTransposeMatrix", &worldMatrix);
g_pEffect->SetMatrix("worldViewProjectionMatrix", &worldViewProjMatrix);
g_pEffect->SetValue("cameraPos", &g_camera.getPosition(), sizeof(D3DXVECTOR3));
g_pEffect->SetValue("globalAmbient", &g_globalAmbient, sizeof(g_globalAmbient));
// A directional light that's shining directly at the ball as it moves.
g_pEffect->SetValue("light.dir", g_camera.getViewDirection(), sizeof(D3DXVECTOR3));
g_pEffect->SetValue("light.ambient", g_light.ambient, sizeof(g_light.ambient));
g_pEffect->SetValue("light.diffuse", g_light.diffuse, sizeof(g_light.diffuse));
g_pEffect->SetValue("light.specular", g_light.specular, sizeof(g_light.specular));
g_pEffect->SetValue("material.ambient", g_material.ambient, sizeof(g_material.ambient));
g_pEffect->SetValue("material.diffuse", g_material.diffuse, sizeof(g_material.diffuse));
g_pEffect->SetValue("material.emissive", g_material.emissive, sizeof(g_material.emissive));
g_pEffect->SetValue("material.specular", g_material.specular, sizeof(g_material.specular));
g_pEffect->SetFloat("material.shininess", g_material.shininess);
g_pEffect->SetTexture("colorMapTexture", g_pPlayerTexture);
hTechnique = g_pEffect->GetTechniqueByName("PerPixelDirectionalLighting");
if (SUCCEEDED(g_pEffect->SetTechnique(hTechnique)))
{
if (SUCCEEDED(g_pEffect->Begin(&totalPasses, 0)))
{
for (UINT i = 0; i < totalPasses; ++i)
{
if (SUCCEEDED(g_pEffect->BeginPass(i)))
{
g_pPlayerMesh->DrawSubset(0);
g_pEffect->EndPass();
}
}
g_pEffect->End();
}
}
}
In my game, I draw the objects in the world in two separate functions:
DrawWorld(void)
void DrawWorld(void)
{
/* Draw the floor */
g_pDevice->SetTransform(D3DTS_WORLD, &IDENTITY_MTX);
g_pDevice->SetTexture(0, g_pFloorTexture);
g_pDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(Vertex));
g_pDevice->SetVertexDeclaration(g_pVertexDecl);
g_pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
//g_pDevice->SetStreamSource(0, 0, 0, 0);
/* Draw the sky object */
g_pDevice->SetTransform(D3DTS_WORLD, &g_skysphere.getWorldMatrix());
g_pDevice->SetTexture(0, g_pSkyTexture);
g_pSkyMesh->DrawSubset(0);
g_pDevice->SetTexture(0, 0);
/* Draw the building object */
g_pDevice->SetTransform(D3DTS_WORLD, &g_building.getWorldMatrix());
g_pDevice->SetTexture(0, g_pBuildingTexture);
g_pBuildingMesh->DrawSubset(0);
g_pDevice->SetTexture(0, 0);
/* Draw the building object */
g_pDevice->SetTransform(D3DTS_WORLD, &g_building2.getWorldMatrix());
g_pDevice->SetTexture(0, g_pBuildingTexture2);
g_pBuildingMesh2->DrawSubset(0);
g_pDevice->SetTexture(0, 0);
/* Draw the lamp object */
g_pDevice->SetTransform(D3DTS_WORLD, &g_lamp.getWorldMatrix());
g_pDevice->SetTexture(0, g_pLampTexture);
g_pLampMesh->DrawSubset(0);
g_pDevice->SetTexture(0, 0);
}
and DrawPlayer(void)
void DrawPlayer(void)
{
g_pDevice->SetTransform(D3DTS_PROJECTION, &g_camera.projMatrix);
g_pDevice->SetTransform(D3DTS_VIEW, &g_camera.viewMatrix);
g_pDevice->SetTransform(D3DTS_WORLD, &g_player.getWorldMatrix());
g_pDevice->SetTexture(0, g_pPlayerTexture);
g_pPlayerMesh->DrawSubset(0);
}
I also got an EnemyDraw(void) function almost similar to the above once. How do I implement so there is lighting only on the center of the floor and on the player?
Any help is highly appreciated.
Thanks in advance.
Best regards.