Got bump-mapping to work. . . but I'm confused. . .

Ostsol

New member
I must not understand lighting too well (not suprising). GL_LIGHTING seems to mess up bump-mapping. Actually, it appears to force the colour of each vertex to be white. When it GL_LIGHTING is disabled, the colours that I assign to the vertices remains. The thing is that for normal texture maps (no bump-mapping) the texture isn't lit at all. So I guess this means that when I render normal textures I have to enable GL_LIGHTING and disable it for bump-mapped textures. Right?
 
Yeah, when you're doing bumpmapping you're basically doing your own lighting, so turn lighting off. It can be combined with the standard lighting though, for instance for the attenuation, but I wouldn't recommend that.
 
Ah. . . Ok. . . I have another problem, though. :( I tried making a cubic room with the light source in the centre. Here's a code segment from my draw-loop:

// dot3 bump map
glActiveTextureARB (GL_TEXTURE0_ARB);
glBindTexture (GL_TEXTURE_2D, texture[polygon.texindex[1]]);
glEnable (GL_TEXTURE_2D);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);

// base texture
glActiveTextureARB (GL_TEXTURE1_ARB);
glBindTexture (GL_TEXTURE_2D, texture[polygon.texindex[0]]);
glEnable (GL_TEXTURE_2D);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);

static float lpes[3]; // light position in eye space
static float lpos[3]; // light position in object space
static float lv[3]; // vector from vertex to light
static float lvts[3]; // light vector in tangent space

static float modelViewMatrix[16];
static float modelViewMatrixInverse[16];

glGetFloatv (GL_MODELVIEW_MATRIX, modelViewMatrix);
matrixInvert (modelViewMatrix, modelViewMatrixInverse);

lpes[0] = light[1].position[0];
lpes[1] = light[1].position[1];
lpes[2] = light[1].position[2];

vectorMultMatrix (lpes, modelViewMatrixInverse, lpos);

for (int i = 0; i < polygon.vertices; i++)
{
lv[0] = lpes[0] - polygonlist.vertlist[polygon.vertindex].x;
lv[1] = lpes[1] - polygonlist.vertlist[polygon.vertindex].y;
lv[2] = lpes[2] - polygonlist.vertlist[polygon.vertindex].z;
vectorNormalize (lv);

vectorMult3x3Matrix (lv, tangentMatrix, lvts);
lvts[0] = lvts[0] * 0.5f + 0.5f;
lvts[1] = lvts[1] * 0.5f + 0.5f;
lvts[2] = lvts[2] * 0.5f + 0.5f;

polygonlist.vertlist[polygon.vertindex].r = lvts[0];
polygonlist.vertlist[polygon.vertindex].g = lvts[1];
polygonlist.vertlist[polygon.vertindex].b = lvts[2];

int offset = sizeof (VERTEXDATA) * polygon.vertindex;

glUpdateObjectBufferATI (gluiVertexObject, offset, sizeof (VERTEXDATA), &polygonlist.vertlist[polygon.vertindex], GL_PRESERVE_ATI);
}

glDrawElements (GetDrawType (polygon.shape), polygon.vertices, GL_UNSIGNED_INT, polygon.vertindex);


What happens is that only half of the cube is lit, the far half, such that only one square surface (rendered using triangle-strips) is properly lit. When I turn bump-mapping off and the lights back on, everything seems to be working properly.
 
Hmm. . . Nevermind. . . I figured it out. After looking at a few webpages for clues and then a sample from the Radeon SDK, I figured out exactly what the deal is with the tangent matrix.

The tangent matrix I used in the above code is from the Simple DOT3 sample in the Radeon SDK. Unfortunately, that demo only deals with a single surface. Because of this, the demo only has to take into account a single set of normal, binormal, and tangent vectors and therefore a single tangent matrix. The tangent matrix was a static piece of data that never changed in that demo. In my own program I have six surfaces making up a cube and each has a different normal (all normals pointing inward to the centre) and therefore and different binormal and tangent vectors.

I'm really quite suprised that it is so difficult to find a thorough tutorial on the subject. The theoretical info I found on a webpage was actually a quite different than that which was used in the DOT3Bump3DLight sample in the Radeon SDK. The tangent matrix was put together a bit differently, which really messed me up. When I just plugged in the normal vector, the result was really quite wrong. However, when I tried the matrix configuration in the DOT3Bump3DLight sample it worked quite perfectly. Strange. . .
 
Back
Top