package classwork; import java.awt.event.KeyEvent; import javax.media.opengl.*; import jocode.*; import jomodel.*; /** * GLART_4_light_triangles.java * * Very basic lighting demo. Shines a light on a three triangles arranged * to create a curved surface. Calculate and draw face normals for all triangles. * * Use arrow keys to rotate model. * * Use glShadeModel() to SMOOTH shade or FLAT shade the triangles. */ public class GLART_4_light_triangles extends JOApp { float rotation = 0; // Color value for the overall scene lighting float sceneAmbientLight[] = { 0.18f, 0.1f, .15f, 1f }; // Color values for light float lightDiffuse[] = { 1f, 1f, .8f, 1f }; float lightSpecular[] = { 1f, 1f, .8f, 1f }; float lightAmbient[] = { 0.5f, 0.5f, .4f, 1f }; // Light position: if last value is 0, then this describes light direction. If 1, then light position. float lightPosition[] = { -4f, 3f, 3f, 1f }; // to toggle smooth/flat shading boolean smoothShading = true; /** * Main function just creates and runs the application. */ public static void main(String args[]) { GLART_4_light_triangles app = new GLART_4_light_triangles(); app.run(); } /** * Initialize OpenGL * */ public void setup() { // Select the Projection Matrix (controls perspective) gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); // Reset The Projection Matrix // Define perspective glu.gluPerspective( 45.0f, // Field Of View (float)getWidth() / (float)getHeight(), // aspect ratio 0.1f, // near Z clipping plane 100.0f); // far Z clipping plane // Select The Modelview Matrix (controls model orientation) gl.glMatrixMode(GL.GL_MODELVIEW); // make sure OpenGL correctly layers objects gl.glEnable(GL.GL_DEPTH_TEST); // OpenGL won't draw backward facing triangles ("back faces") gl.glEnable(GL.GL_CULL_FACE); // turn lighting on (does not create a light) gl.glEnable(GL.GL_LIGHTING); // Create a light // diffuse is the color of direct light from this light source // specular is the color of reflected light from this source // ambient is the color of scattered light from this source // position is where the light is, or it's direction setLight( GL.GL_LIGHT1, lightDiffuse, lightAmbient, lightSpecular, lightPosition ); // dim overall scene lighting setAmbientLight(sceneAmbientLight); // How to shade faces: // GL_FLAT -- each face has same lighting (looks faceted) // GL_SMOOTH -- lighting is blended across face gl.glShadeModel(GL.GL_SMOOTH); } /** * rotate scene if right or left arrow keys are pressed */ public void keyDown(int keycode) { if(keycode == KeyEvent.VK_RIGHT) { rotation -= .5f; } else if(keycode == KeyEvent.VK_LEFT) { rotation += .5f; } } /** * rotate scene if right or left arrow keys are pressed */ public void keyUp(int keycode) { if (keycode == KeyEvent.VK_SPACE) { smoothShading = ! smoothShading; if (smoothShading) { gl.glShadeModel(GL.GL_SMOOTH); } else { gl.glShadeModel(GL.GL_FLAT); } } } /** * Render the scene. */ public void draw() { // three triangles (three verts each) JOVector[] tri1 = new JOVector[3]; JOVector[] tri2 = new JOVector[3]; JOVector[] tri3 = new JOVector[3]; // triangle vertices center tri1[0] = new JOVector( 0f, .75f, 0f); // top tri1[1] = new JOVector(-1f, -1f, 0f); // lower left tri1[2] = new JOVector( 1f, -1f, 0f); // lower right // triangle vertices left tri2[0] = new JOVector(-1f, -1f, 0f); // bottom tri2[1] = new JOVector( 0f, .75f, 0f); // top right tri2[2] = new JOVector(-2f, .75f, -.8f); // top left // triangle vertices right tri3[0] = new JOVector( 1f, -1f, 0f); // bottom tri3[1] = new JOVector( 2f, .75f, -.8f); // top right tri3[2] = new JOVector( 0f, .75f, 0f); // top left // calculate normal of triangle JOVector normal1 = JOVector.getNormal(tri1[0], tri1[1], tri1[2]); JOVector normal2 = JOVector.getNormal(tri2[0], tri2[1], tri2[2]); JOVector normal3 = JOVector.getNormal(tri3[0], tri3[1], tri3[2]); // calculate center of triangle JOVector center1 = JOVector.avg(tri1[0],tri1[1],tri1[2]); JOVector center2 = JOVector.avg(tri2[0],tri2[1],tri2[2]); JOVector center3 = JOVector.avg(tri3[0],tri3[1],tri3[2]); // Clear screen and depth buffer gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Select The Modelview Matrix (controls model orientation) // and reset the coordinate system to center of screen gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); // Where is the 'eye' glu.gluLookAt( 0f, 0f, 5f, // eye position 0f, 0f, 0f, // target to look at 0f, 1f, 0f); // which way is up // lines will be 2 pixels gl.glLineWidth(2); // Draw the triangle and normal, rotating gl.glPushMatrix(); { gl.glRotatef(rotation, 0,1,0); drawTriangle(tri1,normal1); drawNormal(center1,normal1); drawTriangle(tri2,normal2); drawNormal(center2,normal2); drawTriangle(tri3,normal3); drawNormal(center3,normal3); } gl.glPopMatrix(); } public void drawTriangle(JOVector[] tri, JOVector normal) { // draw a triangle gl.glBegin(GL.GL_TRIANGLES); { // set the normal (affects all following verts) gl.glNormal3f(normal.x, normal.y, normal.z); gl.glVertex3f(tri[0].x, tri[0].y, tri[0].z); gl.glVertex3f(tri[1].x, tri[1].y, tri[1].z); gl.glVertex3f(tri[2].x, tri[2].y, tri[2].z); } gl.glEnd(); } /** * Draw a red line to indicate the normal. Disable lighting * so we can use glColor(). ReEnable lighting before returning. */ public void drawNormal(JOVector center, JOVector normal) { // draw a red line to indicate where the normal is gl.glDisable(GL.GL_LIGHTING); // turn off so we can use glColor() gl.glColor4f(1, 0, 0, 1); gl.glBegin(GL.GL_LINES); { gl.glVertex3f(center.x, center.y, center.z); gl.glVertex3f(center.x+normal.x, center.y+normal.y, center.z+normal.z); } gl.glEnd(); gl.glEnable(GL.GL_LIGHTING); } }