summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-02-27 23:56:13 +0100
committerSven Gothel <[email protected]>2014-02-27 23:56:13 +0100
commit67ec86e539a3db0d06e5cc3550db453589594384 (patch)
tree66d006ff20407cb6bfc16fb288a5d4665df077cf
parent2cafc01f08f9ab05748be6eeb82c417de38b31f7 (diff)
Bug 801: Graph TextRenderer Cleanup Part-4: Text[Render->Region]Util API: Better separation of cached and uncached regions
-rw-r--r--src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java (renamed from src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderUtil.java)83
-rw-r--r--src/jogl/classes/com/jogamp/graph/font/Font.java6
-rw-r--r--src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java43
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java47
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java31
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java7
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/GLReadBuffer00Base.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java12
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java12
11 files changed, 136 insertions, 121 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderUtil.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java
index 944050a14..e7ed335ec 100644
--- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderUtil.java
+++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java
@@ -30,7 +30,6 @@ 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;
@@ -41,47 +40,36 @@ 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 !
- *
+ * Text {@link GLRegion} Utility Class
*/
-public class TextRenderUtil {
+public class TextRegionUtil {
public final RegionRenderer renderer;
- public TextRenderUtil(final RegionRenderer renderer) {
+ public TextRegionUtil(final RegionRenderer 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}
+ * Add the string in 3D space w.r.t. the font and pixelSize at the end of the {@link GLRegion}.
+ * @param region the {@link GLRegion} sink
* @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) {
+ public static void addStringToRegion(final GLRegion region, final Factory<? extends Vertex> vertexFactory,
+ final Font font, final CharSequence str, final int pixelSize) {
final int charCount = str.length();
- final GLRegion region = GLRegion.create(renderModes);
// region.setFlipped(true);
final Font.Metrics metrics = font.getMetrics();
+ final float lineHeight = font.getLineHeight(pixelSize);
- 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);
@@ -92,7 +80,7 @@ public class TextRenderUtil {
for(int i=0; i< charCount; i++) {
final char character = str.charAt(i);
if( '\n' == character ) {
- y += advanceY;
+ y -= lineHeight;
advanceTotal = 0;
} else if (character == ' ') {
advanceTotal += font.getAdvanceWidth(Glyph.ID_SPACE, pixelSize);
@@ -114,37 +102,41 @@ public class TextRenderUtil {
advanceTotal += glyph.getAdvance(pixelSize, true);
}
}
- 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
+ * Render the string in 3D space w.r.t. the font and pixelSize
+ * using a cached {@link GLRegion} for reuse.
+ * <p>
+ * Cached {@link GLRegion}s will be destroyed w/ {@link #clear(GL2ES2)} or to free memory.
+ * </p>
* @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.
+ * @param texSize 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()){
+ 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);
+ region = GLRegion.create(renderer.getRenderModes());
+ addStringToRegion(region, rs.getVertexFactory(), font, str, pixelSize);
addCachedRegion(gl, font, str, pixelSize, region);
}
region.draw(gl, renderer, 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
+ * Render the string in 3D space w.r.t. the font and pixelSize
+ * using a temporary {@link GLRegion}, which will be destroyed afterwards.
* @param gl the current GL state
* @param font {@link Font} to be used
* @param str text to be rendered
@@ -154,27 +146,22 @@ public class TextRenderUtil {
* @throws Exception if TextRenderer not initialized
*/
public static void drawString3D(final RegionRenderer renderer, final GL2ES2 gl,
- final Font font, final CharSequence str, final int fontSize, final int[/*1*/] texSize) {
+ 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);
+ final GLRegion region = GLRegion.create(renderer.getRenderModes());
+ addStringToRegion(region, rs.getVertexFactory(), font, str, fontSize);
region.draw(gl, renderer, texSize);
+ region.destroy(gl, renderer);
}
- /** 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) {
+ /**
+ * Clear all cached {@link GLRegions}.
+ */
+ public void clear(GL2ES2 gl) {
// fluchCache(gl) already called
final Iterator<GLRegion> iterator = stringCacheMap.values().iterator();
while(iterator.hasNext()){
@@ -252,9 +239,11 @@ public class TextRenderUtil {
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);
+ if( null != key ) {
+ final GLRegion region = stringCacheMap.remove(key);
+ if(null != region) {
+ region.destroy(gl, renderer);
+ }
}
}
diff --git a/src/jogl/classes/com/jogamp/graph/font/Font.java b/src/jogl/classes/com/jogamp/graph/font/Font.java
index afffe0654..122015218 100644
--- a/src/jogl/classes/com/jogamp/graph/font/Font.java
+++ b/src/jogl/classes/com/jogamp/graph/font/Font.java
@@ -73,6 +73,9 @@ public interface Font {
/**
* Glyph for font
+ *
+ * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6cmap.html
+ * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6glyf.html
*/
public interface Glyph {
// reserved special glyph IDs
@@ -103,11 +106,12 @@ public interface Font {
public StringBuilder getAllNames(StringBuilder string, String separator);
- public float getAdvanceWidth(int i, float pixelSize);
+ public float getAdvanceWidth(int glyphID, float pixelSize);
public Metrics getMetrics();
public Glyph getGlyph(char symbol);
public int getNumGlyphs();
+ public float getLineHeight(float pixelSize);
public float getStringWidth(CharSequence string, float pixelSize);
public float getStringHeight(CharSequence string, float pixelSize);
public AABBox getStringBounds(CharSequence string, float pixelSize);
diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
index 81c06cd83..8dd9ce4d7 100644
--- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
+++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java
@@ -166,8 +166,8 @@ class TypecastFont implements Font {
}
@Override
- public float getAdvanceWidth(int i, float pixelSize) {
- return font.getHmtxTable().getAdvanceWidth(i) * metrics.getScale(pixelSize);
+ public float getAdvanceWidth(int glyphID, float pixelSize) {
+ return font.getHmtxTable().getAdvanceWidth(glyphID) * metrics.getScale(pixelSize);
}
@Override
@@ -197,7 +197,7 @@ class TypecastFont implements Font {
if(null == glyph) {
throw new RuntimeException("Could not retrieve glyph for symbol: <"+symbol+"> "+(int)symbol+" -> glyph id "+code);
}
- final OutlineShape shape = TypecastRenderer.buildShape(glyph, vertexFactory);
+ final OutlineShape shape = TypecastRenderer.buildShape(symbol, glyph, vertexFactory);
result = new TypecastGlyph(this, symbol, code, glyph.getBBox(), glyph.getAdvanceWidth(), shape);
if(DEBUG) {
System.err.println("New glyph: " + (int)symbol + " ( " + symbol +" ) -> " + code + ", contours " + glyph.getPointCount() + ": " + shape);
@@ -222,12 +222,21 @@ class TypecastFont implements Font {
}
@Override
+ public float getLineHeight(float pixelSize) {
+ final Metrics metrics = getMetrics();
+ final float lineGap = metrics.getLineGap(pixelSize) ; // negative value!
+ final float ascent = metrics.getAscent(pixelSize) ; // negative value!
+ final float descent = metrics.getDescent(pixelSize) ; // positive value!
+ final float advanceY = lineGap - descent + ascent; // negative value!
+ return -advanceY;
+ }
+
+ @Override
public float getStringWidth(CharSequence string, float pixelSize) {
float width = 0;
final int len = string.length();
- for (int i=0; i< len; i++)
- {
- char character = string.charAt(i);
+ for (int i=0; i< len; i++) {
+ final char character = string.charAt(i);
if (character == '\n') {
width = 0;
} else {
@@ -235,7 +244,6 @@ class TypecastFont implements Font {
width += glyph.getAdvance(pixelSize, false);
}
}
-
return (int)(width + 0.5f);
}
@@ -243,12 +251,10 @@ class TypecastFont implements Font {
public float getStringHeight(CharSequence string, float pixelSize) {
int height = 0;
- for (int i=0; i<string.length(); i++)
- {
- char character = string.charAt(i);
- if (character != ' ')
- {
- Glyph glyph = getGlyph(character);
+ for (int i=0; i<string.length(); i++) {
+ final char character = string.charAt(i);
+ if (character != ' ') {
+ final Glyph glyph = getGlyph(character);
AABBox bbox = glyph.getBBox(pixelSize);
height = (int)Math.ceil(Math.max(bbox.getHeight(), height));
}
@@ -261,11 +267,8 @@ class TypecastFont implements Font {
if (string == null) {
return new AABBox();
}
- final Metrics metrics = 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 lineHeight = getLineHeight(pixelSize);
+
float totalHeight = 0;
float totalWidth = 0;
float curLineWidth = 0;
@@ -274,14 +277,14 @@ class TypecastFont implements Font {
if (character == '\n') {
totalWidth = Math.max(curLineWidth, totalWidth);
curLineWidth = 0;
- totalHeight -= advanceY;
+ totalHeight += lineHeight;
continue;
}
Glyph glyph = getGlyph(character);
curLineWidth += glyph.getAdvance(pixelSize, true);
}
if (curLineWidth > 0) {
- totalHeight -= advanceY;
+ totalHeight += lineHeight;
totalWidth = Math.max(curLineWidth, totalWidth);
}
return new AABBox(0, 0, 0, totalWidth, totalHeight,0);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
index 7e151945c..909e90456 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java
@@ -49,7 +49,6 @@ import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
import com.jogamp.common.os.Platform;
-import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontFactory;
@@ -66,6 +65,7 @@ public class TestTextRendererNEWT00 extends UITestCase {
static final boolean DEBUG = false;
static final boolean TRACE = false;
static long duration = 100; // ms
+ static boolean waitStartEnd = false;
static final int[] texSize = new int[] { 0 };
static final int fontSize = 24;
@@ -87,6 +87,8 @@ public class TestTextRendererNEWT00 extends UITestCase {
if(args[i].equals("-time")) {
i++;
duration = atoi(args[i]);
+ } else if(args[i].equals("-wait")) {
+ waitStartEnd = true;
}
}
String tstname = TestTextRendererNEWT00.class.getName();
@@ -128,9 +130,12 @@ public class TestTextRendererNEWT00 extends UITestCase {
caps.setNumSamples(4);
System.err.println("Requested: "+caps);
- GLWindow window = createWindow("text-vbaa0-msaa1", caps, 800, 400);
+ GLWindow window = createWindow("text-vbaa0-msaa1", caps, 1024, 640);
window.display();
System.err.println("Chosen: "+window.getChosenGLCapabilities());
+ if( waitStartEnd ) {
+ UITestCase.waitForKey("Start");
+ }
final RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory());
final TextRendererGLEL textGLListener = new TextRendererGLEL(rs);
@@ -156,10 +161,23 @@ public class TestTextRendererNEWT00 extends UITestCase {
anim.setUpdateFPSFrames(60, null);
sleep();
anim.stop();
+ if( waitStartEnd ) {
+ UITestCase.waitForKey("Stop");
+ }
destroyWindow(window);
}
int screenshot_num = 0;
+ static final String textX2 =
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec nec sapien tellus. \n"+
+ "Ut purus odio, rhoncus sit amet commodo eget, ullamcorper vel urna. Mauris ultricies \n"+
+ "quam iaculis urna cursus ornare. Nullam ut felis a ante ultrices ultricies nec a elit. \n"+
+ "In hac habitasse platea dictumst. Vivamus et mi a quam lacinia pharetra at venenatis est.\n"+
+ "Morbi quis bibendum nibh. Donec lectus orci, sagittis in consequat nec, volutpat nec nisi.\n"+
+ "Donec ut dolor et nulla tristique varius. In nulla magna, fermentum id tempus quis, semper \n"+
+ "in lorem. Maecenas in ipsum ac justo scelerisque sollicitudin. Quisque sit amet neque lorem,\n" +
+ "------- End of Story ;-) ---------\n";
+
private final class TextRendererGLEL extends TextRendererGLELBase {
private final GLReadBufferUtil screenshot;
private long t0;
@@ -222,22 +240,23 @@ public class TestTextRendererNEWT00 extends UITestCase {
final long t1 = Platform.currentTimeMillis();
- final String text1 = String.format("%03.3f/%03.3f s, vsync %d, elapsed %4.4f s",
+ final String text1 = String.format("%03.1f/%03.1f fps, vsync %d, elapsed %4.1f s",
lfps, tfps, gl.getSwapInterval(), (t1-t0)/1000.0);
- int row = 0;
if( false ) {
- renderString(drawable, "112", 0, row++, 0, 0, -1000);
- // renderString(drawable, getFontInfo(), 0, row++, 0, 0, -1000);
+ renderString(drawable, textX2, 0, 0, 0, 0, -1000, true);
+ // renderString(drawable, "0", 0, 0, 0, 0, -1000);
+ // renderString(drawable, getFontInfo(), 0, 0, 0, -1000);
} else {
- renderString(drawable, getFontInfo(), 0, row++, 0, 0, -1000);
- renderString(drawable, "012345678901234567890123456789", 0, row++, 0, 0, -1000);
- renderString(drawable, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 0, row++, 0, 0, -1000);
- renderString(drawable, "Hello World", 0, row++, 0, 0, -1000);
- renderString(drawable, "4567890123456", 4, row++, 0, 0, -1000);
- renderString(drawable, "I like JogAmp", 4, row++, 0, 0, -1000);
- renderString(drawable, "Hello World", 0, row++, 0, 0, -1000);
- renderString(drawable, text1, 0, row++, 0, 0, -1000);
+ renderString(drawable, getFontInfo(), 0, 0, 0, 0, -1000, true);
+ renderString(drawable, "012345678901234567890123456789", 0, 0, 0, -1000, true);
+ renderString(drawable, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 0, 0, 0, -1000, true);
+ renderString(drawable, "Hello World", 0, 0, 0, -1000, true);
+ renderString(drawable, "4567890123456", 4, 0, 0, -1000, true);
+ renderString(drawable, "I like JogAmp", 4, 0, 0, -1000, true);
+ renderString(drawable, "Hello World", 0, 0, 0, -1000, true);
+ renderString(drawable, textX2, 0, 0, 0, -1000, true);
+ renderString(drawable, text1, 0, 0, 0, -1000, false); // no-cache
}
} };
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java
index 2a349b2de..ac59eb10b 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT10.java
@@ -43,7 +43,7 @@ import org.junit.runners.MethodSorters;
import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.curve.opengl.RegionRenderer;
-import com.jogamp.graph.curve.opengl.TextRenderUtil;
+import com.jogamp.graph.curve.opengl.TextRegionUtil;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontFactory;
import com.jogamp.graph.geom.SVertex;
@@ -140,7 +140,7 @@ public class TestTextRendererNEWT10 extends UITestCase {
final RenderState rs = RenderState.createRenderState(new ShaderState(), SVertex.factory());
final RegionRenderer renderer = RegionRenderer.create(rs, 0);
- final TextRenderUtil textRenderUtil = new TextRenderUtil(renderer);
+ final TextRegionUtil textRenderUtil = new TextRegionUtil(renderer);
// init
gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
@@ -179,7 +179,7 @@ public class TestTextRendererNEWT10 extends UITestCase {
int lastRow = -1;
- void renderString(GLDrawable drawable, GL2ES2 gl, TextRenderUtil textRenderUtil, String text, int column, int row, int z0) {
+ void renderString(GLDrawable drawable, GL2ES2 gl, TextRegionUtil textRenderUtil, String text, int column, int row, int z0) {
final int height = drawable.getHeight();
int dx = 0;
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java b/src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java
index da1fb5515..6b955b0db 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TextRendererGLELBase.java
@@ -34,13 +34,13 @@ import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
+import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.curve.opengl.RegionRenderer;
-import com.jogamp.graph.curve.opengl.TextRenderUtil;
+import com.jogamp.graph.curve.opengl.TextRegionUtil;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontFactory;
import com.jogamp.graph.geom.SVertex;
-import com.jogamp.opengl.math.geom.AABBox;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.glsl.ShaderState;
@@ -63,7 +63,7 @@ public abstract class TextRendererGLELBase implements GLEventListener {
protected PMVMatrix usrPMVMatrix = null;
protected RenderState rs = null;
protected RegionRenderer renderer = null;
- protected TextRenderUtil textRenderUtil = null;
+ protected TextRegionUtil textRenderUtil = null;
/** font size in pixels, default is 24 */
protected int fontSize = 24;
@@ -93,7 +93,7 @@ public abstract class TextRendererGLELBase implements GLEventListener {
public void setFlipVerticalInGLOrientation(boolean v) { flipVerticalInGLOrientation=v; }
public final RegionRenderer getRenderer() { return renderer; }
- public final TextRenderUtil getTextRenderUtil() { return textRenderUtil; }
+ public final TextRegionUtil getTextRenderUtil() { return textRenderUtil; }
@Override
public void init(GLAutoDrawable drawable) {
@@ -103,7 +103,7 @@ public abstract class TextRendererGLELBase implements GLEventListener {
this.rs = RenderState.createRenderState(new ShaderState(), SVertex.factory(), usrPMVMatrix);
}
this.renderer = RegionRenderer.create(rs, usrRenderModes);
- this.textRenderUtil = new TextRenderUtil(renderer);
+ this.textRenderUtil = new TextRegionUtil(renderer);
if( 0 == usrRenderModes ) {
texSizeScale = 0;
}
@@ -149,13 +149,12 @@ public abstract class TextRendererGLELBase implements GLEventListener {
int lastRow = -1;
- public void renderString(GLAutoDrawable drawable, String text, int column, float tx, float ty, float tz) {
+ public void renderString(GLAutoDrawable drawable, String text, int column, float tx, float ty, float tz, boolean cacheRegion) {
final int row = lastRow + 1;
- renderString(drawable, text, column, row, tx, ty, tz);
- lastRow = row;
+ renderString(drawable, text, column, row, tx, ty, tz, cacheRegion);
}
- public void renderString(GLAutoDrawable drawable, String text, int column, int row, float tx, float ty, float tz) {
+ public void renderString(GLAutoDrawable drawable, String text, int column, int row, float tx, float ty, float tz, boolean cacheRegion) {
if( null != renderer ) {
final GL2ES2 gl = drawable.getGL().getGL2ES2();
@@ -168,10 +167,10 @@ public abstract class TextRendererGLELBase implements GLEventListener {
final int height = drawable.getHeight();
dy = height-ty;
}
-
- final AABBox textBox = font.getStringBounds(text, fontSize);
+ final int newLineCount = text.length() - text.replace("\n", "").length();
+ final float lineHeight = font.getLineHeight(fontSize);
dx += pixelScale * font.getAdvanceWidth('X', fontSize) * column;
- dy -= pixelScale * (int)textBox.getHeight() * ( row + 1 );
+ dy -= pixelScale * lineHeight * ( row + 1 );
final ShaderState st = rs.getShaderState();
final PMVMatrix pmvMatrix = rs.pmvMatrix();
@@ -191,14 +190,18 @@ public abstract class TextRendererGLELBase implements GLEventListener {
pmvMatrix.glScalef(pixelScale, pixelScale, 1f);
}
renderer.updateMatrix(gl);
- textRenderUtil.drawString3D(gl, font, text, fontSize, texSize);
+ if( cacheRegion ) {
+ textRenderUtil.drawString3D(gl, font, text, fontSize, texSize);
+ } else {
+ TextRegionUtil.drawString3D(renderer, gl, font, text, fontSize, texSize);
+ }
st.useProgram(gl, false);
gl.glDisable(GL2ES2.GL_BLEND);
if( !exclusivePMVMatrix ) {
pmvMatrix.glPopMatrix();
}
- lastRow = -1;
+ lastRow = row + newLineCount;
}
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
index 3fbe5b816..2bd4f0019 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextRendererListenerBase01.java
@@ -37,7 +37,7 @@ import javax.media.opengl.GLException;
import com.jogamp.graph.curve.opengl.RenderState;
import com.jogamp.graph.curve.opengl.RegionRenderer;
-import com.jogamp.graph.curve.opengl.TextRenderUtil;
+import com.jogamp.graph.curve.opengl.TextRegionUtil;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontFactory;
import com.jogamp.newt.event.KeyEvent;
@@ -62,7 +62,7 @@ import com.jogamp.opengl.math.geom.AABBox;
* - i: live input text input (CR ends it, backspace supported)
*/
public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerBase01 {
- public final TextRenderUtil textRenderUtil;
+ public final TextRegionUtil textRenderUtil;
int fontSet = FontFactory.UBUNTU;
Font font;
@@ -103,7 +103,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
public GPUTextRendererListenerBase01(RenderState rs, int renderModes, boolean debug, boolean trace) {
super(RegionRenderer.create(rs, renderModes), renderModes, debug, trace);
- this.textRenderUtil = new TextRenderUtil(this.getRenderer());
+ this.textRenderUtil = new TextRegionUtil(this.getRenderer());
try {
this.font = FontFactory.get(fontSet).getDefault();
dumpFontNames();
@@ -165,7 +165,7 @@ public abstract class GPUTextRendererListenerBase01 extends GPURendererListenerB
final int fpsSp = fpsS.indexOf('.');
renderer.resetModelview(null);
renderer.translate(gl, fontSizeFixed, fontSizeFixed, -6000);
- textRenderUtil.drawString3D(gl, font, fpsS.substring(0, fpsSp+2)+" fps", fontSizeFixed*3, getTexSize());
+ TextRegionUtil.drawString3D(renderer, gl, font, fpsS.substring(0, fpsSp+2)+" fps", fontSizeFixed*3, getTexSize()); // no cache!
}
int dx = width-(int)fontNameBox.getWidth()-2 ;
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java
index 4ce732ef7..18e119441 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/Label.java
@@ -31,7 +31,7 @@ import javax.media.opengl.GL2ES2;
import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.curve.opengl.RegionRenderer;
-import com.jogamp.graph.curve.opengl.TextRenderUtil;
+import com.jogamp.graph.curve.opengl.TextRegionUtil;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.graph.geom.Vertex.Factory;
@@ -96,8 +96,9 @@ public abstract class Label extends UIShape implements UITextShape {
@Override
protected void createShape(RegionRenderer renderer) {
clearImpl(null, null);
- glyphRegion = TextRenderUtil.createRegion(renderer.getRenderModes(), renderer.getRenderState().getVertexFactory(),
- font, text, size);
+ glyphRegion = GLRegion.create(renderer.getRenderModes());
+ TextRegionUtil.addStringToRegion(glyphRegion, renderer.getRenderState().getVertexFactory(),
+ font, text, size);
}
@Override
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/GLReadBuffer00Base.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/GLReadBuffer00Base.java
index 43f8b89bd..910c62eae 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/GLReadBuffer00Base.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/GLReadBuffer00Base.java
@@ -72,7 +72,7 @@ public abstract class GLReadBuffer00Base extends UITestCase {
final String text = String.format("Frame %04d (%03d): %04dx%04d", frameNo, userCounter, drawable.getWidth(), drawable.getHeight());
System.err.println("TextRendererGLEL.display: "+text);
if( null != renderer ) {
- renderString(drawable, text, 0 /* col */, 0 /* row */, 0, 0, -1);
+ renderString(drawable, text, 0 /* col */, 0 /* row */, 0, 0, -1, false);
} else {
System.err.println(text);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
index b148ebabd..61c4244fb 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieCube.java
@@ -215,9 +215,7 @@ public class MovieCube implements GLEventListener {
"; underlineSize "+underlineSize+" "+(pixelScale*underlineSize)+
"; yoff "+yoff1+", yoff2 "+yoff2); */
- // FIXME: Graph TextRenderer does not scale well, i.e. text update per 1/10s cause too much recompute of regions!
- // final String text1 = String.format("%03.1f/%03.1f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %d",
- final String text1 = String.format("%03.0f/%03.0f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %d",
+ final String text1 = String.format("%03.1f/%03.1f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %d",
pts, mPlayer.getDuration() / 1000f,
mPlayer.getState().toString().toLowerCase(), mPlayer.getPlaySpeed(), mPlayer.getAudioVolume(),
aspect, mPlayer.getFramerate(), lfps, tfps, swapIntervalSet);
@@ -227,10 +225,10 @@ public class MovieCube implements GLEventListener {
mPlayer.getVID(), mPlayer.getVideoBitrate()/1000, mPlayer.getVideoCodec());
final String text4 = mPlayer.getURI().getRawPath();
if( displayOSD && null != renderer ) {
- renderString(drawable, text1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff);
- renderString(drawable, text2, 1 /* col */, 0 /* row */, -1+z_diff, yoff2, 1f+z_diff);
- renderString(drawable, text3, 1 /* col */, 1 /* row */, -1+z_diff, yoff2, 1f+z_diff);
- renderString(drawable, text4, 1 /* col */, 2 /* row */, -1+z_diff, yoff2, 1f+z_diff);
+ renderString(drawable, text1, 1 /* col */, -1 /* row */, -1+z_diff, yoff1, 1f+z_diff, false);
+ renderString(drawable, text2, 1 /* col */, 0 /* row */, -1+z_diff, yoff2, 1f+z_diff, true);
+ renderString(drawable, text3, 1 /* col */, 1 /* row */, -1+z_diff, yoff2, 1f+z_diff, true);
+ renderString(drawable, text4, 1 /* col */, 2 /* row */, -1+z_diff, yoff2, 1f+z_diff, true);
}
} };
private final InfoTextRendererGLELBase textRendererGLEL = new InfoTextRendererGLELBase();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
index 787dbab78..22fa63b37 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSimple.java
@@ -158,9 +158,7 @@ public class MovieSimple implements GLEventListener {
final float aspect = (float)mPlayer.getWidth() / (float)mPlayer.getHeight();
- // FIXME: Graph TextRenderer does not scale well, i.e. text update per 1/10s cause too much recompute of regions!
- // final String text1 = String.format("%03.1f/%03.1f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %d",
- final String text1 = String.format("%03.0f/%03.0f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %d",
+ final String text1 = String.format("%03.1f/%03.1f s, %s (%01.2fx, vol %01.2f), a %01.2f, fps %02.1f -> %02.1f / %02.1f, v-sync %d",
pts, mPlayer.getDuration() / 1000f,
mPlayer.getState().toString().toLowerCase(), mPlayer.getPlaySpeed(), mPlayer.getAudioVolume(),
aspect, mPlayer.getFramerate(), lfps, tfps, swapIntervalSet);
@@ -170,10 +168,10 @@ public class MovieSimple implements GLEventListener {
mPlayer.getVID(), mPlayer.getVideoBitrate()/1000, mPlayer.getVideoCodec());
final String text4 = mPlayer.getURI().getRawPath();
if( displayOSD && null != renderer ) {
- renderString(drawable, text1, 1 /* col */, 1 /* row */, 0, 0, -1);
- renderString(drawable, text2, 1 /* col */, -4 /* row */, 0, height, -1);
- renderString(drawable, text3, 1 /* col */, -3 /* row */, 0, height, -1);
- renderString(drawable, text4, 1 /* col */, -2 /* row */, 0, height, -1);
+ renderString(drawable, text1, 1 /* col */, 1 /* row */, 0, 0, -1, false);
+ renderString(drawable, text2, 1 /* col */, -4 /* row */, 0, height, -1, true);
+ renderString(drawable, text3, 1 /* col */, -3 /* row */, 0, height, -1, true);
+ renderString(drawable, text4, 1 /* col */, -2 /* row */, 0, height, -1, true);
}
} };
private final InfoTextRendererGLELBase textRendererGLEL = new InfoTextRendererGLELBase();