mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +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/ShaderObject.cpp
|
||||||
MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp
|
MobileGL/MG_State/GLState/ProgramState/ProgramState.cpp
|
||||||
MobileGL/MG_State/GLState/RenderState/RenderState.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
|
add_library(${CMAKE_PROJECT_NAME} SHARED
|
||||||
|
|||||||
@@ -289,6 +289,35 @@ namespace MobileGL {
|
|||||||
return m_renderState.IsCullFaceEnabled();
|
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
|
} // namespace GLState
|
||||||
|
|
||||||
GLState::GLContext* pGLContext;
|
GLState::GLContext* pGLContext;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "BufferState/BufferState.h"
|
#include "BufferState/BufferState.h"
|
||||||
#include "ProgramState/ProgramState.h"
|
#include "ProgramState/ProgramState.h"
|
||||||
#include "TextureState/TextureState.h"
|
#include "TextureState/TextureState.h"
|
||||||
|
#include "FramebufferState/FramebufferState.h"
|
||||||
#include "VertexArrayState/VertexArrayState.h"
|
#include "VertexArrayState/VertexArrayState.h"
|
||||||
#include "MG_State/GLState/RenderState/RenderState.h"
|
#include "MG_State/GLState/RenderState/RenderState.h"
|
||||||
|
|
||||||
@@ -92,6 +93,15 @@ namespace MobileGL {
|
|||||||
void SetCullFaceEnabled(Bool enabled);
|
void SetCullFaceEnabled(Bool enabled);
|
||||||
Bool IsCullFaceEnabled() const;
|
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:
|
private:
|
||||||
// Error
|
// Error
|
||||||
ErrorState m_errorState;
|
ErrorState m_errorState;
|
||||||
@@ -110,6 +120,9 @@ namespace MobileGL {
|
|||||||
|
|
||||||
// RenderState
|
// RenderState
|
||||||
RenderState m_renderState;
|
RenderState m_renderState;
|
||||||
|
|
||||||
|
// Framebuffer
|
||||||
|
FramebufferState m_framebufferState;
|
||||||
};
|
};
|
||||||
} // namespace GLState
|
} // 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