Archived

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

El Duderino

Lighting and normals

Recommended Posts

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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
post your code. .

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



{ Stating the obvious never helped any situation !! }

Share this post


Link to post
Share on other sites
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 class

class 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 FVF

const DWORD D3DFVF_CVertex=D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1;

// Our processed vertex class

class CProcessedVertex
{
public:
// Processed position

float fX, fY, fZ, fRHW;

DWORD vcolour;

// Texture coordinates

float fU, fV;
};
// The CProcessedVertex FVF

const DWORD D3DFVF_CProcessedVertex=D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;

// Constants to make changing stuff in initialization easier

const 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 variables

HINSTANCE g_hInst;
HWND g_hWnd;

// Whether or not it's fullscreen

bool g_bFullscreen;

// Important Direct3D variables

IDirect3D8 *g_pDirect3D;
IDirect3DDevice8 *g_pDevice;
IDirect3DTexture8 *g_pTexture;
IDirect3DTexture8 *g_pTexture1;

D3DLIGHT8 d3dLight;

// Results from Direct3D function calls are stored here

HRESULT g_hr;

// Instead of an array of vertices, we have a pointer to a vertex buffer

IDirect3DVertexBuffer8 *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

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
The point lights need the position, that is what is missing in your structure. Include position.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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.

Share this post


Link to post
Share on other sites