سؤال

أحاول تحقيق أداء أفضل لتطبيق Java SWT الخاص بي، واكتشفت للتو أنه من الممكن استخدام OpenGL في SWT.يبدو أن هناك أكثر من ربط Java لـ OpenGL.أي واحد تفضل؟

لاحظ أنني لم أستخدم OpenGL من قبل، وأن التطبيق يحتاج إلى العمل على أنظمة التشغيل Windows وLinux وMac OS X.

هل كانت مفيدة؟

المحلول

جوغل

يمكن اقتباس أسبابي من الموقع المرتبط مسبقًا:

يوفر JOGL وصولاً كاملاً إلى واجهات برمجة التطبيقات (APIs) في مواصفات OpenGL 2.0 بالإضافة إلى جميع ملحقات البائعين تقريبًا، ويتكامل مع مجموعات عناصر واجهة المستخدم AWT وSwing.

وأيضًا إذا كنت ترغب في الحصول على بعض المتعة في التعلم والتجول، يعالج هي طريقة ممتازة للبدء (تستخدم المعالجة أيضًا JOGL بالمناسبة...)

نصائح أخرى

أود أن أقترح التحقق من ذلك LWJGL, ، مكتبة ألعاب Java خفيفة الوزن.إنه يحتوي على روابط OpenGL، ولكنه يحتوي أيضًا على روابط OpenAL وبعض البرامج التعليمية الرائعة لتبدأ.

فقط ضع في اعتبارك أن Swing/SWT وOpenGL يُستخدمان بشكل عام لأشياء مختلفة تمامًا.قد ينتهي بك الأمر إلى الرغبة في استخدام مزيج من الاثنين معا.ما عليك سوى تجربة LWJGL ومعرفة مدى ملاءمتها لما تفعله.

ربما يكون JOGL هو الخيار الوحيد الذي يستحق النظر فيه.لاحظ أن هناك خيارين على الأقل لدمجه في تطبيق SWT.هناك GLCanvas الذي ينتمي إلى SWT وGLCanvas الذي ينتمي إلى AWT.الميزة الموجودة في SWT ليست كاملة ولا تتم صيانتها حقًا.من الأفضل استخدام AWT GLCanvas داخل حاوية SWT_AWT.بعض التعليمات البرمجية من مشروع حديث:

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 أفضل أداء وقابلية للنقل.لكن عليك أن تدرك أن تعلم JOGL، والذي هو في الأساس نفس تعلم OpenGL، ليس بالأمر السهل.

أنا شخصياً لست على علم بارتباطات Java لـ OpenGL بخلاف جوغل - أعتقد أن JOGL هو المعيار القياسي لـ Java OpenGL إلى حد كبير.

إنه يعمل في أنظمة التشغيل Windows وLinux وOS X، ولكن قد ترغب في قراءة الوثائق الرسمية للحصول على بعض الملاحظات حول مشكلات محددة في كل نظام أساسي.

ضع في اعتبارك أن نموذج OpenGL يختلف تمامًا عن نموذج Swing/AWT أو Java 2D API؛OpenGL ليس بديلاً مباشرًا لـ Swing.

لقد حالفنا الحظ كثيرًا في العمل باستخدام JOGL.الإصدار الجديد 2.0 موجود في http://jogamp.org/ (الإصدار "القديم" الأخير موجود في http://download.java.net/media/jogl/builds/archive/jsr-231-1.1.1a/).

بالنسبة لـ JOGL 2 مع SWT على وجه التحديد، لدي سلسلة من البرامج التعليمية بدءًا من http://wadeawalker.wordpress.com/2010/10/09/tutorial-a-cross-platform-workbench-program-using-java-opengl-and-Eclipse/ يوضح هذا بالضبط كيفية إنشاء تطبيقات JOGL SWT عبر الأنظمة الأساسية، كاملة مع الثنائيات الأصلية القابلة للتثبيت.

أو إذا كنت لا تريد استخدام Eclipse RCP، فإليك مثالًا أبسط يرسم مثلثًا واحدًا باستخدام JOGL 2 وSWT.ولبنائه، ضعه في مشروع باستخدام swt.jar (from http://www.Eclipse.org/swt/) وأحدث ملفات JOGL autobuild .jar و.dll (من http://jogamp.org/).المشكلة الوحيدة في هذا المثال البسيط هي أنه لن يكون مشتركًا بين الأنظمة الأساسية دون بعض المساعدة الإضافية - فأنت بحاجة إلى القدرة التي يوفرها لك Eclipse RCP لتجميع مجموعات متعددة من مكتبات الأنظمة الأساسية معًا في مشروع واحد.

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();        
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top