Created
October 10, 2011 19:57
-
-
Save davidwparker/1276355 to your computer and use it in GitHub Desktop.
OpenGL Screencast 12: Lighting and material part 1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* Poor man's approximation of PI */ | |
| #define PI 3.1415926535898 | |
| /* Macro for sin & cos in degrees */ | |
| #define Cos(th) cos(PI/180*(th)) | |
| #define Sin(th) sin(PI/180*(th)) | |
| /* Common #defines */ | |
| /* Defaults for window sizing */ | |
| #define DEF_WINDOW_HEIGHT 450 | |
| #define DEF_WINDOW_WIDTH 500 | |
| /* Projection */ | |
| #define DEF_ASP 1 | |
| #define DEF_DIM 10 | |
| #define DEF_TH 340 | |
| #define DEF_PH 30 | |
| #define DEF_FOV 55 | |
| #define DEF_ECX 2 | |
| #define DEF_ECY 0 | |
| #define DEF_ECZ 4 | |
| /* Draw defaults */ | |
| #define DEF_AXES 1 | |
| #define DEF_PARMS 1 | |
| /* Shape degrees */ | |
| #define DEF_D 5 | |
| /* Lighting */ | |
| #define DEF_LIGHT 1 | |
| #define DEF_DISTANCE 10 | |
| #define DEF_AMBIENT 35 | |
| #define DEF_DIFFUSE 100 | |
| #define DEF_EMISSION 0 | |
| #define DEF_SPECULAR 0 | |
| #define DEF_SHININESS 0 | |
| #define DEF_L_Y 0 | |
| #define DEF_L_PH 90 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "screencasts.h" | |
| /* | |
| * displayInit | |
| * ------- | |
| * Initializes display | |
| */ | |
| void displayInit(void) | |
| { | |
| glClearColor(0.0,0.0,0.0,0.0); | |
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | |
| glEnable(GL_DEPTH_TEST); | |
| glLoadIdentity(); | |
| } | |
| /* | |
| * displayEye() | |
| * ------ | |
| * Set the eye position | |
| */ | |
| void displayEye(void) | |
| { | |
| double Ex = -2*dim*Sin(th)*Cos(ph); | |
| double Ey = +2*dim *Sin(ph); | |
| double Ez = +2*dim*Cos(th)*Cos(ph); | |
| /* camera/eye position, aim of camera lens, up-vector */ | |
| gluLookAt(Ex+ecX,Ey,Ez+ecZ , ecX,ecY,ecZ , 0,Cos(ph),0); | |
| } | |
| /* | |
| * displayReshape() | |
| * ------ | |
| * GLUT calls this routine when the window is resized | |
| */ | |
| void displayReshape(int width,int height) | |
| { | |
| asp = (height>0) ? (double)width/height : 1; | |
| glViewport(0,0, width,height); | |
| displayProject(fov,asp,dim); | |
| } | |
| /* | |
| * displayProject() | |
| * ------ | |
| * Sets the projection | |
| */ | |
| void displayProject(double fov, double asp, double dim) | |
| { | |
| glMatrixMode(GL_PROJECTION); | |
| glLoadIdentity(); | |
| gluPerspective(fov,asp,dim/16,16*dim); | |
| glMatrixMode(GL_MODELVIEW); | |
| glLoadIdentity(); | |
| } | |
| /* | |
| * display() | |
| * ------ | |
| * Display the scene | |
| */ | |
| void display(void) | |
| { | |
| /* setup functions */ | |
| displayInit(); | |
| displayEye(); | |
| /* Draw Scene */ | |
| drawScene(); | |
| glFlush(); | |
| glutSwapBuffers(); | |
| errCheck("display sanity check"); | |
| } | |
| /* | |
| * redisplayAll | |
| * ------ | |
| * This is called whenever we need to draw the display | |
| */ | |
| void redisplayAll(void) | |
| { | |
| displayReshape(windowWidth, windowHeight); | |
| glutPostRedisplay(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| void displayInit(void); | |
| void displayEye(void); | |
| void displayReshape(int width,int height); | |
| void displayProject(double fov,double asp,double dim); | |
| void display(void); | |
| void redisplayAll(void); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "screencasts.h" | |
| /* Global descriptions on screencasts.h */ | |
| /* ID-used to keep screencasts separate */ | |
| int screencastID = 0; | |
| /* WINDOW */ | |
| char *windowName="OpenGL screenscasts XX: Placeholder"; | |
| int windowHeight=DEF_WINDOW_HEIGHT; | |
| int windowWidth=DEF_WINDOW_WIDTH; | |
| /* TOGGLE DRAW DISPLAYS */ | |
| int toggleAxes=DEF_AXES; | |
| int toggleParms=DEF_PARMS; | |
| /* PROJECTION */ | |
| double asp=DEF_ASP; | |
| double dim=DEF_DIM; | |
| int th=DEF_TH; | |
| int ph=DEF_PH; | |
| int fov=DEF_FOV; | |
| double ecX=DEF_ECX; | |
| double ecY=DEF_ECY; | |
| double ecZ=DEF_ECZ; | |
| /* LIGHTING */ | |
| int toggleLight=DEF_LIGHT; | |
| int distance=DEF_DISTANCE; | |
| int ambient=DEF_AMBIENT; | |
| int diffuse=DEF_DIFFUSE; | |
| int emission=DEF_EMISSION; | |
| int specular=DEF_SPECULAR; | |
| int shininess=DEF_SHININESS; | |
| float shinyvec[1]={1}; | |
| float lightY=DEF_L_Y; | |
| float white[]={1,1,1,1}; | |
| int lightPh=DEF_L_PH; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "screencasts.h" | |
| void initializeGlobals() | |
| { | |
| /* WINDOW */ | |
| windowHeight=DEF_WINDOW_HEIGHT; | |
| windowWidth=DEF_WINDOW_WIDTH; | |
| /* TOGGLE */ | |
| toggleAxes=DEF_AXES; | |
| toggleParms=DEF_PARMS; | |
| /* PROJECTION */ | |
| dim=DEF_DIM; | |
| th=DEF_TH; | |
| ph=DEF_PH; | |
| fov=DEF_FOV; | |
| asp=DEF_ASP; | |
| ecX=DEF_ECX; | |
| ecY=DEF_ECY; | |
| ecZ=DEF_ECZ; | |
| /* LIGHTING */ | |
| toggleLight=DEF_LIGHT; | |
| distance=DEF_DISTANCE; | |
| ambient=DEF_AMBIENT; | |
| diffuse=DEF_DIFFUSE; | |
| emission=DEF_EMISSION; | |
| specular=DEF_SPECULAR; | |
| shininess=DEF_SHININESS; | |
| lightY=DEF_L_Y; | |
| lightPh=DEF_L_PH; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "screencasts.h" | |
| /* | |
| * windowKey() | |
| * ------ | |
| * GLUT calls this routine when a non-special key is pressed | |
| */ | |
| void windowKey(unsigned char key,int x,int y) | |
| { | |
| /* Exit on ESC */ | |
| if (key == 27) exit(0); | |
| else if (key == 'x' || key == 'X') toggleAxes = 1-toggleAxes; | |
| else if (key == 'v' || key == 'V') toggleParms = 1-toggleParms; | |
| /* Change field of view angle */ | |
| else if (key == '-' && key>1) fov--; | |
| else if (key == '+' && key<179) fov++; | |
| /* Change dimensions */ | |
| else if (key == 'I') dim += 0.2; | |
| else if (key == 'i' && dim>1) dim -= 0.2; | |
| /* BEGIN LIGHTING FUNCTIONALITY */ | |
| /* Toggle lighting */ | |
| else if (key == 'l' || key == 'L') toggleLight = 1-toggleLight; | |
| /* Move light (rotation) */ | |
| else if (key == '<') lightPh -= 5; | |
| else if (key == '>') lightPh += 5; | |
| /* Light elevation */ | |
| else if (key == '[') lightY -= 0.5; | |
| else if (key == ']') lightY += 0.5; | |
| /* Light distance */ | |
| else if (key == '{') distance -= 1; | |
| else if (key == '}') distance += 1; | |
| /* Ambient level */ | |
| else if (key == 'a' && ambient>0) ambient -= 5; | |
| else if (key == 'A' && ambient<100) ambient += 5; | |
| /* Diffuse level */ | |
| else if (key == 'd' && diffuse>0) diffuse -= 5; | |
| else if (key == 'D' && diffuse<100) diffuse += 5; | |
| /* Specular level */ | |
| else if (key == 's' && specular>0) specular -= 5; | |
| else if (key == 'S' && specular<100) specular += 5; | |
| /* Emission level */ | |
| else if (key == 'e' && emission>0) emission -= 5; | |
| else if (key == 'E' && emission<100) emission += 5; | |
| /* Shininess level */ | |
| else if (key == 'n' && shininess>-1) shininess -= 1; | |
| else if (key == 'N' && shininess<7) shininess += 1; | |
| /* Translate shininess power to value (-1 => 0) */ | |
| shinyvec[0] = shininess<0 ? 0 : pow(2.0,shininess); | |
| redisplayAll(); | |
| } | |
| /* | |
| * windowMenu | |
| * ------ | |
| * Window menu is the same as the keyboard clicks | |
| */ | |
| void windowMenu(int value) | |
| { | |
| windowKey((unsigned char)value, 0, 0); | |
| } | |
| /* | |
| * windowSpecial() | |
| * ------ | |
| * GLUT calls this routine when an arrow key is pressed | |
| */ | |
| void windowSpecial(int key,int x,int y) | |
| { | |
| int modifiers = glutGetModifiers(); | |
| /* If holding shift, then rotate/elevate */ | |
| if (modifiers == GLUT_ACTIVE_SHIFT) { | |
| /* Right/Left - rotate */ | |
| if (key == GLUT_KEY_RIGHT) th += 5; | |
| else if (key == GLUT_KEY_LEFT) th -= 5; | |
| /* Up/Down - elevation */ | |
| else if (key == GLUT_KEY_UP) ph += 5; | |
| else if (key == GLUT_KEY_DOWN) ph -= 5; | |
| } | |
| /* Otherwise, just shift the screen */ | |
| else { | |
| /* Shift */ | |
| if (key == GLUT_KEY_RIGHT) ecX -= .5; | |
| else if (key == GLUT_KEY_LEFT) ecX += .5; | |
| else if (key == GLUT_KEY_UP) ecZ += .5; | |
| else if (key == GLUT_KEY_DOWN) ecZ -= .5; | |
| } | |
| /* Keep angles to +/-360 degrees */ | |
| th %= 360; | |
| ph %= 360; | |
| redisplayAll(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Target to build | |
| #TARGET = 011 012 | |
| TARGET = 012 | |
| #EXECS = ./executables/011 ./executables/012 | |
| EXECS = ./executables/012 | |
| # Libraries - LINUX | |
| #LIBS=-lglut -lGLU | |
| # Libraries - OSX | |
| LIBS=-framework OpenGL -framework GLUT | |
| all: $(TARGET) | |
| # Generic compile rules | |
| .c.o: | |
| gcc -c -O -Wall $< | |
| # Generic compile and link | |
| %: %.c screencasts.a | |
| gcc -Wall -O3 -o ./executables/$@ $^ $(LIBS) | |
| clean: | |
| rm -f $(EXECS) *.o *.a | |
| # without .h => globals.o | |
| screencasts.a:globals.o print.o error.o shapes.o models.o interaction.o initialization.o draw.o display.o | |
| ar -rcs screencasts.a $^ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef SCREENCASTS | |
| #define SCREENCASTS | |
| /* standard headers */ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <stdarg.h> | |
| #include <string.h> | |
| #include <math.h> | |
| #include <time.h> | |
| /* OpenGL and friends */ | |
| #ifdef USEGLEW | |
| #include <GL/glew.h> | |
| #endif | |
| #define GL_GLEXT_PROTOTYPES | |
| #ifdef __APPLE__ | |
| #include <GLUT/glut.h> | |
| #else | |
| #include <GL/glut.h> | |
| #endif | |
| /* includes */ | |
| #include "common.h" /* common is just defines */ | |
| #include "print.h" /* printing functions */ | |
| #include "error.h" /* error convenience */ | |
| #include "shapes.h" /* basic shapes (cube, cone, etc) */ | |
| #include "models.h" /* complex objects */ | |
| #include "interaction.h" /* user interactions (keyboard, mouse, etc) */ | |
| #include "initialization.h" /* initialization */ | |
| #include "draw.h" /* draw -> draw whatever objects in the scene */ | |
| #include "display.h" /* display -> setup scene to draw */ | |
| /* GLOBALS (externs required here) */ | |
| /* Don't forget to initialize globals! */ | |
| extern int screencastID; | |
| /* window info */ | |
| extern char *windowName; | |
| extern int windowWidth; | |
| extern int windowHeight; | |
| /* toggle views */ | |
| extern int toggleAxes; /* toggle axes on and off */ | |
| extern int toggleParms; /* toggle parameters on and off */ | |
| /* view */ | |
| extern double asp;/* aspect ratio */ | |
| extern double dim;/* dimension of orthogonal box */ | |
| extern int th; /* azimuth of view angle */ | |
| extern int ph; /* elevation of view angle */ | |
| extern int fov; /* field of view for perspective */ | |
| extern double ecX; /* eye center position x */ | |
| extern double ecY; /* eye center position y */ | |
| extern double ecZ; /* eye center position z */ | |
| /* lighting */ | |
| extern int toggleLight; /* toggle light */ | |
| extern int distance; /* light distance */ | |
| extern int ambient; /* ambient intensity % */ | |
| extern int diffuse; /* diffuse intensity % */ | |
| extern int emission; /* emission intensity % */ | |
| extern int specular; /* specular intensity % */ | |
| extern int shininess; /* shininess (power of two) */ | |
| extern float shinyvec[1]; /* shininess (value) */ | |
| extern float lightY; /* elevation of light */ | |
| extern float white[]; /* the color white */ | |
| extern int lightPh; /* light movement */ | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "screencasts.h" | |
| /* | |
| * cone | |
| * ------ | |
| * Draws a cone | |
| * at (x,y,z) | |
| * with radius r and height h | |
| * with 360/deg sides | |
| */ | |
| void cone(double x,double y,double z, | |
| double r,double h,int deg) | |
| { | |
| int k; | |
| glPushMatrix(); | |
| /* Transform */ | |
| glTranslated(x,y,z); | |
| glScaled(r,h,r); | |
| glRotated(-90,1,0,0); | |
| /* sides */ | |
| glBegin(GL_TRIANGLES); | |
| for (k=0;k<=360;k+=deg){ | |
| glColor3f(0.0,0.0,1.0); | |
| glVertex3f(0,0,1); | |
| glColor3f(0.0,1.0,1.0); | |
| glVertex3f(Cos(k),Sin(k),0); | |
| glColor3f(1.0,0.0,1.0); | |
| glVertex3f(Cos(k+deg),Sin(k+deg),0); | |
| } | |
| glEnd(); | |
| /* bottom circle */ | |
| /* rotate back */ | |
| glRotated(90,1,0,0); | |
| glBegin(GL_TRIANGLES); | |
| glColor3f(1.0,1.0,0.0); | |
| for (k=0;k<=360;k+=deg) { | |
| glVertex3f(0,0,0); | |
| glVertex3f(Cos(k),0,Sin(k)); | |
| glVertex3f(Cos(k+deg),0,Sin(k+deg)); | |
| } | |
| glEnd(); | |
| glPopMatrix(); | |
| } | |
| /* | |
| * cube | |
| * ------ | |
| * Draw a cube | |
| * at (x,y,z) | |
| * dimensions (dx,dy,dz) | |
| * rotated th about the y axis | |
| */ | |
| void cube(double x,double y,double z, | |
| double dx,double dy,double dz, | |
| double th) | |
| { | |
| /* Cube vertices */ | |
| GLfloat vertA[3] = { 0.5, 0.5, 0.5}; | |
| GLfloat vertB[3] = {-0.5, 0.5, 0.5}; | |
| GLfloat vertC[3] = {-0.5,-0.5, 0.5}; | |
| GLfloat vertD[3] = { 0.5,-0.5, 0.5}; | |
| GLfloat vertE[3] = { 0.5, 0.5,-0.5}; | |
| GLfloat vertF[3] = {-0.5, 0.5,-0.5}; | |
| GLfloat vertG[3] = {-0.5,-0.5,-0.5}; | |
| GLfloat vertH[3] = { 0.5,-0.5,-0.5}; | |
| glPushMatrix(); | |
| /* Transform */ | |
| glTranslated(x,y,z); | |
| glRotated(th,0,1,0); | |
| glScaled(dx,dy,dz); | |
| /* Cube */ | |
| glBegin(GL_QUADS); | |
| /* front => ABCD yellow */ | |
| glNormal3f(0,0,1); | |
| glColor3f(1.0,1.0,0.0); | |
| glVertex3fv(vertA); | |
| glVertex3fv(vertB); | |
| glVertex3fv(vertC); | |
| glVertex3fv(vertD); | |
| /* back => FEHG red */ | |
| glNormal3f(0,0,-1); | |
| glColor3f(1.0,0.0,0.0); | |
| glVertex3fv(vertF); | |
| glVertex3fv(vertE); | |
| glVertex3fv(vertH); | |
| glVertex3fv(vertG); | |
| /* right => EADH green */ | |
| glNormal3f(1,0,0); | |
| glColor3f(0.0,1.0,0.0); | |
| glVertex3fv(vertE); | |
| glVertex3fv(vertA); | |
| glVertex3fv(vertD); | |
| glVertex3fv(vertH); | |
| /* left => BFGC blue */ | |
| glNormal3f(-1,0,0); | |
| glColor3f(0.0,0.0,1.0); | |
| glVertex3fv(vertB); | |
| glVertex3fv(vertF); | |
| glVertex3fv(vertG); | |
| glVertex3fv(vertC); | |
| /* top => EFBA turquoise */ | |
| glNormal3f(0,1,0); | |
| glColor3f(0.0,1.0,1.0); | |
| glVertex3fv(vertE); | |
| glVertex3fv(vertF); | |
| glVertex3fv(vertB); | |
| glVertex3fv(vertA); | |
| /* bottom => DCGH pink */ | |
| glNormal3f(0,-1,0); | |
| glColor3f(1.0,0.0,1.0); | |
| glVertex3fv(vertD); | |
| glVertex3fv(vertC); | |
| glVertex3fv(vertG); | |
| glVertex3fv(vertH); | |
| glEnd(); | |
| glPopMatrix(); | |
| } | |
| /* | |
| * sphere | |
| * ------ | |
| * Draw a sphere | |
| * at (x,y,z) | |
| * radius (r) | |
| * rotated rot around the y axis | |
| */ | |
| void sphere(double x,double y,double z,double r,double rot) | |
| { | |
| int th,ph; | |
| float yellow[] = {1.0,1.0,0.0,1.0}; | |
| float emissions[] = {0.0,0.0,0.01*emission,1.0}; | |
| /* | |
| Material shininess = specular exponent | |
| Material specular = specular color of material | |
| Material emission = simulates original lighting from an object | |
| */ | |
| glMaterialfv(GL_FRONT,GL_SHININESS,shinyvec); | |
| glMaterialfv(GL_FRONT,GL_SPECULAR,yellow); | |
| glMaterialfv(GL_FRONT,GL_EMISSION,emissions); | |
| glPushMatrix(); | |
| /* Transform */ | |
| glTranslated(x,y,z); | |
| glScaled(r,r,r); | |
| glRotated(rot,0,1,0); | |
| /* Bands of latitude */ | |
| for (ph=-90;ph<90;ph+=DEF_D) { | |
| glBegin(GL_QUAD_STRIP); | |
| for (th=0;th<=360;th+=2*DEF_D) { | |
| vertex(th,ph); | |
| vertex(th,ph+DEF_D); | |
| } | |
| glEnd(); | |
| } | |
| glPopMatrix(); | |
| } | |
| /* | |
| * vertex | |
| * ------ | |
| * Draw vertex in polar coordinates with normal | |
| */ | |
| void vertex(double th,double ph) | |
| { | |
| double x = Sin(th)*Cos(ph); | |
| double y = Cos(th)*Cos(ph); | |
| double z = Sin(ph); | |
| /* For a sphere at the origin, the position | |
| and normal vectors are the same */ | |
| glNormal3d(x,y,z); | |
| glVertex3d(x,y,z); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| void cone(double x,double y,double z, | |
| double r,double h,int deg); | |
| void cube(double x,double y,double z, | |
| double dx,double dy,double dz, | |
| double th); | |
| void sphere(double x,double y,double z, | |
| double r,double rot); | |
| void vertex(double th,double ph); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment