PDA

View Full Version : VBO and Normal Maps



Mctittles
04-23-2011, 08:42 AM
Hello. I'm following a normal mapping example I found online that creates a spinning textured cube and am trying to convert that to drawing it on a quad vbo for a 2d program. I'm using 3d opengl mode to take advantage of the lights and bump mapping but the program itself has no view changes outside of the 2d realm.

I can get a texture to work on my object with the following code.


GLfloat vertices[] = {1,1,1, -1,1,1, -1,-1,1, 1,-1,1};
GLubyte indices[] = {0,1,2,3};
GLfloat textureCoords [] = {1.0f,0.0f, 0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f};
GLfloat normals[] = {0,0,1, 0,0,1, 0,0,1, 0,0,1};

//....

glActiveTexture(GL_TEXTURE1);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glNormalPointer(GL_FLOAT, 0, normals);
glTexCoordPointer(2, GL_FLOAT, 0,textureCoords);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glBindTexture(GL_TEXTURE_2D, textureMap);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, indices);
glPopMatrix();
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);


It works perfectly fine, however my attempts at applying the multi-texture in the example have only resulted in a blank screen.



I can however get the example as a cube to work which is created with glBegin() and glEnd(). Here is the relevant part of the example code. First the textures are setup:


glActiveTexture(GL_TEXTURE0);

glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glDisable(GL_TEXTURE_3D_EXT);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

glActiveTexture(GL_TEXTURE1);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glDisable(GL_TEXTURE_3D_EXT);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);


glActiveTexture(GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, normalMap);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); // Perform a Dot3 operation...
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_DOT3_RGB_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE); // between the N (of N.L) which is stored in a normal map texture...
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT); // with the L (of N.L) which is stored in the vertex's diffuse color.
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);


glActiveTexture(GL_TEXTURE1);
glBindTexture (GL_TEXTURE_2D, textureMap);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); // Modulate...
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR); // the color argument passed down from the previous stage (stage 0) with...
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR); // the texture for this stage with.


Then some code for adding light:


//
// Transform the light's position from eye-space to object-space
//
vector3f vLightPosES; // Light position (in eye-space)
vector3f vLightPosOS; // Light position (in object-space)
vector3f vVertToLightOS; // L vector of N.L (in object-space)
vector3f vVertToLightTS; // L vector of N.L (in tangent-space)
// Get the light's current position, which is in eye-space.
float fLightsPosition[4];
glGetLightfv( GL_LIGHT0, GL_POSITION, fLightsPosition );
vLightPosES.x = fLightsPosition[0];
vLightPosES.y = fLightsPosition[1];
vLightPosES.z = fLightsPosition[2];

// Transform the light's position from eye-space into object-space
matrix4x4f modelViewMatrix;
matrix4x4f modelViewMatrixInverse;
glGetFloatv(GL_MODELVIEW_MATRIX, &modelViewMatrix.m[0] );
modelViewMatrixInverse = matrix4x4f::invertMatrix( &modelViewMatrix );
vLightPosOS = vLightPosES;
modelViewMatrixInverse.transformPoint( &vLightPosOS );


Finally the cube is drawn:


vector3f vCurrentVertex;
glBegin( GL_QUADS );
for( int i = 0; i < NUM_VERTICES; ++i ) {
vCurrentVertex.x = g_cubeVertices[i].x;
vCurrentVertex.y = g_cubeVertices[i].y;
vCurrentVertex.z = g_cubeVertices[i].z;
glMultiTexCoord2f( GL_TEXTURE0, g_cubeVertices[i].tu, g_cubeVertices[i].tv );
glMultiTexCoord2f( GL_TEXTURE1, g_cubeVertices[i].tu, g_cubeVertices[i].tv );
vVertToLightOS = vLightPosOS - vCurrentVertex;
vVertToLightOS.normalize();
matrix4x4f invTangentMatrix( g_vTangents[i].x, g_vBiNormals[i].x, g_vNormals[i].x, 0.0f,
g_vTangents[i].y, g_vBiNormals[i].y, g_vNormals[i].y, 0.0f,
g_vTangents[i].z, g_vBiNormals[i].z, g_vNormals[i].z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f );
vVertToLightTS = vVertToLightOS;
invTangentMatrix.transformVector( &amp;vVertToLightTS );
vector3f vVertToLightTS_scaledAndBiased = scaleAndBiasVectorAsRGBColor( &amp;vVertToLightTS );

glColor3f( vVertToLightTS_scaledAndBiased.x,
vVertToLightTS_scaledAndBiased.y,
vVertToLightTS_scaledAndBiased.z );

glNormal3f( g_cubeVertices[i].nx, g_cubeVertices[i].ny, g_cubeVertices[i].nz );
glVertex3f( vCurrentVertex.x, vCurrentVertex.y, vCurrentVertex.z );
}
glEnd();


I've tried copying the texture setup part of the code and choosing the texture ( glActiveTexture(GL_TEXTURE1); glBindTexture (GL_TEXTURE_2D, textureMap);) in my code but it always shows blank.


--------------
Also the g_vTangents, g_vBiNormals, and g_vNormals arrays in their code is calculated with a couple functions that convert tangent space for proper lighting (computeTangentsMatricesForEachVertex(); and createTangentSpaceVectors();). Although I understand the theory behind tangent and object space, I don't yet have a full understanding of the math behind it. I think since I am not planning on having real 3d angles in my code and everything is just going to be a texture put on a quad that is always facing the user I won't need to calculate that since it will always be the same? Am I correct in this? If so, if anyone has the correct normals(?) I should be plugging in for a simple quad it would be much appreciated as well :).

Thanks!