package classwork; import javax.media.opengl.*; import jocode.*; import jomodel.*; /** * GLART_4_orbit_lights.java * * Orbit a light source around two spheres. * * Set the light position after glTranslate/glRotate to move the light. * * Use glEnable(GL.GL_NORMALIZE) to force all normals to a length of 1. * This is critical to insure consistent lighting when spheres are * scaled to different sizes (normals will be scaled too!). * * Use the EMISSIVE material property to create a glowing sphere. * * Use a display list to optimize the sphere rendering. */ public class GLART_4_orbit_lights extends JOApp { float rotation = 0f; // Material for planet JOMaterial material = new JOMaterial(); // Material, glowing (for "light") JOMaterial materialE = new JOMaterial(); /** * Main function just creates and runs the application. */ public static void main(String args[]) { GLART_4_orbit_lights app = new GLART_4_orbit_lights(); app.run(); } /** * Initialize OpenGL * */ public void setup() { // Set a basic perspective view setPerspective(); // turn depth testing on gl.glEnable(GL.GL_DEPTH_TEST); // turn lighting on (does not create a light, have to do that below) gl.glEnable(GL.GL_LIGHTING); // Tell OpenGL to force all normal lengths to 1, // so light illuminates all surfaces evenly gl.glEnable(GL.GL_NORMALIZE); //----------------------------------------------- // Create light //----------------------------------------------- // color of light source float lightDiffuse[] = new float[] { 1f, 1f, .5f, 1f }; // direct light float lightSpecular[] = new float[] { 1f, 1f, .5f, 1f }; // highlight float lightAmbient[] = new float[] { .2f, .2f, .1f, 1f }; // scattered light // light position: if last value is 0, then this describes light direction. If 1, then light position. float lightPosition[] = new float[] { -4f, 4f, 4, 1f }; // Create a light // diffuse is the color of direct light from this light source // ambient is the color of reflected light from this source // position is where the light is, or it's direction setLight( GL.GL_LIGHT1, lightDiffuse, lightAmbient, lightSpecular, lightPosition ); // overall scene lighting float ambient[] = new float[] { .4f, .4f, .5f, 1f }; setAmbientLight(ambient); //----------------------------------------------- // Create 2 Materials //----------------------------------------------- // Red material settings float mtlDiffuse[] = { 1f, 0f, 0f, 1f }; // red float mtlAmbient[] = { .5f, 0f, 0f, 1f }; // red float mtlSpecular[] = { .6f, .6f, .6f, 1f }; // light gray: reflective float mtlShininess = 100f; // 0=no highlight, 127=sharp highlight material.setDiffuse(mtlDiffuse); material.setAmbient(mtlAmbient); material.setSpecular(mtlSpecular); material.setShininess(mtlShininess); material.apply(); // make a glowing material for the "light" float mtlEmissive[] = { 1f, 1f, .4f, 1f }; // yellow/white materialE.setEmission(mtlEmissive); } /** * Render the scene. */ public void draw() { rotation += .5f; // Clear screen and depth buffer gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Select The Modelview Matrix (controls model orientation) gl.glMatrixMode(GL.GL_MODELVIEW); // Reset the Modelview matrix // this resets the coordinate system to center of screen gl.glLoadIdentity(); // Where is the 'eye' glu.gluLookAt( 0f, 2f, 20f, // eye position 0f, 0f, 0f, // target to look at 0f, 1f, 0f); // which way is up // 1: draw sphere at center gl.glPushMatrix(); { gl.glScalef(3f, 3f, 3f); renderSphere(48); // 48 divisions around sphere: smoother } gl.glPopMatrix(); // rotate coord system around Y // all rendering below this point will be rotated gl.glRotatef(rotation, 0,1,0); // shift coordinate system right away from center gl.glTranslatef(9, 0, 0); // 2: draw orbiting sphere gl.glPushMatrix(); { // shrink it down gl.glScalef(1.5f, 1.5f, 1.5f); renderSphere(); } gl.glPopMatrix(); // 3: draw white sphere and set light position to that position gl.glPushMatrix(); { // rotate moon around earth gl.glRotatef(rotation * 2.3f, 0, 1, 0); // shift coordinate system right away from earth gl.glTranslatef(4f, 0, 0); // Set light position (will be transformed just like a vertex) setLightPosition(GL.GL_LIGHT1, 0, 0, 0); // shrink gl.glScalef(.3f, .3f, .3f); // turn on light material (glowing), draw small sphere materialE.apply(); renderSphere(); // revert to planet material material.apply(); } gl.glPopMatrix(); } /** * Reshape() is called when window is resized. Reset the viewport to the new window * dimensions and call setPerspective() to reset the perspective view. This will use * the new aspect ratio of the window so the scene will not be squashed or stretched. */ public void reshape(int newDisplayWidth, int newDisplayHeight) { setViewport(0,0,newDisplayWidth,newDisplayHeight); setPerspective(); } }