summaryrefslogtreecommitdiff
path: root/src/core/clip.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/clip.c')
-rw-r--r--src/core/clip.c72
1 files changed, 60 insertions, 12 deletions
diff --git a/src/core/clip.c b/src/core/clip.c
index 37aa9d2..48c376d 100644
--- a/src/core/clip.c
+++ b/src/core/clip.c
@@ -188,9 +188,10 @@ static bool clip_against_plane(
, ClippedBuffer* dst_buffer
, byte* src_data[]
, byte* dst_data[]
+ , uint prim_vcount/*minimum number of primitive vertices*/
) {
bool varying = varying_flag & VARYING_ANY;
- int idx = 0; /*¶¥µãË÷Òý*/
+ int idx = 0;
ClippedVert *prev, *curr;
uint previ, curri;
bool prev_inside, curr_inside;
@@ -241,12 +242,12 @@ static bool clip_against_plane(
}
}
dst_buffer->count = idx;
- return idx < 3;
+ return idx < prim_vcount;
}
-#define CLIP(plane, from, to, from_data, to_data) \
- if (clip_against_plane(plane, varying_flag, from, to, from_data, to_data)) { \
- buffer->count = 0;/*cull this triangle*/ \
+#define CLIP(plane, from, to, from_data, to_data, prim_vcount) \
+ if (clip_against_plane(plane, varying_flag, from, to, from_data, to_data, prim_vcount)) { \
+ buffer->count = 0;/*cull this primitive*/ \
return 1; \
}
@@ -286,13 +287,60 @@ bool clip_triangle(
}
#undef COPY_VERT
- CLIP(POSITIVE_W, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data);
- CLIP(POSITIVE_X, buffer, &temp_clip_buffer, clip_buffer_data, temp_clip_buffer_data);
- CLIP(NEGATIVE_X, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data);
- CLIP(POSITIVE_Y, buffer, &temp_clip_buffer, clip_buffer_data, temp_clip_buffer_data);
- CLIP(NEGATIVE_Y, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data);
- CLIP(POSITIVE_Z, buffer, &temp_clip_buffer, clip_buffer_data, temp_clip_buffer_data);
- CLIP(NEGATIVE_Z, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data);
+ CLIP(POSITIVE_W, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data, 3);
+ CLIP(POSITIVE_X, buffer, &temp_clip_buffer, clip_buffer_data, temp_clip_buffer_data, 3);
+ CLIP(NEGATIVE_X, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data, 3);
+ CLIP(POSITIVE_Y, buffer, &temp_clip_buffer, clip_buffer_data, temp_clip_buffer_data, 3);
+ CLIP(NEGATIVE_Y, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data, 3);
+ CLIP(POSITIVE_Z, buffer, &temp_clip_buffer, clip_buffer_data, temp_clip_buffer_data, 3);
+ CLIP(NEGATIVE_Z, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data, 3);
return 1;
}
+
+uint clip_line(
+ Vec4* c0, Vec4* c1,
+ uint i0, uint i1,
+ uint varying_flag,
+ ClippedBuffer* buffer
+) {
+ bool is_visible = is_vertex_visible(c0) && is_vertex_visible(c1);
+
+ if (is_visible)
+ return 0;
+
+ ssr_assert(buffer == &clip_buffer);
+
+ /*copy vert data to temp_clip_buffer*/
+ temp_clip_buffer.count = 2;
+#define COPY_VERT(i) \
+ temp_clip_buffer.vertices[i].clip_coord = *c##i; \
+ temp_clip_buffer.vertices[i].index = ##i; \
+
+ COPY_VERT(0);
+ COPY_VERT(1);
+
+ int i, index, size;
+ for (i = 0; i < REG_TOTAL; ++i) {
+ index = open_regsi[i];
+ if (index == -1) break;
+ size = registers[index].element_size;
+ ssrM_copy(&temp_clip_buffer_data[index][0], &registers[index].data[i0*size], size);
+ ssrM_copy(&temp_clip_buffer_data[index][size], &registers[index].data[i1*size], size);
+ }
+#undef COPY_VERT
+
+ CLIP(POSITIVE_W, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data, 2);
+ CLIP(POSITIVE_X, buffer, &temp_clip_buffer, clip_buffer_data, temp_clip_buffer_data, 2);
+ CLIP(NEGATIVE_X, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data, 2);
+ CLIP(POSITIVE_Y, buffer, &temp_clip_buffer, clip_buffer_data, temp_clip_buffer_data, 2);
+ CLIP(NEGATIVE_Y, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data, 2);
+ CLIP(POSITIVE_Z, buffer, &temp_clip_buffer, clip_buffer_data, temp_clip_buffer_data, 2);
+ CLIP(NEGATIVE_Z, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data, 2);
+
+ return 1;
+}
+
+uint clip_point(Vec4* c0, uint i0, uint varying_flag, ClippedBuffer* buffer) {
+ return !is_vertex_visible(c0);
+}