#pragma once #include "rendering/renderer_backend.h" #include "core/memory.h" #include "core/camera.h" #include "rendering/shader.h" // OpenGL implementation of the shared RendererBackend interface. It renders the // SAME cross-compiled Geodesic shader the Vulkan backend does (driven by the // same BlackHoleParams + camera), so the application behaves identically on // either backend. Wraps the Engine, which owns the GL geodesic/present passes // and the macOS watchdog-safe tiled rendering. namespace Donut { class Engine; class OpenGLRenderer : public RendererBackend { public: OpenGLRenderer(); ~OpenGLRenderer() override; auto init(void* glfwWindow, int width, int height) -> bool override; auto init_ui() -> bool override; auto shutdown() -> void override; auto resize(int width, int height) -> void override; auto draw_frame(const glm::vec4& clear_color, const std::function& build_ui) -> void override; auto set_scene_mode(bool enabled) -> void override; auto is_scene_mode() const -> bool override; auto set_free_fly(bool enabled) -> void override; auto is_free_fly() const -> bool override; auto reset_camera() -> void override; auto set_hdri(const std::string& path) -> void override; auto current_hdri() const -> const std::string& override; auto scene_objects() -> std::vector& override; auto set_selected_object(int index) -> void override; auto black_hole_params() -> BlackHoleParams& override; auto device_name() const -> const std::string& override; private: auto process_input() -> void; auto create_scene_resources() -> void; // grid + sphere + skybox meshes/shaders auto render_scene(int width, int height) -> void; void* m_window = nullptr; Scope m_engine; // World-builder scene view (normal-scale): mirrors the Vulkan scene view // with the same shared Grid/Sphere/Skybox shaders. Camera m_scene_camera{ 45.0f, 16.0f / 9.0f, 0.1f, 1000.0f }; Ref m_grid_shader, m_sphere_shader, m_skybox_shader; unsigned int m_grid_vao = 0, m_grid_vbo = 0; unsigned int m_sphere_vao = 0, m_sphere_vbo = 0, m_sphere_ebo = 0; unsigned int m_skybox_vao = 0, m_skybox_vbo = 0; int m_grid_vertex_count = 0, m_sphere_index_count = 0; bool m_scene_ready = false; std::vector m_scene_objects{ SceneObject{} }; int m_selected_object = 0; std::string m_hdri_path; std::string m_device_name; bool m_scene_mode = false; bool m_ui_ready = false; double m_last_x = 0.0, m_last_y = 0.0; bool m_left_was_down = false; double m_last_frame_time = 0.0; }; }