diff options
Diffstat (limited to 'src/platform/opengl/opengl_device.cpp')
| -rw-r--r-- | src/platform/opengl/opengl_device.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/platform/opengl/opengl_device.cpp b/src/platform/opengl/opengl_device.cpp index 82fdae1..7ef0ba1 100644 --- a/src/platform/opengl/opengl_device.cpp +++ b/src/platform/opengl/opengl_device.cpp @@ -7,6 +7,7 @@ #include <glad/glad.h> #include <GLFW/glfw3.h> +#include <algorithm> #include <imgui.h> #include <imgui_impl_glfw.h> #include <imgui_impl_opengl3.h> @@ -18,7 +19,7 @@ namespace Donut::RHI auto gl_topology(Topology t) -> GLenum { return t == Topology::Lines ? GL_LINES : GL_TRIANGLES; } auto gl_compare(CompareOp o) -> GLenum { return o == CompareOp::Always ? GL_ALWAYS : o == CompareOp::LessEqual ? GL_LEQUAL : GL_LESS; } auto gl_filter(Filter f) -> GLint { return f == Filter::Nearest ? GL_NEAREST : GL_LINEAR; } - auto gl_internal(Format f) -> GLint { return f == Format::RGBA16F ? GL_RGBA16F : f == Format::D32 ? GL_DEPTH_COMPONENT32F : GL_RGBA8; } + auto gl_internal(Format f) -> GLint { return f == Format::RGBA16F ? GL_RGBA16F : f == Format::RGBA32F ? GL_RGBA32F : f == Format::D32 ? GL_DEPTH_COMPONENT32F : GL_RGBA8; } // ---- Buffer ------------------------------------------------------- class GLBuffer : public Buffer @@ -255,6 +256,37 @@ namespace Donut::RHI } auto end_frame() -> void override { glfwSwapBuffers(static_cast<GLFWwindow*>(m_window)); } + auto run_offscreen(const std::function<void(CommandList&)>& record) -> void override + { + glBindVertexArray(m_vao); // GL is immediate: record executes now + record(*m_cmds); + glFinish(); + } + auto read_render_target(RenderTarget* target, std::vector<uint8_t>& out) -> void override + { + auto* rt = static_cast<GLRenderTarget*>(target); + int w = rt->m_w, h = rt->m_h; + out.resize((size_t)w * h * 4); + glBindFramebuffer(GL_FRAMEBUFFER, rt->m_fbo); + glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, out.data()); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + const size_t row = (size_t)w * 4; // GL is bottom-up -> flip to top-left + for (int y = 0; y < h / 2; ++y) + std::swap_ranges(out.begin() + y * row, out.begin() + (y + 1) * row, out.begin() + (h - 1 - y) * row); + } + auto read_render_target_float(RenderTarget* target, std::vector<float>& out) -> void override + { + auto* rt = static_cast<GLRenderTarget*>(target); + int w = rt->m_w, h = rt->m_h; + out.resize((size_t)w * h * 4); + glBindFramebuffer(GL_FRAMEBUFFER, rt->m_fbo); + glReadPixels(0, 0, w, h, GL_RGBA, GL_FLOAT, out.data()); // GL converts to float32 + glBindFramebuffer(GL_FRAMEBUFFER, 0); + const size_t row = (size_t)w * 4; // GL is bottom-up -> flip to top-left + for (int y = 0; y < h / 2; ++y) + std::swap_ranges(out.begin() + y * row, out.begin() + (y + 1) * row, out.begin() + (h - 1 - y) * row); + } + auto init_imgui() -> void override { IMGUI_CHECKVERSION(); ImGui::CreateContext(); |
