From 8f1373e15eef1fb8bd00dfe500a2eddc71a74d7e Mon Sep 17 00:00:00 2001
From: Sven Gothel
Date: Thu, 7 Nov 2013 15:30:26 +0100
Subject: Android ES3 Movie Demos: Add workaround for: P0003: Extension
'GL_OES_EGL_image_external' not supported
+ // Bug on Nexus 10, ES3 - Android 4.3, where
+ // GL_OES_EGL_image_external extension directive leads to a failure _with_ '#version 300 es' !
+ // P0003: Extension 'GL_OES_EGL_image_external' not supported
+ preludeGLSLVersion = false;
---
.../com/jogamp/opengl/util/av/GLMediaPlayer.java | 3 -
.../opengl/util/texture/TextureSequence.java | 3 +
.../junit/jogl/demos/TextureSequenceDemo01.java | 33 +--
.../jogl/demos/es2/TextureSequenceCubeES2.java | 166 ++++++++-------
.../test/junit/jogl/demos/es2/av/MovieSimple.java | 229 +++++++++++----------
5 files changed, 229 insertions(+), 205 deletions(-)
diff --git a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
index f0864f949..b0a645cbb 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/av/GLMediaPlayer.java
@@ -318,9 +318,6 @@ public interface GLMediaPlayer extends TextureSequence {
public int getTextureCount();
- /** Returns the texture target used by implementation. */
- public int getTextureTarget();
-
/** Sets the texture unit. Defaults to 0. */
public void setTextureUnit(int u);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
index 6f1dd4c64..6c2949c2b 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureSequence.java
@@ -163,6 +163,9 @@ public interface TextureSequence {
public void newFrameAvailable(T ts, TextureFrame newFrame, long when);
}
+ /** Returns the texture target used by implementation. */
+ public int getTextureTarget();
+
/** Return the texture unit used to render the current frame. */
public int getTextureUnit();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureSequenceDemo01.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureSequenceDemo01.java
index ab3899a7b..38d4d8be8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureSequenceDemo01.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/TextureSequenceDemo01.java
@@ -13,16 +13,16 @@ import com.jogamp.opengl.util.texture.TextureIO;
import com.jogamp.opengl.util.texture.TextureSequence;
public class TextureSequenceDemo01 implements TextureSequence {
- TextureSequence.TextureFrame frame = null;
+ TextureSequence.TextureFrame frame = null;
int textureUnit = 0;
protected int[] texMinMagFilter = { GL.GL_NEAREST, GL.GL_NEAREST };
protected int[] texWrapST = { GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE };
final boolean useBuildInTexLookup;
-
+
public TextureSequenceDemo01(boolean useBuildInTexLookup) {
this.useBuildInTexLookup = useBuildInTexLookup;
}
-
+
public void initGLResources(GL gl) throws GLException {
if(null == frame) {
TextureData texData = null;
@@ -38,24 +38,29 @@ public class TextureSequenceDemo01 implements TextureSequence {
frame = new TextureSequence.TextureFrame(tex);
tex.bind(gl);
gl.glTexParameteri(tex.getTarget(), GL.GL_TEXTURE_MIN_FILTER, texMinMagFilter[0]);
- gl.glTexParameteri(tex.getTarget(), GL.GL_TEXTURE_MAG_FILTER, texMinMagFilter[1]);
+ gl.glTexParameteri(tex.getTarget(), GL.GL_TEXTURE_MAG_FILTER, texMinMagFilter[1]);
gl.glTexParameteri(tex.getTarget(), GL.GL_TEXTURE_WRAP_S, texWrapST[0]);
gl.glTexParameteri(tex.getTarget(), GL.GL_TEXTURE_WRAP_T, texWrapST[1]);
}
}
-
+
public void destroyGLResources(GL gl) {
if(null != frame) {
frame.getTexture().destroy(gl);
frame = null;
}
}
-
+
public void destroy(GL gl) throws GLException {
frame.getTexture().destroy(gl);
- frame = null;
+ frame = null;
+ }
+
+ @Override
+ public int getTextureTarget() {
+ return GL.GL_TEXTURE_2D;
}
-
+
@Override
public int getTextureUnit() {
return textureUnit;
@@ -80,19 +85,19 @@ public class TextureSequenceDemo01 implements TextureSequence {
public TextureSequence.TextureFrame getNextTexture(GL gl) throws IllegalStateException {
return frame;
}
-
+
@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) {
@@ -103,7 +108,7 @@ public class TextureSequenceDemo01 implements TextureSequence {
}
return textureLookupFunctionName;
}
-
+
@Override
public String getTextureLookupFragmentShaderImpl() throws IllegalStateException {
if(useBuildInTexLookup) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java
index a2d3eb6bf..616aa52c3 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/TextureSequenceCubeES2.java
@@ -3,14 +3,14 @@
*
* 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
@@ -20,7 +20,7 @@
* 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.
@@ -39,6 +39,7 @@ import javax.media.opengl.GLProfile;
import javax.media.opengl.GLUniformData;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
+import com.jogamp.common.os.Platform;
import com.jogamp.newt.Window;
import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
@@ -73,19 +74,20 @@ public class TextureSequenceCubeES2 implements GLEventListener {
// private float zoom0=-5.0f, zoom=zoom0;
// private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f;
private float zoom=-2.3f;
- private float view_rotx = 0.0f, view_roty = 0.0f, view_rotz = 0.0f;
+ private float view_rotx = 0.0f, view_roty = 0.0f;
+ private final float view_rotz = 0.0f;
int[] vboNames = new int[4];
boolean innerCube;
-
+
private final MouseListener mouseAction = new MouseAdapter() {
int lx = 0;
int ly = 0;
boolean first = false;
public void mousePressed(MouseEvent e) {
- first = true;
+ first = true;
}
- public void mouseMoved(MouseEvent e) {
+ public void mouseMoved(MouseEvent e) {
first = false;
}
public void mouseDragged(MouseEvent e) {
@@ -102,7 +104,7 @@ public class TextureSequenceCubeES2 implements GLEventListener {
height=comp.getHeight();
} else {
throw new RuntimeException("Event source neither Window nor Component: "+source);
- }
+ }
if(e.getPointerCount()==2) {
// 2 pointers zoom ..
if(first) {
@@ -112,14 +114,14 @@ public class TextureSequenceCubeES2 implements GLEventListener {
}
int nv = Math.abs(e.getY(0)-e.getY(1));
int dy = nv - lx;
-
+
{
final float o = zoom;
- final float d = 40f*Math.signum(dy)/(float)height;
+ final float d = 40f*Math.signum(dy)/height;
zoom += d;
System.err.println("zoom.d: "+o+" + "+d+" -> "+zoom);
}
-
+
lx = nv;
} else {
// 1 pointer rotate
@@ -136,7 +138,7 @@ public class TextureSequenceCubeES2 implements GLEventListener {
lx = nx;
ly = ny;
}
- }
+ }
public void mouseWheelMoved(MouseEvent e) {
// System.err.println("XXX "+e);
if( !e.isShiftDown() ) {
@@ -147,31 +149,44 @@ public class TextureSequenceCubeES2 implements GLEventListener {
}
}
};
-
+
static final String shaderBasename = "texsequence_xxx";
static final String myTextureLookupName = "myTexture2D";
-
+
private void initShader(GL2ES2 gl) {
// Create & Compile the shader objects
- ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(),
+ ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(),
"shader", "shader/bin", shaderBasename, true);
- ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(),
+ ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(),
"shader", "shader/bin", shaderBasename, true);
- rsVp.defaultShaderCustomization(gl, true, true);
- int rsFpPos = rsFp.addGLSLVersion(gl);
+ boolean preludeGLSLVersion = true;
+ if( GLES2.GL_TEXTURE_EXTERNAL_OES == texSeq.getTextureTarget() ) {
+ if( !gl.isExtensionAvailable(GLExtensions.OES_EGL_image_external) ) {
+ throw new GLException(GLExtensions.OES_EGL_image_external+" requested but not available");
+ }
+ if( Platform.OSType.ANDROID == Platform.getOSType() && gl.isGLES3() ) {
+ // Bug on Nexus 10, ES3 - Android 4.3, where
+ // GL_OES_EGL_image_external extension directive leads to a failure _with_ '#version 300 es' !
+ // P0003: Extension 'GL_OES_EGL_image_external' not supported
+ preludeGLSLVersion = false;
+ }
+ }
+ rsVp.defaultShaderCustomization(gl, preludeGLSLVersion, true);
+
+ int rsFpPos = preludeGLSLVersion ? rsFp.addGLSLVersion(gl) : 0;
rsFpPos = rsFp.insertShaderSource(0, rsFpPos, texSeq.getRequiredExtensionsShaderStub());
rsFpPos = rsFp.addDefaultShaderPrecision(gl, rsFpPos);
-
- final String texLookupFuncName = texSeq.getTextureLookupFunctionName(myTextureLookupName);
+
+ final String texLookupFuncName = texSeq.getTextureLookupFunctionName(myTextureLookupName);
rsFp.replaceInShaderSource(myTextureLookupName, texLookupFuncName);
-
+
// Inject TextureSequence shader details
final StringBuilder sFpIns = new StringBuilder();
sFpIns.append("uniform ").append(texSeq.getTextureSampler2DType()).append(" mgl_ActiveTexture;\n");
sFpIns.append(texSeq.getTextureLookupFragmentShaderImpl());
rsFp.insertShaderSource(0, "TEXTURE-SEQUENCE-CODE-BEGIN", 0, sFpIns);
-
+
// Create & Link the shader program
ShaderProgram sp = new ShaderProgram();
sp.add(rsVp);
@@ -184,9 +199,9 @@ public class TextureSequenceCubeES2 implements GLEventListener {
st = new ShaderState();
st.attachShaderProgram(gl, sp, false);
}
-
+
GLArrayDataServer interleavedVBO, cubeIndicesVBO;
-
+
public void init(GLAutoDrawable drawable) {
GL2ES2 gl = drawable.getGL().getGL2ES2();
System.err.println(JoglVersion.getGLInfo(gl, null));
@@ -195,15 +210,10 @@ public class TextureSequenceCubeES2 implements GLEventListener {
return;
}
final Texture tex= frame.getTexture();
-
- final boolean useExternalTexture = GLES2.GL_TEXTURE_EXTERNAL_OES == tex.getTarget();
- if(useExternalTexture && !gl.isExtensionAvailable(GLExtensions.OES_EGL_image_external)) {
- throw new GLException(GLExtensions.OES_EGL_image_external+" requested but not available");
- }
-
+
initShader(gl);
- // Push the 1st uniform down the path
+ // Push the 1st uniform down the path
st.useProgram(gl, true);
pmvMatrix = new PMVMatrix();
@@ -215,10 +225,10 @@ public class TextureSequenceCubeES2 implements GLEventListener {
if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", texSeq.getTextureUnit()))) {
throw new GLException("Error setting mgl_ActiveTexture in shader: "+st);
}
-
-
+
+
// calculate centered tex coords w/ aspect ratio
- float[] fixedCubeTexCoords = new float[s_cubeTexCoords.length];
+ float[] fixedCubeTexCoords = new float[s_cubeTexCoords.length];
{
final float aspect = tex.getAspectRatio();
final TextureCoords tc = tex.getImageTexCoords();
@@ -242,27 +252,27 @@ public class TextureSequenceCubeES2 implements GLEventListener {
}
}
}
-
+
interleavedVBO = GLArrayDataServer.createGLSLInterleaved(3+4+2, GL.GL_FLOAT, false, 3*6*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_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<6*4; i++) {
ib.put(s_cubeVertices, i*3, 3);
- ib.put(s_cubeColors, i*4, 4);
+ ib.put(s_cubeColors, i*4, 4);
//ib.put(s_cubeNormals, i*3, 3);
ib.put(fixedCubeTexCoords, i*2, 2);
- }
+ }
}
interleavedVBO.seal(gl, true);
interleavedVBO.enableBuffer(gl, false);
st.ownAttribute(interleavedVBO, true);
-
+
cubeIndicesVBO = GLArrayDataServer.createData(6, GL.GL_UNSIGNED_SHORT, 6, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER);
for(int i=0; i<6*6; i++) {
cubeIndicesVBO.puts(s_cubeIndices[i]);
@@ -270,26 +280,26 @@ public class TextureSequenceCubeES2 implements GLEventListener {
cubeIndicesVBO.seal(gl, true);
cubeIndicesVBO.enableBuffer(gl, false);
st.ownAttribute(cubeIndicesVBO, true);
-
-
+
+
gl.glEnable(GL2ES2.GL_DEPTH_TEST);
st.useProgram(gl, false);
final Object upstreamWidget = drawable.getUpstreamWidget();
- if (upstreamWidget instanceof Window) {
+ if (upstreamWidget instanceof Window) {
final Window window = (Window) upstreamWidget;
window.addMouseListener(mouseAction);
} else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) {
final java.awt.Component comp = (java.awt.Component) upstreamWidget;
new com.jogamp.newt.event.awt.AWTMouseAdapter(mouseAction).addTo(comp);
}
-
+
// Let's show the completed shader state ..
System.out.println("iVBO: "+interleavedVBO);
System.out.println(st);
}
-
+
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
GL2ES2 gl = drawable.getGL().getGL2ES2();
@@ -318,8 +328,8 @@ public class TextureSequenceCubeES2 implements GLEventListener {
st.useProgram(gl, false);
}
}
-
-
+
+
private void reshapePMV(int width, int height) {
if(null != pmvMatrix) {
pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
@@ -332,7 +342,7 @@ public class TextureSequenceCubeES2 implements GLEventListener {
nearPlaneNormalized = 0f;
}
System.err.println("XXX0: Perspective nearPlaneNormalized: "+nearPlaneNormalized);
-
+
pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
pmvMatrix.glLoadIdentity();
pmvMatrix.glTranslatef(0, 0, zoom);
@@ -344,7 +354,7 @@ public class TextureSequenceCubeES2 implements GLEventListener {
public void dispose(GLAutoDrawable drawable) {
GL2ES2 gl = drawable.getGL().getGL2ES2();
- texSeq = null;
+ texSeq = null;
pmvMatrixUniform = null;
if( null != pmvMatrix ) {
pmvMatrix.destroy();
@@ -361,13 +371,13 @@ public class TextureSequenceCubeES2 implements GLEventListener {
GL2ES2 gl = drawable.getGL().getGL2ES2();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
-
+
if( null == st ) {
return;
}
-
+
st.useProgram(gl, true);
-
+
pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
pmvMatrix.glLoadIdentity();
pmvMatrix.glTranslatef(0, 0, zoom);
@@ -383,18 +393,18 @@ public class TextureSequenceCubeES2 implements GLEventListener {
tex = texFrame.getTexture();
gl.glActiveTexture(GL.GL_TEXTURE0+texSeq.getTextureUnit());
tex.enable(gl);
- tex.bind(gl);
+ tex.bind(gl);
}
}
cubeIndicesVBO.bindBuffer(gl, true); // keeps VBO binding
gl.glDrawElements(GL2ES2.GL_TRIANGLES, cubeIndicesVBO.getElementCount() * cubeIndicesVBO.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0);
cubeIndicesVBO.bindBuffer(gl, false);
-
+
if(null != tex) {
- tex.disable(gl);
+ tex.disable(gl);
}
interleavedVBO.enableBuffer(gl, false);
- st.useProgram(gl, false);
+ st.useProgram(gl, false);
}
static final float[] light_position = { -50.f, 50.f, 50.f, 0.f };
@@ -406,18 +416,18 @@ public class TextureSequenceCubeES2 implements GLEventListener {
private static final float[] s_cubeVertices = /* f b t b r l */
{
-1f, 1f, 1f, 1f, -1f, 1f, 1f, 1f, 1f, -1f, -1f, 1f,
-
+
-1f, 1f, -1f, 1f, -1f, -1f, 1f, 1f, -1f, -1f, -1f, -1f,
-
+
-1f, -1f, 1f, 1f, -1f, -1f, 1f, -1f, 1f, -1f, -1f, -1f,
-
+
-1f, 1f, 1f, 1f, 1f, -1f, 1f, 1f, 1f, -1f, 1f, -1f,
-
+
1f, -1f, 1f, 1f, 1f, -1f, 1f, 1f, 1f, 1f, -1f, -1f,
-
+
-1f, -1f, 1f, -1f, 1f, -1f, -1f, 1f, 1f, -1f, -1f, -1f
};
-
+
private static final float[] s_cubeTexCoords =
{ // LT RB RT LB
0f, 1f, 1f, 0f, 1f, 1f, 0f, 0f,
@@ -436,39 +446,39 @@ public class TextureSequenceCubeES2 implements GLEventListener {
private static final float[] s_cubeColors =
{
1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f,
-
+
40f/255f, 80f/255f, 160f/255f, 255f/255f, 40f/255f, 80f/255f, 160f/255f, 255f/255f,
40f/255f, 80f/255f, 160f/255f, 255f/255f, 40f/255f, 80f/255f, 160f/255f, 255f/255f,
-
+
40f/255f, 80f/255f, 160f/255f, 255f/255f, 40f/255f, 80f/255f, 160f/255f, 255f/255f,
- 40f/255f, 80f/255f, 160f/255f, 255f/255f, 40f/255f, 80f/255f, 160f/255f, 255f/255f,
-
+ 40f/255f, 80f/255f, 160f/255f, 255f/255f, 40f/255f, 80f/255f, 160f/255f, 255f/255f,
+
128f/255f, 128f/255f, 128f/255f, 255f/255f, 128f/255f, 128f/255f, 128f/255f, 255f/255f,
128f/255f, 128f/255f, 128f/255f, 255f/255f, 128f/255f, 128f/255f, 128f/255f, 255f/255f,
-
+
255f/255f, 110f/255f, 10f/255f, 255f/255f, 255f/255f, 110f/255f, 10f/255f, 255f/255f,
255f/255f, 110f/255f, 10f/255f, 255f/255f, 255f/255f, 110f/255f, 10f/255f, 255f/255f,
-
+
255f/255f, 70f/255f, 60f/255f, 255f/255f, 255f/255f, 70f/255f, 60f/255f, 255f/255f,
255f/255f, 70f/255f, 60f/255f, 255f/255f, 255f/255f, 70f/255f, 60f/255f, 255f/255f
};
-
+
/*
private static final float[] s_cubeNormals =
{
0f, 0f, 1f, 0f, 0f, 1f, 0f, 0f, 1f, 0f, 0f, 1f,
-
+
0f, 0f, -1f, 0f, 0f, -1f, 0f, 0f, -1f, 0f, 0f, -1f,
-
+
0f, -1f, 0f, 0f, -1f, 0f, 0f, -1f, 0f, 0f, -1f, 0f,
-
+
0f, 1f, 0f, 0f, 1f, 0f, 0f, 1f, 0f, 0f, 1f, 0f,
-
+
1f, 0f, 0f, 1f, 0f, 0f, 1f, 0f, 0f, 1f, 0f, 0f,
-
+
-1f, 0f, 0f, -1f, 0f, 0f, -1f, 0f, 0f, -1f, 0f, 0f
};*/
- private static final short[] s_cubeIndices =
+ private static final short[] s_cubeIndices =
{
0, 3, 1, 2, 0, 1, /* front */
6, 5, 4, 5, 7, 4, /* back */
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
index a087e7e46..897079ec2 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
@@ -3,14 +3,14 @@
*
* 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
@@ -20,7 +20,7 @@
* 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.
@@ -44,6 +44,7 @@ import javax.media.opengl.GLProfile;
import javax.media.opengl.GLUniformData;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
+import com.jogamp.common.os.Platform;
import com.jogamp.newt.Window;
import com.jogamp.newt.event.KeyAdapter;
import com.jogamp.newt.event.KeyEvent;
@@ -74,12 +75,12 @@ import com.jogamp.opengl.util.texture.TextureSequence;
import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
/**
- * Simple planar movie player w/ orthogonal 1:1 projection.
+ * Simple planar movie player w/ orthogonal 1:1 projection.
*/
public class MovieSimple implements GLEventListener {
public static final int EFFECT_NORMAL = 0;
public static final int EFFECT_GRADIENT_BOTTOM2TOP = 1<<1;
- public static final int EFFECT_TRANSPARENT = 1<<3;
+ public static final int EFFECT_TRANSPARENT = 1<<3;
private static boolean waitForKey = false;
private int winWidth, winHeight;
@@ -96,9 +97,9 @@ public class MovieSimple implements GLEventListener {
private int swapInterval = 1;
private GLMediaPlayer mPlayer;
- private boolean mPlayerShared;
+ private final boolean mPlayerShared;
private boolean mPlayerScaleOrig;
- private float[] verts = null;
+ private float[] verts = null;
private GLArrayDataServer interleavedVBO;
private volatile boolean resetGLState = false;
@@ -107,7 +108,7 @@ public class MovieSimple implements GLEventListener {
private GLUniformData pmvMatrixUniform;
private static final String shaderBasename = "texsequence_xxx";
private static final String myTextureLookupName = "myTexture2D";
-
+
/** Blender's Big Buck Bunny Trailer: 24f 640p VP8, Vorbis 44100Hz mono, WebM/Matroska Stream. */
public static final URI defURI;
static {
@@ -119,7 +120,7 @@ public class MovieSimple implements GLEventListener {
}
defURI = _defURI;
}
-
+
private final MouseListener mouseAction = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if(e.getY()<=winHeight/2 && null!=mPlayer && 1 == e.getClickCount()) {
@@ -144,16 +145,16 @@ public class MovieSimple implements GLEventListener {
public void mouseDragged(MouseEvent e) {
int x = e.getX();
int y = e.getY();
-
+
if(y>winHeight/2) {
final float dp = (float)(x-prevMouseX)/(float)winWidth;
- mPlayer.seek(mPlayer.getVideoPTS() + (int) (mPlayer.getDuration() * dp));
+ mPlayer.seek(mPlayer.getVideoPTS() + (int) (mPlayer.getDuration() * dp));
} else {
mPlayer.play();
- rotate = 1;
+ rotate = 1;
zoom = zoom1;
}
-
+
prevMouseX = x;
// prevMouseY = y;
}
@@ -164,12 +165,12 @@ public class MovieSimple implements GLEventListener {
}
}
};
-
+
private final KeyListener keyAction = new KeyAdapter() {
public void keyReleased(KeyEvent e) {
if( e.isAutoRepeat() ) {
return;
- }
+ }
System.err.println("MC "+e);
int pts0 = mPlayer.getVideoPTS();
int pts1 = 0;
@@ -195,7 +196,7 @@ public class MovieSimple implements GLEventListener {
break;
}
case KeyEvent.VK_MULTIPLY:
- mPlayer.setPlaySpeed(1.0f);
+ mPlayer.setPlaySpeed(1.0f);
break;
case KeyEvent.VK_SUBTRACT: {
float playSpeed = mPlayer.getPlaySpeed();
@@ -204,7 +205,7 @@ public class MovieSimple implements GLEventListener {
} else {
playSpeed -= 0.1f;
}
- mPlayer.setPlaySpeed(playSpeed);
+ mPlayer.setPlaySpeed(playSpeed);
} break;
case KeyEvent.VK_ADD: {
float playSpeed = mPlayer.getPlaySpeed();
@@ -213,7 +214,7 @@ public class MovieSimple implements GLEventListener {
} else {
playSpeed += 0.1f;
}
- mPlayer.setPlaySpeed(playSpeed);
+ mPlayer.setPlaySpeed(playSpeed);
} break;
case KeyEvent.VK_M: {
float audioVolume = mPlayer.getAudioVolume();
@@ -222,27 +223,27 @@ public class MovieSimple implements GLEventListener {
} else {
audioVolume = 1f;
}
- mPlayer.setAudioVolume(audioVolume);
+ mPlayer.setAudioVolume(audioVolume);
} break;
}
-
+
if( 0 != pts1 ) {
mPlayer.seek(pts1);
}
- }
+ }
};
-
- /**
- * Default constructor which also issues {@link #initStream(URI, int, int, int)} w/ default values
+
+ /**
+ * Default constructor which also issues {@link #initStream(URI, int, int, int)} w/ default values
* and polls until the {@link GLMediaPlayer} is {@link GLMediaPlayer.State#Initialized}.
* If {@link GLMediaEventListener#EVENT_CHANGE_EOS} is reached, the stream is started over again.
*
* This default constructor is merely useful for some drop-in test, e.g. using an applet.
- *
+ *
*/
public MovieSimple() {
this(null);
-
+
mPlayer.addEventListener(new GLMediaEventListener() {
@Override
public void newFrameAvailable(GLMediaPlayer ts, TextureFrame newFrame, long when) { }
@@ -259,7 +260,7 @@ public class MovieSimple implements GLEventListener {
mPlayer.seek(0);
mPlayer.play();
}
- }
+ }
});
initStream(defURI, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 3 /* textureCount */);
StreamException se = null;
@@ -285,50 +286,63 @@ public class MovieSimple implements GLEventListener {
}
System.out.println("pC.1a shared "+mPlayerShared+", "+mPlayer);
}
-
+
public void initStream(URI streamLoc, int vid, int aid, int textureCount) {
mPlayer.initStream(streamLoc, vid, aid, textureCount);
System.out.println("pC.1b "+mPlayer);
}
-
+
public void setSwapInterval(int v) { this.swapInterval = v; }
-
+
public GLMediaPlayer getGLMediaPlayer() { return mPlayer; }
-
+
public void setScaleOrig(boolean v) {
mPlayerScaleOrig = v;
}
-
+
/** defaults to true */
public void setOrthoProjection(boolean v) { orthoProjection=v; }
public boolean getOrthoProjection() { return orthoProjection; }
-
+
public boolean hasEffect(int e) { return 0 != ( effects & e ) ; }
public void setEffects(int e) { effects = e; };
public void setTransparency(float alpha) {
this.effects |= EFFECT_TRANSPARENT;
this.alpha = alpha;
- }
+ }
public void resetGLState() {
resetGLState = true;
}
-
+
private void initShader(GL2ES2 gl) {
// Create & Compile the shader objects
- ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MovieSimple.class,
+ ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MovieSimple.class,
"../shader", "../shader/bin", shaderBasename, true);
- ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MovieSimple.class,
+ ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MovieSimple.class,
"../shader", "../shader/bin", shaderBasename, true);
- rsVp.defaultShaderCustomization(gl, true, true);
- int rsFpPos = rsFp.addGLSLVersion(gl);
+ boolean preludeGLSLVersion = true;
+ if( GLES2.GL_TEXTURE_EXTERNAL_OES == mPlayer.getTextureTarget() ) {
+ if( !gl.isExtensionAvailable(GLExtensions.OES_EGL_image_external) ) {
+ throw new GLException(GLExtensions.OES_EGL_image_external+" requested but not available");
+ }
+ if( Platform.OSType.ANDROID == Platform.getOSType() && gl.isGLES3() ) {
+ // Bug on Nexus 10, ES3 - Android 4.3, where
+ // GL_OES_EGL_image_external extension directive leads to a failure _with_ '#version 300 es' !
+ // P0003: Extension 'GL_OES_EGL_image_external' not supported
+ preludeGLSLVersion = false;
+ }
+ }
+ rsVp.defaultShaderCustomization(gl, preludeGLSLVersion, true);
+
+ int rsFpPos = preludeGLSLVersion ? rsFp.addGLSLVersion(gl) : 0;
rsFpPos = rsFp.insertShaderSource(0, rsFpPos, mPlayer.getRequiredExtensionsShaderStub());
rsFpPos = rsFp.addDefaultShaderPrecision(gl, rsFpPos);
-
- final String texLookupFuncName = mPlayer.getTextureLookupFunctionName(myTextureLookupName);
+
+ final String texLookupFuncName = mPlayer.getTextureLookupFunctionName(myTextureLookupName);
rsFp.replaceInShaderSource(myTextureLookupName, texLookupFuncName);
-
+
// Inject TextureSequence shader details
final StringBuilder sFpIns = new StringBuilder();
sFpIns.append("uniform ").append(mPlayer.getTextureSampler2DType()).append(" mgl_ActiveTexture;\n");
@@ -350,7 +364,7 @@ public class MovieSimple implements GLEventListener {
@Override
public void init(GLAutoDrawable drawable) {
- if(null == mPlayer) {
+ if(null == mPlayer) {
throw new InternalError("mPlayer null");
}
if( GLMediaPlayer.State.Uninitialized == mPlayer.getState() ) {
@@ -360,21 +374,20 @@ public class MovieSimple implements GLEventListener {
throw new IllegalStateException("mPlayer has no VID/stream selected: "+mPlayer);
}
resetGLState = false;
-
+
zoom0 = orthoProjection ? 0f : -2.5f;
zoom1 = orthoProjection ? 0f : -5f;
- zoom = zoom0;
+ zoom = zoom0;
GL2ES2 gl = drawable.getGL().getGL2ES2();
System.err.println(JoglVersion.getGLInfo(gl, null));
System.err.println("Alpha: "+alpha+", opaque "+drawable.getChosenGLCapabilities().isBackgroundOpaque()+
", "+drawable.getClass().getName()+", "+drawable);
-
+
if(waitForKey) {
UITestCase.waitForKey("Init>");
- }
+ }
final Texture tex;
- boolean useExternalTexture = false;
try {
System.out.println("p0 "+mPlayer+", shared "+mPlayerShared);
if(!mPlayerShared && GLMediaPlayer.State.Initialized == mPlayer.getState() ) {
@@ -386,10 +399,6 @@ public class MovieSimple implements GLEventListener {
throw new InternalError("XXX: "+mPlayer);
}
tex = mPlayer.getLastTexture().getTexture();
- useExternalTexture = GLES2.GL_TEXTURE_EXTERNAL_OES == tex.getTarget();
- if(useExternalTexture && !gl.isExtensionAvailable(GLExtensions.OES_EGL_image_external)) {
- throw new GLException(GLExtensions.OES_EGL_image_external+" requested but not available");
- }
if(!mPlayerShared) {
mPlayer.setTextureMinMagFilter( new int[] { GL.GL_NEAREST, GL.GL_LINEAR } );
}
@@ -401,15 +410,15 @@ public class MovieSimple implements GLEventListener {
}
throw new GLException(glex);
}
-
+
initShader(gl);
- // Push the 1st uniform down the path
+ // Push the 1st uniform down the path
st.useProgram(gl, true);
int[] viewPort = new int[] { 0, 0, drawable.getWidth(), drawable.getHeight()};
pmvMatrix = new PMVMatrix();
- reshapePMV(viewPort[2], viewPort[3]);
+ reshapePMV(viewPort[2], viewPort[3]);
pmvMatrixUniform = new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf());
if(!st.uniform(gl, pmvMatrixUniform)) {
throw new GLException("Error setting PMVMatrix in shader: "+st);
@@ -417,17 +426,17 @@ public class MovieSimple implements GLEventListener {
if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", mPlayer.getTextureUnit()))) {
throw new GLException("Error setting mgl_ActiveTexture in shader: "+st);
}
-
+
float dWidth = drawable.getWidth();
float dHeight = drawable.getHeight();
float mWidth = mPlayer.getWidth();
- float mHeight = mPlayer.getHeight();
+ float mHeight = mPlayer.getHeight();
float mAspect = mWidth/mHeight;
System.err.println("XXX0: mov aspect: "+mAspect);
float xs, ys;
if(orthoProjection) {
if(mPlayerScaleOrig && mWidth < dWidth && mHeight < dHeight) {
- xs = mWidth/2f; ys = xs / mAspect;
+ xs = mWidth/2f; ys = xs / mAspect;
} else {
xs = dWidth/2f; ys = xs / mAspect; // w>h
}
@@ -453,16 +462,16 @@ public class MovieSimple implements GLEventListener {
}
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_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER);
+ {
+ interleavedVBO.addGLSLSubArray("mgl_Vertex", 3, GL.GL_ARRAY_BUFFER);
+ interleavedVBO.addGLSLSubArray("mgl_Color", 4, GL.GL_ARRAY_BUFFER);
+ interleavedVBO.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER);
}
updateInterleavedVBO(gl, tex);
-
+
st.ownAttribute(interleavedVBO, true);
gl.glClearColor(0.3f, 0.3f, 0.3f, 0.3f);
-
+
gl.glEnable(GL2ES2.GL_DEPTH_TEST);
st.useProgram(gl, false);
@@ -474,11 +483,11 @@ public class MovieSimple implements GLEventListener {
if(!mPlayerShared) {
mPlayer.play();
System.out.println("play.0 "+mPlayer);
- }
+ }
startTime = System.currentTimeMillis();
-
+
final Object upstreamWidget = drawable.getUpstreamWidget();
- if (upstreamWidget instanceof Window) {
+ if (upstreamWidget instanceof Window) {
final Window window = (Window) upstreamWidget;
window.addMouseListener(mouseAction);
window.addKeyListener(keyAction);
@@ -486,7 +495,7 @@ public class MovieSimple implements GLEventListener {
winHeight = window.getHeight();
}
}
-
+
protected void updateInterleavedVBO(GL gl, Texture tex) {
final float ss = 1f, ts = 1f; // scale tex-coord
final boolean wasEnabled = interleavedVBO.enabled();
@@ -498,7 +507,7 @@ public class MovieSimple implements GLEventListener {
System.err.println("XXX0: "+tc);
System.err.println("XXX0: tex aspect: "+tex.getAspectRatio());
System.err.println("XXX0: tex y-flip: "+tex.getMustFlipVertically());
-
+
// left-bottom
ib.put(verts[0]); ib.put(verts[1]); ib.put(verts[2]);
if( hasEffect(EFFECT_GRADIENT_BOTTOM2TOP) ) {
@@ -507,11 +516,11 @@ public class MovieSimple implements GLEventListener {
ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
}
ib.put( tc.left() *ss); ib.put( tc.bottom() *ts);
-
+
// right-bottom
ib.put(verts[3]); ib.put(verts[1]); ib.put(verts[2]);
if( hasEffect(EFFECT_GRADIENT_BOTTOM2TOP) ) {
- ib.put( 0); ib.put( 0); ib.put( 0); ib.put(alpha);
+ ib.put( 0); ib.put( 0); ib.put( 0); ib.put(alpha);
} else {
ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
}
@@ -525,22 +534,22 @@ public class MovieSimple implements GLEventListener {
ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
}
ib.put( tc.left() *ss); ib.put( tc.top() *ts);
-
+
// right-top
ib.put(verts[3]); ib.put(verts[4]); ib.put(verts[2]);
if( hasEffect(EFFECT_GRADIENT_BOTTOM2TOP) ) {
ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
} else {
ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha);
- }
- ib.put( tc.right() *ss); ib.put( tc.top() *ts);
+ }
+ ib.put( tc.right() *ss); ib.put( tc.top() *ts);
}
interleavedVBO.seal(gl, true);
if( !wasEnabled ) {
interleavedVBO.enableBuffer(gl, false);
}
}
-
+
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
@@ -550,23 +559,23 @@ public class MovieSimple implements GLEventListener {
if(null == mPlayer) { return; }
winWidth = width;
winHeight = height;
-
+
if(null != st) {
reshapePMV(width, height);
st.useProgram(gl, true);
st.uniform(gl, pmvMatrixUniform);
st.useProgram(gl, false);
}
-
+
System.out.println("pR "+mPlayer);
}
-
+
private void reshapePMV(int width, int height) {
pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
pmvMatrix.glLoadIdentity();
if(orthoProjection) {
- final float fw = (float) width / 2f;
- final float fh = (float) height/ 2f;
+ final float fw = width / 2f;
+ final float fh = height/ 2f;
pmvMatrix.glOrthof(-fw, fw, -fh, fh, -1.0f, 1.0f);
nearPlaneNormalized = 0f;
} else {
@@ -577,26 +586,26 @@ public class MovieSimple implements GLEventListener {
pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
pmvMatrix.glLoadIdentity();
- pmvMatrix.glTranslatef(0, 0, zoom0);
+ pmvMatrix.glTranslatef(0, 0, zoom0);
}
@Override
public void dispose(GLAutoDrawable drawable) {
disposeImpl(drawable, true);
}
-
+
private void disposeImpl(GLAutoDrawable drawable, boolean disposePlayer) {
if(null == mPlayer) { return; }
-
+
final Object upstreamWidget = drawable.getUpstreamWidget();
- if (upstreamWidget instanceof Window) {
+ if (upstreamWidget instanceof Window) {
final Window window = (Window) upstreamWidget;
window.removeMouseListener(mouseAction);
window.removeKeyListener(keyAction);
}
-
- System.out.println("pD.1 "+mPlayer+", disposePlayer "+disposePlayer);
- GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ System.out.println("pD.1 "+mPlayer+", disposePlayer "+disposePlayer);
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
if( disposePlayer ) {
if(!mPlayerShared) {
mPlayer.destroy(gl);
@@ -616,11 +625,11 @@ public class MovieSimple implements GLEventListener {
}
long lastPerfPos = 0;
-
+
@Override
public void display(GLAutoDrawable drawable) {
if(null == mPlayer) { return; }
-
+
if( resetGLState ) {
resetGLState = false;
System.err.println("XXX resetGLState");
@@ -628,35 +637,35 @@ public class MovieSimple implements GLEventListener {
init(drawable);
reshape(drawable, 0, 0, drawable.getWidth(), drawable.getHeight());
}
-
+
final long currentPos = System.currentTimeMillis();
if( currentPos - lastPerfPos > 2000 ) {
System.err.println( mPlayer.getPerfString() );
- lastPerfPos = currentPos;
- }
-
- GL2ES2 gl = drawable.getGL().getGL2ES2();
+ lastPerfPos = currentPos;
+ }
+
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
if(null == st) {
return;
}
-
+
st.useProgram(gl, true);
pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
pmvMatrix.glLoadIdentity();
pmvMatrix.glTranslatef(0, 0, zoom);
if(rotate > 0) {
- final float ang = ((float) (System.currentTimeMillis() - startTime) * 360.0f) / 8000.0f;
+ final float ang = ((System.currentTimeMillis() - startTime) * 360.0f) / 8000.0f;
pmvMatrix.glRotatef(ang, 0, 0, 1);
} else {
rotate = 0;
}
st.uniform(gl, pmvMatrixUniform);
interleavedVBO.enableBuffer(gl, true);
- Texture tex = null;
+ Texture tex = null;
if(null!=mPlayer) {
final TextureSequence.TextureFrame texFrame;
if(mPlayerShared) {
@@ -686,7 +695,7 @@ public class MovieSimple implements GLEventListener {
int textureCount = 3; // default - threaded
boolean ortho = true;
boolean zoom = false;
-
+
boolean forceES2 = false;
boolean forceES3 = false;
boolean forceGL3 = false;
@@ -694,10 +703,10 @@ public class MovieSimple implements GLEventListener {
int vid = GLMediaPlayer.STREAM_ID_AUTO;
int aid = GLMediaPlayer.STREAM_ID_AUTO;
final boolean origSize;
-
+
String url_s=null;
{
- boolean _origSize = false;
+ boolean _origSize = false;
for(int i=0; i