I'm trying to design a renderer that has the ability to batch all the renderables, sort by texture, shader and other parameters and then draw them all at once. Initially, I was thinking of some simple, naive design like
this.
Using something like that, all renderables are given to a list which sorts them appropriately and then passes them to a renderer which draws them. Some example code would be:
void DrawScene()
{
renderList.Add(playerRenderable);
renderer.Update(renderList);
renderer.Draw();
}
void Renderer::Update(boost::shared_ptr<IRenderList> list)
{
// Create VBO and pass every renderable's geometry to it
}
void Renderer::Draw()
{
// Of course, for-each loop isn't in the current standard, but still :P
for (IRenderable* r : list)
{
// Perform necessery transformations for this renderable
// Set texture/shader
// Draw this renderable's geometry using correct indices into the VBO
}
}
I have a few questions:
1) If IRenderList takes IRenderables, then how it will know if each renderable has a texture or shader and be able to sort them correctly? For this to happen, the IRenderables must all share some of the same properties, that is, they all need to contain textures or shaders. This makes the design less flexible. Should every renderable have a shader/texture ID and if a specific renderable doesn't use them, they can just return 0 as the ID?
2) When it comes to drawing everything, how will the renderer know if the renderable needs to transformed or not? And how will handle hierarchical transformations? For example, if there's a person with a weapon, the renderer will need to transform the player and
then the weapon. This means that it will have to draw the weapon straight after the player, but what if they're not next to each other in the new list sorted by IRenderList? Should transformations not even be handled by the renderer?
3) Should this system know if the renderable is visible and don't draw it if it's not? I'm guessing this part would be done when adding the renderable to the list, meaning it's not really part of the renderer per se. For example:
if (someClassDedicatedToVisibilityTesting.IsVisible(renderable))
{
renderList.Add(renderable);
}
Phew, that's pretty much it. I have a feeling I'm going about this the wrong way. As you can probably tell, I haven't done anything like this before, so I'm grateful for any help and advice so I don't fall into as many problems later on. :)