User Guide Vol1

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 312 [warning: Documents this large are best viewed by clicking the View PDF Link!]

User Guide
Volume I
Copyright © 2003 – Criterion Software Ltd.
User Guide
I-2 11 February 2004
Contact Us
Criterion Software Ltd.
For general information about RenderWare Graphics e-mail info@csl.com.
Developer Relations
For information regarding Support please email devrels@csl.com.
Sales
For sales information contact: rw-sales@csl.com
Acknowledgements
Contributors RenderWare Graphics Development and Documentation
Teams
The information in this document is subject to change without notice and does not represent a commitment on the part
of Criterion Software Ltd. The software described in this document is furnished under a license agreement or a non-
disclosure agreement. The software may be used or copied only in accordance with the terms of the agreement. It is
against the law to copy the software on any medium except as specifically allowed in the license or non-disclosure
agreement. No part of this manual may be reproduced or transmitted in any form or by any means for any purpose
without the express written permission of Criterion Software Ltd.
Copyright © 1993 - 2003 Criterion Software Ltd. All rights reserved.
Canon and RenderWare are registered trademarks of Canon Inc. Nintendo is a registered trademark and NINTENDO
GAMECUBE a trademark of Nintendo Co., Ltd. Microsoft is a registered trademark and Xbox is a trademark of Microsoft
Corporation. PlayStation is a registered trademark of Sony Computer Entertainment Inc. All other trademark mentioned
herein are the property of their respective companies.
Foreword
About the User Guide
This is the RenderWare User Guide for release 3.7. The documentation has been
updated for 3.7 and is organized into three volumes of general, platform independent
material. Volume III includes Maestro documentation and a Recommended Reading
appendix .
Xbox, GameCube and PlayStation 2 have a separate platform specific addendum,
containing material which is only useful for that platform and which has been updated
for 3.7.
Volume I contains the core library and the world library, giving basic immediate mode
and retained mode functionality.
Introduction
From the core library:
Fundamental Types
Initialization & Resource Management
Plugin Creation and Usage
The Camera, covering the basics of rendering
Rasters, Images and Textures
Immediate Mode
Serialization
Debugging & Error Handling
From the world library:
World and Static Models
Dynamic Models
Lights
In Volume II elements of the animation systems, special effects and world management
functionality are discussed
Skinning
Fundamental Types for Animation
The Animation Toolkit
Hierarchical Animation
Morph
Delta Morphing
Material Effects
Lightmaps
PTank
Standard Particles (RpPrtStd)
B-splines and Bézier Patches
Collision Detection
Potentially Visible Sets (PVS)
Geometry Conditioning
Foreword
I-4 11 February 2004
Volume III covers the utility libraries, which offer a variety of useful functionality and
an in-depth coverage of PowerPipe, the key to customizing RenderWare for ultimate
performance and unique functionality for your application.
2D Graphics Toolkits
Maestro
The User Data Plugin, on exporting user data
PowerPipe Overview
Pipeline Nodes
Platform specific documentation is included for PlayStation 2, Xbox and GameCube.
PlayStation 2:
PS2All Overview
Pipeline Delivery System (PDS)
Xbox:
Multi-texturing in MatFX
Multi-texturing on Xbox
Xbox State Cache
Xbox Pixel Shaders
Xbox Vertex Format Compression
GameCube:
Multi-texturing in MatFX
Multi-texturing on GameCube
We realize that this User Guide does not cover every single feature in RenderWare
Graphics, but we hope you will find it useful.
Please let us know what you think and feel free to offer any suggestions.
Regards,
The RenderWare Graphics Team
Table of Contents
Chapter 1 - Introduction ....................................................................................... 13
1.1 Welcome to RenderWare Graphics .................................................................14
1.1.1 What you Should Know ...................................................................... 14
1.1.2 What is RenderWare Graphics? ........................................................... 15
1.1.3 Design philosophy ............................................................................. 16
1.2 The RenderWare Graphics SDK......................................................................18
1.2.1 Libraries and Header Files .................................................................. 18
1.2.2 Examples ......................................................................................... 19
1.2.3 Documentation ................................................................................. 20
1.2.4 Artists Tools ..................................................................................... 21
1.2.5 Open Export Framework .................................................................... 21
1.3 RenderWare Graphics Architecture .................................................................22
1.3.1 The Core Library, Plugins and Toolkits ................................................. 22
1.3.2 PowerPipe ........................................................................................ 25
1.3.3 Namespaces ..................................................................................... 25
1.3.4 Just Graphics.................................................................................... 26
1.3.5 Objects ............................................................................................ 26
1.3.6 File I/O ............................................................................................ 27
1.4 Using RenderWare Graphics ..........................................................................28
1.4.1 Creating a scene ............................................................................... 28
1.4.2 Creating prototypes........................................................................... 29
Part A - Core Library ............................................................................................. 31
Chapter 2 - Fundamental Types............................................................................. 33
2.1 Introduction ................................................................................................34
2.2 RenderWare Graphics & Objects ....................................................................35
2.2.1 RenderWare Graphics Objects............................................................. 35
2.2.2 Object Instantiation........................................................................... 35
2.2.3 Object Destruction & Reference Counters ............................................. 36
2.3 The Boolean Type ........................................................................................38
2.4 Characters ..................................................................................................39
2.5 Integer Types..............................................................................................40
2.6 Real Types ..................................................................................................42
2.7 Vectors.......................................................................................................43
2.7.1 Two Dimensional Vectors ................................................................... 43
2.7.2 Three Dimensional Vectors ................................................................. 44
2.8 Coordinate Systems .....................................................................................45
2.8.1 Right-handed Coordinates .................................................................. 45
2.8.2 Object Space .................................................................................... 47
2.8.3 World Space ..................................................................................... 48
2.8.4 Camera Space .................................................................................. 48
2.8.5 Device Space.................................................................................... 48
User Guide
I-6 11 February 2004
2.9 Matrices ..................................................................................................... 50
2.9.1 Matrix Mathematics in RenderWare Graphics ........................................ 50
2.10 Frames....................................................................................................... 52
2.10.1 Hierarchical Models & RenderWare Graphics ....................................... 53
2.10.2 Traversing Frame Hierarchies ........................................................... 54
2.10.3 Matrix Combination Flags in RenderWare Graphics .............................. 55
2.11 Bounding Boxes........................................................................................... 57
2.12 Lines .......................................................................................................... 58
2.13 Rectangles.................................................................................................. 59
2.14 Spheres...................................................................................................... 60
2.15 Colors ........................................................................................................ 61
Chapter 3 - Initialization & Resource Management ............................................... 63
3.1 Introduction ................................................................................................ 64
3.2 Basic Housekeeping ..................................................................................... 65
3.2.1 Initialization ..................................................................................... 65
3.2.2 Shutting down RenderWare Graphics................................................... 70
3.2.3 Changing Video Modes after Initialization ............................................. 71
3.3 Memory Management................................................................................... 72
3.3.1 The OS-level Memory Interface........................................................... 72
3.3.2 FreeLists .......................................................................................... 73
3.3.3 Memory Hints ................................................................................... 75
3.3.4 Resource Arenas ............................................................................... 76
3.3.5 Locking and Unlocking data ................................................................ 77
3.4 Summary ................................................................................................... 79
3.4.1 Starting The Engine........................................................................... 79
3.4.2 Shutting Down The Engine ................................................................. 79
3.4.3 Memory Handling.............................................................................. 80
3.4.4 Plugins ............................................................................................ 80
Chapter 4 - Plugin Creation & Usage ..................................................................... 81
4.1 Introduction ................................................................................................ 82
4.1.1 Toolkits ........................................................................................... 82
4.1.2 Plugins and Streaming....................................................................... 82
4.2 Using Plugins .............................................................................................. 83
4.2.1 Attaching Plugins .............................................................................. 83
4.3 Creating Your Own Plugins............................................................................ 85
4.3.1 Introduction ..................................................................................... 85
4.3.2 Anatomy of a Plugin .......................................................................... 85
4.3.3 The "Plugin" Example ........................................................................ 85
4.3.4 Using the Physics Plugin .................................................................... 88
4.4 Plugin Design .............................................................................................. 91
4.4.1 Introduction ..................................................................................... 91
4.4.2 Extension vs. Derivation .................................................................... 91
4.4.3 Deriving new objects ......................................................................... 91
4.4.4 Plugins & C++ .................................................................................. 92
Table of Contents
RenderWare Graphics 3.7 I-7
Chapter 5 - The Camera ........................................................................................ 95
5.1 Introduction ................................................................................................96
5.1.1 The Camera Example ......................................................................... 96
5.2 The RenderWare Graphics Camera object .......................................................97
5.2.1 Camera Properties............................................................................. 97
5.2.2 The View Frustum ............................................................................. 98
5.2.3 The View Window .............................................................................. 99
5.2.4 The View Offset .............................................................................. 102
5.2.5 Fog ............................................................................................... 102
5.3 The Camera View Matrix ............................................................................. 105
5.4 Rasters & Cameras .................................................................................... 106
5.4.1 Z Buffer Accuracy............................................................................ 106
5.5 Creating a Camera ..................................................................................... 107
5.5.1 Orienting and Positioning a Camera in Scene Space............................. 107
5.6 Rendering to a Camera............................................................................... 109
5.6.1 Destroying a Camera ....................................................................... 110
5.7 Sub-Rasters .............................................................................................. 111
5.8 Other Features .......................................................................................... 112
5.8.1 Clearing the Buffers......................................................................... 112
5.8.2 Cloning a Camera............................................................................ 112
5.9 World Plugin Extensions.............................................................................. 113
5.9.1 About the Extensions....................................................................... 113
5.9.2 Automatic & Manual Culling .............................................................. 113
5.9.3 Clump Cameras .............................................................................. 113
5.9.4 Iterators ........................................................................................ 113
Chapter 6 - Rasters, Images and Textures .......................................................... 115
6.1 Introduction .............................................................................................. 116
6.2 Bitmaps & Textures.................................................................................... 117
6.2.1 Bitmaps ......................................................................................... 117
6.2.2 Images .......................................................................................... 117
6.2.3 Rasters .......................................................................................... 117
6.2.4 Textures ........................................................................................ 118
6.3 The Image Object ...................................................................................... 119
6.3.1 Image Dimensions .......................................................................... 119
6.3.2 Stride ............................................................................................ 119
6.3.3 Palettes ......................................................................................... 119
6.3.4 Gamma Correction .......................................................................... 119
6.3.5 Creating Images ............................................................................. 120
6.3.6 Example: Reading a BMP file ............................................................ 121
6.3.7 Reading the Image .......................................................................... 122
6.3.8 Image Processing............................................................................ 123
6.3.9 Raster Conversion ........................................................................... 125
6.3.10 Destroying Images ........................................................................ 125
6.4 The Raster Object ...................................................................................... 126
6.4.1 Basic Properties .............................................................................. 126
User Guide
I-8 11 February 2004
6.4.2 The Raster as a Display Device ......................................................... 129
6.4.3 Rendering Rasters........................................................................... 130
6.4.4 Accessing Rasters ........................................................................... 131
6.4.5 Reading Rasters from disk................................................................ 131
6.5 Textures & Rasters .................................................................................... 132
6.5.1 Introducing Textures ....................................................................... 132
6.5.2 Loading Textures ............................................................................ 136
6.5.3 Texture Dictionaries ........................................................................ 138
6.5.4 Using Texture Dictionaries................................................................ 139
6.5.5 Platform independent texture dictionaries .......................................... 140
6.5.6 Using PI texture dictionaries............................................................. 140
6.5.7 Non-fixed hardware issues with texture dictionaries ............................ 141
6.5.8 Textures & Binary Streams............................................................... 141
Chapter 7 - Immediate Mode ...............................................................................143
7.1 Introduction .............................................................................................. 144
7.1.1 Properties & Render States .............................................................. 144
7.2 2D Immediate Mode................................................................................... 145
7.2.1 Basic Concepts ............................................................................... 145
7.2.2 Initializing an RwIm2DVertex object.................................................. 147
7.2.3 Primitives....................................................................................... 149
7.2.4 Triangle Winding Order .................................................................... 150
7.2.5 Primitives vs. Indexed Primitives....................................................... 151
7.2.6 Example 1: Rendering A Line............................................................ 152
7.3 3D Immediate Mode................................................................................... 154
7.3.1 Preparation for Rendering ................................................................ 154
7.3.2 Rendering ...................................................................................... 156
7.3.3 Closing the pipeline ......................................................................... 158
7.3.4 3D Immediate Mode & PowerPipe...................................................... 158
7.3.5 Platform Specific Information ........................................................... 159
7.3.6 Camera-space and Z-buffer depth equations ...................................... 160
7.3.7 Rt2D ............................................................................................. 161
7.4 Render States ........................................................................................... 162
7.4.1 Key Features .................................................................................. 162
7.4.2 API................................................................................................ 162
7.4.3 Blending ........................................................................................ 165
7.4.4 Sorting Alpha Primitives................................................................... 166
Chapter 8 - Serialization ......................................................................................167
8.1 Introduction .............................................................................................. 168
8.2 File I/O API ............................................................................................... 169
8.3 RenderWare Binary Streams ....................................................................... 171
8.3.1 Binary Stream Structure .................................................................. 171
8.3.2 Serializing Objects .......................................................................... 173
8.3.3 Explicit Streaming Functions............................................................. 178
8.3.4 RWS files ....................................................................................... 182
8.3.5 Stream Types ................................................................................. 186
Table of Contents
RenderWare Graphics 3.7 I-9
8.4 Summary.................................................................................................. 187
8.4.1 File I/O API .................................................................................... 187
8.4.2 RenderWare Binary Streams............................................................. 187
Chapter 9 - File Systems ..................................................................................... 191
9.1 Introduction .............................................................................................. 192
9.2 File System Management ............................................................................ 193
9.3 The File Systems ....................................................................................... 194
9.3.1 The Generic File System................................................................... 194
9.3.2 OS-Specific File Systems.................................................................. 195
9.4 Using the RenderWare File System............................................................... 196
9.4.1 Basic Usage.................................................................................... 196
9.4.2 Synchronous vs. Asynchronous Access............................................... 198
9.4.3 File System Specific Remarks ........................................................... 199
9.4.4 Creating your Own File System ......................................................... 200
Chapter 10 - The Dictionary Toolkit..................................................................... 203
10.1 Introduction .............................................................................................. 204
10.1.1 This Document.............................................................................. 204
10.1.2 Other Resources............................................................................ 205
10.2 Basic Dictionary Schema Usage ................................................................... 206
10.2.1 Getting the Current Dictionary for a Schema..................................... 206
10.2.2 Setting the Current Dictionary for a Schema ..................................... 206
10.3 Creating and Streaming Dictionaries ............................................................ 207
10.3.1 Dictionary Creation........................................................................ 207
10.3.2 Reading a Dictionary from a Stream ................................................ 207
10.3.3 Writing a Dictionary to a Stream ..................................................... 207
10.4 Dictionary Entries ...................................................................................... 209
10.4.1 Adding Entries to a Dictionary ......................................................... 209
10.4.2 Removing an Entry from a Dictionary............................................... 209
10.4.3 Locating an Entry by Name............................................................. 210
10.5 Advanced Dictionary Schema Usage ............................................................. 211
10.5.1 Schema Structure ......................................................................... 211
10.5.2 Initializing a Schema ..................................................................... 212
10.6 Summary.................................................................................................. 214
Chapter 11 - Debugging and Error Handling........................................................ 215
11.1 RenderWare Graphics Errors ....................................................................... 216
11.2 RenderWare Graphics Builds ....................................................................... 217
11.3 The Debug Object ...................................................................................... 218
11.3.1 The Default Debug Stream Handler.................................................. 218
11.3.2 Sending a Message to the Debug Stream ......................................... 219
11.4 Tracing RenderWare Graphics Activity .......................................................... 220
11.5 Replacing The Stream Handler.......................................................................... 222
11.5.1 Example....................................................................................... 222
Part B - World Library ......................................................................................... 225
User Guide
I-10 11 February 2004
Chapter 12 - World and Static Models ..................................................................227
12.1 Introduction .............................................................................................. 228
12.2 Scenes & Static Models............................................................................... 229
12.2.1 Scenes......................................................................................... 229
12.2.2 RpWorld Object............................................................................. 229
12.2.3 RpWorldSector Object.................................................................... 230
12.3 Iterator Functions ...................................................................................... 231
12.3.1 RpWorld Iterators.......................................................................... 231
12.3.2 RpWorldSector Iterators................................................................. 232
12.3.3 Collision Detection......................................................................... 232
12.4 Modeling Tools .......................................................................................... 233
12.4.1 Viewers........................................................................................ 233
12.5 Creating Worlds......................................................................................... 234
12.5.1 Creating Worlds from Foreign Data .................................................. 234
12.5.2 What is Pre-lighting? ..................................................................... 240
12.6 Rendering................................................................................................. 242
12.6.1 How to Render Worlds ................................................................... 242
12.6.2 Instancing .................................................................................... 242
12.6.3 Pre-instancing Static Geometry ....................................................... 243
12.7 Serialization.............................................................................................. 245
12.7.1 Writing......................................................................................... 246
12.7.2 Reading ....................................................................................... 247
12.8 Destruction ............................................................................................... 248
Chapter 13 - Dynamic Models...............................................................................249
13.1 Introduction .............................................................................................. 250
13.2 The World Plugin ....................................................................................... 251
13.2.1 The Geometry Object..................................................................... 251
13.2.2 The Atomic Object ......................................................................... 251
13.2.3 The Clump Object.......................................................................... 252
13.2.4 Clump Destruction......................................................................... 254
13.3 Creation of Dynamic Models ........................................................................ 255
13.3.1 Model Creation Overview................................................................ 255
13.4 Modeling Tools .......................................................................................... 256
13.4.1 Exporters ..................................................................................... 256
13.4.2 Viewers........................................................................................ 256
13.4.3 Procedural Model Creation .............................................................. 257
13.4.4 Vertices & Triangles....................................................................... 257
13.4.5 Textures & Materials...................................................................... 259
13.4.6 Surface Properties & Geometry ....................................................... 261
13.4.7 Morph Targets .............................................................................. 262
13.4.8 Pentagons & Hexagons .................................................................. 263
13.4.9 Bounding Spheres & Transformations .............................................. 264
13.4.10 Atomics and Clumps ...................................................................... 266
13.5 Objects in more detail ................................................................................ 267
13.5.1 Reference Counting ....................................................................... 267
13.5.2 Texture coordinates....................................................................... 267
Table of Contents
RenderWare Graphics 3.7 I-11
13.5.3 Prelighting.................................................................................... 268
13.5.4 Surface properties ......................................................................... 268
13.5.5 Meshes ........................................................................................ 268
13.6 Atomics, Clumps & Transformations ............................................................. 270
13.6.1 Worlds ......................................................................................... 270
13.6.2 Cloning ........................................................................................ 270
13.6.3 Iterator functions .......................................................................... 271
13.6.4 Sorting Geometry objects by Material .............................................. 273
13.6.5 Animation..................................................................................... 274
13.6.6 Skinned Models ............................................................................. 275
13.7 Optimization ............................................................................................. 276
13.8 Rendering ................................................................................................. 277
13.8.1 How to Render Dynamic Objects ..................................................... 277
13.8.2 Instancing .................................................................................... 278
13.8.3 Pre-instancing Dynamic Geometry ................................................... 279
13.8.4 Converting Model Data to RenderWare Graphics................................ 281
Chapter 14 - Lights ............................................................................................. 285
14.1 Introduction .............................................................................................. 286
14.1.1 Other Documentation..................................................................... 286
14.2 Dynamic Lights.......................................................................................... 287
14.2.1 Dynamic Lights Representation ....................................................... 288
14.2.2 Creating a dynamic light ................................................................ 289
14.2.3 Clump Lights & Streaming .............................................................. 292
14.2.4 Platform-Specific Lighting Models .................................................... 292
14.3 Static Lights using RpLight .......................................................................... 294
14.3.1 Creating Static Lights..................................................................... 294
14.3.2 Static Lighting Techniques .............................................................. 295
14.4 Related Examples ...................................................................................... 297
14.5 Summary.................................................................................................. 300
14.5.1 Dynamic Lights ............................................................................. 300
14.5.2 Static Lights ................................................................................. 301
Index .................................................................................................................. 303
Chapter 1
Introduction
Chapter 1 - Introduction
I-14 11 February 2004
1.1 Welcome to RenderWare Graphics
Welcome to the RenderWare Graphics User Guide!
RenderWare Graphics is a powerful 3D graphics library. This User Guide is
aimed at helping newcomers to RenderWare Graphics become familiar with
the product. This is in addition to the on-line help, and support that is
offered with the purchase of any RenderWare Platform component.
RenderWare Graphics is the result of many years of development, which
began in 1991. The power and flexibility of the product has been increased
with every release. RenderWare Graphics is a multi-platform Application
Programming Interface (API), which is constantly being improved and
updated to keep it at the cutting edge of 3D graphics.
To support the community of developers in the field, we offer our Fully
Managed Support System. Accessible via a personalized web interface, this
allows our technical support personnel to be contacted, the status of
outstanding queries to be tracked, and our knowledge base to be searched
and viewed, plus lots of other useful information. To find out more and
register for the service, point your browser at
https://support.renderware.com/.
If you are new to RenderWare Graphics, it is strongly suggested that you
read this User Guide as you go along to acquaint yourself with its
operation.
Similarly, if you've already been using RenderWare Graphics for a while,
stick around! The User Guide is written by the people who created the
library, so you might gain new insights, tricks and tips. Additionally it has
been revised and expanded to cover all our latest new technology.
RenderWare Graphics is a module of Criterion Software's RenderWare
Platform, the tailored set of open and extensible middleware tools which
allows you to focus on content and gameplay. For further information on
the other Components (including RenderWare Audio, RenderWare AI and
RenderWare Physics) please visit www.renderware.com or contact your
account manager.
1.1.1 What you Should Know
This User Guide makes some assumptions about your level of proficiency
with real-time 3D graphics programming:
This Guide is not aimed at complete newcomers to the field of computer
graphics. If you are new to all this, check out the Recommended
Reading appendix for links to online articles and books you can use as
a starting point.
Welcome to RenderWare Graphics
RenderWare Graphics 3.7 I-15
Secondly, this User Guide will not go into detail about the mathematics
upon which most 3D graphics programming is founded. The whole
point of graphics libraries such as RenderWare Graphics is to do the
math for you.
That said, some college-level math is required to understand some
concepts. If your knowledge of the principles and practices of matrix
and vector manipulation is limited, the Recommended Reading
appendix contains pointers to relevant texts that can help you with this
area.
This User Guide assumes you are an experienced programmer with a
thorough knowledge of the C (or C++) programming language. You
should also be comfortable with the concepts behind object-oriented
programming.
The User Guide is platform-neutral so it will not cover any specific
development environment. Platform-specific variations and optimization
notes will be provided in an appendix.
1.1.2 What is RenderWare Graphics?
A graphics library
RenderWare Graphics is a 2D and 3D graphics API. It is used by
programmers to create real-time 3D graphics applications, such as
computer games and simulations.
Multi-platform
RenderWare Graphics has multi-platform, portable API that allows high
level functionality to be achieved on all platforms, with platform specific
optimizations to get the best from the hardware pipelines.
RenderWare Graphics is available for Sony PlayStation 2, Microsoft
Xbox, NINTENDO GAMECUBE, Microsoft Windows (Direct3D 8),
Microsoft Windows (OpenGL) and Apple MacOS (OpenGL).
Customizable
RenderWare Graphics has a component-based approach to its
architecture based around a small-footprint, thin-layer core library,
supplemented by a number of Plugins and Toolkits.
Plugins are the key to RenderWare Graphics' power; they can extend
existing objects and add new objects of their own that can also be
further extended.
Even the Retained Mode API is a Plugin, which gives RenderWare
Graphics the unique feature of being the only 3D graphics library that
can support any number of Retained Mode APIs.
Chapter 1 - Introduction
I-16 11 February 2004
Further, this Plugin mechanism is fully exposed. You can write your
own Plugins, extending and adding objects, for your own requirements -
we even encourage you to do so, as we do not claim to have thought of
everything!
Compatible with many third-party tools and middleware
RenderWare Graphics is a module of Criterion Software's RenderWare
Platform, the tailored set of middleware tools offering a tightly
integrated game development framework, which includes graphics,
audio and physics modules, with other Components planned for
availability in the future.
1.1.3 Design philosophy
The design brief for RenderWare Graphics was to create a 3D graphics
library that would never be obtrusive. We have tried hard to make sure the
library is the most powerful multi-platform 3D library available.
Platform Independent Development
RenderWare Graphics has been designed from the ground up to let you get
the most out of all its supported platforms – with no compromises. APIs are
provided which expose low-level features and optimization opportunities to
the developer, so the best performance can be obtained from your projects.
The price for this is a little extra work during the porting process: each
platform has different hardware, and different advantages and
disadvantages. RenderWare Graphics gives you the freedom to choose how
far you go down the optimization route:
Need to create a product quickly for more than one platform? No
problem: use the common API features – the facilities provided as
standard across all platforms – and treat it as an ordinary cross-
platform library.
Alternatively, writing custom PowerPipe nodes and plugins enables
RenderWare Graphics to be fine-tuned to specialized performance
requirements. The purchase of a source code license gives the developer
ultimate control over RenderWare Graphics.
RenderWare Graphics gives you the freedom to take either route, or indeed
any path between these two extremes.
Such flexibility does come at a price: where platform-specific features of
RenderWare Graphics are chosen, the code for each target platform will
need to be changed when porting.
C vs. C++
One of the most common questions asked about RenderWare Graphics is
the choice of programming language: C.
Welcome to RenderWare Graphics
RenderWare Graphics 3.7 I-17
There are two reasons for choosing to write RenderWare Graphics in the C
programming language. The first is that there is no standard for C++
libraries; RenderWare Graphics would have to be shipped as a separate set
of libraries for each supported compiler, as well as each platform. Clearly,
this would complicate product support.
Secondly, while C++ has many, many great features, most new platforms –
particularly consoles – don't get a stable, mature C++ compiler until long
after they get a good C compiler. In order for a new platform to be worked
on as soon as possible, the fastest way to achieve this is to use a mixture of
highly optimized C and assembly language.
That said, it is quite possible to mix C and C++. The Plugin mechanism lets
you add space for 'this' pointers to RenderWare Graphics objects with
minimal fuss, and all RenderWare Graphics' header files have the requisite
"extern 'C'" directives to allow the two languages to mix seamlessly.
Several of our licensees have also produced their own C++ wrapper classes
to encapsulate RenderWare Graphics in order to develop in a 'pure' C++
environment.
Chapter 1 - Introduction
I-18 11 February 2004
1.2 The RenderWare Graphics SDK
1.2.1 Libraries and Header Files
RenderWare Graphics is supplied as a number of libraries on the Software
Development Kit (SDK). Applications will need to link against these libraries
and #include the associated header files.
All RenderWare Graphics libraries are static.
Each platform is provided with its own headers and libraries. In addition,
the SDK contains null libraries, which are used by exporters and other
tools. These are provided with all platforms. The null libraries contain all
the PC functionality, but do not perform any rendering.
A NULL target DLL is also provided that the art tools exporters make use of.
This DLL contains almost all of the static NULL libraries.
Note that the static NULL libraries, contained in a RenderWare Graphics
(version 3.5 and above) installation, if linked into an application, require
the multithreaded DLL runtimes.
Null Libraries
On Xbox, GameCube and PlayStation 2 null and nullplatform libraries are also built. For
example, PlayStation 2 RenderWare Graphics SDK is supplied with null and nullsky
libraries. These PC libraries are required for certain tools that process platform specific
data. They can be used for the generation of texture dictionaries.
It should be noted that nullplatform libraries can not create pre-instanced and geometry
data.
Debug, Metrics and Release Libraries
For each platform, separate debug, metrics and release builds of the
RenderWare Graphics libraries are also provided. Debug, release and
metrics libraries live in separate folders inside the rwsdk/lib folder.
RWDEBUG and RWMETRICS preprocessor symbols must be used to indicate
which build is being used.
It is crucial that you do not mix symbols and libraries between these
builds. To illustrate, some API calls are implemented in release builds as
macros. In debug builds these calls are really implemented as functions.
This can mean that if you define the RWDEBUG preprocessor symbol, but link
with the release build of the library you will get numerous "undefined
symbol" link errors.
Compilers supported
Please see the appropriate platform specific top-level readme files supplied
with the RenderWare Graphics SDK for information on the compilers
supported by RenderWare Graphics.
The RenderWare Graphics SDK
RenderWare Graphics 3.7 I-19
SN Systems, Visual Studio IDE integration and Project Files
The RenderWare Graphics SDK provides full support for the SN Systems
Visual Studio Integration features.
Project Build Target settings are included for all platforms supported via
Visual Studio. Developers should ensure the correct Project Build Target is
selected.
1.2.2 Examples
The SDK contains nearly 50 source code examples. Examples are small and
designed to illustrate a particular technique or feature of the RenderWare
Graphics API. They are intended as a means of education: we encourage
you to look through the source code and play with them.
Tools & Viewers
Also included are tools and viewers for you to use during development. Of
particular note is the RenderWare Visualizer viewer, which allows you to
easily view RenderWare Graphics artwork on any target hardware.
Two other viewers are also available for viewing artwork: 'wrldview', and
'clmpview'. 'wrldview' displays static models created for the Retained
Mode API, and 'clmpview' displays dynamic models.
RenderWare Graphics uses a single file format, using chunk-IDs, which is
capable of storing any one or more RenderWare Graphics objects. The
RenderWare Graphics Binary Stream format can be viewed using the
'strview' applet supplied with the SDK.
A Microsoft Visual Studio 6 AppWizard is also supplied with RenderWare
Graphics that can be used to generate an MFC framework-based clump or
world viewer. This AppWizard can be incorporated into Microsoft Visual
C++ and used in the same manner as the standard Microsoft AppWizards.
Please see the accompanying documentation describing how to build a
RenderWare Graphics viewer.
Building the Examples
The examples that are shipped on the SDK should not need compiling to
run them. If you modify them, you will want to re-build the executables.
The Project files provided with the tools and examples are not necessarily
set for your particular platform so make sure you select the correct build
configuration prior to compilation. The two screen shots below show the
Integrated Development Environments (IDEs) and the build targets that
they offer. In Visual Studio, you will need to select the correct Project
Configuration; in CodeWarrior, you must select the correct Target. Further,
there are separate release, debug, and metrics builds. Unless you have
good reason not to, it is suggested that you select:
Chapter 1 - Introduction
I-20 11 February 2004
Win32 D3D8 or D3D9 Release project in Visual Studio for the PC
Xbox Release in Visual Studio for Xbox
PS2 Release in CodeWarrior for the PlayStation 2
GCN Release in CodeWarrior for GameCube
Visual Studio CodeWarrior
1.2.3 Documentation
Documentation is provided in both online and PDF formats. The PDF
format is intended for printing only and is not hyperlinked. The PDF files
have been setup for double sided printing.
The following documentation is provided in the SDK:
This User Guide
API Reference
Tutorials (PC only)
White Papers
Exporter Guides for artists and programmers
Tools and Viewers documentation
Examples document listing all examples with brief explanation
readme_xxx.pdf
All the examples and tools have a related readme.txt file. It is highly
recommended that you read these for information about any last-minute
changes or features.
There is also the top-level SDK readme_xx.pdf file, where xxx is the
platform name, which lists last-minute changes, fixes and known issues
and can be found in the root of the SDK.
The RenderWare Graphics SDK
RenderWare Graphics 3.7 I-21
1.2.4 Artists Tools
The RenderWare Graphics installer can be used to install the artists' tools.
These tools are exporter plugins for exporting 3D model data from packages
such as 3ds max and Maya.
When installed, artists will find:
The modeling package's RenderWare Graphics exporter plugin(s)
Sample artwork demonstrating optimal modeling techniques
Documentation covering how to create and export models successfully for
RenderWare Graphics.
It is strongly recommended that programmers also read the documentation supplied with
the artists tools. The installer adds links to these docs from the start menu.
1.2.5 Open Export Framework
The RenderWare Graphics programmer installer can be used to install the
Open Export SDK that gives you a powerful way of extending the exporters.
Consisting of a series of modular libraries and custom code hooks, you
could soon be introducing new common classes to the modelers, changing
behaviors or creating new object handlers under our plugin architecture.
To get you started, we have provided the Getting Started section in the
Open Export API Reference document. In addition, we have included six
examples of what you can do with the SDK:
ExportObject - An example of a custom object exporter optimizes the
exported textures, by making sure that all texture sizes are beneath a
certain threshold.
MaxSimple - An example of how to write your own custom builder and
export application. To demonstrate this we used a simplified 3dsmax
exporter.
PostProcess An example demonstrates how to post process the entire
list of exported RenderWare Graphics assets, and how to customize the
stream process for streaming them out.
ScaleAnim - This example adds support for animated scale to the
RwExp layer.
TravAction - Demonstrates the use of traverse actions together with
traverse lists that filters out all nodes containing a certain name.
VertexFilter - An example of a vertex filter which pre-lights a scene by
applying per vertex operations.
Chapter 1 - Introduction
I-22 11 February 2004
1.3 RenderWare Graphics Architecture
The diagram below shows how the RenderWare Graphics library fits into a
typical application.
Hardware
RwCore
RpWorld
RW Plugin
Plugin
RW Toolkit
RW Plugin
RW Toolkit
Toolkit
Application
Abstracting the underlying hardware is the RenderWare Graphics Core
Library. Above this is the world plugin. This is the largest and most widely
used of the optional RenderWare Graphics modules. Various plugins
provided with the SDK are shown adding functionality. Also shown are
toolkits, both supplied with the SDK, and non-RenderWare Graphics
Toolkits supplied by third parties. A third party plugin is also shown. Above
these components is the application which uses the services (functions)
exposed by the various components.
The gray boxes above that labeled RwCore are optional. Unlike monolithic
3D graphics libraries, most of the higher-level features can be omitted.
Although it's not explicitly stated in the diagram, RpWorld, which provides
the Retained Mode API, is itself just a Plugin.
1.3.1 The Core Library, Plugins and Toolkits
The RenderWare Graphics components can be broken down:
1. Core Library
2. Plugins
3. Toolkits
The first is the Core Library. The Core Library must always be linked into
your application as it provides the glue that joins all the components
together, as well as basic rendering functionality.
RenderWare Graphics Architecture
RenderWare Graphics 3.7 I-23
Plugins
These are the keys to RenderWare Graphics extensibility. Plugins can
extend existing objects in both the Core Library and other Plugins – and
add their own objects. This feature is what differentiates them from
ordinary libraries. RenderWare Graphics' high-level APIs are all
implemented as Plugins.
Supplied Plugins
The following Plugins are supplied as standard with all releases of the SDK:
PLUGIN DESCRIPTION
RpADC Address Control flag generation
RpAnisot Anisotropy extension for extending textures
RpCollision Collision-detection extensions
RpDMorph Delta morphing and delta animation extensions
RpHAnim Hierarchical animation plugin
RpLODAtomic Level Of Detail extensions for RpWorld's "RpAtomic"
object
RpLtMap Render geometry using detailed static lighting
information from lightmap textures.
RpMatFX Multi-pass special effects, such as environmental
mapping, bump mapping, 2-pass
RpMipmapKL Texture mipmap "K" and "L" value extensions
RpMorph Morph-target animation extensions
RpPatch Bézier patch rendering engine
RpPrtStd Particle animation plugin
RpPTank Creation, management and rendering of user
customizable particles
RpPVS Fast visibility culling extension for RpWorld, using
Potentially Visible Sets
RpRandom Platform-neutral random number generator
RpSkin Skinned model rendering extensions with multiple bone
weights per vertex
RpSpline Spline manipulation extensions
RpUserData Provides functionality for storing user defined data with
geometry
RpUVAnim Attaches UV animations to materials
RpWorld Provides RenderWare Graphics' Retained Mode API –
specifically, the scene graph portion of it
Chapter 1 - Introduction
I-24 11 February 2004
Toolkits
A Toolkit is an ordinary library that just happens to make use of
RenderWare Graphics features. A Toolkit usually provides conversion
functions or other utilities.
Supplied Toolkits
The following Toolkits are supplied as standard with all releases of the SDK:
TOOLKIT DESCRIPTION
Rt2d Advanced 2D Graphics API utilizing underlying 3D
graphics hardware
Rt2dAnim Animation of 2D objects
RtAnim Create, stream and play keyframe animation.
RtBary Mapping points between the barycentric space and
Cartesian space
RtBezPat zier patch generation utility library
RtBMP Microsoft® Windows® Bitmap image format handling
RtCharset A bitmapped character library
RtCmpKey Keyframe system supporting compressed matrix
animation
RtDict Generic containers of named objects
RtFSyst File system manager and custom file systems
RtGCond Geometry Conditioning
RtIntersection Polygon and line intersection testing functions
RtLtMap Generation of lightmap textures - used with RpLtMap
RtMipK Texture mipmap "K" value calculation functions
RtPick Object-picking functions
RtPITexd Platform independent texture dictionary streaming
RtPNG Portable Network Graphics image format handling
RtQuat Quaternion manipulation functions
RtRAS Sun® Raster image format handling
RtRay Ray-casting functions used for picking
RtSkinSplit Skin & Geometry splitter for large bone count models
RtSlerp Spherical Linear Interpolation functions
RtSplinePVS Utility functions to allow PVS generation using spline
paths
RtTIFF Tag Image File Format image format handling
RtTile Tiled rendering functions (used mainly for very high-
resolution renderings)
RtTOC Table Of Contents for a stream
RtVCAT Vertex Cache Aware Tri-stripper
RtWing Winged edge/half-edge
RtWorld Utility functions to be used in conjunction with RpWorld
RenderWare Graphics Architecture
RenderWare Graphics 3.7 I-25
RtWorldImport Utilities for creating RpWorld objects from foreign data
formats
1.3.2 PowerPipe
PowerPipe provides a means of overloading the rendering subsystem either
wholly or piecemeal. You can replace or even create entirely new rendering
pipeline nodes and clusters.
1.3.3 Namespaces
All the RenderWare Graphics functions and objects carry two-letter prefixes
to prevent naming clashes with your own code. This has been used to
provide the best compromise between readability and name length.
The prefixes depend on whether the object in question is part of the Core
Library, part of a Plug-in, or part of a Toolkit. They are:
PREFIX DESCRIPTION
'Rw' Indicates a function situated in the RenderWare Graphics
Core Library ("rwcore.h" / "rwcore.lib"). These functions
are always available as long as the core RenderWare
Graphics library is linked to your application.
Examples:
RwEngineStart() RwCameraCreate()
'Rp' Indicates a function situated in a Plugin library (e.g.
RpMorph.) In most cases, the name of the Plugin follows the
prefix, but this guideline is sometimes ignored to keep
function names sensible.
The appropriate Plugin must be attached if you intend to use
these functions and linked to the appropriate header and
library files.
Examples:
RpMorphPluginAttach() RpPVSAtomicVisible()
'Rt' Indicates a Toolkit. Syntax is similar to that of Plugins,
described above.
Many Toolkits rely on one or more Plugins being attached,
but Toolkits themselves do not need to be attached.
Examples:
RtSlerpCreate() RtTileRender()
'Rx' Used by the PowerPipe API.
Examples:
RxHeapFree() RxPipelineExecute()
'Rs' Source code to a simple (and very basic) platform abstraction
layer used for all examples is provided. Major functions in
this layer use an 'Rs' prefix.
Chapter 1 - Introduction
I-26 11 February 2004
Exceptions These include constants, such as #defines and enum
values. These generally use the same prefixes as above, but
entirely in lower case, followed by an all-caps name, such as:
rwRASTERTYPECAMERA.
1.3.4 Just Graphics
This may seem obvious, but it is important to remember that RenderWare
Graphics only provides multi-platform 3D graphics features. While some
utilities are provided, such as an abstraction layer known as the 'Skeleton',
this code is not officially supported.
Most developers will create their own abstraction layers and write suitable
plugins for RenderWare Graphics to provide a consistent programming
interface across their supported platforms.
1.3.5 Objects
As RenderWare Graphics is written in C and assembler, it makes object-
oriented design that little bit harder to implement. C++ classes might need
to be written to wrap the RenderWare Graphics API.
One important issue to consider is the definition of an object in RenderWare
Graphics.
In C++, objects are an explicit part of the language's design. RenderWare
Graphics 'objects' are either intrinsic, such as int and char, or an ordinary
C struct. These usually have a noun for a name – e.g. World, Clump, and
Vector. The methods or member functions associated with these objects are
ordinary C functions that live outside these structures, but with names
that begin with the same name as the 'object'.
For instance, a hypothetical object called RwThing might have methods
with names like RwThingGetProperty().
RenderWare Graphics objects have been designed to operate in much the
same way as C++ objects. The main difference is that there are no member
selection operators to separate object names from their associated methods.
RenderWare Graphics Architecture
RenderWare Graphics 3.7 I-27
Objects & Properties
Transparent vs. Opaque Objects
RenderWare Graphics developers sometimes make a simple object
transparent. For such objects, you will find complete documentation of the
internals of the object in the API Reference, and often no property-access
function information. This reduces unnecessary function calling overheads:
you are free to directly change the individual object elements.
This reveals the element of trust enshrined with RenderWare Graphics'
design: where a data structure is not explicitly documented, it should be
considered an opaque object. Usually, such objects will have no
documentation for their individual members, so only their associated
property access methods (using the traditional 'Get' and 'Set' convention)
should be used.
The table below shows some examples of opaque objects and access to their
members:
OBJECT PROPERTY 'METHOD' NAME
RwCamera ViewWindow RwCameraGetViewWindow()
RwCameraSetViewWindow()
RpAtomic Geometry RpAtomicGetGeometry()
RpAtomicSetGeometry()
The object’s name always forms the root of the function name. This pattern
is followed consistently throughout the RenderWare Graphics API.
Obviously, the various header files document all members of a particular
struct. In general, these members should not be modified in your code,
but instead use the functions that are supplied in the library.
Of course, C doesn't automatically pass the object instance to the functions, so you still
have to do this explicitly. Usually, the first parameter of a function will be a pointer to the
object.
1.3.6 File I/O
File handling is an important facet of RenderWare Graphics and for this
reason, we provide a file system that can be overloaded. The
RwOsGetFileInterface() can be used to obtain a structure containing
the pointers to the file operation functions. The file pointers in this
structure can be replaced by pointers to your own, which makes it easier to
divert file-handling to the DVD, host machine and possibly even over a
TCP/IP link.
File I/O is enhanced by the file system toolkit, which is composed of a file
system manager, and a set of custom file systems for specific platforms.
More information on this toolkit can be found the File System Chapter.
Chapter 1 - Introduction
I-28 11 February 2004
1.4 Using RenderWare Graphics
1.4.1 Creating a scene
To render scenes in RenderWare Graphics applications, a number of steps
need to be performed:
1. Create assets in a modeling package.
This includes the background scenery and all the characters, props and
other animated models that will populate that scenery. Textures may
need creating in a paint package.
2. Export assets in the RenderWare Graphics format.
The RenderWare Graphics Retained Mode API supports two kinds of
model: static models that live in World objects, and dynamic models that
live in Atomic objects.
Backgrounds and other fixed scenery models are generally considered
static; all other models are dynamic. To add dynamic scenery elements, you
should use dynamic models and position them in the scene accordingly.
These objects are part of the high-level RpWorld Plugin that encapsulates
our Retained Mode API. More on this powerful Plugin can be found in the
two chapters: Worlds & Static Models and Dynamic Models.
3. Load assets into the RenderWare Graphics application.
RenderWare Graphics includes a multi-platform file serialization API –
RwStream – that is used for this purpose.
4. Position them using frames.
Frames, described in the Fundamental Types chapter, are an essential
feature of the RenderWare Graphics architecture. They are attached to
objects so they can be positioned in world space. Frames also manage
model hierarchies.
5. Create lights.
RenderWare Graphics supports a number of lighting models, as well as
both static and dynamic lights, and the standard light model can be
overridden.
6. Create a camera object and orient it.
RenderWare Graphics uses the standard virtual camera metaphor in
the Retained Mode API. This API, and Cameras in general, can be found
in the following chapters: Cameras; Worlds & Static Models and
Dynamic Models.
7. Take a picture.
Using RenderWare Graphics
RenderWare Graphics 3.7 I-29
This process involves the actual rendering of the scene.
8. Update the scene.
If you're producing real-time animation in 3D, you will need to update
the models between renderings.
9. Repeat steps 7 and 8 until the user tells the application to quit.
This is the rendering process in short. Aside from some of the
terminology specific to RenderWare Graphics, this is much the same as
in any other 3D graphics API.
1.4.2 Creating prototypes
In order to be able to write our examples and other sample code just once,
without the need to rewrite it for each target platform, the hardware
abstraction layer called the 'Skeleton' has been developed. Almost all the
sample code supplied with the SDK will use this code as its foundation.
The Skeleton was developed for our sample code. It is not suitable for
anything other than similarly simplistic test-beds and prototyping. It is
absolutely, categorically not intended for use as the basis for a professional
application. However, it does provide a convenient set of functions that can
be used for rapid prototyping of games.
The Skeleton code is completely unsupported. The source code to it is
provided to show you that (a) it can be done, and (b) so that all our tools
and examples can be presented in a consistent way.
Put another way: the Skeleton is provided as-is and with no guarantee for
any suitability or fitness for purpose. You use it entirely at your own risk.
Part A
Core Library
Chapter 2
Fundamental
Types
Chapter 2 - Fundamental Types
I-34 11 February 2004
2.1 Introduction
This chapter covers many of the basic types that are exposed by
RenderWare Graphics.
Some types are simple and transparent, meaning you can access them and
their elements directly. Others may be opaque and you should use the API
provided to manipulate them.
If your development is intended to run on multiple platforms then it is
suggested that you use RenderWare Graphics' data types throughout your
application. The Core Library implements a number of basic data types,
such as RwChar, RwUInt16 and so on, which means that you can rely on
RenderWare Graphics to ensure that on the different platforms the sizes of
these types are correct.
For example, you can rely on the RwChar to be the correct size on a
particular platform to store characters as these are not guaranteed to be
eight bits on all supported platforms.
RenderWare Graphics & Objects
RenderWare Graphics 3.7 I-35
2.2 RenderWare Graphics & Objects
The first chapter explained that RenderWare Graphics is designed along
object-oriented principles. As a result, the concept of objects plays an
important part in understanding how the API works.
Before covering the basic data types then, it is worth looking at the
ramifications of this design in a little more detail.
2.2.1 RenderWare Graphics Objects
C is not an object-oriented language, so one question frequently asked of
the development team is why use C? This question was answered in the
previous chapter, but it leaves open the question of how an object-oriented
design is implemented.
By design, the API looks rather like a C++ based one, without all the extra
punctuation. By necessity, the API supports a plugin mechanism which is
used to extend the "objects". This extension mechanism is managed
programmatically rather than as an intrinsic feature of the programming
language.
For example, a look at the RpWorld plugin's API will reveal a number of
base objects: RwTexture, RpClump, RpWorld and so on. Each of these
objects is actually defined as a standard C struct datatype with their
"methods" – functions – defined as ordinary functions separate from the
data structure.
2.2.2 Object Instantiation
This is usually a two-stage process. The first is to define a variable of the
object's type. For example:
RwTexture myTexture;
It is rare for developers to create automatic instances; allocation on the
heap is far more common. This example therefore defines myTexture as an
object of type RwTexture.
However, C does not support a constructor mechanism in the way C++
does, so myTexture has no valid data in it.
To reduce bugs caused by referencing uninitialized objects, RenderWare
Graphics' API usually provides some form of default object creation
function. In the case of Texture objects, the function is
RwTextureCreate(), which generates a new Texture from the given Raster
object and returns a pointer to the Texture on success.
RwTexture myTexture;
RwTexture * pmyTexture = RwTextureCreate();
Chapter 2 - Fundamental Types
I-36 11 February 2004
Similar creator functions are provided for most RenderWare Graphics
objects and it is advisable to use them where possible.
2.2.3 Object Destruction & Reference Counters
As in C++, RenderWare Graphics objects must be destroyed when you are
finished with them. This is particularly important if you are working on
platforms with limited memory available. However, care is needed to ensure
that you do not destroy objects that are still being referenced elsewhere in
your code…
Although the documentation for RenderWare Graphics talks about things
like container objects, these just boil down to objects that contain lists of
pointers to the objects they contain. The word pointer is emphasized here
because it implies that an object can be referenced by more than one
object.
For example, a Texture can be "contained" by multiple Materials (part of the
World Plugin and a useful container object for Textures), but this just
means these Materials would each contain a pointer to the same Texture.
So far, so obvious, but multiple references can be a problem when it comes
to destroying objects. If a Texture is referenced by multiple objects, some
method is needed to prevent it being destroyed before the other objects
have finished with it.
To avoid this, RenderWare Graphics uses a fairly standard reference
counting system.
For example, if a Texture is referenced by another object, the Texture's
reference counter will be incremented using a call to the Texture's
…AddRef() method. (RwTextureAddRef()) When the Texture is removed
from that object, its counter is decremented. So if the Texture is referenced
by, say, five other objects, its counter will be equal to five.
When the Texture is no longer needed by an object, it should be destroyed
by calling the object's …Destroy() method. (For Textures, the full function
name is RwTextureDestroy().) This function will decrement the reference
counter and, if it is zero, finally destroy the object referred to.
It is important to note that the reference counting system is not fully
automatic. For example, you will need to call …AddRef() and …Destroy()
methods directly if you add a reference to a RenderWare Graphics object to
a structure of your own.
Destruction & Destruction Order
The order in which objects are destroyed is an important consideration.
RenderWare Graphics programming often involves the use of a number of
container objects. A common bug can be brought about by deleting such
containers before deleting the contained objects.
RenderWare Graphics & Objects
RenderWare Graphics 3.7 I-37
For example, take the Clump and Atomic objects. These are part of the
scene graph API provided by the World Plugin (RpWorld). For now, it's
important to know only that Clumps are container objects for Atomics.
A common cause of bugs is to destroy a Clump, then destroy each of its
contained objects by referencing through the Clump. Obviously, the Clump
no longer exists at this point, but many programmers assume that the
pointer is still valid as no code has been executed to overwrite the data yet.
This is a bad assumption to make: some platforms, including Microsoft
Windows, have background tasks running which can easily trigger the
overwriting of such data. This is a common cause of intermittent bugs and
crashes, so you should always destroy objects in the correct order.
Chapter 2 - Fundamental Types
I-38 11 February 2004
2.3 The Boolean Type
RenderWare Graphics supports one Boolean type:
TYPE DESCRIPTION RANGE SIZE
RwBool A standard Boolean type with the
usual two states
FALSE,
TRUE
32 bits
Characters
RenderWare Graphics 3.7 I-39
2.4 Characters
TYPE DESCRIPTION RANGE SIZE
RwChar Character type, in either ANSI or
Unicode format
8 bits (ANSI
char) or 16
bits (Unicode)
RwChar is intended solely for storing individual characters and character
strings (usually 8-bit for ANSI libraries and 16-bit for Unicode libraries).
You should never use RwChar * as pointers to memory as it is wrong to assume it will be
equivalent to the C Language "char" type.
Use RwInt8 * or RwUInt8 * instead.
Chapter 2 - Fundamental Types
I-40 11 February 2004
2.5 Integer Types
RenderWare Graphics is intended to run on a number of platforms. To
ensure consistent behavior, new types are defined to replace the base C
Language ones. The RenderWare Graphics replacements are designed to
behave as consistently as possible over all supported platforms.
RenderWare Graphics defines a number of integer types for specific bit
widths, which are shown in the table on the following page.
These data types are designed to behave identically across all supported
platforms. It therefore makes sense to use these instead of the standard C
data types in your own applications.
Integer Types
RenderWare Graphics 3.7 I-41
Integer types:
TYPE DESCRIPTION RANGE
RwInt8 signed byte (8 bits) -128 to +127
RwUInt8 unsigned byte (8 bits) 0 to 255
RwInt16 signed word (16 bits) RwInt16MINVAL (-32768) to
RwInt16MAXVAL (32767)
RwUInt16 unsigned word (16 bits) RwUInt16MINVAL (0) to
RwUInt16MAXVAL (65535)
RwInt32 signed long (32 bits) RwInt32MINVAL (-231) to
RwInt32MAXVAL (231-1)
RwUInt32 unsigned long (32 bits) RwUInt32MINVAL (0) to
RwUInt32MAXVAL (232-1)
RwInt64 64 bit, signed integers should only ever be
used on platforms with native and
compiler support for 64 bit data types.
On other platforms, this data type is
defined using a struct so no mathematical
operations are available.
-263 to 263-1. No range
defining macros are
defined.
RwUInt64 64 bit, unsigned integers should only ever
be used on platforms with native and
compiler support for 64-bit data types.
On other platforms, this data type is
defined using a struct so no mathematical
operations are available.
0 to 264-1. No range
defining macros are
defined.
RwInt128 128 bit, signed integers should only ever
be used on platforms with native and
compiler support for 128 bit data types.
On other platforms, this data type is
defined using a struct so no mathematical
operations are available.
-2127 to 2127-1. No range
defining macros are
defined.
RwUInt128 128 bit, unsigned integers should only
ever be used on platforms with native and
compiler support for 128 bit data types.
On other platforms, this data type is
defined using a struct so no mathematical
operations are available.
0 to 2128-1. No range
defining macros are
defined.
Chapter 2 - Fundamental Types
I-42 11 February 2004
2.6 Real Types
RenderWare Graphics supports the following real number types:
TYPE DESCRIPTION RANGE SIZE
RwReal Usually equivalent to the C
Language's single-precision
"float" type.
RwRealMINVAL to
RwRealMAXVAL
32
bits
RwFixed 16 bit integer, 16 bit fractional
fixed point value.
Rarely used, as true floating-
point math is usually faster in
current hardware.
RWFIX_MIN to
RWFIX_MAX
32
bits
A common mistake is to forget to provide a trailing "f" on floating point
constants. Some platforms have no double precision hardware support. If
the "f" is omitted from an expression compiled for these platforms the
expression will be assumed to be double precision and it will be emulated
in software. This can dramatically reduce performance. It is recommended
that you get into the habit of either using type prefixes:
RwReal g = 9.8f;
RwReal f = m * g;
or make use of type-casting in expressions, which is more portable:
RwReal g = 9.8;
RwReal f = m * (RwReal)g
Vectors
RenderWare Graphics 3.7 I-43
2.7 Vectors
RenderWare Graphics supports two and three dimensional vector types and
arithmetic.
These types should be considered opaque as they can sometimes map
directly onto underlying hardware vector processing units.
2.7.1 Two Dimensional Vectors
The 2D Vector type is RwV2d. It contains x and y coordinates.
The following functions are provided to manipulate 2D Vectors:
FUNCTION OPERATION
RwV2dAssign() Assignment (Copy) from a source vector to a
target vector
RwV2dAdd() Addition
RwV2dSub() Subtraction
RwV2dLength() Length
RwV2dNormalize() Return a unit normal vector calculated from the
original vector
RwV2dLineNormal() Find a Unit Normal line between two vectors
RwV2dScale() Scale
RwV2dDotProduct() Calculate Dot Product
RwV2dPerp() Calculate a 2D vector perpendicular to the given
2D vector
Chapter 2 - Fundamental Types
I-44 11 February 2004
2.7.2 Three Dimensional Vectors
The 3D Vector type is RwV3d. It contains x, y and z coordinates.
The table below shows the functions available to work with these vectors:
FUNCTION OPERATION
RwV3dAssign() Assignment (Copy) from a source vector
to a target vector
RwV3dAdd() Addition
RwV3dSub() Subtraction
RwV3dLength() Length
RwV3dNormalize() Calculate unit normal vector from the
original vector
RwV3dScale() Scale
RwV3dIncrementScaled() Multiplies the second 3D vector by the
given scalar then adds the resulting
vector to the first vector
RwV3dDotProduct() Calculate Dot Product
RwV3dCrossProduct() Calculate Cross Product
RwV3dNegate() Negation
RwV3dTransformPoints() Transform an array of points or vertices
by the specified matrix
RwV3dTransformVectors() Transform an array of vectors or normals
by the specified matrix
Coordinate Systems
RenderWare Graphics 3.7 I-45
2.8 Coordinate Systems
3D graphics programming requires understanding of a number of common
coordinate systems, known as spaces. Some basic conventions need to be
covered.
2.8.1 Right-handed Coordinates
RenderWare Graphics uses an orthogonal right-handed coordinate system
for its 3D spaces.
Typical right-handed coordinate system
The figure above displays the positive directions of x, y, and z axes with z
pointing away from the screen.
Rotate right-handed coordinate
system about y axis
RenderWare Graphics right-handed
coordinate system
The RenderWare Graphics coordinate system is rotated about the y axis
and the figure on the right displays the positive directions of the x, y and z
axes. The positive z axis points into the screen and the positive x axis
points to the left.
As all the axes are rotated together the coordinate system is always
right-handed.
Chapter 2 - Fundamental Types
I-46 11 February 2004
Axis Naming Conventions
The three axes are defined in RenderWare Graphics by three vectors. By
convention, the axis names used are:
AXIS VECTOR REPRESENTATION
X "Right"
Y "Up"
Z "At"
The vector is sometimes prefixed with the work "look", as in "look-at". This is
commonly used when referring to the camera object which "looks" along the
z axis.
The RenderWare Graphics' coordinate system is right-handed and the x
axis is represented by the right vector. However, as the RenderWare
Graphics coordinate system is rotated the x axis positive direction points to
the left.
For example, the RenderWare Graphics camera faces into the screen,
therefore we're effectively standing behind it. The camera's right vector
points left as the RenderWare Graphics coordinate system has been rotated
about the y axis so that z is pointing into the screen. Therefore moving the
camera, by incrementing its x axis, results in the camera moving further to
the left, along the positive x axis.
In 3D Graphics terminology, the z axis, represented by the "at" vector, is sometimes
referred to as the "front" vector.
Coordinate Systems
RenderWare Graphics 3.7 I-47
2.8.2 Object Space
Dynamic models in RenderWare Graphics are defined in terms of Object
Space. This means that the vertices that define the model are relative to an
arbitrary origin.
For example, the front face of a cube of unit size could be defined thus:
(0,0,0) (1,0,0)
(1,1,0)
(0,1,0)
The origin in this case is the lower-left corner of the front face. However, the
origin could be anywhere – even the center of the cube. This could be
achieved by subtracting (0.5, 0.5, 0.5) from each vertex.
The location of the origin can be important, as it is easier to align models if
their origins are on a shared edge or a corner rather than at some arbitrary
point in the middle or outside the models.
Chapter 2 - Fundamental Types
I-48 11 February 2004
2.8.3 World Space
Dynamic models, defined in Object Space, need to have a frame of reference
so that they can be positioned relative to other models and scene graph
objects. This frame of reference is World Space.
Objects positioned relative to this system are said to reside in world space.
This coordinate system is used, for example, to specify the position of
cameras and lights. Geometry can be positioned in world space using
transformations described later.
A bounding box defines the World Space limits. This is either generated by
a modeling package exporter when exporting World data, or explicitly by the
developer when calling RpWorldCreate().
Frames
The RenderWare Graphics object that allows us to position objects in World
Space is called the Frame (RwFrame). Many RenderWare Graphics objects
require a Frame to be attached before they can be positioned within a
World.
2.8.4 Camera Space
Cameras, like many RenderWare Graphics objects, require a Frame to
define their position and orientation. However, there is another system
called Camera Space which defines the Camera's viewing coordinate
system. A normalized Camera Frustum defines Camera Space as follows:
for a parallel projection model the Camera Frustum space has side
planes at x = 0, x = 1, y = 0 and y = 1
for a Perspective Projection model, it has side planes at x = 0, x = z, y =
0 and y = z
Camera Space is also a right-handed system with an origin at the Camera's
position (given by the Frame's pos vector). The positive z axis of Camera
Space is given by the view direction, which points in the direction of the
Frame's at vector. The units of Camera Space z coordinates are the same as
those for World Space.
RenderWare Graphics also recognizes a two-dimensional coordinate
system.
2.8.5 Device Space
The device coordinate system defines a device space. Its units are those of
the display (screen or window) to which the camera's image buffer is copied
and as such, it has coordinates that only take discrete (or integer) values.
Coordinate Systems
RenderWare Graphics 3.7 I-49
The origin of device space is located at the top-left of the display with the x-
values running from left to right and the y-values running from top to
bottom, as shown in the diagram:
+X
+Y
(0,0)
Device space can also be considered to have a depth component that is
used in the Z buffer.
Chapter 2 - Fundamental Types
I-50 11 February 2004
2.9 Matrices
RenderWare Graphics defines a pseudo-4x4 homogeneous Matrix
(RwMatrix) object to represent 3D transformations. The Frame object, see
2.10 below, makes heavy use of matrices. Matrices in RenderWare Graphics
appear as shown below:
1
0
0
0
zyx
zyx
zyx
zyx
PPP
AAA
UUU
RRR
The row vector (Rx, Ry, Rz) contains the components of the look-right vector,
(Ux, Uy, Uz) are those of the look-up vector, (Ax, Ay, Az) for the look-at vector
and (Px, Py, Pz) are the components of the pos vector. The components of a
matrix are available to the application programmer by using
RwMatrixGetRight(), RwMatrixGetUp(), RwMatrixGetAt() and
RwMatrixGetPos().
2.9.1 Matrix Mathematics in RenderWare Graphics
Matrices are treated as quadruples of row vectors. Each row vector is a
triple of real values. The vectors are the right, up and at vectors, which
orient a Cartesian coordinate system, and the pos vector that positions this
coordinate system with respect to a parent coordinate system. In
conventional 4×4 matrix form, there is an implied last column of (0,0,0,1)T.
The equations for matrix multiplication can then be expanded as shown
below.
×
=
+++++++++
++++++
++++++
++++++
×=
1
0
0
0
1
0
0
0
1
0
0
0
B
z
B
y
B
x
B
z
B
y
B
x
B
z
B
y
B
x
B
z
B
y
B
x
A
z
A
y
A
x
A
z
A
y
A
x
A
z
A
y
A
x
A
z
A
y
A
x
B
z
B
z
A
z
B
z
A
y
B
z
A
x
B
y
B
y
A
z
B
y
A
y
B
y
A
x
B
x
B
x
A
z
B
x
A
y
B
x
A
x
B
z
A
z
B
z
A
y
B
z
A
x
B
y
A
z
B
y
A
y
B
y
A
x
B
x
A
z
B
x
A
y
B
x
A
x
B
z
A
z
B
z
A
y
B
z
A
x
B
y
A
z
B
y
A
y
B
y
A
x
B
x
A
z
B
x
A
y
B
x
A
x
B
z
A
z
B
z
A
y
B
z
A
x
B
y
A
z
B
y
A
y
B
y
A
x
B
x
A
z
B
x
A
y
B
x
A
x
PPP
AAA
UUU
RRR
PPP
AAA
UUU
RRR
PAPUPRPPAPUPRPPAPUPRP
AAUARAAAUARAAAUARA
AUUURUAUUURUAUUURU
ARURRRARURRRARURRR
BAC
Matrix multiplication is not commutative so, the order of the arguments
passed to RwMatrixMultiply() is significant. Transformation of a position
is performed mathematically in the following manner:
Matrices
RenderWare Graphics 3.7 I-51
()
×=
+++
+++
+++
×=
1
0
0
0
1
1zyx
zyx
zyx
zyx
zyx
T
zzzzyzx
yyzyyyx
xxzxyxx
PPP
AAA
UUU
RRR
uuu
PAuUuRu
PAuUuRu
PAuUuRu
Muv
This is the operation performed by RwV3dTransformPoints(). This
function is used to transform position vectors. There is also an
RwV3dTransformVectors() function, which transforms vectors (e.g.
normals). In this case, the matrix is assumed to contain a zero position
vector and so does not contribute to the output vectors.
Put another way: a direction vector is never translated, but only rotated.
Using RwV3dTransformPoints() with normals, or RwV3dTransformVectors() with
vertices will give strange results.
The order of matrix transformations has an effect on the visible orientation
of Atomics, as discussed (see 2.10.3 below).
Chapter 2 - Fundamental Types
I-52 11 February 2004
2.10 Frames
RwFrame objects contain two matrices. These are the Local Transformation
Matrix (or LTM), and the Modeling Matrix. These two matrices can be
retrieved using RwFrameGetLTM() and RwFrameGetMatrix(), respectively.
When transformations are performed on a frame (see next paragraph), it is
the Modeling Matrix that is affected. (The LTM describes the total
transformation from Object Space to World Space.) Unless the Frame
belongs to a hierarchy, the Modeling and Local Transformation Matrices are
identical. Otherwise, the Modeling Matrix is relative to the Frame's parent.
Frames can be transformed using RwFrameTranslate(),
RwFrameRotate(), RwFrameScale() and RwFrameTransform(). Rotation
and scaling is accrued in the top-left 3x3 sub-matrix, while translation is
accumulated in the bottom row.
Given a transformation matrix, individual points and vectors (both of type
RwV3d) can be transformed using RwV3dTransformPoints() and
RwV3dTransformVectors().
Hierarchical modeling is the process of building models that preserve the
hierarchical structure of objects and allow the position and orientation of
an object in the hierarchy to be specified relative to its parent.
Frames
RenderWare Graphics 3.7 I-53
2.10.1 Hierarchical Models & RenderWare Graphics
Hierarchical modeling explicitly models articulation, or joints, connecting
objects. In RenderWare Graphics, these joints are represented by frames
(RwFrame). These only define the hierarchy itself. The model data itself is
sectioned, with each section stored in an atomic (RpAtomic). An atomic
can be linked to a frame, with collections of atomics and frames thus
forming a hierarchical model.
Consider, for example, the modeling of a robot arm consisting of an upper-
arm, lower-arm and a hand represented by three atomics. We wish to
model the arm so that movement of the upper-arm is transferred to the
lower-arm and hand whilst movement of the lower-arm only affects the
hand. Assume each atomic has its own frame (see API function
RpAtomicSetFrame()). Then the required articulation can be achieved by
attaching the lower-arm's frame as a child of the upper-arm's frame and,
similarly, attaching the hand's frame as a child of the lower-arm's frame.
The API function RwFrameAddChild is used to accomplish this.
Atomic1 Atomic2 Atomic3
Upper Arm Lower Arm Hand
Frame1 Frame 2 Frame 3
The modeling matrix of each frame is now described relative to the Frame's
parent Frame object and the corresponding LTM becomes the
concatenation of all the modeling matrices up to the root Frame, in this
case the Frame on the upper-arm's atomic.
For each case we have:
LTM1=MM1
LTM2=MM2LTM1
LTM3=MM3LTM2
(where LTM = local transformation matrix and MM = modeling matrix.)
Only the root Frame's modeling and local transformation matrices are
identical.
The object hierarchy is shown schematically above. Frame1 is the parent of
Frame2 (therefore, Frame2 is the child of Frame1), while Frame2 is the
parent of Frame3. Note that the arrangement of the Atomics is determined
entirely by the frame hierarchy. If these Atomics were all added to a single
Clump object, the Clump would impose no organization. Because a Clump
is designed as a container for Atomics, it can be assumed that the Clump
must order its Atomics but, as you can see, this is not how it works.
Chapter 2 - Fundamental Types
I-54 11 February 2004
To model the robot hand in more detail by adding some fingers:
give the hand three fingers represented by three more Atomics.
build the hand hierarchy by attaching all the fingers' Frames as children
of the hand's Frame (see diagram above).
All the fingers' Frames (frame4, frame5, frame6) are child frames of the
hand's frame and siblings of each other. In terms of the LTMs we have, for
example:
LTM4=MM4 LTM3
This means the LTM of frame4 is the concatenation of the modeling
matrices of Frames Frame1, Frame2, Frame3 and Frame4 – this is the same
for the other fingers. Movement of the hand is now automatically
transferred to all the fingers.
It is recommended, though it is by no means required, that the hierarchy is
encapsulated within a Clump which has its own Frame – see
RpClumpSetFrame() – acting as the root of the Frame hierarchy. For
example, Frame1 would be attached to the Clump's frame (say, Frame0,) as
a child of that Frame. Also, each of the Atomics must be added the Clump
using RpClumpAddAtomic() for this organization to work correctly.
Frames and the Local Transformation Matrix
Frame objects contain a matrix called the Local Transformation Matrix,
(usually abbreviated to "LTM"). This matrix is used when working with
hierarchies of Frame objects.
Local Transformation Matrices are constructed by traversing the hierarchy
from top to bottom. At each level in the hierarchy, the modeling matrix is
pre-multiplied into the local transformation matrix from the level above to
form the LTM for the current level. Because the LTM is used to post
multiply vectors this means that the transformation stored in the lowest
frame in the hierarchy affects the vertex first of all:
011 MMMMVU nn = Λ
In this equation, the Local Transformation Matrix at the root of the
hierarchy is M0 and that at the bottom of the hierarchy is Mn, where there
are n+1 levels in the hierarchy.
2.10.2 Traversing Frame Hierarchies
There are two methods for traversing an object hierarchy depending on
whether it is Frames or the objects hanging from them. It is assumed that a
hierarchy of Frames and Atomics assembled into a Clump where the
Clump's Frame acts as the root of the hierarchy.
Frames
RenderWare Graphics 3.7 I-55
All Frames in the hierarchy may be iterated over using the
RwFrameForAllChildren() iterator. Starting at the root Frame, this
function will apply a user-defined callback to all first generation child
Frames. Repeating RwFrameForAllChildren() on each callback will then
iterate over all second generation, i.e. grandchild, frames, and so on. Also,
for each Frame encountered a call to RwFrameForAllObjects() applies a
callback to each object attached to the Frame.
RwFrameForAllChildren() will only take you down one level in a hierarchy. You must
use your callback function to call RwFrameForAllChildren()again to go down the
hierarchy another level, so your callback should be designed for recursion.
If the Frame hierarchy is not important, a call to the
RpClumpForAllAtomics() iterator will iterate over all the Atomics
registered with a Clump. The supplied user-defined callback function will
be applied to each Atomic in turn.
2.10.3 Matrix Combination Flags in RenderWare
Graphics
Matrix and frame transformation functions in RenderWare Graphics (for
example, RwFrameTransform()and RwMatrixRotate()) take a parameter,
combineOp. This parameter is used to control the order in which the
transform is applied to the matrix or Frame.
The available combine operators are: replace, pre-concatenate, and post-
concatenate.
rwCOMBINEREPLACE assigns the new transformation to the matrix.
The original contents of the matrix are entirely replaced by the new
transform.
RwMatrixTranslate(M, t, rwCOMBINEREPLACE) builds a new
matrix containing only a translation, and stores this matrix in M. Any
rotation component in the matrix M is overwritten with a 3x3 identity
sub-matrix. This is true for all matrix-transforming functions where
the rwCOMBINEREPLACE flag is used.
rwCOMBINEPRECONCAT causes the transform matrix to be pre-
concatenated onto the matrix. This has the effect of applying the
transformation before the transformation already in the matrix. Put
another way: this operator causes the transformation to be made in
object space (or the coordinate space of the matrix).
rwCOMBINEPOSTCONCAT instructs RenderWare Graphics to post-
multiply the transformation into the matrix. The new transformation
will take effect after the transform already in the matrix. In other
words, the transformation takes place in world space.
Chapter 2 - Fundamental Types
I-56 11 February 2004
Example
Consider a call made to RwFrameScale() with a Frame F, and a vector S
encoding the scale. The effect of changing the combination operator will be
looked at. Firstly, however, it should be pointed out that the function alters
the modeling matrix in the frame.
A RenderWare Graphics application should never modify the LTM matrix directly, since
the library is responsible for computing this matrix from the Modeling Matrix and the
LTMs of the Frame hierarchy.
In this example the modeling matrix, denoted M, is stored in Frame F.
Notionally, the RwFrameScale() function computes a scale transformation
matrix, S. This will be a 4x4 zero matrix with a diagonal encoding the
elements from the scale vector, and 1:
=
1000
000
000
000
z
y
x
s
s
s
S
The table below illustrates the result of varying the combine operator on the
matrix M.
OPERATOR RESULTING MATRIX (M)
rwCOMBINEREPLACE S
rwCOMBINEPRECONCAT SM
rwCOMBINEPOSTCONCAT MS
Bounding Boxes
RenderWare Graphics 3.7 I-57
2.11 Bounding Boxes
The Bounding Box (RwBBox) object defines a bounding box using two
points: sup (supremum) and inf (infimum). These two points define
diametrically opposite corners of the box, such that for any axis, the value
in the inf coordinate is never larger than the value in the sup coordinate.
The illustration below shows how this works in practice:
Sup
Inf
The resulting box therefore represents a 3D axis aligned cuboid volume.
Bounding boxes provide the basis for simple tests to determine whether
specific coordinates in the coordinate space are bounded by the volume.
The box may also be expanded to include another point within its volume,
using the RwBBoxAddPoint() function.
Another test available is RwBBoxContainsPoint(), which can be used to
check if a vertex is inside or outside a Bounding Box.
RwBBoxAddPoint() can also be used together with the
RwBBoxInitialize() function. This takes a single vertex and initializes
both the inf and sup elements to this point. RwBBoxAddPoint() can be
called repeatedly to expand the Bounding Box to contain any arbitrary
number of points. This technique is useful if the number of points involved
is unknown.
If, on the other hand, you do have a fixed-length array of vertices, you can
use the RwBBoxCalculate() function to perform a similar operation to the
above. This function is usually the more efficient of the two systems.
Chapter 2 - Fundamental Types
I-58 11 February 2004
2.12 Lines
RenderWare Graphics naturally supports a basic line type. This is called
RwLine and it is defined by two RwV3d objects denoting the start and end
vertices. The RwLine object is used typically as an intersection primitive. Do
not confuse the RwLine object with an immediate mode line, which is a
renderable object.
Rectangles
RenderWare Graphics 3.7 I-59
2.13 Rectangles
Rectangles are defined by the RwRect type. This type takes a positioning
vector to locate the rectangle, as well as two parameters defining its width
and height. As with lines above, the RwRect object is not renderable.
Rectangles are typically used to define sub-regions of the screen.
Chapter 2 - Fundamental Types
I-60 11 February 2004
2.14 Spheres
RenderWare Graphics defines the RwSphere type. This contains both a
center and a radius as elements to define the location and size of the
sphere.
Spheres are heavily used during Retained Mode rendering to determine
which models are within the Camera Frustum. Using spheres for the initial
tests makes for rapid culling. Once this coarse-level checking has been
performed, the remaining models can then be tested and clipped more
accurately.
Note that this object is not renderable, and is used primarily for
intersection testing.
Colors
RenderWare Graphics 3.7 I-61
2.15 Colors
RenderWare Graphics defines two color representation types: RwRGBA,
which is an integer-based primitive for describing colors, and RwRGBAReal,
which defines colors using real numbers rather than integers.
The RwRGBA form is the most used as it corresponds closely with most of
our supported platforms. This structure contains four RwUInt8 elements,
one for each of the Red, Green, Blue and Alpha components.
Although the RwRGBA format is fixed, the bitmap facilities offered by
RenderWare Graphics are not and may differ widely in color element
format. It is therefore possible that conversion may be needed when
extracting or modifying individual pixels in a bitmap and such processing
should thus be kept to a minimum.
See the chapter on Rasters, Images and Textures for information on these
items and their colors.
RwRGBAReal defines four RwReal elements for red, green, blue and alpha.
It is intended to be used in cases where high orders of accuracy are needed
while processing colors. Values range from 0.0f to 1.0f.
Chapter 3
Initialization &
Resource
Management
Chapter 3- Initialization & Resource Management
I-64 11 February 2004
3.1 Introduction
RenderWare Graphics Core Library contains the base feature-set of the API.
All other features are optional, provided in the form of either Plugins or
Toolkits.
The Core Library's functionality is divided up into the following broad
categories:
Memory management
OS-level file and memory management
Plugin management
Basic objects and intrinsic types, such as RwInt32, RwBBox, RwMatrix,
RwImage, etc.
2D and 3D immediate modes
PowerPipe extensible rendering pipeline
Platform-Specific APIs (where applicable)
Managing rendering time through the Lock and Unlock commands.
This chapter focuses on the memory management, plugin management and
file management features of the core library.
Basic Housekeeping
RenderWare Graphics 3.7 I-65
3.2 Basic Housekeeping
At the heart of RenderWare Graphics is the RwEngine object. This engine
performs a number of housekeeping functions, including:
Initialization and shut-down procedures
Selecting the display device and video mode
Querying the underlying hardware about its capabilities
Updating metrics information (when linked to the Metrics libraries)
Managing Plugins
All RenderWare Graphics applications have to initialize the engine before
calling any other RenderWare Graphics functions. We'll look at this process
next.
3.2.1 Initialization
Getting the RenderWare Graphics engine up and running is a three-step
process:
1. Initialization of memory management and default file system interface
2. Setting the video mode
3. Plugins and starting RenderWare Graphics
and there are three functions you need to call:
1. RwEngineInit()
2. RwEngineOpen()
3. RwEngineStart()
These functions must be called in the above order and you cannot start
rendering until after the RwEngineStart() call.
Why the three steps?
RenderWare Graphics has to make allowances for the many platforms it
supports. Splitting the start-up process into three stages lets us open up
such features as file and memory management, as well enabling the plugin
architecture to operate properly.
Let's look at these steps in terms of what they're for
Chapter 3- Initialization & Resource Management
I-66 11 February 2004
Step 1 - Initialization of Memory Management and Default
File System Interface
This first step concerns the API function RwEngineInit() and involves
setting up the memory and file-handling subsystems.
Why Does the Engine need to be Initialized First?
RwEngineInit() must always be the first RenderWare Graphics function
your application calls as all other functions assume the memory
management facilities have been set up. For example, the plugin
mechanism needs to access these memory functions, so they need to be set
up before any Plugins are attached.
Similarly, the display device your application will use may also need some
memory allocated for it. So again, we have to make sure the memory
subsystem is ready first.
The Memory Functions
By default, RenderWare Graphics uses the standard ANSI memory
functions, as implemented by the target platform's compiler, so any
replacement functions must have identical prototypes to their ANSI
counterparts.
In theory, the application can replace the default RenderWare Graphics
handlers with its own at any time. In practice the application should
change the memory handler only at this initialization stage, rather than
later.
Changing the memory and file handling subsystems within the main loop of
your application is possible, but not recommended as it can make
debugging much more difficult.
Pointers to the functions are stored in the RwMemoryFunctions structure
returned by RwOsGetMemoryInterface(). If necessary, the entries in this
structure can be overwritten directly with your own function pointers, but
this is not recommended as the change takes place immediately—if memory
has already been allocated with the original functions, then it is likely that
memory will be "lost" to your application.
Your application should create a new RwMemoryFunctions structure with
pointers to your own functions, then pass a pointer to the structure to
RwEngineInit().
The File Functions
The file system is implemented in a similar way to the memory system, with
a structure containing pointers to default POSIX functions used by default.
Again, any replacement functions will need to share the same prototypes as
the functions they will be replacing.
Basic Housekeeping
RenderWare Graphics 3.7 I-67
A file functions structure filled with the default functions can be retrieved
using RwOsGetFileInterface(). To replace these default function
pointers with your own, overwrite the entries in the structure. Your
functions will then be used when accessing files.
Step 2 - Setting the Video Mode
At this stage, you will need to:
Open the RenderWare Graphics Engine
Determine which graphics subsystem the application should be
using, as some platforms can support more than one
Determine the video display mode the application should use.
Video hardware varies greatly from platform to platform, so this procedure
requires some additional steps of its own.
Opening the RenderWare Graphics Engine
The RenderWare Graphics Engine can be opened using RwEngineOpen().
Choosing the Graphics Subsystem
The RenderWare Graphics API represents a graphics device as a graphics
subsystem.
The application must first determine how many graphics subsystems are
available. This requires a call to RwEngineGetNumSubSystems().
With this information, the application iterates through the available
subsystems, checking each one for suitability. This is achieved by calling
RwEngineGetSubSystemInfo() and interrogating the structure returned.
The following code fragment illustrates this process by printing out the
identifying names of all graphics subsystems on a particular platform:
RwInt32 numSubSystems, i;
RwSubSystemInfo ssInfo;
numSubSystems = RwEngineGetNumSubSystems();
for(i=0; i<numSubSystems; i++)
{
RwSubSystemInfo ssInfo;
if( RwEngineGetSubSystemInfo(&ssInfo, i) )
{
printf("SubSystem %d: %s\n", i, ssInfo.name );
}
}
Chapter 3- Initialization & Resource Management
I-68 11 February 2004
(The RwSubSystemInfo structure contains only the name element.)
Once the subsystem has been chosen, the application must inform
RenderWare Graphics of its choice by calling RwEngineSetSubSystem()
with the requisite index number.
Setting the Video Mode
With the graphics subsystem selected, the application must now set the
video mode. The first step is to determine how many video modes are
supported, and what these modes are.
To determine the number of video modes supported, the application should
call RwEngineGetNumVideoModes(), then iterate through the available
modes by calling RwEngineGetVideoModeInfo().
The code fragment below iterates through the available video modes and
prints the information for each one to stdio.
RwInt32 numVideoModes, j;
RwVideoMode vmodeInfo;
numVideoModes = RwEngineGetNumVideoModes();
for(j=0; j<numVideoModes; j++)
{
if( RwEngineGetVideoModeInfo(&vmodeInfo, j) )
{
printf("Video Mode %d: %dx%dx%d %s\n", j,
vmodeInfo.width, vmodeInfo.height, vmodeInfo.depth,
(vmodeInfo.flags & rwVIDEOMODEEXCLUSIVE)
? "(EXCLUSIVE)" : "" );
}
}
The RwVideoMode object contains the following elements:
width – the width, in pixels, of the video mode;
height – the height, in pixels, of the video mode;
depth – the number of bits per pixel supported by the video mode;
refRate – approximate vertical refresh rate;
format – pixel format of the display buffer. See also:
RwRasterFormat.
flags – contains one or more of the following flags:
Basic Housekeeping
RenderWare Graphics 3.7 I-69
rwVIDEOMODEEXCLUSIVE – if set, the video mode is full-screen
rather than windowed.
Windowed modes are only available on DirectX and OpenGL
platforms.
rwVIDEOMODEINTERLACE – if set, the video mode is interlaced,
with alternate fields being displayed each frame.
Interlaced video modes are more common on platforms that use
televisions for their video output.
rwVIDEOMODEFFINTERLACE – if set, the video mode is interlaced,
but the signal is processed to reduce or eliminate the flickering
normally associated with interlaced video modes.
Interlaced video modes are more common on platforms that use
televisions for their video output.
Owing to differences in hardware design, the flags shown above are not
supported on all platforms. Detailed below are the platform-specific video
mode flags. Please refer to the platform-specific documentation in the API
Reference for additional information on any flags.
- rwVIDEOMODE_XBOX_WIDESCREEN – (Xbox specific) if set, wide screen is
used. The application will also need to adjust the transform matrix to
provide a 16:9 display aspect ratio rather than the more common 4:3
display aspect ratio.
- rwVIDEOMODE_XBOX_PROGRESSIVE – (Xbox specific) if set, progressive
scan is used. Currently the supported progressive scan video modes are
480p and 720p HDTV modes.
- rwVIDEOMODE_XBOX_FIELD – (Xbox specific) field rendering is a special
video mode where the back buffer size is assumed to be half the vertical
height of the output display and the output format is defined to be
interlaced. In this mode, the even lines of the display are rendered
during one field and the odd lines are rendered during the next field.
When using field rendering, the flicker filter is disabled. Field rendering
can reduce the fill-rate and bandwidth requirements of a game
substantially; however, since there is no flicker filter, display quality can
also be degraded.
- rwVIDEOMODE_XBOX_10X11PIXELASPECT – (Xbox specific) if set, the
frame buffer is centered on the display. On a television where the
resolution is 704 pixels across, this would leave a 32 pixel black border
on the left and a 32 pixel black border on the right.
rwVIDEOMODE_PS2_FSAASHRINKBLIT – (PlayStation 2 specific) if
set, this video mode is full-screen anti-aliased by a scaled blit
from the draw buffer to the display buffer.
Chapter 3- Initialization & Resource Management
I-70 11 February 2004
RwVIDEOMODE_PS2_FSAAREADCIRCUIT – (PlayStation 2 specific)
if set, this video mode uses read circuit scan line blending for
flicker reduction.
The video mode is set with a call to RwEngineSetVideoMode(), which
requires the index number of the desired video mode.
Step 3 – Plugins and starting RenderWare Graphics
Plugins are one of the keys to RenderWare Graphics power. Before
RenderWare Graphics can be started, plugins need to be attached. Plugins
usually extend or add objects and provide new functionality. The Retained
Mode API, for example, is exposed by the RpWorld plugin.
RenderWare Graphics is written in C, not C++, so object extensions must
be handled explicitly. One of the most important procedures is attaching a
plugin. This process performs the following steps:
Linking a plugin with any existing RenderWare Graphics objects;
Adding any extensions to those objects;
Informing the RenderWare Graphics engine about any additional
memory the extended objects will need.
Attaching must take place prior to starting the RenderWare Graphics
engine with RwEngineStart().
3.2.2 Shutting down RenderWare Graphics
Each of the three start-up functions has a matching shutdown function,
which also needs to be called in the following order when the application
terminates:
1. RwEngineStop()
2. RwEngineClose()
3. RwEngineTerm()
Each of these functions needs to be called in turn to close down and exit a
RenderWare Graphics application.
Applications running on consoles, such as the PlayStation 2 or Xbox, do
not need to concern themselves with exiting cleanly as console users just
switch off the machine. But developers targeting multi-purpose platforms
like Windows and MacOS will need to use these functions.
A good reason for shutting down is to trigger debugging functions, which
notify the developer of any memory leaks. As these are often tied to the
memory handling functions set up by RwEngineInit(), it may be
necessary to perform a complete shutdown of RenderWare Graphics to
trigger the leakage tests.
Basic Housekeeping
RenderWare Graphics 3.7 I-71
3.2.3 Changing Video Modes after Initialization
Changing video modes after the initialization steps described so far is
tricky. To do so, you will need to partially shut down the RenderWare
Graphics Engine by calling both RwEngineStop() and RwEngineClose(),
then set your new video mode by calling RwEngineOpen() and
RwEngineStart() to restart the RenderWare Graphics Engine.
This procedure requires the deletion and re-initialization of many active
RenderWare Graphics bitmap objects, as hardware issues may require your
graphics data to be in a different format for some display modes.
Chapter 3- Initialization & Resource Management
I-72 11 February 2004
3.3 Memory Management
RenderWare Graphics supports two memory management features, as well
access to those of the underlying platform.
In this part of the chapter, we will take a look at these features, which are:
The OS-level memory interface
The Freelist memory management system
Memory Hints
The Resource Arena
3.3.1 The OS-level Memory Interface
As we've already seen, the RenderWare Graphics initialization function,
RwEngineInit(), lets you set up the memory management subsystem
used by the RenderWare Graphics API. This is a useful feature as you will
be in a far better position to understand your application's memory usage
patterns and can therefore replace the RenderWare Graphics memory
manager with your own, more optimized one if you require.
You can access these functions in your application through an
RwOsGetMemoryInterface() API call. This returns a pointer to an
RwMemoryFunctions structure. The structure contains the default
RenderWare Graphics memory function pointers which map to OS-specific
implementations of the ANSI C malloc(), free(), realloc() and
calloc() functions.
RenderWare Graphics provides macros to directly access these default
memory functions, which are named as follows:
RwMalloc()
RwFree()
RwRealloc()
RwCalloc()
In addition, debug versions of these functions will be substituted in the
macros if a debug build is specified.
Your application can override these default functions by passing a
structure populated with your own function pointers to RwEngineInit().
Your functions will obviously need to take the same parameters as the
RenderWare Graphics ones, please refer to the API Reference for specific
details. Note that once you override these function you will be responsible
for aligning the memory properly. Memory alignment differs between the
various platforms and it can also affect the application performance.
Memory Management
RenderWare Graphics 3.7 I-73
If you want to cut down on porting issues, it's worth using the default
RenderWare Graphics functions, rather than calling the OS ones directly.
This also means your code can seamlessly switch to another memory-
management system if you should decide to replace the default RenderWare
Graphics functions with your own.
3.3.2 FreeLists
In addition to the OS-level memory-management functions, RenderWare
Graphics provides an additional memory-management systems. It’s defined
by the RwFreeList object and is active by default.
A value of rwENGINEINITNOFREELISTS can be passed in the flag parameter
for RwEngineInit(). This will tell RenderWare Graphics to use the default
memory functions (RwMalloc and RwFree) in place of the FreeList functions
instead.
How FreeLists work
FreeLists are initialized with a block size – call it s – and a number – call it
n – which specifies the minimum number of such blocks to allocate at a
time. When you allocate your first object, the FreeList grabs enough
memory to hold n blocks. You're free to allocate and free any of these
blocks as often as you like.
If the FreeList is full and you try and allocate a new block, the FreeList
grabs another (s * n) bytes of memory.
As you develop your application, you should monitor your usage of
FreeLists to determine the best balance between speed and efficient
memory usage.
Why FreeLists are useful
FreeList objects manage blocks of memory of the same size. Applications
often spend most of their time creating and destroying groups of related
objects. Grouping similar objects together under one FreeList object gives
an economy of scale. Instead of allocating lots of small chunks of memory,
the object allocates in bulk, grabbing another big chunk only if the previous
chunk is completely filled. Because a FreeList knows all the objects it
contains are the same size, it can allocate space for an object in a block
much more quickly than the standard system heap allocators that must
handle objects of mixed sizes.
Chapter 3- Initialization & Resource Management
I-74 11 February 2004
FreeLists can also be useful for avoiding memory fragmentation, which can
be particularly problematic on consoles that don't use virtual addressing
systems. If you know how much space your game is likely to need for a
certain type of object, setting aside this space early on and allocating into it
at run time is often better than doing heap allocations at run time.
Depending on the state of the heap and how long allocations stay before
they are deallocated again, you can end up with memory with many small
holes and no contiguous space large enough for allocations you may need
later. Even though there may be enough memory in total, it is fragmented
and therefore unusable. It is possible to "lose" megabytes of memory to
this. RenderWare FreeLists provide a way of setting aside memory at
startup for future allocations to help avoid this problem.
As an example, take a game that needs to instantiate groups of missiles.
Each missile structure requires the same amount of space as that for any
of the other missiles, so it makes sense to avoid multiple RwMalloc() calls
and use a single FreeList object to handle the missiles in batches instead.
We might also know that the game will only ever have a maximum of 64
missiles in play at any one time so we can set aside enough space for all of
them when we create the FreeList and be sure no more allocations for
missiles will occur after then.
In code, our initialization for the missiles FreeList might look something
like this…
RwBool
InitializeMissiles(void)
{
/* First, set up an RwFreeList structure for our missiles... */
/* "TMissile" is our missile structure (wrapped into a typedef).
* We want to allocate them in batches of 64 at a time.
* We need them aligned to 4-byte boundaries,
* ask for one block of these to be set aside now,
* and provide space for the RwFreeList structure itself,
* rather than mallocing it too. */
RwFreeList *ok;
ok = RwFreeListCreateAndPreallocateSpace(
sizeof(TMissile), 64, 4, 1, &Globals.missilesList,
rwMEMHINTDUR_EVENT);
return (ok != NULL);
}
Now, to use our FreeList mechanism, we can do something like this:
...
/* Need a new missile... */
Memory Management
RenderWare Graphics 3.7 I-75
TMissile *myMissile;
myMissile = (TMissile *)RwFreeListAlloc(&Globals.missilesList,
rwMEMHINTDUR);
if (myMissile)
{
/* Do something here with the missile. */
}
And, when we're done with all our missiles, we can destroy our FreeList
storage:
void
DestroyMissilesList(void)
{
RwFreeListDestroy( &Globals.missilesList );
}
You can see that the FreeList allocation and destroy functions are similar to
RwMalloc() and RwFree(), with the important difference that they result
in far fewer calls to those low-level functions.
If you prefer that RwFreeLists don't allocate any memory until you start using them, you
can pass 0 as the number of blocks to allocate on creation. Had we done this for our
example above, the big block allocation would take place during the call to
RwFreeListAlloc(). However, it is probably better to allocate space on start up to avoid
heap fragmentation during run time, as mentioned above.
FreeList usage within RenderWare Graphics
FreeLists are used extensively by RenderWare Graphics for its internal
memory management, particularly for managing groups of textures,
cameras, clumps and other objects. These lists are not accessible directly
by the application. However because the optimal number of objects to
reserve space for is application specific, you can configure the sizes of the
FreeLists RenderWare Graphics uses to suit your application. This should
allow you to have no wasted space and no more allocations than absolutely
necessary. See the RwFreeList overview in the API reference for a list of
functions you may call to configure internal FreeList sizes, e.g.
RwTextureSetFreeListCreateParams.
3.3.3 Memory Hints
All RenderWare Graphics memory-management functions that allocate
memory take an additional RwUInt32 parameter which is a memory hint.
The following RenderWare Graphics functions have this additional memory
hint parameter: RwMalloc, RwRealloc, RwCalloc, RwFreeListCreate,
RwFreeListCreateAndPreallocateSpace, and RwFreeListAlloc.
Chapter 3- Initialization & Resource Management
I-76 11 February 2004
The main purpose of the hints is to help improve memory management,
such as preventing memory fragmentation. To use the memory hints, you
should have provided your own memory-management function through the
RwEngineInit() function. For example, you might want to have a
separate memory heap just for the RwMatrix or RpGeometry objects, or a
separate heap for all temporary allocations inside RenderWare Graphics. As
always, memory-management is very specific to each application and has to
be organized and tuned for each one.
A memory hint contains the following information:
1. Duration. If we are allocating temporary memory which will be
freed inside the function scope, the value for
RwMemoryHintDuration will be rwMEMHINTDUR_FUNCTION. If a
memory is allocated for a duration of a frame the value is
rwMEMHINTDUR_FRAME. For all global allocations, happening on
and before RwEngineStart and which are freed on and after
RwEngineStop, the value is rwMEMHINTDUR_GLOBAL. All
allocations which persist for longer than per frame, but are not
global, have rwMEMHINTDUR_EVENT. This can be per level or per
event.
2. ChunkID. This is the id of either the object for which a memory
request came, or of the module a call for allocation belongs to.
Refer to the memory hints API Reference documentation for a
list of all RenderWare Graphics IDs.
3. Flags. Currently we have only one flag for memory that will
potentially be resized with RwRealloc.
We have three macros for extracting information from a hint:
RwMemoryHintGetDuration(), RwMemoryHintGetChunkID() and
RwMemoryHintGetFlags().
You can extend all of these fields using specific values for duration, object
IDs, flags and create custom hints that can be passed to all the memory
allocation calls you make.
3.3.4 Resource Arenas
The Resource Arena is a cache and only one is supported in an application.
When rendering geometry, RenderWare Graphics will create a platform-
specific version of that geometry—a process known as instancing—in the
Resource Arena. RenderWare Graphics can then use the cached instance of
the geometry directly rather than re-generate the platform-specific data for
each rendering cycle. This is faster than re-instancing the geometry data
every cycle.
This system is most efficient if the model geometry changes infrequently—a
common situation in many 3D graphics applications.
Memory Management
RenderWare Graphics 3.7 I-77
There are some important points to understand:
If you make your Resource Arena too small, your application will suffer
from slowdown by a process known as arena thrashing. This occurs
when objects that are being instanced require that another, previously
instanced object, be kicked out to make room. This kicked out object
will have to be re-instanced in the next rendering frame. This will result
in another object being evicted from the cache, and so on.
Conversely, making the Resource Arena too big makes less than efficient
use of your platform's memory. On platforms like the PC, this is not
such a big issue, but when it comes to consoles, every byte counts.
The answer, as with FreeLists, is to spend some time optimizing the
parameters you use when setting up your Resource Arena.
The Resource Arena API
The RwResources object represents the Resource Arena. This object
represents a list of RwResEntry structures, each describing a block of
memory in the Resource Arena. The API itself is centered on the
RwResources object.
A Resource Arena is always present when using RenderWare Graphics. The
size of the arena is set during RwEngineInit(), which is passed in the
resArenaSize parameter. The arena size can be set to zero if it is not
needed.
Also present in this particular API is the equivalent get function –
RwResourcesGetArenaSize() – which returns the size of the Resource
Arena. This can be used together with RwResourcesGetArenaUsage() to
determine the optimum Arena size. This last should be called just before a
call to RwCameraShowRaster() to obtain meaningful results.
RwResourcesGetArenaUsage() returns the memory used by instancing
and can return a value greater than the maximum value you set. If it does
so, it means that arena thrashing is taking place – geometry is being
instanced, thrown away then re-instanced again because there isn't enough
space to store all the instanced data needed for the frame. You should
increase the maximum size of the Arena to prevent this or, if memory is
tight, reduce the complexity of your geometry to keep the size of the
instanced data down.
RwResourcesSetArenaSize() now determines the size the Resource Arena, which is a
single block of allocated memory. This will free the current resource arena heap, if one
exists, and allocate a new heap.
3.3.5 Locking and Unlocking data
The process of instancing display data into platform-dependent form
generally takes a lot of processing time. The Lock and Unlock functions
that are part of most plugins allow the developer to control this process.
Chapter 3- Initialization & Resource Management
I-78 11 February 2004
The Lock function tells RenderWare Graphics that the developer wants to
access and change some data, like a geometry, texture or palette, and have
it re-instanced so that it can be rendered efficiently. The Unlock function
allows re-instancing, which is generally slow (though for some data, like
vertex positions and colors, re-instancing is postponed until just before
rendering).
Many Lock functions have flags to indicate precisely which data is being
altered and thus avoid recalculating unchanged data.
So the Lock functions should be used judiciously and be avoided when
possible.
Summary
RenderWare Graphics 3.7 I-79
3.4 Summary
3.4.1 Starting The Engine
The initialization phase of your application needs to perform the following
steps to start the RenderWare Graphics engine:
1. Call RwEngineInit(), passing an RwMemoryFunctions structure if
required.
The rwENGINEINITNOFREELISTS flag should also be specified if the
FreeList mechanism is not required, pass the resArenaSize parameter
for the Resource Arena size;
2. Enumerate the available graphics subsystems and use
RwEngineSetSubSystem() to select the subsystem required by the
application;
3. Enumerate the available video modes and use
RwEngineSetVideoMode() to select the video mode required by the
application;
4. Call RwEngineOpen();
5. Attach any required plugins;
6. Call RwEngineStart().
The RenderWare Graphics engine is now started and rendering can take
place.
3.4.2 Shutting Down The Engine
When running on platforms that run multi-tasking operating systems such
as Windows or MacOS, applications should exit gracefully. This is achieved
by calling the following functions in the order shown:
1. RwEngineStop()
2. RwEngineClose()
(At this point, it is possible to change the graphics subsystem and video
mode and restart the engine.)
3. RwEngineTerm()
Chapter 3- Initialization & Resource Management
I-80 11 February 2004
3.4.3 Memory Handling
Default Memory Handlers
RenderWare Graphics provides two default, general-purpose memory-
management mechanisms, only one of which is available at any one time:
FreeList memory management (default);
ANSI-standard memory management functionsRwEngineInit() must
be called with the rwENGINEINITNOFREELISTS flag set;
You can replace the memory-management functions by creating an
RwMemoryFunctions structure with pointers to your own functions, then
passing this structure to RwEngineInit().
The Resource Arena
When rendering takes place, platform-specific instances of the geometry
data are created in the Resource Arena, which acts as a cache. If the same
geometry data is required later, the cached data in the Resource Arena will
be used directly.
3.4.4 Plugins
Plugins extend existing RenderWare Graphics objects and/or create new
ones. In order for this mechanism to work, the memory management
system needs to be in place.
The plugin must also be attached, by calling its associated
...PluginAttach() function prior to the call to RwEngineStart().
Chapter 4
Plugin Creation
& Usage
Chapter 4- Plugin Creation & Usage
I-82 11 February 2004
4.1 Introduction
Plugins are an important feature of RenderWare Graphics. By providing a
mechanism to extend and enhance the in-built objects of RenderWare
Graphics, they give us the flexibility to consistently meet your needs in a
fast-moving industry. The entire Retained Mode functionality for
RenderWare Graphics is, in fact, provided as a plugin.
4.1.1 Toolkits
Toolkits don't extend any core objects or datatypes at all, and usually
provide a set of utility functions.
In fact, a Toolkit is just a library that requires RenderWare Graphics to
work. The RenderWare Graphics team uses the "Toolkit" term to
differentiate a simple utility library from the more complex Plugins, which
must be handled more carefully.
4.1.2 Plugins and Streaming
Streaming is covered in the Serialization chapter.
Using Plugins
RenderWare Graphics 3.7 I-83
4.2 Using Plugins
This part of the chapter focuses on how to use plugins and how they work.
4.2.1 Attaching Plugins
Plugins have to be registered with RenderWare Graphics Core Library. The
reason for this is so that any object extensions have the chance to hook
into the memory handler and allocate space for their additional data
structures. For example, if you wanted a plugin to extend camera objects
by 64 bytes, then RenderWare Graphics needs to be told this before any
cameras are created.
Most RenderWare Graphics applications follow a start-up process along the
following lines (some error checking has been removed for clarity):
...
/* Platform-specific initialization */
... some code ...
/* Initialize RenderWare Graphics Engine: */
/* use default memory handler with Freelists
* and set arena size */
RwEngineInit(NULL, 0, resArenaSize);
/* Attach Plugins */
if (!RpWorldPluginAttach())
{
/* Something went wrong so, */
/* either display an error message, */
/* or just crash.*/
return FALSE;
}
Other plugins should be attached at the same point in the start-up
sequence. After this, accessing a plugin's API is the same as calling any
other function.
After all necessary plugins are attached, the RenderWare Graphics engine
can be opened and started:
...code to choose display device, format and other parameters ...
Chapter 4- Plugin Creation & Usage
I-84 11 February 2004
RwEngineOpen(&openParams);
/* Start Engine */
RwEngineStart(); /* "We have ignition!" */
With the plugins attached, calling their functions is now possible:
...
/* Render World */
RpWorldRender(); /* Render the RpWorld object. */
...
As with toolkits, plugins also have to have associated libraries and header files that must
be included in your build. Merely attaching them is not enough.
Dependencies
Plugins must be attached in the right order. If plugin B relies on plugin A
being present then plugin A should be attached before plugin B.
For example, the World plugin (RpWorld) is required by a number of other
plugins. RpWorld must therefore be attached first.
Creating Your Own Plugins
RenderWare Graphics 3.7 I-85
4.3 Creating Your Own Plugins
4.3.1 Introduction
Your application is not limited to using the plugins supplied with the
RenderWare Graphics SDK. Plugins can be written by any licensed
developer.
In this part of the chapter, we will see how this is done.
4.3.2 Anatomy of a Plugin
A RenderWare Graphics plugin is divided in two parts.
The first part is the exposed API that users of the plugin will have access to.
This API is the one other developers will use: it's the reason for writing the
plugin.
The second part is not usually seen by the plugin's user and performs the
housekeeping tasks: it performs any initialization and shut-down processes
required by the plugin; it tells the core engine how much memory it needs
for the new data structures, and also attaches itself to other plugin objects
if needed.
For instance, when calling RpWorldPluginAttach() to attach the World
plugin, it is the housekeeping functions that are called to create the
extended objects and initialize any data structures.
4.3.3 The "Plugin" Example
Path: examples/plugin
This example defines both a plugin and a simple demo to exercise it.
The main.c file contains the demo program which exercises the plugin.
The plugin code is in physics.c and physics.h.
The physics.h exports the plugin's "public" API. As you can see from the
plugin's API, the plugin extends the World plugin's RpClump object by
adding some basic physical properties.
The base object name for this extension is "ClumpPhysics", so the public
API uses an "RpClumpPhysics…()" prefix.
Defining the Plugin
Near the start of the physics.c file, we see the first requirement for a
plugin, the Plugin ID:
Chapter 4- Plugin Creation & Usage
I-86 11 February 2004
#define rwID_EXAMPLE 0xff
This example uses an ID of 255, but most developers will produce more
than one plugin and so will use ID numbers starting from 0 upwards.
The ID shown above is only part of the full Plugin ID. The complete ID is
created using the MAKECHUNKID macro, which combines your Vendor ID
with the Plugin ID number.
You can see this used in the RpClumpPhysicsPluginAttach() function.
This function is the one called by the application just after
RwEngineOpen(). It performs the operations required to extend the core
library and any other extensible objects.
Plugin & Vendor Ids
The maximum number of plugins possible is 256 per Vendor ID. If you need more than
this, you should contact Criterion Software Ltd. for another Vendor ID.
(Contact devrels@csl.com for your Vendor ID.)
Extensible Objects
These are objects which have a function in their API ending with
"PluginAttach()". Without this functionality, it is impossible to directly
extend such an object.
Because of this, a number of the core library objects, such as RwBBox, are
not directly extensible using the plugin mechanism. Instead, you will need
to define a new, extensible container object with one of the inextensible
objects as a member—a wrapper object—which you can then extend.
New structures
The next step is to define the new structures with which we will extend the
core engine and any other extensible objects.
In this example, we are adding some new global variables (at the core
library, or "global", level), and extending the World plugin's RpClump object
(the "local" level) to support some basic physics variables. Hence, we now
define two structures: PhysicsGlobals and PhysicsLocals.
The global-level structure defines storage for a caption, gravity and a
minimum speed. The caption is there because it is easy to spot when
debugging.
Global structures are added to the core RenderWare Graphics engine itself.
The Local structures in this plugin are attached to each RpClump object
created by the application.
Creating Your Own Plugins
RenderWare Graphics 3.7 I-87
If we were extending other objects, such as Atomics, we'd also need to
define Local structures for them along with associated copiers, constructors
and destructors.
Data Access Macros
One of the original design goals for C++ was that all of its functionality
could be implemented using standard C. The upshot of this is that you can
do object-oriented programming in C. It's just nowhere near as elegant,
natural or pretty.
An important issue is the need for some macros to make accessing the new
"members" of extended objects as painless as possible. In the case of the
Physics example, these macros are defined at the top of the physics.c
code: PHYSICSGLOBAL and PHYSICSLOCAL.
These macros provide access to the base address of the new data structures
within the RpClump object. By using these macros, it is possible to access
the relevant structures directly without having to add the overhead of a
function call. It also makes the code a lot more readable.
Registering the Plugin
While object creation and destruction is relatively trivial stuff for a C++
expert, this kind of thing requires a bit more work when using good, old-
fashioned C. In particular, we have to explicitly define constructors, copiers
and destructors because there are no defaults for these purposes.
Going back to the physics.c code, you'll find functions with words like
"constructor", "destructor" and "copier" in their names. These
functions are defined in the first half of the file and represent the
housekeeping part of the plugin's API.
Just for completeness, we also define functions for serializing the data to
and from RenderWare Graphics binary streams.
As you can see from the source code, we need to produce constructor and
destructor functionality for both the global and local data structures, but
only the local data structures need copiers as well.
Stream reading and writing functionality should only be provided if the
base object also supports streaming. This can be determined by looking for
a function name ending in "…RegisterPluginStream()". If it doesn't, you
should create a new wrapper object containing the base object and provide
full streaming support through this.
The stream support functionality needed is: Read(), Write() and
GetSize() – the last allows the RenderWare Graphics binary stream
functions to work out how much data will be read or written to the stream.
Chapter 4- Plugin Creation & Usage
I-88 11 February 2004
How do we tell RenderWare Graphics about these functions? This is why we
need the plugin attachment process to attach a plugin and register it with
the core library. Once registered in this way, RenderWare Graphics will
automatically call the new functions as callbacks.
Take a look at the RpClumpPhysicsPluginAttach() function. A cursory
glance shows that it is split into three very similar sections:
Registering the Global-Level Extensions
Here, we use the Core Library's RwEngineRegisterPlugin() function to
add the new global variables to the engine and register the constructor and
destructor functions for them.
The return value is the offset into the RenderWare Graphics engine's global
data structure where the new variables will be stored.
This value is very important: it's needed by the data access macros (see
Data Access Macros on page 87.)
Registering the Clump Object Extensions
This section uses the RpClumpRegisterPlugin() function – part of the
World plugin's API. The main difference between this section and the
global-level extensions section is the additional need to register a copier
function which will be called when clumps are copied or cloned.
Registering the Clump's Binary Stream Extensions
Again, very similar except that functions that hook into the stream handler
are registered instead of constructors, destructors or copiers.
Finishing Touches
The rest of the physics.c file consists of the remaining publicly-exposed
API functions. These implement a Newtonian physics model using our new
structures to store the state of each extended clump object.
In keeping with the object-oriented design philosophy behind RenderWare
Graphics, these functions provide access to the new data members.
At this stage, we know how to create a simple plugin; now let's take a look
at the other side of the coin and see the new plugin in action…
4.3.4 Using the Physics Plugin
The example plugin is used by the code found in main.c.
As with all of the other RenderWare Graphics Examples, the "plugin" example is built on
top of a simple platform abstraction layer called "The Skeleton". This is spread through a
number of files and is used to provide a platform-neutral framework for all our sample
code.
Creating Your Own Plugins
RenderWare Graphics 3.7 I-89
For clarity, this chapter only discusses the relevant functions specific to the "plugin"
example.
The full source code to the Skeleton is available for you to peruse and examine. It can be
found in: shared/skel/
The ClumpPhysics Demo
The new plugin – called RpClumpPhysics – is used in a simple demo which
drops some wooden buckyballs onto a simple surface. Each buckyball is
stored in a clump which has been extended using the new plugin. The
physics attributes are used to give each buckyball a random bounciness
and initial speed.
At this point, you should build and run the demo and play with it for a bit.
Stepping through functions with the debugger is also advised so you can
get an idea of the program execution flow.
Most of the code is basic stuff: create a floor, create the buckyballs,
initialize it all and then enter the main event loop.
"Buckyballs
A "buckyball" is a nickname given to any structure or object that looks like a C60 molecule.
The molecule's fully qualified name is Buckminsterfullerene and was named after Richard
Buckminster Fuller (1895-1983), an inventor, architect, engineer, mathematician, poet
and cosmologist. His most famous invention was the geodesic dome, a structure similar to
that of C60.
Preparation
We have already learned that the first thing you need to do when using
plugins is to make sure they're attached. The Skeleton used as a framework
for this example application can make it difficult to see where this process
takes place.
You'll find the plugin being attached within the aptly-named
AttachPlugins() function. This function gets called by the Skeleton's
event handler at the appropriate point during the startup phase and, as
you can see, our plugin isn't the only one being attached.
Dependencies
You'll note that the World plugin, which provides RenderWare Graphics
Retained Mode features, gets attached before our RpClumpPhysics plugin.
This is because our new plugin has to extend the features of the RpClump
object—an object that is only available when the World plugin is attached.
It is important to bear this dependency issue in mind when developing your
own plugins.
Chapter 4- Plugin Creation & Usage
I-90 11 February 2004
Exercising the Plugin
The demo consists of a bunch of buckyballs, dropped from a height onto a
surface and allowed to bounce.
The code which sets up the World itself sets up the lighting, the camera
and the floor. You can see this being done in the CreateScene() function.
See the two chapters, Worlds & Static Models and Dynamic Models, for more
information on scene creation.
The interesting bit begins when the buckyballs are initialized:
The ClumpPhysics plugin is used to add storage space to each of the
buckyballs for some basic physical attributes relating to speed and
"bounciness" – elasticity in technical terms.
This initialization process takes place in the InitClumps() function found
in the main.c file. Look at the section following the "/* Initialize user
plugin data... */" comment and you'll see the new ClumpPhysics
plugin in use.
In this case, we're using the exposed property get/set functions we saw in
physics.c, setting most of the attributes using a random number
generator. (The Active flag we added to the clump object is used to keep a
note on which of the buckyballs is still bouncing.)
Once the initialization phase is completed, the demo starts the main update
cycle. The physics calculations are handled in UpdateClumpDynamics().
Here, the basic Newtonian Laws of Motion are applied to make the
buckyballs behave in a manner approximating reality.
Plugin Design
RenderWare Graphics 3.7 I-91
4.4 Plugin Design
4.4.1 Introduction
The Physics example we have looked at is pretty simple. Most real-world
plugins won't be so trivial as to contain the plugin code within the test-bed
itself: full plugins are usually created as standalone libraries that are linked
into your application like any other library.
In this section, we will look at some design issues that you'll likely come
across when designing your own extensions.
4.4.2 Extension vs. Derivation
The RpClumpPhysics plugin extends an existing object. This is great for
small-scale additions, but this design does have a serious drawback: all
RpClump objects will have these extra data structures attached.
This means that the buckyballs are not the only ones affected: the floor
itself is also a clump and, therefore, it too has the storage space allocated
for our RpClumpPhysics extensions. While this kind of overhead is
acceptable for such basic examples as ClumpPhysics, clearly this is going to
be a problem if memory is tight—as is the case on a number of our
supported platforms.
The trick, then, is to find some way of optimizing the design such that only
objects that actually need the additional data will have it available. By far
the most efficient way of doing this with RenderWare Graphics is to create a
plugin that creates a new object instead of just extending an existing one.
This is the equivalent of C++'s derivation mechanism and most of the
plugins supplied with RenderWare Graphics derive new objects rather than
extending existing ones.
One notable exception is RpWorld's extensions to the RwCamera object. It
adds new functions that retain the "RwCamera" prefix, rather than using
"RpCamera".
4.4.3 Deriving new objects
The process of creating derived objects is not very different from what
you've seen already.
The first step is to decide how to link the new object to its parent object so
that the two can be used to share data efficiently. Thanks to the design of
the C programming language, three options are available to the developer:
1. The object can be extended
2. A container object can be created
Chapter 4- Plugin Creation & Usage
I-92 11 February 2004
3. An extended container object can be created—a combination of options
1 and 2.
Object Extensions
This technique is the one used by the ClumpPhysics example, covered
earlier in this chapter.
The base object is extended by adding a pointer to it which connects that
object to the extended data. Multiple pointers can be used if there are
multiple derivations. In addition, you could add a second pointer so that a
child object can access its parent. This gives you increased flexibility for
such things as iterator functions, without sacrificing too much valuable
memory.
The drawback is the overhead of forcing all instances of the parent object to
have a pointer that may not always be used.
Container Objects
This technique involves creating a master object through which accesses to
the base and derived objects are made. It would usually be a simple
construct such as a pair of linked lists. The RpAtomic object found in the
World plugin is an example of this technique.
Container objects have advantages where you need to derive a large
number of interrelated objects from a single base object with a one-to-many
relationship: the use of a separate linking object removes the need to store
a large number of pointers in the base object.
The disadvantage with this technique is that all access to the interesting
objects must be made via this link object to maintain integrity. The linking
mechanism must therefore be designed carefully to keep access time
overheads as low as possible.
Extended Container Objects
This option sometimes makes sense when the base object has a wildly
variable number of derived objects. The disadvantage is that access to the
derived objects through the list will be relatively slow. In addition, the links
can be tricky to maintain when there are a large number of interdependent
objects.
4.4.4 Plugins & C++
RenderWare Graphics plugin mechanism can make life a lot easier if you're
using C++ as your primary development language.
Plugin Design
RenderWare Graphics 3.7 I-93
As an example, let's assume you're writing a wrapper class for RenderWare
Graphics clump (RpClump) object. Ignoring constructor/destructor methods
and other side-issues, your class might look something like this:
class CClump
{
...
// private data
...
private:
RpClump *myClump;
RwInt32 someData;
...
}
A problem arises when you need to pass the clump data to one of the
RenderWare Graphics iterator functions, such as
RpWorldForAllClumps(). These functions trigger a callback which expects
an RpClump parameter, not your CClump class. So how does the callback
used by the iterator function get a reference to the wrapper class?
The answer is to extend the clump object, using the plugin mechanism, and
add a pointer which your wrapper class then initializes with a pointer to
itself. Now your callback function can get at the rest of the class' data,
(usually by calling a plugin-supplied access function).
Chapter 5
The Camera
Chapter 5 - The Camera
I-96 11 February 2004
5.1 Introduction
Wander into any movie studio's sound stages and you'll see a common set-
up: static sets, props and actors, all lit by a lighting rig and performing in
front of one or more cameras.
RenderWare Graphics defines equivalents for most of these elements:
static sets (static models) are covered in the chapter Worlds & Static
Models;
dynamic elements, such as props and actors, are covered by the chapter
on Dynamic Models;
lighting is covered in the chapter on Lights;
…and the Camera is covered here.
5.1.1 The Camera Example
Computer software has the useful ability to be interactive and can therefore
be used to great effect as an educational tool in its own right. With this in
mind, our RenderWare Graphics Demos Team has created a number of
educational examples that demonstrate particular features of the SDK and
let you play with them to see how they work and interact. The 'camera'
example is one such, and provides an interactive illustration of the Camera
object's features.
This Example will be referred to frequently to highlight the many properties
of the Camera object. In the second part of this chapter, the source code
will be discussed, to understand, how it all fits together.
The Camera Example is in the examples/camera/ folder. (Open up the text
file to view the user interface instructions as these vary from platform to
platform.)
The RenderWare Graphics Camera object
RenderWare Graphics 3.7 I-97
5.2 The RenderWare Graphics Camera
object
The RenderWare Graphics Camera (RwCamera) object is part of the Core
Library. It is the target of all 3D rendering operations and therefore plays
an important part in any 3D graphics application built on RenderWare
Graphics.
5.2.1 Camera Properties
The screenshot below is taken from the 'camera' Example and it has been
annotated to show the primary features of the Camera object:
Other Camera properties, such as projection modes, frame buffers, and fog
handling, will be covered later.
View
Frustum
Far Clip Plane
Near Clip Plane
View Window Actual view
from observed
Camera
Chapter 5 - The Camera
I-98 11 February 2004
5.2.2 The View Frustum
The highlighted volume in the diagram on the previous page represents the
volume in front of the Camera within which a renderable object is
considered visible. This is the View Frustum, defined by the near clip
plane, the far clip plane and the four planes passing through the
Viewpoint and the edges of the View Window. RenderWare Graphics uses
the bounding sphere of the object to determine whether it intersects or lies
within the view frustum. This course-grain visibility test is then used to
determine whether or not to draw the object, and whether the object is
clipped or unclipped. Clipping is a fine-grain visibility test.
If a model does not have a valid bounding sphere, the RenderWare Graphics engine may
produce unexpected results.
The Clipping Planes
Two clip planes define the near and far extents of the view frustum.
The far clip plane defines the point along the Camera Space Z axis, beyond
which objects will not be rendered.
The far clip plane is responsible for the infamous 'pop-up' found in older 3D
games, whereby model geometry suddenly appears on the horizon as if from
nowhere. If a platform has enough 3D graphics processing power, this
plane can be pushed back so far that the 'pop-up' simply isn't visible.
The near clip plane defines the point along the Camera Space Z axis,
nearer than which, objects will not be rendered. It is parallel to the far clip
plane and on the opposite side of the view frustum. Again, this is just a
point along the Z-axis running through the center of the camera object and
into Camera Space.
The near clip plane controls clipping of polygons close to the camera object.
Without it, even models behind the camera might be considered visible by
the engine and be rendered to the camera's frame buffer.
Pushing the Near Clip Plane away from the Camera improves Z Buffer resolution. When
feasible, the Near Clip Plane should be positioned as far away from the Camera as possible
without introducing visible clipping artifacts. The distance at which this will occur
depends on the zoom factor currently applied to the Camera. As a rule of thumb, dividing
the distance of the far clip plane from the camera by the distance of the near clip plane
from the camera should ideally result in a value of less than 1000.
The Viewpoint
When the Camera is set to the more usual Perspective view the View
Frustum defines a section through a pyramid. The apex of this pyramid is
the Viewpoint.
The Viewpoint is the center of projection when using a camera set to
Perspective mode. It is, literally, the 'point of view' – the eye – in the scene.
The RenderWare Graphics Camera object
RenderWare Graphics 3.7 I-99
Projection Modes
RenderWare Graphics provides two Projection Modes: Perspective and
Parallel. Perspective projection is the most generally used and is the
projection system assumed throughout most of this chapter. That said,
Parallel projection mode, while not so frequently used in apps, does lend
itself to a number of more specialist rendering tasks.
Perspective projection makes objects that are more distant (from the
camera) appear smaller on the screen as they do in real life. The angular
field of view may be controlled by calling the RwCameraSetViewWindow()
function, as described in the API Reference Manual.
Parallel projection mode, which can be selected using the
RwCameraSetProjection() function, changes the View Frustum to a View
Cuboid.
PERSPECTIVE PROJECTION PARALLEL PROJECTION
As you can see from the screenshots above, the main difference between
Perspective and Parallel projection modes is that the latter does not scale
vertices in the Z axis – no matter how far away a model is, it won't get any
smaller.
This mode is most often used for orthographic views or for projecting
shadows from area light sources, but it can also be used to duplicate some
popular 2D graphics rendering techniques, such as parallax scrolling. This
has the advantage of using the 3D acceleration hardware features available
on your target platform.
5.2.3 The View Window
Earlier, the Viewpoint was described as being a virtual 'eye' looking into a
scene. If we continue with this analogy, the View Window becomes a
virtual 'retina'. Where the analogy falls down is that the View Window is in
front of the Viewpoint.
Let's go back to the 'camera' Example.
Chapter 5 - The Camera
I-100 11 February 2004
With the 'camera' Example running, you can move the model around and
see its image rendered into the view window. This is shown inside a red
outline close to the near clip plane.
This View Window represents the frame buffer – our virtual retina – upon
which the actual scene is rendered. The picture below shows this
happening.
A useful feature of the 'camera' Example is that it displays the view from
the observed Camera inset at the top-right corner of the screen. (Because of
our view of the Camera object, the image shown in the View Window
appears to be reversed because it is facing away from us.)
It is the contents of the frame buffer the View Window represents which the
end-user gets to see.
View Windows & Aspect Ratio
Aspect ratio is defined by a combination of the View Window's dimensions
and those of the frame buffer Raster.
T
he View
Window.
(Seen from
the rear).
Rendered image
from frame buffer.
(What the
observed Camera
'sees'.)
The RenderWare Graphics Camera object
RenderWare Graphics 3.7 I-101
While you can set the View Window to any arbitrary dimensions, the
resulting image must still fit into the supplied frame buffer. Therefore,
RenderWare Graphics scales the output so that it always fits into the frame
buffer Raster.
This opens up a useful feature of the Camera: by manipulating the
dimensions of the View Window and frame buffer Raster, we can:
Zoom into a scene by decreasing the dimensions of the View Window;
Zoom out of a scene by increasing the dimensions of the View Window;
Duplicate an anamorphic lens by adjusting the dimensions of both the
View Window and the frame buffer and Z buffer Rasters.
This last feature can be used to implement a typical requirement for a
console game: support for anamorphic wide screen displays: Setting the
View Window to a 16:9 aspect ratio, but keeping the frame buffer's
dimensions to the traditional 4:3 TV standard achieves this. The rendered
scenes will be squashed to fit into the frame buffer's smaller width. The
resulting frame buffer can then be displayed on a wide screen TV using its
anamorphic (i.e. 'stretched') setting. The result is that the squeezed frame
buffer image becomes stretched across the entire width of the wide screen
TV's display, restoring it to its intended aspect ratio.
The advantages of this technique are two-fold:
1. It saves memory. By removing the need for a wide screen frame buffer,
we save on precious video RAM.
2. The lower memory overhead typically results in faster performance as
system bus bandwidth requirements are reduced.
This technique can also be used to produce distortion effects.
The View Window is defined as being always one unit away from the Viewpoint mentioned
briefly above.
The Camera View Window API
The View Window is set using an RwV2d vector set to half the required
dimensions in each axis. The function call is RwCameraSetViewWindow().
The property retrieval function is RwCameraGetViewWindow(). Again, the
returned RwV2d vector is set to half the actual dimensions.
The Raster object, used to provide the frame buffer and the Z buffer for
Cameras, is covered in the Rasters, Images & Textures chapter.
Chapter 5 - The Camera
I-102 11 February 2004
5.2.4 The View Offset
The View Offset is used to shear the Camera's view frustum. This is done by
specifying an X and Y (Camera Space) offset for the frustum's apex – the
point defining the center of the far end of the frustum.
The screenshot below, left, shows an un-offset View Frustum. The
screenshot to the right shows the View Frustum with a View Offset of 0.46
in the Y axis:
NO OFFSET OFFSET IN Y AXIS
Notice how the Viewpoint – the apex of the View Frustum – is offset
vertically relative to its original position. The result is the shearing of the
View Frustum so that the View Window renders the lower portion of the
model instead of the middle portion.
This feature can be explored in the 'camera' example (see the associated
readme.txt file for the user interface functions needed to manipulate the
View Offset).
The offsets are absolute values, so repeated calls to
RwCameraSetViewOffset() will not be accumulated.
This function has advantages for such activities as supporting stereoscopic
display devices and tiled rendering to a high resolution output device.
Camera View Offset API
Two functions are supplied for this feature: RwCameraSetViewOffset()
and RwCameraGetViewOffset(). Both take an RwV2d vector to set or store
the offset.
5.2.5 Fog
Fog effects in RenderWare Graphics are tightly coupled to the Camera
model.
The RenderWare Graphics Camera object
RenderWare Graphics 3.7 I-103
A number of different fog models are supported by RenderWare Graphics:
Linear, Exponential, Exponential2 and Table. However, some of these fog
types are only supported on a sub-set of platforms.
Basic Fog Controls
Fogging starts at the distance set by RwCameraSetFogDistance() for
Linear and Table fog types. Also, for the same fog types, the full fog effect is
achieved at the far clip plane.
Fog Distance should never be set to zero.
Most of the fog handling is done through the RwRenderState API, so let's
take a quick look at what's available…
Fog Render State
Fog is controlled through both the RwCamera and RwRenderState APIs. The
Render State API provides the following fog control functionality:
rwRENDERSTATEFOGENABLE
Turns on fogging. All polygons rendered from this point onwards will be
modified by fog processing. Clear this flag to disable fogging.
rwRENDERSTATEFOGCOLOR
The target color for fogging. The denser the fog around a particular
polygon, the closer the polygon's color will be to this target color.
rwRENDERSTATEFOGTYPE
The type of fogging to use. The fog types defined are:
rwFOGTYPELINEAR
Selects the Linear fogging type.
rwFOGTYPEEXPONENTIAL
Selects the first Exponential fog type. This is available on most of
our supported platforms. If the fog effect is represented by f then the
function is:
f = 1 / e(d * density)
(where d is the distance from the Camera's View Point.)
rwFOGTYPEEXPONENTIAL2
Selects the second Exponential fog type. This is using a higher
exponent in the formula to make the fog get denser faster. The
formula is as above except that the exponent – (d * density) – is
further raised to the power of two.
rwRENDERSTATEFOGDENSITY
Select the density of Exponential and Exponential2 fogging. The higher
the value, the denser the fog.
Chapter 5 - The Camera
I-104 11 February 2004
rwRENDERSTATEFOGTABLE
This is the Table form of fogging. The parameter is a 256-entry fog table
placed between fog distance and far clip plane. The table format is not
fixed, so check your platform-specific documentation to see what format
to use if this fog type is supported.
Note that Render States can return FALSE for a number of reasons. Check
the platform-specific information in the API Reference to ensure that a
particular fog type is supported for a particular platform.
The Render State API, consisting of the two RwRenderStateSet() and
RwRenderStateGet() functions should be used to set the fogging as
appropriate.
The Render State represents the RenderWare Graphics state machine and is a shared
resource. This means, when a particular render state is set, it stays set until it is cleared
again, either by your own code, or by code elsewhere in RenderWare Graphics.
RenderWare Graphics makes heavy use of its rendering engine. Check the Render State flags
if you find effects being applied inappropriately – like fog being applied to displaying text.
The Camera View Matrix
RenderWare Graphics 3.7 I-105
5.3 The Camera View Matrix
This matrix transforms world space coordinates to camera clip space. The
camera's clip space is bounded by the near and far clip planes, and side
planes defined as follows:
x = 0, x = z, y = 0 and y = z for a Perspective projection model;
x = 0, x = 1, y = 0 and y = 1 for a Parallel projection model.
Camera View Matrix API
The View Matrix is accessed through the RwCameraGetViewMatrix() function.
Chapter 5 - The Camera
I-106 11 February 2004
5.4 Rasters & Cameras
In order to be useful, a Camera object has a couple of optional buffers
attached to it that are used to store the resulting rendered image. These
provide storage for both a Z Buffer and the frame buffer itself. In
RenderWare Graphics, the Raster object is used for both of these buffers.
Rasters are a key feature of RenderWare Graphics and are covered in much greater detail in
the Rasters, Images & Textures chapter.
The Raster types must be rwRASTERTYPEZBUFFER, for the Z-buffer, and of
type rwRASTERTYPECAMERA for the frame buffer.
The frame buffer Raster holds the rendered image. Since RenderWare
Graphics provides a double-buffered model, this image is stored off-screen
and is displayed when rendering is completed by the
RwCameraShowRaster() function.
5.4.1 Z Buffer Accuracy
This can vary quite dramatically from platform to platform and application
to application.
The Z buffer range is effectively dictated by both the spacing of the near
and far clip planes, and the definition of the Z buffer Raster. This last
might use anything from an array of 8-bit bytes to a map constructed from
IEEE-standard double-precision floating-point values.
Clearly, this means you need to take care when setting up the view frustum
as placing the near and far clip planes too far apart may result in rounding
errors and related problems.
Creating a Camera
RenderWare Graphics 3.7 I-107
5.5 Creating a Camera
The process of constructing a RenderWare Graphics camera is typically as
follows:
Create and allocate a Raster of type rwRASTERTYPECAMERA
Create and allocate another Raster of type rwRASTERTYPEZBUFFER
Create a Camera object using RwCameraCreate()
Attach the two Rasters to the Camera object using
RwCameraSetRaster() and RwCameraSetZRaster()
Create a Frame object and attach it to the Camera object using
RwCameraSetFrame(). The Frame allows for the control of the position
and orientation of the Camera.
Finally, if you're using the RpWorld Retained Mode API, you will need to
'add' the Camera to the World. (See the two Retained Mode API
chapters, Worlds & Static Models and Dynamic Models for more on this.)
At this point, the Camera is ready to use.
5.5.1 Orienting and Positioning a Camera in Scene
Space
A quick skim through the Fundamental Types chapter reminds us that the
Frame object is a container for the matrices used to position and orient
objects in a virtual space.
Cameras use frames to define:
Where they are positioned
Which direction they are facing
The Camera will always face along the Frame's look-at vector. The look-up
vector always points at the top of the View Window.
One oddity is that, because the Camera is facing away from us, its look-right vector is
invariably pointing to the left from the user's point of view.
Transformations
Frames attached to Cameras behave just like Frames attached to anything
else. Transformations are performed by using the RwFrame API and are
used to position and orient a Camera.
Chapter 5 - The Camera
I-108 11 February 2004
Frame Origin
When attached to a Camera, the Frame's origin will be coincident with the
Viewpoint. Note that this means the View Window will always be located
exactly one unit along the look-at vector.
Rendering to a Camera
RenderWare Graphics 3.7 I-109
5.6 Rendering to a Camera
3D graphics rendering takes place between an RwCameraBeginUpdate() /
RwCameraEndUpdate() pair. All rendering must take place between these
two functions, although you can have more than one Begin/End pair
operation before displaying the rendered image using
RwCameraShowRaster().
As many RenderWare Graphics applications use the Retained Mode
(RpWorld) Plugin, a typical render cycle may look like this:
if ( RwCameraBeginUpdate(mainCamera) )
This line prepares the Camera for rendering, pushing its frame buffer
Raster onto the context stack. The top-most Raster on this stack is used as
the target for rendering. (Rasters are covered in more detail in the Rasters,
Images and Textures chapter.)
The context stack is described in more detail in the "Immediate Mode"
chapter.
At this point, Frame objects marked as 'dirty' will also have their Local
Transformation Matrices (LTM) resynchronized. Any hierarchies hanging off
the Frames are also updated. This ensures any rendered objects attached
to the Frames are positioned and oriented correctly.
{
RpWorldRender(gameWorld); /* Render the main game world */
We'll cover the RpWorld Retained Mode API in detail in later chapters. For
now, suffice to say that this function will render an entire scene.
/* Now render any UI overlays, such as HUDs, high score */
… some more rendering code…
At this stage, you may want to add some special effects, such as lens flare
or other visual gloss. Many such effects are often best achieved using the
Immediate Mode APIs.
RwCameraEndUpdate(mainCamera);
/* End of rendering cycle. */
At this point, RenderWare Graphics will pop the Camera's Raster off the
context stack. It also cleans up after itself and performs any necessary
housekeeping.
We do not, however, have a visible result: the rendering has taken place,
but because RenderWare Graphics uses double buffering, we need to swap
the buffers over so we can see the results of our toil...
/* Display the results of the rendering. */
RwCameraShowRaster(mainCamera, (void *)win32Handle,
rwRASTERFLIPWAITVSYNC);
}
Chapter 5 - The Camera
I-110 11 February 2004
This function performs the buffer-swap needed to display our rendered
scene. The parameters are, in order: the Camera object, a platform-specific
parameter (in this case, a HWND container as the Win32 SDK is being used
in this example), and finally, a flag can be specified to tell RenderWare
Graphics to wait for the vertical blanking interrupt. (This last should only
be used in a full-screen application.)
We can now update our scene ready for the next rendering cycle.
5.6.1 Destroying a Camera
Camera objects need to be explicitly destroyed when you are finished with
them. Because the Camera contains references to other objects, these also
need to be destroyed explicitly as RwCameraDestroy() will not destroy
these for you.
So:
1. Obtain pointers to any Rasters attached to the Camera – use
RwCameraGetRaster() and RwCameraGetZRaster() for this.
2. Destroy these Rasters using RwRasterDestroy().
3. Use RwCameraGetFrame() to extract the Frame object and destroy that
also.
4. Destroy the Camera object itself using RwCameraDestroy().
Sub-Rasters
RenderWare Graphics 3.7 I-111
5.7 Sub-Rasters
Sub-Rasters can be used with Cameras to provide the following:
Split-screen views, often seen in multi-player games
Picture-in-picture and other inset effects, such as rear-view mirrors in
driving games
These effects are achieved by sharing a single Raster across multiple
Camera objects.
For full details on how Sub-Rasters work, see the Rasters, Images & Textures chapter.
Chapter 5 - The Camera
I-112 11 February 2004
5.8 Other Features
5.8.1 Clearing the Buffers
This process should be performed at the beginning of each frame unless
your scene rendering is refreshing each pixel in the buffer every cycle
anyway.
The function for this procedure is RwCameraClear(). Refer to the API
Reference Manual for more details.
5.8.2 Cloning a Camera
RenderWare Graphics provides the RwCameraClone() function for this
purpose.
As with most other 'clone' operations in RenderWare Graphics, this means
both the source Camera and the target Camera objects will share the
Frame, frame buffer Raster and Z-buffer Raster. Also, if the source Camera
had been added to a World (RpWorld) object, the cloned Camera will also
be in that World.
World Plugin Extensions
RenderWare Graphics 3.7 I-113
5.9 World Plugin Extensions
5.9.1 About the Extensions
The World Plugin adds a number of additional functions to the Core
Library's Camera API. These are described here.
5.9.2 Automatic & Manual Culling
When rendering scenes using the World Plugin (RpWorld) API, the Plugin
will automatically cull any Atomics and World Sectors that are located
outside the Camera's view frustum. It will also cull any dynamic Lights
whose spheres of influence are inapplicable within the view frustum.
However, this only applies to model data that has been explicitly 'added' to
the World object. If you need to render an object, such as an Atomic,
explicitly – and this is sometimes desirable – then you will need to perform
the culling yourself.
This can be achieved using the RwCameraFrustumTestSphere() function,
which will test a Bounding Sphere (RwSphere) object passed to it and tell
you whether it is inside, outside or intersecting the specified Camera's view
frustum. The values it will return are: rwSPHEREINSIDE, rwSPHEREOUTSIDE
and rwSPHEREBOUNDARY respectively.
5.9.3 Clump Cameras
An RpClump is a container for dynamic objects that are associated with a
frame hierarchy, and are described in more detail in a later chapter. It is
possible to add Cameras to a Clump using the function
RpClumpAddCamera(). Such Cameras are streamed with the Clump, and
their location within the frame hierarchy preserved. This mechanism is
used whenever Cameras are exported from the modeling packages.
5.9.4 Iterators
A number of useful iterator functions are provided to access model data
that falls either within or outside the Camera's view frustum. The iterators
cover a number of object types.
In all cases, the iterators can rely Bounding Spheres to perform their tests.
World Sectors
These represent static model geometry. One iterator is supplied:
RwCameraForAllSectorsInFrustum(). This will iterate through all World
Sectors that are either partially or entirely within the view frustum, calling
a specified callback function for each one it finds.
Chapter 5 - The Camera
I-114 11 February 2004
The World Sector functions include a number of iterators for locating
objects that lie within them, such as Atomics and Lights.
Clumps
Clumps represent dynamic objects and a frustum iterator is supplied:
RwCameraForAllClumpsInFrustum(). Like the World Sector form
described above, this function will iterate through all Clumps that contain
Atomics either partially or entirely within the view frustum. For each such
Clump, it will call the specified callback function.
The callback function is of type RpClumpCallBack().
Chapter 6
Rasters, Images
and Textures
Chapter 6 - Rasters, Images and Textures
I-116 11 February 2004
6.1 Introduction
This chapter discusses bitmaps, images, rasters and textures and explains
when and where they are used. These objects can all be found in the Core
Library:
RwImage
RwRaster
RwTexDictionary
RwTexture
In addition, platform independent texture dictionaries are explained here,
and these require the use of the RtPITexD toolkit.
Bitmaps & Textures
RenderWare Graphics 3.7 I-117
6.2 Bitmaps & Textures
Bitmaps play a major part in any 3D graphics engine. They form the basis
for texture maps.
6.2.1 Bitmaps
RenderWare Graphics' Core Library supports two different types of bitmap
objects: Images and Rasters.
While the APIs for these objects are superficially similar, there is one very
important difference. The Image (RwImage) object is platform independent;
the Raster (RwRaster) is not.
The reason for this duality is to give you the most flexibility without
sacrificing power. Images can be easily processed and manipulated, but
cannot be displayed until they have been converted to Rasters. Rasters
have minimal manipulation and processing facilities, but are highly
optimized for the underlying hardware.
6.2.2 Images
Images provide a platform-independent object for manipulating bitmap
data.
Images are used to load bitmaps from disk or other media storage prior to
conversion to a platform-optimized Raster object, which can then be
manipulated.
6.2.3 Rasters
Rasters provide a platform dependent form of image and are used to hold
image data. Rasters are frequently found inside other RenderWare Graphics
objects. Of particular note are the Camera (RwCamera) and Texture
(RwTexture) objects. For more information about cameras see the chapter
on The Camera.
Rasters are the only form of bitmap that RenderWare Graphics can actually
render to a display device. Image objects are normally used as
intermediaries.
Chapter 6 - Rasters, Images and Textures
I-118 11 February 2004
6.2.4 Textures
A texture is a bitmap that is stretched across a polygon. Textures use
Rasters to store the actual bitmap data. The Rasters are also used to store
mipmaps.
It is the Raster itself that supports mipmapping, not the Texture object.
The Image Object
RenderWare Graphics 3.7 I-119
6.3 The Image Object
Images represent a platform-independent bitmap.
They can support most common image formats and this makes them ideally
suited as intermediaries.
For example, when you load a bitmap, such as a PNG or BMP, from disk, it
ends up in an Image object.
6.3.1 Image Dimensions
Image objects can have any width or height. Dimensions are limited only by
available memory. The color depth can be four, eight or thirty-two bits per
pixel.
Images do not support packed pixel formats. This means that the bitmap
actually stores only one pixel per byte, even if only four of the bits in each
byte are significant.
6.3.2 Stride
An Image is associated with a stride. A stride defines the physical number
of bytes needed to get from one pixel in the bitmap to the one directly
below.
The stride allows a bitmap to be defined as a portion of a larger bitmap.
This kind of usage is popular as it reduces loading times by combining
smaller images into one larger one.