diff options
author | Sven Gothel <[email protected]> | 2023-03-13 05:59:34 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-03-13 05:59:34 +0100 |
commit | 913b00f8b876e29af91677ef61b3eb35d6853e6e (patch) | |
tree | 17bc28ad255f1e086b2aa80028d4e6fb1ffd0456 /src/demos/com/jogamp | |
parent | 5efd3a6d9cf12d38ce6d7c91f9c5968927f3253a (diff) |
GLMediaPlayer: Overhaul and simplify states, allow usage before stream ready showing test-texture. Adding stop(); (API Change)
- allow multiple initGL(..) @ uninitialized and initialized
- allows usage before stream is ready
- using a test-texture @ uninitialized
- adding stop()
API change
- initStream() -> playStream()
- play() -> resume()
FFMPEG: Added 'ready' check for robustness
Diffstat (limited to 'src/demos/com/jogamp')
13 files changed, 576 insertions, 472 deletions
diff --git a/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0a.java b/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0a.java index cdbaa7872..dfd0c94dc 100644 --- a/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0a.java +++ b/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0a.java @@ -125,7 +125,7 @@ public class MovieCubeActivity0a extends NewtBaseActivity { } } }); - demoMain.initStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0); + demoMain.playStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0); } catch (final IOException e) { e.printStackTrace(); } diff --git a/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0b.java b/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0b.java index b04487b5f..649739e09 100644 --- a/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0b.java +++ b/src/demos/com/jogamp/opengl/demos/android/MovieCubeActivity0b.java @@ -127,7 +127,7 @@ public class MovieCubeActivity0b extends NewtBaseActivity { } } }); - demoMain.initStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0); + demoMain.playStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0); } catch (final IOException e) { e.printStackTrace(); } diff --git a/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity0.java b/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity0.java index 07d0b9914..4b051a8cd 100644 --- a/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity0.java +++ b/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity0.java @@ -121,7 +121,7 @@ public class MovieSimpleActivity0 extends NewtBaseActivity { } } }); - demoMain.initStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0); + demoMain.playStream(streamLoc, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0); scrn.removeReference(); diff --git a/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity1.java b/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity1.java index d7a2aeae1..64a3c7c69 100644 --- a/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity1.java +++ b/src/demos/com/jogamp/opengl/demos/android/MovieSimpleActivity1.java @@ -158,7 +158,7 @@ public class MovieSimpleActivity1 extends NewtBaseActivity { } } }); - demoMain.initStream(streamLoc0, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0); + demoMain.playStream(streamLoc0, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0); if(mPlayerHUD) { final GLMediaPlayer mPlayerShared = mPlayerSharedHUD ? mPlayerMain : null; @@ -205,7 +205,7 @@ public class MovieSimpleActivity1 extends NewtBaseActivity { } } }); - demoHUD.initStream(streamLoc1, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0); + demoHUD.playStream(streamLoc1, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 0); glWindowHUD.setPosition(windowBounds.getX(), windowBounds.getY()); glWindowHUD.setSize(windowBounds.getWidth(), windowBounds.getHeight()); diff --git a/src/demos/com/jogamp/opengl/demos/av/CrossFadePlayer.java b/src/demos/com/jogamp/opengl/demos/av/CrossFadePlayer.java index a4d5e73de..0e028279c 100644 --- a/src/demos/com/jogamp/opengl/demos/av/CrossFadePlayer.java +++ b/src/demos/com/jogamp/opengl/demos/av/CrossFadePlayer.java @@ -79,7 +79,7 @@ public class CrossFadePlayer try {
mp.initGL(null);
if ( GLMediaPlayer.State.Paused == mp.getState() ) { // init OK
- mp.play();
+ mp.resume();
}
} catch (final Exception e) {
e.printStackTrace();
@@ -103,7 +103,7 @@ public class CrossFadePlayer public void run() {
System.out.println("mp.setPlaySpeed(1f) returned: " + mp.setPlaySpeed(1f));
mp.seek(0);
- mp.play();
+ mp.resume();
}
}.start();
}
@@ -145,7 +145,7 @@ public class CrossFadePlayer final Uri uri = Uri.valueOf(file);
System.out.println("State of player "+ i +": " + player[i].getState().toString());
System.out.println("...initializing stream "+ i +"...");
- player[i].initStream(uri, GLMediaPlayer.STREAM_ID_NONE, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT);
+ player[i].playStream(uri, GLMediaPlayer.STREAM_ID_NONE, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT);
}
}
diff --git a/src/demos/com/jogamp/opengl/demos/av/MovieCube.java b/src/demos/com/jogamp/opengl/demos/av/MovieCube.java index caf2f9381..33e04d05b 100644 --- a/src/demos/com/jogamp/opengl/demos/av/MovieCube.java +++ b/src/demos/com/jogamp/opengl/demos/av/MovieCube.java @@ -98,7 +98,7 @@ public class MovieCube implements GLEventListener { } /** - * Default constructor which also issues {@link #initStream(URI, int, int, int)} w/ default values + * Default constructor which also issues {@link #playStream(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. * <p> @@ -125,27 +125,16 @@ public class MovieCube implements GLEventListener { public void run() { // loop for-ever .. mPlayer.seek(0); - mPlayer.play(); + mPlayer.resume(); } }.start(); } } }); - initStream(defURI, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT); - StreamException se = null; - while( null == se && GLMediaPlayer.State.Initialized != mPlayer.getState() ) { - try { - Thread.sleep(16); - } catch (final InterruptedException e) { } - se = mPlayer.getStreamException(); - } - if( null != se ) { - se.printStackTrace(); - throw new RuntimeException(se); - } + playStream(defURI, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT); } /** - * Custom constructor, user needs to issue {@link #initStream(URI, int, int, int)} afterwards. + * Custom constructor, user needs to issue {@link #playStream(URI, int, int, int)} afterwards. */ public MovieCube(final float zoom0, final float rotx, final float roty, final boolean showText) throws IOException { this.zoom0 = zoom0; @@ -156,8 +145,8 @@ public class MovieCube implements GLEventListener { mPlayer = GLMediaPlayerFactory.createDefault(); } - public void initStream(final Uri streamLoc, final int vid, final int aid, final int textureCount) { - mPlayer.initStream(streamLoc, vid, aid, textureCount); + public void playStream(final Uri streamLoc, final int vid, final int aid, final int textureCount) { + mPlayer.playStream(streamLoc, vid, aid, textureCount); System.out.println("pC.1b "+mPlayer); } @@ -179,16 +168,12 @@ public class MovieCube implements GLEventListener { private final GLRegion regionFPS; private float pixelSize1, pixelSize2, underlineSize; - InfoTextRendererGLELBase(final GLProfile glp, final int rmode, final boolean lowPerfDevice) { + InfoTextRendererGLELBase(final GLProfile glp, final int rmode) { // FIXME: Graph TextRenderer does not AA well w/o MSAA and FBO super(rmode, MovieCube.this.textSampleCount); this.setRendererCallbacks(RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable); - if( lowPerfDevice ) { - regionFPS = null; - } else { - regionFPS = GLRegion.create(glp, renderModes, null); - System.err.println("RegionFPS "+Region.getRenderModeString(renderModes)+", sampleCount "+textSampleCount[0]+", class "+regionFPS.getClass().getName()); - } + regionFPS = GLRegion.create(glp, renderModes, null); + System.err.println("RegionFPS "+Region.getRenderModeString(renderModes)+", sampleCount "+textSampleCount[0]+", class "+regionFPS.getClass().getName()); staticRGBAColor[0] = 0.1f; staticRGBAColor[1] = 0.1f; staticRGBAColor[2] = 0.1f; @@ -224,6 +209,8 @@ public class MovieCube implements GLEventListener { super.dispose(drawable); } + String text1_old = null; + @Override public void display(final GLAutoDrawable drawable) { final GLAnimatorControl anim = drawable.getAnimator(); @@ -251,12 +238,12 @@ public class MovieCube implements GLEventListener { "; underlineSize "+underlineSize+" "+(pixelScale*underlineSize)+ "; yoff "+yoff1+", yoff2 "+yoff2); */ - final GL gl = drawable.getGL(); + final GL2ES2 gl = drawable.getGL().getGL2ES2(); final String ptsPrec = null != regionFPS ? "3.1" : "3.0"; - final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %d", + final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, swap %d", pts, mPlayer.getDuration() / 1000f, mPlayer.getState().toString().toLowerCase(), mPlayer.getPlaySpeed(), mPlayer.getAudioVolume(), - aspect, mPlayer.getFramerate(), lfps, tfps, swapInterval); + aspect, mPlayer.getFramerate(), lfps, tfps, drawable.getGL().getSwapInterval()); final String text2 = String.format("audio: id %d, kbps %d, codec %s", mPlayer.getAID(), mPlayer.getAudioBitrate()/1000, mPlayer.getAudioCodec()); final String text3 = String.format("video: id %d, kbps %d, codec %s", @@ -264,10 +251,11 @@ public class MovieCube implements GLEventListener { final String text4 = mPlayer.getUri().path.decode(); if( displayOSD && null != renderer ) { gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f); - if( null != regionFPS ) { - renderString(drawable, font, pixelSize1, text1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, regionFPS.clear(gl.getGL2ES2())); // no-cache + if( !text1.equals(text1_old) ) { + renderString(drawable, font, pixelSize1, text1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, regionFPS.clear(gl)); // clear-cache + text1_old = text1; } else { - renderString(drawable, font, pixelSize1, text1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, true); + renderRegion(drawable, font, pixelSize1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, regionFPS); } renderString(drawable, font, pixelSize2, text2, 1 /* col */, 0 /* row */, -1+z_diff, yoff2, 1f+z_diff, true); renderString(drawable, font, pixelSize2, text3, 1 /* col */, 1 /* row */, -1+z_diff, yoff2, 1f+z_diff, true); @@ -337,8 +325,12 @@ public class MovieCube implements GLEventListener { break; } case KeyEvent.VK_SPACE: { - if(GLMediaPlayer.State.Paused == mPlayer.getState()) { - mPlayer.play(); + if( GLMediaPlayer.State.Paused == mPlayer.getState() ) { + mPlayer.resume(); + } else if(GLMediaPlayer.State.Uninitialized == mPlayer.getState()) { + playStream(mPlayer.getUri(), GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 3 /* textureCount */); + } else if( e.isShiftDown() ) { + mPlayer.stop(); } else { mPlayer.pause(false); } @@ -392,12 +384,7 @@ public class MovieCube implements GLEventListener { if(null == mPlayer) { throw new InternalError("mPlayer null"); } - if( GLMediaPlayer.State.Uninitialized == mPlayer.getState() ) { - throw new IllegalStateException("mPlayer in uninitialized state: "+mPlayer); - } - if( GLMediaPlayer.STREAM_ID_NONE == mPlayer.getVID() ) { - // throw new IllegalStateException("mPlayer has no VID/stream selected: "+mPlayer); - } + // final boolean hasVideo = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID(); resetGLState = false; final GL2ES2 gl = drawable.getGL().getGL2ES2(); @@ -409,20 +396,18 @@ public class MovieCube implements GLEventListener { JunitTracer.waitForKey("Init>"); } - if( GLMediaPlayer.State.Initialized == mPlayer.getState() ) { - try { - mPlayer.initGL(gl); - } catch (final Exception e) { - e.printStackTrace(); - if(null != mPlayer) { - mPlayer.destroy(gl); - mPlayer = null; - } - throw new GLException(e); + try { + mPlayer.initGL(gl); + } catch (final Exception e) { + e.printStackTrace(); + if(null != mPlayer) { + mPlayer.destroy(gl); + mPlayer = null; } + throw new GLException(e); } cube.init(drawable); - mPlayer.play(); + mPlayer.resume(); System.out.println("play.0 "+mPlayer); boolean added; @@ -436,8 +421,7 @@ public class MovieCube implements GLEventListener { if( showText ) { final int rmode = drawable.getChosenGLCapabilities().getSampleBuffers() ? 0 : Region.VBAA_RENDERING_BIT; - final boolean lowPerfDevice = gl.isGLES(); - textRendererGLEL = new InfoTextRendererGLELBase(gl.getGLProfile(), rmode, lowPerfDevice); + textRendererGLEL = new InfoTextRendererGLELBase(gl.getGLProfile(), rmode); drawable.addGLEventListener(textRendererGLEL); } } @@ -451,10 +435,6 @@ public class MovieCube implements GLEventListener { @Override public void dispose(final GLAutoDrawable drawable) { System.err.println(Thread.currentThread()+" MovieCube.dispose ... "); - if( null != textRendererGLEL ) { - drawable.disposeGLEventListener(textRendererGLEL, true); - textRendererGLEL = null; - } disposeImpl(drawable, true); } @@ -466,6 +446,10 @@ public class MovieCube implements GLEventListener { window.removeKeyListener(keyAction); } final GL2ES2 gl = drawable.getGL().getGL2ES2(); + if( null != textRendererGLEL ) { + drawable.disposeGLEventListener(textRendererGLEL, true); + textRendererGLEL = null; + } if( disposePlayer ) { mPlayer.destroy(gl); mPlayer=null; @@ -498,7 +482,7 @@ public class MovieCube implements GLEventListener { final long currentPos = System.currentTimeMillis(); if( currentPos - lastPerfPos > 2000 ) { - System.err.println( mPlayer.getPerfString() ); + // System.err.println( mPlayer.getPerfString() ); lastPerfPos = currentPos; } cube.display(drawable); @@ -607,6 +591,7 @@ public class MovieCube implements GLEventListener { anim.stop(); } }); + window.addGLEventListener(mc); window.setSize(width, height); window.setVisible(true); System.err.println("Chosen: "+window.getChosenGLCapabilities()); @@ -626,12 +611,11 @@ public class MovieCube implements GLEventListener { window.setSurfaceSize(mp.getWidth(), mp.getHeight()); } // window.disposeGLEventListener(ms, false /* remove */ ); - mc.resetGLState(); } if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) { - window.addGLEventListener(mc); anim.setUpdateFPSFrames(60, null); anim.resetFPSCounter(); + mc.resetGLState(); } if( 0 != ( GLMediaEventListener.EVENT_CHANGE_PLAY & event_mask ) ) { anim.resetFPSCounter(); @@ -649,7 +633,7 @@ public class MovieCube implements GLEventListener { } } }); - mc.initStream(streamLoc, vid, aid, textureCount); + mc.playStream(streamLoc, vid, aid, textureCount); } } diff --git a/src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java b/src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java index 62e3975dd..519a51a87 100644 --- a/src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java +++ b/src/demos/com/jogamp/opengl/demos/av/MovieSBSStereo.java @@ -218,7 +218,7 @@ public class MovieSBSStereo implements StereoGLEventListener { if(GLMediaPlayer.State.Playing == mPlayer.getState()) { mPlayer.pause(false); } else { - mPlayer.play(); + mPlayer.resume(); } } } @@ -245,7 +245,7 @@ public class MovieSBSStereo implements StereoGLEventListener { final int pts0 = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID() ? mPlayer.getVideoPTS() : mPlayer.getAudioPTS(); mPlayer.seek(pts0 + (int) (mPlayer.getDuration() * dp)); } else { - mPlayer.play(); + mPlayer.resume(); rotate = 1; zoom = zoom1; } @@ -286,7 +286,7 @@ public class MovieSBSStereo implements StereoGLEventListener { } case KeyEvent.VK_SPACE: { if(GLMediaPlayer.State.Paused == mPlayer.getState()) { - mPlayer.play(); + mPlayer.resume(); } else { mPlayer.pause(false); } @@ -329,7 +329,7 @@ public class MovieSBSStereo implements StereoGLEventListener { } } }; - /** user needs to issue {@link #initStream(URI, int, int, int)} afterwards. */ + /** user needs to issue {@link #playStream(URI, int, int, int)} afterwards. */ public MovieSBSStereo() throws IllegalStateException { mPlayerScaleOrig = false; mPlayer = GLMediaPlayerFactory.createDefault(); @@ -338,7 +338,7 @@ public class MovieSBSStereo implements StereoGLEventListener { } public void initStream(final Uri streamLoc, final int vid, final int aid, final int textureCount) { - mPlayer.initStream(streamLoc, vid, aid, textureCount); + mPlayer.playStream(streamLoc, vid, aid, textureCount); System.out.println("pC.1b "+mPlayer); } @@ -531,7 +531,7 @@ public class MovieSBSStereo implements StereoGLEventListener { System.out.println(st); } - mPlayer.play(); + mPlayer.resume(); System.out.println("play.0 "+mPlayer); startTime = System.currentTimeMillis(); @@ -861,7 +861,7 @@ public class MovieSBSStereo implements StereoGLEventListener { public void run() { mp.setPlaySpeed(1f); mp.seek(0); - mp.play(); + mp.resume(); } }.start(); } diff --git a/src/demos/com/jogamp/opengl/demos/av/MovieSimple.java b/src/demos/com/jogamp/opengl/demos/av/MovieSimple.java index 42c7b94a5..27735f4c7 100644 --- a/src/demos/com/jogamp/opengl/demos/av/MovieSimple.java +++ b/src/demos/com/jogamp/opengl/demos/av/MovieSimple.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 JogAmp Community. All rights reserved. + * Copyright 2012-2023 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -32,10 +32,8 @@ import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; -import java.nio.FloatBuffer; import com.jogamp.common.net.Uri; -import com.jogamp.common.os.Platform; import com.jogamp.common.util.InterruptSource; import com.jogamp.graph.curve.Region; import com.jogamp.graph.curve.opengl.GLRegion; @@ -53,36 +51,25 @@ import com.jogamp.newt.event.MouseListener; import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2ES2; import com.jogamp.opengl.GLAnimatorControl; import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.GLCapabilities; -import com.jogamp.opengl.GLES2; import com.jogamp.opengl.GLEventListener; import com.jogamp.opengl.GLException; -import com.jogamp.opengl.GLExtensions; import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.GLRunnable; -import com.jogamp.opengl.GLUniformData; import com.jogamp.opengl.JoglVersion; +import com.jogamp.opengl.demos.es2.TextureSequenceES2; import com.jogamp.opengl.demos.graph.TextRendererGLELBase; import com.jogamp.opengl.demos.util.MiscUtils; -import com.jogamp.opengl.fixedfunc.GLMatrixFunc; import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.util.GLArrayDataServer; import com.jogamp.opengl.util.GLReadBufferUtil; -import com.jogamp.opengl.util.PMVMatrix; import com.jogamp.opengl.util.av.GLMediaPlayer; import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener; import com.jogamp.opengl.util.av.GLMediaPlayer.StreamException; import com.jogamp.opengl.util.av.GLMediaPlayerFactory; -import com.jogamp.opengl.util.glsl.ShaderCode; -import com.jogamp.opengl.util.glsl.ShaderProgram; -import com.jogamp.opengl.util.glsl.ShaderState; -import com.jogamp.opengl.util.texture.Texture; -import com.jogamp.opengl.util.texture.TextureCoords; -import com.jogamp.opengl.util.texture.TextureSequence; import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame; /** @@ -99,9 +86,8 @@ public class MovieSimple implements GLEventListener { private static boolean waitForKey = false; private int surfWidth, surfHeight; private int prevMouseX; // , prevMouseY; - private int rotate = 0; + private final int rotate = 0; private boolean orthoProjection = true; - private float nearPlaneNormalized; private float zoom0; private float zoom1; private float zoom; @@ -111,21 +97,16 @@ public class MovieSimple implements GLEventListener { private int swapInterval = 1; private boolean swapIntervalSet = true; + private TextureSequenceES2 screen=null; private GLMediaPlayer mPlayer; private final boolean mPlayerShared; private boolean mPlayerScaleOrig; - private float[] verts = null; + private final float[] verts = null; private GLArrayDataServer interleavedVBO; private volatile boolean resetGLState = false; private volatile GLAutoDrawable autoDrawable = null; - private ShaderState st; - private PMVMatrix pmvMatrix; - private GLUniformData pmvMatrixUniform; - private static final String shaderBasename = "texsequence_xxx"; - private static final String myTextureLookupName = "myTexture2D"; - /** Blender's Big Buck Bunny: 24f 416p H.264, AAC 48000 Hz, 2 ch, mpeg stream. */ public static final Uri defURI; static { @@ -147,16 +128,12 @@ public class MovieSimple implements GLEventListener { private final float fontSize = 10f; private final GLRegion regionFPS; - InfoTextRendererGLELBase(final GLProfile glp, final int rmode, final boolean lowPerfDevice) { + InfoTextRendererGLELBase(final GLProfile glp, final int rmode) { // FIXME: Graph TextRenderer does not AA well w/o MSAA and FBO super(rmode, textSampleCount); this.setRendererCallbacks(RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable); - if( lowPerfDevice ) { - regionFPS = null; - } else { - regionFPS = GLRegion.create(glp, renderModes, null); - System.err.println("RegionFPS "+Region.getRenderModeString(renderModes)+", sampleCount "+textSampleCount[0]+", class "+regionFPS.getClass().getName()); - } + regionFPS = GLRegion.create(glp, renderModes, null); + System.err.println("RegionFPS "+Region.getRenderModeString(renderModes)+", sampleCount "+textSampleCount[0]+", class "+regionFPS.getClass().getName()); staticRGBAColor[0] = 0.9f; staticRGBAColor[1] = 0.9f; staticRGBAColor[2] = 0.9f; @@ -176,6 +153,8 @@ public class MovieSimple implements GLEventListener { super.dispose(drawable); } + String text1_old = null; + @Override public void display(final GLAutoDrawable drawable) { final GLAnimatorControl anim = drawable.getAnimator(); @@ -191,10 +170,10 @@ public class MovieSimple implements GLEventListener { final float aspect = (float)mPlayer.getWidth() / (float)mPlayer.getHeight(); final String ptsPrec = null != regionFPS ? "3.1" : "3.0"; - final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %b", + final String text1 = String.format("%0"+ptsPrec+"f/%0"+ptsPrec+"f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, swap %d", pts, mPlayer.getDuration() / 1000f, mPlayer.getState().toString().toLowerCase(), mPlayer.getPlaySpeed(), mPlayer.getAudioVolume(), - aspect, mPlayer.getFramerate(), lfps, tfps, swapIntervalSet); + aspect, mPlayer.getFramerate(), lfps, tfps, drawable.getGL().getSwapInterval()); final String text2 = String.format("audio: id %d, kbps %d, codec %s", mPlayer.getAID(), mPlayer.getAudioBitrate()/1000, mPlayer.getAudioCodec()); final String text3 = String.format("video: id %d, kbps %d, codec %s", @@ -203,11 +182,12 @@ public class MovieSimple implements GLEventListener { if( displayOSD && null != renderer ) { // We share ClearColor w/ MovieSimple's init ! final float pixelSize = FontScale.toPixels(fontSize, dpiH); - if( null != regionFPS ) { - final GL2ES2 gl = drawable.getGL().getGL2ES2(); - renderString(drawable, font, pixelSize, text1, 1 /* col */, 1 /* row */, 0, 0, -1, regionFPS.clear(gl)); // no-cache + final GL2ES2 gl = drawable.getGL().getGL2ES2(); + if( !text1.equals(text1_old) ) { + renderString(drawable, font, pixelSize, text1, 1 /* col */, 1 /* row */, 0, 0, -1, regionFPS.clear(gl)); // clear-cache + text1_old = text1; } else { - renderString(drawable, font, pixelSize, text1, 1 /* col */, 1 /* row */, 0, 0, -1, true); + renderRegion(drawable, font, pixelSize, 1 /* col */, 1 /* row */, 0, 0, -1, regionFPS); } renderString(drawable, font, pixelSize, text2, 1 /* col */, -4 /* row */, 0, height, -1, true); renderString(drawable, font, pixelSize, text3, 1 /* col */, -3 /* row */, 0, height, -1, true); @@ -249,15 +229,18 @@ public class MovieSimple implements GLEventListener { if(GLMediaPlayer.State.Playing == mPlayer.getState()) { mPlayer.pause(false); } else { - mPlayer.play(); + mPlayer.resume(); } } } @Override public void mouseReleased(final MouseEvent e) { if(e.getY()<=surfHeight/2) { - rotate = -1; zoom = zoom0; + if( null != screen ) { + screen.setZoom(zoom); + screen.setZRotation(-1f); + } System.err.println("zoom: "+zoom); } } @@ -276,9 +259,12 @@ public class MovieSimple implements GLEventListener { final int pts0 = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID() ? mPlayer.getVideoPTS() : mPlayer.getAudioPTS(); mPlayer.seek(pts0 + (int) (mPlayer.getDuration() * dp)); } else { - mPlayer.play(); - rotate = 1; + mPlayer.resume(); zoom = zoom1; + if( null != screen ) { + screen.setZoom(zoom); + screen.setZRotation(1f); + } } prevMouseX = x; @@ -288,6 +274,9 @@ public class MovieSimple implements GLEventListener { public void mouseWheelMoved(final MouseEvent e) { if( !e.isShiftDown() ) { zoom += e.getRotation()[1]/10f; // vertical: wheel + if( null != screen ) { + screen.setZoom(zoom); + } System.err.println("zoom: "+zoom); } } }; @@ -326,8 +315,12 @@ public class MovieSimple implements GLEventListener { break; } case KeyEvent.VK_SPACE: { - if(GLMediaPlayer.State.Paused == mPlayer.getState()) { - mPlayer.play(); + if( GLMediaPlayer.State.Paused == mPlayer.getState() ) { + mPlayer.resume(); + } else if(GLMediaPlayer.State.Uninitialized == mPlayer.getState()) { + playStream(mPlayer.getUri(), GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 3 /* textureCount */); + } else if( e.isShiftDown() ) { + mPlayer.stop(); } else { mPlayer.pause(false); } @@ -376,7 +369,7 @@ public class MovieSimple implements GLEventListener { } }; /** - * Default constructor which also issues {@link #initStream(URI, int, int, int)} w/ default values + * Default constructor which also issues {@link #playStream(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. * <p> @@ -394,35 +387,21 @@ public class MovieSimple implements GLEventListener { public void attributesChanged(final GLMediaPlayer mp, final int event_mask, final long when) { System.err.println("MovieCube AttributesChanges: events_mask 0x"+Integer.toHexString(event_mask)+", when "+when); System.err.println("MovieCube State: "+mp); - if( 0 != ( GLMediaEventListener.EVENT_CHANGE_SIZE & event_mask ) ) { - resetGLState(); - } if( 0 != ( GLMediaEventListener.EVENT_CHANGE_EOS & event_mask ) ) { new InterruptSource.Thread() { @Override public void run() { // loop for-ever .. mPlayer.seek(0); - mPlayer.play(); + mPlayer.resume(); } }.start(); } } }); - initStream(defURI, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 3 /* textureCount */); - StreamException se = null; - while( null == se && GLMediaPlayer.State.Initialized != mPlayer.getState() ) { - try { - Thread.sleep(16); - } catch (final InterruptedException e) { } - se = mPlayer.getStreamException(); - } - if( null != se ) { - se.printStackTrace(); - throw new RuntimeException(se); - } + playStream(defURI, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 3 /* textureCount */); } - /** Custom constructor, user needs to issue {@link #initStream(URI, int, int, int)} afterwards. */ + /** Custom constructor, user needs to issue {@link #playStream(URI, int, int, int)} afterwards. */ public MovieSimple(final GLMediaPlayer sharedMediaPlayer) throws IllegalStateException { screenshot = new GLReadBufferUtil(false, false); mPlayer = sharedMediaPlayer; @@ -435,8 +414,8 @@ public class MovieSimple implements GLEventListener { System.out.println("pC.1a shared "+mPlayerShared+", "+mPlayer); } - public void initStream(final Uri streamLoc, final int vid, final int aid, final int textureCount) { - mPlayer.initStream(streamLoc, vid, aid, textureCount); + public void playStream(final Uri streamLoc, final int vid, final int aid, final int textureCount) { + mPlayer.playStream(streamLoc, vid, aid, textureCount); System.out.println("pC.1b "+mPlayer); } @@ -452,73 +431,19 @@ public class MovieSimple implements GLEventListener { public void setOrthoProjection(final boolean v) { orthoProjection=v; } public boolean getOrthoProjection() { return orthoProjection; } - public boolean hasEffect(final int e) { return 0 != ( effects & e ) ; } public void setEffects(final int e) { effects = e; }; - public void setTransparency(final float alpha) { - this.effects |= EFFECT_TRANSPARENT; - this.alpha = alpha; - } + public void setTransparency(final float alpha) { this.alpha = alpha; } public void resetGLState() { resetGLState = true; } - private void initShader(final GL2ES2 gl) { - // Create & Compile the shader objects - final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, MovieSimple.class, - "../shader", "../shader/bin", shaderBasename, true); - final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, MovieSimple.class, - "../shader", "../shader/bin", shaderBasename, true); - - 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()); - rsFp.addDefaultShaderPrecision(gl, rsFpPos); - - 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"); - sFpIns.append(mPlayer.getTextureLookupFragmentShaderImpl()); - rsFp.insertShaderSource(0, "TEXTURE-SEQUENCE-CODE-BEGIN", 0, sFpIns); - - // Create & Link the shader program - final ShaderProgram sp = new ShaderProgram(); - sp.add(rsVp); - sp.add(rsFp); - if(!sp.link(gl, System.err)) { - throw new GLException("Couldn't link program: "+sp); - } - - // Let's manage all our states using ShaderState. - st = new ShaderState(); - st.attachShaderProgram(gl, sp, false); - } - @Override public void init(final GLAutoDrawable drawable) { if(null == mPlayer) { throw new InternalError("mPlayer null"); } - if( GLMediaPlayer.State.Uninitialized == mPlayer.getState() ) { - throw new IllegalStateException("mPlayer in uninitialized state: "+mPlayer); - } - final boolean hasVideo = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID(); + // final boolean hasVideo = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID(); resetGLState = false; zoom0 = orthoProjection ? 0f : -2.5f; @@ -532,118 +457,26 @@ public class MovieSimple implements GLEventListener { System.err.println("Alpha: "+alpha+", opaque "+drawable.getChosenGLCapabilities().isBackgroundOpaque()+ ", "+drawable.getClass().getName()+", "+drawable); + screen = new TextureSequenceES2(mPlayer, mPlayerShared, orthoProjection, zoom); + screen.setEffects(effects); + screen.setTransparency(alpha); + if(waitForKey) { JunitTracer.waitForKey("Init>"); } - final Texture tex; + try { - System.out.println("p0 "+mPlayer+", shared "+mPlayerShared); - if(!mPlayerShared && GLMediaPlayer.State.Initialized == mPlayer.getState() ) { - mPlayer.initGL(gl); - } - System.out.println("p1 "+mPlayer+", shared "+mPlayerShared); - final TextureFrame frame = mPlayer.getLastTexture(); - if( null != frame ) { - if( !hasVideo ) { - throw new InternalError("XXX: "+mPlayer); - } - tex = frame.getTexture(); - if( null == tex ) { - throw new InternalError("XXX: "+mPlayer); - } - } else { - tex = null; - if( hasVideo ) { - throw new InternalError("XXX: "+mPlayer); - } - } - if(!mPlayerShared) { - mPlayer.setTextureMinMagFilter( new int[] { GL.GL_NEAREST, GL.GL_LINEAR } ); - } - } catch (final Exception glex) { - glex.printStackTrace(); - if(!mPlayerShared && null != mPlayer) { + mPlayer.initGL(gl); + } catch (final Exception e) { + e.printStackTrace(); + if(null != mPlayer) { mPlayer.destroy(gl); mPlayer = null; } - throw new GLException(glex); + throw new GLException(e); } + screen.init(drawable); - if( hasVideo ) { - initShader(gl); - - // Push the 1st uniform down the path - st.useProgram(gl, true); - - final int[] viewPort = new int[] { 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight()}; - pmvMatrix = new PMVMatrix(); - 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); - } - if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", mPlayer.getTextureUnit()))) { - throw new GLException("Error setting mgl_ActiveTexture in shader: "+st); - } - - final float dWidth = drawable.getSurfaceWidth(); - final float dHeight = drawable.getSurfaceHeight(); - final float mWidth = mPlayer.getWidth(); - final float mHeight = mPlayer.getHeight(); - final 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; - } else { - xs = dWidth/2f; ys = xs / mAspect; // w>h - } - } else { - if(mPlayerScaleOrig && mWidth < dWidth && mHeight < dHeight) { - xs = mAspect * ( mWidth / dWidth ) ; ys = xs / mAspect ; - } else { - xs = mAspect; ys = 1f; // b>h - } - } - verts = new float[] { -1f*xs, -1f*ys, 0f, // LB - 1f*xs, 1f*ys, 0f // RT - }; - { - System.err.println("XXX0: pixel LB: "+verts[0]+", "+verts[1]+", "+verts[2]); - System.err.println("XXX0: pixel RT: "+verts[3]+", "+verts[4]+", "+verts[5]); - final float[] winLB = new float[3]; - final float[] winRT = new float[3]; - pmvMatrix.gluProject(verts[0], verts[1], verts[2], viewPort, 0, winLB, 0); - pmvMatrix.gluProject(verts[3], verts[4], verts[5], viewPort, 0, winRT, 0); - System.err.println("XXX0: win LB: "+winLB[0]+", "+winLB[1]+", "+winLB[2]); - System.err.println("XXX0: win RT: "+winRT[0]+", "+winRT[1]+", "+winRT[2]); - } - - 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); - } - updateInterleavedVBO(gl, tex); - - st.ownAttribute(interleavedVBO, true); - gl.glClearColor(0.3f, 0.3f, 0.3f, 0.3f); - - gl.glEnable(GL.GL_DEPTH_TEST); - - st.useProgram(gl, false); - - // Let's show the completed shader state .. - System.out.println("iVBO: "+interleavedVBO); - System.out.println(st); - } - - if(!mPlayerShared) { - mPlayer.play(); - System.out.println("play.0 "+mPlayer); - } startTime = System.currentTimeMillis(); final Object upstreamWidget = drawable.getUpstreamWidget(); @@ -655,101 +488,22 @@ public class MovieSimple implements GLEventListener { surfHeight = window.getSurfaceHeight(); } final int rmode = drawable.getChosenGLCapabilities().getSampleBuffers() ? 0 : Region.VBAA_RENDERING_BIT; - final boolean lowPerfDevice = gl.isGLES(); - textRendererGLEL = new InfoTextRendererGLELBase(gl.getGLProfile(), rmode, lowPerfDevice); + textRendererGLEL = new InfoTextRendererGLELBase(gl.getGLProfile(), rmode); drawable.addGLEventListener(textRendererGLEL); } - protected void updateInterleavedVBO(final GL gl, final Texture tex) { - final float ss = 1f, ts = 1f; // scale tex-coord - final boolean wasEnabled = interleavedVBO.enabled(); - interleavedVBO.seal(gl, false); - interleavedVBO.rewind(); - { - final FloatBuffer ib = (FloatBuffer)interleavedVBO.getBuffer(); - final TextureCoords tc = tex.getImageTexCoords(); - 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) ) { - 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); - } - 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); - } else { - ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha); - } - ib.put( tc.right() *ss); ib.put( tc.bottom() *ts); - - // left-top - ib.put(verts[0]); ib.put(verts[4]); ib.put(verts[2]); - 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]); - ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha); - ib.put( tc.right() *ss); ib.put( tc.top() *ts); - } - interleavedVBO.seal(gl, true); - if( !wasEnabled ) { - interleavedVBO.enableBuffer(gl, false); - } - } - @Override public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { - final GL2ES2 gl = drawable.getGL().getGL2ES2(); if(null == mPlayer) { return; } + screen.reshape(drawable, x, y, width, height); surfWidth = width; surfHeight = 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 final float zNear = 1f; - private final float zFar = 10f; - - private void reshapePMV(final int width, final int height) { - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - pmvMatrix.glLoadIdentity(); - if(orthoProjection) { - final float fw = width / 2f; - final float fh = height/ 2f; - pmvMatrix.glOrthof(-fw, fw, -fh, fh, -1.0f, 1.0f); - nearPlaneNormalized = 0f; - } else { - pmvMatrix.gluPerspective(45.0f, (float)width / (float)height, zNear, zFar); - nearPlaneNormalized = 1f/(10f-1f); - } - System.err.println("XXX0: Perspective nearPlaneNormalized: "+nearPlaneNormalized); - - pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); - pmvMatrix.glLoadIdentity(); - pmvMatrix.glTranslatef(0, 0, zoom0); - } - @Override public void dispose(final GLAutoDrawable drawable) { autoDrawable = null; - drawable.disposeGLEventListener(textRendererGLEL, true); - textRendererGLEL = null; screenshot.dispose(drawable.getGL()); disposeImpl(drawable, true); } @@ -766,21 +520,21 @@ public class MovieSimple implements GLEventListener { System.out.println("pD.1 "+mPlayer+", disposePlayer "+disposePlayer); final GL2ES2 gl = drawable.getGL().getGL2ES2(); + if( null != textRendererGLEL ) { + drawable.disposeGLEventListener(textRendererGLEL, true); + textRendererGLEL = null; + } if( disposePlayer ) { if(!mPlayerShared) { mPlayer.destroy(gl); + } else { + // mPlayer.stop(gl); } System.out.println("pD.X "+mPlayer); mPlayer=null; } - pmvMatrixUniform = null; - if(null != pmvMatrix) { - pmvMatrix=null; - } - if(null != st) { - st.destroy(gl); - st=null; - } + screen.dispose(drawable); + screen = null; } long lastPerfPos = 0; @@ -791,7 +545,9 @@ public class MovieSimple implements GLEventListener { if( swapIntervalSet ) { final int _swapInterval = swapInterval; gl.setSwapInterval(_swapInterval); // in case switching the drawable (impl. may bound attribute there) - drawable.getAnimator().resetFPSCounter(); + if( null != drawable.getAnimator() ) { + drawable.getAnimator().resetFPSCounter(); + } swapInterval = gl.getSwapInterval(); System.err.println("Swap Interval: "+_swapInterval+" -> "+swapInterval); swapIntervalSet = false; @@ -808,50 +564,10 @@ public class MovieSimple implements GLEventListener { final long currentPos = System.currentTimeMillis(); if( currentPos - lastPerfPos > 2000 ) { - System.err.println( mPlayer.getPerfString() ); + // System.err.println( mPlayer.getPerfString() ); lastPerfPos = currentPos; } - - 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 = ((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; - if(null!=mPlayer) { - final TextureSequence.TextureFrame texFrame; - if( mPlayerShared ) { - texFrame=mPlayer.getLastTexture(); - } else { - texFrame=mPlayer.getNextTexture(gl); - } - if(null != texFrame) { - tex = texFrame.getTexture(); - gl.glActiveTexture(GL.GL_TEXTURE0+mPlayer.getTextureUnit()); - tex.enable(gl); - tex.bind(gl); - } - } - gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4); - if(null != tex) { - tex.disable(gl); - } - interleavedVBO.enableBuffer(gl, false); - st.useProgram(gl, false); + screen.display(drawable); } static class MyGLMediaEventListener implements GLMediaEventListener { @@ -879,15 +595,16 @@ public class MovieSimple implements GLEventListener { window.setSurfaceSize(mp.getWidth(), mp.getHeight()); } // window.disposeGLEventListener(ms, false /* remove */ ); - ms.resetGLState(); + // ms.resetGLState(); } if( 0 != ( GLMediaEventListener.EVENT_CHANGE_INIT & event_mask ) ) { System.err.println("MovieSimple State: INIT"); // Use GLEventListener in all cases [A+V, V, A] - window.addGLEventListener(ms); final GLAnimatorControl anim = window.getAnimator(); anim.setUpdateFPSFrames(60, null); anim.resetFPSCounter(); + ms.resetGLState(); + /** * Kick off player w/o GLEventListener, i.e. for audio only. * @@ -928,7 +645,7 @@ public class MovieSimple implements GLEventListener { public void run() { mp.setPlaySpeed(1f); mp.seek(0); - mp.play(); + mp.resume(); } }.start(); } else { @@ -1100,10 +817,11 @@ public class MovieSimple implements GLEventListener { mss[i].mPlayer.attachObject(WINDOW_KEY, windows[i]); mss[i].mPlayer.addEventListener(myGLMediaEventListener); + anim.add(windows[i]); + windows[i].addGLEventListener(mss[i]); windows[i].setTitle("Player "+i); windows[i].setSize(width, height); windows[i].setVisible(true); - anim.add(windows[i]); final Uri streamLocN; if( 0 == i ) { @@ -1116,7 +834,7 @@ public class MovieSimple implements GLEventListener { } } System.err.println("Win #"+i+": stream "+streamLocN); - mss[i].initStream(streamLocN, vid, aid, textureCount); + mss[i].playStream(streamLocN, vid, aid, textureCount); } } diff --git a/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceCubeES2.java b/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceCubeES2.java index 6a7115143..26a26e3e1 100644 --- a/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceCubeES2.java +++ b/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceCubeES2.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 JogAmp Community. All rights reserved. + * Copyright 2012-2023 JogAmp Community. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: @@ -45,7 +45,6 @@ import com.jogamp.newt.event.MouseAdapter; import com.jogamp.newt.event.MouseEvent; import com.jogamp.newt.event.MouseListener; import com.jogamp.opengl.GLExtensions; -import com.jogamp.opengl.JoglVersion; import com.jogamp.opengl.util.GLArrayDataServer; import com.jogamp.opengl.util.PMVMatrix; import com.jogamp.opengl.util.glsl.ShaderCode; @@ -84,12 +83,15 @@ public class TextureSequenceCubeES2 implements GLEventListener { int ly = 0; boolean first = false; + @Override public void mousePressed(final MouseEvent e) { first = true; } + @Override public void mouseMoved(final MouseEvent e) { first = false; } + @Override public void mouseDragged(final MouseEvent e) { int width, height; final Object source = e.getSource(); @@ -143,6 +145,7 @@ public class TextureSequenceCubeES2 implements GLEventListener { ly = ny; } } + @Override public void mouseWheelMoved(final MouseEvent e) { // System.err.println("XXX "+e); if( !e.isShiftDown() ) { @@ -206,9 +209,9 @@ public class TextureSequenceCubeES2 implements GLEventListener { GLArrayDataServer interleavedVBO, cubeIndicesVBO; + @Override public void init(final GLAutoDrawable drawable) { final GL2ES2 gl = drawable.getGL().getGL2ES2(); - System.err.println(JoglVersion.getGLInfo(gl, null)); final TextureFrame frame = texSeq.getLastTexture(); if( null == frame ) { return; @@ -304,6 +307,7 @@ public class TextureSequenceCubeES2 implements GLEventListener { System.out.println(st); } + @Override public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { final GL2ES2 gl = drawable.getGL().getGL2ES2(); diff --git a/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceES2.java b/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceES2.java new file mode 100644 index 000000000..fd934cb1e --- /dev/null +++ b/src/demos/com/jogamp/opengl/demos/es2/TextureSequenceES2.java @@ -0,0 +1,373 @@ +/** + * Copyright 2012-2023 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.demos.es2; + +import java.nio.FloatBuffer; + +import com.jogamp.common.os.Platform; +import com.jogamp.opengl.GL; +import com.jogamp.opengl.GL2ES2; +import com.jogamp.opengl.GLAutoDrawable; +import com.jogamp.opengl.GLES2; +import com.jogamp.opengl.GLEventListener; +import com.jogamp.opengl.GLException; +import com.jogamp.opengl.GLExtensions; +import com.jogamp.opengl.GLUniformData; +import com.jogamp.opengl.fixedfunc.GLMatrixFunc; +import com.jogamp.opengl.util.GLArrayDataServer; +import com.jogamp.opengl.util.PMVMatrix; +import com.jogamp.opengl.util.glsl.ShaderCode; +import com.jogamp.opengl.util.glsl.ShaderProgram; +import com.jogamp.opengl.util.glsl.ShaderState; +import com.jogamp.opengl.util.texture.Texture; +import com.jogamp.opengl.util.texture.TextureCoords; +import com.jogamp.opengl.util.texture.TextureSequence; +import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame; + +/** + * Simple planar movie player w/ orthogonal 1:1 projection. + */ +public class TextureSequenceES2 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; + + private TextureSequence texSeq; + private final boolean texSeqShared; + private ShaderState st; + private PMVMatrix pmvMatrix; + private GLUniformData pmvMatrixUniform; + + private float zrot = 0f; + private final boolean orthoProjection; + private float nearPlaneNormalized; + private float zoom; + + private int effects = EFFECT_NORMAL; + private float alpha = 1.0f; + + private boolean mPlayerScaleOrig; + private float[] verts = null; + private GLArrayDataServer interleavedVBO; + + public TextureSequenceES2(final TextureSequence texSource, final boolean texSeqShared, final boolean orthoProjection, final float zoom0) throws IllegalStateException { + this.texSeq = texSource; + this.texSeqShared = texSeqShared; + this.orthoProjection = orthoProjection; + this.zoom = zoom0; + } + + public void setZoom(final float zoom) { this.zoom = zoom; } + public float getZoom() { return zoom; } + public void setZRotation(final float zrot) { this.zrot = zrot; } + public boolean hasEffect(final int e) { return 0 != ( effects & e ) ; } + public void setEffects(final int e) { effects = e; }; + public void setTransparency(final float alpha) { + this.effects |= EFFECT_TRANSPARENT; + this.alpha = alpha; + } + + private static final String shaderBasename = "texsequence_xxx"; + private static final String myTextureLookupName = "myTexture2D"; + + private void initShader(final GL2ES2 gl) { + // Create & Compile the shader objects + final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), + "shader", "shader/bin", shaderBasename, true); + final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), + "shader", "shader/bin", shaderBasename, true); + + 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()); + rsFp.addDefaultShaderPrecision(gl, rsFpPos); + + 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 + final ShaderProgram sp = new ShaderProgram(); + sp.add(rsVp); + sp.add(rsFp); + if(!sp.link(gl, System.err)) { + throw new GLException("Couldn't link program: "+sp); + } + + // Let's manage all our states using ShaderState. + st = new ShaderState(); + st.attachShaderProgram(gl, sp, false); + } + + @Override + public void init(final GLAutoDrawable drawable) { + if(null == texSeq) { + throw new InternalError("texSeq null"); + } + final GL2ES2 gl = drawable.getGL().getGL2ES2(); + final TextureFrame frame = texSeq.getLastTexture(); + if( null == frame ) { + return; + } + final Texture tex = frame.getTexture(); + + initShader(gl); + + // Push the 1st uniform down the path + st.useProgram(gl, true); + + final int[] viewPort = new int[] { 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight()}; + pmvMatrix = new PMVMatrix(); + 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); + } + if(!st.uniform(gl, new GLUniformData("mgl_ActiveTexture", texSeq.getTextureUnit()))) { + throw new GLException("Error setting mgl_ActiveTexture in shader: "+st); + } + + final float dWidth = drawable.getSurfaceWidth(); + final float dHeight = drawable.getSurfaceHeight(); + final float mWidth = tex.getImageWidth(); + final float mHeight = tex.getImageHeight(); + final 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; + } else { + xs = dWidth/2f; ys = xs / mAspect; // w>h + } + } else { + if(mPlayerScaleOrig && mWidth < dWidth && mHeight < dHeight) { + xs = mAspect * ( mWidth / dWidth ) ; ys = xs / mAspect ; + } else { + xs = mAspect; ys = 1f; // b>h + } + } + verts = new float[] { -1f*xs, -1f*ys, 0f, // LB + 1f*xs, 1f*ys, 0f // RT + }; + { + System.err.println("XXX0: pixel LB: "+verts[0]+", "+verts[1]+", "+verts[2]); + System.err.println("XXX0: pixel RT: "+verts[3]+", "+verts[4]+", "+verts[5]); + final float[] winLB = new float[3]; + final float[] winRT = new float[3]; + pmvMatrix.gluProject(verts[0], verts[1], verts[2], viewPort, 0, winLB, 0); + pmvMatrix.gluProject(verts[3], verts[4], verts[5], viewPort, 0, winRT, 0); + System.err.println("XXX0: win LB: "+winLB[0]+", "+winLB[1]+", "+winLB[2]); + System.err.println("XXX0: win RT: "+winRT[0]+", "+winRT[1]+", "+winRT[2]); + } + + 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); + } + updateInterleavedVBO(gl, tex); + + st.ownAttribute(interleavedVBO, true); + gl.glClearColor(0.3f, 0.3f, 0.3f, 0.3f); + + gl.glEnable(GL.GL_DEPTH_TEST); + + st.useProgram(gl, false); + + // Let's show the completed shader state .. + System.out.println("iVBO: "+interleavedVBO); + System.out.println(st); + } + + protected void updateInterleavedVBO(final GL gl, final Texture tex) { + final float ss = 1f, ts = 1f; // scale tex-coord + final boolean wasEnabled = interleavedVBO.enabled(); + interleavedVBO.seal(gl, false); + interleavedVBO.rewind(); + { + final FloatBuffer ib = (FloatBuffer)interleavedVBO.getBuffer(); + final TextureCoords tc = tex.getImageTexCoords(); + 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) ) { + 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); + } + 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); + } else { + ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha); + } + ib.put( tc.right() *ss); ib.put( tc.bottom() *ts); + + // left-top + ib.put(verts[0]); ib.put(verts[4]); ib.put(verts[2]); + 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]); + ib.put( 1); ib.put( 1); ib.put( 1); ib.put(alpha); + ib.put( tc.right() *ss); ib.put( tc.top() *ts); + } + interleavedVBO.seal(gl, true); + if( !wasEnabled ) { + interleavedVBO.enableBuffer(gl, false); + } + } + + @Override + public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) { + final GL2ES2 gl = drawable.getGL().getGL2ES2(); + + if(null != st) { + reshapePMV(width, height); + st.useProgram(gl, true); + st.uniform(gl, pmvMatrixUniform); + st.useProgram(gl, false); + } + + System.out.println("pR "+texSeq); + } + + private final float zNear = 1f; + private final float zFar = 10f; + + private void reshapePMV(final int width, final int height) { + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + pmvMatrix.glLoadIdentity(); + if(orthoProjection) { + final float fw = width / 2f; + final float fh = height/ 2f; + pmvMatrix.glOrthof(-fw, fw, -fh, fh, -1.0f, 1.0f); + nearPlaneNormalized = 0f; + } else { + pmvMatrix.gluPerspective(45.0f, (float)width / (float)height, zNear, zFar); + nearPlaneNormalized = 1f/(10f-1f); + } + System.err.println("XXX0: Perspective nearPlaneNormalized: "+nearPlaneNormalized); + + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + pmvMatrix.glLoadIdentity(); + pmvMatrix.glTranslatef(0, 0, zoom); + } + + @Override + public void dispose(final GLAutoDrawable drawable) { + if(null == texSeq) { return; } + disposeImpl(drawable, true); + } + private void disposeImpl(final GLAutoDrawable drawable, final boolean disposeTexSeq) { + if( disposeTexSeq ) { + texSeq = null; + } + pmvMatrixUniform = null; + pmvMatrix=null; + if(null != st) { + final GL2ES2 gl = drawable.getGL().getGL2ES2(); + st.destroy(gl); + st=null; + } + } + + @Override + public void display(final GLAutoDrawable drawable) { + if(null == texSeq) { return; } + final 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(zrot > 0f) { + pmvMatrix.glRotatef(zrot, 0, 0, 1); + } else { + zrot = 0; + } + st.uniform(gl, pmvMatrixUniform); + interleavedVBO.enableBuffer(gl, true); + Texture tex = null; + if(null!=texSeq) { + final TextureSequence.TextureFrame texFrame; + if( texSeqShared ) { + texFrame = texSeq.getLastTexture(); + } else { + texFrame = texSeq.getNextTexture(gl); + } + if(null != texFrame) { + tex = texFrame.getTexture(); + gl.glActiveTexture(GL.GL_TEXTURE0+texSeq.getTextureUnit()); + tex.enable(gl); + tex.bind(gl); + } + } + gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, 4); + if(null != tex) { + tex.disable(gl); + } + interleavedVBO.enableBuffer(gl, false); + st.useProgram(gl, false); + } +} diff --git a/src/demos/com/jogamp/opengl/demos/graph/TextRendererGLELBase.java b/src/demos/com/jogamp/opengl/demos/graph/TextRendererGLELBase.java index 61240e4a2..7ab5e6b8c 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/TextRendererGLELBase.java +++ b/src/demos/com/jogamp/opengl/demos/graph/TextRendererGLELBase.java @@ -133,6 +133,10 @@ public abstract class TextRendererGLELBase implements GLEventListener { public void setFlipVerticalInGLOrientation(final boolean v) { flipVerticalInGLOrientation=v; } public final RegionRenderer getRenderer() { return renderer; } public final TextRegionUtil getTextRenderUtil() { return textRenderUtil; } + public int[] getVBAASampleCount() { return this.vbaaSampleCount; } + + public PMVMatrix getMatrix() { return rs.getMatrix(); }; + public boolean isMatrixShared() { return !exclusivePMVMatrix; }; @Override public void init(final GLAutoDrawable drawable) { @@ -276,9 +280,9 @@ public abstract class TextRendererGLELBase implements GLEventListener { if( cacheRegion ) { textRenderUtil.drawString3D(gl, renderer, font, text, null, vbaaSampleCount); } else if( null != region ) { - TextRegionUtil.drawString3D(gl, region, renderer, font, text, null, vbaaSampleCount, tempT1, tempT1); + TextRegionUtil.drawString3D(gl, region, renderer, font, text, null, vbaaSampleCount, tempT1, tempT2); } else { - TextRegionUtil.drawString3D(gl, renderModes, renderer, font, text, null, vbaaSampleCount, tempT1, tempT1); + TextRegionUtil.drawString3D(gl, renderModes, renderer, font, text, null, vbaaSampleCount, tempT1, tempT2); } renderer.enable(gl, false); @@ -288,4 +292,47 @@ public abstract class TextRendererGLELBase implements GLEventListener { lastRow = row + newLineCount; } } + public void renderRegion(final GLAutoDrawable drawable, + final Font font, final float pixelSize, + final int column, final int row, + final float tx, final float ty, final float tz, final GLRegion region) { + if( null != renderer ) { + final GL2ES2 gl = drawable.getGL().getGL2ES2(); + + float dx = tx; + float dy; + + if( !exclusivePMVMatrix ) { + dy = 1f-ty; + } else { + final int height = drawable.getSurfaceHeight(); + dy = height-ty; + } + final float sxy = pixelScale * pixelSize; + final float lineHeight = font.getLineHeight(); + dx += sxy * font.getAdvanceWidth('X') * column; + dy -= sxy * lineHeight * ( row + 1 ); + + final PMVMatrix pmvMatrix = rs.getMatrix(); + pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + if( !exclusivePMVMatrix ) { + pmvMatrix.glPushMatrix(); + } else { + pmvMatrix.glLoadIdentity(); + } + pmvMatrix.glTranslatef(dx, dy, tz); + if( flipVerticalInGLOrientation && drawable.isGLOriented() ) { + pmvMatrix.glScalef(sxy, -1f*sxy, 1.0f); + } else { + pmvMatrix.glScalef(sxy, sxy, 1.0f); + } + renderer.enable(gl, true); + region.draw(gl, renderer, vbaaSampleCount); + renderer.enable(gl, false); + + if( !exclusivePMVMatrix ) { + pmvMatrix.glPopMatrix(); + } + } + } } diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneGLListener0A.java b/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneGLListener0A.java index 990143de8..c73cb7526 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneGLListener0A.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneGLListener0A.java @@ -585,7 +585,7 @@ public class GPUUISceneGLListener0A implements GLEventListener { mPlayer.setAudioVolume( mPlayerButton.isToggleOn() ? 1f : 0f ); } } ); buttons.add(mPlayerButton); - mPlayer.initStream(filmURL, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT); + mPlayer.playStream(filmURL, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT); } if( true ) { final ImageSequence imgSeq = new ImageSequence(texUnitImageButton, true); @@ -943,6 +943,7 @@ public class GPUUISceneGLListener0A implements GLEventListener { @Override public void mouseWheelMoved(final MouseEvent e) { final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment(); + /** final boolean isOnscreen = PointerClass.Onscreen == e.getPointerType(0).getPointerClass(); if( 0 == ( ~InputEvent.BUTTONALL_MASK & e.getModifiers() ) && !isOnscreen ) { // offscreen vertical mouse wheel zoom @@ -958,8 +959,14 @@ public class GPUUISceneGLListener0A implements GLEventListener { VectorUtil.scaleVec3(rot, rot, 2f); } shapeEvent.shape.getRotation().rotateByEuler( rot ); - } + } */ + final float[] rot = VectorUtil.scaleVec3(e.getRotation(), e.getRotation(), FloatUtil.PI / 180.0f); + // swap axis for onscreen rotation matching natural feel + final float tmp = rot[0]; rot[0] = rot[1]; rot[1] = tmp; + VectorUtil.scaleVec3(rot, rot, 2f); + shapeEvent.shape.getRotation().rotateByEuler( rot ); } + /** @Override public void gestureDetected(final GestureEvent e) { final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment(); @@ -969,5 +976,6 @@ public class GPUUISceneGLListener0A implements GLEventListener { System.err.println("Rotate.Zoom.G: "+tz); shapeEvent.shape.move(0f, 0f, tz); } - } }; + } */ + }; } diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneTextAnim01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneTextAnim01.java index 45bfd53f1..8658fdf4d 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneTextAnim01.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/GPUUISceneTextAnim01.java @@ -317,35 +317,5 @@ public class GPUUISceneTextAnim01 implements GLEventListener { actionText = String.format((Locale)null, "Pos %6.2f / %6.2f / %6.2f", tx[0], tx[1], tx[2]); } } - - @Override - public void mouseWheelMoved(final MouseEvent e) { - final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment(); - final boolean isOnscreen = PointerClass.Onscreen == e.getPointerType(0).getPointerClass(); - if( 0 == ( ~InputEvent.BUTTONALL_MASK & e.getModifiers() ) && !isOnscreen ) { - // offscreen vertical mouse wheel zoom - final float tz = 100f*e.getRotation()[1]; // vertical: wheel - System.err.println("Rotate.Zoom.W: "+tz); - shapeEvent.shape.move(0f, 0f, tz); - } else if( isOnscreen || e.isControlDown() ) { - final float[] rot = VectorUtil.scaleVec3(e.getRotation(), e.getRotation(), FloatUtil.PI / 180.0f); - if( isOnscreen ) { - System.err.println("XXX: "+e); - // swap axis for onscreen rotation matching natural feel - final float tmp = rot[0]; rot[0] = rot[1]; rot[1] = tmp; - VectorUtil.scaleVec3(rot, rot, 2f); - } - shapeEvent.shape.getRotation().rotateByEuler( rot ); - } - } - @Override - public void gestureDetected(final GestureEvent e) { - final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment(); - if( e instanceof PinchToZoomGesture.ZoomEvent ) { - final PinchToZoomGesture.ZoomEvent ze = (PinchToZoomGesture.ZoomEvent) e; - final float tz = ze.getDelta() * ze.getScale(); - System.err.println("Rotate.Zoom.G: "+tz); - shapeEvent.shape.move(0f, 0f, tz); - } - } }; + }; } |