diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/clip.c | 2 | ||||
-rw-r--r-- | src/core/device.c | 38 | ||||
-rw-r--r-- | src/core/rasterizer.c | 22 |
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; |