diff options
| author | vimene <vincent.menegaux@gmail.com> | 2026-01-17 00:06:31 +0100 |
|---|---|---|
| committer | vimene <vincent.menegaux@gmail.com> | 2026-01-17 00:06:31 +0100 |
| commit | 0d10b77f77459333c5549711334f417623ab1f3e (patch) | |
| tree | 6584ab5d09fa72c93a70ac916bfdf401c7617157 /src/engine.cpp | |
| parent | 175c71637b6bea6dcdd0faf3d614339983809bb1 (diff) | |
| download | engine-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.cpp | 112 |
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); |
