aboutsummaryrefslogtreecommitdiff
path: root/src/engine.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/engine.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/engine.cpp')
-rw-r--r--src/engine.cpp112
1 files changed, 40 insertions, 72 deletions
diff --git a/src/engine.cpp b/src/engine.cpp
index aed0970..305d254 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -21,6 +21,8 @@
#include <fstream>
#include <map>
#include <chrono>
+#include <print>
+#include <cstdio>
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
@@ -32,12 +34,12 @@
#include <ncurses.h>
#endif
+#include "fb/fb.hpp"
#include "fb/chfb.hpp"
#include "fb/pixfb.hpp"
#include "o3d/scene.hpp"
#include "o3d/mesh.hpp"
#include "o3d/obj3d.hpp"
-#include "o3d/vertex_data.hpp"
#include "o3d/tri.hpp"
#include "o3d/camera.hpp"
#include "math/vector.hpp"
@@ -46,12 +48,15 @@
#include "math/tform.hpp"
#include "ctrl/keyboard.hpp"
#include "ctrl/mouse.hpp"
+#include "shaders/shaders.hpp"
+#include "shaders/simple_shaders.hpp"
#include "renderer.hpp"
#include "obj_parser.hpp"
#include "vulkan_utils.hpp"
using
engine::Renderer,
+ engine::fb::FrameBufferConcept,
engine::fb::CharacterFrameBuffer,
engine::fb::PixelFrameBuffer,
engine::o3d::Scene,
@@ -59,7 +64,6 @@ using
engine::o3d::Mesh,
engine::o3d::Triangle,
engine::o3d::Camera,
- engine::o3d::VertexData,
engine::math::Vector2,
engine::math::Vector3,
engine::math::Vector4,
@@ -67,7 +71,9 @@ using
engine::math::Quaternion,
engine::controllers::Keyboard,
engine::controllers::KeyboardKey,
- engine::controllers::Mouse;
+ engine::controllers::Mouse,
+ engine::shaders::ShadersConcept,
+ engine::shaders::SimpleShaders;
#define FPS 60
@@ -102,9 +108,6 @@ static void usage_error_exit() {
exit(EXIT_FAILURE);
}
-extern Camera* camera;
-Camera* camera;
-
template<typename UpdateSurfaceSizeFn, typename PollEventsFn, typename RenderAndPresentFrameFn>
static void scene_main(const Matrix4& final_transform_mat, Scene& scene,
UpdateSurfaceSizeFn update_surface_size, PollEventsFn poll_events, RenderAndPresentFrameFn render_and_present_frame) {
@@ -119,8 +122,6 @@ static void scene_main(const Matrix4& final_transform_mat, Scene& scene,
if (rx > PI / 2.f) rx = PI / 2.f;
} };
- camera = &scene.camera;
-
auto start_time = std::chrono::high_resolution_clock::now();
auto last_time = start_time;
@@ -159,8 +160,8 @@ static void scene_main(const Matrix4& final_transform_mat, Scene& scene,
}
// TODO: find better name
-template<typename FrameBuffer, typename PollEventsFn, typename UpdateRendererSizeFn, typename PresentFrameFn>
-static void render_software(Renderer<FrameBuffer>& renderer, const Matrix4& final_transform_mat, Scene& scene,
+template<FrameBufferConcept FrameBuffer, ShadersConcept Shaders, typename PollEventsFn, typename UpdateRendererSizeFn, typename PresentFrameFn>
+static void render_software(Renderer<FrameBuffer, Shaders>& renderer, const Matrix4& final_transform_mat, Scene& scene,
PollEventsFn poll_events, UpdateRendererSizeFn update_renderer_size, PresentFrameFn present_frame) {
scene_main(final_transform_mat, scene,
// update_surface_size
@@ -172,33 +173,14 @@ static void render_software(Renderer<FrameBuffer>& renderer, const Matrix4& fina
poll_events,
// render_and_present_frame
- [&](const Matrix4& /* view_mat */, const Matrix4& /* proj_mat */, const Matrix4& /* inv_view_mat */, float /* time */, float /* ellapsed_time */) {
+ [&](const Matrix4& view_mat, const Matrix4& proj_mat, const Matrix4& /* inv_view_mat */, float /* time */, float /* ellapsed_time */) {
// TODO: remove
renderer.clear();
- // auto proj_view_mat = proj_mat * view_mat;
- // renderer.clear();
- // for (const auto& obj : scene.objs) {
- // auto model_mat = obj.transform.to_mat4();
- // auto final_mat = proj_view_mat * model_mat;
- // const auto& mesh = obj.mesh;
- // std::vector<Vector4> vertices;
- // std::vector<Vector3> normals;
- // std::vector<VertexData> vertices_data;
- // for (const auto& vertex : mesh.vertices) {
- // Vector4 vertex4 { vertex, 1.f };
- // vertices.push_back(final_mat * vertex4);
- // vertices_data.push_back(VertexData((model_mat * vertex4).xyz()));
- // }
- // for (const auto& normal : mesh.normals)
- // normals.push_back((model_mat * Vector4 { normal, 0.f }).xyz());
- // for (const auto& triangle_indices : mesh.indices) {
- // [&]<std::size_t... j>(std::index_sequence<j...>) {
- // renderer.draw_triangle(
- // {{vertices[triangle_indices[j][0]], normals[triangle_indices[j][1]], vertices_data[triangle_indices[j][0]]}...}
- // );
- // }(std::make_index_sequence<3>());
- // }
- // }
+ renderer.shaders.set_view(view_mat, proj_mat);
+ for (const auto& obj : scene.objs) {
+ renderer.shaders.set_model(obj.transform.to_mat4());
+ renderer.draw_mesh(obj.mesh);
+ }
present_frame();
}
);
@@ -218,10 +200,18 @@ static int main_term(Scene& scene) {
set_escdelay(0);
curs_set(0);
+ int texture_w, texture_h, texture_channels;
+ stbi_uc* texture_pixels = stbi_load(DATADIR "/assets/textures/viking_room.png", &texture_w, &texture_h, &texture_channels, STBI_rgb_alpha);
+
+ if (!texture_pixels) {
+ std::println(stderr, "failed to load texture image, reason: {}", stbi_failure_reason());
+ exit(EXIT_FAILURE);
+ }
+
auto renderer = [&] {
int w, h;
getmaxyx(stdscr, h, w);
- return Renderer { CharacterFrameBuffer { static_cast<unsigned int>(w), static_cast<unsigned int>(h) } };
+ return Renderer { CharacterFrameBuffer { static_cast<unsigned int>(w), static_cast<unsigned int>(h) }, SimpleShaders { texture_w, texture_h, texture_pixels } };
}();
render_software(renderer, Matrix4::scale(Vector3(2.f, 1.f, 1.f)), scene,
@@ -311,6 +301,8 @@ static int main_term(Scene& scene) {
}
);
+ stbi_image_free(texture_pixels);
+
// terminate
endwin();
@@ -1672,7 +1664,7 @@ static int main_graphical(Scene& scene) {
std::tie(depth_img, depth_img_device_mem, depth_img_view) = create_depth_resources(physical_device, device, swapchain_extent, depth_format);
// create texture image
- auto [texture_img, texture_img_device_mem] = [&] {
+ auto [texture_img, texture_img_device_mem, texture_w, texture_h, texture_pixels] = [&] {
int w, h, channels;
stbi_uc* pixels = stbi_load(DATADIR "/assets/textures/viking_room.png", &w, &h, &channels, STBI_rgb_alpha);
@@ -1702,8 +1694,6 @@ static int main_graphical(Scene& scene) {
vkUnmapMemory(device, staging_buf_device_mem);
}
- stbi_image_free(pixels);
-
auto [texture_img, texture_img_device_mem] = create_img(physical_device, device, static_cast<uint32_t>(w), static_cast<uint32_t>(h), VK_FORMAT_R8G8B8A8_SRGB,
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
@@ -1724,7 +1714,7 @@ static int main_graphical(Scene& scene) {
vkFreeMemory(device, staging_buf_device_mem, nullptr);
vkDestroyBuffer(device, staging_buf, nullptr);
- return std::tuple { texture_img, texture_img_device_mem };
+ return std::tuple { texture_img, texture_img_device_mem, w, h, pixels };
}();
// create texture image view
@@ -2099,11 +2089,10 @@ static int main_graphical(Scene& scene) {
std::cout << " ]" << std::endl;
// init software renderer
- // TODO: resize buffer when surface extent change
- Renderer<PixelFrameBuffer> software_renderer { PixelFrameBuffer {
- static_cast<unsigned int>(swapchain_extent.width),
- static_cast<unsigned int>(swapchain_extent.height),
- } };
+ Renderer software_renderer {
+ PixelFrameBuffer { static_cast<unsigned int>(swapchain_extent.width), static_cast<unsigned int>(swapchain_extent.height) },
+ SimpleShaders { texture_w, texture_h, texture_pixels },
+ };
bool first_software_renderer_buf_creation = true;
std::array<VkBuffer, max_frames_in_flight> software_renderer_bufs;
@@ -2286,6 +2275,9 @@ static int main_graphical(Scene& scene) {
}
break;
case GraphicalRendererMode::software:
+ {
+ software_renderer.shaders.set_view(view_mat, proj_mat);
+ }
break;
}
@@ -2294,35 +2286,10 @@ static int main_graphical(Scene& scene) {
break;
case GraphicalRendererMode::software:
{
- auto proj_view_mat = proj_mat * view_mat;
software_renderer.clear();
for (const auto& obj : scene.objs) {
- auto model_mat = obj.transform.to_mat4();
- auto final_mat = proj_view_mat * model_mat;
- const auto& mesh = obj.mesh;
- std::vector<Vector4> vertices;
- std::vector<Vector3> normals;
- std::vector<VertexData> vertices_data;
- for (const auto& vertex : mesh.vertices) {
- Vector4 vertex4 { vertex, 1.f };
- vertices.push_back(final_mat * vertex4);
- vertices_data.push_back(VertexData((model_mat * vertex4).xyz()));
- }
- for (const auto& normal : mesh.normals)
- normals.push_back((model_mat * Vector4 { normal, 0.f }).xyz());
- for (const auto& triangle_indices : mesh.indices) {
- software_renderer.draw_triangle([&]<size_t... j>(std::index_sequence<j...>) constexpr -> engine::o3d::Triangle {
- return {
- {
- vertices[triangle_indices[j][0]],
- normals [triangle_indices[j][1]],
- mesh.uvs[triangle_indices[j][2]],
- vertices_data[triangle_indices[j][0]]
- }
- ...
- };
- }(std::make_index_sequence<3>()));
- }
+ software_renderer.shaders.set_model(obj.transform.to_mat4());
+ software_renderer.draw_mesh(obj.mesh);
}
memcpy(software_renderer_buf_mems[frame_idx], software_renderer.fb.pixels(), swapchain_extent.width * swapchain_extent.height * 4);
}
@@ -2661,6 +2628,7 @@ static int main_graphical(Scene& scene) {
vkDestroyBuffer(device, vertex_bufs[i - 1], nullptr);
}
vkDestroySampler(device, sampler, nullptr);
+ stbi_image_free(texture_pixels);
vkDestroyImageView(device, texture_img_view, nullptr);
vkFreeMemory(device, texture_img_device_mem, nullptr);
vkDestroyImage(device, texture_img, nullptr);