Hello, I have been working with OpenGl for almost two weeks now and I have hit my first road block. Currently I am learning how to do shading and I am having alot of trouble learning how to set the normals for each my of vertices in order for smooth shading to work. Below is the code for a 3D triforce that I have been working on, by triforce I mean three pyramids with two standing side by side on the bottom and one on top of the other two. The program is written in C++ and I am using the linux mint comand prompt as a compiler. My issue is simple, I have no idea how to compute these normals, and everytime I look towards the internet for answers I just get code and formulas thrown at me with no explaination of how to apply it to my own program. If someone can please give me a simple explaination and maybe even a step by step algorithm of how to do this I will be very greatful.
#include <iostream>
#include <stdlib.h> //Needed for “exit” function
//Include OpenGL header files, so that we can use OpenGL
#ifdef APPLE
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
using namespace std;
//Called when a key is pressed
void handleKeypress(unsigned char key, //The key that was pressed
int x, int y) { //The current mouse coordinates
switch (key) {
case 27: //Escape key
exit(0); //Exit the program
}
}
//Initializes 3D rendering
void initRendering() {
//Makes 3D drawing work when something is in front of something else
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING); //Enable lighting
glEnable(GL_LIGHT0); //Enable light #0
glEnable(GL_LIGHT1); //Enable light #1
glEnable(GL_NORMALIZE); //Automatically normalize normals
glShadeModel(GL_SMOOTH); //Enables smmoth shading
}
//Called when the window is resized
void handleResize(int w, int h) {
//Tell OpenGL how to convert from coordinates to pixel values
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective
//Set the camera perspective
glLoadIdentity(); //Reset the camera
gluPerspective(45.0, //The camera angle
(double)w / (double)h, //The width-to-height ratio
1.0, //The near z clipping coordinate
200.0); //The far z clipping coordinate
}
float angle = -70;
//Draws the 3D scene
void drawScene() {
//Clear information from last draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glTranslatef(0.0f, 0.0f, -5.0);
//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.0f, 0.0f, 0.9f, 1.0f}; //Color (0.5, 0.5, 0.5)
GLfloat lightPos0[] = {2.0f, 2.0f, 5.0f, 0.0f}; //Color (0.5, 0.5, 0.5)
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);
//Add directed light
GLfloat lightColor1[] = {0.9f, 0.0f, 0.0f, 1.0f}; //Color (0.5, 0.2, 0.2)
//Coming from the direction (-1.0, 0.5, 0.5)
GLfloat lightPos1[] = {-1.5f, 1.0f, -1.0f, 0.0f};
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1);
glLightfv(GL_LIGHT1, GL_POSITION, lightPos1);
glTranslatef(0.0f, -1.0f, -1.0f);
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
//Front
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f(2.0f, -1.0, 1.0);
glVertex3f(0.0f, -1.0, 1.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(-2.0f, -1.0, 1.0);
glVertex3f(0.0f, -1.0, 1.0);
glVertex3f(-1.0, 1.0, 0.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(0.0f, 3.0, 0.0);
//Middle
glNormal3f(-1.0f, -1.0f, 0.0f);
glVertex3f(0.0f, -1.0, 1.0);
glVertex3f(0.0, -1.0, -1.0);
glVertex3f(1.0, 1.0, 0.0);
glNormal3f(1.0f, -1.0f, 0.0f);
glVertex3f(0.0f, -1.0, 1.0);
glVertex3f(0.0f, -1.0, -1.0);
glVertex3f(-1.0, 1.0, 0.0);
//Left
glNormal3f(-0.75f, 0.0f, 0.0f);
glVertex3f(-2.0f, -1.0, 1.0);
glVertex3f(-2.0f, -1.0, -1.0);
glVertex3f(-1.0, 1.0, 0.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(0.0f, 3.0, 0.0);
//Right
glNormal3f(0.75f, 0.0f, 0.0f);
glVertex3f(2.0f, -1.0, 1.0);
glVertex3f(2.0, -1.0, -1.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0);
glVertex3f(0.0f, 3.0, 0.0);
//Back
glNormal3f(0.0f, 0.0f, -1.0f);
glVertex3f(2.0f, -1.0, -1.0);
glVertex3f(0.0f, -1.0, -1.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(-2.0f, -1.0, -1.0);
glVertex3f(0.0f, -1.0, -1.0);
glVertex3f(-1.0, 1.0, 0.0);
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(1.0, 1.0, -1.0);
glVertex3f(0.0f, 3.0, 0.0);
glEnd();
glutSwapBuffers(); //Send the 3D scene to the screen
}
void update(int value)
{
angle += 2.0f;
if (angle > 360)
{
angle -=360;
}
glutPostRedisplay();
glutTimerFunc(10, update, 0);
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400); //Set the window size
//Create the window
glutCreateWindow("Basic Shapes - videotutorialsrock.com");
initRendering(); //Initialize rendering
//Set handler functions for drawing, keypresses, and window resizes
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutTimerFunc(1, update, 0);
glutMainLoop(); //Start the main loop. glutMainLoop doesn't return.
return 0; //This line is never reached
}