Question

J'essaie d'obtenir de meilleures performances pour mon application Java SWT et je viens de découvrir qu'il est possible d'utiliser OpenGL dans SWT. Il semble qu'il existe plus d'une liaison Java pour OpenGL. Lequel préférez-vous?

Notez que je n’avais jamais utilisé OpenGL auparavant et que l’application doit fonctionner sous Windows, Linux et Mac OS X.

Était-ce utile?

La solution

JOGL

Mes raisons peuvent être citées sur le site précédemment lié:

  

JOGL fournit un accès complet aux API de la spécification OpenGL 2.0 ainsi qu’à la quasi-totalité des extensions de fournisseurs et s’intègre aux ensembles de widgets AWT et Swing.

Si vous souhaitez également apprendre à vous amuser, le traiter est un excellent moyen. pour commencer (le traitement utilise également JOGL btw ...)

Autres conseils

Je suggérerais de consulter la LWJGL , la bibliothèque de jeux Java LightWeight. Il possède des liaisons OpenGL, mais également des liaisons OpenAL et de très bons tutoriels pour vous aider à démarrer.

N'oubliez pas que Swing / SWT et OpenGL sont généralement utilisés pour des choses complètement différentes. Vous voudrez peut-être utiliser une combinaison des deux. Essayez simplement LWJGL et voyez si cela cadre bien avec ce que vous faites.

JOGL est probablement la seule option à considérer. Notez qu’il existe au moins deux options pour l’intégrer dans une application SWT. Il existe un GLCanvas appartenant à SWT et un GLCanvas appartenant à AWT. Celui de SWT n’est pas complet et n’est pas vraiment maintenu. Il est préférable d'utiliser AWT GLCanvas dans un conteneur SWT_AWT. Quelques codes d'un projet récent:

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 vous donnera les meilleures performances et la plus grande portabilité. Sachez toutefois que l’apprentissage de JOGL, qui est essentiellement identique à celui d’apprentissage d’OpenGL, n’est pas facile.

Personnellement, je ne connais même pas de liaisons Java pour OpenGL autres que JOGL - Je pense que JOGL est à peu près la norme pour Java OpenGL.

Cela fonctionne sous Windows, Linux et OS X, mais vous voudrez peut-être lire la documentation officielle pour des notes sur des problèmes spécifiques à chaque plate-forme.

N'oubliez pas que le paradigme OpenGL est assez différent de Swing / AWT ou de l'API 2D 2D; OpenGL ne remplace pas directement Swing.

Nous avons eu beaucoup de chance au travail avec JOGL. La nouvelle version 2.0 se trouve à la http://jogamp.org/ (la dernière "ancienne" version est à http://download.java.net/media/jogl/ builds / archive / jsr-231-1.1.1a / ).

Pour JOGL 2 avec SWT en particulier, une série de tutoriels commence à http://wadeawalker.wordpress.com/2010/10/09/tutorial-a-cross-platform-workbench-program-using- java-opengl-and-eclipse / qui montre exactement comment créer des applications JOGL SWT multiplates-formes avec des fichiers binaires natifs installables.

Ou si vous ne souhaitez pas utiliser Eclipse RCP, voici un exemple encore plus simple qui dessine un triangle avec JOGL 2 et SWT. Pour le construire, placez-le dans un projet avec swt.jar (à partir de http://www.eclipse.org/swt / ) et les derniers fichiers .jar et .dll de JOGL autobuild (tirés de http://jogamp.org/). Le seul problème de cet exemple simple est qu'il ne sera pas multi-plateforme sans aide supplémentaire - vous devez avoir la possibilité qu'Eclipse RCP vous donne de regrouper plusieurs ensembles de bibliothèques de plates-formes dans un même projet.

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();        
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top