mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 20:28:32 +09:00
[Feat] (MG_State/FramebufferState): Implement FramebufferAttachment, FramebufferObject and FramebufferState.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user