Qual é a melhor ligação Java OpenGL?[fechado]
-
09-06-2019 - |
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.
Solução
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();
}
}