2008-09-15 20 views
16

Estoy tratando de obtener un mejor rendimiento para mi aplicación Java SWT, y descubrí que es posible usar OpenGL en SWT. Parece que hay más de un enlace de Java para OpenGL. ¿Cuál prefieres?¿Cuál es el mejor enlace de OpenGL para Java?

Tenga en cuenta que nunca he usado antes de OpenGL, y que la aplicación necesita para funcionar en Windows, Linux y Mac OS X.

Respuesta

9

JOGL

Mis razones pueden ser citados fuera de la página previamente vinculado:

JOGL proporciona acceso completo a las API en la especificación OpenGL 2.0, así como casi todas las extensiones de los proveedores, y se integra con el Conjuntos de widgets AWT y Swing.

Además, si usted quiere tener un poco de diversión y aprendizaje a hurgar, Processing es una excelente manera de empezar (Procesamiento también utiliza JOGL por cierto ...)

+0

2.0? jogl está muerto. – user697111

+3

JOGL proporciona acceso completo a las API en las especificaciones OpenGL 1.3 - 3.0, 3.1 - 3.3, ≥ 4.0, ES 1.x y ES 2.x, así como en casi todas las extensiones de proveedores. Se integra con los conjuntos de widgets AWT y Swing, así como con kits de herramientas de ventanas personalizadas que usan la API NativeWindow. Es parte de un conjunto de tecnologías de código abierto iniciado por Game Technology Group en Sun Microsystems. http://jogamp.org/jogl/www/ –

2

En lo personal, ni siquiera estoy al tanto de enlaces Java para OpenGL que no sea JOGL - - Creo que JOGL es prácticamente el estándar para Java OpenGL.

Funciona en Windows, Linux y OS X, pero es posible que desee leer la documentación oficial de algunas notas sobre problemas específicos en cada plataforma.

Tenga en cuenta que el paradigma OpenGL es bastante diferente de Swing/AWT o la API 2D de Java; OpenGL no reemplaza a Swing.

10

me gustaría sugerir retirar LWJGL, la LightWeight Java Game Library. Tiene enlaces OpenGL, pero también tiene enlaces OpenAL y algunos excelentes tutoriales para que comiences.

Solo tenga en cuenta que Swing/SWT y OpenGL se usan generalmente para cosas completamente diferentes. Puede terminar queriendo usar una combinación de ambos. Solo prueba LWJGL y observa qué tan bien encaja con lo que estás haciendo.

+0

JOGL 2 tiene un mejor soporte de SWT, AWT y Swing. Tiene un lienzo SWT pesado y un lienzo NEWT liviano. Este es probablemente uno de los puntos fuertes de JogAmp (JOGL, JOAL, JOCL), tiene una excelente interoperabilidad con otros kits de herramientas y es importante cuando utilizas Java en aplicaciones no gaming basadas en Eclipse RCP, Netbeans Platform o más API básicas. Se sabe que el soporte AWT del principal competidor de JogAmp no es tan bueno como debería ser, como se puede ver allí: http://lwjgl.org/forum/index.php?topic=4891.0 – gouessej

6

JOGL es probablemente la única opción que vale la pena considerar. Observe que hay al menos dos opciones para integrarlo en una aplicación SWT. Hay un GLCanvas que pertenece a SWT y un GLCanvas que pertenece a AWT. El que está en SWT no es una característica completa y realmente no se mantiene. Es mucho mejor usar AWT GLCanvas dentro de un contenedor SWT_AWT. Parte del código de un proyecto reciente:

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

LWJGL también "vale la pena considerarlo" (no sé sobre 2008, pero al menos ahora en 2012). Especialmente ahora que Oracle está haciendo quién sabe qué con todos los antiguos proyectos de Sun. Todo depende de los requisitos, por supuesto. –

+0

@shoosh: Completamente de acuerdo, esta ha sido mi experiencia también. – axel22

+0

Perce, le recuerdo que JOGL ha sido mantenido activamente por la comunidad JogAmp sin Oracle/Sun desde aproximadamente 2010. – gouessej

3

JOGL le dará un mejor rendimiento y portabilidad. Pero tenga en cuenta que aprender JOGL, que es esencialmente lo mismo que aprender OpenGL, no es fácil.

1

Hemos tenido mucha suerte en el trabajo utilizando JOGL. La nueva versión 2.0 está en http://jogamp.org/ (la última versión "anterior" está en http://download.java.net/media/jogl/builds/archive/jsr-231-1.1.1a/).

Para JOGL 2 con SWT específicamente, tengo una serie de tutoriales que comienzan en http://wadeawalker.wordpress.com/2010/10/09/tutorial-a-cross-platform-workbench-program-using-java-opengl-and-eclipse/ que demuestran exactamente cómo hacer aplicaciones multiplataforma JOGL SWT, completas con binarios nativos instalables.

O si no desea utilizar Eclipse RCP, aquí hay un ejemplo aún más simple que simplemente dibuja un triángulo con JOGL 2 y SWT. Para compilarlo, colóquelo en un proyecto con swt.jar (desde http://www.eclipse.org/swt/) y el último JOGL autobuild .jar y.archivos dll (desde http://jogamp.org/). El único problema con este ejemplo simple es que no será multiplataforma sin ayuda adicional: necesita la capacidad que Eclipse RCP le brinda para agrupar múltiples conjuntos de bibliotecas de plataforma en un solo proyecto.

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