diff options
author | chai <chaifix@163.com> | 2019-12-15 00:39:18 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-12-15 00:39:18 +0800 |
commit | 749bbc6a54e50c297ab49d9e515a3679651d1461 (patch) | |
tree | 097bbe044332e816aa481db1a4e325b8d3f63b0d | |
parent | 3f44877edfe4c301b258d522bcb4e8d9b6e92382 (diff) |
*misc
-rw-r--r-- | src/core/clip.c | 267 | ||||
-rw-r--r-- | src/core/clip.h | 16 | ||||
-rw-r--r-- | src/core/device.c | 118 | ||||
-rw-r--r-- | src/core/device.h | 45 | ||||
-rw-r--r-- | src/core/framebuffer.c | 0 | ||||
-rw-r--r-- | src/core/framebuffer.h | 16 | ||||
-rw-r--r-- | src/core/mem.h | 8 | ||||
-rw-r--r-- | src/core/rasterizer.c | 181 | ||||
-rw-r--r-- | src/core/rasterizer.h | 6 | ||||
-rw-r--r-- | src/core/shader.c | 325 | ||||
-rw-r--r-- | src/core/shader.h | 181 | ||||
-rw-r--r-- | src/core/texture.c | 35 | ||||
-rw-r--r-- | src/core/texture.h | 12 | ||||
-rw-r--r-- | src/core/vert.h | 4 | ||||
-rw-r--r-- | src/example/03_texture.c | 81 | ||||
-rw-r--r-- | src/extend/mesh.c | 209 | ||||
-rw-r--r-- | src/gizmo/gizmo.h | 17 | ||||
-rw-r--r-- | src/gizmo/icon2d.c | 0 | ||||
-rw-r--r-- | src/main.c | 11 | ||||
-rw-r--r-- | src/math/mat.c | 15 | ||||
-rw-r--r-- | src/math/math.h | 21 | ||||
-rw-r--r-- | src/math/vec4.c | 11 | ||||
-rw-r--r-- | src/shaders/common.c | 21 | ||||
-rw-r--r-- | src/shaders/common.h (renamed from src/shaders/common_header.h) | 8 | ||||
-rw-r--r-- | src/shaders/default.c | 51 | ||||
-rw-r--r-- | src/shaders/unlit.c | 38 | ||||
-rw-r--r-- | src/util/type.h | 1 |
27 files changed, 1077 insertions, 621 deletions
diff --git a/src/core/clip.c b/src/core/clip.c index 382c766..1deb4ee 100644 --- a/src/core/clip.c +++ b/src/core/clip.c @@ -1,5 +1,6 @@ #include "clip.h" #include "shader.h" +#include "../util/type.h" typedef enum { POSITIVE_W, @@ -60,73 +61,75 @@ static float get_intersect_ratio(Vec4* prev, Vec4* curr, Plane plane) { return 0; } } - -static bool clip_against_plane(Plane plane, uint varying_flag, ClippedBuffer* src_buffer, ClippedBuffer* dst_buffer) { - int idx = 0; - for (int i = 0; i < src_buffer->count; ++i) { - ClippedVert* prev = &src_buffer->vertices[(i - 1 + src_buffer->count) % src_buffer->count]; - ClippedVert* curr = &src_buffer->vertices[i]; - - bool prev_inside = is_inside_plane(&prev->clip_coord, plane); - bool curr_inside = is_inside_plane(&curr->clip_coord, plane); - - if (prev_inside != curr_inside) { - ClippedVert* dst = &dst_buffer->vertices[idx]; - float t = get_intersect_ratio(&prev->clip_coord, &curr->clip_coord, plane); - ssrS_lerpvec4(t, &prev->clip_coord, &curr->clip_coord, &dst->clip_coord); - /*set varying varibles*/ - if (varying_flag & VARYING_BASIC) { - if (varying_flag & VARYING_POSITION) ssrS_lerpvec3(t, &prev->vertex.position, &curr->vertex.position, &dst->vertex.position); - if (varying_flag & VARYING_NORMAL) ssrS_lerpvec3(t, &prev->vertex.normal, &curr->vertex.normal, &dst->vertex.normal); - if (varying_flag & VARYING_TANGENT) ssrS_lerpvec3(t, &prev->vertex.tangent, &curr->vertex.tangent, &dst->vertex.tangent); - if (varying_flag & VARYING_TEXCOORD) ssrS_lerpvec2(t, &prev->vertex.texcoord, &curr->vertex.texcoord, &dst->vertex.texcoord); - if (varying_flag & VARYING_COLOR) ssrS_lerpcolor(t, prev->vertex.color, curr->vertex.color, &dst->vertex.color); - if (varying_flag & VARYING_JOINT) ssrS_lerpvec4(t, &prev->vertex.joint, &curr->vertex.joint, &dst->vertex.joint); - if (varying_flag & VARYING_WEIGHT) ssrS_lerpvec4(t, &prev->vertex.weight, &curr->vertex.weight, &dst->vertex.weight); - } - if (varying_flag & VARYING_EXTRA) { - int j = 0; - if (varying_flag & VARYING_NUM) { - for (j = 0; j < REG_NUM_COUNT; ++j) { - if (varying_flag & (VARYING_NUM_00 << j)) { - ssrS_lerpnum(t, prev->num[j], curr->num[j], &dst->num[j]); - } - } - } - if (varying_flag & VARYING_V2) { - for (j = 0; j < REG_V2_COUNT; ++j) { - if (varying_flag & (VARYING_V2_00 << j)) { - ssrS_lerpvec2(t, &prev->v2[j], &curr->v2[j], &dst->v2[j]); - } - } - } - if (varying_flag & VARYING_V3) { - for (j = 0; j < REG_V3_COUNT; ++j) { - if (varying_flag & (VARYING_V3_00 << j)) { - ssrS_lerpvec3(t, &prev->v3[j], &curr->v3[j], &dst->v3[j]); - } - } - } - if (varying_flag & VARYING_V4) { - for (j = 0; j < REG_V4_COUNT; ++j) { - if (varying_flag & (VARYING_V4_00 << j)) { - ssrS_lerpvec4(t, &prev->v4[j], &curr->v4[j], &dst->v4[j]); - } - } - } - } - ++idx; - } - - if (curr_inside) { - ClippedVert* dst = &dst_buffer->vertices[idx]; - *dst = *curr; - ++idx; - } - } - dst_buffer->count = idx; - return idx < 3; -} +// +//static bool clip_against_plane(Plane plane, uint varying_flag, ClippedBuffer* src_buffer, ClippedBuffer* dst_buffer) { +// int idx = 0; +// for (int i = 0; i < src_buffer->count; ++i) { +// ClippedVert* prev = &src_buffer->vertices[(i - 1 + src_buffer->count) % src_buffer->count]; +// ClippedVert* curr = &src_buffer->vertices[i]; +// +// bool prev_inside = is_inside_plane(&prev->clip_coord, plane); +// bool curr_inside = is_inside_plane(&curr->clip_coord, plane); +// +// if (prev_inside != curr_inside) { +// ClippedVert* dst = &dst_buffer->vertices[idx]; +// float t = get_intersect_ratio(&prev->clip_coord, &curr->clip_coord, plane); +// ssrS_lerpvec4(t, &prev->clip_coord, &curr->clip_coord, &dst->clip_coord); +// /*set varying varibles*/ +// if (varying_flag & VARYING_BASIC) { +// if (varying_flag & VARYING_POSITION) ssrS_lerpvec3(t, &prev->vertex.position, &curr->vertex.position, &dst->vertex.position); +// if (varying_flag & VARYING_NORMAL) ssrS_lerpvec3(t, &prev->vertex.normal, &curr->vertex.normal, &dst->vertex.normal); +// if (varying_flag & VARYING_TANGENT) ssrS_lerpvec3(t, &prev->vertex.tangent, &curr->vertex.tangent, &dst->vertex.tangent); +// if (varying_flag & VARYING_TEXCOORD) ssrS_lerpvec2(t, &prev->vertex.texcoord, &curr->vertex.texcoord, &dst->vertex.texcoord); +// if (varying_flag & VARYING_COLOR) ssrS_lerpcolor(t, prev->vertex.color, curr->vertex.color, &dst->vertex.color); +///* +// if (varying_flag & VARYING_JOINT) ssrS_lerpvec4(t, &prev->vertex.joint, &curr->vertex.joint, &dst->vertex.joint); +// if (varying_flag & VARYING_WEIGHT) ssrS_lerpvec4(t, &prev->vertex.weight, &curr->vertex.weight, &dst->vertex.weight); +//*/ +// } +// if (varying_flag & VARYING_EXTRA) { +// int j = 0; +// if (varying_flag & VARYING_NUM) { +// for (j = 0; j < REG_NUM_COUNT; ++j) { +// if (varying_flag & (VARYING_NUM_00 << j)) { +// ssrS_lerpnum(t, prev->num[j], curr->num[j], &dst->num[j]); +// } +// } +// } +// if (varying_flag & VARYING_V2) { +// for (j = 0; j < REG_V2_COUNT; ++j) { +// if (varying_flag & (VARYING_V2_00 << j)) { +// ssrS_lerpvec2(t, &prev->v2[j], &curr->v2[j], &dst->v2[j]); +// } +// } +// } +// if (varying_flag & VARYING_V3) { +// for (j = 0; j < REG_V3_COUNT; ++j) { +// if (varying_flag & (VARYING_V3_00 << j)) { +// ssrS_lerpvec3(t, &prev->v3[j], &curr->v3[j], &dst->v3[j]); +// } +// } +// } +// if (varying_flag & VARYING_V4) { +// for (j = 0; j < REG_V4_COUNT; ++j) { +// if (varying_flag & (VARYING_V4_00 << j)) { +// ssrS_lerpvec4(t, &prev->v4[j], &curr->v4[j], &dst->v4[j]); +// } +// } +// } +// } +// ++idx; +// } +// +// if (curr_inside) { +// ClippedVert* dst = &dst_buffer->vertices[idx]; +// *dst = *curr; +// ++idx; +// } +// } +// dst_buffer->count = idx; +// return idx < 3; +//} #define CLIP(plane, from, to) \ do { \ @@ -136,6 +139,36 @@ do { \ } \ }while(0) +ClippedBuffer clip_buffer; + +byte* clip_buffer_data[REG_TOTAL] = +{ + &clip_buffer.temp_reg_num[0], + &clip_buffer.temp_reg_num[1], + &clip_buffer.temp_reg_num[2], + &clip_buffer.temp_reg_num[3], + &clip_buffer.temp_reg_v2[0], + &clip_buffer.temp_reg_v2[1], + &clip_buffer.temp_reg_v2[2], + &clip_buffer.temp_reg_v2[3], + &clip_buffer.temp_reg_v2[4], + &clip_buffer.temp_reg_v2[5], + &clip_buffer.temp_reg_v3[0], + &clip_buffer.temp_reg_v3[1], + &clip_buffer.temp_reg_v3[2], + &clip_buffer.temp_reg_v3[3], + &clip_buffer.temp_reg_v3[4], + &clip_buffer.temp_reg_v3[5], + &clip_buffer.temp_reg_v3[6], + &clip_buffer.temp_reg_v3[7], + &clip_buffer.temp_reg_v4[0], + &clip_buffer.temp_reg_v4[1], + &clip_buffer.temp_reg_v4[2], + &clip_buffer.temp_reg_v4[3], + &clip_buffer.temp_reg_v4[4], + &clip_buffer.temp_reg_v4[5], +}; + bool clip_triangle(Vec4* c0, Vec4* c1, Vec4* c2, Vert* v0, Vert* v1, Vert* v2, uint varying_flag, ClippedBuffer* buffer) { bool is_visible = is_vertex_visible(c0) && is_vertex_visible(c1) @@ -144,55 +177,53 @@ bool clip_triangle(Vec4* c0, Vec4* c1, Vec4* c2, Vert* v0, Vert* v1, Vert* v2, u if (is_visible) { return 0; /*no need to clip*/ } - - /*clipping it*/ - - static ClippedBuffer temp; - - /*copy vert data to temp*/ - temp.count = 3; -#define INIT_CLIP_VERT(idx) \ - temp.vertices[idx].clip_coord = *c##idx; \ - temp.vertices[idx].vertex = *v##idx; \ - if (varying_flag & VARYING_EXTRA) { \ - int i = 0; \ - if(varying_flag & VARYING_NUM) { \ - for (i = 0; i < REG_NUM_COUNT; ++i) { \ - if (varying_flag & (VARYING_NUM_00 << i)) \ - temp.vertices[idx].num[i] = reg_num[i].num[v##idx->index]; \ - } \ - } \ - if(varying_flag & VARYING_V2) { \ - for (i = 0; i < REG_V2_COUNT; ++i) { \ - if (varying_flag & (VARYING_V2_00 << i)) \ - temp.vertices[idx].v2[i] = reg_v2[i].v2[v##idx->index]; \ - } \ - } \ - if(varying_flag & VARYING_V3) { \ - for (i = 0; i < REG_V3_COUNT; ++i) { \ - if (varying_flag & (VARYING_V3_00 << i)) \ - temp.vertices[idx].v3[i] = reg_v3[i].v3[v##idx->index]; \ - } \ - } \ - if(varying_flag & VARYING_V4) { \ - for (i = 0; i < REG_V4_COUNT; ++i) { \ - if (varying_flag & (VARYING_V4_00 << i)) \ - temp.vertices[idx].v4[i] = reg_v4[i].v4[v##idx->index]; \ - } \ - } \ - } - INIT_CLIP_VERT(0); - INIT_CLIP_VERT(1); - INIT_CLIP_VERT(2); -#undef INIT_CLIP_VERT - - CLIP(POSITIVE_W, &temp, buffer); - CLIP(POSITIVE_X, buffer, &temp); - CLIP(NEGATIVE_X, &temp, buffer); - CLIP(POSITIVE_Y, buffer, &temp); - CLIP(NEGATIVE_Y, &temp, buffer); - CLIP(POSITIVE_Z, buffer, &temp); - CLIP(NEGATIVE_Z, &temp, buffer); - - return 1; +// +// /*clipping it*/ +// +// /*copy vert data to clip_buffer*/ +// clip_buffer.count = 3; +//#define INIT_CLIP_VERT(idx) \ +// clip_buffer.vertices[idx].clip_coord = *c##idx; \ +// clip_buffer.vertices[idx].vertex = *v##idx; \ +// if (varying_flag & VARYING_EXTRA) { \ +// int i = 0; \ +// if(varying_flag & VARYING_NUM) { \ +// for (i = 0; i < REG_NUM_COUNT; ++i) { \ +// if (varying_flag & (VARYING_NUM_00 << i)) \ +// clip_buffer.vertices[idx].num[i] = reg_num[i].num[v##idx->index]; \ +// } \ +// } \ +// if(varying_flag & VARYING_V2) { \ +// for (i = 0; i < REG_V2_COUNT; ++i) { \ +// if (varying_flag & (VARYING_V2_00 << i)) \ +// clip_buffer.vertices[idx].v2[i] = reg_v2[i].v2[v##idx->index]; \ +// } \ +// } \ +// if(varying_flag & VARYING_V3) { \ +// for (i = 0; i < REG_V3_COUNT; ++i) { \ +// if (varying_flag & (VARYING_V3_00 << i)) \ +// clip_buffer.vertices[idx].v3[i] = reg_v3[i].v3[v##idx->index]; \ +// } \ +// } \ +// if(varying_flag & VARYING_V4) { \ +// for (i = 0; i < REG_V4_COUNT; ++i) { \ +// if (varying_flag & (VARYING_V4_00 << i)) \ +// clip_buffer.vertices[idx].v4[i] = reg_v4[i].v4[v##idx->index]; \ +// } \ +// } \ +// } +// INIT_CLIP_VERT(0); +// INIT_CLIP_VERT(1); +// INIT_CLIP_VERT(2); +//#undef INIT_CLIP_VERT +// +// CLIP(POSITIVE_W, &clip_buffer, buffer); +// CLIP(POSITIVE_X, buffer, &clip_buffer); +// CLIP(NEGATIVE_X, &clip_buffer, buffer); +// CLIP(POSITIVE_Y, buffer, &clip_buffer); +// CLIP(NEGATIVE_Y, &clip_buffer, buffer); +// CLIP(POSITIVE_Z, buffer, &clip_buffer); +// CLIP(NEGATIVE_Z, &clip_buffer, buffer); +// +// return 1; } diff --git a/src/core/clip.h b/src/core/clip.h index b6f2702..c22bb8d 100644 --- a/src/core/clip.h +++ b/src/core/clip.h @@ -6,25 +6,37 @@ #define LERP(t,a,b) ((1-(t))*(a)+(t)*(b)) -typedef struct ClippedVert { +typedef struct { /*clipping coord*/ Vec4 clip_coord; /*vertex data*/ Vert vertex; /*register values*/ +/* float num[4]; Vec2 v2[6]; Vec3 v3[8]; Vec4 v4[6]; +*/ } ClippedVert; #define CLIP_BUFFER_SIZE 6 -typedef struct ClippedBuffer { +typedef struct { ClippedVert vertices[CLIP_BUFFER_SIZE]; uint count; + /*temp register*/ + float temp_reg_num[4][CLIP_BUFFER_SIZE]; + Vec2 temp_reg_v2[6][CLIP_BUFFER_SIZE]; + Vec3 temp_reg_v3[8][CLIP_BUFFER_SIZE]; + Vec4 temp_reg_v4[6][CLIP_BUFFER_SIZE]; } ClippedBuffer; +ClippedBuffer clip_buffer; + +typedef void* (*BcpInterpolator)(Vec3* bc, void* a, void* b, void* c, void* out); +typedef void* (*LinearInterpolator)(float t, void* a, void* b, void* c, void* out); + bool clip_triangle(Vec4* c0, Vec4* c1, Vec4* c2, Vert* v0, Vert* v1, Vert* v2, uint varying_flag, ClippedBuffer* clipped); uint clip_line(); diff --git a/src/core/device.c b/src/core/device.c index cf9fee2..3566448 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -21,7 +21,7 @@ typedef struct VertexAttr { /* ** 状态结构 */ -struct { +static struct { /* MVP矩阵栈 */ Mat4 matrices[3][MATRIXDEPTH]; uint matrixtop[3]; @@ -33,7 +33,7 @@ struct { uint buffersize; /*framebuffer size in bytess*/ /* zbuffer 深度会被映射到0~1的非线性区间*/ - uint* zbuffer; + float* zbuffer; /* 顶点数据 */ Vert* verts; uint nverts; @@ -43,12 +43,19 @@ struct { Program* program; UniformCollection uniforms; - /*texture relavent*/ + /* texture relavent */ FilterMode filtermode; WrapMode wrapmode; + //FrameBuffer* framebuffer; + uint enable; + struct { + ssr_BlendFactor src; + ssr_BlendFactor dst; + } blendfactor; + } state; /* @@ -75,11 +82,14 @@ void ssr_init(ssr_Config* conf) { state.framebuffer = conf->target; } state.buffersize = sizeof(Color) * config.width * config.height; - state.zbuffer = ssrM_newvector(uint, config.width * config.height); - memset(state.zbuffer, 0xff, sizeof(uint)*config.width*config.height); + state.zbuffer = ssrM_newvector(float, config.width * config.height); + //memset(state.zbuffer, 0xff, sizeof(uint)*config.width*config.height); state.filtermode = FILTERMODE_POINT; state.wrapmode = WRAPMODE_CLAMP; + + state.blendfactor.src = BLENDFACTOR_SRC_ALPHA; + state.blendfactor.dst = BLENDFACTOR_ONE_MINUS_SRC_ALPHA; } float ssr_getaspect() { @@ -110,6 +120,19 @@ WrapMode ssr_getwrapmode() { return state.wrapmode; } +void ssr_bindframebuffer(FrameBuffer* fbo) { + +} + +void ssr_unbindframebuffer() { + +} + +void ssr_setblendfunc(ssr_BlendFactor sfactor, ssr_BlendFactor dfactor) { + state.blendfactor.src = sfactor; + state.blendfactor.dst = dfactor; +} + void ssr_matrixmode(ssr_MatrixMode mode) { state.matrixmode = mode; } @@ -181,6 +204,11 @@ void ssr_getmvp(Mat4* out) { mat4_multiply(&GETMATRIX(MATRIX_PROJECTION), out, out); } +void ssr_getm(Mat4* out) { + ssr_assert(out); + *out = GETMATRIX(MATRIX_MODEL); +} + void ssr_getmv(Mat4* out) { ssr_assert(out); mat4_multiply(&GETMATRIX(MATRIX_VIEW), &GETMATRIX(MATRIX_MODEL), out); @@ -240,7 +268,10 @@ void ssr_clearcolor(Color color) { } void ssr_cleardepth() { - memset(state.zbuffer, 0xff, sizeof(uint)*config.width*config.height); + //memset(state.zbuffer, 0xff, sizeof(uint)*config.width*config.height); + for (int i = 0; i < config.width * config.height; ++i) { + state.zbuffer[i] = 1; + } } void ssr_putpoint(uint screenx, uint screeny, Color color) { @@ -249,24 +280,24 @@ void ssr_putpoint(uint screenx, uint screeny, Color color) { BUFFER[screeny * config.width + screenx] = color; } +void ssr_putpoint32(uint screenx, uint screeny, Color32* c32) { + Color c = color32_tocolor(c32); + ssr_putpoint(screenx, screeny, c); +} + Color ssr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { unsigned int c = (a << 24) | (r << 16) | (g << 8) | b; return c; } -bool ssr_testdepth(uint x, uint y, uint depth) { - if (!contains(x, y, 0, config.width - 1, 0, config.height - 1)) - return 0; +bool ssr_testdepth(uint x, uint y, float depth){ uint off = x + y * config.width; - if (state.zbuffer[off] < depth) - return 0; - state.zbuffer[off] = depth; - return 1; + return state.zbuffer[off] >= depth; } -bool ssr_testdepthf(uint x, uint y, float depth) { - uint d = UINT_MAX * (double)depth; - return ssr_testdepth(x, y, d); +void ssr_writedepth(uint x, uint y, float depth) { + uint off = x + y * config.width; + state.zbuffer[off] = depth; } void ssrU_viewport(Vec2* p, Vec2* out) { @@ -278,6 +309,26 @@ void ssrU_viewport(Vec2* p, Vec2* out) { out->y = (int)round((1 - p->y) * (halfh - 0.5f)); } +void ssr_blend(Color32* src, Color32* dst, Color32* out) { + ssrU_blend(state.blendfactor.src, state.blendfactor.dst, src, dst, out); +} + +void ssrU_blend(ssr_BlendFactor sfactor + , ssr_BlendFactor dfactor + , Color32* src + , Color32* dst + , Color32* out +) { + ssr_assert(src && dst && out); + +} + +Color32 ssr_getfbocolor(uint x, uint y) { + Color c = state.framebuffer[x + y * config.width]; + Color32 c32; color_tocolor32(c, &c32); + return c32; +} + void ssr_bindvertices(Vert* verts, int nverts, uint* indices, int nprims) { ssr_assert(verts && indices); state.verts = verts; @@ -301,7 +352,7 @@ FragmentShaderIn ssr_frag_in; static struct { Vec4* coords; uint length; -} clipping_buffer; +} clip_coords; static ClippedBuffer clipped_buffer; /*clipping result*/ @@ -310,6 +361,7 @@ void ssr_draw(ssr_PrimitiveType primitive) { static Mat4 mvp, mv; + /*set built-in uniforms*/ ssr_getmvp(&mvp); ssr_getmv(&mv); state.uniforms.model = &GETMATRIX(MATRIX_MODEL); @@ -323,15 +375,17 @@ void ssr_draw(ssr_PrimitiveType primitive) { /*prepare registers if necessary*/ if (use_extra_varyings) { - ssrS_setregisters(varying_flag, state.nverts); + ssrS_openregs(varying_flag); + ssrS_setregisters(state.nverts); + ssrS_setactiveregr(); } /*resize clipping coords buffer*/ - if (clipping_buffer.length < state.nverts) { + if (clip_coords.length < state.nverts) { ssrM_resizevector( Vec4, - clipping_buffer.coords, - clipping_buffer.length, + clip_coords.coords, + clip_coords.length, state.nverts, FALSE ); @@ -343,9 +397,9 @@ void ssr_draw(ssr_PrimitiveType primitive) { ssr_vert_in.vertex = vert; /*set register pointers*/ if (use_extra_varyings) { - ssrS_setupregisterpoints(varying_flag, vert->index); + ssrS_setupregisterpoints(vert->index); } - state.program->vertexshader(&state.uniforms, &ssr_vert_in, &clipping_buffer.coords[i]); + state.program->vertexshader(&state.uniforms, &ssr_vert_in, &clip_coords.coords[i]); } /*set register pointer to frag-in*/ @@ -363,9 +417,9 @@ void ssr_draw(ssr_PrimitiveType primitive) { 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]; + h0 = &clip_coords.coords[i0], + h1 = &clip_coords.coords[i1], + h2 = &clip_coords.coords[i2]; v0 = &state.verts[i0]; v1 = &state.verts[i1]; @@ -379,8 +433,9 @@ void ssr_draw(ssr_PrimitiveType primitive) { 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) + if (ab.x * ac.y - ab.y * ac.x <= 0) { continue; /*cull*/ + } } /*clipping*/ @@ -388,20 +443,21 @@ void ssr_draw(ssr_PrimitiveType primitive) { /*rasterization*/ if (!clipped) { - ssrR_triangle(h0, h1, h2, v0, v1, v2, TRUE, NULL, NULL, NULL, state.program, &state.uniforms); + /*ssrS_setactiveregr();*/ + ssrR_triangle(h0, h1, h2, v0, v1, v2, state.program, &state.uniforms); } else { + ssrS_setactiveregc(); if (clipped_buffer.count >= 3) { ClippedVert* vt0 = &clipped_buffer.vertices[0], *vt1, *vt2; for (int i = 1; i <= clipped_buffer.count - 2; ++i) { 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); + v0 = &vt0->vertex; v1 = &vt1->vertex; v2 = &vt2->vertex; + ssrR_triangle(h0, h1, h2, v0, v1, v2, state.program, &state.uniforms); } } } - } } else if (primitive == PRIMITIVE_POINT) { diff --git a/src/core/device.h b/src/core/device.h index b265471..d8daf76 100644 --- a/src/core/device.h +++ b/src/core/device.h @@ -8,30 +8,47 @@ #include "shader.h" #include "rasterizer.h" #include "vert.h" +#include "framebuffer.h" -typedef enum ssr_MatrixMode { +typedef enum { MATRIX_MODEL = 0, MATRIX_VIEW = 1, MATRIX_PROJECTION = 2, } ssr_MatrixMode; -typedef struct ssr_Config { +typedef struct { int width, height; bool dbuffer;/* double buffer? */ Color* target; /* screen target buffer */ } ssr_Config; -typedef enum ssr_PrimitiveType { +typedef enum { PRIMITIVE_POINT, PRIMITIVE_LINE, PRIMITIVE_TRIANGLE, } ssr_PrimitiveType; -typedef enum ssr_EnableMask { - ENABLEMASK_BACKFACECULL = 1 , - ENABLEMASK_DEPTHTEST = 1 << 1, +typedef enum { + ENABLEMASK_BACKFACECULL = 1, + ENABLEMASK_DEPTHTEST = 1 << 1, + ENABLEMASK_MULTISAMPLE = 1 << 2, + ENABLEMASK_BLEND = 1 << 3, + ENABLEMASK_WRITEDEPTH = 1 << 4, } ssr_EnableMask; +typedef enum { + BLENDFACTOR_ONE, + BLENDFACTOR_ZERO, + BLENDFACTOR_SRC_COLOR, + BLENDFACTOR_ONE_MINUS_SRC_COLOR, + BLENDFACTOR_DST_COLOR, + BLENDFACTOR_ONE_MINUS_DST_COLOR, + BLENDFACTOR_SRC_ALPHA, + BLENDFACTOR_ONE_MINUS_SRC_ALPHA, + BLENDFACTOR_DST_ALPHA, + BLENDFACTOR_ONE_MINUS_DST_ALPHA, +} ssr_BlendFactor; + void ssr_init(ssr_Config* config); float ssr_getaspect(); @@ -61,6 +78,7 @@ void ssr_ortho(float l, float r, float b, float t, float n, float f); void ssr_viewport(float l, float r, float b, float t); +void ssr_getm(Mat4* out); void ssr_getmv(Mat4* out); void ssr_getmvp(Mat4* out); @@ -86,19 +104,28 @@ void ssr_clearcolor(Color color); void ssr_cleardepth(); void ssr_putpoint(uint screenx, uint screeny, Color color); /*直接修改某个位置的颜色*/ +void ssr_putpoint32(uint screenx, uint screeny, Color32* c32); void ssr_present(); Color ssr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a); -//bool ssr_cutline(int* x0, int* y0, int* x1, int* y1); +bool ssr_testdepth(uint x, uint y, float depth); +void ssr_writedepth(uint x, uint y, float depth); -bool ssr_testdepth(uint x, uint y, uint depth); /*尝试写入深度,如果可绘制返回true,否则discard*/ -bool ssr_testdepthf(uint x, uint y, float depth01); +void ssr_blend(Color32* src, Color32* dst, Color32* out); void ssrU_viewport(Vec2* p, Vec2* out); +void ssrU_blend(ssr_BlendFactor sfactor, ssr_BlendFactor dfactor, Color32* src, Color32* dst, Color* out); + +Color32 ssr_getfbocolor(uint x, uint y); FilterMode ssr_getfiltermode(); WrapMode ssr_getwrapmode(); +void ssr_bindframebuffer(FrameBuffer* fbo); +void ssr_unbindframebuffer(); + +void ssr_setblendfunc(ssr_BlendFactor sfactor, ssr_BlendFactor dfactor); + #endif
\ No newline at end of file diff --git a/src/core/framebuffer.c b/src/core/framebuffer.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/core/framebuffer.c diff --git a/src/core/framebuffer.h b/src/core/framebuffer.h new file mode 100644 index 0000000..3f03200 --- /dev/null +++ b/src/core/framebuffer.h @@ -0,0 +1,16 @@ +#ifndef _SOFTSHADEROOM_FRAMEBUFFER_H_ +#define _SOFTSHADEROOM_FRAMEBUFFER_H_ + +#include "texture.h" + +/*frame buffer object*/ + +typedef Texture RenderTexture; + +typedef struct FrameBuffer{ + RenderTexture rt; +} FrameBuffer; + +FrameBuffer* fbo_create(uint height, uint width); + +#endif
\ No newline at end of file diff --git a/src/core/mem.h b/src/core/mem.h index 70e8011..b51661b 100644 --- a/src/core/mem.h +++ b/src/core/mem.h @@ -3,9 +3,6 @@ #include <memory.h> -void ssrM_freemem(); -void ssrM_realloc(); - #define ssrM_copy memcpy #define ssrM_zero(obj, size) memset(obj, 0, size) @@ -13,11 +10,10 @@ void ssrM_realloc(); #define ssrM_newvector(T, c) ((T*)calloc(c, sizeof(T))) #define ssrM_free(obj) free(obj) -/*扩容一倍*/ -#define ssrM_scalevector(T, v, curlen) \ +#define ssrM_scalevector(T, v, curlen) \ do{ \ ssr_assert(v); \ - curlen = curlen << 1; \ + curlen <<= 1; \ v = (T*)realloc(v, sizeof(T)*curlen); \ }while(0) diff --git a/src/core/rasterizer.c b/src/core/rasterizer.c index bf210b7..772eb29 100644 --- a/src/core/rasterizer.c +++ b/src/core/rasterizer.c @@ -84,18 +84,11 @@ static void puttriangle(Vec2* A, Vec2* B, Vec2* C, Color c) { 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 -) { +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); static Vec3 SA, SB, SC; - static Vec3 bcp; + static Vec3 bc; vec4_dividew(CA, &SA); ssrU_viewport(&SA, &SA); vec4_dividew(CB, &SB); ssrU_viewport(&SB, &SB); @@ -104,11 +97,11 @@ void ssrR_triangle( puttriangle(&SA, &SB, &SC, 0xffff0000); return; */ - Vec3 *sa = &SA, *sb = &SB, *sc = &SC, *tmp; Vec4* v4tmp; Vert* vtemp; ClippedVert* cvtmp; + 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); if (!from_reg) swap(cvtmp, CVA, CVB); } - if (sc->y < sb->y) { swap(tmp, sb, sc); swap(v4tmp, CB, CC); swap(vtemp, B, C); if (!from_reg) swap(cvtmp, CVC, CVB); } - if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(vtemp, A, B); if (!from_reg) swap(cvtmp, CVA, CVB); } + if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(vtemp, A, B); } + if (sc->y < sb->y) { swap(tmp, sb, sc); swap(v4tmp, CB, CC); swap(vtemp, B, C); } + if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(vtemp, A, B); } #undef swap Vec2 AB = {sb->x - sa->x, sb->y - sa->y}, AC = { sc->x - sa->x, sc->y - sa->y }; @@ -118,7 +111,7 @@ void ssrR_triangle( float invkAB = (sb->x - sa->x) / (sb->y - sa->y + EPSILON); float invkBC = (sc->x - sb->x) / (sc->y - sb->y + EPSILON); - Color color; + Color32 color; float from, to; Vec2 p; float depth; @@ -126,115 +119,67 @@ void ssrR_triangle( 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]); \ - } \ - } - Vec3 s[2], u; s[0].x = sc->x - sa->x; s[0].y = sb->x - sa->x; s[1].x = sc->y - sa->y; s[1].y = sb->y - sa->y; + bool depth_test = ssr_isenable(ENABLEMASK_DEPTHTEST); + bool multi_sample = ssr_isenable(ENABLEMASK_MULTISAMPLE); + bool blend = ssr_isenable(ENABLEMASK_BLEND); + bool write_depth = ssr_isenable(ENABLEMASK_WRITEDEPTH); + +#define DO_INTERPOLATION \ + if (varying_flag & VARYING_BASIC) { \ + if (varying_flag & VARYING_POSITION) ssrS_bcpvec3(&bc, &A->position, &B->position, &C->position, &ssr_frag_in.position); \ + if (varying_flag & VARYING_NORMAL) ssrS_bcpvec3(&bc, &A->normal, &B->normal, &C->normal, &ssr_frag_in.normal); \ + if (varying_flag & VARYING_TANGENT) ssrS_bcpvec3(&bc, &A->tangent, &B->tangent, &C->tangent, &ssr_frag_in.tangent); \ + if (varying_flag & VARYING_TEXCOORD) ssrS_bcpvec2(&bc, &A->texcoord, &B->texcoord, &C->texcoord, &ssr_frag_in.texcoord); \ +/* if (varying_flag & VARYING_JOINT) ssrS_bcpvec4(&bc, &A->joint, &B->joint, &C->joint, &ssr_frag_in.joint); \ + if (varying_flag & VARYING_WEIGHT) ssrS_bcpvec4(&bc, &A->weight, &B->weight, &C->weight, &ssr_frag_in.weight); \ + */ if (varying_flag & VARYING_COLOR) ssrS_bcpcolor(&bc, A->color, B->color, C->color, &ssr_frag_in.color); \ + } + #define RENDER_TRIANGLE \ - for (p.y = FROM->y; p.y < TO->y + OFFSET; ++p.y) { \ - SET_FROM_AND_TO \ - s[1].z = sa->y - p.y; \ - for (p.x = from; order * (p.x - to) <= 0; p.x += order) { \ - s[0].z = sa->x - p.x; \ - vec3_cross(&s[0], &s[1], &u); \ - discardif(compare(u.z, 0)); \ - u.z = 1.f / u.z; \ - 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*/ \ - if(ssr_isenable(ENABLEMASK_DEPTHTEST)){ \ - 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); \ - } \ + for (p.y = FROM->y; p.y < TO->y + OFFSET; ++p.y) { \ + SET_FROM_AND_TO \ + s[1].z = sa->y - p.y; \ + for (p.x = from; order * (p.x - to) <= 0; p.x += order) { \ + s[0].z = sa->x - p.x; \ + vec3_cross(&s[0], &s[1], &u); \ + discardif(compare(u.z, 0)); \ + u.z = 1.f / u.z; \ + bc.x = 1.f - (u.x + u.y) * u.z; \ + bc.y = u.y * u.z; \ + bc.z = u.x * u.z; \ + discardif(bc.x < 0 || bc.y < 0 || bc.z < 0); \ + /*perspective correction*/ \ + bc.x *= CAw; bc.y *= CBw; bc.z *= CCw; \ + vec3_scale(&bc, 1.f / (bc.x + bc.y + bc.z), &bc); \ + /*early depth testing*/ \ + if(depth_test ){ \ + depth = bc.x*sa->z+bc.y*sb->z+bc.z*sc->z; \ + discardif(!ssr_testdepth(p.x, p.y, depth)); \ + } \ + /*set varying variables*/ \ + DO_INTERPOLATION \ + ssrS_solveregs(&bc, A->index, B->index, C->index); \ + /*enter fragment shader*/ \ + if(program->fragmentshader(uniforms, &ssr_frag_in, &color)) { \ + /*MSAA*/ \ + if(multi_sample) { \ + \ + } \ + /*blend*/ \ + if(blend) { \ + Color32 dst; dst = ssr_getfbocolor(p.x, p.y); \ + ssr_blend(&color, &dst, &color); \ + } \ + if(write_depth) { \ + ssr_writedepth(p.x, p.y, depth); \ + } \ + ssr_putpoint32(p.x, p.y, &color); \ + } \ + } \ } #define FROM sa diff --git a/src/core/rasterizer.h b/src/core/rasterizer.h index eceb8c7..8e35511 100644 --- a/src/core/rasterizer.h +++ b/src/core/rasterizer.h @@ -13,11 +13,7 @@ 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, - bool from_reg, - ClippedVert* CVA, ClippedVert* CVB, ClippedVert* CVC, - Program* program, UniformCollection* uniforms +void ssrR_triangle(Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Program* program, UniformCollection* uniforms ); #endif
\ No newline at end of file diff --git a/src/core/shader.c b/src/core/shader.c index a508820..0490362 100644 --- a/src/core/shader.c +++ b/src/core/shader.c @@ -31,199 +31,182 @@ 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 }, +extern FragmentShaderIn ssr_frag_in; + +Register registers[REG_TOTAL] = { + /*4 float registers*/ + { 0, REGTYPE_NUM, sizeof(float), NULL }, + { 0, REGTYPE_NUM, sizeof(float), NULL }, + { 0, REGTYPE_NUM, sizeof(float), NULL }, + { 0, REGTYPE_NUM, sizeof(float), NULL }, + /*6 vec2 registers*/ + { 0, REGTYPE_VEC2, sizeof(Vec2), NULL }, + { 0, REGTYPE_VEC2, sizeof(Vec2), NULL }, + { 0, REGTYPE_VEC2, sizeof(Vec2), NULL }, + { 0, REGTYPE_VEC2, sizeof(Vec2), NULL }, + { 0, REGTYPE_VEC2, sizeof(Vec2), NULL }, + { 0, REGTYPE_VEC2, sizeof(Vec2), NULL }, + /*8 vec3 registers*/ + { 0, REGTYPE_VEC3, sizeof(Vec3), NULL }, + { 0, REGTYPE_VEC3, sizeof(Vec3), NULL }, + { 0, REGTYPE_VEC3, sizeof(Vec3), NULL }, + { 0, REGTYPE_VEC3, sizeof(Vec3), NULL }, + { 0, REGTYPE_VEC3, sizeof(Vec3), NULL }, + { 0, REGTYPE_VEC3, sizeof(Vec3), NULL }, + { 0, REGTYPE_VEC3, sizeof(Vec3), NULL }, + { 0, REGTYPE_VEC3, sizeof(Vec3), NULL }, + /*6 vec4 registers*/ + { 0, REGTYPE_VEC4, sizeof(Vec4), NULL }, + { 0, REGTYPE_VEC4, sizeof(Vec4), NULL }, + { 0, REGTYPE_VEC4, sizeof(Vec4), NULL }, + { 0, REGTYPE_VEC4, sizeof(Vec4), NULL }, + { 0, REGTYPE_VEC4, sizeof(Vec4), NULL }, + { 0, REGTYPE_VEC4, sizeof(Vec4), 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 }, +ActiveReg active_regs[REG_TOTAL] = { + /*4 float registers*/ + { sizeof(float), NULL, ®_num_00, ssrS_bcpnum, &ssr_frag_in.num[0] }, + { sizeof(float), NULL, ®_num_01, ssrS_bcpnum, &ssr_frag_in.num[1] }, + { sizeof(float), NULL, ®_num_02, ssrS_bcpnum, &ssr_frag_in.num[2] }, + { sizeof(float), NULL, ®_num_03, ssrS_bcpnum, &ssr_frag_in.num[3] }, + /*6 vec2 registers*/ + { sizeof(Vec2), NULL, ®_v2_00, ssrS_bcpvec2, &ssr_frag_in.v2[0] }, + { sizeof(Vec2), NULL, ®_v2_01, ssrS_bcpvec2, &ssr_frag_in.v2[1] }, + { sizeof(Vec2), NULL, ®_v2_02, ssrS_bcpvec2, &ssr_frag_in.v2[2] }, + { sizeof(Vec2), NULL, ®_v2_03, ssrS_bcpvec2, &ssr_frag_in.v2[3] }, + { sizeof(Vec2), NULL, ®_v2_04, ssrS_bcpvec2, &ssr_frag_in.v2[4] }, + { sizeof(Vec2), NULL, ®_v2_05, ssrS_bcpvec2, &ssr_frag_in.v2[5] }, + /*8 vec3 registers*/ + { sizeof(Vec3), NULL, ®_v3_00, ssrS_bcpvec3, &ssr_frag_in.v3[0] }, + { sizeof(Vec3), NULL, ®_v3_01, ssrS_bcpvec3, &ssr_frag_in.v3[1] }, + { sizeof(Vec3), NULL, ®_v3_02, ssrS_bcpvec3, &ssr_frag_in.v3[2] }, + { sizeof(Vec3), NULL, ®_v3_03, ssrS_bcpvec3, &ssr_frag_in.v3[3] }, + { sizeof(Vec3), NULL, ®_v3_04, ssrS_bcpvec3, &ssr_frag_in.v3[4] }, + { sizeof(Vec3), NULL, ®_v3_05, ssrS_bcpvec3, &ssr_frag_in.v3[5] }, + { sizeof(Vec3), NULL, ®_v3_06, ssrS_bcpvec3, &ssr_frag_in.v3[6] }, + { sizeof(Vec3), NULL, ®_v3_07, ssrS_bcpvec3, &ssr_frag_in.v3[7] }, + /*6 vec4 registers*/ + { sizeof(Vec4), NULL, ®_v4_00, ssrS_bcpvec4, &ssr_frag_in.v4[0] }, + { sizeof(Vec4), NULL, ®_v4_01, ssrS_bcpvec4, &ssr_frag_in.v4[1] }, + { sizeof(Vec4), NULL, ®_v4_02, ssrS_bcpvec4, &ssr_frag_in.v4[2] }, + { sizeof(Vec4), NULL, ®_v4_03, ssrS_bcpvec4, &ssr_frag_in.v4[3] }, + { sizeof(Vec4), NULL, ®_v4_04, ssrS_bcpvec4, &ssr_frag_in.v4[4] }, + { sizeof(Vec4), NULL, ®_v4_05, ssrS_bcpvec4, &ssr_frag_in.v4[5] } }; -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(Vec2, reg_v2[##i].v2, reg_v2[##i].length, capacity, FALSE) - -#define reg_scale_v3(i) \ -if (flag & VARYING_V3_##i) ssrM_rescalevector(Vec3, reg_v3[##i].v3, reg_v3[##i].length, capacity, FALSE) - -#define reg_scale_v4(i) \ -if (flag & VARYING_V4_##i) ssrM_rescalevector(Vec4, reg_v4[##i].v4, reg_v4[##i].length, capacity, FALSE) - - if (!(flag & VARYING_EXTRA)) +/*设置这个draw call开启的寄存器*/ +void ssrS_openregs(uint varying_flag) { + if (varying_flag & VARYING_EXTRA == 0) + { + open_regsi[0] = -1; 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); + int j = 0; + for (int i = 0; i < REG_TOTAL; ++i) { + if (varying_flag & VARYING_EXTRA == 0) + break; + if (varying_flag & (1 << i)) { + open_regsi[j++] = i; + varying_flag &= ~(1 << i); + } } + if(j < REG_TOTAL) + open_regsi[j] = -1; } -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_setactiveregr() { /*set active reg data from registers*/ + int index = 0; + ActiveReg* reg; + for (int i = 0; i < REG_TOTAL; ++i) { + index = open_regsi[i]; + if (index == -1) break; + reg = &active_regs[index]; + reg->data = registers[index].data; } } -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]; +extern byte* clip_buffer_data[REG_TOTAL]; -#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); +void ssrS_setactiveregc() { /*set active reg data from clipping buffer*/ + int index = 0; + ActiveReg* reg; + for (int i = 0; i < REG_TOTAL; ++i) { + index = open_regsi[i]; + if (index == -1) break; + reg = &active_regs[index]; + reg->data = clip_buffer_data[index]; } - 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); +} + +/*计算寄存器中的值并输出*/ +void ssrS_solveregs(Vec3* bc, uint a, uint b, uint c) { + int index = 0; + uint stride = 0; + ActiveReg* reg; + for (int i = 0; i < REG_TOTAL; ++i) { + index = open_regsi[i]; + if (index == -1) break; + reg = &active_regs[index]; + stride = reg->element_size; + reg->accessor = reg->bcp_interpolator( + bc + , ®->data[a*stride] + , ®->data[b*stride] + , ®->data[c*stride] + , reg->output + ); } - 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); +} + +/*给寄存器扩容(如果需要的话)*/ +void ssrS_setregisters(int capacity) { + Register* reg; + byte* data; + uint index; + for (int i = 0; i < REG_TOTAL; ++i) { + index = open_regsi[i]; + if (index == -1) break; + reg = ®isters[index]; + data = reg->data; + if (reg->length >= capacity) + continue; + if (!data) + data = (byte*)calloc(capacity * reg->element_size, sizeof(byte)); + else + data = (byte*)realloc(data, capacity * reg->element_size); + reg->data = data; + reg->length = capacity; } - 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); +} + +/*进入vert shader前设置寄存器指针到对应顶点的数据在寄存器中的位置*/ +void ssrS_setupregisterpoints(int idx) { + ActiveReg* reg; + uint index; + for (int i = 0; i < REG_TOTAL; ++i) { + index = open_regsi[i]; + if (index == -1) break; + reg = &active_regs[index]; + *reg->accessor = ®->data[idx * reg->element_size]; } } -Color32 texture2d(Texture* tex, Vec2* uv) { - FilterMode filter_mode = ssr_getfiltermode(); - WrapMode wrap_mode = ssr_getwrapmode(); - return texture_sampling(tex, filter_mode, wrap_mode, uv->x, uv->y); +/*进入frag shader前,将寄存器指针设置到fragment-in对应的位置*/ +void ssrS_setregtofragin() { + ActiveReg* reg; + uint index; + for (int i = 0; i < REG_TOTAL; ++i) { + index = open_regsi[i]; + if (index == -1) break; + reg = &active_regs[index]; + *reg->accessor = reg->output; + } } -float* ssrS_bcpnum(Vec3* bc, float A, float B, float C, float* out) { +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; + *out = bc->A * *A + bc->B * *B + bc->C * *C; return out; } diff --git a/src/core/shader.h b/src/core/shader.h index 2e87ac5..d74581d 100644 --- a/src/core/shader.h +++ b/src/core/shader.h @@ -4,8 +4,9 @@ #include "../math/math.h" #include "vert.h" #include "texture.h" +#include "clip.h" -typedef struct UniformCollection { +typedef struct { /*built in varaibles*/ Mat4* model; Mat4* view; @@ -23,12 +24,13 @@ typedef struct UniformCollection { void* userdata; } UniformCollection; -#define TEX(i) (uniforms->var_tex[i]) -#define UM4(i) (&uniforms->var_mat4[i]) -#define UV2(i) (&uniforms->var_vec2[i]) -#define UV3(i) (&uniforms->var_vec3[i]) -#define UV4(i) (&uniforms->var_vec4[i]) -#define UN(i) (&uniforms->var_num[i]) +#define UTEX(i) (uniforms->var_tex[i]) +#define UM4(i) (&uniforms->var_mat4[i]) +#define UV2(i) (&uniforms->var_vec2[i]) +#define UV3(i) (&uniforms->var_vec3[i]) +#define UV4(i) (&uniforms->var_vec4[i]) +#define UN(i) (&uniforms->var_num[i]) +#define UU (uniforms->userdata) typedef struct VertexShaderIn { Vert* vertex; @@ -39,10 +41,10 @@ typedef void(*VertexShader)(UniformCollection* uniforms, VertexShaderIn* in, Vec typedef struct FragmentShaderIn { /*value from vertices interpolation*/ Vec3 position; - Vec3 normal; - Vec3 tangent; - Vec2 texcoord; - Color color; + Vec3 normal; + Vec3 tangent; + Vec2 texcoord; + Color color; Vec4 joint; Vec4 weight; /*value from registers interpolation*/ @@ -52,68 +54,68 @@ typedef struct FragmentShaderIn { Vec4 v4[6]; } FragmentShaderIn; -typedef bool(*FragmentShader)(UniformCollection* uniforms, FragmentShaderIn* in, Color* color); +typedef bool(*FragmentShader)(UniformCollection* uniforms, FragmentShaderIn* in, Color32* color); -typedef struct Program { +typedef struct { VertexShader vertexshader; - FragmentShader fragmentshader; + FragmentShader fragmentshader; uint varying_flag; } Program; #define VARYING_NONE (0) -#define VARYING_POSITION (1U << 31) -#define VARYING_NORMAL (1U << 30) -#define VARYING_TANGENT (1U << 29) -#define VARYING_TEXCOORD (1U << 28) -#define VARYING_COLOR (1U << 27) -#define VARYING_JOINT (1U << 26) -#define VARYING_WEIGHT (1U << 25) +#define VARYING_POSITION (1u << 31) +#define VARYING_NORMAL (1u << 30) +#define VARYING_TANGENT (1u << 29) +#define VARYING_TEXCOORD (1u << 28) +#define VARYING_COLOR (1u << 27) +#define VARYING_JOINT (1u << 26) +#define VARYING_WEIGHT (1u << 25) -#define VARYING_UNUSED (1U << 24) +#define VARYING_UNUSED (1u << 24) #define VARYING_BASIC ( VARYING_UNUSED | VARYING_POSITION | VARYING_NORMAL | VARYING_TANGENT | VARYING_TEXCOORD | VARYING_COLOR | VARYING_JOINT | VARYING_WEIGHT ) -#define VARYING_NUM_00 (1U << 20) -#define VARYING_NUM_01 (1U << 21) -#define VARYING_NUM_02 (1U << 22) -#define VARYING_NUM_03 (1U << 23) +#define VARYING_NUM_00 (1u) +#define VARYING_NUM_01 (1u << 1) +#define VARYING_NUM_02 (1u << 2) +#define VARYING_NUM_03 (1u << 3) #define VARYING_NUM (VARYING_NUM_00 | VARYING_NUM_01 | VARYING_NUM_02 | VARYING_NUM_03 ) -#define VARYING_V2_00 (1U) -#define VARYING_V2_01 (1U << 1) -#define VARYING_V2_02 (1U << 2) -#define VARYING_V2_03 (1U << 3) -#define VARYING_V2_04 (1U << 4) -#define VARYING_V2_05 (1U << 5) +#define VARYING_V2_00 (1u << 4) +#define VARYING_V2_01 (1u << 5) +#define VARYING_V2_02 (1u << 6) +#define VARYING_V2_03 (1u << 7) +#define VARYING_V2_04 (1u << 8) +#define VARYING_V2_05 (1u << 9) #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 (1U << 6) -#define VARYING_V3_01 (1U << 7) -#define VARYING_V3_02 (1U << 8) -#define VARYING_V3_03 (1U << 9) -#define VARYING_V3_04 (1U << 10) -#define VARYING_V3_05 (1U << 11) -#define VARYING_V3_06 (1U << 12) -#define VARYING_V3_07 (1U << 13) +#define VARYING_V3_00 (1u << 10) +#define VARYING_V3_01 (1u << 11) +#define VARYING_V3_02 (1u << 12) +#define VARYING_V3_03 (1u << 13) +#define VARYING_V3_04 (1u << 14) +#define VARYING_V3_05 (1u << 15) +#define VARYING_V3_06 (1u << 16) +#define VARYING_V3_07 (1u << 17) #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 (1U << 14) -#define VARYING_V4_01 (1U << 15) -#define VARYING_V4_02 (1U << 16) -#define VARYING_V4_03 (1U << 17) -#define VARYING_V4_04 (1U << 18) -#define VARYING_V4_05 (1U << 19) +#define VARYING_V4_00 (1u << 18) +#define VARYING_V4_01 (1u << 19) +#define VARYING_V4_02 (1u << 20) +#define VARYING_V4_03 (1u << 21) +#define VARYING_V4_04 (1u << 22) +#define VARYING_V4_05 (1u << 23) #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_NUM | VARYING_V2 | VARYING_V3 | VARYING_V4) -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); +float* ssrS_bcpnum(Vec3* bc, float* A, float* B, float* C, float* 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); @@ -124,23 +126,24 @@ 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 { +typedef enum { REGTYPE_NUM = 1, REGTYPE_VEC2, REGTYPE_VEC4, REGTYPE_VEC3, -}; +} RegisterType; -typedef struct Register { +typedef struct { uint length; uint type; + uint element_size; /*element in bytes, 4\8\12\16*/ union { + byte* data; + /*pecific*/ float* num; Vec2* v2; Vec3* v3; @@ -148,52 +151,52 @@ typedef struct Register { }; } Register; +typedef struct { + uint element_size; + byte* data; /*mutable, either of registers or temp-registers*/ + byte** accessor; + BcpInterpolator bcp_interpolator; + byte* output; /*fragment-in*/ +} ActiveReg; + +#define REG_TOTAL 24 #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]; - -/*寄存器指针,使用错误可能会出现野指针*/ - -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 registers[REG_TOTAL]; +ActiveReg active_regs[REG_TOTAL]; +uint open_regsi[REG_TOTAL]; /*draw call用到的寄存器,可以索引到registers和active_regs*/ + +#define REG_NUM_OFFSET 0 +#define REG_V2_OFFSET 4 +#define REG_V3_OFFSET 10 +#define REG_V4_OFFSET 18 +#define REG_NUM(i) (registers[i]) +#define REG_V2(i) (registers[REG_V2_OFFSET + i]) +#define REG_V3(i) (registers[REG_V3_OFFSET + i]) +#define REG_V4(i) (registers[REG_V4_OFFSET + i]) + +/*寄存器指针accessor,指向寄存器中的某个值,用于在shader里快速访问,使用错误可能会出现野指针*/ +float *reg_num_00, *reg_num_01, *reg_num_02, *reg_num_03; +Vec2 *reg_v2_00, *reg_v2_01, *reg_v2_02, *reg_v2_03, *reg_v2_04, *reg_v2_05; +Vec3 *reg_v3_00, *reg_v3_01, *reg_v3_02, *reg_v3_03, *reg_v3_04, *reg_v3_05, *reg_v3_06, *reg_v3_07; +Vec4 *reg_v4_00, *reg_v4_01, *reg_v4_02, *reg_v4_03, *reg_v4_04, *reg_v4_05; + +void ssrS_openregs(uint varying_flag); +void ssrS_setactiveregr(); +void ssrS_setactiveregc(); +void ssrS_solveregs(Vec3* bc, uint a, uint b, uint c); +void ssrS_setregisters(int capacity); /*设置寄存器指针,指向寄存器(在fragment阶段,指针会指向fragmentIn结构)*/ -void ssrS_setupregisterpoints(uint extra_varying_flag, int idx); +void ssrS_setupregisterpoints(int idx); /*设置寄存器指针,指向fragIn结构*/ -void ssrS_setregtofragin(uint extra_varying_flag, FragmentShaderIn* frag_in); +void ssrS_setregtofragin(); -Color32 texture2d(Texture* tex, Vec2* uv); +#define tex2d(tex, uv) \ +texture_sampling(tex, ssr_getfiltermode(), ssr_getwrapmode(), (uv).x, (uv).y) #endif
\ No newline at end of file diff --git a/src/core/texture.c b/src/core/texture.c index 5b23220..c7dc884 100644 --- a/src/core/texture.c +++ b/src/core/texture.c @@ -16,6 +16,15 @@ static void texture_abgr2argb(Texture* tex) { } } +static void texture_abgr2c32(Color* abgr, Color32* color, int count) { + for (int i = 0; i < count; ++i) { + color[i].r = (abgr[i] & 0xff) / 255.f; + color[i].g = ((abgr[i] >> 8) & 0xff) / 255.f; + color[i].b = ((abgr[i] >> 16) & 0xff) / 255.f; + color[i].a = ((abgr[i] >> 24) & 0xff) / 255.f; + } +} + Texture* texture_loadfromfile(const char* path) { ssr_assert(path); FILE* file = fopen(path, "rb"); @@ -38,13 +47,13 @@ Texture* texture_loadfromfile(const char* path) { if (!pixels) return NULL; Texture* texture = ssrM_new(Texture); texture->width = width; texture->height = height; - texture->pixels = pixels; - texture_abgr2argb(texture); + texture->pixels = ssrM_newvector(Color32, width*height); + texture_abgr2c32(pixels, texture->pixels, width*height); + ssrM_free(pixels); return texture; } static Color32 sampling(Texture* tex, WrapMode wrap_mode, int x, int y) { - Color32 color; if (wrap_mode == WRAPMODE_CLAMP) { /*clamp*/ x = clamp(x, 0, tex->width - 1); y = clamp(y, 0, tex->height - 1); @@ -52,30 +61,36 @@ static Color32 sampling(Texture* tex, WrapMode wrap_mode, int x, int y) { x = x % tex->width; y = y % tex->height; } - color_tocolor32(tex->pixels[x + y * tex->width], &color); - return color; + return tex->pixels[x + y * tex->width]; } Color32 texture_sampling(Texture* tex, FilterMode filter_mode, WrapMode wrap_mode, float x01, float y01) { ssr_assert(tex); - int x = x01 * tex->width, y = (1 - y01) * tex->height; /*map to texture coordinate*/ + float x = x01 * tex->width, y = (1 - y01) * tex->height; /*map to texture coordinate*/ + int x_min = floor(x), y_min = floor(y); + int x_max = ceil(x), y_max = ceil(y); if (filter_mode == FILTERMODE_POINT) { - return sampling(tex, wrap_mode, x, y); + int px = (x_max - x > x - x_min) ? x_min : x_max; + int py = (y_max - y > y - y_min) ? y_min : y_max; + + return sampling(tex, wrap_mode, px, py); } else if (filter_mode == FILTERMODE_BILINEAR) { - int x_min = floor(x), y_min = floor(y); - int x_max = ceil(x), y_max = ceil(y); static Color32 tl, tr, bl, br, t, b, out; + tl = sampling(tex, wrap_mode, x_min, y_min); tr = sampling(tex, wrap_mode, x_max, y_min); bl = sampling(tex, wrap_mode, x_min, y_max); br = sampling(tex, wrap_mode, x_max, y_max); + vec4_lerp(&tl, &tr, x - x_min, &t); vec4_lerp(&bl, &br, x - x_min, &b); vec4_lerp(&t, &b, y - y_min, &out); + return out; } + /* else if (filter_mode == FILTERMODE_TRILINEAR) { - /*TODO*/ } + */ } diff --git a/src/core/texture.h b/src/core/texture.h index 49fed4b..9e0d884 100644 --- a/src/core/texture.h +++ b/src/core/texture.h @@ -3,21 +3,21 @@ #include "vert.h" -typedef enum FilterMode { +typedef enum { FILTERMODE_POINT, FILTERMODE_BILINEAR, - FILTERMODE_TRILINEAR, + /*FILTERMODE_TRILINEAR,*/ } FilterMode; -typedef enum WrapMode{ +typedef enum { WRAPMODE_REPEAT, WRAPMODE_CLAMP, } WrapMode; -typedef struct Texture{ +typedef struct { uint width, height; - Color* pixels; -}Texture; + Color32* pixels; +} Texture; Texture* texture_loadfromfile(const char* path); diff --git a/src/core/vert.h b/src/core/vert.h index a85e38c..d594442 100644 --- a/src/core/vert.h +++ b/src/core/vert.h @@ -25,11 +25,13 @@ typedef struct Vert { uint index; Vec3 position; Vec3 normal; - Vec3 tangent; + Vec4 tangent; Vec2 texcoord; Color color; +/* Vec4 joint; Vec4 weight; +*/ } Vert; #endif
\ No newline at end of file diff --git a/src/example/03_texture.c b/src/example/03_texture.c index d4e08a4..b172b5c 100644 --- a/src/example/03_texture.c +++ b/src/example/03_texture.c @@ -1,4 +1,5 @@ #include "example.h" +#include "../extend/mesh.h" static int cube[] = { 0, 1, 2, 0, 2, 3, @@ -20,32 +21,45 @@ static Vert verts[] = { {7, {1, -1, -1}, {1, -1, -1}, zerovec3, {1, 1} , 0xffFAFF00}, }; -extern Program ssr_built_in_shader_unlit; +extern Program ssr_built_in_shader_default; static Vec3 light = {-1, -1, -1}; -static Texture* texture; +static Texture* mech_albedo; +static Texture* mech_normal; +static Texture* mech_roughness; +static Texture* mech_metalness; +static Mesh* mech_mesh; + +static Texture* ground_albedo; +static Mesh* ground_mesh; + +static Texture* yingham_albedo; +static Mesh* yingham_mesh; void onloadtexture(void* data) { ssr_matrixmode(MATRIX_PROJECTION); ssr_loadidentity(); - ssr_perspective(90, ssr_getaspect(), 0.1f, 10); + ssr_perspective(90, ssr_getaspect(), 0.1f, 1000); //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); ssr_bindvertices(verts, 8, cube, 12); - ssr_useprogram(&ssr_built_in_shader_unlit); - ssr_enable(ENABLEMASK_BACKFACECULL); - ssr_enable(ENABLEMASK_DEPTHTEST); - - texture = texture_loadfromfile("res/helmet/screenshot2.png"); - ssr_setuniformtex(0, texture); + ssr_useprogram(&ssr_built_in_shader_default); + ssr_enable(ENABLEMASK_BACKFACECULL | ENABLEMASK_DEPTHTEST | ENABLEMASK_WRITEDEPTH); ssr_setwrapmode(WRAPMODE_CLAMP); ssr_setfiltermode(FILTERMODE_POINT); + + mech_albedo = texture_loadfromfile("res/dieselpunk/mech_basecolor.tga"); + mech_normal = texture_loadfromfile("res/dieselpunk/mech_normal.tga"); + mech_roughness = texture_loadfromfile("res/dieselpunk/mech_roughness.tga"); + mech_metalness = texture_loadfromfile("res/dieselpunk/mech_metalness.tga"); + mech_mesh = mesh_loadfromobj("res/dieselpunk/mech.obj"); + ground_albedo = texture_loadfromfile("res/dieselpunk/ground_basecolor.tga"); + ground_mesh = mesh_loadfromobj("res/dieselpunk/ground.obj"); + yingham_albedo = texture_loadfromfile("res/dieselpunk/yingham_basecolor.tga"); + yingham_mesh = mesh_loadfromobj("res/dieselpunk/yingham.obj"); + } void oneventtexture(void* data) { @@ -57,20 +71,47 @@ static Quat q; void onupdatetexture(void*data) { uint dt = *(uint*)data; + _t += dt / 1000.f; + + ssr_matrixmode(MATRIX_VIEW); + ssr_loadidentity(); + // Vec3 p = { 700 * sin(_t), 0,700 * cos(_t) }, target = { 0, 0, 0 }; + Vec3 p = { 0, 0, 800}, target = { 0, 0, 0 }; + ssr_lookat(&p, &target, &vec3up); + ssr_matrixmode(MATRIX_MODEL); ssr_loadidentity(); - ssr_translate(0, 0, -3); - ssr_rotate(_t -= dt / 50.f, 1, 0.3, 1); + //ssr_translate(0, 0, -700); + ssr_rotate(_t * 10, 0, 1, 0); + + Vec3 light = {1, 0, 0}; + ssr_setuniformvec3(0, &light); - Vec3 rot = { 1,1,0 }; vec3_normalize(&rot, &rot); - quat_fromaxisangle(&rot, 10, &q); - quat_applytovec3(&q, &light, &light); - ssr_setuniformvec3(0, &light); /*set light direction*/ + Mat4 world2object; + ssr_getm(&world2object); + mat4_invertgeneral3d(&world2object, &world2object); + mat4_transpose(&world2object, &world2object); // transpose it + + ssr_setuniformmat4(0, &world2object); } void ondrawtexture(void*data) { - ssr_clearcolor(0xff303030); + ssr_clearcolor(0xff252525); ssr_cleardepth(); + ssr_setuniformtex(0, mech_albedo); + ssr_setuniformtex(1, mech_normal); + ssr_setuniformtex(2, mech_roughness); + ssr_setuniformtex(3, mech_metalness); + ssr_bindvertices(mech_mesh->vertices, mech_mesh->verts_count, mech_mesh->triangles, mech_mesh->tris_count); ssr_draw(PRIMITIVE_TRIANGLE); + + ssr_setuniformtex(0, ground_albedo); + ssr_bindvertices(ground_mesh->vertices, ground_mesh->verts_count, ground_mesh->triangles, ground_mesh->tris_count); + ssr_draw(PRIMITIVE_TRIANGLE); + + ssr_setuniformtex(0, yingham_albedo); + ssr_bindvertices(yingham_mesh->vertices, yingham_mesh->verts_count, yingham_mesh->triangles, yingham_mesh->tris_count); + ssr_draw(PRIMITIVE_TRIANGLE); + } diff --git a/src/extend/mesh.c b/src/extend/mesh.c index e69de29..4993222 100644 --- a/src/extend/mesh.c +++ b/src/extend/mesh.c @@ -0,0 +1,209 @@ +#include "mesh.h" + +#define LINE_SIZE 1024 + + +#define darray_push(darray, value) \ + do { \ + (darray) = darray_hold((darray), 1, sizeof(*(darray))); \ + (darray)[darray_size(darray) - 1] = (value); \ + } while (0) + +#define DARRAY_RAW_DATA(darray) ((int*)(darray) - 2) +#define DARRAY_CAPACITY(darray) (DARRAY_RAW_DATA(darray)[0]) +#define DARRAY_OCCUPIED(darray) (DARRAY_RAW_DATA(darray)[1]) + +int darray_size(void *darray) { + return darray != NULL ? DARRAY_OCCUPIED(darray) : 0; +} + +void darray_free(void *darray) { + if (darray != NULL) { + free(DARRAY_RAW_DATA(darray)); + } +} + +#define UNUSED_VAR(x) ((void)(x)) + + +void *darray_hold(void *darray, int count, int itemsize) { + assert(count > 0 && itemsize > 0); + if (darray == NULL) { + int raw_size = sizeof(int) * 2 + itemsize * count; + int *base = (int*)malloc(raw_size); + base[0] = count; /* capacity */ + base[1] = count; /* occupied */ + return base + 2; + } + else if (DARRAY_OCCUPIED(darray) + count <= DARRAY_CAPACITY(darray)) { + DARRAY_OCCUPIED(darray) += count; + return darray; + } + else { + int needed_size = DARRAY_OCCUPIED(darray) + count; + int double_curr = DARRAY_CAPACITY(darray) * 2; + int capacity = needed_size > double_curr ? needed_size : double_curr; + int occupied = needed_size; + int raw_size = sizeof(int) * 2 + itemsize * capacity; + int *base = (int*)realloc(DARRAY_RAW_DATA(darray), raw_size); + base[0] = capacity; + base[1] = occupied; + return base + 2; + } +} + +Vec3 vec3_min(Vec3 a, Vec3 b) { + float x = min(a.x, b.x); + float y = min(a.y, b.y); + float z = min(a.z, b.z); + Vec3 r = { x, y, z }; + return r; +} + +Vec3 vec3_max(Vec3 a, Vec3 b) { + float x = max(a.x, b.x); + float y = max(a.y, b.y); + float z = max(a.z, b.z); + Vec3 r = { x, y, z }; + return r; +} + +static Mesh *build_mesh( + Vec3 *positions, Vec2 *texcoords, Vec3 *normals, + Vec4 *tangents, Vec4 *joints, Vec4 *weights, + int *position_indices, int *texcoord_indices, int *normal_indices) { + Vec3 bbox_min = { +1e6, +1e6, +1e6 }; + Vec3 bbox_max = { -1e6, -1e6, -1e6 }; + int num_indices = darray_size(position_indices); + int num_faces = num_indices / 3; + Mesh *mesh; + int i; + + assert(num_faces > 0 && num_faces * 3 == num_indices); + assert(darray_size(position_indices) == num_indices); + assert(darray_size(texcoord_indices) == num_indices); + assert(darray_size(normal_indices) == num_indices); + + mesh = (Mesh*)malloc(sizeof(Mesh)); + mesh->triangles = ssrM_newvector(int, 3 * num_faces); + int nvert = DARRAY_OCCUPIED(positions); + Vert* vertices = ssrM_newvector(Vert, nvert); + + for (i = 0; i < num_indices; i++) { + int position_index = position_indices[i]; + int texcoord_index = texcoord_indices[i]; + int normal_index = normal_indices[i]; + assert(position_index >= 0 && position_index < darray_size(positions)); + assert(texcoord_index >= 0 && texcoord_index < darray_size(texcoords)); + assert(normal_index >= 0 && normal_index < darray_size(normals)); + + vertices[position_index].index = position_index; + vertices[position_index].position = positions[position_index]; + vertices[position_index].texcoord = texcoords[texcoord_index]; + vertices[position_index].normal = normals[normal_index]; + + if (tangents) { + int tangent_index = position_index; + ssr_assert(tangent_index >= 0 && tangent_index < darray_size(tangents)); + vertices[position_index].tangent = tangents[tangent_index]; + } + + mesh->triangles[i] = position_index; + + //bbox_min = vec3_min(bbox_min, vertices[i].position); + //bbox_max = vec3_max(bbox_max, vertices[i].position); + } + + mesh->tris_count = num_faces; + mesh->verts_count = nvert; + mesh->vertices = vertices; + //mesh->center = vec3_div(vec3_add(bbox_min, bbox_max), 2); + + return mesh; +} + +Mesh* mesh_loadfromobj(const char *filename) { + Vec3 *positions = NULL; + Vec2 *texcoords = NULL; + Vec3 *normals = NULL; + Vec4 *tangents = NULL; + Vec4 *joints = NULL; + Vec4 *weights = NULL; + int *position_indices = NULL; + int *texcoord_indices = NULL; + int *normal_indices = NULL; + char line[LINE_SIZE]; + Mesh *mesh; + FILE *file; + + file = fopen(filename, "rb"); + assert(file != NULL); + while (1) { + int items; + if (fgets(line, LINE_SIZE, file) == NULL) { + break; + } + else if (strncmp(line, "v ", 2) == 0) { /* position */ + Vec3 position; + items = sscanf(line, "v %f %f %f", + &position.x, &position.y, &position.z); + assert(items == 3); + darray_push(positions, position); + } + else if (strncmp(line, "vt ", 3) == 0) { /* texcoord */ + Vec2 texcoord; + items = sscanf(line, "vt %f %f", + &texcoord.x, &texcoord.y); + assert(items == 2); + darray_push(texcoords, texcoord); + } + else if (strncmp(line, "vn ", 3) == 0) { /* normal */ + Vec3 normal; + items = sscanf(line, "vn %f %f %f", + &normal.x, &normal.y, &normal.z); + assert(items == 3); + darray_push(normals, normal); + } + else if (strncmp(line, "f ", 2) == 0) { /* face */ + int i; + int pos_indices[3], uv_indices[3], n_indices[3]; + items = sscanf(line, "f %d/%d/%d %d/%d/%d %d/%d/%d", + &pos_indices[0], &uv_indices[0], &n_indices[0], + &pos_indices[1], &uv_indices[1], &n_indices[1], + &pos_indices[2], &uv_indices[2], &n_indices[2]); + assert(items == 9); + for (i = 0; i < 3; i++) { + darray_push(position_indices, pos_indices[i] - 1); + darray_push(texcoord_indices, uv_indices[i] - 1); + darray_push(normal_indices, n_indices[i] - 1); + } + } else if (strncmp(line, "# ext.tangent ", 14) == 0) { /* tangent */ + Vec4 tangent; + items = sscanf(line, "# ext.tangent %f %f %f %f", + &tangent.x, &tangent.y, &tangent.z, &tangent.w); + assert(items == 4); + darray_push(tangents, tangent); + } + } + fclose(file); + + mesh = build_mesh(positions, texcoords, normals, tangents, joints, weights, + position_indices, texcoord_indices, normal_indices); + darray_free(positions); + darray_free(texcoords); + darray_free(normals); + darray_free(tangents); + darray_free(joints); + darray_free(weights); + darray_free(position_indices); + darray_free(texcoord_indices); + darray_free(normal_indices); + + printf("%s: %d verts, %d tris\n", filename, mesh->verts_count, mesh->tris_count); + + return mesh; +} +// +// +//Mesh* mesh_loadfromobj(const char* path) { +//} diff --git a/src/gizmo/gizmo.h b/src/gizmo/gizmo.h new file mode 100644 index 0000000..9e416d0 --- /dev/null +++ b/src/gizmo/gizmo.h @@ -0,0 +1,17 @@ +#ifndef _SOFTSHADEROOM_GIZMO_H_ +#define _SOFTSHADEROOM_GIZMO_H_ + +#include "../math/math.h" + +/*gizmos for visualizing*/ + +typedef enum GizmoIcon2d { + ICON2D_LIGHT, + ICON2D_CAMERA, +}GizmoIcon2d; + +void gizmo_icon2d(float x, float y, float z, GizmoIcon2d icon); + + + +#endif
\ No newline at end of file diff --git a/src/gizmo/icon2d.c b/src/gizmo/icon2d.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/gizmo/icon2d.c @@ -8,8 +8,13 @@ SDL_Surface* suf; -#define SCREEN_WIDTH 600/*800*/ -#define SCREEN_HEIGHT 480/*600*/ +#define SCREEN_WIDTH 600 +#define SCREEN_HEIGHT 480 + +// +//#define SCREEN_WIDTH 800 +//#define SCREEN_HEIGHT 600 +// typedef void(*F)(void*); F onload; @@ -82,7 +87,7 @@ int main(int argc, char* argv[]) ssr_present(); SDL_UpdateWindowSurface(wnd); - Sleep(1); /*reduce cpu usage*/ + /*Sleep(1);*/ /*reduce cpu using*/ } quit: diff --git a/src/math/mat.c b/src/math/mat.c index 84a5a41..f889697 100644 --- a/src/math/mat.c +++ b/src/math/mat.c @@ -9,6 +9,7 @@ static Mat4 sharedMat; static Mat4 sharedMat2; +static Vec3 sharedVec3; static Vec4 sharedVec4; Mat4 mat4identity = { @@ -333,6 +334,20 @@ void mat4_applytovec4(Mat4* mat, Vec4* v, Vec4* out) { out->w = mat->e30 * v->x + mat->e31 * v->y + mat->e32 * v->z + mat->e33 * v->w; } +/* +** mat3 apply to vec3 +*/ +void mat4_applytovec3(Mat4* mat, Vec3* v, Vec3* out) { + ssr_assert(mat && v && out); + if (v == out) { + sharedVec3 = *v; + v = &sharedVec3; + } + out->x = mat->e00 * v->x + mat->e01 * v->y + mat->e02 * v->z; + out->y = mat->e10 * v->x + mat->e11 * v->y + mat->e12 * v->z; + out->z = mat->e20 * v->x + mat->e21 * v->y + mat->e22 * v->z; +} + #define trans(r, c) out->e##r##c = m->e##c##r void mat4_transpose(Mat4* m, Mat4* out) { diff --git a/src/math/math.h b/src/math/math.h index 1db7df7..41b4607 100644 --- a/src/math/math.h +++ b/src/math/math.h @@ -27,11 +27,11 @@ extern char printbuffer[1024]; float rsqrt(float n); float lerp(float from, float to, float t); -typedef struct Vec2 { +typedef struct { float x, y; } Vec2; -typedef union Vec3 { +typedef union { struct { float x, y, z; }; @@ -41,7 +41,7 @@ typedef union Vec3 { Vec2 xy; } Vec3; -typedef union Vec4 { +typedef union { struct { float x, y, z, w; }; @@ -51,7 +51,7 @@ typedef union Vec4 { Vec3 xyz; } Vec4; -typedef union Euler { /*in degree, for visualize quaternion*/ +typedef union { /*in degree, for visualize quaternion*/ struct { float x, y, z; }; @@ -60,11 +60,11 @@ typedef union Euler { /*in degree, for visualize quaternion*/ }; } Euler; -typedef struct Quat { +typedef struct { float x, y, z, w; } Quat; -typedef union Mat4 { +typedef union { float l[16]; float m[4][4]; struct { @@ -95,7 +95,7 @@ typedef union Mat4 { Vec4 colums[4]; } Mat4; -typedef union Mat3 { +typedef union { struct { float e00, e10, e20, /*colum 0*/ @@ -104,7 +104,7 @@ typedef union Mat3 { }; } Mat3; -typedef union Mat23 { +typedef union { struct { float e00, e10, /*colum 0*/ @@ -113,7 +113,7 @@ typedef union Mat23 { }; } Mat23; -typedef union Mat43 { +typedef union { struct { float e00, e10, e20, e30, /*colum 0*/ @@ -184,6 +184,8 @@ void vec4_print(Vec4* v); void vec4_lerp(Vec4* a, Vec4* b, float t, Vec4* out); +void vec4_scale(Vec4* v, float t, Vec4* out); + /************************************************************************/ /* Matrix */ /************************************************************************/ @@ -234,6 +236,7 @@ void mat4_invertpos(Mat4* pos, Mat4* out); /* 对平移矩阵求逆 */ void mat4_decomposetrs(Mat4* src, Vec3* pos, Quat* quat, Vec3* scale); /*分解trs矩阵*/ void mat4_applytovec4(Mat4* m, Vec4* v, Vec4* out); +void mat4_applytovec3(Mat4* m, Vec3* v, Vec3* out); bool mat4_toeuler(Mat4* in, Euler* out); /* 计算YXZ旋转矩阵的欧拉角 */ void mat4_toquat(Mat4* in, Quat* out); /*in是正交矩阵*/ diff --git a/src/math/vec4.c b/src/math/vec4.c index b79adca..202aabd 100644 --- a/src/math/vec4.c +++ b/src/math/vec4.c @@ -6,6 +6,8 @@ Vec4 vec4zero = { 0, 0, 0,0 }; +static Vec4 sharedmat4; + void vec4_dividew(Vec4* v, Vec3* out) { ssr_assert(out && v); float w = 1.f / v->w; @@ -28,4 +30,11 @@ void vec4_lerp(Vec4* a, Vec4* b, float t, Vec4* out) { out->y = lerp(a->y, b->y, t); out->z = lerp(a->z, b->z, t); out->w = lerp(a->w, b->w, t); -}
\ No newline at end of file +} + +void vec4_scale(Vec4* v, float t, Vec4* out) { + out->x = v->x * t; + out->y = v->y * t; + out->z = v->z * t; + out->w = v->w * t; +} diff --git a/src/shaders/common.c b/src/shaders/common.c new file mode 100644 index 0000000..f36e272 --- /dev/null +++ b/src/shaders/common.c @@ -0,0 +1,21 @@ +#include "common.h" + +Vec3 normal_from_color(Color32 c32) { + Vec3 normal = { + c32.r * 2 - 1, + c32.g * 2 - 1, + c32.b * 2 - 1, + }; + return normal; +} + +Mat4 mat4(Vec4* c1, Vec4* c2, Vec4* c3, Vec4* c4); + +Mat3 mat3(Vec3* c1, Vec3* c2, Vec3* c3) { + Mat3 m = { + c1->x,c1->y,c1->z, + c2->x,c2->y,c2->z, + c3->x,c3->y,c3->z, + }; + return m; +} diff --git a/src/shaders/common_header.h b/src/shaders/common.h index 9741a36..2779c7b 100644 --- a/src/shaders/common_header.h +++ b/src/shaders/common.h @@ -5,4 +5,12 @@ extern void ssrR_putline(int x0, int y0, int x1, int y1, Color color); +/* +** shader built in functions +*/ +Vec3 normal_from_color(Color32 c32); + +Mat4 mat4(Vec4* c1, Vec4* c2, Vec4* c3, Vec4* c4); +Mat3 mat3(Vec3* c1, Vec3* c2, Vec3* c3); + #endif
\ No newline at end of file diff --git a/src/shaders/default.c b/src/shaders/default.c index b1345e0..49a80d1 100644 --- a/src/shaders/default.c +++ b/src/shaders/default.c @@ -1,20 +1,51 @@ -#include "common_header.h" +#include "common.h" /*uniforms*/ -#define lightdir UV3(0) -#define shinees UN(0) +#define object2world UM4(0) +#define light UV3(0) +#define maintex UTEX(0) +#define noramltex UTEX(1) +#define roughnesstex UTEX(2) +#define metalnesstex UTEX(3) -/*vertex output*/ -#define uv reg_v2_00 +/*varyings*/ +#define rough reg_num_00 -static void vert(UniformCollection* uniforms, VertexShaderIn* in, Vec4* homocoord) { +static void vert(UniformCollection* uniforms, VertexShaderIn* in, Vec4* clipcoord) { static Vec4 p; p.xyz = in->vertex->position; p.w = 1; - mat4_applytovec4(uniforms->mvp, &p, homocoord); + mat4_applytovec4(uniforms->mvp, &p, clipcoord); + Vec4 normal = { + in->vertex->normal.x, + in->vertex->normal.y, + in->vertex->normal.z, + 1 + }; + Vec4 worldnormal; mat4_applytovec4(object2world, &normal, &worldnormal); + vec3_normalize(light, light); + *reg_num_00 = 1 - vec3_dot(&worldnormal, light); } -static bool frag(UniformCollection* uniforms, FragmentShaderIn* in, Color* color) { - +static bool frag(UniformCollection* uniforms, FragmentShaderIn* in, Color32* color) { + vec3_normalize(light, light); + vec3_normalize(&in->normal, &in->normal); + float roughness = *reg_num_00; + //(*color).r = 1; + //(*color).g = 1; + //(*color).b = 1; + //(*color).a = 1; + //return 1; + //float rough = 1- vec3_dot(&in->normal, light); + Color32 c = tex2d(maintex, in->texcoord); + //Color32 nc = tex2d(noramltex, in->texcoord); + //vec3_scale(&c, roughness, &c); + color32_saturate(&c); + *color = c; return 1; } -Program ssr_built_in_shader_default = { vert, frag };
\ No newline at end of file +Program ssr_built_in_shader_default = { + vert, frag, + VARYING_TEXCOORD | + VARYING_NORMAL | + VARYING_NUM_00 +};
\ No newline at end of file diff --git a/src/shaders/unlit.c b/src/shaders/unlit.c index fe692f0..e5abdce 100644 --- a/src/shaders/unlit.c +++ b/src/shaders/unlit.c @@ -1,28 +1,42 @@ -#include "common_header.h" +#include "common.h" -#define light UV3(0) -#define maintex TEX(0) +/*uniforms*/ +#define object2world UM4(0) +#define light UV3(0) +#define maintex UTEX(0) -#define vert_color reg_v4_00 +/*varyings*/ +#define rough reg_num_00 static void vert(UniformCollection* uniforms, VertexShaderIn* in, Vec4* clipcoord) { static Vec4 p; p.xyz = in->vertex->position; p.w = 1; mat4_applytovec4(uniforms->mvp, &p, clipcoord); - color_tocolor32(in->vertex->color, vert_color); + Vec4 normal = { + in->vertex->normal.x, + in->vertex->normal.y, + in->vertex->normal.z, + 1 + }; + Vec4 worldnormal; mat4_applytovec4(object2world, &normal, &worldnormal); + vec3_normalize(light, light); + *reg_num_00 = 1 - vec3_dot(&worldnormal, light); } -static bool frag(UniformCollection* uniforms, FragmentShaderIn* in, Color* color) { +static bool frag(UniformCollection* uniforms, FragmentShaderIn* in, Color32* color) { vec3_normalize(light, light); vec3_normalize(&in->normal, &in->normal); - float strongness = vec3_dot(light, &in->normal); - vec3_scale(vert_color, 1 - clamp(strongness, 0, 1), vert_color); - *color = color32_tocolor(vert_color); - //Color32 c = texture2d(maintex, &in->texcoord); - //*color = color32_tocolor(&c); + //float rough = 1- vec3_dot(&in->normal, light); + float roughness = *reg_num_00; + Color32 c = tex2d(maintex, in->texcoord); + //vec3_scale(&c, roughness, &c); + //color32_saturate(&c); + *color = c; return 1; } Program ssr_built_in_shader_unlit = { vert, frag, - VARYING_V4_00 | VARYING_TEXCOORD + VARYING_TEXCOORD | + VARYING_NORMAL | + VARYING_NUM_00 }; diff --git a/src/util/type.h b/src/util/type.h index 2f16f7b..219f797 100644 --- a/src/util/type.h +++ b/src/util/type.h @@ -3,6 +3,7 @@ typedef unsigned int uint; typedef unsigned char bool; +typedef unsigned char byte; #define FALSE 0 #define TRUE 1 |