aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-09-20 12:18:48 +0200
committerSven Gothel <[email protected]>2013-09-20 12:18:48 +0200
commitc427ed22244df44b71a0f1f000b0f93e56c283c2 (patch)
treee40dffaf9f3e2776a84413794f27b677318dc186
parent51df3f354a700454498371c0565bfcd6c0d3bf5f (diff)
Fix Bug 826: GLJPanel: Fully restore TextureState and Viewport
In FBO mode save TextureState of current texture-unit, as well as for the fbo texture-unit if the latter is a different. In glslTextureRaster mode for verical flip (using FBO), set the viewport to drawable size if before flipping and restore afterward - if equired. TestGLJPanelTextureStateAWT fully tests use cases: - Keep texture bound w/ same or other texture-unit - Use 2 viewports within one drawable and keep it
-rw-r--r--make/scripts/tests.sh5
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/TextureState.java167
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java53
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/awt/TestGLJPanelTextureStateAWT.java282
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureDraw01Accessor.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java82
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw02ES2ListenerFBO.java285
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/TextureDraw01GL2Listener.java34
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java34
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTCompareNewtAWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGTextureFromFileNEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage01NEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTGATextureFromFileNEWT.java2
16 files changed, 901 insertions, 58 deletions
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 05f5f9652..b94e23dc1 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -216,6 +216,7 @@ function jrun() {
#D_ARGS="-Djogl.debug.GLContext -Dnewt.debug=all -Djogamp.debug.Lock -Djogamp.common.utils.locks.Lock.timeout=10000"
#D_ARGS="-Djogl.debug.GLContext -Dnewt.debug=all"
#D_ARGS="-Dnewt.debug=all"
+ #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.GLJPanel -Djogl.debug.TileRenderer -Djogl.debug.TileRenderer.PNG"
D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.GLJPanel -Djogl.debug.TileRenderer"
#D_ARGS="-Djogl.debug.PNGImage"
#D_ARGS="-Djogl.debug.JPEGImage"
@@ -330,7 +331,8 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.tile.TestRandomTiledRendering2GL2NEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.tile.TestRandomTiledRendering3GL2AWT $*
#testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsAWT $*
-testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsSwingAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsSwingAWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsSwingAWT2 $*
#testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsNewtAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingNIOImageSwingAWT $*
@@ -472,6 +474,7 @@ testawt com.jogamp.opengl.test.junit.jogl.tile.TestTiledPrintingGearsSwingAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestGLCanvasAWTActionDeadlock00AWT $*
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestGLCanvasAWTActionDeadlock01AWT $*
#testawt com.jogamp.opengl.test.junit.jogl.awt.TestGLCanvasAWTActionDeadlock02AWT $*
+testawt com.jogamp.opengl.test.junit.jogl.awt.TestGLJPanelTextureStateAWT $*
#testawt com.jogamp.opengl.test.bugs.Bug735Inv0AppletAWT $*
#testawt com.jogamp.opengl.test.bugs.Bug735Inv1AppletAWT $*
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureState.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureState.java
new file mode 100644
index 000000000..4a5d368e3
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureState.java
@@ -0,0 +1,167 @@
+/**
+ * Copyright 2013 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.util.texture;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GL3;
+import javax.media.opengl.GLException;
+
+/**
+ * Preserves a [ texture-unit, texture-target ] state.
+ * <p>
+ * The states keys are the retrieved active texture-unit and the given texture-target
+ * for which the following states are being queried:
+ * <pre>
+ * - texture-object
+ * - GL.GL_TEXTURE_MAG_FILTER
+ * - GL.GL_TEXTURE_MIN_FILTER
+ * - GL.GL_TEXTURE_WRAP_S
+ * - GL.GL_TEXTURE_WRAP_T
+ * </pre>
+ */
+public class TextureState {
+ /**
+ * Returns the <code>pname</code> to query the <code>textureTarget</code> currently bound to the active texture-unit.
+ * <p>
+ * Returns <code>0</code> is <code>textureTarget</code> is not supported.
+ * </p>
+ */
+ public static final int getTextureTargetQueryName(int textureTarget) {
+ final int texBindQName;
+ switch(textureTarget) {
+ case GL.GL_TEXTURE_2D: texBindQName = GL.GL_TEXTURE_BINDING_2D; break;
+ case GL.GL_TEXTURE_CUBE_MAP: texBindQName = GL.GL_TEXTURE_BINDING_CUBE_MAP; break;
+ case GL2ES2.GL_TEXTURE_3D: texBindQName = GL2ES2.GL_TEXTURE_BINDING_3D; break;
+ case GL2GL3.GL_TEXTURE_1D: texBindQName = GL2GL3.GL_TEXTURE_BINDING_1D; break;
+ case GL2GL3.GL_TEXTURE_1D_ARRAY: texBindQName = GL2GL3.GL_TEXTURE_BINDING_1D_ARRAY; break;
+ case GL2GL3.GL_TEXTURE_2D_ARRAY: texBindQName = GL2GL3.GL_TEXTURE_BINDING_2D_ARRAY; break;
+ case GL2GL3.GL_TEXTURE_RECTANGLE: texBindQName = GL2GL3.GL_TEXTURE_BINDING_RECTANGLE; break;
+ case GL2GL3.GL_TEXTURE_BUFFER: texBindQName = GL2GL3.GL_TEXTURE_BINDING_BUFFER; break;
+ case GL3.GL_TEXTURE_2D_MULTISAMPLE: texBindQName = GL3.GL_TEXTURE_BINDING_2D_MULTISAMPLE; break;
+ case GL3.GL_TEXTURE_2D_MULTISAMPLE_ARRAY: texBindQName = GL3.GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY; break;
+ default: texBindQName = 0;
+ }
+ return texBindQName;
+ }
+
+ private final int target;
+ /**
+ * <pre>
+ * 0 - unit
+ * 1 - texture object
+ * 2 - GL.GL_TEXTURE_MAG_FILTER
+ * 3 - GL.GL_TEXTURE_MIN_FILTER
+ * 4 - GL.GL_TEXTURE_WRAP_S
+ * 5 - GL.GL_TEXTURE_WRAP_T
+ * </pre>
+ */
+ private final int[] state = new int[] { 0, 0, 0, 0, 0, 0 };
+
+ private static final String toHexString(int i) { return "0x"+Integer.toHexString(i); }
+
+ private static final int activeTexture(GL gl) {
+ final int[] vi = { 0 };
+ gl.glGetIntegerv(GL.GL_ACTIVE_TEXTURE, vi, 0);
+ return vi[0];
+ }
+
+ /**
+ * Creates a texture state for the retrieved active texture-unit and the given texture-target.
+ * See {@link TextureState}.
+ * @param gl current GL context's GL object
+ * @param textureTarget
+ * @throws GLException if textureTarget is not supported
+ */
+ public TextureState(GL gl, int textureTarget) throws GLException {
+ this(gl, activeTexture(gl), textureTarget);
+ }
+
+ /**
+ * Creates a texture state for the given active texture-unit and the given texture-target.
+ * See {@link TextureState}.
+ * @param gl current GL context's GL object
+ * @param textureUnit of range [ {@link GL#GL_TEXTURE0}.. ]
+ * @param textureTarget
+ * @throws GLException if textureTarget is not supported
+ */
+ public TextureState(GL gl, int textureUnit, int textureTarget) throws GLException {
+ target = textureTarget;
+ state[0] = textureUnit;
+ final int texBindQName = getTextureTargetQueryName(textureTarget);
+ if( 0 == texBindQName ) {
+ throw new GLException("Unsupported textureTarget "+toHexString(textureTarget));
+ }
+ gl.glGetIntegerv(texBindQName, state, 1);
+ gl.glGetTexParameteriv(target, GL.GL_TEXTURE_MAG_FILTER, state, 2);
+ gl.glGetTexParameteriv(target, GL.GL_TEXTURE_MIN_FILTER, state, 3);
+ gl.glGetTexParameteriv(target, GL.GL_TEXTURE_WRAP_S, state, 4);
+ gl.glGetTexParameteriv(target, GL.GL_TEXTURE_WRAP_T, state, 5);
+ }
+
+ /**
+ * Restores the texture-unit's texture-target state.
+ * <p>
+ * First the texture-unit is activated, then all states are restored.
+ * </p>
+ * @param gl current GL context's GL object
+ */
+ public final void restore(GL gl) {
+ gl.glActiveTexture(state[0]);
+ gl.glBindTexture(target, state[1]);
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, state[2]);
+ gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, state[3]);
+ gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, state[4]);
+ gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, state[5]);
+ }
+
+ /** Returns the texture-unit of this state, key value. Unit is of range [ {@link GL#GL_TEXTURE0}.. ]. */
+ public final int getUnit() { return state[0]; }
+ /** Returns the texture-target of this state, key value. */
+ public final int getTarget() { return target; }
+
+ /** Returns the state's texture-object. */
+ public final int getObject() { return state[1]; }
+ /** Returns the state's mag-filter param. */
+ public final int getMagFilter() { return state[2]; }
+ /** Returns the state's min-filter param. */
+ public final int getMinFilter() { return state[3]; }
+ /** Returns the state's wrap-s param. */
+ public final int getWrapS() { return state[4]; }
+ /** Returns the state's wrap-t param. */
+ public final int getWrapT() { return state[5]; }
+
+
+ public final String toString() {
+ return "TextureState[unit "+(state[0] - GL.GL_TEXTURE0)+", target "+toHexString(target)+
+ ": obj "+toHexString(state[1])+
+ ", filter[mag "+toHexString(state[2])+", min "+toHexString(state[3])+"], "+
+ ": wrap[s "+toHexString(state[4])+", t "+toHexString(state[5])+"]]";
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index e9d1b38d2..61ff4997e 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -101,6 +101,7 @@ import com.jogamp.opengl.util.TileRenderer;
import com.jogamp.opengl.util.awt.AWTGLPixelBuffer;
import com.jogamp.opengl.util.awt.AWTGLPixelBuffer.AWTGLPixelBufferProvider;
import com.jogamp.opengl.util.awt.AWTGLPixelBuffer.SingleAWTGLPixelBufferProvider;
+import com.jogamp.opengl.util.texture.TextureState;
/** A lightweight Swing component which provides OpenGL rendering
support. Provided for compatibility with Swing user interfaces
@@ -1219,6 +1220,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// Implementation using software rendering
private GLDrawableImpl offscreenDrawable;
+ private boolean offscreenIsFBO;
private FBObject fboFlipped;
private GLSLTextureRaster glslTextureRaster;
@@ -1264,7 +1266,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
final GL gl = offscreenContext.getGL();
flipVertical = offscreenDrawable.isGLOriented();
final GLCapabilitiesImmutable chosenCaps = offscreenDrawable.getChosenGLCapabilities();
- if( USE_GLSL_TEXTURE_RASTERIZER && chosenCaps.isFBO() && flipVertical && gl.isGL2ES2() ) {
+ offscreenIsFBO = chosenCaps.isFBO();
+ if( USE_GLSL_TEXTURE_RASTERIZER && offscreenIsFBO && flipVertical && gl.isGL2ES2() ) {
final boolean _autoSwapBufferMode = helper.getAutoSwapBufferMode();
helper.setAutoSwapBufferMode(false);
final GLFBODrawable fboDrawable = (GLFBODrawable) offscreenDrawable;
@@ -1344,6 +1347,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
adevice.close();
}
}
+ offscreenIsFBO = false;
if( null != readBackIntsForCPUVFlip ) {
readBackIntsForCPUVFlip.clear();
@@ -1420,10 +1424,23 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
readBackInts = readBackIntsForCPUVFlip;
}
- if( DEBUG_VIEWPORT ) {
- int[] vp = new int[] { 0, 0, 0, 0 };
- gl.glGetIntegerv(GL.GL_VIEWPORT, vp, 0);
- System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL: Viewport: "+vp[0]+"/"+vp[1]+" "+vp[2]+"x"+vp[3]);
+ final TextureState usrTexState, fboTexState;
+ final int fboTexUnit = GL.GL_TEXTURE0 + ( offscreenIsFBO ? ((GLFBODrawable)offscreenDrawable).getTextureUnit() : 0 );
+
+ if( offscreenIsFBO ) {
+ usrTexState = new TextureState(gl, GL.GL_TEXTURE_2D);
+ if( fboTexUnit != usrTexState.getUnit() ) {
+ // glActiveTexture(..) + glBindTexture(..) are implicit performed in GLFBODrawableImpl's
+ // swapBuffers/contextMadeCurent -> swapFBOImpl.
+ // We need to cache the texture unit's bound texture-id before it's overwritten.
+ gl.glActiveTexture(fboTexUnit);
+ fboTexState = new TextureState(gl, fboTexUnit, GL.GL_TEXTURE_2D);
+ } else {
+ fboTexState = usrTexState;
+ }
+ } else {
+ usrTexState = null;
+ fboTexState = null;
}
// Must now copy pixels from offscreen context into surface
@@ -1439,6 +1456,20 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
offscreenDrawable.swapBuffers();
if(null != glslTextureRaster) { // implies flippedVertical
+ final boolean viewportChange;
+ final int[] usrViewport = new int[] { 0, 0, 0, 0 };
+ gl.glGetIntegerv(GL.GL_VIEWPORT, usrViewport, 0);
+ viewportChange = 0 != usrViewport[0] || 0 != usrViewport[1] ||
+ offscreenDrawable.getWidth() != usrViewport[2] || offscreenDrawable.getHeight() != usrViewport[3];
+ if( DEBUG_VIEWPORT ) {
+ System.err.println(getThreadName()+": GLJPanel.OffscreenBackend.postGL: Viewport: change "+viewportChange+
+ ", "+usrViewport[0]+"/"+usrViewport[1]+" "+usrViewport[2]+"x"+usrViewport[3]+
+ " -> 0/0 "+offscreenDrawable.getWidth()+"x"+offscreenDrawable.getHeight());
+ }
+ if( viewportChange ) {
+ gl.glViewport(0, 0, offscreenDrawable.getWidth(), offscreenDrawable.getHeight());
+ }
+
// perform vert-flipping via OpenGL/FBO
final GLFBODrawable fboDrawable = (GLFBODrawable)offscreenDrawable;
final FBObject.TextureAttachment fboTex = fboDrawable.getTextureBuffer(GL.GL_FRONT);
@@ -1446,12 +1477,17 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
fboFlipped.bind(gl);
// gl.glActiveTexture(GL.GL_TEXTURE0 + fboDrawable.getTextureUnit()); // implicit by GLFBODrawableImpl: swapBuffers/contextMadeCurent -> swapFBOImpl
- gl.glBindTexture(GL.GL_TEXTURE_2D, fboTex.getName());
+ gl.glBindTexture(GL.GL_TEXTURE_2D, fboTex.getName());
// gl.glClear(GL.GL_DEPTH_BUFFER_BIT); // fboFlipped runs w/o DEPTH!
+
glslTextureRaster.display(gl.getGL2ES2());
gl.glReadPixels(0, 0, panelWidth, panelHeight, pixelAttribs.format, pixelAttribs.type, readBackInts);
-
+
fboFlipped.unbind(gl);
+ if( viewportChange ) {
+ gl.glViewport(usrViewport[0], usrViewport[1], usrViewport[2], usrViewport[3]);
+ }
+ fboTexState.restore(gl);
} else {
gl.glReadPixels(0, 0, panelWidth, panelHeight, pixelAttribs.format, pixelAttribs.type, readBackInts);
@@ -1471,6 +1507,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
}
}
+ if( offscreenIsFBO && fboTexUnit != usrTexState.getUnit() ) {
+ usrTexState.restore(gl);
+ }
// Restore saved modes.
psm.restore(gl);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestGLJPanelTextureStateAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestGLJPanelTextureStateAWT.java
new file mode 100644
index 000000000..2d4c6da4d
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestGLJPanelTextureStateAWT.java
@@ -0,0 +1,282 @@
+/**
+ * Copyright 2013 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.awt;
+
+
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.TextureDraw02ES2ListenerFBO;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.QuitAdapter;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.awt.GLJPanel;
+import javax.swing.JFrame;
+
+import com.jogamp.opengl.util.texture.TextureIO;
+import com.jogamp.opengl.util.texture.TextureState;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+
+import java.awt.Dimension;
+
+import java.io.IOException;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+/**
+ * Unit test for bug 826, test {@link GLJPanel}'s {@link TextureState} save and restore.
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TestGLJPanelTextureStateAWT extends UITestCase {
+ static boolean showFPS = false;
+ static long duration = 100; // ms
+
+ @BeforeClass
+ public static void initClass() {
+ }
+
+ public void testImpl(final boolean keepTextureBound, final int texUnit)
+ throws InterruptedException, IOException
+ {
+ final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false);
+ GLProfile glp;
+ if(GLProfile.isAvailable(GLProfile.GL2ES2)) {
+ glp = GLProfile.getGL2ES2();
+ } else {
+ System.err.println(getSimpleTestName(".")+": GLProfile n/a");
+ return;
+ }
+ final GLCapabilities caps = new GLCapabilities(glp);
+
+ final GLJPanel glc = new GLJPanel(caps);
+ Dimension glc_sz = new Dimension(800, 400);
+ glc.setMinimumSize(glc_sz);
+ glc.setPreferredSize(glc_sz);
+ final JFrame frame = new JFrame("TestGLJPanelTextureStateAWT");
+ Assert.assertNotNull(frame);
+ frame.getContentPane().add(glc);
+
+ final TextureDraw02ES2ListenerFBO gle0;
+ {
+ final GearsES2 gle0sub = new GearsES2( 0 );
+ // gle1sub.setClearBuffers(false);
+ gle0 = new TextureDraw02ES2ListenerFBO(gle0sub, 1, texUnit ) ;
+ }
+ gle0.setKeepTextureBound(keepTextureBound);
+ gle0.setClearBuffers(false);
+
+ final RedSquareES2 gle1 = new RedSquareES2( 1 ) ;
+ gle1.setClearBuffers(false);
+
+ glc.addGLEventListener(new GLEventListener() {
+ int gle0X, gle0Y, gle0W, gle0H;
+ int gle1X, gle1Y, gle1W, gle1H;
+ int tX, tY, tW, tH;
+ int shot = 0;
+
+ void setupTex(GL gl) {
+ // Note: FBObject uses diff defaults, i.e.: GL_NEAREST and GL_CLAMP_TO_EDGE
+ if( keepTextureBound ) {
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
+ }
+ }
+
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ // Initialize w/ arbitrary values !
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+ gl.glActiveTexture(GL.GL_TEXTURE0 + 1);
+ gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
+ gl.glActiveTexture(GL.GL_TEXTURE0 + 0);
+ gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
+
+ gle0.init(drawable);
+ gle1.init(drawable);
+ setupTex(gl);
+ }
+
+ @Override
+ public void dispose(GLAutoDrawable drawable) {
+ gle0.dispose(drawable);
+ gle1.dispose(drawable);
+ }
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+
+ // restore viewport test
+ final int[] viewport = new int[] { 0, 0, 0, 0 };
+ gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
+ if( gle0X != viewport[0] || gle0Y != viewport[1] || gle0W != viewport[2] || gle0H != viewport[3] ) {
+ final String msg = "Expected "+viewport[0]+"/"+viewport[1]+" "+viewport[2]+"x"+viewport[3]+
+ ", actual "+gle0X+"/"+gle0Y+" "+gle0W+"x"+gle0H;
+ Assert.assertTrue("Viewport not restored: "+msg, false);
+ }
+
+ // gl.glViewport(gle0X, gle0Y, gle0W, gle0H); // restore viewport test
+ gle0.display(drawable);
+
+ gl.glViewport(gle1X, gle1Y, gle1W, gle1H);
+ gle1.display(drawable);
+
+ shot++;
+ if( 4 == shot ) {
+ gl.glViewport(tX, tY, tW, tH);
+ snapshot(0, null, drawable.getGL(), screenshot, TextureIO.PNG, null);
+ }
+
+ gl.glViewport(gle0X, gle0Y, gle0W, gle0H); // restore viewport test
+
+ final TextureState ts = new TextureState(drawable.getGL(), GL.GL_TEXTURE_2D);
+ // System.err.println("XXX: "+ts);
+ Assert.assertEquals("Texture unit changed", GL.GL_TEXTURE0+texUnit, ts.getUnit());
+ if( keepTextureBound ) {
+ Assert.assertEquals("Texture mag-filter changed", GL.GL_LINEAR, ts.getMagFilter());
+ Assert.assertEquals("Texture mag-filter changed", GL.GL_LINEAR, ts.getMinFilter());
+ Assert.assertEquals("Texture wrap-s changed", GL.GL_REPEAT, ts.getWrapS());
+ Assert.assertEquals("Texture wrap-t changed", GL.GL_REPEAT, ts.getWrapT());
+ }
+ }
+ final int border = 5;
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ gle0X = x + border;
+ gle0Y = y;
+ gle0W = width/2 - 2*border;
+ gle0H = height;
+
+ gle1X = gle0X + gle0W + 2*border;
+ gle1Y = y;
+ gle1W = width/2 - 2*border;
+ gle1H = height;
+
+ tX = x;
+ tY = y;
+ tW = width;
+ tH = height;
+
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+ gl.glViewport(gle0X, gle0Y, gle0W, gle0H);
+ gle0.reshape(drawable, gle0X, gle0Y, gle0W, gle0H);
+
+ gl.glViewport(gle1X, gle1Y, gle1W, gle1H);
+ gle1.reshape(drawable, gle1X, gle1Y, gle1W, gle1H);
+
+ gl.glViewport(gle0X, gle0Y, gle0W, gle0H); // restore viewport test
+
+ if( keepTextureBound ) {
+ setupTex(gl);
+ }
+ }
+ });
+
+ Animator animator = new Animator(glc);
+ animator.setUpdateFPSFrames(60, showFPS ? System.err : null);
+ QuitAdapter quitAdapter = new QuitAdapter();
+ new com.jogamp.newt.event.awt.AWTKeyAdapter(quitAdapter).addTo(glc);
+ new com.jogamp.newt.event.awt.AWTWindowAdapter(quitAdapter).addTo(glc);
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.pack();
+ frame.setVisible(true);
+ }});
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ animator.start();
+
+ while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ Thread.sleep(100);
+ }
+
+ animator.stop();
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(false);
+ frame.remove(glc);
+ frame.dispose();
+ }});
+ } catch( Throwable throwable ) {
+ throwable.printStackTrace();
+ Assume.assumeNoException( throwable );
+ }
+ }
+
+ @Test
+ public void test01_texUnit0_keepTex0_ES2() throws InterruptedException, IOException {
+ testImpl(false /* keepTextureBound */, 0 /* texUnit */);
+ }
+ @Test
+ public void test02_texUnit0_keepTex1_ES2() throws InterruptedException, IOException {
+ testImpl(true /* keepTextureBound */, 0 /* texUnit */);
+ }
+ @Test
+ public void test03_texUnit1_keepTex1_ES2() throws InterruptedException, IOException {
+ testImpl(true /* keepTextureBound */, 1 /* texUnit */);
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ duration = MiscUtils.atol(args[i], duration);
+ }
+ }
+ org.junit.runner.JUnitCore.main(TestGLJPanelTextureStateAWT.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureDraw01Accessor.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureDraw01Accessor.java
index b9ac9faad..7283a204e 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureDraw01Accessor.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureDraw01Accessor.java
@@ -31,5 +31,6 @@ package com.jogamp.opengl.test.junit.jogl.demos;
import com.jogamp.opengl.util.texture.Texture;
public interface TextureDraw01Accessor {
+ public void setKeepTextureBound(boolean v);
public Texture getTexture();
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java
index 55d0a4775..8aa3a006c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw01ES2Listener.java
@@ -51,6 +51,8 @@ import javax.media.opengl.fixedfunc.GLMatrixFunc;
public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01Accessor {
TextureData textureData;
Texture texture;
+ int textureUnit;
+ boolean keepTextureBound;
ShaderState st;
PMVMatrix pmvMatrix;
@@ -58,14 +60,45 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A
GLArrayDataServer interleavedVBO;
float[] clearColor = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
- public TextureDraw01ES2Listener(TextureData td) {
+ /**
+ *
+ * @param td
+ * @param textureUnit of range [0..]
+ */
+ public TextureDraw01ES2Listener(TextureData td, int textureUnit) {
this.textureData = td;
+ this.textureUnit = textureUnit;
+ this.keepTextureBound = false;
}
public void setClearColor(float[] clearColor) {
this.clearColor = clearColor;
}
+ @Override
+ public void setKeepTextureBound(boolean v) {
+ this.keepTextureBound = v;
+ }
+ @Override
+ public Texture getTexture( ) {
+ return this.texture;
+ }
+
+ /**
+ public void setTextureData(GL gl, TextureData textureData ) {
+ if(null!=texture) {
+ texture.disable(gl);
+ texture.destroy(gl);
+ }
+ if(null!=this.textureData) {
+ this.textureData.destroy();
+ }
+ this.textureData = textureData;
+ this.texture = TextureIO.newTexture(this.textureData);
+
+ // fix VBO !
+ } */
+
static final String shaderBasename = "texture01_xxx";
private void initShader(GL2ES2 gl, boolean use_program) {
@@ -90,6 +123,7 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A
st.attachShaderProgram(gl, sp, use_program);
}
+ @Override
public void init(GLAutoDrawable glad) {
if(null!=textureData) {
this.texture = TextureIO.newTexture(glad.getGL(), textureData);
@@ -110,7 +144,7 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A
if(!st.uniform(gl, pmvMatrixUniform)) {
throw new GLException("Error setting PMVMatrix in shader: "+st);
}
- if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", 0))) {
+ if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", textureUnit))) {
throw new GLException("Error setting mgl_ActiveTexture in shader: "+st);
}
@@ -140,33 +174,19 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A
// OpenGL Render Settings
gl.glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
gl.glEnable(GL2ES2.GL_DEPTH_TEST);
- st.useProgram(gl, false);
- }
-
- public Texture getTexture( ) {
- return this.texture;
- }
-
- /**
- public void setTextureData(GL gl, TextureData textureData ) {
- if(null!=texture) {
- texture.disable(gl);
- texture.destroy(gl);
- }
- if(null!=this.textureData) {
- this.textureData.destroy();
- }
- this.textureData = textureData;
- this.texture = TextureIO.newTexture(this.textureData);
- // fix VBO !
- } */
+ if( keepTextureBound && null != texture ) {
+ gl.glActiveTexture(GL.GL_TEXTURE0 + textureUnit);
+ texture.enable(gl);
+ texture.bind(gl);
+ }
+ st.useProgram(gl, false);
+ }
+ @Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
GL2ES2 gl = drawable.getGL().getGL2ES2();
- gl.glViewport(0, 0, width, height);
-
// Clear background to white
gl.glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
if(null != st) {
@@ -183,6 +203,7 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A
}
}
+ @Override
public void dispose(GLAutoDrawable drawable) {
GL2ES2 gl = drawable.getGL().getGL2ES2();
if(null!=texture) {
@@ -200,6 +221,7 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A
st=null;
}
+ @Override
public void display(GLAutoDrawable drawable) {
GL2ES2 gl = drawable.getGL().getGL2ES2();
@@ -207,13 +229,17 @@ public class TextureDraw01ES2Listener implements GLEventListener, TextureDraw01A
st.useProgram(gl, true);
interleavedVBO.enableBuffer(gl, true);
- gl.glActiveTexture(GL.GL_TEXTURE0);
- texture.enable(gl);
- texture.bind(gl);
+ if( !keepTextureBound && null != texture ) {
+ gl.glActiveTexture(GL.GL_TEXTURE0 + textureUnit);
+ texture.enable(gl);
+ texture.bind(gl);
+ }
gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
- texture.disable(gl);
+ if( !keepTextureBound && null != texture ) {
+ texture.disable(gl);
+ }
interleavedVBO.enableBuffer(gl, false);
st.useProgram(gl, false);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw02ES2ListenerFBO.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw02ES2ListenerFBO.java
new file mode 100644
index 000000000..aac0080f2
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureDraw02ES2ListenerFBO.java
@@ -0,0 +1,285 @@
+/**
+ * Copyright (C) 2011 JogAmp Community. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.jogamp.opengl.test.junit.jogl.demos.es2;
+
+import java.nio.FloatBuffer;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLUniformData;
+import javax.media.opengl.fixedfunc.GLMatrixFunc;
+
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.TextureAttachment;
+import com.jogamp.opengl.FBObject.Attachment.Type;
+import com.jogamp.opengl.util.GLArrayDataServer;
+import com.jogamp.opengl.util.PMVMatrix;
+import com.jogamp.opengl.util.glsl.ShaderCode;
+import com.jogamp.opengl.util.glsl.ShaderProgram;
+import com.jogamp.opengl.util.glsl.ShaderState;
+
+public class TextureDraw02ES2ListenerFBO implements GLEventListener {
+ private final GLEventListener demo;
+ private final int swapInterval;
+ private boolean clearBuffers = true;
+ private int numSamples;
+ int textureUnit;
+ boolean keepTextureBound;
+
+ private final ShaderState st;
+ private final PMVMatrix pmvMatrix;
+
+ private final FBObject fbo0;
+
+ private TextureAttachment fbo0Tex;
+
+ private ShaderProgram sp0;
+ private GLUniformData pmvMatrixUniform;
+ private GLArrayDataServer interleavedVBO;
+ private GLUniformData texUnit0;
+
+ public TextureDraw02ES2ListenerFBO(GLEventListener demo, int swapInterval, int textureUnit) {
+ this.demo = demo;
+ this.swapInterval = swapInterval;
+ this.textureUnit = textureUnit;
+ this.keepTextureBound = false;
+
+ st = new ShaderState();
+ // st.setVerbose(true);
+ pmvMatrix = new PMVMatrix();
+
+ fbo0 = new FBObject();
+
+ numSamples = 0;
+ }
+
+ public void setClearBuffers(boolean v) { clearBuffers = v; }
+
+ public void setKeepTextureBound(boolean v) {
+ this.keepTextureBound = v;
+ }
+ public void setMSAA(int numSamples) {
+ this.numSamples=numSamples;
+ }
+ public int getMSAA() { return numSamples; }
+
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ demo.init(drawable);
+
+ final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, TextureDraw02ES2ListenerFBO.class, "shader",
+ "shader/bin", "texture01_xxx", true);
+ final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, TextureDraw02ES2ListenerFBO.class, "shader",
+ "shader/bin", "texture02_xxx", true);
+ vp0.defaultShaderCustomization(gl, true, true);
+ fp0.defaultShaderCustomization(gl, true, true);
+
+ sp0 = new ShaderProgram();
+ sp0.add(gl, vp0, System.err);
+ sp0.add(gl, fp0, System.err);
+ st.attachShaderProgram(gl, sp0, true);
+
+ pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
+ st.ownUniform(pmvMatrixUniform);
+ st.uniform(gl, pmvMatrixUniform);
+
+ interleavedVBO = GLArrayDataServer.createGLSLInterleaved(3+4+2, GL.GL_FLOAT, false, 3*4, GL.GL_STATIC_DRAW);
+ {
+ interleavedVBO.addGLSLSubArray("mgl_Vertex", 3, GL.GL_ARRAY_BUFFER);
+ interleavedVBO.addGLSLSubArray("mgl_Color", 4, GL.GL_ARRAY_BUFFER);
+ //interleavedVBO.addGLSLSubArray("mgl_Normal", 3, GL.GL_ARRAY_BUFFER);
+ interleavedVBO.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER);
+
+ FloatBuffer ib = (FloatBuffer)interleavedVBO.getBuffer();
+
+ for(int i=0; i<4; i++) {
+ ib.put(s_quadVertices, i*3, 3);
+ ib.put(s_quadColors, i*4, 4);
+ //ib.put(s_cubeNormals, i*3, 3);
+ ib.put(s_quadTexCoords, i*2, 2);
+ }
+ }
+ interleavedVBO.seal(gl, true);
+ interleavedVBO.enableBuffer(gl, false);
+ st.ownAttribute(interleavedVBO, true);
+
+ texUnit0 = new GLUniformData("mgl_Texture0", textureUnit);
+ st.ownUniform(texUnit0);
+ st.uniform(gl, texUnit0);
+
+ st.useProgram(gl, false);
+
+ gl.glEnable(GL2ES2.GL_DEPTH_TEST);
+ }
+
+ private void initFBOs(GL gl, int width, int height) {
+ // remove all texture attachments, since MSAA uses just color-render-buffer
+ // and non-MSAA uses texture2d-buffer
+ fbo0.detachAllColorbuffer(gl);
+
+ fbo0.reset(gl, width, height, numSamples, false);
+ numSamples = fbo0.getNumSamples();
+
+ if(numSamples>0) {
+ fbo0.attachColorbuffer(gl, 0, true);
+ fbo0.resetSamplingSink(gl);
+ fbo0Tex = fbo0.getSamplingSink();
+ } else {
+ fbo0Tex = fbo0.attachTexture2D(gl, 0, true);
+ }
+ numSamples=fbo0.getNumSamples();
+ fbo0.attachRenderbuffer(gl, Type.DEPTH, 24);
+ fbo0.unbind(gl);
+ }
+
+ private void resetFBOs(GL gl, int width, int height) {
+ fbo0.reset(gl, width, height, numSamples, true);
+ numSamples = fbo0.getNumSamples();
+ if(numSamples>0) {
+ fbo0Tex = fbo0.getSamplingSink();
+ } else {
+ fbo0Tex = (TextureAttachment) fbo0.getColorbuffer(0);
+ }
+ }
+
+ @Override
+ public void dispose(GLAutoDrawable drawable) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ demo.dispose(drawable);
+ fbo0.destroy(gl);
+ st.destroy(gl);
+
+ fbo0Tex = null;
+ sp0 = null;
+ pmvMatrixUniform = null;
+ interleavedVBO = null;
+ }
+
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ if( fbo0.getNumSamples() != numSamples ) {
+ System.err.println("**** NumSamples: "+fbo0.getNumSamples()+" -> "+numSamples);
+ resetFBOs(gl, drawable.getWidth(), drawable.getHeight());
+ }
+
+ if(0 < numSamples) {
+ gl.glEnable(GL.GL_MULTISAMPLE);
+ }
+
+ fbo0.bind(gl);
+ demo.display(drawable);
+ fbo0.unbind(gl);
+
+ st.useProgram(gl, true);
+ if( clearBuffers ) {
+ gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ }
+
+ if( !keepTextureBound ) {
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());
+ fbo0.use(gl, fbo0Tex);
+ if( !gl.isGLcore() ) {
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ }
+ }
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());
+ interleavedVBO.enableBuffer(gl, true);
+
+ gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+
+ interleavedVBO.enableBuffer(gl, false);
+
+ if( !keepTextureBound ) {
+ fbo0.unuse(gl);
+ }
+
+ st.useProgram(gl, false);
+ }
+
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ if(-1 != swapInterval) {
+ gl.setSwapInterval(swapInterval); // in case switching the drawable (impl. may bound attribute there)
+ }
+
+ if( !fbo0.isInitialized() ) {
+ System.err.println("**** Reshape.Init: "+width+"x"+height);
+ initFBOs(gl, width, height);
+ } else {
+ System.err.println("**** Reshape.Reset: "+width+"x"+height);
+ if( keepTextureBound ) {
+ fbo0.unuse(gl);
+ }
+ resetFBOs(gl, width, height);
+ }
+
+ fbo0.bind(gl);
+ demo.reshape(drawable, x, y, width, height);
+ fbo0.unbind(gl);
+
+ if( keepTextureBound ) {
+ gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit0.intValue());
+ fbo0.use(gl, fbo0Tex);
+ if( !gl.isGLcore() ) {
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ }
+ }
+
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
+ pmvMatrix.glLoadIdentity();
+ pmvMatrix.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 10.0f);
+
+ pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmvMatrix.glLoadIdentity();
+
+ st.useProgram(gl, true);
+ st.uniform(gl, pmvMatrixUniform);
+ st.useProgram(gl, false);
+
+ }
+
+ private static final float[] s_quadVertices = {
+ -1f, -1f, 0f, // LB
+ 1f, -1f, 0f, // RB
+ -1f, 1f, 0f, // LT
+ 1f, 1f, 0f // RT
+ };
+ private static final float[] s_quadColors = {
+ 1f, 1f, 1f, 1f,
+ 1f, 1f, 1f, 1f,
+ 1f, 1f, 1f, 1f,
+ 1f, 1f, 1f, 1f };
+ private static final float[] s_quadTexCoords = {
+ 0f, 0f, // LB
+ 1f, 0f, // RB
+ 0f, 1f, // LT
+ 1f, 1f // RT
+ };
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/TextureDraw01GL2Listener.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/TextureDraw01GL2Listener.java
index af30c265b..fb8e6bfa3 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/TextureDraw01GL2Listener.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/TextureDraw01GL2Listener.java
@@ -43,21 +43,35 @@ public class TextureDraw01GL2Listener implements GLEventListener, TextureDraw01A
private GLU glu = new GLU();
private TextureData textureData;
private Texture texture;
+ boolean keepTextureBound;
public TextureDraw01GL2Listener(TextureData td) {
this.textureData = td;
+ this.keepTextureBound = false;
}
+ @Override
+ public void setKeepTextureBound(boolean v) {
+ this.keepTextureBound = v;
+ }
+ @Override
+ public Texture getTexture( ) {
+ return this.texture;
+ }
+
+ @Override
public void init(GLAutoDrawable drawable) {
+ GL2 gl = drawable.getGL().getGL2();
if(null!=textureData) {
this.texture = TextureIO.newTexture(drawable.getGL(), textureData);
+ if( keepTextureBound ) {
+ texture.enable(gl);
+ texture.bind(gl);
+ }
}
}
- public Texture getTexture( ) {
- return this.texture;
- }
-
+ @Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
GL2 gl = drawable.getGL().getGL2();
gl.glMatrixMode(GL2ES1.GL_PROJECTION);
@@ -67,6 +81,7 @@ public class TextureDraw01GL2Listener implements GLEventListener, TextureDraw01A
gl.glLoadIdentity();
}
+ @Override
public void dispose(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
if(null!=texture) {
@@ -78,13 +93,16 @@ public class TextureDraw01GL2Listener implements GLEventListener, TextureDraw01A
}
}
+ @Override
public void display(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
// draw one quad with the texture
if(null!=texture) {
- texture.enable(gl);
- texture.bind(gl);
+ if( !keepTextureBound ) {
+ texture.enable(gl);
+ texture.bind(gl);
+ }
gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE);
TextureCoords coords = texture.getImageTexCoords();
gl.glBegin(GL2.GL_QUADS);
@@ -97,7 +115,9 @@ public class TextureDraw01GL2Listener implements GLEventListener, TextureDraw01A
gl.glTexCoord2f(coords.left(), coords.top());
gl.glVertex3f(0, 1, 0);
gl.glEnd();
- texture.disable(gl);
+ if( !keepTextureBound ) {
+ texture.disable(gl);
+ }
}
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java
index 75a98ed1e..3e58d3c79 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/DemoGL2ES1TextureImmModeSink.java
@@ -58,9 +58,11 @@ public class DemoGL2ES1TextureImmModeSink implements GLEventListener, TextureDra
private GLU glu = new GLU();
private TextureData textureData;
private Texture texture;
+ boolean keepTextureBound;
public DemoGL2ES1TextureImmModeSink() {
this.ims = ImmModeSink.createFixed(32, 3, GL.GL_FLOAT, 4, GL.GL_FLOAT, 0, GL.GL_FLOAT, 2, GL.GL_FLOAT, GL.GL_STATIC_DRAW);
+ this.keepTextureBound = false;
}
public void setForceFFPEmu(boolean forceFFPEmu, boolean verboseFFPEmu, boolean debugFFPEmu, boolean traceFFPEmu) {
@@ -70,6 +72,17 @@ public class DemoGL2ES1TextureImmModeSink implements GLEventListener, TextureDra
this.traceFFPEmu = traceFFPEmu;
}
+
+ @Override
+ public void setKeepTextureBound(boolean v) {
+ this.keepTextureBound = v;
+ }
+ @Override
+ public Texture getTexture( ) {
+ return this.texture;
+ }
+
+ @Override
public void init(GLAutoDrawable drawable) {
GL _gl = drawable.getGL();
if(debugFFPEmu) {
@@ -87,15 +100,16 @@ public class DemoGL2ES1TextureImmModeSink implements GLEventListener, TextureDra
InputStream testTextureStream = testTextureUrlConn.getInputStream();
textureData = TextureIO.newTextureData(gl.getGLProfile(), testTextureStream , false /* mipmap */, TextureIO.PNG);
texture = TextureIO.newTexture(gl, textureData);
+ if( keepTextureBound && null != texture ) {
+ texture.enable(gl);
+ texture.bind(gl);
+ }
} catch (Exception e) {
e.printStackTrace();
}
}
- public Texture getTexture( ) {
- return this.texture;
- }
-
+ @Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
GL2ES1 gl = drawable.getGL().getGL2ES1();
gl.glMatrixMode(GL2ES1.GL_PROJECTION);
@@ -105,6 +119,7 @@ public class DemoGL2ES1TextureImmModeSink implements GLEventListener, TextureDra
gl.glLoadIdentity();
}
+ @Override
public void dispose(GLAutoDrawable drawable) {
GL2ES1 gl = drawable.getGL().getGL2ES1();
if(null!=texture) {
@@ -116,13 +131,16 @@ public class DemoGL2ES1TextureImmModeSink implements GLEventListener, TextureDra
}
}
+ @Override
public void display(GLAutoDrawable drawable) {
GL2ES1 gl = drawable.getGL().getGL2ES1();
// draw one quad with the texture
if(null!=texture) {
- texture.enable(gl);
- texture.bind(gl);
+ if( !keepTextureBound ) {
+ texture.enable(gl);
+ texture.bind(gl);
+ }
// gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE);
TextureCoords coords = texture.getImageTexCoords();
ims.glBegin(ImmModeSink.GL_QUADS);
@@ -135,7 +153,9 @@ public class DemoGL2ES1TextureImmModeSink implements GLEventListener, TextureDra
ims.glTexCoord2f(coords.left(), coords.top());
ims.glVertex3f(0, 1, 0);
ims.glEnd(gl);
- texture.disable(gl);
+ if( !keepTextureBound ) {
+ texture.disable(gl);
+ }
}
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java
index 8289cc381..c92174a77 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java
@@ -108,7 +108,7 @@ public class TestJPEGImage01NEWT extends UITestCase {
// load texture from file inside current GL context to match the way
// the bug submitter was doing it
- final GLEventListener gle = new TextureDraw01ES2Listener( texData ) ;
+ final GLEventListener gle = new TextureDraw01ES2Listener( texData, 0 ) ;
glad.addGLEventListener(gle);
glad.addGLEventListener(new GLEventListener() {
boolean shot = false;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTCompareNewtAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTCompareNewtAWT.java
index 653923bc4..dbb4002a3 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTCompareNewtAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTCompareNewtAWT.java
@@ -137,7 +137,7 @@ public class TestJPEGJoglAWTCompareNewtAWT extends UITestCase {
// load texture from file inside current GL context to match the way
// the bug submitter was doing it
- final GLEventListener gle = new TextureDraw01ES2Listener( texData ) ;
+ final GLEventListener gle = new TextureDraw01ES2Listener( texData, 0 ) ;
glad1.addGLEventListener(gle);
glad1.addGLEventListener(new GLEventListener() {
boolean shot = false;
@@ -193,7 +193,7 @@ public class TestJPEGJoglAWTCompareNewtAWT extends UITestCase {
// the bug submitter was doing it
final GLEventListener gle;
if( texData != null ) {
- gle = new TextureDraw01ES2Listener( texData ) ;
+ gle = new TextureDraw01ES2Listener( texData, 0 ) ;
glad1.addGLEventListener(gle);
} else {
gle = null;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGTextureFromFileNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGTextureFromFileNEWT.java
index 13686cc22..60855e5be 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGTextureFromFileNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGTextureFromFileNEWT.java
@@ -184,7 +184,7 @@ public class TestJPEGTextureFromFileNEWT extends UITestCase {
// load texture from file inside current GL context to match the way
// the bug submitter was doing it
- final GLEventListener gle = useFFP ? new TextureDraw01GL2Listener( texData ) : new TextureDraw01ES2Listener( texData ) ;
+ final GLEventListener gle = useFFP ? new TextureDraw01GL2Listener( texData ) : new TextureDraw01ES2Listener( texData, 0 ) ;
glad.addGLEventListener(gle);
glad.addGLEventListener(new GLEventListener() {
boolean shot = false;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage01NEWT.java
index 91ace8420..29e041908 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGImage01NEWT.java
@@ -109,7 +109,7 @@ public class TestPNGImage01NEWT extends UITestCase {
// load texture from file inside current GL context to match the way
// the bug submitter was doing it
- final TextureDraw01ES2Listener gle = new TextureDraw01ES2Listener( texData ) ;
+ final TextureDraw01ES2Listener gle = new TextureDraw01ES2Listener( texData, 0 ) ;
// gle.setClearColor(new float[] { 1.0f, 0.0f, 0.0f, 1.0f } );
glad.addGLEventListener(gle);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
index 6a15300a7..191d67d31 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileAWT.java
@@ -133,7 +133,7 @@ public class TestPNGTextureFromFileAWT extends UITestCase {
// load texture from file inside current GL context to match the way
// the bug submitter was doing it
- final GLEventListener gle = useFFP ? new TextureDraw01GL2Listener( texData ) : new TextureDraw01ES2Listener( texData ) ;
+ final GLEventListener gle = useFFP ? new TextureDraw01GL2Listener( texData ) : new TextureDraw01ES2Listener( texData, 0 ) ;
glc.addGLEventListener(gle);
glc.addGLEventListener(new GLEventListener() {
boolean shot = false;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
index 1bc526429..ce363b612 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
@@ -174,7 +174,7 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
// load texture from file inside current GL context to match the way
// the bug submitter was doing it
- final GLEventListener gle = useFFP ? new TextureDraw01GL2Listener( texData ) : new TextureDraw01ES2Listener( texData ) ;
+ final GLEventListener gle = useFFP ? new TextureDraw01GL2Listener( texData ) : new TextureDraw01ES2Listener( texData, 0 ) ;
glad.addGLEventListener(gle);
glad.addGLEventListener(new GLEventListener() {
boolean shot = false;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTGATextureFromFileNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTGATextureFromFileNEWT.java
index 3e1acdb39..859e4e4b5 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTGATextureFromFileNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTGATextureFromFileNEWT.java
@@ -105,7 +105,7 @@ public class TestTGATextureFromFileNEWT extends UITestCase {
// load texture from file inside current GL context to match the way
// the bug submitter was doing it
- final GLEventListener gle = useFFP ? new TextureDraw01GL2Listener( texData ) : new TextureDraw01ES2Listener( texData ) ;
+ final GLEventListener gle = useFFP ? new TextureDraw01GL2Listener( texData ) : new TextureDraw01ES2Listener( texData, 0 ) ;
glad.addGLEventListener(gle);
glad.addGLEventListener(new GLEventListener() {
boolean shot = false;