diff options
author | vimene <vincent.menegaux@gmail.com> | 2023-12-05 10:42:35 +0100 |
---|---|---|
committer | vimene <vincent.menegaux@gmail.com> | 2023-12-05 10:42:35 +0100 |
commit | 9b70ca7b3a1b7bfd3bf434d8b84bde42f5572ca0 (patch) | |
tree | 7078a70f7fc5b590c61386f55f4fbcc67e36b0f3 /src/fb/chfb.cpp | |
parent | 48ec7df0fd27fab05c9918e83a3a7da1cc32d7a0 (diff) | |
download | engine-9b70ca7b3a1b7bfd3bf434d8b84bde42f5572ca0.tar.gz |
added renderer, improved various things
- Added renderer to unify frame buffers
- Added FrameBuffer class as a parent for frame buffers' classes
- Improved formatting in Makefile.am
- Added const modifier in Matrix4's methods
Diffstat (limited to 'src/fb/chfb.cpp')
-rw-r--r-- | src/fb/chfb.cpp | 119 |
1 files changed, 4 insertions, 115 deletions
diff --git a/src/fb/chfb.cpp b/src/fb/chfb.cpp index c0e5cc7..b5c0ae0 100644 --- a/src/fb/chfb.cpp +++ b/src/fb/chfb.cpp @@ -17,7 +17,6 @@ void CharacterFrameBuffer::resize(unsigned int w, unsigned int h) { this->w = w; this->h = h; chars_vector.resize(w * h); - depth_buf.resize(w * h); clear(); } @@ -35,124 +34,14 @@ const char* CharacterFrameBuffer::chars() const { void CharacterFrameBuffer::clear() { std::fill(chars_vector.begin(), chars_vector.end(), ' '); - std::fill(depth_buf.begin(), depth_buf.end(), 1.f); - face_ind = -1; } -void CharacterFrameBuffer::_draw_cropped_triangle(engine::o3d::TriangleVertex3 triangle) { - std::array<engine::o3d::Vertex3*, 3> sorted_vs = { &triangle.vertex1, &triangle.vertex2, &triangle.vertex3 }; - -#define SWAP_IF_LT(X,Y) ({\ - if (sorted_vs[X]->point.y < sorted_vs[Y]->point.y) {\ - engine::o3d::Vertex3* temp = sorted_vs[X];\ - sorted_vs[X] = sorted_vs[Y];\ - sorted_vs[Y] = temp;\ - }\ - }) - SWAP_IF_LT(1, 0); - SWAP_IF_LT(2, 1); - SWAP_IF_LT(1, 0); -#undef SWAP_IF_LT - - engine::o3d::Vertex3 middle_vl = *sorted_vs[1]; - float fac = (sorted_vs[1]->point.y - sorted_vs[0]->point.y) / (sorted_vs[2]->point.y - sorted_vs[0]->point.y); - engine::o3d::Vertex3 middle_vr{ - { - sorted_vs[0]->point.x + fac * (sorted_vs[2]->point.x - sorted_vs[0]->point.x), - sorted_vs[1]->point.y, - sorted_vs[0]->point.z + fac * (sorted_vs[2]->point.z - sorted_vs[0]->point.z) - }, - engine::o3d::VertexData::lerp(sorted_vs[0]->data, sorted_vs[2]->data, fac) - }; - if (middle_vr.point.x < middle_vl.point.x) { - engine::o3d::Vertex3 temp = middle_vr; - middle_vr = middle_vl; - middle_vl = temp; - } - - // top triangle - { - if (sorted_vs[0]->point.y != sorted_vs[1]->point.y) { - int top_y = static_cast<int>(std::floor(sorted_vs[0]->point.y + 1.f)); - int bottom_y = static_cast<int>(std::ceil(sorted_vs[1]->point.y - 1.f)); - for (int y = top_y; y <= bottom_y; y++) { - float iy = static_cast<float>(y); - float s = (iy - sorted_vs[0]->point.y) / (sorted_vs[1]->point.y - sorted_vs[0]->point.y); - float xl = sorted_vs[0]->point.x + s * (middle_vl.point.x - sorted_vs[0]->point.x); - float xr = sorted_vs[0]->point.x + s * (middle_vr.point.x - sorted_vs[0]->point.x); - int left_x = static_cast<int>(std::ceil(xl)); - int right_x = static_cast<int>(std::ceil(xr - 1.f)); - for (int x = left_x; x <= right_x; x++) { - float ix = static_cast<float>(x); - float t = (ix - xl) / (xr - xl); - // depth and vd don't take into account perspective - float depth = sorted_vs[0]->point.z + s * (middle_vl.point.z - sorted_vs[0]->point.z + t * (middle_vr.point.z - middle_vl.point.z)); - // VertexData vd = VertexData::bilerp(sorted_vs[0]->data, middle_vl.data, middle_vr.data, s, t); - if (depth < depth_buf[x + y * w]) { - depth_buf[x + y * w] = depth; - chars_vector[x + y * w] = face_char(); - } - } - } - } - } - - // bottom triangle - { - if (sorted_vs[1]->point.y != sorted_vs[2]->point.y) { - int bottom_y = static_cast<int>(std::floor(sorted_vs[2]->point.y)); - int top_y = static_cast<int>(std::ceil(sorted_vs[1]->point.y)); - for (int y = top_y; y <= bottom_y; y++) { - float iy = static_cast<float>(y); - float s = (iy - sorted_vs[2]->point.y) / (sorted_vs[1]->point.y - sorted_vs[2]->point.y); - float xl = sorted_vs[2]->point.x + s * (middle_vl.point.x - sorted_vs[2]->point.x); - float xr = sorted_vs[2]->point.x + s * (middle_vr.point.x - sorted_vs[2]->point.x); - int left_x = static_cast<int>(std::ceil(xl)); - int right_x = static_cast<int>(std::ceil(xr - 1.f)); - for (int x = left_x; x <= right_x; x++) { - float ix = static_cast<float>(x); - float t = (ix - xl) / (xr - xl); - // depth and vd don't take into account perspective - float depth = sorted_vs[2]->point.z + s * (middle_vl.point.z - sorted_vs[2]->point.z + t * (middle_vr.point.z - middle_vl.point.z)); - // VertexData vd = VertexData::bilerp(sorted_vs[2]->data, middle_vl.data, middle_vr.data, s, t); - if (depth < depth_buf[x + y * w]) { - depth_buf[x + y * w] = depth; - chars_vector[x + y * w] = face_char(); - } - } - } - } - } -} - -void CharacterFrameBuffer::draw_triangle(engine::o3d::TriangleVertex4 triangle) { - face_ind++; - for (auto t1 : triangle.crop_z_out(-1.f, 1.f)) { - auto t1_2 = t1.div_by_w(); - t1_2.vertex1.point.x *= 2.f; - t1_2.vertex2.point.x *= 2.f; - t1_2.vertex3.point.x *= 2.f; - for (auto t2 : t1_2.crop_xy_out(-1.f, 1.f, -1.f, 1.f)) { - engine::math::Vector2 pp1 = t2.vertex1.point.xy(), - pp2 = t2.vertex2.point.xy(), - pp3 = t2.vertex3.point.xy(); - if ((pp2 - pp1).det(pp3 - pp1) >= 0.f) continue; - t2.vertex1.point = (t2.vertex1.point + engine::math::Vector3{1.f, 1.f, 0.f}) / 2.f; - t2.vertex2.point = (t2.vertex2.point + engine::math::Vector3{1.f, 1.f, 0.f}) / 2.f; - t2.vertex3.point = (t2.vertex3.point + engine::math::Vector3{1.f, 1.f, 0.f}) / 2.f; - float fw = static_cast<float>(w), fh = static_cast<float>(h); - t2.vertex1.point.x = t2.vertex1.point.x * fw - .5f; - t2.vertex1.point.y = t2.vertex1.point.y * fh - .5f; - t2.vertex2.point.x = t2.vertex2.point.x * fw - .5f; - t2.vertex2.point.y = t2.vertex2.point.y * fh - .5f; - t2.vertex3.point.x = t2.vertex3.point.x * fw - .5f; - t2.vertex3.point.y = t2.vertex3.point.y * fh - .5f; - _draw_cropped_triangle(t2); - } - } +void CharacterFrameBuffer::draw_point(int x, int y, engine::math::Vector3 loc, const engine::o3d::VertexData& vd) { + (void) vd; + chars_vector[x + y * w] = face_char(static_cast<int>(loc.x)); } -char CharacterFrameBuffer::face_char() const { +char CharacterFrameBuffer::face_char(int face_ind) const { int n = 1 + face_ind / 2; return (n < 10 ? '0' : 'A' - 10) + n; } |