The purpose of this assignment is for you to become familiar with OpenGL and Magican. Your real task is to read the Magician and OpenGL documentation (see the links page), and to play around with the API, trying things out. To demonstrate that you have gotten it working, you must write a simple solar system simulation as described below.
First of all, you must get Magician installed and running properly. There is a sample program at the end of this assignment that you can use to test Magician, and as a starting point for your assignment. There are two things that must be installed to get this code to work properly: OpenGL and Magician. OpenGL is freely available from SGI and you can download and install it on your PC (see the links page). I am actively working on getting WAM to install it in the CS WAM lab, and hopefully it will be installed very soon. If it is not, I will delay the due date on this assignment.
Magician is installed in my account on WAM, and you can access it from T:\wam.umd.edu\home\wam\b\e\bederson\magician. In order for Magician to run properly, you must set your PATH variable to <magician>\lib, and the CLASSPATH variable to <magician>\classes. If you are running Java from the command line, you can set the PATH variable with 'set PATH=%PATH%;<new pathname>', and the CLASSPATH variable similarly. You can set the classpath within Visual J++ through the Project/... Properties menu on the 'classpath' tab. To run Visual J++, you must set the PATH variable through autoexec.bat (for Win98) or the Systems control panel (for Win NT). Because you do not have access to the control panels in the WAM lab, you must run your programs from the command line (sorry). You can use 'jview /cp ".;T:\wam.umd.edu\home\wam\b\e\bederson\magician\classes" yourApp'
Your solar system simulation must:
Have a stationary sun
Have 3 planets circling the sun at different speeds
The planets must rotate about their own axes
The first planet should have no moons, the second planet should have one moon circling it, and the third planet should have two moons circling it.
The moons must rotate about their own axes
You must draw some colored shapes on the surface of the planets and the moons so their rotation will be visible.
/** * Sample OpenGL program using Magician in Java. * It draws a rotating square and sphere. * * @author Benjamin B. Bederson * @date March 6, 2000 */ import java.applet.*; import java.awt.*; import java.awt.event.*; import com.hermetica.magician.*; public class testGL extends Frame implements GLEventListener, KeyListener, WindowListener { // The initial dimensions of the window static private int WIDTH = 400; static private int HEIGHT = 400; // The OpenGL state machine GL gl = null; CoreGL coreGL = new CoreGL(); GLU glu = new CoreGLU(); // The OpenGL-aware Component we are rendering into GLComponent glc = null; // Internal model of scene float angle = 0.0f; // The current rotation angle of the scene public static void main(String argv[]) { testGL d = new testGL(); d.setTitle("Simple OpenGL Test"); d.startDemo(); } public testGL() { gl = coreGL; } public void startDemo() { setLayout(new BorderLayout()); // Create the OpenGL Component glc = (GLComponent)GLDrawableFactory.createGLComponent(WIDTH, HEIGHT); add("Center", glc); pack(); show(); // Setup the context capabilities GLCapabilities cap = glc.getContext().getCapabilities(); cap.setDoubleBuffered(GLCapabilities.DOUBLEBUFFER); glc.addKeyListener(this); // Add the key listener to the component this.addWindowListener(this); // Add the window listener glc.addGLEventListener(this); // Add the listener and initialize the component glc.initialize(); glc.start(); // Start a simple animation which results in the display // method being called over and over again. } /** * Gets called exactly once when GLComponent.initialize() is invoked */ public void initialize(GLDrawable component) { // Set the clear colour for the framebuffer gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Enable lighting gl.glEnable(GL.GL_LIGHTING); gl.glEnable(GL.GL_LIGHT0); gl.glEnable(GL.GL_COLOR_MATERIAL); } /** * Handles viewport resizing */ public void reshape(GLDrawable component, int x, int y, int width, int height) { gl.glViewport(component, x, y, width, height); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho(-100f, 100f, -100f, 100f, 0.1f, 200.0f); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); // Add a simple light at (100, 100, 100); float[] lightPosition = {100.0f, 100.0f, 100.0f, 0.0f}; gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition); } /** * Renders the scene */ public void display(GLDrawable component) { // Clear the framebuffer gl.glClear(GL.GL_COLOR_BUFFER_BIT); gl.glLoadIdentity(); // Start in GCS // Push everything a bit away from the camera gl.glTranslate(0f, 0f, -100f); // Rotate everything around the Y axis gl.glRotatef(angle, 0f, 1f, 0f); // Draw a rectangle gl.glColor3f(0.0f, 0.0f, 1.0f); gl.glBegin(GL.GL_POLYGON); gl.glVertex3f(0f, 0f, 0.0f); gl.glVertex3f(0f, 50f, 0.0f); gl.glVertex3f(50f, 50f, 0.0f); gl.glVertex3f(50f, 0f, 0.0f); gl.glEnd(); // Draw a sphere gl.glTranslatef(50f, 50f, 0f); GLUQuadric quadric = glu.gluNewQuadric(); glu.gluSphere(quadric, 10, 16, 16); angle += 1f; } public GL getGL() { return coreGL; } /***************************************************** * Utilities *****************************************************/ /** * Dump the capabilities of the current OpenGL system * to stdout. */ static public void dumpCapabilities() { GLCapabilities[] caps = GLCapabilities.enumerateCapabilities(); for (int i=0; i<caps.length; i++) { System.out.println("Capabilities[" + i + "]: "); System.out.println(caps[i].toString() + "\n"); } } /***************************************************** * KeyListener Interface implementation *****************************************************/ /** * Handles key pressed event */ public void keyPressed(KeyEvent evt) { if (evt.getKeyChar() == KeyEvent.VK_ESCAPE) { // Destroy the GLContext glc.destroy(); dispose(); System.exit(0); } } /** * Handles key typed events */ public void keyTyped(KeyEvent evt) { } /** * Handles key released events */ public void keyReleased(KeyEvent evt) { } /***************************************************** * WindowListener Interface implementation *****************************************************/ public void windowClosing(WindowEvent evt) { glc.destroy(); dispose(); System.exit(0); } public void windowDeiconified(WindowEvent evt) { if (glc.isRunning()) { glc.resume(); } } public void windowIconified(WindowEvent evt) { if (glc.isRunning()) { glc.suspend(); } } public void windowActivated(WindowEvent evt) { } public void windowClosed(WindowEvent evt) { } public void windowDeactivated(WindowEvent evt) { } public void windowOpened(WindowEvent evt) { } }