aboutsummaryrefslogtreecommitdiff
path: root/src/engine
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-08-23 05:53:33 +0200
committerhachem <im@hachem.wtf>2026-08-23 05:53:33 +0200
commite3aa33fc9a99d8b817bda42a567a4c347e18ab32 (patch)
treeda0e7ba3ce97a3e545d95d49e366be128c6d2112 /src/engine
parent43cee69e40be3cb8b0341c3fc94171fe01712b8c (diff)
[add]: unified interface
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/engine.cpp55
-rw-r--r--src/engine/engine.h7
2 files changed, 40 insertions, 22 deletions
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
index 059fdda..bf5a2b6 100644
--- a/src/engine/engine.cpp
+++ b/src/engine/engine.cpp
@@ -51,7 +51,7 @@ namespace Donut
}
m_camera_ubo = UniformBuffer::create(128, 1);
- m_disk_ubo = UniformBuffer::create(sizeof(float) * 5, 2);
+ m_disk_ubo = UniformBuffer::create(sizeof(float) * 6, 2); // r1,r2,turbulence,thickness,brightness,temperature
uint32_t obj_ubo_size = sizeof(int) + 3 * sizeof(float)
+ 16 * (sizeof(glm::vec4) + sizeof(glm::vec4))
@@ -231,16 +231,25 @@ namespace Donut
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);
+ glm::vec3 pos, fwd;
+ if (cam.get_camera_mode() == CameraMode::FPS)
+ {
+ pos = cam.get_position();
+ fwd = cam.get_forward_direction();
+ }
+ else
+ {
+ pos = cam.get_orbital_position();
+ fwd = glm::normalize(cam.get_orbital_target() - pos);
+ }
+ glm::vec3 right = glm::normalize(glm::cross(fwd, glm::vec3(0, 1, 0)));
+ glm::vec3 up = glm::cross(right, fwd);
- data.pos = cam.get_orbital_position();
+ data.pos = pos;
data.right = right;
data.up = up;
data.forward = fwd;
- data.tan_half_fov = static_cast<float>(tan(glm::radians(60.0f * 0.5f)));
+ data.tan_half_fov = static_cast<float>(tan(glm::radians(m_bh.fov_degrees * 0.5f)));
data.aspect = static_cast<float>(get_compute_width()) / static_cast<float>(m_compute_height);
data.moving = cam.is_dragging() || cam.is_panning();
@@ -275,12 +284,17 @@ namespace Donut
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 };
-
+ // Layout matches the shared Geodesic Disk struct (same as Vulkan). Radii
+ // are in Schwarzschild radii x the shader's SagA_rs constant (1.269e10).
+ const float rs = 1.269e10f;
+ float disk_data[6] = {
+ std::max(m_bh.disk_inner_rs, 3.0f) * rs,
+ std::max(m_bh.disk_outer_rs, m_bh.disk_inner_rs + 0.5f) * rs,
+ std::max(m_bh.turbulence, 0.0f),
+ rs * 0.1f, // slab half-thickness (fixed)
+ std::max(m_bh.brightness, 0.0f),
+ std::max(m_bh.temperature, 1000.0f),
+ };
m_disk_ubo->set_data(disk_data, sizeof(disk_data));
m_disk_ubo->bind(2);
}
@@ -295,20 +309,17 @@ namespace Donut
float time;
} data;
- data.max_steps_moving = m_max_steps_moving;
- data.max_steps_static = m_max_steps_static;
+ data.max_steps_moving = m_bh.quality_steps;
+ data.max_steps_static = m_bh.quality_steps; // resolution/tiling is the lever, not step count
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);
+ // fragment shader under the OS GPU watchdog. Cap the step count so a
+ // single 64px tile stays under the safe per-submission budget (~25M
+ // pixel-steps); Windows/Linux keep the full count.
+ data.max_steps_moving = std::min(data.max_steps_moving, 6000);
data.max_steps_static = std::min(data.max_steps_static, 6000);
#endif
diff --git a/src/engine/engine.h b/src/engine/engine.h
index c7d02b5..fef8b57 100644
--- a/src/engine/engine.h
+++ b/src/engine/engine.h
@@ -12,6 +12,7 @@
#include "object.h"
#include "rendering/renderer.h"
+#include "rendering/renderer_backend.h"
#include "rendering/shader.h"
#include "rendering/vertex_array.h"
#include "rendering/texture.h"
@@ -131,6 +132,10 @@ namespace Donut
auto set_hdri_environment(Ref<CubemapTexture> hdri) -> void { m_hdri_environment = hdri; }
auto get_hdri_environment() const -> Ref<CubemapTexture> { return m_hdri_environment; }
+
+ // Shared live black-hole/disk parameters (drives the geodesic UBOs so the
+ // GL path renders identically to Vulkan). The OpenGL backend mutates this.
+ auto black_hole_params() -> BlackHoleParams& { return m_bh; }
private:
auto create_compute_program(const char* path) -> Ref<Shader>;
std::pair<Ref<VertexArray>, Ref<Texture2D>> QuadVAO();
@@ -175,6 +180,8 @@ namespace Donut
int m_max_steps_static = 30000;
float m_early_exit_distance = 5.0e11f;
+ BlackHoleParams m_bh; // shared UI-tunable disk/camera params (GL geodesic driver)
+
float m_disk_thickness = 0.1f;
float m_disk_density = 0.1f;
float m_rotation_speed = 1.0f;