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 /src/core | |
parent | 3f44877edfe4c301b258d522bcb4e8d9b6e92382 (diff) |
*misc
Diffstat (limited to 'src/core')
-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 |
14 files changed, 648 insertions, 566 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 |