summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/clip.c2
-rw-r--r--src/core/device.c38
-rw-r--r--src/core/rasterizer.c22
3 files changed, 46 insertions, 16 deletions
diff --git a/src/core/clip.c b/src/core/clip.c
index 2880448..d5de4fc 100644
--- a/src/core/clip.c
+++ b/src/core/clip.c
@@ -145,7 +145,7 @@ static bool is_inside_plane(Vec4* c, Plane plane) {
case NEGATIVE_Y:
return c->y >= -c->w;
case POSITIVE_Z:
- return c->z <= +c->w;
+ return c->z <= c->w;
case NEGATIVE_Z:
return c->z >= -c->w;
default:
diff --git a/src/core/device.c b/src/core/device.c
index ac055c9..923a2fa 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -498,18 +498,36 @@ static void render_prims_triangle(uint varying_flag) {
c1 = &clip_coords.coords[i1];
c2 = &clip_coords.coords[i2];
- /*back face culling*/
+ /*early back face culling*/
+ bool early_culled = FALSE;
if (ssr_isenable(ENABLE_BACKFACECULL)) {
/*cull in ndc*/
float w0 = 1 / c0->w, w1 = 1 / c1->w, w2 = 1 / c2->w;
- Vec3 ab, ac;
- ab.x = c1->x * w1 - c0->x * w0;
- ab.y = c1->y * w1 - c0->y * w0;
- ac.x = c2->x * w2 - c0->x * w0;
- ac.y = c2->y * w2 - c0->y * w0;
- if (ab.x * ac.y - ab.y * ac.x <= 0) {
- continue; /*cull*/
+ bool all_front = w0 > 0 && w1 > 0 && w2 > 0;
+ if (all_front)
+ {
+ early_culled = TRUE;
+ Vec2 ab, ac;
+ ab.x = c1->x * w1 - c0->x * w0;
+ ab.y = c1->y * w1 - c0->y * w0;
+ ac.x = c2->x * w2 - c0->x * w0;
+ ac.y = c2->y * w2 - c0->y * w0;
+ if (ab.x * ac.y - ab.y * ac.x <= 0) {
+ continue; /*cull*/
+ }
}
+ //OpenGL algrithm:
+ //float w0 = max(1 / c0->w, 0), w1 = 1 / c1->w, w2 = 1 / c2->w;
+ //Vec2 a = { c0->x * w0, c0->y * w0 };
+ //Vec2 b = { c1->x * w1, c1->y * w1 };
+ //Vec2 c = { c2->x * w2, c2->y * w2 };
+ //float signed_area = 0;
+ //signed_area += a.x * b.y - a.y * b.x;
+ //signed_area += b.x * c.y - b.y * c.x;
+ //signed_area += c.x * a.y - c.y * a.x;
+ //if (signed_area <= 0) {
+ // continue; /*cull*/
+ //}
}
/*clipping*/
@@ -521,7 +539,7 @@ static void render_prims_triangle(uint varying_flag) {
reset_active_reg = FALSE;
ssrS_setactiveregr();
}
- ssrR_triangle(c0, c1, c2, i0, i1, i2, state.program, &state.uniforms);
+ ssrR_triangle(c0, c1, c2, i0, i1, i2, state.program, &state.uniforms, early_culled);
}
else {
if (!reset_active_reg) {
@@ -535,7 +553,7 @@ static void render_prims_triangle(uint varying_flag) {
vt2 = &clip_buffer.vertices[i + 1];
c0 = &vt0->clip_coord; c1 = &vt1->clip_coord; c2 = &vt2->clip_coord;
i0 = vt0->index; i1 = vt1->index; i2 = vt2->index;
- ssrR_triangle(c0, c1, c2, i0, i1, i2, state.program, &state.uniforms);
+ ssrR_triangle(c0, c1, c2, i0, i1, i2, state.program, &state.uniforms, early_culled);
}
}
}
diff --git a/src/core/rasterizer.c b/src/core/rasterizer.c
index 28ae639..c5745ba 100644
--- a/src/core/rasterizer.c
+++ b/src/core/rasterizer.c
@@ -86,19 +86,31 @@ void ssrR_triangle(
Vec4* CA, Vec4* CB, Vec4* CC,
uint IA, uint IB, uint IC,
Program* program,
- UniformCollection* uniforms
+ UniformCollection* uniforms,
+ bool early_culled
) {
ssr_assert(CA && CB && CC && program);
+ /*late back face culling*/
+ if (!early_culled && ssr_isenable(ENABLE_BACKFACECULL)) {
+ float w0 = 1 / CA->w, w1 = 1 / CB->w, w2 = 1 / CC->w;
+ Vec2 ab, ac;
+ ab.x = CB->x * w1 - CA->x * w0;
+ ab.y = CB->y * w1 - CA->y * w0;
+ ac.x = CC->x * w2 - CA->x * w0;
+ ac.y = CC->y * w2 - CA->y * w0;
+ if (ab.x * ac.y - ab.y * ac.x <= 0) {
+ return;
+ }
+ }
+
Vec4 SA, SB, SC;
internal_vec4_dividewnoz(CA, &SA); ssrU_viewport(&SA, &SA);
internal_vec4_dividewnoz(CB, &SB); ssrU_viewport(&SB, &SB);
internal_vec4_dividewnoz(CC, &SC); ssrU_viewport(&SC, &SC);
-/*
- puttriangle(&SA, &SB, &SC, 0xffff0000);
- return;
-*/
+ //puttriangle(&SA, &SB, &SC, 0xffff0000);
+ //return;
Vec4 *sa = &SA, *sb = &SB, *sc = &SC, *tmp;
Vec4 *v4tmp;