JOGL v2.6.0-rc-20250712
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 = "http://archive.org/download/BigBuckBunny_328/BigBuckBunny_512kb.mp4";
190
191 private boolean debug = false;
192 private boolean trace = false;
193
194 private final float noAADPIThreshold;
195 private final Scene scene;
196
197 /** -1 == AUTO, TBD @ init(..) */
198 private int renderModes;
199
200 private final Font font;
201 private final Font fontButtons;
202 private final Font fontSymbols;
203 private final Font fontFPS;
204 private final Uri filmURL;
205
206 private final float relTop = 90f/100f;
207 private final float relMiddle = 22f/100f;
208
209 /** Relative Button Size to Window Height, normalized to 1. */
210 private static final float buttonXSizeNorm = 0.09f; // 0.084f;
211 private static final float fontSizePt = 10f;
212 /** Relative Font Size to Window Height for Main Text, normalized to 1. */
213 private static final float fontSizeFixedNorm = 0.04f;
214 private float dpiV = 96;
215
216 /**
217 * Default DPI threshold value to disable {@link Region#VBAA_RENDERING_BIT VBAA}: {@value} dpi
218 * @see #UISceneDemo20(float)
219 * @see #UISceneDemo20(float, boolean, boolean)
220 */
221 public static final float DefaultNoAADPIThreshold = 200f;
222
223 private int currentText = 0;
224
225 private String actionText = null;
226 private Label[] labels = null;
227 private String[] strings = null;
228 final Group buttonsLeft = new Group();
229 final Group buttonsRight = new Group();
230 private Label truePtSizeLabel = null;
231 private Label jogampLabel = null;
232 private Label fpsLabel = null;
233
234 private GLAutoDrawable cDrawable;
235
236 private final String jogamp = "JogAmp - Jogl Graph Module Demo";
237 private final String truePtSize = fontSizePt+" pt font size label - true scale!";
238
239 private final String longText = "JOGL: Java™ Binding for the OpenGL® API.\n\n"+
240 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec \n"+
241 "Ut purus odio, rhoncus sit amet commodo eget, ullamcorper vel\n"+
242 "quam iaculis urna cursus ornare. Nullam ut felis a ante ultrices\n"+
243 "In hac habitasse platea dictumst. Vivamus et mi a quam lacinia\n"+
244 "Morbi quis bibendum nibh. Donec lectus orci, sagittis in consequat\n"+
245 "Donec ut dolor et nulla tristique varius. In nulla magna, fermentum\n"+
246 "in lorem. Maecenas in ipsum ac justo scelerisque sollicitudin.\n"+
247 "\n"+
248 "Lyford’s in Texas & L’Anse-aux-Griffons in Québec;\n"+
249 "Kwikpak on the Yukon delta, Kvæven in Norway, Kyulu in Kenya, not Rwanda.…\n"+
250 "Ytterbium in the periodic table. Are Toussaint L’Ouverture, Wölfflin, Wolfe,\n"+
251 "\n"+
252 "The quick brown fox jumps over the lazy dog\n";
253
254 /**
255 * @param renderModes
256 */
257 public UISceneDemo20(final int renderModes) {
258 this(null, null, renderModes, false, false);
259 }
260
261 /**
262 * @param filmURL TODO
263 * @param renderModes
264 * @param debug
265 * @param trace
266 */
267 public UISceneDemo20(final String fontfilename, final String filmURL, final int renderModes, final boolean debug, final boolean trace) {
268 this(fontfilename, filmURL, 0f, renderModes, debug, trace);
269 }
270
271 /**
272 * @param filmURL TODO
273 * @param noAADPIThreshold see {@link #DefaultNoAADPIThreshold}
274 * @param debug
275 * @param trace
276 */
277 public UISceneDemo20(final String fontfilename, final String filmURL, final float noAADPIThreshold, final boolean debug, final boolean trace) {
278 this(fontfilename, filmURL, noAADPIThreshold, 0, debug, trace);
279 }
280
281 private UISceneDemo20(final String fontfilename, final String filmURL, final float noAADPIThreshold, final int renderModes, final boolean debug, final boolean trace) {
282 this.noAADPIThreshold = noAADPIThreshold;
283 this.debug = debug;
284 this.trace = trace;
285
286 this.renderModes = renderModes;
287
288 try {
289 if( null == fontfilename ) {
290 font = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeSerif.ttf",
291 FontSetDemos.class.getClassLoader(), FontSetDemos.class).getInputStream(), true);
292 } else {
293 font = FontFactory.get( new File( fontfilename ) );
294 }
295 System.err.println("Font "+font.getFullFamilyName());
296
297 fontButtons = FontFactory.get(FontFactory.UBUNTU).getDefault();
298 fontSymbols = FontFactory.get(FontFactory.SYMBOLS).getDefault();
299 fontFPS = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeMono.ttf",
300 FontSetDemos.class.getClassLoader(), FontSetDemos.class).getInputStream(), true);
301 System.err.println("Font FPS "+fontFPS.getFullFamilyName());
302
303 } catch (final IOException ioe) {
304 throw new RuntimeException(ioe);
305 }
306 try {
307 this.filmURL = Uri.cast( null != filmURL ? filmURL : defaultMediaURL );
308 } catch (final URISyntaxException e1) {
309 throw new RuntimeException(e1);
310 }
311 scene = new Scene(options.graphAASamples);
312 scene.setPMVMatrixSetup(new Scene.DefaultPMVMatrixSetup(-1f));
313 scene.getRenderer().setHintBits(RenderState.BITHINT_GLOBAL_DEPTH_TEST_ENABLED);
314 // scene.setSampleCount(3); // easy on embedded devices w/ just 3 samples (default is 4)?
315 scene.addShape(buttonsLeft);
316 scene.addShape(buttonsRight);
317 }
318
319 private void rotateButtons(final Vec3f angdeg) {
320 angdeg.scale(FloatUtil.PI / 180.0f); // -> radians
321 final List<Shape> sl = new ArrayList<Shape>();
322 sl.addAll(buttonsLeft.getShapes());
323 sl.addAll(buttonsRight.getShapes());
324 for(final Shape s : sl) {
325 s.setRotation( s.getRotation().rotateByEuler( angdeg ) );
326 }
327 }
328
329 private void setButtonsSpacing(final float dx, final float dy) {
330 final List<Shape> sl = new ArrayList<Shape>();
331 sl.addAll(buttonsLeft.getShapes());
332 sl.addAll(buttonsRight.getShapes());
333 for(final Shape s : sl) {
334 if( s instanceof Button ) {
335 final Button lb = (Button) s;
336 final float sx = lb.getSpacing().x()+dx, sy = lb.getSpacing().y()+dy;
337 System.err.println("Spacing: X "+sx+", Y "+sy);
338 lb.setSpacing(sx, sy);
339 }
340 }
341 }
342
343 private void setButtonsCorner(final float dc) {
344 final List<Shape> sl = new ArrayList<Shape>();
345 sl.addAll(buttonsLeft.getShapes());
346 sl.addAll(buttonsRight.getShapes());
347 for(final Shape s : sl) {
348 if( s instanceof BaseButton ) {
349 final BaseButton rb = (BaseButton)s;
350 final float c = rb.getCorner()+dc;
351 System.err.println("Corner: "+c);
352 rb.setCorner(c);
353 }
354 }
355 }
356
357 private void resetButtons() {
358 final List<Shape> sl = new ArrayList<Shape>();
359 sl.addAll(buttonsLeft.getShapes());
360 sl.addAll(buttonsRight.getShapes());
361 for(final Shape s : sl) {
362 if( s instanceof BaseButton ) {
363 final BaseButton b = (BaseButton)s;
364 b.setRotation( b.getRotation().setIdentity() );
365 b.setCorner(BaseButton.ROUND_CORNER);
366 if( b instanceof Button ) {
367 ((Button)b).setSpacing(Button.DEFAULT_SPACING_X, Button.DEFAULT_SPACING_Y);
368 }
369 }
370 }
371 }
372
373 public static final int BUTTON_NEXTTEXT = 100;
374 public static final int BUTTON_FPS = 101;
375 public static final int BUTTON_VSYNC = 102;
376 public static final int BUTTON_QUIT = 102;
377 public static final int BUTTON_MOVIE = 200;
378 public static final int BUTTON_GLEL = 200;
379
380 public Shape getShapeByID(final int name) {
381 return scene.getShapeByID(name);
382 }
383
384 private void initSound(final Shape shape,
385 final com.jogamp.openal.sound3d.Context context,
386 final com.jogamp.openal.sound3d.Source aSource)
387 {
388 final com.jogamp.openal.sound3d.Listener audioListener = AudioSystem3D.getListener();
389 context.makeCurrent(true);
390 try {
391 float[] f3x2;
392 f3x2 = audioListener.getOrientation();
393 System.err.printf("Listener init orientation: at[%.3f %.3f %.3f], up[%.3f %.3f %.3f]%n",
394 f3x2[0], f3x2[1], f3x2[2], f3x2[3], f3x2[4], f3x2[5]);
395 f3x2 = new float[]{ /* at */ 0f, 0f, -1f, /* up */ 0f, 1f, 0f }; // default
396 audioListener.setOrientation(f3x2);
397 f3x2 = audioListener.getOrientation();
398 System.err.printf("Listener set orientation: at[%.3f %.3f %.3f], up[%.3f %.3f %.3f]%n",
399 f3x2[0], f3x2[1], f3x2[2], f3x2[3], f3x2[4], f3x2[5]);
400
401 com.jogamp.openal.sound3d.Vec3f ap = audioListener.getPosition();
402 System.err.printf("Listener init pos: %.3f %.3f %.3f%n", ap.v1, ap.v2, ap.v3);
403 audioListener.setPosition(0, 0, -0.25f);
404 ap = audioListener.getPosition();
405 System.err.printf("Listener set pos: %.3f %.3f %.3f%n", ap.v1, ap.v2, ap.v3);
406
407 System.err.printf("Source init rel: %b%n", aSource.isSourceRelative());
408 aSource.setSourceRelative(false); // default
409 System.err.printf("Source set rel: %b%n", aSource.isSourceRelative());
410
411 ap = aSource.getDirection();
412 System.err.printf("Source init dir: %.3f %.3f %.3f%n", ap.v1, ap.v2, ap.v3);
413
414 final float rollOff0 = aSource.getRolloffFactor();
415 System.err.printf("Source init rollOff: %.3f%n", rollOff0);
416
417 final float refDist0 = aSource.getReferenceDistance();
418 aSource.setReferenceDistance(0.75f); // listener dist is min 0.25 -> 0.5 left; default is 1
419 final float refDist1 = aSource.getReferenceDistance();
420 System.err.printf("Source ref-dist: %.3f -> %.3f%n", refDist0, refDist1);
421
422 ap = aSource.getPosition();
423 System.err.printf("Source init pos: %.3f %.3f %.3f%n", ap.v1, ap.v2, ap.v3);
424 AudioSystem3D.checkError(context.getDevice(), "setup", true, false);
425
426 setSoundPosition(shape, context, aSource);
427 } finally {
428 context.release(true);
429 }
430 }
431
432 private void setSoundPosition(final Shape shape,
433 final com.jogamp.openal.sound3d.Context context,
434 final com.jogamp.openal.sound3d.Source aSource) {
435 AABBox worldBounds;
436 {
437 final PMVMatrix4f pmv = new PMVMatrix4f();
438 worldBounds = scene.getBounds(pmv, shape);
439 }
440 context.makeCurrent(true);
441 try {
442 aSource.setPosition(worldBounds.getCenter().x(), worldBounds.getCenter().y(), worldBounds.getCenter().z());
443 System.err.println("Source pos: "+worldBounds.getCenter());
444 } finally {
445 context.release(true);
446 }
447 }
448
449 private static void setSineSoundLabel(final Button shape, final float freq, final float amp) {
450 final String s;
451 if( shape.isToggleOn() ) {
452 s = String.format("scroll %.0f Hz\nctrl-scroll %.2f amp\nmove spatial", freq, amp);
453 shape.setSpacing(0.05f, 0.20f);
454 } else {
455 s = String.format("click to enable\nf %.0f Hz, a %.2f", freq, amp);
456 shape.setSpacing(Button.DEFAULT_SPACING_X, Button.DEFAULT_SPACING_Y);
457
458 }
459 shape.setText(s);
460 }
461
462 private void initButtons(final GL2ES2 gl) {
463 final boolean pass2Mode = Region.isTwoPass( renderModes ) ;
464 buttonsLeft.removeAllShapes(gl, scene.getRenderer());
465 buttonsRight.removeAllShapes(gl, scene.getRenderer());
466
467 final float buttonLWidth = buttonXSizeNorm;
468 final float buttonLHeight = buttonLWidth / 2.5f;
469 buttonsLeft.setLayout(new GridLayout(buttonLWidth, buttonLHeight, Alignment.Fill, new Gap(buttonLHeight*0.50f, buttonLWidth*0.10f), 7));
470
471 final float buttonRWidth = 2f*buttonLWidth;
472 final float buttonRHeight = 2f*buttonLHeight;
473
474 buttonsRight.setLayout(new GridLayout(1, buttonRWidth, buttonRHeight, Alignment.Fill, new Gap(buttonLHeight*0.50f, buttonLWidth*0.10f)));
475
476 System.err.println("Button Size: "+buttonLWidth+" x "+buttonLHeight);
477 final Vec2f fixedSymSize = new Vec2f(0.0f, 1.0f);
478 final Vec2f symSpacing = new Vec2f(0f, 0.2f);
479
480 BaseButton button;
481 button = new Button(renderModes, fontSymbols, fontSymbols.getUTF16String("fast_forward"), buttonLWidth, buttonLHeight); // next (ffwd)
482 ((Button)button).setSpacing(symSpacing, fixedSymSize);
483 button.setID(BUTTON_NEXTTEXT);
484 button.addMouseListener(new Shape.MouseGestureAdapter() {
485 @Override
486 public void mouseClicked(final MouseEvent e) {
487 if( null != labels[currentText] ) {
488 labels[currentText].setVisible(false);
489 }
490 currentText = (currentText+1)%labels.length;
491 if( null != labels[currentText] ) {
492 labels[currentText].setVisible(true);
493 }
494 } } );
495 button.addMouseListener(dragZoomRotateListener);
496 buttonsLeft.addShape(button);
497
498 button = new Button(renderModes, fontButtons, "Show fps", "Hide fps", buttonLWidth, buttonLHeight, Button.DEFAULT_LABEL_ZOFFSET);
499 button.setID(BUTTON_FPS);
500 button.setToggleable(true);
501 button.setToggle(fpsLabel.isVisible());
502 button.addMouseListener(new Shape.MouseGestureAdapter() {
503 @Override
504 public void mouseClicked(final MouseEvent e) {
505 final GLAnimatorControl a = cDrawable.getAnimator();
506 if( null != a ) {
507 a.resetFPSCounter();
508 }
509 fpsLabel.setVisible(!fpsLabel.isVisible());
510 } } );
511 button.addMouseListener(dragZoomRotateListener);
512 buttonsLeft.addShape(button);
513
514 button = new Button(renderModes, fontButtons, " V-Sync ", buttonLWidth, buttonLHeight);
515 button.setID(BUTTON_VSYNC);
516 button.setToggleable(true);
517 button.setToggle(gl.getSwapInterval()>0);
518 button.addMouseListener(new Shape.MouseGestureAdapter() {
519 @Override
520 public void mouseClicked(final MouseEvent e) {
521 cDrawable.invoke(false, new GLRunnable() {
522 @Override
523 public boolean run(final GLAutoDrawable drawable) {
524 final GL gl = drawable.getGL();
525 gl.setSwapInterval(gl.getSwapInterval()<=0?1:0);
526 final GLAnimatorControl a = drawable.getAnimator();
527 if( null != a ) {
528 a.resetFPSCounter();
529 }
530 return true;
531 }
532 });
533 } } );
534 button.addMouseListener(dragZoomRotateListener);
535 buttonsLeft.addShape(button);
536
537 button = new Button(renderModes, fontButtons, " < Tilt > ", buttonLWidth, buttonLHeight);
538 button.addMouseListener(new Shape.MouseGestureAdapter() {
539 @Override
540 public void mouseClicked(final MouseEvent e) {
541 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
542 if( shapeEvent.objPos.x() < shapeEvent.shape.getBounds().getCenter().x() ) {
543 rotateButtons(new Vec3f( 0f, -5f, 0f ) ); // left-half pressed
544 } else {
545 rotateButtons(new Vec3f( 0f, 5f, 0f ) ); // right-half pressed
546 }
547 }
548 @Override
549 public void mouseWheelMoved(final MouseEvent e) {
550 rotateButtons(new Vec3f( 0f, e.getRotation()[1], 0f ) );
551 } } );
552 buttonsLeft.addShape(button);
553
554 if( pass2Mode ) {
555 button = new Button(renderModes, fontButtons, "< Samples >", buttonLWidth, buttonLHeight);
556 button.addMouseListener(new Shape.MouseGestureAdapter() {
557 @Override
558 public void mouseClicked(final MouseEvent e) {
559 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
560 int sampleCount = scene.getSampleCount();
561 if( shapeEvent.objPos.x() < shapeEvent.shape.getBounds().getCenter().x() ) {
562 // left-half pressed
563 sampleCount--;
564 } else {
565 // right-half pressed
566 sampleCount++;
567 }
568 sampleCount = scene.setSampleCount(sampleCount); // validated / clipped
569 } } );
570 button.addMouseListener(dragZoomRotateListener);
571 buttonsLeft.addShape(button);
572
573 button = new Button(renderModes, fontButtons, "< Quality >", buttonLWidth, buttonLHeight);
574 button.addMouseListener(new Shape.MouseGestureAdapter() {
575 @Override
576 public void mouseClicked(final MouseEvent e) {
577 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
578 if( shapeEvent.shape instanceof GraphShape ) {
579 int quality = scene.getAAQuality();
580 if( shapeEvent.objPos.x() < shapeEvent.shape.getBounds().getCenter().x() ) {
581 // left-half pressed
582 quality--;
583 } else {
584 // right-half pressed
585 quality++;
586 }
587 scene.setAAQuality(quality); // validated / clipped
588 }
589 } } );
590 button.addMouseListener(dragZoomRotateListener);
591 buttonsLeft.addShape(button);
592 }
593
594 button = new Button(renderModes, fontSymbols, fontSymbols.getUTF16String("power_settings_new"), buttonLWidth, buttonLHeight); // exit (power_settings_new)
595 ((Button)button).setSpacing(symSpacing, fixedSymSize);
596 button.setID(BUTTON_QUIT);
597 button.setColor(0.7f, 0.3f, 0.3f, 1.0f);
598 ((Button)button).setLabelColor(1.2f, 1.2f, 1.2f, 1.0f);
599 button.setPressedColorMod(1.1f, 0.0f, 0.0f, 1.0f);
600 button.addMouseListener(new Shape.MouseGestureAdapter() {
601 @Override
602 public void mouseClicked(final MouseEvent e) {
603 MiscUtils.destroyWindow(cDrawable);
604 } } );
605 button.addMouseListener(dragZoomRotateListener);
606 buttonsLeft.addShape(button);
607
608 // second column to the left
609 {
610 button = new Button(renderModes, fontSymbols, fontSymbols.getUTF16String("flip"), buttonLWidth, buttonLHeight); // Y Flip (flip)
611 ((Button)button).setSpacing(symSpacing, fixedSymSize);
612 button.addMouseListener(new Shape.MouseGestureAdapter() {
613 @Override
614 public void mouseClicked(final MouseEvent e) {
615 rotateButtons(new Vec3f ( 0f, 180f, 0f ));
616 } } );
617 button.addMouseListener(dragZoomRotateListener);
618 buttonsLeft.addShape(button);
619
620 button = new Button(renderModes, fontButtons, " X Flip ", buttonLWidth, buttonLHeight);
621 button.addMouseListener(new Shape.MouseGestureAdapter() {
622 @Override
623 public void mouseClicked(final MouseEvent e) {
624 rotateButtons(new Vec3f ( 180f, 0f, 0f ));
625 } } );
626 button.addMouseListener(dragZoomRotateListener);
627 buttonsLeft.addShape(button);
628
629 button = new Button(renderModes, fontButtons, "< Space >", buttonLWidth, buttonLHeight);
630 button.addMouseListener(new Shape.MouseGestureAdapter() {
631 @Override
632 public void mouseClicked(final MouseEvent e) {
633 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
634 final float dx, dy;
635 if( shapeEvent.objPos.x() < shapeEvent.shape.getBounds().getCenter().x() ) {
636 dx=-0.01f; dy=-0.005f;
637 } else {
638 dx=0.01f; dy=0.005f;
639 }
640 setButtonsSpacing(dx, dy);
641 }
642 @Override
643 public void mouseWheelMoved(final MouseEvent e) {
644 setButtonsSpacing(e.getRotation()[0]/100f, e.getRotation()[1]/200f);
645 } } );
646 buttonsLeft.addShape(button);
647
648 button = new Button(renderModes, fontButtons, "< Corner >", buttonLWidth, buttonLHeight);
649 button.addMouseListener(new Shape.MouseGestureAdapter() {
650 @Override
651 public void mouseClicked(final MouseEvent e) {
652 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
653 final float dc;
654 if( shapeEvent.objPos.x() < shapeEvent.shape.getBounds().getCenter().x() ) {
655 dc=-0.1f;
656 } else {
657 dc=0.1f;
658 }
659 setButtonsCorner(dc);
660 }
661 @Override
662 public void mouseWheelMoved(final MouseEvent e) {
663 setButtonsCorner(e.getRotation()[1]/20f);
664 } } );
665 buttonsLeft.addShape(button);
666
667 button = new Button(renderModes, fontSymbols, fontSymbols.getUTF16String("undo"), buttonLWidth, buttonLHeight); // reset (undo)
668 ((Button)button).setSpacing(symSpacing, fixedSymSize);
669 button.addMouseListener(new Shape.MouseGestureAdapter() {
670 @Override
671 public void mouseClicked(final MouseEvent e) {
672 resetButtons();
673 } } );
674 button.addMouseListener(dragZoomRotateListener);
675 buttonsLeft.addShape(button);
676
677 button = new Button(renderModes, fontSymbols, fontSymbols.getUTF16String("camera"), buttonLWidth, buttonLHeight); // snapshot (camera)
678 ((Button)button).setSpacing(symSpacing, fixedSymSize);
679 button.addMouseListener(new Shape.MouseGestureAdapter() {
680 @Override
681 public void mouseClicked(final MouseEvent e) {
682 scene.screenshot(false, scene.nextScreenshotFile(null, UISceneDemo20.class.getSimpleName(), options.renderModes, gl.getContext().getGLDrawable().getChosenGLCapabilities(), null));
683 } } );
684 button.addMouseListener(dragZoomRotateListener);
685 buttonsLeft.addShape(button);
686 }
687
688 //
689 // buttonRight
690 //
691 final int texUnitMediaPlayer, texUnitImageButton, texUnitGLELButton;
692 {
693 // works - but not required ..
694 texUnitMediaPlayer=1;
695 texUnitImageButton=2;
696 texUnitGLELButton=3;
697 }
698
699 if( true ) {
700 final GLMediaPlayer mPlayer = GLMediaPlayerFactory.createDefault();
701 mPlayer.setTextureUnit(texUnitMediaPlayer);
702 mPlayer.setAudioChannelLimit(1); // enforce mono to enjoy spatial 3D position effects
703 button = new MediaButton(renderModes, buttonRWidth, buttonRHeight, mPlayer);
704 button.setID(BUTTON_MOVIE);
705 ((MediaButton)button).setVerbose(false).addDefaultEventListener().setFixedARatioResize(true);
706 button.setToggleable(true);
707 button.setToggle(true); // toggle == false -> mute audio
708 button.setToggleOffColorMod(0f, 1f, 0f, 1.0f);
709 button.addMouseListener(dragZoomRotateListener);
710
711 final ALAudioSink[] alAudioSink = { null };
712
713 button.onToggle( (final Shape s) -> {
714 mPlayer.setAudioVolume( s.isToggleOn() ? 1f : 0f );
715 });
716 mPlayer.addEventListener( new GLMediaEventListener() {
717 @Override
718 public void attributesChanged(final GLMediaPlayer mp, final EventMask eventMask, final long when) {
719 System.err.println("MediaButton AttributesChanges: "+eventMask+", when "+when);
720 System.err.println("MediaButton State: "+mp);
721 if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.Init) ) {
722 final AudioSink audioSink = mp.getAudioSink();
723 if( audioSink instanceof ALAudioSink ) {
724 alAudioSink[0] = (ALAudioSink)audioSink;
725 } else {
726 alAudioSink[0] = null;
727 }
728 }
729 if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.EOS) ) {
730 alAudioSink[0] = null;
731 }
732 }
733
734 });
735 button.onMove((final Shape shape, final Vec3f origin, final Vec3f dest, final MouseEvent e) -> {
736 final ALAudioSink aSink = alAudioSink[0];
737 if( null != aSink && aSink.getContext().isValid() ) {
738 setSoundPosition(shape, aSink.getContext(), aSink.getSource());
739 }
740 } );
741 button.onDraw( (final Shape shape, final GL2ES2 gl_, final RegionRenderer renderer_) -> {
742 final ALAudioSink aSink = alAudioSink[0];
743 if( null != aSink && aSink.getContext().isValid() ) {
744 initSound(shape, aSink.getContext(), aSink.getSource());
745 System.err.println("Media Audio: "+aSink);
746 return true;
747 } else {
748 return false;
749 }
750 });
751 buttonsRight.addShape(button);
752 mPlayer.playStream(filmURL, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_NONE, GLMediaPlayer.TEXTURE_COUNT_DEFAULT);
753 }
754 if( true ) {
755 final SimpleSineSynth sineSound = new SimpleSineSynth();
756 scene.addDisposeAction((final GLAutoDrawable glad) -> {
757 sineSound.stop();
758 return true;
759 } );
760 sineSound.setFreq(200f);
761 sineSound.setAmplitude(0.1f);
762 final Button sineButton = new Button(renderModes, fontButtons, "lala", buttonRWidth, buttonRHeight);
763 button = sineButton;
764 button.setToggleable(true);
765 button.setToggle(false); // toggle == false -> mute audio
766 setSineSoundLabel(sineButton, sineSound.getFreq(), sineSound.getAmplitude());
767
768 final ALAudioSink aSink = sineSound.getSink();
769 final com.jogamp.openal.sound3d.Source aSource = aSink.getSource();
770
771 button.addMouseListener(new Shape.MouseGestureAdapter() {
772 @Override
773 public void mouseReleased(final MouseEvent e) {
774 actionText = null;
775 }
776
777 @Override
778 public void mouseDragged(final MouseEvent e) {
779 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
780 if( e.getPointerCount() == 1 ) {
781 final AABBox worldBounds;
782 {
783 final PMVMatrix4f pmv = new PMVMatrix4f();
784 worldBounds = scene.getBounds(pmv, shapeEvent.shape);
785 }
786 actionText = String.format((Locale)null, "Pos %s", worldBounds.getCenter());
787 }
788 }
789 @Override
790 public void mouseClicked(final MouseEvent e) {
791 final Shape.EventInfo info = (Shape.EventInfo)e.getAttachment();
792 if( info.shape.isToggleOn() ) {
793 sineSound.play();
794 } else {
795 sineSound.pause();
796 }
797 setSineSoundLabel(sineButton, sineSound.getFreq(), sineSound.getAmplitude());
798 }
799 @Override
800 public void mouseWheelMoved(final MouseEvent e) {
801 if( e.isControlDown() ) {
802 final float a1 = sineSound.getAmplitude() + + e.getRotation()[1] / 20f;
803 sineSound.setAmplitude(a1);
804 } else {
805 final float f1 = sineSound.getFreq() + e.getRotation()[1] * 10f;
806 sineSound.setFreq(f1);
807 }
808 setSineSoundLabel(sineButton, sineSound.getFreq(), sineSound.getAmplitude());
809 System.err.println("Sine "+sineSound);
810 } } );
811
812 button.onDraw( (final Shape shape, final GL2ES2 gl_, final RegionRenderer renderer_) -> {
813 if( null != aSink && aSink.getContext().isValid() ) {
814 initSound(shape, aSink.getContext(), aSource);
815 System.err.println("Sine Audio: "+aSink);
816 return true;
817 } else {
818 return false;
819 }
820 } );
821 button.onMove( (final Shape shape, final Vec3f origin, final Vec3f dest, final MouseEvent e) -> {
822 setSoundPosition(shape, aSink.getContext(), aSource);
823 } );
824 buttonsRight.addShape(button);
825 }
826 if( true ) {
827 final ImageSequence imgSeq = new ImageSequence(texUnitImageButton, true);
828 button = new ImageButton(renderModes, buttonRWidth, buttonRHeight, imgSeq);
829 try {
830 imgSeq.addFrame(gl, UISceneDemo20.class, "button-released-145x53.png", TextureIO.PNG);
831 imgSeq.addFrame(gl, UISceneDemo20.class, "button-pressed-145x53.png", TextureIO.PNG);
832 } catch (final IOException e2) {
833 e2.printStackTrace();
834 }
835 imgSeq.setManualStepping(true);
836 button.addMouseListener(dragZoomRotateListener);
837 button.addMouseListener(new Shape.MouseGestureAdapter() {
838 @Override
839 public void mousePressed(final MouseEvent e) {
840 final Shape.EventInfo info = (Shape.EventInfo)e.getAttachment();
841 final ImageButton s = (ImageButton)info.shape;
842 s.setCurrentIdx(1);
843 System.err.println("XXX: "+s);
844 }
845 @Override
846 public void mouseReleased(final MouseEvent e) {
847 final Shape.EventInfo info = (Shape.EventInfo)e.getAttachment();
848 final ImageButton s = (ImageButton)info.shape;
849 s.setCurrentIdx(0);
850 } } );
851 buttonsRight.addShape(button);
852 }
853 if( true ) {
854 // Issues w/ OSX and NewtCanvasAWT when rendering / animating
855 // Probably related to CALayer - FBO - FBO* (of this button)
856 final GearsES2 gears = new GearsES2(0);
857 gears.setVerbose(false);
858 gears.setClearColor(new float[] { 0.9f, 0.9f, 0.9f, 1f } );
859 final boolean[] animate = { true };
860 new Thread(new Runnable() {
861 @Override
862 public void run() {
863 System.err.println("Gears Anim: Waiting");
864 try {
865 gears.waitForInit(true);
866 } catch (final InterruptedException e) { }
867 System.err.println("Gears Anim: Started");
868 while( gears.isInit() ) {
869 if( animate[0] ) {
870 final float ry = ( gears.getRotY() + 1 ) % 360;
871 gears.setRotY(ry);
872 }
873 try {
874 Thread.sleep(15);
875 } catch (final InterruptedException e) { }
876 }
877 System.err.println("Gears Anim: End");
878 }
879 }).start();
880 button = new GLButton(renderModes, buttonRWidth, buttonRHeight,
881 texUnitGLELButton, gears, false /* useAlpha */);
882 button.setID(BUTTON_GLEL);
883 button.setToggleable(true);
884 button.setToggle(false); // toggle == true -> animation
885 ((GLButton)button).setAnimate(false);
886 button.addMouseListener(dragZoomRotateListener);
887 button.addMouseListener(new Shape.MouseGestureAdapter() {
888 @Override
889 public void mouseClicked(final MouseEvent e) {
890 final Shape.EventInfo info = (Shape.EventInfo)e.getAttachment();
891 final GLButton s = (GLButton)info.shape;
892 s.setAnimate( s.isToggleOn() );
893 animate[0] = s.getAnimate();
894 } } );
895 buttonsRight.addShape(button);
896 }
897 }
898
899 private void initTexts() {
900 strings = new String[4];
901 int i = 0;
902
903 strings[i++] = "- Mouse Scroll Over Object\n"+
904 " - General\n"+
905 " - X-Rotation\n"+
906 " - Shift: Y-Rotation\n"+
907 " - Tilt, Space and Corner\n"+
908 " - Their respective action via wheel\n"+
909 " (shift = other value)\n"+
910 "\n"+
911 "- Mouse Drag On Object\n"+
912 " - Click on Object and drag mouse\n"+
913 " - Current postion in status line at bottom\n"+
914 " - Resize when click on 1/4 bottom-left or bottom-right corner.\n"+
915 "\n"+
916 "- Tilt Button Rotate Whole Button Group";
917
918 strings[i++] = "abcdefghijklmn\nopqrstuvwxyz\n"+
919 "ABCDEFGHIJKL\n"+
920 "MNOPQRSTUVWXYZ\n"+
921 "0123456789.:,;(*!?/\\\")$%^&-+@~#<>{}[]";
922
923 strings[i++] = "The quick brown fox jumps over the lazy dog";
924
925 strings[i++] = longText;
926
927 labels = new Label[i];
928
929 currentText = strings.length - 1;
930 }
931
932
933 private static final boolean enableOthers = true;
934
935
936 private void initLabels(final GL2ES2 gl) {
937 jogampLabel = new Label(renderModes, font, fontSizeFixedNorm, jogamp);
938 jogampLabel.addMouseListener(dragZoomRotateListener);
939 jogampLabel.setVisible(enableOthers);
940 scene.addShape(jogampLabel);
941
942 truePtSizeLabel = new Label(renderModes, font, truePtSize);
943 truePtSizeLabel.setVisible(enableOthers);
944 truePtSizeLabel.setColor(0.1f, 0.1f, 0.1f, 1.0f);
945 scene.addShape(truePtSizeLabel);
946
947 /**
948 *
949 * [Label] Display 112.88889 dpi, fontSize 12.0 ppi -> pixelSize 18.814816
950 * [FPS] Display 112.88889 dpi, fontSize 12.0 ppi -> pixelSize 15.679012
951 */
952 fpsLabel = new Label(renderModes, fontFPS, "Nothing there yet");
953 fpsLabel.addMouseListener(dragZoomRotateListener);
954 fpsLabel.setVisible(enableOthers);
955 fpsLabel.setColor(0.1f, 0.1f, 0.1f, 1.0f);
956 scene.addShape(fpsLabel);
957 }
958
959 @Override
960 public void init(final GLAutoDrawable drawable) {
961 final Object upObj = drawable.getUpstreamWidget();
962 if( upObj instanceof Window ) {
963 final Window upWin = (Window)upObj;
964 final MonitorDevice monitor = upWin.getMainMonitor();
965 final float[] monitorDPI = MonitorDevice.perMMToPerInch( monitor.getPixelsPerMM(new float[2]) );
966 final float[] sDPI = MonitorDevice.perMMToPerInch( upWin.getPixelsPerMM(new float[2]) );
967 dpiV = sDPI[1];
968 System.err.println("Monitor detected: "+monitor);
969 System.err.println("Monitor dpi: "+monitorDPI[0]+" x "+monitorDPI[1]);
970 System.err.println("Surface scale: native "+Arrays.toString(upWin.getMaximumSurfaceScale(new float[2]))+", current "+Arrays.toString(upWin.getCurrentSurfaceScale(new float[2])));
971 System.err.println("Surface dpi "+sDPI[0]+" x "+sDPI[1]);
972 } else {
973 System.err.println("Using default DPI of "+dpiV);
974 }
975 if( 0 == renderModes && !FloatUtil.isZero(noAADPIThreshold)) {
976 final boolean noAA = dpiV >= noAADPIThreshold;
977 final String noAAs = noAA ? " >= " : " < ";
978 System.err.println("AUTO RenderMode: dpi "+dpiV+noAAs+noAADPIThreshold+" -> noAA "+noAA);
979 renderModes = noAA ? 0 : Region.VBAA_RENDERING_BIT;
980 }
981 if(drawable instanceof GLWindow) {
982 System.err.println("UISceneDemo20: init (1)");
983 final GLWindow glw = (GLWindow) drawable;
984 scene.attachInputListenerTo(glw);
985 } else {
986 System.err.println("UISceneDemo20: init (0)");
987 }
988 cDrawable = drawable;
989 GL2ES2 gl = drawable.getGL().getGL2ES2();
990 if(debug) {
991 gl = gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Debug", null, gl, null) ).getGL2ES2();
992 }
993 if(trace) {
994 gl = gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Trace", null, gl, new Object[] { System.err } ) ).getGL2ES2();
995 }
996 System.err.println(JoglVersion.getGLInfo(gl, null, false /* withCapsAndExts */).toString());
997 System.err.println("VSync Swap Interval: "+gl.getSwapInterval());
998 System.err.println("Chosen: "+drawable.getChosenGLCapabilities());
999 MSAATool.dump(drawable);
1000
1001 gl.setSwapInterval(1);
1002 gl.glEnable(GL.GL_DEPTH_TEST);
1003 gl.glEnable(GL.GL_BLEND);
1004
1005 initTexts();
1006 initLabels(gl);
1007 initButtons(gl);
1008
1009 scene.setAAQuality(options.graphAAQuality);
1010
1011 scene.init(drawable);
1012
1013 final GLAnimatorControl a = drawable.getAnimator();
1014 if( null != a ) {
1015 a.resetFPSCounter();
1016 }
1017 }
1018
1019 @Override
1020 public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
1021 System.err.println("UISceneDemo20: reshape: "+x+"/"+y+" "+width+"x"+height);
1022 System.err.println("UISceneDemo20: drawable: "+drawable);
1023
1024 //
1025 // Layout all shapes: Relational move regarding object coordinates
1026 //
1027 System.err.println("Reshape: Scene Plane.0 "+scene.getBounds());
1028 final float lastSceneWidth = scene.getBounds().getWidth();
1029 final float lastSceneHeight = scene.getBounds().getHeight();
1030 System.err.println("Reshape: Scene Plane.0 "+lastSceneWidth+" x "+lastSceneHeight);
1031
1032 scene.reshape(drawable, x, y, width, height);
1033 final AABBox sceneBox = scene.getBounds();
1034 final float zEpsilon = scene.getZEpsilon(16);
1035 System.err.println("Reshape: Scene Plane.1 "+sceneBox);
1036 System.err.println("Reshape: Scene zEpsilon "+zEpsilon);
1037
1038 final float sceneWidth = sceneBox.getWidth();
1039 final float sceneHeight = sceneBox.getHeight();
1040 final float button_sxy = sceneWidth > sceneHeight ? sceneWidth : sceneHeight;
1041
1042 TreeTool.forAll(buttonsLeft, (final Shape s) -> { if( s instanceof Button) { ((Button)s).setLabelZOffset(zEpsilon); } return false; } );
1043 TreeTool.forAll(buttonsRight, (final Shape s) -> { if( s instanceof Button) { ((Button)s).setLabelZOffset(zEpsilon); } return false; } );
1044 buttonsLeft.validate(drawable.getGL().getGL2ES2());
1045 buttonsRight.validate(drawable.getGL().getGL2ES2());
1046
1047 buttonsLeft.setScale(button_sxy, button_sxy, 1f);
1048 buttonsRight.setScale(button_sxy, button_sxy, 1f);
1049
1050 final float dz = 0f;
1051 final float dxLeft = sceneBox.getMinX();
1052 final float dyBottom = sceneBox.getMinY();
1053 final float dyTop = dyBottom + sceneHeight * relTop;
1054
1055 System.err.println("XXX: dw "+sceneWidth+", dh "+sceneHeight+", dyTop "+dyTop);
1056 System.err.println("BL "+buttonsLeft);
1057 System.err.println("BL "+buttonsLeft.getLayout());
1058 System.err.println("BR "+buttonsRight);
1059 System.err.println("BR "+buttonsRight.getLayout());
1060 buttonsLeft.moveTo(dxLeft, dyTop - buttonsLeft.getScaledHeight(), dz);
1061 buttonsRight.moveTo(dxLeft + sceneWidth - buttonsRight.getScaledWidth(), dyTop - buttonsRight.getScaledHeight(), dz);
1062
1063 jogampLabel.setScale(sceneHeight, sceneHeight, 1f);
1064
1065 final float dxMiddleAbs = dxLeft + sceneWidth * relMiddle;
1066 final float dyTopLabelAbs = dyBottom + sceneHeight - jogampLabel.getScaledLineHeight();
1067 jogampLabel.moveTo(dxMiddleAbs, dyTopLabelAbs - jogampLabel.getScaledLineHeight(), dz);
1068 {
1069 final float pixelSize10Pt = FontScale.toPixels(fontSizePt, dpiV);
1070 final float scale = pixelSize10Pt / height * sceneHeight; // normalize with dpi / surfaceHeight
1071 System.err.println("10Pt PixelSize: Display "+dpiV+" dpi, fontSize "+fontSizePt+" pt, "+FontScale.ptToMM(fontSizePt)+" mm -> "+pixelSize10Pt+" pixels, "+scale+" scene-size");
1072 truePtSizeLabel.setScale(scale, scale, 1f);
1073 truePtSizeLabel.moveTo(dxMiddleAbs, dyTopLabelAbs - jogampLabel.getScaledLineHeight() - truePtSizeLabel.getScaledLineHeight(), dz);
1074 }
1075 {
1076 final AABBox fbox = fontFPS.getGlyphBounds(scene.getStatusText(drawable, renderModes, dpiV));
1077 final float scale = sceneWidth / ( 1.4f * fbox.getWidth() ); // add 40% width
1078 fpsLabel.setScale(scale, scale, 1f);
1079 fpsLabel.moveTo(sceneBox.getMinX(), sceneBox.getMinY() + scale * ( fontFPS.getMetrics().getLineGap() - fontFPS.getMetrics().getDescent() ), 0f);
1080 fpsLabel.validate(drawable.getGL().getGL2ES2());
1081 System.err.println("StatusLabel Scale: " + scale + " = " + sceneWidth + " / " + fbox.getWidth() + ", " + fbox);
1082 System.err.println("StatusLabel: " + fpsLabel);
1083 }
1084 if( null != labels[currentText] ) {
1085 labels[currentText].setScale(sceneHeight, sceneHeight, 1f);
1086 labels[currentText].moveTo(dxMiddleAbs,
1087 dyTopLabelAbs - jogampLabel.getScaledLineHeight()
1088 - 1.5f * truePtSizeLabel.getScaledLineHeight()
1089 - labels[currentText].getScaledHeight(), 0f);
1090 System.err.println("Label["+currentText+"] MOVE: "+labels[currentText]);
1091 System.err.println("Label["+currentText+"] MOVE: "+labels[currentText].getPosition());
1092 }
1093 }
1094
1095 @Override
1096 public void dispose(final GLAutoDrawable drawable) {
1097 System.err.println("UISceneDemo20: dispose");
1098
1099 scene.dispose(drawable); // disposes all registered UIShapes
1100 }
1101
1102 @Override
1103 public void display(final GLAutoDrawable drawable) {
1104 // System.err.println("UISceneDemo20: display");
1105 final GL2ES2 gl = drawable.getGL().getGL2ES2();
1106 gl.glClearColor(1f, 1f, 1f, 1f);
1108
1109 if(null == labels[currentText]) {
1110 final AABBox sbox = scene.getBounds();
1111 final float sceneHeight = sbox.getHeight();
1112 final float dyTop = sbox.getMinY() + sbox.getHeight() - jogampLabel.getScaledLineHeight();
1113 final float dxMiddle = sbox.getMinX() + sbox.getWidth() * relMiddle;
1114 labels[currentText] = new Label(renderModes, font, fontSizeFixedNorm, strings[currentText]);
1115 labels[currentText].setScale(sceneHeight, sceneHeight, 1f);
1116 labels[currentText].setColor(0.1f, 0.1f, 0.1f, 1.0f);
1117 labels[currentText].setVisible(enableOthers);
1118 labels[currentText].setFixedARatioResize(true);
1119 labels[currentText].validate(gl);
1120 labels[currentText].move(dxMiddle,
1121 dyTop - jogampLabel.getScaledLineHeight()
1122 - 1.5f * truePtSizeLabel.getScaledLineHeight()
1123 - labels[currentText].getScaledHeight(), 0f);
1124 labels[currentText].addMouseListener(dragZoomRotateListener);
1125 scene.addShape(labels[currentText]);
1126 System.err.println("Label["+currentText+"] CTOR: "+labels[currentText]);
1127 System.err.println("Label["+currentText+"] CTOR: "+labels[currentText].getPosition());
1128 }
1129 if( fpsLabel.isVisible() ) {
1130 final String text;
1131 if( null == actionText ) {
1132 text = scene.getStatusText(drawable, renderModes, dpiV);
1133 } else if( null != drawable.getAnimator() ) {
1134 text = Scene.getStatusText(drawable.getAnimator())+", "+actionText;
1135 } else {
1136 text = actionText;
1137 }
1138 if( fpsLabel.setText(text) ) { // marks dirty only if text differs.
1139 // System.err.println(text);
1140 }
1141 }
1142 scene.display(drawable);
1143 }
1144
1145 /**
1146 * We can share this instance w/ all UI elements,
1147 * since only mouse action / gesture is complete for a single one (press, drag, released and click).
1148 */
1149 private final Shape.MouseGestureAdapter dragZoomRotateListener = new Shape.MouseGestureAdapter() {
1150 @Override
1151 public void mouseReleased(final MouseEvent e) {
1152 actionText = null;
1153 }
1154
1155 @Override
1156 public void mouseDragged(final MouseEvent e) {
1157 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
1158 if( e.getPointerCount() == 1 ) {
1159 final AABBox worldBounds;
1160 {
1161 final PMVMatrix4f pmv = new PMVMatrix4f();
1162 worldBounds = scene.getBounds(pmv, shapeEvent.shape);
1163 }
1164 actionText = String.format((Locale)null, "Pos %s", worldBounds.getCenter());
1165 }
1166 }
1167
1168 @Override
1169 public void mouseWheelMoved(final MouseEvent e) {
1170 final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment();
1171 final Vec3f rot = new Vec3f(e.getRotation()).scale( FloatUtil.PI / 180.0f );
1172 // swap axis for onscreen rotation matching natural feel
1173 final float tmp = rot.x(); rot.setX( rot.y() ); rot.setY( tmp );
1174 shapeEvent.shape.setRotation( shapeEvent.shape.getRotation().rotateByEuler( rot.scale( 2f ) ) );
1175 }
1176 };
1177}
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:102
void addShape(final Shape s)
Adds a Shape.
Definition: Scene.java:287
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:650
void init(final GLAutoDrawable drawable)
Called by the drawable immediately after the OpenGL context is initialized.
Definition: Scene.java:407
RegionRenderer getRenderer()
Returns the associated RegionRenderer.
Definition: Scene.java:208
Shape getShapeByID(final int id)
Definition: Scene.java:361
int setAAQuality(final int v)
Sets RegionRenderer#setAAQuality(int).
Definition: Scene.java:383
void dispose(final GLAutoDrawable drawable)
Disposes all added Shapes.
Definition: Scene.java:605
final void setPMVMatrixSetup(final PMVMatrixSetup setup)
Set a custom PMVMatrixSetup.
Definition: Scene.java:745
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:126
AABBox getBounds(final PMVMatrix4f pmv, final Shape shape)
Returns AABBox dimension of given Shape from this container's perspective, i.e.
Definition: Scene.java:676
synchronized void attachInputListenerTo(final GLWindow window)
Definition: Scene.java:246
void display(final GLAutoDrawable drawable)
Called by the drawable to initiate OpenGL rendering by the client.
Definition: Scene.java:487
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:458
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:1381
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:1434
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
Basic Float math utility functions.
Definition: FloatUtil.java:83
static boolean isZero(final float a, final float epsilon)
Returns true if value is zero, i.e.
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[] perMMToPerInch(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.
static final float DefaultNoAADPIThreshold
Default DPI threshold value to disable VBAA: {@value} dpi.
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