I added dot3 bumpmapping to my engine, based on a NeHe tutorial/article. However, i'm getting some weird results with my implementation (see attached image).
The code...
normalization cubemap generation (called on engine init):
Code:
int dot3::gennormcube(UINT size, GLuint &tex)
{
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
unsigned char* data = new unsigned char[size*size*3];
float offset = 0.5f;
float halfSize = size * 0.5f;
vector3d temp;
unsigned int bytePtr = 0;
for(unsigned int j=0; j<size; j++)
{
for(unsigned int i=0; i<size; i++)
{
temp[0] = halfSize;
temp[1] = (j+offset-halfSize);
temp[2] = -(i+offset-halfSize);
if(temp[0] <= 0)
temp[0] == 0;
if(temp[1] <= 0)
temp[1] == 0;
if(temp[2] <= 0)
temp[2] == 0;
if(temp[0] >= 1)
temp[0] == 1;
if(temp[1] >= 1)
temp[1] == 1;
if(temp[2] >= 1)
temp[2] == 1;
data[bytePtr] = (unsigned char)(temp[0] * 255.0f);
data[bytePtr+1] = (unsigned char)(temp[1] * 255.0f);
data[bytePtr+2] = (unsigned char)(temp[2] * 255.0f);
bytePtr+=3;
}
}
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X,
0, GL_RGB8, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
bytePtr = 0;
for(j=0; j<size; j++)
{
for(unsigned int i=0; i<size; i++)
{
temp[0] = -halfSize;
temp[1] = (j+offset-halfSize);
temp[2] = (i+offset-halfSize);
if(temp[0] <= 0)
temp[0] == 0;
if(temp[1] <= 0)
temp[1] == 0;
if(temp[2] <= 0)
temp[2] == 0;
if(temp[0] >= 1)
temp[0] == 1;
if(temp[1] >= 1)
temp[1] == 1;
if(temp[2] >= 1)
temp[2] == 1;
data[bytePtr] = (unsigned char)(temp[0] * 255.0f);
data[bytePtr+1] = (unsigned char)(temp[1] * 255.0f);
data[bytePtr+2] = (unsigned char)(temp[2] * 255.0f);
bytePtr+=3;
}
}
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
0, GL_RGB8, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
bytePtr = 0;
for(j=0; j<size; j++)
{
for(unsigned int i=0; i<size; i++)
{
temp[0] = i+offset-halfSize;
temp[1] = -halfSize;
temp[2] = j+offset-halfSize;
if(temp[0] <= 0)
temp[0] == 0;
if(temp[1] <= 0)
temp[1] == 0;
if(temp[2] <= 0)
temp[2] == 0;
if(temp[0] >= 1)
temp[0] == 1;
if(temp[1] >= 1)
temp[1] == 1;
if(temp[2] >= 1)
temp[2] == 1;
data[bytePtr] = (unsigned char)(temp[0] * 255.0f);
data[bytePtr+1] = (unsigned char)(temp[1] * 255.0f);
data[bytePtr+2] = (unsigned char)(temp[2] * 255.0f);
bytePtr+=3;
}
}
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
0, GL_RGB8, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
bytePtr = 0;
for(j=0; j<size; j++)
{
for(unsigned int i=0; i<size; i++)
{
temp[0] = i+offset-halfSize;
temp[1] = halfSize;
temp[2] = -(j+offset-halfSize);
if(temp[0] <= 0)
temp[0] == 0;
if(temp[1] <= 0)
temp[1] == 0;
if(temp[2] <= 0)
temp[2] == 0;
if(temp[0] >= 1)
temp[0] == 1;
if(temp[1] >= 1)
temp[1] == 1;
if(temp[2] >= 1)
temp[2] == 1;
data[bytePtr] = (unsigned char)(temp[0] * 255.0f);
data[bytePtr+1] = (unsigned char)(temp[1] * 255.0f);
data[bytePtr+2] = (unsigned char)(temp[2] * 255.0f);
bytePtr+=3;
}
}
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
0, GL_RGB8, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
bytePtr = 0;
for(j=0; j<size; j++)
{
for(unsigned int i=0; i<size; i++)
{
temp[0] = i+offset-halfSize;
temp[1] = (j+offset-halfSize);
temp[2] = halfSize;
if(temp[0] <= 0)
temp[0] == 0;
if(temp[1] <= 0)
temp[1] == 0;
if(temp[2] <= 0)
temp[2] == 0;
if(temp[0] >= 1)
temp[0] == 1;
if(temp[1] >= 1)
temp[1] == 1;
if(temp[2] >= 1)
temp[2] == 1;
data[bytePtr] = (unsigned char)(temp[0] * 255.0f);
data[bytePtr+1] = (unsigned char)(temp[1] * 255.0f);
data[bytePtr+2] = (unsigned char)(temp[2] * 255.0f);
bytePtr+=3;
}
}
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
0, GL_RGB8, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
bytePtr = 0;
for(j=0; j<size; j++)
{
for(unsigned int i=0; i<size; i++)
{
temp[0] = -(i+offset-halfSize);
temp[1] = (j+offset-halfSize);
temp[2] = -halfSize;
if(temp[0] <= 0)
temp[0] == 0;
if(temp[1] <= 0)
temp[1] == 0;
if(temp[2] <= 0)
temp[2] == 0;
if(temp[0] >= 1)
temp[0] == 1;
if(temp[1] >= 1)
temp[1] == 1;
if(temp[2] >= 1)
temp[2] == 1;
data[bytePtr] = (unsigned char)(temp[0] * 255.0f);
data[bytePtr+1] = (unsigned char)(temp[1] * 255.0f);
data[bytePtr+2] = (unsigned char)(temp[2] * 255.0f);
bytePtr+=3;
}
}
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
0, GL_RGB8, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
delete [] data;
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
return true;
}
rendering:
Code:
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, dot3texID);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE) ;
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE) ;
glActiveTextureARB(GL_TEXTURE2_ARB);
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, objectP->m_pMaterials[materialIndex].m_texture );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, objectP->m_pMaterials[materialIndex].m_texture1 );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB) ;
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS) ;
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE) ;
.
.
.
vector3d dist;
glBegin( GL_TRIANGLES );
{
for ( int j = 0; j < objectP->m_pMeshes[i].m_numTriangles; j++ )
{
int triangleIndex = objectP->m_pMeshes[i].m_pTriangleIndices[j];
const Triangle *pTri = &objectP->m_pTriangles[triangleIndex];
index[0] = pTri->m_vertexIndices[0];
dist.x = objectP->light.x - objectP->m_pVertices[index[0]].m_location[0];
dist.y = objectP->light.y - objectP->m_pVertices[index[0]].m_location[1];
dist.z = objectP->light.z - objectP->m_pVertices[index[0]].m_location[2];
glNormal3fv( pTri->m_vertexNormals[0] );
glMultiTexCoord3fARB(GL_TEXTURE0_ARB, dist.x, dist.y, dist.z);
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, pTri->m_s[0]*scaleX, pTri->m_t[0]*scaleY );
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, pTri->m_s[0]*scaleX, pTri->m_t[0]*scaleY );
//if(environment...) { glMulti....};
glVertex3fv( objectP->m_pVertices[index[0]].m_location );
index[1] = pTri->m_vertexIndices[1];
dist.x = objectP->light.x - objectP->m_pVertices[index[1]].m_location[0];
dist.y = objectP->light.y - objectP->m_pVertices[index[1]].m_location[1];
dist.z = objectP->light.z - objectP->m_pVertices[index[1]].m_location[2];
glNormal3fv( pTri->m_vertexNormals[1] );
glMultiTexCoord3fARB(GL_TEXTURE0_ARB, dist.x, dist.y, dist.z);
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, pTri->m_s[1]*scaleX, pTri->m_t[1]*scaleY );
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, pTri->m_s[1]*scaleX, pTri->m_t[1]*scaleY );
//if(environment...) { glMulti....};
glVertex3fv( objectP->m_pVertices[index[1]].m_location );
index[2] = pTri->m_vertexIndices[2];
dist.x = objectP->light.x - objectP->m_pVertices[index[2]].m_location[0];
dist.y = objectP->light.y - objectP->m_pVertices[index[2]].m_location[1];
dist.z = objectP->light.z - objectP->m_pVertices[index[2]].m_location[2];
glNormal3fv( pTri->m_vertexNormals[2] );
glMultiTexCoord3fARB(GL_TEXTURE0_ARB, dist.x, dist.y, dist.z);
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, pTri->m_s[2]*scaleX, pTri->m_t[2]*scaleY );
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, pTri->m_s[2]*scaleX, pTri->m_t[2]*scaleY );
//if(environment...) { glMulti....};
glVertex3fv( objectP->m_pVertices[index[2]].m_location );
}
}
glEnd();
Help or information will be much appreciated!
-psychopath