[Resolved] LWJGL Rendering Loop -- Stuttery Performance!

Hiya everyone! I am new to using LWJGL and OpenGL, and I am having a problem with my time-based game loop.
When I run the program, the graphics just seem to stutter occasionally, and I have a bad feeling that it is some oversight in my code causing the problem.
If anyone could be nice enough to look over these portions of my code and tell me what my problem is, I would greatly appreciate it!

I will explain the system so maybe from my explanation you could find a flaw and not even have to look in the code:

I have two base classes, GameWindow and GameControl. GameWindow contains the main() method. Each class has a reference to the active instance of the other class.
GameWindow begins by intializing Display, setting the title, display modes and everything and initializes OpenGL. In then sets the boolean programRunning to true and begins the game loop, contained in GameControl.

GameControl’s game loop works like this:

  1. set variable beforeLoop to System.nanoTime()
  2. Yield the thread
  3. Poll the keyboard for input
  4. run method programLifeTime, passing the value of variable delta, which is a method that keeps track of how long the program has been running.
  5. run method renderGame, which limits the frame rate to a preset value, according to a calculated time period based off of the preset value. For example, if the Desired FPS is 60, the period of time to wait before rendering again would be 16666666 ns. It only renders a maximum of once per loop, then resets the time counter (code example below).
  6. run method updateGame, which then passes the delta value to the requisite areas for game updating.
  7. Update the Display
  8. calculate the delta value according to System.nanotime() - beforeLoop

OpenGL Initialization



private void initGL() {
		// enable textures since we're going to use these for our sprites
		GL11.glEnable(GL11.GL_TEXTURE_2D);
	        GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading
	        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
	        GL11.glClearDepth(1.0); // Depth Buffer Setup
		// 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.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);
		
		GL11.glOrtho(0, windowWidth, windowHeight, 0, -1, 1);
	}

Game Loop



public void gameLoop() {
		
		beforeLoop = System.nanoTime();
		
		Thread.yield();
		Keyboard.poll();
		processKeyboard();
		
		programLifeTime(delta);
		renderGame(delta);
		updateGame(delta);
		
		Display.update();
		
		delta = System.nanoTime() - beforeLoop;
		
	}

public void updateGame(long delta) {
		Display.setTitle(gameWindow.getWindowTitle() + " | Elapsed Time- " + lifeSpanMinutes + "m:" + lifeSpanSeconds + "s " + "FPS: " + currentFPS);
		
		for(int x = 0; x < 10; x++) {
			rect[x].updateEntity(delta);
		}
	}
	
	public void renderGame(long delta) {
		FPS_TIME_ELAPSED = FPS_TIME_ELAPSED + delta;
		fpsCounterTimer = fpsCounterTimer + delta;
		if(FPS_TIME_ELAPSED >= FPS_PERIOD) {
			FPS_TIME_ELAPSED = 0;
			try {
				// clear screen
				GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
				GL11.glMatrixMode(GL11.GL_MODELVIEW);
				GL11.glLoadIdentity();
				} catch(Exception e) {
					e.printStackTrace();
					System.exit(0);
				}
			render();

			fpsCounter++;
			if(fpsCounterTimer > 1000000000) {
				currentFPS = fpsCounter;
				fpsCounter = 0;
				fpsCounterTimer = 0;
			}
		}
	}


And here is my rendering code for rendering a quad (the code stutters even with just a single moving quad on the screen):


public void drawSprite(float x, float y) {
		
		// Set the color to draw geometry as
		GL11.glColor3f(1.0f, 0f, 0f);
		
		GL11.glBegin(GL11.GL_QUADS);
		
		// Upper-Left vertex
		GL11.glVertex2f(x - (width/2), y - (height/2));
		// Bottom-Left vertex
		GL11.glVertex2f(x - (width/2), y + (height/2));
		// Bottom-Right vertex
		GL11.glVertex2f(x + (width/2), y + (height/2));
		// Top-Right Vertex
		GL11.glVertex2f(x + (width/2), y - (height/2));
		
		GL11.glEnd();
		
	}

I know this is alot of code and a huge post to look over and maybe not even enough to find my problem, but if anyone could, I would be so happy!
I cannot figure out why my code stutters!
Thank you so much in advance!

You may want to try the specific LWJGL forum. Maybe post a pointer to this message over there…

Two suggestions:

  1. Since your render(long delta) method only does something some of the time, maybe you should only call Display.update() when something has been done in render(long delta). So maybe put the Display.update() call inside the work block of render(long delta). I don’t think that should matter though.

  2. Normally you want to limit the frame rate of the whole game loop, not just the rendering rate. Besides your Thread.yield() call, the game loop is spinning as fast as it can in a fast loop and periodically rendering. What you would prefer is if the loop slept in between frames. Unfortunately it is somewhat difficult to get accurate sleeps on Windows with Java. Thread.sleep() on Windows has a minimum sleep time of ~15ms no matter what you tell it to do, which automatically drops your frame rate to a maximum of 66. In my project I’m using the Display.sync(int framerate) method which is a very convient way to limit the framerate. It isn’t perfectly accurate either, but it lets you sync up framerates in excess of 60fps pretty easily.

Incidentally I’d point out that I’ve heard elsewhere on these boards that Thread.yield() is often pointless or counterproductive, particularly when all the threads of interest are running at the same priority.

Try Display.sync(int framerate) to sleep your whole loop and see if your situation improves.


public void gameLoop() {

Keyboard.poll();
processKeyboard();

programLifeTime(delta);
renderGame(delta);
updateGame(delta);

Display.update();

[b]Display.sync(desiredFramerate);[/b]
}

And remove the framerate limiting code from renderGame();

PS.
It is also customary, when updating & rendering once per frame, do update first and render last, rather than vice-versa.

Thanks so much for your help anarchotron!
You really helped me clean up the loop – I can now see how horribly inefficient it was before ;D.
Now my animations move across the screen with much smoother graphics and the loop runs through much less often.

Thanks alot!!!