aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-04-09 04:49:41 +0200
committerSven Gothel <[email protected]>2012-04-09 04:49:41 +0200
commit3a26aa701b4a1a0991cd997a0d295a1b83cd12f3 (patch)
tree0bbf0c79127ab8329220e2766177c3073244277b /src
parent1e61021a062b1403f7eed948ac9d2ea0c04ea951 (diff)
GLMediaPlayer*: Revised - Working on buggy MediaPlayer impl. (Android ICS Tegra)
GLMediaPlayer: Merging 'initStream()' and 'initGL()' to 'initGLStream()' due to incompatible/buggy implementations (Android/Tegra) requiring the GL texture being setup before preparing the stream. This also implies that w/o an GL context we cannot fetch the stream information (size, ..) hence we need to evaluate this detail (FIXME). 'getNextTexture(GL gl, boolean blocking)' can request the impl. to block GLMediaEventListener: The TextureFrame not yet available, adding 'when'
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/av/GLMediaEventListener.java17
-rw-r--r--src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java60
-rw-r--r--src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java125
-rw-r--r--src/jogl/classes/jogamp/opengl/av/EGLMediaPlayerImpl.java22
-rw-r--r--src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java135
-rw-r--r--src/jogl/classes/jogamp/opengl/av/NullGLMediaPlayer.java21
-rw-r--r--src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java32
-rw-r--r--src/jogl/native/openmax/jogamp_opengl_omx_OMXGLMediaPlayer.c4
-rw-r--r--src/jogl/native/openmax/omx_tool.c15
-rw-r--r--src/jogl/native/openmax/omx_tool.h2
-rw-r--r--src/test/com/jogamp/opengl/test/android/MovieSimpleActivity.java127
-rw-r--r--src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher00a.java11
-rw-r--r--src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher00b.java9
-rw-r--r--src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher01a.java9
-rw-r--r--src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher01b.java9
-rw-r--r--src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher02.java9
-rwxr-xr-xsrc/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java106
17 files changed, 373 insertions, 340 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/av/GLMediaEventListener.java b/src/jogl/classes/com/jogamp/opengl/av/GLMediaEventListener.java
index a02c8a362..9887a417c 100644
--- a/src/jogl/classes/com/jogamp/opengl/av/GLMediaEventListener.java
+++ b/src/jogl/classes/com/jogamp/opengl/av/GLMediaEventListener.java
@@ -1,7 +1,7 @@
package com.jogamp.opengl.av;
-import com.jogamp.opengl.av.GLMediaPlayer.TextureFrame;
+import javax.media.opengl.GL;
public interface GLMediaEventListener {
@@ -10,8 +10,19 @@ public interface GLMediaEventListener {
static final int EVENT_CHANGE_BPS = 1<<2;
static final int EVENT_CHANGE_LENGTH = 1<<3;
- public void attributesChanges(GLMediaPlayer mp, int event_mask);
- public void newFrameAvailable(GLMediaPlayer mp, TextureFrame frame);
+ /**
+ * @param mp the event source
+ * @param event_mask the changes attributes
+ * @param when system time in msec.
+ */
+ public void attributesChanges(GLMediaPlayer mp, int event_mask, long when);
+
+ /**
+ * Signaling listeners that {@link GLMediaPlayer#getNextTexture(GL, boolean)} is able to deliver a new frame.
+ * @param mp the event source
+ * @param when system time in msec.
+ **/
+ public void newFrameAvailable(GLMediaPlayer mp, long when);
}
diff --git a/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java b/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java
index e5f69b6de..b3827d520 100644
--- a/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java
+++ b/src/jogl/classes/com/jogamp/opengl/av/GLMediaPlayer.java
@@ -36,24 +36,24 @@ import javax.media.opengl.GLException;
import jogamp.opengl.Debug;
import com.jogamp.opengl.util.texture.Texture;
+import com.jogamp.opengl.util.texture.TextureCoords;
/**
* Lifecycle of an GLMediaPlayer:
* <table border="1">
- * <tr><th>action</th> <th>state before</th> <th>state after</th></tr>
- * <tr><td>{@link #initStream(URLConnection)}</td> <td>UninitializedStream</td> <td>UninitializedGL</td></tr>
- * <tr><td>{@link #initGL(GL)}</td> <td>UninitializedGL</td> <td>Stopped</td></tr>
- * <tr><td>{@link #start()}</td> <td>Stopped, Paused</td> <td>Playing</td></tr>
- * <tr><td>{@link #stop()}</td> <td>Playing, Paused</td> <td>Stopped</td></tr>
- * <tr><td>{@link #pause()}</td> <td>Playing</td> <td>Paused</td></tr>
- * <tr><td>{@link #destroy(GL)}</td> <td>ANY</td> <td>UninitializedStream</td></tr>
+ * <tr><th>action</th> <th>state before</th> <th>state after</th></tr>
+ * <tr><td>{@link #initGLStream(GL, URLConnection)}</td> <td>Uninitialized</td> <td>Stopped</td></tr>
+ * <tr><td>{@link #start()}</td> <td>Stopped, Paused</td> <td>Playing</td></tr>
+ * <tr><td>{@link #stop()}</td> <td>Playing, Paused</td> <td>Stopped</td></tr>
+ * <tr><td>{@link #pause()}</td> <td>Playing</td> <td>Paused</td></tr>
+ * <tr><td>{@link #destroy(GL)}</td> <td>ANY</td> <td>Uninitialized</td></tr>
* </table>
*/
public interface GLMediaPlayer {
public static final boolean DEBUG = Debug.debug("GLMediaPlayer");
public enum State {
- UninitializedStream(0), UninitializedGL(1), Stopped(2), Playing(3), Paused(4);
+ Uninitialized(0), Stopped(1), Playing(2), Paused(3);
public final int id;
@@ -83,6 +83,10 @@ public interface GLMediaPlayer {
public int getTextureTarget();
+ /** Defaults to 0 */
+ public void setTextureUnit(int u);
+ public int getTextureUnit();
+
/** Sets the texture min-mag filter, defaults to {@link GL#GL_NEAREST}. */
public void setTextureMinMagFilter(int[] minMagFilter);
public int[] getTextureMinMagFilter();
@@ -92,24 +96,20 @@ public interface GLMediaPlayer {
public int[] getTextureWrapST();
/**
- * Sets the stream to be used. Initializes all stream related states.
+ * Sets the stream to be used. Initializes all stream related states inclusive OpenGL ones,
+ * if <code>gl</code> is not null.
* <p>
- * UninitializedStream -> UninitializedGL
+ * Uninitialized -> Stopped
* </p>
+ * @param gl current GL object. If null, no video output and textures will be available.
+ * @param urlConn the stream connection
+ * @return the new state
+ *
+ * @throws IllegalStateException if not invoked in state Uninitialized
* @throws IOException in case of difficulties to open or process the stream
- * @throws IllegalStateException if not invoked in state UninitializedStream
- */
- public State initStream(URLConnection urlConn) throws IllegalStateException, IOException;
-
- /**
- * Initializes all GL related resources.
- * <p>
- * UninitializedGL -> Stopped
- * </p>
* @throws GLException in case of difficulties to initialize the GL resources
- * @throws IllegalStateException if not invoked in state UninitializedGL
*/
- public State initGL(GL gl) throws IllegalStateException, GLException;
+ public State initGLStream(GL gl, URLConnection urlConn) throws IllegalStateException, GLException, IOException;
/**
* Releases the GL and stream resources.
@@ -157,17 +157,27 @@ public interface GLMediaPlayer {
public long seek(long msec);
/**
- * @return the last updated texture. Not blocking.
+ * @return the last updated texture. Maybe <code>null</code> in case no last frame is available.
+ * Not blocking.
*/
public TextureFrame getLastTexture();
/**
- * @return the next texture, which should be rendered. May block, depending on implementation.
+ * Returns the next texture to be rendered.
+ * <p>
+ * Implementation shall block until next frame is available if <code>blocking</code> is <code>true</code>,
+ * otherwise it shall return the last frame in case a new frame is not available.
+ * </p>
+ * <p>
+ * Shall return <code>null</code> in case <i>no</i> frame is available.
+ * </p>
*
* @see #addEventListener(GLMediaEventListener)
- * @see GLMediaEventListener#newFrameAvailable(GLMediaPlayer, TextureFrame)
+ * @see GLMediaEventListener#newFrameAvailable(GLMediaPlayer, long)
*/
- public TextureFrame getNextTexture();
+ public TextureFrame getNextTexture(GL gl, boolean blocking);
+
+ public TextureCoords getTextureCoords();
public URLConnection getURLConnection();
diff --git a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
index 7e94d3cc5..ae45662db 100644
--- a/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
+++ b/src/jogl/classes/jogamp/opengl/android/av/AndroidGLMediaPlayerAPI14.java
@@ -30,9 +30,10 @@ package jogamp.opengl.android.av;
import java.io.IOException;
import javax.media.opengl.GL;
-import javax.media.opengl.GLContext;
import javax.media.opengl.GLES2;
+import com.jogamp.opengl.util.texture.TextureCoords;
+
import jogamp.common.os.android.StaticContext;
import jogamp.opengl.av.GLMediaPlayerImpl;
@@ -42,31 +43,21 @@ import android.media.MediaPlayer;
import android.net.Uri;
import android.view.Surface;
-import com.jogamp.opengl.util.texture.Texture;
-
/***
* Android API Level 14: {@link MediaPlayer#setSurface(Surface)}
* Android API Level 14: {@link Surface#Surface(android.graphics.SurfaceTexture)}
*/
public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
MediaPlayer mp;
- boolean updateSurface = false;
+ volatile boolean updateSurface = false;
Object updateSurfaceLock = new Object();
- AndroidTextureFrame atex = null;
-
- public static class AndroidTextureFrame extends TextureFrame {
- public AndroidTextureFrame(Texture t, SurfaceTexture stex) {
- super(t);
- this.stex = stex;
- }
-
- public final SurfaceTexture getSurfaceTexture() { return stex; }
-
- public String toString() {
- return "AndroidTextureFrame[" + texture + ", "+ stex + "]";
- }
- protected SurfaceTexture stex;
- }
+ TextureFrame lastTexFrame = null;
+
+ /**
+ private static String toString(MediaPlayer m) {
+ if(null == m) return "<nil>";
+ return "MediaPlayer[playing "+m.isPlaying()+", pos "+m.getCurrentPosition()/1000.0f+"s, "+m.getVideoWidth()+"x"+m.getVideoHeight()+"]";
+ } */
public AndroidGLMediaPlayerAPI14() {
super();
@@ -103,6 +94,7 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
@Override
protected boolean pauseImpl() {
if(null != mp) {
+ wakeUp(false);
try {
mp.pause();
return true;
@@ -118,6 +110,7 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
@Override
protected boolean stopImpl() {
if(null != mp) {
+ wakeUp(false);
try {
mp.stop();
return true;
@@ -141,24 +134,49 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
@Override
public TextureFrame getLastTexture() {
- return atex;
+ return lastTexFrame;
}
@Override
- public TextureFrame getNextTexture() {
- if(null != atex && null != mp) {
- final boolean _updateSurface;
- synchronized(updateSurfaceLock) {
- _updateSurface = updateSurface;
- updateSurface = false;
+ public TextureFrame getNextTexture(GL gl, boolean blocking) {
+ if(null != stex && null != mp) {
+ // Only block once, no while-loop.
+ // This relaxes locking code of non crucial resources/events.
+ boolean update = updateSurface;
+ if(!update && blocking) {
+ synchronized(updateSurfaceLock) {
+ if(!updateSurface) { // volatile OK.
+ try {
+ updateSurfaceLock.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ updateSurface = false;
+ update = true;
+ }
}
- if(_updateSurface) {
- atex.getSurfaceTexture().updateTexImage();
- // atex.getSurfaceTexture().getTransformMatrix(atex.getSTMatrix());
+ if(update) {
+ stex.updateTexImage();
+ // stex.getTransformMatrix(atex.getSTMatrix());
+ lastTexFrame=texFrames[0];
}
- return atex;
- } else {
- return null;
+
+ }
+ return lastTexFrame;
+ }
+
+ @Override
+ public TextureCoords getTextureCoords() {
+ return texFrames[0].getTexture().getImageTexCoords();
+ }
+
+ private void wakeUp(boolean newFrame) {
+ synchronized(updateSurfaceLock) {
+ if(newFrame) {
+ updateSurface = true;
+ }
+ updateSurfaceLock.notifyAll();
}
}
@@ -170,13 +188,16 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
@Override
protected void destroyImpl(GL gl) {
if(null != mp) {
+ wakeUp(false);
mp.release();
mp = null;
}
}
+ SurfaceTexture stex = null;
+
@Override
- protected void initStreamImplPreGL() throws IOException {
+ protected void initGLStreamImpl(GL gl, int[] texNames) throws IOException {
if(null!=mp && null!=urlConn) {
try {
final Uri uri = Uri.parse(urlConn.getURL().toExternalForm());
@@ -188,12 +209,16 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
} catch (IllegalStateException e) {
throw new RuntimeException(e);
}
+ stex = new SurfaceTexture(texNames[0]); // only 1 texture
+ stex.setOnFrameAvailableListener(onFrameAvailableListener);
+ final Surface surf = new Surface(stex);
+ mp.setSurface(surf);
+ surf.release();
try {
mp.prepare();
} catch (IOException ioe) {
throw new IOException("MediaPlayer failed to process stream <"+urlConn.getURL().toExternalForm()+">: "+ioe.getMessage(), ioe);
}
-
width = mp.getVideoWidth();
height = mp.getVideoHeight();
fps = 0;
@@ -206,34 +231,20 @@ public class AndroidGLMediaPlayerAPI14 extends GLMediaPlayerImpl {
}
@Override
- protected void destroyTexImage(GLContext ctx, TextureFrame imgTex) {
- final AndroidTextureFrame atf = (AndroidTextureFrame) imgTex;
- atf.getSurfaceTexture().release();
- atex = null;
- super.destroyTexImage(ctx, imgTex);
+ protected void destroyTexImage(GL gl, TextureFrame imgTex) {
+ if(null != stex) {
+ stex.release();
+ stex = null;
+ }
+ lastTexFrame = null;
+ super.destroyTexImage(gl, imgTex);
}
- @Override
- protected TextureFrame createTexImage(GLContext ctx, int idx, int[] tex) {
- final Texture texture = super.createTexImageImpl(ctx, idx, tex, true);
-
- final SurfaceTexture stex = new SurfaceTexture(tex[idx]);
- stex.setOnFrameAvailableListener(onFrameAvailableListener);
- final Surface surf = new Surface(stex);
- mp.setSurface(surf);
- surf.release();
-
- atex = new AndroidTextureFrame( texture, stex );
- return atex;
- }
-
protected OnFrameAvailableListener onFrameAvailableListener = new OnFrameAvailableListener() {
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
- synchronized(updateSurfaceLock) {
- updateSurface = true;
- }
- AndroidGLMediaPlayerAPI14.this.newFrameAvailable(atex);
+ wakeUp(true);
+ AndroidGLMediaPlayerAPI14.this.newFrameAvailable();
}
};
}
diff --git a/src/jogl/classes/jogamp/opengl/av/EGLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/av/EGLMediaPlayerImpl.java
index abc5d5912..2f6744fc5 100644
--- a/src/jogl/classes/jogamp/opengl/av/EGLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/av/EGLMediaPlayerImpl.java
@@ -27,8 +27,11 @@
*/
package jogamp.opengl.av;
-import javax.media.opengl.GLContext;
+import java.nio.IntBuffer;
+import javax.media.opengl.GL;
+
+import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.util.texture.Texture;
import jogamp.opengl.egl.EGL;
@@ -80,22 +83,23 @@ public abstract class EGLMediaPlayerImpl extends GLMediaPlayerImpl {
}
@Override
- protected TextureFrame createTexImage(GLContext ctx, int idx, int[] tex) {
- final Texture texture = super.createTexImageImpl(ctx, idx, tex, true);
+ protected TextureFrame createTexImage(GL gl, int idx, int[] tex) {
+ final Texture texture = super.createTexImageImpl(gl, idx, tex, true);
final long image;
final long sync;
- final EGLContext eglCtx = (EGLContext) ctx;
+ final EGLContext eglCtx = (EGLContext) gl.getContext();
final EGLExt eglExt = eglCtx.getEGLExt();
final EGLDrawable eglDrawable = (EGLDrawable) eglCtx.getGLDrawable();
int[] tmp = new int[1];
+ IntBuffer nioTmp = Buffers.newDirectIntBuffer(1);
if(TextureType.KHRImage == texType) {
// create EGLImage from texture
- tmp[0] = EGL.EGL_NONE;
+ nioTmp.put(0, EGL.EGL_NONE);
image = eglExt.eglCreateImageKHR( eglDrawable.getDisplay(), eglCtx.getHandle(),
EGLExt.EGL_GL_TEXTURE_2D_KHR,
- tex[idx], tmp, 0);
+ null /* buffer */, nioTmp);
if (0==image) {
throw new RuntimeException("EGLImage creation failed: "+EGL.eglGetError()+", ctx "+eglCtx+", tex "+tex[idx]+", err "+toHexString(EGL.eglGetError()));
}
@@ -119,8 +123,8 @@ public abstract class EGLMediaPlayerImpl extends GLMediaPlayerImpl {
}
@Override
- protected void destroyTexImage(GLContext ctx, TextureFrame imgTex) {
- final EGLContext eglCtx = (EGLContext) ctx;
+ protected void destroyTexImage(GL gl, TextureFrame imgTex) {
+ final EGLContext eglCtx = (EGLContext) gl.getContext();
final EGLExt eglExt = eglCtx.getEGLExt();
final EGLDrawable eglDrawable = (EGLDrawable) eglCtx.getGLDrawable();
final EGLTextureFrame eglTex = (EGLTextureFrame) imgTex;
@@ -131,6 +135,6 @@ public abstract class EGLMediaPlayerImpl extends GLMediaPlayerImpl {
if(0!=eglTex.getSync()) {
eglExt.eglDestroySyncKHR(eglDrawable.getDisplay(), eglTex.getSync());
}
- super.destroyTexImage(ctx, imgTex);
+ super.destroyTexImage(gl, imgTex);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java
index f6fc20afe..acd707288 100644
--- a/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/av/GLMediaPlayerImpl.java
@@ -34,7 +34,6 @@ import java.util.HashMap;
import java.util.Iterator;
import javax.media.opengl.GL;
-import javax.media.opengl.GLContext;
import javax.media.opengl.GLES2;
import javax.media.opengl.GLException;
@@ -59,6 +58,7 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
protected State state;
protected int textureCount;
protected int textureTarget;
+ protected int texUnit;
protected int[] texMinMagFilter = { GL.GL_NEAREST, GL.GL_NEAREST };
protected int[] texWrapST = { GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE };
@@ -67,35 +67,39 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
protected float playSpeed = 1.0f;
- /** Shall be set by the {@link #initStreamImplPreGL()} method implementation. */
+ /** Shall be set by the {@link #initGLStreamImpl(GL, int[])} method implementation. */
protected int width = 0;
- /** Shall be set by the {@link #initStreamImplPreGL()} method implementation. */
+ /** Shall be set by the {@link #initGLStreamImpl(GL, int[])} method implementation. */
protected int height = 0;
- /** Shall be set by the {@link #initStreamImplPreGL()} method implementation. */
+ /** Shall be set by the {@link #initGLStreamImpl(GL, int[])} method implementation. */
protected int fps = 0;
- /** Shall be set by the {@link #initStreamImplPreGL()} method implementation. */
+ /** Shall be set by the {@link #initGLStreamImpl(GL, int[])} method implementation. */
protected long bps = 0;
- /** In frames. Shall be set by the {@link #initStreamImplPreGL()} method implementation. */
+ /** In frames. Shall be set by the {@link #initGLStreamImpl(GL, int[])} method implementation. */
protected long totalFrames = 0;
- /** In ms. Shall be set by the {@link #initStreamImplPreGL()} method implementation. */
+ /** In ms. Shall be set by the {@link #initGLStreamImpl(GL, int[])} method implementation. */
protected long duration = 0;
- /** Shall be set by the {@link #initStreamImplPreGL()} method implementation. */
+ /** Shall be set by the {@link #initGLStreamImpl(GL, int[])} method implementation. */
protected String acodec = null;
- /** Shall be set by the {@link #initStreamImplPreGL()} method implementation. */
+ /** Shall be set by the {@link #initGLStreamImpl(GL, int[])} method implementation. */
protected String vcodec = null;
protected long frameNumber = 0;
- private TextureFrame[] texFrames = null;
+ protected TextureFrame[] texFrames = null;
protected HashMap<Integer, TextureFrame> texFrameMap = new HashMap<Integer, TextureFrame>();
private ArrayList<GLMediaEventListener> eventListeners = new ArrayList<GLMediaEventListener>();
protected GLMediaPlayerImpl() {
this.textureCount=3;
this.textureTarget=GL.GL_TEXTURE_2D;
- this.state = State.UninitializedStream;
+ this.texUnit = 0;
+ this.state = State.Uninitialized;
}
+ public void setTextureUnit(int u) { texUnit = u; }
+ public int getTextureUnit() { return texUnit; }
+
protected final void setTextureCount(int textureCount) {
this.textureCount=textureCount;
}
@@ -162,20 +166,47 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
public final State getState() { return state; }
@Override
- public final State initStream(URLConnection urlConn) throws IllegalStateException, IOException {
- if(State.UninitializedStream != state) {
- throw new IllegalStateException("Instance not in state "+State.UninitializedStream+", but "+state+", "+this);
+ public State initGLStream(GL gl, URLConnection urlConn) throws IllegalStateException, GLException, IOException {
+ if(State.Uninitialized != state) {
+ throw new IllegalStateException("Instance not in state "+State.Uninitialized+", but "+state+", "+this);
}
this.urlConn = urlConn;
if (this.urlConn != null) {
- initStreamImplPreGL();
- state = State.UninitializedGL;
+ try {
+ if(null!=texFrames) {
+ removeAllImageTextures(gl);
+ } else {
+ texFrames = new TextureFrame[textureCount];
+ }
+
+ final int[] tex = new int[textureCount];
+ {
+ gl.glGenTextures(textureCount, tex, 0);
+ final int err = gl.glGetError();
+ if( GL.GL_NO_ERROR != err ) {
+ throw new RuntimeException("TextureNames creation failed (num: "+textureCount+"): err "+toHexString(err));
+ }
+ }
+ initGLStreamImpl(gl, tex);
+
+ for(int i=0; i<textureCount; i++) {
+ final TextureFrame tf = createTexImage(gl, i, tex);
+ texFrames[i] = tf;
+ texFrameMap.put(tex[i], tf);
+ }
+ state = State.Stopped;
+ return state;
+ } catch (Throwable t) {
+ throw new GLException("Error initializing GL resources", t);
+ }
}
- return state;
+ return state;
}
/**
- * Implementation shall set the following set of data here or at {@link #setStreamImplPostGL()}
+ * Implementation shall set the following set of data here
+ * @param gl TODO
+ * @param texNames TODO
* @see #width
* @see #height
* @see #fps
@@ -184,52 +215,13 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
* @see #acodec
* @see #vcodec
*/
- protected abstract void initStreamImplPreGL() throws IOException;
-
- @Override
- public final State initGL(GL gl) throws IllegalStateException, GLException {
- if(State.UninitializedGL != state) {
- throw new IllegalStateException("Instance not in state "+State.UninitializedGL+", but "+state+", "+this);
- }
- final GLContext ctx = gl.getContext();
- if(!ctx.isCurrent()) {
- throw new GLException("Not current: "+ctx);
- }
+ protected abstract void initGLStreamImpl(GL gl, int[] texNames) throws IOException;
- try {
- if(null!=texFrames) {
- removeAllImageTextures(ctx);
- } else {
- texFrames = new TextureFrame[textureCount];
- }
-
- final int[] tex = new int[textureCount];
- {
- gl.glGenTextures(textureCount, tex, 0);
- final int err = gl.glGetError();
- if( GL.GL_NO_ERROR != err ) {
- throw new RuntimeException("TextureNames creation failed (num: "+textureCount+"): err "+toHexString(err));
- }
- }
-
- for(int i=0; i<textureCount; i++) {
- final TextureFrame tf = createTexImage(ctx, i, tex);
- texFrames[i] = tf;
- texFrameMap.put(tex[i], tf);
- }
- state = State.Stopped;
- return state;
- } catch (Throwable t) {
- throw new GLException("Error initializing GL resources", t);
- }
- }
-
- protected TextureFrame createTexImage(GLContext ctx, int idx, int[] tex) {
- return new TextureFrame( createTexImageImpl(ctx, idx, tex, true) );
+ protected TextureFrame createTexImage(GL gl, int idx, int[] tex) {
+ return new TextureFrame( createTexImageImpl(gl, idx, tex, true) );
}
- protected Texture createTexImageImpl(GLContext ctx, int idx, int[] tex, boolean mustFlipVertically) {
- final GL gl = ctx.getGL();
+ protected Texture createTexImageImpl(GL gl, int idx, int[] tex, boolean mustFlipVertically) {
if( 0 > tex[idx] ) {
throw new RuntimeException("TextureName "+toHexString(tex[idx])+" invalid.");
}
@@ -272,16 +264,16 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
mustFlipVertically);
}
- protected void destroyTexImage(GLContext ctx, TextureFrame imgTex) {
- imgTex.getTexture().destroy(ctx.getGL());
+ protected void destroyTexImage(GL gl, TextureFrame imgTex) {
+ imgTex.getTexture().destroy(gl);
}
- protected void removeAllImageTextures(GLContext ctx) {
+ protected void removeAllImageTextures(GL gl) {
if(null != texFrames) {
for(int i=0; i<textureCount; i++) {
final TextureFrame imgTex = texFrames[i];
if(null != imgTex) {
- destroyTexImage(ctx, imgTex);
+ destroyTexImage(gl, imgTex);
texFrames[i] = null;
}
}
@@ -292,15 +284,15 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
protected void attributesUpdated(int event_mask) {
synchronized(eventListenersLock) {
for(Iterator<GLMediaEventListener> i = eventListeners.iterator(); i.hasNext(); ) {
- i.next().attributesChanges(this, event_mask);
+ i.next().attributesChanges(this, event_mask, System.currentTimeMillis());
}
}
}
- protected void newFrameAvailable(TextureFrame frame) {
+ protected void newFrameAvailable() {
frameNumber++;
synchronized(eventListenersLock) {
for(Iterator<GLMediaEventListener> i = eventListeners.iterator(); i.hasNext(); ) {
- i.next().newFrameAvailable(this, frame);
+ i.next().newFrameAvailable(this, System.currentTimeMillis());
}
}
}
@@ -313,8 +305,8 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
@Override
public synchronized State destroy(GL gl) {
destroyImpl(gl);
- removeAllImageTextures(gl.getContext());
- state = State.UninitializedStream;
+ removeAllImageTextures(gl);
+ state = State.Uninitialized;
return state;
}
protected abstract void destroyImpl(GL gl);
@@ -367,7 +359,8 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
@Override
public synchronized String toString() {
final float ct = getCurrentPosition() / 1000.0f, tt = getDuration() / 1000.0f;
- return "GLMediaPlayer ["+state+", "+frameNumber+"/"+totalFrames+" frames, "+ct+"/"+tt+"s, stream [video ["+vcodec+", "+width+"x"+height+", "+fps+"fps, "+bps+"bsp], "+urlConn.getURL().toExternalForm()+"]]";
+ final String loc = ( null != urlConn ) ? urlConn.getURL().toExternalForm() : "<undefined stream>" ;
+ return "GLMediaPlayer ["+state+", "+frameNumber+"/"+totalFrames+" frames, "+ct+"/"+tt+"s, stream [video ["+vcodec+", "+width+"x"+height+", "+fps+"fps, "+bps+"bsp], "+loc+"]]";
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/av/NullGLMediaPlayer.java b/src/jogl/classes/jogamp/opengl/av/NullGLMediaPlayer.java
index c7eb2722c..a5d41bc9c 100644
--- a/src/jogl/classes/jogamp/opengl/av/NullGLMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/av/NullGLMediaPlayer.java
@@ -32,7 +32,6 @@ import java.net.URLConnection;
import java.nio.ByteBuffer;
import javax.media.opengl.GL;
-import javax.media.opengl.GLContext;
import javax.media.opengl.GLProfile;
import jogamp.opengl.av.GLMediaPlayerImpl;
@@ -40,6 +39,7 @@ import jogamp.opengl.av.GLMediaPlayerImpl;
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.IOUtil;
import com.jogamp.opengl.util.texture.Texture;
+import com.jogamp.opengl.util.texture.TextureCoords;
import com.jogamp.opengl.util.texture.TextureData;
import com.jogamp.opengl.util.texture.TextureIO;
@@ -96,11 +96,16 @@ public class NullGLMediaPlayer extends GLMediaPlayerImpl {
}
@Override
- public TextureFrame getNextTexture() {
+ public TextureFrame getNextTexture(GL gl, boolean blocking) {
return frame;
}
@Override
+ public TextureCoords getTextureCoords() {
+ return frame.getTexture().getImageTexCoords();
+ }
+
+ @Override
public long getCurrentPosition() {
pos_ms = System.currentTimeMillis() - pos_start;
validatePos();
@@ -112,7 +117,7 @@ public class NullGLMediaPlayer extends GLMediaPlayerImpl {
}
@Override
- protected void initStreamImplPreGL() throws IOException {
+ protected void initGLStreamImpl(GL gl, int[] texNames) throws IOException {
try {
URLConnection urlConn = IOUtil.getResource("jogl/util/data/av/test-ntsc01-160x90.png", NullGLMediaPlayer.class.getClassLoader());
if(null != urlConn) {
@@ -146,15 +151,15 @@ public class NullGLMediaPlayer extends GLMediaPlayerImpl {
}
@Override
- protected void destroyTexImage(GLContext ctx, TextureFrame imgTex) {
- super.destroyTexImage(ctx, imgTex);
+ protected void destroyTexImage(GL gl, TextureFrame imgTex) {
+ super.destroyTexImage(gl, imgTex);
}
@Override
- protected TextureFrame createTexImage(GLContext ctx, int idx, int[] tex) {
- Texture texture = super.createTexImageImpl(ctx, idx, tex, false);
+ protected TextureFrame createTexImage(GL gl, int idx, int[] tex) {
+ Texture texture = super.createTexImageImpl(gl, idx, tex, false);
if(null != texData) {
- texture.updateImage(ctx.getGL(), texData);
+ texture.updateImage(gl, texData);
}
frame = new TextureFrame( texture );
return frame;
diff --git a/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java b/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java
index 99639ae62..7c775dd9f 100644
--- a/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java
+++ b/src/jogl/classes/jogamp/opengl/omx/OMXGLMediaPlayer.java
@@ -5,10 +5,10 @@ import java.io.IOException;
import java.net.URL;
import javax.media.opengl.GL;
-import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import com.jogamp.opengl.av.GLMediaEventListener;
+import com.jogamp.opengl.util.texture.TextureCoords;
import jogamp.opengl.av.EGLMediaPlayerImpl;
import jogamp.opengl.egl.EGL;
@@ -41,16 +41,16 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
}
@Override
- protected TextureFrame createTexImage(GLContext ctx, int idx, int[] tex) {
- final EGLTextureFrame eglTex = (EGLTextureFrame) super.createTexImage(ctx, idx, tex);
+ protected TextureFrame createTexImage(GL gl, int idx, int[] tex) {
+ final EGLTextureFrame eglTex = (EGLTextureFrame) super.createTexImage(gl, idx, tex);
_setStreamEGLImageTexture2D(moviePtr, idx, tex[idx], eglTex.getImage(), eglTex.getSync());
lastTex = eglTex;
return eglTex;
}
@Override
- protected void destroyTexImage(GLContext ctx, TextureFrame imgTex) {
- super.destroyTexImage(ctx, imgTex);
+ protected void destroyTexImage(GL gl, TextureFrame imgTex) {
+ super.destroyTexImage(gl, imgTex);
}
@Override
@@ -63,7 +63,7 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
}
@Override
- protected void initStreamImplPreGL() throws IOException {
+ protected void initGLStreamImpl(GL gl, int[] texNames) throws IOException {
if(0==moviePtr) {
throw new GLException("OMX native instance null");
}
@@ -140,17 +140,25 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
}
@Override
- public synchronized TextureFrame getNextTexture() {
+ public synchronized TextureFrame getNextTexture(GL gl, boolean blocking) {
if(0==moviePtr) {
throw new GLException("OMX native instance null");
}
- lastTex=null;
- TextureFrame eglImgTex = texFrameMap.get(new Integer(_getNextTextureID(moviePtr)));
- if(null!=eglImgTex) {
- lastTex = eglImgTex;
+ final int nextTex = _getNextTextureID(moviePtr, blocking);
+ if(0 < nextTex) {
+ final TextureFrame eglImgTex = texFrameMap.get(new Integer(_getNextTextureID(moviePtr, blocking)));
+ if(null!=eglImgTex) {
+ lastTex = eglImgTex;
+ }
}
return lastTex;
}
+
+ @Override
+ public TextureCoords getTextureCoords() {
+ return lastTex.getTexture().getImageTexCoords();
+ }
+
protected void attributesUpdated() {
int event_mask = 0;
@@ -222,7 +230,7 @@ public class OMXGLMediaPlayer extends EGLMediaPlayerImpl {
native void _play(long moviePtr);
native void _pause(long moviePtr);
native void _stop(long moviePtr);
- native int _getNextTextureID(long moviePtr);
+ native int _getNextTextureID(long moviePtr, boolean blocking);
native long _getCurrentPosition(long moviePtr);
}
diff --git a/src/jogl/native/openmax/jogamp_opengl_omx_OMXGLMediaPlayer.c b/src/jogl/native/openmax/jogamp_opengl_omx_OMXGLMediaPlayer.c
index 86307ae59..73687f305 100644
--- a/src/jogl/native/openmax/jogamp_opengl_omx_OMXGLMediaPlayer.c
+++ b/src/jogl/native/openmax/jogamp_opengl_omx_OMXGLMediaPlayer.c
@@ -222,12 +222,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1seek
}
JNIEXPORT jint JNICALL Java_jogamp_opengl_omx_OMXGLMediaPlayer__1getNextTextureID
- (JNIEnv *env, jobject instance, jlong ptr)
+ (JNIEnv *env, jobject instance, jlong ptr, jboolean blocking)
{
jint textureID = 0xffffffff;
OMXToolBasicAV_t *pOMXAV = (OMXToolBasicAV_t *)((void *)((intptr_t)ptr));
if (pOMXAV != NULL) {
- textureID = OMXToolBasicAV_GetNextTextureID(pOMXAV);
+ textureID = OMXToolBasicAV_GetNextTextureID(pOMXAV, blocking ? 1 : 0);
}
return textureID;
}
diff --git a/src/jogl/native/openmax/omx_tool.c b/src/jogl/native/openmax/omx_tool.c
index 784d6facf..5e168ad02 100644
--- a/src/jogl/native/openmax/omx_tool.c
+++ b/src/jogl/native/openmax/omx_tool.c
@@ -1411,9 +1411,9 @@ void OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDint64 time)
kdThreadMutexUnlock(pOMXAV->mutex);
}
-GLuint OMXToolBasicAV_GetNextTextureID(OMXToolBasicAV_t * pOMXAV) {
+GLuint OMXToolBasicAV_GetNextTextureID(OMXToolBasicAV_t * pOMXAV, int blocking) {
GLuint texID = 0;
- int ret = pOMXAV->glPos;
+ int idx = pOMXAV->glPos;
kdThreadMutexLock(pOMXAV->mutex);
if(pOMXAV->status==OMXAV_PLAYING) {
@@ -1438,9 +1438,10 @@ GLuint OMXToolBasicAV_GetNextTextureID(OMXToolBasicAV_t * pOMXAV) {
pOMXAV->omxPos = next;
next = (pOMXAV->omxPos + 1) % pOMXAV->vBufferNum;
pOMXAV->filled++;
- }
- else
- {
+ if(!blocking) {
+ break;
+ }
+ } else {
DBG_PRINT2( "GetNextTexture p2.3\n");
break;
}
@@ -1462,11 +1463,11 @@ GLuint OMXToolBasicAV_GetNextTextureID(OMXToolBasicAV_t * pOMXAV) {
pOMXAV->available--;
pOMXAV->filled--;
pOMXAV->glPos = (pOMXAV->glPos + 1) % pOMXAV->vBufferNum;
- ret = pOMXAV->glPos;
+ idx = pOMXAV->glPos;
}
}
- texID = pOMXAV->available ? pOMXAV->buffers[ret].tex : 0;
+ texID = pOMXAV->available ? pOMXAV->buffers[idx].tex : 0;
DBG_PRINT2( "GetNextTexture B avail %d, filled %d, pos o:%d g:%d t:%d\n",
pOMXAV->available, pOMXAV->filled, pOMXAV->omxPos, pOMXAV->glPos, texID);
diff --git a/src/jogl/native/openmax/omx_tool.h b/src/jogl/native/openmax/omx_tool.h
index be5b8f175..1ade60e4f 100644
--- a/src/jogl/native/openmax/omx_tool.h
+++ b/src/jogl/native/openmax/omx_tool.h
@@ -139,7 +139,7 @@ void OMXToolBasicAV_PlayStart(OMXToolBasicAV_t * pOMXAV); // #5
void OMXToolBasicAV_PlayPause(OMXToolBasicAV_t * pOMXAV);
void OMXToolBasicAV_PlayStop(OMXToolBasicAV_t * pOMXAV);
void OMXToolBasicAV_PlaySeek(OMXToolBasicAV_t * pOMXAV, KDint64 time);
-GLuint OMXToolBasicAV_GetNextTextureID(OMXToolBasicAV_t * pOMXAV);
+GLuint OMXToolBasicAV_GetNextTextureID(OMXToolBasicAV_t * pOMXAV, int blocking);
KDint64 OMXToolBasicAV_GetCurrentPosition(OMXToolBasicAV_t * pOMXAV);
diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity.java
index 43bfd5f61..86b3ffb48 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivity.java
@@ -33,7 +33,6 @@ import java.util.Arrays;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
-import javax.media.opengl.GLContext;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
@@ -47,12 +46,12 @@ import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.av.GLMediaPlayer;
-import com.jogamp.opengl.av.GLMediaPlayerFactory;
import com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieSimple;
import com.jogamp.opengl.util.Animator;
import android.os.Bundle;
import android.util.Log;
+import android.view.Gravity;
public class MovieSimpleActivity extends NewtBaseActivity {
static String TAG = "NEWTGearsES2Activity";
@@ -70,10 +69,10 @@ public class MovieSimpleActivity extends NewtBaseActivity {
super.onCreate(savedInstanceState);
final boolean mPlayerLocal = Boolean.valueOf(System.getProperty("jnlp.mplayer.local"));
- final boolean mPlayerNormal = Boolean.valueOf(System.getProperty("jnlp.mplayer.normal"));
final boolean mPlayerNoZoom = Boolean.valueOf(System.getProperty("jnlp.mplayer.nozoom"));
- final boolean mPlayerShared = !mPlayerNormal && Boolean.valueOf(System.getProperty("jnlp.mplayer.shared"));
- Log.d(TAG, "onCreate - 0 - mPlayerLocal "+mPlayerLocal+", mPlayerNormal "+mPlayerNormal+", mPlayerNoScale "+mPlayerNoZoom+", mPlayerShared "+mPlayerShared);
+ final boolean mPlayerHUD = Boolean.valueOf(System.getProperty("jnlp.mplayer.hud"));
+ final boolean mPlayerSharedHUD = mPlayerHUD && Boolean.valueOf(System.getProperty("jnlp.mplayer.hud.shared"));
+ Log.d(TAG, "onCreate - 0 - mPlayerLocal "+mPlayerLocal+", mPlayerNoScale "+mPlayerNoZoom+", mPlayerHUD "+mPlayerHUD+", mPlayerSharedHUD "+mPlayerSharedHUD);
String[] urls0 = new String[] {
System.getProperty("jnlp.media0_url2"),
@@ -85,7 +84,7 @@ public class MovieSimpleActivity extends NewtBaseActivity {
final URLConnection urlConnection1;
{
URLConnection _urlConnection1 = null;
- if(!mPlayerShared && !mPlayerNormal) {
+ if(mPlayerHUD && !mPlayerSharedHUD) {
String[] urls1 = new String[] { System.getProperty("jnlp.media1_url0") };
_urlConnection1 = getResource(urls1, 0);
}
@@ -101,8 +100,7 @@ public class MovieSimpleActivity extends NewtBaseActivity {
// also initializes JOGL
final GLCapabilities capsMain = new GLCapabilities(GLProfile.getGL2ES2());
- capsMain.setBackgroundOpaque(false);
- final GLCapabilities capsHUD = new GLCapabilities(GLProfile.getGL2ES2());
+ capsMain.setBackgroundOpaque(!mPlayerHUD);
// screen for layout params ..
final com.jogamp.newt.Display dpy = NewtFactory.createDisplay(null);
@@ -110,82 +108,79 @@ public class MovieSimpleActivity extends NewtBaseActivity {
scrn.addReference();
try {
- final GLMediaPlayer mPlayerMain = GLMediaPlayerFactory.create();
- mPlayerMain.initStream(urlConnection0);
-
- final GLMediaPlayer mPlayerHUD;
- if(!mPlayerNormal) {
- if(mPlayerShared) {
- mPlayerHUD = mPlayerMain;
- } else {
- mPlayerHUD = GLMediaPlayerFactory.create();
- mPlayerHUD.initStream(urlConnection1);
- }
- } else {
- mPlayerHUD = null;
- }
-
final Animator animator = new Animator();
setAnimator(animator);
// Main
- final MovieSimple demoMain = new MovieSimple(mPlayerMain, false);
- if(!mPlayerNormal) {
+ final MovieSimple demoMain = new MovieSimple(urlConnection0);
+ if(mPlayerHUD) {
demoMain.setEffects(MovieSimple.EFFECT_GRADIENT_BOTTOM2TOP);
demoMain.setTransparency(0.9f);
}
demoMain.setScaleOrig(mPlayerNoZoom);
final GLWindow glWindowMain = GLWindow.create(scrn, capsMain);
- glWindowMain.setFullscreen(true);
- // setContentView(getWindow(), glWindowMain);
- viewGroup.addView(((AndroidWindow)glWindowMain.getDelegatedWindow()).getAndroidView());
- registerNEWTWindow(glWindowMain);
+ {
+ final int padding = mPlayerHUD ? 32 : 0;
+ final android.view.View androidView = ((AndroidWindow)glWindowMain.getDelegatedWindow()).getAndroidView();
+ glWindowMain.setSize(scrn.getWidth()-padding, scrn.getHeight()-padding);
+ glWindowMain.setUndecorated(true);
+ // setContentView(getWindow(), glWindowMain);
+ viewGroup.addView(androidView, new android.widget.FrameLayout.LayoutParams(glWindowMain.getWidth(), glWindowMain.getHeight(), Gravity.BOTTOM|Gravity.RIGHT));
+ registerNEWTWindow(glWindowMain);
+ }
+
glWindowMain.addGLEventListener(demoMain);
animator.add(glWindowMain);
glWindowMain.setVisible(true);
- if(null != mPlayerHUD) {
- final MovieSimple demoHUD = new MovieSimple(mPlayerHUD, mPlayerShared);
- final GLWindow glWindowHUD = GLWindow.create(scrn, capsHUD);
- glWindowHUD.addMouseListener(toFrontMouseListener);
- {
- int x2 = scrn.getX();
- int y2 = scrn.getY();
- int w2 = scrn.getWidth()/2;
- int h2 = scrn.getHeight()/2;
- if(0 < mPlayerHUD.getWidth() && mPlayerHUD.getWidth()<w2) {
- w2 = mPlayerHUD.getWidth();
- }
- if(0 < mPlayerHUD.getHeight() && mPlayerHUD.getHeight()<h2) {
- h2 = mPlayerHUD.getHeight();
- }
- glWindowHUD.setPosition(x2, y2);
- glWindowHUD.setSize(w2, h2);
- System.err.println("HUD: "+mPlayerHUD);
- System.err.println("HUD: "+w2+"x"+h2);
- }
- // addContentView(getWindow(), glWindowHUD, new android.view.ViewGroup.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight()));
- viewGroup.addView(((AndroidWindow)glWindowHUD.getDelegatedWindow()).getAndroidView(), new android.view.ViewGroup.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight()));
- registerNEWTWindow(glWindowHUD);
- glWindowHUD.addGLEventListener(demoHUD);
- // Hand over shared ctx must happen while the shared GLWindow is
- // guaranteed to be initialized.
- glWindowMain.invoke(false, new GLRunnable() {
+ if(mPlayerHUD) {
+ final GLMediaPlayer sharedPlayer = mPlayerSharedHUD ? demoMain.getGLMediaPlayer() : null;
+ final GLCapabilities capsHUD = new GLCapabilities(GLProfile.getGL2ES2());
+ capsHUD.setBackgroundOpaque(false);
+ final GLWindow glWindowHUD = GLWindow.create(scrn, capsHUD);
+ glWindowMain.invoke(false, new GLRunnable() {
@Override
public boolean run(GLAutoDrawable drawable) {
- if(mPlayerShared) {
- GLContext sharedCtx = glWindowMain.getContext();
- System.err.println("Shared: "+sharedCtx);
- glWindowHUD.setSharedContext(sharedCtx);
- }
- animator.add(glWindowHUD);
- glWindowHUD.setVisible(true);
- glWindowHUD.requestFocus(false);
- return true;
+ int x2 = scrn.getX();
+ int y2 = scrn.getY();
+ int w2 = scrn.getWidth()/3;
+ int h2 = scrn.getHeight()/3;
+ if(null != sharedPlayer) {
+ if(0 < sharedPlayer.getWidth() && sharedPlayer.getWidth()<scrn.getWidth()/2 &&
+ 0 < sharedPlayer.getHeight() && sharedPlayer.getHeight()<scrn.getHeight()/2) {
+ w2 = sharedPlayer.getWidth();
+ h2 = sharedPlayer.getHeight();
+ }
+ glWindowHUD.setSharedContext(glWindowMain.getContext());
+ glWindowHUD.addGLEventListener(new MovieSimple(sharedPlayer));
+ } else {
+ try {
+ glWindowHUD.addGLEventListener(new MovieSimple(urlConnection1));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ glWindowHUD.setPosition(x2, y2);
+ glWindowHUD.setSize(w2, h2);
+ System.err.println("HUD: "+mPlayerHUD);
+ System.err.println("HUD: "+w2+"x"+h2);
+ glWindowHUD.addMouseListener(toFrontMouseListener);
+
+ viewGroup.post(new Runnable() {
+ public void run() {
+ final android.view.View androidView = ((AndroidWindow)glWindowHUD.getDelegatedWindow()).getAndroidView();
+ // addContentView(getWindow(), glWindowHUD, new android.view.ViewGroup.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight()));
+ viewGroup.addView(androidView, new android.widget.FrameLayout.LayoutParams(glWindowHUD.getWidth(), glWindowHUD.getHeight(), Gravity.TOP|Gravity.LEFT));
+ registerNEWTWindow(glWindowHUD);
+ animator.add(glWindowHUD);
+ glWindowHUD.setVisible(true);
+ } } );
+ return true;
} } );
}
animator.setUpdateFPSFrames(60, System.err);
+ // animator.setUpdateFPSFrames(-1, null);
animator.resetFPSCounter();
} catch (IOException e) {
e.printStackTrace();
@@ -199,7 +194,7 @@ public class MovieSimpleActivity extends NewtBaseActivity {
static URLConnection getResource(String path[], int off) {
URLConnection uc = null;
for(int i=off; null==uc && i<path.length; i++) {
- if(null != path[i]) {
+ if(null != path[i] && path[i].length()>0) {
uc = IOUtil.getResource(path[i], null);
Log.d(TAG, "Stream: <"+path[i]+">: "+(null!=uc));
}
diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher00a.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher00a.java
index 0fdd2297e..3ad462691 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher00a.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher00a.java
@@ -34,17 +34,18 @@ import com.jogamp.opengl.test.android.LauncherUtil.OrderedProperties;
public class MovieSimpleActivityLauncher00a extends LauncherUtil.BaseActivityLauncher {
- static String demo = "com.jogamp.opengl.test.android.MovieSimpleActivity";
+ static String demo = "com.jogamp.opengl.test.android.MovieSimpleActivity0";
// static String[] pkgs = new String[] { "com.jogamp.common", "javax.media.opengl", "com.jogamp.opengl.test" };
static String[] pkgs = new String[] { "com.jogamp.opengl.test" };
@Override
public void init() {
final OrderedProperties props = getProperties();
- props.setProperty("jnlp.mplayer.normal", "true");
- props.setProperty("jnlp.mplayer.nozoom", "true");
- props.setProperty("jnlp.mplayer.shared", "false");
- props.setProperty("jnlp.media0_url2", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v");
+ props.setProperty("jnlp.mplayer.nozoom", "true");
+ props.setProperty("jnlp.mplayer.hud", "false");
+ props.setProperty("jnlp.mplayer.hud.shared", "false");
+ // props.setProperty("jnlp.media0_url2", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v");
+ props.setProperty("jnlp.media0_url2", "");
props.setProperty("jnlp.media0_url1", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4");
props.setProperty("jnlp.media0_url0", "file:///mnt/sdcard/Movies/BigBuckBunny_320x180.mp4");
props.setProperty("jnlp.media1_url0", "http://archive.org/download/ElephantsDream/ed_1024_512kb.mp4");
diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher00b.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher00b.java
index e52e065c7..a5370e90b 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher00b.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher00b.java
@@ -41,10 +41,11 @@ public class MovieSimpleActivityLauncher00b extends LauncherUtil.BaseActivityLau
@Override
public void init() {
final OrderedProperties props = getProperties();
- props.setProperty("jnlp.mplayer.normal", "true");
- props.setProperty("jnlp.mplayer.nozoom", "false");
- props.setProperty("jnlp.mplayer.shared", "false");
- props.setProperty("jnlp.media0_url2", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v");
+ props.setProperty("jnlp.mplayer.nozoom", "false");
+ props.setProperty("jnlp.mplayer.hud", "false");
+ props.setProperty("jnlp.mplayer.hud.shared", "false");
+ // props.setProperty("jnlp.media0_url2", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v");
+ props.setProperty("jnlp.media0_url2", "");
props.setProperty("jnlp.media0_url1", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4");
props.setProperty("jnlp.media0_url0", "file:///mnt/sdcard/Movies/BigBuckBunny_320x180.mp4");
props.setProperty("jnlp.media1_url0", "http://archive.org/download/ElephantsDream/ed_1024_512kb.mp4");
diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher01a.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher01a.java
index 9e4823a04..ff3fadadf 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher01a.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher01a.java
@@ -41,10 +41,11 @@ public class MovieSimpleActivityLauncher01a extends LauncherUtil.BaseActivityLau
@Override
public void init() {
final OrderedProperties props = getProperties();
- props.setProperty("jnlp.mplayer.normal", "false");
- props.setProperty("jnlp.mplayer.nozoom", "true");
- props.setProperty("jnlp.mplayer.shared", "true");
- props.setProperty("jnlp.media0_url2", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v");
+ props.setProperty("jnlp.mplayer.nozoom", "true");
+ props.setProperty("jnlp.mplayer.hud", "true");
+ props.setProperty("jnlp.mplayer.hud.shared", "true");
+ // props.setProperty("jnlp.media0_url2", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v");
+ props.setProperty("jnlp.media0_url2", "");
props.setProperty("jnlp.media0_url1", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4");
props.setProperty("jnlp.media0_url0", "file:///mnt/sdcard/Movies/BigBuckBunny_320x180.mp4");
props.setProperty("jnlp.media1_url0", "http://archive.org/download/ElephantsDream/ed_1024_512kb.mp4");
diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher01b.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher01b.java
index 81d121b0e..9992ac65a 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher01b.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher01b.java
@@ -41,10 +41,11 @@ public class MovieSimpleActivityLauncher01b extends LauncherUtil.BaseActivityLau
@Override
public void init() {
final OrderedProperties props = getProperties();
- props.setProperty("jnlp.mplayer.normal", "false");
- props.setProperty("jnlp.mplayer.nozoom", "false");
- props.setProperty("jnlp.mplayer.shared", "true");
- props.setProperty("jnlp.media0_url2", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v");
+ props.setProperty("jnlp.mplayer.nozoom", "false");
+ props.setProperty("jnlp.mplayer.hud", "true");
+ props.setProperty("jnlp.mplayer.hud.shared", "true");
+ // props.setProperty("jnlp.media0_url2", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v");
+ props.setProperty("jnlp.media0_url2", "");
props.setProperty("jnlp.media0_url1", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4");
props.setProperty("jnlp.media0_url0", "file:///mnt/sdcard/Movies/BigBuckBunny_320x180.mp4");
props.setProperty("jnlp.media1_url0", "http://archive.org/download/ElephantsDream/ed_1024_512kb.mp4");
diff --git a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher02.java b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher02.java
index a907f063a..082cc6335 100644
--- a/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher02.java
+++ b/src/test/com/jogamp/opengl/test/android/MovieSimpleActivityLauncher02.java
@@ -41,10 +41,11 @@ public class MovieSimpleActivityLauncher02 extends LauncherUtil.BaseActivityLaun
@Override
public void init() {
final OrderedProperties props = getProperties();
- props.setProperty("jnlp.mplayer.normal", "false");
- props.setProperty("jnlp.mplayer.nozoom", "false");
- props.setProperty("jnlp.mplayer.shared", "false");
- props.setProperty("jnlp.media0_url2", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v");
+ props.setProperty("jnlp.mplayer.nozoom", "false");
+ props.setProperty("jnlp.mplayer.hud", "true");
+ props.setProperty("jnlp.mplayer.hud.shared", "false");
+ // props.setProperty("jnlp.media0_url2", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_640x360.m4v");
+ props.setProperty("jnlp.media0_url2", "");
props.setProperty("jnlp.media0_url1", "http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4");
props.setProperty("jnlp.media0_url0", "file:///mnt/sdcard/Movies/BigBuckBunny_320x180.mp4");
props.setProperty("jnlp.media1_url0", "http://archive.org/download/ElephantsDream/ed_1024_512kb.mp4");
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 dc1d97396..d32283473 100755
--- 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
@@ -56,7 +56,6 @@ import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.JoglVersion;
import com.jogamp.opengl.av.GLMediaPlayer;
import com.jogamp.opengl.av.GLMediaEventListener;
-import com.jogamp.opengl.av.GLMediaPlayer.TextureFrame;
import com.jogamp.opengl.av.GLMediaPlayerFactory;
import com.jogamp.opengl.test.junit.util.MiscUtils;
import com.jogamp.opengl.util.Animator;
@@ -80,7 +79,6 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
private long startTime;
private int effects = EFFECT_NORMAL;
private float alpha = 1.0f;
- private int texUnit = 0;
public static final int EFFECT_NORMAL = 0;
public static final int EFFECT_GRADIENT_BOTTOM2TOP = 1<<1;
@@ -90,9 +88,6 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
public void setOrthoProjection(boolean v) { orthoProjection=v; }
public boolean getOrthoProjection() { return orthoProjection; }
- public void setTextureUnit(int u) { texUnit = u; }
- public int getTextureUnit() { return texUnit; }
-
public boolean hasEffect(int e) { return 0 != ( effects & e ) ; }
public void setEffects(int e) { effects = e; };
public void setTransparency(float alpha) {
@@ -149,29 +144,29 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
};
GLMediaPlayer mPlayer;
+ URLConnection stream = null;
boolean mPlayerExternal;
boolean mPlayerShared;
boolean mPlayerScaleOrig;
public MovieSimple(URLConnection stream) throws IOException {
mPlayerScaleOrig = false;
+ mPlayerShared = false;
mPlayerExternal = false;
mPlayer = GLMediaPlayerFactory.create();
mPlayer.addEventListener(this);
- mPlayer.initStream(stream);
- System.out.println("p0.1 "+mPlayer);
+ this.stream = stream;
+ System.out.println("pC.1 "+mPlayer);
}
- public MovieSimple(GLMediaPlayer mediaPlayer, boolean shared) throws IllegalStateException {
- if(!shared && GLMediaPlayer.State.UninitializedGL != mediaPlayer.getState()) {
- throw new IllegalStateException("Given GLMediaPlayer not in state "+GLMediaPlayer.State.UninitializedGL+": "+mediaPlayer);
- }
+ public MovieSimple(GLMediaPlayer sharedMediaPlayer) throws IllegalStateException {
mPlayerScaleOrig = false;
- mPlayerShared = shared;
+ mPlayerShared = true;
mPlayerExternal = true;
- mPlayer = mediaPlayer;
+ mPlayer = sharedMediaPlayer;
mPlayer.addEventListener(this);
- System.out.println("p0.2 shared "+mPlayerShared+", "+mPlayer);
+ this.stream = null;
+ System.out.println("pC.2 shared "+mPlayerShared+", "+mPlayer);
}
public GLMediaPlayer getGLMediaPlayer() { return mPlayer; }
@@ -181,13 +176,13 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
}
@Override
- public void attributesChanges(GLMediaPlayer mp, int event_mask) {
- System.out.println("attributesChanges: "+mp+", 0x"+Integer.toHexString(event_mask));
+ public void attributesChanges(GLMediaPlayer mp, int event_mask, long when) {
+ System.out.println("attributesChanges: "+mp+", 0x"+Integer.toHexString(event_mask)+", when "+when);
}
@Override
- public void newFrameAvailable(GLMediaPlayer mp, TextureFrame frame) {
- // System.out.println("newFrameAvailable: "+mp+", "+frame);
+ public void newFrameAvailable(GLMediaPlayer mp, long when) {
+ // System.out.println("newFrameAvailable: "+mp+", when "+when);
}
public void start() {
@@ -240,13 +235,16 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
System.err.println(JoglVersion.getGLInfo(gl, null));
System.err.println("Alpha: "+alpha+", opaque "+drawable.getChosenGLCapabilities().isBackgroundOpaque()+
", "+drawable.getClass().getName()+", "+drawable);
+
+ gl.glFinish();
boolean useExternalTexture = false;
try {
+ System.out.println("p0 "+mPlayer+", shared "+mPlayerShared);
if(!mPlayerShared) {
- mPlayer.initGL(gl);
+ mPlayer.initGLStream(gl, stream);
}
- System.out.println("p1 "+mPlayer);
+ System.out.println("p1 "+mPlayer+", shared "+mPlayerShared);
useExternalTexture = GLES2.GL_TEXTURE_EXTERNAL_OES == mPlayer.getTextureTarget();
if(useExternalTexture && !gl.isExtensionAvailable("GL_OES_EGL_image_external")) {
throw new GLException("GL_OES_EGL_image_external requested but not available");
@@ -274,8 +272,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
if(!st.uniform(gl, pmvMatrixUniform)) {
throw new GLException("Error setting PMVMatrix in shader: "+st);
}
- final GLMediaPlayer.TextureFrame texFrame = mPlayer.getLastTexture();
- if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", texUnit))) {
+ if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", mPlayer.getTextureUnit()))) {
throw new GLException("Error setting mgl_ActiveTexture in shader: "+st);
}
@@ -320,7 +317,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
FloatBuffer verticeb = (FloatBuffer)vertices.getBuffer();
GLArrayData texcoord = interleaved.addGLSLSubArray("mgl_MultiTexCoord", 2, GL.GL_ARRAY_BUFFER);
- TextureCoords tc = texFrame.getTexture().getImageTexCoords();
+ TextureCoords tc = mPlayer.getTextureCoords();
FloatBuffer texcoordb = (FloatBuffer)texcoord.getBuffer();
GLArrayData colors = interleaved.addGLSLSubArray("mgl_Color", 4, GL.GL_ARRAY_BUFFER);
@@ -364,10 +361,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
}
interleaved.seal(gl, true);
- // OpenGL Render Settings
- // gl.glClearColor(0f, 0f, 0f, 0f);
- // gl.glClearColor(0.9f, 0.9f, 0.9f, 0.3f);
- gl.glClearColor(0.1f, 0.1f, 0.1f, 0.4f);
+ gl.glClearColor(0.3f, 0.3f, 0.3f, 0.3f);
gl.glEnable(GL2ES2.GL_DEPTH_TEST);
@@ -378,7 +372,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
if(null!=mPlayer) {
start();
- System.out.println("p1 "+mPlayer);
+ System.out.println("p2 "+mPlayer);
}
startTime = System.currentTimeMillis();
@@ -395,25 +389,25 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
if(null == mPlayer) { return; }
winWidth = width;
winHeight = height;
+
+ if(null != st) {
+ reshapePMV(width, height);
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+ st.useProgram(gl, true);
+ st.uniform(gl, pmvMatrixUniform);
+ st.useProgram(gl, false);
+ }
- reshapePMV(width, height);
-
- GL2ES2 gl = drawable.getGL().getGL2ES2();
-
- st.useProgram(gl, true);
- st.uniform(gl, pmvMatrixUniform);
- st.useProgram(gl, false);
-
- System.out.println("p2 "+mPlayer);
+ System.out.println("pR "+mPlayer);
}
private void reshapePMV(int width, int height) {
pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
pmvMatrix.glLoadIdentity();
if(orthoProjection) {
- float fw = (float) width;
- float fh = (float) height;
- pmvMatrix.glOrthof(-fw/2f, fw/2f, -fh/2f, fh/2f, -1.0f, 1.0f);
+ final float fw = (float) width / 2f;
+ final float fh = (float) height/ 2f;
+ pmvMatrix.glOrthof(-fw, fw, -fh, fh, -1.0f, 1.0f);
nearPlaneNormalized = 0f;
} else {
pmvMatrix.gluPerspective(45.0f, (float)width / (float)height, 1f, 10.0f);
@@ -430,6 +424,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
if(null == mPlayer) { return; }
stop();
+ System.out.println("pD.1 "+mPlayer);
GL2ES2 gl = drawable.getGL().getGL2ES2();
@@ -437,6 +432,7 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
if(!mPlayerExternal) {
mPlayer.destroy(gl);
}
+ System.out.println("pD.X "+mPlayer);
mPlayer=null;
pmvMatrixUniform = null;
pmvMatrix.destroy();
@@ -448,12 +444,12 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
public void display(GLAutoDrawable drawable) {
if(null == mPlayer) { return; }
- GL2ES2 gl = drawable.getGL().getGL2ES2();
-
- st.useProgram(gl, true);
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ st.useProgram(gl, true);
+
pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
pmvMatrix.glLoadIdentity();
pmvMatrix.glTranslatef(0, 0, zoom);
@@ -465,27 +461,21 @@ public class MovieSimple implements GLEventListener, GLMediaEventListener {
}
st.uniform(gl, pmvMatrixUniform);
- final Texture tex;
if(null!=mPlayer) {
final GLMediaPlayer.TextureFrame texFrame;
if(mPlayerShared) {
texFrame=mPlayer.getLastTexture();
} else {
- texFrame=mPlayer.getNextTexture();
+ texFrame=mPlayer.getNextTexture(gl, true);
+ }
+ if(null != texFrame) {
+ final Texture tex = texFrame.getTexture();
+ gl.glActiveTexture(GL.GL_TEXTURE0+mPlayer.getTextureUnit());
+ tex.enable(gl);
+ tex.bind(gl);
+ gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
+ tex.disable(gl);
}
- tex = texFrame.getTexture();
- gl.glActiveTexture(GL.GL_TEXTURE0+texUnit);
- tex.enable(gl);
- tex.bind(gl);
- } else {
- tex = null;
- }
-
- // Draw a square
- gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4);
-
- if(null!=tex) {
- tex.disable(gl);
}
st.useProgram(gl, false);