aboutsummaryrefslogtreecommitdiff
path: root/src/renderer.cpp
diff options
context:
space:
mode:
authorvimene <vincent.menegaux@gmail.com>2026-01-17 00:06:31 +0100
committervimene <vincent.menegaux@gmail.com>2026-01-17 00:06:31 +0100
commit0d10b77f77459333c5549711334f417623ab1f3e (patch)
tree6584ab5d09fa72c93a70ac916bfdf401c7617157 /src/renderer.cpp
parent175c71637b6bea6dcdd0faf3d614339983809bb1 (diff)
downloadengine-0d10b77f77459333c5549711334f417623ab1f3e.tar.gz
improved software shaders
- unified terminal and graphical software renderer shaders - added vertex shaders for software renderers - removed VertexData - moved shaders from frame buffers to their own class - added FrameBufferConcept and ShadersConcept
Diffstat (limited to 'src/renderer.cpp')
-rw-r--r--src/renderer.cpp57
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>;