diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/device.c | 34 | ||||
-rw-r--r-- | src/core/device.h | 2 | ||||
-rw-r--r-- | src/core/rasterizer.c | 159 | ||||
-rw-r--r-- | src/core/shader.h | 32 |
4 files changed, 148 insertions, 79 deletions
diff --git a/src/core/device.c b/src/core/device.c index f5ed4eb..ad640c6 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -172,12 +172,19 @@ bool ssr_isenable(uint mask) { void ssr_viewport(float l, float r, float b, float t) { } +void ssr_ortho(float l, float r, float b, float t, float n, float f) { + Mat4 m; + mat4_setortho(l, r, b, t, n, f, &m); + mat4_multiply(&MATRIX, &m, &MATRIX); +} + void ssr_frustum(float l, float r, float b, float t, float n, float f) { Mat4 m; mat4_setfrustum(l, r, b, t, n, f, &m); mat4_multiply(&MATRIX, &m, &MATRIX); } +/*注意这里nf都要是正数,代表距离*/ void ssr_perspective(float fov, float aspect, float n, float f) { Mat4 m; mat4_setperspective(fov, aspect, n, f, &m); @@ -232,9 +239,11 @@ bool ssr_testdepthf(uint x, uint y, float depth) { void ssrU_viewport(Vec2* p, Vec2* out) { ssr_assert(p && out); - int halfw = config.width >> 1, halfh = config.height >> 1; - out->x = p->x * halfw + halfw + 0.5f; - out->y = halfh - p->y * halfh + 0.5f; + float halfw = config.width / 2.f, halfh = config.height / 2.f; + out->x = (int)(p->x * halfw + halfw); + out->y = (int)(halfh - p->y * halfh); + //out->x = (int)((p->x + 1) * (halfw - 0.5f)); + //out->y = (int)((1 - p->y) * (halfh - 0.5f)); } void ssr_bindvertices(Vert** verts, int nverts, uint* indices, int nprims) { @@ -254,8 +263,8 @@ void ssr_unuseprogram() { state.program = NULL; } -static Vec4* homos = 0; -static uint tri[3]; /*三角形三个顶点的索引*/ +static Vec4* homos = NULL; +static uint tri[3]; static Vec3 ab, ac; static Mat4 mvp, mv; void ssr_draw(ssr_PrimitiveType primitive) { @@ -285,14 +294,19 @@ void ssr_draw(ssr_PrimitiveType primitive) { tri[2] = state.indices[i * 3 + 2]; /* back face culling */ - if (ssr_isenable(ENABLEMASK_BACKFACECULL)) { - vec3_minus(&homos[tri[1]], &homos[tri[0]], &ab); - vec3_minus(&homos[tri[2]], &homos[tri[0]], &ac); - if (ab.x * ac.y - ab.y * ac.x <= 0) { - continue; + if (ssr_isenable(ENABLEMASK_BACKFACECULL)) { + float w0 = 1 / homos[tri[0]].w, w1 = 1 / homos[tri[1]].w, w2 = 1 / homos[tri[2]].w; + Vec2* h0 = &homos[tri[0]], *h1 = &homos[tri[1]], *h2 = &homos[tri[2]]; + ab.x = h1->x * w1 - h0->x * w0; /*在屏幕空间做背面剔除*/ + ab.y = h1->y * w1 - h0->y * w0; + ac.x = h2->x * w2 - h0->x * w0; + ac.y = h2->y * w2 - h0->y * w0; + if (ab.x * ac.y - ab.y * ac.x <= 0) { + continue; } } + /* render triangle */ ssrR_triangle( &homos[tri[0]], &homos[tri[1]], diff --git a/src/core/device.h b/src/core/device.h index aa6e73f..1350105 100644 --- a/src/core/device.h +++ b/src/core/device.h @@ -52,6 +52,7 @@ void ssr_multmatrix(Mat4* m);/*右乘矩阵*/ void ssr_loadmatrix(Mat4* m); void ssr_frustum(float l, float r, float b, float t, float n, float f); void ssr_perspective(float fov, float aspect, float n, float f); +void ssr_ortho(float l, float r, float b, float t, float n, float f); void ssr_viewport(float l, float r, float b, float t); @@ -78,7 +79,6 @@ void ssr_draw(ssr_PrimitiveType primitive); void ssr_clearcolor(Color color); void ssr_cleardepth(); -/*直接绘制到缓冲区*/ void ssr_putpoint(uint screenx, uint screeny, Color color); /*直接修改某个位置的颜色*/ void ssr_present(); diff --git a/src/core/rasterizer.c b/src/core/rasterizer.c index 0c8c6eb..0e5b785 100644 --- a/src/core/rasterizer.c +++ b/src/core/rasterizer.c @@ -73,51 +73,88 @@ void ssrR_center(Vec2* A, Vec2* B, Vec2* C, Vec2* out) { out->y = k * (A->y + B->y + C->y); } -/* -** clipc 按列排放的三角形三个顶点的齐次裁剪坐标 -** program shader程序 -*/ +static void puttriangle(Vec2* A, Vec2* B, Vec2* C, Color c) { + ssr_assert(A && B && C); + ssrR_putline(A->x, A->y, B->x, B->y, c); + ssrR_putline(A->x, A->y, C->x, C->y, c); + ssrR_putline(C->x, C->y, B->x, B->y, c); +} + +#define discardif(condition) if(condition) continue + static Vec3 SA, SB, SC; // screen coords static Vec3 bcp; // 重心坐标 -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, Vert* A, Vert* B, Vert* C, Program* program, UniformCollection* uniforms) { ssr_assert(CA && CB && CC && program); + vec4_dividew(CA, &SA); ssrU_viewport(&SA, &SA); vec4_dividew(CB, &SB); ssrU_viewport(&SB, &SB); vec4_dividew(CC, &SC); ssrU_viewport(&SC, &SC); - /*根据屏幕空间的y值排序, A的y最小,B居中,C最大*/ + + //puttriangle(&SA, &SB, &SC, 0xffff0000); + //return; + Vec3 *sa = &SA, *sb = &SB, *sc = &SC, *tmp; Vec4* v4tmp; Vert* vtemp; - if (sb->y < sa->y) { sa = &SB; sb = &SA; v4tmp = CA; CA = CB; CB = v4tmp; vtemp = A; A = B; B = vtemp; } - if (sc->y < sb->y) { tmp = sc; sc = sb; sb = tmp; v4tmp = CC; CC = CB; CB = v4tmp; vtemp = B; B = C; C = vtemp; } - if (sc->y < sa->y) { tmp = sc; sc = sa; sa = tmp; v4tmp = CC; CC = CA; CA = v4tmp; vtemp = C; C = A; A = vtemp; } +#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); } +#undef swap - float invkAC = (SC.x - SA.x) / (SC.y - SA.y + EPSILON); - float invkAB = (SB.x - SA.x) / (SB.y - SA.y + EPSILON); - float invkBC = (SC.x - SB.x) / (SC.y - SB.y + EPSILON); + Vec2 AB = {sb->x - sa->x, sb->y - sa->y}, AC = { sc->x - sa->x, sc->y - sa->y }; + int order = (AB.x * AC.y - AC.x * AB.y) > 0 ? 1 : -1; /*1代表B在AC上方*/ - int order = 1; if (((sb->y - sa->y) / (sb->x - sa->x) - invkAC) * invkAC > 0) { order = -1; } + float invkAC = (sc->x - sa->x) / (sc->y - sa->y + EPSILON); + float invkAB = (sb->x - sa->x) / (sb->y - sa->y + EPSILON); + float invkBC = (sc->x - sb->x) / (sc->y - sb->y + EPSILON); FragmentShaderIn in = {A, B, C, 0}; Color color; - Vec2 l, r, p; - float depth; Vec3 cdepth = {SA.z, SB.z, SC.z}; + float from, to; /*scan line*/ + Vec2 p; + float depth; Vec3 cdepth = {sa->z, sb->z, sc->z}; float CAw = 1.f / CA->w, CBw = 1.f / CB->w, CCw = 1.f / CC->w; - for (p.y = sa->y; p.y <= sc->y; ++p.y) { - l.y = p.y; - r.y = p.y; - if (compare(SC.y, SA.y)) r.x = sc->x; - else r.x = sa->x + invkAC * (p.y - sa->y); /*AC*/ - if (p.y <= sb->y) { - if (compare(SB.y, SA.y)) l.x = sb->x; - else l.x = sa->x + invkAB * (p.y - sa->y); - } else { - if (compare(SC.y, SB.y)) l.x = sc->x; - else l.x = sb->x + invkBC * (p.y - sb->y); + for (p.y = sa->y; p.y < sb->y; ++p.y) { + from = (int)(invkAC * (p.y - sa->y) + sa->x); + to = (int)(invkAB * (p.y - sa->y) + sa->x); + for (p.x = from; order * (p.x - to) <= 0; p.x += order) { + + if (!ssrR_barycentric(sa, sb, sc, &p, &bcp)) { + continue; /*discard fragment*/ + } + + discardif(bcp.x < 0 || bcp.y < 0 || bcp.z < 0); + + bcp.x *= CAw; bcp.y *= CBw; bcp.z *= CCw; + vec3_scale(&bcp, 1.f / (bcp.x + bcp.y + bcp.z), &bcp); + /*depth test*/ + depth = vec3_dot(&bcp, &cdepth) * 0.5f + 0.5f; + if (!ssr_testdepthf(p.x, p.y, depth)) { + continue; /*discard fragment*/ + } + /*enter fragment shader*/ + in.bc = &bcp; + program->fragmentshader(uniforms, &in, &color); + ssr_putpoint(p.x, p.y, color); + } + } + for (p.y = sb->y; p.y <= sc->y; ++p.y) { + if (p.y == sb->y && sb->y == sc->y) { + from = sc->x; + to = sb->x; } - for (p.x = l.x; order * (r.x - p.x) >= 0; p.x += order) { + else { + from = (int)(invkAC * (p.y - sa->y) + sa->x); + to = (int)(invkBC * (p.y - sb->y) + sb->x); + } + for (p.x = from; order * (p.x - to) <= 0; p.x += order) { /*计算线性的(齐次裁剪空间)的重心坐标,分三步*/ if (!ssrR_barycentric(sa, sb, sc, &p, &bcp)) { continue; /*discard fragment*/ } + + discardif(bcp.x < 0 || bcp.y < 0 || bcp.z < 0); + bcp.x *= CAw; bcp.y *= CBw; bcp.z *= CCw; vec3_scale(&bcp, 1.f / (bcp.x + bcp.y + bcp.z), &bcp); /*depth test*/ @@ -134,47 +171,67 @@ void _ssrR_triangle(Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Pro } static Vec2 bboxmin, bboxmax; -void ssrR_triangle(Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Program* program, UniformCollection* uniforms) { - ssr_assert(CA && CB && CC && program); +void _ssrR_triangle(Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Program* program, UniformCollection* uniforms) { + ssr_assert(CA && CB && CC && program && A && B && C && uniforms); + vec4_dividew(CA, &SA); ssrU_viewport(&SA, &SA); vec4_dividew(CB, &SB); ssrU_viewport(&SB, &SB); vec4_dividew(CC, &SC); ssrU_viewport(&SC, &SC); - bboxmin.x = min(SA.x, min(SB.x, SC.x)); - bboxmax.x = max(SA.x, max(SB.x, SC.x)); - bboxmin.y = min(SA.y, min(SB.y, SC.y)); - bboxmax.y = max(SA.y, max(SB.y, SC.y)); + + bboxmin.x = (int)min(SA.x, min(SB.x, SC.x)); /*这里一定要int,确保没有缝隙*/ + bboxmax.x = (int)max(SA.x, max(SB.x, SC.x)); + bboxmin.y = (int)min(SA.y, min(SB.y, SC.y)); + bboxmax.y = (int)max(SA.y, max(SB.y, SC.y)); + float CAw = 1.f / CA->w, CBw = 1.f / CB->w, CCw = 1.f / CC->w; float depth; Vec3 cdepth = { SA.z, SB.z, SC.z }; FragmentShaderIn in = { A, B, C, 0 }; - Vec2 p; Color color; + Vec2 p; + Color color; + 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 dontdiscad; for (p.y = bboxmin.y; p.y <= bboxmax.y; ++p.y) { + s[1].z = SA.y - p.y; for (p.x = bboxmin.x; p.x <= bboxmax.x; ++p.x) { - /*计算线性的(齐次裁剪空间)的重心坐标,分三步*/ - if (!ssrR_barycentric(&SA, &SB, &SC, &p, &bcp)) { - continue; /*discard fragment*/ - } - if (bcp.x < 0 || bcp.y < 0 || bcp.z < 0) { - continue; /*discard fragment*/ - } + /*计算线性的(齐次裁剪空间)的重心坐标*/ + 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; + bcp.x = 1.f - (u.x + u.y) * u.z; + bcp.y = u.y * u.z; + bcp.z = u.x * u.z; + + discardif(bcp.x < 0 || bcp.y < 0 || bcp.z < 0); + bcp.x *= CAw; bcp.y *= CBw; bcp.z *= CCw; vec3_scale(&bcp, 1.f / (bcp.x + bcp.y + bcp.z), &bcp); - /*深度测试*/ + /*depth test*/ if (ssr_isenable(ENABLEMASK_DEPTHTEST)) { depth = vec3_dot(&bcp, &cdepth) * 0.5f + 0.5f; - if (!ssr_testdepthf(p.x, p.y, depth)) { - continue; /*discard fragment*/ - } + discardif(!ssr_testdepthf(p.x, p.y, depth)); } /*enter fragment shader*/ in.bc = &bcp; - bool discad = program->fragmentshader(uniforms, &in, &color); - if (!discad) + dontdiscad = program->fragmentshader(uniforms, &in, &color); + if (dontdiscad) ssr_putpoint(p.x, p.y, color); } } - //ssrR_putline(SA.x, SA.y, SB.x, SB.y, 0xffff0000); - //ssrR_putline(SA.x, SA.y, SC.x, SC.y, 0xffff0000); - //ssrR_putline(SC.x, SC.y, SB.x, SB.y, 0xffff0000); -}
\ No newline at end of file +} + +void ssrR_line(Vec4* CA, Vec4* CB, Vert* A, Vert* B, Program* program, UniformCollection* uniforms) { + ssr_assert(CA && CB && program && A && B && uniforms); + +} + +void ssrR_point(Vec4* CA, Vert* A, Program* program, UniformCollection* uniforms) { + ssr_assert(CA && program && A && uniforms); + +} diff --git a/src/core/shader.h b/src/core/shader.h index 8da8ae3..15dfc26 100644 --- a/src/core/shader.h +++ b/src/core/shader.h @@ -18,10 +18,10 @@ typedef struct UniformCollection { Vec2 var_vec2[8]; } UniformCollection; -#define ssrum4(i) (uniforms->var_mat4[i]) -#define ssruv2(i) (uniforms->var_vec2[i]) -#define ssruv3(i) (uniforms->var_vec3[i]) -#define ssruv4(i) (uniforms->var_vec4[i]) +#define UM4(i) (&uniforms->var_mat4[i]) +#define UV2(i) (&uniforms->var_vec2[i]) +#define UV3(i) (&uniforms->var_vec3[i]) +#define UV4(i) (&uniforms->var_vec4[i]) typedef struct VertexShaderIn { Vert* vertex; @@ -46,6 +46,11 @@ void ssrS_bcpvec2(Vec3* bc, Vec2* A, Vec2* B, Vec2* C, Vec2* out); void ssrS_bcpvec3(Vec3* bc, Vec3* A, Vec3* B, Vec3* C, Vec3* out); void ssrS_bcpvec4(Vec3* bc, Vec4* A, Vec4* B, Vec4* C, Vec4* out); +void ssrS_lerpcolor(float t, Color A, Color B, Color* out); +void ssrS_lerpvec2(float t, Vec2* A, Vec2* B, Vec2* out); +void ssrS_lerpvec3(float t, Vec3* A, Vec3* B, Vec3* out); +void ssrS_lerpvec4(float t, Vec4* A, Vec4* B, Vec4* out); + /* ** 顶点数据外,还提供额外的寄存器 */ @@ -65,19 +70,12 @@ typedef struct Register { }; } Register; -void ssrS_setregvec4_01i(uint idx, Vec4* value); -void ssrS_setregvec4_02i(uint idx, Vec4* value); -void ssrS_setregvec2_01i(uint idx, Vec2* value); -void ssrS_setregvec2_02i(uint idx, Vec2* value); -void ssrS_setregvec3_01i(uint idx, Vec3* value); -void ssrS_setregvec3_02i(uint idx, Vec3* value); - -Vec4* ssrS_getregvec4_01i(uint idx); -Vec4* ssrS_getregvec4_02i(uint idx); -Vec2* ssrS_getregvec2_01i(uint idx); -Vec2* ssrS_getregvec2_02i(uint idx); -Vec3* ssrS_getregvec3_01i(uint idx); -Vec3* ssrS_getregvec3_02i(uint idx); +void ssrS_setregvec4_01(Vert* vert, Vec4* value); +void ssrS_setregvec4_02(Vert* vert, Vec4* value); +void ssrS_setregvec2_01(Vert* vert, Vec2* value); +void ssrS_setregvec2_02(Vert* vert, Vec2* value); +void ssrS_setregvec3_01(Vert* vert, Vec3* value); +void ssrS_setregvec3_02(Vert* vert, Vec3* value); Vec4* ssrS_getregvec4_01(Vert* vert); Vec4* ssrS_getregvec4_02(Vert* vert); |