aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/graph/curve
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com/jogamp/graph/curve')
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java144
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/Region.java228
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java40
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java7
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java2
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderUtil.java332
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java193
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java13
8 files changed, 613 insertions, 346 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
index 226e57f07..ee1dae4ca 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java
@@ -107,15 +107,27 @@ public class OutlineShape implements Comparable<OutlineShape> {
}
public static final int DIRTY_BOUNDS = 1 << 0;
+ /**
+ * Modified shape, requires to update the vertices and triangles, here: vertices.
+ */
+ public static final int DIRTY_VERTICES = 1 << 1;
+ /**
+ * Modified shape, requires to update the vertices and triangles, here: triangulation.
+ */
+ public static final int DIRTY_TRIANGLES = 1 << 2;
private final Vertex.Factory<? extends Vertex> vertexFactory;
- private VerticesState outlineState;
/** The list of {@link Outline}s that are part of this
* outline shape.
*/
- private ArrayList<Outline> outlines;
- private AABBox bbox;
+ /* pp */ final ArrayList<Outline> outlines;
+
+ private final AABBox bbox;
+ private final ArrayList<Triangle> triangles;
+ private final ArrayList<Vertex> vertices;
+
+ private VerticesState outlineState;
/** dirty bits DIRTY_BOUNDS */
private int dirtyBits;
@@ -128,6 +140,8 @@ public class OutlineShape implements Comparable<OutlineShape> {
this.outlines.add(new Outline());
this.outlineState = VerticesState.UNDEFINED;
this.bbox = new AABBox();
+ this.triangles = new ArrayList<Triangle>();
+ this.vertices = new ArrayList<Vertex>();
this.dirtyBits = 0;
}
@@ -137,6 +151,8 @@ public class OutlineShape implements Comparable<OutlineShape> {
outlines.add(new Outline());
outlineState = VerticesState.UNDEFINED;
bbox.reset();
+ vertices.clear();
+ triangles.clear();
dirtyBits = 0;
}
@@ -200,6 +216,8 @@ public class OutlineShape implements Comparable<OutlineShape> {
if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
bbox.resize(outline.getBounds());
}
+ // vertices.addAll(outline.getVertices()); // FIXME: can do and remove DIRTY_VERTICES ?
+ dirtyBits |= DIRTY_TRIANGLES | DIRTY_VERTICES;
return;
}
}
@@ -207,6 +225,7 @@ public class OutlineShape implements Comparable<OutlineShape> {
if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
bbox.resize(outline.getBounds());
}
+ dirtyBits |= DIRTY_TRIANGLES | DIRTY_VERTICES;
}
/** Insert the {@link OutlineShape} elements of type {@link Outline}, .. at the end of this shape,
@@ -239,7 +258,7 @@ public class OutlineShape implements Comparable<OutlineShape> {
throw new NullPointerException("outline is null");
}
outlines.set(position, outline);
- dirtyBits |= DIRTY_BOUNDS;
+ dirtyBits |= DIRTY_BOUNDS | DIRTY_TRIANGLES | DIRTY_VERTICES;
}
/** Removes the {@link Outline} element at the given {@code position}.
@@ -249,7 +268,7 @@ public class OutlineShape implements Comparable<OutlineShape> {
* @throws IndexOutOfBoundsException if position is out of range (position < 0 || position >= getOutlineNumber())
*/
public final Outline removeOutline(int position) throws IndexOutOfBoundsException {
- dirtyBits |= DIRTY_BOUNDS;
+ dirtyBits |= DIRTY_BOUNDS | DIRTY_TRIANGLES | DIRTY_VERTICES;
return outlines.remove(position);
}
@@ -278,6 +297,8 @@ public class OutlineShape implements Comparable<OutlineShape> {
if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
bbox.resize(lo.getBounds());
}
+ // vertices.add(v); // FIXME: can do and remove DIRTY_VERTICES ?
+ dirtyBits |= DIRTY_TRIANGLES | DIRTY_VERTICES;
}
/** Adds a vertex to the last open outline in the shape.
@@ -291,6 +312,7 @@ public class OutlineShape implements Comparable<OutlineShape> {
if( 0 == ( dirtyBits & DIRTY_BOUNDS ) ) {
bbox.resize(lo.getBounds());
}
+ dirtyBits |= DIRTY_TRIANGLES | DIRTY_VERTICES;
}
/** Add a 2D {@link Vertex} to the last outline by defining the coordniate attribute
@@ -338,7 +360,9 @@ public class OutlineShape implements Comparable<OutlineShape> {
* is equal to the first.</p>
*/
public void closeLastOutline() {
- getLastOutline().setClosed(true);
+ if( getLastOutline().setClosed(true) ) {
+ dirtyBits |= DIRTY_TRIANGLES | DIRTY_VERTICES;
+ }
}
/**
@@ -348,7 +372,8 @@ public class OutlineShape implements Comparable<OutlineShape> {
return outlineState;
}
- /** Ensure the outlines represent
+ /**
+ * Ensure the outlines represent
* the specified destinationType.
* and removes all overlaps in boundary triangles
* @param destinationType the target outline's vertices state. Currently only
@@ -376,6 +401,7 @@ public class OutlineShape implements Comparable<OutlineShape> {
outline.addVertex(index, vertexFactory.create(v1, 0, 3, false));
outline.addVertex(index+2, vertexFactory.create(v3, 0, 3, false));
+ dirtyBits |= DIRTY_VERTICES;
}
/** Check overlaps between curved triangles
@@ -427,6 +453,10 @@ public class OutlineShape implements Comparable<OutlineShape> {
}while(!overlaps.isEmpty());
}
+ private final float[] tempVecAC = new float[3];
+ private final float[] tempVecAB = new float[3];
+ private final float[] tempVecAP = new float[3];
+
private Vertex checkTriOverlaps(Vertex a, Vertex b, Vertex c) {
int count = getOutlineNumber();
for (int cc = 0; cc < count; cc++) {
@@ -445,15 +475,14 @@ public class OutlineShape implements Comparable<OutlineShape> {
continue;
}
- if(VectorUtil.vertexInTriangle(a.getCoord(), b.getCoord(), c.getCoord(), current.getCoord())
- || VectorUtil.vertexInTriangle(a.getCoord(), b.getCoord(), c.getCoord(), nextV.getCoord())
- || VectorUtil.vertexInTriangle(a.getCoord(), b.getCoord(), c.getCoord(), prevV.getCoord())) {
-
+ if( VectorUtil.vertexInTriangle3(a.getCoord(), b.getCoord(), c.getCoord(),
+ current.getCoord(), nextV.getCoord(), prevV.getCoord(),
+ tempVecAC, tempVecAB, tempVecAP) ) {
return current;
}
- if(VectorUtil.tri2SegIntersection(a, b, c, prevV, current)
- || VectorUtil.tri2SegIntersection(a, b, c, current, nextV)
- || VectorUtil.tri2SegIntersection(a, b, c, prevV, nextV)) {
+ if(VectorUtil.testTri2SegIntersection(a, b, c, prevV, current) ||
+ VectorUtil.testTri2SegIntersection(a, b, c, current, nextV) ||
+ VectorUtil.testTri2SegIntersection(a, b, c, prevV, nextV)) {
return current;
}
}
@@ -477,10 +506,12 @@ public class OutlineShape implements Comparable<OutlineShape> {
i++;
vertexCount++;
outline.addVertex(i, v);
+ dirtyBits |= DIRTY_VERTICES;
}
}
if(vertexCount <= 0) {
outlines.remove(outline);
+ dirtyBits |= DIRTY_VERTICES;
cc--;
count--;
continue;
@@ -508,37 +539,90 @@ public class OutlineShape implements Comparable<OutlineShape> {
}
}
- /** @return the list of concatenated vertices associated with all
- * {@code Outline}s of this object
+ /**
+ * Return list of concatenated vertices associated with all
+ * {@code Outline}s of this object.
+ * <p>
+ * Vertices are cached until marked dirty.
+ * </p>
+ * FIXME: Add memory optimization, i.e. VBO layout
*/
public ArrayList<Vertex> getVertices() {
- ArrayList<Vertex> vertices = new ArrayList<Vertex>();
- for(int i=0; i<outlines.size(); i++) {
- vertices.addAll(outlines.get(i).getVertices());
+ if( 0 != ( DIRTY_VERTICES & dirtyBits ) ) {
+ vertices.clear();
+ for(int i=0; i<outlines.size(); i++) {
+ vertices.addAll(outlines.get(i).getVertices());
+ }
+ dirtyBits &= ~DIRTY_VERTICES;
}
return vertices;
}
+ private void triangulateImpl() {
+ if( 0 < outlines.size() ) {
+ sortOutlines();
+ generateVertexIds();
+
+ triangles.clear();
+ final Triangulator triangulator2d = Triangulation.create();
+ for(int index = 0; index<outlines.size(); index++) {
+ triangulator2d.addCurve(triangles, outlines.get(index));
+ }
+ triangulator2d.generate(triangles);
+ triangulator2d.reset();
+ }
+ dirtyBits &= ~DIRTY_TRIANGLES;
+ }
+
/**
* Triangulate the {@link OutlineShape} generating a list of triangles
+ * while {@link #transformOutlines(VerticesState)} beforehand w/
+ * {@link OutlineShape.VerticesState#QUADRATIC_NURBS}.
+ * <p>
+ * Triangles are cached until marked dirty.
+ * </p>
* @return an arraylist of triangles representing the filled region
* which is produced by the combination of the outlines
+ * FIXME: Add memory optimization, i.e. VBO layout
*/
- public ArrayList<Triangle> triangulate() {
- if(outlines.size() == 0){
- return null;
+ public ArrayList<Triangle> getTriangles() {
+ final boolean updated;
+ if( 0 != ( DIRTY_TRIANGLES & dirtyBits ) ) {
+ transformOutlines(OutlineShape.VerticesState.QUADRATIC_NURBS);
+ triangulateImpl();
+ updated = true;
+ } else {
+ updated = false;
}
- sortOutlines();
- generateVertexIds();
-
- Triangulator triangulator2d = Triangulation.create();
- for(int index = 0; index<outlines.size(); index++) {
- triangulator2d.addCurve(outlines.get(index));
+ if(Region.DEBUG_INSTANCE) {
+ System.err.println("OutlineShape.getTriangles().1: "+triangles.size()+", updated "+updated);
}
- ArrayList<Triangle> triangles = triangulator2d.generate();
- triangulator2d.reset();
+ return triangles;
+ }
+ /**
+ * Triangulate the {@link OutlineShape} generating a list of triangles,
+ * while {@link #transformOutlines(VerticesState)} beforehand.
+ * <p>
+ * Triangles are cached until marked dirty.
+ * </p>
+ * @return an arraylist of triangles representing the filled region
+ * which is produced by the combination of the outlines
+ * FIXME: Add memory optimization, i.e. VBO layout
+ */
+ public ArrayList<Triangle> getTriangles(VerticesState destinationType) {
+ final boolean updated;
+ if( 0 != ( DIRTY_TRIANGLES & dirtyBits ) ) {
+ transformOutlines(destinationType);
+ triangulateImpl();
+ updated = true;
+ } else {
+ updated = false;
+ }
+ if(Region.DEBUG_INSTANCE) {
+ System.err.println("OutlineShape.getTriangles().2: "+triangles.size()+", updated "+updated);
+ }
return triangles;
}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/Region.java b/src/jogl/classes/com/jogamp/graph/curve/Region.java
index a9779523a..2b6da2084 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/Region.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/Region.java
@@ -28,36 +28,35 @@
package com.jogamp.graph.curve;
import java.util.ArrayList;
+import java.util.List;
+import jogamp.graph.curve.opengl.RegionFactory;
+import jogamp.graph.geom.plane.AffineTransform;
import jogamp.opengl.Debug;
+import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.geom.Triangle;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.opengl.math.geom.AABBox;
-/** Abstract Outline shape GL representation
- * define the method an OutlineShape(s) is
- * binded rendered.
+/** Abstract Outline shape GL representation define the method an OutlineShape(s)
+ * is bound and rendered.
*
- * @see GLRegion
- */
+ * @see GLRegion */
public abstract class Region {
- /** Debug flag for region impl (graph.curve)
- */
+ /** Debug flag for region impl (graph.curve) */
public static final boolean DEBUG = Debug.debug("graph.curve");
+ public static final boolean DEBUG_INSTANCE = Debug.debug("graph.curve.instance");
- public static final boolean DEBUG_INSTANCE = false;
-
- /** View based Anti-Aliasing, A Two pass region rendering, slower
- * and more resource hungry (FBO), but AA is perfect.
- * Otherwise the default fast one pass MSAA region rendering is being used.
- */
+ /** View based Anti-Aliasing, A Two pass region rendering, slower and more
+ * resource hungry (FBO), but AA is perfect. Otherwise the default fast one
+ * pass MSAA region rendering is being used. */
public static final int VBAA_RENDERING_BIT = 1 << 0;
/** Use non uniform weights [0.0 .. 1.9] for curve region rendering.
- * Otherwise the default weight 1.0 for uniform curve region rendering is being applied.
- */
+ * Otherwise the default weight 1.0 for uniform curve region rendering is
+ * being applied. */
public static final int VARIABLE_CURVE_WEIGHT_BIT = 1 << 1;
public static final int TWO_PASS_DEFAULT_TEXTURE_UNIT = 0;
@@ -66,20 +65,44 @@ public abstract class Region {
private boolean dirty = true;
protected int numVertices = 0;
protected final AABBox box = new AABBox();
+ /** FIXME: Think about a rendering storage optimization (VBO ... )! */
protected ArrayList<Triangle> triangles = new ArrayList<Triangle>();
+ /** FIXME: Think about a rendering storage optimization (VBO ... )! */
protected ArrayList<Vertex> vertices = new ArrayList<Vertex>();
public static boolean isVBAA(int renderModes) {
- return 0 != ( renderModes & Region.VBAA_RENDERING_BIT );
+ return 0 != (renderModes & Region.VBAA_RENDERING_BIT);
}
/** Check if render mode capable of non uniform weights
- * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT},
- * {@link Region#VBAA_RENDERING_BIT}
- * @return true of capable of non uniform weights
- */
+ *
+ * @param renderModes
+ * bit-field of modes, e.g.
+ * {@link Region#VARIABLE_CURVE_WEIGHT_BIT},
+ * {@link Region#VBAA_RENDERING_BIT}
+ * @return true of capable of non uniform weights */
public static boolean isNonUniformWeight(int renderModes) {
- return 0 != ( renderModes & Region.VARIABLE_CURVE_WEIGHT_BIT );
+ return 0 != (renderModes & Region.VARIABLE_CURVE_WEIGHT_BIT);
+ }
+
+ /** Create a {@link Region} defining the list of {@link OutlineShape}.
+ * Combining the Shapes into single buffers.
+ * @return the resulting Region inclusive the generated region
+ */
+ public static Region create(List<OutlineShape> outlineShapes, int renderModes) {
+ final Region region = RegionFactory.create(renderModes);
+ region.addOutlineShapes(outlineShapes);
+ return region;
+ }
+
+ /**
+ * Create a {@link Region} defining this {@link OutlineShape}
+ * @return the resulting Region.
+ */
+ public static Region create(OutlineShape outlineShape, int renderModes) {
+ final Region region = RegionFactory.create(renderModes);
+ region.addOutlineShape(outlineShape, null);
+ return region;
}
protected Region(int regionRenderModes) {
@@ -87,100 +110,151 @@ public abstract class Region {
}
/** Get current Models
- * @return bit-field of render modes
- */
+ *
+ * @return bit-field of render modes */
public final int getRenderModes() {
return renderModes;
}
/** Check if current Region is using VBAA
- * @return true if capable of two pass rendering - VBAA
- */
+ *
+ * @return true if capable of two pass rendering - VBAA */
public boolean isVBAA() {
return Region.isVBAA(renderModes);
}
/** Check if current instance uses non uniform weights
- * @return true if capable of nonuniform weights
- */
+ *
+ * @return true if capable of nonuniform weights */
public boolean isNonUniformWeight() {
return Region.isNonUniformWeight(renderModes);
}
- /** Get the current number of vertices associated
- * with this region. This number is not necessary equal to
- * the OGL bound number of vertices.
- * @return vertices count
- */
- public final int getNumVertices(){
+ /** Get the current number of vertices associated with this region. This
+ * number is not necessary equal to the OGL bound number of vertices.
+ *
+ * @return vertices count */
+ public final int getNumVertices() {
return numVertices;
}
- /** Adds a {@link Triangle} object to the Region
- * This triangle will be bound to OGL objects
- * on the next call to {@code update}
- * @param tri a triangle object
+ /** Adds a list of {@link Triangle} objects to the Region These triangles are
+ * to be binded to OGL objects on the next call to {@code update}
*
- * @see update(GL2ES2)
- */
- public void addTriangle(Triangle tri) {
- triangles.add(tri);
- setDirty(true);
- }
-
- /** Adds a list of {@link Triangle} objects to the Region
- * These triangles are to be binded to OGL objects
- * on the next call to {@code update}
- * @param tris an arraylist of triangle objects
+ * @param tris
+ * a list of triangle objects
+ * @param idxOffset TODO
*
- * @see update(GL2ES2)
- */
- public void addTriangles(ArrayList<Triangle> tris) {
- triangles.addAll(tris);
+ * @see update(GL2ES2) */
+ public void addTriangles(List<Triangle> tris, AffineTransform t, int idxOffset) {
+ if( true && null != t ) {
+ for(int i=0; i<tris.size(); i++) {
+ final Triangle t2 = tris.get(i).transform(t);
+ t2.addVertexIndicesOffset(idxOffset);
+ triangles.add( t2 );
+ }
+ } else {
+ for(int i=0; i<tris.size(); i++) {
+ final Triangle t2 = new Triangle( tris.get(i) );
+ t2.addVertexIndicesOffset(idxOffset);
+ triangles.add( t2 );
+ }
+ // triangles.addAll(tris);
+ }
+ if(DEBUG_INSTANCE) {
+ System.err.println("Region.addTriangles(): tris: "+triangles.size()+", verts "+vertices.size());
+ }
setDirty(true);
}
- /** Adds a {@link Vertex} object to the Region
- * This vertex will be bound to OGL objects
- * on the next call to {@code update}
- * @param vert a vertex objects
+ /** Adds a {@link Vertex} object to the Region This vertex will be bound to
+ * OGL objects on the next call to {@code update}
*
- * @see update(GL2ES2)
- */
- public void addVertex(Vertex vert) {
- vertices.add(vert);
+ * @param vert
+ * a vertex objects
+ *
+ * @see update(GL2ES2) */
+ public void addVertex(Vertex vert, AffineTransform t) {
+ final Vertex svert = null != t ? t.transform(vert, null) : vert;
+ vertices.add(svert);
numVertices++;
+ assert( vertices.size() == numVertices );
+ if(DEBUG_INSTANCE) {
+ System.err.println("Region.addVertex(): tris: "+triangles.size()+", verts "+vertices.size());
+ }
setDirty(true);
}
- /** Adds a list of {@link Vertex} objects to the Region
- * These vertices are to be binded to OGL objects
- * on the next call to {@code update}
- * @param verts an arraylist of vertex objects
+ /** Adds a list of {@link Vertex} objects to the Region These vertices are to
+ * be binded to OGL objects on the next call to {@code update}
*
- * @see update(GL2ES2)
- */
- public void addVertices(ArrayList<Vertex> verts) {
+ * @param verts
+ * a list of vertex objects
+ *
+ * @see update(GL2ES2) */
+ public void addVertices(List<Vertex> verts) {
vertices.addAll(verts);
numVertices = vertices.size();
+ if(DEBUG_INSTANCE) {
+ System.err.println("Region.addVertices(): tris: "+triangles.size()+", verts "+vertices.size());
+ }
setDirty(true);
}
- /**
- * @return the AxisAligned bounding box of
- * current region
- */
- public final AABBox getBounds(){
+ public void addOutlineShape(OutlineShape shape, AffineTransform t) {
+ final List<Triangle> tris = shape.getTriangles(OutlineShape.VerticesState.QUADRATIC_NURBS);
+ if(null != tris) {
+ if( false && null != t ) {
+ for(int i=0; i<tris.size(); i++) {
+ triangles.add( tris.get(i).transform(t) );
+ }
+ } else {
+ triangles.addAll(tris);
+ }
+ // final List<Vertex> verts = shape.getVertices();
+ // vertices.addAll(verts);
+ for (int j = 0; j < shape.outlines.size(); j++) {
+ final ArrayList<Vertex> sovs = shape.outlines.get(j).getVertices();
+ for (int k = 0; k < sovs.size(); k++) {
+ final Vertex v;
+ if( null != t ) {
+ v = t.transform(sovs.get(k), null);
+ } else {
+ v = sovs.get(k);
+ }
+ v.setId(numVertices++);
+ vertices.add(v);
+ }
+ }
+ // numVertices = vertices.size();
+ }
+ if(DEBUG_INSTANCE) {
+ System.err.println("Region.addOutlineShape(): tris: "+triangles.size()+", verts "+vertices.size());
+ }
+ setDirty(true);
+ }
+
+ public void addOutlineShapes(List<OutlineShape> shapes) {
+ for (int i = 0; i < shapes.size(); i++) {
+ addOutlineShape(shapes.get(i), null);
+ }
+ if(DEBUG_INSTANCE) {
+ System.err.println("Region.addOutlineShapes(): tris: "+triangles.size()+", verts "+vertices.size());
+ }
+ setDirty(true);
+ }
+
+ /** @return the AxisAligned bounding box of current region */
+ public final AABBox getBounds() {
return box;
}
- /** Check if this region is dirty. A region is marked dirty
- * when new Vertices, Triangles, and or Lines are added after a
- * call to update()
+ /** Check if this region is dirty. A region is marked dirty when new
+ * Vertices, Triangles, and or Lines are added after a call to update()
+ *
* @return true if region is Dirty, false otherwise
*
- * @see update(GL2ES2)
- */
+ * @see update(GL2ES2) */
public final boolean isDirty() {
return dirty;
}
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java
index dfb7a95b3..d63e02a9c 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java
@@ -27,17 +27,13 @@
*/
package com.jogamp.graph.curve.opengl;
-
-import java.util.ArrayList;
+import java.util.List;
import javax.media.opengl.GL2ES2;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.graph.curve.OutlineShape;
import com.jogamp.graph.curve.Region;
-import com.jogamp.graph.geom.Triangle;
-import com.jogamp.graph.geom.Vertex;
-import jogamp.graph.curve.opengl.RegionFactory;
/** A GLRegion is the OGL binding of one or more OutlineShapes
* Defined by its vertices and generated triangles. The Region
@@ -55,42 +51,16 @@ public abstract class GLRegion extends Region {
* Combining the Shapes into single buffers.
* @return the resulting Region inclusive the generated region
*/
- public static GLRegion create(OutlineShape[] outlineShapes, int renderModes) {
- final GLRegion region = RegionFactory.create(renderModes);
-
- int numVertices = region.getNumVertices();
-
- for(int index=0; index<outlineShapes.length; index++) {
- OutlineShape outlineShape = outlineShapes[index];
- outlineShape.transformOutlines(OutlineShape.VerticesState.QUADRATIC_NURBS);
-
- ArrayList<Triangle> triangles = outlineShape.triangulate();
- region.addTriangles(triangles);
-
- ArrayList<Vertex> vertices = outlineShape.getVertices();
- for(int pos=0; pos < vertices.size(); pos++){
- Vertex vert = vertices.get(pos);
- vert.setId(numVertices++);
- }
- region.addVertices(vertices);
- }
-
- return region;
+ public static GLRegion create(List<OutlineShape> outlineShapes, int renderModes) {
+ return (GLRegion) Region.create(outlineShapes, renderModes);
}
/**
- * Create an ogl {@link GLRegion} defining this {@link OutlineShape}
+ * Create an ogl {@link Region} defining this {@link OutlineShape}
* @return the resulting Region.
*/
public static GLRegion create(OutlineShape outlineShape, int renderModes) {
- final GLRegion region = RegionFactory.create(renderModes);
-
- outlineShape.transformOutlines(OutlineShape.VerticesState.QUADRATIC_NURBS);
- ArrayList<Triangle> triangles = (ArrayList<Triangle>) outlineShape.triangulate();
- ArrayList<Vertex> vertices = (ArrayList<Vertex>) outlineShape.getVertices();
- region.addVertices(vertices);
- region.addTriangles(triangles);
- return region;
+ return (GLRegion) Region.create(outlineShape, renderModes);
}
protected GLRegion(int renderModes) {
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 f7d4bfd2f..faaf72a99 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java
@@ -53,12 +53,11 @@ public abstract class RegionRenderer extends Renderer {
/** Render an {@link OutlineShape} in 3D space at the position provided
* the triangles of the shapes will be generated, if not yet generated
* @param region the OutlineShape to Render.
- * @param position the initial translation of the outlineShape.
* @param texWidth desired texture width for multipass-rendering.
* The actual used texture-width is written back when mp rendering is enabled, otherwise the store is untouched.
* @throws Exception if HwRegionRenderer not initialized
*/
- public final void draw(GL2ES2 gl, Region region, float[] position, int[/*1*/] texWidth) {
+ public final void draw(GL2ES2 gl, Region region, int[/*1*/] texWidth) {
if(!isInitialized()) {
throw new GLException("RegionRenderer: not initialized!");
}
@@ -66,14 +65,14 @@ public abstract class RegionRenderer extends Renderer {
throw new GLException("Incompatible render modes, : region modes "+region.getRenderModes()+
" doesn't contain renderer modes "+this.getRenderModes());
}
- drawImpl(gl, region, position, texWidth);
+ drawImpl(gl, region, texWidth);
}
/**
* Usually just dispatched the draw call to the Region's draw implementation,
* e.g. {@link com.jogamp.graph.curve.opengl.GLRegion#draw(GL2ES2, RenderState, int, int, int[]) GLRegion#draw(GL2ES2, RenderState, int, int, int[])}.
*/
- protected abstract void drawImpl(GL2ES2 gl, Region region, float[] position, int[] texWidth);
+ protected abstract void drawImpl(GL2ES2 gl, Region region, int[] texWidth);
@Override
protected void destroyImpl(GL2ES2 gl) {
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
index 029286601..31e4f0b8f 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java
@@ -102,7 +102,7 @@ public abstract class Renderer {
* Initialize shader and bindings for GPU based rendering bound to the given GL object's GLContext
* if not initialized yet.
* <p>Leaves the renderer enabled, ie ShaderState.</p>
- * <p>Shall be called by a {@code draw()} method, e.g. {@link RegionRenderer#draw(GL2ES2, Region, float[], int)}</p>
+ * <p>Shall be called by a {@code draw()} method, e.g. {@link RegionRenderer#draw(GL2ES2, Region, int)}</p>
*
* @param gl referencing the current GLContext to which the ShaderState is bound to
* @throws GLException if initialization failed
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderUtil.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderUtil.java
new file mode 100644
index 000000000..cef589f4f
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderUtil.java
@@ -0,0 +1,332 @@
+/**
+ * Copyright 2014 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.opengl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLException;
+
+import jogamp.graph.curve.opengl.RegionFactory;
+import jogamp.graph.geom.plane.AffineTransform;
+
+import com.jogamp.graph.curve.OutlineShape;
+import com.jogamp.graph.curve.Region;
+import com.jogamp.graph.font.Font;
+import com.jogamp.graph.font.Font.Glyph;
+import com.jogamp.graph.geom.Triangle;
+import com.jogamp.graph.geom.Vertex;
+import com.jogamp.graph.geom.Vertex.Factory;
+
+/**
+ *
+ * FIXME: Add VBO Vertex Factory for drawString3D !
+ *
+ */
+public class TextRenderUtil {
+
+ public final Renderer renderer;
+
+ public TextRenderUtil(final Renderer renderer) {
+ this.renderer = renderer;
+ }
+
+ /**
+ * Generate a Region to represent this Object.
+ * <p>
+ * Each glyph is cached and reused.
+ * </p>
+ *
+ * @param renderModes bit-field of modes, e.g. {@link Region#VARIABLE_CURVE_WEIGHT_BIT}, {@link Region#VBAA_RENDERING_BIT}
+ * @param vertexFactory vertex impl factory {@link Factory}
+ * @param font the target {@link Font}
+ * @param str string text
+ * @param pixelSize
+ */
+ public static GLRegion createRegion(final int renderModes, final Factory<? extends Vertex> vertexFactory,
+ final Font font, final CharSequence str, final int pixelSize) {
+ final int charCount = str.length();
+
+ final GLRegion region = RegionFactory.create(renderModes);
+ // region.setFlipped(true);
+ final Font.Metrics metrics = font.getMetrics();
+
+ final float lineGap = metrics.getLineGap(pixelSize) ;
+ final float ascent = metrics.getAscent(pixelSize) ;
+ final float descent = metrics.getDescent(pixelSize) ;
+ final float advanceY = lineGap - descent + ascent;
+ final float scale = metrics.getScale(pixelSize);
+ final AffineTransform transform = new AffineTransform(vertexFactory);
+ final AffineTransform t = new AffineTransform(vertexFactory);
+
+ float y = 0;
+ float advanceTotal = 0;
+ int numVertices = region.getNumVertices();
+
+ for(int i=0; i< charCount; i++) {
+ final char character = str.charAt(i);
+ if( '\n' == character ) {
+ y += advanceY;
+ advanceTotal = 0;
+ } else if (character == ' ') {
+ advanceTotal += font.getAdvanceWidth(Glyph.ID_SPACE, pixelSize);
+ } else {
+ if(Region.DEBUG_INSTANCE) {
+ System.err.println("XXXXXXXXXXXXXXx char: "+character+", scale: "+scale+"; translate: "+advanceTotal+", "+y);
+ }
+ t.setTransform(transform); // reset transform
+ t.translate(advanceTotal, y);
+ t.scale(scale, scale);
+
+ final Font.Glyph glyph = font.getGlyph(character);
+ final OutlineShape glyphShape = glyph.getShape();
+ if( null == glyphShape || glyphShape.getVertices().size() < 3 ) {
+ continue;
+ }
+ // glyphShape.closeLastOutline();
+
+ if( false ) {
+ region.addOutlineShape(glyphShape, t);
+ } else {
+ final ArrayList<Triangle> trisIn = glyphShape.getTriangles();
+ region.addTriangles(trisIn, t, numVertices);
+
+ final ArrayList<Vertex> gVertices = glyphShape.getVertices();
+ for(int j=0; j<gVertices.size(); j++) {
+ final Vertex vert = gVertices.get(j);
+ final Vertex svert = t.transform(vert, null);
+ svert.setId(numVertices++);
+ if(Region.DEBUG_INSTANCE) {
+ System.err.println("IN: "+vert);
+ System.err.println("EX: "+svert);
+ }
+ region.addVertex(svert, null);
+ }
+ }
+ assert( numVertices == region.getNumVertices() );
+
+ advanceTotal += glyph.getAdvance(pixelSize, true);
+ }
+ }
+ return region;
+ }
+
+ private static GLRegion createRegion2(final int renderModes, final Factory<? extends Vertex> vertexFactory,
+ final Font font, final CharSequence str, final int pixelSize) {
+ final List<OutlineShape> shapesIn = font.getOutlineShapes(null, str, pixelSize, vertexFactory);
+ final ArrayList<OutlineShape> shapesOut = new ArrayList<OutlineShape>();
+ final int numGlyps = shapesIn.size();
+ for (int index=0;index<numGlyps;index++){
+ if(shapesIn.get(index) == null){
+ continue;
+ }
+ final OutlineShape glyphShape = shapesIn.get(index);
+
+ if(glyphShape.getVertices().size() < 3) {
+ continue;
+ }
+ shapesOut.add(glyphShape);
+ }
+
+ final GLRegion region = RegionFactory.create(renderModes);
+ // region.setFlipped(true);
+ int numVertices = region.getNumVertices();
+
+ for(int i=0; i< shapesOut.size(); i++) {
+ final OutlineShape shape = shapesOut.get(i);
+ ArrayList<Triangle> gtris = shape.getTriangles();
+ region.addTriangles(gtris, null, 0);
+
+ final ArrayList<Vertex> gVertices = shape.getVertices();
+ for(int j=0; j<gVertices.size(); j++) {
+ final Vertex gVert = gVertices.get(j);
+ gVert.setId(numVertices++);
+ region.addVertex(gVert, null);
+ }
+ }
+ return region;
+ }
+
+
+ /**
+ * Render the String in 3D space wrt to the font provided at the position provided
+ * the outlines will be generated, if not yet generated
+ * @param gl the current GL state
+ * @param font {@link Font} to be used
+ * @param str text to be rendered
+ * @param pixelSize font size
+ * @param texWidth desired texture width for multipass-rendering.
+ * The actual used texture-width is written back when mp rendering is enabled, otherwise the store is untouched.
+ * @throws Exception if TextRenderer not initialized
+ */
+ public void drawString3D(final GL2ES2 gl,
+ final Font font, final CharSequence str, final int pixelSize, final int[/*1*/] texSize) {
+ if(!renderer.isInitialized()){
+ throw new GLException("TextRendererImpl01: not initialized!");
+ }
+ final RenderState rs = renderer.getRenderState();
+ GLRegion region = getCachedRegion(font, str, pixelSize);
+ if(null == region) {
+ region = createRegion(renderer.getRenderModes(), rs.getVertexFactory(), font, str, pixelSize);
+ addCachedRegion(gl, font, str, pixelSize, region);
+ }
+ region.draw(gl, rs, renderer.getWidth(), renderer.getHeight(), texSize);
+ }
+
+ /**
+ * Render the String in 3D space wrt to the font provided at the position provided
+ * the outlines will be generated, if not yet generated
+ * @param gl the current GL state
+ * @param font {@link Font} to be used
+ * @param str text to be rendered
+ * @param fontSize font size
+ * @param texWidth desired texture width for multipass-rendering.
+ * The actual used texture-width is written back when mp rendering is enabled, otherwise the store is untouched.
+ * @throws Exception if TextRenderer not initialized
+ */
+ public static void drawString3D(final Renderer renderer, final GL2ES2 gl,
+ final Font font, final CharSequence str, final int fontSize, final int[/*1*/] texSize) {
+ if(!renderer.isInitialized()){
+ throw new GLException("TextRendererImpl01: not initialized!");
+ }
+ final RenderState rs = renderer.getRenderState();
+ GLRegion region = createRegion(renderer.getRenderModes(), rs.getVertexFactory(), font, str, fontSize);
+ region.draw(gl, rs, renderer.getWidth(), renderer.getHeight(), texSize);
+ }
+
+ /** FIXME
+ public void flushCache(GL2ES2 gl) {
+ Iterator<GlyphString> iterator = stringCacheMap.values().iterator();
+ while(iterator.hasNext()){
+ GlyphString glyphString = iterator.next();
+ glyphString.destroy(gl, rs);
+ }
+ stringCacheMap.clear();
+ stringCacheArray.clear();
+ } */
+
+ public void destroy(GL2ES2 gl) {
+ // fluchCache(gl) already called
+ final Iterator<GLRegion> iterator = stringCacheMap.values().iterator();
+ while(iterator.hasNext()){
+ final GLRegion region = iterator.next();
+ region.destroy(gl, renderer.getRenderState());
+ }
+ stringCacheMap.clear();
+ stringCacheArray.clear();
+ }
+
+ /**
+ * <p>Sets the cache limit for reusing GlyphString's and their Region.
+ * Default is {@link #DEFAULT_CACHE_LIMIT}, -1 unlimited, 0 turns cache off, >0 limited </p>
+ *
+ * <p>The cache will be validate when the next string rendering happens.</p>
+ *
+ * @param newLimit new cache size
+ *
+ * @see #DEFAULT_CACHE_LIMIT
+ */
+ public final void setCacheLimit(int newLimit ) { stringCacheLimit = newLimit; }
+
+ /**
+ * Sets the cache limit, see {@link #setCacheLimit(int)} and validates the cache.
+ *
+ * @see #setCacheLimit(int)
+ *
+ * @param gl current GL used to remove cached objects if required
+ * @param newLimit new cache size
+ */
+ public final void setCacheLimit(GL2ES2 gl, int newLimit ) { stringCacheLimit = newLimit; validateCache(gl, 0); }
+
+ /**
+ * @return the current cache limit
+ */
+ public final int getCacheLimit() { return stringCacheLimit; }
+
+ /**
+ * @return the current utilized cache size, <= {@link #getCacheLimit()}
+ */
+ public final int getCacheSize() { return stringCacheArray.size(); }
+
+ protected final void validateCache(GL2ES2 gl, int space) {
+ if ( getCacheLimit() > 0 ) {
+ while ( getCacheSize() + space > getCacheLimit() ) {
+ removeCachedRegion(gl, 0);
+ }
+ }
+ }
+
+ protected final GLRegion getCachedRegion(Font font, CharSequence str, int fontSize) {
+ return stringCacheMap.get(getKey(font, str, fontSize));
+ }
+
+ protected final void addCachedRegion(GL2ES2 gl, Font font, CharSequence str, int fontSize, GLRegion glyphString) {
+ if ( 0 != getCacheLimit() ) {
+ final String key = getKey(font, str, fontSize);
+ final GLRegion oldRegion = stringCacheMap.put(key, glyphString);
+ if ( null == oldRegion ) {
+ // new entry ..
+ validateCache(gl, 1);
+ stringCacheArray.add(stringCacheArray.size(), key);
+ } /// else overwrite is nop ..
+ }
+ }
+
+ protected final void removeCachedRegion(GL2ES2 gl, Font font, CharSequence str, int fontSize) {
+ final String key = getKey(font, str, fontSize);
+ GLRegion region = stringCacheMap.remove(key);
+ if(null != region) {
+ region.destroy(gl, renderer.getRenderState());
+ }
+ stringCacheArray.remove(key);
+ }
+
+ protected final void removeCachedRegion(GL2ES2 gl, int idx) {
+ final String key = stringCacheArray.remove(idx);
+ final GLRegion region = stringCacheMap.remove(key);
+ if(null != region) {
+ region.destroy(gl, renderer.getRenderState());
+ }
+ }
+
+ protected final String getKey(Font font, CharSequence str, int fontSize) {
+ final StringBuilder sb = new StringBuilder();
+ return font.getName(sb, Font.NAME_UNIQUNAME)
+ .append(".").append(str.hashCode()).append(".").append(fontSize).toString();
+ }
+
+ /** Default cache limit, see {@link #setCacheLimit(int)} */
+ public static final int DEFAULT_CACHE_LIMIT = 256;
+
+ private final HashMap<String, GLRegion> stringCacheMap = new HashMap<String, GLRegion>(DEFAULT_CACHE_LIMIT);
+ private final ArrayList<String> stringCacheArray = new ArrayList<String>(DEFAULT_CACHE_LIMIT);
+ private int stringCacheLimit = DEFAULT_CACHE_LIMIT;
+} \ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java
deleted file mode 100644
index f6ce852d8..000000000
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java
+++ /dev/null
@@ -1,193 +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.opengl;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-
-import javax.media.opengl.GL2ES2;
-
-import jogamp.graph.curve.text.GlyphString;
-
-import com.jogamp.graph.font.Font;
-
-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#VBAA_RENDERING_BIT}
- */
- public static TextRenderer create(RenderState rs, int renderModes) {
- return new jogamp.graph.curve.opengl.TextRendererImpl01(rs, renderModes);
- }
-
- protected TextRenderer(RenderState rs, int type) {
- super(rs, type);
- }
-
-
- /** Render the String in 3D space wrt to the font provided at the position provided
- * the outlines will be generated, if not yet generated
- * @param gl the current GL state
- * @param font {@link Font} to be used
- * @param str text to be rendered
- * @param position the lower left corner of the string
- * @param fontSize font size
- * @param texWidth desired texture width for multipass-rendering.
- * The actual used texture-width is written back when mp rendering is enabled, otherwise the store is untouched.
- * @throws Exception if TextRenderer not initialized
- */
- public abstract void drawString3D(GL2ES2 gl, Font font,
- String str, float[] position, int fontSize, int[/*1*/] texSize);
-
- /**Create the resulting {@link GlyphString} that represents
- * the String wrt to the font.
- * @param font {@link Font} to be used
- * @param size font size
- * @param str {@link String} to be created
- * @return the resulting GlyphString inclusive the generated region
- */
- public GlyphString createString(GL2ES2 gl, Font font, int size, String str) {
- if(DEBUG_INSTANCE) {
- System.err.println("createString: "+getCacheSize()+"/"+getCacheLimit()+" - "+Font.NAME_UNIQUNAME + " - " + str + " - " + size);
- }
- final GlyphString glyphString = GlyphString.createString(null, rs.getVertexFactory(), font, size, str);
- glyphString.createRegion(gl, renderModes);
- return glyphString;
- }
-
- /** FIXME
- public void flushCache(GL2ES2 gl) {
- Iterator<GlyphString> iterator = stringCacheMap.values().iterator();
- while(iterator.hasNext()){
- GlyphString glyphString = iterator.next();
- glyphString.destroy(gl, rs);
- }
- stringCacheMap.clear();
- stringCacheArray.clear();
- } */
-
- @Override
- protected void destroyImpl(GL2ES2 gl) {
- // fluchCache(gl) already called
- Iterator<GlyphString> iterator = stringCacheMap.values().iterator();
- while(iterator.hasNext()){
- GlyphString glyphString = iterator.next();
- glyphString.destroy(gl, rs);
- }
- stringCacheMap.clear();
- stringCacheArray.clear();
- }
-
- /**
- * <p>Sets the cache limit for reusing GlyphString's and their Region.
- * Default is {@link #DEFAULT_CACHE_LIMIT}, -1 unlimited, 0 turns cache off, >0 limited </p>
- *
- * <p>The cache will be validate when the next string rendering happens.</p>
- *
- * @param newLimit new cache size
- *
- * @see #DEFAULT_CACHE_LIMIT
- */
- public final void setCacheLimit(int newLimit ) { stringCacheLimit = newLimit; }
-
- /**
- * Sets the cache limit, see {@link #setCacheLimit(int)} and validates the cache.
- *
- * @see #setCacheLimit(int)
- *
- * @param gl current GL used to remove cached objects if required
- * @param newLimit new cache size
- */
- public final void setCacheLimit(GL2ES2 gl, int newLimit ) { stringCacheLimit = newLimit; validateCache(gl, 0); }
-
- /**
- * @return the current cache limit
- */
- public final int getCacheLimit() { return stringCacheLimit; }
-
- /**
- * @return the current utilized cache size, <= {@link #getCacheLimit()}
- */
- public final int getCacheSize() { return stringCacheArray.size(); }
-
- protected final void validateCache(GL2ES2 gl, int space) {
- if ( getCacheLimit() > 0 ) {
- while ( getCacheSize() + space > getCacheLimit() ) {
- removeCachedGlyphString(gl, 0);
- }
- }
- }
-
- protected final GlyphString getCachedGlyphString(Font font, String str, int fontSize) {
- return stringCacheMap.get(getKey(font, str, fontSize));
- }
-
- protected final void addCachedGlyphString(GL2ES2 gl, Font font, String str, int fontSize, GlyphString glyphString) {
- if ( 0 != getCacheLimit() ) {
- final String key = getKey(font, str, fontSize);
- GlyphString oldGlyphString = stringCacheMap.put(key, glyphString);
- if ( null == oldGlyphString ) {
- // new entry ..
- validateCache(gl, 1);
- stringCacheArray.add(stringCacheArray.size(), key);
- } /// else overwrite is nop ..
- }
- }
-
- protected final void removeCachedGlyphString(GL2ES2 gl, Font font, String str, int fontSize) {
- final String key = getKey(font, str, fontSize);
- GlyphString glyphString = stringCacheMap.remove(key);
- if(null != glyphString) {
- glyphString.destroy(gl, rs);
- }
- stringCacheArray.remove(key);
- }
-
- protected final void removeCachedGlyphString(GL2ES2 gl, int idx) {
- final String key = stringCacheArray.remove(idx);
- final GlyphString glyphString = stringCacheMap.remove(key);
- if(null != glyphString) {
- glyphString.destroy(gl, rs);
- }
- }
-
- protected final String getKey(Font font, String str, int fontSize) {
- final StringBuilder sb = new StringBuilder();
- return font.getName(sb, Font.NAME_UNIQUNAME)
- .append(".").append(str.hashCode()).append(".").append(fontSize).toString();
- }
-
- /** Default cache limit, see {@link #setCacheLimit(int)} */
- public static final int DEFAULT_CACHE_LIMIT = 256;
-
- private HashMap<String, GlyphString> stringCacheMap = new HashMap<String, GlyphString>(DEFAULT_CACHE_LIMIT);
- private ArrayList<String> stringCacheArray = new ArrayList<String>(DEFAULT_CACHE_LIMIT);
- private int stringCacheLimit = DEFAULT_CACHE_LIMIT;
-} \ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java b/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java
index 4e8c400e0..39e84171b 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/tess/Triangulator.java
@@ -28,7 +28,7 @@
package com.jogamp.graph.curve.tess;
-import java.util.ArrayList;
+import java.util.List;
import com.jogamp.graph.geom.Outline;
import com.jogamp.graph.geom.Triangle;
@@ -49,18 +49,19 @@ import com.jogamp.graph.geom.Triangle;
*/
public interface Triangulator {
- /** Add a curve to the list of Outlines
+ /**
+ * Add a curve to the list of Outlines
* describing the shape
+ * @param sink list where the generated triangles will be added
* @param outline a bounding {@link Outline}
*/
- public void addCurve(Outline outline);
+ public void addCurve(List<Triangle> sink, Outline outline);
/** Generate the triangulation of the provided
* List of {@link Outline}s
- * @return an arraylist of {@link Triangle}s resembling the
- * final shape.
+ * @param sink list where the generated triangles will be added
*/
- public ArrayList<Triangle> generate();
+ public void generate(List<Triangle> sink);
/** Reset the triangulation to initial state
* Clearing cached data