Tutorial: A cross-platform graphical application using Java, OpenGL, and Eclipse

Update on 6/24/2017: I updated the GitHub project to launch correctly on Eclipse Neon 3. Many times when they update Eclipse, it changes the dependencies a project like this needs, which means we have to regenerate the Tutorial.product file to make it launch properly again.

To run the tutorial:

This runs the fully-developed tutorial, not just the simple donut below, but you can always paste the donut code into it if you like 🙂 Enjoy!

Update on 6/6/2015: This tutorial’s gotten a bit out of date with changes to JOGL and Eclipse in the last couple of years. The quickest way to get set up now is to just get my two projects from GitHub and import them into an empty Eclipse workspace:

https://github.com/WadeWalker/com.jogamp.jogl
https://github.com/WadeWalker/name.wadewalker.tutorial

This will give you a working RCP app without creating fragment projects like I describe below. Then you can hack on the tutorial app or create your own by following the latter half of the tutorial 🙂

=================================================================

Hi! My name’s Wade Walker. I’m an engineer and wanna-be scientist.

And you may call me “Interstitius”. I am something of a Renaissance-being, but my current occupation is penning the headings between these paragraphs.

Yeah, that doesn’t come across weird at all! But this guy comes highly recommended, so I figured I’d give him a try. What’s with the name, anyway?

It is a Latinate nom de plume, of course. I thought it dashing and flamboyant, much like myself.

Um, OK sure. Don’t ask questions you don’t want answered, et cetera. Anyway moving on!

At my day job, I write engineering apps that help chip designers make the chips that go into all your iStuff. But by night, and also on weekends, I write scientific apps as a hobby. And before anyone asks: no, I don’t live in my mom’s basement. Trust me, I’m perfectly normal. Except for writing science apps.

I’m gonna write a set of tutorials that walk you through creating a cross-platform graphical app using Java, OpenGL, and the Eclipse Rich Client Platform (“Eclipse RCP” for short). There are lots of other ways to do this, like with C++ and Qt, but I’m lazy and I figured I’d stick with what I know.

What do I get out of this? Glad you asked!

No one has asked anything as yet.

Dude, that’s just for color. Not supposed to be literal. Anyway, what I get out of tutorializing is this: I’m in the process of translating my hobby science app from C# and DirectX to Java and OpenGL. So I figured I might as well write up how I do it, and maybe help out some other folks in the process.

In this first tutorial, I’ll make a bare-bones app that draws a rotating 3-D demo object in a window using Java OpenGL (JOGL).

A brief description of the intended audience of this tutorial

Nice heading, I-dog! Just keep ‘em punchy like that and you’ll do great.

I’m aiming these tutorials at people who want to write cross-platform graphical “workbench” apps, the kind where users create some kind of project and edit it interactively using 3D hardware-accelerated graphics. Apps like this are common in the sciences, in engineering, and in the graphic arts.

You should be able to do these tutorials if you’ve got a bit of software dev experience, but you don’t need any prior exposure to Java, Eclipse, or OpenGL. I’ll give you working code for each tutorial that you can adapt and use for whatever you want. Then you can gradually figure out how it works as you customize it.

Java, Eclipse, and OpenGL are all super-deep neck-beard topics that take years of study to master, so don’t feel like you need to totally comprehend every bit of these tutorials the first time you see them. My main point in putting them up here is to give you working starting points for your own stuff and to get you past some common roadblocks, not to instantly transmute you into a super-genius like me.

Quick pro tip for any eager beavers out there: If you already know how to set up an Eclipse workspace and just want to see the money shot, here’s a zip file of the JOGL projects, and here’s another zip file for the tutorial project. Just change the file names to end in “.zip” instead of “-zip-not-a.doc”, unzip them, import them into Eclipse, and go nuts!

Now, let’s do this!

Put “Java” and the “Eclipse development environment” in order

If you don’t already have it, download and install the Standard Edition of the latest Java Development Kit (the Java SE JDK) from here. When I downloaded it, the latest version was JDK 7 update 4. You’ll have to pick the platform you’re running on, too. I’m running Windows 7 64-bit, so I picked the “Windows x64” platform.

Note! A JDK isn’t the same as a Java Runtime Environment (JRE) or Java browser plug-in that you may already have installed. If you’re not sure, check your installed programs to make sure you really have the JDK and not something else.

Further note! If you’re running on Mac OS X, you may already have a Java JDK installed at /System/Library/Java/JavaVirtualMachines/1.6.0.jdk, since it used to ship with the operating system. If not, you can install Oracle’s JDK 7 from here. Or if you don’t want to try JDK 7 on OS X yet, you can install Apple’s JDK 6 as documented here. Just be aware that if you want this tutorial to build on more than one platform without changing any Eclipse settings, it’s best to have the same version of the JDK installed on all your platforms.

After your JDK is set, download and install “Eclipse for RCP and RAP Developers” from here. When I downloaded it, the latest version was 3.7.2, nicknamed “Indigo” because of the obvious similarity between “a dye-producing plant” and “a software development environment”. I downloaded the Windows 64-bit version of this too. To run Eclipse, you just unzip it into any directory and double-click on “eclipse.exe”.

The first time you run Eclipse, it’ll show you the world’s most unhelpful welcome page. Click the “Workbench” button on the right to go past it.

Then Eclipse will ask you what “workspace” to open. Set this to a directory where you want to create your new projects for this tutorial, then click “OK”. You can switch between workspaces or create new ones later on by selecting “File > Switch Workspace” from the main menu.

Here’s what your new empty workspace should look like now.

Eclipse is a great sprawling beast, baroque but hyper-useful, and I can’t even try to explain everything about it here. I’ll just keep to the minimum that we need to make this tutorial work, and you can pick up the rest as you need it.

Obtain “Java OpenGL”, or “JOGL” as it is commonly known

Um, I-man? You don’t have to scare-quote all the tech words. I think our audience can figure it out.

My apologies.

No biggie, just trying to keep it casual up in here. Java OpenGL, or yes, “JOGL” as it’s known to those of us in the know, such as myself, is maintained by the super-programmers at JogAmp. So grab the latest gluegen and JOGL archive files from here. I got five .7z files from gluegen-b547-2012-04-19_20-39-21 and five from jogl-b736-2012-04-19_20-43-43, which were the latest builds at the time of this writing.

  • gluegen-2.0-b547-20120419-linux-amd64.7z
  • gluegen-2.0-b547-20120419-linux-i586.7z
  • gluegen-2.0-b547-20120419-macosx-universal.7z
  • gluegen-2.0-b547-20120419-windows-amd64.7z
  • gluegen-2.0-b547-20120419-windows-i586.7z

 

 

  • jogl-2.0-b736-20120419-linux-amd64.7z
  • jogl-2.0-b736-20120419-linux-i586.7z
  • jogl-2.0-b736-20120419-macosx-universal.7z
  • jogl-2.0-b736-20120419-windows-amd64.7z
  • jogl-2.0-b736-20120419-windows-i586.7z

 

Since I develop on 64-bit Windows 7, I only need gluegen-2.0-b547-20120419-windows-amd64.7z and jogl-2.0-b736-20120419-windows-amd64.7z to run on my main computer, but I got all ten so I can make this project multi-platform. Unzip these files somewhere convenient. To unzip .7z files, I recommend 7-Zip on Windows and Linux, and Keka on Mac OS X.

Create JOGL projects within Eclipse

To use JOGL from an Eclipse RCP project, we have to repackage it a bit. JOGL is made of two types of files: JAR files that are common to all platforms, and library files (.dll files on Windows, .so files on Linux, and .jnilib or .dylib files on Mac OS X) that are specific to each platform you want your program to run on. We’ll put the JOGL JARs in an Eclipse plug-in project, and the JOGL library files in separate Eclipse plug-in fragment projects. If you’re not familiar with Eclipse don’t worry about what the different Eclipse project types mean right now. This setup is just a good way for all the platforms’ libraries to live together without anything blowing up.

First we create a project to hold the JAR files. Select “File > New > Project…” from the Eclipse main menu to bring up the “New Project” wizard. Open “Plug-in Development”, select “Plug-in from Existing JAR Archives”, and click “Next”.

Click “Add External…”, and in the “Open” dialog that pops up, navigate to the “jar” directory inside an unzipped gluegen archive, select “gluegen-rt.jar” and click “Open”. Then do the same thing for the “jogl.all.jar” file in the “jar” directory of an unzipped JOGL archive. It doesn’t matter which platform’s archive you get these JARs from, since they’re all the same. Click “Next” when you’re done.

Enter “com.jogamp.jogl” as the project name. Set the plug-in version to “2.0.0”. Set the plug-in name to “JOGL” and the plug-in provider to “jogamp.org”. Uncheck “Unzip the JAR archives into the project”. Then click “Finish”, and Eclipse will magically create the project especially just for you.

Your finished project should look like this. The new “com.jogamp.jogl” directory is inside your workspace directory. The settings you typed in are stored in the “META-INF/MANIFEST.MF” and “build.properties” files that the wizard just created for you. The wizard also copied the gluegen and JOGL JAR files into your new project.

Next we create projects to hold the platform-specific libraries. Eclipse calls this type of project a “fragment” because it’s an “extra bit” of the earlier JAR project, and it holds stuff we only need on some platforms. Select “File > New > Project…” to bring up the “New Project” wizard again. Then open “Plug-in Development”, select “Fragment Project”, and click “Next”.

Enter “com.jogamp.jogl-windows-amd64” as the project name, then click “Next”.

Set the plug-in version to “2.0.0”, the name to “jogl-windows-amd64”, and the plug-in provider to “jogamp.org”. Set the host plug-in ID to “com.jogamp.jogl” (that’s the project this one is a fragment of). Set the minimum version to “2.0.0”. Then click “Finish” to create the project.

When the overview of this fragment comes up, set the platform filter to the incantation “(& (osgi.os=win32) (osgi.arch=x86_64))”. This makes sure the fragment project is only loaded when your program is run on a 64-bit Windows system.

In Windows, manually copy all the DLLs from the “lib” directories inside the unzipped “*-windows-amd64” gluegen and JOGL archives into the new “com.jogamp.jogl-windows-amd64” directory in your workspace. Then back in Eclipse, right-click the “com.jogamp.jogl-windows-amd64” project and select “Refresh”. You should see the DLLs in your project like this:

To finish setting up this fragment, click the “Build” tab at the bottom of the main window and check all the DLLs under “Binary Build” list. It should look like this:

Create one’s other fragments, mutatis mutandis

I guess what Stish means by that is, we can create fragments for the rest of the platforms that we want to support by redoing what we just did for the 64-bit Windows fragment, but making the necessary changes for each one. Here are the fragment names and platform filters for all five:

  • com.jogamp.jogl-linux-amd64: (& (osgi.os=linux) (osgi.arch=x86_64))
  • com.jogamp.jogl-linux-i586: (& (osgi.os=linux) (osgi.arch=x86))
  • com.jogamp.jogl-macosx-universal: (& (osgi.os=macosx) (osgi.arch=x86_64))
  • com.jogamp.jogl-windows-amd64: (& (osgi.os=win32) (osgi.arch=x86_64))
  • com.jogamp.jogl-windows-i586: (& (osgi.os=win32) (osgi.arch=x86))

And there is a complete table of the names of the native library files on the JogAmp wiki for reference here. When you’ve created all five fragments, your workspace will look like this:

Note for JDK 7 users on Mac OS X! Due to an incompatibility between JDK 6 and JDK 7 documented here and here, you need to either rename your .jnilib files to .dylib (if you only need to run under Java 7), or create copies of the .jnilib files as .dylib files (if you want to run under both Java 6 and Java 7).

You can see there’s a “Platform filter does not match the current environment” warning at the bottom for each of the platforms other than the one Eclipse is running on now. You could ignore those, but if you’re as compulsive as I am, that’s just not an option. So right-click the first fragment project in the Package Explorer on the left, click Properties, then expand “Plug-in Development” on the left and select “Plug-in Manifest Compiler”. Check “Enable project specific settings”, then change “General > Incompatible environment” to “Ignore”. The properties dialog should look like this when you’re done.

Click “OK”, then click “Yes” when it asks you if it can rebuild the project. Do this for all five fragment projects, and your warnings list will be gloriously empty.

With these five fragment projects included, our app will be able to run with no modification on five different platforms. When we run the app, the Eclipse RCP framework will load the com.jogamp.jogl plugin first, then it will load the correct fragment for the platform the app is running on, without you having to write any custom code or wrapper scripts to try to change the Java library path.

Create one’s principal project

Now that JOGL is ready for use, we can create the main project. Select “File > New > Project…” to bring up the “New Project” wizard. Open “Plug-in Development”, select “Plug-in Project”, and click “Next”.

Enter your project’s name. Mine is “name.wadewalker.tutorial”. Then click “Next”.

Then set your project version number (mine is “1.0.0”), your provider (mine is “Wade Walker”), click “Yes” beside “Would you like to create a rich client application?”, and click “Next”.

Select the “Hello RCP” template under “Available Templates”. This will make a minimal RCP app that we can stuff our own JOGL code into. Then click “Next” (not “Finish”).

Fill in your window title (mine’s “Tutorial”), and check the “Add branding” box (this lets you customize your splash screen later). Then click “Finish” to create the project.

Your project overview should look like this:

Now click the “Dependencies” tab at the bottom of the main window. Click “Add…” beside “Required Plug-ins”, and type “com.jo” in the “Select a Plug-in” box. Select “com.jogamp.jogl (2.0.0)” in the list of matching items, then click “OK”.

Your dependencies should look like this:

At this point, if you right-click this project in the list, then select “Run As > Eclipse Application”, you’ll see the most minimal app you can imagine. OK, I guess it could technically be more minimal, but this is pretty bare. But at least it runs! The empty frame inside our window is where the editors go in an RCP app. We’ll get rid of that in a moment, since we don’t want an editor yet.

Add a “view” to one’s principal application

Eclipse calls the kind of window we’re creating for JOGL a “view”. To create it, click the “Extensions” tab, then click the “Add…” button, type “org.eclipse.ui.v” in the “Extension Point filter” box, select “org.eclipse.ui.views”, and click “Finish”.

Right-click “org.eclipse.ui.views” under “All Extensions” and select “New > view”. Then under “Extension Element Details”, fill in the ID (“name.wadewalker.tutorial.joglview”), the name (“JOGLView”), and the class (“name.wadewalker.tutorial.JOGLView”).

Click the “class” hyperlink under “Extension Element Details”, then click “Finish” to create the Java file that implements the JOGL view.

Now we have to tell our program to open this view at startup so we can see it. Open the “Perspective.java” file by double-clicking it in the package explorer:

And change the contents of “Perspective.java” in the text editor to this:

package name.wadewalker.tutorial;

import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveFactory;

public class Perspective implements IPerspectiveFactory {

	public void createInitialLayout(IPageLayout layout) {
		// editor area invisible to avoid empty editor frame below our view
		layout.setEditorAreaVisible( false );
		layout.addView( "name.wadewalker.tutorial.joglview", IPageLayout.TOP,
						IPageLayout.RATIO_MAX, IPageLayout.ID_EDITOR_AREA);
		}
}

Now if you right-click your project in the list, then select “Run As > Eclipse Application”, you’ll see that our app has an empty JOGL view now. Still bare, but getting closer! The empty editor frame’s gone too, since we turned it off in the code above.

Now we put in some demo JOGL code. This snippet was originally used to demonstrate the old JOGL 1.1.1 (pre-JogAmp) in SWT (the windowing toolkit that Eclipse uses). Sven Göthel at JogAmp adapted it for JOGL 2.0, then I adapted that to make it an Eclipse ViewPart. Double-click the “JOGLView.java” file on the left, then replace its contents with this:

/*******************************************************************************
 * Copyright (c) 2000, 2005, 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Sven Gothel     - conversion to JOGL 2.0 (original at http://github.com/sgothel/jogl-demos/blob/master/src/demos/swt/Snippet209.java)
 *     Wade Walker     - conversion to an Eclipse ViewPart
 *
 *******************************************************************************/

package name.wadewalker.tutorial;

/*
 * SWT OpenGL snippet: use JOGL to draw to an SWT GLCanvas
 *
 * For a list of all SWT example snippets see
 * http://www.eclipse.org/swt/snippets/
 *
 * @since 3.2
 */
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GL2ES1;
import javax.media.opengl.GL2GL3;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLProfile;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import javax.media.opengl.glu.GLU;

import org.eclipse.swt.SWT;
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.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

public class JOGLView extends ViewPart {

    /** Holds the OpenGL canvas. */
    private Composite composite;

    /** Widget that displays OpenGL content. */
    private GLCanvas glcanvas;

    /** Used to get OpenGL object that we need to access OpenGL functions. */
    private GLContext glcontext;

    /** Master rotation angle of the torus, in degrees. */
    private int rot = 0;

    public JOGLView() {
    }

    @Override
    public void createPartControl( Composite compositeParent ) {
        GLProfile glprofile = GLProfile.get(GLProfile.GL2);

        composite = new Composite( compositeParent, SWT.NONE );
        composite.setLayout( new FillLayout() );

        GLData gldata = new GLData();
        gldata.doubleBuffer = true;
        glcanvas = new GLCanvas( composite, SWT.NO_BACKGROUND, gldata );
        glcanvas.setCurrent();
        glcontext = GLDrawableFactory.getFactory( glprofile ).createExternalGLContext();

        glcanvas.addListener(SWT.Resize, new Listener() {
            public void handleEvent(Event event) {
                Rectangle bounds = glcanvas.getBounds();
                float fAspect = (float) bounds.width / (float) bounds.height;
                glcanvas.setCurrent();
                glcontext.makeCurrent();
                GL2 gl = glcontext.getGL().getGL2();
                gl.glViewport(0, 0, bounds.width, bounds.height);
                gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
                gl.glLoadIdentity();
                GLU glu = new GLU();
                glu.gluPerspective(45.0f, fAspect, 0.5f, 400.0f);
                gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
                gl.glLoadIdentity();
                glcontext.release();
                }
        });

        glcontext.makeCurrent();
        GL2 gl = glcontext.getGL().getGL2();
        gl.setSwapInterval(1);
        gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        gl.glColor3f(1.0f, 0.0f, 0.0f);
        gl.glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
        gl.glClearDepth(1.0);
        gl.glLineWidth(2);
        gl.glEnable(GL.GL_DEPTH_TEST);
        glcontext.release();

        (new Thread() {
            public void run() {
                while( (glcanvas != null) && !glcanvas.isDisposed() ) {
                    render();
                    try {
                        // don't make loop too tight, or not enough time
                        // to process window messages properly
                        sleep( 1 );
                    } catch( InterruptedException interruptedexception ) {
                        // we just quit on interrupt, so nothing required here
                    }
                }
            }
        }).start();
    }

    protected void render() {
        PlatformUI.getWorkbench().getDisplay().syncExec( new Runnable() {
            public void run() {
                if( (glcanvas != null) && !glcanvas.isDisposed()) {
                    glcanvas.setCurrent();
                    glcontext.makeCurrent();
                    GL2 gl = glcontext.getGL().getGL2();
                    gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
                    gl.glClearColor(.3f, .5f, .8f, 1.0f);
                    gl.glLoadIdentity();
                    gl.glTranslatef(0.0f, 0.0f, -10.0f);
                    gl.glRotatef(0.15f * rot, 2.0f * rot, 10.0f * rot, 1.0f);
                    gl.glRotatef(0.3f * rot, 3.0f * rot, 1.0f * rot, 1.0f);
                    rot++;
                    gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2GL3.GL_LINE);
                    gl.glColor3f(0.9f, 0.9f, 0.9f);
                    drawTorus(gl, 1, 1.9f + ((float) Math.sin((0.004f * rot))), 15, 15);
                    glcanvas.swapBuffers();
                    glcontext.release();
                }
            }
        });
    }

    protected void drawTorus(GL2 gl, float r, float R, int nsides, int rings) {
        float ringDelta = 2.0f * (float) Math.PI / rings;
        float sideDelta = 2.0f * (float) Math.PI / nsides;
        float theta = 0.0f, cosTheta = 1.0f, sinTheta = 0.0f;
        for (int i = rings - 1; i >= 0; i--) {
            float theta1 = theta + ringDelta;
            float cosTheta1 = (float) Math.cos(theta1);
            float sinTheta1 = (float) Math.sin(theta1);
            gl.glBegin(GL2.GL_QUAD_STRIP);
            float phi = 0.0f;
            for (int j = nsides; j >= 0; j--) {
                phi += sideDelta;
                float cosPhi = (float) Math.cos(phi);
                float sinPhi = (float) Math.sin(phi);
                float dist = R + r * cosPhi;
                gl.glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
                gl.glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
                gl.glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
                gl.glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
            }
            gl.glEnd();
            theta = theta1;
            cosTheta = cosTheta1;
            sinTheta = sinTheta1;
        }
    }

    @Override
    public void setFocus() {
    }

    @Override
    public void dispose() {
        glcanvas.dispose();
        super.dispose();
    }
}

Then run the main project again, and finally our JOGL view shows an animated wireframe doughnut – what we super-geniuses call a “torus”. Success!

Here’s what it looks like in Linux:

And last but not least et cetera, here’s the Mac OS X version:

Now that we’ve got this skeleton up and walking, we’ll start putting some meat on it in the next tutorial.

Final touches — solutions to two potential problems

For some versions of JOGL, you may see an error saying there’s something wrong with the JAR cache. If so, simply right-click the project and select “Run As > Run Configurations…”. Make sure “Eclipse Application > name.wadewalker.tutorial.product” is selected in the left pane. Then click the “Arguments” tab on the right and add “ -Djogamp.gluegen.UseTempJarCache=false” to the end of the list of arguments in the “VM Arguments” box. This insures that JOGL won’t attempt to use its JAR caching mechanism, which fails in certain situations.

On Mac OS X, this application may freeze on startup or log an error saying “Can’t start the AWT because Java was started on the first thread”. If it does, simply right-click the project and select “Run As > Run Configurations…”. Make sure “Eclipse Application > name.wadewalker.tutorial.product” is selected in the left pane. Then click the “Arguments” tab on the right and add “ -Djava.awt.headless=true” to the end of the list of arguments in the “VM Arguments” box. This insures that AWT will not be loaded, which can cause problems with SWT applications on Mac OS X.

Resources upon which you may draw for more information

JOGL: Sven Göthel and the guys at http://jogamp.org have the source code for JOGL, zipped builds, and discussion forums. This is the main home for JOGL now, even though it still shows up a few other places on the web. Huge props to these guys for taking on such a large project that’s helpful to so many people around the world!

Eclipse RCP programming: Lars Vogel has a great article about creating Eclipse RCP programs at http://www.vogella.de/articles/EclipseRCP/article.html. The other articles on his site are also awesome.

SWT: The snippets at http://www.eclipse.org/swt/snippets/ are very helpful when putting other controls into RCP apps.

A concise history of the changes which we have made to this document

  • 10/09/2010: Wrote this post.
  • 10/17/2010: Punched up the language, added zip files.
  • 10/23/2010: Added fragments for all platforms; split the zip into two parts; fixed the location of GLProfile.initSingleton() after testing on Linux.
  • 10/26/2010: Fixed the links to full-sized images.
  • 3/23/2011: Fixed quote marks in code snipped from Perspective.java.
  • 4/10/2011: Updated code to work with the latest JOGL across all three major platforms. Updated zip file to JOGL b365. Put in new Linux and Mac OS X screenshots.
  • 10/14/2011: Fixed typo in Mac OS X platform filter.
  • 04/20/2012: Updated text for JOGL b736, Eclipse 3.7.2, and Java 1.7.0_03.
  • 04/21/2012: Uploaded new images.
  • 05/1/2012: Updated with .dylib vs. .jnilib information after I got JDK 7 working on Mac OS X.
  • 05/30/2013: Updated with info on how to turn JOGL’s JAR cache off.
This entry was posted in Eclipse RCP, Java OpenGL, Tutorial. Bookmark the permalink.

138 Responses to Tutorial: A cross-platform graphical application using Java, OpenGL, and Eclipse

  1. Pingback: Tweets that mention Tutorial: A cross-platform workbench program using Java, OpenGL, and Eclipse | Wade Walker's blog -- Topsy.com

  2. Pingback: Tutorial: Faster rendering with vertex buffer objects | Wade Walker's blog

  3. david says:

    thanks for the nice tutorial

    I have a question about javax.media.opengl that you use in your view which comes from JMF library.

    how did you reference to that library from your view without importing the libraries?

    Please let me know.

    Thanks!!

    • Wade Walker says:

      That stuff comes from jogl.all.jar, which is in the com.jogamp.jogl project that you create in the tutorial. It’s imported at the top of JOGLView.java, but you might have to click the little “expand” plus-sign on the left edge of the text editor to see it.

  4. david says:

    Hi,

    I got this error. Can you kindly make sense out of it?

    javax.media.opengl.GLException: Error: attempted to make an external GLContext without a valid pixelformat

    Thanks!!

    • Wade Walker says:

      I’ve seen this error on Windows XP 32-bit, but haven’t had time to track it down properly yet. Try checking your video driver to make sure it’s up to date — JOGL 2 may not work unless the OpenGL driver supports at least OpenGL 2.0.
      If that doesn’t work, you might try using JOGL 1.1.1a instead of JOGL 2 (you can get it at http://download.java.net/media/jogl/builds/archive/jsr-231-1.1.1a/). It requires some slight changes to the code, but I know it works with older drivers.

      • david says:

        Thanks for the prompt reply!

        Okay, here’s a solution I found from searching other forums.

        import com.jogamp.opengl.impl.windows.wgl.GDI;

        insert this line : GDI.GetDC(glcanvas.handle);
        after this line: glcanvas.setCurrent();

        in the View class.

        I am getting familiar with opengl so I don’t know why we have to do this, but I’m sure you can give us a tip? ^^

        Thanks again for the wonderful tutorial.
        David

    • Wade Walker says:

      Hi David,

      I finally duplicated this bug on two different Windows XP systems and entered a full bug report at http://jogamp.org/bugzilla/show_bug.cgi?id=429. You should be able to CC yourself on this report to be notified when the bug gets fixed.

    • Wade Walker says:

      Hi David,

      This error is fixed in recent builds of JOGL, and I’ve verified the fix myself. Please let me know if you have any more problems.

      • Barbara says:

        Hi, it’s me again.
        I have the same problem on Linux x86 with the newest releases of jogl and gluegen (it appeared on two different computers, both with Ubuntu 11.10 Linux x86, with the same project that works fine on Linux amd64 and Windows 64bit).
        I also tried with “GDI.GetDC(glcanvas.handle);” as David suggested, however it doesn’t solve the problem.
        Do you have any idea what I could do to fix it?

      • Wade Walker says:

        Hi Barbara,

        Strange that it works on Linux 64-bit but not Linux 32-bit. Here are some things to try:
        – Make sure your graphics card’s drivers are up to date. This is probably the biggest source of these kinds of problems 🙂
        – Make sure you’re running the 32-bit version of Java, the 32-bit version of Eclipse, and the 32-bit versions of gluegen and JOGL. If some of them get mismatched, it can cause a problem.
        – Try some other OpenGL program on your 32-bit Linux system, just to make sure OpenGL is working at all.

        If these don’t work for you, I’ll create a new 32-bit Ubuntu VM and test it myself, to see if I see the same problem. I’m leaving town for the weekend, though, so I won’t be able to try this for a couple of days.

      • Barbara says:

        Hi Wade,
        firstly, thanks for your quick reply. I tried everything you suggested:
        – my graphic card drivers are up to date (I have Intel GM965/GL960 graphic card and I updated it with installing “xserver-xorg-video-intel”)
        – my eclipse and java are 32bit (here some lines from Eclipse:
        *** System properties:
        linux
        -arch
        x86
        os.arch=i386
        sun.arch.data.model=32
        sun.boot.library.path=/usr/lib/jvm/java-6-sun-1.6.0.26/jre/lib/i386)
        – Again, I also made sure I have Linux32bit JOGL and GLuegen librarys in the linux i586 project…
        – I also tried some other OpenGL test programs and they worked, so obviously OpenGL is also installed properly.

        Could it be a problem, that my architecture is i386 and the librarys for JOGL were compiled on i586?

      • Wade Walker says:

        Let me follow up with you via email on this one — I’ll need to get you to run a few diagnostic tests that would clutter up these comments too much 🙂

  5. Leandro says:

    Hi, sorry for the disturbance of a newbie,

    I have the famous problem of the linux+JOGL : Info: XInitThreads() called for concurrent Thread support

    So I declared this:

    static {
    GLProfile.initSingleton();
    }

    In the constructor of my plugin (its a plugin for imageJ)
    But, when I do so, the program crash before making the window, so the glprofile line is not resolving this and i have run out of options :S

    Do you know what to do?

    Thanks!

  6. Leandro says:

    I’ve updated the JOGL 2.0 version (from Ago to Nov) and it seems they solved some problems. It throws the “Info: XInitThreads() called for concurrent Thread support” anyway, but it apparently had stopped to crash

    • Wade Walker says:

      Excellent, I’m glad that using the latest version of JOGL fixed your problem! The JOGL guys are working hard on the first “release” version of JOGL 2.0, so things are changing quickly right now.

      If you still have a bug, let me know, and I can help submit a bug report to the JOGL bug tracker.

      Sorry for the late reply, I was out for Thanksgiving holiday for the last few days 🙂

  7. Dick says:

    Thanks for the excellent tutorial. Another tutorial I’ve seen (specifically, this one) installs the JOGL jars and native libraries in Eclipse using a User Library. Could you elaborate on the benefits of your approach, particularly with respect to issues relating to cross-platform deployment? Thanks!

    • Wade Walker says:

      Justin’s approach works great as long as the native libraries of all the platforms you support can coexist in one directory.

      For example, the Linux native library “libjogl.so” can coexist with the Windows native library “libjogl.dll”, because the file extensions are different. You set the native library location of “jogl.jar” to a directory that holds both files, and when System.loadLibrary(“jogl”) gets called, it appends the right file extension for the current platform.

      The trouble with that approach comes when you want to support platforms that have identically-named native libraries. For example, if I want to support both 32-bit and 64-bit Windows, or both Solaris and Linux, I’m out of luck, because the native library filenames are identical, and loadLibrary() has no way to choose one set or the other.

      Eclipse RCP fragment projects are a way to get around this problem. Each fragment’s native libraries are in a separate directory, and the “platform filter” for each fragment tells which platform to load that fragment’s native libraries on. This approach will support any number of platforms simultaneously, whether the native library names are different or identical.

  8. Leandro says:

    Hi again, I have a problem that’s killing me.

    I’m making a plugin for ImageJ (this plugin is executed after the creation of the JVM to run the ImageJ program) and this plugin uses JOGL; the task is to launch it in many different platforms. The problem is that I cannot use System.setProperties or System.loadlib to add the library.path of native libs (the changes are reflected in System.getProperties but they are not implemented). So, there’s a way which I could make this possible? I think that I can’t make a JWS or an Eclipse app because this change the way that people add others plugins to the software and I have to keep it simple because the general users aren’t very experienced.

    If you have some clues, I’ll be delighted.
    (Sorry for my ugly English)

    • Leandro says:

      I have to say that the soft is running great in eclipse, where I add the libs manually. The problem comes when I have to make all the plugins.class that, with the native libs and jars, have to run if I copy all them in the ImageJ/plugins directory.

    • Wade Walker says:

      Hi Leandro,

      I have an idea that might work. It’s a bit complex, but see what you think:

      1. Zip all your native libraries into your plugin JAR file (or into a separate zip file installed beside your plugin). Each platform’s libraries should probably be in a separate directory inside the zip/jar.
      2. Put a static code block in your plugin’s main class that will run when your plugin’s main class is loaded by ImageJ (and before JOGL loads).
      3. In that static code block, determine which platform you’re running on (using System.getProperties() to look at the “os.*” properties).
      4. Depending on the platform, unzip the correct native libraries and write them into the ImageJ/plugins directory (using java.util.zip you should be able to do this without creating temporary files). You can optimize this so you don’t re-unzip libraries that are already correct for the platform.
      5. Then, when JOGL is loaded, it calls System.loadLibrary(), and it should find the correct native libraries in ImageJ/plugins (because I assume the ImageJ/plugins directory is put in java.library.path when ImageJ starts).

      I think this is what the Eclipse framework does when you run an RCP app that contains native library fragments. They get extracted into a temporary directory that’s already on the java.library.path set up by the framework at startup.

      Let me know if this works — it may help other people as well.

  9. Leandro says:

    Hi,

    I like this idea 🙂 I’ve tried it at first (in manual mode, copy and paste) but the problem seems that in Linux the plugins folder isn’t in the Java.library.path. I’ve tried to modify the path, but realized that it isn’t possible inside the code (and adding environment variables to the IJ execution is tricky for some users), so the only solution I found was to copy the libs to usr/lib, assuming all the JVM have path there :/ .

    I think the main problem is that the IJ doesn’t have a .conf file like Eclipse, where you can set all the variables…
    (a manifest file could do something like that? )

    • Wade Walker says:

      That seems dangerous — copying to /usr/lib might not work if the user doesn’t have permissions to write into that directory 🙂

      It looks like you can set “-Djava.library.path=whatever” either inside the ImageJ.cfg file (on Windows), or inside the ‘run’ script (on Linux). For example, at http://rsb.info.nih.gov/ij/docs/install/linux.html it shows how to change the VM options to increase the heap size, and you should be able to use the same method to set the library path.

      You might report this as an enhancement request to the ImageJ guys. They probably just didn’t think of someone writing a plugin that uses native libraries. Or you could write an installer for your plugin that changes the ImageJ.cfg and ‘run’ scripts for the user 🙂

  10. Leandro says:

    Thanks for the help! I think that would be the best.

    I’ll be waiting you’re new posts 🙂 (maybe OpenGL performance tips? my plugin is eating alive my procesors jaja )

  11. Tawan Banchuen says:

    Hi,

    I am running your example on Mac OS X Snow Leopard. I got this error without the linux fix, GLProfile.initSingleton(true). With the fix, the application never goes pass the splash screen.

    Could not create the view: drawable has invalid handle: com.jogamp.opengl.impl.macosx.cgl.MacOSXExternalCGLContext$Drawable[Realized true,
    Factory com.jogamp.opengl.impl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory@702eef15,
    handle 0x0,
    Window ProxySurface[config class com.jogamp.opengl.impl.macosx.cgl.MacOSXCGLGraphicsConfiguration[class javax.media.nativewindow.DefaultGraphicsScreen[class javax.media.nativewindow.DefaultGraphicsDevice[type MacOSX, connection decon, unitID 0, handle 0x0], idx 0],…

    Hope you have suggestion.

    Thanks.

    • Wade Walker says:

      Hi Tawan,

      My suggestion is to try an earlier version of JOGL 2 — it’s still pre-release, so a bug might have been introduced. Go to http://jogamp.org/deployment/autobuilds/master/ and try picking a few jogl-bxxx that are further back in time.

      If that doesn’t work, you can easily do the same tutorial for now with JOGL 1.1.1a, which you can get at http://download.java.net/media/jogl/builds/archive/jsr-231-1.1.1a/. There are fewer JARs and library files, but they go into the Eclipse projects the same way. You’ll have to modify the code slightly to change “GL2” to “GL” and “glcontext.getGL().getGL2()” to “glcontext.getGL()”, but after that everything should work just the same.

      And if you wouldn’t mind, could you go to http://jogamp.org/forum.html and post the full stack trace for this bug, along with your JOGL 2 version and graphics card/driver info? That will let me create a bug report so we can track this issue and make sure it gets fixed.

      Thanks!

    • Wade Walker says:

      Hi Tawan,

      I’ve duplicated this error now that I have a Snow Leopard machine, and I’m working on a fix.

    • Wade Walker says:

      Hi Tawan,

      I’ve verified that this demo now works correctly on Mac OS X 10.6 with build b356 and later versions of JOGL. I made a slight change to the tutorial code above — you’ll need a new version of JOGLView.java, and you’ll need to add “-Djava.awt.headless=true” to the run configuration. I’ve also updated the zip files above to contain those changes.

      • Johan says:

        Hi Wade,

        Running AWT headless causes some problems for JOGL, like using TextureIO to load textures, but I assume the standard APIs still work. 🙂

        Cheers.
        //Johan

  12. Cody says:

    Hi, thanks for the great tutorial. Unfortunately I’m stuck on the step to get the JOGL view to appear in the window when I run it. Eclipse tells me that JOGLView can’t be resolved to a variable. :S

    • Wade Walker says:

      Hi Cody,

      Could you tell me your OS version, Eclipse version, and Java version, and paste the full text of the error message in here? That will help me diagnose the problem.

      • Cody says:

        I’m running Windows 7 x64, Java I’m running is jdk1.6.0_24, and my version of Eclipse is Helios.

        public void createInitialLayout(IPageLayout layout) {
        // TODO Auto-generated method stub
        layout.setEditorAreaVisible(true);
        layout.addView(name.[mylastname].tutorial.JOGLView, IPageLayout.TOP, IPageLayout.RATIO_MAX, IPageLayout.ID_EDITOR_AREA);

        }

        Error Message: Description Resource Path Location Type
        name.[mylastname].tutorial.JOGLView cannot be resolved to a variable Perspective.java /name.[mylastname].tutorial/src/name/[mylastname]/tutorial line 12 Java Problem

  13. Wade Walker says:

    Hi Cody,

    It looks like you found an error in my tutorial text 🙂 The quote marks were missing around the JOGLView ID string; the line now looks like this:

    layout.addView( "name.yourlastname.tutorial.JOGLView", IPageLayout.TOP, IPageLayout.RATIO_MAX, IPageLayout.ID_EDITOR_AREA);

    Sorry for the confusion!

  14. Juan Romero Abelleira says:

    Eclipse was giving me an error that it hadn’t found gluegen-rt in java.library.path, although i had added the libs native to Mac OS X. Did you happen to run into this issue?

    • Wade Walker says:

      Hi Juan,

      Are you getting this error in my tutorial, or in another project? In my tutorial, as long as gluegen-rt.jnilib and all the other .jnilib files are in the com.jogamp.jogl-macosx-universal directory and all the *.jnilib files are checked on the Build tab of MANIFEST.MF, it should work.

      If this is a non-RCP project, you need to make sure “Properties > Java Build Path > Libraries > gluegen-rt.jar > Native library location” is set to the directory that contains your *.jnilib files (and the same is true for all the other JOGL JARs).

      One other note: There’s a bug in the Mac JOGL right now where you might have to remove GLProfile.initSingleton() if the program hangs at startup. I’m working on fixing this, but until then removing that statement will work around the problem.

    • Wade Walker says:

      Hi Juan,

      I’ve made a few minor changes to this tutorial, and confirmed that it runs properly on Mac OS X 10.6. Please let me know if you have any more problems.

  15. Ivan says:

    Excuse me for a hand curved programmer, but I have a problem with your tutorial.
    Application has been launched but with message and no torus has been displayed.
    Warning is the following:

    !ENTRY org.eclipse.ui 4 4 2011-04-14 23:03:58.482
    !MESSAGE Exception in org.eclipse.ui.internal.PageLayout.addView: org.eclipse.ui.PartInitException: Could not create view: name.wadewalker.tutorial.joglview
    !STACK 1
    org.eclipse.ui.PartInitException: Could not create view: name.wadewalker.tutorial.joglview
    at org.eclipse.ui.internal.ViewFactory.createView(ViewFactory.java:158)
    at org.eclipse.ui.internal.LayoutHelper.createView(LayoutHelper.java:162)
    at org.eclipse.ui.internal.PageLayout.createView(PageLayout.java:543)
    at org.eclipse.ui.internal.PageLayout.addView(PageLayout.java:416)
    at org.eclipse.ui.internal.PageLayout.addView(PageLayout.java:390)
    at firstpro.Perspective.createInitialLayout(Perspective.java:11)
    at org.eclipse.ui.internal.Perspective.loadPredefinedPersp(Perspective.java:816)
    at org.eclipse.ui.internal.Perspective.createPresentation(Perspective.java:270)
    at org.eclipse.ui.internal.Perspective.(Perspective.java:156)
    at org.eclipse.ui.internal.tweaklets.Workbench3xImplementation.createPerspective(Workbench3xImplementation.java:55)
    at org.eclipse.ui.internal.WorkbenchPage.createPerspective(WorkbenchPage.java:1672)
    at org.eclipse.ui.internal.WorkbenchPage.init(WorkbenchPage.java:2453)
    at org.eclipse.ui.internal.WorkbenchPage.(WorkbenchPage.java:563)
    at org.eclipse.ui.internal.tweaklets.Workbench3xImplementation.createWorkbenchPage(Workbench3xImplementation.java:39)
    at org.eclipse.ui.internal.WorkbenchWindow.busyOpenPage(WorkbenchWindow.java:768)
    at org.eclipse.ui.internal.Workbench$23.runWithException(Workbench.java:1221)
    at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
    at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
    at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4041)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3660)
    at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
    at org.eclipse.ui.internal.Workbench$31.runWithException(Workbench.java:1567)
    at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
    at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
    at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4041)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3660)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2548)
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438)
    at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at firstpro.Application.start(Application.java:20)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:620)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1408)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1384)
    !SUBENTRY 1 org.eclipse.ui 4 0 2011-04-14 23:03:58.483
    !MESSAGE Could not create view: name.wadewalker.tutorial.joglview

  16. Ivan says:

    Many thanks! It works!

  17. Ivan says:

    Hi, Wade Walker!
    I have some experience of dealing with MS Visual Studio (C# language and WPF) and NetBeans. Now I’d like to start my graduation project which will be devoted to application of neural networks. The plans are following: GUI wizard to set neural network, core modules (model) to work with it, some data providers and visualization of results (surfaces, different meshes…). Could you explain the advantages of using Eclipse RCP if there are some of them? It’s a pity but I can’t understand the features of this approach in comparison with technologies I know.

    • Wade Walker says:

      Hi Ivan,

      I believe you can write a great program in any language, using any framework — what matters most is how much effort and care you put into it 🙂 However, that being said, here’s why I chose the tools I chose.

      Until last September, I used Microsoft Visual Studio/C#/Managed DirectX to do my scientific programming, but I switched to Eclipse RCP/Java/OpenGL for four main reasons:

      1. Microsoft discontinued Managed DirectX in favor of XNA Game Studio, which is not a natural fit for scientific programming. There are now a couple of open-source ways to use C# and DirectX together (SlimDX and SharpDX), but they don’t seem to be very widely used, so there’s not much help available online.

      2. Eclipse RCP/Java/OpenGL are open-source and cross-platform, and I thought that would help my code to be more accepted in the academic, scientific and open-source communities.

      3. MSVS is a good development system, but I had to pay for a new version every year if I wanted the latest features. With Eclipse, I get a new version free every summer. Eclipse also has free tools for memory profiling (Eclipse Memory Analyzer) and GUI testing (SWTBot). I couldn’t afford equivalent tools for C#.

      4. MSVS doesn’t really have an equivalent of Eclipse RCP. They do have Visual Studio Automation, but it doesn’t seem to have the ability to create a fully customized standalone app. Once my GUI started getting complex, I found it inconvenient to code the whole thing from scratch in WPF — something like Eclipse RCP/NetBeans Platform/Qt Creator saves me a lot of work.

      I chose Eclipse instead of NetBeans mainly because:

      1. Eclipse RCP seems more mature than NetBeans Platform. Eclipse RCP has been around longer, and there’s more help available online.

      2. Eclipse seems to have a wider selection of plugins for things I need (Git, Mercurial, Checkstyle, ANTLR, etc.).

  18. Victor says:

    Hi Wade Walker,

    I’m trying to run your example on linux amd64 and it crashes JVM.
    When I removed
    static {
    GLProfile.initSingleton( false );
    }

    it runs fine.

    WBR,
    Victor

    • Wade Walker says:

      Hi Victor,

      Thanks for your feedback! I’ve noticed the same problem — on some systems, you need initSingleton() or it will crash, but on other systems initSingleton() itself causes a crash.

      When it crashes, are you getting a Java stack dump, or a HotSpot error file? It would be very helpful if you could post that dump or error file at http://jogamp.org/forum.html, along with your OS version, Java version, graphics card model, and graphics driver version. This will help us figure out what the bug is.

  19. Sarah says:

    Hi Wade,
    I am trying to create a JAR file for a project that uses JOGL and gluegen-rt Jar files. I am not able to create my projects JAR file, I get the following error:
    “Exception in thread “main” java.lang.NoClassDefFoundError: javax/media/opengl/GL
    Canvas”
    Can you please tell me How can I get rid of this error? In eclipse I have added the JAR files in the build path, I have also added the external JAR files in the /lib folder of my project. Is there something else that I am missing out?

    Regards,
    Sarah

  20. cirias says:

    Hi Wade,

    Thanks for the nice tutorial. I noticed you’ve got a typo in the platform filter for mac:
    (& osgi.os=macosx) (osgi.arch=x86_64)) should be (& (osgi.os=macosx) (osgi.arch=x86_64))

  21. cirias says:

    I’m trying to figure out how I should be packaging the various pieces in the main JOGL plugin and the fragments. Where you show how to set up the JOGL plugin and fragments, the plugin doesn’t contain any platform-specific jars and the fragments don’t contain any jars. But the JOGL I’m using has platform-specific jars. I guess the packaging of JOGL has changed? Seems like the platform-specific jars should go in the corresponding fragments, as there’s no point for example in including gluegen-rt-natives-windows-amd64.jar in my mac build. Does that seem right?

    • Wade Walker says:

      Those platform-specific JARs are for use in web apps, not in RCP apps. If you write a Java applet or Java Web Start app, your JNLP file refers to the platform-specific JARs instead of the individual .dll/.so/.jnilib files (for an example, see http://jogamp.org/wiki/index.php/Using_JOGL_in_Java_Web_Start). If you look inside those platform-specific JARs, you’ll see they just wrap up the .dll/.so/.jnilib files in a single file.

      In an RCP app, we need to put the .dll/.so/.jnilib files directly in the fragment projects. Then when you export the app, Eclipse JARs those files up for you, and when you start your app, Eclipse extracts the native libs into temporary directories so they can be loaded.

      Now that JOGL supports auto-extraction of its native libraries, there may be a way to make an RCP app work with the platform-specific JARs, but I haven’t tried it yet.

  22. Oleg says:

    Hallo

    i become a error:

    !SESSION 2012-02-03 19:21:09.273 ———————————————–
    eclipse.buildId=unknown
    java.version=1.6.0_29
    java.vendor=Sun Microsystems Inc.
    BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=de_DE
    Framework arguments: -product name.wadewalker.tutorial.product
    Command-line arguments: -product name.wadewalker.tutorial.product -data D:\Programming\EclipseProjects/../runtime-name.wadewalker.tutorial.product -dev file:D:/Programming/EclipseProjects/.metadata/.plugins/org.eclipse.pde.core/name.wadewalker.tutorial.product/dev.properties -os win32 -ws win32 -arch x86 -consoleLog

    !ENTRY org.eclipse.osgi 4 0 2012-02-03 19:21:12.250
    !MESSAGE Application error
    !STACK 1
    java.lang.NullPointerException
    at org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.(ModelServiceImpl.java:92)
    at org.eclipse.e4.ui.internal.workbench.swt.E4Application.createDefaultContext(E4Application.java:472)
    at org.eclipse.e4.ui.internal.workbench.swt.E4Application.createE4Workbench(E4Application.java:181)
    at org.eclipse.ui.internal.Workbench$3.run(Workbench.java:534)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:520)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at name.wadewalker.tutorial.Application.start(Application.java:20)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:352)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:624)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:579)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1433)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1409)
    An error has occurred. See the log file
    D:\Programming\runtime-name.wadewalker.tutorial.product\.metadata\.log.

    10 times all checked. Downloaded a projects from link from comment above.
    Do you have a idea what is wrong!?

  23. Oleg says:

    Eclipse Version:
    Eclipse Java EE IDE for Web Developers.

    Version: Juno Release
    Build id: 20111215-0110

    (c) Copyright Eclipse contributors and others 2005, 2011. All rights reserved.
    Visit http://www.eclipse.org/webtools

    • Wade Walker says:

      Hi Oleg,

      I haven’t tried running on the Juno release of Eclipse. That’s still a beta/pre-release version, right? The NullPointerException is happening down inside of Eclipse’s code, so I’d suggest trying the Indigo release of Eclipse instead. If it fails for you on Indigo, I’ll re-test it myself, since that’s a released version and should be OK.

  24. gael says:

    Hello, excuse me, I’m new to this programming, and I have a problem with your tutorial.
    Application has been launched but with message and no torus has been displayed.
    Warning is the following:

    [WW: Edited log for length — left the relevant parts]

    !SESSION 2012-02-04 23:31:57.442 ———————————————–
    eclipse.buildId=unknown
    java.version=1.7.0
    java.vendor=Oracle Corporation
    BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=fr_FR
    Framework arguments: -product name.gael.tutorial.product
    Command-line arguments: -product name.gael.tutorial.product -data C:\Users\gael\workspace/../runtime-name.gael.tutorial.product -dev file:C:/Users/gael/workspace/.metadata/.plugins/org.eclipse.pde.core/name.gael.tutorial.product/dev.properties -os win32 -ws win32 -arch x86_64 -consoleLog

    !ENTRY org.eclipse.ui 4 0 2012-02-04 23:32:01.368
    !MESSAGE An unexpected exception was thrown.
    !STACK 0
    java.lang.NullPointerException
    at name.gael.tutorial.JOGLView.dispose(JOGLView.java:165)
    at org.eclipse.ui.internal.ViewReference.createPartHelper(ViewReference.java:463)
    at org.eclipse.ui.internal.ViewReference.createPart(ViewReference.java:229)
    at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
    at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:313)
    at org.eclipse.ui.internal.ViewPane.setVisible(ViewPane.java:534)
    at org.eclipse.ui.internal.presentations.PresentablePart.setVisible(PresentablePart.java:180)
    at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.select(PresentablePartFolder.java:270)
    at org.eclipse.ui.internal.presentations.util.LeftToRightTabOrder.select(LeftToRightTabOrder.java:65)
    at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation.selectPart(TabbedStackPresentation.java:473)
    at org.eclipse.ui.internal.PartStack.refreshPresentationSelection(PartStack.java:1245)
    at org.eclipse.ui.internal.PartStack.setSelection(PartStack.java:1198)
    at org.eclipse.ui.internal.PartStack.showPart(PartStack.java:1597)
    at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:643)
    at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:570)
    at org.eclipse.ui.internal.PartSashContainer.createControl(PartSashContainer.java:568)
    at org.eclipse.ui.internal.PerspectiveHelper.activate(PerspectiveHelper.java:272)
    at org.eclipse.ui.internal.Perspective.onActivate(Perspective.java:981)
    at org.eclipse.ui.internal.WorkbenchPage.onActivate(WorkbenchPage.java:2714)
    at org.eclipse.ui.internal.WorkbenchWindow$27.run(WorkbenchWindow.java:3023)
    at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
    at org.eclipse.ui.internal.WorkbenchWindow.setActivePage(WorkbenchWindow.java:3004)
    at org.eclipse.ui.internal.WorkbenchWindow.busyOpenPage(WorkbenchWindow.java:799)
    at org.eclipse.ui.internal.Workbench$23.runWithException(Workbench.java:1224)
    at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
    at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
    at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4140)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3757)
    at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
    at org.eclipse.ui.internal.Workbench$33.runWithException(Workbench.java:1595)
    at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
    at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
    at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4140)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3757)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494)
    at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at name.gael.tutorial.Application.start(Application.java:20)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1386)

    Do you have any idea?

    Thanks a lot

  25. Wade Walker says:

    Hi Gael,

    Try putting if( glcanvas != null ) before glcanvas.dispose() in the method name.gael.tutorial.JOGLView.dispose(). You might have found some way to make Eclipse call the JOGLView.dispose() method before the canvas is set up.

  26. gael says:

    Hi Wade,

    It is better now!
    But I still have this exception :

    !ENTRY org.eclipse.ui.workbench 4 0 2012-02-06 20:20:16.363
    !MESSAGE Unable to create view ID name.gael.tutorial.joglview: An unexpected exception was thrown.
    !STACK 0
    java.lang.IllegalArgumentException: JAR URL doesn’t start with ‘jar:’, got
    at com.jogamp.common.util.JarUtil.getJarSubURL(JarUtil.java:140)
    at com.jogamp.common.os.Platform$3.run(Platform.java:309)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.jogamp.common.os.Platform.loadGlueGenRTImpl(Platform.java:303)
    at com.jogamp.common.os.Platform.(Platform.java:214)
    at javax.media.opengl.GLProfile.(GLProfile.java:81)
    at name.gael.tutorial.JOGLView.createPartControl(JOGLView.java:58)

  27. Wade Walker says:

    Hi Gael,

    This happens with some newer versions of JOGL. Just open your debug/run configuration, click the Arguments tab, and put -Djogamp.gluegen.UseTempJarCache=false in the VM Arguments box and it should work. Sorry, I need up update these instructions a bit!

  28. gael says:

    It works! Thanks a lot Wade….

  29. Enrique says:

    Hello first of all thank you very much for this tutorial, I have searched for a while now and this is the best one…

    I’m trying to reproduce this code in

    Ubuntu 10.04
    Eclipse Indigo
    JOGL version 2.0-b45-20111219, based on: branch rc –
    commit 2f2b071d60f5b630989140b1ade49d648ad78c20

    I had the exact same problems as Gael, but after the last solution “Add the arguments”, it still does not works…

    Please help…

    Here I provide the Log file…

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    [WW: Edited out parts of log file for space reasons — there were many duplicate entries]

    Caused by: java.lang.IllegalArgumentException: JAR URL doesn’t start with ‘jar:’, got
    at com.jogamp.common.util.JarUtil.getJarSubURL(JarUtil.java:140)
    at com.jogamp.common.os.Platform$3.run(Platform.java:309)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.jogamp.common.os.Platform.loadGlueGenRTImpl(Platform.java:303)
    at com.jogamp.common.os.Platform.(Platform.java:214)
    … 43 more

    • Wade Walker says:

      This does look like the same error Gael had. Are you sure you didn’t miss the “-” at the beginning of the “-Djogamp.gluegen.UseTempJarCache=false”? Or maybe you put this in the wrong place in Eclipse?

  30. Thomas says:

    Hi Wade,

    Many thanks for your tutorial. Your approach using fragments is the first that works and your example runs just fine.

    However, I have some problems in getting jogl to work in combination with processing programming language inside an RCP application. We want to use it for visualizing huge chunks of data. Setting the renderer to OpenGL, I get the following error:

    Exception in thread “Animation Thread” java.lang.NoClassDefFoundError: javax/media/opengl/glu/GLUtessellatorCallback
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
    at java.lang.Class.getConstructor0(Unknown Source)
    at java.lang.Class.getConstructor(Unknown Source)
    at processing.core.PApplet.makeGraphics(Unknown Source)
    at processing.core.PApplet.size(Unknown Source)
    at processing.core.PApplet.size(Unknown Source)
    at ui.processing.BasicVisualization.setup(BasicVisualization.java:38)
    at processing.core.PApplet.handleDraw(Unknown Source)
    at processing.core.PApplet.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    Caused by: java.lang.ClassNotFoundException: javax.media.opengl.glu.GLUtessellatorCallback
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:513)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    … 11 more

    Do you have any idea what could be wrong here?

    • Wade Walker says:

      Hi Thomas,

      This error just looks like the JOGL JAR file is not on the classpath, so the JVM can’t find GLUtessellatorCallback.java (which is definitely part of JOGL). I assume you’re trying to create an RCP project like in my tutorial, but with the Processing libraries included in addition to JOGL? The stack trace you included seems to show that you’re just running processing.exe by itself, not loading Processing libraries from within an RCP app.

      Processing seems to include JOGL directly in its distribution at processing-1.5.1\modes\java\libraries\opengl\library. I assume that on startup, processing.exe determines the current platform, then invokes Java internally with something like “java -Djava.library.path=processing-1.5.1\modes\java\libraries\opengl\library\platformname”, with the classpath set to include the JOGL JARs at processing-1.5.1\modes\java\libraries\opengl\library. So if you’re trying to build an RCP app that uses Processing, I assume you’re going to forgo the use of processing.exe and just use the Processing libraries directly somehow? I may need more information about what you’re doing to help out effectively 🙂

      • Thomas says:

        Hi Wade,

        thanks for the quick reply. I indeed want to use the processing libraries in a RCP project very similar to your tutorial. All libraries are included in a separate Plugin Project and set as dependencies.

        It seems though, that processing (at least version 1.5.1) is not compatible with recent JOGL versions. After recreating the plugin and fragments with JOGL 1.1.1a according to your tutorial it works like a charm. Why the included version did not work is beyond me, but it does now. So thanks again for your quick help!

  31. Wolfgang says:

    Hi Wade,

    thanks for the tutorial.

    I chose the Mac way and I am getting this error when running the program: java.lang.ClassNotFoundException: com.jogamp.common.util.PropertyAccess

    (this come up IN THE APPLICATION WINDOW – not whilst compiling or so …)

    Any idea what went wrong?

    Thank a lot
    Wolfgang

    • Wade Walker says:

      Here are a few things to double-check:

      – Did you create the Mac fragment project called com.jogamp.jogl-macosx-universal, and set its platform filter correctly?
      – Does that Mac fragment project have com.jogamp.jogl as the host plugin?
      – Does the com.jogamp.jogl plugin have the JAR files included properly? Double-click the MANIFEST.MF file, then click the Build tab on the right and look in the “Binary Build” box — all the JARs should be checked there.

      Finally, you could try just downloading the .zip files of the projects from the beginning of the tutorial and running those directly (since it’s already all set up there, you only have to extract and run). If that doesn’t work let me know, maybe I have some error there that I can correct.

      • Wolfgang says:

        wow … this is what I call a fast response!

        I double checked your points:
        – Yes to 1)
        – Yes to 2)
        – Half and half to 3). The problem I had here is that the names of the jar’s of the JOGL I downloaded are not exactly the same as described in your tutorial (or the other way around … the required names were missing). I downloaded the latest package from a couple days ago. So I took the ones with the closest names. I chose: gluegen-gl.jar (instead of gluegen-rt.jar), nativewindow.os.macosx.jar (instead of nativewindow.all.jar), newt-natives-macosx-universal.jar (instead of newt.all.jar). jogl.all.jar was ok by the way.

        I thought that should be ok because the editor didn’t complain about any missing classes.

        Thanks for spending your time for me!

        regards
        Wolfgang

      • Wade Walker says:

        Oops, this is my fault — I need to update the tutorial a little 🙂 JOGL has recently removed some JARs, so now you only need
        gluegen-rt.jar and jogl.all.jar. If you look at http://jogamp.org/wiki/index.php/Downloading_and_installing_JOGL down at the bottom of the page, I’ve recently updated it to show the exact JAR and .jnilib files you should expect to see for the Mac platform.

        The way this tutorial is set up, you don’t use the *-natives-*.jar files, instead you create fragment projects with the native library files (.dll/.so/.jnilib) in them. An alternate way to do it is to put all the *-natives-*.jar files into the com.jogamp.jogl project, then you shouldn’t have to create the fragment projects. I’m going to create another tutorial that describes how to set things up this way, I just haven’t gotten around to it yet.

  32. Wolfgang says:

    Thanks again.

    But there are still 2 inconsistencies:
    – In the latest build there is no gluegen-rt.jar but only a gluegen-gl.jar
    – In the latest build there is no libglugen-rt.jnilib

    regards
    Wolfgang

  33. Sérgio says:

    Hi Wade Walker… nice tutorial… it is well explained!

    if I have a project developed in the classic eclipse IDE, how could I migrate it the eclipse RCP so to apply this stuf?

    Thanks

    • Wade Walker says:

      Hi Sérgio,

      I think any project that will build in Eclipse Classic should build and run without any modification in Eclipse RCP. All you should have to do is install Eclipse RCP, start it, and open your old workspace with it. But once you add RCP plugin projects to your workspace, you may not be able to work on them properly in Eclipse Classic anymore, since I think Classic lacks the plugin manifest editors and such.

      Transforming (for example) a Swing app into an RCP app is a little harder, since you’d have to switch from Swing to SWT. If you’ve only got one or two windows, that’s not too hard. At http://jogamp.org/wiki/index.php/Using_JOGL_in_AWT_SWT_and_Swing I’ve written some examples that show the difference between how you use JOGL in SWT, AWT, and Swing, which may be helpful.

  34. hee cheol says:

    Hi Wade,
    I am Korean
    Tutorial was helpful
    I do not speak English well
    But the problem has occurred.
    Help me..

    !SESSION 2012-06-18 10:25:08.735 ———————————————–
    eclipse.buildId=unknown
    java.version=1.6.0_31
    java.vendor=Sun Microsystems Inc.
    BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=ko_KR
    Framework arguments: -product name.wadewalker.tutorial.product
    Command-line arguments: -product name.wadewalker.tutorial.product -data C:\java\workspace/../runtime-name.wadewalker.tutorial.product -dev file:C:/java/workspace/.metadata/.plugins/org.eclipse.pde.core/name.wadewalker.tutorial.product/dev.properties -os win32 -ws win32 -arch x86 -consoleLog

    !ENTRY org.eclipse.ui.workbench 4 0 2012-06-18 10:25:10.019
    !MESSAGE Unable to create view ID name.wadewalker.tutorial.joglview: com/jogamp/common/jvm/JVMUtil
    !STACK 0
    java.lang.ClassNotFoundException: com.jogamp.common.jvm.JVMUtil
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:513)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at javax.media.opengl.GLProfile.(GLProfile.java:1141)
    at name.wadewalker.tutorial.JOGLView.createPartControl(JOGLView.java:65)
    at org.eclipse.ui.internal.ViewReference.createPartHelper(ViewReference.java:375)
    at org.eclipse.ui.internal.ViewReference.createPart(ViewReference.java:229)
    at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
    at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:313)
    at org.eclipse.ui.internal.ViewPane.setVisible(ViewPane.java:534)
    at org.eclipse.ui.internal.presentations.PresentablePart.setVisible(PresentablePart.java:180)
    at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.select(PresentablePartFolder.java:270)
    at org.eclipse.ui.internal.presentations.util.LeftToRightTabOrder.select(LeftToRightTabOrder.java:65)
    at org.eclipse.ui.internal.presentations.util.TabbedStackPresentation.selectPart(TabbedStackPresentation.java:473)
    at org.eclipse.ui.internal.PartStack.refreshPresentationSelection(PartStack.java:1245)
    at org.eclipse.ui.internal.PartStack.setSelection(PartStack.java:1198)
    at org.eclipse.ui.internal.PartStack.showPart(PartStack.java:1597)
    at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:643)
    at org.eclipse.ui.internal.PartStack.createControl(PartStack.java:570)
    at org.eclipse.ui.internal.PartSashContainer.createControl(PartSashContainer.java:568)
    at org.eclipse.ui.internal.PerspectiveHelper.activate(PerspectiveHelper.java:272)
    at org.eclipse.ui.internal.Perspective.onActivate(Perspective.java:981)
    at org.eclipse.ui.internal.WorkbenchPage.onActivate(WorkbenchPage.java:2714)
    at org.eclipse.ui.internal.WorkbenchWindow$28.run(WorkbenchWindow.java:3030)
    at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
    at org.eclipse.ui.internal.WorkbenchWindow.setActivePage(WorkbenchWindow.java:3011)
    at org.eclipse.ui.internal.WorkbenchWindow.busyOpenPage(WorkbenchWindow.java:799)
    at org.eclipse.ui.internal.Workbench$23.runWithException(Workbench.java:1229)
    at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
    at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
    at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4140)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3757)
    at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
    at org.eclipse.ui.internal.Workbench$33.runWithException(Workbench.java:1600)
    at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
    at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
    at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4140)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3757)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2609)
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
    at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at name.wadewalker.tutorial.Application.start(Application.java:20)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1410)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1386)

    • Wade Walker says:

      Hi Hee Cheol,
      The ClassNotFoundException usually just means the class path is not set up correctly. You may have missed a small step somewhere in the tutorial 🙂 You might try downloading the zip files that I mention at the beginning of the tutorial, to see if my pre-made projects work for you.

      • hee cheol says:

        Thanks for the tips, it was very helpful
        But now another problem has occurred.
        I tried Googling, but could not find an answer.
        What’s the problem?

        java.lang.UnsatisfiedLinkError: com.jogamp.common.os.Platform.getPointerSizeInBitsImpl () I
        at com.jogamp.common.os.Platform.getPointerSizeInBitsImpl (Native Method)
        at com.jogamp.common.os.Platform. (Platform.java: 64)
        at com.jogamp.common.nio.Buffers.nativeOrder (Buffers.java: 252)
        at com.jogamp.common.nio.Buffers.newDirectByteBuffer (Buffers.java: 67)
        at com.jogamp.common.jvm.JVMUtil. (JVMUtil.java: 58)

  35. Wade Walker says:

    UnsatisfiedLinkError means that it’s missing a .dll/.so/.jnilib file, either one from JOGL, or from your OpenGL driver. If you’re using the JOGL in my zip file, this shouldn’t be possible, unless maybe you don’t have an OpenGL driver installed on your machine?

  36. Great tutorial. I was able to get the torus demo up and running on Ubuntu 12.04 (Linux 64amd), but I had to add jogamp to my java security policy to solve mysterious crashes. The fix and more information is here: http://forum.jogamp.org/JOGL-not-launching-on-Ubuntu-12-04-LTS-td4005531.html

  37. Scratch my last comment about security policy. Though that seems to have helped, I’m now not sure if it did. I am still getting intermittent crashes. Sometimes it runs, sometimes it doesn’t. Not sure what’s going on.

  38. Familia says:

    Wade,

    Great tutorial !!!
    I am quite new to jogl and opengl programing, i have been looking at the code that you provided but i can’t figure out the required structure for the rendering process. I have looked at other tutorials (https://sites.google.com/site/justinscsstuff/jogl-tutorial-3), but apparently they use GLCanvas from jogl itself while in your tutorial the GLCanvas comes from org.eclipse.swt.opengl.GLCanvas, which makes things a little bit more confusing to me. Do you mind setting me in the wright way?

    Thanks,
    Carlos

  39. Johan S says:

    Hi Wade,

    I followed your tutorial but ran into a problem when running the empty project. The frame opens up like it should but I get the following error message:

    !ENTRY org.eclipse.e4.ui.workbench 4 0 2012-09-25 10:34:29.992
    !MESSAGE Unable to retrieve the bundle from the URI: bundleclass://org.eclipse.e4.ui.workbench.addons.swt/org.eclipse.e4.ui.workbench.addons.cleanupaddon.CleanupAddon

    !ENTRY org.eclipse.e4.ui.workbench 4 0 2012-09-25 10:34:29.993
    !MESSAGE Unable to retrieve the bundle from the URI: bundleclass://org.eclipse.e4.ui.workbench.addons.swt/org.eclipse.e4.ui.workbench.addons.dndaddon.DnDAddon

    !ENTRY org.eclipse.e4.ui.workbench 4 0 2012-09-25 10:34:29.993
    !MESSAGE Unable to retrieve the bundle from the URI: bundleclass://org.eclipse.e4.ui.workbench.addons.swt/org.eclipse.e4.ui.workbench.addons.minmax.MinMaxAddon

    When I later tried with adding the view nothing happens more than the same error message. Same thing goes for when I put your example code in the JOGLView, but I guess that part was expected after the other problems.

    Thanks for any help! Otherwise really great tutorial!

    • Wade Walker says:

      Hi Johan,

      Are you perhaps using the new Eclipse 4.2? In that case, it seems like there are some extra plugins it needs as dependencies. I poked around a bit online, and eventually found them (I think maybe at http://www.vogella.com/articles/EclipseRCP/article.html I found a hint), but I found that Eclipse 4.2 introduced some other problems in my RCP apps so I haven’t switched over to it yet. I have verified that this tutorial works in Eclipse 3.8, though. The download called “Eclipse 3.8 SDK” will compile and run these RCP projects with no changes.

      One reason to be wary of Eclipse 4.2 for the moment: apparently they’ve redone the whole foundation of RCP apps, so all the view and editor classes are now just a compatibility layer on top of new, relatively untested stuff. It mostly seems to work, but there are some differences with object selection and a few other things I haven’t had a chance to figure out yet. If you find any good info in this regard, please feel free to post it here. Eventually I’ll redo the tutorial as “pure” Eclipse 4, but it didn’t look quite mature enough yet for me to risk this.

      • Johan S says:

        I am yes. Perhaps I look into it but I’m kinda green when it comes to eclipse (or any kinda first time setup :p). Big thanks for a quick answer though!

    • Johannes F says:

      Hi Johan, Hi Wade
      I’ve got the same problem with Eclipse Juno. Does it show you the JOGL grafics or just your empty Eclipse screen?
      I only see the empty eclipse screen, because the Modification in the Perspective class isnt enough for Eclipse 4.2. Currently i’m looking at some 4.2 Tutorials to find out how to fix this.
      Thanks for the Tutorial Wade!

  40. Maralaa says:

    Hi Wade. I have some problems. My eclipse version is Juno and 1.7jdk. There is no class name field in extention detail section. Also there isn’t create any application.java..etc. Only I create Jogl view. The error’s are
    1. Application error
    2.Framework event error
    3. An error occured while automatically activating
    Please help me
    My operation system is window 32 bit

    • Wade Walker says:

      Hi Maralaa,

      I don’t think this tutorial works correctly with Eclipse 4.2.1 (Juno). It will work with Eclipse 3.8.1 SDK (which is the same as 4.2.1, but without the new changes to the framework that break some backwards compatibility). You can download it at http://download.eclipse.org/eclipse/downloads/drops/R-3.8.1-201209141540/ (they hide it pretty well on the Eclipse site).

      I’m going to port this tutorial to 4.2, but it may take a while, since supposedly they’ve completely changed the View/Editor/etc structure and replaced it with something new, and there’s very little documentation yet. You can still run some Eclipse 3.x RCP apps on top of a compatibility layer, but my tests have shown that some things don’t work correctly that way (for example, object selection).

  41. Johannes says:

    Hello Wade,
    Thank you for the awesome tutorial!. It works fine on Eclipse 3.x so far and i learned a lot from it.
    Im trying to get it working with Eclipse Juno 4.2. In Case it turns out to be too difficult: do you know another Java openGL Binding for Juno RCP?
    Greetings
    Johannes

    • Wade Walker says:

      Hi Johannes,

      The problem I had with Eclipse 4.2 was that the app wouldn’t start (it would give warnings about missing packages). To make it work, I had to delete my .product file and create a new “Product Configuration” (in File > New > Other). This creates a new .product file with the correct dependencies for Eclipse 4.2. This is what you’ll have to do if you downloaded the zipped version of the tutorial, because the .product file in the zip is for Eclipse 3.x.

      When creating the new .product file, you’ll also still need to set “-Djogamp.gluegen.UseTempJarCache=false” in the Launching tab under “VM Arguments”. This prevents JOGL from erroring out on startup.

      Other than the .product, all the other code and files should be the same, and it should work. I’ve only tested this on Windows 7 64-bit so far, though.

      • Johannes says:

        Hi Wade,
        It works fine in 4.2 even without changing product for me when i download your package. If i try the tutorial however it wont work.
        Anyway with the package it still uses the old eclipse 3.x components and wont fit into the eclipse 4.2 Application model this way. I will try to figure it out.

  42. aris says:

    java.lang.RuntimeException: No application id has been found. After plug in selection com.jo

  43. Hello Wade.

    This tutorial essentially initializes OpenGL in immediate mode, which works well with SWT. My question is if it is currently possible to initialize together SWT, JOGL and OpenGL in a modern, forward compatible core profile (3.2 maybe) in order to use the programmable pipeline instead? Are there any examples on how to do this?

    Thank you for your time.

    • Wade Walker says:

      Hi Jesus,

      Yes, it is possible to use JOGL with “modern” OpenGL (i.e. all shaders, no fixed-function stuff). I haven’t written a blog posting on it yet, but I can send you some example code if you want — just let me know here, and I’ll send it to you directly (no need to post your email address in the open, I can send it via WordPress to the address you posted from).

  44. Hello.
    Great tutorial, thanks a ton for putting it together. I’m performing academic research and need to update an existing project with the latest releases of JOGL (we were using some version from 2011 or so). Before doing that I wanted to, from scratch, follow some insightful tutorials on ways to create a clean JOGL project for windows/mac/linux.

    I’m getting the error “java.lang.UnsatisfiedLinkError: no gluegen-rt in java.library.path”.

    Running windows 7 64-bit, Eclipse, JDK 1.7.

    I noticed above you’ve already responded to someone with this error running OSX.

    I’m using your tutorial project files from the zips supplied at the top of the page (the plugin and fragments, and the actual rcp project) and haven’t changed them.

    As I understand it, the *.dll files should be detected as long as they are in the fragment(windows-i586) right? I’m not sure what I’m doing wrong.

    Here’s a pastebin of my error log, http://pastebin.com/tzSRnVNm

    • Wade Walker says:

      Glad you liked the tutorial!

      Your error may be because you seem to be running 32-bit Java on a 64-bit OS. Eclipse chooses the 32-bit Windows fragment based on your JVM’s architecture (which is x86 instead of x86_64), so it tries to load the 32-bit DLL on a 64-bit system, which would probably give the link error you see. I’d try with a 64-bit JVM and see if that works.

      In regard to updating to the latest JOGL, there will soon be a new way to do this tutorial which uses the 6 JOGL native library JARs files in one plugin (instead of all the dozen or so dll/so/dynlib files across one plugin and five fragments). It requires a patch to JOGL that I’m just about to submit to the maintainers, so it should be available shortly. If you want to be notified when this is ready, just add yourself to the CC list for the bug at https://jogamp.org/bugzilla/show_bug.cgi?id=687.

      • Wow your response was timely and your advice was dead on. I grabbed a copy of 64-bit JRE and 64-bit Eclipse and now the tutorial’s project runs just fine.

        Thanks again.

        That upcoming patch sounds even more convenient. Do you have any plans on updating this tutorial (or creating a similarly simple/minimal example) with said new setup options?

      • Wade Walker says:

        Glad that fixed the problem! And yes, once my pull request to JOGL is approved, I’ll upgrade the tutorial to show the new method. Right now I’m experimenting with the new method to try to minimize the installed app size.

  45. BENJAMIN VARGHESE says:

    i am getting this error message after i added the given code into JOGLView ….
    !MESSAGE An unexpected exception was thrown.
    !STACK 0
    java.lang.NullPointerException
    at test.JOGLView.dispose(JOGLView.java:156)
    at org.eclipse.ui.internal.ViewReference.createPartHelper(ViewReference.java:463)
    at org.eclipse.ui.internal.ViewReference.createPart(ViewReference.java:229)
    at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:595)
    at org.eclipse.ui.internal.PartPane.setVisible(PartPane.java:313)
    [edited for length]

    !ENTRY org.eclipse.ui.workbench 4 0 2013-02-24 11:03:16.820
    !MESSAGE Unable to create view ID test.joglview: com/jogamp/common/util/PropertyAccess
    !STACK 0
    java.lang.ClassNotFoundException: com.jogamp.common.util.PropertyAccess
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:513)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    [edited for length]

    • Wade Walker says:

      This looks like two different problems. The first NullPointerException is my fault, if you change JOGLView.dispose to do


      if( glcanvas != null )
      glcanvas.dispose();

      that should make the dispose safe even in the unusual case where JOGL fails to load.

      The root problem appears to be the ClassNotFoundException which happens on the load of com.jogamp.common.util.PropertyAccess. This class is in gluegen-rt.jar, which indicates that perhaps gluegen-rt.jar didn’t get put into your com.jogamp.jogl plugin. Try checking your build.properties file of the com.jogamp.jogl project to make sure gluegen-rt.jar is in there.

  46. Samy says:

    Hi wade, i have a problem using jogl 2.0.0 on mac OS X 10.7.5 : i have this message : * quit unexpectedly while using the libnativewindow_macosx.jnilib. Nonetheless it’s working fine on windows 7 for the same project. Any idea?

    • Wade Walker says:

      Hi Samy, I would say try the latest autobuild of JOGL instead of a “release” build, since many Mac fixes have gone in recently (they’re at http://jogamp.org/deployment/autobuilds/master/). I’ve used a recent autobuild with a simiar version of Mac OS, and it works well for me.

      • Samy says:

        Hi wade, i used the latest autobuild for the mac os x 10.7.5, and still i have an issue, it’s really strange that the jogl 1.1.1 works on Mac for my project, but not the 2.0.0. But i need to use the 2.0.0 to use the GLCanvas that support swt ^^’. The autobuild i used is :gluegen-2.0-b669-20130509-macosx-universal and jogl-2.0-b989-20130509-macosx-universal, is it good?

        If you have an idea to help me, that be great, because after 2 months of developement on windows, but having almost all my collegues working on mac, now i’m stuck ^^””’

        (edited for length — original error log now at https://jogamp.org/bugzilla/show_bug.cgi?id=738)

      • Wade Walker says:

        Hi Samy,

        This looks like it might be a real bug in JOGL, rather than a usage problem. I’ve created a bug report for it at https://jogamp.org/bugzilla/show_bug.cgi?id=738. To get the bug solved though, you’ll need to create a “minimal test case” that reproduces it (the absolute minimum amount of code that causes this crash) and add that test case to the bug report. You should also CC yourself onto the bug report so you’ll see updates.

        Thanks for reporting this!

  47. Tuan Anh Nguyen says:

    Dear Wade Walker,
    I followed your tutorial and everything work well. But I got a problem while try show some SWT Widgets over the GLCanvas using AbsoluteLayout.
    composite = new Composite(parent, SWT.NONE);
    composite.setLayout(null);
    Button button = new Button(composite, SWT.NONE);
    button.setText(“New Button”);
    button.setBounds(172, 145, 94, 28);
    glcanvas = GLCanvas.create(composite, SWT.NO_BACKGROUND, null, null, null);
    I thought that the button should be on top of GLCanvas but it is always behind the GLCanvas. Am i doing something wrong ? Please help me, thank you very much.

    • Wade Walker says:

      Hi Tuan,

      I haven’t tried putting an SWT control (like a button) on top of the OpenGL canvas, so I’m not sure if it works properly or not. I have noticed that if another control overlaps the GL canvas (like a tooltip from a neighboring window), it will sometimes get clipped off by the GL draw. In this case, I put code in the SWT repaint event that senses whether the dirty region is shaped like a tooltip, and if it is, doesn’t redraw the Open GL 🙂

      I noticed you asked this over at http://forum.jogamp.org/How-to-overlay-SWT-Widgets-over-GLCanvas-td4029507.html as well, so I’ll go over there to continue the discussion.

  48. Nostia says:

    Hi Wade
    I have a problem while adding view at this step:
    Right-click “org.eclipse.ui.views” under “All Extensions” and select “New > view”.

    I can create only new Generic, but not View. What’s wrong? 😦

    • Wade Walker says:

      Hmmm, that still works on Eclipse 3.8 for me. I just downloaded Eclipse 4.3 and checked it, and it’s OK there too. Perhaps you didn’t download the right version of Eclipse? You need “Eclipse for RCP and RAP Developers” to make sure all the right packages are installed.

  49. Pingback: JZY3D - Java charts | A.Quarter.To.SevenA.Quarter.To.Seven

  50. Juan Ibarra says:

    Hello
    above all receive a warm welcome from me, I’m your follower web paguina as it has helped me a lot in grade i job

    I would like to ask some questions, as you do know how to study and this eclipse as ide to perfection without a tutorial and as you have?

    and good have had minor problems in creating a Java3D plugin for eclipse, I say what I have done to see if I could help

    first

    I think a plug-in where I call java3d.plugin, this project just add the .Jar gives me the library of java 3d

    second

    created a java project called implementare java3d.test which is where the plug-in to see how it works, consists of two clsES, where is the principal declared public static void main, which is where I think the JFrame, and a class where I panel 3d world is where lhasa libraries used java 3d

    to correct the error I add to the project’s dependence on pluguin

    I run the program and it gives me the error and not getting the native dll that uses Java3D jar to work

    according to what they understood fragment creates a plugin that serves to accommodate the dll, pictures or any resource that fence to use dll in my case are

    after doing this the error persists, you have to reference the dll but not like, and can not find information on the internet how to do it, I would also like to do fragment for each operating system so that it is easy to exhorting, there is a project called java3declipse that does what I want, the thing is I want to do and learn for the future that will help me a lot to the libraries I created in C to work with electronics and microcontrollers, and my particular thesis is to create a programming language for pic microcontrolares

    sorry for the inconvenience caused, I hope you can help me

    thank you very much,

    deep peace

    PD: if something does not agree is because I’m using google translator

  51. Thomas Ressel says:

    Epic tutorial!

    One note: I thought it was a good idea to create two bundles, one for Java OpenGL and one for GlueGen, with corresponding fragments for each of them. It turned out it wasn’t, because they depend on each other and every bundle has it’s own class loader, so one bundle doesn’t “see” the libraries loaded by the other. This resulted in an UnsatisfiedLinkError.

    • Wade Walker says:

      Glad my tutorial was helpful! Good point about GlueGen and JOGL depending on each other; as you noticed, they indeed can’t be separated. There’s also another way to create a JOGL bundle now, using JAR files that contain the native libraries instead of putting the native libraries in separate fragments. You can see an example at https://github.com/WadeWalker/com.jogamp.jogl. This other way gets rid of the fragments, but it decompresses the native libraries at runtime into a temp directory, which may be undesirable for some situations and platforms.

  52. Pingback: Build a cross platform JOGL Eclipse Plugin with Tycho - A.Quarter.To.SevenA.Quarter.To.Seven

  53. Wolfgang says:

    Hi Wade,
    First:
    u are awesome, thanks for all your posts.

    Second:
    Small Question. I want to create a simple 3d editor but i need to include 2 libs that i wrote, one for math (glm) and one for parent-children relationships. The second lib depends on the jogl-libs to build it. How should i include those libs or ?can i change the build order of the dependencies?

    Third:
    The last 3 pics of the platform specific builds… how can i build them for each platform. Am i missing something? I havent seen that you reference the platform specific libs.

    Would be really nice to hear from you.
    Keep up the great work.

  54. Psyko says:

    Hello Wade,

    Thanks for the work on the RCP package.
    I’m trying to build an RCP app using Jogl and your com.jogamp.jogl plugin. While it works when testing from within Eclipse, it doesn’t work anymore when I export the product and shows the following error :
    java.lang.UnsatisfiedLinkError: Can’t load library: C:\Users\…..\\win32\win32\x86_64\gluegen-rt.dll

    The shown folder is the output directory of my tycho build (this is the folder I launch the compiled product from)

    I do have the Resolver in my createControl but I don’t really understand what it’s supposed to do.
    Shouldn’t the app be looking for the dll inside the jar file packaged in your plugin ?

    I’m using Eclipse Mars and Tycho for the build.

    Thanks in advance

    • Wade Walker says:

      Hi Psyko,

      Sorry this took me a couple days to get to; I just got back from a vacation 🙂

      The URL resolver is needed because when you’re loading files from an Eclipse plugin, they have URLs that use a special internal Eclipse URL scheme that can’t be resolved to file system path without some help from Eclipse itself. The resolver lets JOGL call Eclipse’s internal URL resolver without making JOGL dependent on Eclipse directly.

      Perhaps due to the way your program works, you’re loading JOGL before the resolver is set up? Try putting a print statement at the resolver setup point and see if it’s happening before you see the error message. If not, you may need to set the resolver earlier, or stop invoking JOGL code before the resolver is set.

  55. Psyko says:

    Thanks for the answer.

    I actually went back to having multiple fragments projects and embedding the natives lib in the JAR. AFAICT It works great with my Tycho build so I don’t need the resolver anymore. Since I’m working with Eclipse and have no plan to switch to some other platform, it will be fine 🙂

    BTW, the delta pack isn’t available anymore in latest Eclipse 4.5. That’s why I switched to tycho build with target platform. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=233789 which is a Wontfix.

  56. Irene Tang says:

    Hi, I am an amateur with JOGL. Recently, I’ve been trying to draw a 3D in SWT. I’ve been searching online for tutorials. I’ve found many JOGL used in AWT examples in which GLEventListener is often used, while less in SWT. The only JOGL used in SWT example I found is here http://jogamp.org/wiki/index.php/Using_JOGL_in_AWT_SWT_and_Swing. Why doesn’t SWT
    use GLEventListener? What’re the differences between com.jogamp.opengl.swt.GLCanvas and org.eclipse.swt.opengl.GLCanvas. I am very looking forward to your response.

    • Wade Walker says:

      Hi Irene,

      That JOGL example with SWT that you found is one that I wrote on the JogAmp wiki 🙂 javax.media.opengl.GLEventListener and the associated canvas javax.media.opengl.GLCanvas were part of the original Sun proposal for interfacing Java with OpenGL from way back in 2003, called JSR-231 (see https://jcp.org/en/jsr/detail?id=231). You can see the original documentation at http://download.java.net/media/jogl/builds/archive/jsr-231-beta5/javadoc_public/javax/media/opengl/package-summary.html. Sometime after 2008, Sun stopped supporting this effort for some reason, and it was spun off into the open-source project JogAmp. Eventually the package was moved from javax.media.opengl to com.jogamp.opengl because of some rules about what’s now supposed to go in javax (the other guys at JogAmp might know more details about this part).

      org.eclipse.swt.opengl.GLCanvas is Eclipse’s original GL canvas, and is part of the Eclipse project. Since it didn’t come out of the JSR-231 code, it doesn’t share anything in common with it, including GLEventListener. It has its own way of doing everything. I use this one in my examples because it was written as part of SWT, so the integration with SWT controls is probably a little better. However, the Eclipse guys haven’t added new features to it for a long time, so it doesn’t support things like anti-aliased rendering.

      com.jogamp.opengl.swt.GLCanvas is a GL canvas that JogAmp’s Sven Goethel wrote to provide a newer SWT canvas. He wrote it to be similar to the other canvases already in JogAmp, so he used GLEventListener instead of doing it how Eclipse had done it. This newer canvas supports anti-aliasing and more advanced pixel format selection. I haven’t used it much, though, so I can’t comment on how well it integrates into Eclipse RCP applications.

      I’d say if you’re writing an SWT program and don’t need anti-aliasing, use the original Eclipse GL canvas. Otherwise, try the new JogAmp GL canvas 🙂

      • Irene Tang says:

        Thanks a lot for answering that fast. The reason I asked you is because I got confused by so many examples online. And I need a more standard way from the beginning. What you said really gets things straight.
        Actually I have drawn a 3D already with the help of that JOGL example with SWT. Now, I want to draw a rectangle marking a selection of a part of the 3D. Here is what I wrote.
        MouseMoveListener mouseMoveDraw = new MouseMoveListener() {
        @Override
        public void mouseMove(MouseEvent e) {
        canvas.setCurrent();
        context.makeCurrent();
        drawRect(context.getGL().getGL2(), currentX, 480 – currentY, e.x, 480 – e.y);
        canvas.swapBuffers();
        context.release();
        }
        private void drawRect(GL2 gl2, int startX, int startY, int endX, int endY) {
        gl2.glBegin(GL2.GL_LINES);
        gl2.glVertex2f(startX, startY);
        gl2.glVertex2f(startX, endY);
        gl2.glVertex2f(endX, endY);
        gl2.glVertex2f(endX, startY);
        gl2.glEnd();
        }};
        public void mouseDown(MouseEvent e) {
        switch(e.button) {
        case 1 :
        updateMousePosition(e.x, e.y);
        canvas.addMouseMoveListener(mouseMoveRotate);
        break;
        case 3 :
        updateMousePosition(e.x, e.y);
        canvas.addMouseMoveListener(mouseMoveDraw);
        break;
        }
        }
        static void updateMousePosition(int x, int y) {
        currentX = x;
        currentY = y;
        }
        I was intended to draw a rectangle from the point where mouse down to point where mouse move. But it didn’t work. Please help me to find out the problem. Thank you!

        As for anti-aliasing, I set
        gl2.glEnable(GL2.GL_POINT_SMOOTH);
        gl2.glEnable(GL2.GL_LINE_SMOOTH);
        gl2.glHint(GL2.GL_LINE_SMOOTH, GL2.GL_NICEST);
        gl2.glHint(GL2.GL_POINT_SMOOTH, GL2.GL_NICEST);
        and it works well avoiding aliasing in lines, but bad in cyclinder. I have no idea. I think I may use org.eclipse.opengl.swt.GLCanvas first, cause I am kind of eager to get the programmer set up.

      • Wade Walker says:

        As far as solving problems with your OpenGL code, I’d urge you to start from working example code, then gradually modify it to do what you want, step by step. It’s hard for a beginner to write a bunch of new code at once and get it debugged — there are too many things that could be wrong, even with a short program. Even OpenGL experts often write a bunch of code and have it come up as a black screen 🙂

        For anti-aliasing, I should have been more specific. Anti-aliasing of lines will work in the Eclipse GL canvas, but full-screen anti-aliasing will not (since that’s a property of the GL canvas that there’s no easy way to turn on). So your lines will look fine, but polygon-based graphics will be aliased.

  57. John Reilly says:

    Hi Wade,

    Trying to use Eclipse Mars. I run your tutorial from over on github as an Eclipse RCP application and I get di.annotations as an unresolved bundle?

    !ENTRY org.eclipse.e4.ui.model.workbench 4 0 2016-05-18 09:48:52.737
    !MESSAGE FrameworkEvent ERROR
    !STACK 0
    org.osgi.framework.BundleException: Could not resolve module: org.eclipse.e4.ui.model.workbench [5]
    Unresolved requirement: Require-Bundle: org.eclipse.e4.core.services; bundle-version=”0.9.0″
    -> Bundle-SymbolicName: org.eclipse.e4.core.services; bundle-version=”2.0.0.v20150403-1912″; singleton:=”true”
    org.eclipse.e4.core.services [31]
    Unresolved requirement: Require-Bundle: org.eclipse.e4.core.di
    -> Bundle-SymbolicName: org.eclipse.e4.core.di; bundle-version=”1.5.0.v20150421-2214″
    org.eclipse.e4.core.di [8]
    Unresolved requirement: Require-Bundle: org.eclipse.e4.core.di.annotations; bundle-version=”[1.4.0,2.0.0)”; visibility:=”reexport”

    Any idea as to what I’ve done wrong?

    Thanks.

    -john.

    • Wade Walker says:

      Hi John,

      You may need to delete and re-create the Tutorial.product file (creation instructions are in the blog entry). I believe Eclipse puts package dependencies in there which are version-specific, so sometimes they need to be updated if Eclipse changes sufficiently. I’m traveling right now, so I can’t check it myself, but let me know if that works and I’ll update the repo.

  58. Pingback: The Beginning – already full of setbacks – Kapil Sinha's Blog

Leave a reply to gael Cancel reply