diff options
author | Sven Gothel <[email protected]> | 2011-06-08 06:00:30 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-06-08 06:00:30 +0200 |
commit | f6bd208d8ef15769e13cb959e614349fd1e7cae1 (patch) | |
tree | 1761440a136814803361efc79a6f7c35c844a603 /src/jogl/classes/jogamp/graph | |
parent | 138ddda3f346db0f1d8b4bac1760d415e7dc3d70 (diff) | |
parent | 820fd3f4e45cfa79e94fad385eb47ff26a5fea2b (diff) |
Merge remote-tracking branch 'rsantina/master'
Diffstat (limited to 'src/jogl/classes/jogamp/graph')
7 files changed, 305 insertions, 92 deletions
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
*
- * <p> In case {@link Region#TWO_PASS_RENDERING_BIT} is being requested the default texture unit
+ * <p> In case {@link Region#VBAA_RENDERING_BIT} is being requested the default texture unit
* {@link Region#TWO_PASS_DEFAULT_TEXTURE_UNIT} is being used.</p>
*
* @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<Loop> loops; + private ArrayList<Vertex> vertices; + + private ArrayList<Triangle> 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<Vertex>(); + triangles = new ArrayList<Triangle>(3); + loops = new ArrayList<Loop>(); + } + + 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<Triangle> generate() { + for(int i=0;i<loops.size();i++) { + Loop loop = loops.get(i); + int numTries = 0; + int size = loop.computeLoopSize(); + while(!loop.isSimplex()){ + Triangle tri = null; + if(numTries > 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<GraphVertex> 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<Vertex> 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/GlyphShape.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java index ed51cce98..578148699 100644 --- a/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java +++ b/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java @@ -29,10 +29,9 @@ package jogamp.graph.curve.text; import java.util.ArrayList; -import jogamp.graph.geom.plane.PathIterator; - import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.geom.Triangle; +import com.jogamp.graph.geom.Vertex.Factory; import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.math.Quaternion; @@ -40,7 +39,6 @@ import com.jogamp.graph.math.Quaternion; public class GlyphShape { private Quaternion quat= null; - private int numVertices = 0; private OutlineShape shape = null; /** Create a new Glyph shape @@ -50,70 +48,24 @@ public class GlyphShape { shape = new OutlineShape(factory); } - /** Create a GlyphShape from a font Path Iterator - * @param pathIterator the path iterator - * - * @see PathIterator + /** Create a new GlyphShape from a {@link OutlineShape} + * @param factory vertex impl factory {@link Factory} + * @param shape {@link OutlineShape} representation of the Glyph */ - public GlyphShape(Vertex.Factory<? extends Vertex> factory, PathIterator pathIterator){ + public GlyphShape(Vertex.Factory<? extends Vertex> factory, OutlineShape shape){ this(factory); - - if(null != pathIterator){ - while(!pathIterator.isDone()){ - float[] coords = new float[6]; - int segmentType = pathIterator.currentSegment(coords); - addOutlineVerticesFromGlyphVector(coords, segmentType); - - pathIterator.next(); - } - } - shape.transformOutlines(OutlineShape.VerticesState.QUADRATIC_NURBS); + this.shape = shape; + this.shape.transformOutlines(OutlineShape.VerticesState.QUADRATIC_NURBS); } public final Vertex.Factory<? extends Vertex> vertexFactory() { return shape.vertexFactory(); } - private void addVertexToLastOutline(Vertex vertex) { - //FIXME: assuming font outline comes in CW order - shape.addVertex(0, vertex); - } - - private void addOutlineVerticesFromGlyphVector(float[] coords, int segmentType){ - switch(segmentType) { - case PathIterator.SEG_MOVETO: - shape.closeLastOutline(); - shape.addEmptyOutline(); - addVertexToLastOutline(vertexFactory().create(coords, 0, 2, true)); - numVertices++; - break; - case PathIterator.SEG_LINETO: - addVertexToLastOutline(vertexFactory().create(coords, 0, 2, true)); - numVertices++; - break; - case PathIterator.SEG_QUADTO: - addVertexToLastOutline(vertexFactory().create(coords, 0, 2, false)); - addVertexToLastOutline(vertexFactory().create(coords, 2, 2, true)); - numVertices+=2; - break; - case PathIterator.SEG_CUBICTO: - addVertexToLastOutline(vertexFactory().create(coords, 0, 2, false)); - addVertexToLastOutline(vertexFactory().create(coords, 2, 2, false)); - addVertexToLastOutline(vertexFactory().create(coords, 4, 2, true)); - numVertices+=3; - break; - case PathIterator.SEG_CLOSE: - shape.closeLastOutline(); - break; - default: - throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType); - } - } - public OutlineShape getShape() { return shape; } public int getNumVertices() { - return numVertices; + return shape.getVertices().size(); } /** Get the rotational Quaternion attached to this Shape diff --git a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java index cd6cd56aa..2fa708404 100644 --- a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java +++ b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java @@ -40,10 +40,6 @@ import javax.media.opengl.GL2ES2; import jogamp.graph.curve.opengl.RegionFactory; import jogamp.graph.font.FontInt; -import jogamp.graph.geom.plane.AffineTransform; -import jogamp.graph.geom.plane.Path2D; -import jogamp.graph.geom.plane.PathIterator; - import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.curve.Region; @@ -68,9 +64,9 @@ public class GlyphString { * <p>No caching is performed.</p> * * @param shape is not null, add all {@link GlyphShape}'s {@link Outline} to this instance. - * @param vertexFactory - * @param font - * @param str + * @param vertexFactory vertex impl factory {@link Factory} + * @param font the target {@link Font} + * @param str string text * @return the created {@link GlyphString} instance */ public static GlyphString createString(OutlineShape shape, Factory<? extends Vertex> vertexFactory, Font font, String str) { @@ -81,20 +77,17 @@ public class GlyphString { * <p>No caching is performed.</p> * * @param shape is not null, add all {@link GlyphShape}'s {@link Outline} to this instance. - * @param vertexFactory - * @param font - * @param size - * @param str + * @param vertexFactory vertex impl factory {@link Factory} + * @param font the target {@link Font} + * @param size font size + * @param str string text * @return the created {@link GlyphString} instance */ public static GlyphString createString(OutlineShape shape, Factory<? extends Vertex> vertexFactory, Font font, int fontSize, String str) { - AffineTransform affineTransform = new AffineTransform(vertexFactory); - - Path2D[] paths = new Path2D[str.length()]; - ((FontInt)font).getPaths(str, fontSize, affineTransform, paths); + ArrayList<OutlineShape> shapes = ((FontInt)font).getOutlineShapes(str, fontSize, vertexFactory); GlyphString glyphString = new GlyphString(font.getName(Font.NAME_UNIQUNAME), str); - glyphString.createfromFontPath(vertexFactory, paths, affineTransform); + glyphString.createfromOutlineShapes(vertexFactory, shapes); if(null != shape) { for(int i=0; i<glyphString.glyphs.size(); i++) { shape.addOutlineShape(glyphString.glyphs.get(i).getShape()); @@ -121,19 +114,17 @@ public class GlyphString { return str; } - /** Creates the Curve based Glyphs from a Font + /**Creates the Curve based Glyphs from a list of {@link OutlineShape} * @param vertexFactory vertex impl factory {@link Factory} - * @param paths a list of FontPath2D objects that define the outline - * @param affineTransform a global affine transformation applied to the paths. + * @param shapes list of {@link OutlineShape} */ - public void createfromFontPath(Factory<? extends Vertex> vertexFactory, Path2D[] paths, AffineTransform affineTransform) { - final int numGlyps = paths.length; + public void createfromOutlineShapes(Factory<? extends Vertex> vertexFactory, ArrayList<OutlineShape> shapes) { + final int numGlyps = shapes.size(); for (int index=0;index<numGlyps;index++){ - if(paths[index] == null){ + if(shapes.get(index) == null){ continue; } - PathIterator iterator = paths[index].iterator(affineTransform); - GlyphShape glyphShape = new GlyphShape(vertexFactory, iterator); + GlyphShape glyphShape = new GlyphShape(vertexFactory, shapes.get(index)); if(glyphShape.getNumVertices() < 3) { continue; @@ -142,10 +133,11 @@ 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/jogl/classes/jogamp/graph/font/FontInt.java b/src/jogl/classes/jogamp/graph/font/FontInt.java index 6c25f9a80..37660bb2c 100644 --- a/src/jogl/classes/jogamp/graph/font/FontInt.java +++ b/src/jogl/classes/jogamp/graph/font/FontInt.java @@ -27,11 +27,14 @@ */ package jogamp.graph.font; -import jogamp.graph.geom.plane.AffineTransform; +import java.util.ArrayList; + 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 interface FontInt extends Font { @@ -46,7 +49,5 @@ public interface FontInt extends Font { public Path2D getPath(float pixelSize); } - public void getPaths(CharSequence string, float pixelSize, - AffineTransform transform, Path2D[] result); - //TODO: Rami - ADD getOutlines without path2D + public ArrayList<OutlineShape> getOutlineShapes(CharSequence string, float pixelSize, Factory<? extends Vertex> vertexFactory); } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java index 2e692e5ce..8806f537d 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java @@ -27,6 +27,8 @@ */ package jogamp.graph.font.typecast; +import java.util.ArrayList; + import jogamp.graph.font.FontInt; import jogamp.graph.font.typecast.ot.OTFont; import jogamp.graph.font.typecast.ot.OTFontCollection; @@ -39,9 +41,12 @@ import jogamp.graph.geom.plane.AffineTransform; import jogamp.graph.geom.plane.Path2D; import com.jogamp.common.util.IntObjectHashMap; +import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.font.Font; import com.jogamp.graph.font.FontFactory; import com.jogamp.graph.geom.AABBox; +import com.jogamp.graph.geom.Vertex; +import com.jogamp.graph.geom.Vertex.Factory; class TypecastFont implements FontInt { static final boolean DEBUG = false; @@ -208,9 +213,10 @@ class TypecastFont implements FontInt { } return result; } - - public void getPaths(CharSequence string, float pixelSize, AffineTransform transform, Path2D[] result) { - TypecastRenderer.getPaths(this, string, pixelSize, transform, result); + + public ArrayList<OutlineShape> getOutlineShapes(CharSequence string, float pixelSize, Factory<? extends Vertex> vertexFactory) { + AffineTransform transform = new AffineTransform(vertexFactory); + return TypecastRenderer.getOutlineShapes(this, string, pixelSize, transform, vertexFactory); } public float getStringWidth(CharSequence string, float pixelSize) { diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java index 310b2b274..50b510d23 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java @@ -27,12 +27,19 @@ */ package jogamp.graph.font.typecast; +import java.util.ArrayList; + +import jogamp.graph.curve.text.GlyphShape; import jogamp.graph.font.typecast.ot.OTGlyph; import jogamp.graph.font.typecast.ot.Point; import jogamp.graph.geom.plane.AffineTransform; import jogamp.graph.geom.plane.Path2D; +import jogamp.graph.geom.plane.PathIterator; +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; /** * Factory to build a {@link com.jogamp.graph.geom.Path2D Path2D} from @@ -40,7 +47,7 @@ import com.jogamp.graph.font.Font; */ public class TypecastRenderer { - public static void getPaths(TypecastFont font, + private static void getPaths(TypecastFont font, CharSequence string, float pixelSize, AffineTransform transform, Path2D[] p) { if (string == null) { @@ -82,6 +89,58 @@ public class TypecastRenderer { } } + public static ArrayList<OutlineShape> getOutlineShapes(TypecastFont font, CharSequence string, float pixelSize, AffineTransform transform, Factory<? extends Vertex> vertexFactory) { + Path2D[] paths = new Path2D[string.length()]; + getPaths(font, string, pixelSize, transform, paths); + + ArrayList<OutlineShape> shapes = new ArrayList<OutlineShape>(); + final int numGlyps = paths.length; + for (int index=0;index<numGlyps;index++) { + if(paths[index] == null){ + continue; + } + OutlineShape shape = new OutlineShape(vertexFactory); + shapes.add(shape); + PathIterator iterator = paths[index].iterator(transform); + if(null != iterator){ + while(!iterator.isDone()){ + float[] coords = new float[6]; + int segmentType = iterator.currentSegment(coords); + addPathVertexToOutline(shape, vertexFactory, coords, segmentType); + iterator.next(); + } + } + } + return shapes; + } + private static void addPathVertexToOutline(OutlineShape shape, Factory<? extends Vertex> vertexFactory, float[] coords, int segmentType){ + switch(segmentType) { + case PathIterator.SEG_MOVETO: + shape.closeLastOutline(); + shape.addEmptyOutline(); + shape.addVertex(0, vertexFactory.create(coords, 0, 2, true)); + //numVertices++; + break; + case PathIterator.SEG_LINETO: + shape.addVertex(0, vertexFactory.create(coords, 0, 2, true)); + break; + case PathIterator.SEG_QUADTO: + shape.addVertex(0, vertexFactory.create(coords, 0, 2, false)); + shape.addVertex(0, vertexFactory.create(coords, 2, 2, true)); + break; + case PathIterator.SEG_CUBICTO: + shape.addVertex(0, vertexFactory.create(coords, 0, 2, false)); + shape.addVertex(0, vertexFactory.create(coords, 2, 2, false)); + shape.addVertex(0, vertexFactory.create(coords, 4, 2, true)); + break; + case PathIterator.SEG_CLOSE: + shape.closeLastOutline(); + break; + default: + throw new IllegalArgumentException("Unhandled Segment Type: "+segmentType); + } + } + /** * Build a {@link com.jogamp.graph.geom.Path2D Path2D} from a * {@link jogamp.graph.font.typecast.ot.OTGlyph Glyph}. This glyph path can then |