NVIDIA driver bug?

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

// set primary color to RED
// the sphere should be rendered
// GREEN, too
glColor3f(1,0,0);
wrong.
The sphere should be rendered red, just because that’s what the vertex program does.
It seems like you expect lighting to be enabled when you call glEnable(GL_LIGHTING), which is the true in almost all cases. “Almost all” cases, why not just “all” cases ? In fact when you use vertex programs, all lighting part is overriden by the vertex program.

have a look three lines of code above.

 glDisable(GL_VERTEX_PROGRAM_ARB); 

i disabled vertex programs and the fixed functions should be used. i tried this program on serveral machines and only cards, that cannot handle vertex programs in hardware show a red sphere.

you can compile the code and try it by yourself.

i think, your “wrong” is wrong :wink:

jan

alright now it makes sense.
so, huh, yes it looks like a driver bug.
I can easily understand the kind of optimizations that yields to this effect, considering software vertex programs need lots of optimizations to be worth playing with.

Hi,

just out of curiosity, does your second sphere turn green if you resubmit the glMaterial* calls ?

I once had some problems with NV boards which made me resubmit glColor* calls (when lighting was on with color material enabled) just before rendering - as the glColor* calls seemed to have been somehow screwed up by too many state changes.

My current workaround (maybe useless with current drivers) was to call glGet* to get the the current color and resubmit the given color using glColor*.

I’m quite curious to know if such a trick could work for you !..

Well Nicolas, you’re invited to copy/paste the above code and try it by yourself :smiley:

the second sphere turns green when leaving lighting enabled during the vertex program pass. it does not disturb the result, but i stepped several hours through my code to find it.

furthermore i omitted the vertexnormal stream in the ambient pass (glClientState(GL_NORMAL_ARRAY disabled), because they are not needed and i wanted to save some memory bandwidth. i turned out to be another reason for that driver “bug”. when passing all the senseless normals to opengl, everything worked as expected and standard ogl lighting was applied. without the normalpointer, wrong lighting was the result.

i hope to get around such problems in the future :slight_smile:
i really dont want to drive crazy, read specs and stuff just to recognize after hours: it has to be a driver bug!

nobody is perfect,
jan

Originally posted by vincoof:
Well Nicolas, you’re invited to copy/paste the above code and try it by yourself :smiley:
FWIW, I don’t have any GeForce 2MX to test on, and as the OP said that
on a geforce5200 i had no problems, too

  • I thought I would have a hard time reproducing the problem.

Anyway, it seems that it was an application bug after all :wink: