I've been working on this Cel-Shading code for a long time and I've never for the life of me been able to get it to work! My code is based off of the NeHe tutorial (#37) and as far as I can tell, I've always followed it to the exact detail! So far, my geometry just comes out black always. Been at this for ages and still can't figure it out. What's going on?? Here's code below:
Global variables & defines. The vertices make a Icosahedron and for each vertex, the normal is the same as the vertex value itself.
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
#define X 0.525731112119133606f
#define Z 0.850650808352039932f
// Vertices
static GLfloat VertexData[12][3] =
{
{-X, 0.0f, Z }, { X, 0.0f, Z }, {-X, 0.0f,-Z }, { X, 0.0f,-Z },
{ 0.0f, Z, X }, { 0.0f, Z,-X }, { 0.0f,-Z, X }, { 0.0f,-Z,-X },
{ Z, X, 0.0f }, {-Z, X, 0.0f }, { Z,-X, 0.0f }, {-Z,-X, 0.0f },
};
// Indices
static GLint TIndices[20][3] =
{
{0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
{8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
{7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
{6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11}
};
// Light angle
GLfloat fLightAngle[3] = { 0.0f, 0.0f, 1.0f };
// Floating point texture values
GLfloat ShaderTexture[] =
{
0.2, 0.2, 0.2, 0.2, 0.5, 0.5, 0.5, 0.5,
0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
};
GLuint uShaderTexture = 0; // Handle to the shader texture
These are the math functions I've been using. They are the same as the NeHe tutorial as well.
//-----------------------------------------------------------------------------
// Basic math functions
//-----------------------------------------------------------------------------
inline float DotProduct3( float v1[3], float v2[3] )
{
return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
}
inline float Magnitude( float v[3] )
{
return sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
}
void Normalize( float v[3] )
{
float m = Magnitude(v);
if( m != 0.0f )
{
v[0] /= m;
v[1] /= m;
v[2] /= m;
}
}
void RotateVector( float m[16], float v[3], float d[3] )
{
d[0] = (m[0]*v[0])+(m[4]*v[1])+(m[8] *v[2]);
d[1] = (m[1]*v[0])+(m[5]*v[1])+(m[8] *v[2]);
d[2] = (m[2]*v[0])+(m[6]*v[1])+(m[10]*v[2]);
}
This is where I initialized my default render states and the 1D cel-shading texture:
//
// Set default render states
//
// Enable depth testing
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LESS );
glClearDepth( 1.0f );
// Disable lighting
glDisable( GL_LIGHTING );
// glEnable( GL_LIGHTING );
// Disable texture mapping (for now)
glDisable( GL_TEXTURE_2D );
// Enable 1D texture mapping
glEnable( GL_TEXTURE_1D );
// Disable blending
glDisable( GL_BLEND );
// Disable dithering
glDisable( GL_DITHER );
// Enable perspective correction and polygon smoothing
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
// Change the default clear colour to blue
glClearColor( 0.0f, 0.0f, 0.5f, 1.0f );
// Create the shader texture
GLfloat textureData[32][3];
glGenTextures( 1, &uShaderTexture );
for( int i = 0; i > 32; i++ )
{
textureData[0] = ShaderTexture;
textureData[1] = ShaderTexture;
textureData[2] = ShaderTexture;
}
glBindTexture( GL_TEXTURE_1D, uShaderTexture );
glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexImage1D( GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGB, GL_FLOAT, textureData );
Normalize( fLightAngle );
Okay, now for the rendering part.
// Move the camera back and rotate the object
glTranslatef( 0.0f, 0.0f,-3.0f );
glRotatef( rotY, 0.0f, 1.0f, 0.0f );
// Get the current matrix (after transformation)
glGetFloatv( GL_MODELVIEW_MATRIX, Matrix );
// Render in wireframe mode.
// glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
//
// Cel-Shading code
//
// Enable 1D textures and bind the shader texture
glEnable( GL_TEXTURE_1D );
glBindTexture( GL_TEXTURE_1D, uShaderTexture );
// Default mesh colour
glColor3f( 1.0f, 1.0f, 1.0f );
// Render Icosahedron
glBegin(GL_TRIANGLES);
for( int i = 0; i < 20; i++ )
{
// This works fine for normal rendering (lighting included).
/*glNormal3fv(&VertexData[TIndices[0]][0]);
glVertex3fv(&VertexData[TIndices[0]][0]);
glNormal3fv(&VertexData[TIndices[1]][0]);
glVertex3fv(&VertexData[TIndices[1]][0]);
glNormal3fv(&VertexData[TIndices[2]][0]);
glVertex3fv(&VertexData[TIndices[2]][0]);*/
for( int j = 0; j < 3; j++ )
{
float tmpNormal[3], tmpVector[3], tmpShade;
tmpNormal[0] = VertexData[TIndices[j]][0];
tmpNormal[1] = VertexData[TIndices[j]][1];
tmpNormal[2] = VertexData[TIndices[j]][2];
RotateVector( Matrix, tmpNormal, tmpVector );
Normalize( tmpVector );
tmpShade = DotProduct3( tmpVector, fLightAngle );
if( tmpShade < 0.0f )
tmpShade = 0.0f;
glTexCoord1f( tmpShade );
glVertex3fv( &VertexData[TIndices[j]][0] );
}
}
glEnd();
So hopefully one of the more experienced members of gamedev.net can give me a hand. They make it look easy, but I guess it isn't. This sucks. Any ideas? Thanks.