Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!

Render Objects in Retained API

  • You cannot reply to this topic
2 replies to this topic

#1 noodleBowl   Members   -  Reputation: 417


Posted Today, 09:22 AM

I have some questions about a retained api system, renderable items, and their VBO/IBOS.

I'm not sure how to really ask this, so please feel to tell me to explain something if it does not make sense


So with a retained api, you do something like this:

renderSystem.AddRenderItem(sprite1); //Just a basic textured sprite 
renderSystem.AddRenderItem(sprite2); //Just a basic textured sprite
renderSystem.AddRenderItem(cubeModel); //Just a basic cube model


And the render system has list of all the renderable items you added to it. Which it is then responsible for drawing those renderable items using the data they provide. But the part I don't understand is the VBO / IBO implementation portion.


Using the code snippet above, lets say all those renderables use the same shader program.

Where each vertex has the following: XYZ position, UV texture coords

So for me, I would want to put all this data into one giant VBO since its all the same layout/format. Then this is where I get a little lost


What do I do about / how do I handle the indices?


If each renderable has their own indices data, then how does it get factored into the system?

Keeping the idea of using a giant singular VBO, I would think there would be a giant singular IBO.

So how does that index data of each renderable get added into this IBO? Added in the sense that the draw calls are efficient / work. Sure I could just slap it in there and use 3 draw calls (one for each renderable) but that seems bad, especially if I need to start rendering more objects


I think it would be better batch them up, but then does that mean I need to formulate the index data on the fly since everything will be in one IBO? Surely that would be horrible, since models can have their index data exported out and it would be more efficient to use that then doing the above.


If they just get slapped into one IBO, then I would think any overall single draw call would make everything look really messed up.

Since the IBO would pull the vertex ids incorrectly


So how are IBOs supposed to be handled in these kinds of systems? Not necessarily just in this system, but how are they supposed to be handled when you have multiple models with there own unique index data?


Please let me know if I need to explain something better



Just in case I forget to say it, I'm targeting OpenGL 3.3  :)


#2 haegarr   Crossbones+   -  Reputation: 5401


Posted Today, 11:08 AM

More recent versions of OpenGL provide glDrawElements* with *BaseVertex* in their name. They allow to specify an offset into the VBO that is added to each index read from the IBO. Those draw calls allow that the indices need not be recalculated due to batching. Sure, you still need a single draw call for each object, but you have at least reduced buffer object switching.


When you additionally want to put all in one draw call, then you need to look for glMultiDraw* routines.


In summary, there is glMultiDrawElementsIndirect that supports both.


Whether those routines are actually efficient … I don't know; never used them. However, although not being the most elegant way, I think that recalculating indices isn't that problematic.

Edited by haegarr, Today, 11:12 AM.

#3 AlexMekhed   Members   -  Reputation: 188


Posted Today, 11:48 AM

Batch where you can. For example, in particle systems using instanced rendering where you can render all particles in one call. In your example you can render two sprites in one call and then render cubeModel. You can store everything (even both vbo and ibo) in one buffer object, but it doesn't mean you have to draw everything in one draw call. More important is to sort your objects to minimize state switching (shaders, textures, buffers) and to minimize overdraw (unless you're submitting lots of small batches). Merging draw calls in such way is possible, but will take much more effort then just sorting out with VBO and IBO (as different render items can have different shader uniform values, samplers) and is basically an effort of three: engine programmer, game programmer and artist.


As for your question. You'll have to modify indices during loading. You load vertices for each model, store an offset, then when loading next model, you add this offset to every index you load. Then you'll be able to merge drawcalls if objects can be drawn in order they were loaded. In this situation your engine shouldn't guess what game programmer wanted to do, your engine should provide facilities to game prorgammer to tell what he wants.