I have setup the lighting to the best of my understanding but all that renders is Ambient lighting. It seems to work on built-in shapes like glutSolidSphere and glutSolidCube, but not my manually coded polygons.
I have spent hours reviewing tutorials and StackOverflow but haven't been able to resolve it on my own.
What am I missing? I am using Netbeans (Windows), C++, FreeGlut.
image: 3D Airplane
#include <GL/glut.h>
#include <GL/glext.h>
GLfloat pos0 [] = {0,1,0,0},
white[] = {1,1,1};
void render(){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glNormal3f(0,1,0);
glScaled(4,4,4);
glRotated(30,1,0,0);
glRotated(60,0,1,0);
glRotated(10,0,0,-1);
glTranslated(0,0,-.2);
glBegin(GL_QUADS);
#define V glVertex3f
// body
glColor3f(.7,.5,.3);
V(0, 0, 0); V( 1,.06,.05); V( 1,.10,.05); V(0, .15, 0);
V(0, 0, 0); V( 1,.06,.05); V( 1,.05,.10); V(0,-.03,.1);
V(0,-.03,.1); V( 1,.05,.10); V( 1,.06,.15); V(0, 0,.2);
V(0, 0,.2); V( 1,.06,.15); V( 1,.10,.15); V(0, .15,.2);
V(0, .15,.2); V( 1,.10,.15); V( 1,.11,.10); V(0, .17,.1);
V(0, .17,.1); V( 1,.11,.10); V( 1,.10,.05); V(0, .15, 0);
V(0, 0, 0); V(-.5,.03,.07); V(-.5,.06,.07); V(0, .15, 0);
V(0, 0, 0); V(-.5,.03,.07); V(-.5,.02,.10); V(0,-.03,.1);
V(0,-.03,.1); V(-.5,.02,.10); V(-.5,.03,.13); V(0, 0,.2);
V(0, 0,.2); V(-.5,.03,.13); V(-.5,.06,.13); V(0, .15,.2);
V(0, .15,.2); V(-.5,.06,.13); V(-.5,.07,.10); V(0, .17,.1);
V(0, .17,.1); V(-.5,.07,.10); V(-.5,.06,.07); V(0, .15, 0);
// wings
glColor3f(.5,.5,.5);
V(-.1,.06, .1); V(.3,.06, .1); V(.4,.10, .7); V( .2,.10, .7);
V(-.1,.10, .1); V(.3,.10, .1); V(.4,.11, .7); V( .2,.11, .7);
V(-.1,.06, .1); V(.2,.10, .7); V(.2,.11, .7); V(-.1,.10, .1);
V( .3,.06, .1); V(.4,.10, .7); V(.3,.10, .1); V( .4,.11, .7);
V( .4,.10, .7); V(.2,.10, .7); V(.4,.11, .7); V( .2,.11, .7);
V(-.1,.06, .1); V(.3,.06, .1); V(.4,.10,-.5); V( .2,.10,-.5);
V(-.1,.10, .1); V(.3,.10, .1); V(.4,.11,-.5); V( .2,.11,-.5);
V(-.1,.06, .1); V(.2,.10,-.5); V(.2,.11,-.5); V(-.1,.10, .1);
V( .3,.06, .1); V(.4,.10,-.5); V(.3,.10, .1); V( .4,.11,-.5);
V( .4,.10,-.5); V(.2,.10,-.5); V(.4,.11,-.5); V( .2,.11,-.5);
// tail
V(.6,.06, .10); V(.8,.06, .10); V(.9,.10, .40); V(.8,.10, .40);
V(.6,.10, .10); V(.8,.10, .10); V(.9,.11, .40); V(.8,.11, .40);
V(.6,.06, .10); V(.8,.10, .40); V(.8,.11, .40); V(.6,.10, .10);
V(.8,.06, .10); V(.9,.10, .40); V(.9,.11, .40); V(.8,.10, .10);
V(.9,.10, .40); V(.8,.10, .40); V(.8,.11, .40); V(.9,.11, .40);
V(.6,.06, .10); V(.8,.06, .10); V(.9,.10,-.20); V(.8,.10,-.20);
V(.6,.10, .10); V(.8,.10, .10); V(.9,.11,-.20); V(.8,.11,-.20);
V(.6,.06, .10); V(.8,.10,-.20); V(.8,.11,-.20); V(.6,.10, .10);
V(.8,.06, .10); V(.9,.10,-.20); V(.9,.11,-.20); V(.8,.10, .10);
V(.9,.10,-.20); V(.8,.10,-.20); V(.8,.11,-.20); V(.9,.11,-.20);
V(.7,.10, .09); V(.9,.10, .09); V( 1,.30, .09); V(.9,.30, .09);
V(.7,.10, .11); V(.9,.10, .11); V( 1,.30, .11); V(.9,.30, .11);
V(.7,.10, .09); V(.9,.30, .09); V(.9,.10, .11); V(.7,.10, .11);
V(.9,.10, .09); V( 1,.30, .09); V( 1,.30, .11); V(.9,.10, .11);
V( 1,.30, .09); V(.9,.30, .09); V(.9,.30, .11); V( 1,.30, .11);
glEnd();
glFlush();
}
int main(int argc,char** argv){
// setup window
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH|GLUT_MULTISAMPLE);
glutInitWindowSize(800,600);
glutCreateWindow("3D Airplane");
glClearColor(0,0,0,1);
// setup perspective
glMatrixMode(GL_PROJECTION);
glFrustum(-2,2, -1.5,1.5, 3,25);
glMatrixMode(GL_MODELVIEW);
gluLookAt(0,0,4, 0,0,0, 0,1,0);
glViewport(0,0,800,600);
glEnable(GL_DEPTH_TEST);
// setup lighting
glLightfv(GL_LIGHT0,GL_POSITION,pos0 );
glLightfv(GL_LIGHT0,GL_DIFFUSE ,white);
glEnable (GL_LIGHT0);
glEnable (GL_LIGHTING);
glEnable (GL_COLOR_MATERIAL);
glutDisplayFunc(render);
glutMainLoop();
}
EDIT: I have written a normal calculation function called calcNormal, and converted my glVertex calls to a quadrilateral array of vertices...
GLfloat* calcNormal(GLfloat* a,GLfloat* b,GLfloat* c){
// define target plane
GLfloat u[] = {b[0]-a[0], b[1]-a[1], b[2]-a[2]};
GLfloat v[] = {c[0]-a[0], c[1]-a[1], c[2]-a[2]};
// calculate cross product
static GLfloat cp[] = { u[1]*v[2] - u[2]*v[1],
u[2]*v[0] - u[0]*v[2],
u[0]*v[1] - u[1]*v[0] };
// normalize
GLfloat length = sqrt(cp[0]*cp[0] + cp[1]*cp[1] + cp[2]*cp[2]);
for(int i=0;i<3;i++) cp[i] /= length;
return cp;
}
render(){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3f(.7,.5,.3);
glPushMatrix();
glScaled(3,3,3);
glRotated(30,1,0,0);
glRotated(60,0,1,0);
glRotated(10,0,0,-1);
glTranslatef(x,y,z);
for(GLint* quad:planeQuads){
#define PV planeVertices
glNormal3fv(calcNormal(PV[quad[0]],PV[quad[1]],PV[quad[2]]));
glBegin(GL_QUADS);
glVertex3fv(PV[quad[0]]);
glVertex3fv(PV[quad[1]]);
glVertex3fv(PV[quad[2]]);
glVertex3fv(PV[quad[3]]);
glEnd();
}
glPopMatrix();
glFlush();
}
...but it still isn't rendering diffuse light, even though I am now setting glNormal for each poly.
My poly/vertex structure now looks like this:
// polygon arrays
GLint planeQuads[37][4] = {
{ 9,15,17,11}, { 9,15,14, 8}, { 8,14,16,10}, {10,16,18,12}, {12,18,19,13}, {13,19,17,11}, // rear body
{ 9, 1, 3,11}, { 9, 1, 0, 8}, { 8, 0, 2,10}, {10, 2, 4,12}, {12, 4, 5,13}, {13, 5, 3,11}, // front body
{ 6,17,20,14}, { 7,19,22,16}, { 6,14,16, 7}, {17,20,19,22}, {20,14,22,16}, // left wing
{ 6,17,23,18}, { 7,19,21,15}, { 6,18,17, 7}, {17,23,19,21}, {23,18,21,15}, // right wing
{24,28,37,31}, {25,30,39,33}, {24,31,33,25}, {28,37,39,30}, {37,31,33,39}, // left fin
{24,28,34,29}, {25,30,38,32}, {24,29,32,25}, {28,34,38,30}, {34,29,32,38}, // right fin
{26,35,48,40}, {27,36,49,41}, {26,40,36,27}, {35,48,49,36}, {48,40,41,49} // tail
};
// vertex arrays
GLfloat planeVertices[50][3] = {
{-.5,0.02,0.10}, {-.5,0.03,0.07}, {-.5,0.03,0.13}, {-.5,0.06,0.07}, {-.5,0.06,0.13},
{-.5,0.07,0.10}, {-.1,0.06,0.10}, {-.1,0.10,0.10}, {0.0,-.03,0.10}, {0.0,0.00,0.00},
{0.0,0.00,0.20}, {0.0,0.15,0.00}, {0.0,0.15,0.20}, {0.0,0.17,0.10}, {0.2,0.10,-.50},
{0.2,0.10,0.70}, {0.2,0.11,-.50}, {0.2,0.11,0.70}, {0.3,0.06,0.10}, {0.3,0.10,0.10},
{0.4,0.10,-.50}, {0.4,0.10,0.70}, {0.4,0.11,-.50}, {0.4,0.11,0.70}, {0.6,0.06,0.10},
{0.6,0.10,0.10}, {0.7,0.10,0.09}, {0.7,0.10,0.11}, {0.8,0.06,0.10}, {0.8,0.10,-.20},
{0.8,0.10,0.10}, {0.8,0.10,0.40}, {0.8,0.11,-.20}, {0.8,0.11,0.40}, {0.9,0.10,-.20},
{0.9,0.10,0.09}, {0.9,0.10,0.11}, {0.9,0.10,0.40}, {0.9,0.11,-.20}, {0.9,0.11,0.40},
{0.9,0.30,0.09}, {0.9,0.30,0.11}, {1.0,0.05,0.10}, {1.0,0.06,0.05}, {1.0,0.06,0.15},
{1.0,0.10,0.05}, {1.0,0.10,0.15}, {1.0,0.11,0.10}, {1.0,0.30,0.09}, {1.0,0.30,0.11}
};