在这篇文章里,摘录了《学习Java对于OpenGl的绑定》。作者吉恩戴维斯解释了如何开始用Java对于OpenGl的绑定开发图形增强的程序
|
然后出现了JOGL
|
GlueGen...几乎和JOGL一样酷? 你应该意识到,OpenGL是为C程序员而写的。这意味着Java想要利用它,必须要用到本机接口。不那么有趣的JNI(Java本机接口)必须用来进行此连接。OpenGL太大了,手写所有的连接太费时。想稍微做出一点复杂的程序,有许多特别出售的特性,OpenGL则保持改进,那意味着得有相应的变化来跟上OpenGL的步伐。简而言之,对于任何试着写与OpenGL保持同步,包含所有Java到本机的接口的代码的尝试,是非常困难的。 让我们进入JOGL家族看看。他们打算利用C头文件写一些代码来实现一切JNI做的事。他们管这个叫做GlueGen。GlueGen解析C头文件然后魔法般地创建出Java和JNI代码以便连接到本机库。这意味着OpenGL的升级可以迅速地在JOGL里体现。 Hello World! 我是一个很传统的人,所以当然我们将从“你好世界”程序开始。这个“你好世界”程序将检验我们的安装是否全部或者一部分安装正确。回忆一下安装JOGL有2个部分,分别是jar文件里的Java库以及其它库的本机代码。 以下是我们的程序: import net.java.games.jogl.*; public class HelloWorld { public static void main (String args[]) { try { System.loadLibrary("jogl"); System.out.println( "Hello World! (The native libraries are installed.)" ); GLCapabilities caps = new GLCapabilities(); System.out.println( "Hello JOGL! (The jar appears to be available.)" ); } catch (Exception e) { System.out.println(e); } } } 首先,这个程序测试了本机库和Java库是否已经安装正确了。只有当jogl.jar和本机库(名字诸如libjogl.jnilib或者jogl.dll)两者都安装好了的时候,JOGL才算是安装完全的。如果本机库不可用,程序会抛java.lang.UnsatisfiedLinkError例外。如果classpath里没有安装JAR,程序则根本编译都通不过。Javac编译器会报诸如此类的错“net.java.games.jogl包不存在”。当这个程序编译通过且运行起来没有异常的话,你可以继续学习JOGL了。 一个好的模板 当你对JOGL感到思维混乱的时候,让我们来继续看几个类,你可以把它们当成有用的模板来使用。我已经不止一次把它们当成模板用了。你可以随心所欲地使用它们。 这个模板由两个类组成。第一个是如下所示的SimpleJoglApp,第二个是在简短说明之后的SimpleGLEventListener。你必须输入两个类来编译模板。主程序如下: import java.awt.*; import java.awt.event.*; import javax.swing.*; import net.java.games.jogl.*; /** * This is a basic JOGL app. Feel free to * reuse this code or modify it. * 这是个基础的JOGL程序,你可以随意重用该代码或者修改它。 */ public class SimpleJoglApp extends JFrame { public static void main(String[] args) { final SimpleJoglApp app = new SimpleJoglApp(); // show what we've done //看一下我们做了什么 SwingUtilities.invokeLater ( new Runnable() { public void run() { app.setVisible(true); } } ); } public SimpleJoglApp() { //set the JFrame title //设置JFrame标题 super("Simple JOGL Application"); //kill the process when the JFrame is closed //当JFrame关闭的时候,结束进程 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //only three JOGL lines of code ... and here they are //只有三行JOGL代码 ... 如下 GLCapabilities glcaps = new GLCapabilities(); GLCanvas glcanvas = GLDrawableFactory.getFactory().createGLCanvas(glcaps); glcanvas.addGLEventListener(new SimpleGLEventListener()); //add the GLCanvas just like we would any Component //像其它组件一样把GLCanvas加入 getContentPane().add(glcanvas, BorderLayout.CENTER); setSize(500, 300); //center the JFrame on the screen //使JFrame显示在屏幕中央 centerWindow(this); } public void 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 ); } } 代码就是这些。让我们把注意力集中在第一个类中与JOGL相关的三行代码上。首先: 这决定了我们的JOGL库和JVM可以使用哪些OpenGL/图形特色。 接着: GLCanvas glcanvas = GLDrawableFactory.getFactory().createGLCanvas(glcaps);
现在我们有GLDrawableFactory了。所以我们用createGLCanvas()方法来创建了可以往上画画的GLCanvas。如果我们不需要AWT组件,而是Swing组件,则可以用createGLJPanel()方法。 import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; /** * For our purposes only two of the * GLEventListeners matter. Those would * be init() and display(). * 为了达到我们的目的,GLEventListener中只有两个方法有用。 * 它们是init()和display()。 */ public class SimpleGLEventListener implements GLEventListener { /** * Take care of initialization here. * 注意这里的初始化。 */ public void init(GLDrawable drawable) { } /** * Take care of drawing here. * 注意这里的绘图。 */ public void display(GLDrawable 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)大小改变时被调用。 * 我们不需要它,但你可能最后会用到——虽然现在并不需要。 */ public void reshape( GLDrawable 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. * 当程序运行时显示深度被改变的时候此方法被调用。 * 现在这种事发生得不多,除非程序里面触发此事。 */ public void displayChanged( GLDrawable drawable, boolean modeChanged, boolean deviceChanged ) {} }
import java.awt.*; import java.awt.event.*; import javax.swing.*; import net.java.games.jogl.*; /** * This is a basic JOGL app. Feel free to * reuse this code or modify it. * 这是个基础的JOGL程序,你可以随意重用该代码或者修改它。 */ public class SecondJoglApp extends JFrame { public static void main(String[] args) { final SecondJoglApp app = new SecondJoglApp(); //show what we've done //看一下我们做了什么 SwingUtilities.invokeLater ( new Runnable() { public void run() { app.setVisible(true); } } ); } public SecondJoglApp() { //set the JFrame title //设置JFrame标题 super("Second JOGL Application"); //kill the process when the JFrame is closed //当JFrame关闭的时候,结束进程 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //only three JOGL lines of code ... and here they are //只有三行JOGL代码 ... 如下 GLCapabilities glcaps = new GLCapabilities(); GLCanvas glcanvas = GLDrawableFactory.getFactory().createGLCanvas(glcaps); glcanvas.addGLEventListener(new SecondGLEventListener()); //add the GLCanvas just like we would any Component //像其它组件一样把GLCanvas加入 getContentPane().add(glcanvas, BorderLayout.CENTER); setSize(500, 300); //center the JFrame on the screen //使JFrame显示在屏幕中央 centerWindow(this); } public void 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 ); } }
import net.java.games.jogl.*; /** * For our purposes only two of the GLEventListeners matter. * Those would be init() and display(). * 为了达到我们的目的,GLEventListener中只有两个方法有用。 * 它们是init()和display()。 */ public class SecondGLEventListener implements GLEventListener { /** * Take care of initialization here. * 注意这里的初始化。 */ public void init(GLDrawable gld) { GL gl = gld.getGL(); GLU glu = gld.getGLU(); 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.0, 0.0, 300.0); } /** * Take care of drawing here. * 注意这里的绘图。 */ public void display(GLDrawable 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(); } } public void reshape( GLDrawable drawable, int x, int y, int width, int height ) {} public void displayChanged( GLDrawable drawable, boolean modeChanged, boolean deviceChanged ) {} } |
以上就是我们第一个有趣的JOGL程序。下图是输出,有很多好看的颜色。 |