diff options
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/engine.cpp | 110 | ||||
| -rw-r--r-- | src/engine/engine.h | 12 |
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; |
