warning: Creating default object from empty value in /home/kappaone/ninjacave.com/modules/taxonomy/taxonomy.pages.inc on line 34.

LWJGL

LWJGL

LWJGL Basics 1 (The Display)

Introduction
The LWJGL library uses its own lightweight native window (known as the Display) and has its own input system. This provides a fast, small context to draw on, enables low latency input and is a solid base for building modern games.

The LWJGL Display
The Display class is LWJGL's most important class. It creates and controls the native window on which all graphics content is rendered.

The Display class has 3 methods that one should be aware of, namely:

  • create()
  • update()
  • destroy()

Tutorials for the Slick-Util Library

Slick-Util (Part 3) - TrueType Fonts for LWJGL

Intro
Part 1 - Loading Images for LWJGL
Part 2 - Loading Sounds for LWJGL
Part 3 - TrueType Fonts for LWJGL

Why is a Library needed for Fonts?
OpenGL has no built-in support for fonts. In order to display fonts you will need to manually implement such support. It can be pretty tricky to implements fonts correctly especially as there are many different ways and techniques to do this in OpenGL. Using bitmaps to display fonts in OpenGL is probably the most popular method.

True Type Font Format
The True Type Font Format (.ttf) is the most widely used format to store and share fonts. There are tons of sites out there which supply fonts in this format for free, e.g.:

http://www.dafont.com/
http://www.1001freefonts.com/
http://www.urbanfonts.com/

Basics
Slick-Util uses Java's built in AWT Font support to load the fonts, so be sure to be familar with the AWT's Font class. You can use either the default built in java fonts or load external ttf files.

The Slick-Util library will convert the AWT Font so that it can be used with OpenGL. The fonts are stored and drawn through slick's TrueTypeFont class.

To load a True Type Font you simply do the following:

TrueTypeFont font;
TrueTypeFont font2;
 
public void init() {
	// load a default java font
	Font awtFont = new Font("Times New Roman", Font.BOLD, 24);
	font = new TrueTypeFont(awtFont, false);
 
	// load font from a .ttf file
	try {
		InputStream inputStream	= ResourceLoader.getResourceAsStream("myfont.ttf");
 
		Font awtFont2 = Font.createFont(Font.TRUETYPE_FONT, inputStream);
		awtFont2 = awtFont2.deriveFont(24f); // set font size
		font2 = new TrueTypeFont(awtFont2, false);
 
	} catch (Exception e) {
		e.printStackTrace();
	}	
}

and its equally simple to render them onto the screen.

public void render() {
	font.drawString(100, 50, "THE LIGHTWEIGHT JAVA GAMES LIBRARY", Color.yellow);
	font2.drawString(100, 100, "NICE LOOKING FONTS!", Color.green);
}

Below is a full working example on how to use the ttf fonts with LWJGL using slick-util.

import java.awt.Font;
import java.io.InputStream;
 
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
 
import org.newdawn.slick.Color;
import org.newdawn.slick.TrueTypeFont;
import org.newdawn.slick.util.ResourceLoader;
 
public class FontExample {
 
	/** The fonts to draw to the screen */
	private TrueTypeFont font;
	private TrueTypeFont font2;
 
	/** Boolean flag on whether AntiAliasing is enabled or not */
	private boolean antiAlias = true;
 
	/**
	 * Start the test 
	 */
	public void start() {
		initGL(800,600);
		init();
 
		while (true) {
			GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
			render();
 
			Display.update();
			Display.sync(100);
 
			if (Display.isCloseRequested()) {
				Display.destroy();
				System.exit(0);
			}
		}
	}
 
	/**
	 * Initialise the GL display
	 * 
	 * @param width The width of the display
	 * @param height The height of the display
	 */
	private void initGL(int width, int height) {
		try {
			Display.setDisplayMode(new DisplayMode(width,height));
			Display.create();
			Display.setVSyncEnabled(true);
		} catch (LWJGLException e) {
			e.printStackTrace();
			System.exit(0);
		}
 
		GL11.glEnable(GL11.GL_TEXTURE_2D);
		GL11.glShadeModel(GL11.GL_SMOOTH);        
		GL11.glDisable(GL11.GL_DEPTH_TEST);
		GL11.glDisable(GL11.GL_LIGHTING);                    
 
		GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);                
        GL11.glClearDepth(1);                                       
 
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
 
        GL11.glViewport(0,0,width,height);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
 
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, width, height, 0, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
	}
 
	/**
	 * Initialise resources
	 */
	public void init() {
		// load a default java font
		Font awtFont = new Font("Times New Roman", Font.BOLD, 24);
		font = new TrueTypeFont(awtFont, antiAlias);
 
		// load font from file
		try {
			InputStream inputStream	= ResourceLoader.getResourceAsStream("myfont.ttf");
 
			Font awtFont2 = Font.createFont(Font.TRUETYPE_FONT, inputStream);
			awtFont2 = awtFont2.deriveFont(24f); // set font size
			font2 = new TrueTypeFont(awtFont2, antiAlias);
 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
 
	/**
	 * Game loop render
	 */
	public void render() {
		Color.white.bind();
 
		font.drawString(100, 50, "THE LIGHTWEIGHT JAVA GAMES LIBRARY", Color.yellow);
		font2.drawString(100, 100, "NICE LOOKING FONTS!", Color.green);
	}
 
	/**
	 * Main method
	 */
	public static void main(String[] argv) {
		FontExample fontExample = new FontExample();
		fontExample.start();
	}
}

You should get an output similar to the image below.

Additional Credit
Kevin Glass for writing the Slick Library and initial example code.

Intro
Part 1 - Loading Images for LWJGL
Part 2 - Loading Sounds for LWJGL
Part 3 - TrueType Fonts for LWJGL

Slick-Util (Part 2) - Loading Sounds for LWJGL

Intro
Part 1 - Loading Images for LWJGL
Part 2 - Loading Sounds for LWJGL
Part 3 - TrueType Fonts for LWJGL

As Java has built in support for the WAV and AIF format Slick-Util can load these sound formats out of the box. Additionally Slick-Util supports the OGG and XM formats using external libraries. Sound formats can either be completely loaded into memory or streamed from the file.

OGG Support
OGG is a patent free format and comparable to MP3 in features. Slick-Util supports this through the use of the Vorbis library. So if you intend to use OGG files you must also add the jorbis-*.jar and jogg-*.jar library jar files to the classpath, these can be found in the Slick-Util zip download.

XM Format
The XM format is a tracker format and is supported in Slick-Util with the support of the IBXM library. So if your using this format you will also need to add the ibxm.jar library jar to the classpath, it can also be found in the Slick-Util zip download.

Basics
Loading sounds with Slick-Util is pretty easy and similar to how textures are loaded. All the sound files are stored in the Audio class and loaded into that class using the AudioLoader class.

Since you are using OpenAL, do not forget to call the '''AL.destroy()''' method before your application closes. This will clean up the sound resources you are using.

import java.io.IOException;
 
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.openal.AL;
import org.newdawn.slick.openal.Audio;
import org.newdawn.slick.openal.AudioLoader;
import org.newdawn.slick.openal.SoundStore;
import org.newdawn.slick.util.ResourceLoader;
 
public class SoundExample {
	/** The ogg sound effect */
	private Audio oggEffect;
	/** The wav sound effect */
	private Audio wavEffect;
	/** The aif source effect */
	private Audio aifEffect;
	/** The ogg stream thats been loaded */
	private Audio oggStream;
	/** The mod stream thats been loaded */
	private Audio modStream;
 
	/**
	 * Start the test 
	 */
	public void start() {
		initGL(800,600);
		init();
 
		while (true) {
			update();
			GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
			render();
 
			Display.update();
			Display.sync(100);
 
			if (Display.isCloseRequested()) {
				Display.destroy();
				AL.destroy();
				System.exit(0);
			}
		}
	}
 
	/**
	 * Initialise the GL display
	 * 
	 * @param width The width of the display
	 * @param height The height of the display
	 */
	private void initGL(int width, int height) {
		try {
			Display.setDisplayMode(new DisplayMode(width,height));
			Display.create();
			Display.setVSyncEnabled(true);
		} catch (LWJGLException e) {
			e.printStackTrace();
			System.exit(0);
		}
 
		GL11.glEnable(GL11.GL_TEXTURE_2D);
		GL11.glShadeModel(GL11.GL_SMOOTH);        
		GL11.glDisable(GL11.GL_DEPTH_TEST);
		GL11.glDisable(GL11.GL_LIGHTING);                    
 
		GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);                
        GL11.glClearDepth(1);                                       
 
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
 
        GL11.glViewport(0,0,width,height);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
 
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, width, height, 0, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
	}
 
    /**
    * Initialise resources
    */
    public void init() {
 
        try {
	    // you can play oggs by loading the complete thing into 
	    // a sound
	    oggEffect = AudioLoader.getAudio("OGG", ResourceLoader.getResourceAsStream("testdata/restart.ogg"));
 
	    // or setting up a stream to read from. Note that the argument becomes
	    // a URL here so it can be reopened when the stream is complete. Probably
	    // should have reset the stream by thats not how the original stuff worked
	    oggStream = AudioLoader.getStreamingAudio("OGG", ResourceLoader.getResource("testdata/bongos.ogg"));
 
	    // can load mods (XM, MOD) using ibxm which is then played through OpenAL. MODs
	    // are always streamed based on the way IBXM works
	    modStream = AudioLoader.getStreamingAudio("MOD", ResourceLoader.getResource("testdata/SMB-X.XM"));
 
	    // playing as music uses that reserved source to play the sound. The first
	    // two arguments are pitch and gain, the boolean is whether to loop the content
	    modStream.playAsMusic(1.0f, 1.0f, true);
 
	    // you can play aifs by loading the complete thing into 
	    // a sound
	    aifEffect = AudioLoader.getAudio("AIF", ResourceLoader.getResourceAsStream("testdata/burp.aif"));
 
	    // you can play wavs by loading the complete thing into 
	    // a sound
	    wavEffect = AudioLoader.getAudio("WAV", ResourceLoader.getResourceAsStream("testdata/cbrown01.wav"));
        } catch (IOException e) {
	    e.printStackTrace();
	}
    }
 
	/**
	 * Game loop update
	 */
	public void update() {
		while (Keyboard.next()) {
			if (Keyboard.getEventKeyState()) {
				if (Keyboard.getEventKey() == Keyboard.KEY_Q) {
					// play as a one off sound effect
					oggEffect.playAsSoundEffect(1.0f, 1.0f, false);
				}
				if (Keyboard.getEventKey() == Keyboard.KEY_W) {
					// replace the music thats curretly playing with 
					// the ogg
					oggStream.playAsMusic(1.0f, 1.0f, true);
				}
				if (Keyboard.getEventKey() == Keyboard.KEY_E) {
					// replace the music thats curretly playing with 
					// the mod
					modStream.playAsMusic(1.0f, 1.0f, true);
				}
				if (Keyboard.getEventKey() == Keyboard.KEY_R) {
					// play as a one off sound effect
					aifEffect.playAsSoundEffect(1.0f, 1.0f, false);
				}
				if (Keyboard.getEventKey() == Keyboard.KEY_T) {
					// play as a one off sound effect
					wavEffect.playAsSoundEffect(1.0f, 1.0f, false);
				}
			}
		}
 
		// polling is required to allow streaming to get a chance to
		// queue buffers.
		SoundStore.get().poll(0);
	}
 
	/**
	 * Game loop render
	 */
	public void render() {
 
	}
 
	/**
	 * Main method
	 */
	public static void main(String[] argv) {
		SoundExample soundExample = new SoundExample();
		soundExample.start();
	}
}

Additional Credit
Kevin Glass for writing the Slick Library and initial example code.

Intro
Part 1 - Loading Images for LWJGL
Part 2 - Loading Sounds for LWJGL
Part 3 - TrueType Fonts for LWJGL

Slick-Util (Part 1) - Loading Images for LWJGL

Intro
Part 1 - Loading Images for LWJGL
Part 2 - Loading Sounds for LWJGL
Part 3 - TrueType Fonts for LWJGL

Slick-Util supports the PNG, JPG, GIF and TGA image formats. It will load them so that you can use them as OpenGL textures.

Loading an image with Slick-Util is pretty simple. The images details will be stored in Slick-Util's Texture class. The Texture class gives you access to various attributes of the image like width, height, etc. To load an image into the Texture class you use Slick's TextureLoader class and its getTexture() method. You first specify the type of image ("PNG, "TGA", etc) and then the path to the image. The following is an example:

Texture texture;
 
public void init() throws IOException {
 
  texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/image.png"));
}

And that is it, the image is now loaded and you can just use the Texture.bind() method to bind the texture.

A full working example on how to bind a texture onto an OpenGL quad is shown below.

import java.io.IOException;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.Color;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;
 
public class TextureExample {
 
	/** The texture that will hold the image details */
	private Texture texture;
 
 
	/**
	 * Start the example
	 */
	public void start() {
		initGL(800,600);
		init();
 
		while (true) {
			GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
			render();
 
			Display.update();
			Display.sync(100);
 
			if (Display.isCloseRequested()) {
				Display.destroy();
				System.exit(0);
			}
		}
	}
 
	/**
	 * Initialise the GL display
	 * 
	 * @param width The width of the display
	 * @param height The height of the display
	 */
	private void initGL(int width, int height) {
		try {
			Display.setDisplayMode(new DisplayMode(width,height));
			Display.create();
			Display.setVSyncEnabled(true);
		} catch (LWJGLException e) {
			e.printStackTrace();
			System.exit(0);
		}
 
		GL11.glEnable(GL11.GL_TEXTURE_2D);               
 
		GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);          
 
        	// enable alpha blending
        	GL11.glEnable(GL11.GL_BLEND);
        	GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
 
        	GL11.glViewport(0,0,width,height);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
 
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, width, height, 0, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
	}
 
	/**
	 * Initialise resources
	 */
	public void init() {
 
		try {
			// load texture from PNG file
			texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/image.png"));
 
			System.out.println("Texture loaded: "+texture);
			System.out.println(">> Image width: "+texture.getImageWidth());
			System.out.println(">> Image height: "+texture.getImageHeight());
			System.out.println(">> Texture width: "+texture.getTextureWidth());
			System.out.println(">> Texture height: "+texture.getTextureHeight());
			System.out.println(">> Texture ID: "+texture.getTextureID());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
 
	/**
	 * draw a quad with the image on it
	 */
	public void render() {
		Color.white.bind();
		texture.bind(); // or GL11.glBind(texture.getTextureID());
 
		GL11.glBegin(GL11.GL_QUADS);
			GL11.glTexCoord2f(0,0);
			GL11.glVertex2f(100,100);
			GL11.glTexCoord2f(1,0);
			GL11.glVertex2f(100+texture.getTextureWidth(),100);
			GL11.glTexCoord2f(1,1);
			GL11.glVertex2f(100+texture.getTextureWidth(),100+texture.getTextureHeight());
			GL11.glTexCoord2f(0,1);
			GL11.glVertex2f(100,100+texture.getTextureHeight());
		GL11.glEnd();
	}
 
	/**
	 * Main Class
	 */
	public static void main(String[] argv) {
		TextureExample textureExample = new TextureExample();
		textureExample.start();
	}
}

Additional Credit
Kevin Glass for writing the Slick Library and initial example code.

Intro
Part 1 - Loading Images for LWJGL
Part 2 - Loading Sounds for LWJGL
Part 3 - TrueType Fonts for LWJGL

Slick-Util Library (Introduction)

Intro
Part 1 - Loading Images for LWJGL
Part 2 - Loading Sounds for LWJGL
Part 3 - TrueType Fonts for LWJGL

What is the Slick-Util Library?
Slick-Util is a small library to enable you to load various image, sound and font formats for use with LWJGL.

Brief Introduction
In order for OpenGL to display images or OpenAL to play sounds, the data needs to be provided to them in the right format. There are lots of different formats out there (png, jpg, xm, ogg, wav, etc). Manually writing a loader for a format is a time consuming task and requires learning how the format is stored and works, so it makes sense to use a library to do this task for you.

Previously LWJGL bundled the Devil and FMOD libraries to assist in loading image and sound formats. However as these were native libraries they required a java wrapper to use and this had to be maintained and updated. This also clashed with LWJGL's minimalistic philosophy. Slick-Util is a pure java alternative to these and is much lighter, requires less maintenance and easier to use with a java library like LWJGL. So those native libraries were dropped and Slick-Util is now the recommended replacement.

Why is it called Slick-Util?
Slick-Util is actually a subset of the Slick2D Library (A 2d games library which uses LWJGL). As Slick2D had features generally useful for all LWJGL games it was only logical to create a subset library which could be used with any LWJGL application (2d or 3d).

Features
Slick-Util provides the following features for LWJGL:

  • Load various image formats for use with OpenGL (png, gif, jpg, etc).
  • Load various sound formats for use with OpenAL (.wav, .xm, .ogg, etc).
  • Load True Type Fonts for use with OpenGL.

Where to get it
You can get the Slick-Util library from here.

Setting up the Slick-Util Library
Just add the slick-util.jar as an external java library to your project like you do with the LWJGL jars.

Intro
Part 1 - Loading Images for LWJGL
Part 2 - Loading Sounds for LWJGL
Part 3 - TrueType Fonts for LWJGL

Tutorial for Setting Up LWJGL with Eclipse

I noticed that alot of people have been asking lately about how to get LWJGL to work with Eclipse, so I wrote a short tutorial on it.

Setting Up LWJGL With Eclipse

Setting up LWJGL with Eclipse

This tutorial will run you through the steps you'll need to get LWJGL setup with the Eclipse IDE.

This can be tricky if you are not familiar with the IDE because unlike most Java libraries LWJGL has two parts, a Java part (lwjgl.jar) and a native code part (*.dll files for Windows, *.so files for linux and *.dylib/*.jnilib for Mac). Both parts must be set in order to use the library.