Fastest possible way to draw 2D...

Ok, so I need to draw 2d graphics for my game.

It’s sprite based, so I have quads with some texture on them.

They way i’m doing it now is I save the sprites with each texture into seperate displaylists. Then whenever I need to draw an actor in my game, i push, translate, callList, pop.

It seems this is quite slow… How can I optimize my code?


    @Override
    public void draw(GL gl)
    {
        gl.glPushMatrix();
        gl.glTranslated(pos.x, pos.y-20 + pos.z, 0);
        gl.glColor4d(1, 1, 1, 1);
        int x = currentAnim[frame][0];
        int y = currentAnim[frame][1];
        spriteBuffer.drawFrame(gl, x, y);
        gl.glPopMatrix();
    }

spriteBuffer.drawFrame(…) calls a displaylist dependant on what frame of animation I ask for. Any help would be nice :slight_smile:

How do you define your display list? How many quads do you draw? What is your machine specs? And what programming language is it? Java?

You don’t use the most effective rendering method (using texture atlas would eliminate much of CPU overhead), but on modern machines you shouldn’t experiance bad performance even with an unoptimized approach like yours.

1.6 ghz dual core pentium(something)
2 gb ram
Intel graphics media 945gm (I think its called that)
I havent counted them, but I should average at most 500-1000 quads. And this is java running on Linux.

The whole displaylist thing is new to me(everything about OpenGL kinda is)

Here is what I use for generating my displaylists:


    public int[][] getSpriteList(SpriteBuffer spriteBuffer)
    {
        gl.glEnable(GL.GL_BLEND);
                        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
        int[][] frames = new int[spriteBuffer.rows][spriteBuffer.cols];
        for (int i = 0; i < spriteBuffer.rows; i++)
        {
            for (int j = 0; j < spriteBuffer.cols; j++)
            {

                frames[i][j] = gl.glGenLists(1);



                double frameHeight = spriteBuffer.frameHeight;
                double frameWidth = spriteBuffer.frameWidth;
                double framePlusI = spriteBuffer.frameHeight * i;
                double framePlusJ = spriteBuffer.frameWidth * j;

//                gl.glColor4f(1, 1, 1, 1);

                int width = 1;
                int height = 1;
                gl.glNewList(frames[i][j], GL.GL_COMPILE);
                spriteBuffer.spriteSheet.enable();
                spriteBuffer.spriteSheet.bind();
                gl.glEnable(GL.GL_TEXTURE_2D);




                gl.glEnable(GL.GL_ALPHA_TEST);
                gl.glAlphaFunc(GL.GL_GREATER, 0);
                gl.glBegin(GL.GL_POLYGON);
                gl.glTexCoord2d(framePlusJ + 0.0f, framePlusI);
                gl.glVertex3f(-width, height, 1.0f);	// Top Left Of The Texture and Quad
                gl.glTexCoord2d(framePlusJ + frameWidth, framePlusI);
                gl.glVertex3f(width, height, 1.0f);	// Bottom Left Of The Texture and Quad
                gl.glTexCoord2d(framePlusJ + frameWidth, framePlusI + frameHeight);
                gl.glVertex3f(width, -height, 1.0f);         // Bottom Right Of The Texture and Quad
                gl.glTexCoord2d(framePlusJ + 0.0f, framePlusI + frameHeight);
                gl.glVertex3f(-width, -height, 1.0f);	// Top Right Of The Texture and Quad
                gl.glEnd();


                spriteBuffer.spriteSheet.disable();
                gl.glDisable(GL.GL_TEXTURE_2D);
                gl.glDisable(GL.GL_ALPHA_TEST);
                gl.glEndList();


            }
        }
        return frames;
    }

I don’t have extensive knowledge on opengl, so some of the calls I havent fully understood, and hence I use them based on some examples, though my general understanding of opengl should be “sufficient”.

this is probably the main reason, the main problem is that you keep rebinding the textures individually for each quad and then most often with a new texture, that means a huge cpu overhead and is the reason it’s slow.

a texture atlas or two is probably the way to go for you.
If you had a better card i would also suggest looking into geometry shaders and texture arrays, but that is not possible on a Intel graphics media 945gm.

Just a question: are you sure your OpenGL is 3d accelerated? What kind of driver do you use for your IGP card? How many FPS does glxgears run?

Well, not too sure. I’m using whatever drivers ubuntu came up with, but im getting roughly the same fps in windows so it should be fine(windows is definately using appropiate drivers).

I’m getting 60 fps on gears, but this is due to the new 8.10 of ubuntu, my drivers f’ed up now. I cant really test it untill i fix the drivers. I will do a clean install soon so I can provide you with more useful information(and continue my game-project).

[quote=“zeoverlord”]

this is probably the main reason, the main problem is that you keep rebinding the textures individually for each quad and then most often with a new texture, that means a huge cpu overhead and is the reason it’s slow.

a texture atlas or two is probably the way to go for you.
If you had a better card i would also suggest looking into geometry shaders and texture arrays, but that is not possible on a Intel graphics media 945gm. [/QUOTE]

It turns out that I’m already using a kind of “texture atlas” in my tilemap-system. This is something which I can easily change so I only bind my texture once. And of course I can do this with my particle system aswell, so this will probably help alot. I wont be able to test it now though, but thanks alot for your attention :slight_smile: This was a great help(I hope)!

Your FPS is probably limited at 60 because that’s the vertical refresh rate of you monitor and the OpenGL settings of your card are set to swap the front and back color buffer in sync with this refresh rate.

I don’t how you can disable that with an Intel card but for an Nvidia, I set
$ export __GL_SYNC_TO_VBLANK=0
or I use nvidia-settings and I uncheck “Sync to VBlank”.