From 824aa5562864ca90ea903e2fa7d99459bbdf3a0b Mon Sep 17 00:00:00 2001 From: vimene Date: Sat, 9 Dec 2023 08:57:38 +0100 Subject: fixed perspective, added plane --- src/engine.cpp | 16 +++++----------- src/fb/pixfb.cpp | 6 ++++-- src/o3d/mesh.cpp | 44 +++++++++++++++++++++++++++++--------------- src/o3d/mesh.h | 3 ++- src/o3d/vertex_data.cpp | 24 +++++++++++------------- src/o3d/vertex_data.h | 8 +++++--- src/renderer.cpp | 46 +++++++++++++++++++--------------------------- src/renderer.h | 1 - 8 files changed, 75 insertions(+), 73 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index adfe43a..96dfd7b 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -54,22 +54,17 @@ static void usage_error_exit() { } static void scene_main(engine::Renderer& renderer, engine::math::Matrix4 final_transform_mat, std::function update_frame) { - float dist = 4.f; + float dist = 1.5f; float rad = 5.f; bool cont = true; engine::o3d::Scene scene{ {{0.f, 0.f, rad * dist}, 0.f, 0.f, 0.f}, // camera { // objects engine::o3d::Object3D{ - engine::o3d::Mesh::cube(), + engine::o3d::Mesh::plane(), -rad * engine::math::Vector3(.5f, .5f, .5f), rad, 0.f, 0.f, 0.f }, - engine::o3d::Object3D{ - engine::o3d::Mesh::cube(), - +rad * engine::math::Vector3(.5f, .5f, .5f), - rad, 0.f, 0.f, 0.f - }, } }; auto scale_mat = engine::math::Matrix4::scale(rad); @@ -84,13 +79,12 @@ static void scene_main(engine::Renderer& renderer, engine::math::Matrix4 final_t * engine::math::Matrix4::rot_x(-scene.camera.rot_x) * engine::math::Matrix4::rot_y(-scene.camera.rot_y) * engine::math::Matrix4::rot_z(-scene.camera.rot_z); - std::array mats{{ - transform_mat * engine::math::Matrix4::translate(engine::math::Vector3{-.5f * rad, -.5f * rad, -.5f * rad}) * scale_mat, - transform_mat * engine::math::Matrix4::translate(engine::math::Vector3{+.5f * rad, +.5f * rad, +.5f * rad}) * scale_mat, + std::array mats{{ + transform_mat * scale_mat, }}; auto pre_final_mat = final_transform_mat * engine::math::Matrix4::projection(static_cast(renderer.height()) / static_cast(renderer.width()), 2.f, 50.f); - for (int i = 0; i < 2; i++) { + for (int i = 0; i < 1; i++) { auto final_mat = pre_final_mat * mats[i]; const auto& mesh = scene.objs[i].mesh; std::vector pts; diff --git a/src/fb/pixfb.cpp b/src/fb/pixfb.cpp index 54da87f..10f2d02 100644 --- a/src/fb/pixfb.cpp +++ b/src/fb/pixfb.cpp @@ -34,8 +34,10 @@ void PixelFrameBuffer::clear() { } void PixelFrameBuffer::draw_point(int x, int y, engine::math::Vector3 loc, const engine::o3d::VertexData& vd) { - (void) vd; - pixels_vector[x + y * w] = face_color(0); + (void) loc; + int ir = ((int) (((float) ((int) (vd.tx * 10.f))) * 25.5f)); + int ig = ((int) (((float) ((int) (vd.ty * 10.f))) * 25.5f)); + pixels_vector[x + y * w] = (ir << 24) | (ig << 16) | 0xFFFF; } uint32_t PixelFrameBuffer::face_color(int face_ind) const { diff --git a/src/o3d/mesh.cpp b/src/o3d/mesh.cpp index 47a1ea2..bf60cc8 100644 --- a/src/o3d/mesh.cpp +++ b/src/o3d/mesh.cpp @@ -6,25 +6,39 @@ using namespace engine::o3d; -Mesh Mesh::cube() { +// Mesh Mesh::cube() { +// return { +// { +// { engine::math::Vector3(-1.f, -1.f, -1.f), {} }, +// { engine::math::Vector3(+1.f, -1.f, -1.f), {} }, +// { engine::math::Vector3(-1.f, +1.f, -1.f), {} }, +// { engine::math::Vector3(+1.f, +1.f, -1.f), {} }, +// { engine::math::Vector3(-1.f, -1.f, +1.f), {} }, +// { engine::math::Vector3(+1.f, -1.f, +1.f), {} }, +// { engine::math::Vector3(-1.f, +1.f, +1.f), {} }, +// { engine::math::Vector3(+1.f, +1.f, +1.f), {} }, +// }, +// { +// { 0, 2, 3 }, { 0, 3, 1 }, // face 1 +// { 0, 4, 6 }, { 0, 6, 2 }, // face 2 +// { 0, 1, 5 }, { 0, 5, 4 }, // face 3 +// { 7, 6, 4 }, { 7, 4, 5 }, // face 4 +// { 7, 3, 2 }, { 7, 2, 6 }, // face 5 +// { 7, 5, 1 }, { 7, 1, 3 }, // face 6 +// } +// }; +// } + +Mesh Mesh::plane() { return { { - { engine::math::Vector3(-1.f, -1.f, -1.f), {} }, - { engine::math::Vector3(+1.f, -1.f, -1.f), {} }, - { engine::math::Vector3(-1.f, +1.f, -1.f), {} }, - { engine::math::Vector3(+1.f, +1.f, -1.f), {} }, - { engine::math::Vector3(-1.f, -1.f, +1.f), {} }, - { engine::math::Vector3(+1.f, -1.f, +1.f), {} }, - { engine::math::Vector3(-1.f, +1.f, +1.f), {} }, - { engine::math::Vector3(+1.f, +1.f, +1.f), {} }, + { engine::math::Vector3(-1.f, 0.f, -1.f), {0.f, 0.f} }, + { engine::math::Vector3(+1.f, 0.f, -1.f), {1.f, 0.f} }, + { engine::math::Vector3(+1.f, 0.f, +1.f), {1.f, 1.f} }, + { engine::math::Vector3(-1.f, 0.f, +1.f), {0.f, 1.f} }, }, { - { 0, 2, 3 }, { 0, 3, 1 }, // face 1 - { 0, 4, 6 }, { 0, 6, 2 }, // face 2 - { 0, 1, 5 }, { 0, 5, 4 }, // face 3 - { 7, 6, 4 }, { 7, 4, 5 }, // face 4 - { 7, 3, 2 }, { 7, 2, 6 }, // face 5 - { 7, 5, 1 }, { 7, 1, 3 }, // face 6 + { 0, 1, 2 }, { 2, 3, 0 }, } }; } diff --git a/src/o3d/mesh.h b/src/o3d/mesh.h index 579c8b2..34d1e09 100644 --- a/src/o3d/mesh.h +++ b/src/o3d/mesh.h @@ -10,7 +10,8 @@ namespace engine::o3d { class Mesh { public: - static Mesh cube(); // this function should not be in this file +// static Mesh cube(); // this function should not be in this file + static Mesh plane(); // this function should not be in this file std::vector pts; std::vector> faces; diff --git a/src/o3d/vertex_data.cpp b/src/o3d/vertex_data.cpp index ea8c5fd..b05e382 100644 --- a/src/o3d/vertex_data.cpp +++ b/src/o3d/vertex_data.cpp @@ -2,21 +2,19 @@ using namespace engine::o3d; -VertexData VertexData::lerp(const VertexData& vd1, const VertexData& vd2, float s) { - (void) vd1; - (void) vd2; - (void) s; - return {}; +VertexData VertexData::lerp(const VertexData& vd1, const VertexData& vd2, float b0) { + return { + b0 * vd1.tx + (1.f - b0) * vd2.tx, + b0 * vd1.ty + (1.f - b0) * vd2.ty + }; } -VertexData VertexData::bilerp(const VertexData& vd1, const VertexData& vd2, const VertexData& vd3, float s, float t) { - (void) vd1; - (void) vd2; - (void) vd3; - (void) s; - (void) t; - return {}; +VertexData VertexData::bilerp(const VertexData& vd1, const VertexData& vd2, const VertexData& vd3, float b0, float b1) { + return { + b0 * vd1.tx + b1 * vd2.tx + (1.f - b0 - b1) * vd3.tx, + b0 * vd1.ty + b1 * vd2.ty + (1.f - b0 - b1) * vd3.ty + }; } -VertexData::VertexData() { +VertexData::VertexData(float tx, float ty) : tx{tx}, ty{ty} { } diff --git a/src/o3d/vertex_data.h b/src/o3d/vertex_data.h index ec5fa25..b8ed14c 100644 --- a/src/o3d/vertex_data.h +++ b/src/o3d/vertex_data.h @@ -5,10 +5,12 @@ namespace engine::o3d { class VertexData { public: - static VertexData lerp(const VertexData& vd1, const VertexData& vd2, float s); - static VertexData bilerp(const VertexData& vd1, const VertexData& vd2, const VertexData& vd3, float s, float t); + static VertexData lerp(const VertexData& vd1, const VertexData& vd2, float b0); + static VertexData bilerp(const VertexData& vd1, const VertexData& vd2, const VertexData& vd3, float b0, float b1); - VertexData(); + float tx, ty; + + VertexData(float tx, float ty); }; } diff --git a/src/renderer.cpp b/src/renderer.cpp index 6e170f3..7a32807 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -31,7 +31,6 @@ unsigned int Renderer::height() const { void Renderer::clear() { std::fill(depth_buf.begin(), depth_buf.end(), 1.f); - face_ind = -1; fb->clear(); } @@ -60,8 +59,8 @@ void Renderer::_draw_cropped_triangle(o3d::TriangleVertex4 root, o3d::TriangleDe fac_b0 * sorted_vs[0]->point.z + (1.f - fac_b0) * sorted_vs[2]->point.z, 1.f / (1.f / sorted_vs[0]->point.w + fac * (1.f / sorted_vs[2]->point.w - 1.f / sorted_vs[0]->point.w)) }, - sorted_vs[0]->b0 + fac * (sorted_vs[2]->b0 - sorted_vs[0]->b0), - sorted_vs[0]->b1 + fac * (sorted_vs[2]->b1 - sorted_vs[0]->b1) + fac_b0 * sorted_vs[0]->b0 + (1.f - fac_b0) * sorted_vs[2]->b0, + fac_b0 * sorted_vs[0]->b1 + (1.f - fac_b0) * sorted_vs[2]->b1 }; if (middle_vr.point.x < middle_vl.point.x) { auto temp = middle_vr; @@ -86,22 +85,19 @@ void Renderer::_draw_cropped_triangle(o3d::TriangleVertex4 root, o3d::TriangleDe float ix = static_cast(x); float t = (ix - xl) / (xr - xl); float sub_bb1 = s * (1.f - t); - float b_fac = 1.f / ( - sub_bb0 / sorted_vs[0]->point.w - + sub_bb1 / middle_vl.point.w - + (1.f - sub_bb0 - sub_bb1) / middle_vr.point.w); + float b_fac = 1.f / (sub_bb0 / sorted_vs[0]->point.w + sub_bb1 / middle_vl.point.w + (1.f - sub_bb0 - sub_bb1) / middle_vr.point.w); float sub_b0 = b_fac * sub_bb0 / sorted_vs[0]->point.w; float sub_b1 = b_fac * sub_bb1 / middle_vl.point.w; + float b0 = sub_b0 * sorted_vs[0]->b0 + sub_b1 * middle_vl.b0 + (1.f - sub_b0 - sub_b1) * middle_vr.b0; + float b1 = sub_b0 * sorted_vs[0]->b1 + sub_b1 * middle_vl.b1 + (1.f - sub_b0 - sub_b1) * middle_vr.b1; math::Vector3 loc{ - sub_b0 * sorted_vs[0]->point.x + sub_b1 * middle_vl.point.x + (1.f - sub_b0 - sub_b1) * middle_vr.point.x, - sub_b0 * sorted_vs[0]->point.y + sub_b1 * middle_vl.point.y + (1.f - sub_b0 - sub_b1) * middle_vr.point.y, - sub_b0 * sorted_vs[0]->point.z + sub_b1 * middle_vl.point.z + (1.f - sub_b0 - sub_b1) * middle_vr.point.z + b0 * root.vertex1.point.x + b1 * root.vertex2.point.x + (1.f - b0 - b1) * root.vertex3.point.x, + b0 * root.vertex1.point.y + b1 * root.vertex2.point.y + (1.f - b0 - b1) * root.vertex3.point.y, + b0 * root.vertex1.point.z + b1 * root.vertex2.point.z + (1.f - b0 - b1) * root.vertex3.point.z }; if (loc.z < depth_buf[x + y * fb->width()]) { depth_buf[x + y * fb->width()] = loc.z; - fb->draw_point(x, y, loc, o3d::VertexData::bilerp(root.vertex1.data, root.vertex2.data, root.vertex3.data, - sub_b0 * sorted_vs[0]->b0 + sub_b1 * middle_vl.b0 + (1.f - sub_b0 - sub_b1) * middle_vr.b0, - sub_b0 * sorted_vs[0]->b1 + sub_b1 * middle_vl.b1 + (1.f - sub_b0 - sub_b1) * middle_vr.b1)); + fb->draw_point(x, y, loc, o3d::VertexData::bilerp(root.vertex1.data, root.vertex2.data, root.vertex3.data, b0, b1)); } } } @@ -125,22 +121,19 @@ void Renderer::_draw_cropped_triangle(o3d::TriangleVertex4 root, o3d::TriangleDe float ix = static_cast(x); float t = (ix - xl) / (xr - xl); float sub_bb1 = s * (1.f - t); - float b_fac = 1.f / ( - sub_bb0 / sorted_vs[2]->point.w - + sub_bb1 / middle_vl.point.w - + (1.f - sub_bb0 - sub_bb1) / middle_vr.point.w); + float b_fac = 1.f / (sub_bb0 / sorted_vs[2]->point.w + sub_bb1 / middle_vl.point.w + (1.f - sub_bb0 - sub_bb1) / middle_vr.point.w); float sub_b0 = b_fac * sub_bb0 / sorted_vs[2]->point.w; float sub_b1 = b_fac * sub_bb1 / middle_vl.point.w; + float b0 = sub_b0 * sorted_vs[2]->b0 + sub_b1 * middle_vl.b0 + (1.f - sub_b0 - sub_b1) * middle_vr.b0; + float b1 = sub_b0 * sorted_vs[2]->b1 + sub_b1 * middle_vl.b1 + (1.f - sub_b0 - sub_b1) * middle_vr.b1; math::Vector3 loc{ - sub_b0 * sorted_vs[2]->point.x + sub_b1 * middle_vl.point.x + (1.f - sub_b0 - sub_b1) * middle_vr.point.x, - sub_b0 * sorted_vs[2]->point.y + sub_b1 * middle_vl.point.y + (1.f - sub_b0 - sub_b1) * middle_vr.point.y, - sub_b0 * sorted_vs[2]->point.z + sub_b1 * middle_vl.point.z + (1.f - sub_b0 - sub_b1) * middle_vr.point.z + b0 * root.vertex1.point.x + b1 * root.vertex2.point.x + (1.f - b0 - b1) * root.vertex3.point.x, + b0 * root.vertex1.point.y + b1 * root.vertex2.point.y + (1.f - b0 - b1) * root.vertex3.point.y, + b0 * root.vertex1.point.z + b1 * root.vertex2.point.z + (1.f - b0 - b1) * root.vertex3.point.z }; if (loc.z < depth_buf[x + y * fb->width()]) { depth_buf[x + y * fb->width()] = loc.z; - fb->draw_point(x, y, loc, o3d::VertexData::bilerp(root.vertex1.data, root.vertex2.data, root.vertex3.data, - sub_b0 * sorted_vs[2]->b0 + sub_b1 * middle_vl.b0 + (1.f - sub_b0 - sub_b1) * middle_vr.b0, - sub_b0 * sorted_vs[2]->b1 + sub_b1 * middle_vl.b1 + (1.f - sub_b0 - sub_b1) * middle_vr.b1)); + fb->draw_point(x, y, loc, o3d::VertexData::bilerp(root.vertex1.data, root.vertex2.data, root.vertex3.data, b0, b1)); } } } @@ -149,12 +142,11 @@ void Renderer::_draw_cropped_triangle(o3d::TriangleVertex4 root, o3d::TriangleDe } void Renderer::draw_triangle(o3d::TriangleVertex4 triangle) { - face_ind++; for (auto t1 : triangle.to_derived().crop_z_out(-1.f, 1.f)) { for (auto t2 : t1.div_by_w().perspective_crop_xy_out(-1.f, 1.f, -1.f, 1.f)) { - math::Vector2 pp1 = t2.derived_vertex1.point.xy(); - math::Vector2 pp2 = t2.derived_vertex2.point.xy(); - math::Vector2 pp3 = t2.derived_vertex3.point.xy(); + auto pp1 = t2.derived_vertex1.point.xy(); + auto pp2 = t2.derived_vertex2.point.xy(); + auto pp3 = t2.derived_vertex3.point.xy(); if ((pp2 - pp1).det(pp3 - pp1) >= 0.f) continue; float fw_over_2 = static_cast(fb->width()) / 2.f, fh_over_2 = static_cast(fb->height()) / 2.f; t2.derived_vertex1.point.x = (t2.derived_vertex1.point.x + 1.f) * fw_over_2 - .5f; diff --git a/src/renderer.h b/src/renderer.h index a82ad56..046a4ef 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -20,7 +20,6 @@ class Renderer { private: std::vector depth_buf; - int face_ind; void _draw_cropped_triangle(o3d::TriangleVertex4 root, o3d::TriangleDerivedVertex4 triangle); }; -- cgit v1.2.3