[Feat] (MG_State/FramebufferState): Implement FramebufferAttachment, FramebufferObject and FramebufferState.

This commit is contained in:
BZLZHH
2025-10-02 21:27:33 +08:00
parent 776e1d99cf
commit d6b54f8e30
7 changed files with 353 additions and 0 deletions
+2
View File
@@ -81,6 +81,8 @@ set(SOURCE_FILES
MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp
MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp
MobileGL/MG_State/GLState/RenderState/RenderState.cpp
MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp
MobileGL/MG_State/GLState/FramebufferState/FramebufferState.cpp
)
add_library(${CMAKE_PROJECT_NAME} SHARED
+29
View File
@@ -289,6 +289,35 @@ namespace MobileGL {
return m_renderState.IsCullFaceEnabled();
}
// Framebuffer
Vector<Uint> GLContext::GenFramebufferNames(Uint number) {
return m_framebufferState.GenerateNames(number);
}
SharedPtr<FramebufferObject> GLContext::GetFramebufferObject(Uint index) {
return m_framebufferState.GetFramebufferObject(index);
}
BindingSlot<FramebufferObject>& GLContext::GetFramebufferBindingSlot(FramebufferTarget target) {
return m_framebufferState.GetBindingSlot(target);
}
SharedPtr<FramebufferObject> GLContext::CreateFramebufferObject(Uint index) {
return m_framebufferState.CreateFramebufferObject(index);
}
void GLContext::MarkFramebufferObjectForDeletion(Uint index) {
m_framebufferState.MarkFramebufferObjectForDeletion(index);
}
Bool GLContext::ValidateFramebufferName(Uint index) const {
return m_framebufferState.ValidateName(index);
}
Bool GLContext::ValidateFramebufferObject(Uint index) const {
return m_framebufferState.ValidateFramebufferObject(index);
}
} // namespace GLState
GLState::GLContext* pGLContext;
+13
View File
@@ -5,6 +5,7 @@
#include "BufferState/BufferState.h"
#include "ProgramState/ProgramState.h"
#include "TextureState/TextureState.h"
#include "FramebufferState/FramebufferState.h"
#include "VertexArrayState/VertexArrayState.h"
#include "MG_State/GLState/RenderState/RenderState.h"
@@ -92,6 +93,15 @@ namespace MobileGL {
void SetCullFaceEnabled(Bool enabled);
Bool IsCullFaceEnabled() const;
// Framebuffer
Vector<Uint> GenFramebufferNames(Uint number);
SharedPtr<FramebufferObject> GetFramebufferObject(Uint index);
BindingSlot<FramebufferObject>& GetFramebufferBindingSlot(FramebufferTarget target);
SharedPtr<FramebufferObject> CreateFramebufferObject(Uint index);
void MarkFramebufferObjectForDeletion(Uint index);
Bool ValidateFramebufferName(Uint index) const;
Bool ValidateFramebufferObject(Uint index) const;
private:
// Error
ErrorState m_errorState;
@@ -110,6 +120,9 @@ namespace MobileGL {
// RenderState
RenderState m_renderState;
// Framebuffer
FramebufferState m_framebufferState;
};
} // namespace GLState
@@ -0,0 +1,113 @@
#include "FramebufferObject.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
// FramebufferAttachment
FramebufferAttachment::FramebufferAttachment(SharedPtr<MG_State::GLState::ITextureObject> texture,
Int level)
: m_texture(texture), m_textureLevel(level) {}
FramebufferAttachment::FramebufferAttachment(SharedPtr<RenderbufferObjectStub> renderbuffer)
: m_renderbuffer(renderbuffer) {}
FramebufferAttachment::FramebufferAttachment(std::nullptr_t)
: m_texture(nullptr), m_renderbuffer(nullptr) {}
Bool FramebufferAttachment::IsTexture() const {
return m_texture != nullptr;
}
Bool FramebufferAttachment::IsRenderbuffer() const {
return false;
}
Bool FramebufferAttachment::IsEmpty() {
return m_texture == nullptr && m_renderbuffer == nullptr;
}
SharedPtr<MG_State::GLState::ITextureObject> FramebufferAttachment::GetTexture() const {
return m_texture;
}
SharedPtr<RenderbufferObjectStub> FramebufferAttachment::GetRenderbuffer() const {
return m_renderbuffer;
}
Int FramebufferAttachment::GetTextureLevel() const {
return m_textureLevel;
}
Bool FramebufferAttachment::IsComplete() const {
if (IsTexture()) {
return m_texture->IsComplete();
} else if (IsRenderbuffer()) {
// TODO
}
return false;
}
IntVec3 FramebufferAttachment::GetSize() const {
if (IsTexture()) {
return m_texture->GetMipmap(m_textureLevel).size;
} else if (IsRenderbuffer()) {
// TODO
}
return {0, 0};
}
// FramebufferObject
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture,
int level) {
m_attachments[static_cast<SizeT>(type)] = FramebufferAttachment(std::move(texture), level);
m_drawBuffersDirty = true;
}
void FramebufferObject::AttachRenderbuffer(FramebufferAttachmentType type,
std::shared_ptr<RenderbufferObjectStub> renderbuffer) {
m_attachments[static_cast<SizeT>(type)] = FramebufferAttachment(renderbuffer);
m_drawBuffersDirty = true;
}
void FramebufferObject::Detach(FramebufferAttachmentType type) {
m_attachments[static_cast<SizeT>(type)] = FramebufferAttachment(nullptr);
m_drawBuffersDirty = true;
}
const FramebufferAttachment& FramebufferObject::GetAttachment(FramebufferAttachmentType type) const {
return m_attachments[static_cast<SizeT>(type)];
}
Bool FramebufferObject::CheckCompleteness() const {
if (m_attachments.empty()) {
return false;
}
int width = -1, height = -1;
for (const auto& attachment : m_attachments) {
auto attachmentSize = attachment.GetSize();
int w = attachmentSize.x();
int h = attachmentSize.y();
if (width == -1) {
width = w;
height = h;
} else if (width != w || height != h) {
return false;
}
if (!attachment.IsComplete()) {
return false;
}
}
return true;
}
void FramebufferObject::SetDrawBuffers(const std::vector<FramebufferAttachmentType>& buffers) {
m_drawBuffers = buffers;
m_drawBuffersDirty = true;
}
const Vector<FramebufferAttachmentType>& FramebufferObject::GetDrawBuffers() const {
return m_drawBuffers;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -0,0 +1,105 @@
#pragma once
#include "MG_Util/Types.h"
#include <Includes.h>
#include <MG_State/GLState/TextureState/TextureObject.h>
namespace MobileGL {
enum class FramebufferTarget {
Draw,
Read,
FramebufferTargetCount,
Unknown = -1
};
enum class FramebufferAttachmentType {
Color0,
Color1,
Color2,
Color3,
Color4,
Color5,
Color6,
Color7,
Color8,
Color9,
Color10,
Color11,
Color12,
Color13,
Color14,
Color15,
Color16,
Color17,
Color18,
Color19,
Color20,
Color21,
Color22,
Color23,
Color24,
Color25,
Color26,
Color27,
Color28,
Color29,
Color30,
Color31,
Depth,
Stencil,
DepthStencil,
FramebufferAttachmentTypeCount,
Unknown = -1
};
namespace MG_State {
namespace GLState {
class RenderbufferObjectStub {}; // TODO
class FramebufferAttachment {
public:
// TODO: add Renderbuffer when it is implemented
explicit FramebufferAttachment(SharedPtr<MG_State::GLState::ITextureObject> texture, Int level = 0);
explicit FramebufferAttachment(SharedPtr<RenderbufferObjectStub> renderbuffer);
explicit FramebufferAttachment(std::nullptr_t);
Bool IsTexture() const;
Bool IsRenderbuffer() const;
Bool IsEmpty();
SharedPtr<MG_State::GLState::ITextureObject> GetTexture() const;
SharedPtr<RenderbufferObjectStub> GetRenderbuffer() const;
Int GetTextureLevel() const;
Bool IsComplete() const;
IntVec3 GetSize() const;
private:
SharedPtr<MG_State::GLState::ITextureObject> m_texture;
SharedPtr<RenderbufferObjectStub> m_renderbuffer;
Int m_textureLevel = 0;
};
class FramebufferObject {
public:
using TargetEnum = FramebufferTarget;
FramebufferObject();
void AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture, int level = 0);
void AttachRenderbuffer(FramebufferAttachmentType type,
std::shared_ptr<RenderbufferObjectStub> renderbuffer);
void Detach(FramebufferAttachmentType type);
const FramebufferAttachment& GetAttachment(FramebufferAttachmentType type) const;
Bool CheckCompleteness() const;
void SetDrawBuffers(const std::vector<FramebufferAttachmentType>& buffers);
const Vector<FramebufferAttachmentType>& GetDrawBuffers() const;
private:
Array<FramebufferAttachment,
static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>
m_attachments;
Bool m_drawBuffersDirty = true;
Vector<FramebufferAttachmentType> m_drawBuffers;
};
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -0,0 +1,62 @@
#include "FramebufferState.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
FramebufferState::FramebufferState() {}
SharedPtr<FramebufferObject> FramebufferState::GetFramebufferObject(Uint index) {
auto it = m_bufferObjects.find(index);
if (it != m_bufferObjects.end()) {
return it->second;
}
return nullptr;
}
Vector<Uint> FramebufferState::GenerateNames(Uint number) {
Vector<Uint> buffers(number);
m_indexGenerator.Generate(number, buffers.data());
return buffers;
}
SharedPtr<FramebufferObject> FramebufferState::CreateFramebufferObject(Uint index) {
auto bufferObject = MakeShared<FramebufferObject>();
m_bufferObjects[index] = bufferObject;
return bufferObject;
}
BindingSlot<FramebufferObject>& FramebufferState::GetBindingSlot(FramebufferTarget target) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
if (m_bindingSlots[i].GetTarget() == target) {
return m_bindingSlots[i];
}
}
assert(false);
return m_bindingSlots[0];
}
void FramebufferState::MarkFramebufferObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
auto it = m_bufferObjects.find(index);
if (it != m_bufferObjects.end()) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
if (m_bindingSlots[i].GetBoundObject() == it->second) {
m_bindingSlots[i].Bind(nullptr);
}
}
m_bufferObjects.erase(it);
}
m_indexGenerator.Delete(index);
}
}
Bool FramebufferState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool FramebufferState::ValidateFramebufferObject(Uint index) const {
return m_bufferObjects.find(index) != m_bufferObjects.end();
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -0,0 +1,29 @@
#pragma once
#include <Includes.h>
#include <MG_Util/Miscellany/IndexGenerator.h>
#include "FramebufferObject.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
class FramebufferState {
public:
FramebufferState();
SharedPtr<FramebufferObject> GetFramebufferObject(Uint index);
Vector<Uint> GenerateNames(Uint number);
SharedPtr<FramebufferObject> CreateFramebufferObject(Uint index);
BindingSlot<FramebufferObject>& GetBindingSlot(FramebufferTarget target);
void MarkFramebufferObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const;
Bool ValidateFramebufferObject(Uint index) const;
private:
UnorderedMap<Uint, SharedPtr<FramebufferObject>> m_bufferObjects;
IndexGenerator<Uint> m_indexGenerator;
Array<BindingSlot<FramebufferObject>, static_cast<SizeT>(FramebufferTarget::FramebufferTargetCount)>
m_bindingSlots;
};
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL