spec. highlights on textured surface

Hi,
in the superbible I found sth. about how to keep specular highlights on textures. That’s done by drawing the textured Object twice, first without texture and only with the highlights turned on, and then, drawing the object textured with all types of light turned on, except the spec. highlights. Before drawing the object the second time, GL_BLEND is enabled with glBlendFunc(GL_ONE, GL_ONE).
When doing this, GL_DEPTH_TEST should be disabled, becaus otherwise the two objects are drawn at the same place, and that could result into problems with depth-testing (an effect calles z-fighting).

But I’d like to do this with bezier-surfaces, and because of blending, I can look trough a ‘hill’ at the ground that is actually lying behind the hill.

Has someone an idea that helps me out?
Thanks!

mathias_123

There’s a function in OpenGL which lets you apply specular highlight after texturing, instead of before.

glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);

And to go back to the original mode.

glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SINGLE_COLOR_EXT);

This requires the extensions GL_EXT_separate_specular_color or OpenGL 1.2.

Thanks, but I don’t have that extension.
Does somebody know another way?
I already succeeded in doing specular highlights on textured spheres, so I believe that it must be possible on bezier-surfaces, too.

mahias_123

One thing I didn’t think about when reading your post the first time, was that you disable the depth buffer. You should not disable the depthbuffer in the second pass, but disable writing to it, and set depth function to GL_EQUAL.

glDepthMask(GL_FALSE);
glDepthFunc(GL_EQUAL);

If you disable depth test, objects far away won’t be occluded by by objects near the viewpoint. The GL_EQUAL should not introduce any Z-fighting, unless you change some states between the two passes, that affect the fragment position (like matrices).

This may not be an extension. It’s part of core OpenGL now AFAIK. Look in the header files for similar tokens, maybe it was made an ARB extension, or is full on core. I don’t track all this stuff.

For the depth issues, the equal depth test is not a solution. You still need to depth test but less than or equal is still the right test. You should use plPolygonOffset to avoid ‘interference’ or zfighting between rendering passes.

The depth mask is a good idea, but obviously you’d never need it with a GL_EQUAL depth test.

[This message has been edited by dorbie (edited 01-29-2002).]

The depth mask is rendurant if you only want to make it work, yes. But if you disable the depth mask, you will also make sure you don’t do any rendurant updates of the depth buffer when a fragment with equal depth is generated. Some drivers might be smart enough to realize this, but you can’t be sure every driver are.