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

LWJGL

LWJGL

NeHe Tutorials for LWJGL

The NeonHelium (NeHe) OpenGL tutorials are one of the most widely used resource for people starting to learn OpenGL. The tutorials are starting to show their age now as they mostly cover old techniques but are still a good place to get started with OpenGL.

Basic LWJGL Tutorial 5

Added the fifth tutorial in the series of tutorials to cover the basics of LWJGL.

LWJGL Basics 5 (Fullscreen)

Basic LWJGL Tutorial 4

Added the forth tutorial in the series of tutorials to cover the basics of LWJGL.

LWJGL Basics 4 (Timing)

Basic LWJGL Tutorial 3

Added the third tutorial in the series of tutorials to cover the basics of LWJGL.

LWJGL Basics 3 (The Quad)

LWJGL Basics 3 (The Quad)

Introduction
This tutorial will explain how to access OpenGL with LWJGL and is not intended to teach you OpenGL. The LWJGL OpenGL API pretty much maps 1:1 onto the C version (with a few exceptions). This allows one to easily use or adapt any of the many OpenGL tutorials and guides available online and elsewhere for use with LWJGL.

Structure
All the OpenGL methods are found in the org.lwjgl.opengl.* package and are stored in relevant named classes e.g. GL11, GL12, GL13, GL20, ARBVertexShader, ARBFragmentShader, etc.

All methods from OpenGL 1.1 are found in the class GL11, All methods introduced in OpenGL 1.2 are found in the class GL12, etc. This allows one to easily identify and target specific versions or extensions of OpenGL.

Drawing a Quad with OpenGL
The code from the Display tutorial will be used with a few modifications to draw a quad on the Display. A 2d view should be sufficient for drawing a quad, this will be set by using an orthographic matrix of size 800*600 with a clipping distance between 1 and -1. This only needs to be set once and will be called outside the main loop.

GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 800, 0, 600, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);

The remaining code needs to be called every frame and will go in the main loop. This will clear the screen, set the color of the quad, and draw the verticies of the quad.

// Clear the screen and depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);	
 
// set the color of the quad (R,G,B,A)
GL11.glColor3f(0.5f,0.5f,1.0f);
 
// draw quad
GL11.glBegin(GL11.GL_QUADS);
    GL11.glVertex2f(100,100);
    GL11.glVertex2f(100+200,100);
    GL11.glVertex2f(100+200,100+200);
    GL11.glVertex2f(100,100+200);
GL11.glEnd();

A full working example is found below

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
 
public class QuadExample {
 
    public void start() {
        try {
	    Display.setDisplayMode(new DisplayMode(800,600));
	    Display.create();
	} catch (LWJGLException e) {
	    e.printStackTrace();
	    System.exit(0);
	}
 
	// init OpenGL
	GL11.glMatrixMode(GL11.GL_PROJECTION);
	GL11.glLoadIdentity();
	GL11.glOrtho(0, 800, 0, 600, 1, -1);
	GL11.glMatrixMode(GL11.GL_MODELVIEW);
 
	while (!Display.isCloseRequested()) {
	    // Clear the screen and depth buffer
	    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);	
 
	    // set the color of the quad (R,G,B,A)
	    GL11.glColor3f(0.5f,0.5f,1.0f);
 
	    // draw quad
	    GL11.glBegin(GL11.GL_QUADS);
	        GL11.glVertex2f(100,100);
		GL11.glVertex2f(100+200,100);
		GL11.glVertex2f(100+200,100+200);
		GL11.glVertex2f(100,100+200);
	    GL11.glEnd();
 
	    Display.update();
	}
 
	Display.destroy();
    }
 
    public static void main(String[] argv) {
        QuadExample quadExample = new QuadExample();
        quadExample.start();
    }
}

This should be enough to get started with OpenGL and LWJGL. The LWJGL Javadoc contains a full list of all classes and methods supported by LWJGL and should be used as a reference to find specific OpenGL functionality.

Static Import
All OpenGL methods in LWJGL are accessed statically, meaning the class name is present before the method name. Depending on your coding style you may prefer not to type the class name on every OpenGL method. Java's static import feature can be used here to hide the class names.

import static org.lwjgl.opengl.GL11.*;

The above line imports all the methods from the GL11 class to allow use without specifying the class. The code can now be typed as follows:

// clear the screen and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
 
// set the color of the quad (R,G,B,A)
glColor3f(0.5f,0.5f,1.0f);
 
// draw quad
glBegin(GL_QUADS);
    glVertex2f(100,100);
    glVertex2f(100+200,100);
    glVertex2f(100+200,100+200);
    glVertex2f(100,100+200);
glEnd();

Basic LWJGL Tutorial 2

Added the second tutorial in the series of tutorials to cover the basics of LWJGL.

LWJGL Basics 2 (Input)

Basic LWJGL Tutorial 1

Added a tutorial for LWJGL. This will be the first part in a series of tutorials to cover the basics of LWJGL.

LWJGL Basics 1 (The Display)

LWJGL Basics 4 (Timing)

Timers
Accurate timing is important for any high performance application or game. Typically a timer with an accuracy of at least 1 millisecond is needed.

Java's System.currentTimeMillis() has an accuracy of anywhere between 1 to 55 milliseconds depending on the operating system its run on. This makes it unsuitable for cross-platform games.

System.nanoTime() was introduced in Java 1.5 and is able to produce millisecond accuracy. To get milliseconds from System.nanoTime() the value just needs to be divided by 1,000,000 (nanoseconds -> milliseconds).

/**
 * Get the time in milliseconds
 * 
 * @return The system time in milliseconds
 */
public long getTime() {
    return System.nanoTime() / 1000000;
}

Sys.getTime() is LWJGL's high resolution timer and will return time in 'ticks'. This value can be in any format (nanoseconds, microsecond, milliseconds, etc) whichever is deemed to be best on the platform. The Sys.getTimerResolution() method will return the number of 'ticks' in a second. When both these methods are used together it allows conversion to any required metric (including milliseconds). See the Javadoc for LWJGL Sys class for more information.

To get milliseconds from Sys.getTime(), the 'ticks' are multiplied by 1000 so that the end result will be in milliseconds and then divide by the number of ticks in a second.

/**
 * Get the time in milliseconds
 * 
 * @return The system time in milliseconds
 */
public long getTime() {
    return (Sys.getTime() * 1000) / Sys.getTimerResolution();
}

Either of the timers above should be sufficient.

Delta Time
In many games an int value (usually called delta) is used to store the number of milliseconds that have passed since the last frame. This value can be used to move entities in the game in a frame independent way. Meaning that regardless of how fast or slow the fps is everything should move at a constant speed.

This value is calculated by saving the time from the timer every frame and subtracting it from the time on the previous frame.

public int getDelta() {
    long time = getTime();
    int delta = (int) (time - lastFrame);
    lastFrame = time;
 
    return delta;
}

Sleeping and Display.sync()
Sleeping is very important in games and is needed otherwise the game loop will run as fast as possible, taking up all the system resources and in most cases heating CPU's, GPU's and draining batteries. Sleeping will allow the application to sleep and thus not use all the resources on the computer. There are various loops that can be created using options like Thread.sleep() and Thread.yield(). However LWJGL provides the method Display.sync(int fps) to make this easier. This method allows the game loop to run at the specified frame rate (e.g 60fps) and sleep for any extra time. This method must be called every frame (i.e. put it in the game loop). Vsync is another option that can be used to achieve this but that will be covered in a later tutorial.

Calculating FPS
Frame Per Second can be calculated by incrementing an int variable every frame and after a second has passed showing this value to the user (the value is reset to 0 thereafter for next frame). For simplicity we will use the Display.setTitle(String title) method to display the frame rate in the window title.

public void start() {
    lastFPS = getTime(); //initialise lastFPS by setting to current Time
}
 
/**
 * Calculate the FPS and set it in the title bar
 */
public void updateFPS() {
    if (getTime() - lastFPS > 1000) {
        Display.setTitle("FPS: " + fps);
	fps = 0;
	lastFPS += 1000;
    }
    fps++;
}

The full example below will use the delta value to rotate and move a quad. Use the cursor keys to move the quad around.

import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
 
public class TimerExample {
 
	/** position of quad */
	float x = 400, y = 300;
	/** angle of quad rotation */
	float rotation = 0;
 
	/** time at last frame */
	long lastFrame;
 
	/** frames per second */
	int fps;
	/** last fps time */
	long lastFPS;
 
	public void start() {
		try {
			Display.setDisplayMode(new DisplayMode(800, 600));
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
			System.exit(0);
		}
 
		initGL(); // init OpenGL
		getDelta(); // call once before loop to initialise lastFrame
		lastFPS = getTime(); // call before loop to initialise fps timer
 
		while (!Display.isCloseRequested()) {
			int delta = getDelta();
 
			update(delta);
			renderGL();
 
			Display.update();
			Display.sync(60); // cap fps to 60fps
		}
 
		Display.destroy();
	}
 
	public void update(int delta) {
		// rotate quad
		rotation += 0.15f * delta;
 
		if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) x -= 0.35f * delta;
		if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) x += 0.35f * delta;
 
		if (Keyboard.isKeyDown(Keyboard.KEY_UP)) y -= 0.35f * delta;
		if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) y += 0.35f * delta;
 
		// keep quad on the screen
		if (x < 0) x = 0;
		if (x > 800) x = 800;
		if (y < 0) y = 0;
		if (y > 600) y = 600;
 
		updateFPS(); // update FPS Counter
	}
 
	/** 
	 * Calculate how many milliseconds have passed 
	 * since last frame.
	 * 
	 * @return milliseconds passed since last frame 
	 */
	public int getDelta() {
	    long time = getTime();
	    int delta = (int) (time - lastFrame);
	    lastFrame = time;
 
	    return delta;
	}
 
	/**
	 * Get the accurate system time
	 * 
	 * @return The system time in milliseconds
	 */
	public long getTime() {
	    return (Sys.getTime() * 1000) / Sys.getTimerResolution();
	}
 
	/**
	 * Calculate the FPS and set it in the title bar
	 */
	public void updateFPS() {
		if (getTime() - lastFPS > 1000) {
			Display.setTitle("FPS: " + fps);
			fps = 0;
			lastFPS += 1000;
		}
		fps++;
	}
 
	public void initGL() {
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, 800, 0, 600, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
	}
 
	public void renderGL() {
		// Clear The Screen And The Depth Buffer
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
 
		// R,G,B,A Set The Color To Blue One Time Only
		GL11.glColor3f(0.5f, 0.5f, 1.0f);
 
		// draw quad
		GL11.glPushMatrix();
			GL11.glTranslatef(x, y, 0);
			GL11.glRotatef(rotation, 0f, 0f, 1f);
			GL11.glTranslatef(-x, -y, 0);
 
			GL11.glBegin(GL11.GL_QUADS);
				GL11.glVertex2f(x - 50, y - 50);
				GL11.glVertex2f(x + 50, y - 50);
				GL11.glVertex2f(x + 50, y + 50);
				GL11.glVertex2f(x - 50, y + 50);
			GL11.glEnd();
		GL11.glPopMatrix();
	}
 
	public static void main(String[] argv) {
		TimerExample timerExample = new TimerExample();
		timerExample.start();
	}
}

LWJGL Basics 5 (Fullscreen)

Why use Fullscreen?
There are many reasons for using fullscreen mode which may include the following:
- Changing the screen resolution to get extra speed from the game or better looking graphics.
- Enable VSync to allow tear free graphics.
- Enable a much more immersive experience for users.

Using Fullscreen
Creating a windowed Display was covered in tutorial 1 and is just two lines of code.

Display.setDisplayMode(new DisplayMode(width,height));
Display.create();

To use a fullscreen Display, a DisplayMode that is supported in fullscreen mode must be set and fullscreen must be enabled by calling Display.setFullscreen(true).

Display.setDisplayMode(displayMode);
Display.setFullscreen(true);
Display.create();

What is a DisplayMode?
DisplayMode is a class that encapsulates the various properties that make up the Display. This includes the following properties :

getWidth() - The width of the Display in pixels.
getHeight() - The height of the Display in pixels.
getBitsPerPixel() - Bits per pixel, also sometimes known as the number of colors.
getFrequency() - Refresh rate or frequency of frame drawing.

The initial DisplayMode will be the same as the computers desktop resolution. The original desktop resolution can be obtained at any time as a DisplayMode by calling Display.getDesktopDisplayMode().

Obtaining DisplayModes supported in fullscreen
A list of fullscreen resolutions supported by the graphics card can be obtained by calling the Display.getAvailableDisplayModes() method. This list can then be scrolled through to pick the desired DisplayMode.

DisplayMode[] modes = Display.getAvailableDisplayModes();
 
for (int i=0;i<modes.length;i++) {
    DisplayMode current = modes[i];
    System.out.println(current.getWidth() + "x" + current.getHeight() + "x" +
                        current.getBitsPerPixel() + " " + current.getFrequency() + "Hz");
}

The DisplayMode is set by using Display.setDisplayMode(). If the Display has already been created then the Display will resize immediately to match the new DisplayMode otherwise it will be apply once Display.create() is called.

The current set DisplayMode can be obtained by calling Display.getDisplayMode(), if no DisplayMode is set it will be the same as Display.getDesktopDisplayMode().

The Display.setFullscreen(boolean) method can be used to switch to fullscreen mode or back to windowed mode.

The BitsPerPixel value has pretty much standardised these days to either 32bit color (Windows) or 24bit color (Linux and Mac). It has become rare to find computers that still use the old 16bit, 256 color or even *shock* 16 color modes. Accordingly, it is a good idea to just pick and use the default desktop color value.

The Frequency value is the rate at which frames are drawn. Again its a good idea to just use the default desktop frequency as its more likely to be supported by the monitor (even if the video card supports others). CRT monitors can easily support different frequencies and refresh rates but with TFT monitors now becoming more common it is best to just stick with the default frequncy.

Convenience method to Switch Resolution
Using the above information the following method is an example that will allow finding and switching to a requested DisplayMode.

/**
 * Set the display mode to be used 
 * 
 * @param width The width of the display required
 * @param height The height of the display required
 * @param fullscreen True if we want fullscreen mode
 */
public void setDisplayMode(int width, int height, boolean fullscreen) {
 
    // return if requested DisplayMode is already set
    if ((Display.getDisplayMode().getWidth() == width) && 
        (Display.getDisplayMode().getHeight() == height) && 
	(Display.isFullscreen() == fullscreen)) {
	    return;
    }
 
    try {
        DisplayMode targetDisplayMode = null;
 
	if (fullscreen) {
	    DisplayMode[] modes = Display.getAvailableDisplayModes();
	    int freq = 0;
 
	    for (int i=0;i<modes.length;i++) {
	        DisplayMode current = modes[i];
 
		if ((current.getWidth() == width) && (current.getHeight() == height)) {
		    if ((targetDisplayMode == null) || (current.getFrequency() >= freq)) {
		        if ((targetDisplayMode == null) || (current.getBitsPerPixel() > targetDisplayMode.getBitsPerPixel())) {
			    targetDisplayMode = current;
			    freq = targetDisplayMode.getFrequency();
                        }
                    }
 
		    // if we've found a match for bpp and frequence against the 
		    // original display mode then it's probably best to go for this one
		    // since it's most likely compatible with the monitor
		    if ((current.getBitsPerPixel() == Display.getDesktopDisplayMode().getBitsPerPixel()) &&
                        (current.getFrequency() == Display.getDesktopDisplayMode().getFrequency())) {
                            targetDisplayMode = current;
                            break;
                    }
                }
            }
        } else {
            targetDisplayMode = new DisplayMode(width,height);
        }
 
        if (targetDisplayMode == null) {
            System.out.println("Failed to find value mode: "+width+"x"+height+" fs="+fullscreen);
            return;
        }
 
        Display.setDisplayMode(targetDisplayMode);
        Display.setFullscreen(fullscreen);
 
    } catch (LWJGLException e) {
        System.out.println("Unable to setup mode "+width+"x"+height+" fullscreen="+fullscreen + e);
    }
}

Vsync
For tear free graphics vertical synchronization needs to be enabled. This is enabled/disabled using the Display.setVSyncEnabled(boolean) method. Vsync only works in fullscreen mode as windowed application do not have direct access to or control over the screen and any buffer flipping is handled by the OS. However Vsync can still act as a framerate limiter in windowed mode.

A full working example is found below. Use the 'F' key to switch to and from fullscreen and use the 'V' key to enable or disable VSync.

import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
 
public class FullscreenExample {
 
	/** position of quad */
	float x = 400, y = 300;
	/** angle of quad rotation */
	float rotation = 0;
 
	/** time at last frame */
	long lastFrame;
 
	/** frames per second */
	int fps;
	/** last fps time */
	long lastFPS;
 
	/** is VSync Enabled */
	boolean vsync;
 
	public void start() {
		try {
			Display.setDisplayMode(new DisplayMode(800, 600));
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
			System.exit(0);
		}
 
		initGL(); // init OpenGL
		getDelta(); // call once before loop to initialise lastFrame
		lastFPS = getTime(); // call before loop to initialise fps timer
 
		while (!Display.isCloseRequested()) {
			int delta = getDelta();
 
			update(delta);
			renderGL();
 
			Display.update();
			Display.sync(60); // cap fps to 60fps
		}
 
		Display.destroy();
	}
 
	public void update(int delta) {
		// rotate quad
		rotation += 0.15f * delta;
 
		if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) x -= 0.35f * delta;
		if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) x += 0.35f * delta;
 
		if (Keyboard.isKeyDown(Keyboard.KEY_UP)) y -= 0.35f * delta;
		if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) y += 0.35f * delta;
 
		while (Keyboard.next()) {
		    if (Keyboard.getEventKeyState()) {
		        if (Keyboard.getEventKey() == Keyboard.KEY_F) {
		        	setDisplayMode(800, 600, !Display.isFullscreen());
		        }
		        else if (Keyboard.getEventKey() == Keyboard.KEY_V) {
		        	vsync = !vsync;
		        	Display.setVSyncEnabled(vsync);
		        }
		    }
		}
 
		// keep quad on the screen
		if (x < 0) x = 0;
		if (x > 800) x = 800;
		if (y < 0) y = 0;
		if (y > 600) y = 600;
 
		updateFPS(); // update FPS Counter
	}
 
	/**
	 * Set the display mode to be used 
	 * 
	 * @param width The width of the display required
	 * @param height The height of the display required
	 * @param fullscreen True if we want fullscreen mode
	 */
	public void setDisplayMode(int width, int height, boolean fullscreen) {
 
		// return if requested DisplayMode is already set
                if ((Display.getDisplayMode().getWidth() == width) && 
			(Display.getDisplayMode().getHeight() == height) && 
			(Display.isFullscreen() == fullscreen)) {
			return;
		}
 
		try {
			DisplayMode targetDisplayMode = null;
 
			if (fullscreen) {
				DisplayMode[] modes = Display.getAvailableDisplayModes();
				int freq = 0;
 
				for (int i=0;i<modes.length;i++) {
					DisplayMode current = modes[i];
 
					if ((current.getWidth() == width) && (current.getHeight() == height)) {
						if ((targetDisplayMode == null) || (current.getFrequency() >= freq)) {
							if ((targetDisplayMode == null) || (current.getBitsPerPixel() > targetDisplayMode.getBitsPerPixel())) {
								targetDisplayMode = current;
								freq = targetDisplayMode.getFrequency();
							}
						}
 
						// if we've found a match for bpp and frequence against the 
						// original display mode then it's probably best to go for this one
						// since it's most likely compatible with the monitor
						if ((current.getBitsPerPixel() == Display.getDesktopDisplayMode().getBitsPerPixel()) &&
						    (current.getFrequency() == Display.getDesktopDisplayMode().getFrequency())) {
							targetDisplayMode = current;
							break;
						}
					}
				}
			} else {
				targetDisplayMode = new DisplayMode(width,height);
			}
 
			if (targetDisplayMode == null) {
				System.out.println("Failed to find value mode: "+width+"x"+height+" fs="+fullscreen);
				return;
			}
 
			Display.setDisplayMode(targetDisplayMode);
			Display.setFullscreen(fullscreen);
 
		} catch (LWJGLException e) {
			System.out.println("Unable to setup mode "+width+"x"+height+" fullscreen="+fullscreen + e);
		}
	}
 
	/** 
	 * Calculate how many milliseconds have passed 
	 * since last frame.
	 * 
	 * @return milliseconds passed since last frame 
	 */
	public int getDelta() {
	    long time = getTime();
	    int delta = (int) (time - lastFrame);
	    lastFrame = time;
 
	    return delta;
	}
 
	/**
	 * Get the accurate system time
	 * 
	 * @return The system time in milliseconds
	 */
	public long getTime() {
	    return (Sys.getTime() * 1000) / Sys.getTimerResolution();
	}
 
	/**
	 * Calculate the FPS and set it in the title bar
	 */
	public void updateFPS() {
		if (getTime() - lastFPS > 1000) {
			Display.setTitle("FPS: " + fps);
			fps = 0;
			lastFPS += 1000;
		}
		fps++;
	}
 
	public void initGL() {
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, 800, 0, 600, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
	}
 
	public void renderGL() {
		// Clear The Screen And The Depth Buffer
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
 
		// R,G,B,A Set The Color To Blue One Time Only
		GL11.glColor3f(0.5f, 0.5f, 1.0f);
 
		// draw quad
		GL11.glPushMatrix();
			GL11.glTranslatef(x, y, 0);
			GL11.glRotatef(rotation, 0f, 0f, 1f);
			GL11.glTranslatef(-x, -y, 0);
 
			GL11.glBegin(GL11.GL_QUADS);
				GL11.glVertex2f(x - 50, y - 50);
				GL11.glVertex2f(x + 50, y - 50);
				GL11.glVertex2f(x + 50, y + 50);
				GL11.glVertex2f(x - 50, y + 50);
			GL11.glEnd();
		GL11.glPopMatrix();
	}
 
	public static void main(String[] argv) {
		FullscreenExample fullscreenExample = new FullscreenExample();
		fullscreenExample.start();
	}
}

LWJGL Basics 2 (Input)

LWJGL handles its own input with its Keyboard and Mouse classes. In order to get updates the Keyboard and Mouse classes must be polled. This is done automatically when you call the Display.update() method therefore the poll() method in those classes does not need to be called manually.

The Mouse
The position of the Mouse on the Display can be obtained by calling the following methods:

int x = Mouse.getX(); // will return the X coordinate on the Display.
int y = Mouse.getY(); // will return the Y coordinate on the Display.