Jump to content
  • Advertisement
Sign in to follow this  
Mantear

Lighting problem

This topic is 4761 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've re-worked the rendering section of my program and somehow broke the lighting. I've compared my different versions of the code and can't figure out what's different. What happens is all objects are lit as if they were positioned at the origin. I can move the light source arround, and the lighting is updated as expected. I can rotate the object around, and the lighting is updated as expected. But when I translate the object, it is drawn in the new, expected position, but lit as if it were still at the origin. Anyone have any ideas? I can post code if needed. Thanks!

Share this post


Link to post
Share on other sites
Advertisement
Light sources are transformed by the modelview matrix. Are you placing the light after a glLoadIdentity call and before the glTranslate call?

Share this post


Link to post
Share on other sites
Here's the order I do things in:
glClearColor()
glClear()
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective()

glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glPushMatrix()
// according to camera view...
glRotate() & glTranslatef()

//apply lighting
glEnable(GL_LIGHTING)
glLightfv(GL_LIGHT0, GL_POSITION, pLight0Position)
glEnable(GL_LIGHT0)

// Draw the objects
glPushMatrix()
// according to object...
glRotate() & glTranslatef()

// Draw VBOs

glPopMatrix()
glPopMatrix()

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho()
// Draw my GUI


Any ideas? Thanks.

Share this post


Link to post
Share on other sites
What trippytarka predicted is actually true in your case. Your lights are transformed by the camera matrix. So they are actually positioned w.r.t. the camera. If the light position you contain in pLight0Position is supposed to be a coordinate in world space, swap your code as follows:

glPushMatrix()
// first apply lighting
glEnable(GL_LIGHTING)
glLightfv(GL_LIGHT0, GL_POSITION, pLight0Position)
glEnable(GL_LIGHT0)

// then transform according to camera view...
glRotate() & glTranslatef()

// rest of code here...





Tom

Share this post


Link to post
Share on other sites
I find this a simple workaround:
Say you are doing a

glTranslatef (x, y, z);
// draw code
// lighting code

Just add before lighting code,
glTranslatef (-x, -y, -z);

That was the way my code was set up and so this is the way I fixed it. Your's may be different, but anyway I hope this helped.

Share this post


Link to post
Share on other sites
dimebolt, I tried what you suggested, but I ended up with the same result. I can move the camera around, I can move the light around, I can move the object around. Everything works as expected, except that the object remains lit as if its position is located at the origin. Rotating the object works fine, moving the light around works fine, moving the camera around, etc... But I move the object -10 on the Z axis, with the point light located at -5, and the object still remains lit on the -Z side.

This is really stumping me.

Share this post


Link to post
Share on other sites
Quote:
Original post by Mantear
dimebolt, I tried what you suggested, but I ended up with the same result. I can move the camera around, I can move the light around, I can move the object around. Everything works as expected, except that the object remains lit as if its position is located at the origin. Rotating the object works fine, moving the light around works fine, moving the camera around, etc... But I move the object -10 on the Z axis, with the point light located at -5, and the object still remains lit on the -Z side.

This is really stumping me.


It's stumping me too :) Could you post the real code? Clearly something fishy is going on...

Tom

Share this post


Link to post
Share on other sites

void RenderEngine::RenderScene(int width, int height)
{
// Set the Background color
glClearColor(BGColor[0], BGColor[1], BGColor[2], BGColor[3]);

// Clear the screen and the depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Select and initialize the Projection Matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( Camera.GetViewAngle(),
(float)width/(float)height,
Camera.GetNearClip(),
Camera.GetFarClip());

// Select and reset the ModelView Maxtrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Set up the scene
glPushMatrix();
{
// Translate and rotate according to the current viewing object
glRotatef(*CurrentViewObject.GetMirrorDataPtr()->pRotationX, -1.0f, 0.0f, 0.0f);
glRotatef(*CurrentViewObject.GetMirrorDataPtr()->pRotationY, 0.0f, -1.0f, 0.0f);
glRotatef(*CurrentViewObject.GetMirrorDataPtr()->pRotationZ, 0.0f, 0.0f, -1.0f);

glTranslatef( -*CurrentViewObject.GetMirrorDataPtr()->pPositionX,
-*CurrentViewObject.GetMirrorDataPtr()->pPositionY,
-*CurrentViewObject.GetMirrorDataPtr()->pPositionZ);

// Draw the scene
DrawScene();
}
glPopMatrix();

// Switch to the Projection Matrix, reset it,
// and load some nice coordinates for doing the GUI
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, 0, height);

// Don't allow lighting to affect the GUI and make sure textures are enabled
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);

// Display the GUI
pGUI->DisplayGUI();
}


void RenderEngine::DrawScene(void)
{
// Apply the lighting for the objects
ApplyLighting();

// Draw each object
for (int i = 0; i < ObjectsCurrentSize; i++)
{
// Only draw if it is not hidden
if (!pObjects.IsHidden())
{
pObjects.DrawObject();
}
}

// Anything drawn past here won't have textures or lighting applied
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);

// Draw things like normals, bounding boxes, camera and light models, etc
}


void RenderEngine::ApplyLighting(void)
{
// Is overall lighting enabled?
if (LightingEnabled)
{
// Yes, so enable lighting
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);

for (int i = 0; i < 8; i++)
{
// Is this light enabled?
if (Lights.IsEnabled())
{
// Apply light properties
glLightfv(GL_LIGHT0 + i, GL_AMBIENT, Lights.GetAmbient());
glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, Lights.GetDiffuse());
glLightfv(GL_LIGHT0 + i, GL_SPECULAR, Lights.GetSpecular());

// Distant, Point, or Spot light
switch(Lights.GetLightType())
{
case DistantLight:
case PointLight:
glLightfv(GL_LIGHT0 + i, GL_POSITION, Lights.GetPosition());
break;

case SpotLight:
glLightfv(GL_LIGHT0 + i, GL_POSITION, Lights.GetPosition());

// TO DO: Get this part working!
glLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, Lights.GetSpotDirection());
glLightf(GL_LIGHT0 + i, GL_SPOT_CUTOFF, Lights.GetSpotCutoff());
glLightf(GL_LIGHT0 + i, GL_SPOT_EXPONENT, Lights.GetSpotExponent());

break;
default:
// Invalid light type
break;
}

// Apply Attenuation
glLightf(GL_LIGHT0 + i, Lights.GetAttenuationType(), Lights.GetAttenuation());

// Enable the light
glEnable(GL_LIGHT0 + i);
}
else
{
// Disable the light
glDisable(GL_LIGHT0 + i);
}
}
}
else
{
// No, disanbel lighting
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
}
}



void Objects::DrawObject(void)
{
glPushMatrix();
{
// Translate
glTranslatef(*MirrorData.pPositionX, *MirrorData.pPositionY, *MirrorData.pPositionZ);

// Then rotate
glRotatef(*MirrorData.pRotationZ, 0.0f, 0.0f, 1.0f);
glRotatef(*MirrorData.pRotationY, 0.0f, 1.0f, 0.0f);
glRotatef(*MirrorData.pRotationX, 1.0f, 0.0f, 0.0f);

// Bind the vertex data
glBindBufferARB(GL_ARRAY_BUFFER, *MirrorData.pVertexName);
glVertexPointer(3, GL_FLOAT, 0, 0);
// Bind the color data
glBindBufferARB(GL_ARRAY_BUFFER, *MirrorData.pColorName);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0);
// Bind the normal data
glBindBufferARB(GL_ARRAY_BUFFER, *MirrorData.pNormalName);
glNormalPointer(GL_FLOAT, 0, 0);
// Bind the texture data
glBindBufferARB(GL_ARRAY_BUFFER, *MirrorData.pTexCoordName);
glTexCoordPointer(2, GL_FLOAT, 0, 0);

// Draw the Points
if (MirrorData.pPoints->IndexCurrentSize > 0)
{
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, MirrorData.pPoints->VBOName);
glDrawRangeElements(GL_POINTS,
0,
MirrorData.pPoints->IndexCurrentSize,
MirrorData.pPoints->IndexCurrentSize,
GL_UNSIGNED_INT,
NULL);
}
// Draw the Lines
if (Lines.IndexCurrentSize > 0)
{
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Lines.VBOName);
glDrawRangeElements(GL_LINES,
0,
MirrorData.pLines->IndexCurrentSize,
MirrorData.pLines->IndexCurrentSize,
GL_UNSIGNED_INT,
NULL);
}
// Draw the Triangles
if (Triangles.IndexCurrentSize > 0)
{
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Triangles.VBOName);
glDrawRangeElements(GL_TRIANGLES,
0,
MirrorData.pTriangles->IndexCurrentSize,
MirrorData.pTriangles->IndexCurrentSize,
GL_UNSIGNED_INT,
NULL);
}
// Draw the Quads
if (Quads.IndexCurrentSize > 0)
{
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Quads.VBOName);
glDrawRangeElements(GL_QUADS,
0,
MirrorData.pQuads->IndexCurrentSize,
MirrorData.pQuads->IndexCurrentSize,
GL_UNSIGNED_INT,
NULL);
}
}
glPopMatrix();
}


Here's my source code, nearly un-altered (removed commented out sections, drawing of camera/light objects, a background grid, etc). MirrorData is a structure of pointers that points to the data within the object, or can be set to point to another object (in this way I'm going to see if I can't 'mirror' an object without having to duplicte all the data). For now, they always 'mirror' themselves, pointing to their own data.

Thanks for your help, this is a very frustrating problem and I'm running out of ideas.

Share this post


Link to post
Share on other sites
It does seem you still apply some transformations before the lighting:

glPushMatrix();
{
// some transformations:
glRotatef(*CurrentViewObject.GetMirrorDataPtr()->pRotationX, -1.0f, 0.0f, 0.0f);
glRotatef(*CurrentViewObject.GetMirrorDataPtr()->pRotationY, 0.0f, -1.0f, 0.0f);
glRotatef(*CurrentViewObject.GetMirrorDataPtr()->pRotationZ, 0.0f, 0.0f, -1.0f);

glTranslatef( -*CurrentViewObject.GetMirrorDataPtr()->pPositionX,
-*CurrentViewObject.GetMirrorDataPtr()->pPositionY,
-*CurrentViewObject.GetMirrorDataPtr()->pPositionZ);

// Draw the scene with lighting first:
DrawScene();
}
glPopMatrix();



Could you try pulling the lighting out of the DrawScene and run like this:


glPushMatrix();
{
// light:
ApplyLighting();

// transformsations:
glRotatef(*CurrentViewObject.GetMirrorDataPtr()->pRotationX, -1.0f, 0.0f, 0.0f);
glRotatef(*CurrentViewObject.GetMirrorDataPtr()->pRotationY, 0.0f, -1.0f, 0.0f);
glRotatef(*CurrentViewObject.GetMirrorDataPtr()->pRotationZ, 0.0f, 0.0f, -1.0f);

glTranslatef( -*CurrentViewObject.GetMirrorDataPtr()->pPositionX,
-*CurrentViewObject.GetMirrorDataPtr()->pPositionY,
-*CurrentViewObject.GetMirrorDataPtr()->pPositionZ);

// Draw the scene without lighting first:
DrawScene();
}
glPopMatrix();




That may solve your problem.

Tom

Share this post


Link to post
Share on other sites
I'm beginning to use my brains now and started looking into my own code.
Forget my post on the camera code, that was nonsense.
This is a simplified, mono-scopic version of what I do in my SG:

void caOpenGLProcessor::Process(caSequence *seq)
{
if (!Setup())
return;
Render(seq);
}

bool caOpenGLProcessor::Setup()
{
if (!SetupViewport())
return false;
if (!ClearFrameBuffer())
return false;
if (!SetupProjectionAndView())
return false;
return true;
}

bool caOpenGLProcessor::SetupProjectionAndView()
{
caCamera *camera = viewport->Camera();
afrustum frust;
amatrix proj, view;

frust = camera->Frustum();
proj.make_perspective(frust);
view = camera->InverseViewMatrix();

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(proj.m);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(view.m);
}

void caOpenGLProcessor::Render(caSequence *seq)
{
// emit lights
EmitLights(seq->lights);

// continue with appearances and shapes
EmitGeometries(seq->geometries);

// continue with transparent appearances and shapes
glDepthMask(GL_FALSE);
EmitGeometries(s->transparents);
glDepthMask(GL_TRUE);

glFlush();
}





As you can see, I do load the viewmatrix before the lighting as you had in your initial code. I messed up, you were right there. The problem is probably what I stated in the previous post. Try to rewrite your code to do:

glMatrixMode(GL_PROJECTION);
LoadProjectionMatrix();
glMatrixMode(GL_MODELVIEW);
LoadViewMatrix();
glPushMatrix();
{
ApplyLighting();
DoMirroringTransforms(); // I'm not sure what they do, bu I assume you need them
DrawScene();
}
glPopMatrix();





Sorry about the confusion...

Tom

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!