aboutsummaryrefslogtreecommitdiff
path: root/src/platform/opengl/opengl_renderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/opengl/opengl_renderer.cpp')
-rw-r--r--src/platform/opengl/opengl_renderer.cpp377
1 files changed, 0 insertions, 377 deletions
diff --git a/src/platform/opengl/opengl_renderer.cpp b/src/platform/opengl/opengl_renderer.cpp
deleted file mode 100644
index ae12f10..0000000
--- a/src/platform/opengl/opengl_renderer.cpp
+++ /dev/null
@@ -1,377 +0,0 @@
-#include "opengl_renderer.h"
-
-#include "engine/engine.h"
-#include "core/log.h"
-#include "core/camera.h"
-#include "core/hdri_manager.h"
-#include "rendering/renderer.h" // Renderer::init / RenderCommand
-
-#include <glad/glad.h>
-#include <GLFW/glfw3.h>
-#include <imgui.h>
-#include <imgui_impl_glfw.h>
-#include <imgui_impl_opengl3.h>
-#include <glm/glm.hpp>
-#include <glm/gtc/matrix_transform.hpp>
-#include <cmath>
-#include <vector>
-
-#include "core/hdri_manager.h"
-#include "rendering/texture.h" // CubemapTexture::bind
-
-namespace Donut
-{
- // Scroll is accumulated through a chained GLFW callback (keeps ImGui's scroll
- // handling intact), consumed once per frame for orbital zoom.
- static double g_scroll_accum = 0.0;
- static GLFWscrollfun g_prev_scroll = nullptr;
- static void gl_scroll_cb(GLFWwindow* w, double x, double y)
- {
- if (g_prev_scroll) g_prev_scroll(w, x, y);
- g_scroll_accum += y;
- }
-
- OpenGLRenderer::OpenGLRenderer() = default;
- OpenGLRenderer::~OpenGLRenderer() = default;
-
- auto OpenGLRenderer::init(void* glfwWindow, int width, int height) -> bool
- {
- m_window = glfwWindow;
- auto* win = static_cast<GLFWwindow*>(glfwWindow);
- glfwMakeContextCurrent(win);
-
- Renderer::init(); // GLAD load + default GL state
- RenderCommand::set_face_culling(false);
-
- const GLubyte* name = glGetString(GL_RENDERER);
- m_device_name = name ? reinterpret_cast<const char*>(name) : "OpenGL";
-
- m_engine = create_scope<Engine>();
- m_engine->set_window_dimensions(width, height);
-#ifdef __APPLE__
- m_engine->set_compute_height(256); // capped for the macOS watchdog (tiled fragment pass)
-#else
- m_engine->set_compute_height(540);
-#endif
- m_engine->update_compute_dimensions();
-
- // Match the Vulkan framing exactly (camera sits outside the disk).
- Camera& cam = m_engine->get_camera();
- cam.set_camera_mode(CameraMode::Orbital);
- cam.set_orbital_target(glm::vec3(0.0f));
- cam.set_orbital_radius(4e11);
- cam.set_orbital_limits(2.2e11, 1.5e12);
- cam.set_orbital_speed(0.01f);
- cam.set_zoom_speed(3e10);
- cam.set_azimuth(0.0f);
- cam.set_elevation(1.25f);
-
- m_hdri_path = "assets/hdri/HDR_blue_nebulae-1.hdr";
- HDRIManager::get().set_current_hdri(m_hdri_path);
-
- create_scene_resources();
-
- DONUT_INFO("OpenGL renderer ready: {} ({}x{})", m_device_name, width, height);
- return true;
- }
-
- auto OpenGLRenderer::init_ui() -> bool
- {
- IMGUI_CHECKVERSION();
- ImGui::CreateContext();
- ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;
- ImGui::StyleColorsDark();
- ImGui_ImplGlfw_InitForOpenGL(static_cast<GLFWwindow*>(m_window), true);
- ImGui_ImplOpenGL3_Init("#version 410");
- g_prev_scroll = glfwSetScrollCallback(static_cast<GLFWwindow*>(m_window), gl_scroll_cb);
- m_ui_ready = true;
- DONUT_INFO("OpenGL: ImGui backend initialized");
- return true;
- }
-
- auto OpenGLRenderer::shutdown() -> void
- {
- if (m_ui_ready)
- {
- ImGui_ImplOpenGL3_Shutdown();
- ImGui_ImplGlfw_Shutdown();
- ImGui::DestroyContext();
- m_ui_ready = false;
- }
- m_engine.reset();
- }
-
- auto OpenGLRenderer::resize(int width, int height) -> void
- {
- if (m_engine) m_engine->set_window_dimensions(width, height);
- }
-
- auto OpenGLRenderer::process_input() -> void
- {
- auto* win = static_cast<GLFWwindow*>(m_window);
- Camera& cam = m_scene_mode ? m_scene_camera : m_engine->get_camera();
- bool over_ui = m_ui_ready && ImGui::GetIO().WantCaptureMouse;
-
- double now = glfwGetTime();
- float dt = m_last_frame_time > 0.0 ? static_cast<float>(now - m_last_frame_time) : 0.0f;
- m_last_frame_time = now;
-
- double mx = 0, my = 0; glfwGetCursorPos(win, &mx, &my);
- bool left_down = glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS;
-
- if (!m_scene_mode && cam.get_camera_mode() == CameraMode::FPS)
- {
- if (left_down && !m_left_was_down) { m_last_x = mx; m_last_y = my; }
- if (left_down && !over_ui)
- cam.on_mouse_move(static_cast<float>(mx - m_last_x), static_cast<float>(m_last_y - my));
- m_last_x = mx; m_last_y = my; m_left_was_down = left_down;
-
- bool over_kb = m_ui_ready && ImGui::GetIO().WantCaptureKeyboard;
- if (!over_kb && dt > 0.0f)
- {
- float mdt = dt * (glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS ? 4.0f : 1.0f);
- if (glfwGetKey(win, GLFW_KEY_W) == GLFW_PRESS) cam.move_forward(mdt);
- if (glfwGetKey(win, GLFW_KEY_S) == GLFW_PRESS) cam.move_backward(mdt);
- if (glfwGetKey(win, GLFW_KEY_A) == GLFW_PRESS) cam.move_left(mdt);
- if (glfwGetKey(win, GLFW_KEY_D) == GLFW_PRESS) cam.move_right(mdt);
- if (glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS) cam.move_up(mdt);
- if (glfwGetKey(win, GLFW_KEY_Q) == GLFW_PRESS) cam.move_down(mdt);
- }
- g_scroll_accum = 0.0; // scroll unused in free-fly
- }
- else
- {
- if (left_down && !m_left_was_down && !over_ui)
- cam.process_orbital_mouse_button(GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, 0);
- else if (!left_down && m_left_was_down)
- cam.process_orbital_mouse_button(GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE, 0);
- m_left_was_down = left_down;
-
- cam.process_orbital_mouse_move(mx, my);
- double scroll = g_scroll_accum; g_scroll_accum = 0.0;
- if (scroll != 0.0 && !over_ui) cam.process_orbital_scroll(0.0, scroll);
- }
- }
-
- // 36-vertex unit cube for the skybox (positions only; the shader forces depth=1).
- static const float SKYBOX_CUBE[] = {
- -1, 1,-1, -1,-1,-1, 1,-1,-1, 1,-1,-1, 1, 1,-1, -1, 1,-1,
- -1,-1, 1, -1,-1,-1, -1, 1,-1, -1, 1,-1, -1, 1, 1, -1,-1, 1,
- 1,-1,-1, 1,-1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1, 1,-1,-1,
- -1,-1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1, 1, -1,-1, 1,
- -1, 1,-1, 1, 1,-1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1,-1,
- -1,-1,-1, -1,-1, 1, 1,-1,-1, 1,-1,-1, -1,-1, 1, 1,-1, 1,
- };
-
- auto OpenGLRenderer::create_scene_resources() -> void
- {
- const float PI = 3.14159265358979f;
-
- m_grid_shader = Ref<Shader>(Shader::create("assets/shaders/Grid.glsl"));
- m_sphere_shader = Ref<Shader>(Shader::create("assets/shaders/Sphere.glsl"));
- m_skybox_shader = Ref<Shader>(Shader::create("assets/shaders/Skybox.glsl"));
-
- m_scene_camera.set_camera_mode(CameraMode::Orbital);
- m_scene_camera.set_orbital_target(glm::vec3(0.0f));
- m_scene_camera.set_orbital_radius(15.0);
- m_scene_camera.set_orbital_limits(2.0, 200.0);
- m_scene_camera.set_orbital_speed(0.01f);
- m_scene_camera.set_zoom_speed(2.0);
- m_scene_camera.set_azimuth(0.0f);
- m_scene_camera.set_elevation(PI / 3.0f);
-
- // Grid: +/-50 lines on the XZ plane (Grid shader scales by u_GridSize/50).
- std::vector<glm::vec3> lines;
- for (int i = -50; i <= 50; ++i)
- {
- lines.push_back({ (float)i, 0.0f, -50.0f }); lines.push_back({ (float)i, 0.0f, 50.0f });
- lines.push_back({ -50.0f, 0.0f, (float)i }); lines.push_back({ 50.0f, 0.0f, (float)i });
- }
- m_grid_vertex_count = (int)lines.size();
- glGenVertexArrays(1, &m_grid_vao); glGenBuffers(1, &m_grid_vbo);
- glBindVertexArray(m_grid_vao); glBindBuffer(GL_ARRAY_BUFFER, m_grid_vbo);
- glBufferData(GL_ARRAY_BUFFER, lines.size() * sizeof(glm::vec3), lines.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
-
- // Sphere: indexed UV sphere (position + normal), unit radius.
- const int RINGS = 24, SECT = 48;
- std::vector<float> sv; std::vector<unsigned int> si;
- for (int r = 0; r <= RINGS; ++r)
- {
- float th = PI * r / RINGS;
- for (int s = 0; s <= SECT; ++s)
- {
- float ph = 2.0f * PI * s / SECT;
- glm::vec3 p(sinf(th) * cosf(ph), cosf(th), sinf(th) * sinf(ph));
- sv.insert(sv.end(), { p.x, p.y, p.z, p.x, p.y, p.z }); // pos, normal (unit sphere)
- }
- }
- for (int r = 0; r < RINGS; ++r)
- for (int s = 0; s < SECT; ++s)
- {
- int a = r * (SECT + 1) + s, b = a + SECT + 1;
- si.insert(si.end(), { (unsigned)a, (unsigned)b, (unsigned)(a + 1),
- (unsigned)(a + 1), (unsigned)b, (unsigned)(b + 1) });
- }
- m_sphere_index_count = (int)si.size();
- glGenVertexArrays(1, &m_sphere_vao); glGenBuffers(1, &m_sphere_vbo); glGenBuffers(1, &m_sphere_ebo);
- glBindVertexArray(m_sphere_vao);
- glBindBuffer(GL_ARRAY_BUFFER, m_sphere_vbo);
- glBufferData(GL_ARRAY_BUFFER, sv.size() * sizeof(float), sv.data(), GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_sphere_ebo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, si.size() * sizeof(unsigned), si.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
- glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
-
- // Skybox cube.
- glGenVertexArrays(1, &m_skybox_vao); glGenBuffers(1, &m_skybox_vbo);
- glBindVertexArray(m_skybox_vao); glBindBuffer(GL_ARRAY_BUFFER, m_skybox_vbo);
- glBufferData(GL_ARRAY_BUFFER, sizeof(SKYBOX_CUBE), SKYBOX_CUBE, GL_STATIC_DRAW);
- glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
-
- glBindVertexArray(0);
- m_scene_ready = true;
- }
-
- auto OpenGLRenderer::render_scene(int w, int h) -> void
- {
- if (!m_grid_shader || !m_sphere_shader || !m_skybox_shader) return;
- glViewport(0, 0, w, h);
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- float aspect = h > 0 ? (float)w / (float)h : 1.0f;
- m_scene_camera.set_projection(45.0f, aspect, 0.1f, 1000.0f);
- glm::mat4 proj = m_scene_camera.get_projection_matrix();
- glm::mat4 view = m_scene_camera.get_view_matrix();
- glm::mat4 vp = proj * view;
- glm::vec3 cam = m_scene_camera.get_orbital_position();
-
- // Skybox behind everything (depth test on, write off; shader forces depth=1).
- glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glDepthMask(GL_FALSE);
- m_skybox_shader->bind();
- m_skybox_shader->set_mat4("u_Projection", proj);
- m_skybox_shader->set_mat4("u_View", glm::mat4(glm::mat3(view))); // strip translation
- auto hdri = HDRIManager::get().get_current_hdri();
- if (hdri) { hdri->bind(0); m_skybox_shader->set_int("u_Skybox", 0); }
- glBindVertexArray(m_skybox_vao); glDrawArrays(GL_TRIANGLES, 0, 36);
-
- // Lit spheres.
- glDepthFunc(GL_LESS); glDepthMask(GL_TRUE);
- m_sphere_shader->bind(); glBindVertexArray(m_sphere_vao);
- for (int i = 0; i < (int)m_scene_objects.size(); ++i)
- {
- const SceneObject& o = m_scene_objects[i];
- m_sphere_shader->set_mat4("u_ViewProjection", vp);
- m_sphere_shader->set_mat4("u_Transform",
- glm::translate(glm::mat4(1.0f), o.position) * glm::scale(glm::mat4(1.0f), glm::vec3(o.radius)));
- m_sphere_shader->set_float3("u_Color", o.color);
- m_sphere_shader->set_float("u_Specular", 0.6f);
- m_sphere_shader->set_float("u_Emission", 0.0f);
- m_sphere_shader->set_float3("u_LightPos", glm::vec3(10.0f, 20.0f, 10.0f));
- m_sphere_shader->set_float3("u_CameraPos", cam);
- m_sphere_shader->set_int("u_IsSelected", i == m_selected_object ? 1 : 0);
- m_sphere_shader->set_float3("u_OutlineColor", glm::vec3(1.0f, 1.0f, 0.0f));
- m_sphere_shader->set_float("u_OutlineWidth", 0.15f);
- glDrawElements(GL_TRIANGLES, m_sphere_index_count, GL_UNSIGNED_INT, 0);
- }
-
- // Transparent grid on top (test, no depth write).
- glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- m_grid_shader->bind();
- m_grid_shader->set_mat4("u_ViewProjection", vp);
- m_grid_shader->set_mat4("u_Transform", glm::mat4(1.0f));
- m_grid_shader->set_float("u_GridSize", 50.0f);
- m_grid_shader->set_float3("u_GridColor", glm::vec3(0.55f, 0.55f, 0.6f));
- m_grid_shader->set_float("u_GridAlpha", 0.75f);
- m_grid_shader->set_float3("u_CameraPos", cam);
- glBindVertexArray(m_grid_vao); glDrawArrays(GL_LINES, 0, m_grid_vertex_count);
- glDisable(GL_BLEND); glDepthMask(GL_TRUE); glBindVertexArray(0);
- }
-
- auto OpenGLRenderer::draw_frame(const glm::vec4& clear_color,
- const std::function<void()>& build_ui) -> void
- {
- auto* win = static_cast<GLFWwindow*>(m_window);
- process_input();
-
- int w = 0, h = 0; glfwGetFramebufferSize(win, &w, &h);
-
- if (m_scene_mode)
- {
- render_scene(w, h);
- }
- else
- {
- m_engine->set_window_dimensions(w, h);
- // Geodesic pass -> low-res texture (watchdog-tiled on macOS), then
- // upscale to the window. Disk/camera come from the shared BlackHoleParams.
- m_engine->dispatch_compute(m_engine->get_camera());
- RenderCommand::set_viewport(0, 0, w, h);
- RenderCommand::set_clear_color(clear_color);
- RenderCommand::clear();
- m_engine->draw_full_screen_quad();
- }
-
- if (m_ui_ready)
- {
- ImGui_ImplOpenGL3_NewFrame();
- ImGui_ImplGlfw_NewFrame();
- ImGui::NewFrame();
- if (build_ui) build_ui();
- ImGui::Render();
- ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
- }
- glfwSwapBuffers(win);
- }
-
- auto OpenGLRenderer::set_scene_mode(bool enabled) -> void { m_scene_mode = enabled; }
- auto OpenGLRenderer::is_scene_mode() const -> bool { return m_scene_mode; }
-
- auto OpenGLRenderer::set_free_fly(bool enabled) -> void
- {
- Camera& cam = m_engine->get_camera();
- if (enabled && cam.get_camera_mode() != CameraMode::FPS)
- {
- glm::vec3 pos = cam.get_orbital_position();
- glm::vec3 fwd = glm::normalize(cam.get_orbital_target() - pos);
- float pitch = glm::degrees(asinf(glm::clamp(fwd.y, -1.0f, 1.0f)));
- float yaw = glm::degrees(atan2f(fwd.z, fwd.x));
- cam.set_position(pos);
- cam.set_rotation(glm::vec3(pitch, yaw, 0.0f));
- cam.set_movement_speed(2.0e10f);
- cam.set_mouse_sensitivity(0.15f);
- cam.set_camera_mode(CameraMode::FPS);
- }
- else if (!enabled)
- {
- cam.set_camera_mode(CameraMode::Orbital);
- }
- }
-
- auto OpenGLRenderer::is_free_fly() const -> bool
- {
- return m_engine->get_camera().get_camera_mode() == CameraMode::FPS;
- }
-
- auto OpenGLRenderer::reset_camera() -> void
- {
- Camera& cam = m_engine->get_camera();
- cam.set_camera_mode(CameraMode::Orbital);
- cam.set_orbital_radius(4e11);
- cam.set_azimuth(0.0f);
- cam.set_elevation(1.25f);
- }
-
- auto OpenGLRenderer::set_hdri(const std::string& path) -> void
- {
- HDRIManager::get().set_current_hdri(path); // the Engine re-reads it each frame
- m_hdri_path = path;
- }
-
- auto OpenGLRenderer::current_hdri() const -> const std::string& { return m_hdri_path; }
- auto OpenGLRenderer::scene_objects() -> std::vector<SceneObject>& { return m_scene_objects; }
- auto OpenGLRenderer::set_selected_object(int index) -> void { m_selected_object = index; }
- auto OpenGLRenderer::black_hole_params() -> BlackHoleParams& { return m_engine->black_hole_params(); }
- auto OpenGLRenderer::device_name() const -> const std::string& { return m_device_name; }
-}