summaryrefslogtreecommitdiff
path: root/src/core
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 /src/core
parent3f44877edfe4c301b258d522bcb4e8d9b6e92382 (diff)
*misc
Diffstat (limited to 'src/core')
-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
14 files changed, 648 insertions, 566 deletions
diff --git a/src/core/clip.c b/src/core/clip.c
index 382c766..1deb4ee 100644
--- a/src/core/clip.c
+++ b/src/core/clip.c
@@ -1,5 +1,6 @@
#include "clip.h"
#include "shader.h"
+#include "../util/type.h"
typedef enum {
POSITIVE_W,
@@ -60,73 +61,75 @@ static float get_intersect_ratio(Vec4* prev, Vec4* curr, Plane plane) {
return 0;
}
}
-
-static bool clip_against_plane(Plane plane, uint varying_flag, ClippedBuffer* src_buffer, ClippedBuffer* dst_buffer) {
- int idx = 0;
- for (int i = 0; i < src_buffer->count; ++i) {
- ClippedVert* prev = &src_buffer->vertices[(i - 1 + src_buffer->count) % src_buffer->count];
- ClippedVert* curr = &src_buffer->vertices[i];
-
- bool prev_inside = is_inside_plane(&prev->clip_coord, plane);
- bool curr_inside = is_inside_plane(&curr->clip_coord, plane);
-
- if (prev_inside != curr_inside) {
- ClippedVert* dst = &dst_buffer->vertices[idx];
- float t = get_intersect_ratio(&prev->clip_coord, &curr->clip_coord, plane);
- ssrS_lerpvec4(t, &prev->clip_coord, &curr->clip_coord, &dst->clip_coord);
- /*set varying varibles*/
- if (varying_flag & VARYING_BASIC) {
- if (varying_flag & VARYING_POSITION) ssrS_lerpvec3(t, &prev->vertex.position, &curr->vertex.position, &dst->vertex.position);
- if (varying_flag & VARYING_NORMAL) ssrS_lerpvec3(t, &prev->vertex.normal, &curr->vertex.normal, &dst->vertex.normal);
- if (varying_flag & VARYING_TANGENT) ssrS_lerpvec3(t, &prev->vertex.tangent, &curr->vertex.tangent, &dst->vertex.tangent);
- if (varying_flag & VARYING_TEXCOORD) ssrS_lerpvec2(t, &prev->vertex.texcoord, &curr->vertex.texcoord, &dst->vertex.texcoord);
- if (varying_flag & VARYING_COLOR) ssrS_lerpcolor(t, prev->vertex.color, curr->vertex.color, &dst->vertex.color);
- if (varying_flag & VARYING_JOINT) ssrS_lerpvec4(t, &prev->vertex.joint, &curr->vertex.joint, &dst->vertex.joint);
- if (varying_flag & VARYING_WEIGHT) ssrS_lerpvec4(t, &prev->vertex.weight, &curr->vertex.weight, &dst->vertex.weight);
- }
- if (varying_flag & VARYING_EXTRA) {
- int j = 0;
- if (varying_flag & VARYING_NUM) {
- for (j = 0; j < REG_NUM_COUNT; ++j) {
- if (varying_flag & (VARYING_NUM_00 << j)) {
- ssrS_lerpnum(t, prev->num[j], curr->num[j], &dst->num[j]);
- }
- }
- }
- if (varying_flag & VARYING_V2) {
- for (j = 0; j < REG_V2_COUNT; ++j) {
- if (varying_flag & (VARYING_V2_00 << j)) {
- ssrS_lerpvec2(t, &prev->v2[j], &curr->v2[j], &dst->v2[j]);
- }
- }
- }
- if (varying_flag & VARYING_V3) {
- for (j = 0; j < REG_V3_COUNT; ++j) {
- if (varying_flag & (VARYING_V3_00 << j)) {
- ssrS_lerpvec3(t, &prev->v3[j], &curr->v3[j], &dst->v3[j]);
- }
- }
- }
- if (varying_flag & VARYING_V4) {
- for (j = 0; j < REG_V4_COUNT; ++j) {
- if (varying_flag & (VARYING_V4_00 << j)) {
- ssrS_lerpvec4(t, &prev->v4[j], &curr->v4[j], &dst->v4[j]);
- }
- }
- }
- }
- ++idx;
- }
-
- if (curr_inside) {
- ClippedVert* dst = &dst_buffer->vertices[idx];
- *dst = *curr;
- ++idx;
- }
- }
- dst_buffer->count = idx;
- return idx < 3;
-}
+//
+//static bool clip_against_plane(Plane plane, uint varying_flag, ClippedBuffer* src_buffer, ClippedBuffer* dst_buffer) {
+// int idx = 0;
+// for (int i = 0; i < src_buffer->count; ++i) {
+// ClippedVert* prev = &src_buffer->vertices[(i - 1 + src_buffer->count) % src_buffer->count];
+// ClippedVert* curr = &src_buffer->vertices[i];
+//
+// bool prev_inside = is_inside_plane(&prev->clip_coord, plane);
+// bool curr_inside = is_inside_plane(&curr->clip_coord, plane);
+//
+// if (prev_inside != curr_inside) {
+// ClippedVert* dst = &dst_buffer->vertices[idx];
+// float t = get_intersect_ratio(&prev->clip_coord, &curr->clip_coord, plane);
+// ssrS_lerpvec4(t, &prev->clip_coord, &curr->clip_coord, &dst->clip_coord);
+// /*set varying varibles*/
+// if (varying_flag & VARYING_BASIC) {
+// if (varying_flag & VARYING_POSITION) ssrS_lerpvec3(t, &prev->vertex.position, &curr->vertex.position, &dst->vertex.position);
+// if (varying_flag & VARYING_NORMAL) ssrS_lerpvec3(t, &prev->vertex.normal, &curr->vertex.normal, &dst->vertex.normal);
+// if (varying_flag & VARYING_TANGENT) ssrS_lerpvec3(t, &prev->vertex.tangent, &curr->vertex.tangent, &dst->vertex.tangent);
+// if (varying_flag & VARYING_TEXCOORD) ssrS_lerpvec2(t, &prev->vertex.texcoord, &curr->vertex.texcoord, &dst->vertex.texcoord);
+// if (varying_flag & VARYING_COLOR) ssrS_lerpcolor(t, prev->vertex.color, curr->vertex.color, &dst->vertex.color);
+///*
+// if (varying_flag & VARYING_JOINT) ssrS_lerpvec4(t, &prev->vertex.joint, &curr->vertex.joint, &dst->vertex.joint);
+// if (varying_flag & VARYING_WEIGHT) ssrS_lerpvec4(t, &prev->vertex.weight, &curr->vertex.weight, &dst->vertex.weight);
+//*/
+// }
+// if (varying_flag & VARYING_EXTRA) {
+// int j = 0;
+// if (varying_flag & VARYING_NUM) {
+// for (j = 0; j < REG_NUM_COUNT; ++j) {
+// if (varying_flag & (VARYING_NUM_00 << j)) {
+// ssrS_lerpnum(t, prev->num[j], curr->num[j], &dst->num[j]);
+// }
+// }
+// }
+// if (varying_flag & VARYING_V2) {
+// for (j = 0; j < REG_V2_COUNT; ++j) {
+// if (varying_flag & (VARYING_V2_00 << j)) {
+// ssrS_lerpvec2(t, &prev->v2[j], &curr->v2[j], &dst->v2[j]);
+// }
+// }
+// }
+// if (varying_flag & VARYING_V3) {
+// for (j = 0; j < REG_V3_COUNT; ++j) {
+// if (varying_flag & (VARYING_V3_00 << j)) {
+// ssrS_lerpvec3(t, &prev->v3[j], &curr->v3[j], &dst->v3[j]);
+// }
+// }
+// }
+// if (varying_flag & VARYING_V4) {
+// for (j = 0; j < REG_V4_COUNT; ++j) {
+// if (varying_flag & (VARYING_V4_00 << j)) {
+// ssrS_lerpvec4(t, &prev->v4[j], &curr->v4[j], &dst->v4[j]);
+// }
+// }
+// }
+// }
+// ++idx;
+// }
+//
+// if (curr_inside) {
+// ClippedVert* dst = &dst_buffer->vertices[idx];
+// *dst = *curr;
+// ++idx;
+// }
+// }
+// dst_buffer->count = idx;
+// return idx < 3;
+//}
#define CLIP(plane, from, to) \
do { \
@@ -136,6 +139,36 @@ do { \
} \
}while(0)
+ClippedBuffer clip_buffer;
+
+byte* clip_buffer_data[REG_TOTAL] =
+{
+ &clip_buffer.temp_reg_num[0],
+ &clip_buffer.temp_reg_num[1],
+ &clip_buffer.temp_reg_num[2],
+ &clip_buffer.temp_reg_num[3],
+ &clip_buffer.temp_reg_v2[0],
+ &clip_buffer.temp_reg_v2[1],
+ &clip_buffer.temp_reg_v2[2],
+ &clip_buffer.temp_reg_v2[3],
+ &clip_buffer.temp_reg_v2[4],
+ &clip_buffer.temp_reg_v2[5],
+ &clip_buffer.temp_reg_v3[0],
+ &clip_buffer.temp_reg_v3[1],
+ &clip_buffer.temp_reg_v3[2],
+ &clip_buffer.temp_reg_v3[3],
+ &clip_buffer.temp_reg_v3[4],
+ &clip_buffer.temp_reg_v3[5],
+ &clip_buffer.temp_reg_v3[6],
+ &clip_buffer.temp_reg_v3[7],
+ &clip_buffer.temp_reg_v4[0],
+ &clip_buffer.temp_reg_v4[1],
+ &clip_buffer.temp_reg_v4[2],
+ &clip_buffer.temp_reg_v4[3],
+ &clip_buffer.temp_reg_v4[4],
+ &clip_buffer.temp_reg_v4[5],
+};
+
bool clip_triangle(Vec4* c0, Vec4* c1, Vec4* c2, Vert* v0, Vert* v1, Vert* v2, uint varying_flag, ClippedBuffer* buffer) {
bool is_visible = is_vertex_visible(c0)
&& is_vertex_visible(c1)
@@ -144,55 +177,53 @@ bool clip_triangle(Vec4* c0, Vec4* c1, Vec4* c2, Vert* v0, Vert* v1, Vert* v2, u
if (is_visible) {
return 0; /*no need to clip*/
}
-
- /*clipping it*/
-
- static ClippedBuffer temp;
-
- /*copy vert data to temp*/
- temp.count = 3;
-#define INIT_CLIP_VERT(idx) \
- temp.vertices[idx].clip_coord = *c##idx; \
- temp.vertices[idx].vertex = *v##idx; \
- if (varying_flag & VARYING_EXTRA) { \
- int i = 0; \
- if(varying_flag & VARYING_NUM) { \
- for (i = 0; i < REG_NUM_COUNT; ++i) { \
- if (varying_flag & (VARYING_NUM_00 << i)) \
- temp.vertices[idx].num[i] = reg_num[i].num[v##idx->index]; \
- } \
- } \
- if(varying_flag & VARYING_V2) { \
- for (i = 0; i < REG_V2_COUNT; ++i) { \
- if (varying_flag & (VARYING_V2_00 << i)) \
- temp.vertices[idx].v2[i] = reg_v2[i].v2[v##idx->index]; \
- } \
- } \
- if(varying_flag & VARYING_V3) { \
- for (i = 0; i < REG_V3_COUNT; ++i) { \
- if (varying_flag & (VARYING_V3_00 << i)) \
- temp.vertices[idx].v3[i] = reg_v3[i].v3[v##idx->index]; \
- } \
- } \
- if(varying_flag & VARYING_V4) { \
- for (i = 0; i < REG_V4_COUNT; ++i) { \
- if (varying_flag & (VARYING_V4_00 << i)) \
- temp.vertices[idx].v4[i] = reg_v4[i].v4[v##idx->index]; \
- } \
- } \
- }
- INIT_CLIP_VERT(0);
- INIT_CLIP_VERT(1);
- INIT_CLIP_VERT(2);
-#undef INIT_CLIP_VERT
-
- CLIP(POSITIVE_W, &temp, buffer);
- CLIP(POSITIVE_X, buffer, &temp);
- CLIP(NEGATIVE_X, &temp, buffer);
- CLIP(POSITIVE_Y, buffer, &temp);
- CLIP(NEGATIVE_Y, &temp, buffer);
- CLIP(POSITIVE_Z, buffer, &temp);
- CLIP(NEGATIVE_Z, &temp, buffer);
-
- return 1;
+//
+// /*clipping it*/
+//
+// /*copy vert data to clip_buffer*/
+// clip_buffer.count = 3;
+//#define INIT_CLIP_VERT(idx) \
+// clip_buffer.vertices[idx].clip_coord = *c##idx; \
+// clip_buffer.vertices[idx].vertex = *v##idx; \
+// if (varying_flag & VARYING_EXTRA) { \
+// int i = 0; \
+// if(varying_flag & VARYING_NUM) { \
+// for (i = 0; i < REG_NUM_COUNT; ++i) { \
+// if (varying_flag & (VARYING_NUM_00 << i)) \
+// clip_buffer.vertices[idx].num[i] = reg_num[i].num[v##idx->index]; \
+// } \
+// } \
+// if(varying_flag & VARYING_V2) { \
+// for (i = 0; i < REG_V2_COUNT; ++i) { \
+// if (varying_flag & (VARYING_V2_00 << i)) \
+// clip_buffer.vertices[idx].v2[i] = reg_v2[i].v2[v##idx->index]; \
+// } \
+// } \
+// if(varying_flag & VARYING_V3) { \
+// for (i = 0; i < REG_V3_COUNT; ++i) { \
+// if (varying_flag & (VARYING_V3_00 << i)) \
+// clip_buffer.vertices[idx].v3[i] = reg_v3[i].v3[v##idx->index]; \
+// } \
+// } \
+// if(varying_flag & VARYING_V4) { \
+// for (i = 0; i < REG_V4_COUNT; ++i) { \
+// if (varying_flag & (VARYING_V4_00 << i)) \
+// clip_buffer.vertices[idx].v4[i] = reg_v4[i].v4[v##idx->index]; \
+// } \
+// } \
+// }
+// INIT_CLIP_VERT(0);
+// INIT_CLIP_VERT(1);
+// INIT_CLIP_VERT(2);
+//#undef INIT_CLIP_VERT
+//
+// CLIP(POSITIVE_W, &clip_buffer, buffer);
+// CLIP(POSITIVE_X, buffer, &clip_buffer);
+// CLIP(NEGATIVE_X, &clip_buffer, buffer);
+// CLIP(POSITIVE_Y, buffer, &clip_buffer);
+// CLIP(NEGATIVE_Y, &clip_buffer, buffer);
+// CLIP(POSITIVE_Z, buffer, &clip_buffer);
+// CLIP(NEGATIVE_Z, &clip_buffer, buffer);
+//
+// return 1;
}
diff --git a/src/core/clip.h b/src/core/clip.h
index b6f2702..c22bb8d 100644
--- a/src/core/clip.h
+++ b/src/core/clip.h
@@ -6,25 +6,37 @@
#define LERP(t,a,b) ((1-(t))*(a)+(t)*(b))
-typedef struct ClippedVert {
+typedef struct {
/*clipping coord*/
Vec4 clip_coord;
/*vertex data*/
Vert vertex;
/*register values*/
+/*
float num[4];
Vec2 v2[6];
Vec3 v3[8];
Vec4 v4[6];
+*/
} ClippedVert;
#define CLIP_BUFFER_SIZE 6
-typedef struct ClippedBuffer {
+typedef struct {
ClippedVert vertices[CLIP_BUFFER_SIZE];
uint count;
+ /*temp register*/
+ float temp_reg_num[4][CLIP_BUFFER_SIZE];
+ Vec2 temp_reg_v2[6][CLIP_BUFFER_SIZE];
+ Vec3 temp_reg_v3[8][CLIP_BUFFER_SIZE];
+ Vec4 temp_reg_v4[6][CLIP_BUFFER_SIZE];
} ClippedBuffer;
+ClippedBuffer clip_buffer;
+
+typedef void* (*BcpInterpolator)(Vec3* bc, void* a, void* b, void* c, void* out);
+typedef void* (*LinearInterpolator)(float t, void* a, void* b, void* c, void* out);
+
bool clip_triangle(Vec4* c0, Vec4* c1, Vec4* c2, Vert* v0, Vert* v1, Vert* v2, uint varying_flag, ClippedBuffer* clipped);
uint clip_line();
diff --git a/src/core/device.c b/src/core/device.c
index cf9fee2..3566448 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -21,7 +21,7 @@ typedef struct VertexAttr {
/*
** 状态结构
*/
-struct {
+static struct {
/* MVP矩阵栈 */
Mat4 matrices[3][MATRIXDEPTH];
uint matrixtop[3];
@@ -33,7 +33,7 @@ struct {
uint buffersize; /*framebuffer size in bytess*/
/* zbuffer 深度会被映射到0~1的非线性区间*/
- uint* zbuffer;
+ float* zbuffer;
/* 顶点数据 */
Vert* verts; uint nverts;
@@ -43,12 +43,19 @@ struct {
Program* program;
UniformCollection uniforms;
- /*texture relavent*/
+ /* texture relavent */
FilterMode filtermode;
WrapMode wrapmode;
+ //FrameBuffer* framebuffer;
+
uint enable;
+ struct {
+ ssr_BlendFactor src;
+ ssr_BlendFactor dst;
+ } blendfactor;
+
} state;
/*
@@ -75,11 +82,14 @@ void ssr_init(ssr_Config* conf) {
state.framebuffer = conf->target;
}
state.buffersize = sizeof(Color) * config.width * config.height;
- state.zbuffer = ssrM_newvector(uint, config.width * config.height);
- memset(state.zbuffer, 0xff, sizeof(uint)*config.width*config.height);
+ state.zbuffer = ssrM_newvector(float, config.width * config.height);
+ //memset(state.zbuffer, 0xff, sizeof(uint)*config.width*config.height);
state.filtermode = FILTERMODE_POINT;
state.wrapmode = WRAPMODE_CLAMP;
+
+ state.blendfactor.src = BLENDFACTOR_SRC_ALPHA;
+ state.blendfactor.dst = BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
}
float ssr_getaspect() {
@@ -110,6 +120,19 @@ WrapMode ssr_getwrapmode() {
return state.wrapmode;
}
+void ssr_bindframebuffer(FrameBuffer* fbo) {
+
+}
+
+void ssr_unbindframebuffer() {
+
+}
+
+void ssr_setblendfunc(ssr_BlendFactor sfactor, ssr_BlendFactor dfactor) {
+ state.blendfactor.src = sfactor;
+ state.blendfactor.dst = dfactor;
+}
+
void ssr_matrixmode(ssr_MatrixMode mode) {
state.matrixmode = mode;
}
@@ -181,6 +204,11 @@ void ssr_getmvp(Mat4* out) {
mat4_multiply(&GETMATRIX(MATRIX_PROJECTION), out, out);
}
+void ssr_getm(Mat4* out) {
+ ssr_assert(out);
+ *out = GETMATRIX(MATRIX_MODEL);
+}
+
void ssr_getmv(Mat4* out) {
ssr_assert(out);
mat4_multiply(&GETMATRIX(MATRIX_VIEW), &GETMATRIX(MATRIX_MODEL), out);
@@ -240,7 +268,10 @@ void ssr_clearcolor(Color color) {
}
void ssr_cleardepth() {
- memset(state.zbuffer, 0xff, sizeof(uint)*config.width*config.height);
+ //memset(state.zbuffer, 0xff, sizeof(uint)*config.width*config.height);
+ for (int i = 0; i < config.width * config.height; ++i) {
+ state.zbuffer[i] = 1;
+ }
}
void ssr_putpoint(uint screenx, uint screeny, Color color) {
@@ -249,24 +280,24 @@ void ssr_putpoint(uint screenx, uint screeny, Color color) {
BUFFER[screeny * config.width + screenx] = color;
}
+void ssr_putpoint32(uint screenx, uint screeny, Color32* c32) {
+ Color c = color32_tocolor(c32);
+ ssr_putpoint(screenx, screeny, c);
+}
+
Color ssr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
unsigned int c = (a << 24) | (r << 16) | (g << 8) | b;
return c;
}
-bool ssr_testdepth(uint x, uint y, uint depth) {
- if (!contains(x, y, 0, config.width - 1, 0, config.height - 1))
- return 0;
+bool ssr_testdepth(uint x, uint y, float depth){
uint off = x + y * config.width;
- if (state.zbuffer[off] < depth)
- return 0;
- state.zbuffer[off] = depth;
- return 1;
+ return state.zbuffer[off] >= depth;
}
-bool ssr_testdepthf(uint x, uint y, float depth) {
- uint d = UINT_MAX * (double)depth;
- return ssr_testdepth(x, y, d);
+void ssr_writedepth(uint x, uint y, float depth) {
+ uint off = x + y * config.width;
+ state.zbuffer[off] = depth;
}
void ssrU_viewport(Vec2* p, Vec2* out) {
@@ -278,6 +309,26 @@ void ssrU_viewport(Vec2* p, Vec2* out) {
out->y = (int)round((1 - p->y) * (halfh - 0.5f));
}
+void ssr_blend(Color32* src, Color32* dst, Color32* out) {
+ ssrU_blend(state.blendfactor.src, state.blendfactor.dst, src, dst, out);
+}
+
+void ssrU_blend(ssr_BlendFactor sfactor
+ , ssr_BlendFactor dfactor
+ , Color32* src
+ , Color32* dst
+ , Color32* out
+) {
+ ssr_assert(src && dst && out);
+
+}
+
+Color32 ssr_getfbocolor(uint x, uint y) {
+ Color c = state.framebuffer[x + y * config.width];
+ Color32 c32; color_tocolor32(c, &c32);
+ return c32;
+}
+
void ssr_bindvertices(Vert* verts, int nverts, uint* indices, int nprims) {
ssr_assert(verts && indices);
state.verts = verts;
@@ -301,7 +352,7 @@ FragmentShaderIn ssr_frag_in;
static struct {
Vec4* coords;
uint length;
-} clipping_buffer;
+} clip_coords;
static ClippedBuffer clipped_buffer; /*clipping result*/
@@ -310,6 +361,7 @@ void ssr_draw(ssr_PrimitiveType primitive) {
static Mat4 mvp, mv;
+ /*set built-in uniforms*/
ssr_getmvp(&mvp);
ssr_getmv(&mv);
state.uniforms.model = &GETMATRIX(MATRIX_MODEL);
@@ -323,15 +375,17 @@ void ssr_draw(ssr_PrimitiveType primitive) {
/*prepare registers if necessary*/
if (use_extra_varyings) {
- ssrS_setregisters(varying_flag, state.nverts);
+ ssrS_openregs(varying_flag);
+ ssrS_setregisters(state.nverts);
+ ssrS_setactiveregr();
}
/*resize clipping coords buffer*/
- if (clipping_buffer.length < state.nverts) {
+ if (clip_coords.length < state.nverts) {
ssrM_resizevector(
Vec4,
- clipping_buffer.coords,
- clipping_buffer.length,
+ clip_coords.coords,
+ clip_coords.length,
state.nverts,
FALSE
);
@@ -343,9 +397,9 @@ void ssr_draw(ssr_PrimitiveType primitive) {
ssr_vert_in.vertex = vert;
/*set register pointers*/
if (use_extra_varyings) {
- ssrS_setupregisterpoints(varying_flag, vert->index);
+ ssrS_setupregisterpoints(vert->index);
}
- state.program->vertexshader(&state.uniforms, &ssr_vert_in, &clipping_buffer.coords[i]);
+ state.program->vertexshader(&state.uniforms, &ssr_vert_in, &clip_coords.coords[i]);
}
/*set register pointer to frag-in*/
@@ -363,9 +417,9 @@ void ssr_draw(ssr_PrimitiveType primitive) {
i1 = state.indices[i * 3 + 1];
i2 = state.indices[i * 3 + 2];
- h0 = &clipping_buffer.coords[i0],
- h1 = &clipping_buffer.coords[i1],
- h2 = &clipping_buffer.coords[i2];
+ h0 = &clip_coords.coords[i0],
+ h1 = &clip_coords.coords[i1],
+ h2 = &clip_coords.coords[i2];
v0 = &state.verts[i0];
v1 = &state.verts[i1];
@@ -379,8 +433,9 @@ void ssr_draw(ssr_PrimitiveType primitive) {
ab.y = h1->y * w1 - h0->y * w0;
ac.x = h2->x * w2 - h0->x * w0;
ac.y = h2->y * w2 - h0->y * w0;
- if (ab.x * ac.y - ab.y * ac.x <= 0)
+ if (ab.x * ac.y - ab.y * ac.x <= 0) {
continue; /*cull*/
+ }
}
/*clipping*/
@@ -388,20 +443,21 @@ void ssr_draw(ssr_PrimitiveType primitive) {
/*rasterization*/
if (!clipped) {
- ssrR_triangle(h0, h1, h2, v0, v1, v2, TRUE, NULL, NULL, NULL, state.program, &state.uniforms);
+ /*ssrS_setactiveregr();*/
+ ssrR_triangle(h0, h1, h2, v0, v1, v2, state.program, &state.uniforms);
} else {
+ ssrS_setactiveregc();
if (clipped_buffer.count >= 3) {
ClippedVert* vt0 = &clipped_buffer.vertices[0], *vt1, *vt2;
for (int i = 1; i <= clipped_buffer.count - 2; ++i) {
vt1 = &clipped_buffer.vertices[i];
vt2 = &clipped_buffer.vertices[i + 1];
h0 = &vt0->clip_coord; h1 = &vt1->clip_coord; h2 = &vt2->clip_coord;
- v0 = &vt0->vertex; v1 = &vt1->vertex; v2 = &vt2->vertex;
- ssrR_triangle(h0, h1, h2, v0, v1, v2, FALSE, vt0, vt1, vt2, state.program, &state.uniforms);
+ v0 = &vt0->vertex; v1 = &vt1->vertex; v2 = &vt2->vertex;
+ ssrR_triangle(h0, h1, h2, v0, v1, v2, state.program, &state.uniforms);
}
}
}
-
}
} else if (primitive == PRIMITIVE_POINT) {
diff --git a/src/core/device.h b/src/core/device.h
index b265471..d8daf76 100644
--- a/src/core/device.h
+++ b/src/core/device.h
@@ -8,30 +8,47 @@
#include "shader.h"
#include "rasterizer.h"
#include "vert.h"
+#include "framebuffer.h"
-typedef enum ssr_MatrixMode {
+typedef enum {
MATRIX_MODEL = 0,
MATRIX_VIEW = 1,
MATRIX_PROJECTION = 2,
} ssr_MatrixMode;
-typedef struct ssr_Config {
+typedef struct {
int width, height;
bool dbuffer;/* double buffer? */
Color* target; /* screen target buffer */
} ssr_Config;
-typedef enum ssr_PrimitiveType {
+typedef enum {
PRIMITIVE_POINT,
PRIMITIVE_LINE,
PRIMITIVE_TRIANGLE,
} ssr_PrimitiveType;
-typedef enum ssr_EnableMask {
- ENABLEMASK_BACKFACECULL = 1 ,
- ENABLEMASK_DEPTHTEST = 1 << 1,
+typedef enum {
+ ENABLEMASK_BACKFACECULL = 1,
+ ENABLEMASK_DEPTHTEST = 1 << 1,
+ ENABLEMASK_MULTISAMPLE = 1 << 2,
+ ENABLEMASK_BLEND = 1 << 3,
+ ENABLEMASK_WRITEDEPTH = 1 << 4,
} ssr_EnableMask;
+typedef enum {
+ BLENDFACTOR_ONE,
+ BLENDFACTOR_ZERO,
+ BLENDFACTOR_SRC_COLOR,
+ BLENDFACTOR_ONE_MINUS_SRC_COLOR,
+ BLENDFACTOR_DST_COLOR,
+ BLENDFACTOR_ONE_MINUS_DST_COLOR,
+ BLENDFACTOR_SRC_ALPHA,
+ BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
+ BLENDFACTOR_DST_ALPHA,
+ BLENDFACTOR_ONE_MINUS_DST_ALPHA,
+} ssr_BlendFactor;
+
void ssr_init(ssr_Config* config);
float ssr_getaspect();
@@ -61,6 +78,7 @@ void ssr_ortho(float l, float r, float b, float t, float n, float f);
void ssr_viewport(float l, float r, float b, float t);
+void ssr_getm(Mat4* out);
void ssr_getmv(Mat4* out);
void ssr_getmvp(Mat4* out);
@@ -86,19 +104,28 @@ void ssr_clearcolor(Color color);
void ssr_cleardepth();
void ssr_putpoint(uint screenx, uint screeny, Color color); /*直接修改某个位置的颜色*/
+void ssr_putpoint32(uint screenx, uint screeny, Color32* c32);
void ssr_present();
Color ssr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
-//bool ssr_cutline(int* x0, int* y0, int* x1, int* y1);
+bool ssr_testdepth(uint x, uint y, float depth);
+void ssr_writedepth(uint x, uint y, float depth);
-bool ssr_testdepth(uint x, uint y, uint depth); /*尝试写入深度,如果可绘制返回true,否则discard*/
-bool ssr_testdepthf(uint x, uint y, float depth01);
+void ssr_blend(Color32* src, Color32* dst, Color32* out);
void ssrU_viewport(Vec2* p, Vec2* out);
+void ssrU_blend(ssr_BlendFactor sfactor, ssr_BlendFactor dfactor, Color32* src, Color32* dst, Color* out);
+
+Color32 ssr_getfbocolor(uint x, uint y);
FilterMode ssr_getfiltermode();
WrapMode ssr_getwrapmode();
+void ssr_bindframebuffer(FrameBuffer* fbo);
+void ssr_unbindframebuffer();
+
+void ssr_setblendfunc(ssr_BlendFactor sfactor, ssr_BlendFactor dfactor);
+
#endif \ No newline at end of file
diff --git a/src/core/framebuffer.c b/src/core/framebuffer.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/core/framebuffer.c
diff --git a/src/core/framebuffer.h b/src/core/framebuffer.h
new file mode 100644
index 0000000..3f03200
--- /dev/null
+++ b/src/core/framebuffer.h
@@ -0,0 +1,16 @@
+#ifndef _SOFTSHADEROOM_FRAMEBUFFER_H_
+#define _SOFTSHADEROOM_FRAMEBUFFER_H_
+
+#include "texture.h"
+
+/*frame buffer object*/
+
+typedef Texture RenderTexture;
+
+typedef struct FrameBuffer{
+ RenderTexture rt;
+} FrameBuffer;
+
+FrameBuffer* fbo_create(uint height, uint width);
+
+#endif \ No newline at end of file
diff --git a/src/core/mem.h b/src/core/mem.h
index 70e8011..b51661b 100644
--- a/src/core/mem.h
+++ b/src/core/mem.h
@@ -3,9 +3,6 @@
#include <memory.h>
-void ssrM_freemem();
-void ssrM_realloc();
-
#define ssrM_copy memcpy
#define ssrM_zero(obj, size) memset(obj, 0, size)
@@ -13,11 +10,10 @@ void ssrM_realloc();
#define ssrM_newvector(T, c) ((T*)calloc(c, sizeof(T)))
#define ssrM_free(obj) free(obj)
-/*扩容一倍*/
-#define ssrM_scalevector(T, v, curlen) \
+#define ssrM_scalevector(T, v, curlen) \
do{ \
ssr_assert(v); \
- curlen = curlen << 1; \
+ curlen <<= 1; \
v = (T*)realloc(v, sizeof(T)*curlen); \
}while(0)
diff --git a/src/core/rasterizer.c b/src/core/rasterizer.c
index bf210b7..772eb29 100644
--- a/src/core/rasterizer.c
+++ b/src/core/rasterizer.c
@@ -84,18 +84,11 @@ static void puttriangle(Vec2* A, Vec2* B, Vec2* C, Color c) {
extern FragmentShaderIn ssr_frag_in;
-void ssrR_triangle(
- Vec4* CA, Vec4* CB, Vec4* CC,
- Vert* A, Vert* B, Vert* C,
- bool from_reg,
- ClippedVert* CVA, ClippedVert* CVB, ClippedVert* CVC,
- Program* program,
- UniformCollection* uniforms
-) {
+void ssrR_triangle( Vec4* CA, Vec4* CB, Vec4* CC, Vert* A, Vert* B, Vert* C, Program* program, UniformCollection* uniforms ) {
ssr_assert(CA && CB && CC && program);
static Vec3 SA, SB, SC;
- static Vec3 bcp;
+ static Vec3 bc;
vec4_dividew(CA, &SA); ssrU_viewport(&SA, &SA);
vec4_dividew(CB, &SB); ssrU_viewport(&SB, &SB);
@@ -104,11 +97,11 @@ void ssrR_triangle(
puttriangle(&SA, &SB, &SC, 0xffff0000);
return;
*/
- Vec3 *sa = &SA, *sb = &SB, *sc = &SC, *tmp; Vec4* v4tmp; Vert* vtemp; ClippedVert* cvtmp;
+ Vec3 *sa = &SA, *sb = &SB, *sc = &SC, *tmp; Vec4* v4tmp; Vert* vtemp;
#define swap(t, a, b) {t = a; a = b; b = t;} /*sort in y axis*/
- if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(vtemp, A, B); if (!from_reg) swap(cvtmp, CVA, CVB); }
- if (sc->y < sb->y) { swap(tmp, sb, sc); swap(v4tmp, CB, CC); swap(vtemp, B, C); if (!from_reg) swap(cvtmp, CVC, CVB); }
- if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(vtemp, A, B); if (!from_reg) swap(cvtmp, CVA, CVB); }
+ if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(vtemp, A, B); }
+ if (sc->y < sb->y) { swap(tmp, sb, sc); swap(v4tmp, CB, CC); swap(vtemp, B, C); }
+ if (sb->y < sa->y) { swap(tmp, sa, sb); swap(v4tmp, CA, CB); swap(vtemp, A, B); }
#undef swap
Vec2 AB = {sb->x - sa->x, sb->y - sa->y}, AC = { sc->x - sa->x, sc->y - sa->y };
@@ -118,7 +111,7 @@ void ssrR_triangle(
float invkAB = (sb->x - sa->x) / (sb->y - sa->y + EPSILON);
float invkBC = (sc->x - sb->x) / (sc->y - sb->y + EPSILON);
- Color color;
+ Color32 color;
float from, to;
Vec2 p;
float depth;
@@ -126,115 +119,67 @@ void ssrR_triangle(
uint varying_flag = program->varying_flag;
-#define DO_INTERPOLATION \
- if (varying_flag & VARYING_BASIC) { \
- if (varying_flag & VARYING_POSITION) ssrS_bcpvec3(&bcp, &A->position, &B->position, &C->position, &ssr_frag_in.position); \
- if (varying_flag & VARYING_NORMAL) ssrS_bcpvec3(&bcp, &A->normal, &B->normal, &C->normal, &ssr_frag_in.normal); \
- if (varying_flag & VARYING_TANGENT) ssrS_bcpvec3(&bcp, &A->tangent, &B->tangent, &C->tangent, &ssr_frag_in.tangent); \
- if (varying_flag & VARYING_TEXCOORD) ssrS_bcpvec2(&bcp, &A->texcoord, &B->texcoord, &C->texcoord, &ssr_frag_in.texcoord); \
- if (varying_flag & VARYING_JOINT) ssrS_bcpvec4(&bcp, &A->joint, &B->joint, &C->joint, &ssr_frag_in.joint); \
- if (varying_flag & VARYING_WEIGHT) ssrS_bcpvec4(&bcp, &A->weight, &B->weight, &C->weight, &ssr_frag_in.weight); \
- if (varying_flag & VARYING_COLOR) ssrS_bcpcolor(&bcp, A->color, B->color, C->color, &ssr_frag_in.color); \
- } \
- if (from_reg) { /*extra varying*/ \
- uint i_a = A->index, i_b = B->index, i_c = C->index; \
- if (varying_flag & VARYING_NUM) { \
- if (varying_flag & VARYING_NUM_00) reg_num_00 = ssrS_bcpnum(&bcp, reg_num[0].num[i_a], reg_num[0].num[i_b], reg_num[0].num[i_c], &ssr_frag_in.num[0]); \
- if (varying_flag & VARYING_NUM_01) reg_num_01 = ssrS_bcpnum(&bcp, reg_num[1].num[i_a], reg_num[1].num[i_b], reg_num[1].num[i_c], &ssr_frag_in.num[1]); \
- if (varying_flag & VARYING_NUM_02) reg_num_02 = ssrS_bcpnum(&bcp, reg_num[2].num[i_a], reg_num[2].num[i_b], reg_num[2].num[i_c], &ssr_frag_in.num[2]); \
- if (varying_flag & VARYING_NUM_03) reg_num_03 = ssrS_bcpnum(&bcp, reg_num[3].num[i_a], reg_num[3].num[i_b], reg_num[3].num[i_c], &ssr_frag_in.num[3]); \
- } \
- if (varying_flag & VARYING_V2) { \
- if (varying_flag & VARYING_V2_00) reg_v2_00 = ssrS_bcpvec2(&bcp, &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