Files
MobileGL/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp
T

162 lines
5.9 KiB
C++

// MobileGL - MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp
// Copyright (c) 2025-2026 MobileGL-Dev
// Licensed under the GNU Lesser General Public License v3.0:
// https://www.gnu.org/licenses/gpl-3.0.txt
// https://www.gnu.org/licenses/lgpl-3.0.txt
// SPDX-License-Identifier: LGPL-3.0-only
// End of Source File Header
#include "FramebufferObject.h"
#include "MG_Util/Types.h"
namespace MobileGL::MG_State::GLState {
// FramebufferAttachmentObject
FramebufferAttachmentObject::FramebufferAttachmentObject(
const SharedPtr<MG_State::GLState::ITextureObject>& texture, Int level)
: m_texture(texture), m_textureLevel(level) {}
FramebufferAttachmentObject::FramebufferAttachmentObject(const SharedPtr<RenderbufferObject>& renderbuffer)
: m_renderbuffer(renderbuffer) {}
FramebufferAttachmentObject::FramebufferAttachmentObject(Bool IsValid)
: m_texture(nullptr), m_renderbuffer(nullptr) {
m_isValid = IsValid;
}
Bool FramebufferAttachmentObject::IsTexture() const {
return m_texture != nullptr;
}
Bool FramebufferAttachmentObject::IsRenderbuffer() const {
return m_renderbuffer != nullptr;
}
Bool FramebufferAttachmentObject::IsEmpty() const {
return m_texture == nullptr && m_renderbuffer == nullptr;
}
const SharedPtr<MG_State::GLState::ITextureObject>& FramebufferAttachmentObject::GetTexture() const {
return m_texture;
}
const SharedPtr<RenderbufferObject>& FramebufferAttachmentObject::GetRenderbuffer() const {
return m_renderbuffer;
}
Int FramebufferAttachmentObject::GetTextureLevel() const {
return m_textureLevel;
}
Bool FramebufferAttachmentObject::IsComplete() const {
if (IsTexture()) {
Bool complete = m_texture->IsComplete();
return complete;
} else if (IsRenderbuffer()) {
Bool complete = m_renderbuffer->IsAllocated();
return complete;
}
return false;
}
IntVec3 FramebufferAttachmentObject::GetSize() const {
if (IsTexture()) {
// TODO: get correct upload target
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get()),
"Texture object here should always be an object with mipmap");
auto textureMipmapObject = dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get());
return textureMipmapObject->GetMipmapTexelSize(TextureUploadTarget::Texture2D, m_textureLevel);
} else if (IsRenderbuffer()) {
return {m_renderbuffer->GetWidth(), m_renderbuffer->GetHeight(), 1};
}
return {0, 0, 0};
}
Bool FramebufferAttachmentObject::IsValid() const {
return m_isValid;
}
// FramebufferObject
FramebufferObject::FramebufferObject(Uint externalIndex)
: m_externalIndex(externalIndex), m_attachmentVersions{}, m_drawBuffers{} {
m_attachmentObjects.fill(FramebufferAttachmentObject(false));
m_drawBuffers.fill(FramebufferAttachmentType::None);
m_drawBuffers[0] = FramebufferAttachmentType::Color0;
m_attachmentVersions.fill(0);
}
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, const SharedPtr<ITextureObject>& texture,
int level) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(texture, level);
BumpAttachmentVersion(type);
}
void FramebufferObject::AttachRenderbuffer(FramebufferAttachmentType type,
const SharedPtr<RenderbufferObject>& renderbuffer) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(renderbuffer);
BumpAttachmentVersion(type);
}
void FramebufferObject::Detach(FramebufferAttachmentType type) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(false);
BumpAttachmentVersion(type);
}
const FramebufferAttachmentObject& FramebufferObject::GetAttachment(FramebufferAttachmentType type) const {
return m_attachmentObjects[static_cast<SizeT>(type)];
}
const FramebufferObject::FramebufferAttachmentObjectArray& FramebufferObject::GetAllAttachmentObjects() const {
return m_attachmentObjects;
}
Bool FramebufferObject::CheckCompleteness() const {
if (m_attachmentObjects.empty()) {
return false;
}
Int width = -1, height = -1;
Int validAttachmentCount = 0;
for (const auto& attachmentObject : m_attachmentObjects) {
if (!attachmentObject.IsValid()) continue;
++validAttachmentCount;
const auto& attachment = attachmentObject;
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;
}
}
if (validAttachmentCount == 0) return false;
return true;
}
void FramebufferObject::SetDrawBuffer(Uint index, FramebufferAttachmentType buffer) {
if (m_drawBuffers[index] == buffer) return;
m_drawBuffers[index] = buffer;
BumpAttachmentVersion(buffer);
}
const FramebufferObject::FramebufferAttachmentArray& FramebufferObject::GetDrawBuffers() const {
return m_drawBuffers;
}
Uint FramebufferObject::GetExternalIndex() const {
return m_externalIndex;
}
void FramebufferObject::BumpAttachmentVersion(FramebufferAttachmentType type) {
++m_attachmentVersions[static_cast<SizeT>(type)];
++m_objectVersion;
}
} // namespace MobileGL::MG_State::GLState