Lighting and normals

Started by
8 comments, last by El Duderino 22 years, 9 months ago
Hello I am having a little trouble getting things lit ... I have set and enabled a light point, that seems to be ok. I''ve set textures and texture stages. I have set lighting as true in the render state. But I get a blank screen. Is this because I have no normals in my processed vertex buffer ? Thanks in advance, El Duderino
Advertisement
In order to get lighting calculations to work vertex normals are required in the FVF. If you don''t have normals for the vertices then no lighting calculations will be done and if there is not other vertex colours etc defined then you will probably see nothing as you describe. There are a few good examples of using lighting and vertex normals in the sdk.

henry
HenryLecturer in Computer Games TechnologyUniversity of Abertay DundeeScotlandUK
what is FVF please?
Thanks Lucien, lighting is still not working properly

The FVF for my unprocessed vertices is :

D3DFVF_CVertex=D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_NORMAL | D3DFVF_DIFFUSE;

and for my processed vertices is this :

D3DFVF_CProcessedVertex=D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE;

El Duderino
Don't put "D3DFVF_NORMAL" and "D3DFVF_DIFFUSE" together.
If you work with lighting, erase "D3DFVF_DIFFUSE" (not for processed vertices, only for unprocessed)...
Maybe it will work...

Edited by - HiddenInBSP on June 27, 2001 2:20:39 PM

Edited by - HiddenInBSP on June 27, 2001 2:22:39 PM
Your FVF order is going to screw you up. Reverse "D3DFVF_TEX1" and "D3DFVF_NORMAL" in the Unprocessed FVF, and remove the "D3DFVF_DIFFUSE". Otherwise, D3D will try to use tu, tv, and nx for your normal, and ny, and nz, as your texture coordinates =).

Z.
______________"Evil is Loud"
post your code. .

post the creation of the vertex buffer, lighting and rendering ..



{ Stating the obvious never helped any situation !! }
Thanks for helping me fellas, I need it bad.

EDIT - As I posted my source I saw a severe problem - the function I had changed to include my normals was kaput !! I defined the x component three times in my cut and paste frenzy and forgot to go back and change two of the x's to y and z ... so the source included here works now !!

HiddeninBSP : I took your advice and ripped the diffuse from the unprocessed buffer, but no benefit ... I went on to rip it out of my processed buffer too, but again, not the result I'd hoped for. The former case resulted in a colourful flickering screen and the latter resulted in my texture seeming to emit light (yes even with no ambient lighting, no diffuse component, my light range at 0.0f and lighting turned on, the texture just glows away).

Zaei : The order of components in the buffer is crucial, but the order of my FVF definition should not be, after all they are all ORed together to give a single value in the end.

Anyway here is the offending code (it's quite a lot, but it's simple stuff, a modified NeXe tute).

My polys are co-planar - the plane is an x/z plane so I set my normals (x, y, z) to 0, 1, 0 ... perhaps I've messed up there.
    // Includes for Windows and DirectX#include <windows.h>#include <d3d8.h>#include <d3dx8.h>#include <stdlib.h>#include <time.h>// Our vertex classclass CVertex{public:	// Its coordinates	float fX, fY, fZ;	float fNX, fNY, fNZ;	DWORD vcolour;	// Its texture coordinates	float fU, fV;	// A function to simplify initialization	void Create(float fp_fX,float fp_fY,float fp_fZ, float fp_fNX, float fp_fNY, float fp_fNZ, DWORD vcol, float fp_fU, float fp_fV)	{		fX=fp_fX;		fY=fp_fY;		fZ=fp_fZ;                fNX=fp_fNX;		fNY=fp_fNY;		fNZ=fp_fNZ;		vcolour=vcol;		fU=fp_fU;		fV=fp_fV;	}};// The CVertex FVFconst DWORD D3DFVF_CVertex=D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1; // Our processed vertex classclass CProcessedVertex{public:	// Processed position	float fX, fY, fZ, fRHW;    DWORD vcolour;	// Texture coordinates	float fU, fV;};// The CProcessedVertex FVFconst DWORD D3DFVF_CProcessedVertex=D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1; // Constants to make changing stuff in initialization easierconst int WINDOW_WIDTH = 800; const int WINDOW_HEIGHT = 600; const int WINDOW_X = 0; const int WINDOW_Y = 0; const char *WINDOW_TITLE="NeXe Tutorial 5";const char *WINDOW_CLASS_NAME="NeXe Tutorial"; // Important Windows variablesHINSTANCE g_hInst;HWND g_hWnd;	// Whether or not it's fullscreenbool g_bFullscreen;// Important Direct3D variablesIDirect3D8 *g_pDirect3D;IDirect3DDevice8 *g_pDevice;IDirect3DTexture8 *g_pTexture;IDirect3DTexture8 *g_pTexture1;D3DLIGHT8		d3dLight;// Results from Direct3D function calls are stored hereHRESULT g_hr;// Instead of an array of vertices, we have a pointer to a vertex bufferIDirect3DVertexBuffer8 *g_pVertexBuffer;// Also, when using vertex buffers, you have two copies of the data, the unprocessed data, and the processed data.IDirect3DVertexBuffer8 *g_pProcessedVertexBuffer;bool Direct3DInit(){	// Create the IDirect3D object	g_pDirect3D=Direct3DCreate8(D3D_SDK_VERSION);	if (g_pDirect3D==NULL)		return 0;		// Set up a structure with either the current display mode for windowed mode or the desired display mode for fullscreen	D3DDISPLAYMODE displayMode;	if (g_bFullscreen==false)	{		g_hr=g_pDirect3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &displayMode);		if (FAILED(g_hr))			return 0;	}	else	{		displayMode.Width=WINDOW_WIDTH;		displayMode.Height=WINDOW_HEIGHT;		displayMode.RefreshRate=0;		displayMode.Format=D3DFMT_A8R8G8B8;	}	// Setup the present parameters	D3DPRESENT_PARAMETERS presentParameters;	memset(&presentParameters, 0, sizeof(D3DPRESENT_PARAMETERS));	if (g_bFullscreen==false)	{		presentParameters.Windowed   = TRUE;	}	else	{		presentParameters.Windowed   = FALSE;	}	presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;	presentParameters.BackBufferFormat = displayMode.Format;	presentParameters.BackBufferWidth = displayMode.Width;	presentParameters.BackBufferHeight = displayMode.Height;	// Create the device	g_hr=g_pDirect3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,                                  D3DCREATE_SOFTWARE_VERTEXPROCESSING,                                  &presentParameters, &g_pDevice ); 	if (FAILED(g_hr))		return false;	// Matrix code	D3DXMATRIX mat;		D3DXMatrixPerspectiveFovLH(&mat, D3DX_PI/6, WINDOW_WIDTH/WINDOW_HEIGHT, 1.0, 180.0);	g_pDevice->SetTransform(D3DTS_PROJECTION, &(D3DMATRIX)mat);	D3DXMatrixIdentity(&mat);	g_pDevice->SetTransform(D3DTS_WORLD, &(D3DMATRIX)mat);	// Setup the vertex buffer	g_pDevice->CreateVertexBuffer(sizeof(CVertex)*1600, NULL, D3DFVF_CVertex, D3DPOOL_MANAGED, &g_pVertexBuffer);		CVertex *vtxQuad;	g_pVertexBuffer->Lock(0, 0, (BYTE **)&vtxQuad, NULL);	float Mapx=-10.0f, Mapy=-10.0f;	int   Counter=0;	for (Mapy=-10; Mapy < 10; Mapy++)	{		for (Mapx=-10; Mapx < 10; Mapx++)		{			vtxQuad[Counter].Create(Mapx    , 1, Mapy    , 0, 1, 0, 0xffffffff, 0, 1);			Counter++;			vtxQuad[Counter].Create(Mapx    , 1, Mapy + 1, 0, 1, 0, 0xffffffff, 0, 0);			Counter++;			vtxQuad[Counter].Create(Mapx + 1, 1, Mapy    , 0, 1, 0, 0xffffffff, 1, 1);			Counter++;			vtxQuad[Counter].Create(Mapx + 1, 1, Mapy + 1, 0, 1, 0, 0xffffffff, 0, 1);			Counter++;		}	}		g_pVertexBuffer->Unlock();	// Create the processed vertex buffer	g_hr = g_pDevice->CreateVertexBuffer(sizeof(CProcessedVertex)*1600, NULL, D3DFVF_CProcessedVertex, D3DPOOL_MANAGED, &g_pProcessedVertexBuffer);	if (FAILED(g_hr))	{		MessageBox(g_hWnd, "Create processed buffer no good", "Error Box", MB_OK);	    return false;	}	ZeroMemory(&d3dLight, sizeof(D3DLIGHT8));	d3dLight.Type = D3DLIGHT_POINT;	d3dLight.Diffuse.r  = 1.0f;	d3dLight.Diffuse.g  = 1.0f;	d3dLight.Diffuse.b  = 1.0f;	d3dLight.Position.x = 0.0f;	d3dLight.Position.y = 100.0f;	d3dLight.Position.z = 0.0f;// Don't attenuate.	d3dLight.Attenuation0 = 1.0f; 	d3dLight.Range      = 1000.0f;// Set the property information for the light.g_hr = g_pDevice->SetLight(0, &d3dLight);if (FAILED(g_hr)){	MessageBox(g_hWnd, "SetLight no good", "Error Box", MB_OK);    return false;}g_hr = g_pDevice->LightEnable(0, TRUE);if (FAILED(g_hr)){	MessageBox(g_hWnd, "LightEnable no good", "Error Box", MB_OK);    return false; }	g_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );		g_pDevice->SetRenderState( D3DRS_LIGHTING, TRUE); 	g_pDevice->SetRenderState( D3DRS_AMBIENT, 0x000f0f0f);	g_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);	g_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);	g_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);	// Turn off the alpha channel since the texture doesn't have one	g_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);	// Create the texture	D3DXCreateTextureFromFile(g_pDevice, "TileLas.bmp", &g_pTexture);	D3DXCreateTextureFromFile(g_pDevice, "TileLbs.bmp", &g_pTexture1);	srand((unsigned)time(NULL));	return true;}void UpdateScene(){	// We have a static integer for how many degrees to generate the rotation matrix for	static float i=0;	static int   si=0;	static int   toggle=0;	// Setup a matrix 	D3DXMATRIX mat;	D3DXMatrixTranslation(&mat, 0, 0, i + 20.0f);	g_pDevice->SetTransform(D3DTS_VIEW, &(D3DMATRIX)mat);	int x = 90, y = 15, z = 270;	D3DXMatrixRotationYawPitchRoll(&mat, D3DXToRadian(x), D3DXToRadian(y), D3DXToRadian(z));		g_pDevice->MultiplyTransform(D3DTS_VIEW, &(D3DMATRIX)mat);			// Change the zoom/pan.	if (toggle==0)	{		i++;		if (i==150)			toggle^=1;	}	else	{		i--;		if (i==0)			toggle^=1;	}}void DrawScene(){	// Clear the screen	g_pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(10, 10, 10), 1.0f, 0 );	// Make it so we can draw stuff	g_pDevice->BeginScene();	int  PCount=0;	byte PToggle=0;	for (PCount=0; PCount < 400; PCount++)	{		// Tell it the source vertex buffer is g_pVertexBuffer		g_pDevice->SetStreamSource(0, g_pVertexBuffer, sizeof(CVertex));		// Tell it to process the source vertex buffer using the CVertex FVF		g_pDevice->SetVertexShader(D3DFVF_CVertex);			// Tell it to process the vertices		g_pDevice->ProcessVertices(PCount * 4, 0, 4, g_pProcessedVertexBuffer, NULL);		// Tell it to use our texture		if (PToggle == 0)		{			g_pDevice->SetTexture(0, g_pTexture);		}		else		{			g_pDevice->SetTexture(0, g_pTexture1);		}		PToggle^=1;		// Set the source vertex buffer to our processed vertices		g_pDevice->SetStreamSource(0, g_pProcessedVertexBuffer, sizeof(CProcessedVertex));		// Tell it to process the source vertex buffer using the CProcessedVertex FVF		g_pDevice->SetVertexShader(D3DFVF_CProcessedVertex);		// Draw the source vertex buffer		g_pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);	}	// Make it so we can't draw stuff	g_pDevice->EndScene();	// Put the back buffer onto the screen	g_pDevice->Present(NULL, NULL, NULL, NULL);}    


El Duderino


Edited by - El Duderino on June 28, 2001 8:58:55 AM
The point lights need the position, that is what is missing in your structure. Include position.

Sorry about that, try using the keyboard. if you press L lights go off or on.

lighting_on=!lighting_on;
lpD3DDevice->SetRenderState(D3DRS_LIGHTING,lighting_on);

Make bool lighting.

Change the value of position y, make a static value and see if you can see the light.

This topic is closed to new replies.

Advertisement