From a17d0e5ca8ad6e5622d6ca701cdc3552e3063496 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 25 Sep 2008 12:14:20 +0000 Subject: [PATCH] glmatrix cleanup git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@2761 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/geom.h | 34 +++++++++++++-------- source/src/protos.h | 2 +- source/src/rendergl.cpp | 68 +++++++++++++++-------------------------- source/src/tools.cpp | 63 ++++++++++++++++++++++++++++++++++++++ source/src/vertmodel.h | 2 +- source/src/water.cpp | 21 +++++-------- 6 files changed, 118 insertions(+), 72 deletions(-) diff --git a/source/src/geom.h b/source/src/geom.h index 5ca5a350..6c1c540e 100644 --- a/source/src/geom.h +++ b/source/src/geom.h @@ -137,10 +137,12 @@ static inline uint hthash(const ivec &k) return k.x^k.y^k.z; } -#ifndef STANDALONE struct glmatrixf { - GLfloat v[16]; + float v[16]; + + float operator[](int i) const { return v[i]; } + float &operator[](int i) { return v[i]; } #define ROTVEC(A, B) \ { \ @@ -196,7 +198,7 @@ struct glmatrixf void identity() { - static const GLfloat m[16] = + static const float m[16] = { 1, 0, 0, 0, 0, 1, 0, 0, @@ -225,6 +227,11 @@ struct glmatrixf v[8] *= z; v[9] *= z; v[10] *= z; v[11] *= z; } + void projective() + { + loopi(2) loopj(4) v[i + j*4] = 0.5f*(v[i + j*4] + v[3 + j*4]); + } + void invertnormal(vec &dir) const { vec n(dir); @@ -244,14 +251,6 @@ struct glmatrixf pos.z = p.x*v[8] + p.y*v[9] + p.z*v[10]; } - void transform(const vec &in, vec4 &out) const - { - out.x = in.x*v[0] + in.y*v[4] + in.z*v[8] + v[12]; - out.y = in.x*v[1] + in.y*v[5] + in.z*v[9] + v[13]; - out.z = in.x*v[2] + in.y*v[6] + in.z*v[10] + v[14]; - out.w = in.x*v[3] + in.y*v[7] + in.z*v[11] + v[15]; - } - float transformx(const vec &p) const { return p.x*v[0] + p.y*v[4] + p.z*v[8] + v[12]; @@ -272,10 +271,21 @@ struct glmatrixf return p.x*v[3] + p.y*v[7] + p.z*v[11] + v[15]; } + void transform(const vec &in, vec4 &out) const + { + out.x = transformx(in); + out.y = transformy(in); + out.z = transformz(in); + out.w = transformw(in); + } + vec gettranslation() const { return vec(v[12], v[13], v[14]); } + + float determinant() const; + void adjoint(const glmatrixf &m); + bool invert(const glmatrixf &m, float mindet = 1.0e-10f); }; -#endif diff --git a/source/src/protos.h b/source/src/protos.h index d10a5f35..d06f48c4 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -203,7 +203,7 @@ extern serverinfo *getconnectedserverinfo(); extern void pingservers(); // rendergl -extern GLdouble mvmatrix[16], projmatrix[16], mvpmatrix[16], invmvmatrix[16]; +extern glmatrixf mvmatrix, projmatrix, mvpmatrix, invmvmatrix, invmvpmatrix; extern void gl_checkextensions(); extern void gl_init(int w, int h, int bpp, int depth, int fsaa); diff --git a/source/src/rendergl.cpp b/source/src/rendergl.cpp index 316f09b0..d1292dfa 100644 --- a/source/src/rendergl.cpp +++ b/source/src/rendergl.cpp @@ -144,12 +144,11 @@ void enablepolygonoffset(GLenum type) return; } - GLdouble offsetmatrix[16]; - memcpy(offsetmatrix, projmatrix, 16*sizeof(GLdouble)); + glmatrixf offsetmatrix = projmatrix; offsetmatrix[14] += depthoffset * projmatrix[10]; glMatrixMode(GL_PROJECTION); - glLoadMatrixd(offsetmatrix); + glLoadMatrixf(offsetmatrix.v); glMatrixMode(GL_MODELVIEW); } @@ -164,7 +163,7 @@ void disablepolygonoffset(GLenum type, bool restore) if(restore) { glMatrixMode(GL_PROJECTION); - glLoadMatrixd(projmatrix); + glLoadMatrixf(projmatrix.v); glMatrixMode(GL_MODELVIEW); } } @@ -510,18 +509,17 @@ void transplayer() glTranslatef(-camera1->o.x, -camera1->o.y, -camera1->o.z); } -void genclipmatrix(double a, double b, double c, double d, GLdouble matrix[16]) +void genclipmatrix(float a, float b, float c, float d, glmatrixf &matrix) { // transform the clip plane into camera space - double clip[4]; + float clip[4]; loopi(4) clip[i] = a*invmvmatrix[i*4 + 0] + b*invmvmatrix[i*4 + 1] + c*invmvmatrix[i*4 + 2] + d*invmvmatrix[i*4 + 3]; - memcpy(matrix, projmatrix, 16*sizeof(GLdouble)); - - float x = ((clip[0]<0 ? -1 : (clip[0]>0 ? 1 : 0)) + matrix[8]) / matrix[0], - y = ((clip[1]<0 ? -1 : (clip[1]>0 ? 1 : 0)) + matrix[9]) / matrix[5], - w = (1 + matrix[10]) / matrix[14], + float x = ((clip[0]<0 ? -1 : (clip[0]>0 ? 1 : 0)) + projmatrix[8]) / projmatrix[0], + y = ((clip[1]<0 ? -1 : (clip[1]>0 ? 1 : 0)) + projmatrix[9]) / projmatrix[5], + w = (1 + projmatrix[10]) / projmatrix[14], scale = 2 / (x*clip[0] + y*clip[1] - clip[2] + w*clip[3]); + matrix = projmatrix; matrix[2] = clip[0]*scale; matrix[6] = clip[1]*scale; matrix[10] = clip[2]*scale + 1.0f; @@ -599,11 +597,11 @@ void drawreflection(float hf, int w, int h, float changelod, bool refract) glScalef(1, 1, -1); } - GLdouble clipmat[16]; + glmatrixf clipmat; genclipmatrix(0, 0, -1, 0.1f*reflectclip+hf, clipmat); glMatrixMode(GL_PROJECTION); glPushMatrix(); - glLoadMatrixd(clipmat); + glLoadMatrixf(clipmat.v); glMatrixMode(GL_MODELVIEW); renderstripssky(); @@ -811,37 +809,20 @@ bool outsidemap(physent *pl) } float cursordepth = 0.9f; -GLint viewport[4]; -GLdouble mvmatrix[16], projmatrix[16], mvpmatrix[16], invmvmatrix[16]; +glmatrixf mvmatrix, projmatrix, mvpmatrix, invmvmatrix, invmvpmatrix; vec worldpos, camdir, camup, camright; void readmatrices() { - glGetIntegerv(GL_VIEWPORT, viewport); - glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix); - glGetDoublev(GL_PROJECTION_MATRIX, projmatrix); - camright = vec(float(mvmatrix[0]), float(mvmatrix[4]), float(mvmatrix[8])); - camup = vec(float(mvmatrix[1]), float(mvmatrix[5]), float(mvmatrix[9])); - camdir = vec(float(-mvmatrix[2]), float(-mvmatrix[6]), float(-mvmatrix[10])); + glGetFloatv(GL_MODELVIEW_MATRIX, mvmatrix.v); + glGetFloatv(GL_PROJECTION_MATRIX, projmatrix.v); + camright = vec(mvmatrix[0], mvmatrix[4], mvmatrix[8]); + camup = vec(mvmatrix[1], mvmatrix[5], mvmatrix[9]); + camdir = vec(-mvmatrix[2], -mvmatrix[6], -mvmatrix[10]); - loopi(4) loopj(4) - { - double c = 0; - loopk(4) c += projmatrix[k*4 + j] * mvmatrix[i*4 + k]; - mvpmatrix[i*4 + j] = c; - } - loopi(3) - { - loopj(3) invmvmatrix[i*4 + j] = mvmatrix[i + j*4]; - invmvmatrix[i*4 + 3] = 0; - } - loopi(3) - { - double c = 0; - loopj(3) c -= mvmatrix[i*4 + j] * mvmatrix[12 + j]; - invmvmatrix[12 + i] = c; - } - invmvmatrix[15] = 1; + mvpmatrix.mul(projmatrix, mvmatrix); + invmvmatrix.invert(mvmatrix); + invmvpmatrix.invert(mvpmatrix); } // stupid function to cater for stupid ATI linux drivers that return incorrect depth values @@ -860,11 +841,10 @@ float depthcorrect(float d) void readdepth(int w, int h, vec &pos) { glReadPixels(w/2, h/2, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &cursordepth); - double worldx = 0, worldy = 0, worldz = 0; - gluUnProject(w/2, h/2, depthcorrect(cursordepth), mvmatrix, projmatrix, viewport, &worldx, &worldy, &worldz); - pos.x = (float)worldx; - pos.y = (float)worldy; - pos.z = (float)worldz; + vec screen(0, 0, depthcorrect(cursordepth)*2 - 1); + vec4 world; + invmvpmatrix.transform(screen, world); + pos = vec(world.x, world.y, world.z).div(world.w); } void gl_drawframe(int w, int h, float changelod, float curfps) diff --git a/source/src/tools.cpp b/source/src/tools.cpp index 3b2365d9..6891c96f 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -296,3 +296,66 @@ bool isbigendian() return !(*((char *)(&one))); } +//////////////// geometry utils //////////////// + +static inline float det2x2(float a, float b, float c, float d) { return a*d - b*c; } +static inline float det3x3(float a1, float a2, float a3, + float b1, float b2, float b3, + float c1, float c2, float c3) +{ + return a1 * det2x2(b2, b3, c2, c3) + - b1 * det2x2(a2, a3, c2, c3) + + c1 * det2x2(a2, a3, b2, b3); +} + +float glmatrixf::determinant() const +{ + float a1 = v[0], a2 = v[1], a3 = v[2], a4 = v[3], + b1 = v[4], b2 = v[5], b3 = v[6], b4 = v[7], + c1 = v[8], c2 = v[9], c3 = v[10], c4 = v[11], + d1 = v[12], d2 = v[13], d3 = v[14], d4 = v[15]; + + return a1 * det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4) + - b1 * det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4) + + c1 * det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4) + - d1 * det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4); +} + +void glmatrixf::adjoint(const glmatrixf &m) +{ + float a1 = m.v[0], a2 = m.v[1], a3 = m.v[2], a4 = m.v[3], + b1 = m.v[4], b2 = m.v[5], b3 = m.v[6], b4 = m.v[7], + c1 = m.v[8], c2 = m.v[9], c3 = m.v[10], c4 = m.v[11], + d1 = m.v[12], d2 = m.v[13], d3 = m.v[14], d4 = m.v[15]; + + v[0] = det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4); + v[1] = -det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4); + v[2] = det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4); + v[3] = -det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4); + + v[4] = -det3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4); + v[5] = det3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4); + v[6] = -det3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4); + v[7] = det3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4); + + v[8] = det3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4); + v[9] = -det3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4); + v[10] = det3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4); + v[11] = -det3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4); + + v[12] = -det3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3); + v[13] = det3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3); + v[14] = -det3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3); + v[15] = det3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3); +} + +bool glmatrixf::invert(const glmatrixf &m, float mindet) +{ + float det = m.determinant(); + if(fabs(det) < mindet) return false; + adjoint(m); + float invdet = 1/det; + loopi(16) v[i] *= invdet; + return true; +} + diff --git a/source/src/vertmodel.h b/source/src/vertmodel.h index bdd49cc3..c6a2935d 100644 --- a/source/src/vertmodel.h +++ b/source/src/vertmodel.h @@ -446,7 +446,7 @@ struct vertmodel : model bb curbb; getcurbb(curbb, as, cur, prev, ai_t); glmatrixf mat; - mat.mul(mvpmatrix, matrixstack[matrixpos].v); + mat.mul(mvpmatrix, matrixstack[matrixpos]); if(!addshadowbox(curbb.low, curbb.high, shadowpos, mat)) return; } diff --git a/source/src/water.cpp b/source/src/water.cpp index fe9fc68b..14472fe8 100644 --- a/source/src/water.cpp +++ b/source/src/water.cpp @@ -75,13 +75,11 @@ extern int nquads; void setprojtexmatrix() { - GLdouble matrix[16]; - - memcpy(matrix, mvpmatrix, 16*sizeof(GLdouble)); - loopi(2) loopj(4) matrix[i + j*4] = 0.5f*(matrix[i + j*4] + matrix[3 + j*4]); + glmatrixf projtex = mvpmatrix; + projtex.projective(); glMatrixMode(GL_TEXTURE); - glLoadMatrixd(matrix); + glLoadMatrixf(projtex.v); } void setupmultitexrefract(GLuint reflecttex, GLuint refracttex) @@ -238,16 +236,11 @@ void calcwaterscissor() float sx1 = 1, sy1 = 1, sx2 = -1, sy2 = -1; loopi(4) { - vec p(i&1 ? wx2 : wx1, i&2 ? wy2 : wy1, hdr.waterlevel-0.3f); - float w = p.x*mvpmatrix[3] + p.y*mvpmatrix[7] + p.z*mvpmatrix[11] + mvpmatrix[15], - x = p.x*mvpmatrix[0] + p.y*mvpmatrix[4] + p.z*mvpmatrix[8] + mvpmatrix[12], - y = p.x*mvpmatrix[1] + p.y*mvpmatrix[5] + p.z*mvpmatrix[9] + mvpmatrix[13], - z = p.x*mvpmatrix[2] + p.y*mvpmatrix[6] + p.z*mvpmatrix[10] + mvpmatrix[14]; - v[i] = vec4(x, y, z, w); - if(z >= 0) + vec4 &p = v[i]; + mvpmatrix.transform(vec(i&1 ? wx2 : wx1, i&2 ? wy2 : wy1, hdr.waterlevel-0.3f), p); + if(p.z >= 0) { - x /= w; - y /= w; + float x = p.x / p.w, y = p.y / p.w; sx1 = min(sx1, x); sy1 = min(sy1, y); sx2 = max(sx2, x);