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
00116 extern void Invert2( float *mat, float *dst );
00117
00118 void glLoadMatrixf( const GLfloat *m )
00119 {
00120 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00121 cpu_mat_44 newMat;
00122
00123
00124 float *dest = reinterpret_cast<float*>(&newMat);
00125 for ( int i = 0; i < 16; i++ )
00126 *dest++ = *m++;
00127
00128 cpu_mat_44 invMatrix;
00129 Invert2( (float*)&newMat, (float*)&invMatrix );
00130
00131 matStack.SetTop( newMat, invMatrix );
00132 }
00133
00134 void glFrustum( GLdouble left, GLdouble right,
00135 GLdouble bottom, GLdouble top,
00136 GLdouble zNear, GLdouble zFar )
00137 {
00138 cpu_mat_44 xform( cpu_vec_xyzw( (2.0f * zNear)
00139 / (right - left),
00140 0.0f,
00141 0.0f,
00142 0.0f ),
00143 cpu_vec_xyzw( 0.0f,
00144 (2.0f * zNear)
00145 / (top - bottom),
00146 0.0f,
00147 0.0f ),
00148 cpu_vec_xyzw( (right + left)
00149 / (right - left),
00150 (top + bottom)
00151 / (top - bottom),
00152 -(zFar + zNear)
00153 / (zFar - zNear),
00154 -1.0f ),
00155 cpu_vec_xyzw( 0.0f,
00156 0.0f,
00157 (-2.0f * zFar * zNear)
00158 / (zFar - zNear),
00159 0.0f )
00160 );
00161
00162 cpu_mat_44 inv( cpu_vec_xyzw( (right - left)
00163 / (2 * zNear),
00164 0,
00165 0,
00166 0 ),
00167 cpu_vec_xyzw( 0,
00168 (top - bottom)
00169 / (2 * zNear),
00170 0,
00171 0 ),
00172 cpu_vec_xyzw( 0,
00173 0,
00174 0,
00175 -(zFar - zNear)
00176 / (2 * zFar * zNear) ),
00177 cpu_vec_xyzw( (right + left)
00178 / (2 * zNear),
00179 (top + bottom)
00180 / (2 * zNear),
00181 -1,
00182 (zFar + zNear)
00183 / (2 * zFar * zNear) )
00184 );
00185
00186 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00187 matStack.Concat( xform, inv );
00188 }
00189
00190 void glOrtho( GLdouble left, GLdouble right,
00191 GLdouble bottom, GLdouble top,
00192 GLdouble zNear, GLdouble zFar )
00193 {
00194 cpu_mat_44 xform( cpu_vec_xyzw( (2.0f)
00195 / (right - left),
00196 0.0f,
00197 0.0f,
00198 0.0f ),
00199 cpu_vec_xyzw( 0.0f,
00200 (2.0f)
00201 / (top - bottom),
00202 0.0f,
00203 0.0f ),
00204 cpu_vec_xyzw( 0.0f,
00205 0.0f,
00206 -2
00207 / (zFar - zNear),
00208 0.0f ),
00209 cpu_vec_xyzw( - (right + left)
00210 / (right - left),
00211 - (top + bottom)
00212 / (top - bottom),
00213 - (zFar + zNear)
00214 / (zFar - zNear),
00215 1.0f )
00216 );
00217
00218 cpu_mat_44 inv( cpu_vec_xyzw( (right - left)
00219 / 2,
00220 0,
00221 0,
00222 0 ),
00223 cpu_vec_xyzw( 0,
00224 (top - bottom)
00225 / 2,
00226 0,
00227 0 ),
00228 cpu_vec_xyzw( 0,
00229 0,
00230 (zFar - zNear)
00231 / -2,
00232 0 ),
00233 cpu_vec_xyzw( (right + left)
00234 / 2,
00235 (top + bottom)
00236 / 2,
00237 (zFar + zNear)
00238 / 2,
00239 1 )
00240 );
00241
00242 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
00243 matStack.Concat( xform, inv );
00244 }
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 }