From e6db0986ce19057cb3a3b946ef2ad6884178f7a1 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Wed, 4 Nov 2020 19:54:04 +0000 Subject: [PATCH] Fix clipping issues --- GL/flush.c | 34 ++++++++++++++++++++++++++-------- GL/flush.h | 14 ++------------ tests/test_nearz_clipping.h | 30 +++++++++++++++++++++++++++--- 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/GL/flush.c b/GL/flush.c index 38f1329..dc95b63 100644 --- a/GL/flush.c +++ b/GL/flush.c @@ -250,15 +250,19 @@ static ListIterator* clip110(ListIterator* it) { interpolate_vertex(it->triangle[0], it->triangle[2], gen3); interpolate_vertex(it->triangle[1], it->triangle[2], gen4); - assert(isVisible(gen1)); - assert(isVisible(gen2)); - assert(isVertex(gen1)); - assert(isVertex(gen2)); - /* Return A */ it->active = gen1; it->stack_idx--; + assert(isVisible(gen1)); + assert(isVisible(gen2)); + assert(isVisible(gen3)); + assert(isVisible(gen4)); + assert(isVertex(gen1)); + assert(isVertex(gen2)); + assert(isVertex(gen3)); + assert(isVertex(gen4)); + return finish_clip(it); } @@ -278,14 +282,14 @@ static ListIterator* clip101(ListIterator* it) { /* First and last need to be the same*/ *gen1 = *it->triangle[0]; - *gen3 = *it->triangle[2]; + *gen2 = *it->triangle[2]; gen1->flags = PVR_CMD_VERTEX; gen2->flags = PVR_CMD_VERTEX; gen3->flags = PVR_CMD_VERTEX; gen4->flags = PVR_CMD_VERTEX_EOL; /* 4 is now last in the list */ - interpolate_vertex(it->triangle[0], it->triangle[1], gen2); + interpolate_vertex(it->triangle[0], it->triangle[1], gen3); interpolate_vertex(it->triangle[1], it->triangle[2], gen4); it->active = gen1; @@ -343,7 +347,7 @@ static ListIterator* clip001(ListIterator* it) { gen3->flags = PVR_CMD_VERTEX_EOL; interpolate_vertex(it->triangle[0], it->triangle[2], gen1); - interpolate_vertex(it->triangle[1], it->triangle[2], gen2); + interpolate_vertex(it->triangle[2], it->triangle[1], gen2); it->active = gen1; it->stack_idx--; @@ -378,6 +382,20 @@ static ListIterator* clip010(ListIterator* it) { return finish_clip(it); } +ListIterator* _glIteratorBegin(void* src, int n) { + TRACE(); + + ListIterator* it = (ListIterator*) malloc(sizeof(ListIterator)); + it->remaining = n - 1; + it->active = (Vertex*) src; + it->src = it->active + 1; + it->stack_idx = -1; + it->triangle_count = 0; + it->visibility = 0; + it->triangle[0] = it->triangle[1] = it->triangle[2] = NULL; + return (n) ? it : NULL; +} + ListIterator* _glIteratorNext(ListIterator* it) { TRACE(); diff --git a/GL/flush.h b/GL/flush.h index 760e3e4..279ccc9 100644 --- a/GL/flush.h +++ b/GL/flush.h @@ -41,17 +41,7 @@ typedef struct { uint8_t padding; } ListIterator; -inline ListIterator* _glIteratorBegin(void* src, int n) { - ListIterator* it = (ListIterator*) malloc(sizeof(ListIterator)); - it->remaining = n - 1; - it->active = (Vertex*) src; - it->src = it->active + 1; - it->stack_idx = -1; - it->triangle_count = 0; - it->visibility = 0; - it->triangle[0] = it->triangle[1] = it->triangle[2] = NULL; - return (n) ? it : NULL; -} +ListIterator* _glIteratorBegin(void* src, int n); GL_FORCE_INLINE GLboolean isVertex(const Vertex* vertex) { assert(vertex); @@ -66,7 +56,7 @@ GL_FORCE_INLINE GLboolean isVisible(const Vertex* vertex) { TRACE(); assert(vertex != NULL); - return vertex->w >= -0.00001f; // && vertex->xyz[2] >= -vertex->w; + return vertex->w > 0.0000f; // && vertex->xyz[2] >= -vertex->w; } ListIterator* _glIteratorNext(ListIterator* it); diff --git a/tests/test_nearz_clipping.h b/tests/test_nearz_clipping.h index 4dd28ba..0469d4a 100644 --- a/tests/test_nearz_clipping.h +++ b/tests/test_nearz_clipping.h @@ -53,9 +53,9 @@ private: #define assert_vertex_equal(v, x, y, z) \ assert_is_not_null(v); \ printf("> %f, %f, %f\n", v->xyz[0], v->xyz[1], v->xyz[2]); \ - assert_equal(v->xyz[0], x); \ - assert_equal(v->xyz[1], y); \ - assert_equal(v->xyz[2], z); \ + assert_close(v->xyz[0], x, 0.0001f); \ + assert_close(v->xyz[1], y, 0.0001f); \ + assert_close(v->xyz[2], z, 0.0001f); \ #define assert_is_header(v) \ assert_false(isVertex(v)); \ @@ -202,6 +202,30 @@ public: } void test_clipping_101() { + VertexBuilder builder; + + auto list = builder. + add_header(). + add(1, 1, 2, 1). + add(1, 0, 2, -1). + add_last(0, 1, 2, 1).done(); + + ListIterator* it = _glIteratorBegin(list.first, list.second); + Vertex* v0 = it->active; + assert_is_not_null(v0); + assert_false(isVertex(v0)); // Should be a header + + it = _glIteratorNext(it); + assert_is_not_null(it); + assert_vertex_equal(it->active, 1, 1, 2); + + it = _glIteratorNext(it); + assert_is_not_null(it); + assert_vertex_equal(it->active, 0, 1, 2); + + it = _glIteratorNext(it); + assert_is_not_null(it); + assert_vertex_equal(it->active, 1, 0.5f, 2); }