Made a simple image drawer that is choppy and ugly...

Hey guys, I made a simple program to get myself familiar with LWJGL before converting a Java2D game over to it. I got it to display an image and draw it to the screen, moving around as you press different arrow keys.

The image looks fine, except it seems like only part of it is refreshed at a time. The image gets choppy and parts sort of drag behind as you move it along. I’m guessing LWJGL will not always be like this, and the problem is most likely in my code. I used Kevin’s Texture, TextureLoader, and Sprite classes from the Space Invaders game provided on LWJGL’s source forge, then simplified his main Game class to display a single image.

Here’s my Main class.


import org.lwjgl.LWJGLException;
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;

public class Main
{
	private boolean fullscreen;
	private TextureLoader textureLoader;
	private ImageViewer imageViewer;
	private boolean running;
	int x, y;
	
	public Main (boolean fs)
	{
		fullscreen = fs;
		initialize();
	}
	
	public void initialize()
	{
		// initialize the window beforehand
		try
		{
			setDisplayMode();
	      	Display.setTitle("LWJGL Sprite Tester");
	      	Display.setFullscreen(fullscreen);
	      	Display.create();
	      	running = true;
	      	x = y = 100;
      
			// grab the mouse, dont want that hideous cursor when we're playing!
			Mouse.setGrabbed(true);
	
			// enable textures since we're going to use these for our sprites
			GL11.glEnable(GL11.GL_TEXTURE_2D);
	
			// disable the OpenGL depth test since we're rendering 2D graphics
			GL11.glDisable(GL11.GL_DEPTH_TEST);
	
			GL11.glMatrixMode(GL11.GL_PROJECTION);
			GL11.glLoadIdentity();
	
			GL11.glOrtho(0, 800, 600, 0, -1, 1);

			textureLoader = new TextureLoader();
			imageViewer = new ImageViewer(textureLoader);
		}
		catch (LWJGLException le)
		{
			System.out.println("Game exiting - exception in initialization:");
			le.printStackTrace();
			return;
		}
	}
	
	private boolean setDisplayMode()
	{
		try
		{
			DisplayMode[] dm = org.lwjgl.util.Display.getAvailableDisplayModes(800, 600, -1, -1, -1, -1, 60, 60);

			org.lwjgl.util.Display.setDisplayMode(dm, new String[]
			     {
					"width=" + 800,
					"height=" + 600,
					"freq=" + 60,
					"bpp=" + org.lwjgl.opengl.Display.getDisplayMode().getBitsPerPixel()
			     }); 
			return true;
		} catch (Exception e)
		{
			e.printStackTrace();
			System.out.println("Unable to enter fullscreen, continuing in windowed mode");
		}
		return false;
	}

	//Within this loop, everything happens
	private void mainLoop()
	{
		running = true;
		while (running)
		{
			// refresh screen, similar to repaint
			GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
			GL11.glMatrixMode(GL11.GL_MODELVIEW);
			GL11.glLoadIdentity();

			// the equivalent of a paint(Graphics g) method
			paint();

			// update window contents
			Display.update();
			
			//evaulates keyboard entries
			keyboard();
		}
	}
	
	private void paint()
	{
		Display.sync(60);
		//in my actual program a sprite is created once and referenced from memory
		//simply changed to not reference another class
		new Sprite(tl, "splash.gif").draw(x,y);
	}
	
	private void keyboard()
	{
		if (Keyboard.isKeyDown(Keyboard.KEY_LEFT))
			x -= 5;
		if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT))
			x += 5;
		if (Keyboard.isKeyDown(Keyboard.KEY_UP))
			y -= 5;
		if (Keyboard.isKeyDown(Keyboard.KEY_DOWN))
			y += 5;
	}
	
	public static void main(String[] args)
	{
		Main m = new Main(true);
		m.mainLoop();
	}
}

If you guys need me to put Kevin’s code up here, let me know. It seems to me that perhaps I am somehow calling the update() method midway through updating the image’s location, or something like that. Help is appreciated.

PS – Should I just switch to DevIL?

Oh, while I’m here, what exactly does the Display.sync(int) method do? Does it try to make the game update at that many fps?

The sync() method does indeed try and sync the FPS to the value you specify. For right now I’d suggest you remove it. Also, creating a new Sprite() each loop might be painful, try creating that once at initialisation and just redrawing it.

It sounds like what you’re seeing is “tearing” of the image. Try enabled the vsync (Display.setVSyncEnabled(true)?) at initialisation.

Kev

Yeah, that seemed to fix it. Thanks, Kev.