Tuesday, March 10, 2009

Details of how compositor works

The compositor framework hooked into the Ogre rendering pipeline by setting up a RenderTargetListener(CompositorChain).
It is setup when the client call CompositorManager::addCompositor() -> CompositorChain::addCompositor() -> "mViewport->getTarget()->addListener(this);".
It is responsible for registering another listener: RenderQueueListener(CompositorChain::RQListener).

When the "renderQueueStarted" event of RenderQueueListener is fired, it executes all the render operations inside that CompositorChain.
Render operations are represented by the class "CompositorInstance::TargetOperation".
It is the abstract class. The real render operations("clear", "stencil", "quad") are based on it.

The real rendering is executed immediately when CompositorInstance::TargetOperation::execute() is called. For example, in "quad" operation, it sets up the camera, viewport, the full screen quad object, and inject it into the SceneManager and render it.

In the compositor framework, CompositorInstance is just a render operations container, which enqueues the render operations into the CompositorChain. The CompositorChain is the real important class.

Monday, March 9, 2009

GPU Geoclipmap screenshots

Solid mode:

This is Mars

Wire frame:

Grids across 2 faces

Grids across 3 faces

These are the screenshots of my geoclipmap demo.
The algorithm is based on the rectangle geoclipmap [paper link]
The grid of the sphere is indeed a grid cube, which composes of 6 rectangle geoclipmap patches, and the grid cube is then projected into sphere.
The inter-plane cracks are eliminated by my own algorithm. It is quite simple, but it works quite well.
The heightmap sampling and the sphere projection are all done on GPU. Therefore it requires a SM4.0+ GPU to run it.
The shading of the terrain is just a simple height to color mapping. I'm going to implement a more sophisticated shading scheme later. My current focus is to get the partial texture update working, which requires some modifications on Ogre3D.

Thursday, March 5, 2009

The flow of renderOneFrame()

Root::renderOneFrame() -> Root::_updateAllRenderTargets() -> RenderTarget::update() -> Viewport::update() -> Camera::_renderScene() -> SceneManager::_renderScene()

SceneManager::_renderScene()
   \ ->SceneManager::_findVisibleObjects()
   \ ->SceneManager::_renderVisibleObjects() -> SceneManager::_renderQueueGroupObjects() -> SceneManager::renderObjects() -> SceneMgrQueuedRenderableVisitor::visit() -> SceneManager::renderSingleObject()

SceneManager::_renderScene() is the real rendering function.
Most importantly it calls SceneManager::_findVisibleObjects(), which traversals the scene graph and adds visible object to the render queue.
Then, after setting up the render system (e.g. matrices, lighting, etc), real rendering is started by calling SceneManager::_renderVisibleObjects().

SceneManager::renderSingleObject() is the real function that render a object. It setup the render states of the object. (e.g matrices, materials, shaders, vertex/index buffers)