From 02b5c756ff10c088a9418ee9727cdbf13b9cc085 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Sun, 30 May 2010 15:06:21 +0000 Subject: [PATCH] Support for fonts that require more than one opengl texture --- android/core/src/processing/core/PFont.java | 171 +++++++----------- .../processing/core/PGraphicsAndroid3D.java | 17 +- 2 files changed, 69 insertions(+), 119 deletions(-) diff --git a/android/core/src/processing/core/PFont.java b/android/core/src/processing/core/PFont.java index d2450bbaf..76cef6857 100644 --- a/android/core/src/processing/core/PFont.java +++ b/android/core/src/processing/core/PFont.java @@ -139,30 +139,19 @@ public class PFont implements PConstants { Paint lazyPaint; // FontMetrics lazyMetrics; int[] lazySamples; - - - // OpenGL-based texturing + /** + * Required for OpenGL-based font rendering. + */ + protected GL10 gl10; protected int texWidth; protected int texHeight; protected int offsetX; protected int offsetY; protected int lineHeight; - protected int mTextureID = -1; - protected int currentID = -1; - - - /* - protected int offsetU; - protected int offsetV; - protected int texU; - protected int texV; - protected int texLineHeight; - protected Bitmap mBitmap; - protected Canvas mCanvas; -//protected Paint mClearPaint; - */ - + protected int[] texIDList = null; + protected int currentTexID = -1; + protected int lastTexID = -1; public PFont() { } // for subclasses @@ -334,7 +323,14 @@ public class PFont implements PConstants { } } - + protected void finalize() { + if (gl10 != null && texIDList != null) { + gl10.glDeleteTextures(texIDList.length, texIDList, 0); + texIDList = null; + } + } + + /** * Write this PFont to an OutputStream. *

@@ -677,6 +673,7 @@ public class PFont implements PConstants { // OPENGL stuff public void initialize(GL10 gl, int w, int h) { + gl10 = gl; texWidth = w; texHeight = h; @@ -685,35 +682,12 @@ public class PFont implements PConstants { offsetX = 0; offsetY = 0; lineHeight = 0; - - -/* - texU = 0; - texV = 0; - texLineHeight = 0; - - - - mBitmap = Bitmap.createBitmap(texWidth, texHeight, Config.ARGB_8888); - mCanvas =new Canvas(mBitmap); - */ - - /* - // We do the initialization of the bitmap and canvas so we can call beginAdding/endAdding - // multiple times without deleting previously added labels. - Bitmap.Config config = mFullColor ? - Bitmap.Config.ARGB_4444 : Bitmap.Config.ALPHA_8; - mBitmap = Bitmap.createBitmap(mStrikeWidth, mStrikeHeight, config); - mCanvas = new Canvas(mBitmap); - mBitmap.eraseColor(0); - */ } public void addTexture(GL10 gl) { int[] textures = new int[1]; gl.glGenTextures(1, textures, 0); - mTextureID = textures[0]; - gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID); + gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); // Use Nearest for performance. gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); @@ -723,52 +697,27 @@ public class PFont implements PConstants { gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE); - - currentID = mTextureID; - } - -/* - // Who calls this one... ? The finalize method of the class? - public void shutdown(GL10 gl) { - - // Reclaim storage used by bitmap and canvas. - mBitmap.recycle(); - mBitmap = null; - mCanvas = null; - - - if ( gl != null) { - if (mState > STATE_NEW) { - int[] textures = new int[1]; - textures[0] = mTextureID; - gl.glDeleteTextures(1, textures, 0); - mState = STATE_NEW; - } - } + + if (texIDList == null) { + texIDList = new int[1]; + texIDList[0] = textures[0]; + } else { + int[] tmp = texIDList; + texIDList = new int[texIDList.length + 1]; + PApplet.arrayCopy(tmp, texIDList, tmp.length); + texIDList[tmp.length] = textures[0]; } - */ + currentTexID = textures[0]; + } - // Add all the current glyphs to texure. - public void addToTexture(GL10 gl) { + // Add all the current glyphs to opengl texture. + public void addAllGlyphsToTexture(GL10 gl) { // loop over current glyphs. for (int i = 0; i < glyphCount; i++) { - beginAddToTexture(gl); glyphs[i].addToTexture(gl); - endAddToTexture(gl); } } - - public void beginAddToTexture(GL10 gl) { - // Nothing to do here... - } - - public void endAddToTexture(GL10 gl) { - // Copy bitmap to (current) texture): - //gl.glBindTexture(GL10.GL_TEXTURE_2D, currentID); - //GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0); - //GLUtils.texSubImage2D(GL10.GL_TEXTURE_2D, 0, offsetU, offsetV, lazyBitmap); - } - + ///////////////////////////////////////////////////////////// /** @@ -935,25 +884,7 @@ public class PFont implements PConstants { } // Adds this glyph to the opengl texture in PFont. - protected void addToTexture(GL10 gl) { - // Is there room for this glyph on the current line? - if (offsetX + width> texWidth) { - // No room, go to the next line: - offsetX = 0; - offsetY += lineHeight; - lineHeight = 0; - } - lineHeight = Math.max(lineHeight, height); - if (offsetY + lineHeight > texHeight) { - // We run out of space in the current texture, we add a new texture: - addTexture(gl); - - // Reseting texture coordinates and line. - offsetX = 0; - offsetY = 0; - lineHeight = 0; - } - + protected void addToTexture(GL10 gl) { // Converting the pixels array from the PImage into a valid RGBA array for OpenGL. int[] rgba = new int[width * height]; int t = 0; @@ -973,9 +904,36 @@ public class PFont implements PConstants { } } } + + // Is there room for this glyph on the current line? + if (offsetX + width> texWidth) { + // No room, go to the next line: + offsetX = 0; + offsetY += lineHeight; + lineHeight = 0; + } + lineHeight = Math.max(lineHeight, height); + if (offsetY + lineHeight > texHeight) { + // We run out of space in the current texture, we add a new texture: + addTexture(gl); + + // Reseting texture coordinates and line. + offsetX = 0; + offsetY = 0; + lineHeight = 0; + lastTexID = currentTexID; + } + + if (lastTexID == -1) { + lastTexID = texIDList[0]; + } + gl.glEnable(GL10.GL_TEXTURE_2D); + gl.glBindTexture(GL10.GL_TEXTURE_2D, lastTexID); + currentTexID = lastTexID; + gl.glTexSubImage2D(GL10.GL_TEXTURE_2D, 0, offsetX, offsetY, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, IntBuffer.wrap(rgba)); - texture = new TextureInfo(currentID, offsetX, offsetY, width, height); + texture = new TextureInfo(currentTexID, offsetX, offsetY, width, height); offsetX += width; @@ -1044,12 +1002,8 @@ public class PFont implements PConstants { } public class TextureInfo { - public TextureInfo(int glid, /*, float width, float height, float baseLine,*/ - int cropX, int cropY, int cropW, int cropH) { + public TextureInfo(int glid, int cropX, int cropY, int cropW, int cropH) { this.glid = glid; -// this.width = width; -// this.height = height; -// this.baseline = baseLine; crop = new int[4]; crop[0] = cropX; crop[1] = cropY; @@ -1058,9 +1012,6 @@ public class PFont implements PConstants { } public int glid; - //public float width; - //public float height; - //public float baseline; public int[] crop; } } diff --git a/android/core/src/processing/core/PGraphicsAndroid3D.java b/android/core/src/processing/core/PGraphicsAndroid3D.java index 18355afaf..cde51392c 100644 --- a/android/core/src/processing/core/PGraphicsAndroid3D.java +++ b/android/core/src/processing/core/PGraphicsAndroid3D.java @@ -2259,17 +2259,17 @@ public class PGraphicsAndroid3D extends PGraphics { protected void textLineImpl(char buffer[], int start, int stop, float x, float y) { - if (textFont.mTextureID == -1) { + if (textFont.texIDList == null) { textFont.initialize(gl, maxTextureSize, maxTextureSize); - // add the current fonts to texture. - textFont.addToTexture(gl); + // Add all the current glyphs to the texture. + textFont.addAllGlyphsToTexture(gl); } // Init opengl state for text rendering... - textFontTexID = textFont.currentID; - gl.glBindTexture(GL10.GL_TEXTURE_2D, textFontTexID); + textFontTexID = textFont.currentTexID; gl.glEnable(GL10.GL_TEXTURE_2D); + gl.glBindTexture(GL10.GL_TEXTURE_2D, textFontTexID); //gl.glShadeModel(GL10.GL_FLAT); // Should be restored to default shade model after text rendering. //gl.glEnable(GL10.GL_BLEND); @@ -2306,11 +2306,8 @@ public class PGraphicsAndroid3D extends PGraphics { PFont.Glyph glyph = textFont.getGlyph(ch); if (glyph.texture == null) { - // Adding new glyph to texture. - textFont.beginAddToTexture(gl); // we need this becuause new glyps can be added during text rendering... - // but it is ok with the texture binded. probably yes. + // Adding new glyph to the font texture. glyph.addToTexture(gl); - textFont.endAddToTexture(gl); } if (glyph != null) { @@ -2350,6 +2347,7 @@ public class PGraphicsAndroid3D extends PGraphics { if (textFontTexID != tex.glid) { textFontTexID = tex.glid; gl.glBindTexture(GL10.GL_TEXTURE_2D, textFontTexID); + textFont.currentTexID = textFontTexID; } //gl.glPushMatrix(); @@ -2389,6 +2387,7 @@ public class PGraphicsAndroid3D extends PGraphics { if (textFontTexID != tex.glid) { textFontTexID = tex.glid; gl.glBindTexture(GL10.GL_TEXTURE_2D, textFontTexID); + textFont.currentTexID = textFontTexID; } //gl.glPushMatrix();