diff options
author | chai <chaifix@163.com> | 2019-12-21 22:24:15 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-12-21 22:24:15 +0800 |
commit | ec111247c614663d8231245a17c314b9b8b4a28c (patch) | |
tree | a66058508161da488371c90316865ae850b8be15 /src/core/rasterizer.c | |
parent | c3f45735ecfab6e567be371758f21395e92dfef6 (diff) |
*misc
Diffstat (limited to 'src/core/rasterizer.c')
-rw-r--r-- | src/core/rasterizer.c | 130 |
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 |