summaryrefslogtreecommitdiff
path: root/src/core/rasterizer.c
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-12-21 22:24:15 +0800
committerchai <chaifix@163.com>2019-12-21 22:24:15 +0800
commitec111247c614663d8231245a17c314b9b8b4a28c (patch)
treea66058508161da488371c90316865ae850b8be15 /src/core/rasterizer.c
parentc3f45735ecfab6e567be371758f21395e92dfef6 (diff)
*misc
Diffstat (limited to 'src/core/rasterizer.c')
-rw-r--r--src/core/rasterizer.c130
1 files changed, 76 insertions, 54 deletions
diff --git a/src/core/rasterizer.c b/src/core/rasterizer.c
index 2319d44..5618fde 100644
--- a/src/core/rasterizer.c
+++ b/src/core/rasterizer.c
@@ -80,28 +80,33 @@ static void puttriangle(Vec2* A, Vec2* B, Vec2* C, Color c) {
ssrR_putline(C->x, C->y, B->x, B->y, c);
}
-#define discardif(condition) if(condition) continue
-
extern FragmentShaderIn ssr_frag_in;
-void ssrR_triangle( Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Program* program, UniformCollection* uniforms ) {
+void ssrR_triangle(
+ Vec4* CA, Vec4* CB, Vec4* CC,
+ uint IA, uint IB, uint IC,
+ Program* program,
+ UniformCollection* uniforms
+) {
ssr_assert(CA && CB && CC && program);
- static Vec3 SA, SB, SC;
- static Vec3 bc;
-
+ Vec3 SA, SB, SC;
vec4_dividew(CA, &SA); ssrU_viewport(&SA, &SA);
vec4_dividew(CB, &SB); ssrU_viewport(&SB, &SB);
vec4_dividew(CC, &SC); ssrU_viewport(&SC, &SC);
+
/*
puttriangle(&SA, &SB, &SC, 0xffff0000);
return;
*/
- Vec3 *sa = &SA, *sb = &SB, *sc = &SC, *tmp; Vec4* v4tmp; Vert* vtemp;
+
+ Vec3 *sa = &SA, *sb = &SB, *sc = &SC, *tmp;
+ Vec4 *v4tmp;
+ uint itmp;
#define swap(t, a, b) {t = a; a = b; b = t;} /*sort in y axis*/
- if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(vtemp, A, B); }
- if (sc->y < sb->y) { swap(tmp, sb, sc); swap(v4tmp, CB, CC); swap(vtemp, B, C); }
- if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(vtemp, A, B); }
+ if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(itmp, IA, IB); }
+ if (sc->y < sb->y) { swap(tmp, sb, sc); swap(v4tmp, CB, CC); swap(itmp, IB, IC); }
+ if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(itmp, IA, IB); }
#undef swap
Vec2 AB = {sb->x - sa->x, sb->y - sa->y}, AC = { sc->x - sa->x, sc->y - sa->y };
@@ -111,60 +116,75 @@ void ssrR_triangle( Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Pro
float invkAB = (sb->x - sa->x) / (sb->y - sa->y + EPSILON);
float invkBC = (sc->x - sb->x) / (sc->y - sb->y + EPSILON);
- Color32 color;
float from, to;
- Vec2 p;
float depth;
float CAw = 1.f / CA->w, CBw = 1.f / CB->w, CCw = 1.f / CC->w;
- uint varying_flag = program->varying_flag;
+ bool depth_test = ssr_isenable(ENABLE_DEPTHTEST);
+ bool multi_sample = ssr_isenable(ENABLE_MULTISAMPLE);
+ bool blend = ssr_isenable(ENABLE_BLEND);
+ bool write_depth = ssr_isenable(ENABLE_WRITEDEPTH);
+ bool stencil_test = ssr_isenable(ENABLE_STENCILTEST);
+ bool write_stencil = ssr_iswritesencil();
+
+ bool pass_depth_test = TRUE;
+ bool pass_stencil_test = TRUE;
+ bool discard = FALSE;
+
+ FragmentShader frag_shader = program->fragmentshader;
+
+ Vec3 s[2], u; /*edge of triangle*/
- Vec3 s[2], u;
s[0].x = sc->x - sa->x; s[0].y = sb->x - sa->x;
s[1].x = sc->y - sa->y; s[1].y = sb->y - sa->y;
- bool depth_test = ssr_isenable(ENABLE_DEPTHTEST);
- bool multi_sample = ssr_isenable(ENABLE_MULTISAMPLE);
- bool blend = ssr_isenable(ENABLE_BLEND);
- bool write_depth = ssr_isenable(ENABLE_WRITEDEPTH);
+ Vec2 p;
+ Vec3 bc;
+
+#define discardif(condition) if(condition) continue
#define RENDER_TRIANGLE \
- for (p.y = FROM->y; p.y < TO->y + OFFSET; ++p.y) { \
- SET_FROM_AND_TO \
- s[1].z = sa->y - p.y; \
- for (p.x = from; order * (p.x - to) <= 0; p.x += order) { \
- s[0].z = sa->x - p.x; \
- vec3_cross(&s[0], &s[1], &u); \
- discardif(compare(u.z, 0)); \
- u.z = 1.f / u.z; \
- bc.x = 1.f - (u.x + u.y) * u.z; \
- bc.y = u.y * u.z; \
- bc.z = u.x * u.z; \
- discardif(bc.x < 0 || bc.y < 0 || bc.z < 0); \
- /*perspective correction*/ \
- bc.x *= CAw; bc.y *= CBw; bc.z *= CCw; \
- vec3_scale(&bc, 1.f / (bc.x + bc.y + bc.z), &bc); \
- /*early depth testing*/ \
- if(depth_test ){ \
- depth = bc.x*sa->z+bc.y*sb->z+bc.z*sc->z; \
- discardif(!ssr_testdepth(p.x, p.y, depth)); \
- } \
- /*set varying variables*/ \
- ssrS_solveregs(&bc, A->index, B->index, C->index); \
- /*enter fragment shader*/ \
- if(program->fragmentshader(uniforms, &ssr_frag_in, &color)) { \
- /*blend*/ \
- if(blend) { \
- Color32 dst; dst = ssr_getfbocolor(p.x, p.y); \
- ssr_blend(&color, &dst, &color); \
- } \
- if(write_depth) { \
- ssr_writedepth(p.x, p.y, depth); \
- } \
- color32_saturate(&color); \
- ssr_putpoint32(p.x, p.y, &color); \
- } \
- } \
+ for (p.y = FROM->y; p.y < TO->y + OFFSET; ++p.y) { \
+ SET_FROM_AND_TO \
+ s[1].z = sa->y - p.y; \
+ for (p.x = from; order * (p.x - to) <= 0; p.x += order) { \
+ /*calculate barycentric coordinate*/ \
+ s[0].z = sa->x - p.x; \
+ vec3_cross(&s[0], &s[1], &u); \
+ discardif(compare(u.z, 0)); \
+ u.z = 1.f / u.z; \
+ bc.x = 1.f - (u.x + u.y) * u.z; \
+ bc.y = u.y * u.z; \
+ bc.z = u.x * u.z; \
+ discardif(bc.x < 0 || bc.y < 0 || bc.z < 0); \
+ /*perspective correction*/ \
+ bc.x *= CAw; bc.y *= CBw; bc.z *= CCw; \
+ vec3_scale(&bc, 1.f / (bc.x + bc.y + bc.z), &bc); \
+ /*early depth testing*/ \
+ if(depth_test){ \
+ depth = bc.x*sa->z+bc.y*sb->z+bc.z*sc->z; \
+ pass_depth_test = ssr_testdepth(p.x, p.y, depth); \
+ } \
+ /*early stencil testing*/ \
+ if(stencil_test){ \
+ pass_stencil_test = ssr_teststencil(p.x, p.y, pass_depth_test); \
+ } \
+ discardif(!pass_depth_test || !pass_stencil_test); \
+ /*interpolate varying variables*/ \
+ ssrS_solveregs(&bc, IA, IB, IC); \
+ /*enter fragment shader*/ \
+ discard = !frag_shader(uniforms, &ssr_frag_in, out_color[0]); \
+ discardif(discard); \
+ /*put point*/ \
+ ssr_blendandputpoint(p.x, p.y, blend); \
+ /*write depth and stencil*/ \
+ if(write_depth) { \
+ ssr_writedepth(p.x, p.y, depth); \
+ } \
+ if(write_stencil) { \
+ ssr_writestencil(p.x, p.y, pass_depth_test, pass_stencil_test); \
+ } \
+ } \
}
#define FROM sa
@@ -194,6 +214,8 @@ void ssrR_triangle( Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Pro
}
RENDER_TRIANGLE
+
+#undef discardif
#undef FROM
#undef TO