Archived

This topic is now archived and is closed to further replies.

me22

Speed of glBindTexture()

Recommended Posts

I''ve been playing around with making a viewer for the Total Annihilation TNT map format. It stores the terrain as indicies into a list of unique tiles, which nicely lowers memory requirements and made display in the original game easy -- just copy it straight onto the screen. If I want to do it in OpenGL and allow a camera with more than 3 Degrees of Freedom ( I could do all three translation axes with glRasterPos, glDrawPixel, and glPixelScale ) then I assume I have to make each tile in a texture. Then to draw it however, I have to bind a new texture every time in my terrain draw loop. Does the glBindTexture call represent a signifigant part of the drawing cost, or is it negligable compared to drawing the textured quads (that I use for the tiles)? - Scott "me22" McMurray ( email/MSN me22@fastmail.ca ICQ 37213887 )

Share this post


Link to post
Share on other sites
While i dont know the "cost" per say of the glbindtxt command the general rule of thumb for rendering anything is to batch common elements together, so in this case maybe you could do a pre-processing step which groups all the tiles by texture so that when you render you keep the state changes down to a min.

Share this post


Link to post
Share on other sites
glBindTexture can be expensive if you''re calling it a lot. You might want to profile it in your own code to see just how bad it can be. Make sure you''re not calling it unnecessarily; group tiles by texture and render them by group, only calling glBindTexture once per group.

Or, if you don''t mind not using mipmapping, you could even pack all your tile textures into a single large texture.

Share this post


Link to post
Share on other sites
Thanks for the prompt replies!

( For reference, here''s the file format doc I wrote: http://visualta.tauniverse.com/Downloads/ta-tnt-fmt-v2.txt )

Firstly, making one large texture is not feasable. For the entire map it would be larger than 8192x8192 for even the small maps, way larger than the maximum allowable texture size even if you didn''t mind using all that ram. Also, the tiles scheme saves a ton of space by not storing repeated tiles more than once -- this means that you can have gigantic (63x63 screens) maps without needing a gig of ram.

As for binding, then drawing all the tiles using that texture, s it really efficient to find out the order to draw? I''d appreciate any solution you can think of that doesn''t take a 3D loop...

As for profiling, how do you suggest I do it? I couldn''t get gprof working with Dev-C++...

- Scott "me22" McMurray
( email/MSN me22@fastmail.ca ICQ 37213887 )

Share this post


Link to post
Share on other sites
You could use vectors and store a lists for each texture type, instead of the entire map with an ID, store the location & ID, then loop through each type and display them in their correct location. This would only require one glBind per call, and will not decrease the speed of the engine either.

Share this post


Link to post
Share on other sites
I believe Superpig''s Enginuity articles had a section on writing a profiler. But really you shouldn''t need to do that if you know what you''re trying to test: Just time how long it takes to render your scene over 1000 frames with and without glBindTexture calls, and subtract. But bear in mind that the performance of glBindTexture tends to vary from chipset to chipset.

BTW, you don''t necessarily have to use one big texture. You could use several large textures to achieve what you need. Either way, you''re reducing the number of binds.

____________________________________________________________
www.elf-stone.com | Automated GL Extension Loading: GLee 2.00 for Win32 and Linux

Share this post


Link to post
Share on other sites
Just to clarify: benjamin bunny was suggesting you pack the tiles into a texture and then display the appropriate part of the texture on each tile, so each tile is stored exactly once in the texture, i.e.:

+----+----+
| #1 | #2 |
+----+----+
| #3 | #4 |
+----+----+

then for all tiles with texture #1 you do e.g.:

glTexCoord2f(0, 0);
glVertex2f(x, y);
glTexCoord2f(0.5, 0);
glVertex2f(x + 1, y);
glTexCoord2f(0.5, 0.5);
glVertex2f(x + 1, y + 1);
glTexCoord2f(0, 0.5);
glVertex2f(x, y + 1);

and for texture #2 the texture coords would be (0.5, 0), (1, 0), (1, 0.5), (0.5, 0.5) e.t.c.

This has exactly the same memmory requirements as storing each tile in a seperate texture (except for texture object state, unused space due to odd number of tiles e.t.c.).

Enigma

Share this post


Link to post
Share on other sites
Yep you can use the (text group) trick above + make batches based on same texture AND some kind of proximity condition. Thus you get the best of both worlds (z-buffer + minimize state changes). I suppose that elements sharing common textures are most probable to be found in the same area. So this should work better than any of the two radical solutions (pure z-order or pure by texture order)

Share this post


Link to post
Share on other sites