diff options
author | Sven Gothel <[email protected]> | 2014-02-24 13:32:34 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-02-24 13:32:34 +0100 |
commit | c3621221b9a563495b4f54fe60e18e8db8cc57fb (patch) | |
tree | 00aded20f3582e517372c12f58e19d3524582099 /src/jogl/classes/jogamp/graph/curve | |
parent | f69df875d0b9f969a816d143ed589b25e50cd9e7 (diff) |
Bug 802: Graph TextRenderer Performance Part-1 (incomplete, rendering artifacts)
Strategy Change:
- Font.Glyph itself holds it's OutlineShape
with it's default scaling.
Triangulation is done only once per glyph!
- A CharSequence produces a Region
by translating and scaling each Glyphs's OutlineShape.
This removes the need for re-triangulate - see above.
See: TextRendererUtil
- The indices of re-added Triangles are
offset to the new vertices (FIXME, seems not be be accurate yet).
- OutlineShape's vertices and triangles are reused if 'clean'.
- Simplified code
- Reduced copies
API Changes:
- OutlineShape, Region, ...: See above
- Removed TextRenderer, GlyphShape and GlyphString: Redundant
- Added TextRendererUtil to produce the Region from CharSequence
Result:
- Over 600 fps while changing text for each frame.
Previously only ~60fps max.
TODO:
- Region shall not hold the triangles itself,
but the indices instead.
This will remove the need to swizzle w/ vertices in the Region Renderer impl
and easies reusage of OutlineShapes.
Diffstat (limited to 'src/jogl/classes/jogamp/graph/curve')
6 files changed, 54 insertions, 500 deletions
diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java b/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java deleted file mode 100644 index c3c7e0cac..000000000 --- a/src/jogl/classes/jogamp/graph/curve/opengl/TextRendererImpl01.java +++ /dev/null @@ -1,108 +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 jogamp.graph.curve.opengl; - -import javax.media.opengl.GL2ES2; -import javax.media.opengl.GLException; - -import jogamp.graph.curve.opengl.shader.AttributeNames; -import jogamp.graph.curve.text.GlyphString; - -import com.jogamp.graph.curve.opengl.RenderState; -import com.jogamp.graph.curve.opengl.TextRenderer; -import com.jogamp.graph.font.Font; -import com.jogamp.opengl.GLExtensions; -import com.jogamp.opengl.util.glsl.ShaderCode; -import com.jogamp.opengl.util.glsl.ShaderProgram; -import com.jogamp.opengl.util.glsl.ShaderState; - -public class TextRendererImpl01 extends TextRenderer { - public TextRendererImpl01(RenderState rs, int type) { - super(rs, type); - } - - @Override - protected boolean initShaderProgram(GL2ES2 gl){ - final ShaderState st = rs.getShaderState(); - - final ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, TextRendererImpl01.class, "shader", - "shader/bin", getVertexShaderName(), true); - final ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, TextRendererImpl01.class, "shader", - "shader/bin", getFragmentShaderName(), true); - rsVp.defaultShaderCustomization(gl, true, true); - // rsFp.defaultShaderCustomization(gl, true, true); - int pos = rsFp.addGLSLVersion(gl); - if( gl.isGLES() ) { - pos = rsFp.insertShaderSource(0, pos, ShaderCode.createExtensionDirective(GLExtensions.OES_standard_derivatives, ShaderCode.ENABLE)); - } - final String rsFpDefPrecision = getFragmentShaderPrecision(gl); - if( null != rsFpDefPrecision ) { - rsFp.insertShaderSource(0, pos, rsFpDefPrecision); - } - - final ShaderProgram sp = new ShaderProgram(); - sp.add(rsVp); - sp.add(rsFp); - - if( !sp.init(gl) ) { - throw new GLException("RegionRenderer: Couldn't init program: "+sp); - } - st.attachShaderProgram(gl, sp, false); - st.bindAttribLocation(gl, AttributeNames.VERTEX_ATTR_IDX, AttributeNames.VERTEX_ATTR_NAME); - st.bindAttribLocation(gl, AttributeNames.TEXCOORD_ATTR_IDX, AttributeNames.TEXCOORD_ATTR_NAME); - - if(!sp.link(gl, System.err)) { - throw new GLException("TextRendererImpl01: Couldn't link program: "+sp); - } - st.useProgram(gl, true); - - if(DEBUG) { - System.err.println("TextRendererImpl01 initialized: " + Thread.currentThread()+" "+st); - } - return true; - } - - @Override - protected void destroyImpl(GL2ES2 gl) { - super.destroyImpl(gl); - } - - @Override - public void drawString3D(GL2ES2 gl, Font font, String str, int fontSize, int[/*1*/] texSize) { - if(!isInitialized()){ - throw new GLException("TextRendererImpl01: not initialized!"); - } - GlyphString glyphString = getCachedGlyphString(font, str, fontSize); - if(null == glyphString) { - glyphString = createString(gl, font, fontSize, str); - addCachedGlyphString(gl, font, str, fontSize, glyphString); - } - - glyphString.renderString3D(gl, rs, vp_width, vp_height, texSize); - } -} diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java index 9feb18a12..3cc6152b2 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java @@ -42,7 +42,7 @@ import com.jogamp.opengl.util.glsl.ShaderState; public class VBORegionSPES2 extends GLRegion { private GLArrayDataServer verticeAttr = null; private GLArrayDataServer texCoordAttr = null; - private GLArrayDataServer indices = null; + private GLArrayDataServer indicesBuffer = null; protected VBORegionSPES2(int renderModes) { super(renderModes); @@ -54,11 +54,11 @@ public class VBORegionSPES2 extends GLRegion { return; } - if(null == indices) { + if(null == indicesBuffer) { final int initialElementCount = 256; final ShaderState st = rs.getShaderState(); - indices = GLArrayDataServer.createData(3, GL2ES2.GL_SHORT, initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + indicesBuffer = GLArrayDataServer.createData(3, GL2ES2.GL_SHORT, initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); verticeAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL2ES2.GL_FLOAT, false, initialElementCount, GL.GL_STATIC_DRAW); @@ -73,9 +73,12 @@ public class VBORegionSPES2 extends GLRegion { } } + if(DEBUG_INSTANCE) { + System.err.println("VBORegionSPES2 Indices of "+triangles.size()+", triangles"); + } // process triangles - indices.seal(gl, false); - indices.rewind(); + indicesBuffer.seal(gl, false); + indicesBuffer.rewind(); for(int i=0; i<triangles.size(); i++) { final Triangle t = triangles.get(i); final Vertex[] t_vertices = t.getVertices(); @@ -89,17 +92,25 @@ public class VBORegionSPES2 extends GLRegion { vertices.add(t_vertices[1]); vertices.add(t_vertices[2]); - indices.puts((short) t_vertices[0].getId()); - indices.puts((short) t_vertices[1].getId()); - indices.puts((short) t_vertices[2].getId()); + indicesBuffer.puts((short) t_vertices[0].getId()); + indicesBuffer.puts((short) t_vertices[1].getId()); + indicesBuffer.puts((short) t_vertices[2].getId()); + if(DEBUG_INSTANCE) { + System.err.println("VBORegionSPES2.Indices.1: "+ + t_vertices[0].getId()+", "+t_vertices[1].getId()+", "+t_vertices[2].getId()); + } } else { - indices.puts((short) t_vertices[0].getId()); - indices.puts((short) t_vertices[1].getId()); - indices.puts((short) t_vertices[2].getId()); + indicesBuffer.puts((short) t_vertices[0].getId()); + indicesBuffer.puts((short) t_vertices[1].getId()); + indicesBuffer.puts((short) t_vertices[2].getId()); + if(DEBUG_INSTANCE) { + System.err.println("VBORegionSPES2.Indices.2: "+ + t_vertices[0].getId()+", "+t_vertices[1].getId()+", "+t_vertices[2].getId()); + } } } - indices.seal(gl, true); - indices.enableBuffer(gl, false); + indicesBuffer.seal(gl, true); + indicesBuffer.enableBuffer(gl, false); // process vertices and update bbox box.reset(); @@ -130,11 +141,11 @@ public class VBORegionSPES2 extends GLRegion { protected void drawImpl(GL2ES2 gl, RenderState rs, int vp_width, int vp_height, int[/*1*/] texWidth) { verticeAttr.enableBuffer(gl, true); texCoordAttr.enableBuffer(gl, true); - indices.bindBuffer(gl, true); // keeps VBO binding + indicesBuffer.bindBuffer(gl, true); // keeps VBO binding - gl.glDrawElements(GL2ES2.GL_TRIANGLES, indices.getElementCount() * indices.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); + gl.glDrawElements(GL2ES2.GL_TRIANGLES, indicesBuffer.getElementCount() * indicesBuffer.getComponentCount(), GL2ES2.GL_UNSIGNED_SHORT, 0); - indices.bindBuffer(gl, false); + indicesBuffer.bindBuffer(gl, false); texCoordAttr.enableBuffer(gl, false); verticeAttr.enableBuffer(gl, false); } @@ -155,9 +166,9 @@ public class VBORegionSPES2 extends GLRegion { texCoordAttr.destroy(gl); texCoordAttr = null; } - if(null != indices) { - indices.destroy(gl); - indices = null; + if(null != indicesBuffer) { + indicesBuffer.destroy(gl); + indicesBuffer = null; } } } diff --git a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java index f0910c465..a82c2ee7a 100644 --- a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java +++ b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java @@ -29,7 +29,7 @@ package jogamp.graph.curve.tess; import java.util.ArrayList; - +import java.util.List; import com.jogamp.graph.curve.tess.Triangulator; import com.jogamp.graph.geom.Outline; @@ -48,11 +48,10 @@ public class CDTriangulator2D implements Triangulator{ protected static final boolean DEBUG = Debug.debug("Triangulation"); - private float sharpness = 0.5f; + private final float sharpness = 0.5f; private ArrayList<Loop> loops; - private ArrayList<Vertex> vertices; + // FIXME ? private ArrayList<Vertex> vertices; - private ArrayList<Triangle> triangles; private int maxTriID = 0; @@ -68,13 +67,12 @@ public class CDTriangulator2D implements Triangulator{ @Override public void reset() { maxTriID = 0; - vertices = new ArrayList<Vertex>(); - triangles = new ArrayList<Triangle>(3); + // vertices = new ArrayList<Vertex>(); loops = new ArrayList<Loop>(); } @Override - public void addCurve(Outline polyline) { + public void addCurve(List<Triangle> sink, Outline polyline) { Loop loop = null; if(!loops.isEmpty()) { @@ -82,27 +80,27 @@ public class CDTriangulator2D implements Triangulator{ } if(loop == null) { - GraphOutline outline = new GraphOutline(polyline); - GraphOutline innerPoly = extractBoundaryTriangles(outline, false); - vertices.addAll(polyline.getVertices()); + final GraphOutline outline = new GraphOutline(polyline); + final GraphOutline innerPoly = extractBoundaryTriangles(sink, 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()); + final GraphOutline outline = new GraphOutline(polyline); + final GraphOutline innerPoly = extractBoundaryTriangles(sink, outline, true); + // vertices.addAll(innerPoly.getVertices()); loop.addConstraintCurve(innerPoly); } } @Override - public ArrayList<Triangle> generate() { + public void generate(List<Triangle> sink) { 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; + final Triangle tri; if(numTries > size){ tri = loop.cut(false); } @@ -115,7 +113,7 @@ public class CDTriangulator2D implements Triangulator{ numTries = 0; size--; tri.setId(maxTriID++); - triangles.add(tri); + sink.add(tri); if(DEBUG){ System.err.println(tri); } @@ -127,15 +125,14 @@ public class CDTriangulator2D implements Triangulator{ break; } } - Triangle tri = loop.cut(true); + final Triangle tri = loop.cut(true); if(tri != null) { - triangles.add(tri); + sink.add(tri); } } - return triangles; } - private GraphOutline extractBoundaryTriangles(GraphOutline outline, boolean hole) { + private GraphOutline extractBoundaryTriangles(List<Triangle> sink, GraphOutline outline, boolean hole) { GraphOutline innerOutline = new GraphOutline(); ArrayList<GraphVertex> outVertices = outline.getGraphPoint(); int size = outVertices.size(); @@ -146,9 +143,9 @@ public class CDTriangulator2D implements Triangulator{ GraphVertex gv1 = currentVertex; if(!currentVertex.getPoint().isOnCurve()) { - Vertex v0 = gv0.getPoint().clone(); - Vertex v2 = gv2.getPoint().clone(); - Vertex v1 = gv1.getPoint().clone(); + final Vertex v0 = gv0.getPoint().clone(); + final Vertex v2 = gv2.getPoint().clone(); + final Vertex v1 = gv1.getPoint().clone(); gv0.setBoundaryContained(true); gv1.setBoundaryContained(true); @@ -164,7 +161,7 @@ public class CDTriangulator2D implements Triangulator{ t = new Triangle(v2, v1, v0); } t.setId(maxTriID++); - triangles.add(t); + sink.add(t); if(DEBUG){ System.err.println(t); } diff --git a/src/jogl/classes/jogamp/graph/curve/tess/Loop.java b/src/jogl/classes/jogamp/graph/curve/tess/Loop.java index c1dafc0d1..5810e3bc9 100644 --- a/src/jogl/classes/jogamp/graph/curve/tess/Loop.java +++ b/src/jogl/classes/jogamp/graph/curve/tess/Loop.java @@ -37,7 +37,7 @@ import com.jogamp.opengl.math.geom.AABBox; public class Loop { private HEdge root = null; - private AABBox box = new AABBox(); + private final AABBox box = new AABBox(); private GraphOutline initialOutline = null; public Loop(GraphOutline polyline, VectorUtil.Winding winding){ @@ -272,13 +272,13 @@ public class Loop { * @return the triangle iff it satisfies, null otherwise */ private Triangle createTriangle(Vertex v1, Vertex v2, Vertex v3, HEdge rootT){ - Triangle t = new Triangle(v1, v2, v3); + final Triangle t = new Triangle(v1, v2, v3); t.setVerticesBoundary(checkVerticesBoundary(rootT)); return t; } private boolean[] checkVerticesBoundary(HEdge rootT) { - boolean[] boundary = new boolean[3]; + final boolean[] boundary = new boolean[3]; HEdge e1 = rootT; HEdge e2 = rootT.getNext(); HEdge e3 = rootT.getNext().getNext(); diff --git a/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java deleted file mode 100644 index 8c214dd0b..000000000 --- a/src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java +++ /dev/null @@ -1,112 +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 jogamp.graph.curve.text; - -import java.util.ArrayList; - -import com.jogamp.graph.font.Font.Glyph; -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.opengl.math.Quaternion; - -public class GlyphShape { - - // private Quaternion quat= null; - private Glyph glyph; - private OutlineShape shape; - - /** Create a new Glyph shape - * based on Parametric curve control polyline - */ - public GlyphShape(Vertex.Factory<? extends Vertex> factory){ - this.shape = new OutlineShape(factory); - this.glyph = null; - } - - /** 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, Glyph glyph, OutlineShape shape){ - this(factory); - this.shape = shape; - this.shape.transformOutlines(OutlineShape.VerticesState.QUADRATIC_NURBS); - this.glyph = glyph; - } - - public final void destroy() { - shape.clear(); - shape = null; - glyph = null; - } - - public final Vertex.Factory<? extends Vertex> vertexFactory() { return shape.vertexFactory(); } - - public final Glyph getGlyph() { - return glyph; - } - - public final OutlineShape getShape() { - return shape; - } - - public final int getNumVertices() { - return shape.getVertices().size(); - } - - /** Get the rotational quaternion attached to this Shape. - * @return the Quaternion Object - public final Quaternion getQuat() { - return quat; - } - - /** - * Set the Quaternion that shall define the rotation - * of this shape. - * @param quat - public final void setQuat(Quaternion quat) { - this.quat = quat; - } - */ - - /** Triangluate the glyph shape - * @return ArrayList of triangles which define this shape - */ - public final ArrayList<Triangle> triangulate(){ - return shape.triangulate(); - } - - /** Get the list of Vertices of this Object - * @return arrayList of Vertices - */ - public final ArrayList<Vertex> getVertices(){ - return shape.getVertices(); - } -} diff --git a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java deleted file mode 100644 index 5fb547e69..000000000 --- a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java +++ /dev/null @@ -1,234 +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 jogamp.graph.curve.text; - -import java.util.ArrayList; -import java.util.List; - -import com.jogamp.graph.font.Font; -import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.Triangle; -import com.jogamp.graph.geom.Vertex.Factory; -import com.jogamp.graph.geom.opengl.SVertex; - -import javax.media.opengl.GL2ES2; - -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.curve.opengl.GLRegion; -import com.jogamp.graph.curve.opengl.RenderState; -import com.jogamp.opengl.math.geom.AABBox; -import com.jogamp.opengl.util.PMVMatrix; - -/** - * @deprecated use {@link com.jogamp.graph.font.Font#getOutlineShapes(java.util.List, CharSequence, float, Factory)}, - * {@link com.jogamp.graph.curve.Region#create(OutlineShape, int)} - * and a {@link com.jogamp.graph.curve.opengl.RegionRenderer}. - */ -public class GlyphString { - /** Static font size for all default font OutlineShape generations via {@link #createString(OutlineShape, Factory, Font, String)}. - * <p>The actual font size shall be accomplished by the GL PMV matrix.</p> - */ - public static final int STATIC_FONT_SIZE = 10; - - private final ArrayList<GlyphShape> glyphs = new ArrayList<GlyphShape>(); - private final CharSequence str; - private final String fontname; - private GLRegion region; - - private final SVertex origin = new SVertex(); - - /** - * <p>Uses {@link #STATIC_FONT_SIZE}.</p> - * <p>No caching is performed.</p> - * - * @param shape is not null, add all {@link GlyphShape}'s {@link Outline} to this instance. - * @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) { - return createString(shape, vertexFactory, font, STATIC_FONT_SIZE, str); - } - - /** - * <p>No caching is performed.</p> - * - * @param shape is not null, add all {@link GlyphShape}'s {@link Outline} to this instance. - * @param vertexFactory vertex impl factory {@link Factory} - * @param font the target {@link Font} - * @param fontSize 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, CharSequence str) { - List<OutlineShape> shapes = font.getOutlineShapes(null, str, fontSize, vertexFactory); - - GlyphString glyphString = new GlyphString(font.getName(Font.NAME_UNIQUNAME), str); - glyphString.createfromOutlineShapes(vertexFactory, font, str, shapes); - if(null != shape) { - for(int i=0; i<glyphString.glyphs.size(); i++) { - shape.addOutlineShape(glyphString.glyphs.get(i).getShape()); - } - } - return glyphString; - } - - /** Create a new GlyphString object - * @param fontname the name of the font that this String is - * associated with - * @param str the string object - */ - public GlyphString(String fontname, CharSequence str){ - this.fontname = fontname; - this.str = str; - } - - public void addGlyphShape(GlyphShape glyph){ - glyphs.add(glyph); - } - - public CharSequence getString(){ - return str; - } - - /**Creates the Curve based Glyphs from a list of {@link OutlineShape} - * @param vertexFactory vertex impl factory {@link Factory} - * @param shapes list of {@link OutlineShape} - */ - public void createfromOutlineShapes(Factory<? extends Vertex> vertexFactory, Font font, CharSequence str, List<OutlineShape> shapes) { - if(shapes.size() != str.length()) { - throw new InternalError("XXX"); - } - final int numGlyps = shapes.size(); - for (int index=0;index<numGlyps;index++){ - if(shapes.get(index) == null){ - continue; - } - GlyphShape glyphShape = new GlyphShape(vertexFactory, - font.getGlyph(str.charAt(index)), - shapes.get(index)); - - if(glyphShape.getNumVertices() < 3) { - continue; - } - addGlyphShape(glyphShape); - } - } - - - /** 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#VBAA_RENDERING_BIT} - */ - public GLRegion createRegion(GL2ES2 gl, int renderModes){ - region = RegionFactory.create(renderModes); - // region.setFlipped(true); - float y = 0; - float advanceTotal = 0; - AffineTransform t = new AffineTransform(); - - int numVertices = region.getNumVertices(); - - for(int i=0; i< glyphs.size(); i++) { - final GlyphShape glyphShape = glyphs.get(i); - Font.Metrics metrics = glyphShape.getGlyph().getFont().getMetrics(); - final float scale = metrics.getScale(STATIC_FONT_SIZE); - t.translate(advanceTotal, y); - t.scale(scale, scale); - - ArrayList<Triangle> gtris = glyphShape.triangulate(); - region.addTriangles(gtris); - - final ArrayList<Vertex> gVertices = glyphShape.getVertices(); - for(int j=0; j<gVertices.size(); j++) { - final Vertex gVert = gVertices.get(j); - gVert.setId(numVertices++); - region.addVertex(gVert); - } - - advanceTotal += glyphShape.getGlyph().getAdvance(STATIC_FONT_SIZE, true); - } - return region; - } - - /** Generate a Hashcode for this object - * @return a string defining the hashcode - */ - public String getTextHashCode(){ - return "" + fontname.hashCode() + str.hashCode(); - } - - /** Render the Object based using the associated Region - * previously generated. - */ - public void renderString3D(GL2ES2 gl) { - region.draw(gl, null, 0, 0, null); - } - /** Render the Object based using the associated Region - * previously generated. - * @param matrix current {@link PMVMatrix}. - * @param rs the RenderState to be used - * @param vp_width current screen width - * @param vp_height current screen height - * @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. - */ - public void renderString3D(GL2ES2 gl, RenderState rs, int vp_width, int vp_height, int[/*1*/] texWidth) { - region.draw(gl, rs, vp_width, vp_height, texWidth); - } - - /** Get the Origin of this GlyphString - * @return - */ - public Vertex getOrigin() { - return origin; - } - - /** Destroy the associated OGL objects - * @param rs the current attached RenderState - */ - public void destroy(GL2ES2 gl, RenderState rs) { - if(null != gl && null != rs) { - region.destroy(gl, rs); - region = null; - } else if(null != region) { - throw new InternalError("destroy called w/o GL context, but has a region"); - } - glyphs.clear(); - } - - public AABBox getBounds(){ - return region.getBounds(); - } -} |