I am experimenting with bump mapping using quantized normal maps. The last step in the procedure generates a one component bitmap (greyscale bitmap) of unsigned bytes. Dark areas are pixels facing away from the light source, light areas are pixels facing the light source and grey areas are somewhere in between.
I want to multiply each pixel of my greyscale map with its corresponding pixel in the diffuse map using multipass texturing. Lets say r0, g0, b0, a0 represent a pixel from the diffuse map, n0 is a pixel from the greyscale bitmap and r1, g1, b1, a1 is the result. In the end here’s what I’m looking for:
r1 = r0 * n0
g1 = g0 * n0
b1 = b0 * n0
a1 = a0
So far I’ve done all the multipling in software and using OpenGL simply to draw the resulting bitmap. Everything works but slow. I now want to draw the diffuse map in one pass and the greyscale map in another pass and let my video card do all the multipling in hardware. Is this possible?
My attempts so far produce either alot of nothing or an inverted bumpped greyscale and no diffuse map. Please help.
Should I draw the greyscale first or the diffuse?
What should I use for glTexEnv(,?) for the greyscale?
What should I use for glTexEnv(,?) for the the diffuse?
Do I need to use blending?
What should I use for glTexImage2D’s internalFormat and format parameters for the greyscale map?
Thanks in advance.
There is a multipass solution that works so long you are not doing any blending with the object (ie. you want it to be fully opaque).
Draw the diffuse pass first and then the greyscale map using glBlendFunc(GL_ZERO, GL_SRC_ALPHA).
If you want to use multitexturing, you can just set the texture environment to GL_MODULATE for the diffuse map and GL_MODULATE for the greyscale map. This would let you do it all in one pass.
with multitexturing you dont have to use blending but for multipass you will have to blend the second pass over the first.
use GL_MODULATE AB == BA so it doesnt matter in which order you draw them.
just make sure the environment colours are set right ie white
Thanks for all the suggestions but still no go.
Here what the code looks like currently:
// pass one draw diffuse texture. some diffuse parts are transparent.
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
glBindTexture( GL_TEXTURE_2D, _diffuseTexName );
glCallList( _quad );
// pass two multiply with greyscale map
// generate greyscale normal map here --> _pNormalMap
glBlendFunc( GL_ZERO, GL_SRC_ALPHA );
glEnable( GL_BLEND );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA8, 256, 256, 0,
GL_ALPHA, GL_UNSIGNED_BYTE, _pNormalMap );
glCallList( _quad );
glDisable( GL_BLEND );
The result is no diffuse map but greyscale does appear. Depth testing off. Environment color is glClearColor(1,1,1,1). Alpha testing off.
Blending off produces nothing. Setting internalFormat & format to GL_ALPHA8 & GL_ALPHA respectively seems tobe the only combo that produces anything meaningful.
That code above should have done the job I think. I wonder if I didn’t loose something during the conversion from software rendering to OpenGL. Let me check everything again.
Instead of using glBlendFunc(GL_ZERO, GL_SRC_ALPHA), maybe try glBlendFunc(GL_ZERO, GL_SRC_COLOR) and store your greyscale map as a GL_LUMINANCE8 texture?
There’s an example here that does a similar technique to what you want, only the effect achieved is an underwater caustic effect -> http://reality.sgi.com/opengl/tips/caustics/
Check the code that’s included.