From 9cefde9395002717bb6bfde461f4a65c69a888dd Mon Sep 17 00:00:00 2001 From: Rami Santina Date: Thu, 2 Jun 2011 16:00:01 +0300 Subject: Font and TypecastRender generate array of OutlineShapes instead of Path2D GlyphShape and GlyphString use only OutlineShapes --- src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src/jogl/classes/com/jogamp/graph') diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java index 073afe9bd..5e25a4ced 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java @@ -31,18 +31,11 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; -import javax.media.opengl.GL; import javax.media.opengl.GL2ES2; import jogamp.graph.curve.text.GlyphString; -import jogamp.graph.font.FontInt; -import jogamp.graph.geom.plane.AffineTransform; -import jogamp.graph.geom.plane.Path2D; -import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.font.Font; -import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.Vertex.Factory; public abstract class TextRenderer extends Renderer { /** -- cgit v1.2.3 From 64c7bea57d353729c93e1f60272e400a712ca47e Mon Sep 17 00:00:00 2001 From: Rami Santina Date: Sun, 5 Jun 2011 10:37:19 +0300 Subject: Fix: transform to Quadratic; Refactor method names --- .../com/jogamp/graph/curve/OutlineShape.java | 1054 ++++++++++---------- .../jogamp/graph/curve/tess/CDTriangulator2D.java | 4 +- .../classes/com/jogamp/graph/geom/Outline.java | 6 +- 3 files changed, 536 insertions(+), 528 deletions(-) (limited to 'src/jogl/classes/com/jogamp/graph') diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java index 5b94d6bda..16bd054e2 100755 --- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java +++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java @@ -1,523 +1,531 @@ -/** - * 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.graph.curve; - -import java.util.ArrayList; -import java.util.Collections; - - -import com.jogamp.graph.geom.AABBox; -import com.jogamp.graph.geom.Outline; -import com.jogamp.graph.geom.Triangle; -import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.math.VectorUtil; - -import com.jogamp.graph.curve.tess.CDTriangulator2D; - -/** A Generic shape objects which is defined by a list of Outlines. - * This Shape can be transformed to Triangulations. - * The list of triangles generated are render-able by a Region object. - * The triangulation produced by this Shape will define the - * closed region defined by the outlines. - * - * One or more OutlineShape Object can be associated to a region - * this is left as a high-level representation of the Objects. For - * optimizations, flexibility requirements for future features. - * - *

- * Example to creating an Outline Shape: - *
-      addVertex(...)
-      addVertex(...)
-      addVertex(...)
-      addEmptyOutline()
-      addVertex(...)
-      addVertex(...)
-      addVertex(...)
- * 
- * - * The above will create two outlines each with three vertices. By adding these two outlines to - * the OutlineShape, we are stating that the combination of the two outlines represent the shape. - *
- * - * To specify that the shape is curved at a region, the on-curve flag should be set to false - * for the vertex that is in the middle of the curved region (if the curved region is defined by 3 - * vertices (quadratic curve). - *
- * In case the curved region is defined by 4 or more vertices the middle vertices should both have - * the on-curve flag set to false. - * - *
Example:
- *
-      addVertex(0,0, true);
-      addVertex(0,1, false);
-      addVertex(1,1, false);
-      addVertex(1,0, true);
- * 
- * - * The above snippet defines a cubic nurbs curve where (0,1 and 1,1) - * do not belong to the final rendered shape. - * - * Implementation Notes:
- * - * - * @see Outline - * @see Region - */ -public class OutlineShape implements Comparable { - /** - * Outline's vertices have undefined state until transformed. - */ - public enum VerticesState { - UNDEFINED(0), QUADRATIC_NURBS(1); - - public final int state; - - VerticesState(int state){ - this.state = state; - } - } - - public static final int DIRTY_BOUNDS = 1 << 0; - - private final Vertex.Factory vertexFactory; - private VerticesState outlineState; - - /** The list of {@link Outline}s that are part of this - * outline shape. - */ - private ArrayList outlines; - private AABBox bbox; - - /** dirty bits DIRTY_BOUNDS */ - private int dirtyBits; - - /** Create a new Outline based Shape - */ - public OutlineShape(Vertex.Factory factory) { - this.vertexFactory = factory; - this.outlines = new ArrayList(3); - this.outlines.add(new Outline()); - this.outlineState = VerticesState.UNDEFINED; - this.bbox = new AABBox(); - this.dirtyBits = 0; - } - - /** Clears all data and reset all states as if this instance was newly created */ - public void clear() { - outlines.clear(); - outlines.add(new Outline()); - outlineState = VerticesState.UNDEFINED; - bbox.reset(); - dirtyBits = 0; - } - - /** Returns the associated vertex factory of this outline shape - * @return Vertex.Factory object - */ - public final Vertex.Factory vertexFactory() { return vertexFactory; } - - public int getOutlineNumber() { - return outlines.size(); - } - - /** Add a new empty {@link Outline} - * to the end of this shape's outline list. - *

If the {@link #getLastOutline()} is empty already, no new one will be added.

- * - * After a call to this function all new vertices added - * will belong to the new outline - */ - public void addEmptyOutline(){ - if( !getLastOutline().isEmpty() ) { - outlines.add(new Outline()); - } - } - - /** Appends the {@link Outline} element to the end, - * ensuring a clean tail. - * - *

A clean tail is ensured, no double empty Outlines are produced - * and a pre-existing empty outline will be replaced with the given one.

- * - * @param outline Outline object to be added - * @throws NullPointerException if the {@link Outline} element is null - */ - public void addOutline(Outline outline) throws NullPointerException { - addOutline(outlines.size(), outline); - } - - /** Insert the {@link Outline} element at the given {@code position}. - * - *

If the {@code position} indicates the end of this list, - * a clean tail is ensured, no double empty Outlines are produced - * and a pre-existing empty outline will be replaced with the given one.

- * - * @param position of the added Outline - * @param outline Outline object to be added - * @throws NullPointerException if the {@link Outline} element is null - * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getOutlineNumber()) - */ - public void addOutline(int position, Outline outline) throws NullPointerException, IndexOutOfBoundsException { - if (null == outline) { - throw new NullPointerException("outline is null"); - } - if( outlines.size() == position ) { - final Outline lastOutline = getLastOutline(); - if( outline.isEmpty() && lastOutline.isEmpty() ) { - return; - } - if( lastOutline.isEmpty() ) { - outlines.set(position-1, outline); - if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) { - bbox.resize(outline.getBounds()); - } - return; - } - } - outlines.add(position, outline); - if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) { - bbox.resize(outline.getBounds()); - } - } - - /** Insert the {@link OutlineShape} elements of type {@link Outline}, .. at the end of this shape, - * using {@link #addOutline(Outline)} for each element. - *

Closes the current last outline via {@link #closeLastOutline()} before adding the new ones.

- * @param outlineShape OutlineShape elements to be added. - * @throws NullPointerException if the {@link OutlineShape} is null - * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getOutlineNumber()) - */ - public void addOutlineShape(OutlineShape outlineShape) throws NullPointerException { - if (null == outlineShape) { - throw new NullPointerException("OutlineShape is null"); - } - closeLastOutline(); - for(int i=0; iSets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.

- * - * @param position of the replaced Outline - * @param outline replacement Outline object - * @throws NullPointerException if the {@link Outline} element is null - * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber()) - */ - public void setOutline(int position, Outline outline) throws NullPointerException, IndexOutOfBoundsException { - if (null == outline) { - throw new NullPointerException("outline is null"); - } - outlines.set(position, outline); - dirtyBits |= DIRTY_BOUNDS; - } - - /** Removes the {@link Outline} element at the given {@code position}. - *

Sets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.

- * - * @param position of the to be removed Outline - * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber()) - */ - public final Outline removeOutline(int position) throws IndexOutOfBoundsException { - dirtyBits |= DIRTY_BOUNDS; - return outlines.remove(position); - } - - /** Get the last added outline to the list - * of outlines that define the shape - * @return the last outline - */ - public final Outline getLastOutline(){ - return outlines.get(outlines.size()-1); - } - - /** @return the {@code Outline} at {@code position} - * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber()) - */ - public Outline getOutline(int position) throws IndexOutOfBoundsException { - return outlines.get(position); - } - - /** Adds a vertex to the last open outline in the - * shape. - * @param v the vertex to be added to the OutlineShape - */ - public final void addVertex(Vertex v){ - final Outline lo = getLastOutline(); - lo.addVertex(v); - if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) { - bbox.resize(lo.getBounds()); - } - } - - /** Adds a vertex to the last open outline in the shape. - * at {@code position} - * @param position indx at which the vertex will be added - * @param v the vertex to be added to the OutlineShape - */ - public final void addVertex(int position, Vertex v){ - final Outline lo = getLastOutline(); - lo.addVertex(position, v); - if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) { - bbox.resize(lo.getBounds()); - } - } - - /** Add a 2D {@link Vertex} to the last outline by defining the coordniate attribute - * of the vertex. The 2D vertex will be represented as Z=0. - * - * @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 - * of the shape around this vertex. - */ - public final void addVertex(float x, float y, boolean onCurve) { - addVertex(vertexFactory.create(x, y, 0f, onCurve)); - } - - /** Add a 3D {@link Vertex} to the last outline by defining the coordniate attribute - * of the vertex. - * @param x the x coordinate - * @param y the y coordinate - * @param z the z coordinate - * @param onCurve flag if this vertex is on the final curve or defines a curved region - * of the shape around this vertex. - */ - public final void addVertex(float x, float y, float z, boolean onCurve) { - addVertex(vertexFactory.create(x, y, z, onCurve)); - } - - /** Add a vertex to the last outline by passing a float array and specifying the - * offset and length in which. The attributes of the vertex are located. - * The attributes should be continuous (stride = 0). - * Attributes which value are not set (when length less than 3) - * are set implicitly to zero. - * @param coordsBuffer the coordinate array where the vertex attributes are to be picked from - * @param offset the offset in the buffer to the x coordinate - * @param length the number of attributes to pick from the buffer (maximum 3) - * @param onCurve flag if this vertex is on the final curve or defines a curved region - * of the shape around this vertex. - */ - public final void addVertex(float[] coordsBuffer, int offset, int length, boolean onCurve) { - addVertex(vertexFactory.create(coordsBuffer, offset, length, onCurve)); - } - - /** Closes the last outline in the shape. - *

If last vertex is not equal to first vertex. - * A new temp vertex is added at the end which - * is equal to the first.

- */ - public void closeLastOutline(){ - getLastOutline().setClosed(true); - } - - /** - * @return the outline's vertices state, {@link OutlineShape.VerticesState} - */ - public final VerticesState getOutlineState() { - return outlineState; - } - - /** Ensure the outlines represent - * the specified destinationType. - * - * @param destinationType the target outline's vertices state. Currently only {@link OutlineShape.VerticesState#QUADRATIC_NURBS} are supported. - */ - public void transformOutlines(VerticesState destinationType){ - if(outlineState != destinationType){ - if(destinationType == VerticesState.QUADRATIC_NURBS){ - transformOutlines2Quadratic(); - } else { - throw new IllegalStateException("destinationType "+destinationType.name()+" not supported (currently "+outlineState.name()+")"); - } - } - } - - private void transformOutlines2Quadratic(){ - final int count = getOutlineNumber(); - for (int cc = 0; cc < count; cc++){ - final Outline outline = getOutline(cc); - int vertexNumberLessOne = outline.getVertexNumber() - 1; - for(int i=0; i < vertexNumberLessOne; i++) { - final Vertex currentVertex = outline.getVertex(i); - final Vertex nextVertex = outline.getVertex(i+1); - if ( !currentVertex.isOnCurve() && !nextVertex.isOnCurve() ) { - final float[] newCoords = VectorUtil.mid(currentVertex.getCoord(), nextVertex.getCoord()); - final Vertex v = vertexFactory.create(newCoords, 0, 3, true); - v.setOnCurve(true); - i++; - vertexNumberLessOne++; - outline.addVertex(i, v); - } - } - // Cut off last vertex (which is on-curve) - // FIXME: original code skipped the last element (it _is_ unrelated to the xform above) - // FIXME: understand why the last element produces artifacts in rendering - if( vertexNumberLessOne >= 0 ) { - outline.removeVertex(vertexNumberLessOne); - } - } - outlineState = VerticesState.QUADRATIC_NURBS; - } - - private void generateVertexIds(){ - int maxVertexId = 0; - for(int i=0; i vertices = outlines.get(i).getVertices(); - for(int pos=0; pos getVertices() { - ArrayList vertices = new ArrayList(); - for(int i=0; i triangulate() { - if(outlines.size() == 0){ - return null; - } - sortOutlines(); - generateVertexIds(); - - CDTriangulator2D triangulator2d = new CDTriangulator2D(); - for(int index = 0; index triangles = triangulator2d.generateTriangulation(); - triangulator2d.reset(); - - return triangles; - } - - /** Sort the outlines from large - * to small depending on the AABox - */ - private void sortOutlines() { - Collections.sort(outlines); - Collections.reverse(outlines); - } - - /** Compare two outline shapes with Bounding Box area - * as criteria. - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - public final int compareTo(OutlineShape outline) { - float size = getBounds().getSize(); - float newSize = outline.getBounds().getSize(); - if(size < newSize){ - return -1; - } - else if(size > newSize){ - return 1; - } - return 0; - } - - private final void validateBoundingBox() { - dirtyBits &= ~DIRTY_BOUNDS; - bbox.reset(); - for (int i=0; i=0; i--) { - if( ! getOutline(i).equals( o.getOutline(i) ) ) { - return false; - } - } - return true; - } - - /** - * @return deep clone of this OutlineShape w/o Region - */ - public OutlineShape clone() { - OutlineShape o; - try { - o = (OutlineShape) super.clone(); - } catch (CloneNotSupportedException e) { throw new InternalError(); } - o.bbox = bbox.clone(); - o.outlines = new ArrayList(outlines.size()); - for(int i=0; i
+ * Example to creating an Outline Shape: + *
+      addVertex(...)
+      addVertex(...)
+      addVertex(...)
+      addEmptyOutline()
+      addVertex(...)
+      addVertex(...)
+      addVertex(...)
+ * 
+ * + * The above will create two outlines each with three vertices. By adding these two outlines to + * the OutlineShape, we are stating that the combination of the two outlines represent the shape. + *
+ * + * To specify that the shape is curved at a region, the on-curve flag should be set to false + * for the vertex that is in the middle of the curved region (if the curved region is defined by 3 + * vertices (quadratic curve). + *
+ * In case the curved region is defined by 4 or more vertices the middle vertices should both have + * the on-curve flag set to false. + * + *
Example:
+ *
+      addVertex(0,0, true);
+      addVertex(0,1, false);
+      addVertex(1,1, false);
+      addVertex(1,0, true);
+ * 
+ * + * The above snippet defines a cubic nurbs curve where (0,1 and 1,1) + * do not belong to the final rendered shape. + * + * Implementation Notes:
+ *
    + *
  • The first vertex of any outline belonging to the shape should be on-curve
  • + *
  • Intersections between off-curved parts of the outline is not handled
  • + *
+ * + * @see Outline + * @see Region + */ +public class OutlineShape implements Comparable { + /** + * Outline's vertices have undefined state until transformed. + */ + public enum VerticesState { + UNDEFINED(0), QUADRATIC_NURBS(1); + + public final int state; + + VerticesState(int state){ + this.state = state; + } + } + + public static final int DIRTY_BOUNDS = 1 << 0; + + private final Vertex.Factory vertexFactory; + private VerticesState outlineState; + + /** The list of {@link Outline}s that are part of this + * outline shape. + */ + private ArrayList outlines; + private AABBox bbox; + + /** dirty bits DIRTY_BOUNDS */ + private int dirtyBits; + + /** Create a new Outline based Shape + */ + public OutlineShape(Vertex.Factory factory) { + this.vertexFactory = factory; + this.outlines = new ArrayList(3); + this.outlines.add(new Outline()); + this.outlineState = VerticesState.UNDEFINED; + this.bbox = new AABBox(); + this.dirtyBits = 0; + } + + /** Clears all data and reset all states as if this instance was newly created */ + public void clear() { + outlines.clear(); + outlines.add(new Outline()); + outlineState = VerticesState.UNDEFINED; + bbox.reset(); + dirtyBits = 0; + } + + /** Returns the associated vertex factory of this outline shape + * @return Vertex.Factory object + */ + public final Vertex.Factory vertexFactory() { return vertexFactory; } + + public int getOutlineNumber() { + return outlines.size(); + } + + /** Add a new empty {@link Outline} + * to the end of this shape's outline list. + *

If the {@link #getLastOutline()} is empty already, no new one will be added.

+ * + * After a call to this function all new vertices added + * will belong to the new outline + */ + public void addEmptyOutline() { + if( !getLastOutline().isEmpty() ) { + outlines.add(new Outline()); + } + } + + /** Appends the {@link Outline} element to the end, + * ensuring a clean tail. + * + *

A clean tail is ensured, no double empty Outlines are produced + * and a pre-existing empty outline will be replaced with the given one.

+ * + * @param outline Outline object to be added + * @throws NullPointerException if the {@link Outline} element is null + */ + public void addOutline(Outline outline) throws NullPointerException { + addOutline(outlines.size(), outline); + } + + /** Insert the {@link Outline} element at the given {@code position}. + * + *

If the {@code position} indicates the end of this list, + * a clean tail is ensured, no double empty Outlines are produced + * and a pre-existing empty outline will be replaced with the given one.

+ * + * @param position of the added Outline + * @param outline Outline object to be added + * @throws NullPointerException if the {@link Outline} element is null + * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getOutlineNumber()) + */ + public void addOutline(int position, Outline outline) throws NullPointerException, IndexOutOfBoundsException { + if (null == outline) { + throw new NullPointerException("outline is null"); + } + if( outlines.size() == position ) { + final Outline lastOutline = getLastOutline(); + if( outline.isEmpty() && lastOutline.isEmpty() ) { + return; + } + if( lastOutline.isEmpty() ) { + outlines.set(position-1, outline); + if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) { + bbox.resize(outline.getBounds()); + } + return; + } + } + outlines.add(position, outline); + if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) { + bbox.resize(outline.getBounds()); + } + } + + /** Insert the {@link OutlineShape} elements of type {@link Outline}, .. at the end of this shape, + * using {@link #addOutline(Outline)} for each element. + *

Closes the current last outline via {@link #closeLastOutline()} before adding the new ones.

+ * @param outlineShape OutlineShape elements to be added. + * @throws NullPointerException if the {@link OutlineShape} is null + * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position > getOutlineNumber()) + */ + public void addOutlineShape(OutlineShape outlineShape) throws NullPointerException { + if (null == outlineShape) { + throw new NullPointerException("OutlineShape is null"); + } + closeLastOutline(); + for(int i=0; iSets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.

+ * + * @param position of the replaced Outline + * @param outline replacement Outline object + * @throws NullPointerException if the {@link Outline} element is null + * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber()) + */ + public void setOutline(int position, Outline outline) throws NullPointerException, IndexOutOfBoundsException { + if (null == outline) { + throw new NullPointerException("outline is null"); + } + outlines.set(position, outline); + dirtyBits |= DIRTY_BOUNDS; + } + + /** Removes the {@link Outline} element at the given {@code position}. + *

Sets the bounding box dirty, hence a next call to {@link #getBounds()} will validate it.

+ * + * @param position of the to be removed Outline + * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber()) + */ + public final Outline removeOutline(int position) throws IndexOutOfBoundsException { + dirtyBits |= DIRTY_BOUNDS; + return outlines.remove(position); + } + + /** Get the last added outline to the list + * of outlines that define the shape + * @return the last outline + */ + public final Outline getLastOutline() { + return outlines.get(outlines.size()-1); + } + + /** @return the {@code Outline} at {@code position} + * @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber()) + */ + public Outline getOutline(int position) throws IndexOutOfBoundsException { + return outlines.get(position); + } + + /** Adds a vertex to the last open outline in the + * shape. + * @param v the vertex to be added to the OutlineShape + */ + public final void addVertex(Vertex v) { + final Outline lo = getLastOutline(); + lo.addVertex(v); + if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) { + bbox.resize(lo.getBounds()); + } + } + + /** Adds a vertex to the last open outline in the shape. + * at {@code position} + * @param position indx at which the vertex will be added + * @param v the vertex to be added to the OutlineShape + */ + public final void addVertex(int position, Vertex v) { + final Outline lo = getLastOutline(); + lo.addVertex(position, v); + if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) { + bbox.resize(lo.getBounds()); + } + } + + /** Add a 2D {@link Vertex} to the last outline by defining the coordniate attribute + * of the vertex. The 2D vertex will be represented as Z=0. + * + * @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 + * of the shape around this vertex. + */ + public final void addVertex(float x, float y, boolean onCurve) { + addVertex(vertexFactory.create(x, y, 0f, onCurve)); + } + + /** Add a 3D {@link Vertex} to the last outline by defining the coordniate attribute + * of the vertex. + * @param x the x coordinate + * @param y the y coordinate + * @param z the z coordinate + * @param onCurve flag if this vertex is on the final curve or defines a curved region + * of the shape around this vertex. + */ + public final void addVertex(float x, float y, float z, boolean onCurve) { + addVertex(vertexFactory.create(x, y, z, onCurve)); + } + + /** Add a vertex to the last outline by passing a float array and specifying the + * offset and length in which. The attributes of the vertex are located. + * The attributes should be continuous (stride = 0). + * Attributes which value are not set (when length less than 3) + * are set implicitly to zero. + * @param coordsBuffer the coordinate array where the vertex attributes are to be picked from + * @param offset the offset in the buffer to the x coordinate + * @param length the number of attributes to pick from the buffer (maximum 3) + * @param onCurve flag if this vertex is on the final curve or defines a curved region + * of the shape around this vertex. + */ + public final void addVertex(float[] coordsBuffer, int offset, int length, boolean onCurve) { + addVertex(vertexFactory.create(coordsBuffer, offset, length, onCurve)); + } + + /** Closes the last outline in the shape. + *

If last vertex is not equal to first vertex. + * A new temp vertex is added at the end which + * is equal to the first.

+ */ + public void closeLastOutline() { + getLastOutline().setClosed(true); + } + + /** + * @return the outline's vertices state, {@link OutlineShape.VerticesState} + */ + public final VerticesState getOutlineState() { + return outlineState; + } + + /** Ensure the outlines represent + * the specified destinationType. + * + * @param destinationType the target outline's vertices state. Currently only {@link OutlineShape.VerticesState#QUADRATIC_NURBS} are supported. + */ + public void transformOutlines(VerticesState destinationType) { + if(outlineState != destinationType){ + if(destinationType == VerticesState.QUADRATIC_NURBS){ + transformOutlines2Quadratic(); + } else { + throw new IllegalStateException("destinationType "+destinationType.name()+" not supported (currently "+outlineState.name()+")"); + } + } + } + + private void transformOutlines2Quadratic() { + int count = getOutlineNumber(); + for (int cc = 0; cc < count; cc++) { + final Outline outline = getOutline(cc); + int vertexCount = outline.getVertexCount(); + + for(int i=0; i < vertexCount; i++) { + final Vertex currentVertex = outline.getVertex(i); + final Vertex nextVertex = outline.getVertex((i+1)%vertexCount); + if ( !currentVertex.isOnCurve() && !nextVertex.isOnCurve() ) { + final float[] newCoords = VectorUtil.mid(currentVertex.getCoord(), + nextVertex.getCoord()); + final Vertex v = vertexFactory.create(newCoords, 0, 3, true); + i++; + vertexCount++; + outline.addVertex(i, v); + } + } + if(vertexCount <= 0) { + outlines.remove(outline); + cc--; + count--; + continue; + } + + if( vertexCount > 0 ) { + if(VectorUtil.checkEquality(outline.getVertex(0).getCoord(), + outline.getLastVertex().getCoord())) { + outline.removeVertex(vertexCount-1); + } + } + } + outlineState = VerticesState.QUADRATIC_NURBS; + } + + private void generateVertexIds() { + int maxVertexId = 0; + for(int i=0; i vertices = outlines.get(i).getVertices(); + for(int pos=0; pos getVertices() { + ArrayList vertices = new ArrayList(); + for(int i=0; i triangulate() { + if(outlines.size() == 0){ + return null; + } + sortOutlines(); + generateVertexIds(); + + CDTriangulator2D triangulator2d = new CDTriangulator2D(); + for(int index = 0; index triangles = triangulator2d.generate(); + triangulator2d.reset(); + + return triangles; + } + + /** Sort the outlines from large + * to small depending on the AABox + */ + private void sortOutlines() { + Collections.sort(outlines); + Collections.reverse(outlines); + } + + /** Compare two outline shapes with Bounding Box area + * as criteria. + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public final int compareTo(OutlineShape outline) { + float size = getBounds().getSize(); + float newSize = outline.getBounds().getSize(); + if(size < newSize){ + return -1; + } + else if(size > newSize){ + return 1; + } + return 0; + } + + private final void validateBoundingBox() { + dirtyBits &= ~DIRTY_BOUNDS; + bbox.reset(); + for (int i=0; i=0; i--) { + if( ! getOutline(i).equals( o.getOutline(i) ) ) { + return false; + } + } + return true; + } + + /** + * @return deep clone of this OutlineShape w/o Region + */ + public OutlineShape clone() { + OutlineShape o; + try { + o = (OutlineShape) super.clone(); + } catch (CloneNotSupportedException e) { throw new InternalError(); } + o.bbox = bbox.clone(); + o.outlines = new ArrayList(outlines.size()); + for(int i=0; i generateTriangulation(){ + public ArrayList generate() { for(int i=0;i { public Outline() { } - public final int getVertexNumber() { + public final int getVertexCount() { return vertices.size(); } @@ -207,13 +207,13 @@ public class Outline implements Cloneable, Comparable { return false; } final Outline o = (Outline) obj; - if(getVertexNumber() != o.getVertexNumber()) { + if(getVertexCount() != o.getVertexCount()) { return false; } if( !getBounds().equals( o.getBounds() ) ) { return false; } - for (int i=getVertexNumber()-1; i>=0; i--) { + for (int i=getVertexCount()-1; i>=0; i--) { if( ! getVertex(i).equals( o.getVertex(i) ) ) { return false; } -- cgit v1.2.3 From 820fd3f4e45cfa79e94fad385eb47ff26a5fea2b Mon Sep 17 00:00:00 2001 From: Rami Santina Date: Sun, 5 Jun 2011 16:17:47 +0300 Subject: Add Factory for triangulation with base Interface; misc cleanup CDTriangulation moved to impl (jogamp.graph), where additional triangulations or a wrapper to GLU triangulation can be added to triangulator. TWO_PASS_RENDERING renamed to VBAA (algorithm name) misc comments cleanups --- .../com/jogamp/graph/curve/OutlineShape.java | 6 +- .../classes/com/jogamp/graph/curve/Region.java | 14 +- .../jogamp/graph/curve/opengl/RegionRenderer.java | 2 +- .../jogamp/graph/curve/opengl/TextRenderer.java | 6 +- .../jogamp/graph/curve/tess/CDTriangulator2D.java | 213 --------------------- .../com/jogamp/graph/curve/tess/Triangulation.java | 44 +++++ .../com/jogamp/graph/curve/tess/Triangulator.java | 69 +++++++ .../jogamp/graph/curve/opengl/RegionFactory.java | 6 +- .../jogamp/graph/curve/tess/CDTriangulator2D.java | 203 ++++++++++++++++++++ .../jogamp/graph/curve/text/GlyphString.java | 2 +- .../test/junit/graph/TestRegionRendererNEWT01.java | 2 +- .../test/junit/graph/TestTextRendererNEWT01.java | 2 +- .../junit/graph/demos/GPURegionNewtDemo02.java | 2 +- .../graph/demos/GPURendererListenerBase01.java | 2 +- .../test/junit/graph/demos/GPUTextNewtDemo02.java | 2 +- 15 files changed, 340 insertions(+), 235 deletions(-) delete mode 100644 src/jogl/classes/com/jogamp/graph/curve/tess/CDTriangulator2D.java create mode 100644 src/jogl/classes/com/jogamp/graph/curve/tess/Triangulation.java create mode 100644 src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java create mode 100644 src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java (limited to 'src/jogl/classes/com/jogamp/graph') diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java index 16bd054e2..e4f80ab76 100755 --- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java +++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java @@ -30,14 +30,14 @@ package com.jogamp.graph.curve; import java.util.ArrayList; import java.util.Collections; - +import com.jogamp.graph.curve.tess.Triangulation; +import com.jogamp.graph.curve.tess.Triangulator; import com.jogamp.graph.geom.AABBox; import com.jogamp.graph.geom.Outline; import com.jogamp.graph.geom.Triangle; import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.math.VectorUtil; -import com.jogamp.graph.curve.tess.CDTriangulator2D; /** A Generic shape objects which is defined by a list of Outlines. * This Shape can be transformed to Triangulations. @@ -433,7 +433,7 @@ public class OutlineShape implements Comparable { sortOutlines(); generateVertexIds(); - CDTriangulator2D triangulator2d = new CDTriangulator2D(); + Triangulator triangulator2d = Triangulation.create(); for(int index = 0; index triangles = new ArrayList(); protected ArrayList vertices = new ArrayList(); - public static boolean usesTwoPassRendering(int renderModes) { - return 0 != ( renderModes & Region.TWO_PASS_RENDERING_BIT ); + public static boolean isVBAA(int renderModes) { + return 0 != ( renderModes & Region.VBAA_RENDERING_BIT ); } public static boolean usesVariableCurveWeight(int renderModes) { @@ -71,7 +73,7 @@ public abstract class Region { public final int getRenderModes() { return renderModes; } - public boolean usesTwoPassRendering() { return Region.usesTwoPassRendering(renderModes); } + public boolean isVBAA() { return Region.isVBAA(renderModes); } public boolean usesVariableCurveWeight() { return Region.usesVariableCurveWeight(renderModes); } /** Get the current number of vertices associated diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java index 8624c582c..86d962fd8 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java @@ -38,7 +38,7 @@ public abstract class RegionRenderer extends Renderer { /** * Create a Hardware accelerated Region Renderer. * @param rs the used {@link RenderState} - * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#TWO_PASS_RENDERING_BIT} + * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT} * @return an instance of Region Renderer */ public static RegionRenderer create(RenderState rs, int renderModes) { diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java index 5e25a4ced..b466670cc 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java @@ -41,10 +41,10 @@ public abstract class TextRenderer extends Renderer { /** * Create a Hardware accelerated Text Renderer. * @param rs the used {@link RenderState} - * @param renderModes either {@link com.jogamp.graph.curve.opengl.GLRegion#SINGLE_PASS} or {@link com.jogamp.graph.curve.Region#TWO_PASS_RENDERING_BIT} + * @param renderModes either {@link com.jogamp.graph.curve.opengl.GLRegion#SINGLE_PASS} or {@link com.jogamp.graph.curve.Region#VBAA_RENDERING_BIT} */ - public static TextRenderer create(RenderState rs, int type) { - return new jogamp.graph.curve.opengl.TextRendererImpl01(rs, type); + public static TextRenderer create(RenderState rs, int renderModes) { + return new jogamp.graph.curve.opengl.TextRendererImpl01(rs, renderModes); } protected TextRenderer(RenderState rs, int type) { diff --git a/src/jogl/classes/com/jogamp/graph/curve/tess/CDTriangulator2D.java b/src/jogl/classes/com/jogamp/graph/curve/tess/CDTriangulator2D.java deleted file mode 100644 index f71105983..000000000 --- a/src/jogl/classes/com/jogamp/graph/curve/tess/CDTriangulator2D.java +++ /dev/null @@ -1,213 +0,0 @@ -/** - * 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.graph.curve.tess; - -import java.util.ArrayList; - -import jogamp.graph.curve.tess.GraphOutline; -import jogamp.graph.curve.tess.GraphVertex; -import jogamp.graph.curve.tess.Loop; - -import com.jogamp.graph.geom.Outline; -import com.jogamp.graph.geom.Triangle; -import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.math.VectorUtil; - -import jogamp.opengl.Debug; - -/** Constrained Delaunay Triangulation - * implementation of a list of Outlines that define a set of - * Closed Regions with optional n holes. - * - */ -public class CDTriangulator2D { - - protected static final boolean DEBUG = Debug.debug("Triangulation"); - - private float sharpness = 0.5f; - private ArrayList loops; - private ArrayList vertices; - - private ArrayList triangles; - private int maxTriID = 0; - - - /** Constructor for a new Delaunay triangulator - */ - public CDTriangulator2D() { - reset(); - } - - /** Reset the triangulation to initial state - * Clearing cached data - */ - public void reset() { - maxTriID = 0; - vertices = new ArrayList(); - triangles = new ArrayList(3); - loops = new ArrayList(); - } - - /** Add a curve to the list of profiles provided - * @param polyline a bounding {@link Outline} - */ - public void addCurve(Outline polyline) { - Loop loop = null; - - // FIXME: multiple in/out and CW/CCW tests (as follows) ?? - - if(!loops.isEmpty()) { - loop = getContainerLoop(polyline); - } - - if(loop == null) { - GraphOutline outline = new GraphOutline(polyline); - GraphOutline innerPoly = extractBoundaryTriangles(outline, false); - vertices.addAll(polyline.getVertices()); - loop = new Loop(innerPoly, VectorUtil.Winding.CCW); - loops.add(loop); - } else { - GraphOutline outline = new GraphOutline(polyline); - GraphOutline innerPoly = extractBoundaryTriangles(outline, true); - vertices.addAll(innerPoly.getVertices()); - loop.addConstraintCurve(innerPoly); - } - } - - /** Generate the triangulation of the provided - * List of {@link Outline}s - */ - public ArrayList generate() { - for(int i=0;i size){ - tri = loop.cut(false); - } - else{ - tri = loop.cut(true); - } - numTries++; - - if(tri != null) { - numTries = 0; - size--; - tri.setId(maxTriID++); - triangles.add(tri); - if(DEBUG){ - System.err.println(tri); - } - } - if(numTries > size*2){ - if(DEBUG){ - System.err.println("Triangulation not complete!"); - } - break; - } - } - Triangle tri = loop.cut(true); - if(tri != null) - triangles.add(tri); - } - return triangles; - } - - private GraphOutline extractBoundaryTriangles(GraphOutline outline, boolean hole) { - GraphOutline innerOutline = new GraphOutline(); - ArrayList outVertices = outline.getGraphPoint(); - int size = outVertices.size(); - for(int i=0; i < size; i++) { - GraphVertex currentVertex = outVertices.get(i); - GraphVertex gv0 = outVertices.get((i+size-1)%size); - GraphVertex gv2 = outVertices.get((i+1)%size); - GraphVertex gv1 = currentVertex; - - if(!currentVertex.getPoint().isOnCurve()) { - Vertex v0 = gv0.getPoint().clone(); - Vertex v2 = gv2.getPoint().clone(); - Vertex v1 = gv1.getPoint().clone(); - - gv0.setBoundaryContained(true); - gv1.setBoundaryContained(true); - gv2.setBoundaryContained(true); - - final Triangle t; - final boolean holeLike; - if(VectorUtil.ccw(v0,v1,v2)) { - holeLike = false; - t = new Triangle(v0, v1, v2); - } else { - holeLike = true; - t = new Triangle(v2, v1, v0); - } - t.setId(maxTriID++); - triangles.add(t); - if(DEBUG){ - System.err.println(t); - } - if( hole || holeLike ) { - v0.setTexCoord(0, -0.1f); - v2.setTexCoord(1, -0.1f); - v1.setTexCoord(0.5f, -1*sharpness -0.1f); - innerOutline.addVertex(currentVertex); - } else { - v0.setTexCoord(0, 0.1f); - v2.setTexCoord(1, 0.1f); - v1.setTexCoord(0.5f, sharpness+0.1f); - } - } - else { - if(!gv2.getPoint().isOnCurve() || !gv0.getPoint().isOnCurve()){ - currentVertex.setBoundaryContained(true); - } - innerOutline.addVertex(currentVertex); - } - } - return innerOutline; - } - - private Loop getContainerLoop(Outline polyline) { - ArrayList vertices = polyline.getVertices(); - for(int i=0; i < loops.size(); i++) { - Loop loop = loops.get(i); - boolean inside = false; - for(int j=0; j < vertices.size(); j++) { - Vertex v = vertices.get(j); - inside |= loop.checkInside(v); - } - if(inside) { - return loop; - } - } - return null; - } -} diff --git a/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulation.java b/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulation.java new file mode 100644 index 000000000..7728efcaf --- /dev/null +++ b/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulation.java @@ -0,0 +1,44 @@ +/** + * Copyright 2011 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.graph.curve.tess; + +import jogamp.graph.curve.tess.CDTriangulator2D; + + +public class Triangulation { + /** Create a new instance of a triangulation. + * Currently only a modified version of Constraint Delaunay + * is implemented. + * @return instance of a triangulator + * @see Triangulator + */ + public static Triangulator create() { + return new CDTriangulator2D(); + } +} diff --git a/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java b/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java new file mode 100644 index 000000000..1ffaccebc --- /dev/null +++ b/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java @@ -0,0 +1,69 @@ +/** + * Copyright 2011 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.graph.curve.tess; + +import java.util.ArrayList; + +import com.jogamp.graph.geom.Outline; +import com.jogamp.graph.geom.Triangle; + +/** Interface to the triangulation algorithms provided + * A triangulation of 2D outlines where you can + * provides an easy one or more outlines to be triangulated + * + * example usage: + * addCurve(o1); + * addCurve(o2); + * addCurve(o3); + * generate(); + * reset(); + * + * @see Outline + * @see Triangulation + */ +public interface Triangulator { + + /** Add a curve to the list of Outlines + * describing the shape + * @param outline a bounding {@link Outline} + */ + public void addCurve(Outline outline); + + /** Generate the triangulation of the provided + * List of {@link Outline}s + * @return an arraylist of {@link Triangle}s resembling the + * final shape. + */ + public ArrayList generate(); + + /** Reset the triangulation to initial state + * Clearing cached data + */ + public void reset(); +} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java b/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java index b5a89b40a..e33a78ed8 100755 --- a/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/RegionFactory.java @@ -39,14 +39,14 @@ public class RegionFactory { /** * Create a Region using the passed render mode * - *

In case {@link Region#TWO_PASS_RENDERING_BIT} is being requested the default texture unit + *

In case {@link Region#VBAA_RENDERING_BIT} is being requested the default texture unit * {@link Region#TWO_PASS_DEFAULT_TEXTURE_UNIT} is being used.

* * @param rs the RenderState to be used - * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#TWO_PASS_RENDERING_BIT} + * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT} */ public static GLRegion create(int renderModes) { - if( 0 != ( Region.TWO_PASS_RENDERING_BIT & renderModes ) ){ + if( 0 != ( Region.VBAA_RENDERING_BIT & renderModes ) ){ return new VBORegion2PES2(renderModes, Region.TWO_PASS_DEFAULT_TEXTURE_UNIT); } else{ diff --git a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java new file mode 100644 index 000000000..10b6d6847 --- /dev/null +++ b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java @@ -0,0 +1,203 @@ +/** + * 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 jogamp.graph.curve.tess; + +import java.util.ArrayList; + + +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.math.VectorUtil; + +import jogamp.opengl.Debug; + +/** Constrained Delaunay Triangulation + * implementation of a list of Outlines that define a set of + * Closed Regions with optional n holes. + * + */ +public class CDTriangulator2D implements Triangulator{ + + protected static final boolean DEBUG = Debug.debug("Triangulation"); + + private float sharpness = 0.5f; + private ArrayList loops; + private ArrayList vertices; + + private ArrayList triangles; + private int maxTriID = 0; + + + /** Constructor for a new Delaunay triangulator + */ + public CDTriangulator2D() { + reset(); + } + + /** Reset the triangulation to initial state + * Clearing cached data + */ + public void reset() { + maxTriID = 0; + vertices = new ArrayList(); + triangles = new ArrayList(3); + loops = new ArrayList(); + } + + public void addCurve(Outline polyline) { + Loop loop = null; + + if(!loops.isEmpty()) { + loop = getContainerLoop(polyline); + } + + if(loop == null) { + GraphOutline outline = new GraphOutline(polyline); + GraphOutline innerPoly = extractBoundaryTriangles(outline, false); + vertices.addAll(polyline.getVertices()); + loop = new Loop(innerPoly, VectorUtil.Winding.CCW); + loops.add(loop); + } else { + GraphOutline outline = new GraphOutline(polyline); + GraphOutline innerPoly = extractBoundaryTriangles(outline, true); + vertices.addAll(innerPoly.getVertices()); + loop.addConstraintCurve(innerPoly); + } + } + + public ArrayList generate() { + for(int i=0;i size){ + tri = loop.cut(false); + } + else{ + tri = loop.cut(true); + } + numTries++; + + if(tri != null) { + numTries = 0; + size--; + tri.setId(maxTriID++); + triangles.add(tri); + if(DEBUG){ + System.err.println(tri); + } + } + if(numTries > size*2){ + if(DEBUG){ + System.err.println("Triangulation not complete!"); + } + break; + } + } + Triangle tri = loop.cut(true); + if(tri != null) + triangles.add(tri); + } + return triangles; + } + + private GraphOutline extractBoundaryTriangles(GraphOutline outline, boolean hole) { + GraphOutline innerOutline = new GraphOutline(); + ArrayList outVertices = outline.getGraphPoint(); + int size = outVertices.size(); + for(int i=0; i < size; i++) { + GraphVertex currentVertex = outVertices.get(i); + GraphVertex gv0 = outVertices.get((i+size-1)%size); + GraphVertex gv2 = outVertices.get((i+1)%size); + GraphVertex gv1 = currentVertex; + + if(!currentVertex.getPoint().isOnCurve()) { + Vertex v0 = gv0.getPoint().clone(); + Vertex v2 = gv2.getPoint().clone(); + Vertex v1 = gv1.getPoint().clone(); + + gv0.setBoundaryContained(true); + gv1.setBoundaryContained(true); + gv2.setBoundaryContained(true); + + final Triangle t; + final boolean holeLike; + if(VectorUtil.ccw(v0,v1,v2)) { + holeLike = false; + t = new Triangle(v0, v1, v2); + } else { + holeLike = true; + t = new Triangle(v2, v1, v0); + } + t.setId(maxTriID++); + triangles.add(t); + if(DEBUG){ + System.err.println(t); + } + if( hole || holeLike ) { + v0.setTexCoord(0, -0.1f); + v2.setTexCoord(1, -0.1f); + v1.setTexCoord(0.5f, -1*sharpness -0.1f); + innerOutline.addVertex(currentVertex); + } else { + v0.setTexCoord(0, 0.1f); + v2.setTexCoord(1, 0.1f); + v1.setTexCoord(0.5f, sharpness+0.1f); + } + } + else { + if(!gv2.getPoint().isOnCurve() || !gv0.getPoint().isOnCurve()){ + currentVertex.setBoundaryContained(true); + } + innerOutline.addVertex(currentVertex); + } + } + return innerOutline; + } + + private Loop getContainerLoop(Outline polyline) { + ArrayList vertices = polyline.getVertices(); + for(int i=0; i < loops.size(); i++) { + Loop loop = loops.get(i); + boolean inside = false; + for(int j=0; j < vertices.size(); j++) { + Vertex v = vertices.get(j); + inside |= loop.checkInside(v); + } + if(inside) { + return loop; + } + } + return null; + } +} diff --git a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java index c07b41a7b..2fa708404 100644 --- a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java +++ b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java @@ -137,7 +137,7 @@ public class GlyphString { /** Generate a OGL Region to represent this Object. * @param gl the current gl object * @param rs the current attached RenderState - * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#TWO_PASS_RENDERING_BIT} + * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT} */ public GLRegion createRegion(GL2ES2 gl, int renderModes){ region = RegionFactory.create(renderModes); 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 c9c235c69..13aa266dc 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java @@ -67,7 +67,7 @@ public class TestRegionRendererNEWT01 extends UITestCase { GLWindow window = createWindow("shape-vbaa1-msaa0", caps, 800,400); RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory()); - GPURegionGLListener02 demo02Listener = new GPURegionGLListener02 (rs, Region.TWO_PASS_RENDERING_BIT, 1140, false, false); + GPURegionGLListener02 demo02Listener = new GPURegionGLListener02 (rs, Region.VBAA_RENDERING_BIT, 1140, false, false); demo02Listener.attachInputListenerTo(window); window.addGLEventListener(demo02Listener); diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java index a3bf215d9..acbcbc7da 100755 --- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java @@ -69,7 +69,7 @@ public class TestTextRendererNEWT01 extends UITestCase { GLWindow window = createWindow("text-vbaa1-msaa0", caps, 800,400); RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory()); - TextGLListener textGLListener = new TextGLListener(rs, Region.TWO_PASS_RENDERING_BIT, DEBUG, TRACE); + TextGLListener textGLListener = new TextGLListener(rs, Region.VBAA_RENDERING_BIT, DEBUG, TRACE); textGLListener.attachInputListenerTo(window); window.addGLEventListener(textGLListener); diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo02.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo02.java index 4cba9cbd5..f1db1ccdd 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo02.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo02.java @@ -64,7 +64,7 @@ public class GPURegionNewtDemo02 { window.setTitle("GPU Curve Region Newt Demo 02 - vbaa1 msaa0"); RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory()); - GPURegionGLListener02 regionGLListener = new GPURegionGLListener02 (rs, Region.TWO_PASS_RENDERING_BIT|Region.VARIABLE_CURVE_WEIGHT_BIT, 1140, DEBUG, TRACE); + GPURegionGLListener02 regionGLListener = new GPURegionGLListener02 (rs, Region.VBAA_RENDERING_BIT|Region.VARIABLE_CURVE_WEIGHT_BIT, 1140, DEBUG, TRACE); regionGLListener.attachInputListenerTo(window); window.addGLEventListener(regionGLListener); diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java index 9587a672d..e9df473ac 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURendererListenerBase01.java @@ -274,7 +274,7 @@ public abstract class GPURendererListenerBase01 implements GLEventListener { autoDrawable.invoke(false, new GLRunnable() { public void run(GLAutoDrawable drawable) { try { - final String type = Region.usesTwoPassRendering(renderModes) ? "r2t0-msaa1" : "r2t1-msaa0" + ( Region.usesVariableCurveWeight(renderModes) ? "-vc" : "-uc" ) ; + final String type = Region.isVBAA(renderModes) ? "vbaa0-msaa1" : "vbaa1-msaa0" + ( Region.usesVariableCurveWeight(renderModes) ? "-vc" : "-uc" ) ; printScreen(drawable, "./", "demo-"+type, "snap"+screenshot_num, false); screenshot_num++; } catch (GLException e) { diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java index 320e79472..d7dff5170 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java @@ -71,7 +71,7 @@ public class GPUTextNewtDemo02 { window.setTitle("GPU Text Newt Demo 02 - vbaa1 msaa0"); RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory()); - GPUTextGLListener0A textGLListener = new GPUTextGLListener0A(rs, Region.TWO_PASS_RENDERING_BIT, window.getWidth()*3, DEBUG, TRACE); + GPUTextGLListener0A textGLListener = new GPUTextGLListener0A(rs, Region.VBAA_RENDERING_BIT, window.getWidth()*3, DEBUG, TRACE); // ((TextRenderer)textGLListener.getRenderer()).setCacheLimit(32); textGLListener.attachInputListenerTo(window); window.addGLEventListener(textGLListener); -- cgit v1.2.3