Jump to content
  • Advertisement
Sign in to follow this  
Sir Sapo

OpenGL Which is Faster?

This topic is 4883 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

I hear that it is really expensive to switch textures in an OpenGL program which got me thinking about optimizing my tile engine. Lets say I have 300 tiles in a level and each tile can have one of 30 textures binded to it. Would this way be faster than binding the same textures 300 times? I have a for loop that binds one of the 30 textures, looks through all the tiles and only draws the ones that are supposed to have that texture bound to them, and then moves on to the next texture and repeats the process. My writing sucks so I'll write some code too:

for(int tex = 0; tex < 30; tex ++)
{
glBindTexture(GL_TEXTURE_2D , textures[tex]);

for(int tile = 0; tile < 300; tile ++)
{
if(Tiles[tile]->getTexture() == tex)
Tiles[tile]->RenderTile();
}


}




Would this even make a measurable effect on the speed of my game if I'm only doing this 300 times anyway?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Sir Sapo
I hear that it is really expensive to switch textures in an OpenGL program which got me thinking about optimizing my tile engine.

Lets say I have 300 tiles in a level and each tile can have one of 30 textures binded to it. Would this way be faster than binding the same textures 300 times? I have a for loop that binds one of the 30 textures, looks through all the tiles and only draws the ones that are supposed to have that texture bound to them, and then moves on to the next texture and repeats the process.

My writing sucks so I'll write some code too:

*** Source Snippet Removed ***

Would this even make a measurable effect on the speed of my game if I'm only doing this 300 times anyway?



Sorting by texture and/or minimizing texture switching usually does help. Just how much in your case, you'll have to profile and find out [smile].

btw your loop would be more efficient if you sorted your tiles by texture instead of the nested loop like that. Something like the following then.


tex = 0;
for(int tile = 0; tile < 300; tile ++)
{
if(Tiles[tile]->getTexture() != tex)
{
glBindTexture(GL_TEXTURE_2D , Tiles[tile]->getTexture());
tex = Tiles[tile]->getTexture();
}
Tiles[tile]->RenderTile();
}



executes 300 times instead of 9000 :) but for maximum efficiency sort the tiles before hand by their textures (above will work without sorting aswell but not as efficiently).

HTH

Share this post


Link to post
Share on other sites
Quote:
I hear that it is really expensive to switch textures in an OpenGL program


It is only really expensive if you have modified the texture since you last drew it, or if you're binding more textures during a frame than fits in your graphics cards' VRAM (after framebuffer, Z buffer, double buffer etc are subtracted).

In OpenGL version 1.0, about ten years ago, there were no texture objects, and the texture had to be uploaded to the card each time you wanted to use it -- really quite expensive. Display lists were usually used to "hint" to the driver that it could cache that texture. However, as of texture objects, in OpenGL 1.1, that hasn't been an issue. It's long dead and buried.

Binding a new vertex program, or even worse, fragment program, is likely to cause a far bigger stall in your pipeline than switching textures. Pipe stalls == fewer pixels processed == lower frame rate, if that's your limiting factor.

Share this post


Link to post
Share on other sites
Even if the texture is sitting in the graphics cards VRAM the GPU has to do a fair amount of work when the texture is changed. Caches are flushed, data has to be shifted about, states setup etc.

So, yes, while a shader change is more expensive texture changes can hurt as well which is why its advised to minmise them.

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
Binding a new vertex program, or even worse, fragment program, is likely to cause a far bigger stall in your pipeline than switching textures.


Eh in OpenGL, you can only bind Program Objects which consist of both Vertex and Pixel Shaders, and from the fact that after linking a program object, modifying the original vertex/pixel shaders does not affect the already linked Program Object, am i right to conclude that for OpenGL atleast, sorting by vertex/pixel shaders is of no use and you should instead sort by Program Objects? Because it appears to me that the driver makes a copy of the program object upon linking which is why changes made to the original vertex/pixel shaders do not affect it.

Share this post


Link to post
Share on other sites
Quote:
Original post by GamerSg
Quote:
Original post by hplus0603
Binding a new vertex program, or even worse, fragment program, is likely to cause a far bigger stall in your pipeline than switching textures.


Eh in OpenGL, you can only bind Program Objects which consist of both Vertex and Pixel Shaders, and from the fact that after linking a program object, modifying the original vertex/pixel shaders does not affect the already linked Program Object, am i right to conclude that for OpenGL atleast, sorting by vertex/pixel shaders is of no use and you should instead sort by Program Objects? Because it appears to me that the driver makes a copy of the program object upon linking which is why changes made to the original vertex/pixel shaders do not affect it.

You're probably right if you're talking about GLSL Program Objects, but IIRC with the previous shader extensions you could bind just a fragment program or just a vertex program.

Share this post


Link to post
Share on other sites
Quote:
Original post by OrangyTang
IIRC with the previous shader extensions you could bind just a fragment program or just a vertex program.


You are also able to not include either vertex-, or fragment-shader in GLSL program-object. Not to be picky about it, but I couldn't resist ;)

ch.

Share this post


Link to post
Share on other sites
What if you were to compile your textures into one file?
I suppose having 30 textures in one file is quite large, but what if you had 10 textures in 3 files? It'd probably be even better to logically spearate the tiles with other like tiles. Say, have all the grass textures in one "master grass texture file"?

Then, you could do 3 passes, one with each of the "master texture files" bound. Depending on the texture that needs to be drawn, you could simply alter the texture coordinates of the quad you draw.

Share this post


Link to post
Share on other sites
Quote:

What if you were to compile your textures into one file?
I suppose having 30 textures in one file is quite large, but what if you had 10 textures in 3 files? It'd probably be even better to logically spearate the tiles with other like tiles. Say, have all the grass textures in one "master grass texture file"?

Then, you could do 3 passes, one with each of the "master texture files" bound. Depending on the texture that needs to be drawn, you could simply alter the texture coordinates of the quad you draw.


The only problem I see with that is that there will be ugly-looking grid lines at the edges of the quads, at least that's what I've experienced when using multiple parts of one image as multiple textures. If anyone can tell me how to fix that, please let me know, its handy.

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!