summaryrefslogtreecommitdiffstats
path: root/src/test/com/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-02-16 05:39:04 +0100
committerSven Gothel <[email protected]>2023-02-16 05:39:04 +0100
commit996ffe0df682981c0eba88130e134c4f94a06415 (patch)
tree61493e9d8a63f091fd8b392efa3e62c306f6f259 /src/test/com/jogamp
parent6558c7b744525d1db5fe1f0a227958e4f0025622 (diff)
Graph Unit Tests: General cleanup, adding UITypeDemo01 w/ TestObject* to determine CurveRenderer issues
Diffstat (limited to 'src/test/com/jogamp')
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/FontSet01.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextGLListener0A.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java93
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Rectangle.java113
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TestObject01.java294
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TestObject02.java352
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShapeDemo01.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UITypeDemo01.java584
9 files changed, 1400 insertions, 52 deletions
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/FontSet01.java b/src/test/com/jogamp/opengl/test/junit/graph/FontSet01.java
index 38eda9adf..a2dc8430d 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/FontSet01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/FontSet01.java
@@ -12,8 +12,8 @@ public class FontSet01 {
final Font[] fonts = new Font[11];
int i = 0;
fonts[i++] = FontFactory.get(FontFactory.UBUNTU).getDefault(); // FontSet.FAMILY_REGULAR, FontSet.STYLE_NONE
- fonts[i++] = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_REGULAR, FontSet.STYLE_ITALIC);
- fonts[i++] = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_REGULAR, FontSet.STYLE_BOLD);
+ fonts[i++] = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_NONE);
+ fonts[i++] = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_ITALIC);
fonts[i++] = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeMono.ttf",
TestTextRendererNEWTBugXXXX.class.getClassLoader(), TestTextRendererNEWTBugXXXX.class).getInputStream(), true);
fonts[i++] = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeMonoBold.ttf",
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextGLListener0A.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextGLListener0A.java
index bf0a907b0..5b7044fee 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextGLListener0A.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextGLListener0A.java
@@ -39,14 +39,11 @@ import com.jogamp.newt.opengl.GLWindow;
public class GPUTextGLListener0A extends GPUTextRendererListenerBase01 {
- public GPUTextGLListener0A() {
- super(RenderState.createRenderState(SVertex.factory()), Region.VBAA_RENDERING_BIT, 4, true, false, false);
- }
-
public GPUTextGLListener0A(final RenderState rs, final int renderModes, final int sampleCount, final boolean blending, final boolean debug, final boolean trace) {
super(rs, renderModes, sampleCount, blending, debug, trace);
}
+ @Override
public void init(final GLAutoDrawable drawable) {
if(drawable instanceof GLWindow) {
final GLWindow glw = (GLWindow) drawable;
@@ -64,6 +61,7 @@ public class GPUTextGLListener0A extends GPUTextRendererListenerBase01 {
rs.setColorStatic(0.1f, 0.1f, 0.1f, 1.0f);
}
+ @Override
public void dispose(final GLAutoDrawable drawable) {
if(drawable instanceof GLWindow) {
final GLWindow glw = (GLWindow) drawable;
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo.java
index ade84b3a3..59956b435 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo.java
@@ -148,7 +148,7 @@ public class GPUTextNewtDemo {
// FPSAnimator animator = new FPSAnimator(60);
final Animator animator = new Animator();
- animator.setUpdateFPSFrames(60, System.err);
+ // animator.setUpdateFPSFrames(60, System.err);
animator.add(window);
window.addKeyListener(new KeyAdapter() {
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
index e49d2a9e4..b86cc60aa 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
@@ -154,15 +154,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
this.regionFPS = GLRegion.create(renderModes, null);
this.regionHead = GLRegion.create(renderModes, null);
this.regionBottom = GLRegion.create(renderModes, null);
- try {
- // this.font = FontFactory.get(fontSet).getDefault();
- this.font = FontFactory.get(fontSet).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_NONE);
-
- this.fontName = font.toString();
- } catch (final IOException ioe) {
- System.err.println("Caught: "+ioe.getMessage());
- ioe.printStackTrace();
- }
+ setFontSet(fontSet, FontSet.FAMILY_LIGHT, FontSet.STYLE_NONE);
setMatrix(0, 0, 0, 0f, sampleCount);
}
@@ -206,6 +198,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
}
final int w2 = Math.max(window.getSurfaceWidth(), w);
final int h2 = Math.max(window.getSurfaceHeight(), h);
+ System.err.println("upsizeWindowSurface: "+window.getSurfaceWidth()+"x"+window.getSurfaceHeight()+" -> "+w+"x"+h+" -> "+w2+"x"+h2);
if( off_thread ) {
new InterruptSource.Thread() {
@Override
@@ -231,9 +224,17 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
} else {
System.err.println("Using vertical default DPI of "+dpiV+", "+ppmmV+" pixel/mm");
}
- fontNameBox = font.getMetricBounds(fontName);
+ fontNameBox = font.getGlyphBounds(fontName);
setHeadBox(headType, true);
-
+ {
+ final float pixelSizeFName = FontScale.toPixels(fontSizeFName, dpiV);
+ System.err.println("XXX: fontName size "+fontSizeFName+"pt, dpiV "+dpiV+" -> "+pixelSizeFName+"px");
+ System.err.println("XXX: fontName boxM fu "+font.getMetricBoundsFU(fontName));
+ System.err.println("XXX: fontName boxG fu "+font.getGlyphBoundsFU(fontName));
+ System.err.println("XXX: fontName boxM em "+font.getMetricBounds(fontName));
+ System.err.println("XXX: fontName boxG em "+font.getGlyphBounds(fontName));
+ System.err.println("XXX: fontName box height px "+(fontNameBox.getHeight() * pixelSizeFName));
+ }
}
@Override
@@ -299,6 +300,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
renderer.enable(gl, true);
if( drawFPS ) {
+ pmv.glPushMatrix();
final float pixelSizeFPS = FontScale.toPixels(fontSizeFPS, dpiV);
final float lfps, tfps, td;
final GLAnimatorControl animator = drawable.getAnimator();
@@ -328,27 +330,29 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
}
// No cache, keep region alive!
TextRegionUtil.drawString3D(gl, regionFPS, renderer, font, text, null, sampleCountFPS);
+ pmv.glPopMatrix();
}
- float dx = width - ( fontNameBox.getWidth() - font.getAdvanceWidth(Glyph.ID_SPACE) ) * pixelSizeFName;
+ // float dx = width - ( fontNameBox.getWidth() + font.getAdvanceWidth( Glyph.ID_SPACE ) ) * pixelSizeFName;
+ float dx = width - ( fontNameBox.getWidth() + 2 * font.getAdvanceWidth( font.getGlyphID('X') ) ) * pixelSizeFName;
float dy = height - fontNameBox.getHeight() * pixelSizeFName;
-
- pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
- pmv.glLoadIdentity();
- pmv.glTranslatef(nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy), nearPlaneZ0);
{
- final float sxy = nearPlaneS * pixelSizeFName;
- pmv.glScalef(sxy, sxy, 1.0f);
+ pmv.glPushMatrix();
+ pmv.glTranslatef(nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy), nearPlaneZ0);
+ {
+ final float sxy = nearPlaneS * pixelSizeFName;
+ pmv.glScalef(sxy, sxy, 1.0f);
+ }
+ // System.err.printf("FontN: [%f %f] -> [%f %f]%n", dx, dy, nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy));
+ textRegionUtil.drawString3D(gl, renderer, font, fontName, null, getSampleCount());
+ pmv.glPopMatrix();
}
- // System.err.printf("FontN: [%f %f] -> [%f %f]%n", dx, dy, nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy));
- textRegionUtil.drawString3D(gl, renderer, font, fontName, null, getSampleCount());
dx = 10f;
dy += -fontNameBox.getHeight() * pixelSizeFName - 10f;
if(null != headtext) {
- pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
- pmv.glLoadIdentity();
+ pmv.glPushMatrix();
// System.err.printf("Head: [%f %f] -> [%f %f]%n", dx, dy, nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy));
pmv.glTranslatef(nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy), nearPlaneZ0);
{
@@ -357,37 +361,40 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
}
// pmv.glTranslatef(x0, y1, z0);
textRegionUtil.drawString3D(gl, renderer, font, headtext, null, getSampleCount());
+ pmv.glPopMatrix();
}
dy += ( -headbox.getHeight() - font.getLineHeight() ) * pixelSizeCenter;
- pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
- pmv.glLoadIdentity();
- pmv.glTranslatef(nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy), nearPlaneZ0);
- // System.err.printf("Bottom: [%f %f] -> [%f %f]%n", dx, dy, nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy));
- pmv.glTranslatef(getXTran(), getYTran(), getZTran());
- pmv.glRotatef(getAngle(), 0, 1, 0);
{
- final float sxy = nearPlaneS * pixelSizeCenter;
- pmv.glScalef(sxy, sxy, 1.0f);
- }
- rs.setColorStatic(0.9f, 0.0f, 0.0f, 1.0f);
+ pmv.glPushMatrix();
+ pmv.glTranslatef(nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy), nearPlaneZ0);
+ // System.err.printf("Bottom: [%f %f] -> [%f %f]%n", dx, dy, nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy));
+ pmv.glTranslatef(getXTran(), getYTran(), getZTran());
+ pmv.glRotatef(getAngle(), 0, 1, 0);
+ {
+ final float sxy = nearPlaneS * pixelSizeCenter;
+ pmv.glScalef(sxy, sxy, 1.0f);
+ }
+ rs.setColorStatic(0.9f, 0.0f, 0.0f, 1.0f);
- if( bottomTextUseFrustum ) {
- regionBottom.setFrustum(pmv.glGetFrustum());
- }
- if(!userInput) {
if( bottomTextUseFrustum ) {
- TextRegionUtil.drawString3D(gl, regionBottom, renderer, font, text2, null, getSampleCount());
- } else {
- textRegionUtil.drawString3D(gl, renderer, font, text2, null, getSampleCount());
+ regionBottom.setFrustum(pmv.glGetFrustum());
}
- } else {
- if( bottomTextUseFrustum ) {
- TextRegionUtil.drawString3D(gl, regionBottom, renderer, font, userString.toString(), null, getSampleCount());
+ if(!userInput) {
+ if( bottomTextUseFrustum ) {
+ TextRegionUtil.drawString3D(gl, regionBottom, renderer, font, text2, null, getSampleCount());
+ } else {
+ textRegionUtil.drawString3D(gl, renderer, font, text2, null, getSampleCount());
+ }
} else {
- textRegionUtil.drawString3D(gl, renderer, font, userString.toString(), null, getSampleCount());
+ if( bottomTextUseFrustum ) {
+ TextRegionUtil.drawString3D(gl, regionBottom, renderer, font, userString.toString(), null, getSampleCount());
+ } else {
+ textRegionUtil.drawString3D(gl, renderer, font, userString.toString(), null, getSampleCount());
+ }
}
+ pmv.glPopMatrix();
}
renderer.enable(gl, false);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Rectangle.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Rectangle.java
new file mode 100644
index 000000000..aa9400050
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Rectangle.java
@@ -0,0 +1,113 @@
+/**
+ * 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.test.junit.graph.demos.ui;
+
+import com.jogamp.opengl.GL2ES2;
+
+import com.jogamp.graph.curve.OutlineShape;
+import com.jogamp.graph.curve.opengl.RegionRenderer;
+import com.jogamp.graph.geom.Vertex;
+import com.jogamp.graph.geom.Vertex.Factory;
+
+/**
+ * GPU based resolution independent Rectangle
+ */
+public class Rectangle extends UIShape {
+ private float width, height, lineWidth;
+
+ public Rectangle(final Factory<? extends Vertex> factory, final int renderModes, final float width, final float height, final float linewidth) {
+ super(factory, renderModes);
+ this.width = width;
+ this.height = height;
+ this.lineWidth = linewidth;
+ }
+
+ public final float getWidth() { return width; }
+ public final float getHeight() { return height; }
+ public final float getLineWidth() { return lineWidth; }
+
+ public void setDimension(final float width, final float height, final float lineWidth) {
+ this.width = width;
+ this.height = height;
+ this.lineWidth = lineWidth;
+ markShapeDirty();
+ }
+
+ @Override
+ protected void clearImpl(final GL2ES2 gl, final RegionRenderer renderer) {
+ }
+
+ @Override
+ protected void destroyImpl(final GL2ES2 gl, final RegionRenderer renderer) {
+ }
+
+ @Override
+ protected void addShapeToRegion(final GL2ES2 gl, final RegionRenderer renderer) {
+ final OutlineShape shape = new OutlineShape(renderer.getRenderState().getVertexFactory());
+
+ final float lwh = lineWidth/2f;
+
+ final float tw = getWidth();
+ final float th = getHeight();
+
+ final float twh = tw/2f;
+ final float twh_o = twh+lwh;
+ final float twh_i = twh-lwh;
+ final float thh = th/2f;
+ final float thh_o = thh+lwh;
+ final float thh_i = thh-lwh;
+
+ final float ctrX = 0f, ctrY = 0f;
+ final float ctrZ = 0f;
+
+ // outer (CCW!)
+ shape.moveTo(ctrX-twh_o, ctrY-thh_o, ctrZ);
+ shape.lineTo(ctrX+twh_o, ctrY-thh_o, ctrZ);
+ shape.lineTo(ctrX+twh_o, ctrY+thh_o, ctrZ);
+ shape.lineTo(ctrX-twh_o, ctrY+thh_o, ctrZ);
+ shape.closePath();
+
+ // inner (CCW!)
+ shape.moveTo(ctrX-twh_i, ctrY-thh_i, ctrZ);
+ shape.lineTo(ctrX+twh_i, ctrY-thh_i, ctrZ);
+ shape.lineTo(ctrX+twh_i, ctrY+thh_i, ctrZ);
+ shape.lineTo(ctrX-twh_i, ctrY+thh_i, ctrZ);
+ shape.closePath();
+
+ shape.setIsQuadraticNurbs();
+ shape.setSharpness(shapesSharpness);
+ region.addOutlineShape(shape, null, rgbaColor);
+
+ box.resize(shape.getBounds());
+ }
+
+ @Override
+ public String getSubString() {
+ return super.getSubString()+", dim "+getWidth() + "x" + getHeight();
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TestObject01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TestObject01.java
new file mode 100644
index 000000000..c3df7c7ed
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TestObject01.java
@@ -0,0 +1,294 @@
+/**
+ * Copyright 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.test.junit.graph.demos.ui;
+
+import com.jogamp.opengl.GL2ES2;
+
+import com.jogamp.graph.curve.OutlineShape;
+import com.jogamp.graph.curve.opengl.RegionRenderer;
+import com.jogamp.graph.geom.Vertex;
+import com.jogamp.graph.geom.Vertex.Factory;
+
+/**
+ * GPU based resolution independent test object
+ */
+public class TestObject01 extends UIShape {
+
+ public TestObject01(final Factory<? extends Vertex> factory, final int renderModes) {
+ super(factory, renderModes);
+ }
+
+ @Override
+ protected void clearImpl(final GL2ES2 gl, final RegionRenderer renderer) {
+ }
+
+ @Override
+ protected void destroyImpl(final GL2ES2 gl, final RegionRenderer renderer) {
+ }
+
+ @Override
+ protected void addShapeToRegion(final GL2ES2 gl, final RegionRenderer renderer) {
+ final OutlineShape shape = new OutlineShape(renderer.getRenderState().getVertexFactory());
+
+ // lower case 'o'
+ // Start TTF Shape for Glyph 82
+ if( true ) {
+ // Shape.MoveTo:
+ shape.closeLastOutline(false);
+ shape.addEmptyOutline();
+ shape.addVertex(0, 0.527000f, 0.258000f, true);
+ // 000: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.527000f, 0.197000f, false);
+ shape.addVertex(0, 0.510000f, 0.147000f, true);
+ // 002: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.492000f, 0.097000f, false);
+ shape.addVertex(0, 0.461000f, 0.062000f, true);
+ // 003: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.429000f, 0.027000f, false);
+ shape.addVertex(0, 0.386000f, 0.008000f, true);
+ // 004: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.343000f, -0.012000f, false);
+ shape.addVertex(0, 0.291000f, -0.012000f, true);
+ // 005: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.239000f, -0.012000f, false);
+ shape.addVertex(0, 0.196000f, 0.007000f, true);
+ // 007: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.153000f, 0.027000f, false);
+ shape.addVertex(0, 0.122000f, 0.062000f, true);
+ // 008: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.090000f, 0.097000f, false);
+ shape.addVertex(0, 0.073000f, 0.147000f, true);
+ // 009: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.055000f, 0.197000f, false);
+ shape.addVertex(0, 0.055000f, 0.258000f, true);
+ // 010: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.055000f, 0.319000f, false);
+ shape.addVertex(0, 0.072000f, 0.369000f, true);
+ // 012: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.090000f, 0.419000f, false);
+ shape.addVertex(0, 0.121000f, 0.454000f, true);
+ // 013: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.153000f, 0.490000f, false);
+ shape.addVertex(0, 0.196000f, 0.509000f, true);
+ // 014: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.239000f, 0.529000f, false);
+ shape.addVertex(0, 0.291000f, 0.529000f, true);
+ // 015: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.343000f, 0.529000f, false);
+ shape.addVertex(0, 0.386000f, 0.510000f, true);
+ // 017: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.429000f, 0.490000f, false);
+ shape.addVertex(0, 0.460000f, 0.455000f, true);
+ // 018: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.492000f, 0.419000f, false);
+ shape.addVertex(0, 0.509000f, 0.369000f, true);
+ // 019: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.527000f, 0.319000f, false);
+ shape.addVertex(0, 0.527000f, 0.258000f, true);
+ shape.closeLastOutline(false);
+ } else {
+ // Shape.MoveTo:
+ shape.closeLastOutline(false);
+ shape.addEmptyOutline();
+ shape.addVertex(0.527000f, 0.258000f, true);
+ // 000: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.527000f, 0.197000f, false);
+ shape.addVertex(0.510000f, 0.147000f, true);
+ // 002: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.492000f, 0.097000f, false);
+ shape.addVertex(0.461000f, 0.062000f, true);
+ // 003: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.429000f, 0.027000f, false);
+ shape.addVertex(0.386000f, 0.008000f, true);
+ // 004: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0.343000f, -0.012000f, false);
+ shape.addVertex(0.291000f, -0.012000f, true);
+ // 005: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.239000f, -0.012000f, false);
+ shape.addVertex(0.196000f, 0.007000f, true);
+ // 007: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.153000f, 0.027000f, false);
+ shape.addVertex(0.122000f, 0.062000f, true);
+ // 008: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.090000f, 0.097000f, false);
+ shape.addVertex(0.073000f, 0.147000f, true);
+ // 009: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0.055000f, 0.197000f, false);
+ shape.addVertex(0.055000f, 0.258000f, true);
+ // 010: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.055000f, 0.319000f, false);
+ shape.addVertex(0.072000f, 0.369000f, true);
+ // 012: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.090000f, 0.419000f, false);
+ shape.addVertex(0.121000f, 0.454000f, true);
+ // 013: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.153000f, 0.490000f, false);
+ shape.addVertex(0.196000f, 0.509000f, true);
+ // 014: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0.239000f, 0.529000f, false);
+ shape.addVertex(0.291000f, 0.529000f, true);
+ // 015: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.343000f, 0.529000f, false);
+ shape.addVertex(0.386000f, 0.510000f, true);
+ // 017: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.429000f, 0.490000f, false);
+ shape.addVertex(0.460000f, 0.455000f, true);
+ // 018: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.492000f, 0.419000f, false);
+ shape.addVertex(0.509000f, 0.369000f, true);
+ // 019: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0.527000f, 0.319000f, false);
+ shape.addVertex(0.527000f, 0.258000f, true);
+ shape.closeLastOutline(false);
+ }
+
+ if( false ) {
+ // Shape.MoveTo:
+ shape.closeLastOutline(false);
+ shape.addEmptyOutline();
+ shape.addVertex(0, 0.458000f, 0.258000f, true);
+ // 020: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.458000f, 0.355000f, false);
+ shape.addVertex(0, 0.413000f, 0.412000f, true);
+ // 022: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.368000f, 0.470000f, false);
+ shape.addVertex(0, 0.291000f, 0.470000f, true);
+ // 023: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.214000f, 0.470000f, false);
+ shape.addVertex(0, 0.169000f, 0.413000f, true);
+ // 025: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.124000f, 0.355000f, false);
+ shape.addVertex(0, 0.124000f, 0.258000f, true);
+ // 026: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.124000f, 0.161000f, false);
+ shape.addVertex(0, 0.169000f, 0.104000f, true);
+ // 028: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.214000f, 0.047000f, false);
+ shape.addVertex(0, 0.291000f, 0.047000f, true);
+ // 029: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.368000f, 0.047000f, false);
+ shape.addVertex(0, 0.413000f, 0.104000f, true);
+ // 031: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.458000f, 0.161000f, false);
+ shape.addVertex(0, 0.458000f, 0.258000f, true);
+ shape.closeLastOutline(false);
+ } else {
+ // Shape.MoveTo:
+ shape.closeLastOutline(false);
+ shape.addEmptyOutline();
+
+ shape.addVertex(0.458000f, 0.258000f, true);
+ // 020: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.458000f, 0.355000f, false);
+ shape.addVertex(0.413000f, 0.412000f, true);
+ // 022: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0.368000f, 0.470000f, false);
+ shape.addVertex(0.291000f, 0.470000f, true);
+ // 023: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.214000f, 0.470000f, false);
+ shape.addVertex(0.169000f, 0.413000f, true);
+ // 025: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0.124000f, 0.355000f, false);
+ shape.addVertex(0.124000f, 0.258000f, true);
+ // 026: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.124000f, 0.161000f, false);
+ shape.addVertex(0.169000f, 0.104000f, true);
+ // 028: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0.214000f, 0.047000f, false);
+ shape.addVertex(0.291000f, 0.047000f, true);
+ // 029: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0.368000f, 0.047000f, false);
+ shape.addVertex(0.413000f, 0.104000f, true);
+ // 031: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0.458000f, 0.161000f, false);
+ shape.addVertex(0.458000f, 0.258000f, true);
+
+ shape.closeLastOutline(false);
+ }
+ // End Shape for Glyph 82
+
+ shape.setIsQuadraticNurbs();
+ shape.setSharpness(shapesSharpness);
+ region.addOutlineShape(shape, null, rgbaColor);
+
+ box.resize(shape.getBounds());
+ }
+
+ @Override
+ public String getSubString() {
+ return super.getSubString();
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TestObject02.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TestObject02.java
new file mode 100644
index 000000000..34aec67c3
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/TestObject02.java
@@ -0,0 +1,352 @@
+/**
+ * Copyright 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.test.junit.graph.demos.ui;
+
+import com.jogamp.opengl.GL2ES2;
+
+import com.jogamp.graph.curve.OutlineShape;
+import com.jogamp.graph.curve.opengl.RegionRenderer;
+import com.jogamp.graph.geom.Vertex;
+import com.jogamp.graph.geom.Vertex.Factory;
+
+/**
+ * GPU based resolution independent test object
+ */
+public class TestObject02 extends UIShape {
+
+ public TestObject02(final Factory<? extends Vertex> factory, final int renderModes) {
+ super(factory, renderModes);
+ }
+
+ @Override
+ protected void clearImpl(final GL2ES2 gl, final RegionRenderer renderer) {
+ }
+
+ @Override
+ protected void destroyImpl(final GL2ES2 gl, final RegionRenderer renderer) {
+ }
+
+ @Override
+ protected void addShapeToRegion(final GL2ES2 gl, final RegionRenderer renderer) {
+ final OutlineShape shape = new OutlineShape(renderer.getRenderState().getVertexFactory());
+
+ // lower case 'æ'
+
+ // Start TTF Shape for Glyph 193
+ {
+ // Shape.MoveTo:
+ shape.closeLastOutline(false);
+ shape.addEmptyOutline();
+ shape.addVertex(0, 0.728000f, 0.300000f, true);
+ // 000: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.726000f, 0.381000f, false);
+ shape.addVertex(0, 0.690000f, 0.426000f, true);
+ // 002: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.654000f, 0.471000f, false);
+ shape.addVertex(0, 0.588000f, 0.471000f, true);
+ // 003: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.553000f, 0.471000f, false);
+ shape.addVertex(0, 0.526000f, 0.457000f, true);
+ // 005: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.498000f, 0.443000f, false);
+ shape.addVertex(0, 0.478000f, 0.420000f, true);
+ // 006: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.457000f, 0.396000f, false);
+ shape.addVertex(0, 0.446000f, 0.365000f, true);
+ // 007: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.434000f, 0.334000f, false);
+ shape.addVertex(0, 0.432000f, 0.300000f, true);
+ // 008: B1: line-to p0-p1
+ // Shape.LineTo:
+ shape.addVertex(0, 0.728000f, 0.300000f, true);
+ shape.closeLastOutline(false);
+ }
+
+ {
+ // Shape.MoveTo:
+ shape.closeLastOutline(false);
+ shape.addEmptyOutline();
+ shape.addVertex(0, 0.252000f, -0.011000f, true);
+ // 009: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.208000f, -0.011000f, false);
+ shape.addVertex(0, 0.171000f, -0.002000f, true);
+ // 011: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.133000f, 0.007000f, false);
+ shape.addVertex(0, 0.106000f, 0.026000f, true);
+ // 012: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.079000f, 0.046000f, false);
+ shape.addVertex(0, 0.064000f, 0.076000f, true);
+ // 013: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.048000f, 0.107000f, false);
+ shape.addVertex(0, 0.048000f, 0.151000f, true);
+ // 014: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.048000f, 0.193000f, false);
+ shape.addVertex(0, 0.064000f, 0.223000f, true);
+ // 016: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.080000f, 0.253000f, false);
+ shape.addVertex(0, 0.109000f, 0.272000f, true);
+ // 017: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.138000f, 0.292000f, false);
+ shape.addVertex(0, 0.178000f, 0.301000f, true);
+ // 018: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.218000f, 0.310000f, false);
+ shape.addVertex(0, 0.265000f, 0.310000f, true);
+ // 019: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.279000f, 0.310000f, false);
+ shape.addVertex(0, 0.294000f, 0.309000f, true);
+ // 021: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.310000f, 0.307000f, false);
+ shape.addVertex(0, 0.324000f, 0.305000f, true);
+ // 022: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.339000f, 0.302000f, false);
+ shape.addVertex(0, 0.349000f, 0.300000f, true);
+ // 023: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.360000f, 0.297000f, false);
+ shape.addVertex(0, 0.364000f, 0.295000f, true);
+ // 024: B1: line-to p0-p1
+ // Shape.LineTo:
+ shape.addVertex(0, 0.364000f, 0.327000f, true);
+ // 025: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.364000f, 0.354000f, false);
+ shape.addVertex(0, 0.360000f, 0.379000f, true);
+ // 027: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.356000f, 0.405000f, false);
+ shape.addVertex(0, 0.343000f, 0.425000f, true);
+ // 028: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.329000f, 0.446000f, false);
+ shape.addVertex(0, 0.305000f, 0.458000f, true);
+ // 029: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.280000f, 0.471000f, false);
+ shape.addVertex(0, 0.240000f, 0.471000f, true);
+ // 030: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.186000f, 0.471000f, false);
+ shape.addVertex(0, 0.156000f, 0.464000f, true);
+ // 032: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.126000f, 0.456000f, false);
+ shape.addVertex(0, 0.113000f, 0.451000f, true);
+ // 033: B1: line-to p0-p1
+ // Shape.LineTo:
+ shape.addVertex(0, 0.105000f, 0.507000f, true);
+ // 034: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.122000f, 0.515000f, false);
+ shape.addVertex(0, 0.158000f, 0.522000f, true);
+ // 036: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.194000f, 0.529000f, false);
+ shape.addVertex(0, 0.243000f, 0.529000f, true);
+ // 037: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.314000f, 0.529000f, false);
+ shape.addVertex(0, 0.354000f, 0.503000f, true);
+ // 039: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.395000f, 0.476000f, false);
+ shape.addVertex(0, 0.412000f, 0.431000f, true);
+ // 040: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.445000f, 0.480000f, false);
+ shape.addVertex(0, 0.491000f, 0.504000f, true);
+ // 042: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.537000f, 0.529000f, false);
+ shape.addVertex(0, 0.587000f, 0.529000f, true);
+ // 043: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.682000f, 0.529000f, false);
+ shape.addVertex(0, 0.738000f, 0.467000f, true);
+ // 045: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.795000f, 0.405000f, false);
+ shape.addVertex(0, 0.795000f, 0.276000f, true);
+ // 046: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.795000f, 0.268000f, false);
+ shape.addVertex(0, 0.795000f, 0.260000f, true);
+ // 048: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.794000f, 0.252000f, false);
+ shape.addVertex(0, 0.793000f, 0.245000f, true);
+ // 049: B1: line-to p0-p1
+ // Shape.LineTo:
+ shape.addVertex(0, 0.430000f, 0.245000f, true);
+ // 050: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.433000f, 0.150000f, false);
+ shape.addVertex(0, 0.477000f, 0.099000f, true);
+ // 052: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.521000f, 0.048000f, false);
+ shape.addVertex(0, 0.617000f, 0.048000f, true);
+ // 053: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.670000f, 0.048000f, false);
+ shape.addVertex(0, 0.701000f, 0.058000f, true);
+ // 055: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.732000f, 0.068000f, false);
+ shape.addVertex(0, 0.746000f, 0.075000f, true);
+ // 056: B1: line-to p0-p1
+ // Shape.LineTo:
+ shape.addVertex(0, 0.758000f, 0.019000f, true);
+ // 057: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.744000f, 0.011000f, false);
+ shape.addVertex(0, 0.706000f, 0.000000f, true);
+ // 059: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.667000f, -0.011000f, false);
+ shape.addVertex(0, 0.615000f, -0.011000f, true);
+ // 060: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.558000f, -0.011000f, false);
+ shape.addVertex(0, 0.514000f, 0.003000f, true);
+ // 062: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.470000f, 0.017000f, false);
+ shape.addVertex(0, 0.437000f, 0.049000f, true);
+ // 063: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.426000f, 0.040000f, false);
+ shape.addVertex(0, 0.410000f, 0.030000f, true);
+ // 065: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.393000f, 0.019000f, false);
+ shape.addVertex(0, 0.370000f, 0.010000f, true);
+ // 066: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.347000f, 0.001000f, false);
+ shape.addVertex(0, 0.318000f, -0.005000f, true);
+ // 067: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.289000f, -0.011000f, false);
+ shape.addVertex(0, 0.252000f, -0.011000f, true);
+ shape.closeLastOutline(false);
+ }
+
+ if( true ) {
+ // Shape.MoveTo:
+ shape.closeLastOutline(false);
+ shape.addEmptyOutline();
+ shape.addVertex(0, 0.365000f, 0.238000f, true);
+ // 068: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.354000f, 0.243000f, false);
+ shape.addVertex(0, 0.330000f, 0.248000f, true);
+ // 070: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.305000f, 0.254000f, false);
+ shape.addVertex(0, 0.263000f, 0.254000f, true);
+ // 071: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.239000f, 0.254000f, false);
+ shape.addVertex(0, 0.213000f, 0.251000f, true);
+ // 073: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.187000f, 0.247000f, false);
+ shape.addVertex(0, 0.165000f, 0.236000f, true);
+ // 074: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.143000f, 0.224000f, false);
+ shape.addVertex(0, 0.129000f, 0.204000f, true);
+ // 075: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.115000f, 0.184000f, false);
+ shape.addVertex(0, 0.115000f, 0.151000f, true);
+ // 076: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.115000f, 0.122000f, false);
+ shape.addVertex(0, 0.125000f, 0.102000f, true);
+ // 078: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.135000f, 0.082000f, false);
+ shape.addVertex(0, 0.153000f, 0.070000f, true);
+ // 079: B5: quad-to pMh-p0-p1h ***** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.172000f, 0.058000f, false);
+ shape.addVertex(0, 0.197000f, 0.053000f, true);
+ // 080: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.222000f, 0.047000f, false);
+ shape.addVertex(0, 0.252000f, 0.047000f, true);
+ // 081: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.314000f, 0.047000f, false);
+ shape.addVertex(0, 0.350000f, 0.063000f, true);
+ // 083: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.386000f, 0.080000f, false);
+ shape.addVertex(0, 0.400000f, 0.093000f, true);
+ // 084: B4: quad-to p0-p1-p2h **** MID
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.384000f, 0.119000f, false);
+ shape.addVertex(0, 0.375000f, 0.154000f, true);
+ // 086: B6: quad-to pMh-p0-p1
+ // Shape.QuadTo:
+ shape.addVertex(0, 0.366000f, 0.190000f, false);
+ shape.addVertex(0, 0.365000f, 0.238000f, true);
+ shape.closeLastOutline(false);
+ }
+ // End Shape for Glyph 193
+
+ shape.setIsQuadraticNurbs();
+ shape.setSharpness(shapesSharpness);
+ region.addOutlineShape(shape, null, rgbaColor);
+
+ box.resize(shape.getBounds());
+ }
+
+ @Override
+ public String getSubString() {
+ return super.getSubString();
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShapeDemo01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShapeDemo01.java
index b9d249e19..4a61a2be0 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShapeDemo01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UIShapeDemo01.java
@@ -275,7 +275,7 @@ public class UIShapeDemo01 implements GLEventListener {
}
full_width_o = objCoord1[0] - objCoord0[0];
}
- final AABBox txt_box_em = font.getPointsBounds(null, text);
+ final AABBox txt_box_em = font.getGlyphBounds(text);
final float full_width_s = full_width_o / txt_box_em.getWidth();
final float txt_scale = full_width_s/2f;
pmv.glPushMatrix();
@@ -283,7 +283,7 @@ public class UIShapeDemo01 implements GLEventListener {
pmv.glTranslatef(-txt_box_em.getWidth(), 0f, 0f);
final AABBox txt_box_r = TextRegionUtil.drawString3D(gl, renderModes, renderer, font, text, new float[] { 0, 0, 0, 1 }, sampleCount);
if( once ) {
- final AABBox txt_box_em2 = font.getPointsBounds2(null, text);
+ final AABBox txt_box_em2 = font.getGlyphShapeBounds(null, text);
System.err.println("XXX: full_width: "+full_width_o+" / "+txt_box_em.getWidth()+" -> "+full_width_s);
System.err.println("XXX: txt_box_em "+txt_box_em);
System.err.println("XXX: txt_box_e2 "+txt_box_em2);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UITypeDemo01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UITypeDemo01.java
new file mode 100644
index 000000000..0fe9b300e
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UITypeDemo01.java
@@ -0,0 +1,584 @@
+/**
+ * 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.test.junit.graph.demos.ui;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import com.jogamp.opengl.FPSCounter;
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GL2ES2;
+import com.jogamp.opengl.GLAnimatorControl;
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.GLCapabilities;
+import com.jogamp.opengl.GLEventListener;
+import com.jogamp.opengl.GLException;
+import com.jogamp.opengl.GLPipelineFactory;
+import com.jogamp.opengl.GLProfile;
+import com.jogamp.opengl.GLRunnable;
+import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
+import com.jogamp.opengl.math.FloatUtil;
+import com.jogamp.opengl.math.geom.AABBox;
+import com.jogamp.opengl.test.junit.graph.demos.MSAATool;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.common.util.InterruptSource;
+import com.jogamp.graph.curve.Region;
+import com.jogamp.graph.curve.opengl.GLRegion;
+import com.jogamp.graph.curve.opengl.RegionRenderer;
+import com.jogamp.graph.curve.opengl.RenderState;
+import com.jogamp.graph.curve.opengl.TextRegionUtil;
+import com.jogamp.graph.font.Font;
+import com.jogamp.graph.font.FontFactory;
+import com.jogamp.graph.font.FontSet;
+import com.jogamp.graph.font.Font.Glyph;
+import com.jogamp.graph.geom.SVertex;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.KeyAdapter;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.MouseEvent;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.util.GLReadBufferUtil;
+import com.jogamp.opengl.util.PMVMatrix;
+
+/**
+ * Basic UIShape and Type Rendering demo.
+ *
+ * Action Keys:
+ * - 1/2: zoom in/out
+ * - 4/5: increase/decrease shape/text spacing
+ * - 6/7: increase/decrease corner size
+ * - 0/9: rotate
+ * - v: toggle v-sync
+ * - s: screenshot
+ */
+public class UITypeDemo01 implements GLEventListener {
+ static final boolean DEBUG = false;
+ static final boolean TRACE = false;
+
+ public static void main(final String[] args) throws IOException {
+ Font font = null;
+ String text = "Hello Origin.";
+ int glyph_id = 0;
+ if( 0 != args.length ) {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-font")) {
+ i++;
+ font = FontFactory.get(new File(args[i]));
+ } else if(args[i].equals("-text")) {
+ i++;
+ text = args[i];
+ } else if(args[i].equals("-glyph")) {
+ i++;
+ glyph_id = MiscUtils.atoi(args[i], 0);
+ }
+ }
+ }
+ if( null == font ) {
+ font = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_SERIF);
+ }
+ System.err.println("Font: "+font.getFullFamilyName());
+ System.err.println("Text: "+text);
+
+ final GLProfile glp = GLProfile.getGL2ES2();
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setAlphaBits(4);
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(4);
+ System.out.println("Requested: " + caps);
+
+ final GLWindow window = GLWindow.create(caps);
+ // window.setPosition(10, 10);
+ window.setSize(800, 400);
+ window.setTitle(UITypeDemo01.class.getSimpleName()+": "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight());
+ final RenderState rs = RenderState.createRenderState(SVertex.factory());
+ final UITypeDemo01 uiGLListener = new UITypeDemo01(font, glyph_id, text, Region.COLORCHANNEL_RENDERING_BIT, rs, DEBUG, TRACE);
+ uiGLListener.attachInputListenerTo(window);
+ window.addGLEventListener(uiGLListener);
+ window.setVisible(true);
+
+ final Animator animator = new Animator();
+ // animator.setUpdateFPSFrames(60, System.err);
+ animator.add(window);
+
+ window.addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyPressed(final KeyEvent arg0) {
+ if(arg0.getKeyCode() == KeyEvent.VK_F4) {
+ new InterruptSource.Thread() {
+ @Override
+ public void run() {
+ window.destroy();
+ } }.start();
+ }
+ }
+ });
+ window.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowDestroyed(final WindowEvent e) {
+ animator.stop();
+ }
+ });
+
+ animator.start();
+ }
+
+ private final float[] fg_color = new float[] { 0, 0, 0, 1 };
+ private final Font font;
+ private final String text;
+ private final int glyph_id;
+ private final GLReadBufferUtil screenshot;
+ private final int renderModes;
+ private final RegionRenderer rRenderer;
+ private final boolean debug;
+ private final boolean trace;
+
+ private final CrossHair crossHair;
+ private final UIShape testObj;
+
+ private KeyAction keyAction;
+ private MouseAction mouseAction;
+
+ private volatile GLAutoDrawable autoDrawable = null;
+
+ private final float[] position = new float[] {0,0,0};
+
+ private static final float xTran = 0f;
+ private static final float yTran = 0f;
+ private static final float zTran = -1/5f;
+ private static final float zNear = 0.1f;
+ private static final float zFar = 7000.0f;
+
+ boolean ignoreInput = false;
+
+ @SuppressWarnings("unused")
+ public UITypeDemo01(final Font font, final int glyph_id, final String text, final int renderModes, final RenderState rs, final boolean debug, final boolean trace) {
+ this.font = font;
+ this.text = text;
+ this.glyph_id = glyph_id;
+ this.renderModes = renderModes;
+ this.rRenderer = RegionRenderer.create(rs, RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable);
+ this.debug = debug;
+ this.trace = trace;
+ this.screenshot = new GLReadBufferUtil(false, false);
+
+ crossHair = new CrossHair(SVertex.factory(), renderModes, 1/20f, 1/20f, 1/1000f);
+ crossHair.setColor(0f,0f,1f,1f);
+ crossHair.setEnabled(true);
+
+ if (false ) {
+ final Rectangle o = new Rectangle(SVertex.factory(), renderModes, 1/10f, 1/20f, 1/1000f);
+ o.translate(o.getWidth(), -o.getHeight(), 0f);
+ testObj = o;
+ } else {
+ final float scale = 0.15312886f;
+ final float size_xz = 0.541f;
+ final UIShape o = new TestObject01(SVertex.factory(), renderModes);
+ o.scale(scale, scale, 1f);
+ // o.translate(size_xz, -size_xz, 0f);
+ testObj = o;
+ }
+ testObj.setColor(0f, 0f, 0f, 1f);
+ testObj.setEnabled(true);
+ }
+
+ public final RegionRenderer getRegionRenderer() { return rRenderer; }
+ public final float[] getPosition() { return position; }
+
+ @Override
+ public void init(final GLAutoDrawable drawable) {
+ autoDrawable = drawable;
+ GL2ES2 gl = drawable.getGL().getGL2ES2();
+ if(debug) {
+ gl = gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Debug", null, gl, null) ).getGL2ES2();
+ }
+ if(trace) {
+ gl = gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Trace", null, gl, new Object[] { System.err } ) ).getGL2ES2();
+ }
+ gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ getRegionRenderer().init(gl, renderModes);
+
+ gl.setSwapInterval(1);
+ gl.glEnable(GL.GL_DEPTH_TEST);
+ gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
+ MSAATool.dump(drawable);
+ }
+
+ @Override
+ public void reshape(final GLAutoDrawable drawable, final int xstart, final int ystart, final int width, final int height) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ gl.glViewport(xstart, ystart, width, height);
+ rRenderer.reshapePerspective(45.0f, width, height, zNear, zFar);
+ // rRenderer.reshapeOrtho(width, height, zNear, zFar);
+
+ lastWidth = width;
+ lastHeight = height;
+ if( drawable instanceof Window ) {
+ ((Window)drawable).setTitle(UITypeDemo01.class.getSimpleName()+": "+drawable.getSurfaceWidth()+" x "+drawable.getSurfaceHeight());
+ }
+ }
+ float lastWidth = 0f, lastHeight = 0f;
+
+ final int[] sampleCount = { 4 };
+
+ private void drawShape(final GL2ES2 gl, final PMVMatrix pmv, final RegionRenderer renderer, final UIShape shape) {
+ pmv.glPushMatrix();
+ shape.setTransform(pmv);
+ shape.drawShape(gl, renderer, sampleCount);
+ pmv.glPopMatrix();
+ }
+
+ @Override
+ public void display(final GLAutoDrawable drawable) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
+
+ final RegionRenderer renderer = getRegionRenderer();
+ final PMVMatrix pmv = renderer.getMatrix();
+ pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmv.glLoadIdentity();
+ pmv.glTranslatef(xTran, yTran, zTran);
+ renderer.enable(gl, true);
+ drawShape(gl, pmv, renderer, testObj);
+ drawShape(gl, pmv, renderer, crossHair);
+ {
+ final float full_width_o;
+ final float full_height_o;
+ {
+ final float orthoDist = -zTran; // assume orthogonal plane at -zTran
+ float glWinX = 0;
+ float glWinY = 0;
+ final float winZ = FloatUtil.getOrthoWinZ(orthoDist, zNear, zFar);
+ final float[] objCoord0 = new float[3];
+ final float[] objCoord1 = new float[3];
+ if( pmv.gluUnProject(glWinX, glWinY, winZ, renderer.getViewport(), 0, objCoord0, 0) ) {
+ if( once ) {
+ System.err.printf("winToObjCoord: win [%f, %f, %f] -> obj [%f, %f, %f]%n", glWinX, glWinY, winZ, objCoord0[0], objCoord0[1], objCoord0[2]);
+ }
+ }
+ glWinX = drawable.getSurfaceWidth();
+ glWinY = drawable.getSurfaceHeight();
+ if( pmv.gluUnProject(glWinX, glWinY, winZ, renderer.getViewport(), 0, objCoord1, 0) ) {
+ if( once ) {
+ System.err.printf("winToObjCoord: win [%f, %f, %f] -> obj [%f, %f, %f]%n", glWinX, glWinY, winZ, objCoord1[0], objCoord1[1], objCoord1[2]);
+ }
+ }
+ full_width_o = objCoord1[0] - objCoord0[0];
+ full_height_o = objCoord1[1] - objCoord0[1];
+ }
+ final Font.Glyph glyph = Glyph.ID_UNKNOWN != glyph_id ? font.getGlyph(glyph_id) : null;
+ if( null != glyph && null != glyph.getShape() && glyph.getID() != Glyph.ID_UNKNOWN ) {
+ final AABBox txt_box_em = glyph.getBBox();
+ final float full_width_s = full_width_o / txt_box_em.getWidth();
+ final float full_height_s = full_height_o / txt_box_em.getHeight();
+ final float txt_scale = full_width_s < full_height_s ? full_width_s/2f : full_height_s/2f;
+ pmv.glPushMatrix();
+ pmv.glScalef(txt_scale, txt_scale, 1f);
+ pmv.glTranslatef(-txt_box_em.getWidth(), 0f, 0f);
+ {
+ final GLRegion region = GLRegion.create(renderModes, null);
+ region.addOutlineShape(glyph.getShape(), null, region.hasColorChannel() ? fg_color : null);
+ region.draw(gl, renderer, sampleCount);
+ region.destroy(gl);
+ }
+ if( once ) {
+ final AABBox txt_box_em2 = font.getGlyphShapeBounds(null, text);
+ System.err.println("XXX: full_width: "+full_width_o+" / "+txt_box_em.getWidth()+" -> "+full_width_s);
+ System.err.println("XXX: full_height: "+full_height_o+" / "+txt_box_em.getHeight()+" -> "+full_height_s);
+ System.err.println("XXX: txt_scale: "+txt_scale);
+ System.err.println("XXX: txt_box_em "+txt_box_em);
+ System.err.println("XXX: txt_box_e2 "+txt_box_em2);
+ once = false;
+ }
+ } else {
+ final AABBox txt_box_em = font.getGlyphBounds(text);
+ final float full_width_s = full_width_o / txt_box_em.getWidth();
+ final float full_height_s = full_height_o / txt_box_em.getHeight();
+ final float txt_scale = full_width_s < full_height_s ? full_width_s/2f : full_height_s/2f;
+ pmv.glPushMatrix();
+ pmv.glScalef(txt_scale, txt_scale, 1f);
+ pmv.glTranslatef(-txt_box_em.getWidth(), 0f, 0f);
+ final AABBox txt_box_r = TextRegionUtil.drawString3D(gl, renderModes, renderer, font, text, fg_color, sampleCount);
+ if( once ) {
+ final AABBox txt_box_em2 = font.getGlyphShapeBounds(null, text);
+ System.err.println("XXX: full_width: "+full_width_o+" / "+txt_box_em.getWidth()+" -> "+full_width_s);
+ System.err.println("XXX: full_height: "+full_height_o+" / "+txt_box_em.getHeight()+" -> "+full_height_s);
+ System.err.println("XXX: txt_scale: "+txt_scale);
+ System.err.println("XXX: txt_box_em "+txt_box_em);
+ System.err.println("XXX: txt_box_e2 "+txt_box_em2);
+ System.err.println("XXX: txt_box_rg "+txt_box_r);
+ once = false;
+ }
+ }
+ pmv.glPopMatrix();
+ }
+ renderer.enable(gl, false);
+ }
+ static boolean once = true;
+
+ @Override
+ public void dispose(final GLAutoDrawable drawable) {
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+ crossHair.destroy(gl, getRegionRenderer());
+ testObj.destroy(gl, getRegionRenderer());
+
+ autoDrawable = null;
+ screenshot.dispose(gl);
+ rRenderer.destroy(gl);
+ }
+
+ /** Attach the input listener to the window */
+ public void attachInputListenerTo(final GLWindow window) {
+ if ( null == keyAction ) {
+ keyAction = new KeyAction();
+ window.addKeyListener(keyAction);
+ }
+ if ( null == mouseAction ) {
+ mouseAction = new MouseAction();
+ window.addMouseListener(mouseAction);
+ }
+ }
+
+ public void detachFrom(final GLWindow window) {
+ if ( null == keyAction ) {
+ return;
+ }
+ if ( null == mouseAction ) {
+ return;
+ }
+ window.removeGLEventListener(this);
+ window.removeKeyListener(keyAction);
+ window.removeMouseListener(mouseAction);
+ }
+
+ public void printScreen(final GLAutoDrawable drawable, final String dir, final String tech, final String objName, final boolean exportAlpha) throws GLException, IOException {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw);
+ pw.printf("-%03dx%03d-Z%04d-T%04d-%s", drawable.getSurfaceWidth(), drawable.getSurfaceHeight(), (int)Math.abs(zTran), 0, objName);
+
+ final String filename = dir + tech + sw +".png";
+ if(screenshot.readPixels(drawable.getGL(), false)) {
+ screenshot.write(new File(filename));
+ }
+ }
+
+ int screenshot_num = 0;
+
+ public void setIgnoreInput(final boolean v) {
+ ignoreInput = v;
+ }
+ public boolean getIgnoreInput() {
+ return ignoreInput;
+ }
+
+ public class MouseAction implements MouseListener{
+
+ @Override
+ public void mouseClicked(final MouseEvent e) {
+
+ }
+
+ @Override
+ public void mouseEntered(final MouseEvent e) {
+ }
+
+ @Override
+ public void mouseExited(final MouseEvent e) {
+ }
+
+ @Override
+ public void mousePressed(final MouseEvent e) {
+ autoDrawable.invoke(false, new GLRunnable() { // avoid data-race
+ @Override
+ public boolean run(final GLAutoDrawable drawable) {
+ System.err.println("\n\nMouse: "+e);
+
+ final RegionRenderer renderer = getRegionRenderer();
+ final PMVMatrix pmv = renderer.getMatrix();
+ pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmv.glLoadIdentity();
+ pmv.glTranslatef(xTran, yTran, zTran);
+
+ // flip to GL window coordinates, origin bottom-left
+ final int[] viewport = renderer.getViewport(new int[4]);
+ final int glWinX = e.getX();
+ final int glWinY = viewport[3] - e.getY() - 1;
+
+ {
+ final float[] objPosC = crossHair.getBounds().getCenter();
+ final int[] objWinPos = new int[2];
+ System.err.println("\n\nCrossHair: "+crossHair);
+ if( crossHair.objToWinCoord(renderer, objPosC, objWinPos) ) {
+ System.err.println("CrossHair: Obj: Obj "+objPosC[0]+"/"+objPosC[1]+"/"+objPosC[1]+" -> Win "+objWinPos[0]+"/"+objWinPos[1]);
+ }
+
+ final float[] objPos2 = new float[3];
+ crossHair.winToObjCoord(renderer, objWinPos[0], objWinPos[1], objPos2);
+ System.err.println("CrossHair: Obj: Win "+objWinPos[0]+"/"+objWinPos[1]+" -> Obj "+objPos2[0]+"/"+objPos2[1]+"/"+objPos2[1]);
+
+ final float[] winObjPos = new float[3];
+ if( crossHair.winToObjCoord(renderer, glWinX, glWinY, winObjPos) ) {
+ // final float[] translate = crossHair.getTranslate();
+ // final float[] objPosT = new float[] { objPosC[0]+translate[0], objPosC[1]+translate[1], objPosC[2]+translate[2] };
+ final float dx = winObjPos[0] - objPosC[0];
+ final float dy = winObjPos[1] - objPosC[1];
+ // final float dz = winObjPos[2] - objPosT[2];
+ if( !FloatUtil.isZero(dx, FloatUtil.EPSILON) || !FloatUtil.isZero(dy, FloatUtil.EPSILON) ) {
+ System.err.println("CrossHair: Move.1: Win "+glWinX+"/"+glWinY+" -> Obj "+winObjPos[0]+"/"+winObjPos[1]+"/"+winObjPos[1]+" -> diff "+dx+" / "+dy);
+ crossHair.translate(dx, dy, 0f);
+ } else {
+ System.err.println("CrossHair: Move.0: Win "+glWinX+"/"+glWinY+" -> Obj "+winObjPos[0]+"/"+winObjPos[1]+"/"+winObjPos[1]+" -> diff "+dx+" / "+dy);
+ }
+ }
+
+ final int[] surfaceSize = new int[2];
+ crossHair.getSurfaceSize(renderer, surfaceSize);
+ System.err.println("CrossHair: Size: Pixel "+surfaceSize[0]+" x "+surfaceSize[1]);
+ }
+ return true;
+ } } );
+
+ }
+
+ @Override
+ public void mouseReleased(final MouseEvent e) {
+ }
+
+ @Override
+ public void mouseMoved(final MouseEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void mouseDragged(final MouseEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void mouseWheelMoved(final MouseEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ }
+
+ public class KeyAction implements KeyListener {
+ @Override
+ public void keyPressed(final KeyEvent arg0) {
+ if(ignoreInput) {
+ return;
+ }
+
+ if(arg0.getKeyCode() == KeyEvent.VK_1){
+ crossHair.translate(0f, 0f, -zTran/10f);
+ }
+ else if(arg0.getKeyCode() == KeyEvent.VK_2){
+ crossHair.translate(0f, 0f, zTran/10f);
+ }
+ else if(arg0.getKeyCode() == KeyEvent.VK_UP){
+ crossHair.translate(0f, crossHair.getHeight()/10f, 0f);
+ }
+ else if(arg0.getKeyCode() == KeyEvent.VK_DOWN){
+ crossHair.translate(0f, -crossHair.getHeight()/10f, 0f);
+ }
+ else if(arg0.getKeyCode() == KeyEvent.VK_LEFT){
+ crossHair.translate(-crossHair.getWidth()/10f, 0f, 0f);
+ }
+ else if(arg0.getKeyCode() == KeyEvent.VK_RIGHT){
+ crossHair.translate(crossHair.getWidth()/10f, 0f, 0f);
+ }
+ else if(arg0.getKeyCode() == KeyEvent.VK_0){
+ // rotate(1);
+ }
+ else if(arg0.getKeyCode() == KeyEvent.VK_9){
+ // rotate(-1);
+ }
+ else if(arg0.getKeyCode() == KeyEvent.VK_V) {
+ if(null != autoDrawable) {
+ autoDrawable.invoke(false, new GLRunnable() {
+ @Override
+ public boolean run(final GLAutoDrawable drawable) {
+ final GL gl = drawable.getGL();
+ final int _i = gl.getSwapInterval();
+ final int i;
+ switch(_i) {
+ case 0: i = 1; break;
+ case 1: i = -1; break;
+ case -1: i = 0; break;
+ default: i = 1; break;
+ }
+ gl.setSwapInterval(i);
+
+ final GLAnimatorControl a = drawable.getAnimator();
+ if( null != a ) {
+ a.resetFPSCounter();
+ }
+ if(drawable instanceof FPSCounter) {
+ ((FPSCounter)drawable).resetFPSCounter();
+ }
+ System.err.println("Swap Interval: "+_i+" -> "+i+" -> "+gl.getSwapInterval());
+ return true;
+ }
+ });
+ }
+ }
+ else if(arg0.getKeyCode() == KeyEvent.VK_S){
+ if(null != autoDrawable) {
+ autoDrawable.invoke(false, new GLRunnable() {
+ @Override
+ public boolean run(final GLAutoDrawable drawable) {
+ try {
+ final String type = Region.getRenderModeString(renderModes);
+ printScreen(drawable, "./", "demo-"+type, "snap"+screenshot_num, false);
+ screenshot_num++;
+ } catch (final GLException e) {
+ e.printStackTrace();
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+ });
+ }
+ }
+ }
+ @Override
+ public void keyReleased(final KeyEvent arg0) {}
+ }
+}