aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--make/scripts/tests.sh10
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java257
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/Outline.java1
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/plane/AffineTransform.java2
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/plane/Crossing2F.java (renamed from src/jogl/classes/com/jogamp/graph/geom/plane/Crossing.java)74
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/plane/Path2D.java454
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/plane/Path2F.java603
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/plane/PathIterator.java60
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/plane/Winding.java18
-rw-r--r--src/jogl/classes/com/jogamp/graph/geom/plane/WindingRule.java28
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java12
-rw-r--r--src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java3
-rw-r--r--src/jogl/classes/jogamp/graph/curve/tess/Loop.java13
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java51
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener00.java133
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener01.java179
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener10.java (renamed from src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener02.java)7
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo.java9
18 files changed, 1316 insertions, 598 deletions
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index dfa9bbec2..a5a221198 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -70,7 +70,7 @@ fi
#export LIBGL_DEBUG=verbose
#export MESA_DEBUG=true
-export LIBGL_ALWAYS_SOFTWARE=true
+#export LIBGL_ALWAYS_SOFTWARE=true
#export INTEL_DEBUG="buf bat"
#export INTEL_STRICT_CONFORMANCE=1
@@ -191,6 +191,7 @@ function jrun() {
#D_ARGS="-Djogl.debug.GLSLCode"
#D_ARGS="-Djogl.debug.GLSLCode -Djogl.debug.TraceGL"
#D_ARGS="-Djogl.debug.GLSLCode -Djogl.debug.DebugGL"
+ #D_ARGS="-Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode"
#D_ARGS="-Djogl.debug.GLContext -Dnativewindow.debug.JAWT -Dnewt.debug.Window"
#D_ARGS="-Dnativewindow.debug.JAWT -Djogl.debug.GLCanvas"
#D_ARGS="-Dnativewindow.debug.JAWT -Djogamp.debug.TaskBase.TraceSource"
@@ -203,7 +204,6 @@ function jrun() {
#D_ARGS="-Djogl.debug.FixedFuncPipeline"
#D_ARGS="-Djogl.debug.ImmModeSink.Buffer -Djogl.debug.ImmModeSink.Draw"
#D_ARGS="-Djogl.debug.FixedFuncPipeline -Djogl.debug.GLSLState -Djogl.debug.ImmModeSink.Buffer -Djogl.debug.ImmModeSink.Draw"
- #D_ARGS="-Djogl.debug.TraceGL -Djogl.debug.DebugGL -Djogl.debug.GLSLCode"
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.FBObject -Djogl.debug.GLContext -Djogl.debug.GLDrawable -Djogl.debug.GLCanvas -Dnewt.debug.Window"
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.GLContext -Djogl.debug.GLContext.TraceSwitch -Djogl.debug.GLDrawable"
#D_ARGS="-Dnativewindow.debug.GraphicsConfiguration -Djogl.debug.GLDrawable -Djogl.debug.GLContext -Djogl.debug.FBObject"
@@ -242,7 +242,7 @@ function jrun() {
#D_ARGS="-Djogl.1thread=true -Djogl.debug.Threading"
#D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch -Djogl.debug=all"
#D_ARGS="-Djogl.debug.GLArrayData"
- D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.Window"
+ #D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.Window"
#D_ARGS="-Dnewt.debug.Window"
#D_ARGS="-Dnewt.debug.Screen"
#D_ARGS="-Dnewt.window.icons=null,null"
@@ -930,7 +930,7 @@ function testawtswt() {
#
# Graph
#
-#testnoawt com.jogamp.opengl.test.junit.graph.TestRegionRendererNEWT01 $*
+testnoawt com.jogamp.opengl.test.junit.graph.TestRegionRendererNEWT01 $*
#testnoawt com.jogamp.opengl.test.junit.graph.TestTextRendererNEWT00 $*
#testnoawt com.jogamp.opengl.test.junit.graph.TestTextRendererNEWT01 $*
#testnoawt com.jogamp.opengl.test.junit.graph.TestTextRendererNEWT10 $*
@@ -983,7 +983,7 @@ function testawtswt() {
#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT2 $*
-testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT $*
+#testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch10NEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch11NewtAWT $*
diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
index 4bc1d0820..be5a1d1bf 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
@@ -37,6 +37,8 @@ import com.jogamp.graph.geom.Outline;
import com.jogamp.graph.geom.Triangle;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.geom.plane.AffineTransform;
+import com.jogamp.graph.geom.plane.Path2F;
+import com.jogamp.graph.geom.plane.Winding;
import com.jogamp.opengl.math.FloatUtil;
import com.jogamp.opengl.math.VectorUtil;
import com.jogamp.opengl.math.geom.AABBox;
@@ -91,6 +93,7 @@ import com.jogamp.opengl.math.geom.AABBox;
* <ul>
* <li> The first vertex of any outline belonging to the shape should be on-curve</li>
* <li> Intersections between off-curved parts of the outline is not handled</li>
+ * <li> Outline shape winding shall be constructed counter clock wise ({@link Winding#CCW}).</li>
* </ul>
*
* @see Outline
@@ -342,6 +345,9 @@ public final class OutlineShape implements Comparable<OutlineShape> {
/**
* Adds a vertex to the last open outline to the shape's tail.
+ *
+ * The constructed shape should be {@link Winding#CCW}.
+ *
* @param v the vertex to be added to the OutlineShape
*/
public final void addVertex(final Vertex v) {
@@ -356,6 +362,9 @@ public final class OutlineShape implements Comparable<OutlineShape> {
/**
* Adds a vertex to the last open outline to the shape at {@code position}
+ *
+ * The constructed shape should be {@link Winding#CCW}.
+ *
* @param position index within the last open outline, at which the vertex will be added
* @param v the vertex to be added to the OutlineShape
*/
@@ -372,6 +381,8 @@ public final class OutlineShape implements Comparable<OutlineShape> {
* Add a 2D {@link Vertex} to the last open outline to the shape's tail.
* The 2D vertex will be represented as Z=0.
*
+ * The constructed shape should be {@link Winding#CCW}.
+ *
* @param x the x coordinate
* @param y the y coordniate
* @param onCurve flag if this vertex is on the final curve or defines a curved region
@@ -385,6 +396,8 @@ public final class OutlineShape implements Comparable<OutlineShape> {
* Add a 2D {@link Vertex} to the last open outline to the shape at {@code position}.
* The 2D vertex will be represented as Z=0.
*
+ * The constructed shape should be {@link Winding#CCW}.
+ *
* @param position index within the last open outline, at which the vertex will be added
* @param x the x coordinate
* @param y the y coordniate
@@ -397,6 +410,9 @@ public final class OutlineShape implements Comparable<OutlineShape> {
/**
* Add a 3D {@link Vertex} to the last open outline to the shape's tail.
+ *
+ * The constructed shape should be {@link Winding#CCW}.
+ *
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coordinate
@@ -410,6 +426,8 @@ public final class OutlineShape implements Comparable<OutlineShape> {
/**
* Add a 3D {@link Vertex} to the last open outline to the shape at {@code position}.
*
+ * The constructed shape should be {@link Winding#CCW}.
+ *
* @param position index within the last open outline, at which the vertex will be added
* @param x the x coordinate
* @param y the y coordniate
@@ -424,6 +442,8 @@ public final class OutlineShape implements Comparable<OutlineShape> {
/**
* Add a vertex to the last open outline to the shape's tail.
*
+ * The constructed shape should be {@link Winding#CCW}.
+ *
* The vertex is passed as a float array and its offset where its attributes are located.
* The attributes should be continuous (stride = 0).
* Attributes which value are not set (when length less than 3)
@@ -441,6 +461,8 @@ public final class OutlineShape implements Comparable<OutlineShape> {
/**
* Add a vertex to the last open outline to the shape at {@code position}.
*
+ * The constructed shape should be {@link Winding#CCW}.
+ *
* The vertex is passed as a float array and its offset where its attributes are located.
* The attributes should be continuous (stride = 0).
* Attributes which value are not set (when length less than 3)
@@ -467,12 +489,245 @@ public final class OutlineShape implements Comparable<OutlineShape> {
* otherwise a clone of the last vertex will be prepended.
*/
public final void closeLastOutline(final boolean closeTail) {
- if( getLastOutline().setClosed(true) ) {
+ if( getLastOutline().setClosed( closeTail ) ) {
dirtyBits |= DIRTY_TRIANGLES | DIRTY_VERTICES;
}
}
/**
+ * Append the given path geometry to this outline shape.
+ *
+ * The given path geometry should be {@link Winding#CCW}.
+ *
+ * If the given path geometry is {@link Winding#CW}, use {@link #addPathRev(Path2F, boolean)}.
+ *
+ * @param path the {@link Path2F} to append to this outline shape, should be {@link Winding#CCW}.
+ * @param connect pass true to turn an initial moveTo segment into a lineTo segment to connect the new geometry to the existing path, otherwise pass false.
+ * @see Path2F#getWinding()
+ */
+ public void addPath(final Path2F path, final boolean connect) {
+ addPath(path.iterator(null), connect);
+ }
+
+ /**
+ * Add the given {@link Path2F.Iterator} to this outline shape.
+ *
+ * The given path geometry should be {@link Winding#CCW}.
+ *
+ * If the given path geometry is {@link Winding#CW}, use {@link #addPathRev(Path2F.Iterator, boolean).
+ *
+ * @param pathI the {@link Path2F.Iterator} to append to this outline shape, should be {@link Winding#CCW}.
+ * @param connect pass true to turn an initial moveTo segment into a lineTo segment to connect the new geometry to the existing path, otherwise pass false.
+ * @see Path2F.Iterator#getWinding()
+ */
+ public final void addPath(final Path2F.Iterator pathI, boolean connect) {
+ final float[] points = pathI.points();
+ while ( pathI.hasNext() ) {
+ final int idx = pathI.index();
+ final Path2F.SegmentType type = pathI.next();
+ switch(type) {
+ case MOVETO:
+ final Outline lo = this.getLastOutline();
+ final int lo_sz = lo.getVertexCount();
+ if ( 0 == lo_sz ) {
+ addVertex(points, idx, 2, true);
+ break;
+ } else if ( !connect ) {
+ closeLastOutline(false);
+ addEmptyOutline();
+ addVertex(points, idx, 2, true);
+ break;
+ }
+ {
+ // Skip if last vertex in last outline matching this point -> already connected.
+ final float[] llc = lo.getVertex(lo_sz-1).getCoord();
+ if( llc[0] == points[idx+0] &&
+ llc[1] == points[idx+1] ) {
+ break;
+ }
+ }
+ // fallthrough: MOVETO -> LINETO
+ case LINETO:
+ addVertex(points, idx, 2, true);
+ break;
+ case QUADTO:
+ addVertex(points, idx, 2, false);
+ addVertex(points, idx+2, 2, true);
+ break;
+ case CUBICTO:
+ addVertex(points, idx, 2, false);
+ addVertex(points, idx+2, 2, false);
+ addVertex(points, idx+4, 2, true);
+ break;
+ case CLOSE:
+ closeLastOutline(true);
+ addEmptyOutline();
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled Segment Type: "+type);
+ }
+ connect = false;
+ }
+ }
+
+ /**
+ * Append the given path geometry to this outline shape in reverse order.
+ *
+ * The given path geometry should be {@link Winding#CW}.
+ *
+ * If the given path geometry is {@link Winding#CCW}, use {@link #addPath(Path2F, boolean)}.
+ *
+ * @param path the {@link Path2F} to append to this outline shape, should be {@link Winding#CW}.
+ * @param connect pass true to turn an initial moveTo segment into a lineTo segment to connect the new geometry to the existing path, otherwise pass false.
+ */
+ public void addPathRev(final Path2F path, final boolean connect) {
+ addPathRev(path.iterator(null), connect);
+ }
+
+ /**
+ * Add the given {@link Path2F.Iterator} to this outline shape in reverse order.
+ *
+ * The given path geometry should be {@link Winding#CW}.
+ *
+ * If the given path geometry is {@link Winding#CCW}, use {@link #addPath(Path2F.Iterator, boolean).
+ *
+ * @param pathI the {@link Path2F.Iterator} to append to this outline shape, should be {@link Winding#CW}.
+ * @param connect pass true to turn an initial moveTo segment into a lineTo segment to connect the new geometry to the existing path, otherwise pass false.
+ */
+ public final void addPathRev(final Path2F.Iterator pathI, boolean connect) {
+ final float[] points = pathI.points();
+ while ( pathI.hasNext() ) {
+ final int idx = pathI.index();
+ final Path2F.SegmentType type = pathI.next();
+ switch(type) {
+ case MOVETO:
+ final Outline lo = this.getLastOutline();
+ final int lo_sz = lo.getVertexCount();
+ if ( 0 == lo_sz ) {
+ addVertex(0, points, idx, 2, true);
+ break;
+ } else if ( !connect ) {
+ closeLastOutline(false);
+ addEmptyOutline();
+ addVertex(0, points, idx, 2, true);
+ break;
+ }
+ {
+ // Skip if last vertex in last outline matching this point -> already connected.
+ final float[] llc = lo.getVertex(0).getCoord();
+ if( llc[0] == points[idx+0] &&
+ llc[1] == points[idx+1] ) {
+ break;
+ }
+ }
+ // fallthrough: MOVETO -> LINETO
+ case LINETO:
+ addVertex(0, points, idx, 2, true);
+ break;
+ case QUADTO:
+ addVertex(0, points, idx, 2, false);
+ addVertex(0, points, idx+2, 2, true);
+ break;
+ case CUBICTO:
+ addVertex(0, points, idx, 2, false);
+ addVertex(0, points, idx+2, 2, false);
+ addVertex(0, points, idx+4, 2, true);
+ break;
+ case CLOSE:
+ closeLastOutline(true);
+ addEmptyOutline();
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled Segment Type: "+type);
+ }
+ connect = false;
+ }
+ }
+
+ /**
+ * Start a new position for the next line segment at given point x/y (P1).
+ *
+ * The constructed shape should be {@link Winding#CCW}.
+ *
+ * @param x point (P1)
+ * @param y point (P1)
+ * @see Path2F#moveTo(float, float)
+ * @see #addPath(com.jogamp.graph.geom.plane.Path2F.Iterator, boolean)
+ */
+ public final void moveTo(final float x, final float y) {
+ if ( 0 == getLastOutline().getVertexCount() ) {
+ addVertex(x, y, true);
+ } else {
+ closeLastOutline(false);
+ addEmptyOutline();
+ addVertex(x, y, true);
+ }
+ }
+
+ /**
+ * Add a line segment, intersecting the last point and the given point x/y (P1).
+ *
+ * The constructed shape should be {@link Winding#CCW}.
+ *
+ * @param x final point (P1)
+ * @param y final point (P1)
+ * @see Path2F#lineTo(float, float)
+ * @see #addPath(com.jogamp.graph.geom.plane.Path2F.Iterator, boolean)
+ */
+ public final void lineTo(final float x, final float y) {
+ addVertex(x, y, true);
+ }
+
+ /**
+ * Add a quadratic curve segment, intersecting the last point and the second given point x2/y2 (P2).
+ *
+ * The constructed shape should be {@link Winding#CCW}.
+ *
+ * @param x1 quadratic parametric control point (P1)
+ * @param y1 quadratic parametric control point (P1)
+ * @param x2 final interpolated control point (P2)
+ * @param y2 final interpolated control point (P2)
+ * @see Path2F#quadTo(float, float, float, float)
+ * @see #addPath(com.jogamp.graph.geom.plane.Path2F.Iterator, boolean)
+ */
+ public final void quadTo(final float x1, final float y1, final float x2, final float y2) {
+ addVertex(x1, y1, false);
+ addVertex(x2, y2, true);
+ }
+
+ /**
+ * Add a cubic Bézier curve segment, intersecting the last point and the second given point x3/y3 (P3).
+ *
+ * The constructed shape should be {@link Winding#CCW}.
+ *
+ * @param x1 Bézier control point (P1)
+ * @param y1 Bézier control point (P1)
+ * @param x2 Bézier control point (P2)
+ * @param y2 Bézier control point (P2)
+ * @param x3 final interpolated control point (P3)
+ * @param y3 final interpolated control point (P3)
+ * @see Path2F#cubicTo(float, float, float, float, float, float)
+ * @see #addPath(com.jogamp.graph.geom.plane.Path2F.Iterator, boolean)
+ */
+ public final void cubicTo(final float x1, final float y1, final float x2, final float y2, final float x3, final float y3) {
+ addVertex(x1, y1, false);
+ addVertex(x2, y2, false);
+ addVertex(x3, y3, true);
+ }
+
+ /**
+ * Closes the current sub-path segment by drawing a straight line back to the coordinates of the last moveTo. If the path is already closed then this method has no effect.
+ * @see Path2F#closePath()
+ * @see #addPath(com.jogamp.graph.geom.plane.Path2F.Iterator, boolean)
+ */
+ public final void closePath() {
+ if ( 0 < getLastOutline().getVertexCount() ) {
+ closeLastOutline(true);
+ addEmptyOutline();
+ }
+ }
+
+ /**
* Return the outline's vertices state, {@link OutlineShape.VerticesState}
*/
public final VerticesState getOutlineState() {
diff --git a/src/jogl/classes/com/jogamp/graph/geom/Outline.java b/src/jogl/classes/com/jogamp/graph/geom/Outline.java
index 486e787a2..b18d51849 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/Outline.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/Outline.java
@@ -29,7 +29,6 @@ package com.jogamp.graph.geom;
import java.util.ArrayList;
-import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.geom.plane.AffineTransform;
import com.jogamp.graph.curve.OutlineShape;
import com.jogamp.graph.curve.Region;
diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/AffineTransform.java b/src/jogl/classes/com/jogamp/graph/geom/plane/AffineTransform.java
index a5b3cac93..62cda0322 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/plane/AffineTransform.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/plane/AffineTransform.java
@@ -530,7 +530,7 @@ public class AffineTransform implements Cloneable {
}
}
- public final Path2D createTransformedShape(final Path2D src) {
+ public final Path2F createTransformedShape(final Path2F src) {
if (src == null) {
return null;
}
diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/Crossing.java b/src/jogl/classes/com/jogamp/graph/geom/plane/Crossing2F.java
index 173f1d4b4..0cd4b66ff 100644
--- a/src/jogl/classes/com/jogamp/graph/geom/plane/Crossing.java
+++ b/src/jogl/classes/com/jogamp/graph/geom/plane/Crossing2F.java
@@ -21,9 +21,7 @@ package com.jogamp.graph.geom.plane;
import com.jogamp.opengl.math.FloatUtil;
-
-
-public class Crossing {
+/* pp */ class Crossing2F {
/**
* Allowable tolerance for bounds comparison
@@ -464,38 +462,36 @@ public class Crossing {
/**
* Returns how many times ray from point (x,y) cross path
*/
- public static int crossPath(final PathIterator p, final float x, final float y) {
+ public static int crossPath(final Path2F.Iterator p, final float x, final float y) {
int cross = 0;
float mx, my, cx, cy;
mx = my = cx = cy = 0.0f;
- final float coords[] = new float[6];
-
- while (!p.isDone()) {
- final int segmentType = p.currentSegment(coords);
+ final float[] points = p.points();
+ while ( p.hasNext() ) {
+ final int idx = p.index();
+ final Path2F.SegmentType segmentType = p.next();
switch (segmentType) {
- case PathIterator.SEG_MOVETO:
+ case MOVETO:
if (cx != mx || cy != my) {
cross += crossLine(cx, cy, mx, my, x, y);
}
- mx = cx = coords[0];
- my = cy = coords[1];
+ mx = cx = points[idx+0];
+ my = cy = points[idx+1];
break;
- case PathIterator.SEG_LINETO:
- cross += crossLine(cx, cy, cx = coords[0], cy = coords[1], x, y);
+ case LINETO:
+ cross += crossLine(cx, cy, cx = points[idx+0], cy = points[idx+1], x, y);
break;
- case PathIterator.SEG_QUADTO:
- cross += crossQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3], x, y);
+ case QUADTO:
+ cross += crossQuad(cx, cy, points[idx+0], points[idx+1], cx = points[idx+2], cy = points[idx+3], x, y);
break;
- case PathIterator.SEG_CUBICTO:
- cross += crossCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5], x, y);
+ case CUBICTO:
+ cross += crossCubic(cx, cy, points[idx+0], points[idx+1], points[idx+2], points[idx+3], cx = points[idx+4], cy = points[idx+5], x, y);
break;
- case PathIterator.SEG_CLOSE:
+ case CLOSE:
if (cy != my || cx != mx) {
cross += crossLine(cx, cy, cx = mx, cy = my, x, y);
}
break;
- default:
- throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType);
}
// checks if the point (x,y) is the vertex of shape with PathIterator p
@@ -504,7 +500,6 @@ public class Crossing {
cy = my;
break;
}
- p.next();
}
if (cy != my) {
cross += crossLine(cx, cy, mx, my, x, y);
@@ -515,7 +510,7 @@ public class Crossing {
/**
* Returns how many times ray from point (x,y) cross shape
*/
- public static int crossShape(final Path2D s, final float x, final float y) {
+ public static int crossShape(final Path2F s, final float x, final float y) {
if (!s.getBounds2D().contains(x, y)) {
return 0;
}
@@ -819,54 +814,53 @@ public class Crossing {
/**
* Returns how many times rectangle stripe cross path or the are intersect
*/
- public static int intersectPath(final PathIterator p, final float x, final float y, final float w, final float h) {
+ public static int intersectPath(final Path2F.Iterator p, final float x, final float y, final float w, final float h) {
int cross = 0;
int count;
float mx, my, cx, cy;
mx = my = cx = cy = 0.0f;
- final float coords[] = new float[6];
final float rx1 = x;
final float ry1 = y;
final float rx2 = x + w;
final float ry2 = y + h;
- while (!p.isDone()) {
+ final float[] points = p.points();
+
+ while ( p.hasNext() ) {
+ final int idx = p.index();
+ final Path2F.SegmentType segmentType = p.next();
count = 0;
- final int segmentType = p.currentSegment(coords);
switch (segmentType) {
- case PathIterator.SEG_MOVETO:
+ case MOVETO:
if (cx != mx || cy != my) {
count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
}
- mx = cx = coords[0];
- my = cy = coords[1];
+ mx = cx = points[idx+0];
+ my = cy = points[idx+1];
break;
- case PathIterator.SEG_LINETO:
- count = intersectLine(cx, cy, cx = coords[0], cy = coords[1], rx1, ry1, rx2, ry2);
+ case LINETO:
+ count = intersectLine(cx, cy, cx = points[idx+0], cy = points[idx+1], rx1, ry1, rx2, ry2);
break;
- case PathIterator.SEG_QUADTO:
- count = intersectQuad(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3], rx1, ry1, rx2, ry2);
+ case QUADTO:
+ count = intersectQuad(cx, cy, points[idx+0], points[idx+1], cx = points[idx+2], cy = points[idx+3], rx1, ry1, rx2, ry2);
break;
- case PathIterator.SEG_CUBICTO:
- count = intersectCubic(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5], rx1, ry1, rx2, ry2);
+ case CUBICTO:
+ count = intersectCubic(cx, cy, points[idx+0], points[idx+1], points[idx+2], points[idx+3], cx = points[idx+4], cy = points[idx+5], rx1, ry1, rx2, ry2);
break;
- case PathIterator.SEG_CLOSE:
+ case CLOSE:
if (cy != my || cx != mx) {
count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
}
cx = mx;
cy = my;
break;
- default:
- throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType);
}
if (count == CROSSING) {
return CROSSING;
}
cross += count;
- p.next();
}
if (cy != my) {
count = intersectLine(cx, cy, mx, my, rx1, ry1, rx2, ry2);
@@ -881,7 +875,7 @@ public class Crossing {
/**
* Returns how many times rectangle stripe cross shape or the are intersect
*/
- public static int intersectShape(final Path2D s, final float x, final float y, final float w, final float h) {
+ public static int intersectShape(final Path2F s, final float x, final float y, final float w, final float h) {
if (!s.getBounds2D().intersects2DRegion(x, y, w, h)) {
return 0;
}
diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/Path2D.java b/src/jogl/classes/com/jogamp/graph/geom/plane/Path2D.java
deleted file mode 100644
index 8dbc5fd21..000000000
--- a/src/jogl/classes/com/jogamp/graph/geom/plane/Path2D.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @author Sven Gothel
- */
-package com.jogamp.graph.geom.plane;
-
-import java.util.NoSuchElementException;
-
-import com.jogamp.graph.geom.SVertex;
-import com.jogamp.graph.geom.Vertex;
-import com.jogamp.opengl.math.geom.AABBox;
-
-
-public final class Path2D implements Cloneable {
-
- public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD;
- public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;
-
- static final String invalidWindingRuleValue = "Invalid winding rule value";
- static final String iteratorOutOfBounds = "Iterator out of bounds";
-
- /**
- * The buffers size
- */
- private static final int BUFFER_SIZE = 10;
-
- /**
- * The buffers capacity
- */
- private static final int BUFFER_CAPACITY = 10;
-
- /**
- * The point's types buffer
- */
- byte[] m_types;
-
- /**
- * The points buffer
- */
- float[] m_points;
-
- /**
- * The point's type buffer size
- */
- int m_typeSize;
-
- /**
- * The points buffer size
- */
- int m_pointSize;
-
- /**
- * The path rule
- */
- int m_rule;
-
- /**
- * The space amount in points buffer for different segmenet's types
- */
- static int pointShift[] = {
- 2, // MOVETO
- 2, // LINETO
- 4, // QUADTO
- 6, // CUBICTO
- 0}; // CLOSE
-
- /*
- * GeneralPath path iterator
- */
- static class Iterator implements PathIterator {
-
- /**
- * The current cursor position in types buffer
- */
- int typeIndex;
-
- /**
- * The current cursor position in points buffer
- */
- int pointIndex;
-
- /**
- * The source GeneralPath object
- */
- Path2D p;
-
- /**
- * The path iterator transformation
- */
- AffineTransform t;
-
- /**
- * Constructs a new GeneralPath.Iterator for given general path
- * @param path - the source GeneralPath object
- */
- Iterator(final Path2D path) {
- this(path, null);
- }
-
- /**
- * Constructs a new GeneralPath.Iterator for given general path and transformation
- * @param path - the source GeneralPath object
- * @param at - the AffineTransform object to apply rectangle path
- */
- Iterator(final Path2D path, final AffineTransform at) {
- this.p = path;
- this.t = at;
- }
-
- @Override
- public int getWindingRule() {
- return p.getWindingRule();
- }
-
- @Override
- public int index() { return typeIndex; }
-
- @Override
- public float[] points() { return p.m_points; }
-
- @Override
- public int getType(final int idx) { return p.m_types[idx]; }
-
- @Override
- public boolean isDone() {
- return typeIndex >= p.m_typeSize;
- }
-
- @Override
- public void next() {
- typeIndex++;
- }
-
- @Override
- public int currentSegment(final float[] coords) {
- if (isDone()) {
- throw new NoSuchElementException(iteratorOutOfBounds);
- }
- final int type = p.m_types[typeIndex];
- final int count = Path2D.pointShift[type];
- System.arraycopy(p.m_points, pointIndex, coords, 0, count);
- if (t != null) {
- t.transform(coords, 0, coords, 0, count / 2);
- }
- pointIndex += count;
- return type;
- }
-
- }
-
- public static int getPointCount(final int type) { return pointShift[type]; }
-
- public Path2D() {
- this(WIND_NON_ZERO, BUFFER_SIZE);
- }
-
- public Path2D(final int rule) {
- this(rule, BUFFER_SIZE);
- }
-
- public Path2D(final int rule, final int initialCapacity) {
- setWindingRule(rule);
- m_types = new byte[initialCapacity];
- m_points = new float[initialCapacity * 2];
- }
-
- public Path2D(final Path2D path) {
- this(WIND_NON_ZERO, BUFFER_SIZE);
- final PathIterator p = path.iterator(null);
- setWindingRule(p.getWindingRule());
- append(p, false);
- }
-
- public void setWindingRule(final int rule) {
- if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO) {
- throw new NoSuchElementException(invalidWindingRuleValue);
- }
- this.m_rule = rule;
- }
-
- public int getWindingRule() {
- return m_rule;
- }
-
- /**
- * Checks points and types buffer size to add pointCount points. If necessary realloc buffers to enlarge size.
- * @param pointCount - the point count to be added in buffer
- */
- void checkBuf(final int pointCount, final boolean checkMove) {
- if (checkMove && m_typeSize == 0) {
- throw new IllegalPathStateException("First segment should be SEG_MOVETO type");
- }
- if (m_typeSize == m_types.length) {
- final byte tmp[] = new byte[m_typeSize + BUFFER_CAPACITY];
- System.arraycopy(m_types, 0, tmp, 0, m_typeSize);
- m_types = tmp;
- }
- if (m_pointSize + pointCount > m_points.length) {
- final float tmp[] = new float[m_pointSize + Math.max(BUFFER_CAPACITY * 2, pointCount)];
- System.arraycopy(m_points, 0, tmp, 0, m_pointSize);
- m_points = tmp;
- }
- }
-
- public void moveTo(final float x, final float y) {
- if (m_typeSize > 0 && m_types[m_typeSize - 1] == PathIterator.SEG_MOVETO) {
- m_points[m_pointSize - 2] = x;
- m_points[m_pointSize - 1] = y;
- } else {
- checkBuf(2, false);
- m_types[m_typeSize++] = PathIterator.SEG_MOVETO;
- m_points[m_pointSize++] = x;
- m_points[m_pointSize++] = y;
- }
- }
-
- public void lineTo(final float x, final float y) {
- checkBuf(2, true);
- m_types[m_typeSize++] = PathIterator.SEG_LINETO;
- m_points[m_pointSize++] = x;
- m_points[m_pointSize++] = y;
- }
-
- public void quadTo(final float x1, final float y1, final float x2, final float y2) {
- checkBuf(4, true);
- m_types[m_typeSize++] = PathIterator.SEG_QUADTO;
- m_points[m_pointSize++] = x1;
- m_points[m_pointSize++] = y1;
- m_points[m_pointSize++] = x2;
- m_points[m_pointSize++] = y2;
- }
-
- public void curveTo(final float x1, final float y1, final float x2, final float y2, final float x3, final float y3) {
- checkBuf(6, true);
- m_types[m_typeSize++] = PathIterator.SEG_CUBICTO;
- m_points[m_pointSize++] = x1;
- m_points[m_pointSize++] = y1;
- m_points[m_pointSize++] = x2;
- m_points[m_pointSize++] = y2;
- m_points[m_pointSize++] = x3;
- m_points[m_pointSize++] = y3;
- }
-
- final public int size() {
- return m_typeSize;
- }
-
- final public boolean isClosed() {
- return m_typeSize > 0 && m_types[m_typeSize - 1] == PathIterator.SEG_CLOSE ;
- }
-
- public void closePath() {
- if (!isClosed()) {
- checkBuf(0, true);
- m_types[m_typeSize++] = PathIterator.SEG_CLOSE;
- }
- }
-
- @Override
- public String toString() {
- return "[size "+size()+", closed "+isClosed()+"]";
- }
-
- public void append(final Path2D path, final boolean connect) {
- final PathIterator p = path.iterator(null);
- append(p, connect);
- }
-
- /**
- * Append the given path geometry to this instance
- * @param path the {@link PathIterator} to append to this {@link Path2D}
- * @param connect pass true to turn an initial moveTo segment into a lineTo segment to connect the new geometry to the existing path, otherwise pass false.
- */
- public void append(final PathIterator path, boolean connect) {
- final float[] points = path.points();
- while ( !path.isDone() ) {
- final int index = path.index();
- final int type = path.getType(index);
- switch ( type ) {
- case PathIterator.SEG_MOVETO:
- if ( !connect || 0 == m_typeSize ) {
- moveTo(points[index+0], points[index+1]);
- break;
- }
- if ( m_types[m_typeSize - 1] != PathIterator.SEG_CLOSE &&
- m_points[m_pointSize - 2] == points[index+0] &&
- m_points[m_pointSize - 1] == points[index+1]
- )
- {
- break;
- }
- // fallthrough: MOVETO -> LINETO
- case PathIterator.SEG_LINETO:
- lineTo(points[index+0], points[index+1]);
- break;
- case PathIterator.SEG_QUADTO:
- quadTo(points[index+0], points[index+1], points[index+2], points[index+3]);
- break;
- case PathIterator.SEG_CUBICTO:
- curveTo(points[index+0], points[index+1], points[index+2], points[index+3], points[index+4], points[index+5]);
- break;
- case PathIterator.SEG_CLOSE:
- closePath();
- break;
- default:
- throw new IllegalArgumentException("Unhandled Segment Type: "+type);
- }
- path.next();
- connect = false;
- }
- }
-
- public SVertex getCurrentPoint() {
- if (m_typeSize == 0) {
- return null;
- }
- int j = m_pointSize - 2;
- if (m_types[m_typeSize - 1] == PathIterator.SEG_CLOSE) {
-
- for (int i = m_typeSize - 2; i > 0; i--) {
- final int type = m_types[i];
- if (type == PathIterator.SEG_MOVETO) {
- break;
- }
- j -= pointShift[type];
- }
- }
- return new SVertex(m_points[j], m_points[j + 1], 0f, true);
- }
-
- public void reset() {
- m_typeSize = 0;
- m_pointSize = 0;
- }
-
- public void transform(final AffineTransform t) {
- t.transform(m_points, 0, m_points, 0, m_pointSize / 2);
- }
-
- public Path2D createTransformedShape(final AffineTransform t) {
- final Path2D p = (Path2D)clone();
- if (t != null) {
- p.transform(t);
- }
- return p;
- }
-
- public final synchronized AABBox getBounds2D() {
- float rx1, ry1, rx2, ry2;
- if (m_pointSize == 0) {
- rx1 = ry1 = rx2 = ry2 = 0.0f;
- } else {
- int i = m_pointSize - 1;
- ry1 = ry2 = m_points[i--];
- rx1 = rx2 = m_points[i--];
- while (i > 0) {
- final float y = m_points[i--];
- final float x = m_points[i--];
- if (x < rx1) {
- rx1 = x;
- } else
- if (x > rx2) {
- rx2 = x;
- }
- if (y < ry1) {
- ry1 = y;
- } else
- if (y > ry2) {
- ry2 = y;
- }
- }
- }
- return new AABBox(rx1, ry1, 0f, rx2, ry2, 0f);
- }
-
- /**
- * Checks cross count according to path rule to define is it point inside shape or not.
- * @param cross - the point cross count
- * @return true if point is inside path, or false otherwise
- */
- boolean isInside(final int cross) {
- if (m_rule == WIND_NON_ZERO) {
- return Crossing.isInsideNonZero(cross);
- }
- return Crossing.isInsideEvenOdd(cross);
- }
-
- public boolean contains(final float px, final float py) {
- return isInside(Crossing.crossShape(this, px, py));
- }
-
- public boolean contains(final float rx, final float ry, final float rw, final float rh) {
- final int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
- return cross != Crossing.CROSSING && isInside(cross);
- }
-
- public boolean intersects(final float rx, final float ry, final float rw, final float rh) {
- final int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
- return cross == Crossing.CROSSING || isInside(cross);
- }
-
- public boolean contains(final Vertex p) {
- return contains(p.getX(), p.getY());
- }
-
- public boolean contains(final AABBox r) {
- return contains(r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight());
- }
-
- public boolean intersects(final AABBox r) {
- return intersects(r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight());
- }
-
- public PathIterator iterator() {
- return new Iterator(this);
- }
-
- public PathIterator iterator(final AffineTransform t) {
- return new Iterator(this, t);
- }
-
- /* public PathIterator getPathIterator(AffineTransform t, float flatness) {
- return new FlatteningPathIterator(getPathIterator(t), flatness);
- } */
-
- @Override
- public Object clone() {
- try {
- final Path2D p = (Path2D) super.clone();
- p.m_types = m_types.clone();
- p.m_points = m_points.clone();
- return p;
- } catch (final CloneNotSupportedException e) {
- throw new InternalError();
- }
- }
-}
-
diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/Path2F.java b/src/jogl/classes/com/jogamp/graph/geom/plane/Path2F.java
new file mode 100644
index 000000000..588232d9a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/graph/geom/plane/Path2F.java
@@ -0,0 +1,603 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Denis M. Kishenko
+ * @author Sven Gothel
+ */
+package com.jogamp.graph.geom.plane;
+
+import java.io.PrintStream;
+import java.util.NoSuchElementException;
+
+import com.jogamp.opengl.math.geom.AABBox;
+
+/**
+ * Path2F represents and provides construction method for a 2D shape using float[2] points.
+ */
+public final class Path2F implements Cloneable {
+ static final String invalidWindingRuleValue = "Invalid winding rule value";
+ static final String iteratorOutOfBounds = "Iterator out of bounds";
+
+ /** A Path2D segment type */
+ public static enum SegmentType {
+ MOVETO(1),
+ LINETO(1),
+ QUADTO(2),
+ CUBICTO(3),
+ CLOSE(0);
+
+ /** Number of points associated with this segment type */
+ public final int point_count;
+
+ /** Return the integer segment type value as a byte */
+ public byte integer() {
+ return (byte) this.ordinal();
+ }
+
+ /** Return the SegmentType associated with the integer segment type */
+ public static SegmentType valueOf(final int type) {
+ switch( type ) {
+ case 0: return MOVETO;
+ case 1: return LINETO;
+ case 2: return QUADTO;
+ case 3: return CUBICTO;
+ case 4: return CLOSE;
+ default:
+ throw new IllegalArgumentException("Unhandled Segment Type: "+type);
+ }
+ }
+
+ /** Return the number of points associated with the integer segment type */
+ public static int getPointCount(final int type) {
+ switch( type ) {
+ case 0: return MOVETO.point_count;
+ case 1: return LINETO.point_count;
+ case 2: return QUADTO.point_count;
+ case 3: return CUBICTO.point_count;
+ case 4: return CLOSE.point_count;
+ default:
+ throw new IllegalArgumentException("Unhandled Segment Type: "+type);
+ }
+ }
+
+ SegmentType(final int v) {
+ this.point_count = v;
+ }
+ }
+
+ /**
+ * The buffers size
+ */
+ private static final int BUFFER_SIZE = 10;
+
+ /**
+ * The buffers capacity
+ */
+ private static final int BUFFER_CAPACITY = 10;
+
+ /**
+ * The point's types buffer
+ */
+ private byte[] m_types;
+
+ /**
+ * The points buffer
+ */
+ private float[] m_points;
+
+ /**
+ * The point's type buffer size
+ */
+ private int m_typeSize;
+
+ /**
+ * The points buffer size
+ */
+ private int m_pointSize;
+
+ /**
+ * The winding path rule
+ */
+ private WindingRule m_rule;
+
+ /*
+ * GeneralPath path iterator
+ */
+ public static final class Iterator {
+
+ /**
+ * The source GeneralPath object
+ */
+ private final Path2F p;
+
+ /**
+ * The path iterator transformation
+ */
+ private final AffineTransform t;
+
+ /**
+ * The current cursor position in types buffer
+ */
+ private int typeIndex;
+
+ /**
+ * The current cursor position in points buffer
+ */
+ private int pointIndex;
+
+ /**
+ * Constructs a new GeneralPath.Iterator for given general path
+ * @param path - the source GeneralPath object
+ */
+ Iterator(final Path2F path) {
+ this(path, null);
+ }
+
+ /**
+ * Constructs a new GeneralPath.Iterator for given general path and transformation
+ * @param path - the source GeneralPath object
+ * @param at - the AffineTransform object to apply rectangle path
+ */
+ public Iterator(final Path2F path, final AffineTransform at) {
+ this.p = path;
+ this.t = at;
+ reset();
+ }
+
+ private void reset() {
+ typeIndex = 0;
+ pointIndex = 0;
+ }
+
+ /** Return the {@link WindingRule} set */
+ public WindingRule getWindingRule() {
+ return p.getWindingRule();
+ }
+
+ /**
+ * Compute the general winding of the vertices
+ * @return CCW or CW {@link Winding}
+ */
+ public Winding getWinding() {
+ return area() >= 0 ? Winding.CCW : Winding.CW ;
+ }
+
+ /** Returns reference of the point array covering the whole iteration of Path2D, use {@link #index()} to access the current point. */
+ public float[] points() { return p.m_points; }
+
+ /** Return the {@link #points()} index for the current segment. */
+ public int index() { return pointIndex; }
+
+ /** Return current segment type */
+ public SegmentType getType() { return SegmentType.valueOf( p.m_types[typeIndex] ); }
+
+ /**
+ * Return the current segment type and copies the current segment's points to given storage
+ * @param coords storage for current segment's points
+ * @return current segment type
+ * @see #points()
+ * @see #type_index()
+ * @see #getType()
+ * @deprecated try to use {@link #index()}, {@link #points()} and {@link #next()} to avoid copying
+ */
+ @Deprecated
+ public SegmentType currentSegment(final float[] coords) {
+ if (!hasNext()) {
+ throw new NoSuchElementException(iteratorOutOfBounds);
+ }
+ final SegmentType type = getType();
+ final int count = type.point_count;
+ System.arraycopy(p.m_points, pointIndex, coords, 0, count*2);
+ if (t != null) {
+ t.transform(coords, 0, coords, 0, count);
+ }
+ return type;
+ }
+
+ /** Returns true if the iteration has more elements. */
+ public boolean hasNext() {
+ return typeIndex < p.m_typeSize;
+ }
+
+ /** Returns the current segment type in the iteration, then moving to the next path segment. */
+ public SegmentType next() {
+ final SegmentType t = getType();
+ pointIndex += 2 * t.point_count;
+ ++typeIndex;
+ return t;
+ }
+
+ /**
+ * Computes the area of the path to check if ccw
+ * @return positive area if ccw else negative area value
+ */
+ private float area() {
+ float area = 0.0f;
+ final float[] points = points();
+ final float[] pCoord = new float[2];
+ while ( hasNext() ) {
+ final int idx = index();
+ final SegmentType type = next();
+ switch ( type ) {
+ case MOVETO:
+ pCoord[0] = points[idx+0];
+ pCoord[1] = points[idx+1];
+ break;
+ case LINETO:
+ area += pCoord[0] * points[idx+1] - points[idx+0] * pCoord[1];
+ pCoord[0] = points[idx+0];
+ pCoord[1] = points[idx+1];
+ break;
+ case QUADTO:
+ area += pCoord[0] * points[idx+1] - points[idx+0] * pCoord[1];
+ area += points[idx+0] * points[idx+3] - points[idx+2] * points[idx+1];
+ pCoord[0] = points[idx+2];
+ pCoord[1] = points[idx+3];
+ break;
+ case CUBICTO:
+ area += pCoord[0] * points[idx+1] - points[idx+0] * pCoord[1];
+ area += points[idx+0] * points[idx+3] - points[idx+2] * points[idx+1];
+ area += points[idx+2] * points[idx+5] - points[idx+4] * points[idx+3];
+ pCoord[0] = points[idx+4];
+ pCoord[1] = points[idx+5];
+ break;
+ case CLOSE:
+ break;
+ }
+ }
+ reset();
+ return area;
+ }
+ }
+
+ public Path2F() {
+ this(WindingRule.NON_ZERO, BUFFER_SIZE, BUFFER_SIZE);
+ }
+
+ public Path2F(final WindingRule rule) {
+ this(rule, BUFFER_SIZE, BUFFER_SIZE);
+ }
+
+ public Path2F(final WindingRule rule, final int initialCapacity) {
+ this(rule, initialCapacity, initialCapacity);
+ }
+
+ public Path2F(final WindingRule rule, final int initialTypeCapacity, final int initialPointCapacity) {
+ setWindingRule(rule);
+ m_types = new byte[initialTypeCapacity];
+ m_points = new float[initialPointCapacity * 2];
+ }
+
+ public Path2F(final Path2F path) {
+ this(WindingRule.NON_ZERO, BUFFER_SIZE);
+ final Iterator p = path.iterator(null);
+ setWindingRule(p.getWindingRule());
+ append(p, false);
+ }
+
+ /** Set the {@link WindingRule} set */
+ public void setWindingRule(final WindingRule rule) {
+ this.m_rule = rule;
+ }
+
+ /** Return the {@link WindingRule} set */
+ public WindingRule getWindingRule() {
+ return m_rule;
+ }
+
+ /**
+ * Checks points and types buffer size to add pointCount points. If necessary realloc buffers to enlarge size.
+ * @param pointCount - the point count to be added in buffer
+ */
+ private void checkBuf(final int pointCount, final boolean checkMove) {
+ if (checkMove && m_typeSize == 0) {
+ throw new IllegalPathStateException("First segment should be SEG_MOVETO type");
+ }
+ if (m_typeSize == m_types.length) {
+ final byte tmp[] = new byte[m_typeSize + BUFFER_CAPACITY];
+ System.arraycopy(m_types, 0, tmp, 0, m_typeSize);
+ m_types = tmp;
+ }
+ if (m_pointSize + pointCount > m_points.length) {
+ final float tmp[] = new float[m_pointSize + Math.max(BUFFER_CAPACITY * 2, pointCount)];
+ System.arraycopy(m_points, 0, tmp, 0, m_pointSize);
+ m_points = tmp;
+ }
+ }
+
+ /**
+ * Start a new position for the next line segment at given point x/y (P1).
+ * @param x point (P1)
+ * @param y point (P1)
+ */
+ public void moveTo(final float x, final float y) {
+ if ( m_typeSize > 0 && m_types[m_typeSize - 1] == SegmentType.MOVETO.integer() ) {
+ m_points[m_pointSize - 2] = x;
+ m_points[m_pointSize - 1] = y;
+ } else {
+ checkBuf(2, false);
+ m_types[m_typeSize++] = SegmentType.MOVETO.integer();
+ m_points[m_pointSize++] = x;
+ m_points[m_pointSize++] = y;
+ }
+ }
+
+ /**
+ * Add a line segment, intersecting the last point and the given point x/y (P1).
+ * @param x final point (P1)
+ * @param y final point (P1)
+ */
+ public void lineTo(final float x, final float y) {
+ checkBuf(2, true);
+ m_types[m_typeSize++] = SegmentType.LINETO.integer();
+ m_points[m_pointSize++] = x;
+ m_points[m_pointSize++] = y;
+ }
+
+ /**
+ * Add a quadratic curve segment, intersecting the last point and the second given point x2/y2 (P2).
+ * @param x1 quadratic parametric control point (P1)
+ * @param y1 quadratic parametric control point (P1)
+ * @param x2 final interpolated control point (P2)
+ * @param y2 final interpolated control point (P2)
+ */
+ public void quadTo(final float x1, final float y1, final float x2, final float y2) {
+ checkBuf(4, true);
+ m_types[m_typeSize++] = SegmentType.QUADTO.integer();
+ m_points[m_pointSize++] = x1;
+ m_points[m_pointSize++] = y1;
+ m_points[m_pointSize++] = x2;
+ m_points[m_pointSize++] = y2;
+ }
+
+ /**
+ * Add a cubic Bézier curve segment, intersecting the last point and the second given point x3/y3 (P3).
+ * @param x1 Bézier control point (P1)
+ * @param y1 Bézier control point (P1)
+ * @param x2 Bézier control point (P2)
+ * @param y2 Bézier control point (P2)
+ * @param x3 final interpolated control point (P3)
+ * @param y3 final interpolated control point (P3)
+ */
+ public void cubicTo(final float x1, final float y1, final float x2, final float y2, final float x3, final float y3) {
+ checkBuf(6, true);
+ m_types[m_typeSize++] = SegmentType.CUBICTO.integer();
+ m_points[m_pointSize++] = x1;
+ m_points[m_pointSize++] = y1;
+ m_points[m_pointSize++] = x2;
+ m_points[m_pointSize++] = y2;
+ m_points[m_pointSize++] = x3;
+ m_points[m_pointSize++] = y3;
+ }
+
+ /**
+ * Closes the current sub-path segment by drawing a straight line back to the coordinates of the last moveTo. If the path is already closed then this method has no effect.
+ */
+ public void closePath() {
+ if (!isClosed()) {
+ checkBuf(0, true);
+ m_types[m_typeSize++] = SegmentType.CLOSE.integer();
+ }
+ }
+
+ final public int size() {
+ return m_typeSize;
+ }
+
+ /**
+ * Returns true if the last sub-path is closed, otherwise false.
+ */
+ final public boolean isClosed() {
+ return m_typeSize > 0 && m_types[m_typeSize - 1] == SegmentType.CLOSE.integer() ;
+ }
+
+ /**
+ * Compute the general winding of the vertices
+ * @param vertices array of Vertices
+ * @return CCW or CW {@link Winding}
+ */
+ public Winding getWinding() {
+ return iterator(null).getWinding();
+ }
+
+ @Override
+ public String toString() {
+ return "[size "+size()+", closed "+isClosed()+", winding[rule "+getWindingRule()+", "+getWinding()+"]]";
+ }
+
+ /**
+ * Append the given path geometry to this instance
+ * @param path the {@link Path2F} to append to this instance
+ * @param connect pass true to turn an initial moveTo segment into a lineTo segment to connect the new geometry to the existing path, otherwise pass false.
+ */
+ public void append(final Path2F path, final boolean connect) {
+ append(path.iterator(null), connect);
+ }
+
+ /**
+ * Append the given path geometry to this instance
+ * @param path the {@link Path2F.Iterator} to append to this instance
+ * @param connect pass true to turn an initial moveTo segment into a lineTo segment to connect the new geometry to the existing path, otherwise pass false.
+ */
+ public void append(final Iterator path, boolean connect) {
+ final float[] points = path.points();
+ while ( path.hasNext() ) {
+ final int idx = path.index();
+ final SegmentType type = path.next();
+ switch ( type ) {
+ case MOVETO:
+ if ( !connect || 0 == m_typeSize ) {
+ moveTo(points[idx+0], points[idx+1]);
+ break;
+ }
+ if ( m_types[m_typeSize - 1] != SegmentType.CLOSE.integer() &&
+ m_points[m_pointSize - 2] == points[idx+0] &&
+ m_points[m_pointSize - 1] == points[idx+1]
+ )
+ {
+ break;
+ }
+ // fallthrough: MOVETO -> LINETO
+ case LINETO:
+ lineTo(points[idx+0], points[idx+1]);
+ break;
+ case QUADTO:
+ quadTo(points[idx+0], points[idx+1], points[idx+2], points[idx+3]);
+ break;
+ case CUBICTO:
+ cubicTo(points[idx+0], points[idx+1], points[idx+2], points[idx+3], points[idx+4], points[idx+5]);
+ break;
+ case CLOSE:
+ closePath();
+ break;
+ }
+ connect = false;
+ }
+ }
+
+ public void printSegments(final PrintStream out) {
+ final Iterator path = iterator();
+ final float[] points = path.points();
+ int i = 0;
+ while ( path.hasNext() ) {
+ final int idx = path.index();
+ final SegmentType type = path.next();
+ switch ( type ) {
+ case MOVETO:
+ out.printf("%2d: moveTo(%.4f/%.4f)%n", i, points[idx+0], points[idx+1]);
+ break;
+ case LINETO:
+ out.printf("%2d: lineTo(%.4f/%.4f)%n", i, points[idx+0], points[idx+1]);
+ break;
+ case QUADTO:
+ out.printf("%2d: quadTo(%.4f/%.4f, %.4f/%.4f)%n", i, points[idx+0], points[idx+1], points[idx+2], points[idx+3]);
+ break;
+ case CUBICTO:
+ out.printf("%2d: cubicTo(%.4f/%.4f, %.4f/%.4f, %.4f/%.4f)%n", i, points[idx+0], points[idx+1], points[idx+2], points[idx+3], points[idx+4], points[idx+5]);
+ break;
+ case CLOSE:
+ out.printf("%2d: closePath()%n", i);
+ break;
+ }
+ ++i;
+ }
+ }
+
+ public void reset() {
+ m_typeSize = 0;
+ m_pointSize = 0;
+ }
+
+ public void transform(final AffineTransform t) {
+ t.transform(m_points, 0, m_points, 0, m_pointSize / 2);
+ }
+
+ public Path2F createTransformedShape(final AffineTransform t) {
+ final Path2F p = (Path2F)clone();
+ if (t != null) {
+ p.transform(t);
+ }
+ return p;
+ }
+
+ public final synchronized AABBox getBounds2D() {
+ float rx1, ry1, rx2, ry2;
+ if (m_pointSize == 0) {
+ rx1 = ry1 = rx2 = ry2 = 0.0f;
+ } else {
+ int i = m_pointSize - 1;
+ ry1 = ry2 = m_points[i--];
+ rx1 = rx2 = m_points[i--];
+ while (i > 0) {
+ final float y = m_points[i--];
+ final float x = m_points[i--];
+ if (x < rx1) {
+ rx1 = x;
+ } else
+ if (x > rx2) {
+ rx2 = x;
+ }
+ if (y < ry1) {
+ ry1 = y;
+ } else
+ if (y > ry2) {
+ ry2 = y;
+ }
+ }
+ }
+ return new AABBox(rx1, ry1, 0f, rx2, ry2, 0f);
+ }
+
+ /**
+ * Checks cross count according to path rule to define is it point inside shape or not.
+ * @param cross - the point cross count
+ * @return true if point is inside path, or false otherwise
+ */
+ boolean isInside(final int cross) {
+ if (m_rule == WindingRule.NON_ZERO) {
+ return Crossing2F.isInsideNonZero(cross);
+ }
+ return Crossing2F.isInsideEvenOdd(cross);
+ }
+
+ public boolean contains(final float px, final float py) {
+ return isInside(Crossing2F.crossShape(this, px, py));
+ }
+
+ public boolean contains(final float rx, final float ry, final float rw, final float rh) {
+ final int cross = Crossing2F.intersectShape(this, rx, ry, rw, rh);
+ return cross != Crossing2F.CROSSING && isInside(cross);
+ }
+
+ public boolean intersects(final float rx, final float ry, final float rw, final float rh) {
+ final int cross = Crossing2F.intersectShape(this, rx, ry, rw, rh);
+ return cross == Crossing2F.CROSSING || isInside(cross);
+ }
+
+ public boolean contains(final AABBox r) {
+ return contains(r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight());
+ }
+
+ public boolean intersects(final AABBox r) {
+ return intersects(r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight());
+ }
+
+ public Iterator iterator() {
+ return new Iterator(this);
+ }
+
+ public Iterator iterator(final AffineTransform t) {
+ return new Iterator(this, t);
+ }
+
+ /* public Path2F.Iterator getPathIterator(AffineTransform t, float flatness) {
+ return new FlatteningPathIterator(getPathIterator(t), flatness);
+ } */
+
+ @Override
+ public Object clone() {
+ try {
+ final Path2F p = (Path2F) super.clone();
+ p.m_types = m_types.clone();
+ p.m_points = m_points.clone();
+ return p;
+ } catch (final CloneNotSupportedException e) {
+ throw new InternalError();
+ }
+ }
+}
+
diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/PathIterator.java b/src/jogl/classes/com/jogamp/graph/geom/plane/PathIterator.java
deleted file mode 100644
index 3aae2a172..000000000
--- a/src/jogl/classes/com/jogamp/graph/geom/plane/PathIterator.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * @author Denis M. Kishenko
- * @author Sven Gothel
- */
-package com.jogamp.graph.geom.plane;
-
-public interface PathIterator {
-
- public static final int WIND_EVEN_ODD = 0;
- public static final int WIND_NON_ZERO = 1;
-
- public static final int SEG_MOVETO = 0;
- public static final int SEG_LINETO = 1;
- public static final int SEG_QUADTO = 2;
- public static final int SEG_CUBICTO = 3;
- public static final int SEG_CLOSE = 4;
-
- int getWindingRule();
-
- /** Return the current {@link #points()} index for the current segment. */
- int index();
-
- /** Returns reference of the point array for the whole Path2D */
- float[] points();
-
- /** Return current segment type */
- int getType(final int idx);
-
- /** Returns true if completed */
- boolean isDone();
-
- void next();
-
- /**
- * Return the path segment type and copies the current segment's points to given storage
- * @param coords storage for current segment's points
- * @return segment type
- * @see #points()
- * @see #index()
- * @see #getType(int)
- */
- int currentSegment(float[] coords);
-}
-
diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/Winding.java b/src/jogl/classes/com/jogamp/graph/geom/plane/Winding.java
new file mode 100644
index 000000000..bfa214c22
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/graph/geom/plane/Winding.java
@@ -0,0 +1,18 @@
+package com.jogamp.graph.geom.plane;
+
+/**
+ * Winding direction, either clockwise (CW) or counter-clockwise (CCW).
+ */
+public enum Winding {
+ /** Clockwise (Cw) negative winding direction */
+ CW(-1),
+ /** Counter-Clockwise (CCW) positive winding direction */
+ CCW(1);
+
+ /** The winding direction sign, i.e. positive 1 for CCW and negative -1 for CW. */
+ public final int dir;
+
+ Winding(final int dir) {
+ this.dir = dir;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/WindingRule.java b/src/jogl/classes/com/jogamp/graph/geom/plane/WindingRule.java
new file mode 100644
index 000000000..46ef167a3
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/graph/geom/plane/WindingRule.java
@@ -0,0 +1,28 @@
+package com.jogamp.graph.geom.plane;
+
+/**
+ * Winding rule, either EVEN_ODD or NON_ZERO (like for TrueType fonts).
+ */
+public enum WindingRule {
+ /**
+ * The even-odd rule specifies that a point lies inside the path
+ * if a ray drawn in any direction from that point to infinity is crossed by path segments
+ * an odd number of times.
+ */
+ EVEN_ODD(0),
+
+ /**
+ * The non-zero rule specifies that a point lies inside the path
+ * if a ray drawn in any direction from that point to infinity is crossed by path segments
+ * a different number of times in the counter-clockwise direction than the clockwise direction.
+ *
+ * Non-zero winding rule is used by TrueType fonts.
+ */
+ NON_ZERO(1);
+
+ public final int value;
+
+ WindingRule(final int v) {
+ this.value = v;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java
index 36222cf4a..3ee504a29 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java
@@ -29,6 +29,8 @@ package com.jogamp.opengl.math;
import java.util.ArrayList;
+import com.jogamp.graph.geom.plane.Winding;
+
public final class VectorUtil {
public static final float[] VEC3_ONE = { 1f, 1f, 1f };
@@ -38,16 +40,6 @@ public final class VectorUtil {
public static final float[] VEC3_UNIT_Z = { 0f, 0f, 1f };
public static final float[] VEC3_UNIT_Z_NEG = { 0f, 0f, -1f };
- public enum Winding {
- CW(-1), CCW(1);
-
- public final int dir;
-
- Winding(final int dir) {
- this.dir = dir;
- }
- }
-
/**
* Copies a vector of length 2
* @param dst output vector
diff --git a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java
index 4473d040f..369d0b493 100644
--- a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java
+++ b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java
@@ -35,6 +35,7 @@ import com.jogamp.graph.curve.tess.Triangulator;
import com.jogamp.graph.geom.Outline;
import com.jogamp.graph.geom.Triangle;
import com.jogamp.graph.geom.Vertex;
+import com.jogamp.graph.geom.plane.Winding;
import com.jogamp.opengl.math.VectorUtil;
import jogamp.opengl.Debug;
@@ -89,7 +90,7 @@ public class CDTriangulator2D implements Triangulator {
final GraphOutline outline = new GraphOutline(polyline);
final GraphOutline innerPoly = extractBoundaryTriangles(sink, outline, false, sharpness);
// vertices.addAll(polyline.getVertices());
- loop = new Loop(innerPoly, VectorUtil.Winding.CCW);
+ loop = new Loop(innerPoly, Winding.CCW);
loops.add(loop);
} else {
final GraphOutline outline = new GraphOutline(polyline);
diff --git a/src/jogl/classes/jogamp/graph/curve/tess/Loop.java b/src/jogl/classes/jogamp/graph/curve/tess/Loop.java
index 6563219cc..5d1bc051f 100644
--- a/src/jogl/classes/jogamp/graph/curve/tess/Loop.java
+++ b/src/jogl/classes/jogamp/graph/curve/tess/Loop.java
@@ -31,6 +31,7 @@ import java.util.ArrayList;
import com.jogamp.graph.geom.Vertex;
+import com.jogamp.graph.geom.plane.Winding;
import com.jogamp.graph.geom.Triangle;
import com.jogamp.opengl.math.VectorUtil;
import com.jogamp.opengl.math.geom.AABBox;
@@ -40,7 +41,7 @@ public class Loop {
private final AABBox box = new AABBox();
private GraphOutline initialOutline = null;
- public Loop(final GraphOutline polyline, final VectorUtil.Winding winding){
+ public Loop(final GraphOutline polyline, final Winding winding){
initialOutline = polyline;
this.root = initFromPolyline(initialOutline, winding);
}
@@ -94,23 +95,23 @@ public class Loop {
* from the boundary profile
* @param reqWinding requested winding of edges (CCW or CW)
*/
- private HEdge initFromPolyline(final GraphOutline outline, final VectorUtil.Winding reqWinding){
+ private HEdge initFromPolyline(final GraphOutline outline, final Winding reqWinding){
final ArrayList<GraphVertex> vertices = outline.getGraphPoint();
if(vertices.size()<3) {
throw new IllegalArgumentException("outline's vertices < 3: " + vertices.size());
}
- final VectorUtil.Winding hasWinding = VectorUtil.getWinding(
+ final Winding hasWinding = VectorUtil.getWinding(
vertices.get(0).getPoint(),
vertices.get(1).getPoint(),
vertices.get(2).getPoint());
//FIXME: handle case when vertices come inverted - Rami
// skips inversion CW -> CCW
final boolean invert = hasWinding != reqWinding &&
- reqWinding == VectorUtil.Winding.CW;
+ reqWinding == Winding.CW;
final int max;
- final int edgeType = reqWinding == VectorUtil.Winding.CCW ? HEdge.BOUNDARY : HEdge.HOLE ;
+ final int edgeType = reqWinding == Winding.CCW ? HEdge.BOUNDARY : HEdge.HOLE ;
int index;
HEdge firstEdge = null;
HEdge lastEdge = null;
@@ -158,7 +159,7 @@ public class Loop {
public void addConstraintCurve(final GraphOutline polyline) {
// GraphOutline outline = new GraphOutline(polyline);
/**needed to generate vertex references.*/
- initFromPolyline(polyline, VectorUtil.Winding.CW);
+ initFromPolyline(polyline, Winding.CW);
final GraphVertex v3 = locateClosestVertex(polyline);
final HEdge v3Edge = v3.findBoundEdge();
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java b/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java
index b5c0d259e..b9d62cac4 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java
@@ -49,7 +49,7 @@ import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.geom.SVertex;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.graph.demos.GPURegionGLListener01;
-import com.jogamp.opengl.test.junit.graph.demos.GPURegionGLListener02;
+import com.jogamp.opengl.test.junit.graph.demos.GPURegionGLListener10;
import com.jogamp.opengl.test.junit.graph.demos.GPURendererListenerBase01;
import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -88,7 +88,7 @@ public class TestRegionRendererNEWT01 extends UITestCase {
// caps.setOnscreen(false);
caps.setAlphaBits(4);
- final GLWindow window = createWindow("shape-vbaa0-msaa0", caps, 800, 400);
+ final GLWindow window = createWindow("t00-shape-vbaa0-msaa0", caps, 800, 400);
final RenderState rs = RenderState.createRenderState(SVertex.factory());
final GPURegionGLListener01 demo01Listener = new GPURegionGLListener01 (rs, 0, 0, false, false);
@@ -122,7 +122,7 @@ public class TestRegionRendererNEWT01 extends UITestCase {
final GLCapabilities caps = new GLCapabilities(glp);
caps.setAlphaBits(4);
- final GLWindow window = createWindow("shape-vbaa0-msaa0", caps, 800, 400);
+ final GLWindow window = createWindow("t01-shape-vbaa0-msaa0", caps, 800, 400);
final RenderState rs = RenderState.createRenderState(SVertex.factory());
final GPURegionGLListener01 demo01Listener = new GPURegionGLListener01 (rs, Region.VARWEIGHT_RENDERING_BIT, 0, false, false);
@@ -153,7 +153,7 @@ public class TestRegionRendererNEWT01 extends UITestCase {
caps.setSampleBuffers(true);
caps.setNumSamples(4);
- final GLWindow window = createWindow("shape-vbaa0-msaa1", caps, 800, 400);
+ final GLWindow window = createWindow("t10-shape-vbaa0-msaa1", caps, 800, 400);
final RenderState rs = RenderState.createRenderState(SVertex.factory());
final GPURegionGLListener01 demo01Listener = new GPURegionGLListener01 (rs, 0, 0, false, false);
@@ -189,7 +189,7 @@ public class TestRegionRendererNEWT01 extends UITestCase {
caps.setSampleBuffers(true);
caps.setNumSamples(4);
- final GLWindow window = createWindow("shape-vbaa0-msaa1", caps, 800, 400);
+ final GLWindow window = createWindow("t11-shape-vbaa0-msaa1", caps, 800, 400);
final RenderState rs = RenderState.createRenderState(SVertex.factory());
final GPURegionGLListener01 demo01Listener = new GPURegionGLListener01 (rs, Region.VARWEIGHT_RENDERING_BIT, 0, false, false);
@@ -224,9 +224,9 @@ public class TestRegionRendererNEWT01 extends UITestCase {
//caps.setOnscreen(false);
caps.setAlphaBits(4);
- final GLWindow window = createWindow("shape-vbaa1-msaa0", caps, 800,400);
+ final GLWindow window = createWindow("t20-shape-vbaa1-msaa0", caps, 800,400);
final RenderState rs = RenderState.createRenderState(SVertex.factory());
- final GPURegionGLListener02 demo02Listener = new GPURegionGLListener02 (rs, Region.VBAA_RENDERING_BIT, 4, false, false);
+ final GPURegionGLListener10 demo02Listener = new GPURegionGLListener10 (rs, Region.VBAA_RENDERING_BIT, 4, false, false);
demo02Listener.attachInputListenerTo(window);
window.addGLEventListener(demo02Listener);
@@ -245,6 +245,39 @@ public class TestRegionRendererNEWT01 extends UITestCase {
destroyWindow(window);
}
+ private void test30RegionRendererShapesImpl(final GLCapabilities caps, final int shape_ctor_mode) throws InterruptedException {
+ final GLWindow window = createWindow("t30-shape0"+shape_ctor_mode+"-vbaa0-msaa1", caps, 800, 400);
+ final RenderState rs = RenderState.createRenderState(SVertex.factory());
+
+ final GPURegionGLListener01 demo01Listener = new GPURegionGLListener01 (shape_ctor_mode, rs, 0, 0, false, false);
+ demo01Listener.attachInputListenerTo(window);
+ window.addGLEventListener(demo01Listener);
+
+ final RegionGLListener listener = new RegionGLListener(demo01Listener, window.getTitle(), "GPURegion01");
+ window.addGLEventListener(listener);
+
+ // listener.setTech(-20, 00, -300, 0f, 2);
+ listener.setTech(-20, 00, -50, 0f, 4);
+ window.display();
+
+ destroyWindow(window);
+ }
+
+ @Test
+ public void test30RegionRendererShapes() throws InterruptedException {
+ final GLProfile glp = GLProfile.get(GLProfile.GL2ES2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ // caps.setOnscreen(false);
+ caps.setAlphaBits(4);
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(4);
+
+ test30RegionRendererShapesImpl(caps, 1);
+ test30RegionRendererShapesImpl(caps, 2);
+ test30RegionRendererShapesImpl(caps, 3);
+ test30RegionRendererShapesImpl(caps, 4);
+ }
+
private static class RegionGLListener implements GLEventListener {
String winTitle;
String name;
@@ -260,10 +293,12 @@ public class TestRegionRendererNEWT01 extends UITestCase {
impl.setMatrix(xt, yt, zt, angle, sampleCount);
}
+ @Override
public void init(final GLAutoDrawable drawable) {
impl.init(drawable);
}
+ @Override
public void display(final GLAutoDrawable drawable) {
impl.display(drawable);
@@ -276,11 +311,13 @@ public class TestRegionRendererNEWT01 extends UITestCase {
}
}
+ @Override
public void dispose(final GLAutoDrawable drawable) {
impl.dispose(drawable);
}
+ @Override
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
impl.reshape(drawable, x, y, width, height);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener00.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener00.java
new file mode 100644
index 000000000..1059423f3
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener00.java
@@ -0,0 +1,133 @@
+/**
+ * Copyright 2010 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;
+
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GL2ES2;
+import com.jogamp.opengl.GLAutoDrawable;
+import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
+
+import com.jogamp.graph.curve.OutlineShape;
+import com.jogamp.graph.curve.opengl.GLRegion;
+import com.jogamp.graph.curve.opengl.RenderState;
+import com.jogamp.graph.curve.opengl.RegionRenderer;
+import com.jogamp.opengl.util.PMVMatrix;
+
+/** Demonstrate the rendering of multiple outlines into one region/OutlineShape
+ * These Outlines are not necessary connected or contained.
+ * The output of this demo shows two identical shapes but the left one
+ * has some vertices with off-curve flag set to true, and the right allt he vertices
+ * are on the curve. Demos the Res. Independent Nurbs based Curve rendering
+ *
+ */
+public class GPURegionGLListener00 extends GPURendererListenerBase01 {
+ OutlineShape outlineShape = null;
+
+ public GPURegionGLListener00 (final RenderState rs, final int renderModes, final int sampleCount, final boolean debug, final boolean trace) {
+ super(RegionRenderer.create(rs, RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable), renderModes, debug, trace);
+ rs.setHintMask(RenderState.BITHINT_GLOBAL_DEPTH_TEST_ENABLED);
+ setMatrix(-20, 00, -50, 0f, sampleCount);
+ }
+
+ private void createTestOutline(){
+ outlineShape = new OutlineShape(getRenderer().getRenderState().getVertexFactory());
+ outlineShape.addVertex(0.0f,-10.0f, true);
+ outlineShape.addVertex(15.0f,-10.0f, true);
+ outlineShape.addVertex(10.0f,5.0f, false);
+ outlineShape.addVertex(15.0f,10.0f, true);
+ outlineShape.addVertex(6.0f,15.0f, false);
+ outlineShape.addVertex(5.0f,8.0f, false);
+ outlineShape.addVertex(0.0f,10.0f,true);
+ outlineShape.closeLastOutline(true);
+ outlineShape.addEmptyOutline();
+ outlineShape.addVertex(5.0f,-5.0f,true);
+ outlineShape.addVertex(10.0f,-5.0f, false);
+ outlineShape.addVertex(10.0f,0.0f, true);
+ outlineShape.addVertex(5.0f,0.0f, false);
+ outlineShape.closeLastOutline(true);
+
+ /** Same shape as above but without any off-curve vertices */
+ final float offset = 30;
+ outlineShape.addEmptyOutline();
+ outlineShape.addVertex(offset+0.0f,-10.0f, true);
+ outlineShape.addVertex(offset+17.0f,-10.0f, true);
+ outlineShape.addVertex(offset+11.0f,5.0f, true);
+ outlineShape.addVertex(offset+16.0f,10.0f, true);
+ outlineShape.addVertex(offset+7.0f,15.0f, true);
+ outlineShape.addVertex(offset+6.0f,8.0f, true);
+ outlineShape.addVertex(offset+0.0f,10.0f, true);
+ outlineShape.closeLastOutline(true);
+ outlineShape.addEmptyOutline();
+ outlineShape.addVertex(offset+5.0f,0.0f, true);
+ outlineShape.addVertex(offset+5.0f,-5.0f, true);
+ outlineShape.addVertex(offset+10.0f,-5.0f, true);
+ outlineShape.addVertex(offset+10.0f,0.0f, true);
+ outlineShape.closeLastOutline(true);
+
+ region = GLRegion.create(getRenderModes(), null);
+ region.addOutlineShape(outlineShape, null, region.hasColorChannel() ? getRenderer().getRenderState().getColorStatic(new float[4]) : null);
+ }
+
+ @Override
+ public void init(final GLAutoDrawable drawable) {
+ super.init(drawable);
+
+ final GL2ES2 gl = drawable.getGL().getGL2ES2();
+
+ final RenderState rs = getRenderer().getRenderState();
+
+ gl.setSwapInterval(1);
+ gl.glEnable(GL.GL_DEPTH_TEST);
+ gl.glEnable(GL.GL_BLEND);
+ rs.setColorStatic(0.0f, 0.0f, 0.0f, 1.0f);
+
+ createTestOutline();
+ }
+
+ @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 regionRenderer = getRenderer();
+ final PMVMatrix pmv = regionRenderer.getMatrix();
+ pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
+ pmv.glLoadIdentity();
+ pmv.glTranslatef(getXTran(), getYTran(), getZTran());
+ pmv.glRotatef(getAngle(), 0, 1, 0);
+ if( weight != regionRenderer.getRenderState().getWeight() ) {
+ regionRenderer.getRenderState().setWeight(weight);
+ }
+ regionRenderer.enable(gl, true);
+ region.draw(gl, regionRenderer, getSampleCount());
+ regionRenderer.enable(gl, false);
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener01.java
index 73952684e..7dc217c2d 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener01.java
@@ -36,6 +36,8 @@ import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
import com.jogamp.graph.curve.OutlineShape;
import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.curve.opengl.RenderState;
+import com.jogamp.graph.geom.plane.Path2F;
+import com.jogamp.graph.geom.plane.WindingRule;
import com.jogamp.graph.curve.opengl.RegionRenderer;
import com.jogamp.opengl.util.PMVMatrix;
@@ -47,17 +49,21 @@ import com.jogamp.opengl.util.PMVMatrix;
*
*/
public class GPURegionGLListener01 extends GPURendererListenerBase01 {
+ final int shape_ctor_mode;
OutlineShape outlineShape = null;
public GPURegionGLListener01 (final RenderState rs, final int renderModes, final int sampleCount, final boolean debug, final boolean trace) {
+ this(1, rs, renderModes, sampleCount, debug, trace);
+ }
+
+ public GPURegionGLListener01 (final int shape_ctor_mode, final RenderState rs, final int renderModes, final int sampleCount, final boolean debug, final boolean trace) {
super(RegionRenderer.create(rs, RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable), renderModes, debug, trace);
+ this.shape_ctor_mode = shape_ctor_mode;
rs.setHintMask(RenderState.BITHINT_GLOBAL_DEPTH_TEST_ENABLED);
setMatrix(-20, 00, -50, 0f, sampleCount);
}
- private void createTestOutline(){
- float offset = 0;
- outlineShape = new OutlineShape(getRenderer().getRenderState().getVertexFactory());
+ private void createTestOutline00(){
outlineShape.addVertex(0.0f,-10.0f, true);
outlineShape.addVertex(15.0f,-10.0f, true);
outlineShape.addVertex(10.0f,5.0f, false);
@@ -74,7 +80,7 @@ public class GPURegionGLListener01 extends GPURendererListenerBase01 {
outlineShape.closeLastOutline(true);
/** Same shape as above but without any off-curve vertices */
- offset = 30;
+ final float offset = 30;
outlineShape.addEmptyOutline();
outlineShape.addVertex(offset+0.0f,-10.0f, true);
outlineShape.addVertex(offset+17.0f,-10.0f, true);
@@ -90,9 +96,149 @@ public class GPURegionGLListener01 extends GPURendererListenerBase01 {
outlineShape.addVertex(offset+10.0f,-5.0f, true);
outlineShape.addVertex(offset+10.0f,0.0f, true);
outlineShape.closeLastOutline(true);
+ }
- region = GLRegion.create(getRenderModes(), null);
- region.addOutlineShape(outlineShape, null, region.hasColorChannel() ? getRenderer().getRenderState().getColorStatic(new float[4]) : null);
+ private void createTestOutline01(){
+ outlineShape.moveTo(0.0f,-10.0f);
+ outlineShape.lineTo(15.0f,-10.0f);
+ outlineShape.quadTo(10.0f,5.0f, 15.0f,10.0f);
+ outlineShape.cubicTo(6.0f,15.0f, 5.0f,8.0f, 0.0f,10.0f);
+ outlineShape.closePath();
+ outlineShape.moveTo(5.0f,-5.0f);
+ outlineShape.quadTo(10.0f,-5.0f, 10.0f,0.0f);
+ outlineShape.quadTo(5.0f,0.0f, 5.0f,-5.0f);
+ outlineShape.closePath();
+
+ /** Same shape as above but without any off-curve vertices */
+ final float offset = 30;
+ outlineShape.moveTo(offset+0.0f,-10.0f);
+ outlineShape.lineTo(offset+17.0f,-10.0f);
+ outlineShape.lineTo(offset+11.0f,5.0f);
+ outlineShape.lineTo(offset+16.0f,10.0f);
+ outlineShape.lineTo(offset+7.0f,15.0f);
+ outlineShape.lineTo(offset+6.0f,8.0f);
+ outlineShape.lineTo(offset+0.0f,10.0f);
+ outlineShape.closePath();
+ outlineShape.moveTo(offset+5.0f,0.0f);
+ outlineShape.lineTo(offset+5.0f,-5.0f);
+ outlineShape.lineTo(offset+10.0f,-5.0f);
+ outlineShape.lineTo(offset+10.0f,0.0f);
+ outlineShape.closePath();
+ }
+
+ private void createTestOutline02(){
+ final Path2F path = new Path2F(WindingRule.NON_ZERO);
+ path.moveTo(0.0f,-10.0f);
+ path.lineTo(15.0f,-10.0f);
+ path.quadTo(10.0f,5.0f, 15.0f,10.0f);
+ path.cubicTo(6.0f,15.0f, 5.0f,8.0f, 0.0f,10.0f);
+ path.closePath();
+ path.moveTo(5.0f,-5.0f);
+ path.quadTo(10.0f,-5.0f, 10.0f,0.0f);
+ path.quadTo(5.0f,0.0f, 5.0f,-5.0f);
+ path.closePath();
+
+ /** Same shape as above but without any off-curve vertices */
+ final float offset = 30;
+ path.moveTo(offset+0.0f,-10.0f);
+ path.lineTo(offset+17.0f,-10.0f);
+ path.lineTo(offset+11.0f,5.0f);
+ path.lineTo(offset+16.0f,10.0f);
+ path.lineTo(offset+7.0f,15.0f);
+ path.lineTo(offset+6.0f,8.0f);
+ path.lineTo(offset+0.0f,10.0f);
+ path.closePath();
+ path.moveTo(offset+5.0f,0.0f);
+ path.lineTo(offset+5.0f,-5.0f);
+ path.lineTo(offset+10.0f,-5.0f);
+ path.lineTo(offset+10.0f,0.0f);
+ path.closePath();
+
+ System.err.println("GPURegionGLListener01.createTestOutline02.X: path "+path);
+ path.printSegments(System.err);
+ outlineShape.addPath(path, false /* connect */);
+ }
+
+ private void createTestOutline03(){
+ {
+ final Path2F path = new Path2F(WindingRule.NON_ZERO);
+ path.moveTo(0.0f,-10.0f);
+ path.lineTo(15.0f,-10.0f);
+ path.quadTo(10.0f,5.0f, 15.0f,10.0f);
+ path.cubicTo(6.0f,15.0f, 5.0f,8.0f, 0.0f,10.0f);
+ path.closePath();
+ System.err.println("GPURegionGLListener01.createTestOutline03.0: path "+path);
+ path.printSegments(System.err);
+ {
+ final Path2F path2 = new Path2F(WindingRule.NON_ZERO);
+ path2.moveTo(5.0f,-5.0f);
+ path2.quadTo(10.0f,-5.0f, 10.0f,0.0f);
+ path2.quadTo(5.0f,0.0f, 5.0f,-5.0f);
+ path2.closePath();
+ System.err.println("GPURegionGLListener01.createTestOutline03.0: path2 "+path2);
+ path2.printSegments(System.err);
+ path.append(path2, false);
+ System.err.println("GPURegionGLListener01.createTestOutline03.1: path "+path);
+ path.printSegments(System.err);
+ }
+ outlineShape.addPath(path, false /* connect */);
+ }
+ {
+ /** Same shape as above but without any off-curve vertices */
+ final float offset = 30;
+ final Path2F path = new Path2F(WindingRule.NON_ZERO);
+ path.moveTo(offset+0.0f,-10.0f);
+ path.lineTo(offset+17.0f,-10.0f);
+ path.lineTo(offset+11.0f,5.0f);
+ path.lineTo(offset+16.0f,10.0f);
+ path.lineTo(offset+7.0f,15.0f);
+ path.lineTo(offset+6.0f,8.0f);
+ path.lineTo(offset+0.0f,10.0f);
+ path.closePath();
+ path.moveTo(offset+5.0f,0.0f);
+ path.lineTo(offset+5.0f,-5.0f);
+ path.lineTo(offset+10.0f,-5.0f);
+ path.lineTo(offset+10.0f,0.0f);
+ path.closePath();
+ System.err.println("GPURegionGLListener01.createTestOutline03.3: path "+path);
+ path.printSegments(System.err);
+ outlineShape.addPath(path, false /* connect */);
+ }
+
+ }
+
+ private void createTestOutline04(){
+ final Path2F path = new Path2F(WindingRule.NON_ZERO);
+
+ path.moveTo(0.0f,10.0f);
+ path.cubicTo(5.0f,8.0f, 6.0f,15.0f, 15.0f,10.0f);
+ path.quadTo(10.0f,5.0f, 15.0f,-10.0f);
+ path.lineTo(0.0f,-10.0f);
+ path.closePath();
+ path.moveTo(5.0f,-5.0f);
+ path.quadTo(5.0f,0.0f, 10.0f,0.0f);
+ path.quadTo(10.0f,-5.0f, 5.0f,-5.0f);
+ path.closePath();
+
+ /** Same shape as above but without any off-curve vertices */
+ final float offset = 30;
+ path.moveTo(offset+0.0f,10.0f);
+ path.lineTo(offset+6.0f,8.0f);
+ path.lineTo(offset+7.0f,15.0f);
+ path.lineTo(offset+16.0f,10.0f);
+ path.lineTo(offset+11.0f,5.0f);
+ path.lineTo(offset+17.0f,-10.0f);
+ path.lineTo(offset+0.0f,-10.0f);
+ path.closePath();
+ path.moveTo(offset+10.0f,0.0f);
+ path.lineTo(offset+10.0f,-5.0f);
+ path.lineTo(offset+5.0f,-5.0f);
+ path.lineTo(offset+5.0f,0.0f);
+ path.closePath();
+
+ System.err.println("GPURegionGLListener01.createTestOutline04.X: path "+path);
+ path.printSegments(System.err);
+ outlineShape.addPathRev(path, false /* connect */);
}
@Override
@@ -108,7 +254,26 @@ public class GPURegionGLListener01 extends GPURendererListenerBase01 {
gl.glEnable(GL.GL_BLEND);
rs.setColorStatic(0.0f, 0.0f, 0.0f, 1.0f);
- createTestOutline();
+ outlineShape = new OutlineShape(getRenderer().getRenderState().getVertexFactory());
+ switch( shape_ctor_mode ) {
+ case 0:
+ createTestOutline00();
+ break;
+ case 2:
+ createTestOutline02();
+ break;
+ case 3:
+ createTestOutline03();
+ break;
+ case 4:
+ createTestOutline04();
+ break;
+ default:
+ createTestOutline01();
+ break;
+ }
+ region = GLRegion.create(getRenderModes(), null);
+ region.addOutlineShape(outlineShape, null, region.hasColorChannel() ? getRenderer().getRenderState().getColorStatic(new float[4]) : null);
}
@Override
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener02.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener10.java
index d79bbb970..13c168ee7 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener02.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionGLListener10.java
@@ -46,17 +46,16 @@ import com.jogamp.opengl.util.PMVMatrix;
* into one region
*
*/
-public class GPURegionGLListener02 extends GPURendererListenerBase01 {
+public class GPURegionGLListener10 extends GPURendererListenerBase01 {
List<OutlineShape> outlineShapes = new ArrayList<OutlineShape>();
- public GPURegionGLListener02 (final RenderState rs, final int renderModes, final int sampleCount, final boolean debug, final boolean trace) {
+ public GPURegionGLListener10 (final RenderState rs, final int renderModes, final int sampleCount, final boolean debug, final boolean trace) {
super(RegionRenderer.create(rs, RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable), renderModes, debug, trace);
rs.setHintMask(RenderState.BITHINT_GLOBAL_DEPTH_TEST_ENABLED);
setMatrix(-20, 00, -50, 0f, sampleCount);
}
private void createTestOutline(){
- float offset = 0;
OutlineShape shape = new OutlineShape(getRenderer().getRenderState().getVertexFactory());
outlineShapes.add(shape);
shape.addVertex(0.0f,-10.0f,true);
@@ -77,7 +76,7 @@ public class GPURegionGLListener02 extends GPURendererListenerBase01 {
/** Same shape as above but without any off-curve vertices */
shape = new OutlineShape(getRenderer().getRenderState().getVertexFactory());
outlineShapes.add(shape);
- offset = 30;
+ final float offset = 30;
shape.addVertex(offset+0.0f,-10.0f, true);
shape.addVertex(offset+17.0f,-10.0f, true);
shape.addVertex(offset+11.0f,5.0f, true);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo.java
index fd6c9a882..a5990af89 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo.java
@@ -53,6 +53,7 @@ public class GPURegionNewtDemo {
static final boolean DEBUG = false;
static final boolean TRACE = false;
+ static int shape_ctor_mode = 1;
static int SceneMSAASamples = 0;
static int GraphVBAASamples = 4;
static int GraphMSAASamples = 0;
@@ -93,11 +94,15 @@ public class GPURegionNewtDemo {
} else if(args[i].equals("-y")) {
i++;
y = MiscUtils.atoi(args[i], y);
+ } else if(args[i].equals("-shape_ctor")) {
+ i++;
+ shape_ctor_mode = MiscUtils.atoi(args[i], shape_ctor_mode);
}
}
}
System.err.println("Desired win size "+width+"x"+height);
System.err.println("Desired win pos "+x+"/"+y);
+ System.err.println("Shape_ctor_mode "+shape_ctor_mode);
System.err.println("Scene MSAA Samples "+SceneMSAASamples);
System.err.println("Graph MSAA Samples"+GraphMSAASamples);
System.err.println("Graph VBAA Samples "+GraphVBAASamples);
@@ -128,7 +133,7 @@ public class GPURegionNewtDemo {
window.setTitle("GPU Curve Region Newt Demo - graph[vbaa"+GraphVBAASamples+" msaa"+GraphMSAASamples+"], msaa "+SceneMSAASamples);
final RenderState rs = RenderState.createRenderState(SVertex.factory());
- final GPURegionGLListener01 regionGLListener = new GPURegionGLListener01 (rs, rmode, sampleCount, DEBUG, TRACE);
+ final GPURegionGLListener01 regionGLListener = new GPURegionGLListener01 (shape_ctor_mode, rs, rmode, sampleCount, DEBUG, TRACE);
regionGLListener.attachInputListenerTo(window);
window.addGLEventListener(regionGLListener);
window.setVisible(true);
@@ -139,6 +144,7 @@ public class GPURegionNewtDemo {
animator.add(window);
window.addKeyListener(new KeyAdapter() {
+ @Override
public void keyPressed(final KeyEvent arg0) {
if(arg0.getKeyCode() == KeyEvent.VK_F4) {
window.destroy();
@@ -146,6 +152,7 @@ public class GPURegionNewtDemo {
}
});
window.addWindowListener(new WindowAdapter() {
+ @Override
public void windowDestroyed(final WindowEvent e) {
animator.stop();
}