ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

matrix.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 /*
00024  * This file is based on, or a modified version of code from TinyGL (C) 1997-1998 Fabrice Bellard,
00025  * which is licensed under the zlib-license (see LICENSE).
00026  * It also has modifications by the ResidualVM-team, which are covered under the GPLv2 (or later).
00027  */
00028 
00029 #define FORBIDDEN_SYMBOL_EXCEPTION_fprintf
00030 #define FORBIDDEN_SYMBOL_EXCEPTION_stderr
00031 
00032 #include "graphics/tinygl/zgl.h"
00033 
00034 namespace TinyGL {
00035 
00036 void gl_print_matrix(const float *m) {
00037     for (int i = 0; i < 4; i++) {
00038         fprintf(stderr, "%f %f %f %f\n", m[i], m[4 + i], m[8 + i], m[12 + i]);
00039     }
00040 }
00041 
00042 static inline void gl_matrix_update(GLContext *c) {
00043     c->matrix_model_projection_updated |= (c->matrix_mode <= 1);
00044 }
00045 
00046 void glopMatrixMode(GLContext *c, GLParam *p) {
00047     int mode = p[1].i;
00048     switch (mode) {
00049     case TGL_MODELVIEW:
00050         c->matrix_mode = 0;
00051         break;
00052     case TGL_PROJECTION:
00053         c->matrix_mode = 1;
00054         break;
00055     case TGL_TEXTURE:
00056         c->matrix_mode = 2;
00057         break;
00058     default:
00059         assert(0);
00060     }
00061 }
00062 
00063 void glopLoadMatrix(GLContext *c, GLParam *p) {
00064     Matrix4 *m;
00065     GLParam *q;
00066 
00067     m = c->matrix_stack_ptr[c->matrix_mode];
00068     q = p + 1;
00069 
00070     for (int i = 0; i < 4; i++) {
00071         m->_m[0][i] = q[0].f;
00072         m->_m[1][i] = q[1].f;
00073         m->_m[2][i] = q[2].f;
00074         m->_m[3][i] = q[3].f;
00075         q += 4;
00076     }
00077 
00078     gl_matrix_update(c);
00079 }
00080 
00081 void glopLoadIdentity(GLContext *c, GLParam *) {
00082     c->matrix_stack_ptr[c->matrix_mode]->identity();
00083     gl_matrix_update(c);
00084 }
00085 
00086 void glopMultMatrix(GLContext *c, GLParam *p) {
00087     Matrix4 m;
00088     GLParam *q;
00089     q = p + 1;
00090 
00091     for (int i = 0; i < 4; i++) {
00092         m._m[0][i] = q[0].f;
00093         m._m[1][i] = q[1].f;
00094         m._m[2][i] = q[2].f;
00095         m._m[3][i] = q[3].f;
00096         q += 4;
00097     }
00098 
00099     *c->matrix_stack_ptr[c->matrix_mode] *= m;
00100 
00101     gl_matrix_update(c);
00102 }
00103 
00104 
00105 void glopPushMatrix(GLContext *c, GLParam *) {
00106     int n = c->matrix_mode;
00107     Matrix4 *m;
00108 
00109     assert((c->matrix_stack_ptr[n] - c->matrix_stack[n] + 1) < c->matrix_stack_depth_max[n]);
00110 
00111     m = ++c->matrix_stack_ptr[n];
00112 
00113     m[0] = m[-1];
00114 
00115     gl_matrix_update(c);
00116 }
00117 
00118 void glopPopMatrix(GLContext *c, GLParam *) {
00119     int n = c->matrix_mode;
00120 
00121     assert(c->matrix_stack_ptr[n] > c->matrix_stack[n]);
00122     c->matrix_stack_ptr[n]--;
00123     gl_matrix_update(c);
00124 }
00125 
00126 void glopRotate(GLContext *c, GLParam *p) {
00127     Matrix4 m;
00128     float u[3];
00129     float angle;
00130     int dir_code;
00131 
00132     angle = (float)(p[1].f * LOCAL_PI / 180.0);
00133     u[0] = p[2].f;
00134     u[1] = p[3].f;
00135     u[2] = p[4].f;
00136 
00137     // simple case detection
00138     dir_code = ((u[0] != 0) << 2) | ((u[1] != 0) << 1) | (u[2] != 0);
00139 
00140     switch (dir_code) {
00141     case 0:
00142         m.identity();
00143         break;
00144     case 4:
00145         if (u[0] < 0) angle = -angle;
00146         m.rotation(angle, 0);
00147         break;
00148     case 2:
00149         if (u[1] < 0) angle = -angle;
00150         m.rotation(angle, 1);
00151         break;
00152     case 1:
00153         if (u[2] < 0) angle = -angle;
00154         m.rotation(angle, 2);
00155         break;
00156     default: {
00157         float cost, sint;
00158 
00159         // normalize vector
00160         float len = u[0] * u[0] + u[1] * u[1] + u[2] * u[2];
00161         if (len == 0.0f)
00162             return;
00163         len = 1.0f / sqrt(len);
00164         u[0] *= len;
00165         u[1] *= len;
00166         u[2] *= len;
00167 
00168         // store cos and sin values
00169         cost = cos(angle);
00170         sint = sin(angle);
00171 
00172         // fill in the values
00173         m._m[3][0] = 0.0f;
00174         m._m[3][2] = 0.0f;
00175         m._m[0][3] = 0.0f;
00176         m._m[1][3] = 0.0f;
00177         m._m[2][3] = 0.0f;
00178         m._m[3][3] = 1.0f;
00179 
00180         // do the math
00181         m._m[0][0] = u[0] * u[0] + cost * (1 - u[0] * u[0]);
00182         m._m[1][0] = u[0] * u[1] * (1 -cost) - u[2] * sint;
00183         m._m[2][0] = u[2] * u[0] * (1 -cost) + u[1] * sint;
00184         m._m[0][1] = u[0] * u[1] * (1 -cost) + u[2] * sint;
00185         m._m[1][1] = u[1] * u[1] + cost * (1 - u[1] * u[1]);
00186         m._m[2][1] = u[1] * u[2] * (1 - cost) - u[0] * sint;
00187         m._m[0][2] = u[2] * u[0] * (1 - cost) - u[1] * sint;
00188         m._m[1][2] = u[1] * u[2] * (1 - cost) + u[0] * sint;
00189         m._m[2][2] = u[2] * u[2] + cost * (1 - u[2] * u[2]);
00190     }
00191     }
00192 
00193     *c->matrix_stack_ptr[c->matrix_mode] *= m;
00194 
00195     gl_matrix_update(c);
00196 }
00197 
00198 void glopScale(GLContext *c, GLParam *p) {
00199     c->matrix_stack_ptr[c->matrix_mode]->scale(p[1].f, p[2].f, p[3].f);
00200     gl_matrix_update(c);
00201 }
00202 
00203 void glopTranslate(GLContext *c, GLParam *p) {
00204     c->matrix_stack_ptr[c->matrix_mode]->translate(p[1].f, p[2].f, p[3].f);
00205     gl_matrix_update(c);
00206 }
00207 
00208 void glopFrustum(GLContext *c, GLParam *p) {
00209     float left = p[1].f;
00210     float right = p[2].f;
00211     float bottom = p[3].f;
00212     float top = p[4].f;
00213     float nearp = p[5].f;
00214     float farp = p[6].f;
00215     Matrix4 m = Matrix4::frustum(left, right, bottom, top, nearp, farp);
00216 
00217     *c->matrix_stack_ptr[c->matrix_mode] *= m;
00218 
00219     gl_matrix_update(c);
00220 }
00221 
00222 void glopOrtho(GLContext *context, GLParam *p) {
00223     float *r;
00224     TinyGL::Matrix4 m;
00225     float left = p[1].f;
00226     float right = p[2].f;
00227     float bottom = p[3].f;
00228     float top = p[4].f;
00229     float zNear = p[5].f;
00230     float zFar = p[6].f;
00231 
00232     float a = 2.0f / (right - left);
00233     float b = 2.0f / (top - bottom);
00234     float c = -2.0f / (zFar - zNear);
00235 
00236     float tx = -(right + left) / (right - left);
00237     float ty = -(top + bottom) / (top - bottom);
00238     float tz = -(zFar + zNear) / (zFar - zNear);
00239 
00240     r = &m._m[0][0];
00241     r[0] = a; r[1] = 0; r[2] = 0; r[3] = tx;
00242     r[4] = 0; r[5] = b; r[6] = 0; r[7] = ty;
00243     r[8] = 0; r[9] = 0; r[10] = c; r[11] = tz;
00244     r[12] = 0; r[13] = 0; r[14] = 0; r[15] = 1;
00245 
00246     *context->matrix_stack_ptr[context->matrix_mode] *= m;
00247     gl_matrix_update(context);
00248 }
00249 
00250 } // end of namespace TinyGL


Generated on Sat Dec 14 2019 05:00:47 for ResidualVM by doxygen 1.7.1
curved edge   curved edge