Added 1-pixeld wide to the glyphs in PFontTexture to solve some issues with bilinear filtering

This commit is contained in:
codeanticode
2011-06-14 06:24:17 +00:00
parent b83b8e94d3
commit e3a9086fbc
2 changed files with 51 additions and 26 deletions

View File

@@ -98,7 +98,10 @@ class PFontTexture implements PConstants {
resize = false;
}
PTexture tex = new PTexture(parent, w, h, new PTexture.Parameters(ARGB, BILINEAR));
PTexture.Parameters par = new PTexture.Parameters(ARGB, BILINEAR);
par.wrapU = CLAMP;
par.wrapV = CLAMP;
PTexture tex = new PTexture(parent, w, h, par);
if (textures == null) {
textures = new PTexture[1];
@@ -180,33 +183,54 @@ class PFontTexture implements PConstants {
// Adds this glyph to the opengl texture in PFont.
protected void addToTexture(int idx, PFont.Glyph glyph) {
// Converting the pixels array from the PImage into a valid RGBA array for OpenGL.
int[] rgba = new int[glyph.width * glyph.height];
protected void addToTexture(int idx, PFont.Glyph glyph) {
// We add one pixel to avoid issues when sampling the font texture at fractional
// screen positions. I.e.: the pixel on the screen only contains half of the
// font rectangle, so it would sample half of the color from the glyph
// area in the texture, and the other half from the contiguous pixel. If the
// later contains a portion of the neighbor glyph and former doesn't, this
// would result in a shaded pixel when the correct output is blank.
// This is a consequence of putting all the glyphs in a common texture with
// bilinear sampling.
int w = 1 + glyph.width + 1;
int h = 1 + glyph.height + 1;
// Converting the pixels array from the PImage into a valid RGBA array for OpenGL.
int[] rgba = new int[w * h];
int t = 0;
int p = 0;
if (PGraphicsOpenGL2.BIG_ENDIAN) {
if (PGraphicsOpenGL2.BIG_ENDIAN) {
java.util.Arrays.fill(rgba, 0, w, 0xFFFFFF00); // Set the first row to blank pixels.
t = w;
for (int y = 0; y < glyph.height; y++) {
rgba[t++] = 0xFFFFFF00; // Set the leftmost pixel in this row as blank
for (int x = 0; x < glyph.width; x++) {
rgba[t++] = 0xFFFFFF00 | glyph.image.pixels[p++];
}
}
rgba[t++] = 0xFFFFFF00; // Set the rightmost pixel in this row as blank
}
java.util.Arrays.fill(rgba, (h - 1) * w, h * w, 0xFFFFFF00); // Set the last row to blank pixels.
} else {
java.util.Arrays.fill(rgba, 0, w, 0x00FFFFFF); // Set the first row to blank pixels.
t = w;
for (int y = 0; y < glyph.height; y++) {
rgba[t++] = 0x00FFFFFF; // Set the leftmost pixel in this row as blank
for (int x = 0; x < glyph.width; x++) {
rgba[t++] = (glyph.image.pixels[p++] << 24) | 0x00FFFFFF;
}
rgba[t++] = 0x00FFFFFF; // Set the rightmost pixel in this row as blank
}
java.util.Arrays.fill(rgba, (h - 1) * w, h * w, 0x00FFFFFF); // Set the last row to blank pixels.
}
// Is there room for this glyph in the current line?
if (offsetX + glyph.width> textures[currentTex].glWidth) {
if (offsetX + w > textures[currentTex].glWidth) {
// No room, go to the next line:
offsetX = 0;
offsetY += lineHeight;
lineHeight = 0;
}
lineHeight = Math.max(lineHeight, glyph.height);
lineHeight = Math.max(lineHeight, h);
boolean resized = false;
if (offsetY + lineHeight > textures[currentTex].glHeight) {
@@ -237,10 +261,10 @@ class PFontTexture implements PConstants {
setTexture(lastTex);
}
textures[currentTex].setTexels(offsetX, offsetY, glyph.width, glyph.height, rgba);
textures[currentTex].setTexels(offsetX, offsetY, w, h, rgba);
TextureInfo tinfo = new TextureInfo(currentTex, offsetX, offsetY, glyph.width, glyph.height);
offsetX += glyph.width;
TextureInfo tinfo = new TextureInfo(currentTex, offsetX, offsetY, w, h);
offsetX += w;
if (idx == glyphTexinfos.length) {
TextureInfo[] temp = new TextureInfo[glyphTexinfos.length + 1];
@@ -262,18 +286,16 @@ class PFontTexture implements PConstants {
public float v0, v1;
public TextureInfo(int tidx, int cropX, int cropY, int cropW, int cropH) {
texIndex = tidx;
width = textures[tidx].glWidth;
height = textures[tidx].glHeight;
texIndex = tidx;
crop = new int[4];
crop[0] = cropX;
crop[1] = cropY + cropH;
crop[2] = cropW;
crop[3] = -cropH;
u0 = (float)cropX / (float)width;
u1 = u0 + (float)cropW / (float)width;
v0 = (float)cropY / (float)height;
v1 = v0 + (float)cropH / (float)height;
// The region of the texture corresponding to the glyph is surrounded by a
// 1-pixel wide border to avoid artifacts due to bilinear sampling. This is
// why the additions and subtractions to the crop values.
crop[0] = cropX + 1;
crop[1] = cropY + 1 + cropH - 2;
crop[2] = cropW - 2;
crop[3] = -cropH + 2;
updateUV();
}
void updateUV() {

View File

@@ -1294,6 +1294,7 @@ public class PGraphicsOpenGL2 extends PGraphics {
if (opengl2X) {
if (primarySurface) {
releaseContext();
// TODO: we need to recreate resources here...?
context.destroy();
context = null;
allocate();
@@ -1310,6 +1311,7 @@ public class PGraphicsOpenGL2 extends PGraphics {
if (!opengl4X) {
if (primarySurface) {
releaseContext();
// TODO: we need to recreate resources here...?
context.destroy();
context = null;
allocate();
@@ -3403,7 +3405,7 @@ public class PGraphicsOpenGL2 extends PGraphics {
// protected void textLineAlignImpl(char buffer[], int start, int stop,
// float x, float y)
/**
* Implementation of actual drawing for a line of text.
*/
@@ -3474,7 +3476,7 @@ public class PGraphicsOpenGL2 extends PGraphics {
tinfo = textTex.addToTexture(glyph);
}
if (textMode == MODEL) {
if (textMode == MODEL) {
float high = glyph.height / (float) textFont.getSize();
float bwidth = glyph.width / (float) textFont.getSize();
float lextent = glyph.leftExtent / (float) textFont.getSize();
@@ -3486,7 +3488,6 @@ public class PGraphicsOpenGL2 extends PGraphics {
float y2 = y1 + high * textSize;
textCharModelImpl(tinfo, x1, y1, x2, y2);
} else if (textMode == SCREEN) {
int xx = (int) x + glyph.leftExtent;
int yy = (int) y - glyph.topExtent;
@@ -6773,7 +6774,9 @@ public class PGraphicsOpenGL2 extends PGraphics {
} else if (hints[ENABLE_OPENGL_4X_SMOOTH]) {
capabilities.setSampleBuffers(true);
capabilities.setNumSamples(4);
}
} else {
capabilities.setSampleBuffers(false);
}
// Getting the native window:
// http://www.java-gaming.org/index.php/topic,21559.0.html