getData() {
+ double dXIncrement = 2.0 * Math.PI * (1.0 / siXIncrements);
+ double dX = -Math.PI;
+ for( int i = 0; i < siXIncrements; dX += dXIncrement, i++ ) {
+ double dY = Math.sin( dX + dT );
+ DataObject dataobject = listDataObjects.get( i );
+ dataobject.setX( dX );
+ dataobject.setY( dY > 0 ? 0 : dY );
+ dataobject.setWidth( dXIncrement );
+ dataobject.setHeight( Math.abs( dY ) );
+ }
+ return( listDataObjects );
+ }
+
+ //==============================================================================
+ /**
+ * Increments the current time.
+ * @param dDeltaT Amount to increment time by, in arbitrary units.
+ */
+ public void incrementTime( double dDeltaT ) {
+ dT += dDeltaT;
+ }
+}
diff --git a/src/name/wadewalker/tutorial/Perspective.java b/tutorial-plugin/src/name/wadewalker/tutorial/Perspective.java
similarity index 100%
rename from src/name/wadewalker/tutorial/Perspective.java
rename to tutorial-plugin/src/name/wadewalker/tutorial/Perspective.java
diff --git a/src/name/wadewalker/tutorial/jogleditor/JOGLEditor.java b/tutorial-plugin/src/name/wadewalker/tutorial/jogleditor/JOGLEditor.java
similarity index 90%
rename from src/name/wadewalker/tutorial/jogleditor/JOGLEditor.java
rename to tutorial-plugin/src/name/wadewalker/tutorial/jogleditor/JOGLEditor.java
index 8e840a2..7a57f9b 100644
--- a/src/name/wadewalker/tutorial/jogleditor/JOGLEditor.java
+++ b/tutorial-plugin/src/name/wadewalker/tutorial/jogleditor/JOGLEditor.java
@@ -1,479 +1,450 @@
-package name.wadewalker.tutorial.jogleditor;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.util.List;
-
-import javax.media.opengl.GL;
-import javax.media.opengl.GL2;
-import javax.media.opengl.GL2ES1;
-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 com.jogamp.common.nio.Buffers;
-import com.jogamp.common.util.JarUtil;
-
-import name.wadewalker.tutorial.Activator;
-import name.wadewalker.tutorial.DataSource;
-import name.wadewalker.tutorial.DataSource.DataObject;
-
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.bindings.keys.ParseException;
-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.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.part.EditorPart;
-
-//==============================================================================
-/**
- * Copyright (c) 2010-2011 Wade Walker. Free for any use, but credit is appreciated.
- * @author Wade Walker
- */
-public class JOGLEditor extends EditorPart {
-
- /** Workbench uses this ID to refer to instances of this type of editor. */
- public static final String ssID = "name.wadewalker.tutorial.jogleditor";
-
- /** Constant used in FPS calculation. */
- protected static final long slMillisecondsPerSecond = 1000;
-
- /** Ratio of world-space units to screen pixels.
- * Increasing this zooms the display out,
- * decreasing it zooms the display in. */
- protected static final float sfObjectUnitsPerPixel = 0.03f;
-
- /** Amount to increment time on each sim step. */
- protected static final double sdTimeStep = 0.005;
-
- /** Milliseconds to sleep in each render cycle. */
- protected static final int siSleepPerStepMS = 1;
-
- /** Holds the OpenGL canvas. */
- protected Composite composite;
-
- /** Widget that displays OpenGL content. */
- protected GLCanvas glcanvas;
-
- /** Used to get OpenGL object that we need to access OpenGL functions. */
- protected GLContext glcontext;
-
- /** Source of data to draw. */
- protected DataSource datasource;
-
- /** X distance to translate the viewport by. */
- protected float fViewTranslateX;
-
- /** Y distance to translate the viewport by. */
- protected float fViewTranslateY;
-
- /** Index of vertex buffer object. We store interleaved vertex and color data here
- * like this: x0, r0, y0, g0, z0, b0, x1, r1, y1, g1, z1, b1...
- * Stored in an array because glGenBuffers requires it. */
- protected int [] aiVertexBufferIndices = new int [] {-1};
-
- /** Number of frames drawn since last FPS calculation. */
- protected int iFPSFrames;
-
- /** Time in milliseconds at start of FPS calculation interval. */
- protected long lFPSIntervalStartTimeMS;
-
- //==============================================================================
- /**
- * Constructor.
- */
- public JOGLEditor() {
- datasource = new DataSource();
- }
-
- //==============================================================================
- /**
- * {@inheritDoc}
- */
- @Override
- public void doSave( IProgressMonitor iprogressmonitor ) {
- }
-
- //==============================================================================
- /**
- * {@inheritDoc}
- */
- @Override
- public void doSaveAs() {
- }
-
- //==============================================================================
- /**
- * Sets up key action handlers.
- * {@inheritDoc}
- */
- @Override
- public void init( IEditorSite ieditorsite, IEditorInput ieditorinput ) throws PartInitException {
-
- setSite( ieditorsite );
- if( ieditorinput != null )
- setInput( ieditorinput );
-
- // create action handlers
- try {
- Activator.createKeyBinding(
- new IAction [] {
- ieditorsite.getActionBars().getGlobalActionHandler( RunPauseAction.ssID ),
- },
- new String [] {
- "Space",
- },
- getSite() );
- }
- catch( ParseException parseexception ) {
- throw new PartInitException( parseexception.getMessage() );
- }
- catch( IOException ioexception ) {
- throw new PartInitException( ioexception.getMessage() );
- }
- }
-
- //==============================================================================
- /**
- * Disposes all OpenGL resources in case this view is closed and reopened.
- * @see org.eclipse.ui.part.WorkbenchPart#dispose()
- */
- @Override
- public void dispose() {
- disposeVertexBuffers();
- glcanvas.dispose();
- super.dispose();
- }
-
- //==============================================================================
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isDirty() {
- return false;
- }
-
- //==============================================================================
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isSaveAsAllowed() {
- return false;
- }
-
- //==============================================================================
- /**
- * Sets up an OpenGL canvas to draw in.
- * {@inheritDoc}
- */
- @Override
- public void createPartControl( Composite compositeParent ) {
- JarUtil.setResolver( new JarUtil.Resolver() {
- public URL resolve( URL url ) {
- try {
- URL urlTest = FileLocator.resolve( url );
- // HACK: required because FileLocator.resolve() doesn't return an
- // escaped URL, which makes conversion to a URI inside JOGL fail.
- // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=145096 for details.
- URI uriResolved = null;
- try {
- uriResolved = new URI(urlTest.getProtocol(), urlTest.getPath(), null);
- }
- catch( URISyntaxException urisyntaxexception ) {
- // should never happen, since FileLocator's URLs should at least be syntactically correct
- urisyntaxexception.printStackTrace();
- }
- URL urlNew = uriResolved.toURL();
- return( urlNew );
- }
- catch( IOException ioexception ) {
- return( url );
- }
- }
- } );
-
- 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 ) {
- glcanvas.setCurrent();
- glcontext.makeCurrent();
- GL2 gl2 = glcontext.getGL().getGL2();
- setTransformsAndViewport( gl2 );
- glcontext.release();
- }
- });
-
- glcontext.makeCurrent();
- GL2 gl2 = glcontext.getGL().getGL2();
- gl2.setSwapInterval( 1 );
- gl2.glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
- gl2.glColor3f( 1.0f, 0.0f, 0.0f );
- gl2.glHint( GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST );
- gl2.glClearDepth( 1.0 );
- gl2.glLineWidth( 2 );
- gl2.glEnable( GL.GL_DEPTH_TEST );
- glcontext.release();
-
- // spawn a worker thread to call the renderer in a loop until the program closes.
- (new Thread() {
- public void run() {
-
- // look at the run/pause button state to see whether we should be running or not
- RunPauseAction runpauseaction = (RunPauseAction)getEditorSite().getActionBars().getGlobalActionHandler( RunPauseAction.ssID );
-
- // render once to get it on screen (we start out paused)
- render();
-
- try {
- while( (glcanvas != null) && !glcanvas.isDisposed() ) {
- // if we're running, render in the GUI thread
- if( runpauseaction.isRunning() )
- render();
- // else we're paused, so sleep for a little so we don't peg the CPU
- else
- sleep( siSleepPerStepMS );
- }
- }
- catch( InterruptedException interruptedexception ) {
- // if sleep interrupted just let the thread quite
- }
- }
- }).start();
- }
-
- //==============================================================================
- /**
- * Calculates the FPS and shows it in the status line.
- */
- protected void calculateAndShowFPS() {
- ++iFPSFrames;
- long lTime = System.currentTimeMillis();
- // update the FPS (once per second at most, to avoid flooding
- // the UI with text updates)
- long lTimeIntervalMS = lTime - lFPSIntervalStartTimeMS;
- if( lTimeIntervalMS >= slMillisecondsPerSecond ) {
- lFPSIntervalStartTimeMS = lTime;
- int iFPS = (int)((double)(iFPSFrames * slMillisecondsPerSecond) / (double)lTimeIntervalMS);
- iFPSFrames = 0;
- getEditorSite().getActionBars().getStatusLineManager().setMessage( String.format( "FPS: %d", iFPS ) );
- }
- }
-
- //==============================================================================
- /**
- * Renders into the GUI thread synchronously. Meant to be called
- * from a worker thread.
- */
- private void render() {
-
- PlatformUI.getWorkbench().getDisplay().syncExec( new Runnable() {
- public void run() {
- if( (glcanvas != null) && !glcanvas.isDisposed() ) {
- glcanvas.setCurrent();
- glcontext.makeCurrent();
- GL2 gl2 = glcontext.getGL().getGL2();
- gl2.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
- gl2.glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
-
- // create vertex buffers if needed, then copy data in
- int [] aiNumOfVertices = createAndFillVertexBuffer( gl2, datasource.getData() );
-
- // needed so material for quads will be set from color map
- gl2.glColorMaterial( GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT_AND_DIFFUSE );
- gl2.glEnable( GL2.GL_COLOR_MATERIAL );
-
- // draw all quads in vertex buffer
- gl2.glBindBuffer( GL.GL_ARRAY_BUFFER, aiVertexBufferIndices[0] );
- gl2.glEnableClientState( GL2.GL_VERTEX_ARRAY );
- gl2.glEnableClientState( GL2.GL_COLOR_ARRAY );
- gl2.glVertexPointer( 3, GL.GL_FLOAT, 6 * Buffers.SIZEOF_FLOAT, 0 );
- gl2.glColorPointer( 3, GL.GL_FLOAT, 6 * Buffers.SIZEOF_FLOAT, 3 * Buffers.SIZEOF_FLOAT );
- gl2.glPolygonMode( GL.GL_FRONT, GL2.GL_FILL );
- gl2.glDrawArrays( GL2.GL_QUADS, 0, aiNumOfVertices[0] );
-
- // disable arrays once we're done
- gl2.glBindBuffer( GL.GL_ARRAY_BUFFER, 0 );
- gl2.glDisableClientState( GL2.GL_VERTEX_ARRAY );
- gl2.glDisableClientState( GL2.GL_COLOR_ARRAY );
- gl2.glDisable( GL2.GL_COLOR_MATERIAL );
-
- glcanvas.swapBuffers();
- glcontext.release();
-
- // advance time so the data changes for the next frame
- datasource.incrementTime( sdTimeStep );
-
- calculateAndShowFPS();
- }
- }
- });
- }
-
- //==============================================================================
- /**
- * Sets up an orthogonal projection suitable for a 2D CAD program.
- *
- * @param gl2 GL object to set transforms and viewport on.
- */
- protected void setTransformsAndViewport( GL2 gl2 ) {
-
- Rectangle rectangle = glcanvas.getClientArea();
- int iWidth = rectangle.width;
- int iHeight = Math.max( rectangle.height, 1 );
-
- gl2.glMatrixMode( GLMatrixFunc.GL_PROJECTION );
- gl2.glLoadIdentity();
-
- // set the clipping planes based on the ratio of object units
- // to screen pixels, but preserving the correct aspect ratio
- GLU glu = new GLU();
- glu.gluOrtho2D( -(sfObjectUnitsPerPixel * iWidth) / 2.0f,
- (sfObjectUnitsPerPixel * iWidth) / 2.0f,
- -(sfObjectUnitsPerPixel * iHeight) / 2.0f,
- (sfObjectUnitsPerPixel * iHeight) / 2.0f );
-
- gl2.glMatrixMode( GLMatrixFunc.GL_MODELVIEW );
- gl2.glViewport( 0, 0, iWidth, iHeight );
- gl2.glLoadIdentity();
- gl2.glTranslatef( fViewTranslateX, fViewTranslateY, 0.0f );
- }
-
- //==============================================================================
- /**
- * Creates vertex buffer object used to store vertices and colors
- * (if it doesn't exist). Fills the object with the latest
- * vertices and colors from the data store.
- *
- * @param gl2 GL object used to access all GL functions.
- * @param listDataObjects Data objects to get vertices from.
- * @return the number of vertices in each of the buffers.
- */
- protected int [] createAndFillVertexBuffer( GL2 gl2, List listDataObjects ) {
-
- int [] aiNumOfVertices = new int [] {listDataObjects.size() * 4};
-
- // create vertex buffer object if needed
- if( aiVertexBufferIndices[0] == -1 ) {
- // check for VBO support
- if( !gl2.isFunctionAvailable( "glGenBuffers" )
- || !gl2.isFunctionAvailable( "glBindBuffer" )
- || !gl2.isFunctionAvailable( "glBufferData" )
- || !gl2.isFunctionAvailable( "glDeleteBuffers" ) ) {
- Activator.openError( "Error", "Vertex buffer objects not supported." );
- }
-
- gl2.glGenBuffers( 1, aiVertexBufferIndices, 0 );
-
- // create vertex buffer data store without initial copy
- gl2.glBindBuffer( GL.GL_ARRAY_BUFFER, aiVertexBufferIndices[0] );
- gl2.glBufferData( GL.GL_ARRAY_BUFFER,
- aiNumOfVertices[0] * 3 * Buffers.SIZEOF_FLOAT * 2,
- null,
- GL2.GL_DYNAMIC_DRAW );
- }
-
- // map the buffer and write vertex and color data directly into it
- gl2.glBindBuffer( GL.GL_ARRAY_BUFFER, aiVertexBufferIndices[0] );
- ByteBuffer bytebuffer = gl2.glMapBuffer( GL.GL_ARRAY_BUFFER, GL2.GL_WRITE_ONLY );
- FloatBuffer floatbuffer = bytebuffer.order( ByteOrder.nativeOrder() ).asFloatBuffer();
-
- for( DataObject dataobject : listDataObjects )
- storeVerticesAndColors( floatbuffer, dataobject );
-
- gl2.glUnmapBuffer( GL.GL_ARRAY_BUFFER );
-
- return( aiNumOfVertices );
- }
-
- //==============================================================================
- /**
- * Stores the vertices and colors of one object interleaved into
- * a buffer (vertices in counterclockwise order).
- * @param floatbuffer Buffer to store vertices and colors in.
- * @param dataobject Object whose vertices and colors are stored.
- */
- protected void storeVerticesAndColors( FloatBuffer floatbuffer, DataObject dataobject ) {
-
- floatbuffer.put( dataobject.getX() );
- floatbuffer.put( dataobject.getY() );
- floatbuffer.put( 0.0f );
-
- floatbuffer.put( dataobject.getColor()[0] );
- floatbuffer.put( dataobject.getColor()[1] );
- floatbuffer.put( dataobject.getColor()[2] );
-
- floatbuffer.put( dataobject.getX() + dataobject.getWidth() );
- floatbuffer.put( dataobject.getY() );
- floatbuffer.put( 0.0f );
-
- floatbuffer.put( dataobject.getColor()[0] );
- floatbuffer.put( dataobject.getColor()[1] );
- floatbuffer.put( dataobject.getColor()[2] );
-
- floatbuffer.put( dataobject.getX() + dataobject.getWidth() );
- floatbuffer.put( dataobject.getY() + dataobject.getHeight() );
- floatbuffer.put( 0.0f );
-
- floatbuffer.put( dataobject.getColor()[0] );
- floatbuffer.put( dataobject.getColor()[1] );
- floatbuffer.put( dataobject.getColor()[2] );
-
- floatbuffer.put( dataobject.getX() );
- floatbuffer.put( dataobject.getY() + dataobject.getHeight() );
- floatbuffer.put( 0.0f );
-
- floatbuffer.put( dataobject.getColor()[0] );
- floatbuffer.put( dataobject.getColor()[1] );
- floatbuffer.put( dataobject.getColor()[2] );
- }
-
- //==============================================================================
- /**
- * Deletes the vertex and color buffers.
- */
- protected void disposeVertexBuffers() {
- glcontext.makeCurrent();
- GL2 gl2 = glcontext.getGL().getGL2();
- gl2.glDeleteBuffers( 1, aiVertexBufferIndices, 0 );
- aiVertexBufferIndices[0] = -1;
- glcontext.release();
- }
-
- //==============================================================================
- /**
- * {@inheritDoc}
- */
- @Override
- public void setFocus() {
- }
-}
+package name.wadewalker.tutorial.jogleditor;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.List;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES1;
+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 com.jogamp.common.nio.Buffers;
+
+import name.wadewalker.tutorial.Activator;
+import name.wadewalker.tutorial.DataSource;
+import name.wadewalker.tutorial.DataSource.DataObject;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.bindings.keys.ParseException;
+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.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.EditorPart;
+
+//==============================================================================
+/**
+ * Copyright (c) 2010-2011 Wade Walker. Free for any use, but credit is appreciated.
+ * @author Wade Walker
+ */
+public class JOGLEditor extends EditorPart {
+
+ /** Workbench uses this ID to refer to instances of this type of editor. */
+ public static final String ssID = "name.wadewalker.tutorial.jogleditor";
+
+ /** Constant used in FPS calculation. */
+ protected static final long slMillisecondsPerSecond = 1000;
+
+ /** Ratio of world-space units to screen pixels.
+ * Increasing this zooms the display out,
+ * decreasing it zooms the display in. */
+ protected static final float sfObjectUnitsPerPixel = 0.03f;
+
+ /** Amount to increment time on each sim step. */
+ protected static final double sdTimeStep = 0.005;
+
+ /** Milliseconds to sleep in each render cycle. */
+ protected static final int siSleepPerStepMS = 1;
+
+ /** Holds the OpenGL canvas. */
+ protected Composite composite;
+
+ /** Widget that displays OpenGL content. */
+ protected GLCanvas glcanvas;
+
+ /** Used to get OpenGL object that we need to access OpenGL functions. */
+ protected GLContext glcontext;
+
+ /** Source of data to draw. */
+ protected DataSource datasource;
+
+ /** X distance to translate the viewport by. */
+ protected float fViewTranslateX;
+
+ /** Y distance to translate the viewport by. */
+ protected float fViewTranslateY;
+
+ /** Index of vertex buffer object. We store interleaved vertex and color data here
+ * like this: x0, r0, y0, g0, z0, b0, x1, r1, y1, g1, z1, b1...
+ * Stored in an array because glGenBuffers requires it. */
+ protected int [] aiVertexBufferIndices = new int [] {-1};
+
+ /** Number of frames drawn since last FPS calculation. */
+ protected int iFPSFrames;
+
+ /** Time in milliseconds at start of FPS calculation interval. */
+ protected long lFPSIntervalStartTimeMS;
+
+ //==============================================================================
+ /**
+ * Constructor.
+ */
+ public JOGLEditor() {
+ datasource = new DataSource();
+ }
+
+ //==============================================================================
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void doSave( IProgressMonitor iprogressmonitor ) {
+ }
+
+ //==============================================================================
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void doSaveAs() {
+ }
+
+ //==============================================================================
+ /**
+ * Sets up key action handlers.
+ * {@inheritDoc}
+ */
+ @Override
+ public void init( IEditorSite ieditorsite, IEditorInput ieditorinput ) throws PartInitException {
+
+ setSite( ieditorsite );
+ if( ieditorinput != null )
+ setInput( ieditorinput );
+
+ // create action handlers
+ try {
+ Activator.createKeyBinding(
+ new IAction [] {
+ ieditorsite.getActionBars().getGlobalActionHandler( RunPauseAction.ssID ),
+ },
+ new String [] {
+ "Space",
+ },
+ getSite() );
+ }
+ catch( ParseException parseexception ) {
+ throw new PartInitException( parseexception.getMessage() );
+ }
+ catch( IOException ioexception ) {
+ throw new PartInitException( ioexception.getMessage() );
+ }
+ }
+
+ //==============================================================================
+ /**
+ * Disposes all OpenGL resources in case this view is closed and reopened.
+ * @see org.eclipse.ui.part.WorkbenchPart#dispose()
+ */
+ @Override
+ public void dispose() {
+ disposeVertexBuffers();
+ glcanvas.dispose();
+ super.dispose();
+ }
+
+ //==============================================================================
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isDirty() {
+ return false;
+ }
+
+ //==============================================================================
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isSaveAsAllowed() {
+ return false;
+ }
+
+ //==============================================================================
+ /**
+ * Sets up an OpenGL canvas to draw in.
+ * {@inheritDoc}
+ */
+ @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 ) {
+ glcanvas.setCurrent();
+ glcontext.makeCurrent();
+ GL2 gl2 = glcontext.getGL().getGL2();
+ setTransformsAndViewport( gl2 );
+ glcontext.release();
+ }
+ });
+
+ glcontext.makeCurrent();
+ GL2 gl2 = glcontext.getGL().getGL2();
+ gl2.setSwapInterval( 1 );
+ gl2.glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
+ gl2.glColor3f( 1.0f, 0.0f, 0.0f );
+ gl2.glHint( GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST );
+ gl2.glClearDepth( 1.0 );
+ gl2.glLineWidth( 2 );
+ gl2.glEnable( GL.GL_DEPTH_TEST );
+ glcontext.release();
+
+ // spawn a worker thread to call the renderer in a loop until the program closes.
+ (new Thread() {
+ public void run() {
+
+ // look at the run/pause button state to see whether we should be running or not
+ RunPauseAction runpauseaction = (RunPauseAction)getEditorSite().getActionBars().getGlobalActionHandler( RunPauseAction.ssID );
+
+ // render once to get it on screen (we start out paused)
+ render();
+
+ try {
+ while( (glcanvas != null) && !glcanvas.isDisposed() ) {
+ // if we're running, render in the GUI thread
+ if( runpauseaction.isRunning() )
+ render();
+ // else we're paused, so sleep for a little so we don't peg the CPU
+ else
+ sleep( siSleepPerStepMS );
+ }
+ }
+ catch( InterruptedException interruptedexception ) {
+ // if sleep interrupted just let the thread quite
+ }
+ }
+ }).start();
+ }
+
+ //==============================================================================
+ /**
+ * Calculates the FPS and shows it in the status line.
+ */
+ protected void calculateAndShowFPS() {
+ ++iFPSFrames;
+ long lTime = System.currentTimeMillis();
+ // update the FPS (once per second at most, to avoid flooding
+ // the UI with text updates)
+ long lTimeIntervalMS = lTime - lFPSIntervalStartTimeMS;
+ if( lTimeIntervalMS >= slMillisecondsPerSecond ) {
+ lFPSIntervalStartTimeMS = lTime;
+ int iFPS = (int)((double)(iFPSFrames * slMillisecondsPerSecond) / (double)lTimeIntervalMS);
+ iFPSFrames = 0;
+ getEditorSite().getActionBars().getStatusLineManager().setMessage( String.format( "FPS: %d", iFPS ) );
+ }
+ }
+
+ //==============================================================================
+ /**
+ * Renders into the GUI thread synchronously. Meant to be called
+ * from a worker thread.
+ */
+ private void render() {
+
+ PlatformUI.getWorkbench().getDisplay().syncExec( new Runnable() {
+ public void run() {
+ if( (glcanvas != null) && !glcanvas.isDisposed() ) {
+ glcanvas.setCurrent();
+ glcontext.makeCurrent();
+ GL2 gl2 = glcontext.getGL().getGL2();
+ gl2.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
+ gl2.glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
+
+ // create vertex buffers if needed, then copy data in
+ int [] aiNumOfVertices = createAndFillVertexBuffer( gl2, datasource.getData() );
+
+ // needed so material for quads will be set from color map
+ gl2.glColorMaterial( GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT_AND_DIFFUSE );
+ gl2.glEnable( GL2.GL_COLOR_MATERIAL );
+
+ // draw all quads in vertex buffer
+ gl2.glBindBuffer( GL.GL_ARRAY_BUFFER, aiVertexBufferIndices[0] );
+ gl2.glEnableClientState( GL2.GL_VERTEX_ARRAY );
+ gl2.glEnableClientState( GL2.GL_COLOR_ARRAY );
+ gl2.glVertexPointer( 3, GL.GL_FLOAT, 6 * Buffers.SIZEOF_FLOAT, 0 );
+ gl2.glColorPointer( 3, GL.GL_FLOAT, 6 * Buffers.SIZEOF_FLOAT, 3 * Buffers.SIZEOF_FLOAT );
+ gl2.glPolygonMode( GL.GL_FRONT, GL2.GL_FILL );
+ gl2.glDrawArrays( GL2.GL_QUADS, 0, aiNumOfVertices[0] );
+
+ // disable arrays once we're done
+ gl2.glBindBuffer( GL.GL_ARRAY_BUFFER, 0 );
+ gl2.glDisableClientState( GL2.GL_VERTEX_ARRAY );
+ gl2.glDisableClientState( GL2.GL_COLOR_ARRAY );
+ gl2.glDisable( GL2.GL_COLOR_MATERIAL );
+
+ glcanvas.swapBuffers();
+ glcontext.release();
+
+ // advance time so the data changes for the next frame
+ datasource.incrementTime( sdTimeStep );
+
+ calculateAndShowFPS();
+ }
+ }
+ });
+ }
+
+ //==============================================================================
+ /**
+ * Sets up an orthogonal projection suitable for a 2D CAD program.
+ *
+ * @param gl2 GL object to set transforms and viewport on.
+ */
+ protected void setTransformsAndViewport( GL2 gl2 ) {
+
+ Rectangle rectangle = glcanvas.getClientArea();
+ int iWidth = rectangle.width;
+ int iHeight = Math.max( rectangle.height, 1 );
+
+ gl2.glMatrixMode( GLMatrixFunc.GL_PROJECTION );
+ gl2.glLoadIdentity();
+
+ // set the clipping planes based on the ratio of object units
+ // to screen pixels, but preserving the correct aspect ratio
+ GLU glu = new GLU();
+ glu.gluOrtho2D( -(sfObjectUnitsPerPixel * iWidth) / 2.0f,
+ (sfObjectUnitsPerPixel * iWidth) / 2.0f,
+ -(sfObjectUnitsPerPixel * iHeight) / 2.0f,
+ (sfObjectUnitsPerPixel * iHeight) / 2.0f );
+
+ gl2.glMatrixMode( GLMatrixFunc.GL_MODELVIEW );
+ gl2.glViewport( 0, 0, iWidth, iHeight );
+ gl2.glLoadIdentity();
+ gl2.glTranslatef( fViewTranslateX, fViewTranslateY, 0.0f );
+ }
+
+ //==============================================================================
+ /**
+ * Creates vertex buffer object used to store vertices and colors
+ * (if it doesn't exist). Fills the object with the latest
+ * vertices and colors from the data store.
+ *
+ * @param gl2 GL object used to access all GL functions.
+ * @param listDataObjects Data objects to get vertices from.
+ * @return the number of vertices in each of the buffers.
+ */
+ protected int [] createAndFillVertexBuffer( GL2 gl2, List listDataObjects ) {
+
+ int [] aiNumOfVertices = new int [] {listDataObjects.size() * 4};
+
+ // create vertex buffer object if needed
+ if( aiVertexBufferIndices[0] == -1 ) {
+ // check for VBO support
+ if( !gl2.isFunctionAvailable( "glGenBuffers" )
+ || !gl2.isFunctionAvailable( "glBindBuffer" )
+ || !gl2.isFunctionAvailable( "glBufferData" )
+ || !gl2.isFunctionAvailable( "glDeleteBuffers" ) ) {
+ Activator.openError( "Error", "Vertex buffer objects not supported." );
+ }
+
+ gl2.glGenBuffers( 1, aiVertexBufferIndices, 0 );
+
+ // create vertex buffer data store without initial copy
+ gl2.glBindBuffer( GL.GL_ARRAY_BUFFER, aiVertexBufferIndices[0] );
+ gl2.glBufferData( GL.GL_ARRAY_BUFFER,
+ aiNumOfVertices[0] * 3 * Buffers.SIZEOF_FLOAT * 2,
+ null,
+ GL2.GL_DYNAMIC_DRAW );
+ }
+
+ // map the buffer and write vertex and color data directly into it
+ gl2.glBindBuffer( GL.GL_ARRAY_BUFFER, aiVertexBufferIndices[0] );
+ ByteBuffer bytebuffer = gl2.glMapBuffer( GL.GL_ARRAY_BUFFER, GL2.GL_WRITE_ONLY );
+ FloatBuffer floatbuffer = bytebuffer.order( ByteOrder.nativeOrder() ).asFloatBuffer();
+
+ for( DataObject dataobject : listDataObjects )
+ storeVerticesAndColors( floatbuffer, dataobject );
+
+ gl2.glUnmapBuffer( GL.GL_ARRAY_BUFFER );
+
+ return( aiNumOfVertices );
+ }
+
+ //==============================================================================
+ /**
+ * Stores the vertices and colors of one object interleaved into
+ * a buffer (vertices in counterclockwise order).
+ * @param floatbuffer Buffer to store vertices and colors in.
+ * @param dataobject Object whose vertices and colors are stored.
+ */
+ protected void storeVerticesAndColors( FloatBuffer floatbuffer, DataObject dataobject ) {
+
+ floatbuffer.put( dataobject.getX() );
+ floatbuffer.put( dataobject.getY() );
+ floatbuffer.put( 0.0f );
+
+ floatbuffer.put( dataobject.getColor()[0] );
+ floatbuffer.put( dataobject.getColor()[1] );
+ floatbuffer.put( dataobject.getColor()[2] );
+
+ floatbuffer.put( dataobject.getX() + dataobject.getWidth() );
+ floatbuffer.put( dataobject.getY() );
+ floatbuffer.put( 0.0f );
+
+ floatbuffer.put( dataobject.getColor()[0] );
+ floatbuffer.put( dataobject.getColor()[1] );
+ floatbuffer.put( dataobject.getColor()[2] );
+
+ floatbuffer.put( dataobject.getX() + dataobject.getWidth() );
+ floatbuffer.put( dataobject.getY() + dataobject.getHeight() );
+ floatbuffer.put( 0.0f );
+
+ floatbuffer.put( dataobject.getColor()[0] );
+ floatbuffer.put( dataobject.getColor()[1] );
+ floatbuffer.put( dataobject.getColor()[2] );
+
+ floatbuffer.put( dataobject.getX() );
+ floatbuffer.put( dataobject.getY() + dataobject.getHeight() );
+ floatbuffer.put( 0.0f );
+
+ floatbuffer.put( dataobject.getColor()[0] );
+ floatbuffer.put( dataobject.getColor()[1] );
+ floatbuffer.put( dataobject.getColor()[2] );
+ }
+
+ //==============================================================================
+ /**
+ * Deletes the vertex and color buffers.
+ */
+ protected void disposeVertexBuffers() {
+ glcontext.makeCurrent();
+ GL2 gl2 = glcontext.getGL().getGL2();
+ gl2.glDeleteBuffers( 1, aiVertexBufferIndices, 0 );
+ aiVertexBufferIndices[0] = -1;
+ glcontext.release();
+ }
+
+ //==============================================================================
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setFocus() {
+ }
+}
diff --git a/src/name/wadewalker/tutorial/jogleditor/JOGLEditorActionBarContributor.java b/tutorial-plugin/src/name/wadewalker/tutorial/jogleditor/JOGLEditorActionBarContributor.java
similarity index 97%
rename from src/name/wadewalker/tutorial/jogleditor/JOGLEditorActionBarContributor.java
rename to tutorial-plugin/src/name/wadewalker/tutorial/jogleditor/JOGLEditorActionBarContributor.java
index 69e206e..d45fe03 100644
--- a/src/name/wadewalker/tutorial/jogleditor/JOGLEditorActionBarContributor.java
+++ b/tutorial-plugin/src/name/wadewalker/tutorial/jogleditor/JOGLEditorActionBarContributor.java
@@ -1,55 +1,55 @@
-package name.wadewalker.tutorial.jogleditor;
-
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.part.EditorActionBarContributor;
-
-//==============================================================================
-/**
- * Contributes the JOGLEditor's actions to the action bar.
- *
- * Copyright (c) 2010-2011 Wade Walker. Free for any use, but credit is appreciated.
- * @author Wade Walker
- */
-public class JOGLEditorActionBarContributor extends EditorActionBarContributor {
-
- /** Runs and pauses the simulation. */
- private RunPauseAction runpauseaction;
-
- //==============================================================================
- /**
- * Constructor. Creates the actions.
- */
- public JOGLEditorActionBarContributor() {
- runpauseaction = new RunPauseAction();
- }
-
- //==============================================================================
- /**
- * Registers action handlers.
- *
- * @param iactionbars Used to register global actions.
- * @param iworkbenchpage Used to set part listeners.
- * @see org.eclipse.ui.part.EditorActionBarContributor#init(org.eclipse.ui.IActionBars, org.eclipse.ui.IWorkbenchPage)
- */
- @Override
- public void init( IActionBars iactionbars, IWorkbenchPage iworkbenchpage ) {
- super.init( iactionbars, iworkbenchpage );
-
- // register handlers
- iactionbars.setGlobalActionHandler( RunPauseAction.ssID, runpauseaction );
- }
-
- //==============================================================================
- /**
- * Contributes the editor's actions to the tool bar.
- *
- * @param itoolbarmanager Used to add actions to the editor tool bar.
- * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToToolBar(org.eclipse.jface.action.IToolBarManager)
- */
- @Override
- public void contributeToToolBar( IToolBarManager itoolbarmanager ) {
- itoolbarmanager.add( runpauseaction );
- }
-}
+package name.wadewalker.tutorial.jogleditor;
+
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+//==============================================================================
+/**
+ * Contributes the JOGLEditor's actions to the action bar.
+ *
+ * Copyright (c) 2010-2011 Wade Walker. Free for any use, but credit is appreciated.
+ * @author Wade Walker
+ */
+public class JOGLEditorActionBarContributor extends EditorActionBarContributor {
+
+ /** Runs and pauses the simulation. */
+ private RunPauseAction runpauseaction;
+
+ //==============================================================================
+ /**
+ * Constructor. Creates the actions.
+ */
+ public JOGLEditorActionBarContributor() {
+ runpauseaction = new RunPauseAction();
+ }
+
+ //==============================================================================
+ /**
+ * Registers action handlers.
+ *
+ * @param iactionbars Used to register global actions.
+ * @param iworkbenchpage Used to set part listeners.
+ * @see org.eclipse.ui.part.EditorActionBarContributor#init(org.eclipse.ui.IActionBars, org.eclipse.ui.IWorkbenchPage)
+ */
+ @Override
+ public void init( IActionBars iactionbars, IWorkbenchPage iworkbenchpage ) {
+ super.init( iactionbars, iworkbenchpage );
+
+ // register handlers
+ iactionbars.setGlobalActionHandler( RunPauseAction.ssID, runpauseaction );
+ }
+
+ //==============================================================================
+ /**
+ * Contributes the editor's actions to the tool bar.
+ *
+ * @param itoolbarmanager Used to add actions to the editor tool bar.
+ * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToToolBar(org.eclipse.jface.action.IToolBarManager)
+ */
+ @Override
+ public void contributeToToolBar( IToolBarManager itoolbarmanager ) {
+ itoolbarmanager.add( runpauseaction );
+ }
+}
diff --git a/src/name/wadewalker/tutorial/jogleditor/JOGLEditorInput.java b/tutorial-plugin/src/name/wadewalker/tutorial/jogleditor/JOGLEditorInput.java
similarity index 96%
rename from src/name/wadewalker/tutorial/jogleditor/JOGLEditorInput.java
rename to tutorial-plugin/src/name/wadewalker/tutorial/jogleditor/JOGLEditorInput.java
index 1b68caa..33bc1ed 100644
--- a/src/name/wadewalker/tutorial/jogleditor/JOGLEditorInput.java
+++ b/tutorial-plugin/src/name/wadewalker/tutorial/jogleditor/JOGLEditorInput.java
@@ -1,80 +1,80 @@
-package name.wadewalker.tutorial.jogleditor;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IPersistableElement;
-
-//==============================================================================
-/**
- * Editor input object for the JOGL editor. Currently these editors
- * aren't associated with any files, but eventually they will be.
- *
- * Copyright (c) 2010-2011 Wade Walker. Free for any use, but credit is appreciated.
- * @author Wade Walker
- */
-public class JOGLEditorInput implements IEditorInput {
-
- //==============================================================================
- /**
- * Returns an object which is an instance of the given class
- * associated with this object. Returns null if no such object can
- * be found.
- *
- * @param classAdapter the adapter class to look up.
- * @return an object castable to the given class, or null if this
- * object does not have an adapter for the given class.
- * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
- */
- @SuppressWarnings("rawtypes")
- public Object getAdapter( Class classAdapter ) {
- if( classAdapter.equals( JOGLEditorInput.class ) )
- return this;
-
- return null;
- }
-
- //==============================================================================
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean exists() {
- return true;
- }
-
- //==============================================================================
- /**
- * {@inheritDoc}
- */
- @Override
- public ImageDescriptor getImageDescriptor() {
- return null;
- }
-
- //==============================================================================
- /**
- * {@inheritDoc}
- */
- @Override
- public String getName() {
- return "JOGLEditor";
- }
-
- //==============================================================================
- /**
- * {@inheritDoc}
- */
- @Override
- public IPersistableElement getPersistable() {
- return null;
- }
-
- //==============================================================================
- /**
- * {@inheritDoc}
- */
- @Override
- public String getToolTipText() {
- return "Editor that uses JOGL";
- }
-}
+package name.wadewalker.tutorial.jogleditor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPersistableElement;
+
+//==============================================================================
+/**
+ * Editor input object for the JOGL editor. Currently these editors
+ * aren't associated with any files, but eventually they will be.
+ *
+ * Copyright (c) 2010-2011 Wade Walker. Free for any use, but credit is appreciated.
+ * @author Wade Walker
+ */
+public class JOGLEditorInput implements IEditorInput {
+
+ //==============================================================================
+ /**
+ * Returns an object which is an instance of the given class
+ * associated with this object. Returns null if no such object can
+ * be found.
+ *
+ * @param classAdapter the adapter class to look up.
+ * @return an object castable to the given class, or null if this
+ * object does not have an adapter for the given class.
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getAdapter( Class classAdapter ) {
+ if( classAdapter.equals( JOGLEditorInput.class ) )
+ return this;
+
+ return null;
+ }
+
+ //==============================================================================
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean exists() {
+ return true;
+ }
+
+ //==============================================================================
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ImageDescriptor getImageDescriptor() {
+ return null;
+ }
+
+ //==============================================================================
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getName() {
+ return "JOGLEditor";
+ }
+
+ //==============================================================================
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IPersistableElement getPersistable() {
+ return null;
+ }
+
+ //==============================================================================
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getToolTipText() {
+ return "Editor that uses JOGL";
+ }
+}
diff --git a/src/name/wadewalker/tutorial/jogleditor/RunPauseAction.java b/tutorial-plugin/src/name/wadewalker/tutorial/jogleditor/RunPauseAction.java
similarity index 96%
rename from src/name/wadewalker/tutorial/jogleditor/RunPauseAction.java
rename to tutorial-plugin/src/name/wadewalker/tutorial/jogleditor/RunPauseAction.java
index e223bcf..eeb45a3 100644
--- a/src/name/wadewalker/tutorial/jogleditor/RunPauseAction.java
+++ b/tutorial-plugin/src/name/wadewalker/tutorial/jogleditor/RunPauseAction.java
@@ -1,62 +1,62 @@
-package name.wadewalker.tutorial.jogleditor;
-
-import name.wadewalker.tutorial.Activator;
-
-import org.eclipse.jface.action.Action;
-
-//==============================================================================
-/**
- * Runs or pauses the simulation on alternate button presses.
- * Changes the picture and tooltip of the button accordingly.
- *
- * Copyright (c) 2010-2011 Wade Walker. Free for any use, but credit is appreciated.
- * @author Wade Walker
- */
-public class RunPauseAction extends Action {
-
- /** Unique action ID for the Eclipse platform. */
- public static final String ssID = "JOGLEditor.RunPauseAction";
-
- /** True if the simulation is running, false if it's paused. */
- private boolean bRunning;
-
- //==============================================================================
- /**
- * Constructor.
- */
- public RunPauseAction() {
- super( "Run", Action.AS_PUSH_BUTTON );
- setToolTipText( "Run simulation" );
- setImageDescriptor( Activator.getIcon( "jogleditor/resume_co.gif" ) );
- setId( ssID );
- setActionDefinitionId( ssID );
- }
-
- //==============================================================================
- /**
- * Code to run the action.
- *
- * @see org.eclipse.jface.action.Action#run()
- */
- @Override
- public void run() {
- if( bRunning ) {
- setToolTipText( "Run simulation" );
- setImageDescriptor( Activator.getIcon( "jogleditor/resume_co.gif" ) );
- }
- else {
- setToolTipText( "Pause simulation" );
- setImageDescriptor( Activator.getIcon( "jogleditor/suspend_co.gif" ) );
- }
- bRunning = !bRunning;
- }
-
- //==============================================================================
- /**
- * Accessor.
- * @return true if the simulation is running, false otherwise.
- */
- public boolean isRunning() {
- return( bRunning );
- }
-}
+package name.wadewalker.tutorial.jogleditor;
+
+import name.wadewalker.tutorial.Activator;
+
+import org.eclipse.jface.action.Action;
+
+//==============================================================================
+/**
+ * Runs or pauses the simulation on alternate button presses.
+ * Changes the picture and tooltip of the button accordingly.
+ *
+ * Copyright (c) 2010-2011 Wade Walker. Free for any use, but credit is appreciated.
+ * @author Wade Walker
+ */
+public class RunPauseAction extends Action {
+
+ /** Unique action ID for the Eclipse platform. */
+ public static final String ssID = "JOGLEditor.RunPauseAction";
+
+ /** True if the simulation is running, false if it's paused. */
+ private boolean bRunning;
+
+ //==============================================================================
+ /**
+ * Constructor.
+ */
+ public RunPauseAction() {
+ super( "Run", Action.AS_PUSH_BUTTON );
+ setToolTipText( "Run simulation" );
+ setImageDescriptor( Activator.getIcon( "jogleditor/resume_co.gif" ) );
+ setId( ssID );
+ setActionDefinitionId( ssID );
+ }
+
+ //==============================================================================
+ /**
+ * Code to run the action.
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ if( bRunning ) {
+ setToolTipText( "Run simulation" );
+ setImageDescriptor( Activator.getIcon( "jogleditor/resume_co.gif" ) );
+ }
+ else {
+ setToolTipText( "Pause simulation" );
+ setImageDescriptor( Activator.getIcon( "jogleditor/suspend_co.gif" ) );
+ }
+ bRunning = !bRunning;
+ }
+
+ //==============================================================================
+ /**
+ * Accessor.
+ * @return true if the simulation is running, false otherwise.
+ */
+ public boolean isRunning() {
+ return( bRunning );
+ }
+}
diff --git a/tutorial-product/.classpath b/tutorial-product/.classpath
new file mode 100755
index 0000000..464509f
--- /dev/null
+++ b/tutorial-product/.classpath
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/tutorial-product/.project b/tutorial-product/.project
new file mode 100755
index 0000000..1ee6bb4
--- /dev/null
+++ b/tutorial-product/.project
@@ -0,0 +1,23 @@
+
+
+ tutorial-product
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/tutorial-product/.settings/org.eclipse.jdt.core.prefs b/tutorial-product/.settings/org.eclipse.jdt.core.prefs
new file mode 100755
index 0000000..4ede96d
--- /dev/null
+++ b/tutorial-product/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
diff --git a/tutorial-product/.settings/org.eclipse.m2e.core.prefs b/tutorial-product/.settings/org.eclipse.m2e.core.prefs
new file mode 100755
index 0000000..f897a7f
--- /dev/null
+++ b/tutorial-product/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/Tutorial.product b/tutorial-product/Tutorial.product
old mode 100644
new mode 100755
similarity index 80%
rename from Tutorial.product
rename to tutorial-product/Tutorial.product
index 3ab1d6a..b264bce
--- a/Tutorial.product
+++ b/tutorial-product/Tutorial.product
@@ -1,18 +1,21 @@
-
+
+
- -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts -Djava.awt.headless=true
+ -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts
-
+
+
@@ -20,16 +23,17 @@
+
+
+
-
-
@@ -80,7 +84,6 @@
-
@@ -89,7 +92,14 @@
+
+
+
+
+
+
+
diff --git a/tutorial-product/fix-mod.sh b/tutorial-product/fix-mod.sh
new file mode 100755
index 0000000..1e98a52
--- /dev/null
+++ b/tutorial-product/fix-mod.sh
@@ -0,0 +1,14 @@
+#! /bin/bash
+
+readonly SELF=$(cd $(dirname $0) && pwd)
+readonly productPath="${SELF}/target/products"
+readonly productZip=name.wadewalker.tutorial.product-win32.win32.x86_64.zip
+readonly installDir="${productPath}/Tutorial"
+
+unzip -q "${productPath}/${productZip}" -d "${installDir}"
+
+# Make things executable that Tycho goofs up
+chmod a+x "${installDir}/Tutorial.exe"
+find "${installDir}/plugins" -print0 -name '*.dll' | xargs --null chmod a+x
+ # chmod a+x $(find "${installDir}/plugins" -name '*.dll')
+
diff --git a/tutorial-product/pom.xml b/tutorial-product/pom.xml
new file mode 100755
index 0000000..dfe9c85
--- /dev/null
+++ b/tutorial-product/pom.xml
@@ -0,0 +1,50 @@
+
+ 4.0.0
+
+
+ name.wadewalker.tutorial
+ tutorial-parent
+ 1.0.0-SNAPSHOT
+ ../tutorial-parent
+
+
+ tutorial-product
+ eclipse-repository
+
+ JOGL Eclipse Tutorial Product
+ JOGL Eclipse tutorial product
+
+
+
+
+
+ org.eclipse.tycho
+ tycho-p2-director-plugin
+ ${tycho.version}
+
+
+ materialize-products
+
+ materialize-products
+
+
+
+ archive-products
+
+ archive-products
+
+
+
+
+
+
+
+
+
+ name.wadewalker.tutorial
+ tutorial-plugin
+ 1.0.0-SNAPSHOT
+
+
+
+