Hello Guest

Complete TrueTypeFont class that only requires LWJGL

  • 27 Replies
  • 65970 Views
*

Offline bobjob

  • ****
  • 394
  • LWJGL: WOW SO GOOD
Complete TrueTypeFont class that only requires LWJGL
« on: June 28, 2009, 00:54:50 »
I went through the slick implentation for TrueTypeFonts
and made some changes:
* does not require the slick package
* added scaling as well as its artifact correction
* removed dependency on blending
* alignment (added: right and center)
* takes into account the newline character: '\n'
* now works with BACK face CULLING on, if used in 3D.

Code: [Select]
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.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
import java.awt.GraphicsEnvironment;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;


/**
 * A TrueType font implementation originally for Slick, edited for Bobjob's Engine
 *
 * @original author James Chambers (Jimmy)
 * @original author Jeremy Adams (elias4444)
 * @original author Kevin Glass (kevglass)
 * @original author Peter Korzuszek (genail)
 *
 * @new version edited by David Aaron Muhar (bobjob)
 */
public class TrueTypeFont {
public final static int
ALIGN_LEFT = 0,
ALIGN_RIGHT = 1,
ALIGN_CENTER = 2;
/** Array that holds necessary information about the font characters */
private IntObject[] charArray = new IntObject[256];

/** Map of user defined font characters (Character <-> IntObject) */
private Map customChars = new HashMap();

/** Boolean flag on whether AntiAliasing is enabled or not */
private boolean antiAlias;

/** Font's size */
private int fontSize = 0;

/** Font's height */
private int fontHeight = 0;

/** Texture used to cache the font 0-255 characters */
private int fontTextureID;

/** Default font texture width */
private int textureWidth = 512;

/** Default font texture height */
private int textureHeight = 512;

/** A reference to Java's AWT Font that we create our font texture from */
private Font font;

/** The font metrics for our Java AWT font */
private FontMetrics fontMetrics;


private int correctL = 9, correctR = 8;

private class IntObject {
/** Character's width */
public int width;

/** Character's height */
public int height;

/** Character's stored x position */
public int storedX;

/** Character's stored y position */
public int storedY;
}


public TrueTypeFont(Font font, boolean antiAlias, char[] additionalChars) {
this.font = font;
this.fontSize = font.getSize()+3;
this.antiAlias = antiAlias;

createSet( additionalChars );

fontHeight -= 1;
if (fontHeight <= 0) fontHeight = 1;
}

public TrueTypeFont(Font font, boolean antiAlias) {
this( font, antiAlias, null );
}
public void setCorrection(boolean on) {
if (on) {
correctL = 2;
correctR = 1;
} else {
correctL = 0;
correctR = 0;
}
}
private BufferedImage getFontImage(char ch) {
// Create a temporary image to extract the character's size
BufferedImage tempfontImage = new BufferedImage(1, 1,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) tempfontImage.getGraphics();
if (antiAlias == true) {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
g.setFont(font);
fontMetrics = g.getFontMetrics();
int charwidth = fontMetrics.charWidth(ch)+8;

if (charwidth <= 0) {
charwidth = 7;
}
int charheight = fontMetrics.getHeight()+3;
if (charheight <= 0) {
charheight = fontSize;
}

// Create another image holding the character we are creating
BufferedImage fontImage;
fontImage = new BufferedImage(charwidth, charheight,
BufferedImage.TYPE_INT_ARGB);
Graphics2D gt = (Graphics2D) fontImage.getGraphics();
if (antiAlias == true) {
gt.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
gt.setFont(font);

gt.setColor(Color.WHITE);
int charx = 3;
int chary = 1;
gt.drawString(String.valueOf(ch), (charx), (chary)
+ fontMetrics.getAscent());

return fontImage;

}

private void createSet( char[] customCharsArray ) {
// If there are custom chars then I expand the font texture twice
if (customCharsArray != null && customCharsArray.length > 0) {
textureWidth *= 2;
}

// In any case this should be done in other way. Texture with size 512x512
// can maintain only 256 characters with resolution of 32x32. The texture
// size should be calculated dynamicaly by looking at character sizes.

try {

BufferedImage imgTemp = new BufferedImage(textureWidth, textureHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) imgTemp.getGraphics();

g.setColor(new Color(0,0,0,1));
g.fillRect(0,0,textureWidth,textureHeight);

int rowHeight = 0;
int positionX = 0;
int positionY = 0;

int customCharsLength = ( customCharsArray != null ) ? customCharsArray.length : 0;

for (int i = 0; i < 256 + customCharsLength; i++) {

// get 0-255 characters and then custom characters
char ch = ( i < 256 ) ? (char) i : customCharsArray[i-256];

BufferedImage fontImage = getFontImage(ch);

IntObject newIntObject = new IntObject();

newIntObject.width = fontImage.getWidth();
newIntObject.height = fontImage.getHeight();

if (positionX + newIntObject.width >= textureWidth) {
positionX = 0;
positionY += rowHeight;
rowHeight = 0;
}

newIntObject.storedX = positionX;
newIntObject.storedY = positionY;

if (newIntObject.height > fontHeight) {
fontHeight = newIntObject.height;
}

if (newIntObject.height > rowHeight) {
rowHeight = newIntObject.height;
}

// Draw it here
g.drawImage(fontImage, positionX, positionY, null);

positionX += newIntObject.width;

if( i < 256 ) { // standard characters
charArray[i] = newIntObject;
} else { // custom characters
customChars.put( new Character( ch ), newIntObject );
}

fontImage = null;
}

fontTextureID = loadImage(imgTemp);



//.getTexture(font.toString(), imgTemp);

} catch (Exception e) {
System.err.println("Failed to create font.");
e.printStackTrace();
}
}

private void drawQuad(float drawX, float drawY, float drawX2, float drawY2,
float srcX, float srcY, float srcX2, float srcY2) {
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);

GL11.glTexCoord2f(TextureSrcX, TextureSrcY);
GL11.glVertex2f(drawX, drawY);
GL11.glTexCoord2f(TextureSrcX, TextureSrcY + RenderHeight);
GL11.glVertex2f(drawX, drawY + DrawHeight);
GL11.glTexCoord2f(TextureSrcX + RenderWidth, TextureSrcY + RenderHeight);
GL11.glVertex2f(drawX + DrawWidth, drawY + DrawHeight);
GL11.glTexCoord2f(TextureSrcX + RenderWidth, TextureSrcY);
GL11.glVertex2f(drawX + DrawWidth, drawY);
}

public int getWidth(String whatchars) {
int totalwidth = 0;
IntObject intObject = null;
int currentChar = 0;
for (int i = 0; i < whatchars.length(); i++) {
currentChar = whatchars.charAt(i);
if (currentChar < 256) {
intObject = charArray[currentChar];
} else {
intObject = (IntObject)customChars.get( new Character( (char) currentChar ) );
}

if( intObject != null )
totalwidth += intObject.width;
}
return totalwidth;
}

public int getHeight() {
return fontHeight;
}


public int getHeight(String HeightString) {
return fontHeight;
}

public int getLineHeight() {
return fontHeight;
}

public void drawString(float x, float y,
String whatchars, float scaleX, float scaleY) {
drawString(x,y,whatchars, 0, whatchars.length()-1, scaleX, scaleY, ALIGN_LEFT);
}
public void drawString(float x, float y,
String whatchars, float scaleX, float scaleY, int format) {
drawString(x,y,whatchars, 0, whatchars.length()-1, scaleX, scaleY, format);
}


public void drawString(float x, float y,
String whatchars, int startIndex, int endIndex,
float scaleX, float scaleY,
int format
) {

IntObject intObject = null;
int charCurrent;


int totalwidth = 0;
int i = startIndex, d, c;
float startY = 0;



switch (format) {
case ALIGN_RIGHT: {
d = -1;
c = correctR;

while (i < endIndex) {
if (whatchars.charAt(i) == '\n') startY -= fontHeight;
i++;
}
break;
}
case ALIGN_CENTER: {
for (int l = startIndex; l <= endIndex; l++) {
charCurrent = whatchars.charAt(l);
if (charCurrent == '\n') break;
if (charCurrent < 256) {
intObject = charArray[charCurrent];
} else {
intObject = (IntObject)customChars.get( new Character( (char) charCurrent ) );
}
totalwidth += intObject.width-correctL;
}
totalwidth /= -2;
}
case ALIGN_LEFT:
default: {
d = 1;
c = correctL;
break;
}

}

GL11.glBindTexture(GL11.GL_TEXTURE_2D, fontTextureID);
GL11.glBegin(GL11.GL_QUADS);

while (i >= startIndex && i <= endIndex) {

charCurrent = whatchars.charAt(i);
if (charCurrent < 256) {
intObject = charArray[charCurrent];
} else {
intObject = (IntObject)customChars.get( new Character( (char) charCurrent ) );
}

if( intObject != null ) {
if (d < 0) totalwidth += (intObject.width-c) * d;
if (charCurrent == '\n') {
startY -= fontHeight * d;
totalwidth = 0;
if (format == ALIGN_CENTER) {
for (int l = i+1; l <= endIndex; l++) {
charCurrent = whatchars.charAt(l);
if (charCurrent == '\n') break;
if (charCurrent < 256) {
intObject = charArray[charCurrent];
} else {
intObject = (IntObject)customChars.get( new Character( (char) charCurrent ) );
}
totalwidth += intObject.width-correctL;
}
totalwidth /= -2;
}
//if center get next lines total width/2;
}
else {
drawQuad((totalwidth + intObject.width) * scaleX + x, startY * scaleY + y,
totalwidth * scaleX + x,
(startY + intObject.height) * scaleY + y, intObject.storedX + intObject.width,
intObject.storedY + intObject.height,intObject.storedX,
intObject.storedY);
if (d > 0) totalwidth += (intObject.width-c) * d ;
}
i += d;

}
}
GL11.glEnd();
}
public static int loadImage(BufferedImage bufferedImage) {
    try {
    short width       = (short)bufferedImage.getWidth();
    short height      = (short)bufferedImage.getHeight();
    //textureLoader.bpp = bufferedImage.getColorModel().hasAlpha() ? (byte)32 : (byte)24;
    int bpp = (byte)bufferedImage.getColorModel().getPixelSize();
    ByteBuffer byteBuffer;
    DataBuffer db = bufferedImage.getData().getDataBuffer();
    if (db instanceof DataBufferInt) {
    int intI[] = ((DataBufferInt)(bufferedImage.getData().getDataBuffer())).getData();
    byte newI[] = new byte[intI.length * 4];
    for (int i = 0; i < intI.length; i++) {
    byte b[] = intToByteArray(intI[i]);
    int newIndex = i*4;
   
    newI[newIndex]   = b[1];
    newI[newIndex+1] = b[2];
    newI[newIndex+2] = b[3];
    newI[newIndex+3] = b[0];
    }
   
    byteBuffer  = ByteBuffer.allocateDirect(
    width*height*(bpp/8))
                           .order(ByteOrder.nativeOrder())
                            .put(newI);
    } else {
    byteBuffer  = ByteBuffer.allocateDirect(
    width*height*(bpp/8))
                           .order(ByteOrder.nativeOrder())
                            .put(((DataBufferByte)(bufferedImage.getData().getDataBuffer())).getData());
    }
    byteBuffer.flip();
   
   
    int internalFormat = GL11.GL_RGBA8,
format = GL11.GL_RGBA;
IntBuffer   textureId =  BufferUtils.createIntBuffer(1);;
GL11.glGenTextures(textureId);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId.get(0));


GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);

GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);

GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);



GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D,
      internalFormat,
      width,
      height,
      format,
      GL11.GL_UNSIGNED_BYTE,
      byteBuffer);
return textureId.get(0);
   
} catch (Exception e) {
    e.printStackTrace();
    System.exit(-1);
    }

return -1;
}
public static boolean isSupported(String fontname) {
Font font[] = getFonts();
for (int i = font.length-1; i >= 0; i--) {
if (font[i].getName().equalsIgnoreCase(fontname))
return true;
}
return false;
}
public static Font[] getFonts() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
}
public static byte[] intToByteArray(int value) {
        return new byte[] {
                (byte)(value >>> 24),
                (byte)(value >>> 16),
                (byte)(value >>> 8),
                (byte)value};
}

public void destroy() {
IntBuffer scratch = BufferUtils.createIntBuffer(1);
scratch.put(0, fontTextureID);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GL11.glDeleteTextures(scratch);
}
}
« Last Edit: July 10, 2009, 10:34:10 by bobjob »

*

Offline bobjob

  • ****
  • 394
  • LWJGL: WOW SO GOOD
Re: Complete TrueTypeFont class that only required LWJGL
« Reply #1 on: June 28, 2009, 00:55:49 »
Test case
Code: [Select]
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;


import java.awt.Font;

public class TTFTest {
public static int width = 800, height = 600;
protected static final String TITLE = "Template v1";
static boolean running = true;
final public static int FRAME_RATE = 60;
static FPSCounter fpsCounter;
public static void main(String args[]) {
new TTFTest();
}
public TTFTest() {
try {
initDisplay(false);
initGL();
loadResources();
run();
cleanup();
} catch (Exception e) {
e.printStackTrace();
Sys.alert(TITLE, "Error 101: " + e.toString());
}
}
private static void initDisplay(boolean fullscreen) throws Exception {

Display.setTitle(TITLE); // sets aplication name
Display.setFullscreen(fullscreen);  // create a full screen window if possible

        DisplayMode displayMode = null;
        DisplayMode d[] = Display.getAvailableDisplayModes();
        for (int i = d.length - 1; i >= 0; i--) {
            displayMode = d[i];
            if (d[i].getWidth() == width
                && d[i].getHeight() == height
                && (d[i].getBitsPerPixel() >= 24 &&  d[i].getBitsPerPixel() <= 24 + 8 )
                && d[i].getFrequency() == FRAME_RATE) {
                break;
            }
        } // Finds a suitable resolution
        Display.setDisplayMode(displayMode); // sets display resoulation
        if (fullscreen) Display.setVSyncEnabled(true); // enable vsync if poosible
Display.create();
}
public static void initGL() {

       
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
        GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping
        GL11.glClearColor(0.5f,0.5f,0.5f,0f); // Black Background
        GL11.glDisable(GL11.GL_DITHER);
        GL11.glDepthFunc(GL11.GL_LESS); // Depth function less or equal
        GL11.glEnable(GL11.GL_NORMALIZE); // calculated normals when scaling
        GL11.glEnable(GL11.GL_CULL_FACE); // prevent render of back surface   
        GL11.glEnable(GL11.GL_BLEND); // Enabled blending
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); // selects blending method
        GL11.glEnable(GL11.GL_ALPHA_TEST); // allows alpha channels or transperancy
        GL11.glAlphaFunc(GL11.GL_GREATER, 0.1f); // sets aplha function
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST); // High quality visuals
        GL11.glHint(GL11.GL_POLYGON_SMOOTH_HINT, GL11.GL_NICEST); //  Really Nice Perspective Calculations
        GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading
GL11.glViewport(0, 0, 800, 600);
        GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
        GL11.glLoadIdentity(); // Reset The Projection Matrix
        GLU.gluPerspective(30, width/(float)height, 1f, 300f);  //Aspect Ratio Of The Window
        GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix
        GL11.glDepthMask(true); // Enable Depth Mask
}
static TrueTypeFont trueTypeFont;
private static void loadResources() {
Keyboard.enableRepeatEvents(false);
// initialise the font
String fontName = "Agent Orange";
if (!TrueTypeFont.isSupported(fontName)) fontName = "serif";
Font font = new Font(fontName, Font.ITALIC | Font.BOLD, 40);
trueTypeFont = new TrueTypeFont(font, true);
fpsCounter = new FPSCounter();
fpsCounter.init();
// render some text to the screen
//trueTypeFont.drawString(20.0f, 20.0f, "Slick displaying True Type Fonts", Color.green);

}

public static void run() {
while (running) {
if (Display.isCloseRequested()) running = false;

// Display.sync(FRAME_RATE);
logic();
if (Display.isActive() && Display.isVisible()){
render();
Display.update();
} else {
Display.update();
}
}
}
    static String lastFPS;
public static void logic() {
if (fpsCounter != null) {
if (fpsCounter.update()) lastFPS = "FPS " + fpsCounter.getFPS();
Display.setTitle(lastFPS);
}
int x = Mouse.getX();
int y = Mouse.getY();


while (Mouse.next()) {
if (Mouse.getEventButtonState()) {
int mouse = Mouse.getEventButton();
switch (mouse) {
case 0: {
System.out.println("" + x + " " + y);

break;
}
case 1: {
System.out.println("" + x + " " + y);

break;
}
case 2: {
break;
}
}
}
}

while (Keyboard.next()) {
if (Keyboard.getEventKeyState()) {
int key =  Keyboard.getEventKey();

switch (key) {
case Keyboard.KEY_SPACE: {

break;
}
case Keyboard.KEY_RETURN: {

break;
}
}
}
}


}


public static void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT |GL11.GL_DEPTH_BUFFER_BIT);     // Clear Screen And Depth Buffer
//3D Render Code


//2D Render Code
set2DMode(0, width, 0, height);




//DRAW STRING FROM THE - DEFAULT
//SCALE OF 1.5
trueTypeFont.drawString(0, trueTypeFont.getHeight()*10, "I wrote this song about you!\nIsn't that cliche of me, to do?", 1.5f,1.5f
);

//DRAW STRING FROM THE - RIGHT
//DEFAULT SCALE OF 1
trueTypeFont.drawString(width, trueTypeFont.getHeight()*6, "But its nothing for you,\n" +
"the band just needed something more to play.\n" +
"So dont blush or hooray,\n"
, 1f, 1f, TrueTypeFont.ALIGN_RIGHT);

//DRAW STRING FROM THE - CENTER
//HALF SCALE OF 0.5f
trueTypeFont.drawString(width/2, trueTypeFont.getHeight()*3,
"at the possible sound of your name.\n" +
"No I wouldnt go that far.\n" +
"No.", 0.5f, 0.5f, TrueTypeFont.ALIGN_CENTER);

//End 2D Render Code
set3DMode();
}
public static void cleanup() {
trueTypeFont.destroy();
Keyboard.destroy();
Mouse.destroy();
Display.destroy();
System.gc();
try {
Thread.sleep(1000);
} catch (Exception e) {}

System.exit(0);
}
    public static void set2DMode(float x, float width, float y, float height) {
    //GL11.glDisable(GL11.GL_DEPTH_TEST);
    GL11.glMatrixMode(GL11.GL_PROJECTION);                        // Select The Projection Matrix
        GL11.glPushMatrix();                                     // Store The Projection Matrix
        GL11.glLoadIdentity();                                   // Reset The Projection Matrix
        GL11.glOrtho(x, width, y, height, -1, 1);                          // Set Up An Ortho Screen
        GL11.glMatrixMode(GL11.GL_MODELVIEW);                         // Select The Modelview Matrix
        GL11.glPushMatrix();                                     // Store The Modelview Matrix
        GL11.glLoadIdentity();                                   // Reset The Modelview Matrix
    }
    public static void set3DMode() {
    GL11.glMatrixMode(GL11.GL_PROJECTION);                        // Select The Projection Matrix
        GL11.glPopMatrix();                                      // Restore The Old Projection Matrix
        GL11.glMatrixMode(GL11.GL_MODELVIEW);                         // Select The Modelview Matrix
        GL11.glPopMatrix();                                      // Restore The Old Projection Matrix
        //GL11.glEnable(GL11.GL_DEPTH_TEST);
    }
}
class FPSCounter {
private float FPS = 0, fc = 0;

    private long updateFrequency,
                 currentTime,
                 elapsedTime,
                 lastTime;
   
    void init() {
        updateFrequency = Sys.getTimerResolution()>>1;
        currentTime     = 0;
        elapsedTime     = Sys.getTime();
        lastTime        = Sys.getTime();

    }
    boolean update() {
currentTime = Sys.getTime();

      fc++;
     
      if((elapsedTime = currentTime - lastTime) >= updateFrequency){
        FPS         = (fc/elapsedTime)*updateFrequency*2;
        fc         = 0;
        lastTime    = currentTime;
        elapsedTime = 0;
        return true;
      }
      return false;
    }
    float getFPS() {
    return FPS;
    }
}



relavent lines of code:
Code: [Select]
Font font = new Font("Serif", Font.BOLD, 32);
trueTypeFont = new TrueTypeFont(font, true);
trueTypeFont.drawString();
trueTypeFont.destroy();

//static utility function
TrueTypeFont.isSupported(String fontName);

Please tell me if you find this useful. Or any other improvement ideas.
« Last Edit: July 26, 2009, 21:47:19 by bobjob »

Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #2 on: July 08, 2009, 21:20:43 »
Nice, I just brought a simple improvement:

Code: [Select]
public static Font getFont(String fontname, int style, float size) {
Font result = null;
GraphicsEnvironment graphicsenvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
for ( Font font :  graphicsenvironment.getAllFonts() ) {
if (font.getName().equalsIgnoreCase(fontname)) {
result = font.deriveFont(style, size);
break;
}
}
return result;
}

usable this way:

Code: [Select]
Font font = TrueTypeFont.getFont("Courier New", Font.BOLD, 32);
if (font == null) {
font = new Font("Serif", Font.BOLD, 32);
}
trueTypeFont = new TrueTypeFont(font, true);
Dark Skull Software
http://www.darkskull.net

*

Offline bobjob

  • ****
  • 394
  • LWJGL: WOW SO GOOD
Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #3 on: July 10, 2009, 10:15:43 »
Nice, I just brought a simple improvement:

Cool. I put it in as:
boolean isSupported(String fontName)

Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #4 on: July 25, 2009, 20:22:27 »
Nice work. Thanks a lot, very useful. I just looked for a simple implementation of writing text under opengl
« Last Edit: July 25, 2009, 20:47:46 by dunno »

*

Offline bobjob

  • ****
  • 394
  • LWJGL: WOW SO GOOD
Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #5 on: July 26, 2009, 00:31:10 »
glad someone got some use out of it.

*

Offline manji

  • *
  • 41
    • toyWars
Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #6 on: July 26, 2009, 11:19:47 »
The example you posted hangs my whole system. Don't know why yet.

*

Offline bobjob

  • ****
  • 394
  • LWJGL: WOW SO GOOD
Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #7 on: July 26, 2009, 21:44:25 »
if you can setup your own LWJGL display do that, then just use the relavent lines of code for the TrueTypeFont class.

*

Offline manji

  • *
  • 41
    • toyWars
Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #8 on: July 28, 2009, 15:51:20 »
I tried it again, within my framework, and it works fine. I will use it for now, and I will let you know if any problem occurs. Great work, thnx a lot.

Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #9 on: August 12, 2009, 18:25:21 »
Nice!

Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #10 on: August 20, 2009, 08:00:31 »
Haven't tried it yet, but its very neat :)

The main thing i am missing while reading the source is the possibility to save/load into any given texture format or at least saving it into any reusable format and just calling the load/draw functions afterall.

Anyway, have to try it myself and see how TT look alike :)

Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #11 on: August 20, 2009, 17:13:28 »
Is there any way to change TrueTypeFont class or smth to represent non-english alphabet (I'm interesting in cyrillic actually)?
Now when I trying to pass cyrillic string to the drawString method, program halts and doesn't respond (with no error messages).
There is only one file in my jre/lib/fonts folder: LucidaSansRegular.ttf and it seems to have cyrillic symbols... Although, I'm not very sure.
« Last Edit: August 20, 2009, 17:24:21 by dunno »

Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #12 on: August 20, 2009, 19:05:50 »
TrueTypeFont does link new textures for a character, doesn^'t it? there's actually another way to render fonts, with bezier curves and that's faster for as long as I've tested it against texture-render.
I may post the sample code for bezier-curves, but you can find it in the package sf3jswing-jigaxtended RenderingScene.class _GLRenderText2D method with renderGlyphs enabled (see the link to the sf3jswing project below) !

*

Offline bobjob

  • ****
  • 394
  • LWJGL: WOW SO GOOD
Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #13 on: August 20, 2009, 19:44:32 »
The main thing i am missing while reading the source is the possibility to save/load into any given texture format or at least saving it into any reusable format and just calling the load/draw functions afterall.

Even though it would be simple enough to implement saving/loading, in/from a texture aswell as a script file for character offsets.

My intention for this class was to just give a simple self containted text implementation that doesnt require other resources (mainly for new LWJGL users).

I remember when i was first started to learn LWJGL and found a texture loader class for devIL somewere, it made a world of difference having a self contained class. It was extremly easy for me to get through alot of opengl lessons after that.

I honestly still find navigating through new packages intimidating  ::) especially when the classes in the package needs other classes in the same package.

Re: Complete TrueTypeFont class that only requires LWJGL
« Reply #14 on: August 20, 2009, 20:58:19 »
Oh, I finally get it. For the first time I missed that constructor with char[] additionalChars:
public TrueTypeFont(Font font, boolean antiAlias, char[] additionalChars)
I used another one.
So, one must create such char[] array with specific characters and pass it to that TrueTypeFont constructor and it's work!
Thanks anyway, guys! :)

2broumbroum
>I may post the sample code for bezier-curves
would be great, if you do it, please)

upd:
oh, I found your thread, thanks!
« Last Edit: August 20, 2009, 21:01:04 by dunno »