From f8d1fa34399c25ea42068524aad2132fbc2e1496 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Wed, 3 Apr 2024 21:19:36 +0100 Subject: [PATCH] Fix some issues with clipping --- GL/platforms/sh4.c | 45 +++++++----- samples/zclip_trianglestrip/main.c | 112 ++++++++++++++++++++--------- 2 files changed, 105 insertions(+), 52 deletions(-) diff --git a/GL/platforms/sh4.c b/GL/platforms/sh4.c index 2a356f6..8503136 100644 --- a/GL/platforms/sh4.c +++ b/GL/platforms/sh4.c @@ -4,7 +4,7 @@ #include "sh4.h" -#define CLIP_DEBUG 1 +#define CLIP_DEBUG 0 #define PVR_VERTEX_BUF_SIZE 2560 * 256 @@ -192,7 +192,7 @@ void SceneListSubmit(Vertex* vertices, int n) { #if CLIP_DEBUG fprintf(stderr, "----\n"); - + Vertex* vertex = (Vertex*) vertices; for(int i = 0; i < n; ++i) { fprintf(stderr, "IN: {%f, %f, %f, %f}, // %x (%x)\n", vertex[i].xyz[0], vertex[i].xyz[1], vertex[i].xyz[2], vertex[i].w, vertex[i].flags, &vertex[i]); @@ -230,6 +230,27 @@ void SceneListSubmit(Vertex* vertices, int n) { Vertex* v1 = v0 + 1; Vertex* v2 = v0 + 2; + assert(!is_header(v1)); + + if(is_header(v2)) { + // OK so we've hit a new context header + // we need to finalize this strip and move on + SUBMIT_QUEUED_VERTEX(qv.flags); + + _glPerspectiveDivideVertex(v0, h); + _glPushHeaderOrVertex(v0); + + _glPerspectiveDivideVertex(v1, h); + _glPushHeaderOrVertex(v1); + i += 2; + continue; + } + + assert(!is_header(v2)); + + // FIXME: What if v1 or v2 are headers? Should we handle that or just + // assume the user has done something weird and all bets are off? + int visible_mask = ( (v0->xyz[2] >= -v0->w) << 0 | (v1->xyz[2] >= -v1->w) << 1 | @@ -244,9 +265,9 @@ void SceneListSubmit(Vertex* vertices, int n) { SUBMIT_QUEUED_VERTEX(qv.flags); } - #if CLIP_DEBUG - fprintf(stderr, "0x%x 0x%x 0x%x -> %d\n", v0, v1, v2, visible_mask); - #endif +#if CLIP_DEBUG + fprintf(stderr, "0x%x 0x%x 0x%x -> %d\n", v0, v1, v2, visible_mask); +#endif Vertex __attribute__((aligned(32))) scratch[4]; Vertex* a = &scratch[0], *b = &scratch[1], *c = &scratch[2], *d = &scratch[3]; @@ -277,7 +298,7 @@ void SceneListSubmit(Vertex* vertices, int n) { QUEUE_VERTEX(b); break; - case SECOND_VISIBLE: + case SECOND_VISIBLE: memcpy_vertex(c, v1); _glClipEdge(v0, v1, a); @@ -385,18 +406,6 @@ void SceneListSubmit(Vertex* vertices, int n) { default: fprintf(stderr, "ERROR\n"); } - - if(v2->flags == GPU_CMD_VERTEX_EOL && visible_mask == ALL_VISIBLE) { - SUBMIT_QUEUED_VERTEX(qv.flags); - - _glPerspectiveDivideVertex(v1, h); - _glPushHeaderOrVertex(v1); - - _glPerspectiveDivideVertex(v2, h); - _glPushHeaderOrVertex(v2); - - i += 2; - } } SUBMIT_QUEUED_VERTEX(GPU_CMD_VERTEX_EOL); diff --git a/samples/zclip_trianglestrip/main.c b/samples/zclip_trianglestrip/main.c index 7d4b698..4960c1c 100644 --- a/samples/zclip_trianglestrip/main.c +++ b/samples/zclip_trianglestrip/main.c @@ -20,7 +20,7 @@ void InitGL(int Width, int Height) // We call this right after our OpenG glEnable(GL_DEPTH_TEST); // Enables Depth Testing glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading glEnable(GL_TEXTURE_2D); - glEnable(GL_CULL_FACE); + glDisable(GL_CULL_FACE); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Reset The Projection Matrix @@ -64,30 +64,38 @@ int check_start() { return 0; } +static GLfloat movement = 0.0f; +static GLfloat rotation = 0.0f; + +void update_movement() { +#ifdef __DREAMCAST__ + maple_device_t *cont; + cont_state_t *state; + + cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); + + if(cont) { + state = (cont_state_t *)maple_dev_status(cont); + if(state) { + if(state->buttons & CONT_DPAD_UP) { + movement += 0.5f; + } else if(state->buttons & CONT_DPAD_DOWN) { + movement -= 0.5f; + } + + if(state->buttons & CONT_DPAD_LEFT) { + rotation += 0.5f; + } else if(state->buttons & CONT_DPAD_RIGHT) { + rotation -= 0.5f; + } + } + } +#endif +} + /* The main drawing function. */ void DrawGLScene() { - static GLfloat movement = 0.0f; - static GLfloat rotation = 0.0f; - static GLboolean increasing = GL_TRUE; - - if(movement > 10.0) { - increasing = GL_FALSE; - } else if(movement < -10.0f) { - increasing = GL_TRUE; - } - - if(increasing) { - movement += 0.05f; - } else { - movement -= 0.05f; - } - - rotation += 0.1f; - if(rotation > 360.0f) { - rotation -= 360.0f; - } - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer glLoadIdentity(); // Reset The View @@ -95,24 +103,58 @@ void DrawGLScene() glTranslatef(0.0f, -1.0f, movement); glRotatef(rotation, 0.0f, 1.0, 0.0f); - glBegin(GL_TRIANGLE_STRIP); - glColor3f(1.0f, 1.0f, 0.0f); - glVertex3f(-2.5f, 0.0f, 5.0f); + /* We create a horseshoe shape tri-strip here because that allows for situations where a strip + leaves and re-enters the viewport */ - glColor3f(1.0f, 0.0f, 0.0f); - glVertex3f(2.5f, 0.0f, 5.0f); + glBegin(GL_TRIANGLE_STRIP); + // Left side + glColor3f(1.0f, 1.0f, 0.0f); + glVertex3f(-2.0f, 0.0f, 5.0f); + + glColor3f(1.0f, 1.0f, 0.0f); + glVertex3f(-1.0f, 0.0f, 5.0f); + + glColor3f(1.0f, 1.0f, 0.0f); + glVertex3f(-2.0f, 0.0f, 3.0f); + + glColor3f(1.0f, 1.0f, 0.0f); + glVertex3f(-1.0f, 0.0f, 3.0f); + + glColor3f(1.0f, 1.0f, 0.0f); + glVertex3f(-2.0f, 0.0f, 1.0f); + + glColor3f(1.0f, 1.0f, 0.0f); + glVertex3f(-1.0f, 0.0f, 1.0f); + + // Curve + glColor3f(0.0f, 1.0f, 0.0f); + glVertex3f(-1.0f, 0.0f, -1.0f); glColor3f(0.0f, 1.0f, 0.0f); - glVertex3f(-2.5f, 0.0f, -5.0f); + glVertex3f(1.0f, 0.0f, 1.0f); - glColor3f(0.0f, 0.0f, 1.0f); - glVertex3f(2.5f, 0.0f, -5.0f); + glColor3f(0.0f, 1.0f, 0.0f); + glVertex3f(1.0f, 0.0f, -1.0f); - glColor3f(0.0f, 1.0f, 1.0f); - glVertex3f(-2.5f, 0.0f, -10.0f); + // Right side + // Degenerate to reverse ordering + glColor3f(1.0f, 0.0f, 0.0f); + glVertex3f(2.0f, 0.0f, 1.0f); - glColor3f(1.0f, 0.0f, 1.0f); - glVertex3f(2.5f, 0.0f, -10.0f); + glColor3f(0.0f, 1.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 1.0f); + + glColor3f(1.0f, 0.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 3.0f); + + glColor3f(1.0f, 0.0f, 0.0f); + glVertex3f(2.0f, 0.0f, 3.0f); + + glColor3f(1.0f, 0.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 5.0f); + + glColor3f(1.0f, 0.0f, 0.0f); + glVertex3f(2.0f, 0.0f, 5.0f); glEnd(); glPopMatrix(); @@ -131,6 +173,8 @@ int main(int argc, char **argv) if(check_start()) break; + update_movement(); + DrawGLScene(); }