PS2 Linux Programming
3D Graphics API for PS2 Linux
This tutorial introduces a 3D graphics API for use with PS2 Linux. The API uses a quad buffered VU memory layout and incorporates three directional lights and ambient light. A pipeline class is used to configure and manage the 3D graphics pipeline. Several of the topics and techniques introduced in the tutorials are included in the API.
The pipeline class definition is shown below for clarity.
class CPipeline : public CSingleton<CPipeline>
inline const Matrix4x4 & GetProjection(void) const;
inline const Matrix4x4 & GetCamera(void) const;
inline const Matrix4x4 & GetViewProjection(void) const;
inline const Matrix4x4 & GetLightDirs(void) const;
inline const Matrix4x4 & GetLightCols(void) const;
inline const Vector4 & GetScaleVector(void) const;
void SetLight1(const Vector4 & Direction, const Vector4 & Colour);
void SetLight2(const Vector4 & Direction, const Vector4 & Colour);
void SetLight3(const Vector4 & Direction, const Vector4 & Colour);
void SetAmbient(const Vector4 & Colour);
void Update(float Strafe, float Advance, float UpDown, float XRot, float YRot);
void PositionCamera(const Vector4 & Position, const float XRot, const float YRot);
float m_near; // Near plane
float m_far; // Far plane
float m_FOV; // Field of View
float m_Aspect; // Aspect Ratio
float m_ScreenW; // Screen Width
float m_ScreenH; // Screen height;
float m_XRot, m_YRot;
The class contains the projection, camera and combined ViewProjection matrices. It also contains matrices to hold the light direction vectors and the light colours. In addition to this, various variables are maintained to facilitate the calculation and setting of appropriate matrices. Along with the data, there are various methods within the class which are used to set, calculate and get the appropriate matrix data for use within the application. Note that the pipeline class is used as a singleton, and as such there is only one instance of this class within the application.
VU Data Memory Layout
The layout of VU data memory used within the API is illustrated below.
32 Qwords of memory are allocated at the top of VU memory to contain the matrix and other data that does not change for each batch of vertices to be processed. It can be seen that a maximum to 82 vertices can be processed in each batch, with each vertex having position, texture coordinate and normal data associated with it. Note that not all of the 32 Qwords at the start of VU memory are used, and there is room there to include additional features into the API such as Point and Specular lighting (plus lots more).
Within the API framework, classes have been defined to render a 3D model in MilkShape3D ASCII format, a terrain and some simple user defined geometry such as a cube. Note that due to the VU memory layout used, these classes are different from similar ones used in various other tutorials – the principles of operation are however identical.
The Example Code
The purpose of the example code is to illustrate the configuration and use of the API. The pipeline matrices are initialised with the following calls.
// Initialise graphics pipline class
// Initialise Lighting, Three lights and Ambient light
// Direction vector Colour
Pipeline.SetLight1(Vector4( 1.0f, 0.2f, 0.0f, 0.0f), Vector4(128.0f,128.0f,128.0f,0.0f));
Pipeline.SetLight2(Vector4(-1.0f,-0.2f, 0.0f, 0.0f), Vector4(0.0f,128.0f,0.0f,0.0f));
Pipeline.SetLight3(Vector4( 0.0f, 0.0f,-1.0f, 0.0f), Vector4(0.0f,0.0f,128.0f,0.0f));
Pipeline.Initialise() configures the pipeline matrices and positions the camera at the origin looking directly down the negative z axis. The other methods shown above, configure the lighting vectors and colours. Note that if no lighting parameters are supplied at this stage, the directional lights will be off and the ambient light will be turned fully on by default.
Within the main render loop, the objects are rendered as appropriate and it is only necessary to supply the world transformation matrix for each object to be rendered. The other matrices required for the render process are extracted from the pipeline class.
Within the render loop the following call is made:
Pipeline.Update(Strafe, Advance, UpDown, YRot, XRot);
This call updates all of the pipeline matrices based upon the parameters supplied. As can be seen, these parameters are the movement and rotation characteristics of the camera.
Within the example application a flat terrain consisting of about 130,000 vertices, a 3D model consisting of about 1,500 vertices and a couple of low vertex count cubes are drawn. All of the objects are textures and lit. It can be seen from the on-screen statistics that the API returns a frame rate of about 868 FPS which is quite acceptable.
This tutorial has introduced a simple 3D API for PlayStation2 Linux which can be used as the basis for many 3D games applications.
Dr Henry S Fortuna
University of Abertay Dundee