More clipping fixes

This commit is contained in:
Luke Benstead 2018-09-08 20:53:28 +01:00
parent 06b065dc7e
commit 17c9699966
5 changed files with 28 additions and 20 deletions

View File

@ -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_EOL = 0xf0000000;
const uint32_t VERTEX_CMD = 0xe0000000; 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, const uint8_t flatShade) __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) {
uint8_t i, c = 0; uint8_t i, c = 0;
uint8_t lastVisible = 255; uint8_t lastVisible = 255;
ClipVertex* last = NULL; ClipVertex* last = NULL;
/* Used when flat shading is enabled */
uint32_t finalColour = *((uint32_t*) vertices[2].bgra);
for(i = 0; i < 4; ++i) { for(i = 0; i < 4; ++i) {
uint8_t thisIndex = (i == 3) ? 0 : 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); interpolateVec3(v1->nxyz, v2->nxyz, t, next.nxyz);
interpolateVec2(v1->uv, v2->uv, t, next.uv); interpolateVec2(v1->uv, v2->uv, t, next.uv);
interpolateVec2(v1->st, v2->st, t, next.st); interpolateVec2(v1->st, v2->st, t, next.st);
if(flatShade) {
*((uint32_t*) next.bgra) = finalColour;
} else {
interpolateColour(v1->bgra, v2->bgra, t, next.bgra); interpolateColour(v1->bgra, v2->bgra, t, next.bgra);
}
last = aligned_vector_push_back(output, &next, 1); last = aligned_vector_push_back(output, &next, 1);
last->flags = VERTEX_CMD; last->flags = VERTEX_CMD;
@ -143,7 +151,7 @@ static inline void markDead(ClipVertex* vert) {
vert->flags = VERTEX_CMD_EOL; 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 */ /* Room for clipping 16 triangles */
typedef struct { typedef struct {
ClipVertex vertex[3]; ClipVertex vertex[3];
@ -240,25 +248,21 @@ void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset) {
/* Last triangle in strip so end a vertex early */ /* Last triangle in strip so end a vertex early */
if(triangle == 0) { if(triangle == 0) {
// Wipe out the triangle completely // Wipe out the triangle completely
markDead(vertex - 2); markDead(v1);
markDead(vertex - 1); markDead(v2);
} else { } else {
// End the strip // End the strip
(vertex - 1)->flags = VERTEX_CMD_EOL; (vertex - 1)->flags = VERTEX_CMD_EOL;
} }
markDead(vertex); markDead(vertex);
} else if(triangle == 0) { } else if(triangle == 0) {
/* First triangle in strip, remove first vertex and swap latter two /* First triangle in strip, remove first vertex */
to restart the strip */ markDead(v1);
ClipVertex tmp = *v2;
*v2 = *v3;
*v3 = tmp;
markDead(vertex - 2); v2->flags = VERTEX_CMD;
v3->flags = VERTEX_CMD;
(vertex - 1)->flags = VERTEX_CMD;
vertex->flags = VERTEX_CMD;
triangle = -1; triangle = -1;
} else { } else {
@ -302,6 +306,6 @@ void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset) {
/* Now, clip all the triangles and append them to the output */ /* Now, clip all the triangles and append them to the output */
for(i = 0; i < CLIP_COUNT; ++i) { 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);
} }
} }

View File

@ -40,8 +40,7 @@ typedef struct {
} ClipVertex; } ClipVertex;
void clipLineToNearZ(const ClipVertex* v1, const ClipVertex* v2, ClipVertex* vout, float* t); 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, uint8_t fladeShade);
void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -626,7 +626,7 @@ static void transform(ClipVertex* output, const GLsizei count) {
static GLsizei clip(AlignedVector* polylist, uint32_t offset, const GLsizei count) { static GLsizei clip(AlignedVector* polylist, uint32_t offset, const GLsizei count) {
/* Perform clipping, generating new vertices as necessary */ /* 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 */ /* List size, minus the original offset (which includes the header), minus the header */
return polylist->size - offset - 1; return polylist->size - offset - 1;

View File

@ -120,6 +120,7 @@ AttribPointer* _glGetDiffuseAttribPointer();
AttribPointer* _glGetNormalAttribPointer(); AttribPointer* _glGetNormalAttribPointer();
AttribPointer* _glGetUVAttribPointer(); AttribPointer* _glGetUVAttribPointer();
AttribPointer* _glGetSTAttribPointer(); AttribPointer* _glGetSTAttribPointer();
GLenum _glGetShadeModel();
TextureObject* getTexture0(); TextureObject* getTexture0();
TextureObject* getTexture1(); TextureObject* getTexture1();

View File

@ -413,6 +413,10 @@ GLAPI void APIENTRY glCullFace(GLenum mode) {
GL_CONTEXT.gen.culling = _calc_pvr_face_culling(); 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 */ /* Shading - Flat or Goraud */
GLAPI void APIENTRY glShadeModel(GLenum mode) { GLAPI void APIENTRY glShadeModel(GLenum mode) {
GL_CONTEXT.gen.shading = (mode == GL_SMOOTH) ? PVR_SHADE_GOURAUD : PVR_SHADE_FLAT; GL_CONTEXT.gen.shading = (mode == GL_SMOOTH) ? PVR_SHADE_GOURAUD : PVR_SHADE_FLAT;