aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-08-20 03:00:56 +0200
committerhachem <im@hachem.wtf>2026-08-20 08:13:17 +0200
commit9a19ae463880e06bae84eb8ae1b7279595ecdc38 (patch)
treea652344ef39837096dc76b0386550870eec3f77e /src
parentb0be47e54943bf45babac5bce6c2f6f0dc5cb4dc (diff)
[fix]: path for the logo
Diffstat (limited to 'src')
-rw-r--r--src/Core/Application.cpp238
-rw-r--r--src/Core/Application.h53
-rw-r--r--src/Core/Camera.cpp225
-rw-r--r--src/Core/Camera.h131
-rw-r--r--src/Core/Event.h362
-rw-r--r--src/Core/Log.cpp156
-rw-r--r--src/Core/Log.h156
-rw-r--r--src/Core/Memory.h24
-rw-r--r--src/Core/State.h19
-rw-r--r--src/Core/Window.cpp341
-rw-r--r--src/Core/Window.h78
-rw-r--r--src/Engine/Engine.cpp614
-rw-r--r--src/Engine/Engine.h184
-rw-r--r--src/Engine/Object.h76
-rw-r--r--src/Engine/Scene.h70
-rw-r--r--src/Rendering/Framebuffer.cpp17
-rw-r--r--src/Rendering/Framebuffer.h65
-rw-r--r--src/Rendering/Renderer.cpp64
-rw-r--r--src/Rendering/Renderer.h158
-rw-r--r--src/Rendering/Shader.cpp84
-rw-r--r--src/Rendering/Shader.h58
-rw-r--r--src/Rendering/Texture.cpp68
-rw-r--r--src/Rendering/Texture.h42
23 files changed, 0 insertions, 3283 deletions
diff --git a/src/Core/Application.cpp b/src/Core/Application.cpp
deleted file mode 100644
index 667fc73..0000000
--- a/src/Core/Application.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-#include "application.h"
-
-#include "rendering/renderer.h"
-#include "settings_manager.h"
-
-#include "states/simulation_state.h"
-#include "states/config_state.h"
-#include "states/world_builder_state.h"
-
-#include <GLFW/glfw3.h>
-#include <imgui.h>
-#include <ImGuizmo.h>
-
-#include "platform/vulkan/vulkan_renderer.h"
-
-#ifdef __APPLE__
-#include "platform/metal/metal_context.h"
-#include "platform/vulkan/vulkan_context.h"
-#endif
-
-namespace Donut
-{
- Application* Application::s_instance = nullptr;
-
- Application::Application(const std::string& name, int width, int height)
- : m_running(true), m_minimized(false)
- {
- s_instance = this;
-
- // Select the render API before the window is created: the window is
- // built differently for Vulkan (GLFW_NO_API) than for OpenGL.
- Logger::init();
- SettingsManager::initialize();
- {
- const auto& settings = SettingsManager::get_settings_const();
- RendererAPI::set_api(settings.graphics.render_api == "Vulkan"
- ? RendererAPI::API::Vulkan : RendererAPI::API::OpenGL);
- }
-
- if (RendererAPI::get_api() == RendererAPI::API::Vulkan)
- vulkan_prepare_glfw(); // must precede glfwInit() inside the Window ctor
-
- m_window = create_scope<Window>(name, width, height);
- m_window->set_event_callback([this](Event& event)
- {
- on_event(event);
- });
-
- on_init();
- }
-
- Application::~Application()
- {
- on_shutdown();
- s_instance = nullptr;
- }
-
- auto Application::run() -> void
- {
- while (m_running)
- {
- if (m_vulkan_renderer)
- {
- glfwPollEvents(); // before the ImGui frame so input is current
- if (!m_minimized)
- m_vulkan_renderer->draw_frame(glm::vec4(0.05f, 0.06f, 0.10f, 1.0f),
- [this] { build_vulkan_ui(); });
- }
- else
- {
- if (!m_minimized)
- {
- on_update();
- on_render();
- }
- m_window->on_update(); // polls events + swaps buffers (OpenGL)
- }
- }
- }
-
- auto Application::build_vulkan_ui() -> void
- {
- // Placeholder UI proving the ImGui Vulkan backend renders. The real
- // application UI (states' on_im_ui_render) moves here once the scene is
- // ported to Vulkan (B-3).
- ImGui::Begin("Donut - Vulkan backend");
- ImGui::Text("Geodesic black hole through Vulkan (MoltenVK).");
- ImGui::Text("%.1f FPS", ImGui::GetIO().Framerate);
- ImGui::Separator();
- ImGui::TextWrapped("Drag to orbit, scroll to zoom. HDRI starfield is live; "
- "next is porting the simulation UI to Vulkan.");
- ImGui::End();
- }
-
- auto Application::close() -> void
- {
- m_running = false;
- }
-
- auto Application::on_event(Event& event) -> void
- {
- EventDispatcher dispatcher(event);
- dispatcher.dispatch<WindowCloseEvent>([this, &event](WindowCloseEvent& e)
- {
- m_running = false;
- event.handled = true;
- return true;
- });
-
- dispatcher.dispatch<WindowResizeEvent>([this, &event](WindowResizeEvent& e)
- {
- if (e.get_width() == 0 || e.get_height() == 0)
- m_minimized = true;
- else
- m_minimized = false;
-
- if (m_vulkan_renderer)
- {
- m_vulkan_renderer->on_resize(e.get_width(), e.get_height());
- }
- else
- {
- Renderer::on_window_resize(e.get_width(), e.get_height());
- if (m_engine) m_engine->set_window_dimensions(e.get_width(), e.get_height());
- }
- event.handled = true;
- return true;
- });
-
- dispatcher.dispatch<KeyPressedEvent>([this, &event](KeyPressedEvent& e)
- {
- if (!m_state_manager)
- return true;
- if (e.get_key_code() == GLFW_KEY_1)
- {
- m_state_manager->switch_to_state("Config");
- event.handled = true;
- return true;
- }
- else if (e.get_key_code() == GLFW_KEY_2)
- {
- m_state_manager->switch_to_state("Simulation");
- event.handled = true;
- return true;
- }
- else if (e.get_key_code() == GLFW_KEY_3)
- {
- m_state_manager->switch_to_state("WorldBuilder");
- event.handled = true;
- return true;
- }
-
- return true;
- });
-
- if (m_state_manager)
- m_state_manager->on_event(event);
- }
-
- auto Application::on_init() -> void
- {
- // (Logger, settings and API selection happen in the constructor.)
-
- if (RendererAPI::get_api() == RendererAPI::API::Vulkan)
- {
- int w = 0, h = 0;
- glfwGetFramebufferSize((GLFWwindow*)m_window->get_native_window(), &w, &h);
- m_vulkan_renderer = create_scope<VulkanRenderer>();
- if (!m_vulkan_renderer->init(m_window->get_native_window(), w, h))
- DONUT_ERROR("Vulkan renderer initialization failed");
- else
- m_vulkan_renderer->init_im_gui();
- // Scene rendering hooks in here in the B-3 phase; the Vulkan path now
- // clears, presents, and draws the ImGui UI.
- return;
- }
-
- Renderer::init();
- m_window->init_im_gui();
-
- Renderer::on_window_resize(1280, 720);
- RenderCommand::set_face_culling(false);
-
- m_engine = create_scope<Engine>();
- m_engine->set_window_dimensions(1280, 720);
-
- m_state_manager = create_scope<StateManager>();
- m_state_manager->register_state("Config", create_scope<ConfigState>());
- m_state_manager->register_state("Simulation", create_scope<SimulationState>());
- m_state_manager->register_state("WorldBuilder", create_scope<WorldBuilderState>());
- m_state_manager->switch_to_state("Config");
- }
-
- auto Application::on_shutdown() -> void
- {
- if (m_vulkan_renderer)
- {
- m_vulkan_renderer->shutdown();
- m_vulkan_renderer.reset();
- }
- else
- {
- if (m_state_manager)
- m_state_manager->shutdown();
- Renderer::shutdown();
- }
- SettingsManager::shutdown();
- Logger::shutdown();
- }
-
- auto Application::on_update() -> void
- {
- float current_frame = (float)glfwGetTime();
- m_delta_time = current_frame - m_last_frame;
- m_last_frame = current_frame;
-
- m_state_manager->update(m_delta_time);
- }
-
- auto Application::on_render() -> void
- {
- m_state_manager->render();
- m_window->begin_im_gui_frame();
-
- ImGuizmo::BeginFrame();
- ImGuizmo::SetOrthographic(false);
-
- setup_docking_layout();
- m_state_manager->on_im_ui_render();
- m_window->end_im_gui_frame();
- }
-
- auto Application::setup_docking_layout() -> void
- {
- ImGuiViewport* viewport = ImGui::GetMainViewport();
- ImGui::DockSpaceOverViewport(0, viewport, ImGuiDockNodeFlags_PassthruCentralNode);
- }
-};
diff --git a/src/Core/Application.h b/src/Core/Application.h
deleted file mode 100644
index 06c4e94..0000000
--- a/src/Core/Application.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once
-
-#include "state_manager.h"
-#include "memory.h"
-#include "window.h"
-#include "event.h"
-#include "log.h"
-
-#include "engine/engine.h"
-
-namespace Donut
-{
- class VulkanRenderer; // live-window Vulkan backend (platform/vulkan)
-
- class Application
- {
- public:
- Application(const std::string& name = "Donut",
- int width = 1280, int height = 720);
- ~Application();
-
- auto run() -> void;
- auto close() -> void;
-
- auto get_window() -> Window& { return *m_window; }
- auto get_state_manager() -> StateManager& { return *m_state_manager; }
- auto get_engine() -> Engine& { return *m_engine; }
- static auto get() -> Application& { return *s_instance; }
-
- private:
- auto on_init() -> void;
- auto on_shutdown() -> void;
- auto on_update() -> void;
- auto on_render() -> void;
- auto on_event(Event& event) -> void;
- auto setup_docking_layout() -> void;
- auto build_vulkan_ui() -> void; // ImGui UI built each frame on the Vulkan path
-
- private:
- Scope<StateManager> m_state_manager;
- Scope<Window> m_window;
- Scope<Engine> m_engine;
- Scope<VulkanRenderer> m_vulkan_renderer; // non-null only when the Vulkan API is selected
-
- bool m_running;
- bool m_minimized;
-
- float m_delta_time = 0.0f;
- float m_last_frame = 0.0f;
-
- static Application* s_instance;
- };
-}
diff --git a/src/Core/Camera.cpp b/src/Core/Camera.cpp
deleted file mode 100644
index 35b7a2f..0000000
--- a/src/Core/Camera.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-#include "camera.h"
-
-#include <glm/gtc/quaternion.hpp>
-#include <GLFW/glfw3.h>
-
-namespace Donut
-{
- Camera::Camera(float fov, float aspect_ratio, float near_plane, float far_plane)
- : m_fov(fov), m_aspect_ratio(aspect_ratio), m_near_plane(near_plane), m_far_plane(far_plane)
- {
- recalculate_projection_matrix();
- recalculate_view_matrix();
- }
-
- auto Camera::set_projection(float fov, float aspect_ratio, float near_plane, float far_plane) -> void
- {
- m_fov = fov;
- m_aspect_ratio = aspect_ratio;
- m_near_plane = near_plane;
- m_far_plane = far_plane;
- recalculate_projection_matrix();
- }
-
- auto Camera::recalculate_projection_matrix() -> void
- {
- m_projection_matrix = glm::perspective(glm::radians(m_fov), m_aspect_ratio, m_near_plane, m_far_plane);
- m_view_projection_matrix = m_projection_matrix * m_view_matrix;
- }
-
- auto Camera::recalculate_view_matrix() -> void
- {
- if (m_camera_mode == CameraMode::FPS)
- {
- float pitch = glm::radians(m_rotation.x);
- float yaw = glm::radians(m_rotation.y);
- float roll = glm::radians(m_rotation.z);
-
- glm::vec3 direction;
- direction.x = cos(yaw) * cos(pitch);
- direction.y = sin(pitch);
- direction.z = sin(yaw) * cos(pitch);
-
- glm::vec3 world_up(0.0f, 1.0f, 0.0f);
- glm::vec3 front = glm::normalize(direction);
- glm::vec3 right = glm::normalize(glm::cross(front, world_up));
- glm::vec3 up = glm::normalize(glm::cross(right, front));
-
- m_view_matrix = glm::lookAt(m_position, m_position + front, up);
- m_view_projection_matrix = m_projection_matrix * m_view_matrix;
- }
- else if (m_camera_mode == CameraMode::Orbital)
- {
- glm::vec3 position = get_orbital_position();
- glm::vec3 target = m_orbital_target;
- glm::vec3 up(0.0f, 1.0f, 0.0f);
-
- m_view_matrix = glm::lookAt(position, target, up);
- m_view_projection_matrix = m_projection_matrix * m_view_matrix;
- }
- }
-
- auto Camera::get_forward_direction() const -> glm::vec3
- {
- float pitch = glm::radians(m_rotation.x);
- float yaw = glm::radians(m_rotation.y);
-
- glm::vec3 direction;
- direction.x = cos(yaw) * cos(pitch);
- direction.y = sin(pitch);
- direction.z = sin(yaw) * cos(pitch);
-
- return glm::normalize(direction);
- }
-
- auto Camera::get_right_direction() const -> glm::vec3
- {
- glm::vec3 world_up(0.0f, 1.0f, 0.0f);
- return glm::normalize(glm::cross(get_forward_direction(), world_up));
- }
-
- auto Camera::get_up_direction() const -> glm::vec3
- {
- return glm::normalize(glm::cross(get_right_direction(), get_forward_direction()));
- }
-
- auto Camera::on_mouse_move(float x_offset, float y_offset, bool constrain_pitch) -> void
- {
- if (m_camera_mode == CameraMode::FPS)
- {
- x_offset *= m_mouse_sensitivity;
- y_offset *= m_mouse_sensitivity;
-
- m_rotation.y += x_offset;
- m_rotation.x += y_offset;
-
- if (constrain_pitch)
- {
- if (m_rotation.x > 89.0f)
- m_rotation.x = 89.0f;
- if (m_rotation.x < -89.0f)
- m_rotation.x = -89.0f;
- }
-
- recalculate_view_matrix();
- }
- }
-
- auto Camera::move_forward(float delta_time) -> void
- {
- if (m_camera_mode == CameraMode::FPS)
- {
- m_position += get_forward_direction() * m_movement_speed * delta_time;
- recalculate_view_matrix();
- }
- }
-
- auto Camera::move_backward(float delta_time) -> void
- {
- if (m_camera_mode == CameraMode::FPS)
- {
- m_position -= get_forward_direction() * m_movement_speed * delta_time;
- recalculate_view_matrix();
- }
- }
-
- auto Camera::move_right(float delta_time) -> void
- {
- if (m_camera_mode == CameraMode::FPS)
- {
- m_position += get_right_direction() * m_movement_speed * delta_time;
- recalculate_view_matrix();
- }
- }
-
- auto Camera::move_left(float delta_time) -> void
- {
- if (m_camera_mode == CameraMode::FPS)
- {
- m_position -= get_right_direction() * m_movement_speed * delta_time;
- recalculate_view_matrix();
- }
- }
-
- auto Camera::move_up(float delta_time) -> void
- {
- if (m_camera_mode == CameraMode::FPS)
- {
- glm::vec3 world_up(0.0f, 1.0f, 0.0f);
- m_position += world_up * m_movement_speed * delta_time;
- recalculate_view_matrix();
- }
- }
-
- auto Camera::move_down(float delta_time) -> void
- {
- if (m_camera_mode == CameraMode::FPS)
- {
- glm::vec3 world_up(0.0f, 1.0f, 0.0f);
- m_position -= world_up * m_movement_speed * delta_time;
- recalculate_view_matrix();
- }
- }
-
- auto Camera::get_orbital_position() const -> glm::vec3
- {
- float clamped_elevation = glm::clamp(m_elevation, 0.01f, float(std::numbers::pi) - 0.01f);
- return glm::vec3
- (
- m_orbital_radius * sin(clamped_elevation) * cos(m_azimuth),
- m_orbital_radius * cos(clamped_elevation),
- m_orbital_radius * sin(clamped_elevation) * sin(m_azimuth)
- );
- }
-
- auto Camera::update_orbital() -> void
- {
- m_orbital_target = glm::vec3(0.0f, 0.0f, 0.0f);
- if (m_dragging || m_panning)
- m_moving = true;
- else
- m_moving = false;
- recalculate_view_matrix();
- }
-
- auto Camera::process_orbital_mouse_move(double x, double y) -> void
- {
- if (m_dragging && !m_panning)
- {
- float dx = float(x - m_last_x_orbital);
- float dy = float(y - m_last_y_orbital);
-
- m_azimuth += dx * m_orbital_speed;
- m_elevation -= dy * m_orbital_speed;
- m_elevation = glm::clamp(m_elevation, 0.01f, float(std::numbers::pi) - 0.01f);
- }
-
- m_last_x_orbital = x;
- m_last_y_orbital = y;
- update_orbital();
- }
-
- auto Camera::process_orbital_mouse_button(int button, int action, int mods) -> void
- {
- if (button == GLFW_MOUSE_BUTTON_LEFT)
- {
- if (action == GLFW_PRESS)
- {
- m_dragging = true;
- m_panning = false;
- }
- else if (action == GLFW_RELEASE)
- {
- m_dragging = false;
- m_panning = false;
- }
- }
- }
-
- auto Camera::process_orbital_scroll(double x_offset, double y_offset) -> void
- {
- m_orbital_radius -= y_offset * m_zoom_speed;
- m_orbital_radius = glm::clamp(m_orbital_radius, m_orbital_min_radius, m_orbital_max_radius);
- update_orbital();
- }
-}
diff --git a/src/Core/Camera.h b/src/Core/Camera.h
deleted file mode 100644
index c997c35..0000000
--- a/src/Core/Camera.h
+++ /dev/null
@@ -1,131 +0,0 @@
-#pragma once
-
-#include <glm/glm.hpp>
-#include <glm/gtc/matrix_transform.hpp>
-
-#include <numbers>
-
-namespace Donut
-{
- enum class CameraMode
- {
- FPS,
- Orbital
- };
-
- class Camera
- {
- public:
- Camera(float fov = 45.0f, float aspect_ratio = 16.0f / 9.0f,
- float near_plane = 0.1f, float far_plane = 100.0f);
- ~Camera() = default;
-
- auto set_position(const glm::vec3& position) -> void { m_position = position; recalculate_view_matrix(); }
- auto set_rotation(const glm::vec3& rotation) -> void { m_rotation = rotation; recalculate_view_matrix(); }
-
- auto get_position() const -> const glm::vec3& { return m_position; }
- auto get_rotation() const -> const glm::vec3& { return m_rotation; }
-
- auto get_forward_direction() const -> glm::vec3;
- auto get_right_direction() const -> glm::vec3;
- auto get_up_direction() const -> glm::vec3;
-
- auto get_projection_matrix() const -> const glm::mat4& { return m_projection_matrix; }
- auto get_view_matrix() const -> const glm::mat4& { return m_view_matrix; }
- auto get_view_projection_matrix() const -> const glm::mat4& { return m_view_projection_matrix; }
-
- auto set_projection(float fov, float aspect_ratio, float near_plane, float far_plane) -> void;
- auto on_mouse_move(float x_offset, float y_offset, bool constrain_pitch = true) -> void;
-
- auto move_forward(float delta_time) -> void;
- auto move_backward(float delta_time) -> void;
- auto move_right(float delta_time) -> void;
- auto move_left(float delta_time) -> void;
- auto move_up(float delta_time) -> void;
- auto move_down(float delta_time) -> void;
-
- auto set_mouse_sensitivity(float sensitivity) -> void { m_mouse_sensitivity = sensitivity; }
- auto get_mouse_sensitivity() const -> float { return m_mouse_sensitivity; }
-
- auto set_movement_speed(float speed) -> void { m_movement_speed = speed; }
- auto get_movement_speed() const -> float { return m_movement_speed; }
-
- auto set_orbital_target(const glm::vec3& target) -> void { m_orbital_target = target; }
- auto get_orbital_target() const -> const glm::vec3& { return m_orbital_target; }
-
- auto set_orbital_radius(double radius) -> void { m_orbital_radius = radius; }
- auto get_orbital_radius() const -> double { return m_orbital_radius; }
-
- auto set_orbital_limits(double min_radius, double max_radius) -> void
- {
- m_orbital_min_radius = min_radius;
- m_orbital_max_radius = max_radius;
- }
-
- auto set_orbital_speed(float speed) -> void { m_orbital_speed = speed; }
- auto get_orbital_speed() const -> float { return m_orbital_speed; }
-
- auto set_zoom_speed(double speed) -> void { m_zoom_speed = speed; }
- auto get_zoom_speed() const -> double { return m_zoom_speed; }
-
- auto set_azimuth(float azimuth) -> void { m_azimuth = azimuth; }
- auto get_azimuth() const -> float { return m_azimuth; }
-
- auto set_elevation(float elevation) -> void { m_elevation = elevation; }
- auto get_elevation() const -> float { return m_elevation; }
-
- auto get_orbital_position() const -> glm::vec3;
- auto update_orbital() -> void;
- auto process_orbital_mouse_move(double x, double y) -> void;
- auto process_orbital_mouse_button(int button, int action, int mods) -> void;
- auto process_orbital_scroll(double x_offset, double y_offset) -> void;
-
- auto set_camera_mode(CameraMode mode) -> void { m_camera_mode = mode; }
- auto get_camera_mode() const -> CameraMode { return m_camera_mode; }
-
- auto is_dragging() const -> bool { return m_dragging; }
- auto is_panning() const -> bool { return m_panning; }
- auto is_moving() const -> bool { return m_moving; }
- auto get_last_x() const -> double { return m_last_x; }
- auto get_last_y() const -> double { return m_last_y; }
-
- private:
- auto recalculate_view_matrix() -> void;
- auto recalculate_projection_matrix() -> void;
-
- private:
- CameraMode m_camera_mode = CameraMode::FPS;
-
- glm::mat4 m_projection_matrix;
- glm::mat4 m_view_matrix;
- glm::mat4 m_view_projection_matrix;
-
- glm::vec3 m_position = { 0.0f, 0.0f, 3.0f };
- glm::vec3 m_rotation = { 0.0f, 0.0f, 0.0f };
-
- float m_fov = 45.0f;
- float m_aspect_ratio = 16.0f / 9.0f;
- float m_near_plane = 0.1f;
- float m_far_plane = 100.0f;
-
- float m_mouse_sensitivity = 0.1f;
- float m_movement_speed = 5.0f;
- bool m_first_mouse = true;
- float m_last_x = 0.0f;
- float m_last_y = 0.0f;
-
- glm::vec3 m_orbital_target = glm::vec3(0.0f, 0.0f, 0.0f);
- double m_orbital_radius = 6.34194e10;
- double m_orbital_min_radius = 1e10;
- double m_orbital_max_radius = 1e12;
- float m_azimuth = 0.0f;
- float m_elevation = static_cast<float>(std::numbers::pi) / 2.0f;
- float m_orbital_speed = 0.01f;
- double m_zoom_speed = 25e9f;
- bool m_dragging = false;
- bool m_panning = false;
- bool m_moving = false;
- double m_last_x_orbital = 0.0;
- double m_last_y_orbital = 0.0;
- };
-}
diff --git a/src/Core/Event.h b/src/Core/Event.h
deleted file mode 100644
index 1891206..0000000
--- a/src/Core/Event.h
+++ /dev/null
@@ -1,362 +0,0 @@
-#pragma once
-
-#include <functional>
-#include <unordered_map>
-#include <vector>
-#include <string>
-#include <sstream>
-
-namespace Donut
-{
- class Event;
- class EventDispatcher;
-
- enum class EventType
- {
- None = 0,
-
- WindowClose,
- WindowResize,
- WindowFocus,
- WindowLostFocus,
- WindowMoved,
-
- KeyPressed,
- KeyReleased,
- KeyTyped,
-
- MouseButtonPressed,
- MouseButtonReleased,
- MouseMoved,
- MouseScrolled
- };
-
- enum EventCategory
- {
- None = 0,
- EventCategoryApplication = 1 << 0,
- EventCategoryInput = 1 << 1,
- EventCategoryKeyboard = 1 << 2,
- EventCategoryMouse = 1 << 3,
- EventCategoryMouseButton = 1 << 4
- };
-
- class Event
- {
- public:
- virtual ~Event() = default;
-
- virtual auto get_event_type() const -> EventType = 0;
- virtual auto get_name() const -> const char* = 0;
- virtual auto get_category_flags() const -> int = 0;
- virtual auto to_string() const -> std::string { return get_name(); }
-
- auto is_in_category(EventCategory category) -> bool { return get_category_flags() & category; }
-
- bool handled = false;
- };
-
- #define EVENT_CLASS_TYPE(type) \
- static auto get_static_type() -> EventType { return EventType::type; } \
- virtual auto get_event_type() const -> EventType override { return get_static_type(); } \
- virtual auto get_name() const -> const char* override { return #type; }
-
- #define APPLICATION_EVENT_CLASS_TYPE(type) \
- EVENT_CLASS_TYPE(type) \
- virtual auto get_category_flags() const -> int override { return EventCategoryApplication; }
-
- #define MOUSE_EVENT_CLASS_TYPE(type) \
- EVENT_CLASS_TYPE(type) \
- virtual auto get_category_flags() const -> int override { return EventCategoryMouse | \
- EventCategoryInput; }
-
- #define MOUSE_BUTTON_EVENT_CLASS_TYPE(type) \
- EVENT_CLASS_TYPE(type) \
- virtual auto get_category_flags() const -> int override { return EventCategoryMouseButton | \
- EventCategoryMouse | \
- EventCategoryInput; }
-
- #define KEYBOARD_EVENT_CLASS_TYPE(type) \
- EVENT_CLASS_TYPE(type) \
- virtual auto get_category_flags() const -> int override { return EventCategoryKeyboard | \
- EventCategoryInput; }
-
- class WindowResizeEvent
- : public Event
- {
- public:
- WindowResizeEvent(unsigned int width, unsigned int height)
- : m_width(width), m_height(height) { }
-
- auto get_width() const -> unsigned int { return m_width; }
- auto get_height() const -> unsigned int { return m_height; }
-
- auto to_string() const -> std::string override
- {
- return "WindowResizeEvent: " + std::to_string(m_width) + ", " + std::to_string(m_height);
- }
-
- APPLICATION_EVENT_CLASS_TYPE(WindowResize)
-
- private:
- unsigned int m_width, m_height;
- };
-
- class WindowCloseEvent
- : public Event
- {
- public:
- WindowCloseEvent() = default;
- APPLICATION_EVENT_CLASS_TYPE(WindowClose)
- };
-
- class WindowFocusEvent
- : public Event
- {
- public:
- WindowFocusEvent() = default;
- APPLICATION_EVENT_CLASS_TYPE(WindowFocus)
- };
-
- class WindowLostFocusEvent
- : public Event
- {
- public:
- WindowLostFocusEvent() = default;
- APPLICATION_EVENT_CLASS_TYPE(WindowLostFocus)
- };
-
- class WindowMovedEvent
- : public Event
- {
- public:
- WindowMovedEvent(int x, int y)
- : m_x(x), m_y(y) { }
-
- auto get_x() const -> int { return m_x; }
- auto get_y() const -> int { return m_y; }
-
- auto to_string() const -> std::string override
- {
- return "WindowMovedEvent: " + std::to_string(m_x) + ", " + std::to_string(m_y);
- }
-
- APPLICATION_EVENT_CLASS_TYPE(WindowMoved)
-
- private:
- int m_x, m_y;
- };
-
- class KeyEvent
- : public Event
- {
- public:
- auto get_key_code() const -> int { return m_key_code; }
- virtual auto get_category_flags() const -> int override { return EventCategoryKeyboard |
- EventCategoryInput; }
-
- protected:
- KeyEvent(int keycode)
- : m_key_code(keycode) { }
- int m_key_code;
- };
-
- class KeyPressedEvent
- : public KeyEvent
- {
- public:
- KeyPressedEvent(int keycode, bool is_repeat = false)
- : KeyEvent(keycode), m_is_repeat(is_repeat) { }
-
- auto is_repeat() const -> bool { return m_is_repeat; }
-
- auto to_string() const -> std::string override
- {
- return "KeyPressedEvent: " + std::to_string(m_key_code) +
- " (repeat = " + std::to_string(m_is_repeat) + ")";
- }
-
- KEYBOARD_EVENT_CLASS_TYPE(KeyPressed)
-
- private:
- bool m_is_repeat;
- };
-
- class KeyReleasedEvent
- : public KeyEvent
- {
- public:
- KeyReleasedEvent(int keycode)
- : KeyEvent(keycode) { }
-
- auto to_string() const -> std::string override
- {
- return "KeyReleasedEvent: " + std::to_string(m_key_code);
- }
-
- KEYBOARD_EVENT_CLASS_TYPE(KeyReleased)
- };
-
- class KeyTypedEvent
- : public KeyEvent
- {
- public:
- KeyTypedEvent(int keycode)
- : KeyEvent(keycode) { }
-
- auto to_string() const -> std::string override
- {
- return "KeyTypedEvent: " + std::to_string(m_key_code);
- }
-
- KEYBOARD_EVENT_CLASS_TYPE(KeyTyped)
- };
-
- class MouseMovedEvent
- : public Event
- {
- public:
- MouseMovedEvent(float x, float y)
- : m_mouse_x(x), m_mouse_y(y) { }
-
- auto get_x() const -> float { return m_mouse_x; }
- auto get_y() const -> float { return m_mouse_y; }
-
- auto to_string() const -> std::string override
- {
- return "MouseMovedEvent: " + std::to_string(m_mouse_x) + ", " + std::to_string(m_mouse_y);
- }
-
- MOUSE_EVENT_CLASS_TYPE(MouseMoved)
-
- private:
- float m_mouse_x, m_mouse_y;
- };
-
- class MouseScrolledEvent
- : public Event
- {
- public:
- MouseScrolledEvent(float x_offset, float y_offset)
- : m_x_offset(x_offset), m_y_offset(y_offset) { }
-
- auto get_x_offset() const -> float { return m_x_offset; }
- auto get_y_offset() const -> float { return m_y_offset; }
-
- auto to_string() const -> std::string override
- {
- return "MouseScrolledEvent: " + std::to_string(m_x_offset) +
- ", " + std::to_string(m_y_offset);
- }
-
- MOUSE_EVENT_CLASS_TYPE(MouseScrolled)
-
- private:
- float m_x_offset, m_y_offset;
- };
-
- class MouseButtonEvent
- : public Event
- {
- public:
- auto get_mouse_button() const -> int { return m_button; }
- virtual auto get_category_flags() const -> int override { return EventCategoryMouseButton |
- EventCategoryMouse |
- EventCategoryInput; }
-
- protected:
- MouseButtonEvent(int button)
- : m_button(button) { }
- int m_button;
- };
-
- class MouseButtonPressedEvent
- : public MouseButtonEvent
- {
- public:
- MouseButtonPressedEvent(int button)
- : MouseButtonEvent(button) { }
-
- auto to_string() const -> std::string override
- {
- return "MouseButtonPressedEvent: " + std::to_string(m_button);
- }
-
- MOUSE_BUTTON_EVENT_CLASS_TYPE(MouseButtonPressed)
- };
-
- class MouseButtonReleasedEvent
- : public MouseButtonEvent
- {
- public:
- MouseButtonReleasedEvent(int button)
- : MouseButtonEvent(button) { }
-
- auto to_string() const -> std::string override
- {
- return "MouseButtonReleasedEvent: " + std::to_string(m_button);
- }
-
- MOUSE_BUTTON_EVENT_CLASS_TYPE(MouseButtonReleased)
- };
-
- class EventDispatcher
- {
- public:
- EventDispatcher(Event& event)
- : m_event(event) { }
-
- template<typename T, typename F>
- auto dispatch(const F& func) -> bool
- {
- if (m_event.get_event_type() == T::get_static_type())
- {
- m_event.handled = func(static_cast<T&>(m_event));
- return true;
- }
- return false;
- }
-
- private:
- Event& m_event;
- };
-
- class EventHandler
- {
- public:
- using EventCallbackFn = std::function<void(Event&)>;
-
- EventHandler() = default;
- ~EventHandler() = default;
-
- auto set_event_callback(const EventCallbackFn& callback) -> void
- {
- m_event_callback = callback;
- }
-
- auto on_event(Event& event) -> void
- {
- if (m_event_callback)
- m_event_callback(event);
- }
-
- template<typename T>
- auto bind_event(const std::function<void(T&)>& callback) -> void
- {
- m_event_callback = [callback](Event& event)
- {
- if (event.get_event_type() == T::get_static_type())
- callback(static_cast<T&>(event));
- };
- }
-
- private:
- EventCallbackFn m_event_callback;
- };
-
- #undef EVENT_CLASS_TYPE
- #undef APPLICATION_EVENT_CLASS_TYPE
- #undef MOUSE_EVENT_CLASS_TYPE
- #undef MOUSE_BUTTON_EVENT_CLASS_TYPE
- #undef KEYBOARD_EVENT_CLASS_TYPE
-}
diff --git a/src/Core/Log.cpp b/src/Core/Log.cpp
deleted file mode 100644
index 5a0434f..0000000
--- a/src/Core/Log.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-#include "log.h"
-
-#include <filesystem>
-
-#if defined(DONUT_WINDOWS)
- #include <windows.h>
-#endif
-
-namespace Donut
-{
- Ref<Logger> Logger::s_logger;
-
- auto Logger::init() -> void
- {
- s_logger = create_ref<Logger>();
- s_logger->set_log_level(LogLevel::Info);
- s_logger->enable_console_output(true);
- s_logger->enable_file_output(true);
- s_logger->set_log_file("logs/donut.log");
-
- s_logger->log_message(LogLevel::Info, "Logging system initialized");
- }
-
- auto Logger::shutdown() -> void
- {
- if (s_logger)
- s_logger->log_message(LogLevel::Info, "Shutting down logging system");
- s_logger.reset();
- }
-
- auto Logger::get_logger() -> Ref<Logger>
- {
- return s_logger;
- }
-
- Logger::Logger()
- : m_log_level(LogLevel::Info),
- m_console_output(true),
- m_file_output(false) { }
-
- Logger::~Logger()
- {
- if (m_log_file.is_open())
- m_log_file.close();
- }
-
- auto Logger::set_log_file(const std::string& filename) -> void
- {
- std::filesystem::path log_path(filename);
- std::filesystem::create_directories(log_path.parent_path());
-
- m_log_file.open(filename, std::ios::app);
- if (!m_log_file.is_open())
- std::cerr << "Failed to open log file: " << filename << std::endl;
- }
-
- auto Logger::get_time_stamp() -> std::string
- {
- auto now = std::chrono::system_clock::now();
- auto time = std::chrono::system_clock::to_time_t(now);
-
- std::stringstream ss;
- ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S");
-
- return ss.str();
- }
-
- auto Logger::get_log_level_string(LogLevel level) -> std::string
- {
- switch (level)
- {
- case LogLevel::trace: return "TRACE";
- case LogLevel::Info: return "INFO";
- case LogLevel::Warn: return "WARN";
- case LogLevel::Err: return "ERROR";
- case LogLevel::Fatal: return "FATAL";
- default: return "UNKNOWN";
- }
- }
-
- auto Logger::set_console_color(LogLevel level) -> void
- {
-#if defined(DONUT_WINDOWS)
- HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
- WORD color;
-
- switch (level) {
- case LogLevel::trace:
- color = FOREGROUND_RED |
- FOREGROUND_GREEN |
- FOREGROUND_BLUE;
- break;
- case LogLevel::Info:
- color = FOREGROUND_GREEN |
- FOREGROUND_INTENSITY;
- break;
- case LogLevel::Warn:
- color = FOREGROUND_RED |
- FOREGROUND_GREEN |
- FOREGROUND_INTENSITY;
- break;
- case LogLevel::Err:
- color = FOREGROUND_RED |
- FOREGROUND_INTENSITY;
- break;
- case LogLevel::Fatal:
- color = FOREGROUND_RED |
- FOREGROUND_BLUE |
- FOREGROUND_INTENSITY;
- break;
- default:
- color = FOREGROUND_RED |
- FOREGROUND_GREEN |
- FOREGROUND_BLUE;
- break;
- }
-
- SetConsoleTextAttribute(h_console, color);
-#else
- const char* color_code;
- switch (level) {
- case LogLevel::trace:
- color_code = "\033[37m";
- break;
- case LogLevel::Info:
- color_code = "\033[32;1m";
- break;
- case LogLevel::Warn:
- color_code = "\033[33;1m";
- break;
- case LogLevel::Err:
- color_code = "\033[31;1m";
- break;
- case LogLevel::Fatal:
- color_code = "\033[35;1m";
- break;
- default:
- color_code = "\033[37m";
- break;
- }
- std::cout << color_code;
-#endif
- }
-
- auto Logger::reset_console_color() -> void
- {
-#if defined(DONUT_WINDOWS)
- HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
- SetConsoleTextAttribute(h_console, FOREGROUND_RED |
- FOREGROUND_GREEN |
- FOREGROUND_BLUE);
-#else
- std::cout << "\033[0m";
-#endif
- }
-}
diff --git a/src/Core/Log.h b/src/Core/Log.h
deleted file mode 100644
index db6b4b4..0000000
--- a/src/Core/Log.h
+++ /dev/null
@@ -1,156 +0,0 @@
-#pragma once
-
-#include "core/memory.h"
-
-#include <string>
-#include <vector>
-#include <sstream>
-#include <iostream>
-#include <fstream>
-#include <chrono>
-#include <iomanip>
-#include <mutex>
-#include <string_view>
-
-namespace Donut
-{
- enum class LogLevel
- {
- trace = 0,
- Info = 2,
- Warn = 3,
- Err = 4,
- Fatal = 5
- };
-
- class Logger
- {
- public:
- Logger();
- ~Logger();
-
- static auto init() -> void;
- static auto shutdown() -> void;
-
- static auto get_logger() -> Ref<Logger>;
-
- template<typename... Args>
- static auto trace(const std::string_view& format, const Args&... args) -> void
- {
- auto logger = get_logger();
- if (logger) logger->log_message(LogLevel::trace, format, args...);
- }
-
- template<typename... Args>
- static auto info(const std::string_view& format, const Args&... args) -> void
- {
- auto logger = get_logger();
- if (logger) logger->log_message(LogLevel::Info, format, args...);
- }
-
- template<typename... Args>
- static auto warn(const std::string_view& format, const Args&... args) -> void
- {
- auto logger = get_logger();
- if (logger) logger->log_message(LogLevel::Warn, format, args...);
- }
-
- template<typename... Args>
- static auto error(const std::string_view& format, const Args&... args) -> void
- {
- auto logger = get_logger();
- if (logger) logger->log_message(LogLevel::Err, format, args...);
- }
-
- template<typename... Args>
- static auto fatal(const std::string_view& format, const Args&... args) -> void
- {
- auto logger = get_logger();
- if (logger) logger->log_message(LogLevel::Fatal, format, args...);
- }
-
- template<typename... Args>
- auto log_message(LogLevel level, const std::string_view& format, const Args&... args) -> void
- {
- if (level < m_log_level)
- return;
-
- std::lock_guard<std::mutex> lock(m_mutex);
- std::string message = format_string(format, args...);
- std::string full_message = get_time_stamp() + " [" + get_log_level_string(level) + "] " + message;
-
- if (m_console_output)
- {
- set_console_color(level);
- std::cout << full_message << std::endl;
- reset_console_color();
- }
-
- if (m_file_output && m_log_file.is_open())
- {
- m_log_file << full_message << std::endl;
- m_log_file.flush();
- }
- }
-
- template<typename... Args>
- auto format_string(const std::string_view& format, const Args&... args) -> std::string
- {
- std::string result = format.data();
- std::vector<std::string> arg_strings = { to_string(args)... };
-
- size_t arg_index = 0;
- size_t pos = 0;
-
- while ((pos = result.find("{}", pos)) != std::string::npos && arg_index < arg_strings.size())
- {
- result.replace(pos, 2, arg_strings[arg_index]);
- pos += arg_strings[arg_index].length();
- arg_index++;
- }
-
- return result;
- }
-
- template<typename T>
- auto to_string(const T& value) -> std::string
- {
- std::stringstream ss;
- ss << value;
- return ss.str();
- }
-
- auto set_log_level(LogLevel level) -> void { m_log_level = level; }
- auto enable_console_output(bool enable) -> void { m_console_output = enable; }
- auto enable_file_output(bool enable) -> void { m_file_output = enable; }
- auto set_log_file(const std::string& filename) -> void;
-
- auto get_time_stamp() -> std::string;
- auto get_log_level_string(LogLevel level) -> std::string;
- auto set_console_color(LogLevel level) -> void;
- auto reset_console_color() -> void;
-
- private:
- LogLevel m_log_level;
- bool m_console_output;
- bool m_file_output;
- std::ofstream m_log_file;
- std::mutex m_mutex;
-
- static Ref<Logger> s_logger;
- };
-}
-
-#if defined(DONUT_DEBUG)
- #define DONUT_TRACE(format, ...) ::Donut::Logger::trace(format, ##__VA_ARGS__)
- #define DONUT_INFO(format, ...) ::Donut::Logger::info(format, ##__VA_ARGS__)
- #define DONUT_WARN(format, ...) ::Donut::Logger::warn(format, ##__VA_ARGS__)
- #define DONUT_ERROR(format, ...) ::Donut::Logger::error(format, ##__VA_ARGS__)
- #define DONUT_FATAL(format, ...) ::Donut::Logger::fatal(format, ##__VA_ARGS__)
-#else
- #define DONUT_TRACE(format, ...) {}
- #define DONUT_INFO(format, ...) {}
- #define DONUT_WARN(format, ...) {}
- #define DONUT_ERROR(format, ...) {}
- #define DONUT_FATAL(format, ...) {}
-#endif
diff --git a/src/Core/Memory.h b/src/Core/Memory.h
deleted file mode 100644
index 3240c71..0000000
--- a/src/Core/Memory.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <memory>
-
-namespace Donut
-{
- template<typename T>
- using Ref = std::shared_ptr<T>;
-
- template<typename T>
- using Scope = std::unique_ptr<T>;
-
- template<typename T, typename ... Args>
- constexpr auto create_scope(Args&& ... args) -> Scope<T>
- {
- return std::make_unique<T>(std::forward<Args>(args)...);
- }
-
- template<typename T, typename ... Args>
- constexpr auto create_ref(Args&& ... args) -> Ref<T>
- {
- return std::make_shared<T>(std::forward<Args>(args)...);
- }
-};
diff --git a/src/Core/State.h b/src/Core/State.h
deleted file mode 100644
index 623f1c2..0000000
--- a/src/Core/State.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-
-#include "event.h"
-
-namespace Donut
-{
- class State
- {
- public:
- virtual ~State() = default;
-
- virtual auto on_enter() -> void = 0;
- virtual auto on_exit() -> void = 0;
- virtual auto on_update(float delta_time) -> void = 0;
- virtual auto on_render() -> void = 0;
- virtual auto on_im_ui_render() -> void = 0;
- virtual auto on_event(Event& event) -> void = 0;
- };
-};
diff --git a/src/Core/Window.cpp b/src/Core/Window.cpp
deleted file mode 100644
index 047ef0d..0000000
--- a/src/Core/Window.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-#include <glad/glad.h>
-#include "window.h"
-#include "theme_manager.h"
-#include "rendering/renderer.h" // RendererAPI::get_api()
-
-#include <cstdint>
-
-#include <imgui.h>
-#include <imgui_impl_glfw.h>
-#include <imgui_impl_opengl3.h>
-
-namespace Donut
-{
- static bool s_glfw_initialized = false;
- static uint32_t s_glfw_window_count = 0;
-
- Window::Window(const std::string& title, int width, int height)
- : m_title(title), m_width(width),
- m_height(height), m_is_closed(false)
- {
- init();
- }
-
- Window::~Window()
- {
- shutdown();
- }
-
- auto Window::init() -> void
- {
- DONUT_INFO("Initializing window: ", m_title, " (", m_width, "x", m_height, ")");
-
- if (!s_glfw_initialized)
- {
- int success = glfwInit();
- if (!success)
- {
- DONUT_ERROR("Could not initialize GLFW!");
- return;
- }
-
- s_glfw_initialized = true;
- DONUT_INFO("GLFW initialized successfully");
- }
-
- if (RendererAPI::get_api() == RendererAPI::API::Vulkan)
- {
- // Vulkan manages presentation itself; GLFW must not create a GL context.
- glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
- }
- else
- {
-#ifdef __APPLE__
- // macOS only exposes OpenGL up to 4.1 Core Profile, and requires a
- // forward-compatible core-profile context for any modern (>= 3.3)
- // shader to compile. Without these hints GLFW hands back a legacy
- // 2.1 context and every GLSL shader in the project fails to build.
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
-#endif
- }
-
- m_window = glfwCreateWindow(m_width, m_height, m_title.c_str(), nullptr, nullptr);
- if (!m_window)
- {
- DONUT_ERROR("Could not create GLFW window!");
- glfwTerminate();
- return;
- }
-
- DONUT_INFO("GLFW window created successfully");
-
- if (RendererAPI::get_api() != RendererAPI::API::Vulkan)
- glfwMakeContextCurrent(m_window);
- glfwSetWindowUserPointer(m_window, this);
-
- glfwSetErrorCallback(glfw_error_callback);
- glfwSetWindowCloseCallback(m_window, glfw_window_close_callback);
- glfwSetWindowSizeCallback(m_window, glfw_window_size_callback);
- glfwSetWindowFocusCallback(m_window, glfw_window_focus_callback);
- glfwSetWindowPosCallback(m_window, glfw_window_pos_callback);
- glfwSetKeyCallback(m_window, glfw_key_callback);
- glfwSetCharCallback(m_window, glfw_char_callback);
- glfwSetMouseButtonCallback(m_window, glfw_mouse_button_callback);
- glfwSetScrollCallback(m_window, glfw_mouse_scroll_callback);
- glfwSetCursorPosCallback(m_window, glfw_cursor_pos_callback);
-
- s_glfw_window_count++;
- }
-
- auto Window::shutdown() -> void
- {
- DONUT_INFO("Shutting down window: ", m_title);
-
- shutdown_im_gui();
-
- glfwDestroyWindow(m_window);
- s_glfw_window_count--;
-
- if (s_glfw_window_count == 0)
- {
- glfwTerminate();
- s_glfw_initialized = false;
- DONUT_INFO("GLFW terminated (no more windows)");
- }
- }
-
- auto Window::on_update() const -> void
- {
- glfwPollEvents();
- if (RendererAPI::get_api() != RendererAPI::API::Vulkan)
- glfwSwapBuffers(m_window); // Vulkan presents via the swapchain instead
- }
-
- auto Window::should_close() const -> bool
- {
- return glfwWindowShouldClose(m_window) || m_is_closed;
- }
-
- auto Window::set_cursor_locked(bool locked) -> void
- {
- m_cursor_locked = locked;
- glfwSetInputMode(m_window, GLFW_CURSOR, locked ?
- GLFW_CURSOR_DISABLED : GLFW_CURSOR_NORMAL);
- }
-
- auto Window::set_cursor_visible(bool visible) -> void
- {
- m_cursor_visible = visible;
- glfwSetInputMode(m_window, GLFW_CURSOR, visible ?
- GLFW_CURSOR_NORMAL : GLFW_CURSOR_HIDDEN);
- }
-
- auto Window::init_im_gui() -> void
- {
- IMGUI_CHECKVERSION();
- ImGui::CreateContext();
- ImGuiIO& io = ImGui::GetIO();
- io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
- io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
-#ifndef __APPLE__
- // Multi-viewport (dragging ImGui panels out as separate OS windows)
- // relies on a populated platform-monitor list and is unreliable on
- // macOS, where it intermittently asserts (Monitors.Size > 0) and
- // aborts. Docking stays enabled; panels just remain inside the window.
- io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
-#endif
-
- setup_im_gui_fonts();
- ThemeManager::set_theme(Theme::Dark);
-
- ImGuiStyle& style = ImGui::GetStyle();
- if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
- {
- style.WindowRounding = 0.0f;
- style.Colors[ImGuiCol_WindowBg].w = 1.0f;
- }
-
- ImGui_ImplGlfw_InitForOpenGL(m_window, true);
-#ifdef __APPLE__
- // macOS uses a core-profile context, which rejects the legacy
- // "#version 130" GLSL the ImGui backend defaults to. 150 is the
- // minimum core-profile GLSL that macOS's OpenGL 4.1 accepts.
- ImGui_ImplOpenGL3_Init("#version 150");
-#else
- ImGui_ImplOpenGL3_Init("#version 130");
-#endif
-
- DONUT_INFO("ImGUI initialized successfully");
- }
-
- auto Window::setup_im_gui_fonts() -> void
- {
- ImGuiIO& io = ImGui::GetIO();
- io.Fonts->Clear();
-
- m_main_font = io.Fonts->AddFontFromFileTTF("assets/fonts/inter/static/Inter_18pt-Regular.ttf", 16.0f);
- if (!m_main_font)
- {
- DONUT_WARN("Failed to load Inter font, falling back to default");
- m_main_font = io.Fonts->AddFontDefault();
- }
- else
- DONUT_INFO("Successfully loaded Inter font");
-
- m_large_font = io.Fonts->AddFontFromFileTTF("assets/fonts/inter/static/Inter_18pt-Bold.ttf", 20.0f);
- if (!m_large_font)
- m_large_font = m_main_font;
-
- m_small_font = io.Fonts->AddFontFromFileTTF("assets/fonts/inter/static/Inter_18pt-Light.ttf", 12.0f);
- if (!m_small_font)
- m_small_font = m_main_font;
-
- io.FontDefault = m_main_font;
- DONUT_INFO("ImGUI fonts loaded successfully");
- }
-
- auto Window::shutdown_im_gui() -> void
- {
- ImGui_ImplOpenGL3_Shutdown();
- ImGui_ImplGlfw_Shutdown();
- ImGui::DestroyContext();
-
- DONUT_INFO("ImGUI shutdown");
- }
-
- auto Window::begin_im_gui_frame() -> void
- {
- ImGui_ImplOpenGL3_NewFrame();
- ImGui_ImplGlfw_NewFrame();
- ImGui::NewFrame();
- }
-
- auto Window::end_im_gui_frame() -> void
- {
- ImGui::Render();
- ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
-
- ImGuiIO& io = ImGui::GetIO();
- if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
- {
- GLFWwindow* backup_current_context = glfwGetCurrentContext();
- ImGui::UpdatePlatformWindows();
- ImGui::RenderPlatformWindowsDefault();
- glfwMakeContextCurrent(backup_current_context);
- }
- }
-
- auto Window::glfw_error_callback(int error, const char* description) -> void
- {
- DONUT_ERROR("GLFW Error ({}): {}", error, description ? description : "");
- }
-
- auto Window::glfw_window_close_callback(GLFWwindow* window) -> void
- {
- Window* win = static_cast<Window*>(glfwGetWindowUserPointer(window));
- WindowCloseEvent event;
- win->m_event_handler.on_event(event);
- }
-
- auto Window::glfw_window_size_callback(GLFWwindow* window, int width, int height) -> void
- {
- Window* win = static_cast<Window*>(glfwGetWindowUserPointer(window));
- win->m_width = width;
- win->m_height = height;
-
- WindowResizeEvent event(width, height);
- win->m_event_handler.on_event(event);
- }
-
- auto Window::glfw_window_focus_callback(GLFWwindow* window, int focused) -> void
- {
- Window* win = static_cast<Window*>(glfwGetWindowUserPointer(window));
-
- if (focused)
- {
- WindowFocusEvent event;
- win->m_event_handler.on_event(event);
- }
- else
- {
- WindowLostFocusEvent event;
- win->m_event_handler.on_event(event);
- }
- }
-
- auto Window::glfw_window_pos_callback(GLFWwindow* window, int xpos, int ypos) -> void
- {
- Window* win = static_cast<Window*>(glfwGetWindowUserPointer(window));
- WindowMovedEvent event(xpos, ypos);
- win->m_event_handler.on_event(event);
- }
-
- auto Window::glfw_key_callback(GLFWwindow* window, int key, int scancode,
- int action, int mods) -> void
- {
- Window* win = static_cast<Window*>(glfwGetWindowUserPointer(window));
-
- switch (action)
- {
- case GLFW_PRESS:
- {
- KeyPressedEvent event(key, false);
- win->m_event_handler.on_event(event);
- } break;
- case GLFW_RELEASE:
- {
- KeyReleasedEvent event(key);
- win->m_event_handler.on_event(event);
- } break;
- case GLFW_REPEAT:
- {
- KeyPressedEvent event(key, true);
- win->m_event_handler.on_event(event);
- } break;
- }
- }
-
- auto Window::glfw_char_callback(GLFWwindow* window, unsigned int keycode) -> void
- {
- Window* win = static_cast<Window*>(glfwGetWindowUserPointer(window));
- KeyTypedEvent event(keycode);
- win->m_event_handler.on_event(event);
- }
-
- auto Window::glfw_mouse_button_callback(GLFWwindow* window, int button,
- int action, int mods) -> void
- {
- Window* win = static_cast<Window*>(glfwGetWindowUserPointer(window));
-
- switch (action)
- {
- case GLFW_PRESS:
- {
- MouseButtonPressedEvent event(button);
- win->m_event_handler.on_event(event);
- } break;
- case GLFW_RELEASE:
- {
- MouseButtonReleasedEvent event(button);
- win->m_event_handler.on_event(event);
- } break;
- }
- }
-
- auto Window::glfw_mouse_scroll_callback(GLFWwindow* window, double x_offset, double y_offset) -> void
- {
- Window* win = static_cast<Window*>(glfwGetWindowUserPointer(window));
- MouseScrolledEvent event((float)x_offset, (float)y_offset);
- win->m_event_handler.on_event(event);
- }
-
- auto Window::glfw_cursor_pos_callback(GLFWwindow* window, double x_pos, double y_pos) -> void
- {
- Window* win = static_cast<Window*>(glfwGetWindowUserPointer(window));
- MouseMovedEvent event((float)x_pos, (float)y_pos);
- win->m_event_handler.on_event(event);
- }
-}
diff --git a/src/Core/Window.h b/src/Core/Window.h
deleted file mode 100644
index 9b7d7b9..0000000
--- a/src/Core/Window.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#pragma once
-
-#include "event.h"
-#include "log.h"
-
-#include <GLFW/glfw3.h>
-#include <imgui.h>
-
-#include <string>
-
-namespace Donut
-{
- class Window
- {
- public:
- using EventCallbackFn = std::function<void(Event&)>;
-
- Window(const std::string& title, int width, int height);
- ~Window();
-
- auto should_close() const -> bool;
- auto on_update() const -> void;
-
- auto set_event_callback(const EventCallbackFn& callback) -> void
- {
- m_event_handler.set_event_callback(callback);
- }
-
- auto get_event_handler() -> EventHandler& { return m_event_handler; }
-
- auto get_width() const -> unsigned int { return m_width; }
- auto get_height() const -> unsigned int { return m_height; }
-
- auto get_native_window() const -> void* { return m_window; }
-
- auto set_cursor_locked(bool locked) -> void;
- auto set_cursor_visible(bool visible) -> void;
- auto is_cursor_locked() const -> bool { return m_cursor_locked; }
- auto is_cursor_visible() const -> bool { return m_cursor_visible; }
-
- auto init_im_gui() -> void;
- auto begin_im_gui_frame() -> void;
- auto end_im_gui_frame() -> void;
-
- private:
- auto init() -> void;
- auto shutdown() -> void;
-
- auto setup_im_gui_fonts() -> void;
- auto shutdown_im_gui() -> void;
-
- static auto glfw_error_callback(int error, const char* description) -> void;
- static auto glfw_window_close_callback(GLFWwindow* window) -> void;
- static auto glfw_window_size_callback(GLFWwindow* window, int width, int height) -> void;
- static auto glfw_window_focus_callback(GLFWwindow* window, int focused) -> void;
- static auto glfw_window_pos_callback(GLFWwindow* window, int xpos, int ypos) -> void;
- static auto glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -> void;
- static auto glfw_char_callback(GLFWwindow* window, unsigned int keycode) -> void;
- static auto glfw_mouse_button_callback(GLFWwindow* window, int button, int action, int mods) -> void;
- static auto glfw_mouse_scroll_callback(GLFWwindow* window, double x_offset, double y_offset) -> void;
- static auto glfw_cursor_pos_callback(GLFWwindow* window, double x_pos, double y_pos) -> void;
-
- private:
- GLFWwindow* m_window;
- EventHandler m_event_handler;
-
- std::string m_title;
- unsigned int m_width;
- unsigned int m_height;
- bool m_is_closed;
- bool m_cursor_locked = false;
- bool m_cursor_visible = true;
-
- ImFont* m_main_font = nullptr;
- ImFont* m_small_font = nullptr;
- ImFont* m_large_font = nullptr;
- };
-}
diff --git a/src/Engine/Engine.cpp b/src/Engine/Engine.cpp
deleted file mode 100644
index 059fdda..0000000
--- a/src/Engine/Engine.cpp
+++ /dev/null
@@ -1,614 +0,0 @@
-#include <iostream>
-#include <fstream>
-#include <sstream>
-
-#include <GLFW/glfw3.h>
-#include <glad/glad.h>
-
-#define STB_IMAGE_WRITE_IMPLEMENTATION
-#include "stb_image_write.h"
-
-#include "engine.h"
-#include "core/log.h"
-#include "core/hdri_manager.h"
-#include "rendering/vertex_buffer.h"
-#include "rendering/index_buffer.h"
-
-namespace Donut
-{
- Engine::Engine()
- : m_sag_a(glm::vec3(0.0f, 0.0f, 0.0f), 8.54e36f)
- {
- m_width = 1280;
- m_height = 720;
-
- m_camera.set_camera_mode(CameraMode::Orbital);
- m_camera.set_orbital_radius(1e11);
- m_camera.set_orbital_limits(1e9, 1e13);
- m_camera.set_orbital_speed(0.01f);
- m_camera.set_zoom_speed(1e10f);
-
- m_objects =
- {
- { glm::vec4(0.00f, 0.00f, 0.00f, m_sag_a.m_rs), glm::vec4(0, 0, 0, 1), static_cast<float>(m_sag_a.m_mass) }
- };
-
- // The geodesic ray tracer used to be a compute shader; it is now a
- // fullscreen vertex+fragment pass (see dispatch_compute) so it runs on
- // macOS OpenGL 4.1, which has no compute shaders.
- m_compute_program = Ref<Shader>(Shader::create("assets/shaders/Geodesic.glsl"));
- m_shader_program = Ref<Shader>(Shader::create("assets/shaders/TexturedQuad.glsl"));
- m_blur_shader = Ref<Shader>(Shader::create("assets/shaders/Blur.glsl"));
-
- auto& hdri_manager = HDRIManager::get();
- m_hdri_environment = hdri_manager.get_current_hdri();
- if (!m_hdri_environment)
- {
- hdri_manager.set_current_hdri("assets/hdri/HDR_blue_nebulae-1.hdr");
- m_hdri_environment = hdri_manager.get_current_hdri();
- if (!m_hdri_environment)
- DONUT_WARN("Failed to load default HDRI, using fallback");
- }
-
- m_camera_ubo = UniformBuffer::create(128, 1);
- m_disk_ubo = UniformBuffer::create(sizeof(float) * 5, 2);
-
- uint32_t obj_ubo_size = sizeof(int) + 3 * sizeof(float)
- + 16 * (sizeof(glm::vec4) + sizeof(glm::vec4))
- + 16 * sizeof(float);
- m_objects_ubo = UniformBuffer::create(obj_ubo_size, 3);
-
- m_simulation_ubo = UniformBuffer::create(sizeof(int) * 2 + sizeof(float) * 2, 4);
-
- auto result = QuadVAO();
- m_quad_vao = result.first;
- m_texture = result.second;
-
- // GLSL 4.10 forbids explicit binding qualifiers on uniform blocks, so
- // associate the geodesic shader's blocks with their UBO binding points
- // from the host side instead.
- if (m_compute_program)
- {
- uint32_t prog = m_compute_program->get_renderer_id();
- struct { const char* name; uint32_t point; } blocks[] =
- {
- { "Camera", 1 }, { "Disk", 2 }, { "Objects", 3 }, { "Simulation", 4 }
- };
- for (const auto& b : blocks)
- {
- uint32_t idx = glGetUniformBlockIndex(prog, b.name);
- if (idx != GL_INVALID_INDEX)
- glUniformBlockBinding(prog, idx, b.point);
- }
- }
-
- glGenFramebuffers(1, &m_geodesic_fbo);
- }
-
- auto Engine::update_window_dimensions() -> void
- {
- update_compute_dimensions();
- }
-
- auto Engine::set_window_dimensions(int width, int height) -> void
- {
- int old_width = m_width;
- int old_height = m_height;
- int old_compute_height = m_compute_height;
-
- m_width = width;
- m_height = height;
-
- if (old_width != m_width ||
- old_height != m_height ||
- old_compute_height != m_compute_height)
- update_compute_dimensions();
- }
-
- auto Engine::update_performance(float delta_time) -> void
- {
- if (delta_time > 0.0f)
- m_current_fps = 1.0f / delta_time;
- }
-
- auto Engine::update_compute_dimensions() -> void
- {
- m_texture = Texture2D::create(get_compute_width(), m_compute_height);
- }
-
- auto Engine::draw_full_screen_quad() -> void
- {
- RenderCommand::set_viewport(0, 0, m_width, m_height);
-
- m_shader_program->bind();
- m_quad_vao->bind();
-
- m_texture->bind(0);
- m_shader_program->set_int("u_ScreenTexture", 0);
-
- RenderCommand::disable_depth_test();
- RenderCommand::draw_arrays(6);
- RenderCommand::enable_depth_test();
- }
-
- auto Engine::draw_blur_pass() -> void
- {
- RenderCommand::set_viewport(0, 0, m_width, m_height);
-
- m_blur_shader->bind();
- m_quad_vao->bind();
-
- m_texture->bind(0);
- m_blur_shader->set_int("u_ScreenTexture", 0);
- m_blur_shader->set_float2("u_Resolution", glm::vec2(m_width, m_height));
- m_blur_shader->set_float("u_BlurStrength", m_blur_strength);
- m_blur_shader->set_float("u_GlowIntensity", m_glow_intensity);
-
- RenderCommand::disable_depth_test();
- RenderCommand::draw_arrays(6);
- RenderCommand::enable_depth_test();
- }
-
- auto Engine::draw_geodesic_pass(int cw, int ch) -> void
- {
- m_quad_vao->bind();
- RenderCommand::disable_depth_test();
-
-#ifdef __APPLE__
- // macOS aborts any GPU submission that runs longer than a couple of
- // seconds ("GPU Hang"). The geodesic ray-marcher can far exceed that in
- // a single fullscreen draw, so render it in scissored tiles and flush
- // after each, keeping every submission short enough to survive the
- // watchdog. Compute-capable platforms draw it in one pass.
- // Largest tile that keeps a tile's worst-case work (tile^2 * step_cap)
- // inside the safe watchdog zone measured on this GPU (~25M pixel-steps
- // per submission); bigger tiles mean fewer glFinish stalls.
- const int tile = 64;
- glEnable(GL_SCISSOR_TEST);
- for (int y = 0; y < ch; y += tile)
- {
- int th = std::min(tile, ch - y);
- for (int x = 0; x < cw; x += tile)
- {
- int tw = std::min(tile, cw - x);
- glScissor(x, y, tw, th);
- RenderCommand::draw_arrays(6);
- glFinish();
- }
- }
- glDisable(GL_SCISSOR_TEST);
-#else
- RenderCommand::draw_arrays(6);
-#endif
-
- RenderCommand::enable_depth_test();
- }
-
- auto Engine::dispatch_compute(const Camera& cam) -> void
- {
- auto& hdri_manager = HDRIManager::get();
- m_hdri_environment = hdri_manager.get_current_hdri();
-
- int cw = get_compute_width();
- int ch = m_compute_height;
-
- // Render the geodesic pass into m_texture through an FBO. This replaces
- // the old compute dispatch + image_store path, which relied on OpenGL
- // 4.3 compute and 4.2 image load/store that macOS does not provide.
- glBindFramebuffer(GL_FRAMEBUFFER, m_geodesic_fbo);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->get_renderer_id(), 0);
- glViewport(0, 0, cw, ch);
-
- m_compute_program->bind();
- upload_camera_ubo(cam);
- upload_disk_ubo();
- upload_objects_ubo(m_objects);
- upload_simulation_ubo();
- m_compute_program->set_float2("u_Resolution", glm::vec2(static_cast<float>(cw), static_cast<float>(ch)));
-
- if (m_hdri_environment)
- {
- m_hdri_environment->bind(5);
- m_compute_program->set_int("u_HDRIEnvironment", 5);
- }
-
- draw_geodesic_pass(cw, ch);
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
-
- auto Engine::upload_camera_ubo(const Camera& cam) -> void
- {
- struct UBOData
- {
- glm::vec3 pos; float _pad0;
- glm::vec3 right; float _pad1;
- glm::vec3 up; float _pad2;
- glm::vec3 forward; float _pad3;
- float tan_half_fov;
- float aspect;
- bool moving;
- int _pad4;
- } data;
-
- glm::vec3 fwd = glm::normalize(cam.get_orbital_target() - cam.get_orbital_position());
- glm::vec3 up = glm::vec3(0, 1, 0);
- glm::vec3 right = glm::normalize(glm::cross(fwd, up));
- up = glm::cross(right, fwd);
-
- data.pos = cam.get_orbital_position();
- data.right = right;
- data.up = up;
- data.forward = fwd;
- data.tan_half_fov = static_cast<float>(tan(glm::radians(60.0f * 0.5f)));
- data.aspect = static_cast<float>(get_compute_width()) / static_cast<float>(m_compute_height);
- data.moving = cam.is_dragging() || cam.is_panning();
-
- m_camera_ubo->set_data(&data, sizeof(UBOData));
- m_camera_ubo->bind(1);
- }
-
- auto Engine::upload_objects_ubo(const std::vector<ObjectData>& objs) -> void
- {
- struct UBOData
- {
- int num_objects;
- float _pad0, _pad1, _pad2;
- glm::vec4 pos_radius[16];
- glm::vec4 color[16];
- float mass[16];
- } data;
-
- size_t count = std::min(objs.size(), size_t(16));
- data.num_objects = static_cast<int>(count);
-
- for (size_t i = 0; i < count; ++i)
- {
- data.pos_radius[i] = objs[i].m_pos_radius;
- data.color[i] = objs[i].m_color;
- data.mass[i] = objs[i].m_mass;
- }
-
- m_objects_ubo->set_data(&data, sizeof(data));
- m_objects_ubo->bind(3);
- }
-
- auto Engine::upload_disk_ubo() -> void
- {
- float r1 = static_cast<float>(m_sag_a.m_rs * 2.2);
- float r2 = static_cast<float>(m_sag_a.m_rs * 5.2);
- float num = 2.0f;
- float thickness = static_cast<float>(m_sag_a.m_rs * m_disk_thickness);
- float disk_data[5] = { r1, r2, num, thickness, m_disk_density };
-
- m_disk_ubo->set_data(disk_data, sizeof(disk_data));
- m_disk_ubo->bind(2);
- }
-
- auto Engine::upload_simulation_ubo() -> void
- {
- struct UBOData
- {
- int max_steps_moving;
- int max_steps_static;
- float early_exit_distance;
- float time;
- } data;
-
- data.max_steps_moving = m_max_steps_moving;
- data.max_steps_static = m_max_steps_static;
- data.early_exit_distance = m_early_exit_distance;
- data.time = static_cast<float>(glfwGetTime()) * m_rotation_speed;
-
-#ifdef __APPLE__
- // macOS has no compute shaders, so the geodesic pass runs as a tiled
- // fragment shader under the OS GPU watchdog. The stock step counts
- // (up to 30000) make a single tile exceed the watchdog and hang the
- // GPU, so cap them here. Windows/Linux keep the full step count.
- // While the camera moves, render cheaply so interaction stays smooth;
- // when it settles, spend more steps for a cleaner image. Both stay well
- // under the per-tile GPU-watchdog budget (see draw_geodesic_pass).
- data.max_steps_moving = std::min(data.max_steps_moving, 4000);
- data.max_steps_static = std::min(data.max_steps_static, 6000);
-#endif
-
- m_simulation_ubo->set_data(&data, sizeof(data));
- m_simulation_ubo->bind(4);
- }
-
- auto Engine::update_physics(float delta_time) -> void
- {
- for (auto& obj : m_objects)
- {
- for (auto& obj2 : m_objects)
- {
- if (&obj == &obj2) continue;
- float dx = obj2.m_pos_radius.x - obj.m_pos_radius.x;
- float dy = obj2.m_pos_radius.y - obj.m_pos_radius.y;
- float dz = obj2.m_pos_radius.z - obj.m_pos_radius.z;
- float distance = sqrt(dx * dx + dy * dy + dz * dz);
- if (distance > 0)
- {
- std::vector<double> direction = {dx / distance, dy / distance, dz / distance};
- double Gforce = (G * obj.m_mass * obj2.m_mass) / (distance * distance);
- double acc1 = Gforce / obj.m_mass;
- std::vector<double> acc = {direction[0] * acc1, direction[1] * acc1, direction[2] * acc1};
-
- if (m_gravity)
- {
- obj.m_velocity.x += static_cast<float>(acc[0]);
- obj.m_velocity.y += static_cast<float>(acc[1]);
- obj.m_velocity.z += static_cast<float>(acc[2]);
-
- obj.m_pos_radius.x += static_cast<float>(obj.m_velocity.x);
- obj.m_pos_radius.y += static_cast<float>(obj.m_velocity.y);
- obj.m_pos_radius.z += static_cast<float>(obj.m_velocity.z);
- }
- }
- }
- }
- }
-
- auto Engine::render_scene() -> void
- {
- RenderCommand::clear();
- m_shader_program->bind();
- m_quad_vao->bind();
- m_texture->bind(0);
- RenderCommand::draw_arrays(6);
- }
-
- auto Engine::create_compute_program(const char* path) -> Ref<Shader>
- {
- std::ifstream in(path);
- if(!in.is_open())
- {
- std::cerr << "Failed to open compute shader: " << path << "\n";
- return nullptr;
- }
- std::stringstream ss;
- ss << in.rdbuf();
- std::string src_str = ss.str();
- return Ref<Shader>(Shader::create_compute("ComputeShader", src_str));
- }
-
- auto Engine::QuadVAO() -> std::pair<Ref<VertexArray>, Ref<Texture2D>>
- {
- float quad_vertices[] =
- {
- // Positions // TexCoords
- -1.0f, 1.0f, 0.0f, 1.0f,
- -1.0f, -1.0f, 0.0f, 0.0f,
- 1.0f, -1.0f, 1.0f, 0.0f,
- -1.0f, 1.0f, 0.0f, 1.0f,
- 1.0f, -1.0f, 1.0f, 0.0f,
- 1.0f, 1.0f, 1.0f, 1.0f
- };
-
- auto vertex_buffer = Ref<VertexBuffer>(VertexBuffer::create(quad_vertices, static_cast<uint32_t>(sizeof(quad_vertices))));
- VertexBufferLayout layout;
- layout.push<float>(2); // Position (x, y)
- layout.push<float>(2); // TexCoord (u, v)
- vertex_buffer->set_layout(layout);
-
- auto vertex_array = Ref<VertexArray>(VertexArray::create());
- vertex_array->add_vertex_buffer(vertex_buffer);
- auto texture = Texture2D::create(get_compute_width(), m_compute_height);
-
- return { vertex_array, texture };
- }
-
- auto Engine::load_objects_from_scene(const std::vector<Donut::Object>& objects) -> void
- {
- m_objects.clear();
- m_objects.push_back(
- {
- glm::vec4(0.00f, 0.00f, 0.00f, m_sag_a.m_rs),
- glm::vec4(0, 0, 0, 1),
- static_cast<float>(m_sag_a.m_mass)
- });
-
- for (const auto& obj : objects)
- {
- ObjectData engine_obj;
-
- float scale_factor = 1e10f;
- engine_obj.m_pos_radius = glm::vec4
- (
- obj.m_centre.x * scale_factor,
- obj.m_centre.y * scale_factor,
- obj.m_centre.z * scale_factor,
- obj.m_radius * scale_factor
- );
-
- engine_obj.m_color = glm::vec4(obj.m_material.m_color, 1.0f);
-
- float volume = (4.0f / 3.0f) * 3.14159f * engine_obj.m_pos_radius.w * engine_obj.m_pos_radius.w * engine_obj.m_pos_radius.w;
- float density = 1e12f;
- engine_obj.m_mass = volume * density;
- engine_obj.m_velocity = glm::vec3(0.0f, 0.0f, 0.0f);
-
- m_objects.push_back(engine_obj);
- }
-
- DONUT_INFO("Loaded {} objects from WorldBuilder scene (scaled up by {})", objects.size(), 1e10f);
- print_object_info();
- }
-
- auto Engine::print_object_info() const -> void
- {
- DONUT_INFO("=== Object Information ===");
- DONUT_INFO("Total objects: {}", m_objects.size());
-
- for (size_t i = 0; i < m_objects.size(); ++i)
- {
- const auto& obj = m_objects[i];
- DONUT_INFO("Object {}: Pos=({}, {}, {}), Radius={}, Mass={}, Color=({}, {}, {})",
- i,
- obj.m_pos_radius.x, obj.m_pos_radius.y, obj.m_pos_radius.z,
- obj.m_pos_radius.w,
- obj.m_mass,
- obj.m_color.x, obj.m_color.y, obj.m_color.z
- );
- }
- DONUT_INFO("Camera position: ({}, {}, {})",
- m_camera.get_orbital_position().x,
- m_camera.get_orbital_position().y,
- m_camera.get_orbital_position().z
- );
- DONUT_INFO("Camera radius: {}", m_camera.get_orbital_radius());
- DONUT_INFO("========================");
- }
-
- auto Engine::export_high_res_frame(const std::string& filename, int width, int height) -> void
- {
- DONUT_INFO("Exporting high-resolution frame: {}x{} to {}", width, height, filename);
-
- if (width <= 0 || height <= 0)
- {
- DONUT_ERROR("Invalid dimensions for export: {}x{}", width, height);
- return;
- }
-
- if (filename.empty())
- {
- DONUT_ERROR("Invalid filename for export");
- return;
- }
-
- int original_width = m_width;
- int original_height = m_height;
- int original_compute_height = m_compute_height;
-
- m_width = width;
- m_height = height;
- m_compute_height = height;
-
- int compute_height = height;
- int compute_width = (width * compute_height) / height;
-
- if (compute_width <= 0 || compute_height <= 0)
- {
- DONUT_ERROR("Invalid compute dimensions: {}x{}", compute_width, compute_height);
- return;
- }
-
- FramebufferSpecification fb_spec;
- fb_spec.Width = width;
- fb_spec.Height = height;
- fb_spec.attachments = { FramebufferTextureFormat::RGBA8 };
-
- auto high_res_framebuffer = Framebuffer::create(fb_spec);
- if (!high_res_framebuffer)
- {
- DONUT_ERROR("Failed to create high-resolution framebuffer");
- return;
- }
-
- auto high_res_texture = Texture2D::create(compute_width, compute_height);
- if (!high_res_texture)
- {
- DONUT_ERROR("Failed to create high-resolution texture");
- return;
- }
-
- // Render the geodesic pass into high_res_texture through the geodesic FBO.
- glBindFramebuffer(GL_FRAMEBUFFER, m_geodesic_fbo);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, high_res_texture->get_renderer_id(), 0);
- glViewport(0, 0, compute_width, compute_height);
-
- m_compute_program->bind();
-
- struct UBOData
- {
- glm::vec3 pos; float _pad0;
- glm::vec3 right; float _pad1;
- glm::vec3 up; float _pad2;
- glm::vec3 forward; float _pad3;
- float tan_half_fov;
- float aspect;
- bool moving;
- int _pad4;
- } data;
-
- glm::vec3 fwd = glm::normalize(m_camera.get_orbital_target() - m_camera.get_orbital_position());
- glm::vec3 up = glm::vec3(0, 1, 0);
- glm::vec3 right = glm::normalize(glm::cross(fwd, up));
- up = glm::cross(right, fwd);
-
- data.pos = m_camera.get_orbital_position();
- data.right = right;
- data.up = up;
- data.forward = fwd;
- data.tan_half_fov = static_cast<float>(tan(glm::radians(60.0f * 0.5f)));
- data.aspect = static_cast<float>(compute_width) / static_cast<float>(compute_height);
- data.moving = m_camera.is_dragging() || m_camera.is_panning();
-
- m_camera_ubo->set_data(&data, sizeof(UBOData));
- m_camera_ubo->bind(1);
-
- upload_disk_ubo();
- upload_objects_ubo(m_objects);
- upload_simulation_ubo();
- m_compute_program->set_float2("u_Resolution", glm::vec2(static_cast<float>(compute_width), static_cast<float>(compute_height)));
-
- if (m_hdri_environment)
- {
- m_hdri_environment->bind(5);
- m_compute_program->set_int("u_HDRIEnvironment", 5);
- }
-
- draw_geodesic_pass(compute_width, compute_height);
-
- // Display the rendered frame into the high-res framebuffer for read-back.
- high_res_framebuffer->bind();
- RenderCommand::set_viewport(0, 0, width, height);
- RenderCommand::clear();
-
- m_shader_program->bind();
- m_quad_vao->bind();
-
- high_res_texture->bind(0);
- m_shader_program->set_int("u_ScreenTexture", 0);
-
- RenderCommand::disable_depth_test();
- RenderCommand::draw_arrays(6);
- RenderCommand::enable_depth_test();
-
- std::vector<unsigned char> pixels(width * height * 4);
- DONUT_INFO("Reading {} pixels from framebuffer...", width * height);
- RenderCommand::read_pixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
-
- DONUT_INFO("Flipping image vertically...");
- std::vector<unsigned char> flipped_pixels(width * height * 4);
- for (int y = 0; y < height; ++y)
- {
- for (int x = 0; x < width; ++x)
- {
- int src_index = (y * width + x) * 4;
- int dst_index = ((height - 1 - y) * width + x) * 4;
- flipped_pixels[dst_index + 0] = pixels[src_index + 0]; // R
- flipped_pixels[dst_index + 1] = pixels[src_index + 1]; // G
- flipped_pixels[dst_index + 2] = pixels[src_index + 2]; // B
- flipped_pixels[dst_index + 3] = pixels[src_index + 3]; // A
- }
- }
-
- DONUT_INFO("Saving PNG file: {}...", filename);
- int result = stbi_write_png(filename.c_str(), width, height, 4, flipped_pixels.data(), width * 4);
-
- if (result)
- DONUT_INFO("Successfully exported high-resolution frame to: {}", filename);
- else
- DONUT_ERROR("Failed to export high-resolution frame to: {}", filename);
-
- high_res_framebuffer->unbind();
-
- m_width = original_width;
- m_height = original_height;
- m_compute_height = original_compute_height;
-
- RenderCommand::set_viewport(0, 0, original_width, original_height);
- }
-
-}
diff --git a/src/Engine/Engine.h b/src/Engine/Engine.h
deleted file mode 100644
index c7d02b5..0000000
--- a/src/Engine/Engine.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#pragma once
-
-#include <vector>
-#include <numbers>
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <chrono>
-#include <cmath>
-
-#include "core/camera.h"
-#include "object.h"
-
-#include "rendering/renderer.h"
-#include "rendering/shader.h"
-#include "rendering/vertex_array.h"
-#include "rendering/texture.h"
-#include "rendering/uniform_buffer.h"
-#include "rendering/texture_manager.h"
-
-#include <GLFW/glfw3.h>
-#include <glm/glm.hpp>
-#include <glm/gtc/matrix_transform.hpp>
-#include <glm/gtc/type_ptr.hpp>
-
-namespace Donut
-{
- const double c = 299792458.0;
- const double G = 6.67430e-11;
-
- struct BlackHole
- {
- glm::vec3 m_position;
- double m_mass;
- double m_radius;
- double m_rs;
-
- BlackHole(glm::vec3 pos, float mass)
- : m_position(pos), m_mass(mass)
- {
- m_rs = 2.0 * G * m_mass / (c * c);
- }
-
- bool intercept(float px, float py, float pz) const
- {
- double dx = double(px) - double(m_position.x);
- double dy = double(py) - double(m_position.y);
- double dz = double(pz) - double(m_position.z);
- double dist2 = dx * dx + dy * dy + dz * dz;
- return dist2 < m_rs * m_rs;
- }
- };
-
- struct ObjectData
- {
- glm::vec4 m_pos_radius;
- glm::vec4 m_color;
- float m_mass;
- glm::vec3 m_velocity = glm::vec3(0.0f, 0.0f, 0.0f);
- };
-
- class Engine
- {
- public:
- Engine();
- ~Engine() = default;
-
- auto draw_full_screen_quad() -> void;
- auto draw_blur_pass() -> void;
- auto dispatch_compute(const Camera& cam) -> void;
- auto upload_camera_ubo(const Camera& cam) -> void;
- auto upload_objects_ubo(const std::vector<ObjectData>& objs) -> void;
- auto upload_disk_ubo() -> void;
- auto upload_simulation_ubo() -> void;
- auto render_scene() -> void;
- auto update_physics(float delta_time) -> void;
- auto update_window_dimensions() -> void;
- auto set_window_dimensions(int width, int height) -> void;
-
- auto get_width() const -> int { return m_width; }
- auto get_height() const -> int { return m_height; }
-
- auto get_objects() -> std::vector<ObjectData>& { return m_objects; }
- auto get_sag_a() -> BlackHole& { return m_sag_a; }
- auto get_camera() -> Camera& { return m_camera; }
- auto get_gravity() -> bool& { return m_gravity; }
-
- auto update_performance(float delta_time) -> void;
- auto set_target_fps(int fps) -> void { m_target_fps = fps; }
- auto get_target_fps() const -> int { return m_target_fps; }
- auto get_current_fps() const -> float { return m_current_fps; }
- void set_compute_height(int height)
- {
-#ifdef __APPLE__
- // Without compute shaders the geodesic pass runs as a tiled
- // fragment shader (see draw_geodesic_pass), so very high working
- // resolutions make each frame take many seconds. Cap it on macOS.
- if (height > 256) height = 256;
-#endif
- m_compute_height = height;
- }
- auto get_compute_height() const -> int { return m_compute_height; }
- auto get_compute_width() const -> int { return (m_width * m_compute_height) / m_height; }
- auto update_compute_dimensions() -> void;
-
- auto get_max_steps_moving() const -> int { return m_max_steps_moving; }
- auto get_max_steps_static() const -> int { return m_max_steps_static; }
- auto get_early_exit_distance() const -> float { return m_early_exit_distance; }
- auto set_max_steps_moving(int steps) -> void { m_max_steps_moving = steps; }
- auto set_max_steps_static(int steps) -> void { m_max_steps_static = steps; }
- auto set_early_exit_distance(float distance) -> void { m_early_exit_distance = distance; }
-
- auto get_disk_thickness() const -> float { return m_disk_thickness; }
- auto set_disk_thickness(float thickness) -> void { m_disk_thickness = thickness; }
-
- auto get_disk_density() const -> float { return m_disk_density; }
- auto set_disk_density(float density) -> void { m_disk_density = density; }
-
- auto get_rotation_speed() const -> float { return m_rotation_speed; }
- auto set_rotation_speed(float speed) -> void { m_rotation_speed = speed; }
-
- auto get_blur_strength() const -> float { return m_blur_strength; }
- auto set_blur_strength(float strength) -> void { m_blur_strength = strength; }
-
- auto get_glow_intensity() const -> float { return m_glow_intensity; }
- auto set_glow_intensity(float intensity) -> void { m_glow_intensity = intensity; }
-
- auto load_objects_from_scene(const std::vector<Donut::Object>& objects) -> void;
- auto export_high_res_frame(const std::string& filename, int width = 4096, int height = 3072) -> void;
- auto print_object_info() const -> void;
-
- auto set_hdri_environment(Ref<CubemapTexture> hdri) -> void { m_hdri_environment = hdri; }
- auto get_hdri_environment() const -> Ref<CubemapTexture> { return m_hdri_environment; }
- private:
- auto create_compute_program(const char* path) -> Ref<Shader>;
- std::pair<Ref<VertexArray>, Ref<Texture2D>> QuadVAO();
-
- // Draws the bound geodesic shader over a cw x ch target. On macOS this
- // is split into scissored tiles (with a flush each) so no single GPU
- // submission trips the OS watchdog; elsewhere it is one fast draw.
- auto draw_geodesic_pass(int cw, int ch) -> void;
- private:
- Ref<VertexArray> m_quad_vao;
- Ref<Texture2D> m_texture;
- Ref<CubemapTexture> m_hdri_environment;
- Ref<Shader> m_shader_program;
- Ref<Shader> m_compute_program;
- Ref<Shader> m_blur_shader;
- Ref<UniformBuffer> m_camera_ubo;
- Ref<UniformBuffer> m_disk_ubo;
- Ref<UniformBuffer> m_objects_ubo;
- Ref<UniformBuffer> m_simulation_ubo;
-
- // FBO used to render the geodesic pass into m_texture. The geodesic
- // shader is a fragment shader (macOS has no compute), so it draws a
- // fullscreen quad into this framebuffer instead of dispatching compute.
- uint32_t m_geodesic_fbo = 0;
-
- int m_width;
- int m_height;
- float m_width_f = 100.0f*1e10f;
- float m_height_f = 75.0f*1e10f;
-
- int m_target_fps = 60;
- float m_current_fps = 60.0f;
- float m_last_frame_time = 0.0f;
- int m_compute_height = 150;
-
- std::vector<ObjectData> m_objects;
- BlackHole m_sag_a;
- Camera m_camera;
- bool m_gravity = false;
-
- int m_max_steps_moving = 60000;
- int m_max_steps_static = 30000;
- float m_early_exit_distance = 5.0e11f;
-
- float m_disk_thickness = 0.1f;
- float m_disk_density = 0.1f;
- float m_rotation_speed = 1.0f;
- float m_blur_strength = 2.0f;
- float m_glow_intensity = 0.1f;
- };
-};
diff --git a/src/Engine/Object.h b/src/Engine/Object.h
deleted file mode 100644
index 8101540..0000000
--- a/src/Engine/Object.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#pragma once
-
-#include <glm/glm.hpp>
-
-namespace Donut
-{
- class Ray
- {
- public:
- Ray(glm::vec3 o, glm::vec3 d)
- : m_origin(o),
- m_direction(glm::normalize(d)) { }
-
- public:
- glm::vec3 m_direction;
- glm::vec3 m_origin;
- };
-
- class Material
- {
- public:
- Material() : m_color(1.0f, 1.0f, 1.0f), m_specular(0.5f), m_emission(0.0f) { }
- Material(glm::vec3 c, float s, float e)
- : m_color(c),
- m_specular(s),
- m_emission(e) { }
-
- public:
- glm::vec3 m_color;
- float m_specular;
- float m_emission;
- };
-
- class Object
- {
- public:
- Object() : m_centre(0.0f, 0.0f, 0.0f), m_radius(1.0f), m_material() { }
- Object(glm::vec3 c, float r, Material m)
- : m_centre(c),
- m_radius(r),
- m_material(m) { }
-
- auto intersect(Ray& ray, float& t) -> bool
- {
- glm::vec3 oc = ray.m_origin - m_centre;
- float a = glm::dot(ray.m_direction, ray.m_direction);
- float b = 2.0f * glm::dot(oc, ray.m_direction);
- float c = glm::dot(oc, oc) - m_radius * m_radius;
- float discriminant = static_cast<float>(b*b - 4*a*c);
-
- if (discriminant < 0)
- return false;
-
- float intercept = (-b - sqrt(discriminant)) / (2.0f*a);
- if (intercept < 0)
- {
- intercept = (-b + sqrt(discriminant)) / (2.0f*a);
- if (intercept < 0)
- return false;
- }
-
- t = intercept;
- return true;
- }
-
- auto get_normal(glm::vec3& point) const -> glm::vec3
- {
- return glm::normalize(point - m_centre);
- }
-
- public:
- glm::vec3 m_centre;
- float m_radius;
- Material m_material;
- };
-};
diff --git a/src/Engine/Scene.h b/src/Engine/Scene.h
deleted file mode 100644
index 4b41203..0000000
--- a/src/Engine/Scene.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#pragma once
-
-#include <vector>
-#include <limits>
-
-#include "object.h"
-
-namespace Donut
-{
- class Scene
- {
- public:
- Scene()
- : m_light_pos(5.0f, 5.0f, 5.0f) { }
-
- auto trace(Ray& ray) -> glm::vec3
- {
- float closest = std::numeric_limits<float>::infinity();
- const Object* hit_obj = nullptr;
-
- for (auto& obj : objs)
- {
- float t;
-
- if (obj.intersect(ray, t))
- if (t < closest)
- {
- closest = t;
- hit_obj = &obj;
- }
- }
-
- if (hit_obj)
- {
- glm::vec3 hit_point = ray.m_origin + ray.m_direction * closest;
- glm::vec3 normal = hit_obj->get_normal(hit_point);
- glm::vec3 light_dir = glm::normalize(m_light_pos - hit_point);
-
- float diff = std::max(glm::dot(normal, light_dir), 0.0f);
-
- Ray shadow_ray(hit_point + normal * 0.001f, light_dir);
- bool in_shadow = false;
-
- for (auto& obj : objs)
- {
- float t;
-
- if (obj.intersect(shadow_ray, t))
- {
- in_shadow = true;
- break;
- }
- }
-
- glm::vec3 color = hit_obj->m_material.m_color;
- float ambient = 0.1f;
-
- if (in_shadow)
- return color * ambient;
- return color * (ambient + diff * 0.9f);
- }
-
- return glm::vec3(0.0f, 0.0f, 0.1f);
- }
-
- public:
- std::vector<Object> objs;
- glm::vec3 m_light_pos;
- };
-};
diff --git a/src/Rendering/Framebuffer.cpp b/src/Rendering/Framebuffer.cpp
deleted file mode 100644
index 089c31e..0000000
--- a/src/Rendering/Framebuffer.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "framebuffer.h"
-#include "renderer.h"
-
-#include "platform/opengl/opengl_framebuffer.h"
-
-namespace Donut
-{
- auto Framebuffer::create(const FramebufferSpecification& spec) -> Ref<Framebuffer>
- {
- switch (Renderer::get_api())
- {
- case RendererAPI::API::OpenGL: return create_ref<OpenGLFramebuffer>(spec);
- }
-
- return nullptr;
- }
-};
diff --git a/src/Rendering/Framebuffer.h b/src/Rendering/Framebuffer.h
deleted file mode 100644
index a01a81b..0000000
--- a/src/Rendering/Framebuffer.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#pragma once
-
-#include "core/memory.h"
-#include "texture.h"
-
-namespace Donut
-{
- enum class FramebufferTextureFormat
- {
- None = 0,
-
- RGBA8,
- RED_INTEGER,
-
- DEPTH24STENCIL8,
-
- Depth = DEPTH24STENCIL8
- };
-
- struct FramebufferTextureSpecification
- {
- FramebufferTextureSpecification() = default;
- FramebufferTextureSpecification(FramebufferTextureFormat format)
- : texture_format(format) {}
-
- FramebufferTextureFormat texture_format = FramebufferTextureFormat::None;
- };
-
- struct FramebufferAttachmentSpecification
- {
- FramebufferAttachmentSpecification() = default;
- FramebufferAttachmentSpecification(std::initializer_list<FramebufferTextureSpecification> attachments)
- : attachments(attachments) {}
-
- std::vector<FramebufferTextureSpecification> attachments;
- };
-
- struct FramebufferSpecification
- {
- uint32_t Width = 0, Height = 0;
- FramebufferAttachmentSpecification attachments;
- uint32_t Samples = 1;
-
- bool SwapChainTarget = false;
- };
-
- class Framebuffer
- {
- public:
- virtual ~Framebuffer() = default;
-
- virtual auto bind() -> void = 0;
- virtual auto unbind() -> void = 0;
-
- virtual auto resize(uint32_t width, uint32_t height) -> void = 0;
- virtual auto read_pixel(uint32_t attachment_index, int x, int y) -> int = 0;
-
- virtual auto clear_attachment(uint32_t attachment_index, int value) -> void = 0;
- virtual auto get_color_attachment_renderer_id(uint32_t index = 0) const -> uint32_t = 0;
-
- virtual auto get_specification() const -> const FramebufferSpecification& = 0;
-
- static auto create(const FramebufferSpecification& spec) -> Ref<Framebuffer>;
- };
-};
diff --git a/src/Rendering/Renderer.cpp b/src/Rendering/Renderer.cpp
deleted file mode 100644
index 28b7962..0000000
--- a/src/Rendering/Renderer.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#include "renderer.h"
-
-#include "platform/opengl/opengl_renderer_api.h"
-#include "platform/vulkan/vulkan_renderer_api.h"
-
-#include <glm/gtc/matrix_transform.hpp>
-
-namespace Donut
-{
- auto RendererAPI::create() -> Scope<RendererAPI>
- {
- switch (s_api)
- {
- case API::OpenGL:
- return create_scope<OpenGLRendererAPI>();
- case API::Vulkan:
- return create_scope<VulkanRendererAPI>();
- default:
- return nullptr;
- }
- }
-
- RendererAPI::API RendererAPI::s_api = RendererAPI::API::OpenGL;
-
- auto Renderer::init() -> void
- {
- RenderCommand::init();
- RenderCommand::enable_depth_test();
- }
-
- auto Renderer::shutdown() -> void
- {
- }
-
- auto Renderer::on_window_resize(uint32_t width, uint32_t height) -> void
- {
- RenderCommand::set_viewport(0, 0, width, height);
- }
-
- auto Renderer::submit(const Ref<Shader>& shader,
- const Ref<VertexArray>& vertex_array,
- const glm::mat4& transform,
- const glm::mat4& view_projection) -> void
- {
- shader->bind();
- shader->set_mat4("u_ViewProjection", view_projection);
- shader->set_mat4("u_Transform", transform);
-
- vertex_array->bind();
- RenderCommand::draw_indexed(vertex_array);
- }
-
- Scope<RendererAPI> RenderCommand::s_renderer_api = RendererAPI::create();
-
- auto Renderer::set_clear_color(const glm::vec4& color) -> void
- {
- RenderCommand::set_clear_color(color);
- }
-
- auto Renderer::clear() -> void
- {
- RenderCommand::clear();
- }
-};
diff --git a/src/Rendering/Renderer.h b/src/Rendering/Renderer.h
deleted file mode 100644
index 189723d..0000000
--- a/src/Rendering/Renderer.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#pragma once
-
-#include "core/memory.h"
-#include "vertex_array.h"
-#include "shader.h"
-#include "framebuffer.h"
-
-#include <glm/glm.hpp>
-
-namespace Donut
-{
- class RendererAPI
- {
- public:
- enum class API
- {
- None = 0,
- OpenGL = 1,
- Vulkan = 2,
- };
-
- public:
- virtual ~RendererAPI() = default;
-
- virtual auto init() -> void = 0;
- virtual auto set_viewport(uint32_t x, uint32_t y,
- uint32_t width, uint32_t height) -> void = 0;
- virtual auto set_clear_color(const glm::vec4& color) -> void = 0;
- virtual auto clear() -> void = 0;
- virtual auto enable_depth_test() -> void = 0;
- virtual auto disable_depth_test() -> void = 0;
- virtual auto set_face_culling(bool enabled) -> void = 0;
- virtual auto enable_blending() -> void = 0;
- virtual auto disable_blending() -> void = 0;
-
- virtual auto draw_indexed(const Ref<VertexArray>& vertex_array,
- uint32_t index_count = 0) -> void = 0;
-
- virtual auto draw_arrays(uint32_t vertex_count, uint32_t first = 0) -> void = 0;
- virtual auto draw_lines(const Ref<VertexArray>& vertex_array,
- uint32_t index_count = 0) -> void = 0;
- virtual auto bind_texture(uint32_t texture_id, uint32_t slot = 0) -> void = 0;
- virtual auto bind_image_texture(uint32_t texture_id,
- uint32_t slot = 0,
- bool read_only = false) -> void = 0;
- virtual auto read_pixels(uint32_t x, uint32_t y, uint32_t width, uint32_t height,
- uint32_t format, uint32_t type, void* pixels) -> void = 0;
-
- inline static auto get_api() -> API { return s_api; }
- inline static auto set_api(API api) -> void { s_api = api; }
- static auto create() -> Scope<RendererAPI>;
-
- private:
- static API s_api;
- };
-
- class RenderCommand
- {
- public:
- inline static auto init() -> void
- {
- s_renderer_api->init();
- }
-
- inline static auto set_viewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) -> void
- {
- s_renderer_api->set_viewport(x, y, width, height);
- }
-
- inline static auto set_clear_color(const glm::vec4& color) -> void
- {
- s_renderer_api->set_clear_color(color);
- }
-
- inline static auto clear() -> void
- {
- s_renderer_api->clear();
- }
-
- inline static auto enable_depth_test() -> void
- {
- s_renderer_api->enable_depth_test();
- }
-
- inline static auto disable_depth_test() -> void
- {
- s_renderer_api->disable_depth_test();
- }
-
- inline static auto set_face_culling(bool enabled) -> void
- {
- s_renderer_api->set_face_culling(enabled);
- }
-
- inline static auto enable_blending() -> void
- {
- s_renderer_api->enable_blending();
- }
-
- inline static auto disable_blending() -> void
- {
- s_renderer_api->disable_blending();
- }
-
- inline static auto draw_indexed(const Ref<VertexArray>& vertex_array, uint32_t index_count = 0) -> void
- {
- s_renderer_api->draw_indexed(vertex_array, index_count);
- }
-
- inline static auto draw_arrays(uint32_t vertex_count, uint32_t first = 0) -> void
- {
- s_renderer_api->draw_arrays(vertex_count, first);
- }
-
- inline static auto draw_lines(const Ref<VertexArray>& vertex_array, uint32_t index_count = 0) -> void
- {
- s_renderer_api->draw_lines(vertex_array, index_count);
- }
-
- inline static auto bind_texture(uint32_t texture_id, uint32_t slot = 0) -> void
- {
- s_renderer_api->bind_texture(texture_id, slot);
- }
-
- inline static auto bind_image_texture(uint32_t texture_id, uint32_t slot = 0, bool read_only = false) -> void
- {
- s_renderer_api->bind_image_texture(texture_id, slot, read_only);
- }
-
- inline static auto read_pixels(uint32_t x, uint32_t y, uint32_t width, uint32_t height,
- uint32_t format, uint32_t type, void* pixels) -> void
- {
- s_renderer_api->read_pixels(x, y, width, height, format, type, pixels);
- }
-
- private:
- static Scope<RendererAPI> s_renderer_api;
- };
-
- class Renderer
- {
- public:
- static auto init() -> void;
- static auto shutdown() -> void;
-
- static auto on_window_resize(uint32_t width, uint32_t height) -> void;
-
- static auto submit(const Ref<Shader>& shader,
- const Ref<VertexArray>& vertex_array,
- const glm::mat4& transform,
- const glm::mat4& view_projection) -> void;
-
- static auto set_clear_color(const glm::vec4& color) -> void;
- static auto clear() -> void;
-
- inline static auto get_api() -> RendererAPI::API { return RendererAPI::get_api(); }
- };
-};
diff --git a/src/Rendering/Shader.cpp b/src/Rendering/Shader.cpp
deleted file mode 100644
index 167b855..0000000
--- a/src/Rendering/Shader.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-#include "shader.h"
-#include "renderer.h"
-
-#include "platform/opengl/opengl_shader.h"
-#include "platform/vulkan/vulkan_shader.h"
-
-namespace Donut
-{
- auto Shader::create(const std::string& filepath) -> Shader*
- {
- switch (Renderer::get_api())
- {
- case RendererAPI::API::OpenGL:
- return new OpenGLShader(filepath);
- case RendererAPI::API::Vulkan:
- return new VulkanShader(filepath);
- default:
- return nullptr;
- }
- }
-
- auto Shader::create(const std::string& name, const std::string& vertex_src, const std::string& fragment_src) -> Shader*
- {
- switch (Renderer::get_api())
- {
- case RendererAPI::API::OpenGL:
- return new OpenGLShader(name, vertex_src, fragment_src);
- case RendererAPI::API::Vulkan:
- return new VulkanShader(name, vertex_src, fragment_src);
- default:
- return nullptr;
- }
- }
-
- auto Shader::create_compute(const std::string& name, const std::string& compute_src) -> Shader*
- {
- switch (Renderer::get_api())
- {
- case RendererAPI::API::OpenGL:
- return new OpenGLShader(name, compute_src);
- case RendererAPI::API::Vulkan:
- return new VulkanShader(name, compute_src);
- default:
- return nullptr;
- }
- }
-
- auto ShaderLibrary::add(const Ref<Shader>& shader) -> void
- {
- auto& name = shader->get_name();
- add(name, shader);
- }
-
- auto ShaderLibrary::add(const std::string& name, const Ref<Shader>& shader) -> void
- {
- m_shaders[name] = shader;
- }
-
- auto ShaderLibrary::load(const std::string& filepath) -> Ref<Shader>
- {
- auto shader = Ref<Shader>(Shader::create(filepath));
- add(shader);
- return shader;
- }
-
- auto ShaderLibrary::load(const std::string& name, const std::string& filepath) -> Ref<Shader>
- {
- auto shader = Ref<Shader>(Shader::create(filepath));
- add(name, shader);
- return shader;
- }
-
- auto ShaderLibrary::Get(const std::string& name) -> Ref<Shader>
- {
- if (exists(name))
- return m_shaders[name];
- return nullptr;
- }
-
- auto ShaderLibrary::exists(const std::string& name) const -> bool
- {
- return m_shaders.find(name) != m_shaders.end();
- }
-};
diff --git a/src/Rendering/Shader.h b/src/Rendering/Shader.h
deleted file mode 100644
index bc3fd9a..0000000
--- a/src/Rendering/Shader.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#pragma once
-
-#include "core/memory.h"
-
-#include <string>
-#include <unordered_map>
-#include <glm/glm.hpp>
-
-#define SHADER_STORAGE_BARRIER_BIT 0x00002000
-#define UNIFORM_BARRIER_BIT 0x00000004
-#define TEXTURE_FETCH_BARRIER_BIT 0x00000008
-#define IMAGE_ACCESS_BARRIER_BIT 0x00000020
-
-namespace Donut
-{
- class Shader
- {
- public:
- virtual ~Shader() = default;
-
- virtual auto bind() const -> void = 0;
- virtual auto unbind() const -> void = 0;
-
- virtual auto set_int( const std::string& name, int value) -> void = 0;
- virtual auto set_int_array(const std::string& name, int* values, uint32_t count) -> void = 0;
- virtual auto set_float( const std::string& name, float value) -> void = 0;
- virtual auto set_float2( const std::string& name, const glm::vec2& value) -> void = 0;
- virtual auto set_float3( const std::string& name, const glm::vec3& value) -> void = 0;
- virtual auto set_float4( const std::string& name, const glm::vec4& value) -> void = 0;
- virtual auto set_mat4( const std::string& name, const glm::mat4& value) -> void = 0;
-
- virtual auto dispatch(uint32_t x, uint32_t y = 1, uint32_t z = 1) -> void = 0;
- virtual auto dispatch_indirect(uint32_t offset = 0) -> void = 0;
- virtual auto memory_barrier(uint32_t barriers) -> void = 0;
-
- virtual auto get_name() const -> const std::string& = 0;
- virtual auto get_renderer_id() const -> uint32_t = 0;
-
- static auto create(const std::string& filepath) -> Shader*;
- static auto create(const std::string& name, const std::string& vertex_src, const std::string& fragment_src) -> Shader*;
- static auto create_compute(const std::string& name, const std::string& compute_src) -> Shader*;
- };
-
- class ShaderLibrary
- {
- public:
- auto add(const Ref<Shader>& shader) -> void;
- auto add(const std::string& name, const Ref<Shader>& shader) -> void;
- auto load(const std::string& filepath) -> Ref<Shader>;
- auto load(const std::string& name, const std::string& filepath) -> Ref<Shader>;
-
- Ref<Shader> Get(const std::string& name);
-
- auto exists(const std::string& name) const -> bool;
- private:
- std::unordered_map<std::string, Ref<Shader>> m_shaders;
- };
-};
diff --git a/src/Rendering/Texture.cpp b/src/Rendering/Texture.cpp
deleted file mode 100644
index 2470e46..0000000
--- a/src/Rendering/Texture.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-#include "texture.h"
-#include "renderer.h"
-
-#include "platform/opengl/opengl_texture.h"
-#include "platform/vulkan/vulkan_texture.h"
-
-namespace Donut
-{
- auto Texture2D::create(uint32_t width, uint32_t height) -> Ref<Texture2D>
- {
- switch (Renderer::get_api())
- {
- case RendererAPI::API::OpenGL:
- return create_ref<OpenGLTexture2D>(width, height);
- case RendererAPI::API::Vulkan:
- return create_ref<VulkanTexture2D>(width, height);
- case RendererAPI::API::None:
- return nullptr;
- default:
- return nullptr;
- }
- }
-
- auto Texture2D::create(const std::string& path) -> Ref<Texture2D>
- {
- switch (Renderer::get_api())
- {
- case RendererAPI::API::OpenGL:
- return create_ref<OpenGLTexture2D>(path);
- case RendererAPI::API::Vulkan:
- return create_ref<VulkanTexture2D>(path);
- case RendererAPI::API::None:
- return nullptr;
- default:
- return nullptr;
- }
- }
-
- auto CubemapTexture::create(uint32_t width, uint32_t height) -> Ref<CubemapTexture>
- {
- switch (Renderer::get_api())
- {
- case RendererAPI::API::OpenGL:
- return create_ref<OpenGLCubemapTexture>(width, height);
- case RendererAPI::API::Vulkan:
- return create_ref<VulkanCubemapTexture>(width, height);
- case RendererAPI::API::None:
- return nullptr;
- default:
- return nullptr;
- }
- }
-
- auto CubemapTexture::create_from_hdri(const std::string& path) -> Ref<CubemapTexture>
- {
- switch (Renderer::get_api())
- {
- case RendererAPI::API::OpenGL:
- return create_ref<OpenGLCubemapTexture>(path);
- case RendererAPI::API::Vulkan:
- return create_ref<VulkanCubemapTexture>(path);
- case RendererAPI::API::None:
- return nullptr;
- default:
- return nullptr;
- }
- }
-}; \ No newline at end of file
diff --git a/src/Rendering/Texture.h b/src/Rendering/Texture.h
deleted file mode 100644
index e9b3e0a..0000000
--- a/src/Rendering/Texture.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-
-#include "core/memory.h"
-
-#include <string>
-#include <glm/glm.hpp>
-
-namespace Donut
-{
- class Texture
- {
- public:
- virtual ~Texture() = default;
-
- virtual auto get_width() const -> uint32_t = 0;
- virtual auto get_height() const -> uint32_t = 0;
- virtual auto get_renderer_id() const -> uint32_t = 0;
-
- virtual auto set_data(void* data, uint32_t size) -> void = 0;
- virtual auto bind(uint32_t slot = 0) const -> void = 0;
- virtual void bind_as_image(uint32_t slot = 0,
- bool read_only = false) const = 0;
-
- virtual bool operator==(const Texture& other) const = 0;
- };
-
- class Texture2D
- : public Texture
- {
- public:
- static auto create(uint32_t width, uint32_t height) -> Ref<Texture2D>;
- static auto create(const std::string& path) -> Ref<Texture2D>;
- };
-
- class CubemapTexture
- : public Texture
- {
- public:
- static auto create(uint32_t width, uint32_t height) -> Ref<CubemapTexture>;
- static auto create_from_hdri(const std::string& path) -> Ref<CubemapTexture>;
- };
-}; \ No newline at end of file