#include #include #include #include #include struct surface { int x, y; int num_verts; int num_tris; float **verts; int **tris; }; // Window size int width = 400, height = 400; // Camera Rotation float c_rot_ang = 0.0; char c_rot = 1; // Global Light Model float lm_view = 1.0; float lm_amb[4] = {0.2, 0.2, 0.2, 1.0}; // Light 0 float l0_amb[4] = {0.0, 0.0, 0.0, 1.0}; float l0_diff[4] = {0.5, 0.5, 0.5, 1.0}; float l0_spec[4] = {1.0, 1.0, 1.0, 1.0}; //float l0_spot[2] = {0.0, 180.0}; float l0_spot[2] = {20, 25.0}; float l0_atten[3] = {1.0, 0.0, 0.0}; float l0_pos[4] = {10.0, 10.0, 30.0, 1.0}; float l0_dir[3] = {-10.0, -10.0, -30.0}; // Light 1 float l1_amb[4] = {0.0, 0.0, 0.0, 1.0}; float l1_diff[4] = {0.5, 0.5, 1.0, 1.0}; float l1_spec[4] = {1.0, 1.0, 1.0, 1.0}; float l1_spot[2] = {0.0, 180.0}; //float l1_spot[2] = {1.0, 45.0}; float l1_atten[3] = {1.0, 0.0, 0.0}; float l1_pos[4] = {-10.0, 10.0, 30.0, 1.0}; float l1_dir[3] = {10.0, -10.0, -50.0}; // Mesh surface struct surface *s; // Wall1 Material float w1m_amb[4] = {0.2, 0.0, 0.0, 1.0}; float w1m_diff[4] = {0.8, 0.0, 0.0, 1.0}; float w1m_spec[4] = {0.0, 0.0, 0.0, 1.0}; float w1m_emm[4] = {0.0, 0.0, 0.0, 1.0}; float w1m_shiny = 0.0; // Wall1 Material float w2m_amb[4] = {0.0, 0.2, 0.0, 1.0}; float w2m_diff[4] = {0.0, 0.8, 0.0, 1.0}; float w2m_spec[4] = {0.0, 0.0, 0.0, 1.0}; float w2m_emm[4] = {0.0, 0.0, 0.0, 1.0}; float w2m_shiny = 0.0; // Wall1 Material float w3m_amb[4] = {0.0, 0.0, 0.2, 1.0}; float w3m_diff[4] = {0.0, 0.0, 0.8, 1.0}; float w3m_spec[4] = {0.0, 0.0, 0.0, 1.0}; float w3m_emm[4] = {0.0, 0.0, 0.0, 1.0}; float w3m_shiny = 0.0; // Teapot Material (Mark Kilgard's brass) float tpm_amb[4] = {0.33, 0.22, 0.03, 1.0}; float tpm_diff[4] = {0.78, 0.57, 0.11, 1.0}; float tpm_spec[4] = {0.99, 0.91, 0.81, 1.0}; float tpm_emm[4] = {0.0, 0.0, 0.0, 1.0}; float tpm_shiny = 27.8; // Creates a mesh surface struct surface *createSurface (int x, int y) { struct surface *sur = (struct surface *)malloc(sizeof(struct surface)); int ind; // Initialize structure sur->x = x; sur->y = y; sur->num_verts = x * y; sur->num_tris = (x - 1) * (y - 1) * 2; sur->verts = (float **)malloc(sizeof(float *) * sur->num_verts); sur->tris = (int **)malloc(sizeof(int *) * sur->num_tris); for (int i = 0; i < sur->num_verts; i++) sur->verts[i] = (float *)malloc(sizeof(float) * 3); for (int i = 0; i < sur->num_tris; i++) sur->tris[i] = (int *)malloc(sizeof(int) * 3); // Setup verts for (int i = 0; i < y; i++) for (int j = 0; j < x; j++) { ind = i * x + j; sur->verts[ind][0] = 1.0f * j / (float)(x - 1); sur->verts[ind][1] = 1.0f * i / (float)(y - 1); sur->verts[ind][2] = 0.0f; } // Setup tris for (int i = 0; i < y - 1; i++) for (int j = 0; j < x - 1; j++) { ind = i * (x - 1) * 2 + j * 2; sur->tris[ind][0] = i * x + j; sur->tris[ind][1] = (i + 1) * x + j + 1; sur->tris[ind][2] = (i + 1) * x + j; sur->tris[ind + 1][0] = i * x + j; sur->tris[ind + 1][1] = i * x + j + 1; sur->tris[ind + 1][2] = (i + 1) * x + j + 1; } return sur; } void drawSurface () { // Draw wall triangles for (int i = 0; i < s->num_tris; i++) { glNormal3f(0.0f, 0.0f, 1.0f); glVertex3fv(s->verts[s->tris[i][0]]); glNormal3f(0.0f, 0.0f, 1.0f); glVertex3fv(s->verts[s->tris[i][1]]); glNormal3f(0.0f, 0.0f, 1.0f); glVertex3fv(s->verts[s->tris[i][2]]); } } void draw () { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Setup Projection glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, width / (float)height, 0.1f, 100.0f); // Setup Camera glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0f, 30.0f, 50.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); if (c_rot) { glRotatef(c_rot_ang, 0.0, 1.0, 0.0); c_rot_ang += 1; } // Setup global light model glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, lm_view); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lm_amb); // Setup Light 0 glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, l0_spot[0]); glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, l0_spot[1]); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, l0_atten[0]); glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, l0_atten[1]); glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, l0_atten[2]); glLightfv(GL_LIGHT0, GL_AMBIENT, l0_amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, l0_diff); glLightfv(GL_LIGHT0, GL_SPECULAR, l0_spec); glLightfv(GL_LIGHT0, GL_POSITION, l0_pos); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, l0_dir); // Setup Light 1 glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, l1_spot[0]); glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, l1_spot[1]); glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, l1_atten[0]); glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, l1_atten[1]); glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, l1_atten[2]); glLightfv(GL_LIGHT1, GL_AMBIENT, l1_amb); glLightfv(GL_LIGHT1, GL_DIFFUSE, l1_diff); glLightfv(GL_LIGHT1, GL_SPECULAR, l1_spec); glLightfv(GL_LIGHT1, GL_POSITION, l1_pos); glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, l1_dir); // Disable lighting to draw unlit things glDisable(GL_LIGHTING); // Place dot where light is glPointSize(10.0); glColor3f(1.0f, 1.0f, 0.0f); glBegin(GL_POINTS); glVertex3fv(l0_pos); glVertex3fv(l1_pos); glEnd(); // Enable lighting glEnable(GL_LIGHTING); // Draw right wall glMaterialfv(GL_FRONT, GL_AMBIENT, w1m_amb); glMaterialfv(GL_FRONT, GL_DIFFUSE, w1m_diff); glMaterialfv(GL_FRONT, GL_SPECULAR, w1m_spec); glMaterialfv(GL_FRONT, GL_EMISSION, w1m_emm); glMaterialf(GL_FRONT, GL_SHININESS, w1m_shiny); glColor3f(1.0f, 0.0f, 0.0f); glPushMatrix(); glRotatef(-45.0f, 0.0f, 1.0f, 0.0f); glScalef(25.0f, 25.0f, 0.0f); glBegin(GL_TRIANGLES); drawSurface(); glEnd(); glPopMatrix(); // Draw left wall glMaterialfv(GL_FRONT, GL_AMBIENT, w2m_amb); glMaterialfv(GL_FRONT, GL_DIFFUSE, w2m_diff); glMaterialfv(GL_FRONT, GL_SPECULAR, w2m_spec); glMaterialfv(GL_FRONT, GL_EMISSION, w2m_emm); glMaterialf(GL_FRONT, GL_SHININESS, w2m_shiny); glColor3f(0.0f, 1.0f, 0.0f); glPushMatrix(); glRotatef(45.0f, 0.0f, 1.0f, 0.0f); glScalef(25.0f, 25.0f, 0.0f); glTranslatef(-1.0f, 0.0f, 0.0f); glBegin(GL_TRIANGLES); drawSurface(); glEnd(); glPopMatrix(); // Draw bottom glMaterialfv(GL_FRONT, GL_AMBIENT, w3m_amb); glMaterialfv(GL_FRONT, GL_DIFFUSE, w3m_diff); glMaterialfv(GL_FRONT, GL_SPECULAR, w3m_spec); glMaterialfv(GL_FRONT, GL_EMISSION, w3m_emm); glMaterialf(GL_FRONT, GL_SHININESS, w3m_shiny); glColor3f(0.0f, 0.0f, 1.0f); glPushMatrix(); glRotatef(-135.0f, 0.0f, 1.0f, 0.0f); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); glScalef(25.0f, 25.0f, 0.0f); glBegin(GL_TRIANGLES); drawSurface(); glEnd(); glPopMatrix(); // Draw Teapot glMaterialfv(GL_FRONT, GL_AMBIENT, tpm_amb); glMaterialfv(GL_FRONT, GL_DIFFUSE, tpm_diff); glMaterialfv(GL_FRONT, GL_SPECULAR, tpm_spec); glMaterialfv(GL_FRONT, GL_EMISSION, tpm_emm); glMaterialf(GL_FRONT, GL_SHININESS, tpm_shiny); glColor3f(0.0f, 1.0f, 0.5f); glPushMatrix(); glTranslatef(0.0, 3.0, 15.0); glFrontFace(GL_CW); // Teapot is stored incorrectly glutSolidTeapot(3.0); glFrontFace(GL_CCW); glPopMatrix(); glutSwapBuffers(); } void glInit () { // Turn on lighting glEnable(GL_NORMALIZE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); // Enable depth buffering glEnable(GL_DEPTH_TEST); // Enable Backface culling glEnable(GL_CULL_FACE); glCullFace(GL_BACK); } void exiting () { printf("Finished.\n"); } int main (int argc, char **argv) { glutInit(&argc, argv); atexit(exiting); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(width, height); glutCreateWindow("Lighting Test"); glutDisplayFunc(draw); glutIdleFunc(draw); glInit(); s = createSurface(200, 200); glutMainLoop(); return 0; }