JOGL v2.6.0-rc-20250722
JOGL, High-Performance Graphics Binding for Java™ (public API).
UISceneDemo20.java
Go to the documentation of this file.
1/**
2 * Copyright 2010-2024 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 */
28package com.jogamp.opengl.demos.graph.ui;
29
30import java.io.File;
31import java.io.IOException;
32import java.net.URISyntaxException;
33import java.util.ArrayList;
34import java.util.Arrays;
35import java.util.List;
36import java.util.Locale;
37
38import com.jogamp.common.av.AudioSink;
39import com.jogamp.common.net.Uri;
40import com.jogamp.common.util.IOUtil;
41import com.jogamp.common.util.VersionUtil;
42import com.jogamp.graph.curve.Region;
43import com.jogamp.graph.curve.opengl.RegionRenderer;
44import com.jogamp.graph.curve.opengl.RenderState;
45import com.jogamp.graph.font.Font;
46import com.jogamp.graph.font.FontFactory;
47import com.jogamp.graph.font.FontScale;
48import com.jogamp.graph.ui.GraphShape;
49import com.jogamp.graph.ui.Group;
50import com.jogamp.graph.ui.Scene;
51import com.jogamp.graph.ui.Shape;
52import com.jogamp.graph.ui.layout.Alignment;
53import com.jogamp.graph.ui.layout.Gap;
54import com.jogamp.graph.ui.layout.GridLayout;
55import com.jogamp.graph.ui.shapes.Button;
56import com.jogamp.graph.ui.shapes.GLButton;
57import com.jogamp.graph.ui.shapes.ImageButton;
58import com.jogamp.graph.ui.shapes.Label;
59import com.jogamp.graph.ui.shapes.MediaButton;
60import com.jogamp.math.FloatUtil;
61import com.jogamp.math.Vec2f;
62import com.jogamp.math.Vec3f;
63import com.jogamp.math.geom.AABBox;
64import com.jogamp.math.util.PMVMatrix4f;
65import com.jogamp.graph.ui.shapes.BaseButton;
66import com.jogamp.nativewindow.ScalableSurface;
67import com.jogamp.newt.Display;
68import com.jogamp.newt.MonitorDevice;
69import com.jogamp.newt.NewtFactory;
70import com.jogamp.newt.Screen;
71import com.jogamp.newt.Window;
72import com.jogamp.newt.event.MouseEvent;
73import com.jogamp.newt.event.WindowAdapter;
74import com.jogamp.newt.event.WindowEvent;
75import com.jogamp.newt.opengl.GLWindow;
76import com.jogamp.openal.sound3d.AudioSystem3D;
77import com.jogamp.openal.util.ALAudioSink;
78import com.jogamp.openal.util.SimpleSineSynth;
79import com.jogamp.opengl.GL;
80import com.jogamp.opengl.GL2ES2;
81import com.jogamp.opengl.GLAnimatorControl;
82import com.jogamp.opengl.GLAutoDrawable;
83import com.jogamp.opengl.GLCapabilities;
84import com.jogamp.opengl.GLEventListener;
85import com.jogamp.opengl.GLPipelineFactory;
86import com.jogamp.opengl.GLRunnable;
87import com.jogamp.opengl.JoglVersion;
88import com.jogamp.opengl.demos.es2.GearsES2;
89import com.jogamp.opengl.demos.graph.FontSetDemos;
90import com.jogamp.opengl.demos.graph.MSAATool;
91import com.jogamp.opengl.demos.util.CommandlineOptions;
92import com.jogamp.opengl.demos.util.MiscUtils;
93import com.jogamp.opengl.util.Animator;
94import com.jogamp.opengl.util.av.GLMediaPlayer;
95import com.jogamp.opengl.util.av.GLMediaPlayer.EventMask;
96import com.jogamp.opengl.util.av.GLMediaPlayer.GLMediaEventListener;
97import com.jogamp.opengl.util.av.GLMediaPlayerFactory;
98import com.jogamp.opengl.util.caps.NonFSAAGLCapsChooser;
99import com.jogamp.opengl.util.texture.ImageSequence;
100import com.jogamp.opengl.util.texture.TextureIO;
101
102import jogamp.graph.ui.TreeTool;
103
104/**
105 * Complex interactive GraphUI Scene demo with different Button and Label Shapes layout on the screen.
106 * <p>
107 * This demo uses sets up an own {@link Scene.PMVMatrixSetup}, {@link MyPMVMatrixSetup},
108 * with a plane origin bottom-left and keeping the perspective non-normalized object screen dimension of < 1.
109 * </p>
110 * <p>
111 * Unlike {@link UISceneDemo00}, the {@link Scene}'s {@link GLEventListener} method are called directly
112 * from this {@link GLEventListener} implementation, i.e. the {@link Scene} is not attached
113 * to {@link GLAutoDrawable#addGLEventListener(GLEventListener)} itself.
114 * </p>
115 */
116public class UISceneDemo20 implements GLEventListener {
117 static final boolean DEBUG = false;
118 static final boolean TRACE = false;
119
120 static CommandlineOptions options = new CommandlineOptions(1280, 720, Region.VBAA_RENDERING_BIT);
121
122 public static void main(final String[] args) {
123 final float[] reqSurfacePixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
124
125 String fontfilename = null;
126 String filmURL = null;
127
128 if( 0 != args.length ) {
129 final int[] idx = { 0 };
130 for (idx[0] = 0; idx[0] < args.length; ++idx[0]) {
131 if( options.parse(args, idx) ) {
132 continue;
133 } else if(args[idx[0]].equals("-font")) {
134 idx[0]++;
135 fontfilename = args[idx[0]];
136 } else if(args[idx[0]].equals("-pixelScale")) {
137 idx[0]++;
138 final float pS = MiscUtils.atof(args[idx[0]], reqSurfacePixelScale[0]);
139 reqSurfacePixelScale[0] = pS;
140 reqSurfacePixelScale[1] = pS;
141 } else if(args[idx[0]].equals("-film") || args[idx[0]].equals("-file")) {
142 idx[0]++;
143 filmURL = args[idx[0]];
144 }
145 }
146 }
147 System.err.println(options);
148
149 final Display dpy = NewtFactory.createDisplay(null);
150 final Screen screen = NewtFactory.createScreen(dpy, 0);
151 System.err.println(VersionUtil.getPlatformInfo());
152 // System.err.println(JoglVersion.getAllAvailableCapabilitiesInfo(dpy.getGraphicsDevice(), null).toString());
153
154 final GLCapabilities caps = options.getGLCaps();
155 System.out.println("Requested: " + caps);
156
157 final GLWindow window = GLWindow.create(screen, caps);
158 window.invoke(false, (final GLAutoDrawable glad) -> {
159 glad.getGL().setSwapInterval(options.swapInterval);
160 return true;
161 } );
162 if( 0 == options.sceneMSAASamples ) {
164 }
165 window.setSize(options.surface_width, options.surface_height);
166 window.setTitle("GraphUI Newt Demo: graph["+Region.getRenderModeString(options.renderModes)+"], msaa "+options.sceneMSAASamples);
167 window.setSurfaceScale(reqSurfacePixelScale);
168 // final float[] valReqSurfacePixelScale = window.getRequestedSurfaceScale(new float[2]);
169
170 final UISceneDemo20 scene = new UISceneDemo20(fontfilename, filmURL, options.renderModes, DEBUG, TRACE);
171 window.addGLEventListener(scene);
172
173 final Animator animator = new Animator(0 /* w/o AWT */);
174 animator.setUpdateFPSFrames(5*60, null);
175 animator.add(window);
176 animator.setExclusiveContext(options.exclusiveContext);
177
178 window.addWindowListener(new WindowAdapter() {
179 @Override
180 public void windowDestroyed(final WindowEvent e) {
181 animator.stop();
182 }
183 });
184
185 window.setVisible(true);
186 animator.start();
187 }
188
189 static private final String defaultMediaURL = "https://archive.org/download/BigBuckBunny_328/BigBuckBunny_512kb.mp4";
190
191 private boolean debug = false;
192 private boolean trace = false;
193
194 private final Scene scene;
195
196 private final Font font;
197 private final Font fontButtons;
198 private final Font fontSymbols;
199 private final Font fontFPS;
200 private final Uri filmURL;
201
202 private final float relTop = 90f/100f;
203 private final float relMiddle = 22f/100f;
204
205 /** Relative Button Size to Window Height, normalized to 1. */
206 private static final float buttonXSizeNorm = 0.09f; // 0.084f;
207 private static final float fontSizePt = 10f;
208 /** Relative Font Size to Window Height for Main Text, normalized to 1. */
209 private static final float fontSizeFixedNorm = 0.04f;
210 private float dpiV = 96;
211
212 private int currentText = 0;
213
214 private String actionText = null;
215 private Label[] labels = null;
216 private String[] strings = null;
217 final Group buttonsLeft = new Group();
218 final Group buttonsRight = new Group();
219 private Label truePtSizeLabel = null;
220 private Label jogampLabel = null;
221 private Label fpsLabel = null;
222
223 private GLAutoDrawable cDrawable;
224
225 private final String jogamp = "JogAmp - Jogl Graph Module Demo";
226 private final String truePtSize = fontSizePt+" pt font size label - true scale!";
227
228 private final String longText = "JOGL: Java™ Binding for the OpenGL® API.\n\n"+
229 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec \n"+
230 "Ut purus odio, rhoncus sit amet commodo eget, ullamcorper vel\n"+
231 "quam iaculis urna cursus ornare. Nullam ut felis a ante ultrices\n"+
232 "In hac habitasse platea dictumst. Vivamus et mi a quam lacinia\n"+
233 "Morbi quis bibendum nibh. Donec lectus orci, sagittis in consequat\n"+
234 "Donec ut dolor et nulla tristique varius. In nulla magna, fermentum\n"+
235 "in lorem. Maecenas in ipsum ac justo scelerisque sollicitudin.\n"+
236 "\n"+
237 "Lyford’s in Texas & L’Anse-aux-Griffons in Québec;\n"+
238 "Kwikpak on the Yukon delta, Kvæven in Norway, Kyulu in Kenya, not Rwanda.…\n"+
239 "Ytterbium in the periodic table. Are Toussaint L’Ouverture, Wölfflin, Wolfe,\n"+
240 "\n"+
241 "The quick brown fox jumps over the lazy dog\n";
242
243 /**
244 * @param renderModes
245 */
246 public UISceneDemo20(final int renderModes) {
247 this(null, null, options.noAADPIThreshold, renderModes, false, false);
248 }
249
250 /**
251 * @param filmURL TODO
252 * @param renderModes
253 * @param debug
254 * @param trace
255 */
256 public UISceneDemo20(final String fontfilename, final String filmURL, final int renderModes, final boolean debug, final boolean trace) {
257 this(fontfilename, filmURL, options.noAADPIThreshold, renderModes, debug, trace);
258 }
259
260 /**
261 * @param filmURL TODO
262 * @param noAADPIThreshold see {@link #DefaultNoAADPIThreshold}
263 * @param debug
264 * @param trace
265 */
266 public UISceneDemo20(final String fontfilename, final String filmURL, final float noAADPIThreshold, final boolean debug, final boolean trace) {
267 this(fontfilename, filmURL, noAADPIThreshold, 0, debug, trace);
268 }
269
270 private UISceneDemo20(final String fontfilename, final String filmURL, final float noAADPIThreshold, final int renderModes, final boolean debug, final boolean trace) {
271 options.noAADPIThreshold = noAADPIThreshold;
272 this.debug = debug;
273 this.trace = trace;
274
275 UISceneDemo20.options.renderModes = renderModes;
276
277 try {
278 if( null == fontfilename ) {
279 font = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeSerif.ttf",
280 FontSetDemos.class.getClassLoader(), FontSetDemos.class).getInputStream(), true);
281 } else {
282 font = FontFactory.get( new File( fontfilename ) );
283 }
284 System.err.println("Font "+font.getFullFamilyName());
285
286 fontButtons = FontFactory.get(FontFactory.UBUNTU).getDefault();
287 fontSymbols = FontFactory.get(FontFactory.SYMBOLS).getDefault();
288 fontFPS = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeMono.ttf",
289 FontSetDemos.class.getClassLoader(), FontSetDemos.class).getInputStream(), true);
290 System.err.println("Font FPS "+fontFPS.getFullFamilyName());
291
292 } catch (final IOException ioe) {
293 throw new RuntimeException(ioe);
294 }
295 try {
296 this.filmURL = Uri.cast( null != filmURL ? filmURL : defaultMediaURL );
297 } catch (final URISyntaxException e1) {
298 throw new RuntimeException(e1);
299 }
300 scene = new Scene(options.graphAASamples);
301 scene.setPMVMatrixSetup(new Scene.DefaultPMVMatrixSetup(-1f));
302 scene.getRenderer().setHintBits(RenderState.BITHINT_GLOBAL_DEPTH_TEST_ENABLED);
303 // scene.setSampleCount(3); // easy on embedded devices w/ just 3 samples (default is 4)?
304 scene.addShape(buttonsLeft);
305 scene.addShape(buttonsRight);
306 }
307
308 private void rotateButtons(final Vec3f angdeg) {
309 angdeg.scale(FloatUtil.PI / 180.0f); // -> radians
310 final List<Shape> sl = new ArrayList<Shape>();
311 sl.addAll(buttonsLeft.getShapes());
312 sl.addAll(buttonsRight.getShapes());
313 for(final Shape s : sl) {
314 s.setRotation( s.getRotation().rotateByEuler( angdeg ) );
315 }
316 }
317
318 private void setButtonsSpacing(final float dx, final float dy) {
319 final List<Shape> sl = new ArrayList<Shape>();
320 sl.addAll(buttonsLeft.getShapes());
321 sl.addAll(buttonsRight.getShapes());
322 for(final Shape s : sl) {
323 if( s instanceof Button ) {
324 final Button lb = (Button) s;
325 final float sx = lb.getSpacing().x()+dx, sy = lb.getSpacing().y()+dy;
326 System.err.println("Spacing: X "+sx+", Y "+sy);
327 lb.setSpacing(sx, sy);
328 }
329 }
330 }
331
332 private void setButtonsCorner(final float dc) {
333 final List<Shape> sl = new ArrayList<Shape>();
334 sl.addAll(buttonsLeft.getShapes());
335 sl.addAll(buttonsRight.getShapes());
336 for(final Shape s : sl) {
337 if( s instanceof BaseButton ) {
338 final BaseButton rb = (BaseButton)s;
339 final float c = rb.getCorner()+dc;
340 System.err.println("Corner: "+c);
341 rb.setCorner(c);
342 }
343 }
344 }
345
346 private void resetButtons() {
347 final List<Shape> sl = new ArrayList<Shape>();
348 sl.addAll(buttonsLeft.getShapes());
349 sl.addAll(buttonsRight.getShapes());
350 for(final Shape s : sl) {
351 if( s instanceof BaseButton ) {
352 final BaseButton b = (BaseButton)s;
353 b.setRotation( b.getRotation().setIdentity() );
354 b.setCorner(BaseButton.ROUND_CORNER);
355 if( b instanceof Button ) {
356 ((Button)b).setSpacing(Button.DEFAULT_SPACING_X, Button.DEFAULT_SPACING_Y);
357 }
358 }
359 }
360 }
361
362 public static final int BUTTON_NEXTTEXT = 100;
363 public static final int BUTTON_FPS = 101;
364 public static final int BUTTON_VSYNC = 102;
365 public static final int BUTTON_QUIT = 102;
366 public static final int BUTTON_MOVIE = 200;
367 public static final int BUTTON_GLEL = 200;
368
369 public Shape getShapeByID(final int name) {
370 return scene.getShapeByID(name);
371 }
372
373 private void initSound(final Shape shape,
374 final com.jogamp.openal.sound3d.Context context,
375 final com.jogamp.openal.sound3d.Source aSource)
376 {
377 final com.jogamp.openal.sound3d.Listener audioListener = AudioSystem3D.getListener();
378 context.makeCurrent(true);
379 try {
380 float[] f3x2;
381 f3x2 = audioListener.getOrientation();
382 System.err.printf("Listener init orientation: at[%.3f %.3f %.3f], up[%.3f %.3f %.3f]%n",
383 f3x2[0], f3x2[1], f3x2[2], f3x2[3], f3x2[4], f3x2[5]);
384 f3x2 = new float[]{ /* at */ 0f, 0f, -1f, /* up */ 0f, 1f, 0f }; // default
385 audioListener.setOrientation(f3x2);
386 f3x2 = audioListener.getOrientation();
387 System.err.printf("Listener set orientation: at[%.3f %.3f %.3f], up[%.3f %.3f %.3f]%n",
388 f3x2[0], f3x2[1], f3x2[2], f3x2[3], f3x2[4], f3x2[5]);
389
390 com.jogamp.openal.sound3d.Vec3f ap = audioListener.getPosition();
391 System.err.printf("Listener init pos: %.3f %.3f %.3f%n", ap.v1, ap.v2, ap.v3);
392 audioListener.setPosition(0, 0, -0.25f);
393 ap = audioListener.getPosition();
394 System.err.printf("Listener set pos: %.3f %.3f %.3f%n", ap.v1, ap.v2, ap.v3);
395
396 System.err.printf("Source init rel: %b%n", aSource.isSourceRelative());
397 aSource.setSourceRelative(false); // default
398 System.err.printf("Source set rel: %b%n", aSource.isSourceRelative());
399
400 ap = aSource.getDirection();
401 System.err.printf("Source init dir: %.3f %.3f %.3f%n", ap.v1, ap.v2, ap.v3);
402
403 final float rollOff0 = aSource.getRolloffFactor();
404 System.err.printf("Source init rollOff: %.3f%n", rollOff0);
405
406 final float refDist0 = aSource.getReferenceDistance();
407 aSource.setReferenceDistance(0.75f); // listener dist is min 0.25 -> 0.5 left; default is 1
408 final float refDist1 = aSource.getReferenceDistance();
409 System.err.printf("Source ref-dist: %.3f -> %.3f%n", refDist0, refDist1);
410
411 ap = aSource.getPosition();
412 System.err.printf("Source init pos: %.3f %.3f %.3f%n", ap.v1, ap.v2, ap.v3);
413 AudioSystem3D.checkError(context.getDevice(), "setup", true, false);
414
415 setSoundPosition(shape, context, aSource);
416 } finally {
417 context.release(true);
418 }
419 }
420
421 private void setSoundPosition(final Shape shape,
422 final com.jogamp.openal.sound3d.Context context,
423 final com.jogamp.openal.sound3d.Source aSource) {
424 AABBox worldBounds;
425 {
426 final PMVMatrix4f pmv = new PMVMatrix4f();
427 worldBounds = scene.getBounds(pmv, shape);
428 }
429 context.makeCurrent(true);
430 try {
431 aSource.setPosition(worldBounds.getCenter().x(), worldBounds.getCenter().y(), worldBounds.getCenter().z());
432 System.err.println("Source pos: "+worldBounds.getCenter());
433 } finally {
434 context.release(true);
435 }
436 }
437
438 private static void setSineSoundLabel(final Button shape, final float freq, final float amp) {
439 final String s;
440 if( shape.isToggleOn() ) {
441 s = String.format("scroll %.0f Hz\nctrl-scroll %.2f amp\nmove spatial", freq, amp);
442 shape.setSpacing(0.05f, 0.20f);
443 } else {
444 s = String.format("click to enable\nf %.0f Hz, a %.2f", freq, amp);
445 shape.setSpacing(Button.DEFAULT_SPACING_X, Button.DEFAULT_SPACING_Y);
446
447 }
448 shape.setText(s);
449 }
450
451 private void initButtons(final GL2ES2 gl) {
452 final boolean pass2Mode = Region.isTwoPass( options.renderModes ) ;
453 buttonsLeft.removeAllShapes(gl, scene.getRenderer());
454 buttonsRight.removeAllShapes(gl, scene.getRenderer());
455
456 final float buttonLWidth = buttonXSizeNorm;
457 final float buttonLHeight = buttonLWidth / 2.5f;
458 buttonsLeft.setLayout(new GridLayout(buttonLWidth, buttonLHeight, Alignment.Fill, new Gap(buttonLHeight*0.50f, buttonLWidth*0.10f), 7));
459
460 final float buttonRWidth = 2f*buttonLWidth;
461 final float buttonRHeight = 2f*buttonLHeight;
462
463 buttonsRight.setLayout(new GridLayout(1, buttonRWidth, buttonRHeight, Alignment.Fill, new Gap(buttonLHeight*0.50f, buttonLWidth*0.10f)));
464
465 System.err.println("Button Size: "+buttonLWidth+" x "+buttonLHeight);
466 final Vec2f fixedSymSize = new Vec2f(0.0f, 1.0f);
467 final Vec2f symSpacing = new Vec2f(0f, 0.2f);
468
469 BaseButton button;
470 button = new Button(options.renderModes, fontSymbols, fontSymbols.getUTF16String("fast_forward"), buttonLWidth, buttonLHeight); // next (ffwd)
471 ((Button)button).setSpacing(symSpacing, fixedSymSize);
472 button.setID(BUTTON_NEXTTEXT);
473 button.addMouseListener(new Shape.MouseGestureAdapter() {
474 @Override
475 public void mouseClicked(final MouseEvent e) {
476 if( null != labels[currentText] ) {
477 labels[currentText].setVisible(false);
478 }
479 currentText = (currentText+1)%labels.length;
480 if( null != labels[currentText] ) {
481 labels[currentText].setVisible(true);
482 }
483 } } );
484 button.addMouseListener(dragZoomRotateListener);
485 buttonsLeft.addShape(button);
486
487 button = new Button(options.renderModes, fontButtons, "Show fps", "Hide fps", buttonLWidth, buttonLHeight, Button.DEFAULT_LABEL_ZOFFSET);
488 button.setID(BUTTON_FPS);
489 button.setToggleable(true);
490 button.setToggle(fpsLabel.isVisible());
491 button.addMouseListener(new Shape.MouseGestureAdapter() {
492 @Override
493 public void mouseClicked(final MouseEvent e) {
494 final GLAnimatorControl a = cDrawable.getAnimator();
495 if( null != a ) {
496 a.resetFPSCounter();
497 }
498 fpsLabel.setVisible(!fpsLabel.isVisible());
499 } } );
500 button.addMouseListener(dragZoomRotateListener);
501 buttonsLeft.addShape(button);
502
503 button = new Button(options.renderModes, fontButtons, " V-Sync ", buttonLWidth, buttonLHeight);
504 button.setID(BUTTON_VSYNC);
505 button.setToggleable(true);
506 button.setToggle(gl.getSwapInterval()>0);
507 button.addMouseListener(new Shape.MouseGestureAdapter() {
508 @Override
509 public void mouseClicked(final MouseEvent e) {
510 cDrawable.invoke(false, new GLRunnable() {
511 @Override
512 public boolean run(final GLAutoDrawable drawable) {
513 final GL gl = drawable.getGL();
514 gl.setSwapInterval(gl.getSwapInterval()<=0?1:0);
515 final GLAnimatorControl a = drawable.getAnimator();
516 if( null != a ) {
517 a.resetFPSCounter();
518 }
519 return true;
520 }
521 });
522 } } );
523 button.addMouseListener(dragZoomRotateListener);
524 buttonsLeft.addShape(button);
525
526 button = new Button(options.renderModes, fontButtons, " < Tilt > ", buttonLWidth, buttonLHeight);
527 button.addMouseListener(new Shape.MouseGestureAdapter() {
528 @Override
529 public void mouseClicked(final MouseEvent e) {
530 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
531 if( shapeEvent.objPos.x() < shapeEvent.shape.getBounds().getCenter().x() ) {
532 rotateButtons(new Vec3f( 0f, -5f, 0f ) ); // left-half pressed
533 } else {
534 rotateButtons(new Vec3f( 0f, 5f, 0f ) ); // right-half pressed
535 }
536 }
537 @Override
538 public void mouseWheelMoved(final MouseEvent e) {
539 rotateButtons(new Vec3f( 0f, e.getRotation()[1], 0f ) );
540 } } );
541 buttonsLeft.addShape(button);
542
543 if( pass2Mode ) {
544 button = new Button(options.renderModes, fontButtons, "< Samples >", buttonLWidth, buttonLHeight);
545 button.addMouseListener(new Shape.MouseGestureAdapter() {
546 @Override
547 public void mouseClicked(final MouseEvent e) {
548 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
549 int sampleCount = scene.getSampleCount();
550 if( shapeEvent.objPos.x() < shapeEvent.shape.getBounds().getCenter().x() ) {
551 // left-half pressed
552 sampleCount--;
553 } else {
554 // right-half pressed
555 sampleCount++;
556 }
557 sampleCount = scene.setSampleCount(sampleCount); // validated / clipped
558 } } );
559 button.addMouseListener(dragZoomRotateListener);
560 buttonsLeft.addShape(button);
561
562 button = new Button(options.renderModes, fontButtons, "< Quality >", buttonLWidth, buttonLHeight);
563 button.addMouseListener(new Shape.MouseGestureAdapter() {
564 @Override
565 public void mouseClicked(final MouseEvent e) {
566 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
567 if( shapeEvent.shape instanceof GraphShape ) {
568 int quality = scene.getAAQuality();
569 if( shapeEvent.objPos.x() < shapeEvent.shape.getBounds().getCenter().x() ) {
570 // left-half pressed
571 quality--;
572 } else {
573 // right-half pressed
574 quality++;
575 }
576 scene.setAAQuality(quality); // validated / clipped
577 }
578 } } );
579 button.addMouseListener(dragZoomRotateListener);
580 buttonsLeft.addShape(button);
581 }
582
583 button = new Button(options.renderModes, fontSymbols, fontSymbols.getUTF16String("power_settings_new"), buttonLWidth, buttonLHeight); // exit (power_settings_new)
584 ((Button)button).setSpacing(symSpacing, fixedSymSize);
585 button.setID(BUTTON_QUIT);
586 button.setColor(0.7f, 0.3f, 0.3f, 1.0f);
587 ((Button)button).setLabelColor(1.2f, 1.2f, 1.2f, 1.0f);
588 button.setPressedColorMod(1.1f, 0.0f, 0.0f, 1.0f);
589 button.addMouseListener(new Shape.MouseGestureAdapter() {
590 @Override
591 public void mouseClicked(final MouseEvent e) {
592 MiscUtils.destroyWindow(cDrawable);
593 } } );
594 button.addMouseListener(dragZoomRotateListener);
595 buttonsLeft.addShape(button);
596
597 // second column to the left
598 {
599 button = new Button(options.renderModes, fontSymbols, fontSymbols.getUTF16String("flip"), buttonLWidth, buttonLHeight); // Y Flip (flip)
600 ((Button)button).setSpacing(symSpacing, fixedSymSize);
601 button.addMouseListener(new Shape.MouseGestureAdapter() {
602 @Override
603 public void mouseClicked(final MouseEvent e) {
604 rotateButtons(new Vec3f ( 0f, 180f, 0f ));
605 } } );
606 button.addMouseListener(dragZoomRotateListener);
607 buttonsLeft.addShape(button);
608
609 button = new Button(options.renderModes, fontButtons, " X Flip ", buttonLWidth, buttonLHeight);
610 button.addMouseListener(new Shape.MouseGestureAdapter() {
611 @Override
612 public void mouseClicked(final MouseEvent e) {
613 rotateButtons(new Vec3f ( 180f, 0f, 0f ));
614 } } );
615 button.addMouseListener(dragZoomRotateListener);
616 buttonsLeft.addShape(button);
617
618 button = new Button(options.renderModes, fontButtons, "< Space >", buttonLWidth, buttonLHeight);
619 button.addMouseListener(new Shape.MouseGestureAdapter() {
620 @Override
621 public void mouseClicked(final MouseEvent e) {
622 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
623 final float dx, dy;
624 if( shapeEvent.objPos.x() < shapeEvent.shape.getBounds().getCenter().x() ) {
625 dx=-0.01f; dy=-0.005f;
626 } else {
627 dx=0.01f; dy=0.005f;
628 }
629 setButtonsSpacing(dx, dy);
630 }
631 @Override
632 public void mouseWheelMoved(final MouseEvent e) {
633 setButtonsSpacing(e.getRotation()[0]/100f, e.getRotation()[1]/200f);
634 } } );
635 buttonsLeft.addShape(button);
636
637 button = new Button(options.renderModes, fontButtons, "< Corner >", buttonLWidth, buttonLHeight);
638 button.addMouseListener(new Shape.MouseGestureAdapter() {
639 @Override
640 public void mouseClicked(final MouseEvent e) {
641 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
642 final float dc;
643 if( shapeEvent.objPos.x() < shapeEvent.shape.getBounds().getCenter().x() ) {
644 dc=-0.1f;
645 } else {
646 dc=0.1f;
647 }
648 setButtonsCorner(dc);
649 }
650 @Override
651 public void mouseWheelMoved(final MouseEvent e) {
652 setButtonsCorner(e.getRotation()[1]/20f);
653 } } );
654 buttonsLeft.addShape(button);
655
656 button = new Button(options.renderModes, fontSymbols, fontSymbols.getUTF16String("undo"), buttonLWidth, buttonLHeight); // reset (undo)
657 ((Button)button).setSpacing(symSpacing, fixedSymSize);
658 button.addMouseListener(new Shape.MouseGestureAdapter() {
659 @Override
660 public void mouseClicked(final MouseEvent e) {
661 resetButtons();
662 } } );
663 button.addMouseListener(dragZoomRotateListener);
664 buttonsLeft.addShape(button);
665
666 button = new Button(options.renderModes, fontSymbols, fontSymbols.getUTF16String("camera"), buttonLWidth, buttonLHeight); // snapshot (camera)
667 ((Button)button).setSpacing(symSpacing, fixedSymSize);
668 button.addMouseListener(new Shape.MouseGestureAdapter() {
669 @Override
670 public void mouseClicked(final MouseEvent e) {
671 scene.screenshot(false, scene.nextScreenshotFile(null, UISceneDemo20.class.getSimpleName(), options.renderModes, gl.getContext().getGLDrawable().getChosenGLCapabilities(), null));
672 } } );
673 button.addMouseListener(dragZoomRotateListener);
674 buttonsLeft.addShape(button);
675 }
676
677 //
678 // buttonRight
679 //
680 final int texUnitMediaPlayer, texUnitImageButton, texUnitGLELButton;
681 {
682 // works - but not required ..
683 texUnitMediaPlayer=1;
684 texUnitImageButton=2;
685 texUnitGLELButton=3;
686 }
687
688 if( true ) {
689 final GLMediaPlayer mPlayer = GLMediaPlayerFactory.createDefault();
690 mPlayer.setTextureUnit(texUnitMediaPlayer);
691 mPlayer.setAudioChannelLimit(1); // enforce mono to enjoy spatial 3D position effects
692 button = new MediaButton(options.renderModes, buttonRWidth, buttonRHeight, mPlayer);
693 button.setID(BUTTON_MOVIE);
694 ((MediaButton)button).setVerbose(false).addDefaultEventListener().setFixedARatioResize(true);
695 button.setToggleable(true);
696 button.setToggle(true); // toggle == false -> mute audio
697 button.setToggleOffColorMod(0f, 1f, 0f, 1.0f);
698 button.addMouseListener(dragZoomRotateListener);
699
700 button.onToggle( (final Shape s) -> {
701 mPlayer.setAudioVolume( s.isToggleOn() ? 1f : 0f );
702 });
703
704 {
705 final ALAudioSink[] alAudioSink = { null };
706
707 mPlayer.addEventListener( new GLMediaEventListener() {
708 @Override
709 public void attributesChanged(final GLMediaPlayer mp, final EventMask eventMask, final long when) {
710 System.err.println("MediaButton AttributesChanges: "+eventMask+", when "+when);
711 System.err.println("MediaButton State: "+mp);
712 if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.Init) ) {
713 final AudioSink audioSink = mp.getAudioSink();
714 if( audioSink instanceof ALAudioSink ) {
715 alAudioSink[0] = (ALAudioSink)audioSink;
716 } else {
717 alAudioSink[0] = null;
718 }
719 }
720 if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.EOS) ) {
721 alAudioSink[0] = null;
722 }
723 }
724
725 });
726 button.onMove((final Shape shape, final Vec3f origin, final Vec3f dest, final MouseEvent e) -> {
727 final ALAudioSink aSink = alAudioSink[0];
728 if( null != aSink && aSink.getContext().isValid() ) {
729 setSoundPosition(shape, aSink.getContext(), aSink.getSource());
730 }
731 } );
732 button.onDraw( (final Shape shape, final GL2ES2 gl_, final RegionRenderer renderer_) -> {
733 final ALAudioSink aSink = alAudioSink[0];
734 if( null != aSink && aSink.getContext().isValid() ) {
735 initSound(shape, aSink.getContext(), aSink.getSource());
736 System.err.println("Media Audio: "+aSink);
737 return true;
738 } else {
739 return false;
740 }
741 });
742 }
743 buttonsRight.addShape(button);
744 mPlayer.playStream(filmURL, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_NONE, GLMediaPlayer.TEXTURE_COUNT_DEFAULT);
745 }
746 {
747 final SimpleSineSynth sineSound = new SimpleSineSynth();
748 scene.addDisposeAction((final GLAutoDrawable glad) -> {
749 sineSound.stop();
750 return true;
751 } );
752 sineSound.setFreq(200f);
753 sineSound.setAmplitude(0.1f);
754 final Button sineButton = new Button(options.renderModes, fontButtons, "lala", buttonRWidth, buttonRHeight);
755 button = sineButton;
756 button.setToggleable(true);
757 button.setToggle(false); // toggle == false -> mute audio
758 setSineSoundLabel(sineButton, sineSound.getFreq(), sineSound.getAmplitude());
759
760 final ALAudioSink aSink = sineSound.getSink();
761 final com.jogamp.openal.sound3d.Source aSource = aSink.getSource();
762
763 button.addMouseListener(new Shape.MouseGestureAdapter() {
764 @Override
765 public void mouseReleased(final MouseEvent e) {
766 actionText = null;
767 }
768
769 @Override
770 public void mouseDragged(final MouseEvent e) {
771 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
772 if( e.getPointerCount() == 1 ) {
773 final AABBox worldBounds;
774 {
775 final PMVMatrix4f pmv = new PMVMatrix4f();
776 worldBounds = scene.getBounds(pmv, shapeEvent.shape);
777 }
778 actionText = String.format((Locale)null, "Pos %s", worldBounds.getCenter());
779 }
780 }
781 @Override
782 public void mouseClicked(final MouseEvent e) {
783 final Shape.EventInfo info = (Shape.EventInfo)e.getAttachment();
784 if( info.shape.isToggleOn() ) {
785 sineSound.play();
786 } else {
787 sineSound.pause();
788 }
789 setSineSoundLabel(sineButton, sineSound.getFreq(), sineSound.getAmplitude());
790 }
791 @Override
792 public void mouseWheelMoved(final MouseEvent e) {
793 if( e.isControlDown() ) {
794 final float a1 = sineSound.getAmplitude() + + e.getRotation()[1] / 20f;
795 sineSound.setAmplitude(a1);
796 } else {
797 final float f1 = sineSound.getFreq() + e.getRotation()[1] * 10f;
798 sineSound.setFreq(f1);
799 }
800 setSineSoundLabel(sineButton, sineSound.getFreq(), sineSound.getAmplitude());
801 System.err.println("Sine "+sineSound);
802 } } );
803
804 button.onDraw( (final Shape shape, final GL2ES2 gl_, final RegionRenderer renderer_) -> {
805 if( null != aSink && aSink.getContext().isValid() ) {
806 initSound(shape, aSink.getContext(), aSource);
807 System.err.println("Sine Audio: "+aSink);
808 return true;
809 } else {
810 return false;
811 }
812 } );
813 button.onMove( (final Shape shape, final Vec3f origin, final Vec3f dest, final MouseEvent e) -> {
814 setSoundPosition(shape, aSink.getContext(), aSource);
815 } );
816 buttonsRight.addShape(button);
817 }
818 if( true ) {
819 final ImageSequence imgSeq = new ImageSequence(texUnitImageButton, true);
820 button = new ImageButton(options.renderModes, buttonRWidth, buttonRHeight, imgSeq);
821 try {
822 imgSeq.addFrame(gl, UISceneDemo20.class, "button-released-145x53.png", TextureIO.PNG);
823 imgSeq.addFrame(gl, UISceneDemo20.class, "button-pressed-145x53.png", TextureIO.PNG);
824 } catch (final IOException e2) {
825 e2.printStackTrace();
826 }
827 imgSeq.setManualStepping(true);
828 button.addMouseListener(dragZoomRotateListener);
829 button.addMouseListener(new Shape.MouseGestureAdapter() {
830 @Override
831 public void mousePressed(final MouseEvent e) {
832 final Shape.EventInfo info = (Shape.EventInfo)e.getAttachment();
833 final ImageButton s = (ImageButton)info.shape;
834 s.setCurrentIdx(1);
835 System.err.println("XXX: "+s);
836 }
837 @Override
838 public void mouseReleased(final MouseEvent e) {
839 final Shape.EventInfo info = (Shape.EventInfo)e.getAttachment();
840 final ImageButton s = (ImageButton)info.shape;
841 s.setCurrentIdx(0);
842 } } );
843 buttonsRight.addShape(button);
844 }
845 if( true ) {
846 // Issues w/ OSX and NewtCanvasAWT when rendering / animating
847 // Probably related to CALayer - FBO - FBO* (of this button)
848 final GearsES2 gears = new GearsES2(0);
849 gears.setVerbose(false);
850 gears.setClearColor(new float[] { 0.9f, 0.9f, 0.9f, 1f } );
851 final boolean[] animate = { true };
852 new Thread(new Runnable() {
853 @Override
854 public void run() {
855 System.err.println("Gears Anim: Waiting");
856 try {
857 gears.waitForInit(true);
858 } catch (final InterruptedException e) { }
859 System.err.println("Gears Anim: Started");
860 while( gears.isInit() ) {
861 if( animate[0] ) {
862 final float ry = ( gears.getRotY() + 1 ) % 360;
863 gears.setRotY(ry);
864 }
865 try {
866 Thread.sleep(15);
867 } catch (final InterruptedException e) { }
868 }
869 System.err.println("Gears Anim: End");
870 }
871 }).start();
872 button = new GLButton(options.renderModes, buttonRWidth, buttonRHeight,
873 texUnitGLELButton, gears, false /* useAlpha */);
874 button.setID(BUTTON_GLEL);
875 button.setToggleable(true);
876 button.setToggle(false); // toggle == true -> animation
877 ((GLButton)button).setAnimate(false);
878 button.addMouseListener(dragZoomRotateListener);
879 button.addMouseListener(new Shape.MouseGestureAdapter() {
880 @Override
881 public void mouseClicked(final MouseEvent e) {
882 final Shape.EventInfo info = (Shape.EventInfo)e.getAttachment();
883 final GLButton s = (GLButton)info.shape;
884 s.setAnimate( s.isToggleOn() );
885 animate[0] = s.getAnimate();
886 } } );
887 buttonsRight.addShape(button);
888 }
889 }
890
891 private void initTexts() {
892 strings = new String[4];
893 int i = 0;
894
895 strings[i++] = "- Mouse Scroll Over Object\n"+
896 " - General\n"+
897 " - X-Rotation\n"+
898 " - Shift: Y-Rotation\n"+
899 " - Tilt, Space and Corner\n"+
900 " - Their respective action via wheel\n"+
901 " (shift = other value)\n"+
902 "\n"+
903 "- Mouse Drag On Object\n"+
904 " - Click on Object and drag mouse\n"+
905 " - Current postion in status line at bottom\n"+
906 " - Resize when click on 1/4 bottom-left or bottom-right corner.\n"+
907 "\n"+
908 "- Tilt Button Rotate Whole Button Group";
909
910 strings[i++] = "abcdefghijklmn\nopqrstuvwxyz\n"+
911 "ABCDEFGHIJKL\n"+
912 "MNOPQRSTUVWXYZ\n"+
913 "0123456789.:,;(*!?/\\\")$%^&-+@~#<>{}[]";
914
915 strings[i++] = "The quick brown fox jumps over the lazy dog";
916
917 strings[i++] = longText;
918
919 labels = new Label[i];
920
921 currentText = strings.length - 1;
922 }
923
924
925 private static final boolean enableOthers = true;
926
927
928 private void initLabels(final GL2ES2 gl) {
929 jogampLabel = new Label(options.renderModes, font, fontSizeFixedNorm, jogamp);
930 jogampLabel.addMouseListener(dragZoomRotateListener);
931 jogampLabel.setVisible(enableOthers);
932 scene.addShape(jogampLabel);
933
934 truePtSizeLabel = new Label(options.renderModes, font, truePtSize);
935 truePtSizeLabel.setVisible(enableOthers);
936 truePtSizeLabel.setColor(0.1f, 0.1f, 0.1f, 1.0f);
937 scene.addShape(truePtSizeLabel);
938
939 /**
940 *
941 * [Label] Display 112.88889 dpi, fontSize 12.0 ppi -> pixelSize 18.814816
942 * [FPS] Display 112.88889 dpi, fontSize 12.0 ppi -> pixelSize 15.679012
943 */
944 fpsLabel = new Label(options.renderModes, fontFPS, "Nothing there yet");
945 fpsLabel.addMouseListener(dragZoomRotateListener);
946 fpsLabel.setVisible(enableOthers);
947 fpsLabel.setColor(0.1f, 0.1f, 0.1f, 1.0f);
948 scene.addShape(fpsLabel);
949 }
950
951 @Override
952 public void init(final GLAutoDrawable drawable) {
953 final Object upObj = drawable.getUpstreamWidget();
954 if( upObj instanceof Window ) {
955 final Window upWin = (Window)upObj;
956 final MonitorDevice monitor = upWin.getMainMonitor();
957 final float[] monitorDPI = MonitorDevice.mmToInch( monitor.getPixelsPerMM(new float[2]) );
958 final float[] sDPI = MonitorDevice.mmToInch( upWin.getPixelsPerMM(new float[2]) );
959 dpiV = sDPI[1];
960 System.err.println("Monitor detected: "+monitor);
961 System.err.println("Monitor dpi: "+monitorDPI[0]+" x "+monitorDPI[1]);
962 System.err.println("Surface scale: native "+Arrays.toString(upWin.getMaximumSurfaceScale(new float[2]))+", current "+Arrays.toString(upWin.getCurrentSurfaceScale(new float[2])));
963 System.err.println("Surface dpi "+sDPI[0]+" x "+sDPI[1]);
964 } else {
965 System.err.println("Using default DPI of "+dpiV);
966 }
967 {
968 final int o = options.fixDefaultAARenderModeWithDPIThreshold(dpiV);
969 System.err.println("AUTO RenderMode: dpi "+dpiV+", threshold "+options.noAADPIThreshold+
970 ", mode "+Region.getRenderModeString(o)+" -> "+
972 }
973 if(drawable instanceof GLWindow) {
974 System.err.println("UISceneDemo20: init (1)");
975 final GLWindow glw = (GLWindow) drawable;
976 scene.attachInputListenerTo(glw);
977 } else {
978 System.err.println("UISceneDemo20: init (0)");
979 }
980 cDrawable = drawable;
981 GL2ES2 gl = drawable.getGL().getGL2ES2();
982 if(debug) {
983 gl = gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Debug", null, gl, null) ).getGL2ES2();
984 }
985 if(trace) {
986 gl = gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Trace", null, gl, new Object[] { System.err } ) ).getGL2ES2();
987 }
988 System.err.println(JoglVersion.getGLInfo(gl, null, false /* withCapsAndExts */).toString());
989 System.err.println("VSync Swap Interval: "+gl.getSwapInterval());
990 System.err.println("Chosen: "+drawable.getChosenGLCapabilities());
991 MSAATool.dump(drawable);
992
993 gl.setSwapInterval(1);
994 gl.glEnable(GL.GL_DEPTH_TEST);
995 gl.glEnable(GL.GL_BLEND);
996
997 initTexts();
998 initLabels(gl);
999 initButtons(gl);
1000
1001 scene.setAAQuality(options.graphAAQuality);
1002
1003 scene.init(drawable);
1004
1005 final GLAnimatorControl a = drawable.getAnimator();
1006 if( null != a ) {
1007 a.resetFPSCounter();
1008 }
1009 }
1010
1011 @Override
1012 public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
1013 System.err.println("UISceneDemo20: reshape: "+x+"/"+y+" "+width+"x"+height);
1014 System.err.println("UISceneDemo20: drawable: "+drawable);
1015
1016 //
1017 // Layout all shapes: Relational move regarding object coordinates
1018 //
1019 System.err.println("Reshape: Scene Plane.0 "+scene.getBounds());
1020 final float lastSceneWidth = scene.getBounds().getWidth();
1021 final float lastSceneHeight = scene.getBounds().getHeight();
1022 System.err.println("Reshape: Scene Plane.0 "+lastSceneWidth+" x "+lastSceneHeight);
1023
1024 scene.reshape(drawable, x, y, width, height);
1025 final AABBox sceneBox = scene.getBounds();
1026 final float zEpsilon = scene.getZEpsilon(16);
1027 System.err.println("Reshape: Scene Plane.1 "+sceneBox);
1028 System.err.println("Reshape: Scene zEpsilon "+zEpsilon);
1029
1030 final float sceneWidth = sceneBox.getWidth();
1031 final float sceneHeight = sceneBox.getHeight();
1032 final float button_sxy = sceneWidth > sceneHeight ? sceneWidth : sceneHeight;
1033
1034 TreeTool.forAll(buttonsLeft, (final Shape s) -> { if( s instanceof Button) { ((Button)s).setLabelZOffset(zEpsilon); } return false; } );
1035 TreeTool.forAll(buttonsRight, (final Shape s) -> { if( s instanceof Button) { ((Button)s).setLabelZOffset(zEpsilon); } return false; } );
1036 buttonsLeft.validate(drawable.getGL().getGL2ES2());
1037 buttonsRight.validate(drawable.getGL().getGL2ES2());
1038
1039 buttonsLeft.setScale(button_sxy, button_sxy, 1f);
1040 buttonsRight.setScale(button_sxy, button_sxy, 1f);
1041
1042 final float dz = 0f;
1043 final float dxLeft = sceneBox.getMinX();
1044 final float dyBottom = sceneBox.getMinY();
1045 final float dyTop = dyBottom + sceneHeight * relTop;
1046
1047 System.err.println("XXX: dw "+sceneWidth+", dh "+sceneHeight+", dyTop "+dyTop);
1048 System.err.println("BL "+buttonsLeft);
1049 System.err.println("BL "+buttonsLeft.getLayout());
1050 System.err.println("BR "+buttonsRight);
1051 System.err.println("BR "+buttonsRight.getLayout());
1052 buttonsLeft.moveTo(dxLeft, dyTop - buttonsLeft.getScaledHeight(), dz);
1053 buttonsRight.moveTo(dxLeft + sceneWidth - buttonsRight.getScaledWidth(), dyTop - buttonsRight.getScaledHeight(), dz);
1054
1055 jogampLabel.setScale(sceneHeight, sceneHeight, 1f);
1056
1057 final float dxMiddleAbs = dxLeft + sceneWidth * relMiddle;
1058 final float dyTopLabelAbs = dyBottom + sceneHeight - jogampLabel.getScaledLineHeight();
1059 jogampLabel.moveTo(dxMiddleAbs, dyTopLabelAbs - jogampLabel.getScaledLineHeight(), dz);
1060 {
1061 final float pixelSize10Pt = FontScale.toPixels(fontSizePt, dpiV);
1062 final float scale = pixelSize10Pt / height * sceneHeight; // normalize with dpi / surfaceHeight
1063 System.err.println("10Pt PixelSize: Display "+dpiV+" dpi, fontSize "+fontSizePt+" pt, "+FontScale.ptToMM(fontSizePt)+" mm -> "+pixelSize10Pt+" pixels, "+scale+" scene-size");
1064 truePtSizeLabel.setScale(scale, scale, 1f);
1065 truePtSizeLabel.moveTo(dxMiddleAbs, dyTopLabelAbs - jogampLabel.getScaledLineHeight() - truePtSizeLabel.getScaledLineHeight(), dz);
1066 }
1067 {
1068 final AABBox fbox = fontFPS.getGlyphBounds(scene.getStatusText(drawable, options.renderModes, dpiV));
1069 final float scale = sceneWidth / ( 1.4f * fbox.getWidth() ); // add 40% width
1070 fpsLabel.setScale(scale, scale, 1f);
1071 fpsLabel.moveTo(sceneBox.getMinX(), sceneBox.getMinY() + scale * ( fontFPS.getMetrics().getLineGap() - fontFPS.getMetrics().getDescent() ), 0f);
1072 fpsLabel.validate(drawable.getGL().getGL2ES2());
1073 System.err.println("StatusLabel Scale: " + scale + " = " + sceneWidth + " / " + fbox.getWidth() + ", " + fbox);
1074 System.err.println("StatusLabel: " + fpsLabel);
1075 }
1076 if( null != labels[currentText] ) {
1077 labels[currentText].setScale(sceneHeight, sceneHeight, 1f);
1078 labels[currentText].moveTo(dxMiddleAbs,
1079 dyTopLabelAbs - jogampLabel.getScaledLineHeight()
1080 - 1.5f * truePtSizeLabel.getScaledLineHeight()
1081 - labels[currentText].getScaledHeight(), 0f);
1082 System.err.println("Label["+currentText+"] MOVE: "+labels[currentText]);
1083 System.err.println("Label["+currentText+"] MOVE: "+labels[currentText].getPosition());
1084 }
1085 }
1086
1087 @Override
1088 public void dispose(final GLAutoDrawable drawable) {
1089 System.err.println("UISceneDemo20: dispose");
1090
1091 scene.dispose(drawable); // disposes all registered UIShapes
1092 }
1093
1094 @Override
1095 public void display(final GLAutoDrawable drawable) {
1096 // System.err.println("UISceneDemo20: display");
1097 final GL2ES2 gl = drawable.getGL().getGL2ES2();
1098 gl.glClearColor(1f, 1f, 1f, 1f);
1100
1101 if(null == labels[currentText]) {
1102 final AABBox sbox = scene.getBounds();
1103 final float sceneHeight = sbox.getHeight();
1104 final float dyTop = sbox.getMinY() + sbox.getHeight() - jogampLabel.getScaledLineHeight();
1105 final float dxMiddle = sbox.getMinX() + sbox.getWidth() * relMiddle;
1106 labels[currentText] = new Label(options.renderModes, font, fontSizeFixedNorm, strings[currentText]);
1107 labels[currentText].setScale(sceneHeight, sceneHeight, 1f);
1108 labels[currentText].setColor(0.1f, 0.1f, 0.1f, 1.0f);
1109 labels[currentText].setVisible(enableOthers);
1110 labels[currentText].setFixedARatioResize(true);
1111 labels[currentText].validate(gl);
1112 labels[currentText].move(dxMiddle,
1113 dyTop - jogampLabel.getScaledLineHeight()
1114 - 1.5f * truePtSizeLabel.getScaledLineHeight()
1115 - labels[currentText].getScaledHeight(), 0f);
1116 labels[currentText].addMouseListener(dragZoomRotateListener);
1117 scene.addShape(labels[currentText]);
1118 System.err.println("Label["+currentText+"] CTOR: "+labels[currentText]);
1119 System.err.println("Label["+currentText+"] CTOR: "+labels[currentText].getPosition());
1120 }
1121 if( fpsLabel.isVisible() ) {
1122 final String text;
1123 if( null == actionText ) {
1124 text = scene.getStatusText(drawable, options.renderModes, dpiV);
1125 } else if( null != drawable.getAnimator() ) {
1126 text = Scene.getStatusText(drawable.getAnimator())+", "+actionText;
1127 } else {
1128 text = actionText;
1129 }
1130 if( fpsLabel.setText(text) ) { // marks dirty only if text differs.
1131 // System.err.println(text);
1132 }
1133 }
1134 scene.display(drawable);
1135 }
1136
1137 /**
1138 * We can share this instance w/ all UI elements,
1139 * since only mouse action / gesture is complete for a single one (press, drag, released and click).
1140 */
1141 private final Shape.MouseGestureAdapter dragZoomRotateListener = new Shape.MouseGestureAdapter() {
1142 @Override
1143 public void mouseReleased(final MouseEvent e) {
1144 actionText = null;
1145 }
1146
1147 @Override
1148 public void mouseDragged(final MouseEvent e) {
1149 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
1150 if( e.getPointerCount() == 1 ) {
1151 final AABBox worldBounds;
1152 {
1153 final PMVMatrix4f pmv = new PMVMatrix4f();
1154 worldBounds = scene.getBounds(pmv, shapeEvent.shape);
1155 }
1156 actionText = String.format((Locale)null, "Pos %s", worldBounds.getCenter());
1157 }
1158 }
1159
1160 @Override
1161 public void mouseWheelMoved(final MouseEvent e) {
1162 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
1163 final Vec3f rot = new Vec3f(e.getRotation()).scale( FloatUtil.PI / 180.0f );
1164 // swap axis for onscreen rotation matching natural feel
1165 final float tmp = rot.x(); rot.setX( rot.y() ); rot.setY( tmp );
1166 shapeEvent.shape.setRotation( shapeEvent.shape.getRotation().rotateByEuler( rot.scale( 2f ) ) );
1167 }
1168 };
1169}
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 VBAA_RENDERING_BIT
Rendering-Mode bit for Region.
Definition: Region.java:115
The optional property jogamp.graph.font.ctor allows user to specify the FontConstructor implementatio...
static final FontSet get(final int font)
Simple static font scale methods for unit conversions.
Definition: FontScale.java:37
static float ptToMM(final float points)
Converts the the given points size to mm, dividing by 72 * 25.4 points per inch.
Definition: FontScale.java:58
static float toPixels(final float points, final float res_dpi)
Converts typical font size in points and screen resolution in dpi (pixels-per-inch) to font size in p...
Definition: FontScale.java:76
Group of Shapes, optionally utilizing a Group.Layout.
Definition: Group.java:61
void addShape(final Shape s)
Adds a Shape.
Definition: Group.java:225
void removeAllShapes(final GL2ES2 gl, final RegionRenderer renderer)
Removes all contained shapes with Shape#destroy(GL2ES2, RegionRenderer).
Definition: Group.java:296
List< Shape > getShapes()
Returns added Shapes.
Definition: Group.java:219
Layout getLayout()
Return current Group.Layout.
Definition: Group.java:150
Group setLayout(final Layout l)
Set Group.Layout.
Definition: Group.java:153
GraphUI Scene.
Definition: Scene.java:103
void addShape(final Shape s)
Adds a Shape.
Definition: Scene.java:292
void addDisposeAction(final GLRunnable action)
Add a user one-time GLRunnable disposal action to an internal list, all invoked at {@Link dispose(GLA...
Definition: Scene.java:657
void init(final GLAutoDrawable drawable)
Called by the drawable immediately after the OpenGL context is initialized.
Definition: Scene.java:412
RegionRenderer getRenderer()
Returns the associated RegionRenderer.
Definition: Scene.java:213
Shape getShapeByID(final int id)
Definition: Scene.java:366
int setAAQuality(final int v)
Sets RegionRenderer#setAAQuality(int).
Definition: Scene.java:388
void dispose(final GLAutoDrawable drawable)
Disposes all added Shapes.
Definition: Scene.java:610
final void setPMVMatrixSetup(final PMVMatrixSetup setup)
Set a custom PMVMatrixSetup.
Definition: Scene.java:752
static float getZEpsilon(final int zBits, final PMVMatrixSetup setup)
Default Z precision on 16-bit depth buffer using -1 z-position and DEFAULT_ZNEAR.
Definition: Scene.java:127
AABBox getBounds(final PMVMatrix4f pmv, final Shape shape)
Returns AABBox dimension of given Shape from this container's perspective, i.e.
Definition: Scene.java:683
synchronized void attachInputListenerTo(final GLWindow window)
Definition: Scene.java:251
void display(final GLAutoDrawable drawable)
Called by the drawable to initiate OpenGL rendering by the client.
Definition: Scene.java:492
void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height)
Reshape scene using setupMatrix(PMVMatrix4f, int, int, int, int) using PMVMatrixSetup.
Definition: Scene.java:463
String getStatusText(final GLAutoDrawable glad, final int renderModes, final float dpi)
Return a formatted status string containing avg fps and avg frame duration.
Definition: Scene.java:1388
File nextScreenshotFile(final String dir, final String prefix, final int renderModes, final GLCapabilitiesImmutable caps, final String contentDetail)
Return the unique next technical screenshot PNG File instance as follows:
Definition: Scene.java:1441
Convenient adapter combining dummy implementation for MouseListener and GestureListener.
Definition: Shape.java:1884
Generic Shape, potentially using a Graph via GraphShape or other means of representing content.
Definition: Shape.java:87
Shape setColor(final float r, final float g, final float b, final float a)
Set base color.
Definition: Shape.java:1389
final Shape move(final float dtx, final float dty, final float dtz)
Move about scaled distance.
Definition: Shape.java:557
final Shape setScale(final Vec3f s)
Set scale factor to given scale.
Definition: Shape.java:641
final Shape setFixedARatioResize(final boolean v)
Sets whether aspect-ratio shall be kept at resize, if isResizable().
Definition: Shape.java:1788
final Shape moveTo(final float tx, final float ty, final float tz)
Move to scaled position.
Definition: Shape.java:543
final float getScaledWidth()
Returns the scaled width of the bounding AABBox for this shape.
Definition: Shape.java:745
final float getScaledHeight()
Returns the scaled height of the bounding AABBox for this shape.
Definition: Shape.java:760
final Vec3f getPosition()
Returns position Vec3f reference, i.e.
Definition: Shape.java:587
final boolean isVisible()
Returns true if this shape is set visible by the user, otherwise false.
Definition: Shape.java:353
final Shape validate(final GL2ES2 gl)
Validates the shape's underlying GLRegion.
Definition: Shape.java:850
final Shape addMouseListener(final MouseGestureListener l)
Definition: Shape.java:1807
final Shape setVisible(final boolean v)
Enable (default) or disable this shape's visibility.
Definition: Shape.java:363
A GraphUI text labeled BaseButton GraphShape.
Definition: Button.java:61
A GraphUI text label GraphShape.
Definition: Label.java:50
boolean setText(final CharSequence text)
Set the text to be rendered.
Definition: Label.java:94
float getScaledLineHeight()
Returns Font#getLineHeight() * getFontScale() * getScaleY().
Definition: Label.java:169
Axis Aligned Bounding Box.
Definition: AABBox.java:54
final float getWidth()
Definition: AABBox.java:879
final float getHeight()
Definition: AABBox.java:883
final AABBox scale(final float s)
Scale this AABBox by a constant around fixed center.
Definition: AABBox.java:750
final Vec3f getCenter()
Returns computed center of this AABBox of getLow() and getHigh().
Definition: AABBox.java:737
PMVMatrix4f implements the basic computer graphics Matrix4f pack using projection (P),...
Visual output device, i.e.
static float[] mmToInch(final float[] ppmm)
Converts [1/mm] to [1/inch] in place.
final float[] getPixelsPerMM(final float[] ppmmStore)
Returns the pixels per millimeter value according to the current mode's surface resolution.
static Display createDisplay(final String name)
Create a Display entity.
static Screen createScreen(final Display display, final int index)
Create a Screen entity.
A screen may span multiple MonitorDevices representing their combined virtual size.
Definition: Screen.java:58
Pointer event of type PointerType.
Definition: MouseEvent.java:74
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 setTitle(final String title)
Definition: GLWindow.java:297
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 addWindowListener(final WindowListener l)
Appends the given com.jogamp.newt.event.WindowListener to the end of the list.
Definition: GLWindow.java:882
CapabilitiesChooser setCapabilitiesChooser(final CapabilitiesChooser chooser)
Set the CapabilitiesChooser to help determine the native visual type.
Definition: GLWindow.java:261
final boolean setSurfaceScale(final float[] pixelScale)
Request a pixel scale in x- and y-direction for the associated NativeSurface, where size_in_pixel_uni...
Definition: GLWindow.java:495
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.
abstract GL setGL(GL gl)
Sets the GL pipeline object for this GLContext.
Factory for pipelining GL instances.
static final GL create(final String pipelineClazzBaseName, final Class<?> reqInterface, final GL downstream, final Object[] additionalArgs)
Creates a pipelined GL instance using the given downstream downstream and optional arguments addition...
static StringBuilder getGLInfo(final GL gl, final StringBuilder sb)
static void dump(final GLAutoDrawable drawable)
Definition: MSAATool.java:51
Complex interactive GraphUI Scene demo with different Button and Label Shapes layout on the screen.
UISceneDemo20(final String fontfilename, final String filmURL, final int renderModes, final boolean debug, final boolean trace)
void display(final GLAutoDrawable drawable)
Called by the drawable to initiate OpenGL rendering by the client.
static void main(final String[] args)
void dispose(final GLAutoDrawable drawable)
Notifies the listener to perform the release of all OpenGL resources per GLContext,...
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.
UISceneDemo20(final String fontfilename, final String filmURL, final float noAADPIThreshold, final boolean debug, final boolean trace)
void init(final GLAutoDrawable drawable)
Called by the drawable immediately after the OpenGL context is initialized.
int fixDefaultAARenderModeWithDPIThreshold(final float dpiV)
Fix default AA rendering bit, forced if having default_aa_setting is true.
int graphAASamples
Sample count for Graph Region AA render-modes: Region#VBAA_RENDERING_BIT or Region#MSAA_RENDERING_BIT...
int graphAAQuality
Pass2 AA-quality rendering for Graph Region AA render-modes: VBAA_RENDERING_BIT.
static float atof(final String str, final float def)
Definition: MiscUtils.java:78
final synchronized void add(final GLAutoDrawable drawable)
Adds a drawable to this animator's list of rendering drawables.
final synchronized Thread setExclusiveContext(final Thread t)
Dedicate all GLAutoDrawable's context to the given exclusive context thread.
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
Custom GLCapabilitiesChooser, filtering out all full screen anti-aliasing (FSAA, multisample) capabil...
float getDescent()
Distance from baseline of lowest descender, a negative value.
float getLineGap()
Typographic line gap, a positive value.
Interface wrapper for font implementation.
Definition: Font.java:60
String getFullFamilyName()
Shall return the family and subfamily name, separated a dash.
AABBox getGlyphBounds(final CharSequence string)
Try using getGlyphBounds(CharSequence, AffineTransform, AffineTransform) to reuse AffineTransform ins...
static String getUTF16String(final char codepoint)
Returns UTF-16 representation of the specified (unicode) codepoint symbol like Character#toChars(int)...
Definition: Font.java:338
Adding mutable surface pixel scale property to implementing class, usually to a NativeSurface impleme...
float[] getMaximumSurfaceScale(final float[] result)
Returns the maximum pixel scale of the associated NativeSurface.
static final float AUTOMAX_PIXELSCALE
Setting surface-pixel-scale of {@value}, results in maximum platform dependent pixel-scale,...
float[] getCurrentSurfaceScale(final float[] result)
Returns the current pixel scale of the associated NativeSurface.
Specifying NEWT's Window functionality:
Definition: Window.java:115
float[] getPixelsPerMM(final float[] ppmmStore)
Returns the pixels per millimeter of this window's NativeSurface according to the main monitor's curr...
MonitorDevice getMainMonitor()
Returns the MonitorDevice with the highest viewport coverage of this window.
void resetFPSCounter()
Reset all performance counter (startTime, currentTime, frame number)
An animator control interface, which implementation may drive a com.jogamp.opengl....
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()
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.
GLContext getContext()
Returns the GLContext associated which this GL object.
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.
static final int GL_COLOR_BUFFER_BIT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_COLOR_BUFFER_BIT" wit...
Definition: GL.java:390
void glClearColor(float red, float green, float blue, float alpha)
Entry point to C language function: void {@native glClearColor}(GLfloat red, GLfloat green,...
static final int GL_DEPTH_TEST
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_DEPTH_TEST" with expr...
Definition: GL.java:43
void glClear(int mask)
Entry point to C language function: void {@native glClear}(GLbitfield mask) Part of GL_ES_VERSION_...
static final int GL_BLEND
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_BLEND" with expressio...
Definition: GL.java:704
static final int GL_DEPTH_BUFFER_BIT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_DEPTH_BUFFER_BIT" wit...
Definition: GL.java:738