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