2

I am working on an OpenGL-based app that needs to be able to generate a changing set of textures on the fly.

From my initial reading it sounds like it would be a really bad idea to use a separate texture for each image that I need to draw as the operation of binding a texture so that is can be used for rendering is really slow.

The preferred approach would be to combine many of these needed images into a single bigger image and binding that texture once and drawing only excerpts from it (sprites).

Unfortunately my images can have very different sizes and become needed and obsolete in somewhat unpredictable ways.

So, what I need is a sort of memory manager that maintains a list of used and free regions in my texture(s) and can allocate/dispose areas for new/obsolete images.

It's basically what every program needs to do for memory management (allocate and dispose variables of different size in the heap), except it's a 2D problem, since I'm allocating rectangles inside a big square rather than short "lines" in a longer one.

Is there a name for the problem I am trying to solve and is there a (or multiple) standard/best-practice approach(es)?

(A quick clarification: I'm not looking for ways to handle the reference counting and such to figure out which images are no longer used. I'm looking for a way to reserve new rectangles in a patch-work of existing ones and gaps, that minimizes (eliminates?) any re-arranging of the other rectangles.)

UPDATE:

I came up with an idea for a different approach but decided to post it as a new question to investigate.

Community
  • 1
  • 1
Markus A.
  • 12,349
  • 8
  • 52
  • 116
  • Well as usual, it's good to avoid premature optimizations. You don't know now that the texture binding overhead is going to be significant compared to other overheads. – chbaker0 May 21 '15 at 02:11
  • @chbaker0 Point taken. But from reading all sorts of documentation and blog posts, it seems like the worst mistake one can make when it comes to OpenGL performance is too much data transfer between the CPU and the GPU and the second is constant texture re-binding. So, I'd like to avoid those two from the get-go. – Markus A. May 21 '15 at 03:29

1 Answers1

1

This looks similar to a 2D bin-packing problem - this is NP-hard, however you can use a guillotine cut heuristic (see here for an explanation and here for some source code) which approximately solves the problem in polynomial time.

The standard 2D bin-packing algorithm doesn't include the deletion of objects. My recommendation is to maintain a search tree of free spaces and assign new objects to free space using first-fit or best-fit, then when everything becomes sufficiently fragmented (e.g. when you're not able to find enough free space to allocate an object) you re-run the full bin-packing algorithm. If a full rearrangement of objects is highly undesirable then you can instead split the screen space into quarters (or sixteenths or whatever) and only re-run the bin-packing algorithm on the portion(s) of the screen with the most free space.

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69