00001
00002
00003 This file is subject to the terms and conditions of the GNU Lesser
00004 General Public License Version 2.1. See the file "COPYING" in the
00005 main directory of this archive for more details. */
00006
00007 #include "ps2s/math.h"
00008
00009 #include "ps2gl/matrix.h"
00010 #include "ps2gl/glcontext.h"
00011 #include "ps2gl/dlist.h"
00012 #include "ps2gl/immgmanager.h"
00013 #include "ps2gl/dlgmanager.h"
00014
00015
00016 * CDListMatrixStack
00017 */
00018
00019
00020 class CMatrixPopCmd : public CDListCmd {
00021 public:
00022 CMatrixPopCmd() {}
00023 CDListCmd* Play() { glPopMatrix(); return CDListCmd::GetNextCmd(this); }
00024 };
00025
00026 void
00027 CDListMatrixStack::Pop()
00028 {
00029 GLContext.GetDListGeomManager().Flush();
00030 GLContext.GetDListManager().GetOpenDList() += CMatrixPopCmd();
00031 GLContext.XformChanged();
00032 }
00033
00034 class CMatrixPushCmd : public CDListCmd {
00035 public:
00036 CMatrixPushCmd() {}
00037 CDListCmd* Play() { glPushMatrix(); return CDListCmd::GetNextCmd(this); }
00038 };
00039
00040 void
00041 CDListMatrixStack::Push()
00042 {
00043 GLContext.GetDListManager().GetOpenDList() += CMatrixPushCmd();
00044 }
00045
00046 class CMatrixConcatCmd : public CDListCmd {
00047 cpu_mat_44 Matrix, Inverse;
00048 public:
00049 CMatrixConcatCmd( const cpu_mat_44 &mat, const cpu_mat_44 &inv )
00050 : Matrix(mat), Inverse(inv) {}
00051 CDListCmd* Play() {
00052 pGLContext->GetCurMatrixStack().Concat( Matrix, Inverse );
00053 return CDListCmd::GetNextCmd(this);
00054 }
00055 };
00056
00057 void
00058 CDListMatrixStack::Concat( const cpu_mat_44& xform, const cpu_mat_44& inverse )
00059 {
00060 GLContext.GetDListGeomManager().Flush();
00061 GLContext.GetDListManager().GetOpenDList() += CMatrixConcatCmd( xform, inverse );
00062 GLContext.XformChanged();
00063 }
00064
00065 class CMatrixSetTopCmd : public CDListCmd {
00066 cpu_mat_44 Matrix, Inverse;
00067 public:
00068 CMatrixSetTopCmd( const cpu_mat_44 &mat, const cpu_mat_44 &inv )
00069 : Matrix(mat), Inverse(inv) {}
00070 CDListCmd* Play() {
00071 pGLContext->GetCurMatrixStack().SetTop( Matrix, Inverse );
00072 return CDListCmd::GetNextCmd(this);
00073 }
00074 };
00075
00076 void
00077 CDListMatrixStack::SetTop( const cpu_mat_44 &newMat, const cpu_mat_44 &newInv )
00078 {
00079 GLContext.GetDListGeomManager().Flush();
00080 GLContext.GetDListManager().GetOpenDList() += CMatrixSetTopCmd( newMat, newInv );
00081 GLContext.XformChanged();
00082 }
00083
00084
00085
00086 * gl api
00087 */
00088
00089 void glMatrixMode( GLenum mode )
00090 {
00091 pGLContext->SetMatrixMode( mode );
00092 }
00093
00094 void glLoadIdentity( void )
00095 {
00096 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00097
00098 cpu_mat_44 ident;
00099 ident.set_identity();
00100 matStack.SetTop( ident, ident );
00101 }
00102
00103 void glPushMatrix( void )
00104 {
00105 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00106 matStack.Push();
00107 }
00108
00109 void glPopMatrix( void )
00110 {
00111 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00112 matStack.Pop();
00113 }
00114
00115 void glLoadMatrixf( const GLfloat *m )
00116 {
00117 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00118 cpu_mat_44 newMat;
00119
00120
00121 float *dest = reinterpret_cast<float*>(&newMat);
00122 for ( int i = 0; i < 16; i++ )
00123 *dest++ = *m++;
00124
00125
00126 mNotImplemented( "LoadMatrix is broken.. inverses won't be correct." );
00127 cpu_mat_44 dummy;
00128 matStack.SetTop( newMat, dummy );
00129 }
00130
00131 void glFrustum( GLdouble left, GLdouble right,
00132 GLdouble bottom, GLdouble top,
00133 GLdouble zNear, GLdouble zFar )
00134 {
00135 cpu_mat_44 xform( cpu_vec_xyzw( (2.0f * zNear)
00136 / (right - left),
00137 0.0f,
00138 0.0f,
00139 0.0f ),
00140 cpu_vec_xyzw( 0.0f,
00141 (2.0f * zNear)
00142 / (top - bottom),
00143 0.0f,
00144 0.0f ),
00145 cpu_vec_xyzw( (right + left)
00146 / (right - left),
00147 (top + bottom)
00148 / (top - bottom),
00149 -(zFar + zNear)
00150 / (zFar - zNear),
00151 -1.0f ),
00152 cpu_vec_xyzw( 0.0f,
00153 0.0f,
00154 (-2.0f * zFar * zNear)
00155 / (zFar - zNear),
00156 0.0f )
00157 );
00158
00159 cpu_mat_44 inv( cpu_vec_xyzw( (right - left)
00160 / (2 * zNear),
00161 0,
00162 0,
00163 0 ),
00164 cpu_vec_xyzw( 0,
00165 (top - bottom)
00166 / (2 * zNear),
00167 0,
00168 0 ),
00169 cpu_vec_xyzw( 0,
00170 0,
00171 0,
00172 -(zFar - zNear)
00173 / (2 * zFar * zNear) ),
00174 cpu_vec_xyzw( (right + left)
00175 / (2 * zNear),
00176 (top + bottom)
00177 / (2 * zNear),
00178 -1,
00179 (zFar + zNear)
00180 / (2 * zFar * zNear) )
00181 );
00182
00183 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00184 matStack.Concat( xform, inv );
00185 }
00186
00187 void glOrtho( GLdouble left, GLdouble right,
00188 GLdouble bottom, GLdouble top,
00189 GLdouble zNear, GLdouble zFar )
00190 {
00191 cpu_mat_44 xform( cpu_vec_xyzw( (2.0f)
00192 / (right - left),
00193 0.0f,
00194 0.0f,
00195 0.0f ),
00196 cpu_vec_xyzw( 0.0f,
00197 (2.0f)
00198 / (top - bottom),
00199 0.0f,
00200 0.0f ),
00201 cpu_vec_xyzw( 0.0f,
00202 0.0f,
00203 -2
00204 / (zFar - zNear),
00205 0.0f ),
00206 cpu_vec_xyzw( - (right + left)
00207 / (right - left),
00208 - (top + bottom)
00209 / (top - bottom),
00210 - (zFar + zNear)
00211 / (zFar - zNear),
00212 1.0f )
00213 );
00214
00215 cpu_mat_44 inv( cpu_vec_xyzw( (right - left)
00216 / 2,
00217 0,
00218 0,
00219 0 ),
00220 cpu_vec_xyzw( 0,
00221 (top - bottom)
00222 / 2,
00223 0,
00224 0 ),
00225 cpu_vec_xyzw( 0,
00226 0,
00227 (zFar - zNear)
00228 / -2,
00229 0 ),
00230 cpu_vec_xyzw( (right + left)
00231 / 2,
00232 (top + bottom)
00233 / 2,
00234 (zFar + zNear)
00235 / 2,
00236 1 )
00237 );
00238
00239 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00240 matStack.Concat( xform, inv );
00241 }
00242
00243
00244 extern void Invert2( float *mat, float *dst );
00245
00246 void glMultMatrixf( const GLfloat *m )
00247 {
00248
00249
00250 cpu_mat_44 newMatrix( cpu_vec_xyzw( (float)m[0], (float)m[1], (float)m[2], (float)m[3] ),
00251 cpu_vec_xyzw( (float)m[4], (float)m[5], (float)m[6], (float)m[7] ),
00252 cpu_vec_xyzw( (float)m[8], (float)m[9], (float)m[10], (float)m[11] ),
00253 cpu_vec_xyzw( (float)m[12], (float)m[13], (float)m[14], (float)m[15] ) );
00254
00255
00256
00257
00258 // assume that newMatrix consists of rotations, uniform scales, and translations
00259 cpu_vec_xyzw scaledVec( 1, 0, 0, 0 );
00260 scaledVec = newMatrix * scaledVec;
00261 float scale = scaledVec.length();
00262
00263 cpu_mat_44 invMatrix = newMatrix;
00264 invMatrix.set_col3( cpu_vec_xyzw(0,0,0,0) );
00265 invMatrix.transpose_in_place();
00266 invMatrix.set_col3( -newMatrix.get_col3() );
00267 cpu_mat_44 scaleMat;
00268 scaleMat.set_scale( cpu_vec_xyz(scale, scale, scale) );
00269 invMatrix = scaleMat * invMatrix;
00270 */
00271
00272 cpu_mat_44 invMatrix;
00273
00274 Invert2( (float*)&newMatrix, (float*)&invMatrix );
00275 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00276 matStack.Concat( newMatrix, invMatrix );
00277
00278
00279
00280 }
00281
00282 void glRotatef( GLfloat angle,
00283 GLfloat x, GLfloat y, GLfloat z )
00284 {
00285 cpu_mat_44 xform, inverse;
00286 cpu_vec_xyz axis(x,y,z);
00287 axis.normalize();
00288 xform.set_rotate( Math::DegToRad(angle), axis );
00289 inverse.set_rotate( Math::DegToRad(-angle), axis );
00290
00291 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00292 matStack.Concat( xform, inverse );
00293 }
00294
00295 void glScalef( GLfloat x, GLfloat y, GLfloat z )
00296 {
00297 cpu_mat_44 xform, inverse;
00298 xform.set_scale( cpu_vec_xyz(x,y,z) );
00299 inverse.set_scale( cpu_vec_xyz(1.0f/x, 1.0f/y, 1.0f/z) );
00300
00301 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00302 matStack.Concat( xform, inverse );
00303 }
00304
00305 void glTranslatef( GLfloat x, GLfloat y, GLfloat z )
00306 {
00307 cpu_mat_44 xform, inverse;
00308 cpu_vec_xyz direction(x, y, z);
00309 xform.set_translate( direction );
00310 inverse.set_translate( -direction );
00311
00312 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00313 matStack.Concat( xform, inverse );
00314 }