Prototyping a renderer in seven days - Rendering
Last post I talked about an experiment I made to prototype a renderer under a short deadline. This time I'll continue on this and explain how I did the rendering.
Rendering
Since this was to be done in seven days I didn't have time to go fancy with the rendering. It had to be quickly implemented, simple and at the same time fast.
The easiest to achieve better performance in 3D rendering is find the functions that are the most expensive (processing wise) and to modify the code to call them less often. In Direct3D those are the device's change state functions. So I set this as a requirement when I created the renderer and this was in fact the only real optimization made on the rendering system.
SceneDatabase class
This class contains the structure that represents the scene in memory. The scene was constructed in a tree form made to reduce automatically the calls to the change states functions. Each node of the tree represented settings to send to the renderer prior to the rendering itself.
Tree nodes were created for specific simple attributes : Materials, Transforms, Renderables. Material nodes contained information related to the material of the object to render whether it was a texture, an effect (shader) or colors. Transform nodes were the world transform to apply before rendering the object. Finally, Renderable nodes were used for all the meshes to render to the screen.
To minimize cost of the change state functions the nodes were set according to their cost. Under the root of the tree were the Materials which will cost more and you need to optimize, next were the Transforms and then the Renderables.
RenderQueue, RenderOperation, Renderer classes
Those are the three classes (with the SceneDatabase) that form the core of the rendering system. The renderer queries the SceneDatabase for a list of objects to render, this was implemented using the RenderQueue class. The RenderOperation class contained all the information for what I'd call a "unit of rendering".
The render operation (RenderOperation) was formed of a Material, Transform and Renderable which were previously queried in the SceneDatabase. In other words all the information needed to render a mesh was present.
The RenderQueue is a structure mostly designed to contain a list/vector of RenderOperations. The SceneDatabase, by its design already sorts the RenderOperations by Materials. Here, the RenderQueue could sort them by other factors implemented in a way that resembles the function that some of the std containers have that acts like operators used for sorting.
What went wrong
Nothing was really wrong, since this was meant for simplicity I was avoiding a lot of problems. The only real problem I got there was the problems I got with the content pipeline, I didn't have loadable content to test the rendering part until the last hours. Testing and debugging weren't done so there is probably a lot of buggy code due to the fact I was doing my midterms at the same time and had a lot of homework (I was also sleepy in the last hours I worked on this project).
What went right
This was designed for simplicity and I kept it simple until the end. The only thing that complicates the design is the RenderQueue and RenderOperation classes which were there because of the requirement to minimize the number of calls to the Direct3D device.
How to improve the design
The design was lacking a lot of feature I'd like to see in an engine. Mostly I'd drop the fixed pipeline and use shaders everywhere I could leading to a code that could be easier to bring to newer grounds (like DirectX 10).
I'd also add scene partitioning structures like quadtrees/octrees to structure so it would be easier to implement some features that requires spatial information on the scene (ex.: collisions).

