diff options
10 files changed, 736 insertions, 561 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java index 920e63421..31b679077 100644 --- a/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java +++ b/src/jogl/classes/com/jogamp/opengl/swt/GLCanvas.java @@ -117,7 +117,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable { private final ProxySurface proxySurface; /* Construction parameters stored for GLAutoDrawable accessor methods */ - private int ctxCreationFlags = 0; + private int additionalCtxCreationFlags = 0; private final GLCapabilitiesImmutable glCapsRequested; @@ -327,7 +327,7 @@ public class GLCanvas extends Canvas implements GLAutoDrawable { @Override public int getContextCreationFlags() { - return ctxCreationFlags; + return additionalCtxCreationFlags; } @Override @@ -357,16 +357,22 @@ public class GLCanvas extends Canvas implements GLAutoDrawable { } @Override - public void setContext(final GLContext ctx) { - if (ctx instanceof GLContextImpl) { - ((GLContextImpl) ctx).setContextCreationFlags(ctxCreationFlags); + public GLContext setContext(GLContext newCtx) { + final GLContext oldCtx = context; + final boolean newCtxCurrent = drawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags); + context=(GLContextImpl)newCtx; + if(newCtxCurrent) { + context.makeCurrent(); } - this.context = ctx; + return oldCtx; } @Override public void setContextCreationFlags(final int arg0) { - ctxCreationFlags = arg0; + additionalCtxCreationFlags = arg0; + if(null != context) { + context.setContextCreationFlags(additionalCtxCreationFlags); + } } @Override @@ -379,8 +385,13 @@ public class GLCanvas extends Canvas implements GLAutoDrawable { } @Override - public GLContext createContext(final GLContext arg0) { - return (drawable != null) ? drawable.createContext(arg0) : null; + public GLContext createContext(final GLContext shareWith) { + if(drawable != null) { + final GLContext _ctx = drawable.createContext(shareWith); + _ctx.setContextCreationFlags(additionalCtxCreationFlags); + return _ctx; + } + return null; } @Override diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java index 94e4bad66..e4aaad23d 100644 --- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java +++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java @@ -122,10 +122,36 @@ public interface GLAutoDrawable extends GLDrawable { public GLContext getContext(); /** - * Associate a new context to this drawable. + * Associate a new context to this drawable and also propagates the context/drawable switch by + * calling {@link GLContext#setGLDrawable(GLDrawable, boolean) newCtx.setGLDrawable(drawable, true);}. + * <code>drawable</code> might be an inner GLDrawable instance if using such a delegation pattern, + * or this GLAutoDrawable itself. + * <p> + * If the old context's drawable was an {@link GLAutoDrawable}, it's reference to the given drawable + * is being cleared by calling + * {@link GLAutoDrawable#setContext(GLContext) ((GLAutoDrawable)oldCtx.getGLDrawable()).setContext(null)}. + * </p> + * <p> + * If the old or new context was current on this thread, it is being released before switching the drawable. + * The new context will be made current afterwards, if it was current before. + * However the user shall take extra care that not other thread + * attempts to make this context current. Otherwise a race condition may happen. + * </p> + * <p> + * <b>Disclaimer</b>: Even though the API may allows this functionality in theory, your mileage may vary + * switching the drawable of an already established GLContext, i.e. which is already made current once. + * FIXME: Validate functionality! + * </p> + * + * @param newCtx the new context + * @return the replaced GLContext, maybe <code>null</code> + * + * @see GLContext#setGLDrawable(GLDrawable, boolean) + * @see GLContext#setGLReadDrawable(GLDrawable) + * @see jogamp.opengl.GLDrawableHelper#switchContext(GLDrawable, GLContext, GLContext, int) */ - public void setContext(GLContext context); - + public GLContext setContext(GLContext newCtx); + /** Adds a {@link GLEventListener} to the end of this drawable queue. The listeners are notified of events in the order of the queue. */ public void addGLEventListener(GLEventListener listener); @@ -271,6 +297,21 @@ public interface GLAutoDrawable extends GLDrawable { */ public int getContextCreationFlags(); + /** + * {@inheritDoc} + * <p> + * This GLAutoDrawable implementation holds it's own GLContext reference, + * thus created a GLContext using this methods won't replace it implicitly. + * To replace or set this GLAutoDrawable's GLContext you need to call {@link #setContext(GLContext)}. + * </p> + * <p> + * The GLAutoDrawable implementation shall also set the + * context creation flags as customized w/ {@link #setContextCreationFlags(int)}. + * </p> + */ + @Override + public GLContext createContext(GLContext shareWith); + /** Returns the {@link GL} pipeline object this GLAutoDrawable uses. If this method is called outside of the {@link GLEventListener}'s callback methods (init, display, etc.) it may diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java new file mode 100644 index 000000000..992bf9fee --- /dev/null +++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawableDelegate.java @@ -0,0 +1,100 @@ +/** + * Copyright 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package javax.media.opengl; + +import jogamp.opengl.Debug; +import jogamp.opengl.GLAutoDrawableBase; +import jogamp.opengl.GLContextImpl; +import jogamp.opengl.GLDrawableImpl; + + +/** + * Fully functional {@link GLAutoDrawable} implementation + * utilizing already created created {@link GLDrawable} and {@link GLContext} instances. + * <p> + * Since no native windowing system events are being processed, it is recommended + * to handle at least {@link com.jogamp.newt.event.WindowListener#windowResized(com.jogamp.newt.event.WindowEvent) resize}, + * {@link com.jogamp.newt.event.WindowListener#windowDestroyNotify(com.jogamp.newt.event.WindowEvent) destroy-notify} + * and maybe {@link com.jogamp.newt.event.WindowListener#windowRepaint(com.jogamp.newt.event.WindowUpdateEvent) repaint}. + * The latter is only required if no {@link GLAnimatorControl} is being used. + * </p> + */ +public class GLAutoDrawableDelegate extends GLAutoDrawableBase { + public static final boolean DEBUG = Debug.debug("GLAutoDrawableDelegate"); + + public GLAutoDrawableDelegate(GLDrawable drawable, GLContext context) { + super((GLDrawableImpl)drawable, (GLContextImpl)context); + } + + public void defaultRepaintOp() { + super.defaultRepaintOp(); + } + + public void defaultReshapeOp() { + super.defaultReshapeOp(); + } + + // + // Complete GLAutoDrawable + // + + /** + * {@inheritDoc} + * <p> + * This implementation simply removes references to drawable and context. + * </p> + */ + @Override + public void destroy() { + drawable = null; + context = null; + } + + @Override + public void display() { + if( null == drawable || !drawable.isRealized() || null == context ) { return; } + + // surface is locked/unlocked implicit by context's makeCurrent/release + helper.invokeGL(drawable, context, defaultDisplayAction, defaultInitAction); + } + + // + // GLDrawable delegation + // + + @Override + public final GLDrawableFactory getFactory() { + return drawable.getFactory(); + } + + @Override + public final void setRealized(boolean realized) { + } + +} diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 71026a247..8c6e594b5 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -392,10 +392,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing } @Override - public GLContext createContext(GLContext shareWith) { - return (null != drawable) ? drawable.createContext(shareWith) : null; + public GLContext createContext(final GLContext shareWith) { + if(drawable != null) { + final GLContext _ctx = drawable.createContext(shareWith); + _ctx.setContextCreationFlags(additionalCtxCreationFlags); + return _ctx; + } + return null; } - + @Override public void setRealized(boolean realized) { } @@ -694,11 +699,14 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing } @Override - public void setContext(GLContext ctx) { - context=(GLContextImpl)ctx; - if(null != context) { - context.setContextCreationFlags(additionalCtxCreationFlags); - } + public GLContext setContext(GLContext newCtx) { + final GLContext oldCtx = context; + final boolean newCtxCurrent = drawableHelper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags); + context=(GLContextImpl)newCtx; + if(newCtxCurrent) { + context.makeCurrent(); + } + return oldCtx; } @Override @@ -744,6 +752,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing @Override public void setContextCreationFlags(int flags) { additionalCtxCreationFlags = flags; + if(null != context) { + context.setContextCreationFlags(additionalCtxCreationFlags); + } } @Override diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 152326006..c6c7cf9a1 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -456,16 +456,20 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing } @Override - public void setContext(GLContext ctx) { - if (backend == null) { - return; - } - if(null != ctx) { - ctx.setContextCreationFlags(additionalCtxCreationFlags); - } - backend.setContext(ctx); + public GLContext setContext(GLContext newCtx) { + if (backend == null) { + return null; + } + final GLContext oldCtx = backend.getContext(); + final boolean newCtxCurrent = drawableHelper.switchContext(backend.getDrawable(), oldCtx, newCtx, additionalCtxCreationFlags); + backend.setContext(newCtx); + if(newCtxCurrent) { + newCtx.makeCurrent(); + } + return oldCtx; } + @Override public GLContext getContext() { if (backend == null) { @@ -1160,7 +1164,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing @Override public void setContext(GLContext ctx) { - if (pbuffer == null && Beans.isDesignTime()) { + if (pbuffer == null || Beans.isDesignTime()) { return; } pbuffer.setContext(ctx); @@ -1169,7 +1173,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing @Override public GLContext getContext() { // Workaround for crashes in NetBeans GUI builder - if (pbuffer == null && Beans.isDesignTime()) { + if (null == pbuffer || Beans.isDesignTime()) { return null; } return pbuffer.getContext(); diff --git a/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java new file mode 100644 index 000000000..3f50fe420 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/GLAutoDrawableBase.java @@ -0,0 +1,337 @@ +/** + * Copyright 2012 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package jogamp.opengl; + +import java.io.PrintStream; + +import javax.media.nativewindow.NativeSurface; +import javax.media.opengl.FPSCounter; +import javax.media.opengl.GL; +import javax.media.opengl.GLAnimatorControl; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLAutoDrawableDelegate; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawable; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; +import javax.media.opengl.GLRunnable; + +import com.jogamp.opengl.util.Animator; + + +/** + * Abstract common code for GLAutoDrawable implementations. + * + * @see GLAutoDrawable + * @see GLAutoDrawableDelegate + * @see GLPBufferImpl + * @see GLWindow + */ +public abstract class GLAutoDrawableBase implements GLAutoDrawable, FPSCounter { + public static final boolean DEBUG = Debug.debug("GLAutoDrawable"); + + protected final GLDrawableHelper helper = new GLDrawableHelper(); + protected final FPSCounterImpl fpsCounter = new FPSCounterImpl(); + + protected GLDrawableImpl drawable; + protected GLContextImpl context; + protected int additionalCtxCreationFlags = 0; + protected boolean sendReshape = false; + protected boolean sendDestroy = false; + + public GLAutoDrawableBase(GLDrawableImpl drawable, GLContextImpl context) { + this.drawable = drawable; + this.context = context; + resetFPSCounter(); + } + + /** Returns the delegated GLDrawable */ + public final GLDrawable getDelegatedDrawable() { return drawable; } + + protected void defaultRepaintOp() { + if( null != drawable && drawable.isRealized() ) { + if( !drawable.getNativeSurface().isSurfaceLockedByOtherThread() && !helper.isAnimatorAnimating() ) { + display(); + } + } + } + + protected void defaultReshapeOp() { + if( null!=drawable ) { + if(DEBUG) { + System.err.println("GLAutoDrawableBase.sizeChanged: ("+Thread.currentThread().getName()+"): "+getWidth()+"x"+getHeight()+" - surfaceHandle 0x"+Long.toHexString(getNativeSurface().getSurfaceHandle())); + } + sendReshape = true; + defaultRepaintOp(); + } + } + + // + // GLAutoDrawable + // + + protected final Runnable defaultInitAction = new Runnable() { + @Override + public final void run() { + // Lock: Locked Surface/Window by MakeCurrent/Release + helper.init(GLAutoDrawableBase.this); + resetFPSCounter(); + } }; + + protected final Runnable defaultDisplayAction = new Runnable() { + @Override + public final void run() { + // Lock: Locked Surface/Window by display _and_ MakeCurrent/Release + if (sendReshape) { + helper.reshape(GLAutoDrawableBase.this, 0, 0, getWidth(), getHeight()); + sendReshape = false; + } + helper.display(GLAutoDrawableBase.this); + fpsCounter.tickFPS(); + } }; + + @Override + public final GLContext getContext() { + return context; + } + + @Override + public final GLContext setContext(GLContext newCtx) { + final GLContext oldCtx = context; + final boolean newCtxCurrent = helper.switchContext(drawable, oldCtx, newCtx, additionalCtxCreationFlags); + context=(GLContextImpl)newCtx; + if(newCtxCurrent) { + context.makeCurrent(); + } + return oldCtx; + } + + @Override + public final GL getGL() { + if (context == null) { + return null; + } + return context.getGL(); + } + + @Override + public final GL setGL(GL gl) { + if (context != null) { + context.setGL(gl); + return gl; + } + return null; + } + + @Override + public final void addGLEventListener(GLEventListener listener) { + helper.addGLEventListener(listener); + } + + @Override + public final void addGLEventListener(int index, GLEventListener listener) + throws IndexOutOfBoundsException { + helper.addGLEventListener(index, listener); + } + + @Override + public final void removeGLEventListener(GLEventListener listener) { + helper.removeGLEventListener(listener); + } + + @Override + public final void setAnimator(GLAnimatorControl animatorControl) + throws GLException { + helper.setAnimator(animatorControl); + } + + @Override + public final GLAnimatorControl getAnimator() { + return helper.getAnimator(); + } + + @Override + public final void invoke(boolean wait, GLRunnable glRunnable) { + helper.invoke(this, wait, glRunnable); + } + + @Override + public final void setAutoSwapBufferMode(boolean enable) { + helper.setAutoSwapBufferMode(enable); + } + + @Override + public final boolean getAutoSwapBufferMode() { + return helper.getAutoSwapBufferMode(); + } + + @Override + public final void setContextCreationFlags(int flags) { + additionalCtxCreationFlags = flags; + if(null != context) { + context.setContextCreationFlags(additionalCtxCreationFlags); + } + } + + @Override + public final int getContextCreationFlags() { + return additionalCtxCreationFlags; + } + + // + // FPSCounter + // + + @Override + public final void setUpdateFPSFrames(int frames, PrintStream out) { + fpsCounter.setUpdateFPSFrames(frames, out); + } + + @Override + public final void resetFPSCounter() { + fpsCounter.resetFPSCounter(); + } + + @Override + public final int getUpdateFPSFrames() { + return fpsCounter.getUpdateFPSFrames(); + } + + @Override + public final long getFPSStartTime() { + return fpsCounter.getFPSStartTime(); + } + + @Override + public final long getLastFPSUpdateTime() { + return fpsCounter.getLastFPSUpdateTime(); + } + + @Override + public final long getLastFPSPeriod() { + return fpsCounter.getLastFPSPeriod(); + } + + @Override + public final float getLastFPS() { + return fpsCounter.getLastFPS(); + } + + @Override + public final int getTotalFPSFrames() { + return fpsCounter.getTotalFPSFrames(); + } + + @Override + public final long getTotalFPSDuration() { + return fpsCounter.getTotalFPSDuration(); + } + + @Override + public final float getTotalFPS() { + return fpsCounter.getTotalFPS(); + } + + // + // GLDrawable delegation + // + + @Override + public final GLContext createContext(final GLContext shareWith) { + if(drawable != null) { + final GLContext _ctx = drawable.createContext(shareWith); + _ctx.setContextCreationFlags(additionalCtxCreationFlags); + return _ctx; + } + return null; + } + + @Override + public final boolean isRealized() { + return null != drawable ? drawable.isRealized() : false; + } + + @Override + public int getWidth() { + return null != drawable ? drawable.getWidth() : 0; + } + + @Override + public int getHeight() { + return null != drawable ? drawable.getHeight() : 0; + } + + /** + * @param t the thread for which context release shall be skipped, usually the animation thread, + * ie. {@link Animator#getThread()}. + * @deprecated this is an experimental feature, + * intended for measuring performance in regards to GL context switch + */ + @Deprecated + public void setSkipContextReleaseThread(Thread t) { + helper.setSkipContextReleaseThread(t); + } + + /** + * @deprecated see {@link #setSkipContextReleaseThread(Thread)} + */ + @Deprecated + public Thread getSkipContextReleaseThread() { + return helper.getSkipContextReleaseThread(); + } + + @Override + public final void swapBuffers() throws GLException { + if(drawable!=null && context != null) { + drawable.swapBuffers(); + } + } + + @Override + public final GLCapabilitiesImmutable getChosenGLCapabilities() { + return null != drawable ? drawable.getChosenGLCapabilities() : null; + } + + @Override + public final GLProfile getGLProfile() { + return null != drawable ? drawable.getGLProfile() : null; + } + + @Override + public final NativeSurface getNativeSurface() { + return null != drawable ? drawable.getNativeSurface() : null; + } + + @Override + public final long getHandle() { + return null != drawable ? drawable.getHandle() : 0; + } +} diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java index 3c60eb699..e5c44a8d4 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java @@ -130,8 +130,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { throw new IllegalArgumentException("Null target"); } final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration(); - GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); - AbstractGraphicsDevice adevice = config.getScreen().getDevice(); + final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + final AbstractGraphicsDevice adevice = config.getScreen().getDevice(); GLDrawable result = null; adevice.lock(); try { @@ -183,7 +183,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { //--------------------------------------------------------------------------- // - // PBuffer GLDrawable construction + // PBuffer Offscreen GLDrawable construction // public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device); @@ -226,7 +226,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory { return new GLPbufferImpl( drawable, shareWith); } - //--------------------------------------------------------------------------- // // Offscreen GLDrawable construction diff --git a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java index 0ed3be48b..d98b41bdc 100644 --- a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java @@ -41,38 +41,26 @@ package jogamp.opengl; import javax.media.nativewindow.AbstractGraphicsDevice; -import javax.media.nativewindow.NativeSurface; -import javax.media.opengl.GL; -import javax.media.opengl.GLAnimatorControl; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; -import javax.media.opengl.GLDrawable; import javax.media.opengl.GLDrawableFactory; -import javax.media.opengl.GLEventListener; import javax.media.opengl.GLException; import javax.media.opengl.GLPbuffer; -import javax.media.opengl.GLProfile; -import javax.media.opengl.GLRunnable; - -import com.jogamp.common.util.locks.LockFactory; -import com.jogamp.common.util.locks.RecursiveLock; /** Platform-independent class exposing pbuffer functionality to applications. This class is not exposed in the public API as it would probably add no value; however it implements the GLDrawable interface so can be interacted with via its display() method. */ -public class GLPbufferImpl implements GLPbuffer { - private GLDrawableImpl pbufferDrawable; - private GLContextImpl context; - private GLDrawableHelper drawableHelper = new GLDrawableHelper(); +public class GLPbufferImpl extends GLAutoDrawableBase implements GLPbuffer { private int floatMode; - private int additionalCtxCreationFlags = 0; public GLPbufferImpl(GLDrawableImpl pbufferDrawable, - GLContext parentContext) { + GLContext sharedContext) { + super(pbufferDrawable, null); // drawable := pbufferDrawable + GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) - pbufferDrawable.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities(); + drawable.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities(); if(caps.isOnscreen()) { if(caps.isPBuffer()) { throw new IllegalArgumentException("Error: Given drawable is Onscreen and Pbuffer: "+pbufferDrawable); @@ -83,40 +71,63 @@ public class GLPbufferImpl implements GLPbuffer { throw new IllegalArgumentException("Error: Given drawable is not Pbuffer: "+pbufferDrawable); } } - this.pbufferDrawable = pbufferDrawable; - context = (GLContextImpl) pbufferDrawable.createContext(parentContext); + context = (GLContextImpl) drawable.createContext(sharedContext); } + // + // pbuffer specifics + // + @Override - public final GLContext createContext(GLContext shareWith) { - return pbufferDrawable.createContext(shareWith); + public void bindTexture() { + // Doesn't make much sense to try to do this on the event dispatch + // thread given that it has to be called while the context is current + context.bindPbufferToTexture(); } @Override - public final void setRealized(boolean realized) { + public void releaseTexture() { + // Doesn't make much sense to try to do this on the event dispatch + // thread given that it has to be called while the context is current + context.releasePbufferFromTexture(); } @Override - public final boolean isRealized() { - return true; + public int getFloatingPointMode() { + if (floatMode == 0) { + throw new GLException("Pbuffer not initialized, or floating-point support not requested"); + } + return floatMode; } + // + // GLDrawable delegation + // + + @Override + public final void setRealized(boolean realized) { + } + + // + // GLAutoDrawable completion + // + @Override public void destroy() { - if(pbufferDrawable.isRealized()) { - final AbstractGraphicsDevice adevice = pbufferDrawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice(); + if(drawable.isRealized()) { + final AbstractGraphicsDevice adevice = drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice(); if (null != context && context.isCreated()) { try { - drawableHelper.disposeGL(GLPbufferImpl.this, pbufferDrawable, context, null); + helper.disposeGL(GLPbufferImpl.this, drawable, context, null); } catch (GLException gle) { gle.printStackTrace(); } context = null; // drawableHelper.reset(); } - pbufferDrawable.destroy(); - pbufferDrawable = null; + drawable.destroy(); + drawable = null; if(null != adevice) { adevice.close(); @@ -124,217 +135,26 @@ public class GLPbufferImpl implements GLPbuffer { } } - public void setSize(int width, int height) { - // FIXME - throw new GLException("Not yet implemented"); - } - - @Override - public NativeSurface getNativeSurface() { - return pbufferDrawable.getNativeSurface(); - } - - @Override - public long getHandle() { - return pbufferDrawable.getHandle(); - } - @Override public GLDrawableFactory getFactory() { - return pbufferDrawable.getFactory(); - } - - @Override - public int getWidth() { - return pbufferDrawable.getWidth(); - } - - @Override - public int getHeight() { - return pbufferDrawable.getHeight(); + return drawable.getFactory(); } @Override public void display() { - invokeGL(displayAction); - } - - public void repaint() { - display(); - } - - @Override - public void addGLEventListener(GLEventListener listener) { - drawableHelper.addGLEventListener(listener); - } - - @Override - public void addGLEventListener(int index, GLEventListener listener) { - drawableHelper.addGLEventListener(index, listener); - } - - @Override - public void removeGLEventListener(GLEventListener listener) { - drawableHelper.removeGLEventListener(listener); - } - - @Override - public void setAnimator(GLAnimatorControl animatorControl) { - drawableHelper.setAnimator(animatorControl); - } - - @Override - public GLAnimatorControl getAnimator() { - return drawableHelper.getAnimator(); - } - - @Override - public void invoke(boolean wait, GLRunnable glRunnable) { - drawableHelper.invoke(this, wait, glRunnable); - } - - @Override - public void setContext(GLContext ctx) { - context=(GLContextImpl)ctx; - if(null != context) { - context.setContextCreationFlags(additionalCtxCreationFlags); - } - } - - @Override - public GLContext getContext() { - return context; - } - - public GLDrawable getDrawable() { - return pbufferDrawable; - } - - @Override - public GL getGL() { - return getContext().getGL(); - } - - @Override - public GL setGL(GL gl) { - return getContext().setGL(gl); - } - - @Override - public void setAutoSwapBufferMode(boolean onOrOff) { - drawableHelper.setAutoSwapBufferMode(onOrOff); - } - - @Override - public boolean getAutoSwapBufferMode() { - return drawableHelper.getAutoSwapBufferMode(); - } - - @Override - public void swapBuffers() { - invokeGL(swapBuffersAction); - } - - @Override - public void setContextCreationFlags(int flags) { - additionalCtxCreationFlags = flags; - if(null != context) { - context.setContextCreationFlags(additionalCtxCreationFlags); - } - } - - @Override - public int getContextCreationFlags() { - return additionalCtxCreationFlags; - } - - @Override - public void bindTexture() { - // Doesn't make much sense to try to do this on the event dispatch - // thread given that it has to be called while the context is current - context.bindPbufferToTexture(); - } - - @Override - public void releaseTexture() { - // Doesn't make much sense to try to do this on the event dispatch - // thread given that it has to be called while the context is current - context.releasePbufferFromTexture(); - } - - @Override - public GLCapabilitiesImmutable getChosenGLCapabilities() { - if (pbufferDrawable == null) - return null; - - return pbufferDrawable.getChosenGLCapabilities(); - } - - public GLCapabilitiesImmutable getRequestedGLCapabilities() { - if (pbufferDrawable == null) - return null; - - return pbufferDrawable.getRequestedGLCapabilities(); - } - - @Override - public GLProfile getGLProfile() { - if (pbufferDrawable == null) - return null; - - return pbufferDrawable.getGLProfile(); - } - - private RecursiveLock recurLock = LockFactory.createRecursiveLock(); - - public int lockSurface() throws GLException { - recurLock.lock(); - return NativeSurface.LOCK_SUCCESS; - } - - public void unlockSurface() { - recurLock.unlock(); - } - - @Override - public int getFloatingPointMode() { - if (floatMode == 0) { - throw new GLException("Pbuffer not initialized, or floating-point support not requested"); - } - return floatMode; + if( null == drawable || !drawable.isRealized() || null == context ) { return; } + helper.invokeGL(drawable, context, defaultDisplayAction, initAction); } //---------------------------------------------------------------------- // Internals only below this point // - private void invokeGL(Runnable invokeGLAction) { - drawableHelper.invokeGL(pbufferDrawable, context, invokeGLAction, initAction); - } - - - class InitAction implements Runnable { + protected final Runnable initAction = new Runnable() { @Override - public void run() { - floatMode = context.getFloatingPointMode(); - drawableHelper.init(GLPbufferImpl.this); - } - } - private InitAction initAction = new InitAction(); - - class DisplayAction implements Runnable { - @Override - public void run() { - drawableHelper.display(GLPbufferImpl.this); - } - } - private DisplayAction displayAction = new DisplayAction(); - - class SwapBuffersAction implements Runnable { - @Override - public void run() { - pbufferDrawable.swapBuffers(); - } - } - private SwapBuffersAction swapBuffersAction = new SwapBuffersAction(); + public final void run() { + floatMode = context.getFloatingPointMode(); + defaultInitAction.run(); + } }; + } diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index bff1efcb5..6a328ed07 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -34,8 +34,6 @@ package com.jogamp.newt.opengl; -import java.io.PrintStream; - import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; @@ -53,16 +51,15 @@ import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLCapabilitiesImmutable; import javax.media.opengl.GLContext; -import javax.media.opengl.GLDrawable; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLEventListener; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; -import javax.media.opengl.GLRunnable; import jogamp.newt.WindowImpl; -import jogamp.opengl.FPSCounterImpl; -import jogamp.opengl.GLDrawableHelper; +import jogamp.opengl.GLAutoDrawableBase; +import jogamp.opengl.GLContextImpl; +import jogamp.opengl.GLDrawableImpl; import com.jogamp.common.GlueGenVersion; import com.jogamp.common.util.VersionUtil; @@ -78,7 +75,6 @@ import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.event.WindowListener; import com.jogamp.newt.event.WindowUpdateEvent; import com.jogamp.opengl.JoglVersion; -import com.jogamp.opengl.util.Animator; /** * An implementation of {@link GLAutoDrawable} and {@link Window} interface, @@ -100,30 +96,25 @@ import com.jogamp.opengl.util.Animator; GLAutoDrawable implementations, she is safe due to the implicit locked state. * </p> */ -public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSCounter { +public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Window, NEWTEventConsumer, FPSCounter { private final WindowImpl window; /** * Constructor. Do not call this directly -- use {@link #create()} instead. */ protected GLWindow(Window window) { - resetFPSCounter(); + super(null, null); this.window = (WindowImpl) window; this.window.setHandleDestroyNotify(false); window.addWindowListener(new WindowAdapter() { @Override public void windowRepaint(WindowUpdateEvent e) { - if( !GLWindow.this.window.isWindowLockedByOtherThread() && !GLWindow.this.helper.isAnimatorAnimating() ) { - display(); - } + defaultRepaintOp(); } @Override public void windowResized(WindowEvent e) { - sendReshape = true; - if( !GLWindow.this.window.isWindowLockedByOtherThread() && !GLWindow.this.helper.isAnimatorAnimating() ) { - display(); - } + defaultReshapeOp(); } @Override @@ -132,7 +123,7 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC // Is an animator thread perform rendering? if (GLWindow.this.helper.isExternalAnimatorRunning()) { // Pause animations before initiating safe destroy. - GLAnimatorControl ctrl = GLWindow.this.helper.getAnimator(); + final GLAnimatorControl ctrl = GLWindow.this.helper.getAnimator(); boolean isPaused = ctrl.pause(); destroy(); if(isPaused) { @@ -343,6 +334,26 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC } @Override + public final int getX() { + return window.getX(); + } + + @Override + public final int getY() { + return window.getY(); + } + + @Override + public final int getWidth() { + return window.getWidth(); + } + + @Override + public final int getHeight() { + return window.getHeight(); + } + + @Override public final void setPosition(int x, int y) { window.setPosition(x, y); } @@ -495,10 +506,10 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC factory = GLDrawableFactory.getFactory(glCaps.getGLProfile()); } if(null==drawable) { - drawable = factory.createGLDrawable(nw); + drawable = (GLDrawableImpl) factory.createGLDrawable(nw); } drawable.setRealized(true); - context = drawable.createContext(sharedContext); + context = (GLContextImpl) drawable.createContext(sharedContext); context.setContextCreationFlags(additionalCtxCreationFlags); } if(Window.DEBUG_IMPLEMENTATION) { @@ -531,20 +542,6 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC // private GLContext sharedContext = null; - private int additionalCtxCreationFlags = 0; - private GLDrawableFactory factory; - private GLDrawable drawable; - private GLContext context; - private GLDrawableHelper helper = new GLDrawableHelper(); - // To make reshape events be sent immediately before a display event - private boolean sendReshape=false; - private boolean sendDestroy=false; - private final FPSCounterImpl fpsCounter = new FPSCounterImpl(); - - @Override - public GLDrawableFactory getFactory() { - return factory; - } /** * Specifies an {@link javax.media.opengl.GLContext OpenGL context} to share with.<br> @@ -559,79 +556,6 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC } @Override - public void setContext(GLContext newCtx) { - context = newCtx; - if(null != context) { - context.setContextCreationFlags(additionalCtxCreationFlags); - } - } - - @Override - public GLContext getContext() { - return context; - } - - @Override - public GL getGL() { - if (context == null) { - return null; - } - return context.getGL(); - } - - @Override - public GL setGL(GL gl) { - if (context != null) { - context.setGL(gl); - return gl; - } - return null; - } - - @Override - public void addGLEventListener(GLEventListener listener) { - if(null!=helper) { - helper.addGLEventListener(listener); - } - } - - @Override - public void addGLEventListener(int index, GLEventListener listener) { - if(null!=helper) { - helper.addGLEventListener(index, listener); - } - } - - @Override - public void removeGLEventListener(GLEventListener listener) { - if(null!=helper) { - helper.removeGLEventListener(listener); - } - } - - @Override - public void setAnimator(GLAnimatorControl animatorControl) { - if(null!=helper) { - helper.setAnimator(animatorControl); - } - } - - @Override - public GLAnimatorControl getAnimator() { - if(null!=helper) { - return helper.getAnimator(); - } - return null; - } - - @Override - public void invoke(boolean wait, GLRunnable glRunnable) { - if(null!=helper) { - helper.invoke(this, wait, glRunnable); - } - } - - @Override public void display() { if( !isNativeValid() || !isVisible() ) { return; } @@ -650,215 +574,27 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC if( null != context ) { // surface is locked/unlocked implicit by context's makeCurrent/release - helper.invokeGL(drawable, context, displayAction, initAction); + helper.invokeGL(drawable, context, defaultDisplayAction, defaultInitAction); } } finally { window.unlockWindow(); } } - @Override - public void setAutoSwapBufferMode(boolean enable) { - if(null!=helper) { - helper.setAutoSwapBufferMode(enable); - } - } - - @Override - public boolean getAutoSwapBufferMode() { - if(null!=helper) { - return helper.getAutoSwapBufferMode(); - } - return false; - } - - /** - * @param t the thread for which context release shall be skipped, usually the animation thread, - * ie. {@link Animator#getThread()}. - * @deprecated this is an experimental feature, - * intended for measuring performance in regards to GL context switch - */ - @Deprecated - public void setSkipContextReleaseThread(Thread t) { - if(null!=helper) { - helper.setSkipContextReleaseThread(t); - } - } - - /** - * @deprecated see {@link #setSkipContextReleaseThread(Thread)} - */ - @Deprecated - public Thread getSkipContextReleaseThread() { - if(null!=helper) { - return helper.getSkipContextReleaseThread(); - } - return null; - } - - @Override - public void swapBuffers() { - if(drawable!=null && context != null) { - drawable.swapBuffers(); - } - } - - @Override - public void setContextCreationFlags(int flags) { - additionalCtxCreationFlags = flags; - } - - @Override - public int getContextCreationFlags() { - return additionalCtxCreationFlags; - } - - private class InitAction implements Runnable { - @Override - public final void run() { - // Lock: Locked Surface/Window by MakeCurrent/Release - helper.init(GLWindow.this); - resetFPSCounter(); - } - } - private InitAction initAction = new InitAction(); - - private class DisplayAction implements Runnable { - @Override - public final void run() { - // Lock: Locked Surface/Window by display _and_ MakeCurrent/Release - if (sendReshape) { - helper.reshape(GLWindow.this, 0, 0, getWidth(), getHeight()); - sendReshape = false; - } - - helper.display(GLWindow.this); - - fpsCounter.tickFPS(); - } - } - private DisplayAction displayAction = new DisplayAction(); - - @Override - public final void setUpdateFPSFrames(int frames, PrintStream out) { - fpsCounter.setUpdateFPSFrames(frames, out); - } - - @Override - public final void resetFPSCounter() { - fpsCounter.resetFPSCounter(); - } - - @Override - public final int getUpdateFPSFrames() { - return fpsCounter.getUpdateFPSFrames(); - } - - @Override - public final long getFPSStartTime() { - return fpsCounter.getFPSStartTime(); - } - - @Override - public final long getLastFPSUpdateTime() { - return fpsCounter.getLastFPSUpdateTime(); - } - - @Override - public final long getLastFPSPeriod() { - return fpsCounter.getLastFPSPeriod(); - } - - @Override - public final float getLastFPS() { - return fpsCounter.getLastFPS(); - } - - @Override - public final int getTotalFPSFrames() { - return fpsCounter.getTotalFPSFrames(); - } - - @Override - public final long getTotalFPSDuration() { - return fpsCounter.getTotalFPSDuration(); - } - - @Override - public final float getTotalFPS() { - return fpsCounter.getTotalFPS(); - } - //---------------------------------------------------------------------- // GLDrawable methods // + private GLDrawableFactory factory; @Override - public final NativeSurface getNativeSurface() { - return null!=drawable ? drawable.getNativeSurface() : null; - } - - @Override - public final long getHandle() { - return null!=drawable ? drawable.getHandle() : 0; - } - - @Override - public final int getX() { - return window.getX(); - } - - @Override - public final int getY() { - return window.getY(); - } - - @Override - public final int getWidth() { - return window.getWidth(); - } - - @Override - public final int getHeight() { - return window.getHeight(); - } - - //---------------------------------------------------------------------- - // GLDrawable methods that are not really needed - // - - @Override - public final GLContext createContext(GLContext shareWith) { - return drawable.createContext(shareWith); + public GLDrawableFactory getFactory() { + return factory; } @Override public final void setRealized(boolean realized) { } - @Override - public final boolean isRealized() { - return ( null != drawable ) ? drawable.isRealized() : false; - } - - @Override - public final GLCapabilitiesImmutable getChosenGLCapabilities() { - if (drawable == null) { - throw new GLException("No drawable yet"); - } - - return drawable.getChosenGLCapabilities(); - } - - @Override - public final GLProfile getGLProfile() { - if (drawable == null) { - throw new GLException("No drawable yet"); - } - - return drawable.getGLProfile(); - } - //---------------------------------------------------------------------- // NEWTEventConsumer // diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java new file mode 100644 index 000000000..be9ae223b --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateNEWT.java @@ -0,0 +1,116 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.jogl.acore; + +import java.io.IOException; + +import javax.media.opengl.GLAnimatorControl; +import javax.media.opengl.GLAutoDrawableDelegate; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +import org.junit.Test; + +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.event.WindowEvent; +import com.jogamp.newt.event.WindowUpdateEvent; +import com.jogamp.opengl.util.Animator; + +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.test.junit.util.NEWTGLContext; +import com.jogamp.opengl.test.junit.util.QuitAdapter; +import com.jogamp.opengl.test.junit.util.UITestCase; + +public class TestGLAutoDrawableDelegateNEWT extends UITestCase { + + @Test + public void test01() throws GLException, InterruptedException { + final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOnscreenWindow( + new GLCapabilities(GLProfile.getGL2ES2()), 640, 480, false); + winctx.context.release(); + + final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(winctx.drawable, winctx.context); + glad.addGLEventListener(new GearsES2(1)); + + // add basic window interaction + winctx.window.addWindowListener(new WindowAdapter() { + @Override + public void windowRepaint(WindowUpdateEvent e) { + glad.defaultRepaintOp(); + } + @Override + public void windowResized(WindowEvent e) { + glad.defaultReshapeOp(); + } + @Override + public void windowDestroyNotify(WindowEvent e) { + final GLAnimatorControl ctrl = glad.getAnimator(); + boolean isPaused = ctrl.pause(); + glad.destroy(); + NEWTGLContext.destroyWindow(winctx); + if(isPaused) { + ctrl.resume(); + } + } + }); + + final QuitAdapter quitAdapter = new QuitAdapter(); + winctx.window.addWindowListener(quitAdapter); + + final Animator animator = new Animator(glad); + animator.setUpdateFPSFrames(60, null); + animator.start(); + + while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) { + Thread.sleep(100); + } + + animator.stop(); + NEWTGLContext.destroyWindow(winctx); + } + + static long duration = 2000; // ms + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + try { + duration = Integer.parseInt(args[i]); + } catch (Exception ex) { ex.printStackTrace(); } + } + } + /** + BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); + System.err.println("Press enter to continue"); + System.err.println(stdin.readLine()); */ + org.junit.runner.JUnitCore.main(TestGLAutoDrawableDelegateNEWT.class.getName()); + } +} |