diff --git a/GL/matrix.c b/GL/matrix.c index fdb9df2..422e3f8 100644 --- a/GL/matrix.c +++ b/GL/matrix.c @@ -31,26 +31,40 @@ static const Matrix4x4 __attribute__((aligned(32))) IDENTITY = { GLfloat NEAR_PLANE_DISTANCE = 0.0f; +Matrix4x4* _glGetModelViewMatrix() { + return (Matrix4x4*) stack_top(&MATRIX_STACKS[0]); +} + Matrix4x4* _glGetProjectionMatrix() { return (Matrix4x4*) stack_top(&MATRIX_STACKS[1]); } -Matrix4x4* _glGetModelViewMatrix() { - return (Matrix4x4*) stack_top(&MATRIX_STACKS[0]); +Matrix4x4* _glGetTextureMatrix() { + return (Matrix4x4*) stack_top(&MATRIX_STACKS[2]); +} + +Matrix4x4* _glGetColorMatrix() { + return (Matrix4x4*) stack_top(&MATRIX_STACKS[3]); } GLenum _glGetMatrixMode() { return MATRIX_MODE; } +GLboolean _glIsIdentity(const Matrix4x4* m) { + return memcmp(m, IDENTITY, sizeof(Matrix4x4)) == 0; +} + void _glInitMatrices() { init_stack(&MATRIX_STACKS[0], sizeof(Matrix4x4), 32); init_stack(&MATRIX_STACKS[1], sizeof(Matrix4x4), 32); init_stack(&MATRIX_STACKS[2], sizeof(Matrix4x4), 32); + init_stack(&MATRIX_STACKS[3], sizeof(Matrix4x4), 32); stack_push(&MATRIX_STACKS[0], IDENTITY); stack_push(&MATRIX_STACKS[1], IDENTITY); stack_push(&MATRIX_STACKS[2], IDENTITY); + stack_push(&MATRIX_STACKS[3], IDENTITY); MEMCPY4(NORMAL_MATRIX, IDENTITY, sizeof(Matrix4x4)); diff --git a/GL/private.h b/GL/private.h index 8c32fc2..a491932 100644 --- a/GL/private.h +++ b/GL/private.h @@ -332,7 +332,10 @@ extern GLfloat HALF_POINT_SIZE; Matrix4x4* _glGetProjectionMatrix(); Matrix4x4* _glGetModelViewMatrix(); +Matrix4x4* _glGetTextureMatrix(); +Matrix4x4* _glGetColorMatrix(); GLenum _glGetMatrixMode(); +GLboolean _glIsIdentity(const Matrix4x4* m); void _glWipeTextureOnFramebuffers(GLuint texture); diff --git a/GL/state.c b/GL/state.c index 6468a3b..88aaad0 100644 --- a/GL/state.c +++ b/GL/state.c @@ -978,6 +978,12 @@ void APIENTRY glGetFloatv(GLenum pname, GLfloat* params) { case GL_MODELVIEW_MATRIX: MEMCPY4(params, _glGetModelViewMatrix(), sizeof(float) * 16); break; + case GL_TEXTURE_MATRIX: + MEMCPY4(params, _glGetTextureMatrix(), sizeof(float) * 16); + break; + case GL_COLOR_MATRIX: + MEMCPY4(params, _glGetColorMatrix(), sizeof(float) * 16); + break; case GL_POLYGON_OFFSET_FACTOR: *params = GPUState.offset_factor; diff --git a/GL/tnl_effects.c b/GL/tnl_effects.c index 2325f5a..97755e1 100644 --- a/GL/tnl_effects.c +++ b/GL/tnl_effects.c @@ -8,55 +8,15 @@ #include "private.h" #include "platform.h" -#define MAX_TNL_EFFECTS 3 -#define TNL_EFFECT_NONE 0x00 -#define TNL_EFFECT_VIEW_SPACE 0x01 - -typedef void (*TnlEffect)(SubmissionTarget* target); -static struct tnl_effect { - GLint flags; - TnlEffect func; -} TNL_EFFECTS[MAX_TNL_EFFECTS]; - -static int TNL_COUNT; -static GLboolean TNL_VIEW; +#define TNL_FX_LIGHTING 0x01 +#define TNL_FX_TEXTURE 0x02 +#define TNL_FX_COLOR 0x04 +static int TNL_EFFECTS; #define ITERATE(count) \ GLuint i = count; \ while(i--) -static void updateEffectList(void) { - TNL_VIEW = GL_FALSE; - - ITERATE(TNL_COUNT) { - if (TNL_EFFECTS[i].flags == TNL_EFFECT_VIEW_SPACE) TNL_VIEW = true; - } -} - -static void _glTnlAddEffect(GLint flags, TnlEffect func) { - if (TNL_COUNT == MAX_TNL_EFFECTS) return; - - TNL_EFFECTS[TNL_COUNT].flags = flags; - TNL_EFFECTS[TNL_COUNT].func = func; - - TNL_COUNT++; - updateEffectList(); -} - -static void _glTnlRemoveEffect(TnlEffect func) { - int i, j; - - for (i = TNL_COUNT - 1; i >= 0; i--) { - if (TNL_EFFECTS[i].func != func) continue; - - for(j = i; j < TNL_COUNT - 1; j++) { - TNL_EFFECTS[j] = TNL_EFFECTS[j + 1]; - } - TNL_COUNT--; - } - updateEffectList(); -} - void _glTnlLoadMatrix(void) { /* If we're lighting, then we need to do some work in * eye-space, so we only transform vertices by the modelview @@ -65,7 +25,7 @@ void _glTnlLoadMatrix(void) { * If we're not doing lighting though we can optimise by taking * vertices straight to clip-space */ - if(TNL_VIEW) { + if(TNL_EFFECTS & TNL_FX_LIGHTING) { _glMatrixLoadModelView(); } else { _glMatrixLoadModelViewProjection(); @@ -86,21 +46,6 @@ static void transformVertices(SubmissionTarget* target) { } } -void _glTnlApplyEffects(SubmissionTarget* target) { - if (!TNL_COUNT) return; - - struct tnl_effect* e = TNL_EFFECTS; - ITERATE(TNL_COUNT) { - e->func(target); - e++; - } - - if (!TNL_VIEW) return; - /* OK eye-space work done, now move into clip space */ - _glMatrixLoadProjection(); - transformVertices(target); -} - static void mat_transform_normal3(VertexExtra* extra, const uint32_t count) { ITERATE(count) { @@ -122,8 +67,21 @@ static void lightingEffect(SubmissionTarget* target) { void _glTnlUpdateLighting(void) { if (_glIsLightingEnabled()) { - _glTnlAddEffect(TNL_EFFECT_VIEW_SPACE, lightingEffect); + TNL_EFFECTS |= TNL_FX_LIGHTING; } else { - _glTnlRemoveEffect(lightingEffect); + TNL_EFFECTS &= ~TNL_FX_LIGHTING; + } +} + +void _glTnlApplyEffects(SubmissionTarget* target) { + if (!TNL_EFFECTS) return; + + if (TNL_EFFECTS & TNL_FX_LIGHTING) + lightingEffect(target); + + if (TNL_EFFECTS & TNL_FX_LIGHTING) { + /* OK eye-space work done, now move into clip space */ + _glMatrixLoadProjection(); + transformVertices(target); } }