hi,
i was testing a multipass normalmapping technique with a geforce2mx. there at least two passes, one ambient pass (uses standard lighting) and a diffuse part (uses ARB_vertex_program). when i enable vertex programs, disable lighting, render geometry and disable vertex programs, after the next glEnable(GL_LIGHTING) call, lighting will be ignored at all and instead the primary color is used for rendering. i stripped down the problem to a little test application (given below).
i tried to use the softwarerasterizer enabled with NVemulate and everything rendered as expected. on a geforce5200 i had no problems, too. the problem seems to occur with boards, that cannot handle vertex programs in hardware.
i used detonators 53.30 and 56.xx or 57.xx. always the same.
#include <windows.h>
#include <wingdi.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <glut.h>
PFNGLGENPROGRAMSARBPROC glGenProgramsARB = NULL;
PFNGLBINDPROGRAMARBPROC glBindProgramARB = NULL;
PFNGLPROGRAMSTRINGARBPROC glProgramStringARB = NULL;
// just a dumb vertex program
char* vp_code =
"!!ARBvp1.0
"
"OPTION ARB_position_invariant;"
"MOV result.color, vertex.color;"
"END";
GLuint vp_id = 0;
void init() {
// only ambient material is set to GREEN
GLfloat mat_ambient[4] = {0,1,0,1};
GLfloat mat_black[4] = {0,0,0,1};
// setup just the ambient term
GLfloat light_ambient[4] = {1,1,1,1};
GLfloat light_black[4] = {0,0,0,1};
glClearColor(0,0,0,0);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_black);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_black);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_black);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_black);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 1);
glDisable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
glEnable(GL_CULL_FACE);
glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)wglGetProcAddress("glGenProgramsARB");
glBindProgramARB = (PFNGLBINDPROGRAMARBPROC)wglGetProcAddress("glBindProgramARB");
glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)wglGetProcAddress("glProgramStringARB");
glGenProgramsARB(1, &vp_id);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vp_id);
glProgramStringARB(GL_VERTEX_PROGRAM_ARB,
GL_PROGRAM_FORMAT_ASCII_ARB,
(GLsizei)strlen(vp_code), vp_code);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
// primary color set to magenta
// nothing should be rendered in another
// color than GREEN, because of activated
// lighting
glColor3f(1,0,1);
glLoadIdentity();
glTranslatef(-0.5f, 0.5f, -50);
glScalef(0.5f, 0.5f, 0.5f);
glutSolidSphere(1, 20, 16);
// switch of lighting an bind the vertex program
glDisable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_VERTEX_PROGRAM_ARB);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vp_id);
// if you dont draw anything, everything seems
// to be normal
glBegin(GL_POINTS);
glVertex2f(0,0);
glEnd();
glDisable(GL_VERTEX_PROGRAM_ARB);
// activate lighting again
glEnable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
// set primary color to RED
// the sphere should be rendered
// GREEN, too
glColor3f(1,0,0);
glLoadIdentity();
glTranslatef(0.5f, -0.5f, -50);
glScalef(0.5f, 0.5f, 0.5f);
glutSolidSphere(1, 20, 16);
glDisable(GL_DEPTH_TEST);
glutSwapBuffers();
}
void reshape(int w, int h) {
glViewport(0,0,(GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if ( w <= h )
glOrtho(-1, 1, -1*(GLfloat)h/(GLfloat)w, 1*(GLfloat)h/(GLfloat)w, -100, 100);
else
glOrtho(-1*(GLfloat)w/(GLfloat)h, 1*(GLfloat)w/(GLfloat)h, -1, 1, -100, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(512, 512);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
the app renders two spheres, one in the upper left and one in the lower right corner. if everything works correctly, both spheres should be GREEN colored. on my geforce2mx, the lower right sphere is RED colored.
can anyone confirm this BUG or guide me into the right direction?
regards,
jan