();
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;
private int textureFragmentShaderHashCode = 0;
private boolean aRatioAdjustment = true;
private boolean aRatioLbox = false;
private final Vec4f aRatioLboxBackColor = new Vec4f();
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 TextureSequence.TextureFrame addFrame(final GL gl, final Texture tex) {
return addFrame(gl, new TextureSequence.TextureFrame(tex));
}
public final TextureSequence.TextureFrame addFrame(final GL gl, final TextureSequence.TextureFrame frame) {
frames.add(frame);
frame.texture.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]);
return frame;
}
public boolean removeFrame(final TextureFrame tex) {
return frames.remove(tex);
}
public void removeAllFrames() {
frames.clear();
}
public final void addFrame(final GL gl, final Class> context, final String imageResourcePath, final String imageSuffix) throws IOException {
final URLConnection urlConn = IOUtil.getResource(imageResourcePath, context.getClassLoader(), context);
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 isManualStepping() { return manualStepping; }
/** Returns {@code true} if not {@link #isManualStepping()} and {@link #getFrameCount()} > 1 */
public final boolean isSequenceAnimating() { return !manualStepping && frames.size() > 1; }
public final TextureSequence.TextureFrame getFrame(final int idx) { return frames.get(idx); }
public void destroy(final 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;
}
/**
* {@inheritDoc}
*
* Defaults to {@code true} and toggling is supported via {@link #setARatioAdjustment(boolean)}
*
*/
@Override
public boolean useARatioAdjustment() { return aRatioAdjustment; }
/**
* {@inheritDoc}
*
* Defaults to {@code true}.
*
*/
@Override
public void setARatioAdjustment(final boolean v) { aRatioAdjustment = v; }
/**
* {@inheritDoc}
*
* Defaults to {@code false} and toggling is supported via {@link #setARatioLetterbox(boolean, Vec4f)}
*
*/
@Override
public boolean useARatioLetterbox() { return aRatioLbox; }
@Override
public Vec4f getARatioLetterboxBackColor() { return aRatioLboxBackColor; }
/**
* {@inheritDoc}
*
* Defaults to {@code false}.
*
*/
@Override
public void setARatioLetterbox(final boolean v, final Vec4f backColor) {
aRatioLbox = v;
if( null != backColor ) {
aRatioLboxBackColor.set(backColor);
}
};
@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(final 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 setTextureLookupFunctionName(final String texLookupFuncName) throws IllegalStateException {
if(useBuildInTexLookup) {
textureLookupFunctionName = "texture2D";
} else if(null != texLookupFuncName && texLookupFuncName.length()>0) {
textureLookupFunctionName = texLookupFuncName;
}
textureFragmentShaderHashCode = 0;
return textureLookupFunctionName;
}
@Override
public String getTextureLookupFunctionName() throws IllegalStateException {
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";
}
@Override
public String getTextureFragmentShaderHashID() {
// return getTextureSampler2DType()+";"+getTextureLookupFunctionName()+";"+getTextureLookupFragmentShaderImpl();
if( useBuildInTexLookup ) {
return getTextureSampler2DType()+";"+getTextureLookupFunctionName();
} else {
return getTextureLookupFragmentShaderImpl();
}
}
@Override
public int getTextureFragmentShaderHashCode() {
if( !isTextureAvailable() ) {
textureFragmentShaderHashCode = 0;
return 0;
} else if( 0 == textureFragmentShaderHashCode ) {
final int hash = getTextureFragmentShaderHashID().hashCode();
textureFragmentShaderHashCode = hash;
}
return textureFragmentShaderHashCode;
}
}