Você está na página 1de 61

Technical Design

Date Issued: June 28, 2001 Filing Path: SV040:1676/depot/docs/TechDesign


Document Title: Dark Angel Rendering Engine Technical Design Document
Author: Nigel Brooke
Keywords: Rendering, Dark Angel, Portals, Shadows, Lighting, Bundles

Revision History
Issue Date Person Reason - include problem #, ECN #, etc.

0.1 April 5, 2001 Nigel Brooke Initial version of document.

0.2 May 5, 2001 Nigel Brooke Updated version with detailed class information.

0.3 June 5, 2001 Nigel Brooke Updates after internal review by Bert Sandie.

1.0 June 27, 2001 Nigel Brooke Updates after formal review by Tim Bennison,
Stephen Lambie, Neall Verheyde, Juneko
Kurahashi and Bert Sandie.

2.0 June 28, 2001 Bert Sandie Formatting: added revision history, table of
contents, etc.

 Radical Entertainment. All rights reserved. No part of this publication, or any software included with it may be reproduced, stored in a retrieval
system, or transmitted in any form or by any means, including photocopying, electronic, mechanical, recording or otherwise, without prior written
permission of the copyright holder.

This document contains proprietary information of Radical Entertainment. The contents are confidential and any disclosure to persons other than
the officers, employees, agents, or subcontractors of the owner or licensee of this document, without prior written consent of Radical
Entertainment is strictly prohibited.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

TABLE OF CONTENTS

1. Introduction..............................................................................................................................4
1.1 Scope................................................................................................................................4
1.2 Intended Audience ...........................................................................................................4
1.3 References........................................................................................................................4

2. Rendering Engine Architecture................................................................................................5


2.1 Design Goals....................................................................................................................5
2.2 Loading ............................................................................................................................6
2.3 Rendering.........................................................................................................................7
2.4 State Update ...................................................................................................................11

3. Art Pipeline and Data Formats...............................................................................................14


3.1 Bundles ..........................................................................................................................14
3.2 Data Formats..................................................................................................................14
3.3 Art Pipeline Data Flow ..................................................................................................16
3.4 Pre-generated Lighting Algorithms ...............................................................................16

4. Rendering Engine External Interface.....................................................................................19


4.1 Render::Interface ...........................................................................................................19
4.2 Render::Interface Class Definition ................................................................................19
4.3 Types..............................................................................................................................20
4.4 Individual Function Descriptions...................................................................................21

5. Rendering Engine Detailed Technical Design.......................................................................24


5.1 Overview........................................................................................................................24
5.2 Rendering flow...............................................................................................................25
5.3 Core Engine ...................................................................................................................26
5.4 World Subsystem ...........................................................................................................28
5.5 Object Subsystem...........................................................................................................40
5.6 Effect Subsystem ...........................................................................................................45
5.7 NIS Subsystem...............................................................................................................48
5.8 Display Subsystem.........................................................................................................53
5.9 Debug Subsystem...........................................................................................................57

6. Platform Considerations.........................................................................................................59
6.1 Supported Platforms.......................................................................................................59
6.2 Platform Compatibility ..................................................Error! Bookmark not defined.
6.3 Multi-platform Development Strategy...........................................................................59

7. Development Schedule ..........................................................................................................60

Issue: 2.0 Page 2 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
7.1 Risks...............................................................................................................................60
7.2 Dependencies .................................................................................................................60
7.3 Development Plan..........................................................................................................60
7.4 Test Plan ........................................................................................................................61
7.5 Overall Effort Estimate ..................................................................................................61

Issue: 2.0 Page 3 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

1. INTRODUCTION

The document describes the architecture of the graphics rendering engine to be used for the Dark
Angel project. It outlines the data formats used as input to the rendering engine (and the
algorithms by which they are produced), the rendering algorithms used in the game runtime, a
high-level architectural viewer of the runtime rendering engine, and a detailed technical design
of the classes that make up the rendering engine.

1.1 Scope

This document deals with the runtime components of the rendering engine, as well as the tool
pipeline used to transform data produced by Maya, the World Builder and associated tools, into a
format usable by the runtime. It does not address the World Builder itself, or any runtime
considerations not related to graphics rendering (sound, AI, etc.).

1.2 Intended Audience

A basic knowledge of 3D graphics algorithms and math, as well as familiarity with the Pure3D
API is assumed. Primarily this document is aimed at programmers and other technical personnel
on the project team and in support and management roles.

1.3 References

[1.] Inglehart, Mike. DA Game Design High Concept.

[2.] Inglehart, Mike. DA Preliminary Game Design.

[3.] Keong, Gary. DA: Software Architecture Overview

[4.] Jensen, Henrik: Realistic Image Synthesis Using Photon Mapping

Issue: 2.0 Page 4 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

2. RENDERING ENGINE ARCHITECTURE

2.1 Design Goals

The three key features of the external design of the renderer are:

- Narrowness of interface

- Opacity

- Maximum state retention

- Reuse

“Narrowness of interface” means that the game communicates with the renderer through as small
a set of function entry points as possible. This means that of necessity this interface must be very
high level, and deal in the games concepts rather than in rendering concepts. The key benefits
here is that as long as the interface is defined early and well then the renderer and the rest of the
game can develop with very little dependency on each other.

“Opacity” means that the operations of the rendering system will be completely invisible to
other game systems. Similarly the operation of the other game systems are not visible to the
renderer. The game should never reference internal rendering data structures directly, and vice
versa. The main improvement this brings is in the stability of the system. Since communication
only goes through a small set of entry points (narrowness of interface, above) with no direct
coupling, the set of inputs to the system is easy to examine, and the behavior of the system is
very reproducible. Some exceptions will, unfortunately, need to be made to this principal. In
particular the renderer will need to be in closer collaboration with Scrooby to manage rendering
the front end and overlays that a strict application of this policy would allow for. This is because
the front-end rendering exists in a separate, self-contained system, and thus the renderer will not
be issuing Pure3D calls related to front-end rendering. However this rendering needs to take
place within the context of the Pure3D scene. Thus at some point during a frame, renderer will
need to call into Scrooby to perform front-end rendering.

“Maximum state retention” means that the renderer holds as much data internally from frame to
fame as it can. Rather than the game AI sending the entire state to the renderer every frame, as a
more conventional immediate mode rendering system like Pure3D does, the AI will only send
the renderer information about the changes in the world. As mentioned above, this data would be
in a very high level formal. This give the renderer flexibility to store it’s data in whatever format
it likes (and even change formats dramatically without affecting the rest of the game). Coupled
with the ability to exploit coherence between frames, this will allow the renderer to achieve very
high performance compared to a less flexible immediate mode rendering system.

For example: In a normal immediate mode rendering system where an object was being drawn,
every frame it would be submitted for rendering along with a matrix containing its position. To

Issue: 2.0 Page 5 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
cull this object the object would be compared against the viewing frustum if it is within the
frustum. In the proposed system the object is stored in the renderer, and a new matrix is sent
whenever the object is moved. Because the renderer can distinguish between an object at rest and
it motion, it can avoid performing a visibility test for the object, because it can now that the
object was not visible last frame and has not moved. (Assuming the camera has not moved
either, which the renderer will also know).

“Reuse” means that the system will be set up in such a way that either the whole system or
portions of the system can be reused in other projects. This means that code should have minimal
coupling with the rest of the game engine, and between disparate systems in the renderer itself.
The other goals of opacity and narrowness of interface are helpful in achieving this.

2.2 Loading

Loading will be based on the concept of ”bundles”. A bundle is simple a set of related data. It
could be a character, and NIS, or a room and associated geometry.

Bundles can consist of multiple .p3d (or other types) files. Each bundle will be defined using a
text file. Furthermore there will be a master list of all bundles used in the game (the manifest),
also stored as a text file.

The game can initiate three operations on a bundle :

- A forced load: the bundle will be loaded immediately. Stopping gameplay if


necessary. This will generally happen at the beginning of a level or gameplay section
when a number of needed bundles are loaded.

- A requested load: an asynchronous request to load the data is initiated and will be
completed as soon as possible without interrupting gameplay. This would happen
when the game knows that a new room or object will be needed soon, be the game
needs to continue playing (and the renderer would not be able to determine this via
it’s heuristics for what data to bring in next).

- An unload: the data is removed from memory (if possible, the data may be in use by
the renderer, in which case the unload might not be performed immediately.).

However the system should be set up in such a way that load operations are optional rather than
being forced, and would be primarily used to give hints to the renderer for more efficient data
use. The reason for this is that the bundles, or possibly the manifest, should know what sort of
data resides in each bundle. So that when a particular piece of data is needed inside the renderer
(for example a particular room has become visible, or a character has been allocated) it can
determine which bundle is needed for that data, and load it automatically. This will be done
through the concept of “exports”. Each bundle definition will have a list of exports, which are
lists of the high level data objects that this bundle is used to construct. These exports will be
searchable to allow the system to find a bundle that is capable of producing the high level object
with a given name and type.

Issue: 2.0 Page 6 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
The renderer will have a set of heuristics for determining when rooms need to be brought in,
based on the visibility of rooms in the currently loaded data set and the portal structures. This
will allow it to detect and load rooms ahead of where the player is going without any
intervention from the AI.

`There should be a hierarchical organization to the bundles, either in a directory structure on


disk, or in the structure in the manifest. Loading requests should accept standard wildcards, so
that several bundles can be loaded or unloaded with a single call. For example, if a level consists
of three rooms: Level1.Room1, Level1.Room2 and Level1.Room3, there should be a call of the
form Load(“Level1.*”) that can load all of them.

The bundles will also store dependency information, i.e. if any Pure3D objects in the current
bundle reference objects in other bundles. The loading system will utilize the user-specified store
functionality of the Pure3D loading system to enforce these dependencies, each bundle will live
in a separate Pure3D store derived object, which will be passed into the rendering system, and
each bundle will know what other bundles it can search while loading.

The loading system, despite its name, is really a data management system. Actually disk I/O and
data parsing will be performed by other code. In the case of disk management, the game will
have a unified system for handling all disk access and the renderer loading system will route
requests from files through that through that. The Pure3D loading system will generally handle
data parsing, since most of the renderer’s data is in Pure3D formats.

2.3 Rendering

Each frame the render produces a view of the current state of the game world (how that state is
arrived at is discussed in the next section). This is done in response to a single call in the main
function call interface of the rendering engine. What the rendering engine renders, and how it
renders them is discussed here.

2.3.1 World Geometry

The world geometry system is the foundation of the renderer. It draws all static objects in the
world, as well as serving as a container in which dynamic objects can be held. The fundamental
object in the world geometry rendering system is the Room.

A room consists of the following major components:

- The polygons that make up the base immobile geometry of the room.

- Static objects that can either move along a fixed path, or be destroyed. (any object
that can be moved arbitrarily is a dynamic object, and is handled separately). For
example a door, which can only open or close.

- Information about modifiers that affect dynamic objects as they move through the
room (light & shadow volumes, fog volumes, etc..)

Issue: 2.0 Page 7 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
- A list of references to dynamic geometry that are currently in the room.

- A list of effects (either triggered or constantly updating) that can affect the room.
(these are added to the master effects list at load time)

- Several portal structures that define an area through which another room can be seen.

- A set of convex polyhedra that define the area of the room. These can be used to
determine whether a given point in space is inside a room. (a necessary piece of
information for the visibility calculations)

World rendering will proceed as follows:

- A pointer to the room that the camera is in will be maintained by the rendering
system. This will be updated in response to camera move requests.

- The base geometry will be rendered for the current room.

- All objects in the current room will be tested for visibility against the camera frustum
and rendered if visible.

- For each portal out of the room, the portal polygon is tested against the camera
frustum.

- If a portal is within the frustum a new frustum will be generated that clips the current
camera frustum against the portal polygon. Then that room is rendered using the same
technique.

A portal can also be set up that points into the same room it comes from. This is a mirror portal,
which behaves like a normal portal, except that it inverts the co-ordinate system of the camera
before continuing rendering, resulting in a mirror effect.

Portals can also have textures associated with them that are approximations of the geometry in
the room beyond them, these can be used if the room on the other side of the portal is not loaded,
or if rendering complexity for a give frame is getting too high and the system can’t afford to
render another room.

A portal may have a door associated with it. A door is a triggered world object that when in
particular states may block the portal, causing it to not be rendered through.

2.3.2 Dynamic Objects

Dynamic objects are any object that can move though the world under AI control. This could be
a character, a prop, or a special effect.

There will be a large table of all dynamic objects that can be created in the world, indexed by
name. Each entry will contain a template that can be used to instantiate an object, including

Issue: 2.0 Page 8 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
Pure3D drawables and other information relating to the object. For props this could be very
simple, such as a single tGeometry shader between all instances, for more complex effects or
characters there may be a CompositeDrawable and information about what data can be shared
and what data needs to be duplicated per instance.

When a dynamic object is created, a dynamic object instance is created based on this template
and placed in two other lists. The global dynamic object list is a large table of all dynamic
objects currently existing in the game world. This table is used by the render engine to dispatch
information coming from the AI to specific dynamic objects. A handle into this table is returned
to the AI from the dynamic object creation function.

Each room also has a list of all dynamic objects that are contained within it, that is used by the
renderer to handle visibility determination. As objects move from room to room, they are shifted
around between the tables belonging to those rooms.

Each dynamic object has a matrix associated with it that defines its position in the world.
Dynamic objects may also have two other optional pieces of information associated with them.
For dynamic objects that have a skeleton, they have a pose associated with them. For dynamic
objects that have an AI controlled animation associated with them, there is also a time parameter
that can be set. Some dynamic objects may also have animation information associated with
them that is updated automatically based on time. In this case the global time is essential used as
the time parameter for that object. Dynamic objects that have behavior like this are also effects,
and would also appear in the effects list mentioned below.

2.3.3 Effects

An effect is anything that has a behavior that changes over time. Effects are driven via the tame
parameter passed into the rendering system each frame. Effects by themselves do not have any
sort of drawn representation, that means that anything that is an effect will likely have a
rendering representation that is either a world object or a dynamic object.

There are two lists associated with effects, the active effect list and the inactive effect list. The
active effect list is the list of all effects that are currently running in the world. This list is
traversed each frame to update the state of animation objects based on time. The inactive effects
list contains events that are not currently active, but need to be triggered before they begin
animating. Just because an object is on the inactive list does not mean that it isn’t doing
anything. Objects on the inactive list are simply not being updated automatically.

Whenever a room is loaded, or a dynamic object that has associated effects is created, an
associated effect objects is placed on one of these two lists, depending on the nature of the effect.
For example, a animating water texture in the world would be updating all the time, and thus
would be placed on the active list immediately on room load, a piece of glass that can shatter
would be placed on the inactive list, since the shatter would only happen in response to an event.

Issue: 2.0 Page 9 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
There are three kinds of events that can be sent to effects. Start events, stop events and set time
events. Start events simply move an effect from the inactive list to the active list. Stop events do
the inverse, moving an object from the active to inactive list.

For example, say there is a jet of steam coming from a pipe that is turned on when a player-
initiated certain event occurs (say a valve is turned). The effect would start on the inactive
effects list, and not be drawn. When the valve is turned, the AI would sent the renderer a start
event for the effect, turning on the jet. Thereafter it would proceed under render control. If it is
possible for the player to restore the valve to it’s original position, the AI could then send the
renderer a stop event to turn the jet off.

Set time events only apply to objects on the inactive list, and they directly set the time parameter
on the effect. This means that object on the inactive list are essentially under AI control, if the AI
chooses to exercise that control. An example of direct AI control of an effect might be a wall
texture that can show damage via a texture animation. As the wall becomes more damage the AI
would manually update the effect to move through the texture animation.

2.3.4 Modifiers

Modifiers are areas or objects (generally volumes) that modify dynamic objects that move
through them. These include things like lighting, shadows and fog. These are the trickiest of all
the rendering components, because they require the greatest customization of the rendering
pipeline to implement.

For lighting, each room will store a list of lights that can affect that room. There can theoretically
be a infinite number of lights in a room (in practice there will probably be a reasonable, but large
limit, say 32 or 64). For each dynamic object the lighting system will generate an influence set of
lights. That is a set of lights that conforms to the hardware limits of the platform that
approximates the contributions of all lights in the scene. This may involve selecting which lights
in the scene have the greatest influence, or it may even mean generating new light that
approximate the contributions of several lights in the scene.

2.3.5 Shadowing

Shadowing will be carried out via a number of solutions. For world geometry, all lighting and
shadow information will be stored in light maps.

For characters shadows will be handled in different ways depending on the situation. For normal
gameplay, shadows will be handled by a simple sampling of the world light level to generate a
global illumination value for the object. When more detailed shadowing is needed, characters
will be able to have a projective texture shadows applied to them. Use of these will generally be
reserved for situation where dramatic lighting is artistically important and will need to be hand
built to a certain degree.

For shadows cast from characters a stencil-buffer solution will be used when detailed shadows
are needed. The PS2 does not have direct support for stencil buffer shadows, however it may be

Issue: 2.0 Page 10 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
possible to use the destination alpha channel as a 1-bit stencil buffer (which is all that is needed
for stencil shadows). If this turns out to be infeasible render to texture and projective textures
will be used for detailed character shadows. When detailed shadows are not needed a simple
blob will be used.

2.3.6 Non-interactive sequences (NIS)

The rendering system should be able to play NIS for non-gameplay plot and character
development. The NIS system will be very simple. It will simply use the Pure3D Scene-graph
and Multi-controller systems to display a scene, with animation, exactly as exported from Maya
by the artist responsible for creation. A simple interface will be provided to start and cancel the
playing of an NIS.

Objects drawn in and NIS will be passed though the standard rendering pipe. That is they will be
converted into a temporary object that is equivalent to a dynamic object, they will be passed
through the room structure sot that lighting and other modifiers can be applied to them, and then
on to the display for rendering. This will require a special scenegraph rendering traversal custom
to the engine to be implemented.

The current NIS manager will be reused (with some modification) to perform this task.

2.4 State Update

Each frame, the AI runs and updates the state of the renderer prior to displaying the graphics for
that frame. All these state updates calls are made through the calls into the main function call
interface of the renderer.

The renderer is completely state-driven, that means that given the same set of state calls relative
to display calls, the renderer should produce the exact same rendered frames. This is a useful
property because it makes it possible to reproduce error conditions in the renderer easily given
the correct support structure.

The major elements of state that the renderer needs to deal with are :

- Time

- Camera information

- Dynamic object creation and destruction.

- Dynamic object position & other state

- Trigger events for effects

- Level change information

Issue: 2.0 Page 11 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
2.4.1 Time

Time is the simplest input that the renderer has to deal with. For the most part time is simply
distributed among the dynamically updating components of the system (effects).

In general the renderer will assume that time is monotonically increasing at some rate, however
when an instant replay is occurring, the rendering system needs to rewind time and replay certain
events. The renderer will interpret a negative time as the start of an instant replay.

The renderer will be told at initialization time how long an instant replay it may be called upon
to deal with and will maintain appropriate internal buffers to handle backing up time. The
renderer is not responsible for storing positions and animations frames to be replayed during
instant replay. It assumes that the AI will be feeding it that information again. However it does
need to buffer certain triggering and creation destruction information. For example if an object
existed at the time that the instant replay is returning to, but has been subsequently destroyed, the
renderer should be able to resuscitate that object automatically.

The system does not deal with highlight reel or replay of long sections of time. In these cases the
AI needs to store all information relating to the playback, including, events outside the time of
the replay. The deterministic nature of the renderer is helpful here, but there is no direct support
for this sort of replay.

2.4.2 Camera

The camera defines the current position from which the view of the world is rendered. The AI
can set the properties of the camera, including the position, orientation and field-of-view.

Additionally, the AI can indicate that the movement or change on a given frame is a camera cut,
that is that the camera rather than moving between the current and last position is cutting to a
completely new location. This allows the render to optimize the visibility calculation, since more
information can be re-used from last frame if the camera is moving along a path, and more
complex visibility calculations can be avoided unless the camera has actually moved to a totally
new location. Camera cuts are also required when moving to non-contiguous locations (such as
another level).

A camera cut can also include an optional transition effect, such as a screen flash.

2.4.3 Dynamic object creation

The AI needs to create and destroy characters and items as the game progresses. The dynamic
object creation function adds a new object to the world, based on a named template. Creation
returns a handle that can be used to modify that object later. Objects can also be destroyed, this
will remove the object from the game world completely. Destruction will include an optional
destruction state that will specify a state for the object to be transitioned to before the object is
removed (for a fade out or breaking effect).

Issue: 2.0 Page 12 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
2.4.4 Dynamic object position and state

Dynamic objects can move about the world under AI control. There are methods to set the
position of a dynamic object (including it’s pose if it is a character or other jointed object).

Objects can also have any number of visible states, defined in their bundle, where alternate
geometry can be substituted depending on game events, to simulate damage or activation. States
can include an animation to transition to the state.

2.4.5 Effect events

As mentioned in the rendering section, effects can exist in either an active or inactive state, as
well as being able to have their state updated manually.

2.4.6 Level change

The rendering level needs to know what level the game is currently playing. Although rooms are
loaded asynchronously and levels could theoretically be traveled between in a seamless manner,
this is undesirable for two reasons. One is that to simplify gameplay there will generally be a
sharp transition, with an NIS or mission briefing between levels anyway. The other problem is
that each level will be stored in a different co-ordinate system, so the ordinary system for
classifying objects between rooms will not work for moving between levels.

There will be a set of events (begin/end) that signifies a level change, is taking place. When a
level change begins, all dynamic objects on the previous level will be destroyed (this does not
necessarily meant that the rendering data associated with them is unloaded, only rooms will
definitely be unloaded, textures and object templates can and should remain loaded). During the
level change objects are created and the camera can be moved to a position in the new level.

Issue: 2.0 Page 13 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

3. ART PIPELINE AND DATA FORMATS

3.1 Bundles

A bundle is a package of data used by the renderer. It could consist of textures, animation data,
geometry or many other types of data.

Bundles are specified by a text file, these text files have a standardized extension (.bdl) so that
they can be easily found through directory iteration. This text file contains two kinds of
information about the bundle: what files make up the bundle, and what kind of high level data
the bundle exports (rooms, dynamic object templates, etc).

Bundles consist of a list of keywords with a number of arguments, the important keywords are

- name : The symbolic identifier associated with the bundle

- depend : the name of another bundle that this bundle depends upon

- file : a file that is loaded as part of the bundle

- export : A high level rendering object to be added to the rendering state when the
bundle is loaded.

Some example bundles are shown below.

name Room02
depend TrainTex
depend InteriorTex01
file room02.p3d
export room Room02
export effect Room02-Door1
export effect Room02-Door2
export effect Room02-WindowBreak

name Thug
file thug_skeleton.p3d
file thug_skin.p3d
file thug_basetex.tga
export object Thug

3.2 Data Formats

3.2.1 World Geometry

The primary unit of world geometry is the room. Each room will be stored in a custom Pure3D
chunk. Most other data relating to rooms will be stored in other standard Pure3D chunks. The

Issue: 2.0 Page 14 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
base geometry of a room will be stored as a composite drawable. Which will in turn reference a
geometry representing the static geometry of the room and a number of geometries representing
the objects that have fixed path movements or other state associated with them. Fixed path
movements will be represented as pose animations on the room composite drawable, state
changes as visibility animations on the composite drawable, or other animations

All data in a given room is in a single bundle, except for texture data. Texture data may be
shader between rooms, but all other data is unique to a given room. Objects in the room need not
be given unique names, except for effects that are exported from the room.

An example chunk format for the room chunks (in p3d schema format) is as follows:

chunk tlDAPlaneChunk DA_PLANE {


float A;
float B;
float C;
float D;
};

chunk tlDAConvexHullChunk DA_CONVEX_HULL {


ULONG NumPlanes;
Chunk tlDAPlaneChunk;
}

struct tlDAPortalVert
{
float x;
float y;
float z;
float u;
float v;
}

chunk tlDAPortalVerts DA_PORTAL_VERTS {


{
ULONG nVerts;
tlDAPortalVert verts
array = nVerts;
}

chunk tlDAPortalChunk DA_PORTAL {


string OtherRoomName

ULONG coordSystemChange;
tlMAtrix newCoordinateSystem;

string DoorEffect;
float doorThreshold;

string texture;

Chunk tlDAPortalVerts
}

chunk tlDAProjTexModifier DA_PROJ_TEX_MODIFIER


{
string TextureName;
tlMatrix Projection;
}

Issue: 2.0 Page 15 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
chunk tlDARoomChunk DA_ROOM {
string Name;
string DrawableName;

ULONG NumPortals;
ULONG NumHulls;
ULONG NumModifiers;
ULONG NumLights;

Chunk tlDAPortalChunk;
Chunk tlDAConvexHull;
Chunk tlLightChunk16;
Chunk tlDAProjTexModifier;
}

3.2.2 Characters & Props

Characters & props are store using standard Pure3D data chunks, namely a Pure3D skeleton, for
the base hierarchy if the object ahs one, and a drawable for the rendering structure (generally a
composite drawable in the case of characters, or a geometry in the case of props).

3.2.3 Effects

Effects will, for the most part be stored as standard Pure3D data types (custom types may need to
be added at a later time for custom game-specific effects, these requirement will be addressed
when/if they actually occur). Each effect will have as root objects a multi-controller that drives
the effect.

3.3 Art Pipeline Data Flow

TODO

3.4 Pre-generated Lighting Algorithms

World lighting for DA will be done using lightmaps. A lightmap is a second texture applied to
the world containing the lighting information. This section describes how the lighting
information will be computed.

There are two major steps in building lightmaps, and the tool will be implemented in two stages:

1) Compute the global lighting solution

2) Create the lightmap textures from the global lighting solution

3.4.1 Stage 1

Stage 1 is the computation of the global lighting solution. The tool takes a Pure3D file
representing the world, along with all the light sources in the world, and must compute the
lighting at every point on the surfaces of the world. The technique we will use to do this is

Issue: 2.0 Page 16 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
called the Photon Map. A Photon Map is a statistical approximation of global illumination using
a Monte-Carlo raytracer. Photon maps are described in more detail in [4].

Toollib will be extended to include a mesh object optimized for raytracing, and basic ray/poly
intersection routines. Also, toollib will be extended to include a Photon Map object as described
in [4]. For Stage 1, the tool will simply write the lighting values into the vertex colours of the
world mesh, giving an approximation of the look of the final system.

The basic flow of the tool for Stage 1 is:

1) Create an empty raytracing mesh

2) Load the Pure3D file describing the world, adding each polygon into the ratyracing mesh.

3) Trace photons from each light source, storing them in the photon map until the global photon
limit has been reached.

4) Save the photon map data for possible reuse.

5) For each vertex in the world, ask the photon map data structure for the illumination at that
point, and write it into the CBV. This can be done on the original meshes, deinstancing them
as needed, or if the original meshes aren’t needed, this can be done on the world mesh,
resulting in a single mesh output.

3.4.1.1 Issues / Questions for Stage 1:

a) Are the material specifications in Maya sufficient to capture the surface properties used for
Photon mapping? Do we need a more sophisticated material model?

b) Do we need to maintain individual meshes in the world, or can we output a polygon soup of
all the polygons from all the meshes in the world? If we can return a polygon soup, the last
step is somewhat simpler.

c) How does the tool interact with the rooms/portals system for splitting up the world? There
are a few possible designs for this interaction:

i) The lightmap tool runs independently on each room.


PRO: This is simple
CON: Light won’t flow through doorways, which will probably not look right.

ii) The lightmap tool runs on the whole world before the room tool runs.
PRO: Simple, and with globally correct lighting
CON: Artists can’t iterate on individual rooms, and must wait for a global computation.

iii) The lightmap tool runs on a given room, but using all adjacent rooms for the lighting
computation.
PRO: Iteration on single rooms is possible

Issue: 2.0 Page 17 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
CON: Complicates the pipeline.

iv) It’s possible to use the precomputed photon map from adjacent rooms to compute the
lighting in another room.
CON: This is probably the most complicated solution.

v) Allowing a combination of i) and ii) in the pipeline would allow artists to iterate on the
look of one room and get accurate global lighting in the full game art build.

Issue: 2.0 Page 18 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

4. RENDERING ENGINE EXTERNAL INTERFACE

4.1 Render::Interface

The external interface of the rendering engine will consist of a single class interface
(Render::Engine). This class interface is the only view that the rest of the game will have of the
rendering. This helps the rendering engine to meet its key design goals of opacity and
narrowness of interfaces, as well as making the system far more decoupled.

With one important exception (the front end/overlay system) all Pure3D rendering calls will take
place inside the rendering engine.

The rendering engine object is a singleton, only one can ever exist in a game. There should be
one global object, which must be accessed through a global pointer or accessor function.

To minimize the compilation coupling in the system, the rendering engine pointer exposed to the
AI will be a pure virtual base class, from which the concrete rendering engine implementation
will be derived. Because the rendering engine calls are very high level in nature, the overhead of
having those functions virtual should not be significant.

This class represents the interface to the rendering engine only. See section 5 for a description of
the implementation of the concrete rendering engine class (Engine).

4.2 Render::Interface Class Definition

class Name;
class Handle;
namespace rmt
{
class Vector;
class Matrix;
}
class tPose;

namespace Render
{

class Interface
{
public:
struct InitData
{
unsigned instantReplayTime;
};

class Callback
{
virtual void Do(void) = 0;
};

virtual void Setup(const InitData&) = 0;


virtual void Shutdown(void) = 0;

Issue: 2.0 Page 19 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
virtual void Display(void) = 0;
virtual void SetOverlayCallback(Callback*) = 0;

virtual void LoadForce(const Name&) = 0;


virtual void LoadRequest(const Name&) = 0;
virtual void Unload(const Name&) = 0;

virtual void SetTime(Time&) = 0;

virtual void LevelChange(Name&) = 0;

virtual void BeginNIS(const Name&, Callback*, bool hold = false) = 0;


virtual void CancelNIS(void) = 0;

virtual void CameraCut(Name&) = 0;


virtual void CameraSetPosition(const RadicalMathLibrary::Vector&) = 0;
virtual void CameraSetTarget(const RadicalMathLibrary::Vector&) = 0;
virtual void CameraSetFrustrum(float fov) = 0;

virtual Handle& ObjectCreate(Name&) = 0;


virtual void ObjectShow(bool show) = 0;
virtual void ObjectDestroy(Handle&, const Name& destructionState) = 0;
virtual void ObjectSetState(Handle&, const Name&) = 0;
virtual void ObjectSetLocation(Handle&, RadicalMathLibrary::Matrix&) = 0;
virtual void ObjectSetPose(Handle&,tPose*) = 0;

virtual Handle& EffectGet(Name&) = 0;


virtual Handle& EffectGet(Handle& object, Name&) = 0;
virtual void EffectRelease(Handle&) = 0;
virtual void EffectStart(Handle&) = 0;
virtual void EffectStop(Handle&) = 0;
virtual void EffectStart(Name&) = 0;
virtual void EffectStop(Name&) = 0;
virtual void EffectSetTime(Handle&,Time&) = 0;
};
}

4.3 Types

4.3.1 Name

A name is a symbolic identifier that uniquely identifies an object. All objects have names
associated with them and can be looked up based on those names. Names will be implemented
using a hashing system, with full text strings being stored only in data files (and in the debug
runtime)

4.3.2 Handle

An opaque reference to an object or effect.

4.3.3 InitData

Structure holding the data used to initialize the rendering engine.

4.3.4 Callback

A base class for callback events. Any time the rendering engine needs to notify the rest of the
game of anything, a game object derived from Callback can be passed in to receive the
notification.

Issue: 2.0 Page 20 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
4.4 Individual Function Descriptions

4.4.1 Setup

Initializes the rendering engine, including allocating memory and setting up internal data
structures. Since there are other that other components of the system need to access Pure3D
(front end, animation and physics), the rendering engine is NOT responsible for initializing
Pure3D. It assumes that a platform and context have already been created.

4.4.2 Shutdown

Cleans up the rendering engine, freeing all data associated with rendering.

4.4.3 Display

Draws the current frame of rendering information to the frame buffer.

4.4.4 SetHUDCallback

Singe the rendering engine controls beginning and ending a frame, the overlay system (which
handles it’s own rendering) needs a way to insert itself into the rendering of a frame.

The callback object will be triggered to give the overlay system a change to render after all other
rendering has completed but before calling tContext::EndFrame

4.4.5 LoadForce

Load a bundle of data into the rendering engine, blocking until the data has been successfully
loaded.

4.4.6 LoadRequest

Load a bundle of data into the rendering engine. The request will be processed asynchronously.

4.4.7 Unload

Removes a bundle of data from the currently loaded data set. Call may not actually unload data if
it is still being used.

4.4.8 SetTime

Sets the current time of the game world, for the purpose of updating animations and effects.

Issue: 2.0 Page 21 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
4.4.9 LevelChange

Perform a level change. The data associated with the current level is discarded, and the new level
becomes the one being display.

When changing levels, a camera cut must also occur.

4.4.10 BeginNIS

Statrs playing a named NIS. The NIS will play until canceled or finished. IF the hold parameter
is set, the NIS will hold on the last frame until cancel is called manually by the AI.

4.4.11 CancelNIS

Cancels the currently playing NIS.

4.4.12 CameraCut

Perform a camera cut. The camera is immediately moved to the new location, and undergoes a
full room classification to determine the current visibility state. An optional named camera
transition effect can be specified.

A camera cut will generally be accompanied by one or more other camera state calls. If a camera
cut is taking place, CameraCut should be called first, then other parameters set.

4.4.13 CameraSetPosition

Moves the camera to a new location in the game world. If the camera moves through a portal as
a result of this call, the visibility state of the world is updated appropriately.

4.4.14 CameraSetTarget

Set the point-of-interest for the camera to a new location in the game world.

4.4.15 CameraSetFrustrum

Sets the viewing frustum (field-of-view) of the camera.

4.4.16 ObjectCreate

Creates a dynamic object from the named template.

Returns a handle that can be used by the other object functions to manipulate the dynamic object.

Issue: 2.0 Page 22 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
4.4.17 ObjectDestroy

Destroy the specified dynamic object. If the object supports state transitions, an optional state
can be specified which will be transitioned into before the object is removed from the game
world.

4.4.18 ObjectShow

Used to set the visibility state of an object. Calling this function with false will cause the object
to not be drawn, but without removing it from the game world. Useful for operations such as
turning of characters when an NIS is running.

4.4.19 ObjectSetState

If the object supports state, transition it into the named state.

4.4.20 ObjectSetLocation

Move the object to the specified location in the game world. If the object is moved through a
portal, the world rendering information will be up dated to reflect the change.

4.4.21 ObjectSetPose

If the object is of a type that has an associated pose (i.e. a character) update its pose.

4.4.22 EffectGet

Get a handle to a named effect, so that the state can be updated.

4.4.23 EffectRelease(Handle);

Release a handle returned by EffectGet.

4.4.24 EffectStart

Start playing an effect. There are two forms, one of which takes a handle returned from
EffectGet, the other a name. The name form should be used

4.4.25 EffectStop

Stop playing an effect. As with StartEfect, this can be done either by name or by handle.

4.4.26 EffectSetTime

Manually set the time for an effect. Used for effects that do not play in time but are directly
under AI control.

Issue: 2.0 Page 23 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5. RENDERING ENGINE DETAILED TECHNICAL DESIGN

5.1 Overview

The organization of the rendering engine follows a pyramidal structure, at the top is
Render::Engine, the implantation of the Render::Interface class mentioned earlier. It performs
very little actual work, but is mainly responsible for dispatching request to other objects in the
system. (Hereafter, unless noted, all classes referred to exist in the “Render” namespace.
Qualifier and namespace blocks are omitted for simplicity)

Below it are the major subsystems. Each of which is responsible for one large area of
functionality. They are

- World : Manages world geometry (rooms), and co-ordinates overall rendering flow.

- Object : Handles dynamic object instantiation and update.

- Effects : Handles creation and updating of effects.

- NIS : Plays NIS sequences

Each of these classes also has a number of helper class that it uses to do the actual work, these
will be detailed in the section associated with each major subsystem.

The last to classes are the base services of the renderer. These are used by all the manager
classes to handle common tasks. There are three of these :

- Loader : Handles data loading and management

- Display : Abstracts the display hardware, handle once-per-frame tasks, and buffering
rendering data for display.

- Debug : Handles internal debugging and profiling tasks. Does not exist in release
mode.

Issue: 2.0 Page 24 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.2 Rendering flow

The flow of rendering proceeds as follows:

- The AI set up the current state of the world by calling functons in Interface.

- Rendering is initiated by calling Interface::Display()

- The Display class sets up the initial state of the render, including camera and other
global state

- The World is called into to begin rendering, each room is rendered beginning with the
room the camera is currently in, and proceeding through portals according to the
portal algoritim.

- For each object that is due to be rendered a Drawable is created

- A number of Modifiers are associated with each drawable depending on the location
in the world where it is rendered (Lights, fog, etc.).

- The Drawables are passed to the Display, which either buffers them (if deferring
drawing is need, for example if the object is translucent) or draws them immediately.
IT uses the modifiers associated with the object to update the global rendering state
prior to drawing.

Issue: 2.0 Page 25 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.3 Core Engine

5.3.1 Name

Class Definition
class Name
{
public:
Name(char*);
Name(const Name&);
Name(P3D_U64 uid);

public:
P3D_U64 uid;

#ifndef NDEBUG
char* string;
#endif
}

Public Interface

Name(char*);

Construct a name from a string

Name(const Name&);

Copy constructor

Name(P3D_U64 uid);

Construct a name from a UID

P3D_U64 uid;

A hashed unique identifier, to allow names to be easily searched and compared without
string operations.

char* string;

The text of the name, stored in debug mode only.

5.3.2 List

List is used throughout the class definitions as a shorthand for a arbitrary length list (i.e.
on that can have elements added and removed on the fly. The exact implementation
should be shared with the rest of the project, possibly the Vector class
(code\util\vector.hpp)

Issue: 2.0 Page 26 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
5.3.3 Engine

Declaration
class Engine
{
public:
void Setup(const InitData&);
void Shutdown(void);

void Display(void);
void SetOverlayCallback(Callback*);

void LoadForce(const Name&);


void LoadRequest(const Name&);
void Unload(const Name&);

void SetTime(Time&);

void LevelChange(Name&);

void BeginNIS(const Name&, Callback*, bool hold = false);


void CancelNIS(void);

void CameraCut(Name&);
void CameraSetPosition(const RadicalMathLibrary::Vector&);
void CameraSetTarget(const RadicalMathLibrary::Vector&);
void CameraSetFrustrum(float fov);

Handle& ObjectCreate(Name&) = 0;
void ObjectShow(bool show);
void ObjectDestroy(Handle&, const Name& destructionState);
void ObjectSetState(Handle&, const Name&);
void ObjectSetLocation(Handle&, RadicalMathLibrary::Matrix&);
void ObjectSetPose(Handle&,tPose*);

Handle& EffectGet(Name&) = 0;
Handle& EffectGet(Handle& object, Name&) = 0;
void EffectRelease(Handle&);
void EffectStart(Handle&);
void EffectStop(Handle&);
void EffectStart(Name&);
void EffectStop(Name&);
void EffectSetTime(Handle&,Time&);

private:
Callback* overlayCallback;
World* world;
ObjectManager* objectManager;
EffectManager* effectManager;
NISPlayer * nis;
Loader* loader;
Display* display;

#ifndef NDEBUG
DebugOverlay* debugOverlay;
#endif

Public Interface

Identical to Render::Interface.

Private data

Callback* overlayCallback;

Issue: 2.0 Page 27 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
World* world;

ObjectManager* objectManager;

EffectManager* effectManager;

NISPlayer * nis;

Loader* loader;

Display* display;

References to the other high level rendering classes.

Remarks

- Responsible for system init/shutdown and allocation of other high-level classes

- Dispatches requests to other systems

5.4 World Subsystem

5.4.1 World

Declaration
class World
{
void Display(void);
void Display(Name&);

void MoveCamera(rmt::Vector& position);

void AddObject(Object*);
void MoveObject(Object*, rmt::Vector& position);

bool IsRoomLoaded(Name&);
void LoadRoom(Name&);
void ReleaseRoom(Name&);

protected:
Room* currentRoom;
List<Room*> rooms;
}

Public Interface

void Display(void);

Display the world. It calls into the Display to generate a starting view volume. Then
starting from the current room it renders geometry and objects and recurses through
portals into adjacent rooms.

void Display(Name&);

Issue: 2.0 Page 28 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
Display the named room. Called by Room during traversal of the rooms to request the
display of a room on the other side of a portal.

void MoveCamera(rmt::Vector& position);

Tell the WorldManager that the camera has moved, allowing it to update the current
room pointer.

void AddObject(Object*);

Add an object to the world. This will classify it into the appropriate room.

void RemoveObject(Object*);

Remove an object from the scene.

void MoveObject(Object*);

Notify the world manager that an object has moved. The position is read from the object
and change in room location will be made.

bool IsRoomLoaded(Name&);

Check if a given room is loaded into memory

void LoadRoom(Name&);

Request the load of a room. This will tell the loading system to load the room into
memory, add it to the room list, and register any effects associated with the room with the effects
system.

void ReleaseRoom(Name&);

Request the unloading of a room. The room and any effects associated with it are
removed from the appropriate list and the memory associated with the room is freed..

Private Date

Room* currentRoom;

List<Room*> rooms;

All the rooms currently loaded in the world.

5.4.2 Room

Public Interface
class Room
{
Name& GetName();

Issue: 2.0 Page 29 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
void Display(ConvexHull& viewFrustum);

bool IsPointInside(rmt::Vector&);
Modifier* CalcLighting(Object*);

private:
Name name;

tCompositeDrawable* baseGoemetry;

int nObjects;
int nUsedObjects;
Object** objects;

int nPortals;
Portal* portals;

int nHulls;
ConvexHull* hulls;

int nModifiers;
Modifier* modifier;

int nLights;
Light* lights;
}

Public Interface

Name& GetName();

Get the rooms name

void Display(ConvexHull& viewFrustum);

Draw the room, using the specified hull as the viewing frustrum.

bool IsPointInside(rmt::Vector&);

Test if a point is interior to the room.

Modifier* CalcLighting(Object*);

Calculate a modifier that represents the lighting state of an object in the room.

Issue: 2.0 Page 30 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

Private Members

Name& name;

The rooms name

tCompositeDrawable* baseGoemetry;

The Pure3D geometry of the room.

int nObjects;

int nUsedObjects;

Object** objects;

List of dynamic objects currently in the room.

int nPortals;

Portal* portals;

List of portals leading from this room.

int nHulls;

ConvexHull* hulls;

List of convex hulls defining interior space of room.

int nModifiers;

Modifier* modifier;

List of modifiers affecting objects in the room.

int nLights;

Light* lights;

List of lights in the room.

Issue: 2.0 Page 31 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.4.3 Plane

Plane is a representation of a plane in space.

Declaration
class Plane
{
public:
Plane(const rmt::Vector& normal, float D);
Plane(const rmt::Vector& p1, const rmt::Vector& p2, const rmt::Vector& p3);
Plane(const Plane& plane);

rmt::Vector normal;
float D;
};

Public Interface

Plane(const rmt::Vector& normal, float D);

Construct plane from plane equation

Plane(const rmt::Vector& p1, const rmt::Vector& p2, const


rmt::Vector& p3);

Construct plane from three points in plane

Plane(const Plane& plane);

Copy constructor

rmt::Vector normal;

float D;

Components of the plane equation

Remarks

This class may be allocated a lot during a frame, due to it’s use in the view volume code.
It will need overloaded new and delete operator that allows it to be allocated out of a recycled
memory pool.

Issue: 2.0 Page 32 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.4.4 ConvexHull

Representation of a convex volume. Used for visibility and room classification.

Declaration
class ConvexHull
{
ConvexHull(rmt::Matrix& camera, float near, float far, float fov, float
aspect);
ConvexHull(const ConvexHull&);
ConvexHull(int nPlanes, Plane* planes);

bool PointInside(const tSphere&);


bool SphereInside(const tSphere&);
bool BoxInsde(const tBox3D&);
bool PolygonInside(unsigned count, const rmt::Vector* verts)

ConvexHull& Clip(const ConvexHull&);

private:
unsigned nPlanes;
Plane* planes
}

Public Interface

ConvexHull(rmt::Matrix& camera, float near, float far, float fov,


float aspect);

Construct a convex view volume from camera parameters.

ConvexHull(const ConvexHull&);

Copy constructor

ConvexHull(int nPlanes, Plane* planes);

Construct a convex hull from a set of planes

bool PointInside(const tSphere&);

Test if a point is inside the volume

bool SphereInside(const tSphere&);

Test if a sphere is inside the volume

bool BoxInside(const tBox3D&);

Test if an aligned bounding box is inside the volume

bool PolygonInside(unsigned count, const rmt::Vector* verts)

Issue: 2.0 Page 33 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
Test if a polygon is inside the volume. Works on convex polygons only, results for
concave polygons are undefined.

ConvexHull& Clip(const ConvexHull&);

Clip the hull

Private Data

unsigned nPlanes;

Plane* planes

The array of planes that make up the volume

Issue: 2.0 Page 34 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.4.5 Portal

Declaration
class Portal
{

ConvexHull& GetPortalVolume(const rmt::Vector& eyePoint);

unsigned GetVertexCount(void);
const rmt::Vector* GetVertices(void);

bool HasCoordinateChange(void);
const rmt::Matrix& GetCoordinateChange(void);

bool HasPortalTexture(void);
bool Display();

bool IsDoorOpen(void);

private
int nVerts;
rmt::Vector* verts;

Name& otherRoom;

bool coordinateSystemChange;
Rmt::Matrix newCoordinateSystem;

float doorThreshold
Effect* doorEffect;

tTexture* texture;
pddiVector2* uvs;
}

Public Interface

ConvexHull& GetPortalVolume(const rmt::Vector& eyePoint);

Generate a viewing frustum looking through the portal

unsigned GetVertexCount(void);

const rmt::Vector* GetVertices(void);

Retrieve information about the portal polygon.

bool HasCoordinateChange(void);

const rmt::Matrix& GetCoordinateChange(void);

Retrieve information about any coordinate system change in the portal. A coordinate
system change occurs when the room on the other side of the portal is not in the same world
space co-ordinate system, as the current room. An example would be a portal that stitches two
separately modeled sections of a level together,

Issue: 2.0 Page 35 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
bool HasPortalTexture(void);

Check if the room has a portal simplification texture.

bool Display();

Draw the portal itself (i.e. the portal polygon with the simplification texture applied)

bool IsDoorOpen(void);

Check if the door associated with the room is open .

Private Data

int nVerts;

rmt::Vector* verts;

The polygon that defines the portal

Name& otherRoom;

A reference to the room on the other side of the protal

bool coordinateSystemChange;

Rmt::Matrix newCoordinateSystem;

Information on the co-ordinate system change (if any)

Effect* doorEffect;

A reference to the effect that controls the door that covers this portal.

float doorThreshold

A reference value used to determine if the door effect has gotten far enough for the portal
to be revealed.

tTexture* texture;

The portal simplification texture. A texture that has a reasonable representation of the
room beyond painted on it.

pddiVector2* uvs;

UVs to apply the portal texture to the portal polygon

Issue: 2.0 Page 36 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.4.6 Modifier

Represents an area that modifies the rendering of other objects in the scene. Used by the renderer
to alter state associated with a drawable. An abstract base class.

Class Declaration
class Modifier
{
public:
enum Type =
{
SHADER,
GLOBAL_STATE
}

virtual Type GetType(void) = 0;


virtual ConvexHull GetAffectedArea(void) = 0;
}

Public Interface

enum Type

Describes what the renderer should do with the modifier (i.e. what subtype it should cast
it into and what functions on that subclass it needs to call..

virtual Type GetType(void) = 0;

Returns the type of the modifier

virtual ConvexHull GetAffectedArea(void) = 0;

Get the area that the modifier affects/

5.4.7 GlobalStateModifier

A modifier that changes some aspect of the global rendering state.

Class Declaration
class GlobalStateModifier : public Modifier
{
public:
virtual Type GetType(void) { return GLOBAL_STATE; }
virtual void PreRender(void) = 0;
virtual void PostRender(void) = 0;

Public Interface

virtual void PreRender(void) = 0;

Called prior to rendering the modified object.

Issue: 2.0 Page 37 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
virtual void PostRender(void) = 0;

Called after the modified object is drawn

5.4.8 LightModifier

Class Declaration
class LightModifier : public GlobalStateModifier
{
public:
void PreRender(void);
void PostRender(void);

protected:
int nLights;
tLight** lights;
}

Public Interface

void PreRender(void);

Copies the lighting information into the hardware rendering context.

virtual void PostRender(void) = 0;

Removes lighting information from the hardware context.

Private Members

int nLights;

tLight** lights;

A list of the lights

5.4.9 Shader Modifier

A modifier that changes the shaders applied to an object.

Class Declaration
class ShaderModifier : public Modifier
{
public:
virtual void Set(tShader*) = 0;
virtual void Unset(tShader*) = 0;
}

Public Interface

virtual void Set(tShader*) = 0;

Issue: 2.0 Page 38 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
Perform whatever modification to the shader is necessary.

virtual void Unset(tShader*) = 0;

Undo the shader modification (Note, Pure3D does not currently allow data to be read
back from shaders. This is an issue that we may need to keep an eye on)

5.4.10 ProjectedShadowModifier

Class Declaration
class ProjectedShadowModifier : public ShaderModifier
{
public:
void Set(tShader*);
void Unset(tShader*);

protected:
tTexture* tex;
rmt::Matrix projection;
}

Public Interface

void Set(tShader*);

Apply the projected texture to the appropriate pass of the shader.

void Unset(tShader*);

Disable the projected texture in the shader.

Private Members

tTexture* tex;

The texture to be projected.

rmt::Matrix projection;

The texture projection matrix.

Issue: 2.0 Page 39 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.5 Object Subsystem

5.5.1 ObjectManager

The class that manages

Class Declaration
class ObjectManager
{
unsigned CreateObject(Name&);
Object* GetObject(unsigned);
void DestroyObject(unsigned);

private:
List<Object*> objects;
ObjectFactory* factory;

Public Interface

unsigned CreateObject(Name&);

Create a new object from a template with the specified name, returning a handle.

Object* GetObject(unsigned);

Get an Object based on a handle.

void DestroyObject(unsigned);

Destroy an object

Private Members

List<Object*> objects;

A list of all active objects in the world

ObjectFactory* factory;

A pointer to a factory used to create new objects

Issue: 2.0 Page 40 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.5.2 ObjectFactory

Creates objects from templates

class ObjectFacory
{
public:
void AddObjectTemplate(Name&, ObjectTemplate*);
void DeleteObjectTemplate(Name&);

Object* CreateObject(Name&);

protected:
List<ObjectTemplate*> templates;
}

Public Interface

void AddObjectTemplate(Name&, ObjectTemplate*);

Add an object template. Called by the loading system when a bundle containing a
dynamic object is loaded.

void DeleteObjectTemplate(Name&);

Remove an object template. Called by the loading system when a bundle containing a
template is unloaded.

Object* CreateObject(Name&);

Create an object from the named template.

Private Members

List<ObjectTemplate*> templates;

List of all available templates

Issue: 2.0 Page 41 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.5.3 ObjectTemplate

Class Declaration
class ObjectTemplate
{
public:
Name& GetName(void);
Object* Create(void);

protected:
Object* base;
DuplicationInformation dup;

Public Interface

Name& GetNeme(void);

Get the name of the template

Object* Create(void);

Create an object from the template

Private Members

Object* base;

An object that serves as the basis for creating new ones. For simple objects a new
instance will be just a bitwise copy of this object. For other objects it may need to partially
duplicate some of the hierarchy of objects rooted in this object, or associate special Modifiers
with the object to swap certain objects right before rendering occurs.

DuplicationInformation dup;

Information about how to successfully duplicate complex objects. (Format to be


determined)

Issue: 2.0 Page 42 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.5.4 Object

Class Declaration
class Object
{
public:
tDrawable* GetDrawable(void);

void Display(void);

const rmt::Matrix& GetTransform(void);


void SetTransform(const rmt::Matrix&);

const tPose& GetPose(void);


void SetPose(const tPose&);

void TriggerState(Name&);

bool IsShowing(void);
void Show(bool);

protected:
tDrawable* drawable;
tPose* pose;

StateInformation state;
ObjDuplicationInformation dup;

Public Interface

tDrawable* GetDrawable(void);

Retrieve the drawable associate with the object

void Display(void);

Display the object

const rmt::Matrix& GetTransform(void);

Retrieve the root transform of the object

void SetTransform(const rmt::Matrix&);

Set the root transform of the object

const tPose& GetPose(void);

Retrieve the pose for the object

void SetPose(const tPose&);

Set the pose for the object

void TriggerState(Name&);

Issue: 2.0 Page 43 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
Put the object in the specified state

bool IsShowing(void);

Check if the object is visible

void Show(bool);

Hide/Show the object

Private Members

tDrawable* drawable;

The drawable geometry for the object

tPose* pose;

The objects pose, if it is possible

StateInformation state;

Information about the object states (format to be determined)

ObjDuplicationInformation dup;

Information about how to instance the object (format to be determined, probably a


List<Modifier*>)

Issue: 2.0 Page 44 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.6 Effect Subsystem

5.6.1 EffectManager

Class Declaration
class EffectManager
{
public:
void AddEffect(Effect*, bool active);
Effect* GetEffect(Name& master, Name& name);
void RemoveEffect(Effect*);
void RemoveGroup(Name& master);

void Tick(Time&);

void Activate(Effect*);
void Deactivate(Effect*);

protected:
List<Effect*> activeEffects;
List<Effect*> inactiveEffects;
}

Public Interface

Void AddEffect(Effect*, bool active);

Add an effect the system, placing it on the appropriate list depending on the value of
active.

Effect* GetEffect(Name& master, Name& name);

Retrieve an effect by name, and optionally name of master (master can be empty)

void RemoveEffect(Effect*);

Remove an effect from the system.

void RemoveGroup(Name& master);

Remove all effects with the same master from the system.

void Tick(Time&);

Update the time of the system, updating all active effects.

void Activate(Effect*);

Activate an effect.

void Deactivate(Effect*);

Deactivate an effect

Issue: 2.0 Page 45 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

Private Members

List<Effect*> activeEffects;

The active effects list.

List<Effect*> inactiveEffects;

The inactive effects list.

5.6.2 Effect

The abstract base class for an effect.

Class Declaration
class Effect
{
public:
Name& GetName(void);
Name& GetMaster(void);

virtual void SetTime(void) = 0;

protected:
Name name;
Name master;
}

Public Interface

Name& GetName(void);

Returns the name of the effect.

Name& GetMaster(void);

Returns the name of the effects master object. Either a dynamic object or a room.

virtual void SetTime(void) = 0;

Sets the time parameter for the effect;

Private Members

Name name;

The name of the effect;

Name master;

Issue: 2.0 Page 46 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
The name of the effects master.

5.6.3 AnimEffect

A very simple effect, merely pointing to a Pure3D tFrameController to that it drives

Class Declaration
class AnimEffect
{
public:
virtual void SetTime(void);

protected:
tFrameController* controller;
}

Public Interface

virtual void SetTime(void) = 0;

Sets the time parameter for the effect, by calling advance or set time on the controller.

Private Members

tFrameController* controller;

The Pure3D frame controller associated with the animation

Issue: 2.0 Page 47 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.7 NIS Subsystem

5.7.1 NISPlayer

Class Declaration
class NISPlayer
{
void BeginNIS(Name&);
void CancelNIS(void);

void Tick(Time& time);

void Display(void);

bool IsPlaying(void);

void GetCamera(rmt::Matrix* matrix, float* fov);

protected:
void DisplayScenegraph(Scenegraph::Scenegraph*);

bool playing;

tMultiController* controller;
Scenegraph::Scenegraph* scenegraph;

Public Interface

void BeginNIS(Name&);

Find the NIS with the given name and begin playing it.

void CancelNIS(void);

Cancel the currently playing NIS

void Tick(Time& time);

Update the time on the currently playing NIS

void Display(void);

Draw the scenegraph associated with the NIS

bool IsPlaying(void);

Check if there is an NIS currently playing

void GetCamera(rmt::Matrix* matrix, float* fov);

Retrieve the camera position in the currently playing NIS

Issue: 2.0 Page 48 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

Private Members

void DisplayScenegraph(Scenegraph::Scenegraph*);

Draw a scenegraph, by passing each node through the Render::Display rendering pipe
rather than the standard Pure3D drawing pipe;

bool playing;

Is there an NIS currently playing?

tMultiController* controller;

The multicontroller driving the NIS.

Scenegraph::Scenegraph* scenegraph;

The scenegraph representing the state of the currently playing NIS scene

Issue: 2.0 Page 49 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.7.2 Loader Subsystem

5.7.3 Loader

This class manages loading. It parses the manifest and generates a list of all bundles available for
loading, it can then be directed to load or unload a bundle from memory.

Class Definition
class Loader
{
public:
enum Type =
{
ROOM,
OBJECT,
EFFECT,
NIS
};

Name& Locate(Type. Name&);

void ParseBundleDefinition(char* filename);

bool IsBundleLoaded(Name&);
bool DoesBundleExist(Name&);

void LoadBundle(Name&);
Bundle* GetBundle(Name&);
void UnloadBundle(Bundle*);

void LoadBundles(char* wildcard);


void UnloadBundles(char* wildcard);

protected:
struct BundleStub
{
Name name;
Char* realName;
Bundle* bundle;

char* fileList;

in nDependancies;
Name* dependancyList;

struct Export
{
Name name;
Type type;
};

int nExports
List<Export> exports;
}

List<BundleStub> masterList;
}

Public Interface

Name& Locate(Type. Name&);

Find and object exported from a bundle by name. Returns that name of the bundle in
which the object

Issue: 2.0 Page 50 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

Void ParseBundleDefinition(char* filename);

Parse the specified bundle definition file and add all bundles defined by it to the master
list.

bool IsBundleLoaded(Name&);

Check if a particular bundle is loaded

bool DoesBundleExist(Name&);

Check if the named bundle exists (i.e. has an entry in the master list of bundles.

void LoadBundle(Name&);

Request a load of a named bundle

Bundle* GetBundle(Name&);

Get a reference to a loaded bundle.

void UnloadBundle(Bundle*);

Request an unload of the named bundle

void LoadBundles(char* wildcard);

Load a set of bundles based on a wildcard string

void UnloadBundles(char* wildcard);

Unload a set of bundles based on a wildcard string

Private Member Data

struct BundleStub

A single available bundle. Holding a reference to the bundle object (if it is loaded) and
the information on how to load it (filename and exports).

struct BundleStub::Export

An export point from a bundle.

List<BundleStub> masterList;

The list of all available bundles.

Issue: 2.0 Page 51 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.7.4 Bundle

A unit of related loaded rendering data. It manages all the Pure3D data associated with

Class Definition
class Bundle : public tEntityStore
{
public:
tEntity* Find(tSafeEntityCasterBase& c, const tUID uid);
void Store(tEntity* obj);

protected:
friend class Loader;

void SetSearchDependancies(bool);

tEntityTable* data;

bool searchDependancies;

int nDependancies;
Bundle** dependancies
}

Public Interface

tEntity* Find(tSafeEntityCasterBase& c, const tUID uid);

void Store(tEntity* obj);

Ovverides of the tEntitySore data storage and retreival funcitons

Private Members

void SetSearchDependancies(bool);

bool searchDependancies;

Set whether or not search requests should search dependant bundles. Should only be
turned on during loading of the bundle.

tEntityTable* data;

A table containing the actual Pure3D data in the bundle.

int nDependancies;

Bundle** dependancies

List of all bundles that this bundle is dependant on.

Issue: 2.0 Page 52 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
5.8 Display Subsystem

5.8.1 Display

Class Definition
class Display
{
public:
void SetCamera(rmt::Matrix&, float fov);
void PushCameraChange(rmt::Matrix&);
void PopCameraChange(void);

void GetCamera(rmt::Matrix&*, float fov);


ConvexHull& GetCameraFrustum(void);

void BeginFrame(void);
void BeginScene(void);
void EndScene(void);
void BeginOverlay(void);
void EndOverlay(void);
void EndFrame(void);

void Display(Drawable*);

protected:
tView* view;
tCamera* camera;

tMatrixStack cameraChanges;

List<Drawable*> buffered drawables;

Public Interface

void SetCamera(rmt::Matrix&, float fov);

Set the base camera parameters

void PushCameraChange(rmt::Matrix&);

void PopCameraChange(void);

Change the position of the camera (in response to a portal with a camera change
associated with it)

void GetCamera(rmt::Matrix&*, float fov);

Retrieve the camera parameters

ConvexHull& GetCameraFrustum(void);

Retrieve a camera frustum with which to begin world culling

void BeginFrame(void);

Start a frame of rendering

Issue: 2.0 Page 53 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
void BeginScene(void);

Start drawing the 3D portion of the scene

void EndScene(void);

End drawing the 3D portion of the scene, this wil also render any buffered drawables.

void BeginOverlay(void);

Begin drawing the 2D portion of the scene

void EndOverlay(void);

End drawing the 2D portion of the scene

void EndFrame(void);

End the frame

void Display(Drawable*);

Submit a drawable for display

Private Members

tView* view

Pure3D view object

tCamera* camera;

Pure3D camera object

tMatrixStack cameraChanges;

Matrix stack for holding camera changes

List<Drawable*> buffered drawables;

List of buffered drawables for sorting and rendering at the end of a scene.

5.8.2 Drawable

A single drawable object that the visibility system has determined needs to be renderered. A lot
of Drawables will be allocated and

Issue: 2.0 Page 54 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
Class Definition
class Drawable
{
public:
enum Type =
{
UNKNOWN,
COMPOSITE,
GEOMETRY,
SKIN
}

void* operator new(size_t size);


void operator delete(void*);

Drawable(tDrawable*, const rmt::Matrix&, Type type = UNKNOWN);

bool SetTranslucency(bool);
void AddModifier(Modifier*);

protected:
tDrawable* drawable;
rmt::Matrix transform;
bool translucency;

unsigned nModifiers;
Modifier* modifiers[MAX_MODIFIERS];
}

Public Interface

enum Type

The type of the drawable object. Supplied so that dynamic_cast can be avoided. Some
effects may not render properly if type is no specified correctly.

void* operator new(size_t size);

void operator delete(void*);

Overloaded new and delete, Drawables will be allocated and deallocated a lot during a
frame, so an overloaded new and delete will be necessary for performance and to combat
fragmentation;

Drawable(tDrawable*, const rmt::Matrix&, Type type);

Constrct a drawable from a Pure3D tDrawable and a positioning matrix and a type

bool SetTranslucency(bool);

Set the translucency of the object, controls whether or not the object is buffered.

void AddModifier(Modifier*);

Associate a modifier with an object.

Issue: 2.0 Page 55 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
Private Data

tDrawable* drawable;

The Pure3D object to be drawn.

rmt::Matrix transform;

bool translucency;

unsigned nModifiers;

Modifier* modifiers[MAX_MODIFIERS];

Issue: 2.0 Page 56 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

5.9 Debug Subsystem

5.9.1 DebugOverlay

Class Declaration
class DebugOverlay
{
public:
void Display(void);

void Tick(Time&);

void Message(const char*, Time time = Seconds(5));


void SetStatusLine(unsigned line, const char* text);

private:
struct DebugMessage
{
DebugMessage() : time(0) {};

int time;
char message[STRING_SIZE];
} debugMessages[MAX_MESSAGES];

unsigned nextMessage;

char statusLines[MAX_STATUS][STRING_SIZE];

Public Interface

void Display(void);

Draw the debug overlay

void Tick(Time&);

Update time (to handle message expiration);

void Message(const char*, Time time = Seconds(5));

Print a temporary message to the screen (it will remain onscreen until “time” has
elapsed).

void SetStatusLine(unsigned line, const char* text);

Set one of the available permanent status lines.

Issue: 2.0 Page 57 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

Private Members

debugMessages[MAX_MESSAGES];

unsigned nextMessage;

Structure to hold temporary messages.

char statusLines[MAX_STATUS][STRING_SIZE];

Structure to hold status line text;

Issue: 2.0 Page 58 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

6. PLATFORM CONSIDERATIONS

6.1 Supported Platforms

The platforms that the project is targeted at are the XBox and Playstation2. There is a possibility
that the project may also require a GameCube version at some point.

There should also be an internally maintained Win32 version. The Win32 platform has a number
of advantages as a development environment, including superior debugging and profiling tools,
ease of use, and ubiquity.

A PC Version of the rendering engine, packaged separately from the main game could serve as a
useful artist viewing tool.

6.2 Multi-platform Development Strategy

The code for the PS2 and Xbox will be developed simultaneously.

Issue: 2.0 Page 59 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02

7. DEVELOPMENT SCHEDULE

7.1 Risks

The key technical risk is the implementation of the lighting system. Radical does not currently
have any games which require particularly advanced lighting solutions, so there is no a holistic
system that currently exists for handling lighting and shadowing of dynamic and fixed objects in
a consistent manner. Some research needs to go into testing and evaluating the lighting options
before a final solution is chosen.

The PS2 in particular makes this a risky proposition, since it lacks some rendering features that
will make solutions to the lighting problems easier on the XBox.

7.2 Dependencies

Being the rendering system, the major dependencies in the project are on Pure3D. These include:

- Implementation of an efficient multi-pass rendering system on the PS2. This is


necessary in particular for doing advanced lighting and shadowing on the PS2.

7.3 Development Plan

The first stage of development is to get the renderer test framework up and running. This will be
a small simple application that compiles on all supported platforms and provides basic input
support, and hooks for bolting in renderer test cases. This phase also includes defining the class
headers for the external interface of the renderer and implementing initialization, a simple
loading system, and a simple rendering system (not the ones that will be used in the final system,
but again the goal is to get something running as fast as possible and then never break it).

Once this basic system is in place, development on the rendering engine can begin in earnest.
The major systems that need to be dealt with in approximate order if importance/depandance are
:

- Loading

- Portal rendering

- Dynamic object rendering

- Basic Character rendering

- Effects

- NIS

Issue: 2.0 Page 60 of 61


This Document contains Confidential Information of Radical Entertainment.
Radical Entertainment Technical Design
DA Rendering Engine 18-Oct-02
- Dynamic object lighting

- Advanced character rendering (surface shading)

- World and character shadowing

- Facial animation

7.4 Test Plan

Developing useful test cases for runtime systems is quite difficult, due mainly to the difficulty of
examining the output of the system in a controlled way. There are a number of measures that can
be implemented to verify the correct operation of the renderer.

- A test level : The simplest test available. A small level dedicated to exercising the
features of the renderer, where all code paths available in the rendered will be tested
on a very short walk through of the system.

- A separate executable for the render: As mentioned in the development plan, the
renderer will be initially developed separate from the game code. IF this test
application is maintained, it can be used to test the functionality of the renderer
independent of the game. This removes many variables from testing by not having
code from elsewhere in the game that may itself contain bugs from interfering with
the testing of the renderer.

- A journaling system: Because of the way the interface to render is designed, it would
be a simple manner to intercept all calls into the rendering system and record them.
This journal of a rendering session could then be played back at a later date and
examined in more detail.

The first to systems are fairly simple to implement, and the second is already worked into the
development plan. The third testing aid (journaling) is a little more tricky, and will at the very
least not be pursued in the initial implementation.

7.5 Overall Effort Estimate

The high level estimate for a completed rendering engine with all of the features and
functionality outlined in this document is approximately 80 person days. The work will take on a
number of distinct phases and support for Xbox and PS2 will be performed simultaneously.

Issue: 2.0 Page 61 of 61


This Document contains Confidential Information of Radical Entertainment.

Você também pode gostar