Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

matrix.cpp

Go to the documentation of this file.
00001 /*           Copyright (C) 2001 Sony Computer Entertainment America
00002                               All Rights Reserved
00003                                SCEA Confidential                                */
00004 
00005 #include "ps2s/math.h"
00006 
00007 #include "ps2gl/matrix.h"
00008 #include "ps2gl/glcontext.h"
00009 #include "ps2gl/dlist.h"
00010 #include "ps2gl/immgmanager.h"
00011 #include "ps2gl/dlgmanager.h"
00012 
00013 /********************************************
00014  * CDListMatrixStack
00015  */
00016 
00017 
00018 class CMatrixPopCmd : public CDListCmd {
00019    public:
00020       CMatrixPopCmd() {}
00021       CDListCmd* Play() { glPopMatrix(); return CDListCmd::GetNextCmd(this); }
00022 };
00023 
00024 void
00025 CDListMatrixStack::Pop()
00026 {
00027    GLContext.GetDListGeomManager().Flush();
00028    GLContext.GetDListManager().GetOpenDList() += CMatrixPopCmd();
00029    GLContext.XformChanged();
00030 }
00031 
00032 class CMatrixPushCmd : public CDListCmd {
00033    public:
00034       CMatrixPushCmd() {}
00035       CDListCmd* Play() { glPushMatrix(); return CDListCmd::GetNextCmd(this); }
00036 };
00037 
00038 void
00039 CDListMatrixStack::Push()
00040 {
00041    GLContext.GetDListManager().GetOpenDList() += CMatrixPushCmd();
00042 }
00043 
00044 class CMatrixConcatCmd : public CDListCmd {
00045       cpu_mat_44        Matrix, Inverse;
00046    public:
00047       CMatrixConcatCmd( const cpu_mat_44 &mat, const cpu_mat_44 &inv )
00048          : Matrix(mat), Inverse(inv) {}
00049       CDListCmd* Play() {
00050          pGLContext->GetCurMatrixStack().Concat( Matrix, Inverse );
00051          return CDListCmd::GetNextCmd(this);
00052       }
00053 };
00054 
00055 void
00056 CDListMatrixStack::Concat( const cpu_mat_44& xform, const cpu_mat_44& inverse )
00057 {
00058    GLContext.GetDListGeomManager().Flush();
00059    GLContext.GetDListManager().GetOpenDList() += CMatrixConcatCmd( xform, inverse );
00060    GLContext.XformChanged();
00061 }
00062 
00063 class CMatrixSetTopCmd : public CDListCmd {
00064       cpu_mat_44        Matrix, Inverse;
00065    public:
00066       CMatrixSetTopCmd( const cpu_mat_44 &mat, const cpu_mat_44 &inv )
00067          : Matrix(mat), Inverse(inv) {}
00068       CDListCmd* Play() {
00069          pGLContext->GetCurMatrixStack().SetTop( Matrix, Inverse );
00070          return CDListCmd::GetNextCmd(this);
00071       }
00072 };
00073 
00074 void
00075 CDListMatrixStack::SetTop( const cpu_mat_44 &newMat, const cpu_mat_44 &newInv )
00076 {
00077    GLContext.GetDListGeomManager().Flush();
00078    GLContext.GetDListManager().GetOpenDList() += CMatrixSetTopCmd( newMat, newInv );
00079    GLContext.XformChanged();
00080 }
00081 
00082 
00083 /********************************************
00084  * gl api
00085  */
00086 
00087 void glMatrixMode( GLenum mode )
00088 {
00089    pGLContext->SetMatrixMode( mode );
00090 }
00091 
00092 void glLoadIdentity( void )
00093 {
00094    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00095 
00096    cpu_mat_44 ident;
00097    ident.set_identity();
00098    matStack.SetTop( ident, ident );
00099 }
00100 
00101 void glPushMatrix( void )
00102 {
00103    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00104    matStack.Push();
00105 }
00106 
00107 void glPopMatrix( void )
00108 {
00109    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00110    matStack.Pop();
00111 }
00112 
00113 void glLoadMatrixf( const GLfloat *m )
00114 {
00115    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00116    cpu_mat_44 newMat;
00117 
00118    // unfortunately we can't assume the matrix is qword-aligned
00119    float *dest = reinterpret_cast<float*>(&newMat);
00120    for ( int i = 0; i < 16; i++ )
00121       *dest++ = *m++;
00122 
00123    // FIXME: need to compute the inverse
00124    mNotImplemented( "LoadMatrix is broken.. inverses won't be correct." );
00125    cpu_mat_44 dummy;
00126    matStack.SetTop( newMat, dummy );
00127 }
00128 
00129 void glFrustum( GLdouble left, GLdouble right,
00130                 GLdouble bottom, GLdouble top,
00131                 GLdouble zNear, GLdouble zFar )
00132 {
00133    cpu_mat_44 xform( cpu_vec_xyzw( (2.0f * zNear)
00134                                    / (right - left),
00135                                    0.0f,
00136                                    0.0f,
00137                                    0.0f ),
00138                      cpu_vec_xyzw( 0.0f,
00139                                    (2.0f * zNear)
00140                                    / (top - bottom),
00141                                    0.0f,
00142                                    0.0f ),
00143                      cpu_vec_xyzw( (right + left)
00144                                    / (right - left),
00145                                    (top + bottom)
00146                                    / (top - bottom),
00147                                    -(zFar + zNear)
00148                                    / (zFar - zNear),
00149                                    -1.0f ),
00150                      cpu_vec_xyzw( 0.0f,
00151                                    0.0f,
00152                                    (-2.0f * zFar * zNear)
00153                                    / (zFar - zNear),
00154                                    0.0f )
00155       );
00156 
00157    cpu_mat_44 inv( cpu_vec_xyzw( (right - left)
00158                                  / (2 * zNear),
00159                                  0,
00160                                  0,
00161                                  0 ),
00162                    cpu_vec_xyzw( 0,
00163                                  (top - bottom)
00164                                  / (2 * zNear),
00165                                  0,
00166                                  0 ),
00167                    cpu_vec_xyzw( 0,
00168                                  0,
00169                                  0,
00170                                  -(zFar - zNear)
00171                                  / (2 * zFar * zNear) ),
00172                    cpu_vec_xyzw( (right + left)
00173                                  / (2 * zNear),
00174                                  (top + bottom)
00175                                  / (2 * zNear),
00176                                  -1,
00177                                  (zFar + zNear)
00178                                  / (2 * zFar * zNear) )
00179       );
00180 
00181    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00182    matStack.Concat( xform, inv );
00183 }
00184 
00185 void glMultMatrixf( const GLfloat *m )
00186 {
00187    // unfortunately we can't assume the matrix is qword-aligned
00188    // the casts to float below fix an apparent parse error... something's up here..
00189    cpu_mat_44 newMatrix( cpu_vec_xyzw( (float)m[0], (float)m[1], (float)m[2], (float)m[3] ),
00190                          cpu_vec_xyzw( (float)m[4], (float)m[5], (float)m[6], (float)m[7] ),
00191                          cpu_vec_xyzw( (float)m[8], (float)m[9], (float)m[10], (float)m[11] ),
00192                          cpu_vec_xyzw( (float)m[12], (float)m[13], (float)m[14], (float)m[15] ) );
00193 
00194    // close your eyes.. this is a temporary hack
00195 
00196    /*
00197    // assume that newMatrix consists of rotations, uniform scales, and translations
00198    cpu_vec_xyzw scaledVec( 1, 0, 0, 0 );
00199    scaledVec = newMatrix * scaledVec;
00200    float scale = scaledVec.length();
00201 
00202    cpu_mat_44 invMatrix = newMatrix;
00203    invMatrix.set_col3( cpu_vec_xyzw(0,0,0,0) );
00204    invMatrix.transpose_in_place();
00205    invMatrix.set_col3( -newMatrix.get_col3() );
00206    cpu_mat_44 scaleMat;
00207    scaleMat.set_scale( cpu_vec_xyz(scale, scale, scale) );
00208    invMatrix = scaleMat * invMatrix;
00209    */
00210 
00211    cpu_mat_44 invMatrix;
00212    invMatrix.set_identity();
00213    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00214    matStack.Concat( newMatrix, invMatrix );
00215 
00216    mWarn( "glMultMatrix is not correct" );
00217 }
00218 
00219 void glRotatef( GLfloat angle,
00220                 GLfloat x, GLfloat y, GLfloat z )
00221 {
00222    cpu_mat_44 xform, inverse;
00223    cpu_vec_xyz axis(x,y,z);
00224    xform.set_rotate( Math::DegToRad(angle), axis );
00225    inverse.set_rotate( Math::DegToRad(-angle), axis );
00226 
00227    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00228    matStack.Concat( xform, inverse );
00229 }
00230 
00231 void glScalef( GLfloat x, GLfloat y, GLfloat z )
00232 {
00233    cpu_mat_44 xform, inverse;
00234    xform.set_scale( cpu_vec_xyz(x,y,z) );
00235    inverse.set_scale( cpu_vec_xyz(1.0f/x, 1.0f/y, 1.0f/z) );
00236 
00237    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00238    matStack.Concat( xform, inverse );
00239 }
00240 
00241 void glTranslatef( GLfloat x, GLfloat y, GLfloat z )
00242 {
00243    cpu_mat_44 xform, inverse;
00244    cpu_vec_xyz direction(x, y, z);
00245    xform.set_translate( direction );
00246    inverse.set_translate( -direction );
00247 
00248    CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00249    matStack.Concat( xform, inverse );
00250 }

ps2gl version 0.2