Sunday, March 07, 2010

JOGL程式的基本架構


/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package idv.sean;

import com.sun.opengl.util.FPSAnimator;
import com.sun.opengl.util.GLUT;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import javax.swing.JFrame;

/**
*
* @author sean
*/
public class OpenGLApp3 extends JFrame
implements GLEventListener, KeyListener {

static int year = 0, day = 0;
private KeyEvent key;
private GLCanvas canvas;
private GLCapabilities caps;
GLU glu = new GLU();
GLUT glut = new GLUT();
private FPSAnimator animator;

public OpenGLApp3() {
super("My Test");

caps = new GLCapabilities();
canvas = new GLCanvas(caps);
//canvas.setIgnoreRepaint( true );
canvas.addGLEventListener(this);
canvas.addKeyListener(this);
animator = new FPSAnimator( canvas, 60 );
animator.setRunAsFastAsPossible(false);
getContentPane().add(canvas);
}

public void run() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(512, 512);
setLocationRelativeTo(null);
setVisible(true);
canvas.requestFocus();
animator.start();
}

public static void main(String[] args) {
new OpenGLApp3().run();
}

public void init(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glShadeModel(GL.GL_FLAT);

}

public void display(GLAutoDrawable drawable) {
GL gl = drawable.getGL();

gl.glClear(GL.GL_COLOR_BUFFER_BIT);
gl.glColor3f(1.0f, 1.0f, 1.0f);

gl.glPushMatrix();
glut.glutWireSphere(1.0, 20, 16); /* draw sun */
gl.glRotatef((float) year, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(2.0f, 0.0f, 0.0f);
gl.glRotatef((float) day, 0.0f, 1.0f, 0.0f);
glut.glutWireSphere(0.2, 10, 8); /* draw smaller planet */
gl.glPopMatrix();
drawable.swapBuffers();

}

public void reshape(GLAutoDrawable drawable, int arg1, int arg2, int w, int h) {
GL gl = drawable.getGL();

gl.glViewport(0, 0, w, h);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(60.0, (float) w / (float) h, 1.0, 20.0);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
glu.gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

}

public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) {
}

public void keyTyped(KeyEvent e) {
}

public void keyPressed(KeyEvent key) {
this.key = key;
System.out.println(key.getKeyCode());
switch (key.getKeyChar()) {

case 'd':
day = (day + 10) % 360;
break;
case 'D':
day = (day - 10) % 360;
break;
case 'y':
year = (year + 5) % 360;
break;
case 'Y':
year = (year - 5) % 360;
break;
default:
break;
}

canvas.display();
}

public void keyReleased(KeyEvent e) {
}
}


JOGL的核心在於GLEventListener與GLAutoDrawable這兩個介面。GLAutoDrawable這個介面有兩個實作,一個是GLCanvas,另一個是GLJPanel。前者是AWT的元件,後者是Swing的元件,當你將AWT與Swing元件混用的時候會有一些問題,但是GLCanvas會直接與OpenGL互動,所以效率比較好,之間的取捨就看需求。

GLEventListner則是JOGL繪圖的核心,包含了init、display、reshape、dispose四個函式。init只會被呼叫一次,負責繪圖環境的建置。display相當於java2d的paintComponent,負責實際的繪圖動作。reshape則是在GLAutoDrawable改變大小時進行視點、Viewport的變化。dispose則是GLAutoDrawable物件消失時,負責資源回收的工作。

Labels:

0 Comments:

Post a Comment

<< Home