FPSAnimator hates me

I have a game which uses FPSAnimator for the game loop. The game runs perfectly fine for about a minute, and then becomes choppy. Sometimes, also for seemingly no reason, it might snap back to normal speed. Now, I’m just an amateur programmer, and not great at all with debugging. I can’t really rule out a memory leak, and Netbeans is helping me sort that out, but when debugging comes into play I get stupid.

Does anyone have any thoughts? I don’t know what to post here (as far as code goes), so let me know please.

Are you creating textures every frame, or reading from disk every frame? Otherwise a likely source of choppiness is creating a lot (and I mean a lot) of objects that need to get garbage collected.

Another possibility is that you’re using v-sync and it slows down a little bit java side, but enough to drop an entire frame refresh on the monitor (i.e. 60 fps drops to 30 fps, even if you could get 45-55 fps without v-sync).

No, it’s just the one texture. Not reading from the disk either. I can’t imagine that too many objects are being created… That’s one of the things the Netbeans profilers are good for. I do use vsync, but I just tried turning it off and tweaking the fps desired and the result was horrible. It was choppy and crappy from the start. At least with the original setup the game ran smoothly for a little while and then turned crappy. I’m stumped.

What are you rendering in each frame? Is your code small enough to post?

In the game loop:

//Fixes some stupid bug
gl.glColor3f(1.0f, 1.0f, 1.0f);
// Clear the drawing area
gl.glClear(GL.GL_DEPTH_BUFFER_BIT);// | GL.GL_COLOR_BUFFER_BIT);
// Reset the current matrix to the "identity"
gl.glLoadIdentity();
//Set the view
gl.glOrtho(-8f, 7f, -4f, 3f, 0.1f, 100f);
update(gl);
mapMan.draw_map(gl);

(Part of) the update method:

else if((key_set[3] && !player.get_moving() && mapMan.collision(player.get_player_position('x'), player.get_player_position('y') + 1)) || (player.get_coord('y') > 0 && player.get_coord('y') <= 1f))
        {
            if(!player.set_moving(true))
            {
                player.set_stride(player.get_foot() ? 2 : 1);
                player.set_direction(3);
                mapMan.set_passable(player.get_player_position('x'), player.get_player_position('y')+1, false);
            }
            if(player.set_coord('y', 0.05f))
            {
                player.set_foot();
                if(!key_set[3])
                {
                    player.set_stride(0);
                }
                mapMan.set_passable(player.get_player_position('x'), player.get_player_position('y')-1, true);
                update_map(gl);
                mapMan.update_player_tex(gl, player.get_direction()*3+player.get_stride());
            }
            else
            {
                mapMan.update_player(0.0f, -player.get_coord('y'), gl, player.get_direction()*3+player.get_stride());
            }
        }
        else
        {
            player.set_stride(0);
            mapMan.update_player_tex(gl, player.get_direction()*3+player.get_stride());
        }

Ugh yes I know that’s complex. And that’s just for the down direction. I have not yet optimized it in any way. Lastly:


    public void draw_map(GL gl)
    {
        engine.pass_tex().bind();
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
        gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);

        for(int index = 0; index < VBOtex.length-1; index++)
        {
            gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, VBOtex[index]);
            gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0);
            gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, VBOVertices[0]);
            gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
            gl.glDrawArrays(GL.GL_QUADS, 0, vertexCount);
        }
        gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, VBOtex[4]);
        gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0);
        gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, VBOVertices[1]);
        gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
        gl.glDrawArrays(GL.GL_QUADS, 0, 12);

        gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
    }

The for loop is for drawing all four layers of the map. Ummmm… probably not the best way to do it but I’m still figuring things out.

Thanks for the help.

Never mind I thought I had the answer but it turns out NOPE.

It doesn’t look like your graphics code should be slow at all, certainly nothing that would drop you less than 60fps and make it stutter. You are doing collision detection in your update method, and that might be expensive and slow (I don’t know how many things there are, or how fancy you’re getting), so I’d try to time that method.

You can add some poor-man’s profiling by wrapping calls to a method with something like:


long now = System.nanoTime();
callMethod();
System.out.println("callMethod() took " + ((System.nanoTime() - now) / 1e6f));

and you can time the update method and a single game loop to see what is eating up your performance.

If the methods run fast enough nanoTime() might not be very accurate, so you can accumulate times across multiple loops:


static long updateTime = 0;
static long totalTime = 0;
static int count =0;
// ....
public void loopOnce() {
   totalTime -= System.nanoTime();
   // do some things such as glClear()

   updateTime -= System.nanoTime();
   update()
   updateTime += System.nanoTime();

   // more loop things, such as:
   draw_map(gl);
   totalTime += System.nanoTime();
 
   count++;
   if (count > 10) {
      float avgTotalMillis = totalTime / (1e6f * 10);
      float avgUpdateMillis = updateTime / (1e6f * 10);

      System.out.println("Performance, update = " + avgUpdateMillis + " ms, total = " + avgTotalMillis + " ms");
      count = 0;
      updateTime = 0;
      totalTime = 0;
   }
}

Dude… I never program when I’m drunk (like I am now). However you’re awesome. I will try that. I should say though, that the collision method is not the problem. It takes two ints. Those ints are coordinates in a 2d array. The method returns a simple boolean. I never paid attention in class but that should take a constant amount of time (and not much at theat). Collision aint no problem.

What the hell is up with my code? This is killing me. My pre-VBO code has this problem too.

OKAY. Maybe I should code while drunk. Another post giuy said to release the VBO bindings when done with them. I did that, and ran the program. I let it sit for two minutes, after which point it usually stutters. IT DID NOT. I will do more testing but I am hopeful.

If all you’re doing is checking the player’s position in an array, to see if it’s in a bad spot, then yes the collision detection will be constant time. Usually collision detection in games checks the player with everything (ie in physics) and that can be done in a lot of stupid ways but it doesn’t sound like your collision detection is doing that type of work.

Not really sure about the releasing of VBOs. It’s still a best practice to release VBOs so keep that code in, but in my experience I don’t every remember having that be a speedup. It’s possible that your graphics card is doing something weird and gets in an unoptimized state if there is a VBO bound and you disable the vertex/texture client states. But that’s all conjecture.

[quote=“lhkbob,post:10,topic:36494”]
Well I’m still drunk so I won’t do any more testing (I can’t trust the results in this state) but I think the results were very promising with my fix.

EDIT - No, that did not solve anything. The game still started stuttering.