[Feat] (MG_Impl/Framebuffer): implement glReadBuffer

This commit is contained in:
2026-02-03 12:59:11 +08:00
parent 207b746273
commit 6823b1e46a
3 changed files with 55 additions and 41 deletions
@@ -304,8 +304,23 @@ namespace MobileGL {
} }
} }
void ReadBuffer_State(GLenum src) { void ReadBuffer_State(GLenum mode) {
// TODO: implement auto attType = MG_Util::ConvertGLEnumToFramebufferAttachmentType(mode);
// ------------------- Check validity begin ------------------------
if (attType == FramebufferAttachmentType::Unknown) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("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) { void DeleteRenderbuffers_State(GLsizei n, const GLuint* renderbuffers) {
@@ -12,41 +12,41 @@
namespace MobileGL { namespace MobileGL {
namespace MG_State { namespace MG_State {
namespace GLState { namespace GLState {
// FramebufferAttachment // FramebufferAttachmentObject
FramebufferAttachment::FramebufferAttachment(SharedPtr<MG_State::GLState::ITextureObject> texture, FramebufferAttachmentObject::FramebufferAttachmentObject(SharedPtr<MG_State::GLState::ITextureObject> texture,
Int level) Int level)
: m_texture(texture), m_textureLevel(level) {} : m_texture(texture), m_textureLevel(level) {}
FramebufferAttachment::FramebufferAttachment(SharedPtr<RenderbufferObject> renderbuffer) FramebufferAttachmentObject::FramebufferAttachmentObject(SharedPtr<RenderbufferObject> renderbuffer)
: m_renderbuffer(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; m_isValid = IsValid;
} }
Bool FramebufferAttachment::IsTexture() const { Bool FramebufferAttachmentObject::IsTexture() const {
return m_texture != nullptr; return m_texture != nullptr;
} }
Bool FramebufferAttachment::IsRenderbuffer() const { Bool FramebufferAttachmentObject::IsRenderbuffer() const {
return m_renderbuffer != nullptr; return m_renderbuffer != nullptr;
} }
Bool FramebufferAttachment::IsEmpty() const { Bool FramebufferAttachmentObject::IsEmpty() const {
return m_texture == nullptr && m_renderbuffer == nullptr; return m_texture == nullptr && m_renderbuffer == nullptr;
} }
SharedPtr<MG_State::GLState::ITextureObject> FramebufferAttachment::GetTexture() const { SharedPtr<MG_State::GLState::ITextureObject> FramebufferAttachmentObject::GetTexture() const {
return m_texture; return m_texture;
} }
SharedPtr<RenderbufferObject> FramebufferAttachment::GetRenderbuffer() const { SharedPtr<RenderbufferObject> FramebufferAttachmentObject::GetRenderbuffer() const {
return m_renderbuffer; return m_renderbuffer;
} }
Int FramebufferAttachment::GetTextureLevel() const { Int FramebufferAttachmentObject::GetTextureLevel() const {
return m_textureLevel; return m_textureLevel;
} }
Bool FramebufferAttachment::IsComplete() const { Bool FramebufferAttachmentObject::IsComplete() const {
if (IsTexture()) { if (IsTexture()) {
Bool complete = m_texture->IsComplete(); Bool complete = m_texture->IsComplete();
return complete; return complete;
@@ -58,7 +58,7 @@ namespace MobileGL {
return false; return false;
} }
IntVec3 FramebufferAttachment::GetSize() const { IntVec3 FramebufferAttachmentObject::GetSize() const {
if (IsTexture()) { if (IsTexture()) {
// TODO: get correct upload target // TODO: get correct upload target
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get()), MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get()),
@@ -71,41 +71,39 @@ namespace MobileGL {
return {0, 0, 0}; return {0, 0, 0};
} }
Bool FramebufferAttachment::IsValid() const { Bool FramebufferAttachmentObject::IsValid() const {
return m_isValid; return m_isValid;
} }
// FramebufferObject // FramebufferObject
FramebufferObject::FramebufferObject(Uint externalIndex) : m_externalIndex(externalIndex) { FramebufferObject::FramebufferObject(Uint externalIndex) : m_externalIndex(externalIndex) {
m_attachments.fill(FramebufferAttachment(false)); m_attachments.fill(FramebufferAttachmentObject(false));
m_drawBuffers.fill(FramebufferAttachmentType::None); m_drawBuffers.fill(FramebufferAttachmentType::None);
m_drawBuffers[0] = FramebufferAttachmentType::Color0; m_drawBuffers[0] = FramebufferAttachmentType::Color0;
} }
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture, void FramebufferObject::AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture,
int level) { int level) {
m_attachments[static_cast<SizeT>(type)] = FramebufferAttachment(std::move(texture), level); m_attachments[static_cast<SizeT>(type)] = FramebufferAttachmentObject(std::move(texture), level);
m_drawBuffersDirty = true; m_drawBuffersDirty = true;
} }
void FramebufferObject::AttachRenderbuffer(FramebufferAttachmentType type, void FramebufferObject::AttachRenderbuffer(FramebufferAttachmentType type,
std::shared_ptr<RenderbufferObject> renderbuffer) { std::shared_ptr<RenderbufferObject> renderbuffer) {
m_attachments[static_cast<SizeT>(type)] = FramebufferAttachment(renderbuffer); m_attachments[static_cast<SizeT>(type)] = FramebufferAttachmentObject(renderbuffer);
m_drawBuffersDirty = true; m_drawBuffersDirty = true;
} }
void FramebufferObject::Detach(FramebufferAttachmentType type) { void FramebufferObject::Detach(FramebufferAttachmentType type) {
m_attachments[static_cast<SizeT>(type)] = FramebufferAttachment(false); m_attachments[static_cast<SizeT>(type)] = FramebufferAttachmentObject(false);
m_drawBuffersDirty = true; m_drawBuffersDirty = true;
} }
const FramebufferAttachment& FramebufferObject::GetAttachment(FramebufferAttachmentType type) const { const FramebufferAttachmentObject& FramebufferObject::GetAttachment(FramebufferAttachmentType type) const {
return m_attachments[static_cast<SizeT>(type)]; return m_attachments[static_cast<SizeT>(type)];
} }
const Array<FramebufferAttachment, const FramebufferObject::FramebufferAttachmentObjectArray& FramebufferObject::GetAllAttachments() const {
static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>&
FramebufferObject::GetAllAttachments() const {
return m_attachments; return m_attachments;
} }
@@ -155,8 +153,7 @@ namespace MobileGL {
// //
// } // }
const Array<FramebufferAttachmentType, FramebufferObject::MAX_DRAW_BUFFERS>& FramebufferObject:: const FramebufferObject::FramebufferAttachmentArray& FramebufferObject::GetDrawBuffers() const {
GetDrawBuffers() const {
return m_drawBuffers; return m_drawBuffers;
} }
@@ -69,11 +69,11 @@ namespace MobileGL {
namespace MG_State { namespace MG_State {
namespace GLState { namespace GLState {
class FramebufferAttachment { class FramebufferAttachmentObject {
public: public:
explicit FramebufferAttachment(SharedPtr<MG_State::GLState::ITextureObject> texture, Int level = 0); explicit FramebufferAttachmentObject(SharedPtr<MG_State::GLState::ITextureObject> texture, Int level = 0);
explicit FramebufferAttachment(SharedPtr<RenderbufferObject> renderbuffer); explicit FramebufferAttachmentObject(SharedPtr<RenderbufferObject> renderbuffer);
explicit FramebufferAttachment(Bool IsValid = true); explicit FramebufferAttachmentObject(Bool IsValid = true);
Bool IsTexture() const; Bool IsTexture() const;
Bool IsRenderbuffer() const; Bool IsRenderbuffer() const;
@@ -94,36 +94,38 @@ namespace MobileGL {
class FramebufferObject { class FramebufferObject {
public: public:
using TargetEnum = FramebufferTarget;
static constexpr Uint MAX_DRAW_BUFFERS = 8; static constexpr Uint MAX_DRAW_BUFFERS = 8;
using TargetEnum = FramebufferTarget;
using FramebufferAttachmentObjectArray =
Array<FramebufferAttachmentObject, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
using FramebufferAttachmentArray = Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS>;
FramebufferObject(Uint externalIndex); FramebufferObject(Uint externalIndex);
void AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture, int level = 0); void AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture, int level = 0);
void AttachRenderbuffer(FramebufferAttachmentType type, void AttachRenderbuffer(FramebufferAttachmentType type,
std::shared_ptr<RenderbufferObject> renderbuffer); std::shared_ptr<RenderbufferObject> renderbuffer);
void Detach(FramebufferAttachmentType type); void Detach(FramebufferAttachmentType type);
const FramebufferAttachment& GetAttachment(FramebufferAttachmentType type) const; const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const;
const Array<FramebufferAttachment, const FramebufferAttachmentObjectArray& GetAllAttachments() const;
static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>&
GetAllAttachments() const;
Bool CheckCompleteness() const; Bool CheckCompleteness() const;
// aka. `buffer` as in glDrawBuffers/glReadBuffers // aka. `buffer` as in glDrawBuffers/glReadBuffers
void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer); void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer);
bool DrawBuffersIsDirty() const { return m_drawBuffersDirty; } bool DrawBuffersIsDirty() const { return m_drawBuffersDirty; }
void ClearDrawBuffersDirtyState() { m_drawBuffersDirty = false; } void ClearDrawBuffersDirtyState() { m_drawBuffersDirty = false; }
const Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS>& GetDrawBuffers() const; const FramebufferAttachmentArray& GetDrawBuffers() const;
void SetReadBuffer(FramebufferAttachmentType buf) { m_readBuffer = buf; }
FramebufferAttachmentType GetReadBuffer() const { return m_readBuffer; } FramebufferAttachmentType GetReadBuffer() const { return m_readBuffer; }
Uint GetExternalIndex() const; Uint GetExternalIndex() const;
private: private:
const Uint m_externalIndex = 0; const Uint m_externalIndex = 0;
Array<FramebufferAttachment, FramebufferAttachmentObjectArray m_attachments;
static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)> FramebufferAttachmentArray m_drawBuffers;
m_attachments;
Bool m_drawBuffersDirty = false;
Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS> m_drawBuffers;
FramebufferAttachmentType m_readBuffer = FramebufferAttachmentType::Color0; FramebufferAttachmentType m_readBuffer = FramebufferAttachmentType::Color0;
Bool m_drawBuffersDirty = false;
}; };
} // namespace GLState } // namespace GLState