Hi
So I am fixing up some font rendering code (and improving upon it). The font sheet is created/shown perfectly, but when the regions for each character are checked when rendering individual characters, everything is offset. Just to prevent this, I know I’m “rolling out my own” but it almost works perfectly like it should.
Code:
package game.util;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import static org.lwjgl.opengl.GL11.*;
public class GLFont {
public static HashMap<Float, Texture> textures = new HashMap<Float, Texture>();
private Font font;
private float fontsize;
private IntObject[] objects = new IntObject[256];
private FontMetrics metrics;
private Texture fontTexture;
private BufferedImage image;
private int fontHeight = 0;
public static class IntObject {
public int x, y, width, height;
public void debug(){
System.out.println("IntObject[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]");
}
}
public GLFont(Font _font, float fontsize){
this.fontsize = fontsize;
font = _font.deriveFont(fontsize);
if(textures.get(fontsize) != null){
fontTexture = textures.get(fontsize);
} else {
createTexture();
textures.put(fontsize, fontTexture);
}
}
private float textureWidth = 512, textureHeight = 512;
public void drawText(float x, float y, String text, Color color){
glColor3f(color.getRed() / 255.0f, color.getGreen() / 255.0f, color.getBlue() / 255.0f);
fontTexture.bind();
float drawX = x;
float drawY = y;
glBegin(GL_QUADS);
for(char letter : text.toCharArray()){
IntObject intObject = objects[(int)letter];
intObject.debug();
float drawX2 = drawX + intObject.width;
float drawY2 = drawY + intObject.height;
float srcX = intObject.x; //
float srcY = intObject.y; //
float srcX2 = srcX + intObject.width;
float srcY2 = srcY + intObject.height;
float DrawWidth = drawX2 - drawX;
float DrawHeight = drawY2 - drawY;
float TextureSrcX = srcX / textureWidth; //
float TextureSrcY = srcY / textureHeight; //
float SrcWidth = srcX2 - srcX;
float SrcHeight = srcY2 - srcY;
float RenderWidth = (SrcWidth / textureWidth);
float RenderHeight = (SrcHeight / textureHeight);
// Shift the render row.
TextureSrcY -= RenderHeight;
TextureSrcY += (5.0f / 512.0f);
// Draw the letter
glTexCoord2f(TextureSrcX, TextureSrcY);
glVertex2f(drawX, drawY);
glTexCoord2f(TextureSrcX, TextureSrcY + RenderHeight);
glVertex2f(drawX, drawY + DrawHeight);
glTexCoord2f(TextureSrcX + RenderWidth, TextureSrcY + RenderHeight);
glVertex2f(drawX + DrawWidth, drawY + DrawHeight);
glTexCoord2f(TextureSrcX + RenderWidth, TextureSrcY);
glVertex2f(drawX + DrawWidth, drawY);
drawX += intObject.width;
}
glEnd();
glColor3f(1.0f, 1.0f, 1.0f);
}
public void debug(){
fontTexture.bind();
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(100, 100);
glTexCoord2f(1, 0);
glVertex2f(612, 100);
glTexCoord2f(1, 1);
glVertex2f(612, 612);
glTexCoord2f(0, 1);
glVertex2f(100, 612);
glEnd();
}
public void createTexture(){
image = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB);
BufferedImage scratch = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = scratch.createGraphics();
// get the dimensions
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.setFont(font);
metrics = graphics.getFontMetrics();
// prepare the graphics
Graphics2D realGraphics = image.createGraphics();
realGraphics.setColor(new Color(255, 255, 255, 0));
realGraphics.drawRect(0, 0, 512, 512);
realGraphics.setColor(new Color(255, 255, 255));
realGraphics.setFont(font);
// real work
int rowHeight = 0;
int positionX = 0;
int positionY = 0;
for(int index = 0; index < 256; index++){
char letter = (char) index;
int charwidth = metrics.charWidth(letter);
if (charwidth <= 0) {
charwidth = 1;
}
int charheight = metrics.getHeight();
if (charheight <= 0) {
charheight = Math.round(fontsize);
}
IntObject intObject = new IntObject();
intObject.width = charwidth;
intObject.height = charheight;
if (positionX + intObject.width >= 512) {
positionX = 0;
positionY += rowHeight;
rowHeight = 0;
}
intObject.x = positionX;
intObject.y = positionY;
if(intObject.height > fontHeight){
fontHeight = intObject.height;
}
if(intObject.height > rowHeight){
rowHeight = intObject.height;
}
realGraphics.drawString(String.valueOf(letter), positionX, positionY);
positionX += intObject.width;
objects[index] = intObject;
}
fontTexture = new Texture(image);
}
}
Any assistance in fixing the character regions would be appreciated
CopyableCougar4