From fa9f2883664ba015f778c32df9aa69897db63d55 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 19 May 2014 23:35:06 +0200 Subject: Bug 801: Split GraphUI's TextureButton: TextureSeqButton (Base) and it's derivations ImageSeqButton + GLEventListenerButton + MediaPlayerButton Split GraphUI's TextureButton to TextureSeqButton (Base) and it's derivations: - ImageSeqButton - displays an ImageSequence - GLEventListenerButton - displays any GLEventListener as rendered into FBO as an ImageSequence - MediaPlayerButton - displays movies - Added public ImageSequence impl. TextureSequence, was private SingleTextureSeqFrame. - Demo GPUUISceneGLListener0A shows: - MediaPlayerButton w/ Big Buck Bunny film - GLEventListenerButton w/ GearsES2 - ImageSeqButton w/ 2 textures (pressed/released) --- .../jogamp/opengl/util/texture/ImageSequence.java | 176 +++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java (limited to 'src/jogl') diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java new file mode 100644 index 000000000..4622d6975 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/ImageSequence.java @@ -0,0 +1,176 @@ +/** + * Copyright 2014 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 java.io.IOException; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; + +import javax.media.opengl.GL; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +import com.jogamp.common.util.IOUtil; + +/** + * Simple {@link TextureSequence} implementation + * allowing {@link #addFrame(GL, Texture) existing textures} + * or {@link #addFrame(GL, Class, String, String) image streams} + * to be used and replayed as {@link TextureSequence.TextureFrame frames}. + */ +public class ImageSequence implements TextureSequence { + private final int textureUnit; + private final boolean useBuildInTexLookup; + private final List frames = new ArrayList(); + private final int[] texMinMagFilter = { GL.GL_NEAREST, GL.GL_NEAREST }; + private final int[] texWrapST = { GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE }; + private volatile int frameIdx = 0; + private volatile boolean manualStepping = false; + + public ImageSequence(final int textureUnit, final boolean useBuildInTexLookup) { + this.textureUnit = textureUnit; + this.useBuildInTexLookup = useBuildInTexLookup; + } + + public void setParams(final int magFilter, final int minFilter, final int wrapS, final int wrapT) { + texMinMagFilter[0] = minFilter; + texMinMagFilter[1] = magFilter; + texWrapST[0] = wrapS; + texWrapST[1] = wrapT; + } + + public final void addFrame(final GL gl, final Texture tex) { + final TextureSequence.TextureFrame frame = new TextureSequence.TextureFrame(tex); + frames.add(frame); + tex.bind(gl); + gl.glTexParameteri(getTextureTarget(), GL.GL_TEXTURE_MIN_FILTER, texMinMagFilter[0]); + gl.glTexParameteri(getTextureTarget(), GL.GL_TEXTURE_MAG_FILTER, texMinMagFilter[1]); + gl.glTexParameteri(getTextureTarget(), GL.GL_TEXTURE_WRAP_S, texWrapST[0]); + gl.glTexParameteri(getTextureTarget(), GL.GL_TEXTURE_WRAP_T, texWrapST[1]); + } + + public final void addFrame(final GL gl, final Class context, final String imageResourcePath, final String imageSuffix) throws IOException { + URLConnection urlConn = IOUtil.getResource(context, imageResourcePath); + if(null != urlConn) { + final TextureData texData = TextureIO.newTextureData(GLProfile.getGL2ES2(), urlConn.getInputStream(), false, imageSuffix); + final Texture tex = new Texture(getTextureTarget()); + tex.updateImage(gl, texData); + addFrame(gl, tex); + } + } + public final int getFrameCount() { return frames.size(); } + public final int getCurrentIdx() { return frameIdx; } + public final void setCurrentIdx(final int idx) throws IndexOutOfBoundsException { + if( 0 > idx || idx >= frames.size() ) { + throw new IndexOutOfBoundsException("idx shall be within 0 <= "+idx+" < "+frames.size()); + } + frameIdx=idx; + } + public final void setManualStepping(final boolean v) { manualStepping = v; } + public final boolean getManualStepping() { return manualStepping; } + public final TextureSequence.TextureFrame getFrame(final int idx) { return frames.get(idx); } + + public void destroy(GL gl) throws GLException { + for(int i=frames.size()-1; i>=0; i--) { + frames.get(i).getTexture().destroy(gl); + } + frames.clear(); + } + + @Override + public int getTextureTarget() { + return GL.GL_TEXTURE_2D; + } + + @Override + public int getTextureUnit() { + return textureUnit; + } + + @Override + public int[] getTextureMinMagFilter() { + return texMinMagFilter; + } + + @Override + public int[] getTextureWrapST() { + return texWrapST; + } + + @Override + public boolean isTextureAvailable() { return frames.size() > 0; } + + @Override + public TextureSequence.TextureFrame getLastTexture() throws IllegalStateException { + return frames.get(frameIdx); // may return null + } + + @Override + public TextureSequence.TextureFrame getNextTexture(GL gl) throws IllegalStateException { + if( !manualStepping ) { + frameIdx = ( frameIdx + 1 ) % frames.size(); + } + return frames.get(frameIdx); + } + + @Override + public String getRequiredExtensionsShaderStub() throws IllegalStateException { + return "// TextTextureSequence: No extensions required\n"; + } + + @Override + public String getTextureSampler2DType() throws IllegalStateException { + return "sampler2D" ; + } + + private String textureLookupFunctionName = "myTexture2D"; + + @Override + public String getTextureLookupFunctionName(String desiredFuncName) throws IllegalStateException { + if(useBuildInTexLookup) { + return "texture2D"; + } + if(null != desiredFuncName && desiredFuncName.length()>0) { + textureLookupFunctionName = desiredFuncName; + } + return textureLookupFunctionName; + } + + @Override + public String getTextureLookupFragmentShaderImpl() throws IllegalStateException { + if(useBuildInTexLookup) { + return ""; + } + return + "\n"+ + "vec4 "+textureLookupFunctionName+"(in "+getTextureSampler2DType()+" image, in vec2 texCoord) {\n"+ + " return texture2D(image, texCoord);\n"+ + "}\n\n"; + } +} -- cgit v1.2.3