summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-12-08 00:23:50 +0800
committerchai <chaifix@163.com>2019-12-08 00:23:50 +0800
commit3df29dc54c509c983dc8a0e23eab4160d48144f2 (patch)
treed8c5287c9979e731e373e7a1481aadd79d3f071b
parent8e684dc0c76708e3174f005aebcaabc144b85500 (diff)
+clipping
-rw-r--r--src/core/device.c136
-rw-r--r--src/core/device.h2
-rw-r--r--src/core/mem.h30
-rw-r--r--src/core/rasterizer.c226
-rw-r--r--src/core/rasterizer.h8
-rw-r--r--src/core/shader.c261
-rw-r--r--src/core/shader.h161
-rw-r--r--src/core/tris.c0
-rw-r--r--src/core/tris.h17
-rw-r--r--src/core/vert.c30
-rw-r--r--src/core/vert.h35
-rw-r--r--src/example/example.h2
-rw-r--r--src/example/example_cube.c73
-rw-r--r--src/example/example_dot.c36
-rw-r--r--src/example/example_texture.c88
-rw-r--r--src/extend/transform.h17
-rw-r--r--src/math/math.c2
-rw-r--r--src/math/math.h36
-rw-r--r--src/math/matrix.c753
-rw-r--r--src/math/vec2.c2
-rw-r--r--src/math/vec3.c1
-rw-r--r--src/math/vec4.c2
-rw-r--r--src/util/type.h4
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, &reg_v2[0].v2[i_a], &reg_v2[0].v2[i_b], &reg_v2[0].v2[i_c], &ssr_frag_in.v2[0]); \
+ if (varying_flag & VARYING_V2_01) reg_v2_01 = ssrS_bcpvec2(&bcp, &reg_v2[1].v2[i_a], &reg_v2[1].v2[i_b], &reg_v2[1].v2[i_c], &ssr_frag_in.v2[1]); \
+ if (varying_flag & VARYING_V2_02) reg_v2_02 = ssrS_bcpvec2(&bcp, &reg_v2[2].v2[i_a], &reg_v2[2].v2[i_b], &reg_v2[2].v2[i_c], &ssr_frag_in.v2[2]); \
+ if (varying_flag & VARYING_V2_03) reg_v2_03 = ssrS_bcpvec2(&bcp, &reg_v2[3].v2[i_a], &reg_v2[3].v2[i_b], &reg_v2[3].v2[i_c], &ssr_frag_in.v2[3]); \
+ if (varying_flag & VARYING_V2_04) reg_v2_04 = ssrS_bcpvec2(&bcp, &reg_v2[4].v2[i_a], &reg_v2[4].v2[i_b], &reg_v2[4].v2[i_c], &ssr_frag_in.v2[4]); \
+ if (varying_flag & VARYING_V2_05) reg_v2_05 = ssrS_bcpvec2(&bcp, &reg_v2[5].v2[i_a], &reg_v2[5].v2[i_b], &reg_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, &reg_v3[0].v3[i_a], &reg_v3[0].v3[i_b], &reg_v3[0].v3[i_c], &ssr_frag_in.v3[0]); \
+ if (varying_flag & VARYING_V3_01) reg_v3_01 = ssrS_bcpvec3(&bcp, &reg_v3[1].v3[i_a], &reg_v3[1].v3[i_b], &reg_v3[1].v3[i_c], &ssr_frag_in.v3[1]); \
+ if (varying_flag & VARYING_V3_02) reg_v3_02 = ssrS_bcpvec3(&bcp, &reg_v3[2].v3[i_a], &reg_v3[2].v3[i_b], &reg_v3[2].v3[i_c], &ssr_frag_in.v3[2]); \
+ if (varying_flag & VARYING_V3_03) reg_v3_03 = ssrS_bcpvec3(&bcp, &reg_v3[3].v3[i_a], &reg_v3[3].v3[i_b], &reg_v3[3].v3[i_c], &ssr_frag_in.v3[3]); \
+ if (varying_flag & VARYING_V3_04) reg_v3_04 = ssrS_bcpvec3(&bcp, &reg_v3[4].v3[i_a], &reg_v3[4].v3[i_b], &reg_v3[4].v3[i_c], &ssr_frag_in.v3[4]); \
+ if (varying_flag & VARYING_V3_05) reg_v3_05 = ssrS_bcpvec3(&bcp, &reg_v3[5].v3[i_a], &reg_v3[5].v3[i_b], &reg_v3[5].v3[i_c], &ssr_frag_in.v3[5]); \
+ if (varying_flag & VARYING_V3_06) reg_v3_06 = ssrS_bcpvec3(&bcp, &reg_v3[6].v3[i_a], &reg_v3[6].v3[i_b], &reg_v3[6].v3[i_c], &ssr_frag_in.v3[6]); \
+ if (varying_flag & VARYING_V3_07) reg_v3_07 = ssrS_bcpvec3(&bcp, &reg_v3[7].v3[i_a], &reg_v3[7].v3[i_b], &reg_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, &reg_v4[0].v4[i_a], &reg_v4[0].v4[i_b], &reg_v4[0].v4[i_c], &ssr_frag_in.v4[0]); \
+ if (varying_flag & VARYING_V4_01) reg_v4_01 = ssrS_bcpvec4(&bcp, &reg_v4[1].v4[i_a], &reg_v4[1].v4[i_b], &reg_v4[1].v4[i_c], &ssr_frag_in.v4[1]); \
+ if (varying_flag & VARYING_V4_02) reg_v4_02 = ssrS_bcpvec4(&bcp, &reg_v4[2].v4[i_a], &reg_v4[2].v4[i_b], &reg_v4[2].v4[i_c], &ssr_frag_in.v4[2]); \
+ if (varying_flag & VARYING_V4_03) reg_v4_03 = ssrS_bcpvec4(&bcp, &reg_v4[3].v4[i_a], &reg_v4[3].v4[i_b], &reg_v4[3].v4[i_c], &ssr_frag_in.v4[3]); \
+ if (varying_flag & VARYING_V4_04) reg_v4_04 = ssrS_bcpvec4(&bcp, &reg_v4[4].v4[i_a], &reg_v4[4].v4[i_b], &reg_v4[4].v4[i_c], &ssr_frag_in.v4[4]); \
+ if (varying_flag & VARYING_V4_05) reg_v4_05 = ssrS_bcpvec4(&bcp, &reg_v4[5].v4[i_a], &reg_v4[5].v4[i_b], &reg_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 = &reg_num[##i].num[idx];
+
+#define set_reg_v2_pointer(i)\
+ if (extra_varying_flag & VARYING_V2_##i) reg_v2_##i = &reg_v2[##i].v2[idx];
+
+#define set_reg_v3_pointer(i)\
+ if (extra_varying_flag & VARYING_V3_##i) reg_v3_##i = &reg_v3[##i].v3[idx];
+
+#define set_reg_v4_pointer(i)\
+ if (extra_varying_flag & VARYING_V4_##i) reg_v4_##i = &reg_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