Lighting built-in uniform problem (ATI ?)

The built-in uniform gl_FrontMaterial does not seem to be updated when glMaterialfv() is called (even outside of glBegin() and glEnd()).

this is what I’m doing:

  1. Load (Vertex) Shader:
void main(void)
{
    gl_Position = ftransform();
    gl_FrontColor = gl_FrontMaterial.diffuse;
}
  1. Set diffuse to blue:
    glMaterialfv(GL_FRONT, GL_DIFFUSE, <blue>);
  2. Draw a quad (glBegin()… glEnd())
  3. Set Diffuse to red:
    glMaterialfv(GL_FRONT, GL_DIFFUSE, <red>);
  4. Draw another quad (glBegin()… glEnd())

The result is both quads being blue instead of the first blue and the second red. The same problem occurs with ambient and specular.

I’m on 9600 pro catalyst 5.10. I read some posts about people having other similar problems with the built in lighting variables, but I was hoping drivers would’ve caught up by now. Or at least they could give a warning on the info log whenever we’re trying to use a built-in uniform that’s not fully supported? That would’ve saved hours of frustration.

Anyway, I’m guessing the veterans will suggest using my own uniforms instead?

I’m not using ATI, but I really hope they won’t.

I’ve verified this issue and will file a bug report on it. In the meantime, a workaround (except using uniforms) is to simply call glUseProgramObjectARB() with the same shader again.

Thanks, Humus!

If anyone could verify if other drivers have similar problems, I’d appreciate knowing. So I’m guessing the fastest way (right now) would probably be to use attributes…

nvidia drivers (for a while inc 81.85) suffer from a similar problem where sometimes the uniforms are not set

the solution is to call the following before each program
glGetIntegerv( GL_CURRENT_PROGRAM, &active_programID );
glUseProgram( active_programID );

zed:

Are you suggesting to call glGetIntegerv() and glUseProgram() every time a lighting uniform is changed? Or does calling glGetintegerv() in itself actually fix the bug for you?

no the get isnt important
im just using that to emphasize im not actully changing the program.
for error free rendering u need to reset the program after you change the state ie

void UniqueMaterial::flush_UniqueMaterial( void )
{
	int i;
	g_GL->set_glState( glstate );

	if ( g_Program.options.force_coverup_of_driver_bug_HACK )
	{
		int active_programID;
		glGetIntegerv( GL_CURRENT_PROGRAM, &active_programID );
		
		g_GL->UseProgram( GLuint(active_programID) );

		if ( g_rm.ogl.current_active_programID != active_programID ) // this'll be picked up elsewhere anyways
		{
			LOG_ERROR( "GLprogram mismatch" );
		}
	}

draw meshes

Thanks for the clarification, zed!

I also noticed that I actually have to do:

glUseProgram(0);
glUseProgram(<current program>);

in order to force gl_FrontLightModelProduct to be updated.

Humus: could you please update that bug report to include this detail?

Here’s another mind boggling one.

The following draws light0’s color instead of the expected light1’s:

gl_LightSourceParameters g_lightSource[2];

void foo(int i)
{
    gl_FrontColor = g_lightSource[i].diffuse;
}

void main()
{
    gl_Position = ftransform();
    g_lightSource[0] = gl_LightSource[0];
    g_lightSource[1] = gl_LightSource[1];
    foo(1);
}

However, the following does correctly draw with light1’s color:

vec4 g_vDiffuse[2];

void foo(int i)
{
    gl_FrontColor = g_vDiffuse[i];
}

void main()
{
    gl_Position = ftransform();
    g_vDiffuse[0] = gl_LightSource[0].diffuse;
    g_vDiffuse[1] = gl_LightSource[1].diffuse;
    foo(1);
}

The following also correctly draws with light1’s color:

gl_LightSourceParameters g_lightSource[2];

void main()
{
    gl_Position = ftransform();
    g_lightSource[0] = gl_LightSource[0];
    g_lightSource[1] = gl_LightSource[1];
    gl_FrontColor = g_lightSource[1].diffuse;
}

Seems like a similar problem to the following:
http://www.opengl.org/discussion_boards/cgi_directory/ultimatebb.cgi?ubb=get_topic;f=11;t=000920

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.