hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/engine.cpp110
-rw-r--r--src/engine/engine.h12
2 files changed, 95 insertions, 27 deletions
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
index 28cce2f..4b97a7a 100644
--- a/src/engine/engine.cpp
+++ b/src/engine/engine.cpp
@@ -33,7 +33,7 @@ namespace Donut
{ 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) }
};
- m_compute_program = create_compute_program("assets/shaders/geodesic.glsl");
+ m_compute_program = Ref<Shader>(Shader::create("assets/shaders/geodesic.glsl"));
m_shader_program = Ref<Shader>(Shader::create("assets/shaders/textured_quad.glsl"));
m_blur_shader = Ref<Shader>(Shader::create("assets/shaders/blur.glsl"));
@@ -60,6 +60,23 @@ namespace Donut
auto result = quad_vao();
m_quad_vao = result.first;
m_texture = result.second;
+
+ 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);
}
void Engine::update_window_dimensions()
@@ -126,30 +143,61 @@ namespace Donut
RenderCommand::enable_depth_test();
}
+ void Engine::draw_geodesic_pass(int cw, int ch)
+ {
+ m_quad_vao->bind();
+ RenderCommand::disable_depth_test();
+
+#ifdef __APPLE__
+ const int tile = 24;
+ 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();
+ }
+
void Engine::dispatch_compute(const Camera& cam)
{
auto& hdri_manager = HDRIManager::get();
m_hdri_environment = hdri_manager.get_current_hdri();
-
+
int cw = get_compute_width();
int ch = m_compute_height;
- m_texture->set_data(nullptr, cw * ch * 4);
+ 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_texture->bind_as_image(0, false);
-
+ 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);
-
- uint32_t groups_x = static_cast<uint32_t>(std::ceil(cw / 16.0f));
- uint32_t groups_y = static_cast<uint32_t>(std::ceil(ch / 16.0f));
- m_compute_program->dispatch(groups_x, groups_y, 1);
- m_compute_program->memory_barrier(IMAGE_ACCESS_BARRIER_BIT);
+ m_compute_program->set_int("u_HDRIEnvironment", 5);
+ }
+
+ draw_geodesic_pass(cw, ch);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Engine::upload_camera_ubo(const Camera& cam)
@@ -235,6 +283,11 @@ namespace Donut
data.early_exit_distance = m_early_exit_distance;
data.time = static_cast<float>(glfwGetTime()) * m_rotation_speed;
+#ifdef __APPLE__
+ data.max_steps_moving = std::min(data.max_steps_moving, 10000);
+ data.max_steps_static = std::min(data.max_steps_static, 10000);
+#endif
+
m_simulation_ubo->set_data(&data, sizeof(data));
m_simulation_ubo->bind(4);
}
@@ -427,21 +480,19 @@ namespace Donut
return;
}
- high_res_framebuffer->bind();
-
- RenderCommand::set_viewport(0, 0, width, height);
- RenderCommand::clear();
-
auto high_res_texture = Texture2D::create(compute_width, compute_height);
if (!high_res_texture)
{
DONUT_ERROR("Failed to create high-resolution texture");
return;
}
-
- high_res_texture->set_data(nullptr, compute_width * compute_height * 4);
+
+ 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;
@@ -469,17 +520,24 @@ namespace Donut
m_camera_ubo->set_data(&data, sizeof(UBOData));
m_camera_ubo->bind(1);
-
+
upload_disk_ubo();
upload_objects_ubo(m_objects);
upload_simulation_ubo();
- high_res_texture->bind_as_image(0, false);
-
- uint32_t groups_x = static_cast<uint32_t>(std::ceil(compute_width / 16.0f));
- uint32_t groups_y = static_cast<uint32_t>(std::ceil(compute_height / 16.0f));
- m_compute_program->dispatch(groups_x, groups_y, 1);
- m_compute_program->memory_barrier(IMAGE_ACCESS_BARRIER_BIT);
-
+ 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);
+
+ high_res_framebuffer->bind();
+ RenderCommand::set_viewport(0, 0, width, height);
+ RenderCommand::clear();
+
m_shader_program->bind();
m_quad_vao->bind();
diff --git a/src/engine/engine.h b/src/engine/engine.h
index 88e0058..0a50612 100644
--- a/src/engine/engine.h
+++ b/src/engine/engine.h
@@ -89,7 +89,13 @@ namespace Donut
void set_target_fps(int fps) { m_target_fps = fps; }
int get_target_fps() const { return m_target_fps; }
float get_current_fps() const { return m_current_fps; }
- void set_compute_height(int height) { m_compute_height = height; }
+ void set_compute_height(int height)
+ {
+#ifdef __APPLE__
+ if (height > 256) height = 256;
+#endif
+ m_compute_height = height;
+ }
int get_compute_height() const { return m_compute_height; }
int get_compute_width() const { return (m_width * m_compute_height) / m_height; }
void update_compute_dimensions();
@@ -125,6 +131,8 @@ namespace Donut
private:
Ref<Shader> create_compute_program(const char* path);
std::pair<Ref<VertexArray>, Ref<Texture2D>> quad_vao();
+
+ void draw_geodesic_pass(int cw, int ch);
private:
Ref<VertexArray> m_quad_vao;
Ref<Texture2D> m_texture;
@@ -137,6 +145,8 @@ namespace Donut
Ref<UniformBuffer> m_objects_ubo;
Ref<UniformBuffer> m_simulation_ubo;
+ uint32_t m_geodesic_fbo = 0;
+
int m_width;
int m_height;
float m_width_f = 100.0f*1e10f;