2008-09-15 100 views
16

我正在嘗試爲我的Java SWT應用程序實現更好的性能,並且我發現可以在SWT中使用OpenGL。看起來OpenGL有不止一個Java綁定。你更傾向哪個?什麼是最好的OpenGL java綁定?

注意,我從來沒有使用過的OpenGL,並且該應用程序需要工作在Windows,Linux和Mac OS X.

回答

9

JOGL

我的理由可以被引用過以前鏈接的網站:

JOGL提供了OpenGL 2.0規範的完全訪問權限的API,以及幾乎所有廠商擴展,並與集成AWT和Swing小部件集。

另外如果你想有一些樂趣的學習和閒逛,Processing是開始一個很好的方式(處理也使用JOGL BTW ...)

+0

2.0?喬吉爾已經死了。 – user697111 2011-04-27 01:48:52

+3

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發起的一套開源技術的一部分。 http://jogamp.org/jogl/www/ – 2011-08-04 19:29:18

2

個人而言,我甚至不知道Java綁定的OpenGL以外JOGL的 - - 我認爲JOGL幾乎是Java OpenGL的標準。

它適用於Windows,Linux和OS X,但您可能需要閱讀官方文檔以獲取有關每個平臺中特定問題的注意事項。請注意,OpenGL範例與Swing/AWT或Java 2D API完全不同;請注意,OpenGL範例與Swing/AWT或Java 2D API完全不同;請注意,OpenGL範例與Swing/AWT或Java 2D API完全不同。 OpenGL不是Swing的直接替代品。

10

我建議你檢查出LWJGL,輕量級Java遊戲庫。它有OpenGL綁定,但它也有OpenAL綁定和一些很棒的教程來幫助你入門。

請記住Swing/SWT和OpenGL通常用於完全不同的事情。你可能最終想要使用兩者的組合。只要試試LWJGL,看看它適合你在做什麼。

+0

JOGL 2對SWT,AWT和Swing有更好的支持。它有一個重量級的SWT畫布和一個輕量級的NEWT畫布。這可能是JogAmp(JOGL,JOAL,JOCL)的強項之一,它與其他工具包具有良好的互操作性,當您在基於Eclipse RCP,Netbeans Platform或更基本的API的非遊戲應用程序中使用Java時,它非常重要。 JogAmp主要競爭對手的AWT支持已知不如應有的那樣好,因爲你可以在那看到:http://lwjgl.org/forum/index.php?topic=4891.0 – gouessej 2014-03-29 13:00:30

6

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(); 
    } 
} 
3

JOGL會給你最好的性能和便攜性。但請注意,學習JOGL與學習OpenGL基本相同,並不容易。

1

我們在使用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 autobuild .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();   
    } 
}