From 17c96999669908f07d88dab034d4f24c19a9b59f Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sat, 8 Sep 2018 20:53:28 +0100 Subject: [PATCH] More clipping fixes --- GL/clip.c | 38 +++++++++++++++++++++----------------- GL/clip.h | 3 +-- GL/draw.c | 2 +- GL/private.h | 1 + GL/state.c | 4 ++++ 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/GL/clip.c b/GL/clip.c index 20be872..2e67507 100644 --- a/GL/clip.c +++ b/GL/clip.c @@ -72,14 +72,17 @@ static inline void interpolateColour(const uint8_t* v1, const uint8_t* v2, const const uint32_t VERTEX_CMD_EOL = 0xf0000000; const uint32_t VERTEX_CMD = 0xe0000000; -void clipTriangle(const ClipVertex* vertices, const uint8_t visible, AlignedVector* output) __attribute__((optimize("fast-math"))); -void clipTriangle(const ClipVertex* vertices, const uint8_t visible, AlignedVector* output) { +void clipTriangle(const ClipVertex* vertices, const uint8_t visible, AlignedVector* output, const uint8_t flatShade) __attribute__((optimize("fast-math"))); +void clipTriangle(const ClipVertex* vertices, const uint8_t visible, AlignedVector* output, const uint8_t flatShade) { uint8_t i, c = 0; uint8_t lastVisible = 255; ClipVertex* last = NULL; + /* Used when flat shading is enabled */ + uint32_t finalColour = *((uint32_t*) vertices[2].bgra); + for(i = 0; i < 4; ++i) { uint8_t thisIndex = (i == 3) ? 0 : i; @@ -100,7 +103,12 @@ void clipTriangle(const ClipVertex* vertices, const uint8_t visible, AlignedVect interpolateVec3(v1->nxyz, v2->nxyz, t, next.nxyz); interpolateVec2(v1->uv, v2->uv, t, next.uv); interpolateVec2(v1->st, v2->st, t, next.st); - interpolateColour(v1->bgra, v2->bgra, t, next.bgra); + + if(flatShade) { + *((uint32_t*) next.bgra) = finalColour; + } else { + interpolateColour(v1->bgra, v2->bgra, t, next.bgra); + } last = aligned_vector_push_back(output, &next, 1); last->flags = VERTEX_CMD; @@ -143,7 +151,7 @@ static inline void markDead(ClipVertex* vert) { vert->flags = VERTEX_CMD_EOL; } -void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset) { +void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset, uint8_t fladeShade) { /* Room for clipping 16 triangles */ typedef struct { ClipVertex vertex[3]; @@ -240,28 +248,24 @@ void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset) { /* Last triangle in strip so end a vertex early */ if(triangle == 0) { // Wipe out the triangle completely - markDead(vertex - 2); - markDead(vertex - 1); + markDead(v1); + markDead(v2); } else { // End the strip (vertex - 1)->flags = VERTEX_CMD_EOL; } markDead(vertex); + } else if(triangle == 0) { - /* First triangle in strip, remove first vertex and swap latter two - to restart the strip */ - ClipVertex tmp = *v2; - *v2 = *v3; - *v3 = tmp; + /* First triangle in strip, remove first vertex */ + markDead(v1); - markDead(vertex - 2); - - (vertex - 1)->flags = VERTEX_CMD; - vertex->flags = VERTEX_CMD; + v2->flags = VERTEX_CMD; + v3->flags = VERTEX_CMD; triangle = -1; - } else { + } else { ClipVertex* v4 = vertex + 1; TO_CLIP[CLIP_COUNT].vertex[0] = *v3; @@ -302,6 +306,6 @@ void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset) { /* Now, clip all the triangles and append them to the output */ for(i = 0; i < CLIP_COUNT; ++i) { - clipTriangle(TO_CLIP[i].vertex, TO_CLIP[i].visible, vertices); + clipTriangle(TO_CLIP[i].vertex, TO_CLIP[i].visible, vertices, fladeShade); } } diff --git a/GL/clip.h b/GL/clip.h index 152e709..ce20ee6 100644 --- a/GL/clip.h +++ b/GL/clip.h @@ -40,8 +40,7 @@ typedef struct { } ClipVertex; void clipLineToNearZ(const ClipVertex* v1, const ClipVertex* v2, ClipVertex* vout, float* t); -void clipTriangleStrip(const ClipVertex* vertices, const unsigned int count, AlignedVector* outBuffer); -void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset); +void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset, uint8_t fladeShade); #ifdef __cplusplus } diff --git a/GL/draw.c b/GL/draw.c index b87d15d..136043d 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -626,7 +626,7 @@ static void transform(ClipVertex* output, const GLsizei count) { static GLsizei clip(AlignedVector* polylist, uint32_t offset, const GLsizei count) { /* Perform clipping, generating new vertices as necessary */ - clipTriangleStrip2(polylist, offset); + clipTriangleStrip2(polylist, offset, _glGetShadeModel() == GL_FLAT); /* List size, minus the original offset (which includes the header), minus the header */ return polylist->size - offset - 1; diff --git a/GL/private.h b/GL/private.h index e5b3363..f749f6b 100644 --- a/GL/private.h +++ b/GL/private.h @@ -120,6 +120,7 @@ AttribPointer* _glGetDiffuseAttribPointer(); AttribPointer* _glGetNormalAttribPointer(); AttribPointer* _glGetUVAttribPointer(); AttribPointer* _glGetSTAttribPointer(); +GLenum _glGetShadeModel(); TextureObject* getTexture0(); TextureObject* getTexture1(); diff --git a/GL/state.c b/GL/state.c index 12169f9..a207b80 100644 --- a/GL/state.c +++ b/GL/state.c @@ -413,6 +413,10 @@ GLAPI void APIENTRY glCullFace(GLenum mode) { GL_CONTEXT.gen.culling = _calc_pvr_face_culling(); } +GLenum _glGetShadeModel() { + return (GL_CONTEXT.gen.shading == PVR_SHADE_FLAT) ? GL_FLAT : GL_SMOOTH; +} + /* Shading - Flat or Goraud */ GLAPI void APIENTRY glShadeModel(GLenum mode) { GL_CONTEXT.gen.shading = (mode == GL_SMOOTH) ? PVR_SHADE_GOURAUD : PVR_SHADE_FLAT;