Current situation
ATM we have two ground renderers which can be used in normal game as well as two which are meant to be used with slow videocards or software rendering.
The two normal ground renderers are the Default renderer and the Quick renderer.
Default and Quick renderer use somewhat different tehniques, especially for LOD, but they still share a lot of code which is bad.
Proposal
Proposal is to unify Quick and Default renderer (this has already been agreed on). Basically this would mean partially rewriting the Default renderer, using code from Quick renderer. Of course the resulting class would still be named BoDefaultGroundRenderer, the title of this page only reflects that the two renderers should be unified.
I would also make some changes to ground renderer base classes:
- All geometry handling (that includes to-be-rendered cell arrays which as currently in BoGroundRenderer, as well as geometry rendering) should be moved to BoGroundRendererBase. It should have a method renderGeometry() which would render all nodes found to be visible when generateCellList() was last called.
Thus all vbos would also be moved to BoGroundRendererBase
- BoGroundRenderBase subclasses would implement more advanced rendering tehniques such as texturing and shaders and use BoGroundRendererBase class to do actual geometry rendering after binding textures and shaders.
LOD
LOD code would use a quadtree already present for visibility testing.
Each node in the quadtree would be assigned a LOD level which would be used to render this node. Note that this approach would differ from current one where each node is rendered individually.
This means that if a node's subnodes have mostly equal roughness, then the node needn't be subdivided any further and the whole node would be rendered with constant LOD. Same approach could be used for visibility checking: we needn't check visibility for all individual nodes, it's ok to render e.g. 8x8 nodes even when they're only partially visible.
Rendering
Rendering would work like this:
- BoGroundRenderer::renderCells() is called from BoCanvasRenderer
- BoGroundRenderBase::generateVisibleCells() might be called (or might have been called earlier) to recalculate list of visible quadtree nodes
- BoDefaultGroundRender::renderVisibleCells() is called. This method:
- binds textures and shaders
- calls BoGroundRenderBase::renderGeometry() to render terrain geometry (using binded textures/shaders)
- renderGeometry() would go through all visible nodes and render them with previously calculated LOD (perhaps using some constraints; see below)
Questions
- Should geometry be cached (as indices) in BoGroundRendererBase or should it be recalculated every time renderGeometry() is called?
Caching would mean allocating a big chunk of memory (as we don't know how many indices we'll have)
Recalculating would have some performance impact but wouldn't have memory problem and would make it easier to skip certain nodes (see below)
* Is cell list(currently in BoGroundRenderer) obsolete? It would be replaced by list of indices in BoGroundRendererBase and I don't see any remaining uses for it?
- Current draft doesn't have any methods for skipping nodes which do not have current texture (assuming indices will be cached). This is necessary optimization and must be implemented. How?
- Perhaps each node could be assigned first index number in indices array and number of indices used for this node. Then we could render each node individually but wouldn't need to recalculate indices every time
- Do we really need those classes or can they be integrated into BoGroundRendererBase: BoGroundRendererCellListLOD, CellListBuilder, CellListBuilderTree