PS2 Linux Programming
Rendering a 3D model
Introduction
In this tutorial the MilkShape 3D ASCII 3D model format will be used to load and display a textured 3D model of a character.
It has been seen from previous tutorials that in order to draw objects on screen, information is required about the vertices of the object. Typical information is the position, normal, colour and texture coordinates of all the vertices in the model. Hand coding this information is possible when the model has only a few vertices, but this becomes impractical for models of any size.
A 3D modelling package is used to create models and write the vertex information out to a file. This file can then be read by the rendering program and the model can be displayed and manipulated on screen.
There are many 3D modelling packages such as 3D Studio Max and Maya, but as well as being very expensive to purchase they can also be complex to use, offering much more functionality than is normally required for making a game. There are also very many different 3D modelling file formats that are used to represent the vertices (and other information such as animation details) of a model, but once again some formats are difficult to understand and complex to use.
As an introduction to using 3D models, the MilkShape 3D modelling package has been used to create a model in the MilkShape 3D ASCII format. MilkShape 3D can be found at http://www.milkshape3d.com/ and the ASCII format is relatively easy to understand, use and debug. MilkShape 3D is inexpensive to purchase costing around £20 so is ideal for the low-budget enthusiast.
An extract from a MilkShape 3D ASCII file is given below.
// MilkShape 3D ASCII
Frames: 30
Frame: 1
Meshes: 6
"FaceL" 0 -1
4
0 -20.000000 20.000000 -20.000000 0.000000 0.000000 -1
0 -20.000000 -20.000000 -20.000000 0.000000 1.000000 -1
0 -20.000000 20.000000 20.000000 1.000000 0.000000 -1
0 -20.000000 -20.000000 20.000000 1.000000 1.000000 -1
1
-1.000000 0.000000 0.000000
2
0 0 1 2 0 0 0 2
0 1 3 2 0 0 0 2
Basically, the model is divided up into meshes and each mesh has (among other things) vertex information, normals and triangles associated with it. In the above example, there are four vertices which are specified in terms of position and texture coordinates, there is one normal and there are two triangles. The first triangle is made from vertices 0, 1 and 2 and the second triangle from vertices 1, 3 and 2.
In order to use this format, the triangle information must be expanded so as to obtain the vertex information for each triangle in the mesh.
NOTE: As written, the model class only renders the first mesh in the model – all other meshes are ignored. It is left up to the reader to expand the code to render all the model meshes.
The 3D model class is contained within the files ms3dmodel.cpp and ms3dmodel.h. The 3d model is rendered using the same VU1 quad-buffered scheme (and micro-program) that was used in the tutorial “Setting-Up Quad Buffers in VU Data Memory”. The two major class methods that are used are Load() which is used to load the vertex (and other) information from the ASCII file, and Render() which is used to render the model. Load() configures the model data in static memory along with the lighting values for the model. It is important to remember to set the lighting parameters for the model before calling Load() otherwise the default lighting values will be stored in static memory along with the model data. There are three directional lights and ambient light associated with the model and there are class methods (such as SetLight1Dir()) to set the appropriate parameters.
The model texture being used is also extracted from the model file within the Load() method. Only the first material is used within the model class so it is only possible to use one material with the model. It is left to the reader to expand the number of materials in use if required.
The Example Code
Within main() an instance of the model class is created together with an associated texture class to hold the model texture. Only one directional light and ambient light is being used and the lighting parameters are set prior to calling the Load() method to load and configure the 3d model data. The Render() method takes two parameters, the first is the vertex transformation matrix which is used to transform the vertex data, and the second is the world transformation matrix which is used to transform the model normals for lighting calculations.
The model is rendered at the origin with the camera being setup to view the model. The world transformation matrix is set to rotate the model continuously around it’s y-axis.
In this tutorial a 3D model has been loaded and rendered. Many of the features MilkShape3D ASCII format have not been implemented in the code and it is left up to the reader to explore and implement these features as necessary. Using the tutorial code it is possible to load and display other 3D models which are in the MilkShape3D ASCII format within the limitations of the supplied code.
Dr Henry S Fortuna
University of Abertay Dundee