diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2017-01-24 07:50:10 -0900 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-01-24 09:27:38 -0900 |
commit | 149617bab9a13c60e78009734b619f1c1238cd12 (patch) | |
tree | f5574ac6d749a820a90a7b496ebc68a012493b6e | |
parent | 0b8bdbdec427a5a846d00f276dfca3e1e1aa45a3 (diff) |
Linear algebra improvements
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | inc/shared/matrix.h | 187 | ||||
-rw-r--r-- | inc/shared/shared.h | 117 | ||||
-rw-r--r-- | src/refresh/gl/gl.h | 39 | ||||
-rw-r--r-- | src/refresh/gl/main.c | 69 | ||||
-rw-r--r-- | src/refresh/gl/mesh.c | 71 | ||||
-rw-r--r-- | src/refresh/gl/state.c | 110 | ||||
-rw-r--r-- | src/refresh/gl/tess.c | 7 | ||||
-rw-r--r-- | src/refresh/gl/world.c | 15 | ||||
-rw-r--r-- | src/shared/matrix.c | 83 | ||||
-rw-r--r-- | src/shared/shared.c | 70 |
12 files changed, 421 insertions, 363 deletions
@@ -8,3 +8,5 @@ game*.so cscope.* tags .* +*.o +*.d @@ -148,6 +148,7 @@ COMMON_OBJS := \ src/common/sizebuf.o \ src/common/utils.o \ src/common/zone.o \ + src/shared/matrix.o \ src/shared/shared.o OBJS_c := \ @@ -199,6 +200,7 @@ OBJS_s := \ src/server/world.o OBJS_g := \ + src/shared/matrix.o \ src/shared/shared.o \ src/shared/m_flash.o \ src/baseq2/g_ai.o \ @@ -617,6 +619,18 @@ BUILD_s := .q2proded BUILD_c := .q2pro BUILD_g := .baseq2 +$(OBJS_s): CFLAGS+=$(CFLAGS_s) +$(OBJS_c): CFLAGS+=$(CFLAGS_c) +$(OBJS_g): CFLAGS+=$(CFLAGS_g) + +DEPS_s := $(OBJS_s:.o=.d) +DEPS_c := $(OBJS_c:.o=.d) +DEPS_g := $(OBJS_g:.o=.d) + +-include $(DEPS_s) +-include $(DEPS_c) +-include $(DEPS_g) + # Rewrite paths to build directories OBJS_s := $(patsubst %,$(BUILD_s)/%,$(OBJS_s)) OBJS_c := $(patsubst %,$(BUILD_c)/%,$(OBJS_c)) diff --git a/inc/shared/matrix.h b/inc/shared/matrix.h new file mode 100644 index 0000000..b106d8c --- /dev/null +++ b/inc/shared/matrix.h @@ -0,0 +1,187 @@ +#ifndef _Q_MATRIX_H +#define _Q_MATRIX_H + +/* Linear algebra - vectors and matrices: */ + +typedef float vec_t; +typedef vec_t vec2_t[2]; +typedef vec_t vec3_t[3]; +typedef vec_t vec4_t[4]; +typedef vec_t vec5_t[5]; + +typedef struct { + union { + vec_t i[3][3]; + vec_t array[9]; + }; +} mat3_t; + +typedef struct { + union { + vec_t i[4][4]; + vec_t flat[16]; + }; +} mat4_t; + +#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) + +#define CrossProduct(v1,v2,cross) \ + ((cross)[0]=(v1)[1]*(v2)[2]-(v1)[2]*(v2)[1], \ + (cross)[1]=(v1)[2]*(v2)[0]-(v1)[0]*(v2)[2], \ + (cross)[2]=(v1)[0]*(v2)[1]-(v1)[1]*(v2)[0]) + +#define VectorSubtract(a,b,c) \ + ((c)[0]=(a)[0]-(b)[0], \ + (c)[1]=(a)[1]-(b)[1], \ + (c)[2]=(a)[2]-(b)[2]) + +#define VectorAdd(a,b,c) \ + ((c)[0]=(a)[0]+(b)[0], \ + (c)[1]=(a)[1]+(b)[1], \ + (c)[2]=(a)[2]+(b)[2]) + +#define VectorAdd3(a,b,c,d) \ + ((d)[0]=(a)[0]+(b)[0]+(c)[0], \ + (d)[1]=(a)[1]+(b)[1]+(c)[1], \ + (d)[2]=(a)[2]+(b)[2]+(c)[2]) + +#define VectorCopy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2]) +#define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0) +#define VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2]) +#define VectorInverse(a) ((a)[0]=-(a)[0],(a)[1]=-(a)[1],(a)[2]=-(a)[2]) +#define VectorSet(v, x, y, z) ((v)[0]=(x),(v)[1]=(y),(v)[2]=(z)) +#define VectorAvg(a,b,c) \ + ((c)[0]=((a)[0]+(b)[0])*0.5f, \ + (c)[1]=((a)[1]+(b)[1])*0.5f, \ + (c)[2]=((a)[2]+(b)[2])*0.5f) +#define VectorMA(a,b,c,d) \ + ((d)[0]=(a)[0]+(b)*(c)[0], \ + (d)[1]=(a)[1]+(b)*(c)[1], \ + (d)[2]=(a)[2]+(b)*(c)[2]) +#define VectorVectorMA(a,b,c,d) \ + ((d)[0]=(a)[0]+(b)[0]*(c)[0], \ + (d)[1]=(a)[1]+(b)[1]*(c)[1], \ + (d)[2]=(a)[2]+(b)[2]*(c)[2]) +#define VectorEmpty(v) ((v)[0]==0&&(v)[1]==0&&(v)[2]==0) +#define VectorCompare(v1,v2) ((v1)[0]==(v2)[0]&&(v1)[1]==(v2)[1]&&(v1)[2]==(v2)[2]) +#define VectorLength(v) (sqrt(DotProduct((v),(v)))) +#define VectorLengthSquared(v) (DotProduct((v),(v))) +#define VectorScale(in,scale,out) \ + ((out)[0]=(in)[0]*(scale), \ + (out)[1]=(in)[1]*(scale), \ + (out)[2]=(in)[2]*(scale)) +#define VectorVectorScale(in,scale,out) \ + ((out)[0]=(in)[0]*(scale)[0], \ + (out)[1]=(in)[1]*(scale)[1], \ + (out)[2]=(in)[2]*(scale)[2]) +#define DistanceSquared(v1,v2) \ + (((v1)[0]-(v2)[0])*((v1)[0]-(v2)[0])+ \ + ((v1)[1]-(v2)[1])*((v1)[1]-(v2)[1])+ \ + ((v1)[2]-(v2)[2])*((v1)[2]-(v2)[2])) +#define Distance(v1,v2) (sqrt(DistanceSquared(v1,v2))) +#define LerpAngles(a,b,c,d) \ + ((d)[0]=LerpAngle((a)[0],(b)[0],c), \ + (d)[1]=LerpAngle((a)[1],(b)[1],c), \ + (d)[2]=LerpAngle((a)[2],(b)[2],c)) +#define LerpVector(a,b,c,d) \ + ((d)[0]=(a)[0]+(c)*((b)[0]-(a)[0]), \ + (d)[1]=(a)[1]+(c)*((b)[1]-(a)[1]), \ + (d)[2]=(a)[2]+(c)*((b)[2]-(a)[2])) +#define LerpVector2(a,b,c,d,e) \ + ((e)[0]=(a)[0]*(c)+(b)[0]*(d), \ + (e)[1]=(a)[1]*(c)+(b)[1]*(d), \ + (e)[2]=(a)[2]*(c)+(b)[2]*(d)) +#define PlaneDiff(v,p) (DotProduct(v,(p)->normal)-(p)->dist) + +#define Vector4Subtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2],(c)[3]=(a)[3]-(b)[3]) +#define Vector4Add(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2],(c)[3]=(a)[3]+(b)[3]) +#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) +#define Vector4Clear(a) ((a)[0]=(a)[1]=(a)[2]=(a)[3]=0) +#define Vector4Negate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2],(b)[3]=-(a)[3]) +#define Vector4Set(v, a, b, c, d) ((v)[0]=(a),(v)[1]=(b),(v)[2]=(c),(v)[3]=(d)) + +void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); +vec_t VectorNormalize(vec3_t v); // returns vector length +vec_t VectorNormalize2(vec3_t v, vec3_t out); +mat4_t mul_mat4(const mat4_t *restrict a, const mat4_t *restrict b); + +static inline void AnglesToAxis(vec3_t angles, vec3_t axis[3]) +{ + AngleVectors(angles, axis[0], axis[1], axis[2]); + VectorInverse(axis[1]); +} + +static inline void TransposeAxis(vec3_t axis[3]) +{ + vec_t temp; + + temp = axis[0][1]; + axis[0][1] = axis[1][0]; + axis[1][0] = temp; + + temp = axis[0][2]; + axis[0][2] = axis[2][0]; + axis[2][0] = temp; + + temp = axis[1][2]; + axis[1][2] = axis[2][1]; + axis[2][1] = temp; +} + +static inline void RotatePoint(vec3_t point, vec3_t axis[3]) +{ + vec3_t temp; + + VectorCopy(point, temp); + point[0] = DotProduct(temp, axis[0]); + point[1] = DotProduct(temp, axis[1]); + point[2] = DotProduct(temp, axis[2]); +} + +static inline mat3_t vec3_to_mat3(vec3_t v0, vec3_t v1, vec3_t v2) +{ + return (mat3_t) { + .i = { + [0][0] = v0[0], + [0][1] = v0[1], + [0][2] = v0[2], + + [1][0] = v1[0], + [1][1] = v1[1], + [1][2] = v1[2], + + [2][0] = v2[0], + [2][1] = v2[1], + [2][2] = v2[2], + }, + }; +} + +static inline mat4_t AffineMatrix(mat3_t m, vec3_t v) +{ + mat4_t a; + + for (unsigned i = 0; i < 3; i++) { + for (unsigned j = 0; j < 3; j++) + a.i[i][j] = m.i[i][j]; + + a.i[3][i] = v[i]; + } + + a.i[0][3] = 0; + a.i[1][3] = 0; + a.i[2][3] = 0; + a.i[3][3] = 1; + + return a; +} + +static const mat3_t mat3_identity = { + .i = { + [0][0] = 1, + [1][1] = 1, + [2][2] = 1, + } +}; + +#endif /* _Q_MATRIX_H */ diff --git a/inc/shared/shared.h b/inc/shared/shared.h index 372c792..d6633b2 100644 --- a/inc/shared/shared.h +++ b/inc/shared/shared.h @@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #endif #include "shared/platform.h" +#include "shared/matrix.h" #define q_countof(a) (sizeof(a) / sizeof(a[0])) @@ -131,14 +132,6 @@ MATHLIB ============================================================== */ -typedef float vec_t; -typedef vec_t vec2_t[2]; -typedef vec_t vec3_t[3]; -typedef vec_t vec4_t[4]; -typedef vec_t vec5_t[5]; - -typedef float mat4_t[16]; - typedef union { uint32_t u32; uint8_t u8[4]; @@ -181,119 +174,11 @@ static inline float Q_fabs(float f) #define DEG2RAD(a) (a * M_PI) / 180.0F -#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) -#define CrossProduct(v1,v2,cross) \ - ((cross)[0]=(v1)[1]*(v2)[2]-(v1)[2]*(v2)[1], \ - (cross)[1]=(v1)[2]*(v2)[0]-(v1)[0]*(v2)[2], \ - (cross)[2]=(v1)[0]*(v2)[1]-(v1)[1]*(v2)[0]) -#define VectorSubtract(a,b,c) \ - ((c)[0]=(a)[0]-(b)[0], \ - (c)[1]=(a)[1]-(b)[1], \ - (c)[2]=(a)[2]-(b)[2]) -#define VectorAdd(a,b,c) \ - ((c)[0]=(a)[0]+(b)[0], \ - (c)[1]=(a)[1]+(b)[1], \ - (c)[2]=(a)[2]+(b)[2]) -#define VectorAdd3(a,b,c,d) \ - ((d)[0]=(a)[0]+(b)[0]+(c)[0], \ - (d)[1]=(a)[1]+(b)[1]+(c)[1], \ - (d)[2]=(a)[2]+(b)[2]+(c)[2]) -#define VectorCopy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2]) -#define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0) -#define VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2]) -#define VectorInverse(a) ((a)[0]=-(a)[0],(a)[1]=-(a)[1],(a)[2]=-(a)[2]) -#define VectorSet(v, x, y, z) ((v)[0]=(x),(v)[1]=(y),(v)[2]=(z)) -#define VectorAvg(a,b,c) \ - ((c)[0]=((a)[0]+(b)[0])*0.5f, \ - (c)[1]=((a)[1]+(b)[1])*0.5f, \ - (c)[2]=((a)[2]+(b)[2])*0.5f) -#define VectorMA(a,b,c,d) \ - ((d)[0]=(a)[0]+(b)*(c)[0], \ - (d)[1]=(a)[1]+(b)*(c)[1], \ - (d)[2]=(a)[2]+(b)*(c)[2]) -#define VectorVectorMA(a,b,c,d) \ - ((d)[0]=(a)[0]+(b)[0]*(c)[0], \ - (d)[1]=(a)[1]+(b)[1]*(c)[1], \ - (d)[2]=(a)[2]+(b)[2]*(c)[2]) -#define VectorEmpty(v) ((v)[0]==0&&(v)[1]==0&&(v)[2]==0) -#define VectorCompare(v1,v2) ((v1)[0]==(v2)[0]&&(v1)[1]==(v2)[1]&&(v1)[2]==(v2)[2]) -#define VectorLength(v) (sqrt(DotProduct((v),(v)))) -#define VectorLengthSquared(v) (DotProduct((v),(v))) -#define VectorScale(in,scale,out) \ - ((out)[0]=(in)[0]*(scale), \ - (out)[1]=(in)[1]*(scale), \ - (out)[2]=(in)[2]*(scale)) -#define VectorVectorScale(in,scale,out) \ - ((out)[0]=(in)[0]*(scale)[0], \ - (out)[1]=(in)[1]*(scale)[1], \ - (out)[2]=(in)[2]*(scale)[2]) -#define DistanceSquared(v1,v2) \ - (((v1)[0]-(v2)[0])*((v1)[0]-(v2)[0])+ \ - ((v1)[1]-(v2)[1])*((v1)[1]-(v2)[1])+ \ - ((v1)[2]-(v2)[2])*((v1)[2]-(v2)[2])) -#define Distance(v1,v2) (sqrt(DistanceSquared(v1,v2))) -#define LerpAngles(a,b,c,d) \ - ((d)[0]=LerpAngle((a)[0],(b)[0],c), \ - (d)[1]=LerpAngle((a)[1],(b)[1],c), \ - (d)[2]=LerpAngle((a)[2],(b)[2],c)) -#define LerpVector(a,b,c,d) \ - ((d)[0]=(a)[0]+(c)*((b)[0]-(a)[0]), \ - (d)[1]=(a)[1]+(c)*((b)[1]-(a)[1]), \ - (d)[2]=(a)[2]+(c)*((b)[2]-(a)[2])) -#define LerpVector2(a,b,c,d,e) \ - ((e)[0]=(a)[0]*(c)+(b)[0]*(d), \ - (e)[1]=(a)[1]*(c)+(b)[1]*(d), \ - (e)[2]=(a)[2]*(c)+(b)[2]*(d)) -#define PlaneDiff(v,p) (DotProduct(v,(p)->normal)-(p)->dist) - -#define Vector4Subtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2],(c)[3]=(a)[3]-(b)[3]) -#define Vector4Add(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2],(c)[3]=(a)[3]+(b)[3]) -#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) -#define Vector4Clear(a) ((a)[0]=(a)[1]=(a)[2]=(a)[3]=0) -#define Vector4Negate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2],(b)[3]=-(a)[3]) -#define Vector4Set(v, a, b, c, d) ((v)[0]=(a),(v)[1]=(b),(v)[2]=(c),(v)[3]=(d)) - -void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); -vec_t VectorNormalize(vec3_t v); // returns vector length -vec_t VectorNormalize2(vec3_t v, vec3_t out); void ClearBounds(vec3_t mins, vec3_t maxs); void AddPointToBounds(const vec3_t v, vec3_t mins, vec3_t maxs); vec_t RadiusFromBounds(const vec3_t mins, const vec3_t maxs); void UnionBounds(vec3_t a[2], vec3_t b[2], vec3_t c[2]); -static inline void AnglesToAxis(vec3_t angles, vec3_t axis[3]) -{ - AngleVectors(angles, axis[0], axis[1], axis[2]); - VectorInverse(axis[1]); -} - -static inline void TransposeAxis(vec3_t axis[3]) -{ - vec_t temp; - - temp = axis[0][1]; - axis[0][1] = axis[1][0]; - axis[1][0] = temp; - - temp = axis[0][2]; - axis[0][2] = axis[2][0]; - axis[2][0] = temp; - - temp = axis[1][2]; - axis[1][2] = axis[2][1]; - axis[2][1] = temp; -} - -static inline void RotatePoint(vec3_t point, vec3_t axis[3]) -{ - vec3_t temp; - - VectorCopy(point, temp); - point[0] = DotProduct(temp, axis[0]); - point[1] = DotProduct(temp, axis[1]); - point[2] = DotProduct(temp, axis[2]); -} - static inline unsigned npot32(unsigned k) { if (k == 0) diff --git a/src/refresh/gl/gl.h b/src/refresh/gl/gl.h index 7cfd149..ac04d9a 100644 --- a/src/refresh/gl/gl.h +++ b/src/refresh/gl/gl.h @@ -57,7 +57,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #define NUM_TEXNUMS 6 typedef struct { - qboolean registering; struct { bsp_t *cache; memhunk_t hunk; @@ -79,20 +78,40 @@ typedef struct { typedef struct { refdef_t fd; + /* initialized by R_RenderFrame() -> GL_Setup3D() from fd.viewangles */ vec3_t viewaxis[3]; - GLfloat viewmatrix[16]; + mat4_t viewmatrix; + + /* + * incremented every time we draw the world + * R_RenderFrame() -> GL_DrawWorld() -> GL_MarkLeaves() + */ int visframe; + + /* incremented every time we draw a frame in R_RenderFrame() */ int drawframe; + #if USE_DLIGHTS + /* another counter, incremented by GL_MarkLights() and * GL_TransformLights() */ int dlightframe; #endif + + /* some sort of dirtyness - related to where we are in the BSP */ int viewcluster1; int viewcluster2; + + /* initialized by R_RenderFrame -> GL_SetupFrustrum() */ cplane_t frustumPlanes[4]; + + /* entity we're currently drawing: */ entity_t *ent; qboolean entrotated; - vec3_t entaxis[3]; - GLfloat entmatrix[16]; + + mat3_t entaxis; + + /* initialized by GL_RotateForEntity() */ + mat4_t entmatrix; + lightpoint_t lightpoint; int num_beams; } glRefdef_t; @@ -100,8 +119,8 @@ typedef struct { typedef struct { qboolean es_profile; - int version_major; - int version_minor; + int version_major; + int version_minor; unsigned ext_supported; unsigned ext_enabled; @@ -202,7 +221,6 @@ glCullResult_t GL_CullLocalBox(const vec3_t origin, vec3_t bounds[2]); qboolean GL_AllocBlock(int width, int height, int *inuse, int w, int h, int *s, int *t); -void GL_MultMatrix(GLfloat *out, const GLfloat *a, const GLfloat *b); void GL_RotateForEntity(vec3_t origin); void GL_ClearErrors(void); @@ -310,7 +328,7 @@ typedef struct { GLuint texnums[MAX_TMUS]; glStateBits_t state_bits; glArrayBits_t array_bits; - const GLfloat *currentmatrix; + const mat4_t *currentmatrix; } glState_t; extern glState_t gls; @@ -372,10 +390,10 @@ static inline void GL_UnlockArrays(void) } } -static inline void GL_LoadMatrix(const GLfloat *matrix) +static inline void GL_LoadMatrix(const mat4_t *matrix) { if (gls.currentmatrix != matrix) { - qglLoadMatrixf(matrix); + qglLoadMatrixf(matrix->flat); gls.currentmatrix = matrix; } } @@ -384,7 +402,6 @@ void GL_ForceTexture(GLuint tmu, GLuint texnum); void GL_BindTexture(GLuint tmu, GLuint texnum); void GL_StateBits(glStateBits_t bits); void GL_ArrayBits(glArrayBits_t bits); -void GL_LoadMatrix(const GLfloat *matrix); void GL_Ortho(GLfloat xmin, GLfloat xmax, GLfloat ymin, GLfloat ymax, GLfloat znear, GLfloat zfar); void GL_Setup2D(void); void GL_Setup3D(void); diff --git a/src/refresh/gl/main.c b/src/refresh/gl/main.c index 2f5c6e2..b6df338 100644 --- a/src/refresh/gl/main.c +++ b/src/refresh/gl/main.c @@ -176,11 +176,10 @@ static inline void make_box_points(const vec3_t origin, for (i = 0; i < 8; i++) { VectorCopy(origin, points[i]); - VectorMA(points[i], bounds[(i >> 0) & 1][0], glr.entaxis[0], points[i]); - VectorMA(points[i], bounds[(i >> 1) & 1][1], glr.entaxis[1], points[i]); - VectorMA(points[i], bounds[(i >> 2) & 1][2], glr.entaxis[2], points[i]); + VectorMA(points[i], bounds[(i >> 0) & 1][0], glr.entaxis.i[0], points[i]); + VectorMA(points[i], bounds[(i >> 1) & 1][1], glr.entaxis.i[1], points[i]); + VectorMA(points[i], bounds[(i >> 2) & 1][2], glr.entaxis.i[2], points[i]); } - } glCullResult_t GL_CullLocalBox(const vec3_t origin, vec3_t bounds[2]) @@ -287,51 +286,15 @@ qboolean GL_AllocBlock(int width, int height, int *inuse, return qtrue; } -// P = A * B -void GL_MultMatrix(GLfloat *p, const GLfloat *a, const GLfloat *b) -{ - int i, j; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - p[i * 4 + j] = - a[0 * 4 + j] * b[i * 4 + 0] + - a[1 * 4 + j] * b[i * 4 + 1] + - a[2 * 4 + j] * b[i * 4 + 2] + - a[3 * 4 + j] * b[i * 4 + 3]; - } - } -} - void GL_RotateForEntity(vec3_t origin) { - GLfloat matrix[16]; - - matrix[0] = glr.entaxis[0][0]; - matrix[4] = glr.entaxis[1][0]; - matrix[8] = glr.entaxis[2][0]; - matrix[12] = origin[0]; - - matrix[1] = glr.entaxis[0][1]; - matrix[5] = glr.entaxis[1][1]; - matrix[9] = glr.entaxis[2][1]; - matrix[13] = origin[1]; - - matrix[2] = glr.entaxis[0][2]; - matrix[6] = glr.entaxis[1][2]; - matrix[10] = glr.entaxis[2][2]; - matrix[14] = origin[2]; - - matrix[3] = 0; - matrix[7] = 0; - matrix[11] = 0; - matrix[15] = 1; + mat4_t m = AffineMatrix(glr.entaxis, origin); - GL_MultMatrix(glr.entmatrix, glr.viewmatrix, matrix); - qglLoadMatrixf(glr.entmatrix); + glr.entmatrix = mul_mat4(&glr.viewmatrix, &m); // forced matrix upload - gls.currentmatrix = glr.entmatrix; + qglLoadMatrixf(glr.entmatrix.flat); + gls.currentmatrix = &glr.entmatrix; } static void GL_DrawSpriteModel(model_t *model) @@ -357,7 +320,7 @@ static void GL_DrawSpriteModel(model_t *model) bits |= GLS_BLEND_BLEND; } - GL_LoadMatrix(glr.viewmatrix); + GL_LoadMatrix(&glr.viewmatrix); GL_BindTexture(0, image->texnum); GL_StateBits(bits); GL_ArrayBits(GLA_VERTEX | GLA_TC); @@ -392,11 +355,11 @@ static void GL_DrawNullModel(void) VectorCopy(e->origin, points[2]); VectorCopy(e->origin, points[4]); - VectorMA(e->origin, 16, glr.entaxis[0], points[1]); - VectorMA(e->origin, 16, glr.entaxis[1], points[3]); - VectorMA(e->origin, 16, glr.entaxis[2], points[5]); + VectorMA(e->origin, 16, glr.entaxis.i[0], points[1]); + VectorMA(e->origin, 16, glr.entaxis.i[1], points[3]); + VectorMA(e->origin, 16, glr.entaxis.i[2], points[5]); - GL_LoadMatrix(glr.viewmatrix); + GL_LoadMatrix(&glr.viewmatrix); GL_BindTexture(0, TEXNUM_WHITE); GL_StateBits(GLS_DEFAULT); GL_ArrayBits(GLA_VERTEX | GLA_COLOR); @@ -430,12 +393,10 @@ static void GL_DrawEntities(int mask) // convert angles to axis if (VectorEmpty(ent->angles)) { glr.entrotated = qfalse; - VectorSet(glr.entaxis[0], 1, 0, 0); - VectorSet(glr.entaxis[1], 0, 1, 0); - VectorSet(glr.entaxis[2], 0, 0, 1); + glr.entaxis = mat3_identity; } else { glr.entrotated = qtrue; - AnglesToAxis(ent->angles, glr.entaxis); + AnglesToAxis(ent->angles, glr.entaxis.i); } // inline BSP model @@ -1096,7 +1057,6 @@ void R_BeginRegistration(const char *name) { char fullname[MAX_QPATH]; - gl_static.registering = qtrue; registration_sequence++; memset(&glr, 0, sizeof(glr)); @@ -1116,7 +1076,6 @@ void R_EndRegistration(void) IMG_FreeUnused(); MOD_FreeUnused(); Scrap_Upload(); - gl_static.registering = qfalse; } /* diff --git a/src/refresh/gl/mesh.c b/src/refresh/gl/mesh.c index c10ab45..1396cc6 100644 --- a/src/refresh/gl/mesh.c +++ b/src/refresh/gl/mesh.c @@ -37,7 +37,7 @@ static vec3_t shadedir; static float celscale; -static GLfloat shadowmatrix[16]; +static mat4_t shadowmatrix; static void setup_dotshading(void) { @@ -439,11 +439,11 @@ static void draw_celshading(maliasmesh_t *mesh) static void setup_shadow(void) { - GLfloat matrix[16], tmp[16]; + mat4_t m, tmp; cplane_t *plane; vec3_t dir; - shadowmatrix[15] = 0; + shadowmatrix.i[3][3] = 0; if (!gl_shadows->integer) return; @@ -463,59 +463,41 @@ static void setup_shadow(void) // project shadow on ground plane plane = &glr.lightpoint.plane; - matrix[0] = plane->normal[1] * dir[1] + plane->normal[2] * dir[2]; - matrix[4] = -plane->normal[1] * dir[0]; - matrix[8] = -plane->normal[2] * dir[0]; - matrix[12] = plane->dist * dir[0]; + /* XXX what operation is this? */ + m.i[0][0] = plane->normal[1] * dir[1] + plane->normal[2] * dir[2]; + m.i[1][0] = -plane->normal[1] * dir[0]; + m.i[2][0] = -plane->normal[2] * dir[0]; + m.i[3][0] = plane->dist * dir[0]; - matrix[1] = -plane->normal[0] * dir[1]; - matrix[5] = plane->normal[0] * dir[0] + plane->normal[2] * dir[2]; - matrix[9] = -plane->normal[2] * dir[1]; - matrix[13] = plane->dist * dir[1]; + m.i[0][1] = -plane->normal[0] * dir[1]; + m.i[1][1] = plane->normal[0] * dir[0] + plane->normal[2] * dir[2]; + m.i[2][1] = -plane->normal[2] * dir[1]; + m.i[3][1] = plane->dist * dir[1]; - matrix[2] = -plane->normal[0] * dir[2]; - matrix[6] = -plane->normal[1] * dir[2]; - matrix[10] = plane->normal[0] * dir[0] + plane->normal[1] * dir[1]; - matrix[14] = plane->dist * dir[2]; + m.i[0][2] = -plane->normal[0] * dir[2]; + m.i[1][2] = -plane->normal[1] * dir[2]; + m.i[2][2] = plane->normal[0] * dir[0] + plane->normal[1] * dir[1]; + m.i[3][2] = plane->dist * dir[2]; - matrix[3] = 0; - matrix[7] = 0; - matrix[11] = 0; - matrix[15] = DotProduct(plane->normal, dir); + m.i[0][3] = 0; + m.i[1][3] = 0; + m.i[2][3] = 0; + m.i[3][3] = DotProduct(plane->normal, dir); - GL_MultMatrix(tmp, glr.viewmatrix, matrix); + tmp = mul_mat4(&glr.viewmatrix, &m); // rotate for entity - matrix[0] = glr.entaxis[0][0]; - matrix[4] = glr.entaxis[1][0]; - matrix[8] = glr.entaxis[2][0]; - matrix[12] = origin[0]; - - matrix[1] = glr.entaxis[0][1]; - matrix[5] = glr.entaxis[1][1]; - matrix[9] = glr.entaxis[2][1]; - matrix[13] = origin[1]; - - matrix[2] = glr.entaxis[0][2]; - matrix[6] = glr.entaxis[1][2]; - matrix[10] = glr.entaxis[2][2]; - matrix[14] = origin[2]; - - matrix[3] = 0; - matrix[7] = 0; - matrix[11] = 0; - matrix[15] = 1; - - GL_MultMatrix(shadowmatrix, tmp, matrix); + m = AffineMatrix(glr.entaxis, origin); + shadowmatrix = mul_mat4(&tmp, &m); } static void draw_shadow(maliasmesh_t *mesh) { - if (shadowmatrix[15] < 0.5f) + if (shadowmatrix.i[3][3] < 0.5f) return; // load shadow projection matrix - GL_LoadMatrix(shadowmatrix); + GL_LoadMatrix(&shadowmatrix); // eliminate z-fighting by utilizing stencil buffer, if available if (gl_config.stencilbits) { @@ -573,7 +555,7 @@ static void draw_alias_mesh(maliasmesh_t *mesh) glStateBits_t state = GLS_DEFAULT; // fall back to entity matrix - GL_LoadMatrix(glr.entmatrix); + GL_LoadMatrix(&glr.entmatrix); if (shadelight) state |= GLS_SHADE_SMOOTH; @@ -708,4 +690,3 @@ void GL_DrawAliasModel(model_t *model) qglFrontFace(GL_CW); } } - diff --git a/src/refresh/gl/state.c b/src/refresh/gl/state.c index 996a81f..fd44682 100644 --- a/src/refresh/gl/state.c +++ b/src/refresh/gl/state.c @@ -230,34 +230,34 @@ void GL_ArrayBits(glArrayBits_t bits) void GL_Ortho(GLfloat xmin, GLfloat xmax, GLfloat ymin, GLfloat ymax, GLfloat znear, GLfloat zfar) { GLfloat width, height, depth; - GLfloat matrix[16]; + mat4_t m; width = xmax - xmin; height = ymax - ymin; depth = zfar - znear; - matrix[0] = 2 / width; - matrix[4] = 0; - matrix[8] = 0; - matrix[12] = -(xmax + xmin) / width; + m.i[0][0] = 2 / width; + m.i[1][0] = 0; + m.i[2][0] = 0; + m.i[3][0] = -(xmax + xmin) / width; - matrix[1] = 0; - matrix[5] = 2 / height; - matrix[9] = 0; - matrix[13] = -(ymax + ymin) / height; + m.i[0][1] = 0; + m.i[1][1] = 2 / height; + m.i[2][1] = 0; + m.i[3][1] = -(ymax + ymin) / height; - matrix[2] = 0; - matrix[6] = 0; - matrix[10] = -2 / depth; - matrix[14] = -(zfar + znear) / depth; + m.i[0][2] = 0; + m.i[2][2] = 0; + m.i[2][2] = -2 / depth; + m.i[3][2] = -(zfar + znear) / depth; - matrix[3] = 0; - matrix[7] = 0; - matrix[11] = 0; - matrix[15] = 1; + m.i[0][3] = 0; + m.i[1][3] = 0; + m.i[2][3] = 0; + m.i[3][3] = 1; qglMatrixMode(GL_PROJECTION); - qglLoadMatrixf(matrix); + qglLoadMatrixf(m.flat); } void GL_Setup2D(void) @@ -283,7 +283,7 @@ static void GL_Frustum(void) { GLfloat xmin, xmax, ymin, ymax, zfar, znear; GLfloat width, height, depth; - GLfloat matrix[16]; + mat4_t m; znear = gl_znear->value; @@ -302,61 +302,61 @@ static void GL_Frustum(void) height = ymax - ymin; depth = zfar - znear; - matrix[0] = 2 * znear / width; - matrix[4] = 0; - matrix[8] = (xmax + xmin) / width; - matrix[12] = 0; + m.i[0][0] = 2 * znear / width; + m.i[1][0] = 0; + m.i[2][0] = (xmax + xmin) / width; + m.i[3][0] = 0; - matrix[1] = 0; - matrix[5] = 2 * znear / height; - matrix[9] = (ymax + ymin) / height; - matrix[13] = 0; + m.i[0][1] = 0; + m.i[1][1] = 2 * znear / height; + m.i[2][1] = (ymax + ymin) / height; + m.i[3][1] = 0; - matrix[2] = 0; - matrix[6] = 0; - matrix[10] = -(zfar + znear) / depth; - matrix[14] = -2 * zfar * znear / depth; + m.i[0][2] = 0; + m.i[1][2] = 0; + m.i[2][2] = -(zfar + znear) / depth; + m.i[3][2] = -2 * zfar * znear / depth; - matrix[3] = 0; - matrix[7] = 0; - matrix[11] = -1; - matrix[15] = 0; + m.i[0][3] = 0; + m.i[1][3] = 0; + m.i[2][3] = -1; + m.i[3][3] = 0; qglMatrixMode(GL_PROJECTION); - qglLoadMatrixf(matrix); + qglLoadMatrixf(m.flat); } static void GL_RotateForViewer(void) { - GLfloat *matrix = glr.viewmatrix; + mat4_t *m = &glr.viewmatrix; AnglesToAxis(glr.fd.viewangles, glr.viewaxis); - matrix[0] = -glr.viewaxis[1][0]; - matrix[4] = -glr.viewaxis[1][1]; - matrix[8] = -glr.viewaxis[1][2]; - matrix[12] = DotProduct(glr.viewaxis[1], glr.fd.vieworg); + m->i[0][0] = -glr.viewaxis[1][0]; + m->i[1][0] = -glr.viewaxis[1][1]; + m->i[2][0] = -glr.viewaxis[1][2]; + m->i[3][0] = DotProduct(glr.viewaxis[1], glr.fd.vieworg); - matrix[1] = glr.viewaxis[2][0]; - matrix[5] = glr.viewaxis[2][1]; - matrix[9] = glr.viewaxis[2][2]; - matrix[13] = -DotProduct(glr.viewaxis[2], glr.fd.vieworg); + m->i[0][1] = glr.viewaxis[2][0]; + m->i[1][1] = glr.viewaxis[2][1]; + m->i[2][1] = glr.viewaxis[2][2]; + m->i[3][1] = -DotProduct(glr.viewaxis[2], glr.fd.vieworg); - matrix[2] = -glr.viewaxis[0][0]; - matrix[6] = -glr.viewaxis[0][1]; - matrix[10] = -glr.viewaxis[0][2]; - matrix[14] = DotProduct(glr.viewaxis[0], glr.fd.vieworg); + m->i[0][2] = -glr.viewaxis[0][0]; + m->i[1][2] = -glr.viewaxis[0][1]; + m->i[2][2] = -glr.viewaxis[0][2]; + m->i[3][2] = DotProduct(glr.viewaxis[0], glr.fd.vieworg); - matrix[3] = 0; - matrix[7] = 0; - matrix[11] = 0; - matrix[15] = 1; + m->i[0][3] = 0; + m->i[1][3] = 0; + m->i[2][3] = 0; + m->i[3][3] = 1; qglMatrixMode(GL_MODELVIEW); - qglLoadMatrixf(matrix); + qglLoadMatrixf(m->flat); // forced matrix upload - gls.currentmatrix = matrix; + gls.currentmatrix = m; } void GL_Setup3D(void) diff --git a/src/refresh/gl/tess.c b/src/refresh/gl/tess.c index 56cd3bc..f61e2b1 100644 --- a/src/refresh/gl/tess.c +++ b/src/refresh/gl/tess.c @@ -96,7 +96,7 @@ void GL_DrawParticles(void) else blend = GLS_BLEND_BLEND; - GL_LoadMatrix(glr.viewmatrix); + GL_LoadMatrix(&glr.viewmatrix); GL_VertexPointer(3, 5, tess.vertices); GL_TexCoordPointer(2, 5, tess.vertices + 3); @@ -179,7 +179,7 @@ void GL_DrawBeams(void) return; } - GL_LoadMatrix(glr.viewmatrix); + GL_LoadMatrix(&glr.viewmatrix); GL_BindTexture(0, TEXNUM_BEAM); GL_StateBits(GLS_BLEND_BLEND | GLS_DEPTHMASK_FALSE); GL_ArrayBits(GLA_VERTEX | GLA_TC | GLA_COLOR); @@ -450,7 +450,7 @@ void GL_DrawAlphaFaces(void) glr.ent = &gl_world; - GL_LoadMatrix(glr.viewmatrix); + GL_LoadMatrix(&glr.viewmatrix); GL_BindArrays(); @@ -479,4 +479,3 @@ void GL_AddAlphaFace(mface_t *face) face->next = faces_alpha; faces_alpha = face; } - diff --git a/src/refresh/gl/world.c b/src/refresh/gl/world.c index efede8d..63ff4b8 100644 --- a/src/refresh/gl/world.c +++ b/src/refresh/gl/world.c @@ -203,9 +203,9 @@ static void GL_TransformLights(mmodel_t *model) for (i = 0, light = glr.fd.dlights; i < glr.fd.num_dlights; i++, light++) { VectorSubtract(light->origin, glr.ent->origin, temp); - light->transformed[0] = DotProduct(temp, glr.entaxis[0]); - light->transformed[1] = DotProduct(temp, glr.entaxis[1]); - light->transformed[2] = DotProduct(temp, glr.entaxis[2]); + light->transformed[0] = DotProduct(temp, glr.entaxis.i[0]); + light->transformed[1] = DotProduct(temp, glr.entaxis.i[1]); + light->transformed[2] = DotProduct(temp, glr.entaxis.i[2]); GL_MarkLights_r(model->headnode, light, 1 << i); } } @@ -383,9 +383,10 @@ void GL_DrawBspModel(mmodel_t *model) } } VectorSubtract(glr.fd.vieworg, ent->origin, temp); - transformed[0] = DotProduct(temp, glr.entaxis[0]); - transformed[1] = DotProduct(temp, glr.entaxis[1]); - transformed[2] = DotProduct(temp, glr.entaxis[2]); + + transformed[0] = DotProduct(temp, glr.entaxis.i[0]); + transformed[1] = DotProduct(temp, glr.entaxis.i[1]); + transformed[2] = DotProduct(temp, glr.entaxis.i[2]); } else { VectorAdd(model->mins, ent->origin, bounds[0]); VectorAdd(model->maxs, ent->origin, bounds[1]); @@ -562,7 +563,7 @@ void GL_DrawWorld(void) R_ClearSkyBox(); - GL_LoadMatrix(glr.viewmatrix); + GL_LoadMatrix(&glr.viewmatrix); GL_BindArrays(); diff --git a/src/shared/matrix.c b/src/shared/matrix.c new file mode 100644 index 0000000..86dffbb --- /dev/null +++ b/src/shared/matrix.c @@ -0,0 +1,83 @@ + +#include <math.h> + +#include "shared/shared.h" + +void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) +{ + float angle; + float sr, sp, sy, cr, cp, cy; + + angle = DEG2RAD(angles[YAW]); + sy = sin(angle); + cy = cos(angle); + angle = DEG2RAD(angles[PITCH]); + sp = sin(angle); + cp = cos(angle); + angle = DEG2RAD(angles[ROLL]); + sr = sin(angle); + cr = cos(angle); + + if (forward) { + forward[0] = cp * cy; + forward[1] = cp * sy; + forward[2] = -sp; + } + if (right) { + right[0] = (-1 * sr * sp * cy + -1 * cr * -sy); + right[1] = (-1 * sr * sp * sy + -1 * cr * cy); + right[2] = -1 * sr * cp; + } + if (up) { + up[0] = (cr * sp * cy + -sr * -sy); + up[1] = (cr * sp * sy + -sr * cy); + up[2] = cr * cp; + } +} + +vec_t VectorNormalize(vec3_t v) +{ + float length, ilength; + + length = v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; + length = sqrt(length); // FIXME + + if (length) { + ilength = 1 / length; + v[0] *= ilength; + v[1] *= ilength; + v[2] *= ilength; + } + + return length; + +} + +vec_t VectorNormalize2(vec3_t v, vec3_t out) +{ + float length, ilength; + + length = v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; + length = sqrt(length); // FIXME + + if (length) { + ilength = 1 / length; + out[0] = v[0] * ilength; + out[1] = v[1] * ilength; + out[2] = v[2] * ilength; + } + + return length; +} + +mat4_t mul_mat4(const mat4_t *restrict a, const mat4_t *restrict b) +{ + mat4_t p = { 0 }; + + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + for (int k = 0; k < 4; k++) + p.i[i][j] += a->i[k][j] * b->i[i][k]; + + return p; +} diff --git a/src/shared/shared.c b/src/shared/shared.c index bcbe398..6c181c0 100644 --- a/src/shared/shared.c +++ b/src/shared/shared.c @@ -20,74 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc., vec3_t vec3_origin = { 0, 0, 0 }; -void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) -{ - float angle; - float sr, sp, sy, cr, cp, cy; - - angle = angles[YAW] * (M_PI * 2 / 360); - sy = sin(angle); - cy = cos(angle); - angle = angles[PITCH] * (M_PI * 2 / 360); - sp = sin(angle); - cp = cos(angle); - angle = angles[ROLL] * (M_PI * 2 / 360); - sr = sin(angle); - cr = cos(angle); - - if (forward) { - forward[0] = cp * cy; - forward[1] = cp * sy; - forward[2] = -sp; - } - if (right) { - right[0] = (-1 * sr * sp * cy + -1 * cr * -sy); - right[1] = (-1 * sr * sp * sy + -1 * cr * cy); - right[2] = -1 * sr * cp; - } - if (up) { - up[0] = (cr * sp * cy + -sr * -sy); - up[1] = (cr * sp * sy + -sr * cy); - up[2] = cr * cp; - } -} - -vec_t VectorNormalize(vec3_t v) -{ - float length, ilength; - - length = v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; - length = sqrt(length); // FIXME - - if (length) { - ilength = 1 / length; - v[0] *= ilength; - v[1] *= ilength; - v[2] *= ilength; - } - - return length; - -} - -vec_t VectorNormalize2(vec3_t v, vec3_t out) -{ - float length, ilength; - - length = v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; - length = sqrt(length); // FIXME - - if (length) { - ilength = 1 / length; - out[0] = v[0] * ilength; - out[1] = v[1] * ilength; - out[2] = v[2] * ilength; - } - - return length; - -} - void ClearBounds(vec3_t mins, vec3_t maxs) { mins[0] = mins[1] = mins[2] = 99999; @@ -141,8 +73,6 @@ vec_t RadiusFromBounds(const vec3_t mins, const vec3_t maxs) //==================================================================================== -static const char hexchars[] = "0123456789ABCDEF"; - /* ============ COM_SkipPath |