#pragma once #include "graphics/opengl/texture.hpp" #include #include #include #include #include namespace kuiper { namespace gl { class framebuffer { public: using s_ptr = std::shared_ptr; // OpenGL mandates at least 8 colour buffers static constexpr std::uint32_t max_colour_attachments = 8; using col_tex_storage = std::array; explicit framebuffer(GLuint id) : m_id(id) {} ~framebuffer() { destroy(); } framebuffer(const framebuffer& other) = delete; framebuffer& operator=(const framebuffer& other) = delete; framebuffer(framebuffer&& other) noexcept = default; framebuffer& operator=(framebuffer&& other) noexcept = default; static s_ptr make() noexcept; static s_ptr make_default(std::uint32_t width, std::uint32_t height) noexcept; public: void destroy() noexcept; void bind() const noexcept; void resize(std::uint32_t width, std::uint32_t height) noexcept; GLuint id() const noexcept { return m_id; } const col_tex_storage& colour_tex() const noexcept { return m_colour_texs; } const texture::s_ptr& depth_tex() const noexcept { return m_depth_tex; } glm::u32vec2 dimensions() const noexcept { return {m_width, m_height}; } // Attach a colour texture to the framebuffer, optionally at a given attachment point. Takes ownership of `tex`. void attach_colour(texture::s_ptr&& tex, std::uint32_t attachment_point = 0) noexcept; // Attach a depth AND stencil texture to the framebuffer. Takes ownership of `tex`. void attach_depth(texture::s_ptr&& tex) noexcept; private: GLuint m_id {0}; col_tex_storage m_colour_texs {}; texture::s_ptr m_depth_tex {nullptr}; std::uint32_t m_width {0}; std::uint32_t m_height {0}; }; } // namespace gl } // namespace kuiper