opengl 2D performance

Hello,
Basicly im using jogl to write a 2D game. The problem is that its much slower than i expected. Curently im working on some old computer with some 1,6Ghz cpu and some acient Geforce card, still i remember pretty decent fps when i played years ago some quake 3 engine based games ;).
In my engine(well maybe engine is too big word for now ;)) i get 30-35, and that is after some basic optimalzations i’ve made: culling - without it was horrible.
Needless to say im disspointed since i expected simple 2d game to be much less resource demanding than quake iii.
I have about 300 textured quads on my screen, most of them are ground tiles. Without the ground i get twice as much fps, still i expected some crazy number like 400 or something.
There might be something wrong in my code(its a mess so i’ll post only the opengl part):


	public void init(GLAutoDrawable glDrawable) {	
		GL gl = glDrawable.getGL();
		gl. glEnable( GL.GL_BLEND );
		gl. glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA );
		gl.glEnable(GL.GL_TEXTURE_2D);
		gl.glClearColor(255, 255, 255, 0);
		gl.glViewport(0, 0, width, height);
		gl.glDisable(GL.GL_DEPTH_TEST);		
	

		initGame();
		
		animator = new Animator(glDrawable);		
		animator.start();
	}

	public void display(GLAutoDrawable glDrawable) {		
		GL gl=glDrawable.getGL();
		
		gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
		gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glLoadIdentity();	
		...//drawing sprites
		gl.glFlush();
		
	}


and the method i use to draw the sprite:


	public void draw(GL gl , boolean bind) {
		Texture texture = getTexture();
		if(bind){
			texture.enable();
			texture.bind();
		}
    	TextureCoords coords = texture.getImageTexCoords();

		gl.glPushMatrix();
		gl.glTranslatef(x, y, 0);		
		gl.glColor3f(1,1,1);
        gl.glBegin(GL.GL_QUADS);
        {
            gl.glTexCoord2f(coords.left(), coords.top());
            gl.glVertex2f(0, 0);            
            gl.glTexCoord2f(coords.left(), coords.bottom());
            gl.glVertex2f(0, height);            
            gl.glTexCoord2f(coords.right(), coords.bottom());
            gl.glVertex2f(width, height);            
            gl.glTexCoord2f(coords.right(), coords.top());
            gl.glVertex2f(width, 0);
        }
		gl.glEnd();
		//texture.disable();
		gl.glPopMatrix();
	}

Any ideas?
thanks

Ofcourse we could all write up pages upon pages of optimalisations, but you could also Google it yourself.

Of course, you could just close this subforum since there is google and anyone can use it. Come on man? what is the point of your post? You just simply had 2004 posts and wanted to have 2005? or is there something deeper behind it?

The point is that Googling this stuff yourself is way faster than waiting for an answer on this forum, on which this topic has been beaten to death anyway, so there are more than enough threads for you to dig that info up.

Just show you invest some time into solving a problem, and people are much more likely to help. Your posting feels like: here’s my code, figure out my problem and point out the obvious. I mean… come on put some effort in it.

Oh, and I don’t care about my postcount.

Listen, instead of posting just to say that you are not going to help, just don’t post at all and everyone will be happy. You post to say nothing smarter than ‘google for it nub’ and even worse you discourage other people form helping.
I didn’t ask exacly you to help me, so please don’t post in any of my threads.
thank you.

Oh go on then I’ll help.

  1. You’re using immediate mode rendering. That’s the very slowest way to render things to the screen there is.

  2. You push/translate/pop for every sprite; again, pretty much the slowest possible way to draw, as it flushes the graphics pipeline every time.

Oh, and possibly best to ask OpenGL performance questions over on the OpenGL.org beginner boards too, there are a lot more people there who know what they’re doing than in here!

Cas :slight_smile:

Thank you for your reply. Actually i thought there must be something wrong with my code but its seems that opengl is a bit slower than i expected :). I expected a simple 2d game to be blazing fast without any optimalizations.
I’ll investigate retained mode rendering, i think this is something i need.

I tryied to change that, and to do push and pop only when the texture is changed but i didn’t notice the fps boost. Eariler i implemented sprite sorting by texture, to avoid unnesesery texture binding but it only gave me something like 2 fps and i was a bit disppointed ;).

One of the problems is that you use one glBegin/glEnd per quad.

So if you have the code around to sort by texture, you should also group all those quads in the same glBegin/glEnd to boost your performance significantly.

This will most likely boost your performance quite a bit, after which you can move to vertex arrays, or vertex buffer objects.

Or merging a few textures into 1 big texture to avoid bindings, and allowing you to group more quads in your glBegin/glEnd.

Don’t bother with the matrix stack for sprite positioning, just calculate the coords yourself manually and it’ll be much faster - especially if you’ve only got basic translation going on.

The exception to that is camera positioning, where the matrix stack is much more useful and is only done a handful of times a frame so it’s not an issue.

Maybe you could use my algorithm of cells-and-portals subdivision (the implementation is under GPL license), I think it may be used in a 2D game, it might allow you to pass a smaller part of the whole geometry, otherwise you could use a BSP tree. If you need some examples of Java 2D games, go to the FGF players’ portal, we have a lot of Java open source 2D games available, the only problem is that this current version of the portal is only on Facebook, the web version is not ready.

Thank you for your anwsers. Removig the matrix stack and using glBegin/glEnd only when the texture is changed gave me 15-20 fps boost, which will probably drop once i put more objects on the screen ;).
And no, I’m not interested in using any GPL code, since i don’t want to make an opensource game.

Your next step should probably be to switch from glBegin/End to using vertex arrays (in your case this probably means using glDrawArrays). A quick google found this which should point you in the right direction.

gl.glDisable(GL.GL_DEPTH_TEST);
[…]
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

Very funny. If you don’t use it don’t clear it. If you overdraw everything either way don’t bother with clearing. It’s pointless.

Don’t enable/disable textures over and over again. Enable it and draw your stuff. If you need to disable it for a few things disable it there, draw that stuff, and enable it again.

Before you bind a texture check if it’s already bound (keep track of it with some variable).

Reduce the number of state changes where possible.

Well, even with immediate mode rendering you can render approximately 2000 sprites with a gf1ddr (or gf2mx classic or gf2mx 400) on a 500mhz machine - if the same texture is used for all of em (and no rebinding happens). Even with individual per-sprite begin-quad and end blocks.

Actually, that’s not true. The drivers do that already - for textures, VBOs and FBOs.

Try it, and you’ll see checking it yourself is slightly slower, due to the double check.

Checking it myself gave me a speed boost of about 10% on my gf2mx. It’s sensible to do that stuff on the driver side, but it seems that they’d forgotten to do it here n there.

Seems like it depends on the driver version (or whether it is nVidia, Intel or ATi/AMD)

Thanks for pointing that out! This was really slowing thigns up. Now i get ~20 fps more :).

WTF! That’s weird… Everybody and their dog clears the depth buffer in a 3D game, and it certainly doesn’t/shouldn’t affect framerate that much.

In case you need the depth buffer later on, also clear the stencil buffer. clearing both is much faster than clearing one of them, as their memory is interleaved.

Some cards have fast-erase for the depth buffer and it costs almost nothing; other cards don’t. Assume it’s one of the ones that don’t, and don’t clear it. Especially if you’re doing 2D - no need for a depth buffer in the first place!

Cas :slight_smile:

Acutally now i don’t clear neither color buffer nor the depth buffer. Maybe my graphics card is broken or something but clearing any of these buffers slows everything by 20-30 fps.