aboutsummaryrefslogtreecommitdiffstats
path: root/src/demos/com/jogamp/opengl
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-03-19 16:09:52 +0100
committerSven Gothel <[email protected]>2023-03-19 16:09:52 +0100
commita43869543093d0bbd154df7ea6908a5b53a8302e (patch)
tree34afcd743f2d118b35f510719ed85111047ca89f /src/demos/com/jogamp/opengl
parent01d35625f848ed3a97fae750ff2e8928f9d6538a (diff)
GraphUI: Add UISceneDemo00 for linear animation in one main function; UISceneDemo01 simply provides shape drag-move and -resize
Diffstat (limited to 'src/demos/com/jogamp/opengl')
-rw-r--r--src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo00.java161
-rw-r--r--src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo01.java77
2 files changed, 192 insertions, 46 deletions
diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo00.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo00.java
new file mode 100644
index 000000000..76ee7389d
--- /dev/null
+++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo00.java
@@ -0,0 +1,161 @@
+/**
+ * Copyright 2010-2023 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.demos.graph.ui;
+
+import java.io.IOException;
+
+import com.jogamp.common.os.Clock;
+import com.jogamp.graph.curve.Region;
+import com.jogamp.graph.font.Font;
+import com.jogamp.graph.font.FontFactory;
+import com.jogamp.graph.font.FontSet;
+import com.jogamp.graph.geom.SVertex;
+import com.jogamp.graph.ui.gl.Scene;
+import com.jogamp.graph.ui.gl.Shape;
+import com.jogamp.graph.ui.gl.shapes.Button;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.GLCapabilities;
+import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.GLRunnable;
+import com.jogamp.opengl.math.geom.AABBox;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.util.PMVMatrix;
+
+/**
+ * Res independent Shape, in Scene attached to GLWindow showing simple linear Shape movement within one main function.
+ */
+public class UISceneDemo00 {
+ public static void main(final String[] args) throws IOException {
+ final int surface_width = 1280, surface_height = 720;
+ final int renderModes = Region.VBAA_RENDERING_BIT;
+ final GLProfile glp = GLProfile.getGL2ES2();
+
+ //
+ // Resolution independent, no screen size
+ //
+ final Font font = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_SERIF);
+ System.err.println("Font: "+font.getFullFamilyName());
+
+ final Shape shape = new Button(SVertex.factory(), renderModes, font, "+", 0.10f, 0.10f/2.5f);
+ System.err.println("Shape bounds "+shape.getBounds(glp));
+
+ final Scene scene = new Scene();
+ scene.setClearParams(new float[] { 1f, 1f, 1f, 1f}, GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+ scene.addShape(shape);
+
+ final Animator animator = new Animator();
+ animator.setUpdateFPSFrames(1*60, System.err);
+
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setAlphaBits(4);
+ System.out.println("Requested: " + caps);
+
+ final GLWindow window = GLWindow.create(caps);
+ window.setSize(surface_width, surface_height);
+ window.setTitle(UISceneDemo00.class.getSimpleName()+": "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight());
+ window.setVisible(true);
+ window.addGLEventListener(scene);
+ window.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowDestroyed(final WindowEvent e) {
+ animator.stop();
+ }
+ });
+
+ scene.attachInputListenerTo(window);
+
+ animator.add(window);
+ animator.start();
+
+ //
+ // After initial display we can use screen resolution post initial Scene.reshape(..)
+ // However, in this example we merely use the resolution to
+ // - Scale the shape to the sceneBox, i.e. normalizing to screen-size 1x1
+ // - Compute the animation values with DPI
+ scene.waitUntilDisplayed();
+
+ final AABBox sceneBox = scene.getBounds();
+ shape.scale(sceneBox.getWidth(), sceneBox.getWidth(), 1f); // scale shape to sceneBox, normalizing to screen-size 1x1
+ try { Thread.sleep(1000); } catch (final InterruptedException e1) { }
+
+ //
+ // Compute the metric animation values -> shape obj-velocity
+ //
+ final float min_obj = sceneBox.getMinX();
+ final float max_obj = sceneBox.getMaxX() - shape.getScaledWidth();
+
+ final int[] shapeSizePx = shape.getSurfaceSize(scene, new PMVMatrix(), new int[2]); // [px]
+ final float[] pixPerShapeUnit = shape.getPixelPerShapeUnit(shapeSizePx, new float[2]); // [px]/[shapeUnit]
+
+ final float pixPerMM = window.getPixelsPerMM(new float[2])[0]; // [px]/[mm]
+ final float dist_px = scene.getWidth() - shapeSizePx[0]; // [px]
+ final float dist_m = dist_px/pixPerMM/1e3f; // [m]
+ final float velocity = 50/1e3f; // [m]/[s]
+ final float velocity_px = velocity * 1e3f * pixPerMM; // [px]/[s]
+ final float velovity_obj = velocity_px / pixPerShapeUnit[0]; // [shapeUnit]/[s]
+ final float exp_dur_s = dist_m / velocity; // [s]
+
+ System.err.println();
+ System.err.printf("Shape: %d x %d [pixel], %.4f px/shape_unit%n", shapeSizePx[0], shapeSizePx[1], pixPerShapeUnit[0]);
+ System.err.printf("Shape: %s%n", shape);
+ System.err.println();
+ System.err.printf("Distance: %.0f pixel @ %.3f px/mm, %.3f mm%n", dist_px, pixPerMM, dist_m*1e3f);
+ System.err.printf("Velocity: %.3f mm/s, %.3f px/s, %.6f obj/s, expected travel-duration %.3f s%n",
+ velocity*1e3f, velocity_px, velovity_obj, exp_dur_s);
+
+ final long t0_us = Clock.currentNanos() / 1000; // [us]
+ long t1_us = t0_us;
+ shape.moveTo(min_obj, 0f, 0f); // move shape to min start position
+ while( shape.getPosition()[0] < max_obj ) {
+ final long t2_us = Clock.currentNanos() / 1000;
+ final float dt_s = ( t2_us - t1_us ) / 1e6f;
+ t1_us = t2_us;
+
+ final float dx = velovity_obj * dt_s; // [shapeUnit]
+ // System.err.println("move ")
+
+ // Move on GL thread to have vsync for free
+ // Otherwise we would need to employ a sleep(..) w/ manual vsync
+ window.invoke(true, new GLRunnable() {
+ @Override
+ public boolean run(final GLAutoDrawable drawable) {
+ shape.move(dx, 0f, 0f);
+ return true;
+ }
+ });
+ }
+ final float has_dur_s = ( ( Clock.currentNanos() / 1000 ) - t0_us ) / 1e6f; // [us]
+ System.err.printf("Actual travel-duration %.3f s, delay %.3f s%n", has_dur_s, has_dur_s-exp_dur_s);
+ try { Thread.sleep(1000); } catch (final InterruptedException e1) { }
+ window.destroy();
+ }
+}
diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo01.java
index e580ded9a..221fb5f12 100644
--- a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo01.java
+++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo01.java
@@ -63,7 +63,9 @@ import com.jogamp.opengl.util.av.GLMediaPlayer;
import com.jogamp.opengl.util.av.GLMediaPlayerFactory;
/**
- * Res independent Shape, in Scene attached to GLWindow showing simple linear Shape movement w/ listener attached.
+ * Res independent Shape, in Scene attached to GLWindow w/ listener attached.
+ *
+ * User can test Shape drag-move and drag-resize w/ 1-pointer
*/
public class UISceneDemo01 {
static final boolean DEBUG = false;
@@ -109,20 +111,6 @@ public class UISceneDemo01 {
}
}
}
- if( null == font ) {
- font = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_SERIF);
- }
- System.err.println("Font: "+font.getFullFamilyName());
-
- final GLProfile glp = GLProfile.getGL2ES2();
- final GLCapabilities caps = new GLCapabilities(glp);
- caps.setAlphaBits(4);
- if( sceneMSAASamples > 0 ) {
- caps.setSampleBuffers(true);
- caps.setNumSamples(sceneMSAASamples);
- }
- System.out.println("Requested: " + caps);
-
final int renderModes;
if( graphVBAAMode ) {
renderModes = Region.VBAA_RENDERING_BIT;
@@ -131,11 +119,23 @@ public class UISceneDemo01 {
} else {
renderModes = 0;
}
+ final GLProfile glp = GLProfile.getGL2ES2();
+
+ //
+ // Resolution independent, no screen size
+ //
+ if( null == font ) {
+ font = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_SERIF);
+ }
+ System.err.println("Font: "+font.getFullFamilyName());
+ final Shape shape = makeShape(font, renderModes);
+ System.err.println("m0 shape bounds "+shape.getBounds(glp));
+ System.err.println("m0 "+shape);
+ // Scene for Shape ...
final Scene scene = new Scene();
scene.setClearParams(new float[] { 1f, 1f, 1f, 1f}, GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
- final Shape shape = makeShape(font, renderModes);
shape.onMove(new Shape.Listener() {
@Override
public void run(final Shape shape) {
@@ -163,11 +163,13 @@ public class UISceneDemo01 {
} );
scene.addShape(shape);
- final AABBox shapeBox = shape.getBounds(glp);
- System.err.println("m0 "+shape);
-
-
- // scene.surfaceToPlaneSize(width, height, null);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setAlphaBits(4);
+ if( sceneMSAASamples > 0 ) {
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(sceneMSAASamples);
+ }
+ System.out.println("Requested: " + caps);
final GLWindow window = GLWindow.create(caps);
window.setSize(width, height);
@@ -201,35 +203,20 @@ public class UISceneDemo01 {
animator.start();
+ //
+ // After initial display we can use screen resolution post initial Scene.reshape(..)
+ // However, in this example we merely use the resolution to
+ // - Scale the shape to the sceneBox, i.e. normalizing to screen-size 1x1
scene.waitUntilDisplayed();
final AABBox sceneBox = scene.getBounds();
- System.err.println("m1 scene "+sceneBox);
- System.err.println("m1.0 "+shape);
shape.scale(sceneBox.getWidth(), sceneBox.getWidth(), 1f); // scale shape to sceneBox
System.err.println("m1.1 "+shape);
- shape.scale(0.4f, 0.4f, 1f); // scale shape even smaller
- System.err.println("m1.2 "+shape);
try { Thread.sleep(1000); } catch (final InterruptedException e1) { }
- final float min = sceneBox.getMinX();
- final float max = sceneBox.getMaxX() - shapeBox.getWidth()*shape.getScaleX();
- shape.moveTo(min, 0f, 0f); // move shape to min start position
-
- final float step = (max-min)/1000f;
- System.err.println("m2 ["+min+" .. "+max+"], step "+step);
- for(float x=min; x < max; x+=step) {
- shape.move(step, 0f, 0f);
- final int[] glWinPos = shape.shapeToWinCoord(scene.getPMVMatrixSetup(), scene.getViewport(), shape.getBounds().getCenter(), new PMVMatrix(), new int[2]);
- if( null != glWinPos ) {
- window.warpPointer(glWinPos[0], window.getHeight() - glWinPos[1] - 1);
- }
- System.err.println("mm x "+x+", ["+min+" .. "+max+"], step "+step);
- try { Thread.sleep(5); } catch (final InterruptedException e1) { }
- }
- try { Thread.sleep(1000); } catch (final InterruptedException e1) { }
- System.err.println("The End ..");
- window.destroy();
+ System.err.println("You may test moving the Shape by dragging the shape with 1-pointer.");
+ System.err.println("You may test resizing the Shape by dragging the shape on 1/5th of the bottom-left or bottom-right corner with 1-pointer.");
+ System.err.println("Press F4 or 'window close' to exit ..");
}
static void testProject(final Scene scene, final Shape shape, final int glWinX, final int glWinY) {
@@ -244,9 +231,8 @@ public class UISceneDemo01 {
@SuppressWarnings("unused")
static Shape makeShape(final Font font, final int renderModes) {
- final float sw = 0.2f;
+ final float sw = 0.10f;
final float sh = sw / 2.5f;
- System.err.println("Shape "+sw+" x "+sh);
if( false ) {
Uri filmUri;
@@ -292,7 +278,6 @@ public class UISceneDemo01 {
return b;
} else if( true ){
final Button b = new Button(SVertex.factory(), renderModes, font, "+", sw, sh);
- // b.setLabelColor(0.0f,0.0f,0.0f);
b.setCorner(0.0f);
return b;
} else {