package solarsim.gl; import solarsim.common.State; import solarsim.*; import com.sun.opengl.util.Animator; import com.sun.opengl.util.texture.Texture; import com.sun.opengl.util.texture.TextureCoords; import com.sun.opengl.util.texture.TextureIO; import java.awt.Frame; import java.awt.event.*; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.LinkedList; import java.util.logging.Level; import java.util.logging.Logger; import javax.media.opengl.GL; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCanvas; import javax.media.opengl.GLEventListener; import javax.media.opengl.GLException; import javax.media.opengl.glu.GLU; import javax.media.opengl.glu.GLUquadric; /** * SolarSim.java
* author: Brian Paul (converted to Java by Ron Cemer and Sven Goethel)

* * This version is equal to Brian Paul's version 1.2 1999/10/21 */ public class SolarSim implements GLEventListener, Runnable, KeyListener, MouseListener { float rotate = 0; private final double SCALE_FACTOR = 150E9F; // 150 million km int MoveX = 0; int MoveY = 0; float x1[][]= new float[361][2]; float x2[][]= new float[361][2]; float x3[][]= new float[721][2]; float Xvalue = 0; float Yvalue = 0; float Angle = 0; static final int MODE_SCALE = 0; static final int MODE_ROTATE = 1; static final int MODE_NOTHING = -1; int press_x, press_y; float msX_angle = 0; float msY_angle = 0; int mouseX, mouseY; int mode ; float scale_size = 1; private GLU glu = new GLU(); //private boolean newTexture; private boolean flushTexture; private File file; private Texture textureEarth, textureSun; private LinkedList states; static int count = 0; private volatile boolean running; private Thread thread; Iterator it; public SolarSim(){ this.states = new LinkedList(); } void drawState(State s) { if( count == 0 ) System.out.println(s); if( count++ % 1 != 0 ) return; if( s == null ) return; synchronized( states ) { states.addFirst(s); states.notify(); } } public void init(GLAutoDrawable drawable) { // Use debug pipeline // drawable.setGL(new DebugGL(drawable.getGL())); int i = 0; for(i=0; i <= 360; i++) { x1[i][0] = (float)(Math.sin(i*3.1416/180)*3); x1[i][1] = (float)(Math.cos(i*3.1416/180)*3); } for(i=0; i <= 360; i++) { x2[i][0] = (float)(Math.sin(i*3.1416/180)*1); x2[i][1] = (float)(Math.cos(i*3.1416/180)*1); } for(i=0; i <= 720; i++) { x3[i][0] = (float)(Math.sin(i*3.1416/180)*5); x3[i][1] = (float)(Math.cos(i*3.1416/180)*5); } GL gl = drawable.getGL(); System.err.println("INIT GL IS: " + gl.getClass().getName()); // Enable VSync gl.setSwapInterval(1); // Setup the drawing area and shading mode gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.glShadeModel(GL.GL_SMOOTH); // try setting this to GL_FLAT and see what happens. it = states.iterator(); /* gl.glViewport(0,0,500,300); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(45.0f, 800.0f / 600.0f, 1.0f, 500.0f); gl.glMatrixMode(GL.GL_MODELVIEW);*/ } public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { GL gl = drawable.getGL(); //GLU glu = new GLU(); if (height <= 0) { // avoid a divide by zero error! height = 1; } final float h = (float) width / (float) height; gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(45.0f, h, 1.0, 20.0); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); } public void display(GLAutoDrawable drawable) { /* synchronized( states ) { while( states.isEmpty() ) { try { states.wait(); } catch (InterruptedException ex) { } } }*/ //if (it.hasNext()) // while (it.hasNext()) // { // State s = it.next(); try { GL gl = drawable.getGL(); File file = new File("images/earthS.png"); textureEarth = TextureIO.newTexture(file, true); file = new File("images/sunS.jpg"); textureSun = TextureIO.newTexture(file, true); // Clear the drawing area gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); // Reset the current matrix to the "identity" gl.glLoadIdentity(); gl.glTranslatef(0.0f, 0.0f, -6.0f); if (mode == MODE_ROTATE) { msX_angle += (mouseX - press_x) / 5.0; // System.out.println("changed "+msX_angle); if (msX_angle > 180) { msX_angle -= 360; } else if (msX_angle < -180) { msX_angle += 360; } press_x = mouseX; msY_angle += (mouseY - press_y) / 5.0; if (msY_angle > 180) { msY_angle -= 360; } else if (msY_angle < -180) { msY_angle += 360; } press_y = mouseY; } else if (mode == MODE_SCALE) { float old_size = scale_size; scale_size *= (1 + (mouseY - press_y) / 60.0); if (scale_size < 0) { scale_size = old_size; } press_y = mouseY; } //glu.gluLookAt(0.0, 7.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); glu.gluLookAt(0,7,2, 0,0,0, 0,1,0); gl.glColor3f((float) 1.0, (float) 1.0, (float) 1.0); //rotate scale the entire image gl.glRotatef(msX_angle, 0, 1, 0); gl.glRotatef(msY_angle, 1, 0, 0); gl.glScalef(scale_size, scale_size, scale_size); GLUquadric qobj = glu.gluNewQuadric(); glu.gluQuadricDrawStyle(qobj, GLU.GLU_FILL); glu.gluQuadricNormals(qobj, GLU.GLU_SMOOTH); /* synchronized(states) { // for( State s : states ) { Particle p = s.getParticles().get(0); Vector r = p.getPosition(); int dx = +(int)(r.x/SCALE_FACTOR*300)/20; int dy = -(int)(r.y/SCALE_FACTOR*300)/20; System.out.println(dx + " " + dy); //earth // glu.gluLookAt (0.0, 10.0, 2.0, 0.0, 0.0, 0.0, 1.0, .0, 0.0); gl.glPushMatrix(); gl.glTranslatef(dx, dy, 0.0f); gl.glRotatef(Angle, 0.0f, 0.0f, 1.0f); gl.glColor3f(0f, 0f, 1f); glu.gluSphere(qobj,0.2, 15, 15); gl.glTranslatef(-dx, -dy, 0.0f); gl.glPopMatrix(); // } //}*/ /* gl.glPushMatrix(); gl.glTranslatef(Xvalue, 0.0f, Yvalue); gl.glRotatef(Angle, 0.0f, 0.0f, 1.0f); gl.glColor3f(0f, 0f, 1f); glu.gluSphere(qobj,0.5, 20, 20); gl.glTranslatef(Xvalue, 0.0f, Yvalue); gl.glPopMatrix();*/ if (textureSun != null) { textureSun.enable(); textureSun.bind(); gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); TextureCoords coords = textureSun.getImageTexCoords(); //sun gl.glPushMatrix(); //glu.gluLookAt (0.0, 10.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); gl.glTranslatef(Xvalue, 0.0f, Yvalue); gl.glRotatef(Angle, 0.0f, 0.0f, 1.0f); //glu.gluQuadricNormals(qobj, GLU.GLU_SMOOTH); // gl.glColor4f(1f, 1f, 0f, 1f); gl.glTexCoord2f(coords.left(), coords.bottom()); glu.gluQuadricTexture(qobj, true); glu.gluSphere(qobj, 0.2f, 15, 15); textureSun.disable(); glu.gluQuadricTexture(qobj, false); gl.glPopMatrix(); } if (textureEarth != null) { textureEarth.enable(); textureEarth.bind(); gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); TextureCoords coords = textureEarth.getImageTexCoords(); //earth //glu.gluLookAt (0.0, 10.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); gl.glPushMatrix(); if (MoveX == 360) { MoveX = 0; } gl.glTranslatef(x1[MoveX][1], x1[MoveX][0], 0.0f); gl.glRotatef(Angle, 0.0f, 0.0f, 1.0f); //gl.glColor3f(0f, 0f, 1f); gl.glTexCoord2f(coords.left(), coords.bottom()); glu.gluQuadricTexture(qobj, true); glu.gluSphere(qobj, 0.3f, 15, 15); textureEarth.disable(); glu.gluQuadricTexture(qobj, false); gl.glTranslatef(x2[MoveX][0], x2[MoveX][1], 0.0f); glu.gluSphere(qobj, 0.1f, 10, 10); gl.glPopMatrix(); } //saturn gl.glPushMatrix(); // glu.gluLookAt (0.0, 10.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0); if (MoveY == 720) { MoveY = 0; } gl.glTranslatef(x3[MoveY / 2][1], x3[MoveY / 2][0], 0.0f); gl.glRotatef(Angle, 0.0f, 0.0f, 1.0f); glu.gluSphere(qobj, 0.3f, 15, 15); int i = 0; //glBegin(GL_LINE_STRIP); gl.glBegin(gl.GL_QUAD_STRIP); for (i = 0; i <= 360; i++) { gl.glVertex3f((float) (Math.sin(i*3.1416/180)*0.5), (float) (Math.cos(i*3.1416/180)*0.5), 0f); gl.glVertex3f((float) (Math.sin(i*3.1416/180)*0.7), (float) (Math.cos(i*3.1416/180)*0.7), 0f); } gl.glEnd(); gl.glRotatef(Angle, 0.0f, 0.0f, 1.0f); gl.glPopMatrix(); gl.glFlush(); Angle += 15.0; // glu.glutPostRedisplay(); MoveX += 1; MoveY += 1; // Flush all drawing operations to the graphics card } catch (Exception ex) { Logger.getLogger(SolarSim.class.getName()).log(Level.SEVERE, null, ex); } //} } public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { } public void run() { this.running = true; this.thread = Thread.currentThread(); while( running ) { synchronized( states ) { while( states.isEmpty() ) { try { states.wait(); } catch (InterruptedException ex) { } } // State s = states.removeLast(); } try { thread.sleep(40); } catch( Exception ex ) {} } } public void keyTyped(KeyEvent e) { // throw new UnsupportedOperationException("Not supported yet."); } public void keyPressed(KeyEvent e) { // throw new UnsupportedOperationException("Not supported yet."); } public void keyReleased(KeyEvent e) { // throw new UnsupportedOperationException("Not supported yet."); } public void mouseClicked(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); } public void mousePressed(MouseEvent e) { System.out.println("pressed"); switch(e.getModifiers()) { case InputEvent.BUTTON1_MASK: { mode = MODE_ROTATE; mouseX=e.getX(); mouseY=e.getY(); System.out.println("That's the LEFT button"); break; } case InputEvent.BUTTON3_MASK: { mode = MODE_SCALE; mouseX=e.getX(); mouseY=e.getY(); System.out.println("That's the RIGHT button"); break; } //throw new UnsupportedOperationException("Not supported yet."); } } public void mouseReleased(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); } public void mouseEntered(MouseEvent e) { // throw new UnsupportedOperationException("Not supported yet."); } public void mouseExited(MouseEvent e) { //throw new UnsupportedOperationException("Not supported yet."); } public static void main(String[] args) { try{ SolarSim sim = new SolarSim(); new Thread(sim).start(); Frame frame = new Frame("Simple JOGL Application"); GLCanvas canvas = new GLCanvas(); canvas.requestFocus(); canvas.addGLEventListener(sim); canvas.addKeyListener(sim); canvas.addMouseListener(sim); frame.add(canvas); frame.setSize(800, 600); final Animator animator = new Animator(canvas); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { // Run this on another thread than the AWT event queue to // make sure the call to Animator.stop() completes before // exiting new Thread(new Runnable() { public void run() { animator.stop(); System.exit(0); } }).start(); } }); // Center frame frame.setLocationRelativeTo(null); frame.setVisible(true); animator.start(); /* InputStream is = new FileInputStream("sim.dat"); // TODO must have stop message for( int i = 0; i < 1000000; i++ ) { State s = State.readStateFromInputStream(is); sim.drawState(s); }*/ System.out.println("Stopping."); Thread.currentThread().sleep(1000 * 10); } catch(Exception e) { e.printStackTrace(); } } }