If you don’t want to use AWT, that means you can’t use BufferedImage. So… You need to make a separate program (which does use AWT) to read in the .png with the characterset. You then get the underlying bytes and save them to a file.
You AWTless program, then directly reads the bytes from the file and puts them into a texture or a bitmap. The textured Quad solution looks tempting, however I do have some code for glDrawPixels. It will slow your game down if you write lots of letters.
Here is part of my code to convert a .png file to a set of font characters. Note that this code misses out characters that aren’t used in the game to save space
/** Include font support for all characters in this string */
public void includeFont(String s) {
for (int i=0; i< s.length(); i++) {
char c = s.charAt(i);
if (c>='.' && c<='9') c -='.';
else if (c>='A' && c<='Z') c -='A'-12;
else if (c>='a' && c<='z') c -='a'-38;
else continue;
font[(int)c] = true;
}
}
/** Add 64 character, 16x22 font to the data file */
public void convertFont(String filename) {
try {
// Get the font graphics file
System.out.println(" "+filename);
is = new FileInputStream(filename);
BufferedImage img = ImageIO.read(is);
// Construct 64 bit header
// Bit 0 is set if char 0 is present in file etc.
long f = 0;
for (int i=63; i>=0; i--)
if (font[i])
f=(f<<1) | 1;
else
f<<=1;
// Write header as a 'long'
for (int i=7; i>=0; i--)
os.write( (int)((f>>(i*8)) & 0xff) );
for (int c=0; c<64; c++)
if (font[c])
for (int y=0; y<22; y++)
for (int x=0; x<2; x++) {
int bits = 0;
for (int b=0; b<8; b++) {
int colour = img.getRGB(16*c+8*x+b, 21-y) & 0xffffff;
int mask = (colour==0)?1:0;
bits = bits*2 + mask;
}
os.write(bits);
}
is.close();
} catch (Exception e) {e.printStackTrace(); };
}
Now we need to open the data file (not shown) & stuff the data into a series of ByteBuffers. Of course you could just stick it in one texture & use texture coordinates to select the letter for each Quad, which is probably faster (but I have no code for it)
// Bitmap data
public ByteBuffer[] fontData = new ByteBuffer[64]; // Font data
// Load Font data
long font = is.readLong(); // 64 bits indicating which chars
for (int c=0; c<64;c++) { // are defined
fontData[c] = BufferUtils.createByteBuffer(44);
for (int i=0; i<44; i++)
if ((font & 1) == 1) // Define char
fontData[c].put(is.readByte());
else
fontData[c].put((byte)0); // Space if no definition
fontData[c].rewind();
font>>=1;
}
/** Print text string at x, y at specified size */
public void print(int x, int y, int size, String s) {
GL11.glPixelZoom(size, size);
for (int i=0; i<s.length(); i++) {
char c = s.charAt(i);
if (c>='.' && c<='9') c -='.';
else if (c>='A' && c<='Z') c -='A'-12;
else if (c>='a' && c<='z') c -='a'-38;
else continue;
GL11.glRasterPos2i(x+size*16*i, y);
GL11.glDrawPixels(16, 22, GL11.GL_COLOR_INDEX,
GL11.GL_BITMAP, fontData[(int)c]);
}
}
BTW. You need a fair bit of setup (not shown) to use glDrawPixels, so as to make the background transparent. glBitmap() is easier as the background is automatically transparent, but you can’t scale the letters, nor can you do multi-colour (or anti-aliased) letters.