[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Written by Jorrit Tyberghein, [email protected].
Here is a short run-through of the main rendering loop. This document is not an explanation of portal technology. It just explains how the main rendering loop in Crystal Space works so that you can have a quick idea of where you have to go to see a particular part of the algorithm work. This is a rather technical document and not intended for people who are only interested in using Crystal Space in their own projects. It is intended for people who want to know how Crystal Space works internally.
To understand this you should know how portals are used in Crystal Space. You should also read the tutorial (see section Simple Tutorial 1: Basic Setup, World Creation) as this explains the basics for using Crystal Space. This document is based upon the `simple' application (`CS/apps/tutorial/simple1/') because this discussion looks a lot like a tutorial.
First we start in `apps/tutorial/simple1/simple1.cpp'. In the
main()
function we initialize our engine. This is an instance of the
plugin `iEngine' which actually represents the engine. I will not
explain how all the initialization works. This is explained in the tutorial.
But I will go straight to iEngine::Draw()
which is called indirectly
from within Simple::NextFrame()
. It is called indirectly because first
we call iView::Draw()
which then calls iEngine::Draw()
.
iEngine::Draw()
) The method iEngine::Draw()
is located in
`CS/plugins/engine/3d/engine.cpp'.
iEngine::Draw()
first sets up the initial `iRenderView'
structure. This structure is defined in
`CS/include/iengine/rview.h' and is the main structure which is
used throughout the entire rendering process. It collects all data that
is required for rendering the recursive portal structure.
Basically, it contains the following information:
view
This is the current clipper. A clipper is a 2D polygon which defines what is visible. Every object is clipped to the view first. Every time we go through a portal the view is modified.
g3d
g2d
These are pointers to our 3D and 2D graphics subsystems.
clip_plane
This is a special plane. If `do_clip_plane' is used then we clip all geometry in 3D to `clip_plane'. This is normally not used except in special cases where we have portals that arrive in the middle of a sector. In that case the portal will be used as an extra clipping plane because we don't want to render everything that is behind the arrival plane of the portal.
Another important thing is that `iRenderView' is actually a subclass of `iCamera' (`CS/include/iengine/camera.h') so all camera functionality is present as well.
To set up the initial `iRenderView' structure iEngine::Draw()
creates a new instance based upon the given camera.
After this iEngine::Draw()
gets the current sector from the camera and
calls iSector::Draw()
(`CS/plugins/engine/3d/sector.cpp'). This
will essentially draw the whole screen as discussed below.
After doing this (now that the screen is fully updated) we optionally draw halos. Halos are drawn on top of everything else since they are an effect in the eyes.
iSector::Draw()
) This method iSector::Draw()
is located in
`CS/plugins/engine/3d/sector.cpp'.
iSector::Draw()
is responsible for rendering everything in the current
sector. Before it does that it will ask the current visibility culler
(`frustvis' or `dynavis') what objects are likely to be visible
or not. It will then render all visible objects sorted by render priority
(see section Render Priorities and Objects in Sectors) and using the z-buffer mode that is
associated with every object. It is up to the map designer to make sure
that the objects in their render priority and z-buffer mode will actually
cause the sector to be rendered ok.
Every object that is rendered will get the current camera transformation so it can correctly transform its coordinates from world to camera space: (0,0,0) is the camera pointer, (1,0,0) is one to the right, (0,1,0) is one unit above the camera, and (0,0,1) is one unit in front of the camera.
Every object also gets the current movable (iMovable
) which indicates
where the object currently is in the world. The transform created from
the camera and the movable can be used to transform from object space
to camera space. Note that some objects leave this transformation up to
the 3D renderer which is good because that means hardware accelerated
transforms can be used.
Every mesh object is responsible for drawing itself (see section Mesh Object Plug-In System). The engine decides when to render an object, the object decides on how to render itself. Finally the 3D renderer will process the actual rendering operations done by the mesh object.
The `thing' mesh object type supports portals. When such a thing containing
a portal is rendered the destination sector will be rendered recursively.
This means that rendering of the current sector will be temporarily
suspended while first the destination sector through that portal is rendered.
Going through a portal results in the current `iRenderView'
instance to get a new clipper (a smaller clipper usually). Objects can use
that clipper to decide if they want to be rendered or not. In some special
cases a portal can also transform space (like a mirror). In that case the
world=>camera transformation will also be modified in the current
iRenderView
.
When a sector has finished rendering we conclude by optionally fogging the current sector if this is needed.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated using texi2html 1.76.