PS2GL
OpenGL*-like API for the PS2
Loading...
Searching...
No Matches
matrix.cpp
1/* Copyright (C) 2000,2001,2002 Sony Computer Entertainment America
2
3 This file is subject to the terms and conditions of the GNU Lesser
4 General Public License Version 2.1. See the file "COPYING" in the
5 main directory of this archive for more details. */
6
7#include "ps2s/math.h"
8
9#include "ps2gl/dlgmanager.h"
10#include "ps2gl/dlist.h"
11#include "ps2gl/glcontext.h"
12#include "ps2gl/immgmanager.h"
13#include "ps2gl/matrix.h"
14
15/********************************************
16 * CDListMatrixStack
17 */
18
19class CMatrixPopCmd : public CDListCmd {
20public:
21 CMatrixPopCmd() {}
22 CDListCmd* Play()
23 {
24 glPopMatrix();
25 return CDListCmd::GetNextCmd(this);
26 }
27};
28
29void CDListMatrixStack::Pop()
30{
31 GLContext.GetDListGeomManager().Flush();
32 GLContext.GetDListManager().GetOpenDList() += CMatrixPopCmd();
33 GLContext.XformChanged();
34}
35
36class CMatrixPushCmd : public CDListCmd {
37public:
39 CDListCmd* Play()
40 {
41 glPushMatrix();
42 return CDListCmd::GetNextCmd(this);
43 }
44};
45
46void CDListMatrixStack::Push()
47{
48 GLContext.GetDListManager().GetOpenDList() += CMatrixPushCmd();
49}
50
52 cpu_mat_44 Matrix, Inverse;
53
54public:
55 CMatrixConcatCmd(const cpu_mat_44& mat, const cpu_mat_44& inv)
56 : Matrix(mat)
57 , Inverse(inv)
58 {
59 }
60 CDListCmd* Play()
61 {
62 pGLContext->GetCurMatrixStack().Concat(Matrix, Inverse);
63 return CDListCmd::GetNextCmd(this);
64 }
65};
66
67void CDListMatrixStack::Concat(const cpu_mat_44& xform, const cpu_mat_44& inverse)
68{
69 GLContext.GetDListGeomManager().Flush();
70 GLContext.GetDListManager().GetOpenDList() += CMatrixConcatCmd(xform, inverse);
71 GLContext.XformChanged();
72}
73
75 cpu_mat_44 Matrix, Inverse;
76
77public:
78 CMatrixSetTopCmd(const cpu_mat_44& mat, const cpu_mat_44& inv)
79 : Matrix(mat)
80 , Inverse(inv)
81 {
82 }
83 CDListCmd* Play()
84 {
85 pGLContext->GetCurMatrixStack().SetTop(Matrix, Inverse);
86 return CDListCmd::GetNextCmd(this);
87 }
88};
89
90void CDListMatrixStack::SetTop(const cpu_mat_44& newMat, const cpu_mat_44& newInv)
91{
92 GLContext.GetDListGeomManager().Flush();
93 GLContext.GetDListManager().GetOpenDList() += CMatrixSetTopCmd(newMat, newInv);
94 GLContext.XformChanged();
95}
96
97/********************************************
98 * gl api
99 */
100
101void glMatrixMode(GLenum mode)
102{
103 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
104
105 pGLContext->SetMatrixMode(mode);
106}
107
108void glLoadIdentity(void)
109{
110 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
111
112 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
113
114 cpu_mat_44 ident;
115 ident.set_identity();
116 matStack.SetTop(ident, ident);
117}
118
119void glPushMatrix(void)
120{
121 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
122
123 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
124 matStack.Push();
125}
126
127void glPopMatrix(void)
128{
129 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
130
131 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
132 matStack.Pop();
133}
134
135// courtesy the lovely folks at Intel
136extern void Invert2(float* mat, float* dst);
137
138void glLoadMatrixf(const GLfloat* m)
139{
140 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
141
142 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
143 cpu_mat_44 newMat;
144
145 // unfortunately we can't assume the matrix is qword-aligned
146 float* dest = reinterpret_cast<float*>(&newMat);
147 for (int i = 0; i < 16; i++)
148 *dest++ = *m++;
149
150 cpu_mat_44 invMatrix;
151 Invert2((float*)&newMat, (float*)&invMatrix);
152
153 matStack.SetTop(newMat, invMatrix);
154}
155
156void glFrustum(GLdouble left, GLdouble right,
157 GLdouble bottom, GLdouble top,
158 GLdouble zNear, GLdouble zFar)
159{
160 /*
161 * NOTE:
162 * The PS2 does not support GL_LESS/GL_LEQUAL
163 * but this is what 99% of OpenGL programs use.
164 *
165 * As a result depth is inverted.
166 * See glDepthFunc/glFrustum/glOrtho
167 */
168 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
169
170 cpu_mat_44 xform(
171 cpu_vec_xyzw(
172 (2.0f * zNear) / (right - left),
173 0.0f,
174 0.0f,
175 0.0f),
176 cpu_vec_xyzw(
177 0.0f,
178 (2.0f * zNear) / (top - bottom),
179 0.0f,
180 0.0f),
181 cpu_vec_xyzw(
182 (right + left) / (right - left),
183 (top + bottom) / (top - bottom),
184 -(zFar + zNear) / (zFar - zNear),
185 -1.0f),
186 cpu_vec_xyzw(
187 0.0f,
188 0.0f,
189 (-2.0f * zFar * zNear) / (zFar - zNear),
190 0.0f)
191 );
192
193 cpu_mat_44 inv(
194 cpu_vec_xyzw(
195 (right - left) / (2 * zNear),
196 0,
197 0,
198 0),
199 cpu_vec_xyzw(
200 0,
201 (top - bottom) / (2 * zNear),
202 0,
203 0),
204 cpu_vec_xyzw(
205 0,
206 0,
207 0,
208 -(zFar - zNear) / (2 * zFar * zNear)),
209 cpu_vec_xyzw(
210 (right + left) / (2 * zNear),
211 (top + bottom) / (2 * zNear),
212 -1,
213 (zFar + zNear) / (2 * zFar * zNear))
214 );
215
216 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
217 matStack.Concat(xform, inv);
218}
219
220void glOrtho(GLdouble left, GLdouble right,
221 GLdouble bottom, GLdouble top,
222 GLdouble zNear, GLdouble zFar)
223{
224 /*
225 * NOTE:
226 * The PS2 does not support GL_LESS/GL_LEQUAL
227 * but this is what 99% of OpenGL programs use.
228 *
229 * As a result depth is inverted.
230 * See glDepthFunc/glFrustum/glOrtho
231 */
232 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
233
234 cpu_mat_44 xform(
235 cpu_vec_xyzw(
236 (2.0f) / (right - left),
237 0.0f,
238 0.0f,
239 0.0f),
240 cpu_vec_xyzw(
241 0.0f,
242 (2.0f) / (top - bottom),
243 0.0f,
244 0.0f),
245 cpu_vec_xyzw(
246 0.0f,
247 0.0f,
248 -2 / (zFar - zNear),
249 0.0f),
250 cpu_vec_xyzw(
251 -(right + left) / (right - left),
252 -(top + bottom) / (top - bottom),
253 -(zFar + zNear) / (zFar - zNear),
254 1.0f)
255 );
256
257 cpu_mat_44 inv(
258 cpu_vec_xyzw(
259 (right - left) / 2,
260 0,
261 0,
262 0),
263 cpu_vec_xyzw(
264 0,
265 (top - bottom) / 2,
266 0,
267 0),
268 cpu_vec_xyzw(
269 0,
270 0,
271 (zFar - zNear) / -2,
272 0),
273 cpu_vec_xyzw(
274 (right + left) / 2,
275 (top + bottom) / 2,
276 (zFar + zNear) / 2,
277 1)
278 );
279
280 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
281 matStack.Concat(xform, inv);
282}
283
284void glMultMatrixf(const GLfloat* m)
285{
286 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
287
288 // unfortunately we can't assume the matrix is qword-aligned
289 // the casts to float below fix an apparent parse error... something's up here..
290 cpu_mat_44 newMatrix(cpu_vec_xyzw((float)m[0], (float)m[1], (float)m[2], (float)m[3]),
291 cpu_vec_xyzw((float)m[4], (float)m[5], (float)m[6], (float)m[7]),
292 cpu_vec_xyzw((float)m[8], (float)m[9], (float)m[10], (float)m[11]),
293 cpu_vec_xyzw((float)m[12], (float)m[13], (float)m[14], (float)m[15]));
294
295 // close your eyes.. this is a temporary hack
296
297 /*
298 // assume that newMatrix consists of rotations, uniform scales, and translations
299 cpu_vec_xyzw scaledVec( 1, 0, 0, 0 );
300 scaledVec = newMatrix * scaledVec;
301 float scale = scaledVec.length();
302
303 cpu_mat_44 invMatrix = newMatrix;
304 invMatrix.set_col3( cpu_vec_xyzw(0,0,0,0) );
305 invMatrix.transpose_in_place();
306 invMatrix.set_col3( -newMatrix.get_col3() );
307 cpu_mat_44 scaleMat;
308 scaleMat.set_scale( cpu_vec_xyz(scale, scale, scale) );
309 invMatrix = scaleMat * invMatrix;
310 */
311
312 cpu_mat_44 invMatrix;
313 // invMatrix.set_identity();
314 Invert2((float*)&newMatrix, (float*)&invMatrix);
315 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
316 matStack.Concat(newMatrix, invMatrix);
317
318 // mWarn( "glMultMatrix is not correct" );
319}
320
321void glRotatef(GLfloat angle,
322 GLfloat x, GLfloat y, GLfloat z)
323{
324 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
325
326 cpu_mat_44 xform, inverse;
327 cpu_vec_xyz axis(x, y, z);
328 axis.normalize();
329 xform.set_rotate(Math::DegToRad(angle), axis);
330 inverse.set_rotate(Math::DegToRad(-angle), axis);
331
332 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
333 matStack.Concat(xform, inverse);
334}
335
336void glScalef(GLfloat x, GLfloat y, GLfloat z)
337{
338 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
339
340 cpu_mat_44 xform, inverse;
341 xform.set_scale(cpu_vec_xyz(x, y, z));
342 inverse.set_scale(cpu_vec_xyz(1.0f / x, 1.0f / y, 1.0f / z));
343
344 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
345 matStack.Concat(xform, inverse);
346}
347
348void glTranslatef(GLfloat x, GLfloat y, GLfloat z)
349{
350 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
351
352 cpu_mat_44 xform, inverse;
353 cpu_vec_xyz direction(x, y, z);
354 xform.set_translate(direction);
355 inverse.set_translate(-direction);
356
357 CMatrixStack& matStack = pGLContext->GetCurMatrixStack();
358 matStack.Concat(xform, inverse);
359}