diff options
Diffstat (limited to 'src/renderer.cpp')
| -rw-r--r-- | src/renderer.cpp | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/src/renderer.cpp b/src/renderer.cpp index 35e3ab3..9447119 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -3,12 +3,17 @@ #include <memory> #include <array> #include <tuple> +#include <utility> #include "math/vector.hpp" #include "o3d/tri.hpp" #include "o3d/tri_deriv.hpp" #include "o3d/polygon.hpp" +#include "o3d/mesh.hpp" +#include "fb/fb.hpp" #include "fb/chfb.hpp" #include "fb/pixfb.hpp" +#include "shaders/shaders.hpp" +#include "shaders/simple_shaders.hpp" using namespace engine; using @@ -17,32 +22,35 @@ using engine::math::Vector4, engine::o3d::Triangle, engine::o3d::TriangleDerived, - engine::o3d::VertexData, engine::o3d::DerivedVertex, + engine::o3d::Mesh, engine::fb::CharacterFrameBuffer, - engine::fb::PixelFrameBuffer; + engine::fb::FrameBufferConcept, + engine::fb::PixelFrameBuffer, + engine::shaders::ShadersConcept, + engine::shaders::SimpleShaders; -template<typename FrameBuffer> -Renderer<FrameBuffer>::Renderer(FrameBuffer&& fb) : fb { std::forward<FrameBuffer>(fb) } { +template<FrameBufferConcept FrameBuffer, ShadersConcept Shaders> +Renderer<FrameBuffer, Shaders>::Renderer(FrameBuffer&& fb, Shaders&& shaders) : fb { std::forward<FrameBuffer>(fb) }, shaders { std::forward<Shaders>(shaders) } { depth_buf.resize(this->fb.width() * this->fb.height()); } -template<typename FrameBuffer> -void Renderer<FrameBuffer>::resize(unsigned int w, unsigned int h) { +template<FrameBufferConcept FrameBuffer, ShadersConcept Shaders> +void Renderer<FrameBuffer, Shaders>::resize(unsigned int w, unsigned int h) { fb.resize(w, h); depth_buf.resize(fb.width() * fb.height()); } -template<typename FrameBuffer> -void Renderer<FrameBuffer>::clear() { +template<FrameBufferConcept FrameBuffer, ShadersConcept Shaders> +void Renderer<FrameBuffer, Shaders>::clear() { std::fill(depth_buf.begin(), depth_buf.end(), 1.f); fb.clear(); } enum class TriangleSide { top, bottom }; -template<typename FrameBuffer> -void Renderer<FrameBuffer>::draw_triangle(const Triangle& triangle) { +template<FrameBufferConcept FrameBuffer, ShadersConcept Shaders> +void Renderer<FrameBuffer, Shaders>::draw_triangle(const Triangle& triangle) { const auto& polygon = engine::o3d::polygon::div_by_w(engine::o3d::polygon::from_triangle_derived(triangle.to_derived()).clip_z(0.f, 1.f)); if (engine::o3d::polygon::signed_area_xy(polygon) >= 0) return; const auto& [final_triangles_count, final_triangles] @@ -53,11 +61,25 @@ void Renderer<FrameBuffer>::draw_triangle(const Triangle& triangle) { _draw_cropped_triangle(triangle, final_triangles[i]); } +template<FrameBufferConcept FrameBuffer, ShadersConcept Shaders> +void Renderer<FrameBuffer, Shaders>::draw_mesh(const Mesh& mesh) { + for (const auto& triangle_indices : mesh.indices) { + draw_triangle([&]<std::size_t... j>(std::index_sequence<j...>) -> Triangle { + return { + shaders.vertex(mesh.vertices[triangle_indices[j][0]], + mesh.normals [triangle_indices[j][1]], + mesh.uvs [triangle_indices[j][2]]) + ... + }; + }(std::make_index_sequence<3>())); + } +} + // TODO: the renaming of w to z or the inverse is very confusing. The reason why it happens is // because we use Vector3 to store x, y and w, which therefore gets renamed to w. We should find // another way of doing this -template<typename FrameBuffer> -void Renderer<FrameBuffer>::_draw_cropped_triangle(const Triangle& root, const TriangleDerived<Vector3>& triangle) { +template<FrameBufferConcept FrameBuffer, ShadersConcept Shaders> +void Renderer<FrameBuffer, Shaders>::_draw_cropped_triangle(const Triangle& root, const TriangleDerived<Vector3>& triangle) { std::array<const DerivedVertex<Vector3>*, 3> sorted_vs = { &triangle.derived_vertex1, &triangle.derived_vertex2, &triangle.derived_vertex3 }; { @@ -138,10 +160,9 @@ void Renderer<FrameBuffer>::_draw_cropped_triangle(const Triangle& root, const T depth_buf[x + y * fb.width()] = loc.z; - fb.draw_point(x, y, loc, - Vector3 ::bilerp(root.vertex1.normal, root.vertex2.normal, root.vertex3.normal, b0, b1), - Vector2 ::bilerp(root.vertex1.uv, root.vertex2.uv, root.vertex3.uv, b0, b1), - VertexData::bilerp(root.vertex1.data, root.vertex2.data, root.vertex3.data, b0, b1)); + fb.draw_point(x, y, shaders.fragment(x, y, loc, + Vector3::bilerp(root.vertex1.normal, root.vertex2.normal, root.vertex3.normal, b0, b1), + Vector2::bilerp(root.vertex1.uv, root.vertex2.uv, root.vertex3.uv, b0, b1))); } } }; @@ -149,5 +170,5 @@ void Renderer<FrameBuffer>::_draw_cropped_triangle(const Triangle& root, const T _draw_cropped_triangle_side.template operator()<TriangleSide::bottom>(); } -template class Renderer<CharacterFrameBuffer>; -template class Renderer<PixelFrameBuffer>; +template class Renderer<CharacterFrameBuffer, SimpleShaders>; +template class Renderer<PixelFrameBuffer, SimpleShaders>; |
