Skip to main content
GameDev.net gamedev.net
🔒 Locked

Lighting Problem

Started by Duekiller Dec 8, 2005 at 9:43 AM 18 replies 1.2k views
Original Post
Duekiller
Duekiller
Hi I have created a geometry with lighting set up properly and the whole shabang. I then run the geometry into a display list and then rotate (no need to recalculate every time). The problem that I am running at is that the lighting seems to work, but as soon as I hit the back of my geometry (The none visible side) the light stops working on that part ????? any help ? see image bellow (notice how the back side of the triangle is not lighting correctly). http://www.geocities.com/duekiller/lighting.JPG
ViLiO
ViLiO
Hi,

If you are rotating a mesh then surely you will need to re-calculate the normals as you rotate (mutliply the normal vector by your rotation matrix).

To show an image you can upload an image to imageshack and it will give you the html code you can then paste into the message box when replying.

Regards,
ViLiO
Richard 'ViLiO' Thomasv.net | Twitter | YouTube
Duekiller
Duekiller
Quote:
Original post by ViLiO
Hi,

If you are rotating a mesh then surely you will need to re-calculate the normals as you rotate (mutliply the normal vector by your rotation matrix).

To show an image you can upload an image to imageshack and it will give you the html code you can then paste into the message box when replying.

Regards,
ViLiO


Yeaha, but the lighting seems to be working fine for front face, but not for the back faces. All this multiplication is done when I rotate.
ViLiO
ViLiO
From the image I would say your face normals aren't correct.
Could you maybe give some more information or post some code?

Regards,
ViLiO
Richard 'ViLiO' Thomasv.net | Twitter | YouTube
Duekiller
Duekiller
Well I have the following structure when I draw regularly:

Setup opengl
start display list
draw the geometry
end display list


When I draw from the list I have the following code strucutre:

Setup opengl
draw display list

I see no reason to change to the normal because all the rotation/transformation is being done in the setup opengl function
levjs
levjs
Perhaps your vertices on the back are not in the proper order? Try setting lighting to be computed for both front and back faces by putting
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
in your init code and see if it works right.
Levi
Duekiller
Duekiller
Quote:
Original post by levjs
Perhaps your vertices on the back are not in the proper order? Try setting lighting to be computed for both front and back faces by putting
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
in your init code and see if it works right.
Levi


Nope did not seem to fix the problem.... I think that its an ambient lighting problem.
Nit
Nit
Just to test, set the light position after you perform your rotations. I think ViLio might have been on to something, the light position needs to be rotated by the rotation matrix.
Duekiller
Duekiller
Quote:
Original post by Nit
Just to test, set the light position after you perform your rotations. I think ViLio might have been on to something, the light position needs to be rotated by the rotation matrix.



Right now the light is moved to the correct position and then the model is rotated.
Duekiller
Duekiller
Here is the setup code


// Store current OpenGL machine state:
{
// Viewport:
glGetIntegerv(GL_VIEWPORT, m_dOldViewport);

// Matrices:
glGetIntegerv(GL_MATRIX_MODE, &m_dOldMatrixMode);
glGetDoublev(GL_MODELVIEW_MATRIX, m_dblOldModelViewMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, m_dblOldModelionMatrix);

// Light:
glGetFloatv(GL_LIGHT_MODEL_AMBIENT, m_fltOldLightModelAmbient);
glGetLightfv(GL_LIGHT0, GL_AMBIENT, m_fltOldLight0Ambient);
glGetLightfv(GL_LIGHT0, GL_DIFFUSE, m_fltOldLight0Diffuse);
glGetLightfv(GL_LIGHT0, GL_SPECULAR, m_fltOldLight0Specular);
glGetLightfv(GL_LIGHT0, GL_POSITION, m_fltOldLight0Pos);
}

{
glViewport(lpOpenGL->vx, lpOpenGL->vy, lpOpenGL->vw, lpOpenGL->vh);
glScissor(lpOpenGL->vx, lpOpenGL->vy, lpOpenGL->vw, lpOpenGL->vh);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();
if(mode == GL_SELECT)
{
GLint viewport[4] = {lpOpenGL->vx, lpOpenGL->vy, lpOpenGL->vw, lpOpenGL->vh};
LPPOINT pMouse = reinterpret_cast<LPPOINT>(pModeParam);
if(pMouse)
gluPickMatrix((double)pMouse->x, (double)pMouse->y, 5.0, 5.0, viewport);
else _ASSERT(FALSE);
}

float zDepth = 0.f;
double aspect = double(lpOpenGL->vw)/double(lpOpenGL->vh);
if(perspective)
{
zDepth = lpOpenGL->dz/tan((PERSPECTIVE_ASPECT_ON*float(PI))/360.f);
gluPerspective(PERSPECTIVE_ASPECT_ON, aspect, 0.01f*zDepth, 100.f*zDepth);
}
else
{
zDepth = lpOpenGL->dz/tan((PERSPECTIVE_ASPECT_OFF*float(PI))/360.f);
gluPerspective(PERSPECTIVE_ASPECT_OFF, aspect, 0.01*zDepth, 100.0*zDepth);
}

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Setup light model for the 3D-scene:
{
// Ambient light:
{
// Bright white light - full intensity RGB values:
const GLfloat fltAmbientLight[] = { 0.0f, 0.0f, 0.0f, 1.0f };
// Set light model to use ambient light specified by fltAmbientLight[]:
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fltAmbientLight);
}

// GL_LIGHT0 source:
{
// Light values and coordinates
const GLfloat
fltAmbientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f },
fltDiffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f },
fltSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f },
fltLightPos[] = { 0.0f, 0.0f, 0.0f, 1.0f };

// Setup and enable light 0
glLightfv(GL_LIGHT0, GL_AMBIENT, fltAmbientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, fltDiffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, fltSpecular);
glLightfv(GL_LIGHT0, GL_POSITION, fltLightPos);
}
}

// Move observer away from screen:
glTranslatef(lpOpenGL->px, lpOpenGL->py, -zDepth);
// Z Up -> Rotate x, rotate y, rotate z;
glRotatef(lpOpenGL->rx, 1.0f, 0.0f, 0.0f);
glRotatef(lpOpenGL->ry, 0.0f, 1.0f, 0.0f);
glRotatef(lpOpenGL->rz, 0.0f, 0.0f, 1.0f);
// Move observer to a specified location:
glTranslatef(lpOpenGL->ox, lpOpenGL->oy, lpOpenGL->oz);
[\code]
Nit
Nit
Copy and paste this:
glLightfv(GL_LIGHT0, GL_POSITION, fltLightPos);

and put it right after you perform your rotations and translations.
Duekiller
Duekiller
Quote:
Original post by Nit
Copy and paste this:
glLightfv(GL_LIGHT0, GL_POSITION, fltLightPos);

and put it right after you perform your rotations and translations.


Explain, please????
Duekiller
Duekiller
Quote:
Original post by Nit
Copy and paste this:
glLightfv(GL_LIGHT0, GL_POSITION, fltLightPos);

and put it right after you perform your rotations and translations.


ROTFL, now the wrong side is lit. The backside has proper lighting now, but the front side is dark. (reveresed)

Nit
Nit
I notice that your light position is at 0.0f, 0.0f, 0.0f. Try setting it to 15.0f, 0.0f, 0.0f. Perhaps the light source is inside your sphere.
Duekiller
Duekiller
Quote:
Original post by Nit
I notice that your light position is at 0.0f, 0.0f, 0.0f. Try setting it to 15.0f, 0.0f, 0.0f. Perhaps the light source is inside your sphere.


Even when I create a dozen speheres I get the same result on all the speheres. There front side has normal lighting and the back side does not light corectly, only until I redraw without the display list.

During regular draw we compute the normals, but the normals should not matter for spheres because they always face outwards... because the lighting works fine for the front faces, but not the back faces.

Nit
Nit
Ahhhhh. Let me guess what you are doing. When you use display lists, you make only 1 call to glNormal3f(...), before you do a glCallLists(), right? If that is the case, then that completely explains why you are getting erroneous lighting. You are assigning all faces the same normal, which is wrong.
Duekiller
Duekiller
Quote:
Original post by Nit
Ahhhhh. Let me guess what you are doing. When you use display lists, you make only 1 call to glNormal3f(...), before you do a glCallLists(), right? If that is the case, then that completely explains why you are getting erroneous lighting. You are assigning all faces the same normal, which is wrong.


Well when I make the glnewlist() I assign the normals in that code.

Nit
Nit
Do you calculate the normals for each face (using cross product) or do you assign the same normal to each face?
Kalidor
Kalidor
Quote:
Original post by Duekiller
Even when I create a dozen speheres I get the same result on all the speheres. There front side has normal lighting and the back side does not light corectly, only until I redraw without the display list.

During regular draw we compute the normals, but the normals should not matter for spheres because they always face outwards... because the lighting works fine for the front faces, but not the back faces.
If the lighting is wrong when rendering with display lists but it is correct when rendering without display lists, then there is obviously something different between the two rendering methods. It would help us to help you if you posted that code.
Duekiller
Duekiller
Solved this finally.

There was code in the normal vector to always have the vector point towards the user. The problem was that the vector was not correctly.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.