“你好,JOGL - Java与OpenGl的绑定”是网络上比较容易找到的关于JOGL的入门文章,其英文版“Hello JOGL, Introducing Java Bindings for OpenGL”最早发布于2005年2月,随着JOGL新版本的发布,其中的一些代码无法在新的JOGL中正确的编译,我在学习的过程中对该文中的代码进行修改,从而在新版JOGL中可以正常编译和运行。 文中代码中需要进行的主要变化包括:
模块的打包已改为javax.media.opengl.*;
GLEventListener的接口参数drawable类型改为GLAutoDrawable;
GLCanvas对象已经可以通过构造函数直接创建;
GLU对象可以通过构造函数直接创建,不必从GLAutoDrawable中获取;
GLU类在javax.media.opengl.glu模块中定义,因此需要单独import;
修改后的代码在JOGL
1.1.1
环境下正常编译与运行。
相关经过修改的代码如下:
helloJogl.java:
import javax.media.opengl.*; publicclass helloJogl ...{ publicstaticvoid main (String args[]) ...{ try...{ System.loadLibrary("jogl"); System.out.println("Hello World! (The native libraries are installed.)"); } catch (Exception e) ...{ System.out.println(e); } } }
SimpleJoglApp.java
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.media.opengl.*; /** *//** * This is a basic JOGL app. Feel free to * reuse this code or modify it. */ publicclass SimpleJoglApp extends JFrame ...{ publicstaticvoid main(String[] args) ...{ final SimpleJoglApp app =new SimpleJoglApp(); // show what we've done SwingUtilities.invokeLater ( new Runnable() ...{ publicvoid run() ...{ app.setVisible(true); } } ); } public SimpleJoglApp() ...{ //set the JFrame title super("Simple JOGL Application"); //kill the process when the JFrame is closed setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //only three JOGL lines of code ... and here they are GLCapabilities glcaps =new GLCapabilities(); GLCanvas glcanvas = new GLCanvas(glcaps); //GLDrawableFactory.getFactory().createGLCanvas(glcaps); glcanvas.addGLEventListener(new SimpleGLEventListener()); //add the GLCanvas just like we would any Component getContentPane().add(glcanvas, BorderLayout.CENTER); setSize(500, 300); //center the JFrame on the screen centerWindow(this); } publicvoid centerWindow(Component frame) ...{ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = frame.getSize(); if (frameSize.width > screenSize.width ) frameSize.width = screenSize.width; if (frameSize.height > screenSize.height) frameSize.height = screenSize.height; // Frame.setLocation ( // (screenSize.width - frameSize.width ) >> 1, // (screenSize.height - frameSize.height) >> 1 // ); } }
SimpleGLEventListener.java
import java.awt.*; import java.awt.event.*; import javax.media.opengl.*; /** *//*** For our purposes only two of the * GLEventListeners matter. Those would * be init() and display(). * 为了达到我们的目的,GLEventListener中只有两个方法有用。 * 它们是init()和display()。 */ publicclass SimpleGLEventListener implements GLEventListener...{ /** *//** * Take care of initialization here. * 注意这里的初始化。 */ publicvoid init(GLAutoDrawable drawable) ...{ } /** *//** * Take care of drawing here. * 注意这里的绘图。 */ publicvoid display(GLAutoDrawable drawable) ...{ } /** *//** * Called when the GLDrawable (GLCanvas * or GLJPanel) has changed in size. We * won't need this, but you may eventually * need it -- just not yet. * 当GLDrawable(GLCanvas或GLJPanel)大小改变时被调用。 * 我们不需要它,但你可能最后会用到——虽然现在并不需要。 */ publicvoid reshape( GLAutoDrawable drawable, int x, int y, int width, int height) ...{} /** *//** * If the display depth is changed while the * program is running this method is called. * Nowadays this doesn't happen much, unless * a programmer has his program do it. * 当程序运行时显示深度被改变的时候此方法被调用。 * 现在这种事发生得不多,除非程序里面触发此事。 */ publicvoid displayChanged( GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) ...{} }
SecondJoglApp.java
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.media.opengl.*; /**//* * this is a basic JOGL app, feel free * to reuse this code or mordify it. */ publicclass SecondJoglApp extends JFrame ...{ publicstaticvoid main(String[] args) ...{ final SecondJoglApp app =new SecondJoglApp(); // show what we've done SwingUtilities.invokeLater ( new Runnable() ...{ publicvoid run() ...{ app.setVisible(true); } } ); } public SecondJoglApp() ...{ // set the frame title super("Second JOGL Application"); // kill the process when the JFrame is closed setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // only three JOGL lines of code ... and here they are GLCapabilities glaps =new GLCapabilities(); GLCanvas glcanvas = new GLCanvas(glaps); glcanvas.addGLEventListener(new SecondGLEventListener()); // add the GLCanvas just like we would any component getContentPane().add(glcanvas, BorderLayout.CENTER); setSize(500, 300); // center the JFrame on the screen centerWindow(this); } publicvoid centerWindow(Component Frame) ...{ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = Frame.getSize(); if (frameSize.width > screenSize.width) frameSize.width = screenSize.width; if (frameSize.height > screenSize.height) frameSize.height = screenSize.height; Frame.setLocation ( (screenSize.width - frameSize.width) >>1, (screenSize.height - frameSize.height) >>1); } }
SecondGLEventListener.java
import javax.media.opengl.*; import javax.media.opengl.glu.*; /**//* * for our purposes only tow of the GLEventListeners matter. * those would be init() and display(). */ publicclass SecondGLEventListener implements GLEventListener ...{ /**//* * take care of initialization here. */ publicvoid init (GLAutoDrawable gld) ...{ GL gl = gld.getGL(); GLU glu = new GLU(); gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.glViewport(0, 0, 500, 300); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); glu.gluOrtho2D(0.0, 500.0f, 0.0, 300.0f); } /**//* * take care of drawing here */ publicvoid display(GLAutoDrawable drawable) ...{ float red =0.0f; float green =0.0f; float blue =0.0f; GL gl = drawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT); gl.glPointSize(5.0f); for (int i=0; i<50; i++) ...{ red -= .09f; green -= .12f; blue -= .15f; if (red <0.15) red =1.0f; if (green <0.15) green =1.0f; if (blue <0.15) blue =1.0f; gl.glColor3f(red, green, blue); gl.glBegin(GL.GL_POINTS); gl.glVertex2i(i*10, 150); gl.glEnd(); } } publicvoid reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) ...{} publicvoid displayChanged( GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged ) ...{} }