Jump to content
  • Advertisement
Sign in to follow this  
Elrinth

ogl 2d quads performance issue

This topic is 2499 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'm having troubles with poor performance with drawing of sprites.

I create a sprite sheet from each texture. (a vbo for each texture, which contains position and texcoords for each sprite inside the texture)

Code to draw a letter (from font):

GraphicsManager::GetInstance()->Draw("data\\gfx\\fonts\\ansi-thin.png", letter, iPos, iScale, iColor);


Code in graphics manager to draw a sprite

void GraphicsManager::Draw( string i_fileName, int i_index, Vector3D iPos, Vector2D iScale, ColorF iColor )
{
if (!_isInitialized)
return;
TextureManager::GetInstance()->BindTexture(i_fileName);
glColor4f(iColor.R, iColor.G, iColor.B, iColor.A);
glPushMatrix();
glTranslatef(iPos.X, iPos.Y, iPos.Z);
GetSpriteSheet(i_fileName)->Draw(i_index);
glPopMatrix();
}


Code in SpriteSheet for drawing

void SpriteSheet::Draw( int i_index )
{
if(!isAlreadyBound)
Bind();
glDrawArrays(GL_QUADS, i_index*4, 4);
}


Drawing only a mouse cursor sprite: 4000+ fps.
Drawing mouse cursor AND a letter from font (two texture binds, two vbo binds, two glDrawArrays calls): 2400+ fps
Draw a string of text "Mouse Screen Pos:[1,319]" and the cursor takes me down to: 680 fps.
Filling screen(800x600) with 16x16 tiles, drawing the string of text and mouse cursor makes: 20 fps.

You see that performance drops pretty damn quickly. I'd like to know what I'm doing wrong.

I did also try with ONE universal VBO created with 160 000 vertices before this code. Which had like 3-4 draw calls to that vbo. (one for each texture). Then I drew only parts of that giant VBO for each texture. depending on how many sprites we're drawn.
That didn't give me any performance either. It was because I was constantly changing the VBO (GL_DYNAMIC_DRAW).

Share this post


Link to post
Share on other sites
Advertisement
Does 16 x 16 tiles mean 256 quads?
That is basically nothing even for a GPU from 2000.
Are you perhaps not using mipmaps and getting poor texture cache performance?
Are you perhaps making too many state changes?

Share this post


Link to post
Share on other sites
16x16 tiles means 16 pixels wide and 16 pixels high per tile. Resultion is 800x600. That makes 50 tiles in X and 37.5 (37) tiles in Y. which in total makes 1850 tiles for a screen (resolution will be 640x480 or low later, right now I'm still in testing stage). But this will call the function glDrawArrays (1850 times)


As you can see.. there is barely any state changes. I'm doing glTranslate and glDrawArrays per tile and that's it, they're all using the same texture. I will bind between max something like 5-6 different textures each frame. I'll use sprite sheets for everything.

I might not be using mipmaps. I'm using DevIL to load images. If I set: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
then the textures don't appear.

My computer is decent. i5 processor, 4gb ram, nvidia 560ti. So seeing poor performance already means I'm doing something very wrong, and I'd like some guidence on where the error is and the proper way to get it running faster than the furious :)

Share this post


Link to post
Share on other sites
With that kind of spec you should be getting much higher performance, even with almost 2000 draw calls and even without using a VBO (I half suspect that even immediate mode would run much faster than the times you're getting).

What looks hellishly suspicious to me is that you're passing a file name to your draw and bind (and GetSpriteSheet) routines. Are you certain that you're not reloading an image and recreating a texture each time?

Share this post


Link to post
Share on other sites
Indeed seems what's eating my fps isn't any GL stuff.. I tried commenting out all draw code and FPS remains the same... It's either me allocating memory every frame or it's something else. smile.png

Seems what's eating fps is cause I'm not passing references of variables everywhere smile.png

Share this post


Link to post
Share on other sites

16x16 tiles means 16 pixels wide and 16 pixels high per tile. Resultion is 800x600. That makes 50 tiles in X and 37.5 (37) tiles in Y. which in total makes 1850 tiles for a screen (resolution will be 640x480 or low later, right now I'm still in testing stage). But this will call the function glDrawArrays (1850 times)


As you can see.. there is barely any state changes. I'm doing glTranslate and glDrawArrays per tile and that's it, they're all using the same texture. I will bind between max something like 5-6 different textures each frame. I'll use sprite sheets for everything.

I might not be using mipmaps. I'm using DevIL to load images. If I set: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
then the textures don't appear.

My computer is decent. i5 processor, 4gb ram, nvidia 560ti. So seeing poor performance already means I'm doing something very wrong, and I'd like some guidence on where the error is and the proper way to get it running faster than the furious smile.png


So why don't you use mipmaps?

Share this post


Link to post
Share on other sites

[quote name='Elrinth' timestamp='1328483316' post='4909965']
16x16 tiles means 16 pixels wide and 16 pixels high per tile. Resultion is 800x600. That makes 50 tiles in X and 37.5 (37) tiles in Y. which in total makes 1850 tiles for a screen (resolution will be 640x480 or low later, right now I'm still in testing stage). But this will call the function glDrawArrays (1850 times)


As you can see.. there is barely any state changes. I'm doing glTranslate and glDrawArrays per tile and that's it, they're all using the same texture. I will bind between max something like 5-6 different textures each frame. I'll use sprite sheets for everything.

I might not be using mipmaps. I'm using DevIL to load images. If I set: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
then the textures don't appear.

My computer is decent. i5 processor, 4gb ram, nvidia 560ti. So seeing poor performance already means I'm doing something very wrong, and I'd like some guidence on where the error is and the proper way to get it running faster than the furious smile.png


So why don't you use mipmaps?
[/quote]

i'm assuming that his tile engine is done in ortho mode, so i don't really see why mipmaps are neccessary, it's not like his textures are changing sizes.(although this is just an assumption, i may be wrong.)

@Elrinth: i have to agree with mhagain, any moderate, or even low end pc, should be able to handle something like this easily(and i agree with him, that your binding by filename is a bit suspicious, although mapping strings to binded id's isn't unheard of.).

one last point, to improve your actual draw performance(although with something as simple as just drawing a bunch of tiles, it's probably not needed), is to build a large plane, and subdivide it to the number of tiles that you are drawing, and map the uv coordinates for each tile accordingly.)

Share this post


Link to post
Share on other sites
like you guys suspect. I was doing other stuff which was eating alot of FPS. Still haven't figured everything out. It's still eating quite alot of FPS. But I started with replacing all variables in the draw functions to reference objects rather than copy objects. It's still not quite there yet tho. Filling a screen with tiles and drawing 3 lines of text and drawing mouse cursor still sets me at 240 fps. The moment I don't call the draw methods for all tiles I go back up to 1600 fps. I also tried modifiying the code by removing the glDrawArrays in runtime. It did not affect the FPS at all. Meaning it's calling the methods which is costly. Right now all variables sent thru all "draw"-methods are reference variables.

240~260 fps @ ~0.004 sec per frame with screen filled with tiles @ resolution 800x600.

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!