diff options
Diffstat (limited to 'src/core/device.c')
-rw-r--r-- | src/core/device.c | 192 |
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; } } |