【问题标题】:What is the best OpenGL java binding? [closed]什么是最好的 OpenGL java 绑定? [关闭]
【发布时间】:2010-09-09 03:34:42
【问题描述】:

我正在尝试为我的 Java SWT 应用程序实现更好的性能,我刚刚发现可以在 SWT 中使用 OpenGL。似乎有不止一种用于 OpenGL 的 Java 绑定。你更喜欢哪一个?

请注意,我以前从未使用过 OpenGL,并且该应用程序需要在 Windows、Linux 和 Mac OS X 上运行。

【问题讨论】:

    标签: java user-interface opengl performance swt


    【解决方案1】:

    我建议查看 LWJGL,这是 LightWeight Java 游戏库。它有 OpenGL 绑定,但也有 OpenAL 绑定和一些很棒的教程来帮助您入门。

    请记住,Swing/SWT 和 OpenGL 通常用于完全不同的事情。您可能最终想要使用两者的组合。试一试 LWJGL,看看它与您正在做的事情的契合度。

    【讨论】:

    • JOGL 2 对 SWT、AWT 和 Swing 有更好的支持。它既有重量级的 SWT 画布,也有轻量级的 NEWT 画布。这可能是 JogAmp(JOGL、JOAL、JOCL)的优势之一,它与其他工具包具有出色的互操作性,当您在基于 Eclipse RCP、Netbeans 平台或更基本 API 的非游戏应用程序中使用 Java 时,这很重要。众所周知,JogAmp 的主要竞争对手的 AWT 支持不如您所见的那么好:lwjgl.org/forum/index.php?topic=4891.0
    【解决方案2】:

    JOGL

    我的理由可以引用之前链接的网站:

    JOGL 提供对 OpenGL 2.0 规范中的 API 以及几乎所有供应商扩展的完全访问,并与 AWT 和 Swing 小部件集集成。

    此外,如果您想获得一些有趣的学习和探索,Processing 是一个很好的开始方式(处理也使用 JOGL 顺便说一句...)

    【讨论】:

    • JOGL 提供对 OpenGL 1.3 - 3.0、3.1 - 3.3、≥ 4.0、ES 1.x 和 ES 2.x 规范以及几乎所有供应商扩展的 API 的完全访问权限。它与 AWT 和 Swing 小部件集以及使用 NativeWindow API 的自定义窗口工具包集成。它是 Sun Microsystems 的 Game Technology Group 发起的一套开源技术的一部分。 jogamp.org/jogl/www
    【解决方案3】:

    JOGL 可能是唯一值得考虑的选择。 请注意,至少有两个选项可以将其集成到 SWT 应用程序中。有一个属于 SWT 的 GLCanvas 和一个属于 AWT 的 GLCanvas。 SWT 中的那个不是功能完整的,也没有真正维护。在 SWT_AWT 容器中使用 AWT GLCanvas 要好得多。 最近一个项目的一些代码:

    import org.eclipse.swt.*;
    import org.eclipse.swt.layout.*;
    import org.eclipse.swt.widgets.*;
    
    import javax.media.opengl.*;
    import javax.media.opengl.glu.*;
    
    import org.eclipse.swt.awt.SWT_AWT;
    import org.eclipse.swt.events.*;
    
    public class Main implements GLEventListener
    {
        public static void main(String[] args) 
        {
            Display display = new Display();
        Main main = new Main();
        main.runMain(display);
        display.dispose();
    }
    
    void runMain(Display display)
    {
        final Shell shell = new Shell(display);
        shell.setText("Q*bert 3D - OpenGL Exercise");
        GridLayout gridLayout = new GridLayout();
        gridLayout.marginHeight = 0;
        gridLayout.marginWidth = 0;
    
        shell.setLayout(gridLayout);
    
        // this allows us to set particular properties for the GLCanvas
        GLCapabilities glCapabilities = new GLCapabilities();
    
        glCapabilities.setDoubleBuffered(true);
        glCapabilities.setHardwareAccelerated(true);
    
        // instantiate the canvas
        final GLCanvas canvas = new GLCanvas(glCapabilities);
    
        // we can't use the default Composite because using the AWT bridge
        // requires that it have the property of SWT.EMBEDDED
        Composite composite = new Composite(shell, SWT.EMBEDDED);
        GridData ld = new GridData(GridData.FILL_BOTH);
        composite.setLayoutData(ld);
    
        // set the internal layout so our canvas fills the whole control
        FillLayout clayout = new FillLayout();
        composite.setLayout(clayout);
    
        // create the special frame bridge to AWT
        java.awt.Frame glFrame = SWT_AWT.new_Frame(composite);
        // we need the listener so we get the GL events
        canvas.addGLEventListener(this);
    
        // finally, add our canvas as a child of the frame
        glFrame.add(canvas);
    
        // show it all
        shell.open();
        // the event loop.
        while (!shell.isDisposed ()) {
            if (!display.readAndDispatch ()) display.sleep ();
        }
    }
    

    【讨论】:

    • LWJGL 也“值得考虑”(不知道 2008 年,但至少现在是 2012 年)。尤其是现在甲骨文正在对所有旧的 Sun 项目做什么,谁知道呢。当然,一切都取决于要求。
    • @shoosh:完全同意,这也是我的经验。
    • Perce,我提醒您,自 2010 年左右以来,JogAmp 社区一直在积极维护 JOGL,而没有使用 Oracle/Sun。
    【解决方案4】:

    JOGL 将为您提供最佳性能和便携性。但要注意,学习 JOGL 与学习 OpenGL 本质上是一样的,并不容易。

    【讨论】:

      【解决方案5】:

      就我个人而言,除了JOGL 之外,我什至不知道 OpenGL 的 Java 绑定——我认为 JOGL 几乎是 Java OpenGL 的标准。

      它适用于 Windows、Linux 和 OS X,但您可能需要阅读官方文档以了解有关每个平台中特定问题的一些说明。

      请记住,OpenGL 范式与 Swing/AWT 或 Java 2D API 完全不同; OpenGL 不是 Swing 的直接替代品。

      【讨论】:

        【解决方案6】:

        我们在使用 JOGL 的工作中获得了很多运气。新的 2.0 版本位于 http://jogamp.org/(最后一个“旧”版本位于 http://download.java.net/media/jogl/builds/archive/jsr-231-1.1.1a/)。

        对于带有 SWT 的 JOGL 2,我有一系列教程,从 http://wadeawalker.wordpress.com/2010/10/09/tutorial-a-cross-platform-workbench-program-using-java-opengl-and-eclipse/ 开始,准确地演示了如何制作跨平台的 JOGL SWT 应用程序,以及可安装的本机二进制文件。

        或者,如果您不想使用 Eclipse RCP,这里有一个更简单的示例,它只使用 JOGL 2 和 SWT 绘制一个三角形。要构建它,请将其放入带有 swt.jar(来自 http://www.eclipse.org/swt/)和最新的 JOGL 自动构建 .jar 和 .dll 文件(来自 http://jogamp.org/)的项目中。这个简单示例的唯一问题是,如果没有一些额外的帮助,它就不能跨平台——您需要 Eclipse RCP 提供的将多组平台库捆绑到一个项目中的能力。

        package name.wadewalker.onetriangle;
        
        import org.eclipse.swt.SWT;
        import org.eclipse.swt.events.PaintEvent;
        import org.eclipse.swt.events.PaintListener;
        import org.eclipse.swt.graphics.Rectangle;
        import org.eclipse.swt.layout.FillLayout;
        import org.eclipse.swt.opengl.GLCanvas;
        import org.eclipse.swt.opengl.GLData;
        import org.eclipse.swt.widgets.Composite;
        import org.eclipse.swt.widgets.Display;
        import org.eclipse.swt.widgets.Event;
        import org.eclipse.swt.widgets.Listener;
        import org.eclipse.swt.widgets.Shell;
        
        import javax.media.opengl.GL;
        import javax.media.opengl.GLProfile;
        import javax.media.opengl.GL2;
        import javax.media.opengl.GLContext;
        import javax.media.opengl.GLDrawableFactory;
        import javax.media.opengl.glu.GLU;
        
        public class OneTriangle {
        
            public static void main(String [] args) {
                GLProfile.initSingleton( true );
        
                GLProfile glprofile = GLProfile.get( GLProfile.GL2 );
        
                Display display = new Display();
                Shell shell = new Shell( display );
                shell.setLayout( new FillLayout() );
                Composite composite = new Composite( shell, SWT.NONE );
                composite.setLayout( new FillLayout() );
        
                GLData gldata = new GLData();
                gldata.doubleBuffer = true;
                // need SWT.NO_BACKGROUND to prevent SWT from clearing the window
                // at the wrong times (we use glClear for this instead)
                final GLCanvas glcanvas = new GLCanvas( composite, SWT.NO_BACKGROUND, gldata );
                glcanvas.setCurrent();
                final GLContext glcontext = GLDrawableFactory.getFactory( glprofile ).createExternalGLContext();
        
                // fix the viewport when the user resizes the window
                glcanvas.addListener( SWT.Resize, new Listener() {
                    public void handleEvent(Event event) {
                        setup( glcanvas, glcontext );
                    }
                });
        
                // draw the triangle when the OS tells us that any part of the window needs drawing
                glcanvas.addPaintListener( new PaintListener() {
                    public void paintControl( PaintEvent paintevent ) {
                        render( glcanvas, glcontext );
                    }
                });
        
                shell.setText( "OneTriangle" );
                shell.setSize( 640, 480 );
                shell.open();
        
                while( !shell.isDisposed() ) {
                    if( !display.readAndDispatch() )
                        display.sleep();
                }
        
                glcanvas.dispose();
                display.dispose();
            }
        
            private static void setup( GLCanvas glcanvas, GLContext glcontext ) {
                Rectangle rectangle = glcanvas.getClientArea();
        
                glcanvas.setCurrent();
                glcontext.makeCurrent();
        
                GL2 gl = glcontext.getGL().getGL2();
                gl.glMatrixMode( GL2.GL_PROJECTION );
                gl.glLoadIdentity();
        
                // coordinate system origin at lower left with width and height same as the window
                GLU glu = new GLU();
                glu.gluOrtho2D( 0.0f, rectangle.width, 0.0f, rectangle.height );
        
                gl.glMatrixMode( GL2.GL_MODELVIEW );
                gl.glLoadIdentity();
        
                gl.glViewport( 0, 0, rectangle.width, rectangle.height );
                glcontext.release();        
            }
        
            private static void render( GLCanvas glcanvas, GLContext glcontext ) {
                Rectangle rectangle = glcanvas.getClientArea();
        
                glcanvas.setCurrent();
                glcontext.makeCurrent();
        
                GL2 gl = glcontext.getGL().getGL2();
                gl.glClear( GL.GL_COLOR_BUFFER_BIT );
        
                // draw a triangle filling the window
                gl.glLoadIdentity();
                gl.glBegin( GL.GL_TRIANGLES );
                gl.glColor3f( 1, 0, 0 );
                gl.glVertex2f( 0, 0 );
                gl.glColor3f( 0, 1, 0 );
                gl.glVertex2f( rectangle.width, 0 );
                gl.glColor3f( 0, 0, 1 );
                gl.glVertex2f( rectangle.width / 2, rectangle.height );
                gl.glEnd();
        
                glcanvas.swapBuffers();
                glcontext.release();        
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2011-03-08
          • 2010-09-06
          • 2010-09-15
          • 2011-01-04
          • 2010-10-04
          • 2010-09-21
          • 2010-09-13
          • 2010-09-15
          • 2011-06-29
          相关资源
          最近更新 更多