diff options
34 files changed, 963 insertions, 302 deletions
diff --git a/src/core/clip.c b/src/core/clip.c index 23e18ce..37aa9d2 100644 --- a/src/core/clip.c +++ b/src/core/clip.c @@ -37,13 +37,16 @@ static LinearInterpolator clip_interpolator[REG_TOTAL] = { ssrS_lerpvec4, }; -uint clip_element_size[REG_TOTAL] = { - 4,4,4,4, /*float*/ - 8, 8, 8, 8,8, 8, 8, 8, /*Vec2*/ - 12,12,12,12,12,12,12,12,12,12,12,12, /*Vec3*/ - 16,16,16,16,16,16,16,16 /*Vec4*/ +static uint clip_element_size[REG_TOTAL] = { + sizeof(float),sizeof(float),sizeof(float),sizeof(float), /*float*/ + sizeof(Vec2), sizeof(Vec2), sizeof(Vec2), sizeof(Vec2),sizeof(Vec2), sizeof(Vec2), sizeof(Vec2), sizeof(Vec2), /*Vec2*/ + sizeof(Vec3),sizeof(Vec3),sizeof(Vec3),sizeof(Vec3),sizeof(Vec3),sizeof(Vec3),sizeof(Vec3),sizeof(Vec3),sizeof(Vec3),sizeof(Vec3),sizeof(Vec3),sizeof(Vec3), /*Vec3*/ + sizeof(Vec4),sizeof(Vec4),sizeof(Vec4),sizeof(Vec4),sizeof(Vec4),sizeof(Vec4),sizeof(Vec4),sizeof(Vec4) /*Vec4*/ }; +ClippedBuffer clip_buffer; +static ClippedBuffer temp_clip_buffer; + /*用来访问临时寄存器*/ byte* clip_buffer_data[REG_TOTAL] = { @@ -82,7 +85,7 @@ byte* clip_buffer_data[REG_TOTAL] = }; /*用来访问临时寄存器*/ -byte* temp_clip_buffer_data[REG_TOTAL] = +static byte* temp_clip_buffer_data[REG_TOTAL] = { temp_clip_buffer.temp_reg_num[0], temp_clip_buffer.temp_reg_num[1], @@ -198,8 +201,8 @@ static bool clip_against_plane( prev = &src_buffer->vertices[(i - 1 + src_buffer->count) % src_buffer->count]; curr = &src_buffer->vertices[i]; - previ = prev->vertex.index; - curri = curr->vertex.index; + previ = prev->index; + curri = curr->index; prev_inside = is_inside_plane(&prev->clip_coord, plane); curr_inside = is_inside_plane(&curr->clip_coord, plane); @@ -208,7 +211,7 @@ static bool clip_against_plane( t = get_intersect_ratio(&prev->clip_coord, &curr->clip_coord, plane); dst = &dst_buffer->vertices[idx]; ssrS_lerpvec4(t, &prev->clip_coord, &curr->clip_coord, &dst->clip_coord); - dst->vertex.index = idx; + dst->index = idx; /*set varying variables*/ if (varying) { for (j = 0; j < REG_TOTAL; ++j) { @@ -224,7 +227,7 @@ static bool clip_against_plane( if (curr_inside) { dst = &dst_buffer->vertices[idx]; *dst = *curr; - dst->vertex.index = idx; + dst->index = idx; /*copy varying variables*/ if (varying) { for (j = 0; j < REG_TOTAL; ++j) { @@ -247,18 +250,15 @@ static bool clip_against_plane( return 1; \ } -ClippedBuffer clip_buffer; -ClippedBuffer temp_clip_buffer; - bool clip_triangle( Vec4* c0, Vec4* c1, Vec4* c2 - , Vert* v0, Vert* v1, Vert* v2 + , uint i0, uint i1, uint i2 , uint varying_flag , ClippedBuffer* buffer ) { bool is_visible = is_vertex_visible(c0) - && is_vertex_visible(c1) - && is_vertex_visible(c2); + && is_vertex_visible(c1) + && is_vertex_visible(c2); if (is_visible) return 0; /*no need to clip*/ @@ -269,24 +269,22 @@ bool clip_triangle( temp_clip_buffer.count = 3; #define COPY_VERT(i) \ temp_clip_buffer.vertices[i].clip_coord = *c##i; \ - temp_clip_buffer.vertices[i].vertex = *v##i; \ - temp_clip_buffer.vertices[i].vertex.index = ##i; \ + temp_clip_buffer.vertices[i].index = ##i; \ COPY_VERT(0); COPY_VERT(1); COPY_VERT(2); -#undef COPY_VERT - int i, index, size; for (i = 0; i < REG_TOTAL; ++i) { index = open_regsi[i]; if (index == -1) break; size = registers[index].element_size; - ssrM_copy(&temp_clip_buffer_data[index][0], ®isters[index].data[v0->index*size], size); - ssrM_copy(&temp_clip_buffer_data[index][size], ®isters[index].data[v1->index*size], size); - ssrM_copy(&temp_clip_buffer_data[index][2*size], ®isters[index].data[v2->index*size], size); + ssrM_copy(&temp_clip_buffer_data[index][0], ®isters[index].data[i0*size], size); + ssrM_copy(&temp_clip_buffer_data[index][size], ®isters[index].data[i1*size], size); + ssrM_copy(&temp_clip_buffer_data[index][2*size], ®isters[index].data[i2*size], size); } +#undef COPY_VERT CLIP(POSITIVE_W, &temp_clip_buffer, buffer, temp_clip_buffer_data, clip_buffer_data); CLIP(POSITIVE_X, buffer, &temp_clip_buffer, clip_buffer_data, temp_clip_buffer_data); diff --git a/src/core/clip.h b/src/core/clip.h index c1bb7b6..076d3ab 100644 --- a/src/core/clip.h +++ b/src/core/clip.h @@ -10,15 +10,15 @@ typedef struct { /*clipping coord*/ Vec4 clip_coord; - /*vertex data*/ - Vert vertex; + /*new index*/ + uint index; } ClippedVert; #define CLIP_BUFFER_SIZE 6 typedef struct { + uint count; /*number of resulting vertices*/ ClippedVert vertices[CLIP_BUFFER_SIZE]; - uint count; /*temp register*/ float temp_reg_num[REG_NUM_COUNT][CLIP_BUFFER_SIZE]; Vec2 temp_reg_v2[REG_V2_COUNT][CLIP_BUFFER_SIZE]; @@ -27,9 +27,8 @@ typedef struct { } ClippedBuffer; ClippedBuffer clip_buffer; /*clipping result*/ -ClippedBuffer temp_clip_buffer; -bool clip_triangle(Vec4* c0, Vec4* c1, Vec4* c2, Vert* v0, Vert* v1, Vert* v2, uint varying_flag, ClippedBuffer* clipped); +bool clip_triangle(Vec4* c0, Vec4* c1, Vec4* c2, uint i0, uint i1, uint i2, uint varying_flag, ClippedBuffer* clipped); uint clip_line(); diff --git a/src/core/color.c b/src/core/color.c index 45ca555..4f1a877 100644 --- a/src/core/color.c +++ b/src/core/color.c @@ -1,6 +1,8 @@ #include "vert.h" #include "device.h" +Color32 COLOR32_WHITE = {1,1,1,1}; + Color color32_tocolor(Color32* c) { return ssr_color(0xff * c->r, 0xff * c->g, 0xff * c->b, 0xff * c->a); } diff --git a/src/core/depth.c b/src/core/depth.c new file mode 100644 index 0000000..e2c776b --- /dev/null +++ b/src/core/depth.c @@ -0,0 +1,35 @@ +#include "mem.h" +#include "depth.h" +#include "../util/assert.h" + +bool depth_always(float src, float dst) { + return 1; +} + +bool depth_never(float src, float dst) { + return 0; +} + +bool depth_less(float src, float dst) { + return src < dst; +} + +bool depth_equal(float src, float dst) { + return src == dst; +} + +bool depth_leuqal(float src, float dst) { + return src <= dst; +} + +bool depth_greater(float src, float dst) { + return src > dst; +} + +bool depth_notequal(float src, float dst) { + return src != dst; +} + +bool depth_gequer(float src, float dst) { + return src >= dst; +} diff --git a/src/core/depth.h b/src/core/depth.h new file mode 100644 index 0000000..3914055 --- /dev/null +++ b/src/core/depth.h @@ -0,0 +1,17 @@ +#ifndef _SOFTSHADEROOM_DEPTH_H_ +#define _SOFTSHADEROOM_DEPTH_H_ + +#include "../util/type.h" + +typedef bool(*DepthFunc)(float src, float dst); + +bool depth_always(float src, float dst); +bool depth_never(float src, float dst); +bool depth_less(float src, float dst); +bool depth_equal(float src, float dst); +bool depth_leuqal(float src, float dst); +bool depth_greater(float src, float dst); +bool depth_notequal(float src, float dst); +bool depth_gequer(float src, float dst); + +#endif
\ No newline at end of file diff --git a/src/core/device.c b/src/core/device.c index b5468cd..dc4d80e 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -3,93 +3,111 @@ #include "clip.h" #include "shader.h" #include "../util/assert.h" +#include "framebuffer.h" +#include "depth.h" +#include "stencil.h" ssr_Config config; -typedef enum ssr_VertexAttrMask { +typedef enum { VERTEXATTR_POS = 1, VERTEXATTR_COLOR = 1 << 1, VERTEXATTR_UV = 1 << 2, VERTEXATTR_NORMAL = 1 << 3, } ssr_VertexAttrMask; -typedef struct VertexAttr { +typedef struct { int start; int offset; } VertexAttr; -/* -** 状态结构 -*/ static struct { - /* MVP矩阵栈 */ Mat4 matrices[3][MATRIXDEPTH]; - uint matrixtop[3]; - ssr_MatrixMode matrixmode; + uint matrix_top[3]; + ssr_MatrixMode matrix_mode; + + Vec4 viewport; - /* 屏幕缓冲区 */ Color* target; - Color* framebuffer; - uint buffersize; /*framebuffer size in bytess*/ + Color* color_buffer; /*screen color buffer*/ + uint buffer_size; + + float* depth_buffer; + float* depth_screen_buffer; + DepthFunc depth_func; - /* zbuffer 深度会被映射到0~1的非线性区间*/ - float* zbuffer; + byte* stencil_buffer; + byte* stencil_screen_buffer; + byte stencil_read_mask; + uint stencil_ref; + byte stencil_write_mask; + StencilFunc stencil_func; + StencilOp stencil_failop, stencil_dpfailop, stencil_passop; - /* 顶点数据 */ - Vert* verts; uint nverts; - uint* indices; uint nprims; + Vert* verts; uint vert_count; + uint* indices; uint prim_count; - /* shader program */ Program* program; UniformCollection uniforms; - /* texture relavent */ - FilterMode filtermode; - WrapMode wrapmode; - - //FrameBuffer* framebuffer; + FrameBuffer* frame_buffer; uint enable; struct { ssr_BlendFactor src; ssr_BlendFactor dst; - } blendfactor; + } blend_factor; } state; -/* -** MVP矩阵栈 -*/ -#define MATRIXTOP state.matrixtop[state.matrixmode] -#define MATRIX state.matrices[state.matrixmode][MATRIXTOP] -#define MATRIXSTACK state.matrices[state.matrixmode] +#define MATRIXTOP state.matrix_top[state.matrix_mode] +#define MATRIX state.matrices[state.matrix_mode][MATRIXTOP] +#define MATRIXSTACK state.matrices[state.matrix_mode] -#define GETMATRIX(MODE) state.matrices[MODE][state.matrixtop[MODE]] +#define GETMATRIX(MODE) state.matrices[MODE][state.matrix_top[MODE]] -#define BUFFER (state.framebuffer) +#define BUFFER (state.color_buffer) +/*topleft*/ #define contains(x, y, l, r, t, b) (x >= l && x <= r && y <= b && y >= t) void ssr_init(ssr_Config* conf) { config = *conf; - ssrM_zero(state.matrixtop, sizeof(state.matrixtop)); + ssrM_zero(state.matrix_top, sizeof(state.matrix_top)); + state.target = conf->target; + + int size = config.width * config.height; + if (config.dbuffer) { - state.framebuffer = ssrM_newvector(Color, config.width * config.height); + state.color_buffer = ssrM_newvector(Color, size); } else { - state.framebuffer = conf->target; + state.color_buffer = conf->target; } - state.buffersize = sizeof(Color) * config.width * config.height; - state.zbuffer = ssrM_newvector(float, config.width * config.height); - //memset(state.zbuffer, 0xff, sizeof(uint)*config.width*config.height); + state.buffer_size = sizeof(Color) * size; + + state.depth_screen_buffer = ssrM_newvector(float, size); + state.depth_buffer = state.depth_screen_buffer; + state.depth_func = depth_leuqal; + + state.blend_factor.src = BLEND_SRC_ALPHA; + state.blend_factor.dst = BLEND_ONE_MINUS_SRC_ALPHA; + + state.stencil_screen_buffer = ssrM_newvector(byte, size); + state.stencil_buffer = state.stencil_screen_buffer; + state.stencil_ref = 1; + state.stencil_read_mask = 1; + state.stencil_write_mask = 0; + state.stencil_func = stencil_equal; + state.stencil_failop = stencilop_keep; + state.stencil_dpfailop = stencilop_keep; + state.stencil_passop = stencilop_replace; - state.filtermode = FILTERMODE_POINT; - state.wrapmode = WRAPMODE_CLAMP; + state.frame_buffer = NULL; - state.blendfactor.src = BLEND_SRC_ALPHA; - state.blendfactor.dst = BLEND_ONE_MINUS_SRC_ALPHA; + ssr_viewport(0, config.width, config.height, 0); } float ssr_getaspect() { @@ -104,44 +122,38 @@ int ssr_getframebufferh() { return config.height; } -void ssr_setfiltermode(FilterMode filter_mode) { - state.filtermode = filter_mode; -} - -void ssr_setwrapmode(WrapMode wrap_mode) { - state.wrapmode = wrap_mode; -} - -FilterMode ssr_getfiltermode() { - return state.filtermode; -} - -WrapMode ssr_getwrapmode() { - return state.wrapmode; -} - void ssr_bindframebuffer(FrameBuffer* fbo) { - + ssr_assert(fbo); + state.frame_buffer = fbo; + state.depth_buffer = fbo->depth_buffer; + state.stencil_buffer = fbo->stencil_buffer; } void ssr_unbindframebuffer() { - + state.frame_buffer = NULL; + state.depth_buffer = state.depth_screen_buffer; + state.stencil_buffer = state.stencil_screen_buffer; } void ssr_setblendfunc(ssr_BlendFactor sfactor, ssr_BlendFactor dfactor) { - state.blendfactor.src = sfactor; - state.blendfactor.dst = dfactor; + state.blend_factor.src = sfactor; + state.blend_factor.dst = dfactor; +} + +void ssrU_blendscreencolor(uint x, uint y, Color32* src) { + Color c = state.color_buffer[x + y * config.width]; + Color32 dst; color_tocolor32(c, &dst); + ssr_blend(src, &dst, src); } void ssr_matrixmode(ssr_MatrixMode mode) { - state.matrixmode = mode; + state.matrix_mode = mode; } void ssr_loadidentity() { mat4_setidentity(&MATRIX); } -/* push进去之后会将最新的拷贝一份放在栈顶 */ void ssr_pushmatrix() { ssr_assert(MATRIXTOP < MATRIXDEPTH - 1); ++MATRIXTOP; @@ -152,7 +164,6 @@ void ssr_popmatrix() { MATRIXTOP = clamp(--MATRIXTOP, 0, MATRIXDEPTH - 1); } -/*用来做world->view的变换矩阵*/ /*http://warmcat.org/chai/blog/?p=559*/ void ssr_lookat(Vec3* pos, Vec3* target, Vec3* up) { ssr_assert(pos && target && up); @@ -171,7 +182,6 @@ void ssr_lookat(Vec3* pos, Vec3* target, Vec3* up) { mat4_multiply(&MATRIX, &m, &MATRIX); } -/* scalematrix * matrix */ void ssr_scale(float sx, float sy, float sz) { Vec3 scale = { sx, sy, sz }; mat4_scale(&MATRIX, &scale, &MATRIX); @@ -227,6 +237,10 @@ bool ssr_isenable(uint mask) { } void ssr_viewport(float l, float r, float b, float t) { + state.viewport.x = l; + state.viewport.y = r; + state.viewport.z = b; + state.viewport.w = t; } void ssr_ortho(float l, float r, float b, float t, float n, float f) { @@ -236,13 +250,14 @@ void ssr_ortho(float l, float r, float b, float t, float n, float f) { } void ssr_frustum(float l, float r, float b, float t, float n, float f) { + ssr_assert(n > 0 && f > 0 && f > n); Mat4 m; mat4_setfrustum(l, r, b, t, n, f, &m); mat4_multiply(&MATRIX, &m, &MATRIX); } -/*注意这里nf都要是正数,代表距离*/ void ssr_perspective(float fov, float aspect, float n, float f) { + ssr_assert(n > 0 && f > 0 && f > n); Mat4 m; mat4_setperspective(fov, aspect, n, f, &m); mat4_multiply(&MATRIX, &m, &MATRIX); @@ -250,30 +265,60 @@ void ssr_perspective(float fov, float aspect, float n, float f) { void ssr_present() { if (config.dbuffer) { - memcpy(state.target, state.framebuffer, state.buffersize); + memcpy(state.target, state.color_buffer, state.buffer_size); } } -void ssr_clearcolor(Color color) { +static void _clearscreen(Color color) { if (color == 0x00) { - memset(state.framebuffer, 0, state.buffersize); + memset(state.color_buffer, 0, state.buffer_size); } else { uint size = config.width * sizeof(Color); - for(int x = 0; x < config.width; ++x) - state.framebuffer[x] = color; + for (int x = 0; x < config.width; ++x) + state.color_buffer[x] = color; for (int y = 1; y < config.height; ++y) - ssrM_copy(&state.framebuffer[config.width * y], state.framebuffer, size); + ssrM_copy(&state.color_buffer[config.width * y], state.color_buffer, size); + } +} + +static void _clearcolorbuffer(Color32 color) { + Texture* rt; + Color32* pixels; + for (int i = 0; i < RENDER_TARGET_COUNT; ++i) { + rt = state.frame_buffer->render_textures[i]; + if (rt == NULL) continue; + pixels = rt->pixels; + uint size = rt->width * sizeof(Color32); + for (int x = 0; x < rt->width; ++x) + pixels[x] = color; + for (int y = 1; y < rt->height; ++y) + ssrM_copy(&pixels[rt->width * y], pixels, size); + } +} + +void ssr_clearcolor(Color color) { + if (state.frame_buffer == NULL) { + _clearscreen(color); + } + else { + Color32 c; color_tocolor32(color, &c); + _clearcolorbuffer(c); } } void ssr_cleardepth() { - //memset(state.zbuffer, 0xff, sizeof(uint)*config.width*config.height); + ssr_assert(state.depth_buffer); for (int i = 0; i < config.width * config.height; ++i) { - state.zbuffer[i] = 1; + state.depth_buffer[i] = 1; } } +void ssr_clearstencil(byte val) { + ssr_assert(state.stencil_buffer); + memset(state.stencil_buffer, val, config.width * config.height); +} + void ssr_putpoint(uint screenx, uint screeny, Color color) { if (!contains(screenx, screeny, 0, config.width - 1, 0, config.height - 1)) return; @@ -291,26 +336,46 @@ Color ssr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char } bool ssr_testdepth(uint x, uint y, float depth){ + ssr_assert(state.depth_buffer); uint off = x + y * config.width; - return state.zbuffer[off] >= depth; + return state.depth_func(depth, state.depth_buffer[off]); } void ssr_writedepth(uint x, uint y, float depth) { + ssr_assert(state.depth_buffer); uint off = x + y * config.width; - state.zbuffer[off] = depth; + state.depth_buffer[off] = depth; +} + +void ssr_setdepthfunc(ssr_DepthFunc func) { + switch (func) + { + case DEPTHFUNC_ALWAYS: state.depth_func = depth_always; break; + case DEPTHFUNC_NEVER: state.depth_func = depth_never; break; + case DEPTHFUNC_LESS: state.depth_func = depth_less; break; + case DEPTHFUNC_EQUAL: state.depth_func = depth_equal; break; + case DEPTHFUNC_LEQUAL: state.depth_func = depth_leuqal; break; + case DEPTHFUNC_GREATER: state.depth_func = depth_greater; break; + case DEPTHFUNC_NOTEQUAL: state.depth_func = depth_notequal; break; + case DEPTHFUNC_GEQUAL: state.depth_func = depth_gequer; break; + default: ssr_assert(FALSE); + } } void ssrU_viewport(Vec2* p, Vec2* out) { ssr_assert(p && out); - float halfw = config.width / 2.f, halfh = config.height / 2.f; - //out->x = (int)round(p->x * halfw + halfw); - //out->y = (int)round(halfh - p->y * halfh); - out->x = (int)round((p->x + 1) * (halfw - 0.5f)); - out->y = (int)round((1 - p->y) * (halfh - 0.5f)); + float l = state.viewport.x, + r = state.viewport.y, + b = state.viewport.z, + t = state.viewport.w, + w2 = (r - l) * 0.5f, + h2 = (b - t) * 0.5f; + out->x = (int)round((p->x + 1) * (w2 - 0.5f) + l); + out->y = (int)round((1 - p->y) * (h2 - 0.5f) + t); } void ssr_blend(Color32* src, Color32* dst, Color32* out) { - ssrU_blend(state.blendfactor.src, state.blendfactor.dst, src, dst, out); + ssrU_blend(state.blend_factor.src, state.blend_factor.dst, src, dst, out); } static _blend(ssr_BlendFactor factor, Color32* src, Color32* dst, Color32* out) { @@ -391,18 +456,12 @@ void ssrU_blend( out->a = src->a + dst->a; } -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) { +void ssr_bindvertices(Vert* verts, int vert_count, uint* indices, int prim_count) { ssr_assert(verts && indices); state.verts = verts; - state.nverts = nverts; + state.vert_count = vert_count; state.indices = indices; - state.nprims = nprims; + state.prim_count = prim_count; } void ssr_useprogram(Program* program) { @@ -444,30 +503,31 @@ void ssr_draw(ssr_PrimitiveType primitive) { /*prepare registers if necessary*/ if (use_extra_varyings) { ssrS_openregs(varying_flag); - ssrS_setregisters(state.nverts); + ssrS_setregisters(state.vert_count); ssrS_setactiveregr(); } /*resize clipping coords buffer*/ - if (clip_coords.length < state.nverts) { + if (clip_coords.length < state.vert_count) { ssrM_resizevector( Vec4, clip_coords.coords, clip_coords.length, - state.nverts, + state.vert_count, FALSE ); } /*vertex operation*/ - for (int i = 0; i < state.nverts; ++i) { + VertexShader vert_shader = state.program->vertexshader; + for (int i = 0; i < state.vert_count; ++i) { Vert* vert = &state.verts[i]; ssr_vert_in.vertex = vert; /*set register pointers*/ if (use_extra_varyings) { ssrS_setupregisterpointers(vert->index); } - state.program->vertexshader(&state.uniforms, &ssr_vert_in, &clip_coords.coords[i]); + vert_shader(&state.uniforms, &ssr_vert_in, &clip_coords.coords[i]); } /*set register pointer to frag-in*/ @@ -479,9 +539,8 @@ void ssr_draw(ssr_PrimitiveType primitive) { if (primitive == PRIMITIVE_TRIANGLE) { uint i0, i1, i2; Vec4 *h0, *h1, *h2; - Vert *v0, *v1, *v2; bool reset_active_reg = FALSE; - for (int i = 0; i < state.nprims; ++i) { + for (int i = 0; i < state.prim_count; ++i) { i0 = state.indices[i * 3]; i1 = state.indices[i * 3 + 1]; i2 = state.indices[i * 3 + 2]; @@ -490,10 +549,6 @@ void ssr_draw(ssr_PrimitiveType primitive) { h1 = &clip_coords.coords[i1], h2 = &clip_coords.coords[i2]; - v0 = &state.verts[i0]; - v1 = &state.verts[i1]; - v2 = &state.verts[i2]; - /*back face culling*/ if (ssr_isenable(ENABLE_BACKFACECULL)) { float w0 = 1 / h0->w, w1 = 1 / h1->w, w2 = 1 / h2->w; @@ -508,7 +563,7 @@ void ssr_draw(ssr_PrimitiveType primitive) { } /*clipping*/ - bool clipped = clip_triangle(h0, h1, h2, v0, v1, v2, varying_flag, &clip_buffer); + bool clipped = clip_triangle(h0, h1, h2, i0, i1, i2, varying_flag, &clip_buffer); /*rasterization*/ if (!clipped) { @@ -516,7 +571,7 @@ void ssr_draw(ssr_PrimitiveType primitive) { reset_active_reg = FALSE; ssrS_setactiveregr(); } - ssrR_triangle(h0, h1, h2, v0, v1, v2, state.program, &state.uniforms); + ssrR_triangle(h0, h1, h2, i0, i1, i2, state.program, &state.uniforms); } else { if (!reset_active_reg) { reset_active_reg = TRUE; @@ -528,14 +583,14 @@ void ssr_draw(ssr_PrimitiveType primitive) { vt1 = &clip_buffer.vertices[i]; vt2 = &clip_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, state.program, &state.uniforms); + i0 = vt0->index; i1 = vt1->index; i2 = vt2->index; + ssrR_triangle(h0, h1, h2, i0, i1, i2, state.program, &state.uniforms); } } } } } else if (primitive == PRIMITIVE_POINT) { - + } else if (primitive == PRIMITIVE_LINE) { } @@ -574,3 +629,130 @@ void ssr_setuniformtex(uint idx, Texture* tex) { void ssr_setuniformu(void* userdata) { state.uniforms.userdata = userdata; } + +bool ssr_teststencil(uint x, uint y, bool pass_depth_test) { + int index = x + config.width * y; + byte mask = state.stencil_read_mask; + byte val = state.stencil_buffer[index]; + return state.stencil_func(val, state.stencil_ref); +} + +void ssr_writestencil(uint x, uint y, bool pass_depth_test, bool pass_stencil_test) { + byte write_mask = state.stencil_write_mask; + if (write_mask == 0) return;/*dont write*/ + int index = x + config.width * y; + byte read_mask = state.stencil_read_mask; + byte val = state.stencil_buffer[index]; + if (pass_stencil_test && pass_depth_test) { + val = state.stencil_passop(val & read_mask, state.stencil_ref & read_mask); + } + else if (pass_stencil_test && !pass_depth_test) { + val = state.stencil_dpfailop(val & read_mask, state.stencil_ref & read_mask); + } + else if (!pass_stencil_test) { + val = state.stencil_failop(val & read_mask, state.stencil_ref & read_mask); + } + /*https://stackoverflow.com/questions/31660747/what-exactly-does-glstencilmask-do*/ + state.stencil_buffer[index] &= ~write_mask; + state.stencil_buffer[index] |= (val & write_mask); +} + +void ssr_setstencilfunc(ssr_StencilFunc func, byte ref, uint mask) { + switch (func) + { + case STENCILFUNC_ALWAYS: state.stencil_func = stencil_always; break; + case STENCILFUNC_NEVER: state.stencil_func = stencil_never; break; + case STENCILFUNC_LESS: state.stencil_func = stencil_less; break; + case STENCILFUNC_EQUAL: state.stencil_func = stencil_equal; break; + case STENCILFUNC_LEQUAL: state.stencil_func = stencil_leuqal; break; + case STENCILFUNC_GREATER: state.stencil_func = stencil_greater; break; + case STENCILFUNC_NOTEQUAL: state.stencil_func = stencil_notequal; break; + case STENCILFUNC_GEQUAL: state.stencil_func = stencil_gequer; break; + default: ssr_assert(FALSE); + } + state.stencil_ref = ref; + state.stencil_read_mask = mask; +} + +static void setstencilop(ssr_StencilOp v, StencilOp* op) { + switch (v) { + case STENCILOP_KEEP: *op = stencilop_keep; break; + case STENCILOP_ZERO: *op = stencilop_zero; break; + case STENCILOP_REPLACE: *op = stencilop_replace; break; + case STENCILOP_INCR: *op = stencilop_incr; break; + case STENCILOP_INCR_WRAP: *op = stencilop_incrwrap; break; + case STENCILOP_DECR: *op = stencilop_decr; break; + case STENCILOP_DECR_WRAP: *op = stencilop_decrwrap; break; + case STENCILOP_INVERT: *op = stencilop_invert; break; + default: + ssr_assert(FALSE); + } +} + +void ssr_setstencilop(ssr_StencilOp fail, ssr_StencilOp dpfail, ssr_StencilOp pass) { + setstencilop(fail, &state.stencil_failop); + setstencilop(dpfail, &state.stencil_dpfailop); + setstencilop(pass, &state.stencil_passop); +} + +void ssr_setstencilmask(byte mask) { + state.stencil_write_mask = mask; +} + +bool ssr_iswritesencil() { + return state.stencil_write_mask != 0x00; +} + +void ssr_blendandputpoint(int x, int y, bool blend) { + if (!state.frame_buffer) { /*directly onto screen*/ + if (blend) { + ssrU_blendscreencolor(x, y, out_color[0]); + } + color32_saturate(out_color[0]); + ssr_putpoint32(x, y, out_color[0]); + } + else { /*onto framebuffer color buffer*/ + Color32 *src, *dst; + Texture* rt; + for (int i = 0; i < RENDER_TARGET_COUNT; ++i) { + rt = state.frame_buffer->render_textures[i]; + if (rt == NULL || !contains(x, y, 0, rt->width, 0, rt->height)) + continue; + dst = &rt->pixels[x + y * rt->width]; + src = out_color[i]; + if (blend) + ssr_blend(src, dst, src); + *dst = *src; + } + } +} + +FrameBuffer* fbo_create() { + FrameBuffer* fb = ssrM_new(FrameBuffer); + fbo_attachdepthbuffer(fb, 0); + fbo_attachstencilbuffer(fb, 0); + ssrM_zero(fb->render_textures, sizeof(Texture*) * RENDER_TARGET_COUNT); + return fb; +} + +void fbo_attachrendertexture(FrameBuffer* fb, uint attachment, Texture* rt) { + fb->render_textures[attachment] = rt; +} + +void fbo_attachdepthbuffer(FrameBuffer* fb, float* depthbuffer) { + if (depthbuffer == NULL) + fb->depth_buffer = state.depth_screen_buffer; + else + fb->depth_buffer = depthbuffer; +} + +void fbo_attachstencilbuffer(FrameBuffer* fb, byte* stencilbuffer) { + if (stencilbuffer == NULL) + fb->stencil_buffer = state.stencil_screen_buffer; + else + fb->stencil_buffer = stencilbuffer; +} + +void fbo_free(FrameBuffer* fb) { + ssrM_free(fb); +} diff --git a/src/core/device.h b/src/core/device.h index 6dc8143..0b27b70 100644 --- a/src/core/device.h +++ b/src/core/device.h @@ -34,9 +34,21 @@ typedef enum { ENABLE_MULTISAMPLE = 1 << 2, ENABLE_BLEND = 1 << 3, ENABLE_WRITEDEPTH = 1 << 4, + ENABLE_STENCILTEST = 1 << 5, } ssr_EnableMask; typedef enum { + DEPTHFUNC_ALWAYS, + DEPTHFUNC_NEVER, + DEPTHFUNC_LESS, + DEPTHFUNC_EQUAL, + DEPTHFUNC_LEQUAL, + DEPTHFUNC_GREATER, + DEPTHFUNC_NOTEQUAL, + DEPTHFUNC_GEQUAL, +} ssr_DepthFunc; + +typedef enum { BLEND_ONE, BLEND_ZERO, BLEND_SRC_COLOR, @@ -49,6 +61,28 @@ typedef enum { BLEND_ONE_MINUS_DST_ALPHA, } ssr_BlendFactor; +typedef enum { + STENCILFUNC_ALWAYS, + STENCILFUNC_NEVER, + STENCILFUNC_LESS, + STENCILFUNC_EQUAL, + STENCILFUNC_LEQUAL, + STENCILFUNC_GREATER, + STENCILFUNC_NOTEQUAL, + STENCILFUNC_GEQUAL, +} ssr_StencilFunc; + +typedef enum { + STENCILOP_KEEP, + STENCILOP_ZERO, + STENCILOP_REPLACE, + STENCILOP_INCR, + STENCILOP_INCR_WRAP, + STENCILOP_DECR, + STENCILOP_DECR_WRAP, + STENCILOP_INVERT, +} ssr_StencilOp; + void ssr_init(ssr_Config* config); float ssr_getaspect(); @@ -56,9 +90,6 @@ float ssr_getaspect(); int ssr_getframebufferw(); int ssr_getframebufferh(); -void ssr_setfiltermode(FilterMode filter_mode); -void ssr_setwrapmode(WrapMode wrap_mode); - void ssr_matrixmode(ssr_MatrixMode mode); void ssr_loadidentity(); void ssr_pushmatrix(); @@ -87,7 +118,7 @@ void ssr_disable(uint mask); bool ssr_isenable(uint mask); /* 绑定顶点数据 */ -void ssr_bindvertices(Vert* verts, int nverts, uint* indices, int nprims); +void ssr_bindvertices(Vert* verts, int vert_count, uint* indices, int prim_count); void ssr_unbindvertices(); void ssr_useprogram(Program* program); @@ -103,8 +134,10 @@ void ssr_setuniformu(void* userdata); void ssr_draw(ssr_PrimitiveType primitive); void ssr_clearcolor(Color color); void ssr_cleardepth(); +void ssr_clearstencil(byte val); -void ssr_putpoint(uint screenx, uint screeny, Color color); /*直接修改某个位置的颜色*/ +/*put point onto screen*/ +void ssr_putpoint(uint screenx, uint screeny, Color color); void ssr_putpoint32(uint screenx, uint screeny, Color32* c32); void ssr_present(); @@ -113,20 +146,29 @@ Color ssr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char bool ssr_testdepth(uint x, uint y, float depth); void ssr_writedepth(uint x, uint y, float depth); +void ssr_setdepthfunc(ssr_DepthFunc func); 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); +void ssrU_blendscreencolor(uint x, uint y, Color32* src); + +/*将颜色写入对应的屏幕位置*/ +void ssrU_putpointwithblend(uint x, uint y, Color32* color, bool blend); + +bool ssr_teststencil(uint x, uint y, bool pass_depth_test); +void ssr_writestencil(uint x, uint y, bool pass_depth_test, bool pass_stencil_test); +void ssr_setstencilfunc(ssr_StencilFunc func, byte ref, uint mask); +void ssr_setstencilop(ssr_StencilOp fail, ssr_StencilOp dpfail, ssr_StencilOp pass); +void ssr_setstencilmask(byte mask); +bool ssr_iswritesencil(); + +void ssr_blendandputpoint(int x, int y, bool blend); #endif
\ No newline at end of file diff --git a/src/core/framebuffer.c b/src/core/framebuffer.c deleted file mode 100644 index 7fa0865..0000000 --- a/src/core/framebuffer.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "framebuffer.h" - -FrameBuffer* fbo_create(uint height, uint width) { - -} diff --git a/src/core/framebuffer.h b/src/core/framebuffer.h index 3f03200..78ead0e 100644 --- a/src/core/framebuffer.h +++ b/src/core/framebuffer.h @@ -2,15 +2,31 @@ #define _SOFTSHADEROOM_FRAMEBUFFER_H_ #include "texture.h" +#include "depth.h" +#include "stencil.h" /*frame buffer object*/ -typedef Texture RenderTexture; +#define RENDER_TARGET_COUNT 6 +/* +** OpenGL中fbo的三个挂点可以用renderbuffer或者texture2d绑定,这里考虑效率只提供 +** 8个texture2d可以绑定到color attachment。 +** 如果开启了深度测试或模板测试,那么应该绑定对应的深度缓存和模板缓存 +*/ typedef struct FrameBuffer{ - RenderTexture rt; + Texture* render_textures[RENDER_TARGET_COUNT]; /*color attachments*/ + float* depth_buffer; /*depth attachment*/ + byte* stencil_buffer; /*stencil attachment*/ } FrameBuffer; -FrameBuffer* fbo_create(uint height, uint width); +FrameBuffer* fbo_create(); + +void fbo_attachrendertexture(FrameBuffer* fb, uint attachment, Texture* rt); +/*depth buffer和stencil buffer如果传0,绑定到屏幕缓冲区*/ +void fbo_attachdepthbuffer(FrameBuffer* fb, float* depthbuffer); +void fbo_attachstencilbuffer(FrameBuffer* fb, byte* stencilbuffer); + +void fbo_free(FrameBuffer* fb); #endif
\ No newline at end of file diff --git a/src/core/rasterizer.c b/src/core/rasterizer.c index 2319d44..5618fde 100644 --- a/src/core/rasterizer.c +++ b/src/core/rasterizer.c @@ -80,28 +80,33 @@ static void puttriangle(Vec2* A, Vec2* B, Vec2* C, Color c) { ssrR_putline(C->x, C->y, B->x, B->y, c); } -#define discardif(condition) if(condition) continue - extern FragmentShaderIn ssr_frag_in; -void ssrR_triangle( Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Program* program, UniformCollection* uniforms ) { +void ssrR_triangle( + Vec4* CA, Vec4* CB, Vec4* CC, + uint IA, uint IB, uint IC, + Program* program, + UniformCollection* uniforms +) { ssr_assert(CA && CB && CC && program); - static Vec3 SA, SB, SC; - static Vec3 bc; - + Vec3 SA, SB, SC; vec4_dividew(CA, &SA); ssrU_viewport(&SA, &SA); vec4_dividew(CB, &SB); ssrU_viewport(&SB, &SB); vec4_dividew(CC, &SC); ssrU_viewport(&SC, &SC); + /* puttriangle(&SA, &SB, &SC, 0xffff0000); return; */ - Vec3 *sa = &SA, *sb = &SB, *sc = &SC, *tmp; Vec4* v4tmp; Vert* vtemp; + + Vec3 *sa = &SA, *sb = &SB, *sc = &SC, *tmp; + Vec4 *v4tmp; + uint itmp; #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 (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); } + if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(itmp, IA, IB); } + if (sc->y < sb->y) { swap(tmp, sb, sc); swap(v4tmp, CB, CC); swap(itmp, IB, IC); } + if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(itmp, IA, IB); } #undef swap Vec2 AB = {sb->x - sa->x, sb->y - sa->y}, AC = { sc->x - sa->x, sc->y - sa->y }; @@ -111,60 +116,75 @@ void ssrR_triangle( Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Pro float invkAB = (sb->x - sa->x) / (sb->y - sa->y + EPSILON); float invkBC = (sc->x - sb->x) / (sc->y - sb->y + EPSILON); - Color32 color; float from, to; - Vec2 p; float depth; float CAw = 1.f / CA->w, CBw = 1.f / CB->w, CCw = 1.f / CC->w; - uint varying_flag = program->varying_flag; + bool depth_test = ssr_isenable(ENABLE_DEPTHTEST); + bool multi_sample = ssr_isenable(ENABLE_MULTISAMPLE); + bool blend = ssr_isenable(ENABLE_BLEND); + bool write_depth = ssr_isenable(ENABLE_WRITEDEPTH); + bool stencil_test = ssr_isenable(ENABLE_STENCILTEST); + bool write_stencil = ssr_iswritesencil(); + + bool pass_depth_test = TRUE; + bool pass_stencil_test = TRUE; + bool discard = FALSE; + + FragmentShader frag_shader = program->fragmentshader; + + Vec3 s[2], u; /*edge of triangle*/ - 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(ENABLE_DEPTHTEST); - bool multi_sample = ssr_isenable(ENABLE_MULTISAMPLE); - bool blend = ssr_isenable(ENABLE_BLEND); - bool write_depth = ssr_isenable(ENABLE_WRITEDEPTH); + Vec2 p; + Vec3 bc; + +#define discardif(condition) if(condition) continue #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; \ - 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*/ \ - ssrS_solveregs(&bc, A->index, B->index, C->index); \ - /*enter fragment shader*/ \ - if(program->fragmentshader(uniforms, &ssr_frag_in, &color)) { \ - /*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); \ - } \ - color32_saturate(&color); \ - ssr_putpoint32(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) { \ + /*calculate barycentric coordinate*/ \ + 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; \ + pass_depth_test = ssr_testdepth(p.x, p.y, depth); \ + } \ + /*early stencil testing*/ \ + if(stencil_test){ \ + pass_stencil_test = ssr_teststencil(p.x, p.y, pass_depth_test); \ + } \ + discardif(!pass_depth_test || !pass_stencil_test); \ + /*interpolate varying variables*/ \ + ssrS_solveregs(&bc, IA, IB, IC); \ + /*enter fragment shader*/ \ + discard = !frag_shader(uniforms, &ssr_frag_in, out_color[0]); \ + discardif(discard); \ + /*put point*/ \ + ssr_blendandputpoint(p.x, p.y, blend); \ + /*write depth and stencil*/ \ + if(write_depth) { \ + ssr_writedepth(p.x, p.y, depth); \ + } \ + if(write_stencil) { \ + ssr_writestencil(p.x, p.y, pass_depth_test, pass_stencil_test); \ + } \ + } \ } #define FROM sa @@ -194,6 +214,8 @@ void ssrR_triangle( Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Pro } RENDER_TRIANGLE + +#undef discardif #undef FROM #undef TO diff --git a/src/core/rasterizer.h b/src/core/rasterizer.h index 4fa2482..5f29677 100644 --- a/src/core/rasterizer.h +++ b/src/core/rasterizer.h @@ -13,6 +13,6 @@ bool ssrR_barycentric(Vec2* A, Vec2* B, Vec2* C, Vec2* p, Vec3* out); /*计算重心 void ssrR_center(Vec2* A, Vec2* B, Vec2* C, Vec2* out); /*获得重心*/ bool ssrR_ispointintriangle(Vec2* A, Vec2* B, Vec2* C, Vec2* p); -void ssrR_triangle(Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Program* program, UniformCollection* uniforms); +void ssrR_triangle(Vec4* CA, Vec4* CB, Vec4* CC, uint IA, uint IB, uint IC, Program* program, UniformCollection* uniforms); #endif
\ No newline at end of file diff --git a/src/core/shader.c b/src/core/shader.c index aa271ed..b28a5e2 100644 --- a/src/core/shader.c +++ b/src/core/shader.c @@ -3,42 +3,6 @@ #include "vert.h" #include "device.h" -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; -Vec2* reg_v2_06; -Vec2* reg_v2_07; - -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; -Vec3* reg_v3_08; -Vec3* reg_v3_09; -Vec3* reg_v3_10; -Vec3* reg_v3_11; - -Vec4* reg_v4_00; -Vec4* reg_v4_01; -Vec4* reg_v4_02; -Vec4* reg_v4_03; -Vec4* reg_v4_04; -Vec4* reg_v4_05; -Vec4* reg_v4_06; -Vec4* reg_v4_07; - extern FragmentShaderIn ssr_frag_in; Register registers[REG_TOTAL] = { @@ -164,7 +128,7 @@ void ssrS_setactiveregc() { /*set active reg data from clipping buffer*/ } /*计算寄存器中的值并输出*/ -void ssrS_solveregs(Vec3* bc, uint a, uint b, uint c) { +void ssrS_solveregs(Vec3* bc, uint ia, uint ib, uint ic) { int index = 0; uint stride = 0; ActiveReg* reg; @@ -175,9 +139,9 @@ void ssrS_solveregs(Vec3* bc, uint a, uint b, uint c) { stride = reg->element_size; *reg->accessor = reg->bcp_interpolator( bc - , ®->data[a*stride] - , ®->data[b*stride] - , ®->data[c*stride] + , ®->data[ia*stride] + , ®->data[ib*stride] + , ®->data[ic*stride] , reg->output ); } @@ -299,3 +263,14 @@ void ssrS_lerpvec4(float t, Vec4* A, Vec4* B, Vec4* out) { out->z = lerp(A->z, B->z, t); out->w = lerp(A->w, B->w, t); } + +static Color32 _out_color[RENDER_TARGET_COUNT]; + +Color32* out_color[RENDER_TARGET_COUNT] = { + &_out_color[0], + &_out_color[1], + &_out_color[2], + &_out_color[3], + &_out_color[4], + &_out_color[5], +}; diff --git a/src/core/shader.h b/src/core/shader.h index 15edf4c..9ae757b 100644 --- a/src/core/shader.h +++ b/src/core/shader.h @@ -4,6 +4,7 @@ #include "../math/math.h" #include "vert.h" #include "texture.h" +#include "framebuffer.h" typedef struct { /*built in varaibles*/ @@ -174,10 +175,13 @@ void ssrS_setregisters(int capacity); /*设置寄存器指针,指向寄存器(在fragment阶段,指针会指向fragmentIn结构)*/ void ssrS_setupregisterpointers(int idx); -/*设置寄存器指针,指向fragIn结构*/ +/*set register accessor, point to fragin struct*/ void ssrS_setregtofragin(); #define tex2d(tex, uv) \ -texture_sampling(tex, ssr_getfiltermode(), ssr_getwrapmode(), (uv)->x, (uv)->y) +texture_sampling(tex, (uv)->x, (uv)->y) + +/*frame color buffer output*/ +Color32* out_color[RENDER_TARGET_COUNT]; #endif
\ No newline at end of file diff --git a/src/core/stencil.c b/src/core/stencil.c new file mode 100644 index 0000000..3127544 --- /dev/null +++ b/src/core/stencil.c @@ -0,0 +1,69 @@ +#include "stencil.h" +#include "mem.h" +#include "../util/assert.h" + +bool stencil_always(byte src, byte ref) { + return 1; +} + +bool stencil_never(byte src, byte ref) { + return 0; +} + +bool stencil_less(byte src, byte ref) { + return src < ref; +} + +bool stencil_equal(byte src, byte ref) { + return src == ref; +} + +bool stencil_leuqal(byte src, byte ref) { + return src <= ref; +} + +bool stencil_greater(byte src, byte ref) { + return src > ref; +} + +bool stencil_notequal(byte src, byte ref) { + return src != ref; +} + +bool stencil_gequer(byte src, byte ref) { + return src >= ref; +} + +/*stencil op*/ + +byte stencilop_keep(byte src, byte ref) { + return src; +} + +byte stencilop_zero(byte src, byte ref) { + return 0; +} + +byte stencilop_replace(byte src, byte ref) { + return ref; +} + +byte stencilop_incr(byte src, byte ref) { + return src == 0xff ? 0xff : src + 1; +} + +byte stencilop_incrwrap(byte src, byte ref) { + return src == 0xff ? 0 : src + 1; +} + +byte stencilop_decr(byte src, byte ref) { + return src == 0 ? 0 : src - 1; +} + +byte stencilop_decrwrap(byte src, byte ref) { + return src == 0 ? 0xff : src - 1; +} + +byte stencilop_invert(byte src, byte ref) { + return (~src) & 0xff; +} diff --git a/src/core/stencil.h b/src/core/stencil.h new file mode 100644 index 0000000..8af73d0 --- /dev/null +++ b/src/core/stencil.h @@ -0,0 +1,28 @@ +#ifndef _SOFTSHADEROOM_STENCIL_H_ +#define _SOFTSHADEROOM_STENCIL_H_ + +#include "../util/type.h" + +typedef bool(*StencilFunc)(byte src, byte ref); + +bool stencil_always(byte src, byte ref); +bool stencil_never(byte src, byte ref); +bool stencil_less(byte src, byte ref); +bool stencil_equal(byte src, byte ref); +bool stencil_leuqal(byte src, byte ref); +bool stencil_greater(byte src, byte ref); +bool stencil_notequal(byte src, byte ref); +bool stencil_gequer(byte src, byte ref); + +typedef byte (*StencilOp)(byte src, byte ref); + +byte stencilop_keep(byte src, byte ref); +byte stencilop_zero(byte src, byte ref); +byte stencilop_replace(byte src, byte ref); +byte stencilop_incr(byte src, byte ref); +byte stencilop_incrwrap(byte src, byte ref); +byte stencilop_decr(byte src, byte ref); +byte stencilop_decrwrap(byte src, byte ref); +byte stencilop_invert(byte src, byte ref); + +#endif
\ No newline at end of file diff --git a/src/core/texture.c b/src/core/texture.c index c7dc884..33a00c5 100644 --- a/src/core/texture.c +++ b/src/core/texture.c @@ -48,11 +48,23 @@ Texture* texture_loadfromfile(const char* path) { Texture* texture = ssrM_new(Texture); texture->width = width; texture->height = height; texture->pixels = ssrM_newvector(Color32, width*height); + texture->filter_mode = FILTERMODE_POINT; + texture->wrap_mode = WRAPMODE_CLAMP; texture_abgr2c32(pixels, texture->pixels, width*height); ssrM_free(pixels); return texture; } +Texture* texture_create(uint width, uint height) { + Texture* tex = ssrM_new(Texture); + tex->pixels = ssrM_newvector(Color32, width*height); + tex->width = width; + tex->height = height; + tex->filter_mode = FILTERMODE_POINT; + tex->wrap_mode = WRAPMODE_CLAMP; + return tex; +} + static Color32 sampling(Texture* tex, WrapMode wrap_mode, int x, int y) { if (wrap_mode == WRAPMODE_CLAMP) { /*clamp*/ x = clamp(x, 0, tex->width - 1); @@ -64,8 +76,10 @@ static Color32 sampling(Texture* tex, WrapMode wrap_mode, int x, int y) { return tex->pixels[x + y * tex->width]; } -Color32 texture_sampling(Texture* tex, FilterMode filter_mode, WrapMode wrap_mode, float x01, float y01) { +Color32 texture_sampling(Texture* tex, float x01, float y01) { ssr_assert(tex); + FilterMode filter_mode = tex->filter_mode; + WrapMode wrap_mode = tex->wrap_mode; 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); @@ -94,3 +108,19 @@ Color32 texture_sampling(Texture* tex, FilterMode filter_mode, WrapMode wrap_mod } */ } + +void texture_setfiltermode(Texture* tex, FilterMode filter) { + ssr_assert(tex); + tex->filter_mode = filter; +} + +void texture_setwrapmode(Texture* tex, WrapMode wrap) { + ssr_assert(tex); + tex->wrap_mode = wrap; +} + +void texture_free(Texture* tex) { + if (tex->pixels) + ssrM_free(tex->pixels); + ssrM_free(tex); +} diff --git a/src/core/texture.h b/src/core/texture.h index 9e0d884..06016ad 100644 --- a/src/core/texture.h +++ b/src/core/texture.h @@ -14,13 +14,26 @@ typedef enum { WRAPMODE_CLAMP, } WrapMode; +typedef enum { + COMPONENT_RGBA, + COMPONENT_DEPTH +} TextureComponent; + typedef struct { uint width, height; - Color32* pixels; + Color32* pixels; /*RGBA*/ + FilterMode filter_mode; + WrapMode wrap_mode; } Texture; Texture* texture_loadfromfile(const char* path); +Texture* texture_create(uint width, uint height); + +void texture_setfiltermode(Texture* tex, FilterMode filter); +void texture_setwrapmode(Texture* tex, WrapMode wrap); + +Color32 texture_sampling(Texture* tex, float x, float y); -Color32 texture_sampling(Texture* tex, FilterMode filter_mode, WrapMode wrap_mode, float x, float y); +void texture_free(Texture* tex); #endif
\ No newline at end of file diff --git a/src/core/vert.h b/src/core/vert.h index faf027e..8578d87 100644 --- a/src/core/vert.h +++ b/src/core/vert.h @@ -16,6 +16,8 @@ typedef uint Color; // ARGB typedef Vec4 Color32; +Color32 COLOR32_WHITE; + Color color32_tocolor(Color32* c); void color_tocolor32(Color c, Color32* out); void color32_saturate(Color32* c); diff --git a/src/example/01_dot.c b/src/example/01_dot/01_dot.c index 0a88084..e2902ca 100644 --- a/src/example/01_dot.c +++ b/src/example/01_dot/01_dot.c @@ -1,5 +1,5 @@ -#include "example.h" -#include "../core/rasterizer.h" +#include "../example.h" +#include "../../core/rasterizer.h" Vec3 pos = { 0, 0, 2 }, target = { 0,0,-1 }, up = { 0, 1, 0 }; diff --git a/src/example/02_cube.c b/src/example/02_cube/02_cube.c index c1f2796..4e540e0 100644 --- a/src/example/02_cube.c +++ b/src/example/02_cube/02_cube.c @@ -1,4 +1,4 @@ -#include "example.h" +#include "../example.h" /*正方体*/ Vec3 verts[] = { diff --git a/src/example/03_texture.c b/src/example/03_texture/03_texture.c index 0e48fcb..a0493bb 100644 --- a/src/example/03_texture.c +++ b/src/example/03_texture/03_texture.c @@ -1,5 +1,5 @@ -#include "example.h" -#include "../extend/mesh.h" +#include "../example.h" +#include "../../extend/mesh.h" static int cube[] = { 0, 1, 2, 0, 2, 3, @@ -37,22 +37,19 @@ static Mesh* ground_mesh; static Texture* yingham_albedo; static Mesh* yingham_mesh; -static Texture* gun_albedo; -static Mesh* gun_mesh; +static Texture* cyborg_albedo; +static Mesh* cyborg_mesh; void onloadtexture(void* data) { ssr_matrixmode(MATRIX_PROJECTION); ssr_loadidentity(); - ssr_perspective(90, ssr_getaspect(), 0.1f, 1500); + ssr_perspective(90, ssr_getaspect(), 0.1, 10); //ssr_ortho(-5, 5, -4, 4, 0.1, 10); ssr_bindvertices(verts, 8, cube, 12); ssr_useprogram(&ssr_built_in_shader_pbr); ssr_enable(ENABLE_BACKFACECULL | ENABLE_DEPTHTEST | ENABLE_WRITEDEPTH | ENABLE_BLEND); - ssr_setwrapmode(WRAPMODE_CLAMP); - ssr_setfiltermode(FILTERMODE_POINT); - ssr_setblendfunc(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); mech_albedo = texture_loadfromfile("res/dieselpunk/mech_basecolor.tga"); @@ -64,6 +61,9 @@ void onloadtexture(void* data) { 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"); + + cyborg_albedo = texture_loadfromfile("res/cyborg/cyborg_diffuse.png"); + cyborg_mesh = mesh_loadfromobj("res/cyborg/cyborg.obj"); } void oneventtexture(void* data) { @@ -79,8 +79,8 @@ void onupdatetexture(void*data) { ssr_matrixmode(MATRIX_VIEW); ssr_loadidentity(); - float distance = 800; - Vec3 p = { distance * sin(_t), 300, distance * cos(_t) }, target = { 0, 0, 0 }; + float distance = 2; + Vec3 p = { distance * sin(_t), 3, distance * cos(_t) }, target = { 0, 0, 0 }; //Vec3 p = { 0, 0, 700}, target = { 0, 0, 0 }; ssr_lookat(&p, &target, &vec3up); @@ -103,20 +103,35 @@ void onupdatetexture(void*data) { void ondrawtexture(void*data) { ssr_clearcolor(0xff202020); 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); + ssr_clearstencil(0); +///* +// ssr_enable(ENABLE_STENCILTEST); +// ssr_setstencilfunc(STENCILFUNC_ALWAYS, 1, 0xff); +// ssr_setstencilop(STENCILOP_KEEP, STENCILOP_KEEP, STENCILOP_REPLACE); +//*/ +// /*render mech*/ +// 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->vert_count, mech_mesh->triangles, mech_mesh->tris_count); +// ssr_draw(PRIMITIVE_TRIANGLE); +///* +// ssr_setstencilfunc(STENCILFUNC_EQUAL, 1, 0xff); +// ssr_setstencilop(STENCILOP_KEEP, STENCILOP_KEEP, STENCILOP_KEEP); +//*/ +// /*render yingham*/ +// ssr_setuniformtex(0, yingham_albedo); +// ssr_bindvertices(yingham_mesh->vertices, yingham_mesh->vert_count, yingham_mesh->triangles, yingham_mesh->tris_count); +// ssr_draw(PRIMITIVE_TRIANGLE); +// +// /*render ground*/ +// ssr_setuniformtex(0, ground_albedo); +// ssr_bindvertices(ground_mesh->vertices, ground_mesh->vert_count, ground_mesh->triangles, ground_mesh->tris_count); +// ssr_draw(PRIMITIVE_TRIANGLE); +// + ssr_setuniformtex(0, cyborg_albedo); + ssr_bindvertices(cyborg_mesh->vertices, cyborg_mesh->vert_count, cyborg_mesh->triangles, cyborg_mesh->tris_count); + ssr_draw(PRIMITIVE_TRIANGLE); } diff --git a/src/example/04_bloom.c b/src/example/04_bloom.c deleted file mode 100644 index e69de29..0000000 --- a/src/example/04_bloom.c +++ /dev/null diff --git a/src/example/04_bloom/04_bloom.c b/src/example/04_bloom/04_bloom.c new file mode 100644 index 0000000..6f37f62 --- /dev/null +++ b/src/example/04_bloom/04_bloom.c @@ -0,0 +1,120 @@ +#include "../example.h" +#include "../../extend/mesh.h" + +static int cube[] = { + 0, 1, 2, 0, 2, 3, + 1, 5, 2, 2, 5, 6, + 4, 6, 5, 4, 7, 6, + 0, 3, 7, 0, 7, 4, + 0, 4, 1, 1, 4, 5, + 2, 6, 3, 3, 6, 7 +}; + +static Vert verts[] = { + {0, {1, 1, 1}, {1, 1, 1}, zerovec4, {1, 1}, 0xffff0000}, + {1, {-1, 1, 1}, {-1, 1, 1}, zerovec4, {0, 1},0xff00ff00}, + {2, {-1, -1, 1}, {-1, -1, 1}, zerovec4, {0, 0}, 0xff0000ff}, + {3, {1, -1, 1}, {1, -1, 1}, zerovec4, {1, 0}, 0xffff00ff}, + {4, {1, 1, -1}, {1, 1, -1}, zerovec4, {1, 0} , 0xffaa28aa}, + {5, {-1, 1, -1}, {-1, 1, -1}, zerovec4, {0, 0},0xffFFC58E}, + {6, {-1, -1, -1}, {-1, -1, -1}, zerovec4, {0, 1}, 0xffA100FF}, + {7, {1, -1, -1}, {1, -1, -1}, zerovec4, {1, 1} , 0xffFAFF00}, +}; + +extern Program _04_bloom_preprocess; +extern Program _04_bloom_postprocess; + +static Vec3 light = { -1, -1, -1 }; + +static Texture* cyborg_albedo; +static Mesh* cyborg_mesh; + +static FrameBuffer* fbo; +static float* depth_buffer; +static byte* stencil_buffer; + +static Texture* albedo_tex; +static Texture* bright_tex; + +void onloadbloom(void* data) { + ssr_matrixmode(MATRIX_PROJECTION); + ssr_loadidentity(); + ssr_perspective(90, ssr_getaspect(), 0.1, 10); + //ssr_ortho(-5, 5, -4, 4, 0.1, 10); + + + ssr_setblendfunc(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); + + albedo_tex = texture_create(600, 480); + bright_tex = texture_create(600, 480); + + depth_buffer = ssrM_newvector(float, 600 * 480); + stencil_buffer = ssrM_newvector(byte, 600 * 480); + + fbo = fbo_create(); + fbo_attachrendertexture(fbo, 0, albedo_tex); + fbo_attachrendertexture(fbo, 1, bright_tex); + fbo_attachdepthbuffer(fbo, depth_buffer); + fbo_attachstencilbuffer(fbo, stencil_buffer); +} + +void oneventbloom(void* data) { + SDL_Event* e = (SDL_Event*)data; +} + +static float _t = 0; +static Quat q; + +void onupdatebloom(void*data) { + uint dt = *(uint*)data; + _t += dt / 1000.f; + + ssr_matrixmode(MATRIX_VIEW); + ssr_loadidentity(); + float distance = 2; + Vec3 p = { distance * sin(_t), 5, distance * cos(_t) }, target = { 0, 0, 0 }; + ssr_lookat(&p, &target, &vec3up); + + ssr_matrixmode(MATRIX_MODEL); + ssr_loadidentity(); +} + +static void renderquad() { + /*全屏特效*/ + static Vert verts[] = { + {0, {1, 1, 0}, zerovec3, zerovec3, {1, 1}, 0}, + {1, {-1, 1, 0}, zerovec3, zerovec3, {0, 1},0}, + {2, {-1, -1, 0}, zerovec3, zerovec3, {0, 0}, 0}, + {3, {1, -1, 0}, zerovec3, zerovec3, {1, 0}, 0}, + }; + static int quad[] = { + 0, 1, 2, 0, 2, 3, + }; + ssr_useprogram(&_04_bloom_postprocess); + ssr_bindvertices(verts, 4, quad, 2); + ssr_setuniformtex(0, albedo_tex); + ssr_setuniformtex(1, bright_tex); + ssr_draw(PRIMITIVE_TRIANGLE); +} + +void ondrawbloom(void*data) { + ssr_enable(ENABLE_BACKFACECULL | ENABLE_DEPTHTEST | ENABLE_BLEND | ENABLE_WRITEDEPTH); + + /*render cube*/ + ssr_bindframebuffer(fbo); + ssr_clearcolor(0xff202020); + ssr_cleardepth(); + ssr_clearstencil(0); + ssr_bindvertices(verts, 8, cube, 12); + ssr_useprogram(&_04_bloom_preprocess); + ssr_bindvertices(verts, 8, cube, 12); + ssr_draw(PRIMITIVE_TRIANGLE); + + ssr_disable(ENABLE_BLEND | ENABLE_DEPTHTEST | ENABLE_WRITEDEPTH | ENABLE_BACKFACECULL); + ssr_unbindframebuffer(); + ssr_clearcolor(0xff202020); + ssr_cleardepth(); + ssr_clearstencil(0); + + renderquad(); +} diff --git a/src/example/04_bloom/postprocess.c b/src/example/04_bloom/postprocess.c new file mode 100644 index 0000000..1ec10e4 --- /dev/null +++ b/src/example/04_bloom/postprocess.c @@ -0,0 +1,41 @@ +#include "../../shaders/common.h" + +/*uniforms*/ +#define _frag_tex UTEX(0) +#define _bright_tex UTEX(1) + +/*varyings*/ +#define _texcoord reg_v2_00 + +static float weight[5] = { 0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162 }; + +static void vert(UniformCollection* uniforms, VertexShaderIn* in, Vec4* clipcoord) { + clipcoord->xyz = in->vertex->position; + clipcoord->w = 1; + *_texcoord = in->vertex->texcoord; +} + +static bool frag(UniformCollection* uniforms, FragmentShaderIn* in, Color32* color) { + float off = 1 / 600.f; + //blur + *color = tex2d(_frag_tex, _texcoord); + vec4_scale(color, weight[0], color); + Vec2 p = {0, _texcoord->y}; + Color32 c; + for (int i = 1; i < 5; ++i) { + p.x = _texcoord->x + off * i; + c = tex2d(_frag_tex, &p); + vec4_scale(&c, weight[i], &c); + vec4_add(color, &c, color); + p.x = _texcoord->x - off * i; + c = tex2d(_frag_tex, &p); + vec4_scale(&c, weight[i], &c); + vec4_add(color, &c, color); + } + return 1; +} + +Program _04_bloom_postprocess = { + vert, frag, + VARYING_V2_00 +}; diff --git a/src/example/04_bloom/preprocess.c b/src/example/04_bloom/preprocess.c new file mode 100644 index 0000000..def9fd8 --- /dev/null +++ b/src/example/04_bloom/preprocess.c @@ -0,0 +1,31 @@ +#include "../../shaders/common.h" + +/*uniforms*/ + +/*varyings*/ +#define _color reg_v4_00 + +static void vert(UniformCollection* uniforms, VertexShaderIn* in, Vec4* clipcoord) { + static Vec4 p; p.xyz = in->vertex->position; p.w = 1; + mat4_mulvec4(uniforms->mvp, &p, clipcoord); + color_tocolor32(in->vertex->color, _color); +} + +/*multi target*/ +#define _frag_color out_color[0] +#define _bright_color out_color[1] + +static bool frag(UniformCollection* uniforms, FragmentShaderIn* in, Color32* color) { + //_frag_color->r = 1; + //_frag_color->g = 1; + //_frag_color->b = 1; + //_frag_color->a = 1; + //*_bright_color = *_color; + *_frag_color = *_color; + return 1; +} + +Program _04_bloom_preprocess = { + vert, frag, + VARYING_V4_00 +}; diff --git a/src/example/05_fog.c b/src/example/05_fog/05_fog.c index e69de29..e69de29 100644 --- a/src/example/05_fog.c +++ b/src/example/05_fog/05_fog.c diff --git a/src/example/06_shadow/06_shadow.c b/src/example/06_shadow/06_shadow.c new file mode 100644 index 0000000..015aafd --- /dev/null +++ b/src/example/06_shadow/06_shadow.c @@ -0,0 +1 @@ +/*real time shadow*/ diff --git a/src/example/example.h b/src/example/example.h index 15b547e..6cb9a64 100644 --- a/src/example/example.h +++ b/src/example/example.h @@ -19,5 +19,6 @@ EXAMPLE(cube); EXAMPLE(line); EXAMPLE(dot); EXAMPLE(texture); +EXAMPLE(bloom); #endif
\ No newline at end of file diff --git a/src/extend/mesh.c b/src/extend/mesh.c index 4993222..c8cdf2a 100644 --- a/src/extend/mesh.c +++ b/src/extend/mesh.c @@ -115,7 +115,7 @@ static Mesh *build_mesh( } mesh->tris_count = num_faces; - mesh->verts_count = nvert; + mesh->vert_count = nvert; mesh->vertices = vertices; //mesh->center = vec3_div(vec3_add(bbox_min, bbox_max), 2); @@ -199,7 +199,7 @@ Mesh* mesh_loadfromobj(const char *filename) { darray_free(texcoord_indices); darray_free(normal_indices); - printf("%s: %d verts, %d tris\n", filename, mesh->verts_count, mesh->tris_count); + printf("%s: %d verts, %d tris\n", filename, mesh->vert_count, mesh->tris_count); return mesh; } diff --git a/src/extend/mesh.h b/src/extend/mesh.h index 40ac7ed..2c52669 100644 --- a/src/extend/mesh.h +++ b/src/extend/mesh.h @@ -4,7 +4,7 @@ #include "../core/vert.h" typedef struct Mesh { - Vert* vertices; uint verts_count; + Vert* vertices; uint vert_count; uint* triangles; uint tris_count; } Mesh; diff --git a/src/extern/stb_image.h b/src/extern/stb_image.h index 4df317a..37c4bf7 100644 --- a/src/extern/stb_image.h +++ b/src/extern/stb_image.h @@ -3823,7 +3823,7 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int typedef struct { - stbi_uc *zbuffer, *zbuffer_end; + stbi_uc *depth_buffer, *depth_buffer_end; int num_bits; stbi__uint32 code_buffer; @@ -3837,8 +3837,8 @@ typedef struct stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) { - if (z->zbuffer >= z->zbuffer_end) return 0; - return *z->zbuffer++; + if (z->depth_buffer >= z->depth_buffer_end) return 0; + return *z->depth_buffer++; } static void stbi__fill_bits(stbi__zbuf *z) @@ -4036,11 +4036,11 @@ static int stbi__parse_uncompressed_block(stbi__zbuf *a) len = header[1] * 256 + header[0]; nlen = header[3] * 256 + header[2]; if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); - if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); + if (a->depth_buffer + len > a->depth_buffer_end) return stbi__err("read past buffer","Corrupt PNG"); if (a->zout + len > a->zout_end) if (!stbi__zexpand(a, a->zout, len)) return 0; - memcpy(a->zout, a->zbuffer, len); - a->zbuffer += len; + memcpy(a->zout, a->depth_buffer, len); + a->depth_buffer += len; a->zout += len; return 1; } @@ -4130,8 +4130,8 @@ STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int stbi__zbuf a; char *p = (char *) stbi__malloc(initial_size); if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer + len; + a.depth_buffer = (stbi_uc *) buffer; + a.depth_buffer_end = (stbi_uc *) buffer + len; if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { if (outlen) *outlen = (int) (a.zout - a.zout_start); return a.zout_start; @@ -4151,8 +4151,8 @@ STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, i stbi__zbuf a; char *p = (char *) stbi__malloc(initial_size); if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer + len; + a.depth_buffer = (stbi_uc *) buffer; + a.depth_buffer_end = (stbi_uc *) buffer + len; if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { if (outlen) *outlen = (int) (a.zout - a.zout_start); return a.zout_start; @@ -4165,8 +4165,8 @@ STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, i STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) { stbi__zbuf a; - a.zbuffer = (stbi_uc *) ibuffer; - a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + a.depth_buffer = (stbi_uc *) ibuffer; + a.depth_buffer_end = (stbi_uc *) ibuffer + ilen; if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) return (int) (a.zout - a.zout_start); else @@ -4178,8 +4178,8 @@ STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int stbi__zbuf a; char *p = (char *) stbi__malloc(16384); if (p == NULL) return NULL; - a.zbuffer = (stbi_uc *) buffer; - a.zbuffer_end = (stbi_uc *) buffer+len; + a.depth_buffer = (stbi_uc *) buffer; + a.depth_buffer_end = (stbi_uc *) buffer+len; if (stbi__do_zlib(&a, p, 16384, 1, 0)) { if (outlen) *outlen = (int) (a.zout - a.zout_start); return a.zout_start; @@ -4192,8 +4192,8 @@ STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) { stbi__zbuf a; - a.zbuffer = (stbi_uc *) ibuffer; - a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + a.depth_buffer = (stbi_uc *) ibuffer; + a.depth_buffer_end = (stbi_uc *) ibuffer + ilen; if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) return (int) (a.zout - a.zout_start); else diff --git a/src/math/math.h b/src/math/math.h index 8793336..e63c603 100644 --- a/src/math/math.h +++ b/src/math/math.h @@ -151,9 +151,9 @@ extern Vec3 vec3zero; /*(0,0,0)*/ extern Vec2 vec2zero; /*(0,0,0)*/ extern Vec4 vec4zero; /*(0,0,0)*/ -#define zerovec3 {0, 0, 0} #define zerovec2 {0, 0} -#define zerovec4 {0, 0, 0} +#define zerovec3 {0, 0, 0} +#define zerovec4 {0, 0, 0, 0} void vec3_tostring(Vec3* v, char buf[]); void vec3_print(Vec3* v); @@ -186,6 +186,9 @@ void vec4_lerp(Vec4* a, Vec4* b, float t, Vec4* out); void vec4_scale(Vec4* v, float t, Vec4* out); +void vec4_add(Vec4* v1, Vec4* v2, Vec4* out); + + /************************************************************************/ /* Matrix */ /************************************************************************/ diff --git a/src/math/vec4.c b/src/math/vec4.c index 202aabd..71ec6b6 100644 --- a/src/math/vec4.c +++ b/src/math/vec4.c @@ -38,3 +38,10 @@ void vec4_scale(Vec4* v, float t, Vec4* out) { out->z = v->z * t; out->w = v->w * t; } + +void vec4_add(Vec4* v1, Vec4* v2, Vec4* out) { + out->x = v1->x + v2->x; + out->y = v1->y + v2->y; + out->z = v1->z + v2->z; + out->w = v1->w + v2->w; +} diff --git a/src/shaders/common.h b/src/shaders/common.h index 2779c7b..8b74bec 100644 --- a/src/shaders/common.h +++ b/src/shaders/common.h @@ -13,4 +13,17 @@ Vec3 normal_from_color(Color32 c32); Mat4 mat4(Vec4* c1, Vec4* c2, Vec4* c3, Vec4* c4); Mat3 mat3(Vec3* c1, Vec3* c2, Vec3* c3); +Vec2 texsize(Texture* texture); + +#define discardif(cond) \ +do{ \ +if(cond) return 0; \ +}while(0) + +#define MVP_PROCESS \ +do{ \ +static Vec4 p; p.xyz = in->vertex->position; p.w = 1; \ +mat4_mulvec4(uniforms->mvp, &p, clipcoord); \ +}while(0) + #endif
\ No newline at end of file |