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 | |
parent | 8e684dc0c76708e3174f005aebcaabc144b85500 (diff) |
+clipping
-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 | ||||
-rw-r--r-- | src/example/example.h | 2 | ||||
-rw-r--r-- | src/example/example_cube.c | 73 | ||||
-rw-r--r-- | src/example/example_dot.c | 36 | ||||
-rw-r--r-- | src/example/example_texture.c | 88 | ||||
-rw-r--r-- | src/extend/transform.h | 17 | ||||
-rw-r--r-- | src/math/math.c | 2 | ||||
-rw-r--r-- | src/math/math.h | 36 | ||||
-rw-r--r-- | src/math/matrix.c | 753 | ||||
-rw-r--r-- | src/math/vec2.c | 2 | ||||
-rw-r--r-- | src/math/vec3.c | 1 | ||||
-rw-r--r-- | src/math/vec4.c | 2 | ||||
-rw-r--r-- | src/util/type.h | 4 |
23 files changed, 730 insertions, 1192 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 diff --git a/src/example/example.h b/src/example/example.h index 7879257..15b547e 100644 --- a/src/example/example.h +++ b/src/example/example.h @@ -13,6 +13,8 @@ extern void ondraw##i(void*); #define EXAMPLECUR texture +/*All examples*/ + EXAMPLE(cube); EXAMPLE(line); EXAMPLE(dot); diff --git a/src/example/example_cube.c b/src/example/example_cube.c deleted file mode 100644 index caedd64..0000000 --- a/src/example/example_cube.c +++ /dev/null @@ -1,73 +0,0 @@ -#include "example.h" - -/*正方体*/ -Vec3 verts[] = { - // front face - {1, 1, 1}, {-1, 1, 1}, {-1, -1, 1}, {1, -1, 1}, - // back face - {1, 1, -1}, {-1, 1, -1}, {-1, -1, -1}, {1, -1, -1}, -}; - -Color colors[] = { - 0xffff0000, 0xff00ff00, 0xffff00ff, 0xff00ffff, - 0xff0000ff, 0xff000000, 0xffffff00, 0xffffffff, -}; - -int cube[] = { - 0, 2, 1, 0, 3, 2, - 1, 2, 5, 2, 6, 5, - 4, 5, 6, 4, 6, 7, - 0, 4, 7, 0, 7, 3, - 0, 1, 4, 1, 5, 4, - 2, 3, 6, 3, 7, 6 -}; -Mat4 m; -void onloadcube(void* data) { -} - -void oneventcube(void* data) { - SDL_Event* e = (SDL_Event*)data; -} - -float _t = 0; - -void onupdatecube(void*data) { - uint dt = *(uint*)data; - ssr_matrixmode(MATRIX_MODEL); - ssr_loadidentity(); - ssr_translate(0, 0, -3); - ssr_rotate(360 * sin(_t += 0.001f), 1, 1, 1); - ssr_matrixmode(MATRIX_PROJECTION); - ssr_loadidentity(); - ssr_perspective(100 + 20 * sin(_t * 10), 1.25f, -0.1f, -100); - ssr_matrixmode(MATRIX_VIEW); - ssr_loadidentity(); - Vec3 pos = { 0,0,0 }, target = { 0,0,-1 }, up = { 0,1,0 }; - ssr_lookat(&pos, &target, &up); - ssr_getmvp(&m); -} - -void ondrawcube(void*data) { - ssr_clearcolor(0); - Vec2 proj[8]; - - for (int i = 0; i < 8; ++i) { - Vec4 v = { verts[i].x, verts[i].y ,verts[i].z ,1 }, temp; - mat4_applytovec4(&m, &v, &temp); - temp.x /= temp.w; - temp.y /= temp.w; - temp.z /= temp.w; - //vec4_print(&temp); - proj[i].x = temp.x; - proj[i].y = temp.y; - } - for (int j = 1; j < sizeof(cube) / sizeof(int); ++j) { - int fromx = proj[cube[j]].x * 250.f + 250, fromy = 200 - proj[cube[j]].y * 200.f; - int tox = proj[cube[j - 1]].x * 250.f + 250, toy = 200 - proj[cube[j - 1]].y * 200.f; - ssrR_putline(fromx, fromy , tox, toy, 0xffff0000); - } - - Vec2 v1 = { 0, 0 }, v2 = { 3, 1 }, v3 = {1, 5}; - float area = ssrR_area(&v1, &v2, &v3); - printf("%f\n", area); -} diff --git a/src/example/example_dot.c b/src/example/example_dot.c deleted file mode 100644 index 0a88084..0000000 --- a/src/example/example_dot.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "example.h" -#include "../core/rasterizer.h" - -Vec3 pos = { 0, 0, 2 }, target = { 0,0,-1 }, up = { 0, 1, 0 }; - -float dot[] = { 0, 0, -2 }; - -void onloaddot(void* data) { - -} - -void oneventdot(void* data) { - SDL_Event* e = (SDL_Event*)data; -} - -void onupdatedot(void*data) { - uint dt = *(uint*)data; - ssr_matrixmode(MATRIX_VIEW); - ssr_lookat(&pos, &target, &up); - ssr_matrixmode(MATRIX_PROJECTION); -} - -float j = 0; - -void ondrawdot(void*data) { - ssr_clearcolor(0xffffffff); - - //for (int i = -50; i < 200; ++i) { - // ssr_putpoint(i * sin(j += 0.1f), 300 * cos(j), ssr_color(0xff, 0, 0xff, 0)); - //} - - ssrR_putline(-100, 0, 100, 200, 0xffff0000); - -// printf("%u\n", (UINT_MAX * (double)0.5F)); - -} diff --git a/src/example/example_texture.c b/src/example/example_texture.c deleted file mode 100644 index db2868b..0000000 --- a/src/example/example_texture.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "example.h" - -Vert** quad; -static Vec3 verts[] = { - // front face - {1, 1, 1}, {-1, 1, 1}, {-1, -1, 1}, {1, -1, 1}, - // back face - {1, 1, -1}, {-1, 1, -1}, {-1, -1, -1}, {1, -1, -1}, -}; -static Color colors[] = { - 0xffff0000, 0xff00ff00, 0xff0000ff, 0xffff00ff, - 0xffaa28aa, 0xffFFC58E, 0xffA100FF, 0xffFAFF00, -}; - -int face[] = { - 0, 1, 2, 0, 2, 3, - 1, 5, 2, 2, 5, 6, - 4, 6, 5, 4, 7, 6, - 0, 3, 7, 0, 7, 4, - 0, 4, 1, 1, 4, 5, - 2, 6, 3, 3, 6, 7 -}; - -void vert(UniformCollection* uniforms, VertexShaderIn* in, Vec4* homocoord) { - static Vec4 p; p.xyz = *in->vertex->position; p.w = 1; - mat4_applytovec4(uniforms->mvp, &p, homocoord); -} -bool frag(UniformCollection* uniforms, FragmentShaderIn* in, Color* color) { - ssrS_bcpcolor(in->bc, in->A->color, in->B->color, in->C->color, color); - return 1; -} -Program program = { vert, frag }; - -void onloadtexture(void* data) { - ssr_matrixmode(MATRIX_PROJECTION); - ssr_loadidentity(); - ssr_perspective(90, 1.25f, 0.1f, 10); - //ssr_ortho(-5, 5, -4, 4, 0.1, 10); - ssr_matrixmode(MATRIX_VIEW); - ssr_loadidentity(); - Vec3 p = { 0, 0, 0 }, target = { 0, 0, -1 }; - ssr_lookat(&p, &target, &vec3up); - - quad = ssrM_newvector(Vert*, 8); - quad[0] = vert_new(VERTMASK_POSITION | VERTMASK_COLOR); - quad[1] = vert_new(VERTMASK_POSITION | VERTMASK_COLOR); - quad[2] = vert_new(VERTMASK_POSITION | VERTMASK_COLOR); - quad[3] = vert_new(VERTMASK_POSITION | VERTMASK_COLOR); - quad[4] = vert_new(VERTMASK_POSITION | VERTMASK_COLOR); - quad[5] = vert_new(VERTMASK_POSITION | VERTMASK_COLOR); - quad[6] = vert_new(VERTMASK_POSITION | VERTMASK_COLOR); - quad[7] = vert_new(VERTMASK_POSITION | VERTMASK_COLOR); - quad[0]->index = 0; *quad[0]->position = verts[0]; quad[0]->color = colors[0]; - quad[1]->index = 1; *quad[1]->position = verts[1]; quad[1]->color = colors[1]; - quad[2]->index = 2; *quad[2]->position = verts[2]; quad[2]->color = colors[2]; - quad[3]->index = 3; *quad[3]->position = verts[3]; quad[3]->color = colors[3]; - quad[4]->index = 4; *quad[4]->position = verts[4]; quad[4]->color = colors[4]; - quad[5]->index = 5; *quad[5]->position = verts[5]; quad[5]->color = colors[5]; - quad[6]->index = 6; *quad[6]->position = verts[6]; quad[6]->color = colors[6]; - quad[7]->index = 7; *quad[7]->position = verts[7]; quad[7]->color = colors[7]; - - ssr_bindvertices(quad, 8, face, 12); - - ssr_useprogram(&program); - ssr_enable(ENABLEMASK_BACKFACECULL); - ssr_enable(ENABLEMASK_DEPTHTEST); -} - -void oneventtexture(void* data) { - SDL_Event* e = (SDL_Event*)data; -} - -static float _t = 0; - -void onupdatetexture(void*data) { - uint dt = *(uint*)data; - ssr_matrixmode(MATRIX_MODEL); - ssr_loadidentity(); - ssr_translate(0, 0, -3); - ssr_rotate(_t -= dt / 50.f, 1, 1, 1); -} - -void ondrawtexture(void*data) { - ssr_clearcolor(0x00); - ssr_cleardepth(); - - ssr_draw(PRIMITIVE_TRIANGLE); -} diff --git a/src/extend/transform.h b/src/extend/transform.h index b366305..16b7c7f 100644 --- a/src/extend/transform.h +++ b/src/extend/transform.h @@ -4,11 +4,24 @@ ** Transform要注意按 scale -> rotation -> position 顺序计算 */ typedef struct Transform { + /*local*/ + Vec3 localposition; + Vec3 localscale; + Quat localrotation; + /*global*/ + Transform* parent; Vec3 position; - Vec3 scale; + Vec3 scale; Quat rotation; + bool isdirty; } Transform; -void transformtranslate(Transform* trans, Vec4* v, Vec4* out); +void transform_translate(Transform* trans, Vec4* v, Vec4* out); Vec4 transform_translate(Transform* trans, Vec4* v); + +void transform_getrotation(Quat* out); /*get global rotation*/ +void transform_getposition(Vec3* out); +void transform_getscale(Vec3* out); + +void transform_setdirty(Transform* trans); diff --git a/src/math/math.c b/src/math/math.c index 7d731f8..a149307 100644 --- a/src/math/math.c +++ b/src/math/math.c @@ -1,6 +1,6 @@ #include "math.h" -char printbuffer[2048] = { 0 }; +char printbuffer[1024] = { 0 }; float rsqrt(float number) { long i; diff --git a/src/math/math.h b/src/math/math.h index 90c7521..35219a3 100644 --- a/src/math/math.h +++ b/src/math/math.h @@ -11,14 +11,11 @@ #define PI 3.141592653f #define RAD2DEG 57.295779523f /*180.f/PI*/ #define DEG2RAG 0.0174532925f /*PI/180.f*/ -#define EPSILON 0.000001f +#define EPSILON 1e-6f /* 用来打印的公共buffer */ -extern char printbuffer[2048]; +extern char printbuffer[1024]; -/* -** 数学函数 -*/ #define min(a, b) ((a) < (b) ? (a) : (b)) #define max(a, b) ((a) > (b) ? (a) : (b)) #define clamp(v, l, h) ((v) > (l) ? ((v) < (h) ? (v) : (h)) : (l)) @@ -30,16 +27,10 @@ extern char printbuffer[2048]; float rsqrt(float n); float lerp(float from, float to, float t); -/* -** 二维向量,用来做屏幕上的一些计算 -*/ typedef struct Vec2 { float x, y; } Vec2; -/* -** 三维向量,用来做三维空间的计算 -*/ typedef union Vec3 { struct { float x, y, z; @@ -50,9 +41,6 @@ typedef union Vec3 { Vec2 xy; } Vec3; -/* -** 齐次坐标,列主项,平移变换和透视投影需要 -*/ typedef union Vec4 { struct { float x, y, z, w; @@ -63,10 +51,7 @@ typedef union Vec4 { Vec3 xyz; } Vec4; -/* -** 用来可视化四元数,欧拉角默认使用角度存储,用euler_deg2rad()转弧度 -*/ -typedef union Euler { +typedef union Euler { /*in degree, for visualize quaternion*/ struct { float x, y, z; }; @@ -75,17 +60,10 @@ typedef union Euler { }; } Euler; -/* -** 四元数,用来做旋转变换。在进行变换复合以及插值的时候用,但最终还是需要通过quat_mat4转换成矩阵和其他变换矩阵 -** 一起对向量进行变换 -*/ typedef struct Quat { float x, y, z, w; } Quat; -/* -** 4x4矩阵,列主项,用来做平移和缩放变换。之所以用列主序存储,是为了快速读取矩阵的基向量 -*/ typedef union Mat4 { float l[16]; float m[4][4]; @@ -149,7 +127,6 @@ typedef union Mat43 { }; } Mat43; -//#define MAT(m, r, c) (m->l[r + (c<<2)]) #define MAT(M, r, c) (M->m[c][r]) /************************************************************************/ /* Vec */ @@ -170,6 +147,13 @@ void vec2_print(Vec2* v); extern Vec3 vec3forward; /*(0,0,1)*/ extern Vec3 vec3up; /*(0,1,0)*/ extern Vec3 vec3left;/*(1,0,0)*/ +extern Vec3 vec3zero; /*(0,0,0)*/ +extern Vec2 vec2zero; /*(0,0,0)*/ +extern Vec4 vec4zero; /*(0,0,0)*/ + +#define zerovec3 {0, 0, 0} +#define zerovec2 {0, 0} +#define zerovec4 {0, 0, 0} void vec3_tostring(Vec3* v, char buf[]); void vec3_print(Vec3* v); diff --git a/src/math/matrix.c b/src/math/matrix.c deleted file mode 100644 index 15a194d..0000000 --- a/src/math/matrix.c +++ /dev/null @@ -1,753 +0,0 @@ -#include <math.h> -#include <stdio.h> -#include <string.h> - -#include "math.h" -#include "../util/assert.h" -#include "../core/mem.h" - - -static Mat4 sharedMat; -static Mat4 sharedMat2; -static Vec4 sharedVec4; - -Mat4 mat4identity = { - 1,0,0,0, - 0,1,0,0, - 0,0,1,0, - 0,0,0,1 -}; - -#define shrmat(p) \ -do{\ -sharedMat = *p;\ -p = &sharedMat;\ -}while(0) - -#define shrmat2(p) \ -do{\ -sharedMat2 = *p;\ -p = &sharedMat2;\ -}while(0) - -void mat4_tostring(Mat4* m, char str[]) { - ssrM_zero(str, sizeof(str)); - for (int r = 0; r < 4; ++r) { - for (int c = 0; c < 4; ++c) { - sprintf(str, "%8.3f ", MAT(m, r, c) == -0 ? +0 : MAT(m, r, c)); - str += strlen(str); - } - if(r != 3) sprintf(str, "\n"); - str += strlen(str); - } -} - -void mat4_print(Mat4* m) { - mat4_tostring(m, printbuffer); - printf("\n%s\n", printbuffer); -} - -void mat4_zero(Mat4* out) { - ssr_assert(out); - ssrM_zero(out, sizeof(Mat4)); -} - -void mat4_setidentity(Mat4* out) { - ssr_assert(out); - mat4_zero(out); - out->e00 = 1; - out->e11 = 1; - out->e22 = 1; - out->e33 = 1; -} - -void mat4_setortho(float l, float r, float b, float t, float n, float f, Mat4* out) { - ssr_assert(out); - mat4_zero(out); - out->e00 = 2 / (r - l); - out->e03 = -(r + l) / (r - l); - out->e11 = 2 / (t - b); - out->e13 = -(t + b) / (t - b); - out->e22 = -2 / (f - n); - out->e23 = -(f + n) / (f - n); - out->e33 = 1; -} - -void mat4_setfrustum(float l, float r, float b, float t, float n, float f, Mat4* out) { - ssr_assert(out); - mat4_zero(out); - out->e00 = (2.f * n) / (r - l); - out->e02 = (r + l) / (r - l); - out->e11 = 2.f * n / (t - b); - out->e12 = (t + b) / (t - b); - out->e22 = -(f + n) / (f - n); - out->e23 = -2.f * f * n / (f - n); - out->e32 = -1; -} - -void mat4_setperspective(float _fov, float aspect, float near, float far, Mat4* out) { - float fov = _fov * PI / 180.f; - float tanf = tan(fov * 0.5); - mat4_setfrustum( - -near*tanf*aspect, - near*tanf*aspect, - -near*tanf, - near*tanf, - near, - far, - out - ); -} - -static float _mul(float* r, float* c) { - return c[0] * r[0] + c[1] * r[4] + c[2] * r[8] + c[3] * r[12]; -} - -#define mul(r, c) _mul(&MAT(m1,r,0), &MAT(m2,0,c)) - -void mat4_multiply(Mat4* m1, Mat4* m2, Mat4* out) { - ssr_assert(m1 && m2 && out); - if (mat4_isidentity(m1)) { if(m2 != out) *out = *m2; return; } - if (mat4_isidentity(m2)) { if(m1 != out) *out = *m1; return; } - if (m1 == out) shrmat(m1); - if (m2 == out) shrmat2(m2); - - out->e00 = mul(0, 0); out->e01 = mul(0, 1); out->e02 = mul(0, 2); out->e03 = mul(0, 3); - out->e10 = mul(1, 0); out->e11 = mul(1, 1); out->e12 = mul(1, 2); out->e13 = mul(1, 3); - out->e20 = mul(2, 0); out->e21 = mul(2, 1); out->e22 = mul(2, 2); out->e23 = mul(2, 3); - out->e30 = mul(3, 0); out->e31 = mul(3, 1); out->e32 = mul(3, 2); out->e33 = mul(3, 3); -} - -void mat4_setscale(float kx, float ky, float kz, Mat4* out) { - ssr_assert(out); - mat4_zero(out); - out->e00 = kx; - out->e11 = ky; - out->e22 = kz; - out->e33 = 1; -} - -void mat4_setposition(float x, float y, float z, Mat4* out) { - ssr_assert(out); - mat4_setidentity(out); - out->e03 = x; - out->e13 = y; - out->e23 = z; -} - -void mat4_setrotatez(float angle, Mat4* out) { - ssr_assert(out); - mat4_setidentity(out); - angle = radians(angle); - float s = sin(angle), c = cos(angle); - out->e00 = c; out->e01 = -s; - out->e10 = s; out->e11 = c; -} - -void mat4_setrotatex(float angle, Mat4* out) { - ssr_assert(out); - mat4_setidentity(out); - angle = radians(angle); - float s = sin(angle), c = cos(angle); - out->e11 = c; out->e12 = -s; - out->e21 = s; out->e22 = c; -} - -void mat4_setrotatey(float angle, Mat4* out) { - ssr_assert(out); - mat4_setidentity(out); - angle = radians(angle); - float s = sin(angle), c = cos(angle); - out->e00 = c; out->e02 = s; - out->e20 = -s; out->e22 = c; -} - -/*https://www.geometrictools.com/Documentation/EulerAngles.pdf*/ -void mat4_setrotate(float angleX, float angleY, float angleZ, Mat4* out) { - ssr_assert(out); - mat4_setidentity(out); - angleX = radians(angleX); angleY = radians(angleY); angleZ = radians(angleZ); - float sx = sin(angleX), cx = cos(angleX); - float sy = sin(angleY), cy = cos(angleY); - float sz = sin(angleZ), cz = cos(angleZ); - out->e00 = cy * cz + sx * sy * sz; out->e01 = cz * sx*sy - cy * sz; out->e02 = cx * sy; - out->e10 = cx * sz; out->e11 = cx * cz; out->e12 = -sx; - out->e20 = -cz * sy + cy * sx * sz; out->e21 = cy * cz*sx + sy * sz; out->e22 = cx * cy; -} - -void mat4_setaxisangle(Vec3* ax, float angle, Mat4* out) { - ssr_assert(ax && out); - - float a = radians(angle); - float c = cos(a); - float s = sin(a); - - Vec3 axis = *ax; - Vec3 temp; - vec3_normalize(&axis, &axis); - vec3_scale(&axis, 1 - c, &temp); - - /* - rotation matrix 推导过程 https://zhuanlan.zhihu.com/p/56587491 - X^2(1-c)+c, XY(1-c)-Zs, XZ(1-c)+Ys, 0 - XY(1-c)+Zs, Y^2(1-c)+c, YZ(1-c)-Xs, 0 - XZ(1-c)-Ys, YZ(1-c)+Xs, Z^2(1-c)+c, 0 - 0, 0, 0, 1 - */ - - mat4_setidentity(out); - out->m[0][0] = c + temp.x * axis.x; - out->m[0][1] = 0 + temp.x * axis.y + s * axis.z; - out->m[0][2] = 0 + temp.x * axis.z - s * axis.y; - - out->m[1][0] = 0 + temp.y * axis.x - s * axis.z; - out->m[1][1] = c + temp.y * axis.y; - out->m[1][2] = 0 + temp.y * axis.z + s * axis.x; - - out->m[2][0] = 0 + temp.z * axis.x + s * axis.y; - out->m[2][1] = 0 + temp.z * axis.y - s * axis.x; - out->m[2][2] = c + temp.z * axis.z; - -} - -void mat4_setorthonormalbias(Vec3* x, Vec3* y, Vec3* z, Mat4* out) { - ssr_assert(x && y && z); - mat4_setidentity(out); - Vec4 asix = { x->x, x->y, x->z, 0 }; - Vec4 asiy = { y->x, y->y, y->z, 0 }; - Vec4 asiz = { z->x, z->y, z->z, 0 }; - out->colums[0] = asix; - out->colums[1] = asiy; - out->colums[2] = asiz; -} - -bool mat4_isidentity(Mat4* m) { - ssr_assert(m); - //return memcmp(m, &mat4identity, sizeof(Mat4)) == 0; - return - compare(m->axisx.x, 1) && compare(m->axisx.y, 0) && compare(m->axisx.z,0) && compare(m->axisx.w, 0) && - compare(m->axisy.x, 0) && compare(m->axisy.y, 1) && compare(m->axisy.z,0) && compare(m->axisy.w, 0) && - compare(m->axisz.x, 0) && compare(m->axisz.y, 0) && compare(m->axisz.z,1) && compare(m->axisz.w, 0) && - compare(m->pos.x, 0 ) && compare(m->pos.y, 0 ) && compare(m->pos.z, 0 ) &&compare( m->pos.w, 1); -} - -bool mat4_isorthogonal(Mat4* m) { - ssr_assert(m); - Mat4 trans = {0}, res = { 0 }; - mat4_transpose(m, &trans); - mat4_multiply(m, &trans, &res); - return mat4_isidentity(&res); -} - -/* -** 以z轴为准进行正交化,分为施密特正交化和叉乘正交化,施密特过程更加普遍,叉乘适用于三维空间,两种方法实际上等价 -** 如果用叉乘的方法,只需要关注yz,x通过叉乘得到 -*/ -void mat4_orthogonalize(Mat4* in, Mat4* out) { - ssr_assert(in && out); - if (in == out) { - shrmat(in); - } - - mat4_setidentity(out); - Vec4 z = in->basis.z; - vec3_normalize(&z, &z); - Vec4 y = in->basis.y; - Vec4 x = {0}; - vec3_cross(&y, &z, &x); - vec3_normalize(&x, &x); - vec3_cross(&z, &x, &y); - out->basis.x = x; - out->basis.y = y; - out->basis.z = z; - - /* - mat4_setidentity(out); - - Vec4 x = in->basis.x; - Vec4 y = in->basis.y; - Vec4 z = in->basis.z; - Vec3 temp, temp2; - - vec3_normalize(&z, &z); - out->basis.z = z; - - float dot = vec3_dot(&y, &z); - vec3_scale(&z, dot, &temp); - vec3_minus(&y, &temp, &y); - vec3_normalize(&y, &y); - out->basis.y = y; - - vec3_cross(&y, &z, &out->basis.x); - */ - /*针对右手系调整basis.x的方向*/ - /*https://math.stackexchange.com/questions/1847465/why-to-use-gram-schmidt-process-to-orthonormalise-a-basis-instead-of-cross-produ*/ - /*由于需要针对右手系,这里不这样计算,因为可能要对结果进行翻转 - dot = vec3_dot(&x, &z); - vec3_scale(&z, dot, &temp); - vec3_minus(&x, &temp, &temp2); - dot = vec3_dot(&x, &y); - vec3_scale(&y, dot, &temp); - vec3_minus(&temp2, &temp, &x); - vec3_normalize(&x, &x); - out->basis.x = x; - */ -} - -bool mat4_setlookrotation(Vec3* view, Vec3* up, Mat4* out) { - ssr_assert(view && up && out); - - /*正交化*/ - float mag = vec3_magnitude(view); - if (mag < EPSILON) return 0; - Vec3 z; - vec3_scale(view, 1.f / mag, &z); - - Vec3 x; - vec3_cross(up, &z, &x); - mag = vec3_magnitude(&x); - if (mag < EPSILON) return 0; - vec3_scale(&x, 1.f / mag, &x); - - Vec3 y; - vec3_cross(&z, &x, &y); - mag = vec3_magnitude(&y); - if (!compare(mag, 1)) return 0; - - mat4_setorthonormalbias(&x, &y, &z, out); /*xyz正交*/ - - return 1; -} - -void mat4_applytovec4(Mat4* mat, Vec4* v, Vec4* out) { - ssr_assert(mat && v && out); - if (v == out) { - sharedVec4 = *v; - v = &sharedVec4; - } - out->x = mat->e00 * v->x + mat->e01 * v->y + mat->e02 * v->z + mat->e03 * v->w; - out->y = mat->e10 * v->x + mat->e11 * v->y + mat->e12 * v->z + mat->e13 * v->w; - out->z = mat->e20 * v->x + mat->e21 * v->y + mat->e22 * v->z + mat->e23 * v->w; - out->w = mat->e30 * v->x + mat->e31 * v->y + mat->e32 * v->z + mat->e33 * v->w; -} - -#define trans(r, c) out->e##r##c = m->e##c##r - -void mat4_transpose(Mat4* m, Mat4* out) { - ssr_assert(m && out); - if (m == out) shrmat(m); - - trans(0, 0); trans(0, 1); trans(0, 2); trans(0, 3); - trans(1, 0); trans(1, 1); trans(1, 2); trans(1, 3); - trans(2, 0); trans(2, 1); trans(2, 2); trans(2, 3); - trans(3, 0); trans(3, 1); trans(3, 2); trans(3, 3); -} - -/* -** 使用高斯消元法计算任意矩阵的逆矩阵。针对不含投影的3D变换矩阵,应该使用 -** mat4_invertgeneral3d() -** 更快一些 -*/ -bool mat4_invertfull(Mat4* m, Mat4* out) { - ssr_assert(m && out); - -#define _m(r, c) MAT(m, r, c) - float wtmp[4][8] = { - { /*M*/ _m(0,0), _m(0, 1), _m(0, 2), _m(0, 3), /*I*/ 1, 0, 0, 0 }, - { /*M*/ _m(1,0), _m(1, 1), _m(1, 2), _m(1, 3), /*I*/ 0, 1, 0, 0 }, - { /*M*/ _m(2,0), _m(2, 1), _m(2, 2), _m(2, 3), /*I*/ 0, 0, 1, 0 }, - { /*M*/ _m(3,0), _m(3, 1), _m(3, 2), _m(3, 3), /*I*/ 0, 0, 0, 1 }, - }; -#undef _m - float m0, m1, m2, m3, s; - float *r0, *r1, *r2, *r3; - r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; -#define SWAP_ROWS(a, b) { float *_tmp = a; (a)=(b); (b)=_tmp; } - - //#define optimize(block) if(s!=0.f){block} -#define optimize(block) block - - /* choose pivot - or die */ - if (absf(r3[0]) > absf(r2[0])) SWAP_ROWS(r3, r2); - if (absf(r2[0]) > absf(r1[0])) SWAP_ROWS(r2, r1); - if (absf(r1[0]) > absf(r0[0])) SWAP_ROWS(r1, r0); - if (0.0f == r0[0]) return 0; - - /* eliminate first variable */ - m1 = r1[0] / r0[0]; m2 = r2[0] / r0[0]; m3 = r3[0] / r0[0]; - s = r0[1]; optimize(r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; ) - s = r0[2]; optimize(r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; ) - s = r0[3]; optimize(r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; ) - s = r0[4]; optimize(r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; ) - s = r0[5]; optimize(r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; ) - s = r0[6]; optimize(r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; ) - s = r0[7]; optimize(r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; ) - - /* choose pivot - or die */ - if (absf(r3[1]) > absf(r2[1])) SWAP_ROWS(r3, r2); - if (absf(r2[1]) > absf(r1[1])) SWAP_ROWS(r2, r1); - if (0.0F == r1[1]) return 0; - - /* eliminate second variable */ - m2 = r2[1] / r1[1]; m3 = r3[1] / r1[1]; - s = r1[2]; optimize(r2[2] -= m2 * s; r3[2] -= m3 * s; ) - s = r1[3]; optimize(r2[3] -= m2 * s; r3[3] -= m3 * s; ) - s = r1[4]; optimize(r2[4] -= m2 * s; r3[4] -= m3 * s; ) - s = r1[5]; optimize(r2[5] -= m2 * s; r3[5] -= m3 * s; ) - s = r1[6]; optimize(r2[6] -= m2 * s; r3[6] -= m3 * s; ) - s = r1[7]; optimize(r2[7] -= m2 * s; r3[7] -= m3 * s; ) - - /* choose pivot - or die */ - if (absf(r3[2])>absf(r2[2])) SWAP_ROWS(r3, r2); - if (0.0F == r2[2]) return 0; - - /* eliminate third variable */ - m3 = r3[2] / r2[2]; - s = r2[3]; optimize(r3[3] -= m3 * s; ) - s = r2[4]; optimize(r3[4] -= m3 * s; ) - s = r2[5]; optimize(r3[5] -= m3 * s; ) - s = r2[6]; optimize(r3[6] -= m3 * s; ) - s = r2[7]; optimize(r3[7] -= m3 * s; ) - -#undef optimize - - /* last check */ - if (0.0F == r3[3]) return 0; - - s = 1.0F / r3[3]; /* now back substitute row 3 */ - r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s; - - m2 = r2[3]; /* now back substitute row 2 */ - s = 1.0F / r2[2]; - r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), - r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); - m1 = r1[3]; - r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, - r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; - m0 = r0[3]; - r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, - r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; - - m1 = r1[2]; /* now back substitute row 1 */ - s = 1.0F / r1[1]; - r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), - r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); - m0 = r0[2]; - r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, - r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; - - m0 = r0[1]; /* now back substitute row 0 */ - s = 1.0F / r0[0]; - r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), - r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); - - out->e00 = r0[4]; out->e01 = r0[5]; out->e02 = r0[6]; out->e03 = r0[7]; - out->e10 = r1[4]; out->e11 = r1[5]; out->e12 = r1[6]; out->e13 = r1[7]; - out->e20 = r2[4]; out->e21 = r2[5]; out->e22 = r2[6]; out->e23 = r2[7]; - out->e30 = r3[4]; out->e31 = r3[5]; out->e32 = r3[6]; out->e33 = r3[7]; - -#undef SWAP_ROWS - - return 1; -} - -/* -** 对只包含基本3D变换的矩阵进行变换,先计算左上角3x3的RS矩阵的逆(通过伴随矩阵),然后 -** 乘上平移矩阵的逆矩阵,即 -** M^-1 = (T(RS))^-1 = (RS)^-1 * T^-1 -*/ -bool mat4_invertgeneral3d(Mat4* in, Mat4* out) { - ssr_assert(in && out); - if (in == out) shrmat(in); - - mat4_setidentity(out); - - /*计算左上角3x3矩阵的行列式*/ - float pos = 0, neg = 0, t; - float det; - - t = in->e00 * in->e11 * in->e22; - if (t >= 0) pos += t; else neg += t; - t = in->e10 * in->e21 * in->e02; - if (t >= 0) pos += t; else neg += t; - t = in->e20 * in->e01 * in->e12; - if (t >= 0) pos += t; else neg += t; - - t = -in->e20 * in->e11 * in->e02; - if (t >= 0) pos += t; else neg += t; - t = -in->e10 * in->e01 * in->e22; - if (t >= 0) pos += t; else neg += t; - t = -in->e00 * in->e21 * in->e12; - if (t >= 0) pos += t; else neg += t; - - det = pos + neg; - - if (det * det < 1e-25) - return 0; /*行列式为0*/ - - det = 1.f / det; - MAT(out, 0, 0) = ((MAT(in, 1, 1)*MAT(in, 2, 2) - MAT(in, 2, 1)*MAT(in, 1, 2))*det); - MAT(out, 0, 1) = (-(MAT(in, 0, 1)*MAT(in, 2, 2) - MAT(in, 2, 1)*MAT(in, 0, 2))*det); - MAT(out, 0, 2) = ((MAT(in, 0, 1)*MAT(in, 1, 2) - MAT(in, 1, 1)*MAT(in, 0, 2))*det); - MAT(out, 1, 0) = (-(MAT(in, 1, 0)*MAT(in, 2, 2) - MAT(in, 2, 0)*MAT(in, 1, 2))*det); - MAT(out, 1, 1) = ((MAT(in, 0, 0)*MAT(in, 2, 2) - MAT(in, 2, 0)*MAT(in, 0, 2))*det); - MAT(out, 1, 2) = (-(MAT(in, 0, 0)*MAT(in, 1, 2) - MAT(in, 1, 0)*MAT(in, 0, 2))*det); - MAT(out, 2, 0) = ((MAT(in, 1, 0)*MAT(in, 2, 1) - MAT(in, 2, 0)*MAT(in, 1, 1))*det); - MAT(out, 2, 1) = (-(MAT(in, 0, 0)*MAT(in, 2, 1) - MAT(in, 2, 0)*MAT(in, 0, 1))*det); - MAT(out, 2, 2) = ((MAT(in, 0, 0)*MAT(in, 1, 1) - MAT(in, 1, 0)*MAT(in, 0, 1))*det); - - // 乘T^-1 - MAT(out, 0, 3) = -(MAT(in, 0, 3) * MAT(out, 0, 0) + - MAT(in, 1, 3) * MAT(out, 0, 1) + - MAT(in, 2, 3) * MAT(out, 0, 2)); - MAT(out, 1, 3) = -(MAT(in, 0, 3) * MAT(out, 1, 0) + - MAT(in, 1, 3) * MAT(out, 1, 1) + - MAT(in, 2, 3) * MAT(out, 1, 2)); - MAT(out, 2, 3) = -(MAT(in, 0, 3) * MAT(out, 2, 0) + - MAT(in, 1, 3) * MAT(out, 2, 1) + - MAT(in, 2, 3) * MAT(out, 2, 2)); - - return 1; -} - -void mat4_invertpos(Mat4* in, Mat4* out) { - -} - -void mat4_invertscale(Mat4* in, Mat4* out) { - -} - -void mat4_invertrot(Mat4* in, Mat4* out) { - ssr_assert(in && out); - mat4_transpose(in, out); -} - -void mat4_settr(Vec3* pos, Quat* rot, Mat4* out) { - ssr_assert(pos && rot && out); - mat4_zero(out); - quat_tomat4(rot, out); - out->e03 = pos->x; - out->e13 = pos->y; - out->e23 = pos->z; -} - -void mat4_settrs(Vec3* pos, Quat* rot, Vec3* scale, Mat4* out) { - ssr_assert(pos && rot && scale && out); - mat4_zero(out); - quat_tomat4(rot, out); /*pos*rot*scale的顺序*/ - out->e00 *= scale->x; out->e01 *= scale->y; out->e02 *= scale->z; - out->e10 *= scale->x; out->e11 *= scale->y; out->e12 *= scale->z; - out->e20 *= scale->x; out->e21 *= scale->y; out->e22 *= scale->z; - out->e03 = pos->x; - out->e13 = pos->y; - out->e23 = pos->z; -} - -void mat4_settrinverse(Vec3* pos, Quat* rot, Mat4* out) { - ssr_assert(pos && rot && out); - mat4_zero(out); - quat_invert(rot, rot); - quat_tomat4(rot, out); - Vec3 reverse = { -pos->x, -pos->y, -pos->z}; - mat4_translate(out, &reverse, out); /* (TR)^-1 = R^-1*T^-1所以这里是右乘*/ -} - -void mat4_scale(Mat4* m, Vec3* scale, Mat4* out) { - ssr_assert(m && scale && out); - if (out != m) { - *out = *m; - } - /* - scale matrix - x, 0, 0, 0, - 0, y, 0, 0, - 0, 0, z, 0, - 0, 0, 0, 1 - */ - out->e00 *= scale->x; - out->e10 *= scale->x; - out->e20 *= scale->x; - out->e30 *= scale->x; - - out->e01 *= scale->y; - out->e11 *= scale->y; - out->e21 *= scale->y; - out->e31 *= scale->y; - - out->e02 *= scale->z; - out->e12 *= scale->z; - out->e22 *= scale->z; - out->e32 *= scale->z; -} - -void mat4_translate(Mat4* m, Vec3* pos, Mat4* out) { - ssr_assert(m && pos && out); - if (out != m) { - *out = *m; - } - /* - translate matrix - 1, 0, 0, x, - 0, 1, 0, y, - 0, 0, 1, z, - 0, 0, 0, 1, - */ - out->e03 = out->e00 * pos->x + out->e01 * pos->y + out->e02 * pos->z + out->e03; - out->e13 = out->e10 * pos->x + out->e11 * pos->y + out->e12 * pos->z + out->e13; - out->e23 = out->e20 * pos->x + out->e21 * pos->y + out->e22 * pos->z + out->e23; - out->e33 = out->e30 * pos->x + out->e31 * pos->y + out->e32 * pos->z + out->e33; -} - -void mat4_rotate(Mat4* m, float angle, Vec3* ax, Mat4* out) { - ssr_assert(m && ax && out); - Mat4 rot; - mat4_setaxisangle(ax, angle, &rot); - mat4_multiply(m, &rot, out); -} - -void mat4_decomposetrs(Mat4* src, Vec3* pos, Quat* quat, Vec3* scale) { - ssr_assert(src && pos && quat && scale); - - Vec3* x = &src->colums[0]; - Vec3* y = &src->colums[1]; - Vec3* z = &src->colums[2]; - Vec3* w = &src->colums[3]; - - *pos = *w; - - quat_setlookrotation(z, y, quat); - - scale->x = vec3_magnitude(x); - scale->y = vec3_magnitude(y); - scale->z = vec3_magnitude(z); -} - -static void MakePositive(Euler* euler) {/*弧度制欧拉角*/ - const float negativeFlip = -0.0001F; - const float positiveFlip = (PI * 2.0F) - 0.0001F; - - if (euler->x < negativeFlip) - euler->x += 2.0 * PI; - else if (euler->x > positiveFlip) - euler->x -= 2.0 * PI; - - if (euler->y < negativeFlip) - euler->y += 2.0 * PI; - else if (euler->y > positiveFlip) - euler->y -= 2.0 * PI; - - if (euler->z < negativeFlip) - euler->z += 2.0 * PI; - else if (euler->z > positiveFlip) - euler->z -= 2.0 * PI; -} - -static void SanitizeEuler(Euler* e) {/*弧度制欧拉角*/ - MakePositive(e); -} - -/*from unity src*/ -bool mat4_toeuler(Mat4* in, Euler* out) { - ssr_assert(in && out); - // from http://www.geometrictools.com/Documentation/EulerAngles.pdf - // YXZ order - if (MAT(in, 1, 2) < 0.999F) // some fudge for imprecision - { - if (MAT(in, 1, 2) > -0.999F) // some fudge for imprecision - { - out->x = asin(-MAT(in, 1, 2)); - out->y = atan2(MAT(in, 0, 2), MAT(in, 2, 2)); - out->z = atan2(MAT(in, 1, 0), MAT(in, 1, 1)); - //euler_rad2deg(out, out); - SanitizeEuler(out); - euler_rad2deg(out, out); - return 1; - } - else - { - // WARNING. Not unique. YA - ZA = atan2(r01,r00) - out->x = PI * 0.5F; - out->y = atan2(MAT(in, 0, 1), MAT(in, 0, 0)); - out->z = 0.0F; - //euler_rad2deg(out, out); - SanitizeEuler(out); - euler_rad2deg(out, out); - return 0; - } - } - else - { - // WARNING. Not unique. YA + ZA = atan2(-r01,r00) - out->x = -PI * 0.5F; - out->y = atan2(-MAT(in, 0, 1), MAT(in, 0, 0)); - out->z = 0.0F; - //euler_rad2deg(out, out); - SanitizeEuler(out); - euler_rad2deg(out, out); - return 0; - } -} - -/*from unity src*/ -/*https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/*/ -void mat4_toquat(Mat4* in, Quat* out) { - // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes - // article "Quaternionf Calculus and Fast Animation". - float fTrace = MAT(in, 0, 0) + MAT(in, 1, 1) + MAT(in, 2, 2); - float fRoot; - - if (fTrace > 0.0f) - { - // |w| > 1/2, may as well choose w > 1/2 - fRoot = sqrt(fTrace + 1.0f); // 2w - out->w = 0.5f*fRoot; - fRoot = 0.5f / fRoot; // 1/(4w) - out->x = (MAT(in, 2, 1) - MAT(in, 1, 2))*fRoot; - out->y = (MAT(in, 0, 2) - MAT(in, 2, 0))*fRoot; - out->z = (MAT(in, 1, 0) - MAT(in, 0, 1))*fRoot; - } - else - { - // |w| <= 1/2 - int s_iNext[3] = { 1, 2, 0 }; - int i = 0; - if (MAT(in, 1, 1) > MAT(in, 0, 0)) - i = 1; - if (MAT(in, 2, 2) > MAT(in, i, i)) - i = 2; - int j = s_iNext[i]; - int k = s_iNext[j]; - - fRoot = sqrt(MAT(in, i, i) - MAT(in, j, j) - MAT(in, k, k) + 1.0f); - float* apkQuat[3] = { &out->x, &out->y, &out->z }; - ssr_assert(fRoot >= EPSILON); - *apkQuat[i] = 0.5f*fRoot; - fRoot = 0.5f / fRoot; - out->w = (MAT(in, k, j) - MAT(in, j, k)) * fRoot; - *apkQuat[j] = (MAT(in, j, i) + MAT(in, i, j))*fRoot; - *apkQuat[k] = (MAT(in, k, i) + MAT(in, i, k))*fRoot; - } - quat_normalize(out, out); -} - -void mat3_applytovec3(Mat3* m, Vec3* v, Vec3* out) { - ssr_assert(m && v && out); - out->x = m->e00 * v->x + m->e01 * v->y + m->e02 * v->z; - out->y = m->e10 * v->x + m->e11 * v->y + m->e12 * v->z; - out->z = m->e20 * v->x + m->e21 * v->y + m->e22 * v->z; -} - -void mat23_applytovec3(Mat23* m, Vec3* v, Vec2* out) { - ssr_assert(m && v && out); - out->x = m->e00 * v->x + m->e01 * v->y + m->e02 * v->z; - out->y = m->e10 * v->x + m->e11 * v->y + m->e12 * v->z; -} - -void mat43_applytovec3(Mat43* m, Vec3* v, Vec4* out) { - ssr_assert(m && v && out); - out->x = m->e00 * v->x + m->e01 * v->y + m->e02 * v->z; - out->y = m->e10 * v->x + m->e11 * v->y + m->e12 * v->z; - out->z = m->e20 * v->x + m->e21 * v->y + m->e22 * v->z; - out->w = m->e30 * v->x + m->e31 * v->y + m->e32 * v->z; -}
\ No newline at end of file diff --git a/src/math/vec2.c b/src/math/vec2.c index 86192dc..152f965 100644 --- a/src/math/vec2.c +++ b/src/math/vec2.c @@ -2,6 +2,8 @@ #include "../util/assert.h" #include "../core/mem.h" +Vec2 vec2zero = { 0, 0}; + void vec2_scale(Vec2* v, float k, Vec2* out) { ssr_assert(v && out); out->x = v->x * k; diff --git a/src/math/vec3.c b/src/math/vec3.c index 4ca8519..1deb52e 100644 --- a/src/math/vec3.c +++ b/src/math/vec3.c @@ -7,6 +7,7 @@ Vec3 vec3forward = {0,0,1}; Vec3 vec3up = {0, 1, 0}; Vec3 vec3left = {1, 0, 0}; +Vec3 vec3zero = {0, 0, 0}; void vec3_cross(Vec3* v1, Vec3* v2, Vec3* out) { ssr_assert(v1 && v2 && out); diff --git a/src/math/vec4.c b/src/math/vec4.c index 4216a08..ca64820 100644 --- a/src/math/vec4.c +++ b/src/math/vec4.c @@ -4,7 +4,7 @@ #include "../util/assert.h" #include "../core/mem.h" - +Vec4 vec4zero = { 0, 0, 0,0 }; void vec4_dividew(Vec4* v, Vec3* out) { ssr_assert(out && v); diff --git a/src/util/type.h b/src/util/type.h index f62bbfa..2f16f7b 100644 --- a/src/util/type.h +++ b/src/util/type.h @@ -4,4 +4,8 @@ typedef unsigned int uint; typedef unsigned char bool; +#define FALSE 0 +#define TRUE 1 + + #endif
\ No newline at end of file |