diff options
author | chai <chaifix@163.com> | 2019-12-08 00:23:50 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-12-08 00:23:50 +0800 |
commit | 3df29dc54c509c983dc8a0e23eab4160d48144f2 (patch) | |
tree | d8c5287c9979e731e373e7a1481aadd79d3f071b /src/core | |
parent | 8e684dc0c76708e3174f005aebcaabc144b85500 (diff) |
+clipping
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/device.c | 136 | ||||
-rw-r--r-- | src/core/device.h | 2 | ||||
-rw-r--r-- | src/core/mem.h | 30 | ||||
-rw-r--r-- | src/core/rasterizer.c | 226 | ||||
-rw-r--r-- | src/core/rasterizer.h | 8 | ||||
-rw-r--r-- | src/core/shader.c | 261 | ||||
-rw-r--r-- | src/core/shader.h | 161 | ||||
-rw-r--r-- | src/core/tris.c | 0 | ||||
-rw-r--r-- | src/core/tris.h | 17 | ||||
-rw-r--r-- | src/core/vert.c | 30 | ||||
-rw-r--r-- | src/core/vert.h | 35 |
11 files changed, 694 insertions, 212 deletions
diff --git a/src/core/device.c b/src/core/device.c index ad640c6..f6b1a4e 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -1,5 +1,7 @@ #include "device.h" #include "rasterizer.h" +#include "clip.h" +#include "shader.h" #include "../util/assert.h" ssr_Config config; @@ -34,7 +36,7 @@ struct { uint* zbuffer; /* 顶点数据 */ - Vert** verts; uint nverts; + Vert* verts; uint nverts; uint* indices; uint nprims; /* shader program */ @@ -246,7 +248,7 @@ void ssrU_viewport(Vec2* p, Vec2* out) { //out->y = (int)((1 - p->y) * (halfh - 0.5f)); } -void ssr_bindvertices(Vert** verts, int nverts, uint* indices, int nprims) { +void ssr_bindvertices(Vert* verts, int nverts, uint* indices, int nprims) { ssr_assert(verts && indices); state.verts = verts; state.nverts = nverts; @@ -263,69 +265,119 @@ void ssr_unuseprogram() { state.program = NULL; } -static Vec4* homos = NULL; -static uint tri[3]; -static Vec3 ab, ac; -static Mat4 mvp, mv; +VertexShaderIn ssr_vert_in; +FragmentShaderIn ssr_frag_in; + +static struct { + Vec4* coords; + uint length; +} clipping_buffer; + +static ClippedBuffer clipped_buffer; /*clipping result*/ + void ssr_draw(ssr_PrimitiveType primitive) { ssr_assert(state.verts && state.indices); + static Mat4 mvp, mv; + ssr_getmvp(&mvp); ssr_getmv(&mv); - state.uniforms.model = &GETMATRIX(MATRIX_MODEL); - state.uniforms.view = &GETMATRIX(MATRIX_VIEW); + state.uniforms.model = &GETMATRIX(MATRIX_MODEL); + state.uniforms.view = &GETMATRIX(MATRIX_VIEW); state.uniforms.projection = &GETMATRIX(MATRIX_PROJECTION); - state.uniforms.mvp = &mvp; - state.uniforms.mv = &mv; + state.uniforms.mvp = &mvp; + state.uniforms.mv = &mv; + + uint varying_flag = state.program->varying_flag; + bool use_extra_varyings = varying_flag & VARYING_EXTRA; - VertexShaderIn vertIn = { NULL }; - if (!homos) - homos = ssrM_newvector(Vec4, state.nverts); + /*prepare registers if necessary*/ + if (use_extra_varyings) { + ssrS_setregisters(varying_flag, state.nverts); + } + + /*resize clipping coords buffer*/ + if (clipping_buffer.length < state.nverts) { + ssrM_resizevector( + Vec4, + clipping_buffer.coords, + clipping_buffer.length, + state.nverts, + FALSE + ); + } + + /*vertex operation*/ for (int i = 0; i < state.nverts; ++i) { - Vert* vert = state.verts[i]; - vertIn.vertex = vert; - state.program->vertexshader(&state.uniforms, &vertIn, &homos[i]); + Vert* vert = &state.verts[i]; + ssr_vert_in.vertex = vert; + /*set register pointers*/ + if (use_extra_varyings) { + ssrS_setupregisterpoints(varying_flag, vert->index); + } + state.program->vertexshader(&state.uniforms, &ssr_vert_in, &clipping_buffer.coords[i]); } + /*set register pointer to frag-in*/ + if (use_extra_varyings) { + ssrS_setregtofragin(varying_flag, &ssr_frag_in); + } + + /*primitive assembly*/ if (primitive == PRIMITIVE_TRIANGLE) { + uint i0, i1, i2; + Vec4 *h0, *h1, *h2; + Vert *v0, *v1, *v2; for (int i = 0; i < state.nprims; ++i) { - tri[0] = state.indices[i * 3]; - tri[1] = state.indices[i * 3 + 1]; - tri[2] = state.indices[i * 3 + 2]; + i0 = state.indices[i * 3]; + i1 = state.indices[i * 3 + 1]; + i2 = state.indices[i * 3 + 2]; + + h0 = &clipping_buffer.coords[i0], + h1 = &clipping_buffer.coords[i1], + h2 = &clipping_buffer.coords[i2]; - /* back face culling */ + v0 = &state.verts[i0]; + v1 = &state.verts[i1]; + v2 = &state.verts[i2]; + + /*back face culling*/ 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; /*在屏幕空间做背面剔除*/ + float w0 = 1 / h0->w, w1 = 1 / h1->w, w2 = 1 / h2->w; + Vec3 ab, ac; + 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; + if (ab.x * ac.y - ab.y * ac.x <= 0) + continue; /*cull*/ + } + + /*clipping*/ + bool clipped = clip_triangle(h0, h1, h2, v0, v1, v2, varying_flag, &clipped_buffer); + + /*rasterization*/ + if (!clipped) { + ssrR_triangle(h0, h1, h2, v0, v1, v2, TRUE, NULL, NULL, NULL, state.program, &state.uniforms); + } else { + if (clipped_buffer.count >= 3) { + ClippedVert* vt0 = &clipped_buffer.vertices[0], *vt1, *vt2; + for (int i = 1; i <= clipped_buffer.count - 2; ++i) { /*0->i->i+1*/ + vt1 = &clipped_buffer.vertices[i]; + vt2 = &clipped_buffer.vertices[i + 1]; + h0 = &vt0->clip_coord; h1 = &vt1->clip_coord; h2 = &vt2->clip_coord; + v0 = &vt0->vertex; v1 = &vt1->vertex; v2 = &vt2->vertex; + ssrR_triangle(h0, h1, h2, v0, v1, v2, FALSE, vt0, vt1, vt2, state.program, &state.uniforms); + } } } - /* render triangle */ - ssrR_triangle( - &homos[tri[0]], - &homos[tri[1]], - &homos[tri[2]], - state.verts[tri[0]], - state.verts[tri[1]], - state.verts[tri[2]], - state.program, - &state.uniforms - ); } - } - else if (primitive == PRIMITIVE_POINT) { - - } - else if (primitive == PRIMITIVE_LINE) { + } else if (primitive == PRIMITIVE_POINT) { + } else if (primitive == PRIMITIVE_LINE) { + } - //ssrM_free(homos); } void ssr_setuniformmat4(uint idx, Mat4* src) { diff --git a/src/core/device.h b/src/core/device.h index 1350105..10db509 100644 --- a/src/core/device.h +++ b/src/core/device.h @@ -64,7 +64,7 @@ void ssr_disable(uint mask); bool ssr_isenable(uint mask); /* 绑定顶点数据 */ -void ssr_bindvertices(Vert** verts, int nverts, uint* indices, int nprims); +void ssr_bindvertices(Vert* verts, int nverts, uint* indices, int nprims); void ssr_unbindvertices(); void ssr_useprogram(Program* program); diff --git a/src/core/mem.h b/src/core/mem.h index 1a763f9..e6cc714 100644 --- a/src/core/mem.h +++ b/src/core/mem.h @@ -3,10 +3,6 @@ #include <memory.h> -/* -** 内存分配相关 -*/ - void ssrM_freemem(); void ssrM_realloc(); @@ -15,6 +11,32 @@ void ssrM_realloc(); #define ssrM_newvector(T, c) ((T*)calloc(c, sizeof(T))) #define ssrM_free(obj) free(obj) +/*vector扩容两倍*/ +#define ssrM_scalevector(T, v, curlen, copy) \ +do{\ +ssr_assert(v);\ +T* t = (T*)calloc(curlen << 1, sizeof(T));\ +if (copy) memcpy(t, v, curlen * sizeof(T));\ +free(v);\ +v = t;\ +}while(0) + +/*重设vector容量*/ +#define ssrM_resizevector(T, v, curlen, tarlen, copy) \ +do {\ +T* t = (T*)calloc(tarlen, sizeof(T));\ +if (v && copy) memcpy(t, v, min(curlen, tarlen)* sizeof(T));\ +if (v) free(v);\ +v = t;\ +curlen = tarlen;\ +}while(0) + +#define ssrM_rescalevector(T, v, curlen, tarlen, copy)\ +do{\ +if (curlen >= tarlen) {}\ +else { ssrM_resizevector(T, v, curlen, tarlen, copy); }\ +} while (0) + #define cast(v, T) (*(T*)(&v)) #endif
\ No newline at end of file diff --git a/src/core/rasterizer.c b/src/core/rasterizer.c index 0e5b785..5503e69 100644 --- a/src/core/rasterizer.c +++ b/src/core/rasterizer.c @@ -82,18 +82,21 @@ static void puttriangle(Vec2* A, Vec2* B, Vec2* C, Color 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) { +extern FragmentShaderIn ssr_frag_in; + +void ssrR_triangle(Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, bool from_reg, ClippedVert* CVA, ClippedVert* CVB, ClippedVert* CVC, Program* program, UniformCollection* uniforms) { ssr_assert(CA && CB && CC && program); + static Vec3 SA, SB, SC; + static Vec3 bcp; + 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; - +/* + puttriangle(&SA, &SB, &SC, 0xffff0000); + return; +*/ Vec3 *sa = &SA, *sb = &SB, *sc = &SC, *tmp; Vec4* v4tmp; Vert* 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); } @@ -102,83 +105,174 @@ void ssrR_triangle(Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Prog #undef swap 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 = (AB.x * AC.y - AC.x * AB.y) > 0 ? 1 : -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; - float from, to; /*scan line*/ + float from, to; Vec2 p; - float depth; Vec3 cdepth = {sa->z, sb->z, sc->z}; + float depth; float CAw = 1.f / CA->w, CBw = 1.f / CB->w, CCw = 1.f / CC->w; - 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*/ - } + + uint varying_flag = program->varying_flag; + +#define DO_INTERPOLATION \ + if (varying_flag & VARYING_BASIC) { \ + if (varying_flag & VARYING_POSITION) ssrS_bcpvec3(&bcp, &A->position, &B->position, &C->position, &ssr_frag_in.position); \ + if (varying_flag & VARYING_NORMAL) ssrS_bcpvec3(&bcp, &A->normal, &B->normal, &C->normal, &ssr_frag_in.normal); \ + if (varying_flag & VARYING_TANGENT) ssrS_bcpvec3(&bcp, &A->tangent, &B->tangent, &C->tangent, &ssr_frag_in.tangent); \ + if (varying_flag & VARYING_TEXCOORD) ssrS_bcpvec2(&bcp, &A->texcoord, &B->texcoord, &C->texcoord, &ssr_frag_in.texcoord); \ + if (varying_flag & VARYING_JOINT) ssrS_bcpvec4(&bcp, &A->joint, &B->joint, &C->joint, &ssr_frag_in.joint); \ + if (varying_flag & VARYING_WEIGHT) ssrS_bcpvec4(&bcp, &A->weight, &B->weight, &C->weight, &ssr_frag_in.weight); \ + if (varying_flag & VARYING_COLOR) ssrS_bcpcolor(&bcp, A->color, B->color, C->color, &ssr_frag_in.color); \ + } \ + if (from_reg) { /*extra varying*/ \ + uint i_a = A->index, i_b = B->index, i_c = C->index; \ + if (varying_flag && VARYING_NUM) { \ + if (varying_flag & VARYING_NUM_00) reg_num_00 = ssrS_bcpnum(&bcp, reg_num[0].num[i_a], reg_num[0].num[i_b], reg_num[0].num[i_c], &ssr_frag_in.num[0]); \ + if (varying_flag & VARYING_NUM_01) reg_num_01 = ssrS_bcpnum(&bcp, reg_num[1].num[i_a], reg_num[1].num[i_b], reg_num[1].num[i_c], &ssr_frag_in.num[1]); \ + if (varying_flag & VARYING_NUM_02) reg_num_02 = ssrS_bcpnum(&bcp, reg_num[2].num[i_a], reg_num[2].num[i_b], reg_num[2].num[i_c], &ssr_frag_in.num[2]); \ + if (varying_flag & VARYING_NUM_03) reg_num_03 = ssrS_bcpnum(&bcp, reg_num[3].num[i_a], reg_num[3].num[i_b], reg_num[3].num[i_c], &ssr_frag_in.num[3]); \ + } \ + if (varying_flag && VARYING_V2) { \ + if (varying_flag & VARYING_V2_00) reg_v2_00 = ssrS_bcpvec2(&bcp, ®_v2[0].v2[i_a], ®_v2[0].v2[i_b], ®_v2[0].v2[i_c], &ssr_frag_in.v2[0]); \ + if (varying_flag & VARYING_V2_01) reg_v2_01 = ssrS_bcpvec2(&bcp, ®_v2[1].v2[i_a], ®_v2[1].v2[i_b], ®_v2[1].v2[i_c], &ssr_frag_in.v2[1]); \ + if (varying_flag & VARYING_V2_02) reg_v2_02 = ssrS_bcpvec2(&bcp, ®_v2[2].v2[i_a], ®_v2[2].v2[i_b], ®_v2[2].v2[i_c], &ssr_frag_in.v2[2]); \ + if (varying_flag & VARYING_V2_03) reg_v2_03 = ssrS_bcpvec2(&bcp, ®_v2[3].v2[i_a], ®_v2[3].v2[i_b], ®_v2[3].v2[i_c], &ssr_frag_in.v2[3]); \ + if (varying_flag & VARYING_V2_04) reg_v2_04 = ssrS_bcpvec2(&bcp, ®_v2[4].v2[i_a], ®_v2[4].v2[i_b], ®_v2[4].v2[i_c], &ssr_frag_in.v2[4]); \ + if (varying_flag & VARYING_V2_05) reg_v2_05 = ssrS_bcpvec2(&bcp, ®_v2[5].v2[i_a], ®_v2[5].v2[i_b], ®_v2[5].v2[i_c], &ssr_frag_in.v2[5]); \ + } \ + if (varying_flag && VARYING_V3) { \ + if (varying_flag & VARYING_V3_00) reg_v3_00 = ssrS_bcpvec3(&bcp, ®_v3[0].v3[i_a], ®_v3[0].v3[i_b], ®_v3[0].v3[i_c], &ssr_frag_in.v3[0]); \ + if (varying_flag & VARYING_V3_01) reg_v3_01 = ssrS_bcpvec3(&bcp, ®_v3[1].v3[i_a], ®_v3[1].v3[i_b], ®_v3[1].v3[i_c], &ssr_frag_in.v3[1]); \ + if (varying_flag & VARYING_V3_02) reg_v3_02 = ssrS_bcpvec3(&bcp, ®_v3[2].v3[i_a], ®_v3[2].v3[i_b], ®_v3[2].v3[i_c], &ssr_frag_in.v3[2]); \ + if (varying_flag & VARYING_V3_03) reg_v3_03 = ssrS_bcpvec3(&bcp, ®_v3[3].v3[i_a], ®_v3[3].v3[i_b], ®_v3[3].v3[i_c], &ssr_frag_in.v3[3]); \ + if (varying_flag & VARYING_V3_04) reg_v3_04 = ssrS_bcpvec3(&bcp, ®_v3[4].v3[i_a], ®_v3[4].v3[i_b], ®_v3[4].v3[i_c], &ssr_frag_in.v3[4]); \ + if (varying_flag & VARYING_V3_05) reg_v3_05 = ssrS_bcpvec3(&bcp, ®_v3[5].v3[i_a], ®_v3[5].v3[i_b], ®_v3[5].v3[i_c], &ssr_frag_in.v3[5]); \ + if (varying_flag & VARYING_V3_06) reg_v3_06 = ssrS_bcpvec3(&bcp, ®_v3[6].v3[i_a], ®_v3[6].v3[i_b], ®_v3[6].v3[i_c], &ssr_frag_in.v3[6]); \ + if (varying_flag & VARYING_V3_07) reg_v3_07 = ssrS_bcpvec3(&bcp, ®_v3[7].v3[i_a], ®_v3[7].v3[i_b], ®_v3[7].v3[i_c], &ssr_frag_in.v3[7]); \ + } \ + if (varying_flag && VARYING_V4) { \ + if (varying_flag & VARYING_V4_00) reg_v4_00 = ssrS_bcpvec4(&bcp, ®_v4[0].v4[i_a], ®_v4[0].v4[i_b], ®_v4[0].v4[i_c], &ssr_frag_in.v4[0]); \ + if (varying_flag & VARYING_V4_01) reg_v4_01 = ssrS_bcpvec4(&bcp, ®_v4[1].v4[i_a], ®_v4[1].v4[i_b], ®_v4[1].v4[i_c], &ssr_frag_in.v4[1]); \ + if (varying_flag & VARYING_V4_02) reg_v4_02 = ssrS_bcpvec4(&bcp, ®_v4[2].v4[i_a], ®_v4[2].v4[i_b], ®_v4[2].v4[i_c], &ssr_frag_in.v4[2]); \ + if (varying_flag & VARYING_V4_03) reg_v4_03 = ssrS_bcpvec4(&bcp, ®_v4[3].v4[i_a], ®_v4[3].v4[i_b], ®_v4[3].v4[i_c], &ssr_frag_in.v4[3]); \ + if (varying_flag & VARYING_V4_04) reg_v4_04 = ssrS_bcpvec4(&bcp, ®_v4[4].v4[i_a], ®_v4[4].v4[i_b], ®_v4[4].v4[i_c], &ssr_frag_in.v4[4]); \ + if (varying_flag & VARYING_V4_05) reg_v4_05 = ssrS_bcpvec4(&bcp, ®_v4[5].v4[i_a], ®_v4[5].v4[i_b], ®_v4[5].v4[i_c], &ssr_frag_in.v4[5]); \ + } \ + } else { \ + if (varying_flag && VARYING_NUM) { \ + if (varying_flag & VARYING_NUM_00) reg_num_00 = ssrS_bcpnum(&bcp, CVA->num[0], CVB->num[0], CVC->num[0], &ssr_frag_in.num[0]); \ + if (varying_flag & VARYING_NUM_01) reg_num_01 = ssrS_bcpnum(&bcp, CVA->num[1], CVB->num[1], CVC->num[1], &ssr_frag_in.num[1]); \ + if (varying_flag & VARYING_NUM_02) reg_num_02 = ssrS_bcpnum(&bcp, CVA->num[2], CVB->num[2], CVC->num[2], &ssr_frag_in.num[2]); \ + if (varying_flag & VARYING_NUM_03) reg_num_03 = ssrS_bcpnum(&bcp, CVA->num[3], CVB->num[3], CVC->num[3], &ssr_frag_in.num[3]); \ + } \ + if (varying_flag && VARYING_V2) { \ + if (varying_flag & VARYING_V2_00) reg_v2_00 = ssrS_bcpvec2(&bcp, &CVA->v2[0], &CVB->v2[0], &CVC->v2[0], &ssr_frag_in.v2[0]); \ + if (varying_flag & VARYING_V2_01) reg_v2_01 = ssrS_bcpvec2(&bcp, &CVA->v2[1], &CVB->v2[1], &CVC->v2[1], &ssr_frag_in.v2[1]); \ + if (varying_flag & VARYING_V2_02) reg_v2_02 = ssrS_bcpvec2(&bcp, &CVA->v2[2], &CVB->v2[2], &CVC->v2[2], &ssr_frag_in.v2[2]); \ + if (varying_flag & VARYING_V2_03) reg_v2_03 = ssrS_bcpvec2(&bcp, &CVA->v2[3], &CVB->v2[3], &CVC->v2[3], &ssr_frag_in.v2[3]); \ + if (varying_flag & VARYING_V2_04) reg_v2_04 = ssrS_bcpvec2(&bcp, &CVA->v2[4], &CVB->v2[4], &CVC->v2[4], &ssr_frag_in.v2[4]); \ + if (varying_flag & VARYING_V2_05) reg_v2_05 = ssrS_bcpvec2(&bcp, &CVA->v2[5], &CVB->v2[5], &CVC->v2[5], &ssr_frag_in.v2[5]); \ + } \ + if (varying_flag && VARYING_V3) { \ + if (varying_flag & VARYING_V3_00) reg_v3_00 = ssrS_bcpvec3(&bcp, &CVA->v3[0], &CVB->v3[0], &CVC->v3[0], &ssr_frag_in.v3[0]); \ + if (varying_flag & VARYING_V3_01) reg_v3_01 = ssrS_bcpvec3(&bcp, &CVA->v3[1], &CVB->v3[1], &CVC->v3[1], &ssr_frag_in.v3[1]); \ + if (varying_flag & VARYING_V3_02) reg_v3_02 = ssrS_bcpvec3(&bcp, &CVA->v3[2], &CVB->v3[2], &CVC->v3[2], &ssr_frag_in.v3[2]); \ + if (varying_flag & VARYING_V3_03) reg_v3_03 = ssrS_bcpvec3(&bcp, &CVA->v3[3], &CVB->v3[3], &CVC->v3[3], &ssr_frag_in.v3[3]); \ + if (varying_flag & VARYING_V3_04) reg_v3_04 = ssrS_bcpvec3(&bcp, &CVA->v3[4], &CVB->v3[4], &CVC->v3[4], &ssr_frag_in.v3[4]); \ + if (varying_flag & VARYING_V3_05) reg_v3_05 = ssrS_bcpvec3(&bcp, &CVA->v3[5], &CVB->v3[5], &CVC->v3[5], &ssr_frag_in.v3[5]); \ + if (varying_flag & VARYING_V3_06) reg_v3_06 = ssrS_bcpvec3(&bcp, &CVA->v3[6], &CVB->v3[6], &CVC->v3[6], &ssr_frag_in.v3[6]); \ + if (varying_flag & VARYING_V3_07) reg_v3_07 = ssrS_bcpvec3(&bcp, &CVA->v3[7], &CVB->v3[7], &CVC->v3[7], &ssr_frag_in.v3[7]); \ + } \ + if (varying_flag && VARYING_V4) { \ + if (varying_flag & VARYING_V4_00) reg_v4_00 = ssrS_bcpvec4(&bcp, &CVA->v4[0], &CVB->v4[0], &CVC->v4[0], &ssr_frag_in.v4[0]); \ + if (varying_flag & VARYING_V4_01) reg_v4_01 = ssrS_bcpvec4(&bcp, &CVA->v4[1], &CVB->v4[1], &CVC->v4[1], &ssr_frag_in.v4[1]); \ + if (varying_flag & VARYING_V4_02) reg_v4_02 = ssrS_bcpvec4(&bcp, &CVA->v4[2], &CVB->v4[2], &CVC->v4[2], &ssr_frag_in.v4[2]); \ + if (varying_flag & VARYING_V4_03) reg_v4_03 = ssrS_bcpvec4(&bcp, &CVA->v4[3], &CVB->v4[3], &CVC->v4[3], &ssr_frag_in.v4[3]); \ + if (varying_flag & VARYING_V4_04) reg_v4_04 = ssrS_bcpvec4(&bcp, &CVA->v4[4], &CVB->v4[4], &CVC->v4[4], &ssr_frag_in.v4[4]); \ + if (varying_flag & VARYING_V4_05) reg_v4_05 = ssrS_bcpvec4(&bcp, &CVA->v4[5], &CVB->v4[5], &CVC->v4[5], &ssr_frag_in.v4[5]); \ + } \ + } - discardif(bcp.x < 0 || bcp.y < 0 || bcp.z < 0); + 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; + +#define RENDER_TRIANGLE \ + for (p.y = FROM->y; p.y < TO->y; ++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; \ + 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); \ + /*perspective correction*/ \ + bcp.x *= CAw; bcp.y *= CBw; bcp.z *= CCw; \ + vec3_scale(&bcp, 1.f / (bcp.x + bcp.y + bcp.z), &bcp); \ + /*depth test*/ \ + depth = (bcp.x*sa->z+bcp.y*sb->z+bcp.z*sc->z) * 0.5f + 0.5f; \ + discardif(!ssr_testdepthf(p.x, p.y, depth)); \ + /*set varying variables*/ \ + DO_INTERPOLATION \ + if(program->fragmentshader(uniforms, &ssr_frag_in, &color)) \ + ssr_putpoint(p.x, p.y, color); \ + } \ + } - 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); - } +#define FROM sa +#define TO sb +#define FROMK invkAC +#define TOK invkAB +#define SET_FROM_AND_TO \ + from = (int)(invkAC * (p.y - sa->y) + sa->x); \ + to = (int)(invkAB * (p.y - sa->y) + sa->x); \ + + RENDER_TRIANGLE + +#define FROM sb +#define TO sc +#define FROMK invkAC +#define TOK invkBC +#define SET_FROM_AND_TO \ + if (p.y == sb->y && sb->y == sc->y) { \ + from = sc->x; \ + to = sb->x; \ + } \ + else { \ + from = (int)(invkAC * (p.y - sa->y) + sa->x); \ + to = (int)(invkBC * (p.y - sb->y) + sb->x); \ } - 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; - } - 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); + RENDER_TRIANGLE - 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); - } - } +#undef FROM +#undef TO +#undef FROMK +#undef TOK +#undef SET_FROM_AND_TO +#undef RENDER_TRIANGLE } -static Vec2 bboxmin, bboxmax; -void _ssrR_triangle(Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Program* program, UniformCollection* uniforms) { +/*deprecated*/ +/* +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 && 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 = (int)min(SA.x, min(SB.x, SC.x)); /*这里一定要int,确保没有缝隙*/ + bboxmin.x = (int)min(SA.x, min(SB.x, SC.x)); 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)); @@ -195,7 +289,6 @@ void _ssrR_triangle(Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Pro 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) { - /*计算线性的(齐次裁剪空间)的重心坐标*/ s[0].z = SA.x - p.x; vec3_cross(&s[0], &s[1], &u); @@ -211,13 +304,11 @@ void _ssrR_triangle(Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Pro 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; discardif(!ssr_testdepthf(p.x, p.y, depth)); } - /*enter fragment shader*/ in.bc = &bcp; dontdiscad = program->fragmentshader(uniforms, &in, &color); if (dontdiscad) @@ -225,6 +316,7 @@ void _ssrR_triangle(Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Pro } } } +*/ void ssrR_line(Vec4* CA, Vec4* CB, Vert* A, Vert* B, Program* program, UniformCollection* uniforms) { ssr_assert(CA && CB && program && A && B && uniforms); diff --git a/src/core/rasterizer.h b/src/core/rasterizer.h index e35b24a..eceb8c7 100644 --- a/src/core/rasterizer.h +++ b/src/core/rasterizer.h @@ -3,6 +3,7 @@ #include "../math/math.h" #include "shader.h" +#include "clip.h" void ssrR_putline(int x0, int y0, int x1, int y1, Color color); @@ -12,6 +13,11 @@ bool ssrR_barycentric(Vec2* A, Vec2* B, Vec2* C, Vec2* p, Vec3* out); /*计算重心 void ssrR_center(Vec2* A, Vec2* B, Vec2* C, Vec2* out); /*获得重心*/ bool ssrR_ispointintriangle(Vec2* A, Vec2* B, Vec2* C, Vec2* p); -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, + bool from_reg, + ClippedVert* CVA, ClippedVert* CVB, ClippedVert* CVC, + Program* program, UniformCollection* uniforms +); #endif
\ No newline at end of file diff --git a/src/core/shader.c b/src/core/shader.c index fe25408..b5d8407 100644 --- a/src/core/shader.c +++ b/src/core/shader.c @@ -1,8 +1,226 @@ +#include "../math/math.h" #include "shader.h" #include "vert.h" #include "device.h" -void ssrS_bcpcolor(Vec3* bc, Color A, Color B, Color C, Color* out) { +float* reg_num_00; +float* reg_num_01; +float* reg_num_02; +float* reg_num_03; + +Vec2* reg_v2_00; +Vec2* reg_v2_01; +Vec2* reg_v2_02; +Vec2* reg_v2_03; +Vec2* reg_v2_04; +Vec2* reg_v2_05; + +Vec3* reg_v3_00; +Vec3* reg_v3_01; +Vec3* reg_v3_02; +Vec3* reg_v3_03; +Vec3* reg_v3_04; +Vec3* reg_v3_05; +Vec3* reg_v3_06; +Vec3* reg_v3_07; + +Vec4* reg_v4_00; +Vec4* reg_v4_01; +Vec4* reg_v4_02; +Vec4* reg_v4_03; +Vec4* reg_v4_04; +Vec4* reg_v4_05; + +Register reg_num[4] = { + { 0, REGTYPE_NUM, NULL }, + { 0, REGTYPE_NUM, NULL }, + { 0, REGTYPE_NUM, NULL }, + { 0, REGTYPE_NUM, NULL }, +}; + +Register reg_v2[6] = { + { 0, REGTYPE_VEC2, NULL }, + { 0, REGTYPE_VEC2, NULL }, + { 0, REGTYPE_VEC2, NULL }, + { 0, REGTYPE_VEC2, NULL }, + { 0, REGTYPE_VEC2, NULL }, + { 0, REGTYPE_VEC2, NULL }, +}; + +Register reg_v3[8] = { + { 0, REGTYPE_VEC3, NULL }, + { 0, REGTYPE_VEC3, NULL }, + { 0, REGTYPE_VEC3, NULL }, + { 0, REGTYPE_VEC3, NULL }, + { 0, REGTYPE_VEC3, NULL }, + { 0, REGTYPE_VEC3, NULL }, + { 0, REGTYPE_VEC3, NULL }, + { 0, REGTYPE_VEC3, NULL }, +}; + +Register reg_v4[6] = { + { 0, REGTYPE_VEC4, NULL }, + { 0, REGTYPE_VEC4, NULL }, + { 0, REGTYPE_VEC4, NULL }, + { 0, REGTYPE_VEC4, NULL }, + { 0, REGTYPE_VEC4, NULL }, + { 0, REGTYPE_VEC4, NULL }, +}; + +void ssrS_setregisters(uint flag, int capacity) { +#define reg_scale_num(i) \ +if (flag & VARYING_NUM_##i) ssrM_rescalevector(float, reg_num[##i].num, reg_num[##i].length, capacity, FALSE) + +#define reg_scale_v2(i) \ +if (flag & VARYING_V2_##i) ssrM_rescalevector(float, reg_v2[##i].v2, reg_v2[##i].length, capacity, FALSE) + +#define reg_scale_v3(i) \ +if (flag & VARYING_V3_##i) ssrM_rescalevector(float, reg_v3[##i].v3, reg_v3[##i].length, capacity, FALSE) + +#define reg_scale_v4(i) \ +if (flag & VARYING_V4_##i) ssrM_rescalevector(float, reg_v4[##i].v4, reg_v4[##i].length, capacity, FALSE) + + if (!(flag & VARYING_EXTRA)) + return; + if (flag & VARYING_NUM) { + reg_scale_num(00); + reg_scale_num(01); + reg_scale_num(02); + reg_scale_num(03); + } + if (flag & VARYING_V2) { + reg_scale_v2(00); + reg_scale_v2(01); + reg_scale_v2(02); + reg_scale_v2(03); + reg_scale_v2(04); + reg_scale_v2(05); + } + if (flag & VARYING_V3) { + reg_scale_v3(00); + reg_scale_v3(01); + reg_scale_v3(02); + reg_scale_v3(03); + reg_scale_v3(04); + reg_scale_v3(05); + reg_scale_v3(06); + reg_scale_v3(07); + } + if (flag & VARYING_V4) { + reg_scale_v4(00); + reg_scale_v4(01); + reg_scale_v4(02); + reg_scale_v4(03); + reg_scale_v4(04); + reg_scale_v4(05); + } +} + +void ssrS_setupregisterpoints(uint extra_varying_flag, int idx) { +#define set_reg_num_pointer(i)\ + if (extra_varying_flag & VARYING_NUM_##i) reg_num_##i = ®_num[##i].num[idx]; + +#define set_reg_v2_pointer(i)\ + if (extra_varying_flag & VARYING_V2_##i) reg_v2_##i = ®_v2[##i].v2[idx]; + +#define set_reg_v3_pointer(i)\ + if (extra_varying_flag & VARYING_V3_##i) reg_v3_##i = ®_v3[##i].v3[idx]; + +#define set_reg_v4_pointer(i)\ + if (extra_varying_flag & VARYING_V4_##i) reg_v4_##i = ®_v4[##i].v4[idx]; + + if (!(extra_varying_flag & VARYING_EXTRA)) + return; + if (extra_varying_flag & VARYING_NUM) { + set_reg_num_pointer(00); + set_reg_num_pointer(01); + set_reg_num_pointer(02); + set_reg_num_pointer(03); + } + if (extra_varying_flag & VARYING_V2) { + set_reg_v2_pointer(00); + set_reg_v2_pointer(01); + set_reg_v2_pointer(02); + set_reg_v2_pointer(03); + set_reg_v2_pointer(04); + set_reg_v2_pointer(05); + } + if (extra_varying_flag & VARYING_V3) { + set_reg_v3_pointer(00); + set_reg_v3_pointer(01); + set_reg_v3_pointer(02); + set_reg_v3_pointer(03); + set_reg_v3_pointer(04); + set_reg_v3_pointer(05); + set_reg_v3_pointer(06); + set_reg_v3_pointer(07); + } + if (extra_varying_flag & VARYING_V4) { + set_reg_v4_pointer(00); + set_reg_v4_pointer(01); + set_reg_v4_pointer(02); + set_reg_v4_pointer(03); + set_reg_v4_pointer(04); + set_reg_v4_pointer(05); + } +} + +void ssrS_setregtofragin(uint extra_varying_flag, FragmentShaderIn* frag_in){ +#define set_reg_num_pointer_to_fragin(i)\ + if (extra_varying_flag & VARYING_NUM_##i) reg_num_##i = &frag_in->num[##i]; + +#define set_reg_v2_pointer_to_fragin(i)\ + if (extra_varying_flag & VARYING_V2_##i) reg_v2_##i = &frag_in->v2[##i]; + +#define set_reg_v3_pointer_to_fragin(i)\ + if (extra_varying_flag & VARYING_V3_##i) reg_v3_##i = &frag_in->v3[##i]; + +#define set_reg_v4_pointer_to_fragin(i)\ + if (extra_varying_flag & VARYING_V4_##i) reg_v4_##i = &frag_in->v4[##i]; + + if (!(extra_varying_flag & VARYING_EXTRA)) + return; + if (extra_varying_flag & VARYING_NUM) { + set_reg_num_pointer_to_fragin(00); + set_reg_num_pointer_to_fragin(01); + set_reg_num_pointer_to_fragin(02); + set_reg_num_pointer_to_fragin(03); + } + if (extra_varying_flag & VARYING_V2) { + set_reg_v2_pointer_to_fragin(00); + set_reg_v2_pointer_to_fragin(01); + set_reg_v2_pointer_to_fragin(02); + set_reg_v2_pointer_to_fragin(03); + set_reg_v2_pointer_to_fragin(04); + set_reg_v2_pointer_to_fragin(05); + } + if (extra_varying_flag & VARYING_V3) { + set_reg_v3_pointer_to_fragin(00); + set_reg_v3_pointer_to_fragin(01); + set_reg_v3_pointer_to_fragin(02); + set_reg_v3_pointer_to_fragin(03); + set_reg_v3_pointer_to_fragin(04); + set_reg_v3_pointer_to_fragin(05); + set_reg_v3_pointer_to_fragin(06); + set_reg_v3_pointer_to_fragin(07); + } + if (extra_varying_flag & VARYING_V4) { + set_reg_v4_pointer_to_fragin(00); + set_reg_v4_pointer_to_fragin(01); + set_reg_v4_pointer_to_fragin(02); + set_reg_v4_pointer_to_fragin(03); + set_reg_v4_pointer_to_fragin(04); + set_reg_v4_pointer_to_fragin(05); + } +} + +float* ssrS_bcpnum(Vec3* bc, float A, float B, float C, float* out) { + ssr_assert(bc && out); + *out = bc->A * A + bc->B * B + bc->C * C; + return out; +} + +Color* ssrS_bcpcolor(Vec3* bc, Color A, Color B, Color C, Color* out) { ssr_assert(bc && out); *out = ssr_color( bc->A * COLOR_R(A) + bc->B * COLOR_R(B) + bc->C * COLOR_R(C), @@ -10,25 +228,60 @@ void ssrS_bcpcolor(Vec3* bc, Color A, Color B, Color C, Color* out) { bc->A * COLOR_B(A) + bc->B * COLOR_B(B) + bc->C * COLOR_B(C), bc->A * COLOR_A(A) + bc->B * COLOR_A(B) + bc->C * COLOR_A(C) ); + return out; } -void ssrS_bcpvec2(Vec3* bc, Vec2* A, Vec2* B, Vec2* C, Vec2* out) { +Vec2* ssrS_bcpvec2(Vec3* bc, Vec2* A, Vec2* B, Vec2* C, Vec2* out) { ssr_assert(bc && A && B && C && out); out->x = bc->A * A->x + bc->B * B->x + bc->C * C->x; out->y = bc->A * A->y + bc->B * B->y + bc->C * C->y; + return out; } -void ssrS_bcpvec3(Vec3* bc, Vec3* A, Vec3* B, Vec3* C, Vec3* out) { +Vec3* ssrS_bcpvec3(Vec3* bc, Vec3* A, Vec3* B, Vec3* C, Vec3* out) { ssr_assert(bc && A && B && C && out); out->x = bc->A * A->x + bc->B * B->x + bc->C * C->x; out->y = bc->A * A->y + bc->B * B->y + bc->C * C->y; out->z = bc->A * A->z + bc->B * B->z + bc->C * C->z; + return out; } -void ssrS_bcpvec4(Vec3* bc, Vec4* A, Vec4* B, Vec4* C, Vec4* out) { +Vec4* ssrS_bcpvec4(Vec3* bc, Vec4* A, Vec4* B, Vec4* C, Vec4* out) { ssr_assert(bc && A && B && C && out); out->x = bc->A * A->x + bc->B * B->x + bc->C * C->x; out->y = bc->A * A->y + bc->B * B->y + bc->C * C->y; out->z = bc->A * A->z + bc->B * B->z + bc->C * C->z; out->w = bc->A * A->w + bc->B * B->w + bc->C * C->w; + return out; +} + +void ssrS_lerpnum(float t, float A, float B, float* out) { + *out = lerp(A, B, t); +} + +void ssrS_lerpcolor(float t, Color A, Color B, Color* out) { + *out = ssr_color( + lerp(COLOR_R(A), COLOR_R(B), t), + lerp(COLOR_G(A), COLOR_G(B), t), + lerp(COLOR_B(A), COLOR_B(B), t), + lerp(COLOR_A(A), COLOR_A(B), t) + ); +} + +void ssrS_lerpvec2(float t, Vec2* A, Vec2* B, Vec2* out) { + out->x = lerp(A->x, B->x, t); + out->y = lerp(A->y, B->y, t); +} + +void ssrS_lerpvec3(float t, Vec3* A, Vec3* B, Vec3* out) { + out->x = lerp(A->x, B->x, t); + out->y = lerp(A->y, B->y, t); + out->z = lerp(A->z, B->z, t); +} + +void ssrS_lerpvec4(float t, Vec4* A, Vec4* B, Vec4* out) { + out->x = lerp(A->x, B->x, t); + out->y = lerp(A->y, B->y, t); + out->z = lerp(A->z, B->z, t); + out->w = lerp(A->w, B->w, t); } diff --git a/src/core/shader.h b/src/core/shader.h index 15dfc26..3024a0d 100644 --- a/src/core/shader.h +++ b/src/core/shader.h @@ -11,17 +11,21 @@ typedef struct UniformCollection { Mat4* projection; Mat4* mvp; Mat4* mv; - /*userside variables*/ + /*extra variables*/ Mat4 var_mat4[8]; Vec4 var_vec4[8]; Vec3 var_vec3[8]; Vec2 var_vec2[8]; + float var_num[8]; + /*userdata*/ + void* userdata; } UniformCollection; #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]) +#define UN(i) (&uniforms->var_num[i]) typedef struct VertexShaderIn { Vert* vertex; @@ -30,58 +34,163 @@ typedef struct VertexShaderIn { typedef void(*VertexShader)(UniformCollection* uniforms, VertexShaderIn* in, Vec4* homocoord); typedef struct FragmentShaderIn { - Vert *A, *B, *C; - Vec3* bc; + /*value from vertices interpolation*/ + Vec3 position; + Vec3 normal; + Vec3 tangent; + Vec2 texcoord; + Color color; + Vec4 joint; + Vec4 weight; + /*value from registers interpolation*/ + float num[4]; + Vec2 v2[6]; + Vec3 v3[8]; + Vec4 v4[6]; } FragmentShaderIn; typedef bool(*FragmentShader)(UniformCollection* uniforms, FragmentShaderIn* in, Color* color); typedef struct Program { - VertexShader vertexshader; + VertexShader vertexshader; FragmentShader fragmentshader; + uint varying_flag; } Program; -void ssrS_bcpcolor(Vec3* bc, Color A, Color B, Color C, Color* out); -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); +#define VARYING_NONE (0) +#define VARYING_POSITION (1 << 31) +#define VARYING_NORMAL (1 << 30) +#define VARYING_TANGENT (1 << 29) +#define VARYING_TEXCOORD (1 << 28) +#define VARYING_COLOR (1 << 27) +#define VARYING_JOINT (1 << 26) +#define VARYING_WEIGHT (1 << 25) + +#define VARYING_UNUSED (1 << 24) + +#define VARYING_BASIC ( VARYING_UNUSED | VARYING_POSITION | VARYING_NORMAL | VARYING_TANGENT | VARYING_TEXCOORD | VARYING_COLOR | VARYING_JOINT | VARYING_WEIGHT ) + +#define VARYING_NUM_00 (1 << 20) +#define VARYING_NUM_01 (1 << 21) +#define VARYING_NUM_02 (1 << 22) +#define VARYING_NUM_03 (1 << 23) + +#define VARYING_NUM (VARYING_NUM_00 | VARYING_NUM_01 | VARYING_NUM_02 | VARYING_NUM_03 ) + +#define VARYING_V2_00 (1) +#define VARYING_V2_01 (1 << 1) +#define VARYING_V2_02 (1 << 2) +#define VARYING_V2_03 (1 << 3) +#define VARYING_V2_04 (1 << 4) +#define VARYING_V2_05 (1 << 5) + +#define VARYING_V2 (VARYING_V2_00 | VARYING_V2_01 | VARYING_V2_02 | VARYING_V2_03 | VARYING_V2_04 | VARYING_V2_05) + +#define VARYING_V3_00 (1 << 6) +#define VARYING_V3_01 (1 << 7) +#define VARYING_V3_02 (1 << 8) +#define VARYING_V3_03 (1 << 9) +#define VARYING_V3_04 (1 << 10) +#define VARYING_V3_05 (1 << 11) +#define VARYING_V3_06 (1 << 12) +#define VARYING_V3_07 (1 << 13) + +#define VARYING_V3 (VARYING_V3_00 | VARYING_V3_01 | VARYING_V3_02 | VARYING_V3_03 | VARYING_V3_04 | VARYING_V3_05| VARYING_V3_06| VARYING_V3_07) + +#define VARYING_V4_00 (1 << 14) +#define VARYING_V4_01 (1 << 15) +#define VARYING_V4_02 (1 << 16) +#define VARYING_V4_03 (1 << 17) +#define VARYING_V4_04 (1 << 18) +#define VARYING_V4_05 (1 << 19) + +#define VARYING_V4 (VARYING_V4_00 | VARYING_V4_01 | VARYING_V4_02 | VARYING_V4_03 | VARYING_V4_04 | VARYING_V4_05) + +#define VARYING_EXTRA (~VARYING_BASIC) + +float* ssrS_bcpnum(Vec3* bc, float A, float B, float C, float* out); +Color* ssrS_bcpcolor(Vec3* bc, Color A, Color B, Color C, Color* out); +Vec2* ssrS_bcpvec2(Vec3* bc, Vec2* A, Vec2* B, Vec2* C, Vec2* out); +Vec3* ssrS_bcpvec3(Vec3* bc, Vec3* A, Vec3* B, Vec3* C, Vec3* out); +Vec4* ssrS_bcpvec4(Vec3* bc, Vec4* A, Vec4* B, Vec4* C, Vec4* out); + +void ssrS_lerpnum(float t, float A, float B, float* 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); +void ssrS_setregisters(uint flag, int capacity); + /* -** 顶点数据外,还提供额外的寄存器 +** 顶点数据外,还提供额外的寄存器用来存储vertex shader输出的顶点额外数据 +** 共24个 */ enum RegisterType { - REGTYPE_VEC2 = 1, - REGTYPE_VEC4 = 2, - REGTYPE_VEC3 = 3, + REGTYPE_NUM = 1, + REGTYPE_VEC2, + REGTYPE_VEC4, + REGTYPE_VEC3, }; typedef struct Register { uint length; uint type; union { - Vec4* v4; + float* num; Vec2* v2; + Vec4* v4; Vec3* v3; }; } Register; -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); -Vec2* ssrS_getregvec2_01(Vert* vert); -Vec2* ssrS_getregvec2_02(Vert* vert); -Vec3* ssrS_getregvec3_01(Vert* vert); -Vec3* ssrS_getregvec3_02(Vert* vert); +#define REG_NUM_COUNT 4 +#define REG_V2_COUNT 6 +#define REG_V3_COUNT 8 +#define REG_V4_COUNT 6 + +Register reg_num[4]; +Register reg_v2[6]; +Register reg_v3[8]; +Register reg_v4[6]; + +void reg_all_wipe(); /*标记清空所有寄存器*/ + +/*寄存器指针,使用错误可能会出现野指针*/ + +float* reg_num_00; +float* reg_num_01; +float* reg_num_02; +float* reg_num_03; + +Vec2* reg_v2_00; +Vec2* reg_v2_01; +Vec2* reg_v2_02; +Vec2* reg_v2_03; +Vec2* reg_v2_04; +Vec2* reg_v2_05; + +Vec3* reg_v3_00; +Vec3* reg_v3_01; +Vec3* reg_v3_02; +Vec3* reg_v3_03; +Vec3* reg_v3_04; +Vec3* reg_v3_05; +Vec3* reg_v3_06; +Vec3* reg_v3_07; + +Vec4* reg_v4_00; +Vec4* reg_v4_01; +Vec4* reg_v4_02; +Vec4* reg_v4_03; +Vec4* reg_v4_04; +Vec4* reg_v4_05; + +/*设置寄存器指针,指向寄存器(注意在fragment阶段,指针会指向fragmentIn结构)*/ +void ssrS_setupregisterpoints(uint extra_varying_flag, int idx); + +/*设置寄存器指针,指向fragIn结构*/ +void ssrS_setregtofragin(uint extra_varying_flag, FragmentShaderIn* frag_in); #endif
\ No newline at end of file diff --git a/src/core/tris.c b/src/core/tris.c deleted file mode 100644 index e69de29..0000000 --- a/src/core/tris.c +++ /dev/null diff --git a/src/core/tris.h b/src/core/tris.h deleted file mode 100644 index 1f4208f..0000000 --- a/src/core/tris.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _SOFTSHADEROOM_TRIS_H_ -#define _SOFTSHADEROOM_TRIS_H_ - -#include "../util/type.h" - -/* 用索引表示的三角形,在一系列顶点中索引 */ -typedef union Triangle -{ - uint v[3]; - struct { - uint v1, v2, v3; - }; -} Triangle; - - - -#endif
\ No newline at end of file diff --git a/src/core/vert.c b/src/core/vert.c index 0e62087..95469d3 100644 --- a/src/core/vert.c +++ b/src/core/vert.c @@ -1,42 +1,16 @@ #include "vert.h" -Vert* vert_new(uint comp) { +Vert* vert_new() { Vert* vert = ssrM_new(Vert); - vert->comp = comp; - vert->position = ssrM_new(Vec3); - vert->normal = ssrM_new(Vec3); - vert->tangent = ssrM_new(Vec3); - vert->uv = ssrM_new(Vec2); return vert; } -void vert_init(Vert* v, uint comp) { +void vert_init(Vert* v) { ssr_assert(v); - v->comp = comp; v->index = 0; - if ((comp & VERTMASK_POSITION) && !v->position) - v->position = ssrM_new(Vec3); - else if (!(comp & VERTMASK_POSITION) && v->position) - ssrM_free(v->position); - if ((comp & VERTMASK_NORMAL) && !v->normal) - v->normal = ssrM_new(Vec3); - else if (!(comp & VERTMASK_NORMAL) && v->normal) - ssrM_free(v->normal); - if ((comp & VERTMASK_TANGENT) && !v->tangent) - v->tangent = ssrM_new(Vec3); - else if (!(comp & VERTMASK_TANGENT) && v->tangent) - ssrM_free(v->tangent); - if ((comp & VERTMASK_UV) && !v->uv) - v->uv = ssrM_new(Vec2); - else if (!(comp & VERTMASK_UV) && v->uv) - ssrM_free(v->uv); } void vert_free(Vert* v) { ssr_assert(v); - if (v->position) ssrM_free(v->position); - if (v->normal) ssrM_free(v->normal); - if (v->tangent) ssrM_free(v->tangent); - if (v->uv) ssrM_free(v->uv); ssrM_free(v); }
\ No newline at end of file diff --git a/src/core/vert.h b/src/core/vert.h index a2fdb74..0542ded 100644 --- a/src/core/vert.h +++ b/src/core/vert.h @@ -7,42 +7,33 @@ #include "../util/type.h" #include "../util/assert.h" -//typedef uint Color; // ARGB by default - -typedef uint Color; // ARGB by default +typedef uint Color; // ARGB #define COLOR_A(c) ((c >> 24) & 0xff) #define COLOR_R(c) ((c >> 16) & 0xff) #define COLOR_G(c) ((c >> 8) & 0xff) #define COLOR_B(c) (c & 0xff) -typedef Vec4 Color32; // 4个float的颜色 +typedef Vec4 Color32; Color color32_tocolor(Color32* c); void color_tocolor32(Color c, Color32* out); void color32_saturate(Color32* c); -enum VertMask { - VERTMASK_POSITION = 1 , - VERTMASK_NORMAL = 1 << 1, - VERTMASK_COLOR = 1 << 2, - VERTMASK_TANGENT = 1 << 3, - VERTMASK_UV = 1 << 4, -}; - -/*标准的顶点结构,禁止修改*/ +/*readonly*/ typedef struct Vert { - uint index; - uint comp; - Vec3* position; - Vec3* normal; - Vec3* tangent; - Vec2* uv; + int index; + Vec3 position; + Vec3 normal; + Vec3 tangent; + Vec2 texcoord; Color color; + Vec4 joint; + Vec4 weight; } Vert; -Vert* vert_new(uint comp); /*新建vert*/ -void vert_init(Vert* v, uint comp); /*如果某些component没创建,创建它*/ -void vert_free(Vert* v); /*释放vert*/ +Vert* vert_new(uint comp); +void vert_init(Vert* v, uint comp); +void vert_free(Vert* v); #endif
\ No newline at end of file |