FontTranslator

Started by elias4444, September 01, 2005, 15:28:33

Previous topic - Next topic

elias4444

I love giving back to this community.

Here's a copy of my fonttranslator. Basically, you feed it the location of a ttf font file and then call either of the drawtext methods to write it out to the screen (the only difference between the two is that one requires your red,green,blue color codes to color the text). There's also a getWidth() function to determine the length of your string when output to the screen and a keyrangevalid() method when using this for text-input functions. Feel free to customize it to fit your own needs.

/*
 * Updated on December 9, 2006
 *
 * Written by Jeremy Adams
 *
 */
package tools;

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.BufferedImageOp;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.IOException;

import javolution.util.FastMap;

import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;

/**
 * @author Jeremy Adams (elias4444)
 * 
 * This module utilizes the modules Texture and TextureLoader 
 * in order to load and store texture information. The most
 * complicated thing to know about these classes is that TextureLoader
 * takes the BufferedImage and converts it into a Texture. If an image 
 * is not "power of 2" Textureloader makes it a power of 2 and sets the 
 * texture coordinates appropriately.
 *
 */
public class FontTT {

	private Texture[] charactersp, characterso;
	private HashMap<String, IntObject> charlistp = new HashMap<String, IntObject>();
	private HashMap<String, IntObject> charlisto = new HashMap<String, IntObject>();
	private TextureLoader textureloader;
	private int kerneling;
	private int fontsize = 32;
	private Font font;
	
	/*
	 * Need a special class to hold character information in the hasmaps
	 */
	private class IntObject {
		public int charnum;
		IntObject(int charnumpass) {
			charnum = charnumpass;
		}
	}

	
	
	/* 
	 * Pass in the preloaded truetype font, the resolution at which 
	 * you wish the initial texture to be rendered at, and any extra 
	 * kerneling you want inbetween characters
	 */
	public FontTT(Font font, int fontresolution, int extrakerneling) {

		textureloader = new TextureLoader();
		this.kerneling = extrakerneling;
		this.font = font;
		fontsize = fontresolution;

		createPlainSet();
		createOutlineSet();
	}

	/*
	 * Create a standard Java2D bufferedimage to later be transferred into a texture
	 */
	private BufferedImage getFontImage(char ch) {
		Font tempfont;
		tempfont = font.deriveFont((float)fontsize);
		//Create a temporary image to extract font size
		BufferedImage tempfontImage = new BufferedImage(1,1, BufferedImage.TYPE_INT_ARGB);
		Graphics2D g = (Graphics2D)tempfontImage.getGraphics();
        //// Add AntiAliasing /////
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        ///////////////////////////
		g.setFont(tempfont);
		FontMetrics fm = g.getFontMetrics();
		int charwidth = fm.charWidth(ch);

		if (charwidth <= 0) {
			charwidth = 1;
		}
		int charheight = fm.getHeight();
		if (charheight <= 0) {
			charheight = fontsize;
		}

		//Create another image for texture creation
		BufferedImage fontImage;
		fontImage = new BufferedImage(charwidth,charheight, BufferedImage.TYPE_INT_ARGB);
		Graphics2D gt = (Graphics2D)fontImage.getGraphics();
        //// Add AntiAliasing /////
        gt.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        ///////////////////////////
		gt.setFont(tempfont);

		//// Uncomment these to fill in the texture with a background color
		//// (used for debugging)
		//gt.setColor(Color.RED);
		//gt.fillRect(0, 0, charwidth, fontsize);
		
		gt.setColor(Color.WHITE);
		int charx = 0;
		int chary = 0;
		gt.drawString(String.valueOf(ch), (charx), (chary) + fm.getAscent());

		return fontImage;

	}

	/*
	 * Create a standard Java2D bufferedimage for the font outline to later be
	 * converted into a texture
	 */
	private BufferedImage getOutlineFontImage(char ch) {
		Font tempfont;
		tempfont = font.deriveFont((float)fontsize);

		//Create a temporary image to extract font size
		BufferedImage tempfontImage = new BufferedImage(1,1, BufferedImage.TYPE_INT_ARGB);
		Graphics2D g = (Graphics2D)tempfontImage.getGraphics();
        //// Add AntiAliasing /////
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        ///////////////////////////
		g.setFont(tempfont);
		FontMetrics fm = g.getFontMetrics();
		int charwidth = fm.charWidth(ch);

		if (charwidth <= 0) {
			charwidth = 1;
		}
		int charheight = fm.getHeight();
		if (charheight <= 0) {
			charheight = fontsize;
		}

		//Create another image for texture creation
		int ot = (int)((float)fontsize/24f);

		BufferedImage fontImage;
		fontImage = new BufferedImage(charwidth + 4*ot,charheight + 4*ot, BufferedImage.TYPE_INT_ARGB);
		Graphics2D gt = (Graphics2D)fontImage.getGraphics();
        //// Add AntiAliasing /////
        gt.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        ///////////////////////////
		gt.setFont(tempfont);

		//// Uncomment these to fill in the texture with a background color
		//// (used for debugging)
		//gt.setColor(Color.RED);
		//gt.fillRect(0, 0, charwidth, fontsize);
		
		//// Create Outline by painting the character in multiple positions and blurring it
		gt.setColor(Color.WHITE);
		int charx = -fm.getLeading() + 2*ot;
		int chary = 2*ot;
		gt.drawString(String.valueOf(ch), (charx) + ot, (chary) + fm.getAscent());
		gt.drawString(String.valueOf(ch), (charx) - ot, (chary) + fm.getAscent());
		gt.drawString(String.valueOf(ch), (charx), (chary) + ot + fm.getAscent());
		gt.drawString(String.valueOf(ch), (charx), (chary) - ot + fm.getAscent());
		gt.drawString(String.valueOf(ch), (charx) + ot, (chary) + ot + fm.getAscent());
		gt.drawString(String.valueOf(ch), (charx) + ot, (chary) - ot + fm.getAscent());
		gt.drawString(String.valueOf(ch), (charx) - ot, (chary) + ot + fm.getAscent());
		gt.drawString(String.valueOf(ch), (charx) - ot, (chary) - ot + fm.getAscent());

		float ninth = 1.0f / 9.0f;
		float[] blurKernel = {
				ninth, ninth, ninth,
				ninth, ninth, ninth,
				ninth, ninth, ninth
		};
		BufferedImageOp blur = new ConvolveOp(new Kernel(3, 3, blurKernel));

		BufferedImage returnimage = blur.filter(fontImage, null);

		return returnimage;

	}



	/*
	 * Create and store the plain (non-outlined) set of the given fonts
	 */
	private void createPlainSet() {
		charactersp = new Texture[256];

		try {
			for(int i=0;i<256;i++) {
				char ch = (char)i;

				BufferedImage fontImage = getFontImage(ch);

				String temptexname = "Char." + i;
				charactersp[i] = textureloader.getTexture(temptexname, fontImage);

				charlistp.put(String.valueOf(ch), new IntObject(i));

				fontImage = null;
			}
		} catch (IOException e) {
			System.out.println("FAILED!!!");
			e.printStackTrace();
		}


	}

	/*
	 * creates and stores the outlined set for the font
	 */
	private void createOutlineSet() {
		characterso = new Texture[256];

		try {
			for(int i=0;i<256;i++) {
				char ch = (char)i;

				BufferedImage fontImage = getOutlineFontImage(ch);

				String temptexname = "Charo." + i;
				characterso[i] = textureloader.getTexture(temptexname, fontImage);

				charlisto.put(String.valueOf(ch), new IntObject(i));

				fontImage = null;
			}
		} catch (IOException e) {
			System.out.println("FAILED!!!");
			e.printStackTrace();
		}


	}


	/*
	 * Draws the given characters to the screen
	 * size = size of the font (does not change resolution)
	 * x,y,z = position to draw at
	 * color = color of font to draw
	 * rotx, roty, rotz = how much to rotate the font on each axis
	 * centered = center the font at the given location, or left justify
	 * 
	 */
	public void drawText(String whatchars, float size, float x, float y, float z, ColorRGBA color, float rotxpass, float rotypass, float rotzpass, boolean centered) {
		float fontsizeratio = size/(float)fontsize;

		int tempkerneling = kerneling;

		int k = 0;
		float realwidth = getWidth(whatchars,size,false);
		GL11.glPushMatrix();
		boolean islightingon = GL11.glIsEnabled(GL11.GL_LIGHTING);

		if (islightingon) {
			GL11.glDisable(GL11.GL_LIGHTING);
		}

		GL11.glTranslatef(x, y, z);
		GL11.glRotatef(rotxpass,1,0,0);
		GL11.glRotatef(rotypass,0,1,0);
		GL11.glRotatef(rotzpass,0,0,1);
		float totalwidth = 0;
		if (centered) {
			totalwidth = -realwidth/2f;
		}
		for (int i=0; i < whatchars.length(); i++) {
			String tempstr = whatchars.substring(i,i+1);
			k = ((charlistp.get(tempstr))).charnum;
			drawtexture(charactersp[k],fontsizeratio,totalwidth, 0, color, rotxpass, rotypass, rotzpass);
			totalwidth += (charactersp[k].getImageWidth()*fontsizeratio + tempkerneling);
		}
		if (islightingon) {
			GL11.glEnable(GL11.GL_LIGHTING);
		}
		GL11.glPopMatrix();

	}


	/*
	 * Draws the given characters to the screen with a drop shadow
	 * size = size of the font (does not change resolution)
	 * x,y,z = position to draw at
	 * color = color of font to draw
	 * shadowcolor = color of the drop shadow
	 * rotx, roty, rotz = how much to rotate the font on each axis
	 * centered = center the font at the given location, or left justify
	 * 
	 */
	public void drawText(String whatchars, float size, float x, float y, float z, ColorRGBA color, ColorRGBA shadowcolor, float rotxpass, float rotypass, float rotzpass, boolean centered) {
		drawText(whatchars,size,x+1f,y-1f,z,shadowcolor,rotxpass,rotypass,rotzpass,centered);
		drawText(whatchars,size,x,y,z,color,rotxpass,rotypass,rotzpass,centered);
	}


	/*
	 * Draws the given characters to the screen
	 * size = size of the font (does not change resolution)
	 * x,y,z = position to draw at
	 * color = color of font to draw
	 * outlinecolor = color of the font's outline
	 * rotx, roty, rotz = how much to rotate the font on each axis
	 * centered = center the font at the given location, or left justify
	 * 
	 */
	public void drawOutlinedText(String whatchars, float size, float x, float y, float z, ColorRGBA color, ColorRGBA outlinecolor, float rotxpass, float rotypass, float rotzpass, boolean centered) {
		float fontsizeratio = size/(float)fontsize;

		float tempkerneling = kerneling;

		int k = 0;
		int ko = 0;
		float realwidth = getWidth(whatchars,size,true);
		GL11.glPushMatrix();
		boolean islightingon = GL11.glIsEnabled(GL11.GL_LIGHTING);

		if (islightingon) {
			GL11.glDisable(GL11.GL_LIGHTING);
		}

		GL11.glTranslatef(x, y, z);
		GL11.glRotatef(rotxpass,1,0,0);
		GL11.glRotatef(rotypass,0,1,0);
		GL11.glRotatef(rotzpass,0,0,1);
		float xoffset,yoffset;
		float totalwidth = 0;
		if (centered) {
			totalwidth = -realwidth/2f;
		}
		for (int i=0; i < whatchars.length(); i++) {
			String tempstr = whatchars.substring(i,i+1);
			ko = ((charlisto.get(tempstr))).charnum;
			drawtexture(characterso[ko],fontsizeratio,totalwidth,0,outlinecolor, rotxpass, rotypass, rotzpass);

			k = ((charlistp.get(tempstr))).charnum;
			xoffset = (characterso[k].getImageWidth() - charactersp[k].getImageWidth())*fontsizeratio/2f;
			yoffset = (characterso[k].getImageHeight() - charactersp[k].getImageHeight())*fontsizeratio/2f;
			drawtexture(charactersp[k],fontsizeratio,totalwidth + xoffset,yoffset,color, rotxpass, rotypass, rotzpass);
			totalwidth += ((characterso[k].getImageWidth()*fontsizeratio) + tempkerneling);
		}
		if (islightingon) {
			GL11.glEnable(GL11.GL_LIGHTING);
		}
		GL11.glPopMatrix();
		
	}

	/*
	 * Draw the actual quad with character texture
	 */
	private void drawtexture(Texture texture, float ratio, float x, float y, ColorRGBA color, float rotx, float roty, float rotz) {
		// Get the appropriate measurements from the texture itself
		float imgwidth = texture.getImageWidth() * ratio;
		float imgheight = -texture.getImageHeight() * ratio;
		float texwidth = texture.getWidth();
		float texheight = texture.getHeight();

		// Bind the texture
		texture.bind();

		// translate to the right location
		GL11.glColor4f(color.getRed(),color.getGreen(),color.getBlue(), color.getAlpha());

		// draw a quad with to place the character onto
		GL11.glBegin(GL11.GL_QUADS);
		{
			GL11.glTexCoord2f(0, 0);
			GL11.glVertex2f(0 + x, 0 - y);
			
			GL11.glTexCoord2f(0, texheight);
			GL11.glVertex2f(0 + x, imgheight - y);
			
			GL11.glTexCoord2f(texwidth, texheight);
			GL11.glVertex2f(imgwidth + x,imgheight - y);
			
			GL11.glTexCoord2f(texwidth, 0);
			GL11.glVertex2f(imgwidth + x,0 - y);
		}
		GL11.glEnd();

	}

	/*
	 * Returns the width in pixels of the given string, size, outlined or not
	 * used for determining how to position the string, either for the user
	 * or for this object
	 * 
	 */
	public float getWidth(String whatchars, float size, boolean outlined) {
		float fontsizeratio = size/(float)fontsize;

		float tempkerneling = ((float)kerneling*fontsizeratio);
		float totalwidth = 0;
		int k = 0;
		for (int i=0; i < whatchars.length(); i++) {
			String tempstr = whatchars.substring(i,i+1);
			if (outlined) {
				k = ((charlisto.get(tempstr))).charnum;
				totalwidth += (characterso[k].getImageWidth()*fontsizeratio) + tempkerneling;
			} else {
				k = ((charlistp.get(tempstr))).charnum;
				totalwidth += (charactersp[k].getImageWidth()*fontsizeratio) + tempkerneling;
			}
		}
		return totalwidth;

	}


	/*
	 * For convenience of checking user input keys
	 * Can be taken out if you're not going to use it
	 * 
	 */
    public boolean keyrangevalid(int currentKey) {
        boolean retvalue = false;
        if (currentKey == Keyboard.KEY_A ||
                currentKey == Keyboard.KEY_B ||
                currentKey == Keyboard.KEY_C ||
                currentKey == Keyboard.KEY_D ||
                currentKey == Keyboard.KEY_E ||
                currentKey == Keyboard.KEY_F ||
                currentKey == Keyboard.KEY_G ||
                currentKey == Keyboard.KEY_H ||
                currentKey == Keyboard.KEY_I ||
                currentKey == Keyboard.KEY_J ||
                currentKey == Keyboard.KEY_K ||
                currentKey == Keyboard.KEY_L ||
                currentKey == Keyboard.KEY_M ||
                currentKey == Keyboard.KEY_N ||
                currentKey == Keyboard.KEY_O ||
                currentKey == Keyboard.KEY_P ||
                currentKey == Keyboard.KEY_Q ||
                currentKey == Keyboard.KEY_R ||
                currentKey == Keyboard.KEY_S ||
                currentKey == Keyboard.KEY_T ||
                currentKey == Keyboard.KEY_U ||
                currentKey == Keyboard.KEY_V ||
                currentKey == Keyboard.KEY_W ||
                currentKey == Keyboard.KEY_X ||
                currentKey == Keyboard.KEY_Y ||
                currentKey == Keyboard.KEY_Z ||
                currentKey == Keyboard.KEY_0 ||
                currentKey == Keyboard.KEY_1 ||
                currentKey == Keyboard.KEY_2 ||
                currentKey == Keyboard.KEY_3 ||
                currentKey == Keyboard.KEY_4 ||
                currentKey == Keyboard.KEY_5 ||
                currentKey == Keyboard.KEY_6 ||
                currentKey == Keyboard.KEY_7 ||
                currentKey == Keyboard.KEY_8 ||
                currentKey == Keyboard.KEY_9 ||
                currentKey == Keyboard.KEY_PERIOD ||
                currentKey == Keyboard.KEY_SPACE ||
                currentKey == Keyboard.KEY_RETURN ||
                currentKey == Keyboard.KEY_COMMA ||
                currentKey == Keyboard.KEY_SLASH ||
                currentKey == Keyboard.KEY_SEMICOLON ||
                currentKey == Keyboard.KEY_LBRACKET ||
                currentKey == Keyboard.KEY_RBRACKET ||
                currentKey == Keyboard.KEY_EQUALS ||
                currentKey == Keyboard.KEY_MINUS ||
                currentKey == Keyboard.KEY_APOSTROPHE ||
                currentKey == Keyboard.KEY_BACK
                ) {
            retvalue = true;
        }
        return retvalue;
    }
    
    
    public boolean keyrangevalidnumbers(int currentKey) {
        boolean retvalue = false;
        if (
                currentKey == Keyboard.KEY_0 ||
                currentKey == Keyboard.KEY_1 ||
                currentKey == Keyboard.KEY_2 ||
                currentKey == Keyboard.KEY_3 ||
                currentKey == Keyboard.KEY_4 ||
                currentKey == Keyboard.KEY_5 ||
                currentKey == Keyboard.KEY_6 ||
                currentKey == Keyboard.KEY_7 ||
                currentKey == Keyboard.KEY_8 ||
                currentKey == Keyboard.KEY_9 ||
                currentKey == Keyboard.KEY_PERIOD ||
                currentKey == Keyboard.KEY_BACK
                ) {
            retvalue = true;
        }
        return retvalue;
    }
    
    


}


MAKE SURE TO GRAB THE TextureLoader and Texture classes listed below (in reply #6)!!!!
=-=-=-=-=-======-=-=-=-=-=-
http://www.tommytwisters.com

CaseyB

Very cool!  Thank you!  Actaully color support was one of the things that I added!  I did it by vreating another private class that held the 4 float values and then a setColor() method!  Also, for my uses I am always going to want to display HUD type stuff so I have the drawText() check to see if lighting and depth testing are enabled, if so set a flag, then disable them, run the for loop, then re-enable the appropriate things.  This makes the text display regardless of lighting and as log as it's the last thing you render it will always be on top!  I also wanted to add the ZPlaneMatch stuff from your ScreenManager class because that's a very cool bit of code, but I would like to do my own display stuff instead of using the manager.     :wink:

rainforest

Hello

After finding it interesting I tried to run it on Eclipse but have errors

in loading two types Texture and TextureLoader. Can u please make it clear to me why this is happening? Is my PC not configured properly?

rainforest.
.:: A journey of thousand miles starts with a single step ::.

elias4444

It's probably because you're missing the Texture and TextureLoader classes that go with it. The ones I use are heavily based on the same ones in the Space Invaders demo on the lwjgl demos page. Download those and try them out.
=-=-=-=-=-======-=-=-=-=-=-
http://www.tommytwisters.com

kappa

amazing code, but doesn't compile, i've tried the space invader Texture and TextureLoader classes but i think your TextureLoader class maybe a little different.

the things that are missing from normal space invaders texture loader are:

getTexture(String, BufferedImage); // is not availabe only the one with string is there

new TextureLoader(textureratio); // which isn't available either

rainforest

Dear elias4444

I wonder can u please provide soulution to the problem of the two errors for using the texture and textureloader class of spaceinvaders. I m working on a project where font variation could be useful. Please provide us some link or code help?


rainforest.
.:: A journey of thousand miles starts with a single step ::.

elias4444

These should work:

Modified TextureLoader class:

package tools;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Hashtable;

import javax.imageio.ImageIO;

import org.lwjgl.Sys;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.glu.GLU;

/**
 * Modified from code originally written by:
 * @author Kevin Glass
 * @author Brian Matzon
 * 
 */
public class TextureLoader {
	/** The table of textures that have been loaded in this loader */
	private HashMap<String, Texture> table = new HashMap<String, Texture>();
	
	/** The colour model including alpha for the GL image */
	public ColorModel glAlphaColorModel;
	
	/** The colour model for the GL image */
	private ColorModel glColorModel;
	
	private int target = GL11.GL_TEXTURE_2D;
	private int dstPixelFormat = GL11.GL_RGBA;
	//private int dstPixelFormat = GL13.GL_COMPRESSED_RGBA;
	private int minFilter = GL11.GL_LINEAR_MIPMAP_NEAREST;
	private int magFilter = GL11.GL_LINEAR;
	
	/** 
	 * Create a new texture loader based on the game panel
	 *
	 * @param gl The GL content in which the textures should be loaded
	 */
	public TextureLoader() {
		//dstPixelFormat = 4;
		
		glAlphaColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
				new int[] {8,8,8,8},
				true,
				false,
				ComponentColorModel.TRANSLUCENT,
				DataBuffer.TYPE_BYTE);
		
		glColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
				new int[] {8,8,8,0},
				false,
				false,
				ComponentColorModel.OPAQUE,
				DataBuffer.TYPE_BYTE);
	}
	
	/**
	 * Create a new texture ID 
	 *
	 * @return A new texture ID
	 */
	private int createTextureID() 
	{ 
		IntBuffer tmp = createIntBuffer(1); 
		try {
			GL11.glGenTextures(tmp);
		} catch (NullPointerException e) {
			//e.printStackTrace();
			Sys.alert("Error","Your system is not capable of running this game.\nPlease make sure your video drivers are current.");
			System.exit(0);
		}
		return tmp.get(0);
	} 
	
	/**
	 * Load a texture
	 *
	 * @param resourceName The location of the resource to load
	 * @return The loaded texture
	 * @throws IOException Indicates a failure to access the resource
	 */
	public Texture getTexture(String resourceName, boolean injar) throws IOException {
		Texture tex = table.get(resourceName);
		
		if (tex != null) {
			return tex;
		}
		
		tex = getTexture(resourceName, injar,
				target, // target
				dstPixelFormat,     // dst pixel format
				minFilter, // min filter (unused)
				magFilter);
		
		table.put(resourceName,tex);
		
		return tex;
	}
	
	/**
	 * Load a texture into OpenGL from a image reference on
	 * disk.
	 *
	 * @param resourceName The location of the resource to load
	 * @param target The GL target to load the texture against
	 * @param dstPixelFormat The pixel format of the screen
	 * @param minFilter The minimising filter
	 * @param magFilter The magnification filter
	 * @return The loaded texture
	 * @throws IOException Indicates a failure to access the resource
	 */
	public Texture getTexture(String resourceName, boolean injar,
			int target, 
			int dstPixelFormat, 
			int minFilter, 
			int magFilter) throws IOException 
			{ 
		int srcPixelFormat = 0;
		
		// create the texture ID for this texture 
		int textureID = createTextureID(); 
		Texture texture = new Texture(target,textureID); 
		
		// bind this texture 
		GL11.glBindTexture(target, textureID); 
		
		BufferedImage bufferedImage = loadImage(resourceName, injar); 
		texture.setWidth(bufferedImage.getWidth());
		texture.setHeight(bufferedImage.getHeight());
		
		if (bufferedImage.getColorModel().hasAlpha()) {
			srcPixelFormat = GL11.GL_RGBA;
		} else {
			srcPixelFormat = GL11.GL_RGB;
		}
		
		// convert that image into a byte buffer of texture data 
		ByteBuffer textureBuffer = convertImageData(bufferedImage,texture); 
		
		if (target == GL11.GL_TEXTURE_2D) 
		{ 
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_MIN_FILTER, minFilter); 
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_MAG_FILTER, magFilter); 
		} 
		
		// produce a texture from the byte buffer
		/*
		GL11.glTexImage2D(target, 
				0, 
				dstPixelFormat, 
				get2Fold(bufferedImage.getWidth()), 
				get2Fold(bufferedImage.getHeight()), 
				0, 
				srcPixelFormat, 
				GL11.GL_UNSIGNED_BYTE, 
				textureBuffer ); 
		 */
		
		GLU.gluBuild2DMipmaps(target, dstPixelFormat, get2Fold(bufferedImage.getWidth()), 
				get2Fold(bufferedImage.getHeight()), srcPixelFormat, GL11.GL_UNSIGNED_BYTE, textureBuffer); 

		return texture; 
			} 
	
	
	
	
	/**
	 * Get the closest greater power of 2 to the fold number
	 * 
	 * @param fold The target number
	 * @return The power of 2
	 */
	private int get2Fold(int fold) {
		int ret = 2;
		while (ret < fold) {
			ret *= 2;
		}
		return ret;
	} 
	
	/**
	 * Convert the buffered image to a texture
	 *
	 * @param bufferedImage The image to convert to a texture
	 * @param texture The texture to store the data into
	 * @return A buffer containing the data
	 */
	private ByteBuffer convertImageData(BufferedImage bufferedImage,Texture texture) { 
		ByteBuffer imageBuffer = null; 
		WritableRaster raster;
		BufferedImage texImage;
		
		int texWidth = 2;
		int texHeight = 2;
		
		// find the closest power of 2 for the width and height
		// of the produced texture
		while (texWidth < bufferedImage.getWidth()) {
			texWidth *= 2;
		}
		while (texHeight < bufferedImage.getHeight()) {
			texHeight *= 2;
		}
		
		texture.setTextureHeight(texHeight);
		texture.setTextureWidth(texWidth);
		
		// create a raster that can be used by OpenGL as a source
		// for a texture
		if (bufferedImage.getColorModel().hasAlpha()) {
			raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,texWidth,texHeight,4,null);
			texImage = new BufferedImage(glAlphaColorModel,raster,false,new Hashtable());
		} else {
			raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,texWidth,texHeight,3,null);
			texImage = new BufferedImage(glColorModel,raster,false,new Hashtable());
		}
		
		// copy the source image into the produced image
		Graphics g = texImage.getGraphics();
		g.setColor(new Color(0f,0f,0f,0f));
		g.fillRect(0,0,texWidth,texHeight);
		g.drawImage(bufferedImage,0,0,null);
		
		// build a byte buffer from the temporary image 
		// that be used by OpenGL to produce a texture.
		byte[] data = ((DataBufferByte) texImage.getRaster().getDataBuffer()).getData(); 
		
		imageBuffer = ByteBuffer.allocateDirect(data.length); 
		imageBuffer.order(ByteOrder.nativeOrder()); 
		imageBuffer.put(data, 0, data.length); 
		imageBuffer.flip();
		
		return imageBuffer; 
	} 
	
	/** 
	 * Load a given resource as a buffered image
	 * 
	 * @param ref The location of the resource to load
	 * @return The loaded buffered image
	 * @throws IOException Indicates a failure to find a resource
	 */
	private BufferedImage loadImage(String ref, boolean injar) throws IOException 
	{ 
		//URL url = TextureLoader.class.getClassLoader().getResource(ref);
		
		//if (url == null) {
		//	throw new IOException("Cannot find: "+ref);
		//}
		
		if (injar) {
			BufferedImage bufferedImage = ImageIO.read(new BufferedInputStream(getClass().getClassLoader().getResourceAsStream(ref)));
			return bufferedImage;
		} else {
			File file = new File(ref);
			BufferedImage bufferedImage = null; 
			try {
				bufferedImage = ImageIO.read(file);
			} catch (IOException e) {
				System.out.println("Could not load texture: " + ref);
			}
			return bufferedImage;
		}
		
	}
	
	/**
	 * Creates an integer buffer to hold specified ints
	 * - strictly a utility method
	 *
	 * @param size how many int to contain
	 * @return created IntBuffer
	 */
	protected IntBuffer createIntBuffer(int size) {
		ByteBuffer temp = ByteBuffer.allocateDirect(4 * size);
		temp.order(ByteOrder.nativeOrder());
		
		return temp.asIntBuffer();
	}   
	

	//////////////////////////////////////////////////
	//// Added for BufferedImage Support /////////////
	//////////////////////////////////////////////////
	/**
	 * Load a texture
	 *
	 * @param resourceName The location of the resource to load
	 * @return The loaded texture
	 * @throws IOException Indicates a failure to access the resource
	 */
	public Texture getTexture(String resourceName, BufferedImage resourceImage) throws IOException {
		Texture tex = table.get(resourceName);
		
		if (tex != null) {
			return tex;
		}
		
		tex = getTexture(resourceImage, 
				target, // target
				dstPixelFormat,     // dst pixel format
				minFilter, // min filter (unused)
				magFilter);
		
		table.put(resourceName,tex);
		
		return tex;
	}
	
	/**
	 * Load a texture into OpenGL from a BufferedImage
	 *
	 * @param resourceName The location of the resource to load
	 * @param target The GL target to load the texture against
	 * @param dstPixelFormat The pixel format of the screen
	 * @param minFilter The minimising filter
	 * @param magFilter The magnification filter
	 * @return The loaded texture
	 * @throws IOException Indicates a failure to access the resource
	 */
	public Texture getTexture(BufferedImage resourceimage, 
			int target, 
			int dstPixelFormat, 
			int minFilter, 
			int magFilter) throws IOException 
			{ 
		int srcPixelFormat = 0;
		
		// create the texture ID for this texture 
		int textureID = createTextureID(); 
		Texture texture = new Texture(target,textureID); 
		
		// bind this texture 
		GL11.glBindTexture(target, textureID); 
		
		BufferedImage bufferedImage = resourceimage; 
		texture.setWidth(bufferedImage.getWidth());
		texture.setHeight(bufferedImage.getHeight());
		
		if (bufferedImage.getColorModel().hasAlpha()) {
			srcPixelFormat = GL11.GL_RGBA;
		} else {
			srcPixelFormat = GL11.GL_RGB;
		}
		
		// convert that image into a byte buffer of texture data 
		ByteBuffer textureBuffer = convertImageData(bufferedImage,texture); 
		
		if (target == GL11.GL_TEXTURE_2D) 
		{ 
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_MIN_FILTER, minFilter); 
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_MAG_FILTER, magFilter); 
		} 
		
		// produce a texture from the byte buffer
		/*
		GL11.glTexImage2D(target, 
				0, 
				dstPixelFormat, 
				get2Fold(bufferedImage.getWidth()), 
				get2Fold(bufferedImage.getHeight()), 
				0, 
				srcPixelFormat, 
				GL11.GL_UNSIGNED_BYTE, 
				textureBuffer ); 
		 */
		
		GLU.gluBuild2DMipmaps(target, dstPixelFormat, get2Fold(bufferedImage.getWidth()), 
				get2Fold(bufferedImage.getHeight()), srcPixelFormat, GL11.GL_UNSIGNED_BYTE, textureBuffer); 

		return texture; 
			} 
	
	
	
	//////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////
	
	


	//////////////////////////////////////////////////
	//// Added for No MipMapping Support /////////////
	//////////////////////////////////////////////////
	/**
	 * Load a texture
	 *
	 * @param resourceName The location of the resource to load
	 * @return The loaded texture
	 * @throws IOException Indicates a failure to access the resource
	 */
	public Texture getNMMTexture(String resourceName, BufferedImage resourceImage) throws IOException {
		Texture tex = table.get(resourceName);
		
		if (tex != null) {
			return tex;
		}
		
		tex = getNMMTexture(resourceImage, 
				target, // target
				dstPixelFormat,     // dst pixel format
				GL11.GL_NEAREST, // min filter (unused)
				GL11.GL_LINEAR);
		
		table.put(resourceName,tex);
		
		return tex;
	}
	
	/**
	 * Load a texture into OpenGL from a BufferedImage
	 *
	 * @param resourceName The location of the resource to load
	 * @param target The GL target to load the texture against
	 * @param dstPixelFormat The pixel format of the screen
	 * @param minFilter The minimising filter
	 * @param magFilter The magnification filter
	 * @return The loaded texture
	 * @throws IOException Indicates a failure to access the resource
	 */
	public Texture getNMMTexture(BufferedImage resourceimage, 
			int target, 
			int dstPixelFormat, 
			int minFilter, 
			int magFilter) throws IOException 
			{ 
		int srcPixelFormat = 0;
		
		// create the texture ID for this texture 
		int textureID = createTextureID(); 
		Texture texture = new Texture(target,textureID); 
		
		// bind this texture 
		GL11.glBindTexture(target, textureID); 
		
		BufferedImage bufferedImage = resourceimage; 
		texture.setWidth(bufferedImage.getWidth());
		texture.setHeight(bufferedImage.getHeight());
		
		if (bufferedImage.getColorModel().hasAlpha()) {
			srcPixelFormat = GL11.GL_RGBA;
		} else {
			srcPixelFormat = GL11.GL_RGB;
		}
		
		// convert that image into a byte buffer of texture data 
		ByteBuffer textureBuffer = convertImageData(bufferedImage,texture); 
		
		if (target == GL11.GL_TEXTURE_2D) 
		{ 
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_MIN_FILTER, minFilter); 
			GL11.glTexParameteri(target, GL11.GL_TEXTURE_MAG_FILTER, magFilter); 
		} 
		
		// produce a texture from the byte buffer
		GL11.glTexImage2D(target, 
				0, 
				dstPixelFormat, 
				get2Fold(bufferedImage.getWidth()), 
				get2Fold(bufferedImage.getHeight()), 
				0, 
				srcPixelFormat, 
				GL11.GL_UNSIGNED_BYTE, 
				textureBuffer ); 

		return texture; 
			} 
	
	//////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////
	
	


}


Modified Texture class:

package tools;

import org.lwjgl.opengl.GL11;

/**
 * Modified code originally written by:
 * @author Kevin Glass
 * @author Brian Matzon
 */
public class Texture {
    /** The GL target type */
    public int target; 
    /** The GL texture ID */
    public int textureID;
    /** The height of the image */
    private int height;
    /** The width of the image */
    private int width;
    /** The width of the texture */
    private int texWidth;
    /** The height of the texture */
    private int texHeight;
    /** The ratio of the width of the image to the texture */
    private float widthRatio;
    /** The ratio of the height of the image to the texture */
    private float heightRatio;
    /**
     * Create a new texture
     *
     * @param target The GL target 
     * @param textureID The GL texture ID
     */
    public Texture(int target,int textureID) {
        this.target = target;
        this.textureID = textureID;
    }
    
    /**
     * Bind the specified GL context to a texture
     *
     * @param gl The GL context to bind to
     */
    public void bind() {
      GL11.glBindTexture(target, textureID); 
    }
    
    /**
     * Set the height of the image
     *
     * @param height The height of the image
     */
    public void setHeight(int height) {
        this.height = height;
        setHeight();
    }
    
    /**
     * Set the width of the image
     *
     * @param width The width of the image
     */
    public void setWidth(int width) {
        this.width = width;
        setWidth();
    }
    
    /**
     * Get the height of the original image
     *
     * @return The height of the original image
     */
    public int getImageHeight() {
        return (int)(height);
    }
    
    /** 
     * Get the width of the original image
     *
     * @return The width of the original image
     */
    public int getImageWidth() {
        return (int)(width);
    }
    
    /**
     * Get the height of the physical texture
     *
     * @return The height of physical texture
     */
    public float getHeight() {
        return heightRatio;
    }
    
    /**
     * Get the width of the physical texture
     *
     * @return The width of physical texture
     */
    public float getWidth() {
        return widthRatio;
    }
    
    /**
     * Set the height of this texture 
     *
     * @param texHeight The height of the texture
     */
    public void setTextureHeight(int texHeight) {
        this.texHeight = texHeight;
        setHeight();
    }
    
    /**
     * Set the width of this texture 
     *
     * @param texWidth The width of the texture
     */
    public void setTextureWidth(int texWidth) {
        this.texWidth = texWidth;
        setWidth();
    }
    
    /**
     * Set the height of the texture. This will update the
     * ratio also.
     */
    private void setHeight() {
        if (texHeight != 0) {
            heightRatio = ((float) height)/texHeight;
        }
    }
    
    /**
     * Set the width of the texture. This will update the
     * ratio also.
     */
    private void setWidth() {
        if (texWidth != 0) {
            widthRatio = ((float) width)/texWidth;
        }
    }
}
=-=-=-=-=-======-=-=-=-=-=-
http://www.tommytwisters.com

dauphin65

I didn't find a reply on this, so I'll post it just to clarify to those trying to use bold and italic.  The == equality comparison will not work with strings.  If anyone is having a problem with Bold and Italics this is probably the issue.

if (fontstylepass == "BOLD") {
            font = tempfont.deriveFont(Font.BOLD, fontsize);
         } else if (fontstylepass == "ITALIC") {
            font = tempfont.deriveFont(Font.ITALIC, fontsize);
         } else {
            font = tempfont.deriveFont(Font.PLAIN, fontsize);
         }


should actually be:
if (fontstylepass.equals("BOLD")) {
            font = tempfont.deriveFont(Font.BOLD, fontsize);
         } else if (fontstylepass.equals("ITALIC")) {
            font = tempfont.deriveFont(Font.ITALIC, fontsize);
         } else {
            font = tempfont.deriveFont(Font.PLAIN, fontsize);
         }

elias4444

Drats, sorry about not being around for a while (I've been on-call for my job this last week). I've gotta post my newest version of the code. I did an overhaul of it for use with jMonkeyEngine and then went back and updated the raw LWJGL version. I'll try to get it posted in the next couple of days.
=-=-=-=-=-======-=-=-=-=-=-
http://www.tommytwisters.com

Spezi

I have a problem using your FontTranslator class. I got it working without errors but can't see any text on the screen. I just have a black background and tried writing white text but there's none neither in ortho- nor in normal-mode.

Quote from: elias4444 on July 17, 2006, 00:17:39
I've gotta post my newest version of the code. I did an overhaul of it for use with jMonkeyEngine and then went back and updated the raw LWJGL version. I'll try to get it posted in the next couple of days.

Are you still working on it and if so, is there a chance to get a recent version?  ;)
Ich bin, ich weiß nicht wer.
Ich komme, ich weiß nicht woher.
Ich gehe, ich weiß nicht wohin.
Mich wundert, dass ich so fröhlich bin.

elias4444

I'm so sorry.. I've been horribly busy with things lately. My current version of the code has been more integrated with my engine, which makes posting it without the entire engine kinda tricky.  :-\

I'll see what I can come up with, but please give me some time. The problem you're probably running into is in the translation of the buffered image into a texture. I'll update the code at the beginning of this thread.


=-=-=-=-=-======-=-=-=-=-=-
http://www.tommytwisters.com

Spezi

Of course I don't wanna pressurize you. :)

But even with your updated version (just removed the line "import javolution.util.FastMap;" and changed ColorRGBA to Color) I cannot get any text displayed. Could you please post a simple testdriver?
Ich bin, ich weiß nicht wer.
Ich komme, ich weiß nicht woher.
Ich gehe, ich weiß nicht wohin.
Mich wundert, dass ich so fröhlich bin.

elias4444

Download and check out this jar from my website: www.tommytwisters.com/texturetester.jar

It uses an older version of the fonttranslator, but should show you how to use it.
=-=-=-=-=-======-=-=-=-=-=-
http://www.tommytwisters.com

Betalord

The link is broken, can you upload it again?

elias4444

Ugh... sorry... I'm in the middle of selling my house and moving, and to top it off, I recently switched to a different webhost. Looks like I lost that file in the process. Once things settle down I'll see if I can get to rebuilding that file and posting it.

Edit: Ah ha! Never mind! I found a backup of it! I've reposted it, so please try again.
=-=-=-=-=-======-=-=-=-=-=-
http://www.tommytwisters.com