WIP on a separate T&L effects file

This commit is contained in:
UnknownShadow200 2025-02-22 06:43:44 +11:00
parent e71560f31b
commit 93c81739ba
5 changed files with 142 additions and 50 deletions

View File

@ -80,6 +80,7 @@ set(
GL/matrix.c
GL/state.c
GL/texture.c
GL/tnl_effects.c
GL/util.c
GL/alloc/alloc.c
${CMAKE_CURRENT_BINARY_DIR}/version.c

View File

@ -598,37 +598,6 @@ static void generate(SubmissionTarget* target, const GLenum mode, const GLsizei
}
}
static void transform(SubmissionTarget* target) {
TRACE();
/* Perform modelview transform, storing W */
Vertex* it = _glSubmissionTargetStart(target);
int count = target->count;
for(int i = 0; i < count; ++i, ++it) {
TransformVertex(it->xyz[0], it->xyz[1], it->xyz[2], it->w,
it->xyz, &it->w);
}
}
static void mat_transform_normal3(VertexExtra* extra, const uint32_t count) {
ITERATE(count) {
TransformNormalNoMod(extra->nxyz, extra->nxyz);
extra++;
}
}
static void light(SubmissionTarget* target) {
/* Perform lighting calculations and manipulate the colour */
Vertex* vertex = _glSubmissionTargetStart(target);
VertexExtra* extra = aligned_vector_at(target->extras, 0);
_glMatrixLoadNormal();
mat_transform_normal3(extra, target->count);
_glPerformLighting(vertex, extra, target->count);
}
GL_FORCE_INLINE int _calc_pvr_face_culling() {
if(!_glIsCullingEnabled()) {
return GPU_CULLING_SMALL;
@ -850,28 +819,11 @@ GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count, GL
_glGPUStateMarkClean();
}
/* If we're lighting, then we need to do some work in
* eye-space, so we only transform vertices by the modelview
* matrix, and then later multiply by projection.
*
* If we're not doing lighting though we can optimise by taking
* vertices straight to clip-space */
if(_glIsLightingEnabled()) {
_glMatrixLoadModelView();
} else {
_glMatrixLoadModelViewProjection();
}
_glTnlLoadMatrix();
generate(target, mode, first, count, (GLubyte*) indices, type);
if(_glIsLightingEnabled()){
light(target);
/* OK eye-space work done, now move into clip space */
_glMatrixLoadProjection();
transform(target);
}
_glTnlApplyEffects(target);
// /*
// Now, if multitexturing is enabled, we want to send exactly the same vertices again, except:

View File

@ -485,6 +485,17 @@ void _glGPUStateMarkDirty();
#define SCENE_AMBIENT_MASK 16
#define TNL_EFFECT_NONE 0x00
#define TNL_EFFECT_VIEW_SPACE 0x01
typedef void (*TnlEffect)(SubmissionTarget* target);
void _glTnlAddEffect(GLint flags, TnlEffect func);
void _glTnlRemoveEffect(TnlEffect func);
void _glTnlLoadMatrix(void);
void _glTnlApplyEffects(SubmissionTarget* target);
void _glTnlUpdateLighting(void);
/* This is from KOS pvr_buffers.c */
#define PVR_MIN_Z 0.0001f

View File

@ -473,6 +473,7 @@ GLAPI void APIENTRY glEnable(GLenum cap) {
if(GPUState.lighting_enabled != GL_TRUE) {
GPUState.lighting_enabled = GL_TRUE;
GPUState.is_dirty = GL_TRUE;
_glTnlUpdateLighting();
}
} break;
case GL_FOG:
@ -584,6 +585,7 @@ GLAPI void APIENTRY glDisable(GLenum cap) {
if(GPUState.lighting_enabled != GL_FALSE) {
GPUState.lighting_enabled = GL_FALSE;
GPUState.is_dirty = GL_TRUE;
_glTnlUpdateLighting();
}
} break;
case GL_FOG:

126
GL/tnl_effects.c Normal file
View File

@ -0,0 +1,126 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
#include "private.h"
#include "platform.h"
#define MAX_TNL_EFFECTS 3
static struct tnl_effect {
GLint flags;
TnlEffect func;
} TNL_EFFECTS[MAX_TNL_EFFECTS];
static int TNL_COUNT;
static GLboolean TNL_VIEW;
#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;
}
}
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();
}
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
* matrix, and then later multiply by projection.
*
* If we're not doing lighting though we can optimise by taking
* vertices straight to clip-space */
if(TNL_VIEW) {
_glMatrixLoadModelView();
} else {
_glMatrixLoadModelViewProjection();
}
}
static void transformVertices(SubmissionTarget* target) {
TRACE();
/* Perform modelview transform, storing W */
Vertex* it = _glSubmissionTargetStart(target);
uint32_t count = target->count;
ITERATE(count) {
TransformVertex(it->xyz[0], it->xyz[1], it->xyz[2], it->w,
it->xyz, &it->w);
it++;
}
}
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) {
TransformNormalNoMod(extra->nxyz, extra->nxyz);
extra++;
}
}
static void lightingEffect(SubmissionTarget* target) {
/* Perform lighting calculations and manipulate the colour */
Vertex* vertex = _glSubmissionTargetStart(target);
VertexExtra* extra = aligned_vector_at(target->extras, 0);
_glMatrixLoadNormal();
mat_transform_normal3(extra, target->count);
_glPerformLighting(vertex, extra, target->count);
}
void _glTnlUpdateLighting(void) {
if (_glIsLightingEnabled()) {
_glTnlAddEffect(TNL_EFFECT_VIEW_SPACE, lightingEffect);
} else {
_glTnlRemoveEffect(lightingEffect);
}
}