Domanda

Sto cercando di ottenere prestazioni migliori per la mia applicazione Java SWT e ho appena scoperto che è possibile utilizzare OpenGL in SWT.Sembra che ci sia più di un collegamento Java per OpenGL.Quale preferisci?

Tieni presente che non ho mai utilizzato OpenGL prima e che l'applicazione deve funzionare su Windows, Linux e Mac OS X.

È stato utile?

Soluzione

JOGL

Le mie ragioni possono essere citate dal sito precedentemente collegato:

JOGL fornisce accesso completo alle API nella specifica OpenGL 2.0 nonché a quasi tutte le estensioni dei fornitori e si integra con i set di widget AWT e Swing.

Inoltre, se vuoi divertirti imparando e curiosando, in lavorazione è un ottimo modo per iniziare (Processing utilizza anche JOGL tra l'altro...)

Altri suggerimenti

Suggerirei di dare un'occhiata LWJGL, la libreria di giochi Java leggera.Ha collegamenti OpenGL, ma ha anche collegamenti OpenAL e alcuni ottimi tutorial per iniziare.

Tieni presente che Swing/SWT e OpenGL sono generalmente utilizzati per cose completamente diverse.Potresti finire per voler utilizzare una combinazione di entrambi.Prova semplicemente LWJGL e vedi come si adatta a quello che stai facendo.

JOGL è probabilmente l'unica opzione che vale la pena considerare.Si noti che esistono almeno due opzioni per integrarlo in un'applicazione SWT.C'è un GLCanvas che appartiene a SWT e un GLCanvas che appartiene ad AWT.Quello in SWT non è completo di funzionalità e non è realmente mantenuto.È molto meglio utilizzare AWT GLCanvas all'interno di un contenitore SWT_AWT.Alcuni codici da un progetto recente:

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

JOGL ti offrirà le migliori prestazioni e portabilità.Ma tieni presente che imparare JOGL, che è essenzialmente la stessa cosa che imparare OpenGL, non è facile.

Personalmente, non sono nemmeno a conoscenza di collegamenti Java per OpenGL diversi da JOGL -- Penso che JOGL sia praticamente lo standard per Java OpenGL.

Funziona su Windows, Linux e OS X, ma potresti voler leggere la documentazione ufficiale per alcune note su problemi specifici in ciascuna piattaforma.

Tieni presente che il paradigma OpenGL è abbastanza diverso da Swing/AWT o dall'API Java 2D;OpenGL non è un sostituto immediato di Swing.

Abbiamo avuto molta fortuna nel lavorare usando JOGL.La nuova versione 2.0 è a http://jogamp.org/ (l'ultima versione "vecchia" è a http://download.java.net/media/jogl/builds/archive/jsr-231-1.1.1a/).

Per JOGL 2 con SWT in particolare, ho una serie di tutorial a partire da http://wadeawalker.wordpress.com/2010/10/09/tutorial-a-cross-platform-workbench-program-using-java-opengl-and-eclipse/ che dimostra esattamente come realizzare applicazioni JOGL SWT multipiattaforma, complete di binari nativi installabili.

Oppure, se non vuoi utilizzare Eclipse RCP, ecco un esempio ancora più semplice che disegna solo un triangolo con JOGL 2 e SWT.Per costruirlo, inseriscilo in un progetto con swt.jar (from http://www.eclipse.org/swt/) e gli ultimi file JOGL autobuild .jar e .dll (da http://jogamp.org/).L'unico problema con questo semplice esempio è che non sarà multipiattaforma senza un aiuto aggiuntivo: è necessaria la capacità che Eclipse RCP ti offre di raggruppare più set di librerie di piattaforme in un unico progetto.

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();        
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top