Hi! I’m new to OpenGL and I’m trying to learn it on my own. I’ve been searching for days for a working example of calculating normals in C++. I can’t get any of the examples I’ve found to work. When I run the code below, it shows a spinning pyramid, but the sides of the pyramid grow lighter and darker randomly rather than as they face the light. Maybe I’m giving the points in the wrong order, or maybe the math is wrong. Has anyone dealt with this before?
void Normal(
float p1_0,
float p1_1,
float p1_2,
float p2_0,
float p2_1,
float p2_2,
float p3_0,
float p3_1,
float p3_2
)
{
float v1[3], v2[3];
GLfloat normal[3];
v1[0] = p1_0 - p2_0;
v1[1] = p1_1 - p2_1;
v1[2] = p1_2 - p2_2;
v2[0] = p3_0 - p2_0;
v2[1] = p3_1 - p2_1;
v2[2] = p3_2 - p2_2;
normal[0]=v1[1]*v2[2] - v1[2]*v2[1];
normal[1]=v1[2]*v2[0] - v1[0]*v2[2];
normal[2]=v1[0]*v2[1] - v1[1]*v2[0];
glNormal3f(normal[0],normal[1],normal[2]);
}
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Add ambient light
GLfloat ambientColor[] = {0.2f, 0.2f, 0.2f, 1.0f}; //Color (0.2, 0.2, 0.2)
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);
//Add positioned light
GLfloat lightColor0[] = {0.5f, 0.5f, 0.5f, 1.0f}; //Color (0.5, 0.5, 0.5)
GLfloat lightPos0[] = {4.0f, 0.0f, 8.0f, 1.0f}; //Positioned at (4, 0, 8)
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);
//Add directed light
GLfloat lightColor1[] = {0.5f, 0.2f, 0.2f, 1.0f}; //Color (0.5, 0.2, 0.2)
//Coming from the direction (-1, 0.5, 0.5)
GLfloat lightPos1[] = {-1.0f, 0.5f, 0.5f, 0.0f};
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1);
glLightfv(GL_LIGHT1, GL_POSITION, lightPos1);
glPushMatrix(); //Save the current state of transformations
glTranslatef(0.0f, 0.0f, -3.0f); //Move to the center of the pyramid
glRotatef(_angle, 0.2f, 1.0f, 0.1f); //Rotate about the the vector (1, 2, 3)
glBegin(GL_TRIANGLES);
//Pyramid
Normal(
0.0f, 0.7f, 0.0f, //top
0.5f, 0.0f, -0.5f, //bottom-right
-0.5f, 0.0f, -0.5f //bottom-left
);
glVertex3f(0.0f, 0.7f, 0.0f); //top
glVertex3f(0.5f, 0.0f, -0.5f); //bottom-right
glVertex3f(-0.5f, 0.0f, -0.5f); //bottom-left
Normal(
0.0f, 0.7f, 0.0f, //top
0.5f, 0.0f, 0.5f, //bottom-right
-0.5f, 0.0f, 0.5f //bottom-left
);
glVertex3f(0.0f, 0.7f, 0.0f);
glVertex3f(0.5f, 0.0f, 0.5f);
glVertex3f(-0.5f, 0.0f, 0.5f);
Normal(
0.0f, 0.7f, 0.0f, //top
0.5f, 0.0f, 0.5f, //bottom-right
0.5f, 0.0f, -0.5f //bottom-left
);
glVertex3f(0.0f, 0.7f, 0.0f);
glVertex3f(0.5f, 0.0f, 0.5f);
glVertex3f(0.5f, 0.0f, -0.5f);
Normal(
0.0f, 0.7f, 0.0f, //top
-0.5f, 0.0f, 0.5f, //bottom-right
-0.5f, 0.0f, -0.5f //bottom-left
);
glVertex3f(0.0f, 0.7f, 0.0f);
glVertex3f(-0.5f, 0.0f, 0.5f);
glVertex3f(-0.5f, 0.0f, -0.5f);
glEnd();
glBegin(GL_QUADS);
//Bottom
Normal(
0.5f, 0.0f, 0.5f, //top-right
0.5f, 0.0f, -0.5f, //bottom-right
-0.5f, 0.0f, -0.5f //bottom-left
);
glVertex3f(0.5f, 0.0f, 0.5f); //top-right
glVertex3f(0.5f, 0.0f, -0.5f); //bottom-right
glVertex3f(-0.5f, 0.0f, -0.5f); //bottom-left
glVertex3f(-0.5f, 0.0f, 0.5f); //top-left
glEnd();
glPopMatrix(); //Undo the move to the center of the triangle
glutSwapBuffers();
}