Archived

This topic is now archived and is closed to further replies.

rileyriley

lighting-transformation glitch

Recommended Posts

I''m trying to create a game in which the player controls a sphere that can turn in any direction. That much seems to be working alright. Pressing keys on the num pad will move the main sphere, and the ''camera'' will track behind the main sphere, so in effect, everything else is rotating around the player. Again, that seemed to be working just fine. However, I just added a directional light to the scene, and (I think) it is not behaving correctly. It appears as though the light is being applied to the vertices of the other objects in the scene *before* they are rotated around the player''s sphere (a la the view matrix). The effect is that the spheres look like they are spinning in the direction opposite of what they should be spinning in, *or* that the direction of the light is moving in a circle opposite to the direction that the player spins. To make that more clear, I''ve uploaded the game in it''s present state: http://www.lacking.net/spf100/client.exe (460KB). Again, the numpad turns - w and s accelerate, if you''re interested, and F9 toggles the lighting. Anyway, I''m practically tearing my hair out at this error. Here''s the general structure of my drawing code: Here''s the view matrix setup:
  			camera.rotation = player->getRotation();
			D3DXQuaternionInverse(&camera.rotation, &camera.rotation);
			
			camera.position = player->getPosition();
			
			D3DXMatrixTranslation(&tempMat1, 0.0, 0.0, -10.0);
			D3DXMatrixRotationQuaternion(&tempMat2, &camera.rotation);
			
			D3DXMatrixMultiply(&camera.viewMat, &tempMat2, &tempMat1);
			
			D3DXMatrixTranslation(&tempMat1, -(FLOAT)camera.position.x, -(FLOAT)camera.position.y, -(FLOAT)camera.position.z);
			
			D3DXMatrixMultiply(&camera.viewMat, &tempMat1, &camera.viewMat);
			
			dxWrap.d3dDevice->SetTransform(D3DTS_VIEW, &camera.viewMat);  
The light setup:
  
	light.Direction.x = 1;
	light.Direction.y = 0;
	light.Direction.z = 0;
	
	dxWrap.d3dDevice->LightEnable(0, TRUE);
	dxWrap.d3dDevice->SetRenderState(D3DRS_LIGHTING, useLightingFlag);
	dxWrap.d3dDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_RGBA(190, 190, 190, 255));
	dxWrap.d3dDevice->SetRenderState(D3DRENDERSTATE_NORMALIZENORMALS, TRUE);  
And the code that draws the players:
  	for (int i = MAX_PLAYERS_IN_GAME-1; i >= 0; i--)
	{
		if (game->players[i])
		{
			worldMatStack->Push();
			worldMatStack->LoadIdentity();
			

			D3DXMATRIX temp;
			ZeroMemory(&temp, sizeof(D3DXMATRIX));
		

			D3DXMatrixTranslation(&temp, (FLOAT)game->players[i]->getPosition().x, 
                             (FLOAT)game->players[i]->getPosition().y, 
                             (FLOAT)game->players[i]->getPosition().z);

			worldMatStack->MultMatrixLocal(&temp);

			D3DXMatrixRotationQuaternion(&temp, &game->players[i]->getRotation());

			worldMatStack->MultMatrixLocal(&temp);
			dxWrap.d3dDevice->SetTransform(D3DTS_WORLD, worldMatStack->GetTop());
			
			if (!game->players[i]->vertexBuffers.empty())
			{
				dxWrap.d3dDevice->SetStreamSource( 0, game->players[i]->vertexBuffers[0], sizeof(Vertex) );
				dxWrap.d3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 4 );
			}

			if (!game->players[i]->meshes.empty())
			{
				for (int n = 0; n < game->players[i]->meshes.size(); n++)
				{
					dxWrap.d3dDevice->SetMaterial(&game->players[i]->meshes[n].materials[0]);
					game->players[i]->meshes[n].theMesh->DrawSubset(0);
				}
			}
			
			worldMatStack->Pop();
		}
	}  
Has anyone had this type of problem before? Sorry for the long post.. but I don''t know what might be important. Thanks a ton for any help - I''ve been struggling with this for about a week. At first I thought the spheres were actually rotating the wrong direction. ;( -riley PS- the sphere''s are so polygony on purpose - it''s a lot easier to see the lighting error that way. Also, the red stripes in the scene are just there for reference. The light *should* be coming from their direction.. but it doesn''t seem to. Thanks again for any feedback.

Share this post


Link to post
Share on other sites
Hey I had a look at it. I'm not really sure, but one suggestion I have is that perhaps your triangle wind-order is backwards.

This would cause you to see the "inside" of the sphere, and would give you these kinds of results. try turning off (or reversing) backface culling and see what happens.


EDIT: of course the real solution if this is the problem is to flip the wind order of your triangles :-)

Edited by - Nightshade on February 20, 2002 9:08:37 PM

Share this post


Link to post
Share on other sites
Hmm, it sounds like you''re on the right track.

However, I made those spheres with D3DXCreateSphere, which returns a mesh.. is there a way to reverse the winding?

I''ll try turning off backface culling and see what happens - thanks for your help.

-riley

--------------------------
www.topcoder.com ~ if you register, please use "the_lark" as your referrer

Share this post


Link to post
Share on other sites
Hmmm. D3DXCreateSphere always makes left handed spheres, and I didn''t see a way to really change it easily.

I think this problem usually comes up when there''s some kind of mismatch between the projection matrix, the cull mode, and the model itself. You''ll know more when you turn off culling. I might also temporarily set the fill mode to wireframe, it sometimes makes it easier to tell what''s going on.

good luck!

Share this post


Link to post
Share on other sites
Looks like you were right on the money - I switched to a left handed projection matrix, and now it works perfectly. All of my controls are screwed up of course.... that shouldn''t be too hard to fix though Thanks a lot.

Share this post


Link to post
Share on other sites