Rendering with RenderWare
This article gives an overview over the rendering process in RenderWare. More information and references will be added here in the future.
In RW the basic objects that are needed for rendering a model are Frames (RwFrame), Atomics (RpAtomic), Geometries (RpGeometry), Meshes (RpMesh), Materials (RpMaterial) and Textures (RwTexture). Clumps (RpClump) are a container for Atomics, Lights and Cameras and include a hierarchy of Frames to which these three types of objects are attached. World sectors are not used in GTA and not discussed here.
Atomics & Frames
A Frame defines a location and orientation to which Atomics, Lights and Cameras can be attached to place them in space. Atomics are renderable models but often contain little data, instead they reference a Geometry which contains the actual geometry data. One can think of a Geometry as containing the geometric "idea" (to use platonic terminology) of a model while an Atomic is an actual instance of that idea in our 3D-world. This way the same Geometry can be referenced by multiple atomic and rendered at different points of space. If an Atomic is animated, the Geometry is not modified but the animated geometry is stored with the Atomic.
A Geometry contains the platform-independent definition of a 3D-model: Vertex data (coordinates, normals, colors, texture coordinates) and triangle definitions including material assignment. To improve rendering speed triangles are sorted by material and optionally converted to triangle strips (this is vital on the PS2). All triangles that use the same material are stored in one Mesh (RpMesh). A reference to this list of Meshes (RpMeshHeader) is stored in the Geometry. If an Atomic is to be rendered, its Geometry must be in a platform dependent format that can quickly be rendered by the hardware. Converting the platform independent to hardware specific geometry is called instancing. If a Geometry that has been instanced is streamed out (e.g. to a DFF), only the instanced data will be written, the original data is lost. When it is streamed in again it is said to be pre-instanced. Since the instanced geometry is generally not intended to be modified by the programmer, pre-instanced geometry cannot/should not be modified at runtime. Vertices and normals are contained within Morph targets which in turn are contained in the Geometry. They can be used to morph the geometry into different shapes. This is not used in GTA DFFs -- and Geometries consequently only have one morph target -- but is used to animate wavy water.
A RenderWare PowerPipe (RxPipeline) is a versatile tool that can in theory be flexibly used for many tasks but is in most cases very simple and just used for instancing and rendering geometry. In these cases it is just a collection of functions and configuration values. Pipelines can be assigned to Atomics and Materials; in practice on almost all platforms only Atomic piplines are used, the PS2 being a notable exception. The implementations of pipelines are platform dependent but the general idea is to have a function which instances the geometry and one that renders it. On the PS2 things are a bit more complicated as RW interfaces with the hardware directly instead of an abstraction like DirectX or OpenGL. For an explanation of the format of instanced data see Native Data PLG (RW Section).
Theoretically every pipeline could render the supplied geometry in a completely unique way. In practice however most don't deviate too much from what the stock RW pipes do.
The Geometry has two flags that control rendering: the lighting flag determines whether the geometry is to be lit, the modulate flag determines whether the materials' color should be taken into account for rendering.
A Material has a color, surface properties and an optional texture (surface properties are a value between 0.0 and 1.0 for each of ambient, diffuse and specular lighting). Other plugins (in particular RW's MatFX plugin) add more properties that allow more complex effects.
Lighting on the geometry is the sum of dynamic and static lighting. Dynamic lighting is calculated by the active lights in the scene the geometry's vertex normals. Static lighting is baked into the geometry and stored as vertex colors. The most general equation that calculates each vertice's color is
out = (ambientLight*ambientProperty + diffuseLight*diffuseProperty + prelighting)*materialColor
If the modulate flag is 0, the material color is taken to be white. If the lighting flag is 0, lighting is ignored and the material color is output directly.
Note that RW does not support specular lighting by default. The specular surface properties is free for other uses.