0
\$\begingroup\$

I'm making a race circuit which is constructed using various textures.

To provide some background, I'm writing it in C++ and creating quads with OpenGL to which I assign a loaded .raw texture too. Currently I use 23 500px x 500px textures of which are all loaded and freed individually.

I have now combined them all into a single sprite/tile sheet making it 3000 x 2000 pixels seems the number of textures/tiles I'm using is increasing.

Now I'm wondering if it's more efficient to load them individually or write extra code to extract a certain tile from the sheet?

Is it better to load the sheet, then extract 23 tiles and store them from one sheet, or load the sheet each time and crop it to the correct tile?

There seems to be a number of way to implement it...

Thanks in advance.

\$\endgroup\$
1
\$\begingroup\$

Neither. You want to load a single tile sheet once and load that single texture into the GPU with no cropping or copying.

It's most efficient to actually draw from the tile sheet by figuring out the correct UV coordinates for a sprite in the sheet and then passing those to your draw commands. Individual textures should be avoided if you can, at least for small sprites and frequently-used textures.

You want to avoid any excess state switches and minimize draw calls. This means that you ideally want to only bind a single texture (the one sprite sheet) instead of many individual textures. It also means you ideally want to submit a single draw call (maybe an instanced call) for all your game objects that just use that single texture, instead of needing a separate draw call for each individual sprite (or worse, each individual object). Actually achieving a single state and a single draw call becomes impossible as your game gets more complex, but you want to keep the numbers as low as possible.

You only want to bind the texture once, since it'll be the same spritesheet texture for all sprites. The rest is figuring out the correct UVs. If sprite metadata says that some 500x500 image is located at position (1500,500) within a 3000x3000 spritesheet, then you know that the opposite corners are at (1500,500) and (2000,1000). Divide those by the sprite sheet dimensions to get the normalized UV coordinates, (1/2,1/6) and (2/3,1/3). When you draw the object, use those UVs (and extrapolate to get the other two corners). Ideally, you don't want to draw each object but rather fill a dynamic buffer with position and texcoord information and then draw all your objects (maybe with instancing) using a single draw call sourcing that dynamic buffer.

\$\endgroup\$
  • \$\begingroup\$ What you suggested is what I was trying to describe. Load it once, then extract (or locate) using the correct coordinates (uv). I've loaded the texture into a GLuint, but I'm unsure of the best way to extract that data for each bind. (if that makes sense). Thanks for posting. \$\endgroup\$ – Reanimation Apr 10 '14 at 18:59
  • \$\begingroup\$ You need a function from pixel coordinates to UV values, is what I'm hearing. Try searching for "pixel perfect opengl" and you'll probably find what you're looking for. I think GL_TEXTURE_2D_RECT can be used, but that's an older extension. It is like NPOT textures but specified using pixels instead of UV values. I think it is looked down on, though I think it's darn convenient. \$\endgroup\$ – PatrickB Apr 10 '14 at 21:06
  • \$\begingroup\$ @Reanimation: I tried to explain the UV location bit. It's simple arithmetic, even my crappy description is hopefully enough to set you on the right track. :) \$\endgroup\$ – Sean Middleditch Apr 11 '14 at 2:47
  • \$\begingroup\$ @PatrickB Yeh, I've heard of that when googling earlier. Maybe I should look into it more... I'm just having trouble getting my head around only rendering a section based on uv coords after already binding it. But it's now late so will investigate further tomorrow. @ SeanMiddleditch Excellent. Thanks very much. I'll give it a shot and see if I can work with it. The coordinates seem easy enough :D \$\endgroup\$ – Reanimation Apr 11 '14 at 4:00
  • \$\begingroup\$ @SeanMiddleditch One problem with your description of UV coordinates can be summed up as "pixel edge vs pixel center", but honestly, if he's struggling with how to use UV coords at all, then that might be too much. It's probably better to just copy/paste someone's pixel to UV function and be done with it, then later review that madness. \$\endgroup\$ – PatrickB Apr 11 '14 at 22:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.