3
\$\begingroup\$

I am working on a game that uses opengl 3. The huge geometry is spread over a grid of about 270,000 cells. The geometry in each cell, though not very frequently, can change independently from other cells. Usually most of these cells don't contain any geometry at all.

Until now my approach was to have one vertex buffer object per cell. Today i discovered that alone generating all these VBOs (without any data in them) results in almost 1GB of main memory usage. That would be equivalent to an overhead of around 3KB per VBO.

As it seems this overhead can not be avoided, i first thought of generating a VBO only when the cell creates its first geometry and deleting it once the cell becomes empty again. This might work quite well, but it would still be inefficient if the geometry happens to have very few geometry in every cell.

So i searched for a different solution and read, that one approach is to put multiple meshes in a single VBO. The problem with that is, that the mesh of a cell may change its size and require more memory in the VBO than initially. This would require subsequent meshes in the VBO to be shifted.

Now my question is: How do i do that?

Do i have to save the mesh for every cell, so i can rewrite it into the VBO when it needs to be shifted?
Would glMapBuffer help me?
Also: Is there a better, completely different solution?

Thanks in advance!

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

What you could do is use a pool of big VBOs, with a PoolManager.

The PoolManager would only allocate "big" VBOs, each one having the same size, for example 4/16/256MB, not sure of how much vertex data you have...

Each VBO in the PoolManager would have associated lists of "used" and "free" regions (a region is defined by an offset from VBO start and a size).

When a new object is added to a cell you would ask the PoolManager to give you a VBO + a region inside it.

Internally the PoolManager will either find an available region matching the vertex size needed for the object in an existing big VBO or will need to create a new big VBO.

You would then use glMapBuffer in order to load the object data in the region of the VBO returned by the PoolManager.

Until this point this is easy to implement ...

Things will start to get more complicated as soon as you will need to unload some objects because then you will start to get region fragmentation issues : unloading objects will create holes in the VBOs and you'll need to implement algorithms similar to what is done by memory allocators in order to fix that (those algorithms may force you to have to move/reorganize vertices inside VBOs, which is not very GPU friendly since those VBOs are at the same time used for rendering)

It is not specified in your question if you ever need to unload objects to save memory. If you can afford to only hide an object instead of unloading its vertices from its VBO region then no need to care about region fragmentation.

\$\endgroup\$
  • \$\begingroup\$ One cell would contain one connected mesh that needs to be rendered at once. The mesh can change or be replaced by a mesh of a different size. It's not about adding or removing objects from the cell. But basically this is what i had seen coming. Doing some mesh memory management. I'm a bit concerned about glMapBuffer though. Is there a trade-off in performance compared to glBufferData? \$\endgroup\$ – Speedy Consoles Aug 13 '15 at 17:29
  • \$\begingroup\$ Also: If i have to do it like this, why would i use multiple VBOs anyway? \$\endgroup\$ – Speedy Consoles Aug 13 '15 at 17:39
  • \$\begingroup\$ You need to use multiple VBOs because (I suppose) you do not know in advance the maximum amount of data which will be stored in VBOs by your app...Of course if you can guarantee that the app will never need more than XXMB of vertex data then one VBO would be sufficient \$\endgroup\$ – VB_overflow Aug 13 '15 at 18:17
  • \$\begingroup\$ glMapBuffer / glBufferData have the same performance issue : since they modify a VBO and the GPU may be using this VBO then OpenGL has to force the GPU to stall on glMapBuffer / glBufferData call until the VBO is no more used by the GPU (note that the stall may occur at other code points this depends on driver ... but it will be there somewhere except if the GPU charge is very low in your app). Having multiple VBOs may also reduce the chance of stall (Imagine you have 10 big VBOs and only one needs glMapBuffer this frame, there is less chance than GPU uses it when glMapBuffer is called) \$\endgroup\$ – VB_overflow Aug 13 '15 at 18:19

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.