Jump to content
  • Advertisement
Sign in to follow this  
Totologic

OpenGL Sprite batching performance

This topic is 1264 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi.

 

I am working on a sprite batcher in OpenGL. I use OpenGL 3.1 and GLSL #version 110.

 

My batcher has the following features:

- it works with 1 single atlas texture

- no persistence, meaning you push your whole list of sprites every frame

- each sprite can have his own UV on the atlas and his own 3x3 matrix transformation

- a camera with his own 4x4 matrix

 

The  "no persistence" feature is a choice I made to keep the API very simple. No need to "add" or "remove" the sprites. Just ask to render what you need each frame independantly .

 

Today the batcher can reach 800 sprites at stable 60FPS on a 800x600 window. Running on my laptop:

 

ASUS i7-267M CPU @ 1.80GHz 1.80GHz

RAM 4Go

GPU Intel(R) HD Graphics Family with 116 ext.

 

Is it good performance ?

 

Note: I plan to add a new method in the batcher in order to render more efficiently large tiled backgrounds.

Edited by Totologic

Share this post


Link to post
Share on other sites
Advertisement

It's hard to say based on the information you give.

 

A big factor here will be the size of your sprites, and whether or not any of them overlap.

 

If you're drawing 800 quite small sprites with little or no overlap (like e.g small sparks in a particle system), that's quite poor performance, even for an Intel (I'm guessing it's a HD3000 so while it's not a good Intel, it's not a really bad one either, so you should be expecting close to 1000 fps with that kind of scene).

 

On the other hand if your sprites are large and with lots of overlap, in other words you're getting a lot of blending and hitting the framebuffer a lot, that's not too shabby at all.

 

The theoretical worst case is 800 full-screen blended quads, and I don't think an Intel can do that at any kind of reasonable framerate.

 

If you can't provide the code then at least you should provide a screenshot, so that we can see what kind of scene you're getting this performance with and make a judgement based on that.  It will of course be a rough judgement (there are so many other places that your performance could drop off or could be optimal).

Share this post


Link to post
Share on other sites

My atlas is 1024x1024:
[sharedmedia=gallery:images:6159]
 
A capture of rendering in a 800x400 window at 60FPS in Debug (100FPS in Release):
[sharedmedia=gallery:images:6158]
 
The full pink color in the atlas is considered as transparent by the fragment shader.
 
Here is my main:

Toto2D toto2d; // my batcher
GLFWwindow* window = toto2d.init(800, 400, "atlas.tga"); // create the window

glm::mat3 matTranslate1 = glm::mat3(1.0f);
glm::mat3 matScale = glm::mat3(1.0f);
glm::mat3 matRotation = glm::mat3(1.0f);
glm::mat3 matTranslate2 = glm::mat3(1.0f);
glm::mat3 matTransf = glm::mat3(1.0f);

int i;
int j;
float t = 0.0f;
float k;

while (!glfwWindowShouldClose(window))
{
	toto2d.reset(); // empty batch

	k = 0.0f;
	for (i=0 ; i<40 ; i++)
	{
		for (j=0 ; j<20 ; j++)
		{
			matTranslate1[2][0] = -100.0f;
			matTranslate1[2][1] = -100.0f;
			matScale[0][0] = 1.0f+sin(t+k)*0.5f;
			matScale[1][1] = 1.0f+sin(t+k)*0.5f;
			matRotation[0][0] = cos(t);
			matRotation[1][0] = -sin(t);
			matRotation[0][1] = sin(t);
			matRotation[1][1] = cos(t);
			matTranslate2[2][0] = i*30.0f;
			matTranslate2[2][1] = j*30.0f;

			matTransf = matTranslate2 * matRotation * matScale * matTranslate1; // SHITY LINE !

			// add a sprite to render list,
			// addSpriteMatrix(int textureLeft, int textureTop, int textureWidth, int textureHeight, glm::mat3x3 &transform);
			toto2d.addSpriteMatrix(200*(i%5), 200*(j%5), 200, 200, matTransf);

			k += 0.005;
		}
	}

	t += 0.01f;

	toto2d.setCameraLookAt(600.0f, 300.0f, 0.25f, 0.7f);
	toto2d.render(); // render batch

	glfwPollEvents();
}
Edited by Totologic

Share this post


Link to post
Share on other sites

Doing that 800 times each frame consumes a lot:

matTransf = matTranslate2 * matRotation * matScale * matTranslate1;

 

I reach 100FPS (Debug) when bypassing that (and 120FPS in Release).

 

I am using GLM. Any way to concatenate matrices more efficlently ?

Edited by Totologic

Share this post


Link to post
Share on other sites

You can optimize some of this by precalculating a lot of that stuff.  sin(t) and cos(t) only need to be calculated once rather than 1600 times each, for example.  For matTranslate1 and matTranslate2 you should be able to bake them into the sprite coords rather than having them as separate matrices.  That will help some.

 

see also here - http://www.ies-math.com/math/java/trig/kahote/kahote.html - for precalculating sin(t+k)

Edited by mhagain

Share this post


Link to post
Share on other sites


The full pink color in the atlas is considered as transparent by the fragment shader.

Are you making it transparent by writing enabling alpha test and writing out an alpha of zero, or by using 'discard' in the shader for transparent pixels?

 

The performance of the former is liable to be orders of magnitude higher performance than the latter.

Share this post


Link to post
Share on other sites

Where I'm coming from is that if there's an observable difference of this magnitude between debug and release builds, and assuming that nothing else (physics, AI, sound, etc) is going on, then the OP is most likely CPU-bound.  All other things being equal, code running on the GPU shouldn't demonstrate this kind of difference between debug and release builds, so the first line of attack should be to equalize things a bit better, and having done that, then look to optimize the GPU side of things.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!