Pergunta

Estou tentando obter melhor desempenho para meu aplicativo Java SWT e acabei de descobrir que é possível usar OpenGL no SWT.Parece que há mais de uma ligação Java para OpenGL.Qual você prefere?

Observe que nunca usei OpenGL antes e que o aplicativo precisa funcionar em Windows, Linux e Mac OS X.

Foi útil?

Solução

JOGL

Meus motivos podem ser citados no site vinculado anteriormente:

JOGL fornece acesso total às APIs na especificação OpenGL 2.0, bem como a quase todas as extensões de fornecedores, e integra-se aos conjuntos de widgets AWT e Swing.

Além disso, se você quiser se divertir aprendendo e bisbilhotando, Em processamento é uma excelente maneira de começar (o processamento também usa JOGL, aliás...)

Outras dicas

Eu sugiro verificar LWJGL, a biblioteca de jogos Java LightWeight.Possui ligações OpenGL, mas também possui ligações OpenAL e alguns ótimos tutoriais para você começar.

Apenas tenha em mente que Swing/SWT e OpenGL geralmente são usados ​​para coisas totalmente diferentes.Você pode acabar querendo usar uma combinação de ambos.Experimente o LWJGL e veja se ele se adapta ao que você está fazendo.

JOGL é provavelmente a única opção que vale a pena considerar.Observe que existem pelo menos duas opções para integrá-lo a uma aplicação SWT.Existe um GLCanvas que pertence ao SWT e um GLCanvas que pertence ao AWT.Aquele no SWT não possui recursos completos e não é realmente mantido.É muito melhor usar o AWT GLCanvas dentro de um contêiner SWT_AWT.Algum código de um projeto 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 lhe dará melhor desempenho e portabilidade.Mas esteja ciente de que aprender JOGL, que é essencialmente o mesmo que aprender OpenGL, não é fácil.

Pessoalmente, nem conheço outras ligações Java para OpenGL além de JOGL - Acho que JOGL é praticamente o padrão para Java OpenGL.

Funciona em Windows, Linux e OS X, mas você pode querer ler a documentação oficial para obter algumas notas sobre problemas específicos em cada plataforma.

Tenha em mente que o paradigma OpenGL é bem diferente do Swing/AWT ou da API Java 2D;OpenGL não é um substituto imediato para Swing.

Tivemos muita sorte no trabalho usando JOGL.A nova versão 2.0 está em http://jogamp.org/ (a última versão "antiga" está em http://download.java.net/media/jogl/builds/archive/jsr-231-1.1.1a/).

Especificamente para JOGL 2 com SWT, tenho uma série de tutoriais começando em http://wadeawalker.wordpress.com/2010/10/09/tutorial-a-cross-platform-workbench-program-using-java-opengl-and-eclipse/ que demonstra exatamente como criar aplicativos JOGL SWT multiplataforma, completos com binários nativos instaláveis.

Ou se você não quiser usar o Eclipse RCP, aqui está um exemplo ainda mais simples que apenas desenha um triângulo com JOGL 2 e SWT.Para construí-lo, coloque-o em um projeto com swt.jar (de http://www.eclipse.org/swt/) e os arquivos .jar e .dll do JOGL autobuild mais recentes (de http://jogamp.org/).O único problema com este exemplo simples é que ele não será multiplataforma sem alguma ajuda extra - você precisa da capacidade que o Eclipse RCP oferece para agrupar vários conjuntos de bibliotecas de plataforma em um projeto.

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();        
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top