Advertisement

Need help with Vertex Normal Vectors

Started by June 28, 2002 12:37 PM
5 comments, last by Aram 22 years, 4 months ago
Hi! I have been trying now for some time to set up some test light just to see how things work. When I load a texture, without lights, and run the exe my picture shows up on the screen. But when the lights are turned on the screen is complete black. What I figured is that my normals must be all wacko and that maybe the at Gamedev could help. So please help me... I know this ain''t looking too good... // Koordinates pVERTEX[0].position = D3DXVECTOR3(DestX1,DestY1,1.0f); pVERTEX[1].position = D3DXVECTOR3(DestX2,DestY1,1.0f); pVERTEX[2].position = D3DXVECTOR3(DestX2,DestY2,1.0f); pVERTEX[3].position = D3DXVECTOR3(DestX1,DestY2,1.0f); // normal calculations float modulus[4]; modulus[0] = (float)sqrt((DestY2-DestY1)*(DestY2-DestY1)+(DestX1-DestX2)*(DestX1-DestX2)+(DestX1*DestY1-DestX2*DestY2)*(DestX1*DestY1-DestX2*DestY2)); modulus[1] = (float)sqrt((DestY2-DestY1)*(DestY2-DestY1)+(DestX1-DestX2)*(DestX1-DestX2)+(DestX1*DestY1-DestX2*DestY2)*(DestX1*DestY1-DestX2*DestY2)); modulus[2] = (float)sqrt((DestY1-DestY2)*(DestY1-DestY2)+(DestX2-DestX1)*(DestX2-DestX1)+(DestX2*DestY2-DestX1*DestY1)*(DestX2*DestY2-DestX1*DestY1)); modulus[3] = (float)sqrt((DestY1-DestY2)*(DestY1-DestY2)+(DestX1-DestX2)*(DestX1-DestX2)+(DestX1*DestY2-DestX2*DestY1)*(DestX1*DestY2-DestX2*DestY1)); pVERTEX[0].normal = D3DXVECTOR3((DestY2-DestY1)/modulus[0], (DestX1-DestX2)/modulus[0], (DestX1*DestY1-DestX2*DestY2)/modulus[0]); pVERTEX[1].normal = D3DXVECTOR3((DestY2-DestY1)/modulus[1], (DestX2-DestX1)/modulus[1], (DestX2*DestY1-DestX1*DestY2)/modulus[1]); pVERTEX[2].normal = D3DXVECTOR3((DestY1-DestY2)/modulus[2], (DestX2-DestX1)/modulus[2], (DestX2*DestY2-DestX1*DestY1)/modulus[2]); pVERTEX[3].normal = D3DXVECTOR3((DestY1-DestY2)/modulus[3], (DestX1-DestX2)/modulus[3], (DestX1*DestY2-DestX2*DestY1)/modulus[3]);
True words are not always beautiful, beautiful words are not always truthful.
How about settings up the normals like this:

pVERTEX[...].normal = D3DXVECTOR3(0.0f, 0.0f, -1.0f);

Shouldn''t that work? Sorry if that''s a dumb idea, but i am unable to figure out what you are trying to achieve, i.e. what is the expected result of your calculations?
Advertisement
Well thats what I figured at first but that didn''t seem to work so I found an article here at gamedev.net. In this article there is a formula for calculating normals.

http://www.gamedev.net/reference/articles/article1832.asp

Maybe I have made some errors else where.


My function for loading pictures:


  void LoadPicture( IDirect3DTexture8 **TEXTURE, PANELVERTEX *pVERTEX, LPCTSTR szImage, DWORD TRANSCOLOR, 							float DestX1, float DestY1, float DestX2, float DestY2,											IDirect3DVertexBuffer8 **VERTEX_BUFFER){	IDirect3DVertexBuffer8 *tmp_VERTEX_BUFFER;		D3dDevice->CreateVertexBuffer(4 * sizeof(PANELVERTEX), D3DUSAGE_WRITEONLY,						D3DFVF_PANELVERTEX, D3DPOOL_MANAGED, &tmp_VERTEX_BUFFER);	tmp_VERTEX_BUFFER->Lock(0, 4 * sizeof(PANELVERTEX), (BYTE**)&pVERTEX, 0);// Sätter rektangelns färg till vitt	pVERTEX[0].color = pVERTEX[1].color = pVERTEX[2].color = pVERTEX[3].color = 0xffffffff;// Koordinaterna	pVERTEX[0].position = D3DXVECTOR3(DestX1,DestY1,1.0f);	pVERTEX[1].position = D3DXVECTOR3(DestX2,DestY1,1.0f);	pVERTEX[2].position = D3DXVECTOR3(DestX2,DestY2,1.0f);	pVERTEX[3].position = D3DXVECTOR3(DestX1,DestY2,1.0f);// normalerna	float modulus[4];		modulus[0] = (float)sqrt((DestY2-DestY1)*(DestY2-DestY1)+(DestX1-DestX2)*(DestX1-DestX2)+(DestX1*DestY1-DestX2*DestY2)*(DestX1*DestY1-DestX2*DestY2));		modulus[1] = (float)sqrt((DestY2-DestY1)*(DestY2-DestY1)+(DestX1-DestX2)*(DestX1-DestX2)+(DestX1*DestY1-DestX2*DestY2)*(DestX1*DestY1-DestX2*DestY2));		modulus[2] = (float)sqrt((DestY1-DestY2)*(DestY1-DestY2)+(DestX2-DestX1)*(DestX2-DestX1)+(DestX2*DestY2-DestX1*DestY1)*(DestX2*DestY2-DestX1*DestY1));		modulus[3] = (float)sqrt((DestY1-DestY2)*(DestY1-DestY2)+(DestX1-DestX2)*(DestX1-DestX2)+(DestX1*DestY2-DestX2*DestY1)*(DestX1*DestY2-DestX2*DestY1));		pVERTEX[0].normal = D3DXVECTOR3((DestY2-DestY1)/modulus[0], (DestX1-DestX2)/modulus[0], (DestX1*DestY1-DestX2*DestY2)/modulus[0]);		pVERTEX[1].normal = D3DXVECTOR3((DestY2-DestY1)/modulus[1], (DestX2-DestX1)/modulus[1], (DestX2*DestY1-DestX1*DestY2)/modulus[1]);		pVERTEX[2].normal = D3DXVECTOR3((DestY1-DestY2)/modulus[2], (DestX2-DestX1)/modulus[2], (DestX2*DestY2-DestX1*DestY1)/modulus[2]);		pVERTEX[3].normal = D3DXVECTOR3((DestY1-DestY2)/modulus[3], (DestX1-DestX2)/modulus[3], (DestX1*DestY2-DestX2*DestY1)/modulus[3]);// textur koordinater	pVERTEX[1].u = pVERTEX[2].u = 1.0f;	pVERTEX[0].u = pVERTEX[3].u = 0.0f;	pVERTEX[0].v = pVERTEX[1].v = 0.0f;	pVERTEX[2].v = pVERTEX[3].v = 1.0f;	tmp_VERTEX_BUFFER->Unlock();		*VERTEX_BUFFER = tmp_VERTEX_BUFFER;	IDirect3DTexture8 * tmp_TEXTURE;		D3DXCreateTextureFromFileEx(D3dDevice, szImage, 0, 0, 0, 0,                            D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT,                            D3DX_DEFAULT , TRANSCOLOR, NULL, NULL, &tmp_TEXTURE);	*TEXTURE = tmp_TEXTURE;}  


Setting up the lights:


  // Sätt materialens reflections egenskaper.	ZeroMemory( &material, sizeof( D3DMATERIAL8 ) );		material.Diffuse = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f );		material.Ambient = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f );		//material.Specular = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f );;		//mat.Power = 50.0f;		//mataterial.Emissive = D3DXCOLOR( 0.0f, 0.0f, 0.0f, 0.0f );	D3dDevice->SetMaterial(&material);// Ljus	ZeroMemory(&d3dlight, sizeof( D3DLIGHT8 ) );		d3dlight.Type = D3DLIGHT_POINT;		d3dlight.Diffuse = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f );		d3dlight.Ambient = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f );		//d3dlight.Specular = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f );		//d3dlight.Direction = D3DXVECTOR3( 0.0f , 0.0f, 1.0f );	D3dDevice->SetLight( 0, &d3dlight );	D3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );  



Drawing the scene:


  void DrawScene(){	D3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0 );	D3dDevice->BeginScene();	Init2dMatrices();	D3dDevice->SetStreamSource(0, vb_BackGround, sizeof(PANELVERTEX));	D3dDevice->SetVertexShader(D3DFVF_PANELVERTEX);	//D3dDevice->LightEnable( 0, TRUE );	D3dDevice->SetTexture(0, t_BackGround);	D3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);	D3dDevice->EndScene();	D3dDevice->Present(NULL, NULL, NULL, NULL);}  
True words are not always beautiful, beautiful words are not always truthful.
I''m also new to the D3D programming so I''m mainly guessing: I think you need to also enable the light after setting it:

D3dDevice->SetLight( 0, &d3dlight );
D3dDevice->LightEnable(0, TRUE);
Haha!! Now this is wierd...It seems as if I don''t need any normals anymore. I can''t alter my light properties either or anything else. I think I''m starting to go crazy, everything I do turns out wrong =(...


Does this seem right to you?:

ZeroMemory( &material, sizeof( D3DMATERIAL8 ) );
material.Diffuse = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f );
material.Ambient = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f );
D3dDevice->SetMaterial(&material);

ZeroMemory(&d3dlight, sizeof( D3DLIGHT8 ) );
d3dlight.Type = D3DLIGHT_DIRECTIONAL ;
d3dlight.Direction = D3DXVECTOR3( 0.5f, 0.0f, -0.5f );
d3dlight.Diffuse = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f );
d3dlight.Ambient = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f );
D3dDevice->SetLight( 0, &d3dlight );
D3dDevice->LightEnable( 0, TRUE );
D3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
True words are not always beautiful, beautiful words are not always truthful.
By default the specular color of your vertex is used for ambient and specular lights, the diffuse vertex color for diffuse lights. If you want to use the color of the material instead call:

D3dDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
D3dDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);

Advertisement
Thanks a lot!! Now the light properties etc. seems to work quite fine but I still can''t understand why my normals dont seem to be needed. I can remove them and the lightning still works.
True words are not always beautiful, beautiful words are not always truthful.

This topic is closed to new replies.

Advertisement