Sign in to follow this  
Trislevn

Problem with creating a plane surface with a cone-like spotlight

Recommended Posts

I'm having troubles with creating a rectangular surface that has a cone-like spotlight pointing on it. So far, I've tried to create a 2D cube surface (glutSolidCube()) and use GL_SPOT_XXX to create the spotlight. But I don't for what reason, the light just keeps scattering all over the surface instead of gather into a spot.

So here is my code so far, you can just focus on the init_light() and display() functions. The other functions are there for you to reference if you need to :)

[code]void rotateCamera()
{
/* Rotate camera 2 degrees about selected axis */
theta[axis] += dtheta;
if (theta[axis] > 360.0 ) theta[axis] -= 360.0;
glutPostRedisplay();
}

void computeCameraPosition() {
GLdouble M[16];

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTranslatef(centroid[0], centroid[1], centroid[2]);
glRotatef(theta[0], 1.0, 0.0, 0.0);
glRotatef(theta[1], 0.0, 1.0, 0.0);
glRotatef(theta[2], 0.0, 0.0, 1.0);
glTranslatef(-centroid[0], -centroid[1], -centroid[2]);
glGetDoublev(GL_MODELVIEW_MATRIX, M);

GLdouble newvec[16];

glMultMatrixd(init_vec);
glGetDoublev(GL_MODELVIEW_MATRIX, newvec);
glPopMatrix();

/* the 1st and 2nd columns are the eye position and new y-axis direction */
memcpy(eye, newvec, sizeof(GLdouble)*4);
memcpy(yaxis, newvec+4, sizeof(GLdouble)*4);
}

void init_light()
{
GLfloat spot_direction[] = { 1.0, 1.0, 0.0 };
glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction );
glLightf( GL_LIGHT0, GL_SPOT_EXPONENT, 2.0 );
glLightf( GL_LIGHT0, GL_SPOT_CUTOFF, 45.0 );

glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
}


void display() {
computeCameraPosition();
glClearColor(0.9, 0.9, 0.9, 1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye[0], eye[1], eye[2],
centroid[0], centroid[1], centroid[2],
yaxis[0], yaxis[1], yaxis[2]);
glutSolidCube(2.0);
glFlush();
glutSwapBuffers();
}

int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 800);
glutInitWindowPosition (200, 100);
glutCreateWindow("Scene Editor");
init_light();
glutDisplayFunc(display);
glutMainLoop();
}[/code]

Share this post


Link to post
Share on other sites
Unfortunately, you can't do any better with fixed function pipeline and glut primitives. Look into [i]"per vertex lighting"[/i], and you'll understand why. Only the color values (light) for only the vertices of the cube are calculated, then those color values are interpolated across the surface.

You have to use shaders and[i] "per pixel lighting"[/i].

[url="http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/"]Linky.[/url]
pitfall 2.(note, that the page is pretty old, so the "solution" it presents is old too)

Share this post


Link to post
Share on other sites
Fixed pipeline computes the lighting per vertex, so the quality will depend on the fineness of the surface. For best results, you need to substantially increase the tessellation of the surface. As the number of vertices increase, lighting will tend to approach the quality of per fragment lighting. A better alternative is to use fragment shaders as Szecs previously recommended.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this