JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
MovieCube.java
Go to the documentation of this file.
1/**
2 * Copyright 2012 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.opengl.demos.av;
30
31import java.io.File;
32import java.io.IOException;
33import java.net.URISyntaxException;
34
35import com.jogamp.opengl.GL2ES2;
36import com.jogamp.opengl.GLAnimatorControl;
37import com.jogamp.opengl.GLAutoDrawable;
38import com.jogamp.opengl.GLCapabilities;
39import com.jogamp.opengl.GLEventListener;
40import com.jogamp.opengl.GLException;
41import com.jogamp.opengl.GLProfile;
42import com.jogamp.opengl.GLRunnable;
43import com.jogamp.common.net.Uri;
44import com.jogamp.common.os.Clock;
45import com.jogamp.common.util.InterruptSource;
46import com.jogamp.graph.curve.Region;
47import com.jogamp.graph.curve.opengl.GLRegion;
48import com.jogamp.graph.curve.opengl.RegionRenderer;
49import com.jogamp.graph.font.Font;
50import com.jogamp.graph.font.FontScale;
51import com.jogamp.newt.Window;
52import com.jogamp.newt.event.KeyAdapter;
53import com.jogamp.newt.event.KeyEvent;
54import com.jogamp.newt.event.KeyListener;
55import com.jogamp.newt.event.WindowAdapter;
56import com.jogamp.newt.event.WindowEvent;
57import com.jogamp.newt.opengl.GLWindow;
58import com.jogamp.opengl.JoglVersion;
59import com.jogamp.opengl.demos.es2.TextureSequenceCubeES2;
60import com.jogamp.opengl.demos.graph.TextRendererGLELBase;
61import com.jogamp.opengl.demos.util.MiscUtils;
62import com.jogamp.opengl.util.Animator;
63import com.jogamp.opengl.util.GLReadBufferUtil;
64import com.jogamp.opengl.util.av.GLMediaPlayer;
65import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
66import com.jogamp.opengl.util.av.GLMediaPlayer.StreamException;
67import com.jogamp.opengl.util.av.GLMediaPlayerFactory;
68import com.jogamp.opengl.util.texture.TextureSequence.TextureFrame;
69
70/**
71 * Simple cube movie player w/ aspect ration true projection on a cube.
72 */
73public class MovieCube implements GLEventListener {
74 public static final float zoom_def = -2.77f;
75 private static boolean waitForKey = false;
76 private final float zoom0, rotx, roty;
77 private TextureSequenceCubeES2 cube=null;
78 private GLMediaPlayer mPlayer=null;
79 private int swapInterval = 1;
80 private boolean swapIntervalSet = true;
81 private long lastPerfPos = 0;
82 private volatile boolean resetGLState = false;
83 private volatile GLAutoDrawable autoDrawable = null;
84
85 /** Blender's Big Buck Bunny: 24f 416p H.264, AAC 48000 Hz, 2 ch, mpeg stream. */
86 public static final Uri defURI;
87 static {
88 Uri _defURI = null;
89 try {
90 // Blender's Big Buck Bunny Trailer: 24f 640p VP8, Vorbis 44100Hz mono, WebM/Matroska Stream.
91 // _defURI = new URI("http://video.webmfiles.org/big-buck-bunny_trailer.webm");
92 _defURI = Uri.cast("http://archive.org/download/BigBuckBunny_328/BigBuckBunny_512kb.mp4");
93 } catch (final URISyntaxException e) {
94 e.printStackTrace();
95 }
96 defURI = _defURI;
97 }
98
99 /**
100 * Default constructor which also issues {@link #playStream(URI, int, int, int, int)} w/ default values
101 * and polls until the {@link GLMediaPlayer} is {@link GLMediaPlayer.State#Initialized}.
102 * If {@link GLMediaEventListener#EVENT_CHANGE_EOS} is reached, the stream is started over again.
103 * <p>
104 * This default constructor is merely useful for some <i>drop-in</i> test, e.g. using an applet.
105 * </p>
106 */
107 public MovieCube() throws IOException, URISyntaxException {
108 this(zoom_def, 0f, 0f, true);
109
111 @Override
112 public void attributesChanged(final GLMediaPlayer mp, final GLMediaPlayer.EventMask eventMask, final long when) {
113 System.err.println("MovieCube.0 AttributesChanges: "+eventMask+", when "+when);
114 System.err.println("MovieCube.0 State: "+mp);
115 if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.Size) ) {
116 resetGLState();
117 }
118 if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.EOS) ) {
119 new InterruptSource.Thread() {
120 @Override
121 public void run() {
122 // loop for-ever ..
123 mPlayer.seek(0);
124 mPlayer.resume();
125 } }.start();
126 }
127 }
128 });
130 }
131
132 /**
133 * Custom constructor, user needs to issue {@link #playStream(URI, int, int, int, int)} afterwards.
134 */
135 public MovieCube(final float zoom0, final float rotx, final float roty, final boolean showText) throws IOException {
136 this.zoom0 = zoom0;
137 this.rotx = rotx;
138 this.roty = roty;
139 this.showText = showText;
140 screenshot = new GLReadBufferUtil(false, false);
142 }
143
144 public void playStream(final Uri streamLoc, final int vid, final int aid, final int textureCount) {
145 mPlayer.playStream(streamLoc, vid, aid, GLMediaPlayer.STREAM_ID_NONE, textureCount);
146 System.out.println("pC.1b "+mPlayer);
147 }
148
149 public void setSwapInterval(final int v) { this.swapInterval = v; }
150
151 public GLMediaPlayer getGLMediaPlayer() { return mPlayer; }
152
153 public void resetGLState() {
154 resetGLState = true;
155 }
156
157 private final class InfoTextRendererGLELBase extends TextRendererGLELBase {
158 private static final float z_diff = 0.001f;
159 private final Font font = getFont(0, 0, 0);
160 private final float fontSize1 = 12;
161 private final float fontSize2 = 10;
162 private final GLRegion regionFPS;
163 private float pixelSize1, pixelSize2, underlineSize;
164
165 InfoTextRendererGLELBase(final GLProfile glp, final int rmode) {
166 // FIXME: Graph TextRenderer does not AA well w/o MSAA and FBO
167 super(rmode, Region.DEFAULT_AA_SAMPLE_COUNT);
169 regionFPS = GLRegion.create(glp, renderModes, null, 0, 0);
170 System.err.println("RegionFPS "+Region.getRenderModeString(renderModes)+", sampleCount "+Region.DEFAULT_AA_SAMPLE_COUNT+", class "+regionFPS.getClass().getName());
171 staticRGBAColor[0] = 0.1f;
172 staticRGBAColor[1] = 0.1f;
173 staticRGBAColor[2] = 0.1f;
174 staticRGBAColor[3] = 1.0f;
175 }
176
177 @Override
178 public void init(final GLAutoDrawable drawable) {
179 // non-exclusive mode!
180 this.setSharedPMVMatrix(cube.pmvMatrix);
181 super.init(drawable);
182
183 autoDrawable = drawable;
184
185 pixelSize1 = FontScale.toPixels(fontSize1, dpiH);
186 pixelSize2 = FontScale.toPixels(fontSize2, dpiH);
187 pixelScale = 1.0f / ( pixelSize1 * 20f );
188 // underlineSize: 'underline' amount of pixel below 0/0 (Note: lineGap is negative)
189 final Font.Metrics metrics = font.getMetrics();
190 final float lineGap = pixelSize1 * metrics.getLineGap();
191 final float descent = pixelSize1 * metrics.getDescent();
192 underlineSize = lineGap - descent;
193 System.err.println("XXX: dpiH "+dpiH+", fontSize "+fontSize1+", pixelSize "+pixelSize1+", pixelScale "+pixelScale+", fLG "+lineGap+", fDesc "+descent+", underlineSize "+underlineSize);
194 }
195
196 @Override
197 public void dispose(final GLAutoDrawable drawable) {
198 autoDrawable = null;
199 screenshot.dispose(drawable.getGL());
200 if( null != regionFPS ) {
201 regionFPS.destroy(drawable.getGL().getGL2ES2());
202 }
203 super.dispose(drawable);
204 }
205
206 String text1_old = null;
207
208 @Override
209 public void display(final GLAutoDrawable drawable) {
210 final GLAnimatorControl anim = drawable.getAnimator();
211 final float lfps = null != anim ? anim.getLastFPS() : 0f;
212 final float tfps = null != anim ? anim.getTotalFPS() : 0f;
213 final float pts = mPlayer.getPTS().getCurrent() / 1000f;
214
215 // Note: MODELVIEW is from [ -1 .. 1 ]
216
217 // dy: position right above video rectangle (bottom text line)
218 final float aspect = (float)mPlayer.getWidth() / (float)mPlayer.getHeight();
219 final float aspect_h = 1f/aspect;
220 final float dy = 1f-aspect_h;
221
222 // yoff1: position right above video rectangle (bottom text line)
223 // less than underlineSize, so 'underline' pixels are above video.
224 final float yoff1 = dy-(pixelScale*underlineSize);
225
226 // yoff2: position right below video rectangle (bottom text line)
227 final float yoff2 = 2f-dy;
228
229 /**
230 System.err.println("XXX: a "+aspect+", aspect_h "+aspect_h+", dy "+dy+
231 "; underlineSize "+underlineSize+" "+(pixelScale*underlineSize)+
232 "; yoff "+yoff1+", yoff2 "+yoff2); */
233
234 final GL2ES2 gl = drawable.getGL().getGL2ES2();
235 final String ptsPrec = null != regionFPS ? "3.1" : "3.0";
236 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",
237 pts, mPlayer.getDuration() / 1000f,
238 mPlayer.getState().toString().toLowerCase(), mPlayer.getPlaySpeed(), mPlayer.getAudioVolume(),
239 aspect, mPlayer.getFramerate(), lfps, tfps, drawable.getGL().getSwapInterval());
240 final String text2 = String.format("audio: id %d, kbps %d, codec %s",
241 mPlayer.getAID(), mPlayer.getAudioBitrate()/1000, mPlayer.getAudioCodec());
242 final String text3 = String.format("video: id %d, kbps %d, codec %s",
243 mPlayer.getVID(), mPlayer.getVideoBitrate()/1000, mPlayer.getVideoCodec());
244 final String text4 = mPlayer.getUri().path.decode();
245 if( displayOSD && null != renderer ) {
246 gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
247 if( !text1.equals(text1_old) ) {
248 renderString(drawable, font, pixelSize1, text1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, regionFPS.clear(gl)); // clear-cache
249 text1_old = text1;
250 } else {
251 renderRegion(drawable, font, pixelSize1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, regionFPS);
252 }
253 renderString(drawable, font, pixelSize2, text2, 1 /* col */, 0 /* row */, -1+z_diff, yoff2, 1f+z_diff, true);
254 renderString(drawable, font, pixelSize2, text3, 1 /* col */, 1 /* row */, -1+z_diff, yoff2, 1f+z_diff, true);
255 renderString(drawable, font, pixelSize2, text4, 1 /* col */, 2 /* row */, -1+z_diff, yoff2, 1f+z_diff, true);
256 }
257 } };
258 private InfoTextRendererGLELBase textRendererGLEL = null;
259 final boolean showText;
260 private boolean displayOSD = true;
261
262 public void printScreen(final GLAutoDrawable drawable) throws GLException, IOException {
263 final String filename = String.format("MovieCube-snap%02d-%03dx%03d.png", screenshot_num++, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
264 if(screenshot.readPixels(drawable.getGL(), false)) {
265 screenshot.write(new File(filename.toString()));
266 }
267 }
268 private final GLReadBufferUtil screenshot;
269 private int screenshot_num = 0;
270
271 public void printScreenOnGLThread(final GLAutoDrawable drawable) {
272 drawable.invoke(false, new GLRunnable() {
273 @Override
274 public boolean run(final GLAutoDrawable drawable) {
275 try {
276 printScreen(drawable);
277 } catch (final GLException e) {
278 e.printStackTrace();
279 } catch (final IOException e) {
280 e.printStackTrace();
281 }
282 return true;
283 }
284 });
285 }
286
287 private final KeyListener keyAction = new KeyAdapter() {
288 @Override
289 public void keyReleased(final KeyEvent e) {
290 if( e.isAutoRepeat() ) {
291 return;
292 }
293 System.err.println("MC "+e);
294 final int pts0 = mPlayer.getPTS().getCurrent();
295
296 int pts1 = 0;
297 switch(e.getKeySymbol()) {
298 case KeyEvent.VK_V: {
299 switch(swapInterval) {
300 case 0: swapInterval = -1; break;
301 case -1: swapInterval = 1; break;
302 case 1: swapInterval = 0; break;
303 default: swapInterval = 1; break;
304 }
305 swapIntervalSet = true;
306 break;
307 }
308 case KeyEvent.VK_O: displayOSD = !displayOSD; break;
309 case KeyEvent.VK_RIGHT: pts1 = pts0 + 1000; break;
310 case KeyEvent.VK_UP: pts1 = pts0 + 10000; break;
311 case KeyEvent.VK_PAGE_UP: pts1 = pts0 + 30000; break;
312 case KeyEvent.VK_LEFT: pts1 = pts0 - 1000; break;
313 case KeyEvent.VK_DOWN: pts1 = pts0 - 10000; break;
314 case KeyEvent.VK_PAGE_DOWN: pts1 = pts0 - 30000; break;
315 case KeyEvent.VK_HOME:
316 case KeyEvent.VK_BACK_SPACE: {
317 mPlayer.seek(0);
318 break;
319 }
320 case KeyEvent.VK_SPACE: {
321 if( GLMediaPlayer.State.Paused == mPlayer.getState() ) {
322 mPlayer.resume();
323 } else if(GLMediaPlayer.State.Uninitialized == mPlayer.getState()) {
324 playStream(mPlayer.getUri(), GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, 3 /* textureCount */);
325 } else if( e.isShiftDown() ) {
326 mPlayer.stop();
327 } else {
328 mPlayer.pause(false);
329 }
330 break;
331 }
332 case KeyEvent.VK_MULTIPLY:
333 mPlayer.setPlaySpeed(1.0f);
334 break;
335 case KeyEvent.VK_SUBTRACT: {
336 float playSpeed = mPlayer.getPlaySpeed();
337 if( e.isShiftDown() ) {
338 playSpeed /= 2.0f;
339 } else {
340 playSpeed -= 0.1f;
341 }
342 mPlayer.setPlaySpeed(playSpeed);
343 } break;
344 case KeyEvent.VK_ADD: {
345 float playSpeed = mPlayer.getPlaySpeed();
346 if( e.isShiftDown() ) {
347 playSpeed *= 2.0f;
348 } else {
349 playSpeed += 0.1f;
350 }
351 mPlayer.setPlaySpeed(playSpeed);
352 } break;
353 case KeyEvent.VK_M: {
354 float audioVolume = mPlayer.getAudioVolume();
355 if( audioVolume > 0.5f ) {
356 audioVolume = 0f;
357 } else {
358 audioVolume = 1f;
359 }
360 mPlayer.setAudioVolume(audioVolume);
361 } break;
362 case KeyEvent.VK_S:
363 if(null != autoDrawable) {
364 printScreenOnGLThread(autoDrawable);
365 }
366 break;
367 case KeyEvent.VK_F4:
368 case KeyEvent.VK_ESCAPE:
369 case KeyEvent.VK_Q:
370 if(null != autoDrawable) {
371 MiscUtils.destroyWindow(autoDrawable);
372 }
373 break;
374 }
375
376 if( 0 != pts1 ) {
377 mPlayer.seek(pts1);
378 }
379 }
380 };
381
382 @Override
383 public void init(final GLAutoDrawable drawable) {
384 if(null == mPlayer) {
385 throw new InternalError("mPlayer null");
386 }
387 // final boolean hasVideo = GLMediaPlayer.STREAM_ID_NONE != mPlayer.getVID();
388 resetGLState = false;
389
390 final GL2ES2 gl = drawable.getGL().getGL2ES2();
391 System.err.println(JoglVersion.getGLInfo(gl, null));
392
393 cube = new TextureSequenceCubeES2(mPlayer, false, zoom0, rotx, roty);
394
395 if(waitForKey) {
396 MiscUtils.waitForKey("Init>");
397 }
398
399 try {
400 mPlayer.initGL(gl);
401 } catch (final Exception e) {
402 e.printStackTrace();
403 if(null != mPlayer) {
404 mPlayer.destroy(gl);
405 mPlayer = null;
406 }
407 throw new GLException(e);
408 }
409 cube.init(drawable);
410 mPlayer.resume();
411 System.out.println("play.0 "+mPlayer);
412
413 boolean added;
414 final Object upstreamWidget = drawable.getUpstreamWidget();
415 if (upstreamWidget instanceof Window) {
416 final Window window = (Window) upstreamWidget;
417 window.addKeyListener(keyAction);
418 added = true;
419 } else { added = false; }
420 System.err.println("MC.init: kl-added "+added+", "+drawable.getClass().getName());
421
422 if( showText ) {
423 final int rmode = drawable.getChosenGLCapabilities().getSampleBuffers() ? 0 : Region.VBAA_RENDERING_BIT;
424 textRendererGLEL = new InfoTextRendererGLELBase(gl.getGLProfile(), rmode);
425 drawable.addGLEventListener(textRendererGLEL);
426 }
427 }
428
429 @Override
430 public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
431 if(null == mPlayer) { return; }
432 cube.reshape(drawable, x, y, width, height);
433 }
434
435 @Override
436 public void dispose(final GLAutoDrawable drawable) {
437 System.err.println(Thread.currentThread()+" MovieCube.dispose ... ");
438 disposeImpl(drawable, true);
439 }
440
441 private void disposeImpl(final GLAutoDrawable drawable, final boolean disposePlayer) {
442 if(null == mPlayer) { return; }
443 final Object upstreamWidget = drawable.getUpstreamWidget();
444 if (upstreamWidget instanceof Window) {
445 final Window window = (Window) upstreamWidget;
446 window.removeKeyListener(keyAction);
447 }
448 final GL2ES2 gl = drawable.getGL().getGL2ES2();
449 if( null != textRendererGLEL ) {
450 drawable.disposeGLEventListener(textRendererGLEL, true);
451 textRendererGLEL = null;
452 }
453 if( disposePlayer ) {
454 mPlayer.destroy(gl);
455 mPlayer=null;
456 }
457 cube.dispose(drawable);
458 cube=null;
459 }
460
461
462 @Override
463 public void display(final GLAutoDrawable drawable) {
464 if( swapIntervalSet ) {
465 final GL2ES2 gl = drawable.getGL().getGL2ES2();
466 final int _swapInterval = swapInterval;
467 gl.setSwapInterval(_swapInterval); // in case switching the drawable (impl. may bound attribute there)
468 drawable.getAnimator().resetFPSCounter();
469 swapInterval = gl.getSwapInterval();
470 System.err.println("Swap Interval: "+_swapInterval+" -> "+swapInterval);
471 swapIntervalSet = false;
472 }
473 if(null == mPlayer) { return; }
474
475 if( resetGLState ) {
476 resetGLState = false;
477 System.err.println("XXX resetGLState");
478 disposeImpl(drawable, false);
479 init(drawable);
480 reshape(drawable, 0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
481 }
482
483 final long currentPos = System.currentTimeMillis();
484 if( currentPos - lastPerfPos > 2000 ) {
485 // System.err.println( mPlayer.getPerfString() );
486 lastPerfPos = currentPos;
487 }
488 cube.display(drawable);
489 }
490
491 public static void main(final String[] args) throws IOException, InterruptedException, URISyntaxException {
492 int swapInterval = 1;
493 int width = 800;
494 int height = 600;
495 int textureCount = GLMediaPlayer.TEXTURE_COUNT_DEFAULT; // default - threaded
496
497 boolean forceES2 = false;
498 boolean forceES3 = false;
499 boolean forceGL3 = false;
500 boolean forceGLDef = false;
503 final boolean origSize;
504
505 String url_s=null;
506 final String file_s=null;
507 {
508 boolean _origSize = false;
509 for(int i=0; i<args.length; i++) {
510 if(args[i].equals("-vid")) {
511 i++;
512 vid = MiscUtils.atoi(args[i], vid);
513 } else if(args[i].equals("-aid")) {
514 i++;
515 aid = MiscUtils.atoi(args[i], aid);
516 } else if(args[i].equals("-width")) {
517 i++;
518 width = MiscUtils.atoi(args[i], width);
519 } else if(args[i].equals("-height")) {
520 i++;
521 height = MiscUtils.atoi(args[i], height);
522 } else if(args[i].equals("-osize")) {
523 _origSize = true;
524 } else if(args[i].equals("-textureCount")) {
525 i++;
526 textureCount = MiscUtils.atoi(args[i], textureCount);
527 } else if(args[i].equals("-url")) {
528 i++;
529 url_s = args[i];
530 } else if(args[i].equals("-es2")) {
531 forceES2 = true;
532 } else if(args[i].equals("-es3")) {
533 forceES3 = true;
534 } else if(args[i].equals("-gl3")) {
535 forceGL3 = true;
536 } else if(args[i].equals("-gldef")) {
537 forceGLDef = true;
538 } else if(args[i].equals("-vsync")) {
539 i++;
540 swapInterval = MiscUtils.atoi(args[i], swapInterval);
541 } else if(args[i].equals("-wait")) {
542 waitForKey = true;
543 }
544 }
545 origSize = _origSize;
546 }
547 Uri streamLoc = null;
548 if( null != url_s ) {
549 streamLoc = Uri.tryUriOrFile( url_s );
550 }
551 if( null == streamLoc ) {
552 streamLoc = defURI;
553 }
554 System.err.println("url_s "+url_s);
555 System.err.println("stream "+streamLoc);
556 System.err.println("vid "+vid+", aid "+aid);
557 System.err.println("textureCount "+textureCount);
558 System.err.println("forceES2 "+forceES2);
559 System.err.println("forceES3 "+forceES3);
560 System.err.println("forceGL3 "+forceGL3);
561 System.err.println("forceGLDef "+forceGLDef);
562 System.err.println("swapInterval "+swapInterval);
563
564 final MovieCube mc = new MovieCube(zoom_def, 0f, 0f, true);
565 mc.setSwapInterval(swapInterval);
566
567 final GLProfile glp;
568 if(forceGLDef) {
569 glp = GLProfile.getDefault();
570 } else if(forceGL3) {
571 glp = GLProfile.get(GLProfile.GL3);
572 } else if(forceES3) {
574 } else if(forceES2) {
576 } else {
577 glp = GLProfile.getGL2ES2();
578 }
579 System.err.println("GLProfile: "+glp);
580 final GLCapabilities caps = new GLCapabilities(glp);
581 // caps.setAlphaBits(4); // NOTE_ALPHA_BLENDING: We go w/o alpha and blending!
582 final GLWindow window = GLWindow.create(caps);
583 final Animator anim = new Animator(window);
584 window.addWindowListener(new WindowAdapter() {
585 @Override
586 public void windowDestroyed(final WindowEvent e) {
587 anim.stop();
588 }
589 });
590 window.addGLEventListener(mc);
591 window.setSize(width, height);
592 window.setVisible(true);
593 System.err.println("Chosen: "+window.getChosenGLCapabilities());
594 anim.start();
595
596 mc.mPlayer.addEventListener(new GLMediaEventListener() {
597 @Override
598 public void attributesChanged(final GLMediaPlayer mp, final GLMediaPlayer.EventMask event_mask, final long when) {
599 System.err.println("MovieCube.1 AttributesChanges: events_mask "+event_mask+", when "+when);
600 System.err.println("MovieCube.1 State: "+mp);
601 if( event_mask.isSet(GLMediaPlayer.EventMask.Bit.Size) ) {
602 if( origSize ) {
603 window.setSurfaceSize(mp.getWidth(), mp.getHeight());
604 }
605 // window.disposeGLEventListener(ms, false /* remove */ );
606 }
607 if( event_mask.isSet(GLMediaPlayer.EventMask.Bit.Init) ) {
608 anim.setUpdateFPSFrames(60, null);
609 anim.resetFPSCounter();
610 mc.resetGLState();
611 } else if( event_mask.isSet(GLMediaPlayer.EventMask.Bit.Play) ) {
612 anim.resetFPSCounter();
613 }
614 if( event_mask.isSet(GLMediaPlayer.EventMask.Bit.EOS) ) {
615 new InterruptSource.Thread() {
616 @Override
617 public void run() {
618 // loop for-ever ..
619 mc.mPlayer.seek(0);
620 mc.mPlayer.resume();
621 } }.start();
622 }
623 if( event_mask.isSet(GLMediaPlayer.EventMask.Bit.Error) ) {
624 final StreamException se = mc.mPlayer.getStreamException();
625 if( null != se ) {
626 se.printStackTrace();
627 }
628 new InterruptSource.Thread( () -> { window.destroy(); } ).start();
629 }
630 }
631 });
632 mc.playStream(streamLoc, vid, aid, textureCount);
633 }
634}
635
Abstract Outline shape representation define the method an OutlineShape(s) is bound and rendered.
Definition: Region.java:62
static String getRenderModeString(final int renderModes)
Returns a unique technical description string for renderModes as follows:
Definition: Region.java:251
static final int DEFAULT_AA_SAMPLE_COUNT
Default pass2 AA sample count {@value} for Graph Region AA render-modes: VBAA_RENDERING_BIT or Region...
Definition: Region.java:177
static final int VBAA_RENDERING_BIT
Rendering-Mode bit for Region.
Definition: Region.java:115
A GLRegion is the OGL binding of one or more OutlineShapes Defined by its vertices and generated tria...
Definition: GLRegion.java:70
final GLRegion clear(final GL2ES2 gl)
Clears all buffers, i.e.
Definition: GLRegion.java:436
final void destroy(final GL2ES2 gl)
Delete and clear the associated OGL objects.
Definition: GLRegion.java:460
static GLRegion create(final GLProfile glp, int renderModes, final TextureSequence colorTexSeq, final int pass2TexUnit, final int initialVerticesCount, final int initialIndicesCount)
Create a GLRegion using the passed render mode.
Definition: GLRegion.java:109
static final GLCallback defaultBlendDisable
Default GL#GL_BLEND disable GLCallback, simply turning-off the GL#GL_BLEND state and turning-on depth...
static final GLCallback defaultBlendEnable
Default GL#GL_BLEND enable GLCallback, turning-off depth writing via GL#glDepthMask(boolean) if Rende...
final boolean isShiftDown()
getModifiers() contains SHIFT_MASK.
final boolean isAutoRepeat()
getModifiers() contains AUTOREPEAT_MASK.
final short getKeySymbol()
Returns the virtual key symbol reflecting the current keyboard layout.
Definition: KeyEvent.java:176
NEWT Window events are provided for notification purposes ONLY.
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
final void setSize(final int width, final int height)
Sets the size of the window's client area in window units, excluding decorations.
Definition: GLWindow.java:625
final void setVisible(final boolean visible)
Calls setVisible(true, visible), i.e.
Definition: GLWindow.java:615
final void setSurfaceSize(final int pixelWidth, final int pixelHeight)
Sets the size of the window's surface in pixel units which claims the window's client area excluding ...
Definition: GLWindow.java:629
final void addWindowListener(final WindowListener l)
Appends the given com.jogamp.newt.event.WindowListener to the end of the list.
Definition: GLWindow.java:882
final void destroy()
Destroys all resources associated with this GLAutoDrawable, inclusive the GLContext.
Definition: GLWindow.java:605
static GLWindow create(final GLCapabilitiesImmutable caps)
Creates a new GLWindow attaching a new Window referencing a new default Screen and default Display wi...
Definition: GLWindow.java:169
Specifies a set of OpenGL capabilities.
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static final String GLES3
The embedded OpenGL profile ES 3.x, with x >= 0.
Definition: GLProfile.java:588
static final String GL3
The desktop OpenGL core profile 3.x, with x >= 1.
Definition: GLProfile.java:576
static final String GLES2
The embedded OpenGL profile ES 2.x, with x >= 0.
Definition: GLProfile.java:585
static GLProfile getDefault(final AbstractGraphicsDevice device)
Returns a default GLProfile object, reflecting the best for the running platform.
Definition: GLProfile.java:739
static GLProfile get(final AbstractGraphicsDevice device, String profile)
Returns a GLProfile object.
static GLProfile getGL2ES2(final AbstractGraphicsDevice device)
Returns the GL2ES2 profile implementation, hence compatible w/ GL2ES2.
Definition: GLProfile.java:913
static StringBuilder getGLInfo(final GL gl, final StringBuilder sb)
Simple cube movie player w/ aspect ration true projection on a cube.
Definition: MovieCube.java:73
void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height)
Called by the drawable during the first repaint after the component has been resized.
Definition: MovieCube.java:430
MovieCube(final float zoom0, final float rotx, final float roty, final boolean showText)
Custom constructor, user needs to issue playStream(URI, int, int, int, int) afterwards.
Definition: MovieCube.java:135
static void main(final String[] args)
Definition: MovieCube.java:491
void dispose(final GLAutoDrawable drawable)
Notifies the listener to perform the release of all OpenGL resources per GLContext,...
Definition: MovieCube.java:436
static final Uri defURI
Blender's Big Buck Bunny: 24f 416p H.264, AAC 48000 Hz, 2 ch, mpeg stream.
Definition: MovieCube.java:86
void printScreen(final GLAutoDrawable drawable)
Definition: MovieCube.java:262
void display(final GLAutoDrawable drawable)
Called by the drawable to initiate OpenGL rendering by the client.
Definition: MovieCube.java:463
MovieCube()
Default constructor which also issues playStream(URI, int, int, int, int) w/ default values and polls...
Definition: MovieCube.java:107
void playStream(final Uri streamLoc, final int vid, final int aid, final int textureCount)
Definition: MovieCube.java:144
void printScreenOnGLThread(final GLAutoDrawable drawable)
Definition: MovieCube.java:271
void init(final GLAutoDrawable drawable)
Called by the drawable immediately after the OpenGL context is initialized.
Definition: MovieCube.java:383
void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height)
Called by the drawable during the first repaint after the component has been resized.
void dispose(final GLAutoDrawable drawable)
Notifies the listener to perform the release of all OpenGL resources per GLContext,...
void display(final GLAutoDrawable drawable)
Called by the drawable to initiate OpenGL rendering by the client.
void init(final GLAutoDrawable drawable)
Called by the drawable immediately after the OpenGL context is initialized.
void renderString(final GLAutoDrawable drawable, final Font font, final float pixelSize, final CharSequence text, final int column, final float tx, final float ty, final float tz, final boolean cacheRegion)
static void waitForKey(final String preMessage)
Definition: MiscUtils.java:167
static int atoi(final String str, final int def)
Definition: MiscUtils.java:60
final void resetFPSCounter()
Reset all performance counter (startTime, currentTime, frame number)
final void setUpdateFPSFrames(final int frames, final PrintStream out)
final synchronized boolean start()
Starts this animator, if not running.
Definition: Animator.java:344
final synchronized boolean stop()
Stops this animator.
Definition: Animator.java:368
Utility to read out the current FB to TextureData, optionally writing the data back to a texture obje...
void write(final File dest)
Write the TextureData filled by readPixels(GLAutoDrawable, boolean) to file.
boolean readPixels(final GL gl, final boolean mustFlipVertically)
Read the drawable's pixels to TextureData and Texture, if requested at construction.
A StreamException encapsulates a caught exception in the decoder thread, a.k.a StreamWorker,...
Size
TextureFrame size or vertical flip change.
float getLineGap()
Typographic line gap, a positive value.
Interface wrapper for font implementation.
Definition: Font.java:60
Specifying NEWT's Window functionality:
Definition: Window.java:115
void addKeyListener(KeyListener l)
Appends the given com.jogamp.newt.event.KeyListener to the end of the list.
Listener for KeyEvents.
void resetFPSCounter()
Reset all performance counter (startTime, currentTime, frame number)
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
boolean invoke(boolean wait, GLRunnable glRunnable)
Enqueues a one-shot GLRunnable, which will be executed within the next display() call after all regis...
GLAnimatorControl getAnimator()
GLEventListener disposeGLEventListener(GLEventListener listener, boolean remove)
Disposes the given listener via dispose(..) if it has been initialized and added to this queue.
GL getGL()
Returns the GL pipeline object this GLAutoDrawable uses.
Object getUpstreamWidget()
Method may return the upstream UI toolkit object holding this GLAutoDrawable instance,...
void addGLEventListener(GLEventListener listener)
Adds the given listener to the end of this drawable queue.
GL2ES2 getGL2ES2()
Casts this object to the GL2ES2 interface.
GLProfile getGLProfile()
Returns the GLProfile associated with this GL object.
void setSwapInterval(int interval)
Set the swap interval of the current context and attached onscreen GLDrawable.
int getSwapInterval()
Return the current swap interval.
boolean getSampleBuffers()
Returns whether sample buffers for full-scene antialiasing (FSAA) should be allocated for this drawab...
GLCapabilitiesImmutable getChosenGLCapabilities()
Fetches the GLCapabilitiesImmutable corresponding to the chosen OpenGL capabilities (pixel format / v...
int getSurfaceWidth()
Returns the width of this GLDrawable's surface client area in pixel units.
int getSurfaceHeight()
Returns the height of this GLDrawable's surface client area in pixel units.
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.
As the contract of GLMediaFrameListener and TexSeqEventListener requests, implementations of GLMediaE...
GLMediaPlayer interface specifies a TextureSequence state machine using a multiplexed audio/video str...
State pause(boolean flush)
Pauses the StreamWorker decoding thread.
int getVID()
Return the video stream id, see audio and video Stream IDs.
float getAudioVolume()
Returns the audio volume.
int getDuration()
Return total duration of stream in msec.
int getWidth()
Returns the width of the video.
State destroy(GL gl)
Releases the GL, stream and other resources, including attached user objects.
boolean setAudioVolume(float v)
Sets the audio volume, [0f..1f].
static final int STREAM_ID_NONE
Constant {@value} for mute or not available.
void initGL(GL gl)
Initializes OpenGL related resources.
float getPlaySpeed()
Returns the playback speed.
Uri getUri()
Return the stream location, as set by playStream(Uri, int, int, int, int).
static final int TEXTURE_COUNT_DEFAULT
Default texture count, value {@value}.
boolean setPlaySpeed(float rate)
Sets the playback speed.
void playStream(Uri streamLoc, int vid, int aid, int sid, int textureCount)
Issues asynchronous stream initialization.
int getHeight()
Returns the height of the video.
void addEventListener(GLMediaEventListener l)
Adds a GLMediaEventListener to this player.
StreamException getStreamException()
Returns the StreamException caught in the decoder thread, or null if none occured.
int getAID()
Return the audio stream id, see audio and video Stream IDs.
int getAudioBitrate()
Warning: Optional information, may not be supported by implementation.
float getFramerate()
Warning: Optional information, may not be supported by implementation.
int seek(int msec)
Seeks to the new absolute position.
String getVideoCodec()
Warning: Optional information, may not be supported by implementation.
State resume()
Starts or resumes the StreamWorker decoding thread.
int getVideoBitrate()
Warning: Optional information, may not be supported by implementation.
PTS getPTS()
Returns current System Clock Reference (SCR) presentation timestamp (PTS).
static final int STREAM_ID_AUTO
Constant {@value} for auto or unspecified.
State stop()
Stops streaming and releases the GL, stream and other resources, but keeps attached user objects.
String getAudioCodec()
Warning: Optional information, may not be supported by implementation.