PDA

View Full Version : Positional light rotates with camera



Rainbow Dash
12-04-2016, 12:56 AM
So I've been trying to get a positional light to work in my code for some time now, and I can't seem to get it to work the way I expect. I set the light next to my 'shed', and it will seemingly rotate with the camera. Any ideas?

Here is my code for moving the camera:


void mousemove_func(int x, int y)
{
if (x != glutGet(GLUT_WINDOW_WIDTH) / 2 || y != glutGet(GLUT_WINDOW_HEIGHT) / 2)
{
GLfloat diffx = x - (glutGet(GLUT_WINDOW_WIDTH) / 2);
GLfloat diffy = y - (glutGet(GLUT_WINDOW_HEIGHT) / 2);

if ((camXAngle + diffy) < 70 && (camXAngle + diffy) > -70)
{
camXAngle += (diffy / 5);
camYAngle += (diffx / 5);

if (camYAngle > 360)
{
camYAngle -= 360;
}

else if (camYAngle < 0)
{
camYAngle += 360;
}

glutPostRedisplay();
}

glutWarpPointer(glutGet(GLUT_WINDOW_WIDTH) / 2,
glutGet(GLUT_WINDOW_HEIGHT) / 2);
}
}


Code for the light itself:


void display()
{

...
// positional light
glPushMatrix();

glRotatef(camXAngle, 1, 0, 0);
glRotatef(camYAngle, 0, 1, 0);
glTranslatef(camXPos + 789, camYPos + 150, camZPos + 449); // sets the light at coordinate (789, 150, 449)

shedLight.setSource(GL_LIGHT1);
shedLight.setDiffuse(2, 2, 2);
shedLight.setPosition(0, 0, 0, 1);
shedLight.setDirection(0, -1, 0);
shedLight.enableLight();

glPopMatrix();
...
}


and here is the code for the light...


class light
{
public:

light();
~light();

void setPosition(GLint x, GLint y, GLint z, GLint w = 1);
void setDirection(GLint x, GLint y, GLint z, GLint = 1);
void setDiffuse(GLint r, GLint g, GLint b, GLint w = 1);
void setSource(GLint lightSource);
void setCutoff(GLint angle);

void adjustLight();
void enableLight();
void disableLight();

private:

GLfloat diffuseLight[4];
GLfloat position[4];
GLfloat direction[4];
GLint source;
};

light::light() :
source(GL_LIGHT0)
{
for (int i = 0; i < 4; ++i)
{
diffuseLight[i] = 0;
position[i] = 0;
direction[i] = 0;
}
glLightfv(source, GL_SPOT_DIRECTION, direction);
glLightfv(source, GL_DIFFUSE, diffuseLight);
glLightfv(source, GL_POSITION, position);
}

light::~light()
{
}

void light::setCutoff(GLint angle)
{
glLightf(source, GL_SPOT_CUTOFF, angle);
}

void light::setDiffuse(GLint r, GLint g, GLint b, GLint w)
{
diffuseLight[0] = r;
diffuseLight[1] = g;
diffuseLight[2] = b;
diffuseLight[3] = w;
glLightfv(source, GL_DIFFUSE, diffuseLight);
}

void light::setPosition(GLint x, GLint y, GLint z, GLint w)
{
position[0] = x;
position[1] = y;
position[2] = z;
position[3] = w;
glLightfv(source, GL_POSITION, position);
}

void light::setDirection(GLint x, GLint y, GLint z, GLint w)
{
direction[0] = x;
direction[1] = y;
direction[2] = z;
direction[3] = w;
glLightfv(source, GL_SPOT_DIRECTION, direction);
}

void light::adjustLight()
{
glLightfv(GL_LIGHT0, GL_POSITION, position);
}

void light::setSource(GLint lightSource)
{
source = lightSource;
}

void light::enableLight()
{
glEnable(source);
}

void light::disableLight()
{
glDisable(source);
}

Dark Photon
12-04-2016, 08:44 AM
So I've been trying to get a positional light to work in my code for some time now, and I can't seem to get it to work the way I expect. I set the light next to my 'shed', and it will seemingly rotate with the camera. Any ideas?

See the references to "modelview" on the glLight*() (https://www.opengl.org/sdk/docs/man2/xhtml/glLight.xml) API man page. In particular, for GL_POSITION and GL_SPOT_DIRECTION.

Here are a few helpful links related to your problem:

* OpenGL Wiki: Viewing and Transformations#How does the camera work in OpenGL? (https://www.opengl.org/wiki/Viewing_and_Transformations#How_does_the_camera_wo rk_in_OpenGL.3F)
* OpenGL Wiki: Viewing and Transformations#I put my glULookAt call on my Projection matrix and now fog, lighting, and texture mapping don't work correctly. What happened? (https://www.opengl.org/wiki/Viewing_and_Transformations#I_put_my_gluLookAt.28. 29_call_on_my_Projection_matrix_and_now_fog.2C_lig hting.2C_and_texture_mapping_don.27t_work_correctl y._What_happened.3F)

(Ignore the title of the second link. Just read the contents.)

kaufenpreis
12-22-2016, 08:59 AM
Fixed-Function GL stores the light position in eye space. To do this, the light position is multiplied by the current ModelView matrix at the time of the glLightfv(..., GL__POSITION, ...) call. If you move your camera without re-specifying the light position, it has the effect of a light which remains stationary relative to the camera.

If you want a light which is stationary in the world, you have to load the view matrix (and just the view matrix) and specify the world space light position whenever the view matrix changes.