From 6823b1e46aed984ef9e8a5bfe953768f45330d96 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Tue, 3 Feb 2026 12:59:11 +0800 Subject: [PATCH 1/2] [Feat] (MG_Impl/Framebuffer): implement `glReadBuffer` --- .../GLImpl/Framebuffer/GL_Framebuffer.cpp | 19 +++++++- .../FramebufferState/FramebufferObject.cpp | 45 +++++++++---------- .../FramebufferState/FramebufferObject.h | 32 ++++++------- 3 files changed, 55 insertions(+), 41 deletions(-) diff --git a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp index 6419350a..f0746053 100644 --- a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp @@ -304,8 +304,23 @@ namespace MobileGL { } } - void ReadBuffer_State(GLenum src) { - // TODO: implement + void ReadBuffer_State(GLenum mode) { + auto attType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(mode); + + // ------------------- Check validity begin ------------------------ + if (attType == FramebufferAttachmentType::Unknown) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidEnum, + MakeShared("MG_Impl/GLImpl", __func__, + std::format("`mode` = {} is not an accepted value.", + MG_Util::ConvertGLEnumToString(mode)))); + return; + } + + // Get bound framebuffer + auto& bindingSlot = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read); + auto fbo = bindingSlot.GetBoundObject(); + fbo->SetReadBuffer(attType); } void DeleteRenderbuffers_State(GLsizei n, const GLuint* renderbuffers) { diff --git a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp index 899e2676..3298e640 100644 --- a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp +++ b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp @@ -12,41 +12,41 @@ namespace MobileGL { namespace MG_State { namespace GLState { - // FramebufferAttachment - FramebufferAttachment::FramebufferAttachment(SharedPtr texture, - Int level) + // FramebufferAttachmentObject + FramebufferAttachmentObject::FramebufferAttachmentObject(SharedPtr texture, + Int level) : m_texture(texture), m_textureLevel(level) {} - FramebufferAttachment::FramebufferAttachment(SharedPtr renderbuffer) + FramebufferAttachmentObject::FramebufferAttachmentObject(SharedPtr renderbuffer) : m_renderbuffer(renderbuffer) {} - FramebufferAttachment::FramebufferAttachment(Bool IsValid) : m_texture(nullptr), m_renderbuffer(nullptr) { + FramebufferAttachmentObject::FramebufferAttachmentObject(Bool IsValid) : m_texture(nullptr), m_renderbuffer(nullptr) { m_isValid = IsValid; } - Bool FramebufferAttachment::IsTexture() const { + Bool FramebufferAttachmentObject::IsTexture() const { return m_texture != nullptr; } - Bool FramebufferAttachment::IsRenderbuffer() const { + Bool FramebufferAttachmentObject::IsRenderbuffer() const { return m_renderbuffer != nullptr; } - Bool FramebufferAttachment::IsEmpty() const { + Bool FramebufferAttachmentObject::IsEmpty() const { return m_texture == nullptr && m_renderbuffer == nullptr; } - SharedPtr FramebufferAttachment::GetTexture() const { + SharedPtr FramebufferAttachmentObject::GetTexture() const { return m_texture; } - SharedPtr FramebufferAttachment::GetRenderbuffer() const { + SharedPtr FramebufferAttachmentObject::GetRenderbuffer() const { return m_renderbuffer; } - Int FramebufferAttachment::GetTextureLevel() const { + Int FramebufferAttachmentObject::GetTextureLevel() const { return m_textureLevel; } - Bool FramebufferAttachment::IsComplete() const { + Bool FramebufferAttachmentObject::IsComplete() const { if (IsTexture()) { Bool complete = m_texture->IsComplete(); return complete; @@ -58,7 +58,7 @@ namespace MobileGL { return false; } - IntVec3 FramebufferAttachment::GetSize() const { + IntVec3 FramebufferAttachmentObject::GetSize() const { if (IsTexture()) { // TODO: get correct upload target MOBILEGL_ASSERT(nullptr != dynamic_cast(m_texture.get()), @@ -71,41 +71,39 @@ namespace MobileGL { return {0, 0, 0}; } - Bool FramebufferAttachment::IsValid() const { + Bool FramebufferAttachmentObject::IsValid() const { return m_isValid; } // FramebufferObject FramebufferObject::FramebufferObject(Uint externalIndex) : m_externalIndex(externalIndex) { - m_attachments.fill(FramebufferAttachment(false)); + m_attachments.fill(FramebufferAttachmentObject(false)); m_drawBuffers.fill(FramebufferAttachmentType::None); m_drawBuffers[0] = FramebufferAttachmentType::Color0; } void FramebufferObject::AttachTexture(FramebufferAttachmentType type, SharedPtr texture, int level) { - m_attachments[static_cast(type)] = FramebufferAttachment(std::move(texture), level); + m_attachments[static_cast(type)] = FramebufferAttachmentObject(std::move(texture), level); m_drawBuffersDirty = true; } void FramebufferObject::AttachRenderbuffer(FramebufferAttachmentType type, std::shared_ptr renderbuffer) { - m_attachments[static_cast(type)] = FramebufferAttachment(renderbuffer); + m_attachments[static_cast(type)] = FramebufferAttachmentObject(renderbuffer); m_drawBuffersDirty = true; } void FramebufferObject::Detach(FramebufferAttachmentType type) { - m_attachments[static_cast(type)] = FramebufferAttachment(false); + m_attachments[static_cast(type)] = FramebufferAttachmentObject(false); m_drawBuffersDirty = true; } - const FramebufferAttachment& FramebufferObject::GetAttachment(FramebufferAttachmentType type) const { + const FramebufferAttachmentObject& FramebufferObject::GetAttachment(FramebufferAttachmentType type) const { return m_attachments[static_cast(type)]; } - const Array(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>& - FramebufferObject::GetAllAttachments() const { + const FramebufferObject::FramebufferAttachmentObjectArray& FramebufferObject::GetAllAttachments() const { return m_attachments; } @@ -155,8 +153,7 @@ namespace MobileGL { // // } - const Array& FramebufferObject:: - GetDrawBuffers() const { + const FramebufferObject::FramebufferAttachmentArray& FramebufferObject::GetDrawBuffers() const { return m_drawBuffers; } diff --git a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.h b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.h index f8356cad..55e8b087 100644 --- a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.h +++ b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.h @@ -69,11 +69,11 @@ namespace MobileGL { namespace MG_State { namespace GLState { - class FramebufferAttachment { + class FramebufferAttachmentObject { public: - explicit FramebufferAttachment(SharedPtr texture, Int level = 0); - explicit FramebufferAttachment(SharedPtr renderbuffer); - explicit FramebufferAttachment(Bool IsValid = true); + explicit FramebufferAttachmentObject(SharedPtr texture, Int level = 0); + explicit FramebufferAttachmentObject(SharedPtr renderbuffer); + explicit FramebufferAttachmentObject(Bool IsValid = true); Bool IsTexture() const; Bool IsRenderbuffer() const; @@ -94,36 +94,38 @@ namespace MobileGL { class FramebufferObject { public: - using TargetEnum = FramebufferTarget; static constexpr Uint MAX_DRAW_BUFFERS = 8; + using TargetEnum = FramebufferTarget; + using FramebufferAttachmentObjectArray = + Array(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>; + using FramebufferAttachmentArray = Array; + FramebufferObject(Uint externalIndex); void AttachTexture(FramebufferAttachmentType type, SharedPtr texture, int level = 0); void AttachRenderbuffer(FramebufferAttachmentType type, std::shared_ptr renderbuffer); void Detach(FramebufferAttachmentType type); - const FramebufferAttachment& GetAttachment(FramebufferAttachmentType type) const; - const Array(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>& - GetAllAttachments() const; + const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const; + const FramebufferAttachmentObjectArray& GetAllAttachments() const; Bool CheckCompleteness() const; // aka. `buffer` as in glDrawBuffers/glReadBuffers void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer); bool DrawBuffersIsDirty() const { return m_drawBuffersDirty; } void ClearDrawBuffersDirtyState() { m_drawBuffersDirty = false; } - const Array& GetDrawBuffers() const; + const FramebufferAttachmentArray& GetDrawBuffers() const; + void SetReadBuffer(FramebufferAttachmentType buf) { m_readBuffer = buf; } FramebufferAttachmentType GetReadBuffer() const { return m_readBuffer; } Uint GetExternalIndex() const; private: const Uint m_externalIndex = 0; - Array(FramebufferAttachmentType::FramebufferAttachmentTypeCount)> - m_attachments; - Bool m_drawBuffersDirty = false; - Array m_drawBuffers; + FramebufferAttachmentObjectArray m_attachments; + FramebufferAttachmentArray m_drawBuffers; FramebufferAttachmentType m_readBuffer = FramebufferAttachmentType::Color0; + + Bool m_drawBuffersDirty = false; }; } // namespace GLState From 751c5745b0001a12f9adcb2f4d208c2ceaebbe91 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Tue, 3 Feb 2026 13:06:55 +0800 Subject: [PATCH 2/2] [Fix] (MG_Util/Converters): properly handle `GL_NONE` in `ConvertGLEnumToFramebufferAttachmentType` --- .../GLToMG/FramebufferEnumConverter.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/MobileGL/MG_Util/Converters/GLToMG/FramebufferEnumConverter.cpp b/MobileGL/MG_Util/Converters/GLToMG/FramebufferEnumConverter.cpp index 5e17b568..2336dd12 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/FramebufferEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/GLToMG/FramebufferEnumConverter.cpp @@ -30,13 +30,14 @@ namespace MobileGL { } switch (attachment) { - case GL_DEPTH_ATTACHMENT: - return FramebufferAttachmentType::Depth; - case GL_STENCIL_ATTACHMENT: - return FramebufferAttachmentType::Stencil; - case GL_UNKNOWN_MGL: - default: - return FramebufferAttachmentType::Unknown; + case GL_NONE: + return FramebufferAttachmentType::None; + case GL_DEPTH_ATTACHMENT: + return FramebufferAttachmentType::Depth; + case GL_STENCIL_ATTACHMENT: + return FramebufferAttachmentType::Stencil; + default: + return FramebufferAttachmentType::Unknown; } }