summaryrefslogtreecommitdiff
path: root/src/core/device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/device.c')
-rw-r--r--src/core/device.c192
1 files changed, 132 insertions, 60 deletions
diff --git a/src/core/device.c b/src/core/device.c
index dc4d80e..23e4bb3 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -319,6 +319,7 @@ void ssr_clearstencil(byte val) {
memset(state.stencil_buffer, val, config.width * config.height);
}
+/*directly put point onto screen*/
void ssr_putpoint(uint screenx, uint screeny, Color color) {
if (!contains(screenx, screeny, 0, config.width - 1, 0, config.height - 1))
return;
@@ -369,9 +370,9 @@ void ssrU_viewport(Vec2* p, Vec2* out) {
b = state.viewport.z,
t = state.viewport.w,
w2 = (r - l) * 0.5f,
- h2 = (b - t) * 0.5f;
+ c2 = (b - t) * 0.5f;
out->x = (int)round((p->x + 1) * (w2 - 0.5f) + l);
- out->y = (int)round((1 - p->y) * (h2 - 0.5f) + t);
+ out->y = (int)round((1 - p->y) * (c2 - 0.5f) + t);
}
void ssr_blend(Color32* src, Color32* dst, Color32* out) {
@@ -483,6 +484,124 @@ static struct {
extern ClippedBuffer clip_buffer; /*clipping result*/
+static void render_prims_triangle(uint varying_flag) {
+ uint i0, i1, i2;
+ Vec4 *c0, *c1, *c2;
+ bool reset_active_reg = FALSE;
+ bool clipped = FALSE;
+ for (int i = 0; i < state.prim_count; ++i) {
+ i0 = state.indices[i * 3];
+ i1 = state.indices[i * 3 + 1];
+ i2 = state.indices[i * 3 + 2];
+
+ c0 = &clip_coords.coords[i0];
+ c1 = &clip_coords.coords[i1];
+ c2 = &clip_coords.coords[i2];
+
+ /*back face culling*/
+ if (ssr_isenable(ENABLE_BACKFACECULL)) {
+ float w0 = 1 / c0->w, w1 = 1 / c1->w, w2 = 1 / c2->w;
+ Vec3 ab, ac;
+ ab.x = c1->x * w1 - c0->x * w0;
+ ab.y = c1->y * w1 - c0->y * w0;
+ ac.x = c2->x * w2 - c0->x * w0;
+ ac.y = c2->y * w2 - c0->y * w0;
+ if (ab.x * ac.y - ab.y * ac.x <= 0) {
+ continue; /*cull*/
+ }
+ }
+
+ /*clipping*/
+ clipped = clip_triangle(c0, c1, c2, i0, i1, i2, varying_flag, &clip_buffer);
+
+ /*rasterization*/
+ if (!clipped) {
+ if (reset_active_reg) {
+ reset_active_reg = FALSE;
+ ssrS_setactiveregr();
+ }
+ ssrR_triangle(c0, c1, c2, i0, i1, i2, state.program, &state.uniforms);
+ }
+ else {
+ if (!reset_active_reg) {
+ reset_active_reg = TRUE;
+ ssrS_setactiveregc();
+ }
+ if (clip_buffer.count >= 3) {
+ ClippedVert* vt0 = &clip_buffer.vertices[0], *vt1, *vt2;
+ for (int i = 1; i <= clip_buffer.count - 2; ++i) {
+ vt1 = &clip_buffer.vertices[i];
+ vt2 = &clip_buffer.vertices[i + 1];
+ c0 = &vt0->clip_coord; c1 = &vt1->clip_coord; c2 = &vt2->clip_coord;
+ i0 = vt0->index; i1 = vt1->index; i2 = vt2->index;
+ ssrR_triangle(c0, c1, c2, i0, i1, i2, state.program, &state.uniforms);
+ }
+ }
+ }
+ }
+}
+
+static void render_prims_line(uint varying_flag) {
+ uint i0, i1;
+ Vec4 *c0, *c1;
+ bool reset_active_reg = FALSE;
+ bool clipped = FALSE;
+ for (int i = 0; i < state.prim_count; ++i) {
+ i0 = state.indices[i * 2];
+ i1 = state.indices[i * 2 + 1];
+
+ c0 = &clip_coords.coords[i0];
+ c1 = &clip_coords.coords[i1];
+
+ clipped = clip_line(c0, c1, i0, i1, varying_flag, &clip_buffer);
+
+ if(!clipped) {
+ if (reset_active_reg) {
+ reset_active_reg = FALSE;
+ ssrS_setactiveregr();
+ }
+ ssrR_line(c0, c1, i0, i1, state.program, &state.uniforms);
+ }
+ else {
+ if (!reset_active_reg) {
+ reset_active_reg = TRUE;
+ ssrS_setactiveregc();
+ }
+ if (clip_buffer.count >= 2) {
+ ClippedVert* vt0, *vt1;
+ for (int i = 0; i < clip_buffer.count - 1; ++i) {
+ vt0 = &clip_buffer.vertices[i];
+ vt1 = &clip_buffer.vertices[i + 1];
+ c0 = &vt0->clip_coord; c1 = &vt1->clip_coord;
+ i0 = vt0->index; i1 = vt1->index;
+ ssrR_line(c0, c1, i0, i1, state.program, &state.uniforms);
+ }
+ }
+ }
+ }
+}
+
+static void render_prims_point(uint varying_flag) {
+ uint i0;
+ Vec4 *c0;
+ bool reset_active_reg = FALSE;
+ bool clipped = FALSE;
+ for (int i = 0; i < state.prim_count; ++i) {
+ i0 = state.indices[i];
+
+ c0 = &clip_coords.coords[i0];
+
+ clipped = clip_point(c0, i0, varying_flag, &clip_buffer);
+
+ if (!clipped) {
+ ssrR_point(c0, i0, state.program, &state.uniforms);
+ }
+ else {
+ /*clipped*/
+ }
+ }
+}
+
void ssr_draw(ssr_PrimitiveType primitive) {
ssr_assert(state.verts && state.indices);
@@ -535,64 +654,17 @@ void ssr_draw(ssr_PrimitiveType primitive) {
ssrS_setregtofragin(varying_flag, &ssr_frag_in);
}
- /*primitive assembly*/
- if (primitive == PRIMITIVE_TRIANGLE) {
- uint i0, i1, i2;
- Vec4 *h0, *h1, *h2;
- bool reset_active_reg = FALSE;
- for (int i = 0; i < state.prim_count; ++i) {
- i0 = state.indices[i * 3];
- i1 = state.indices[i * 3 + 1];
- i2 = state.indices[i * 3 + 2];
-
- h0 = &clip_coords.coords[i0],
- h1 = &clip_coords.coords[i1],
- h2 = &clip_coords.coords[i2];
-
- /*back face culling*/
- if (ssr_isenable(ENABLE_BACKFACECULL)) {
- float w0 = 1 / h0->w, w1 = 1 / h1->w, w2 = 1 / h2->w;
- Vec3 ab, ac;
- ab.x = h1->x * w1 - h0->x * w0;
- 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) {
- continue; /*cull*/
- }
- }
-
- /*clipping*/
- bool clipped = clip_triangle(h0, h1, h2, i0, i1, i2, varying_flag, &clip_buffer);
-
- /*rasterization*/
- if (!clipped) {
- if (reset_active_reg) {
- reset_active_reg = FALSE;
- ssrS_setactiveregr();
- }
- ssrR_triangle(h0, h1, h2, i0, i1, i2, state.program, &state.uniforms);
- } else {
- if (!reset_active_reg) {
- reset_active_reg = TRUE;
- ssrS_setactiveregc();
- }
- if (clip_buffer.count >= 3) {
- ClippedVert* vt0 = &clip_buffer.vertices[0], *vt1, *vt2;
- for (int i = 1; i <= clip_buffer.count - 2; ++i) {
- vt1 = &clip_buffer.vertices[i];
- vt2 = &clip_buffer.vertices[i + 1];
- h0 = &vt0->clip_coord; h1 = &vt1->clip_coord; h2 = &vt2->clip_coord;
- i0 = vt0->index; i1 = vt1->index; i2 = vt2->index;
- ssrR_triangle(h0, h1, h2, i0, i1, i2, state.program, &state.uniforms);
- }
- }
- }
- }
- } else if (primitive == PRIMITIVE_POINT) {
-
- } else if (primitive == PRIMITIVE_LINE) {
-
+ /*primitive assembly and rendering*/
+ switch (primitive) {
+ case PRIMITIVE_TRIANGLE:
+ render_prims_triangle(varying_flag);
+ break;
+ case PRIMITIVE_LINE:
+ render_prims_line(varying_flag);
+ break;
+ case PRIMITIVE_POINT:
+ render_prims_point(varying_flag);
+ break;
}
}