diff --git a/CMakeLists.txt b/CMakeLists.txt index 78162e35..02fd54c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,6 +188,8 @@ set(SOURCE_FILES MobileGL/MG_State/GLState/FramebufferState/FramebufferState.cpp MobileGL/MG_State/GLState/SamplerState/SamplerObject.cpp MobileGL/MG_State/GLState/SamplerState/SamplerState.cpp + MobileGL/MG_State/GLState/RenderbufferState/RenderbufferObject.cpp + MobileGL/MG_State/GLState/RenderbufferState/RenderbufferState.cpp ) add_library(${CMAKE_PROJECT_NAME} SHARED diff --git a/MobileGL/MG_State/GLState/RenderbufferState/RenderbufferObject.cpp b/MobileGL/MG_State/GLState/RenderbufferState/RenderbufferObject.cpp new file mode 100644 index 00000000..f97263e6 --- /dev/null +++ b/MobileGL/MG_State/GLState/RenderbufferState/RenderbufferObject.cpp @@ -0,0 +1,32 @@ +#include "RenderbufferObject.h" + +namespace MobileGL { + namespace MG_State { + namespace GLState { + RenderbufferObject::RenderbufferObject(Uint externalIndex) : m_externalIndex(externalIndex) {} + + void RenderbufferObject::Storage(Int internalFormat, Int width, Int height) { + m_internalFormat = internalFormat; + m_width = width; + m_height = height; + m_allocated = true; + } + + Int RenderbufferObject::GetWidth() const { + return m_width; + } + + Int RenderbufferObject::GetHeight() const { + return m_height; + } + + Int RenderbufferObject::GetInternalFormat() const { + return m_internalFormat; + } + + Bool RenderbufferObject::IsAllocated() const { + return m_allocated; + } + } // namespace GLState + } // namespace MG_State +} // namespace MobileGL \ No newline at end of file diff --git a/MobileGL/MG_State/GLState/RenderbufferState/RenderbufferObject.h b/MobileGL/MG_State/GLState/RenderbufferState/RenderbufferObject.h new file mode 100644 index 00000000..0c49ab44 --- /dev/null +++ b/MobileGL/MG_State/GLState/RenderbufferState/RenderbufferObject.h @@ -0,0 +1,34 @@ +#pragma once +#include + +namespace MobileGL { + enum class RenderbufferTarget { // fucky stuff in GL spec + Renderbuffer, + RenderbufferTargetCount, + Unknown = -1 + }; + + namespace MG_State { + namespace GLState { + class RenderbufferObject { + public: + using TargetEnum = RenderbufferTarget; + + RenderbufferObject(Uint externalIndex); + + void Storage(Int internalFormat, Int width, Int height); + Int GetWidth() const; + Int GetHeight() const; + Int GetInternalFormat() const; + Bool IsAllocated() const; + + private: + Uint m_externalIndex = 0; + Int m_internalFormat = 0; + Int m_width = 0; + Int m_height = 0; + Bool m_allocated = false; + }; + } // namespace GLState + } // namespace MG_State +} // namespace MobileGL diff --git a/MobileGL/MG_State/GLState/RenderbufferState/RenderbufferState.cpp b/MobileGL/MG_State/GLState/RenderbufferState/RenderbufferState.cpp new file mode 100644 index 00000000..53ac985e --- /dev/null +++ b/MobileGL/MG_State/GLState/RenderbufferState/RenderbufferState.cpp @@ -0,0 +1,66 @@ +#include "RenderbufferState.h" + +namespace MobileGL { + namespace MG_State { + namespace GLState { + RenderbufferState::RenderbufferState() : m_indexGenerator(1024, 1) { + for (SizeT i = 0; i < m_bindingSlots.size(); ++i) { + m_bindingSlots[i] = BindingSlot(static_cast(i)); + } + } + + SharedPtr RenderbufferState::GetRenderbufferObject(Uint index) { + auto it = m_renderbufferObjects.find(index); + if (it != m_renderbufferObjects.end()) { + return it->second; + } + return nullptr; + } + + Vector RenderbufferState::GenerateNames(Uint number) { + Vector buffers(number); + m_indexGenerator.Generate(number, buffers.data()); + return buffers; + } + + SharedPtr RenderbufferState::CreateRenderbufferObject(Uint index) { + auto bufferObject = MakeShared(index); + m_renderbufferObjects[index] = bufferObject; + return bufferObject; + } + + BindingSlot& RenderbufferState::GetBindingSlot(RenderbufferTarget target) { + for (SizeT i = 0; i < m_bindingSlots.size(); ++i) { + if (m_bindingSlots[i].GetTarget() == target) { + return m_bindingSlots[i]; + } + } + MOBILEGL_ASSERT(false, "Invalid RenderbufferTarget enum value: %d", static_cast(target)); + return m_bindingSlots[0]; + } + + void RenderbufferState::MarkRenderbufferObjectForDeletion(Uint index) { + if (m_indexGenerator.IsValid(index)) { + auto it = m_renderbufferObjects.find(index); + if (it != m_renderbufferObjects.end()) { + for (SizeT i = 0; i < m_bindingSlots.size(); ++i) { + if (m_bindingSlots[i].GetBoundObject() == it->second) { + m_bindingSlots[i].Bind(nullptr); + } + } + m_renderbufferObjects.erase(it); + } + m_indexGenerator.Delete(index); + } + } + + Bool RenderbufferState::ValidateName(Uint index) const { + return m_indexGenerator.IsValid(index); + } + + Bool RenderbufferState::ValidateRenderbufferObject(Uint index) const { + return m_renderbufferObjects.find(index) != m_renderbufferObjects.end(); + } + } // namespace GLState + } // namespace MG_State +} // namespace MobileGL diff --git a/MobileGL/MG_State/GLState/RenderbufferState/RenderbufferState.h b/MobileGL/MG_State/GLState/RenderbufferState/RenderbufferState.h new file mode 100644 index 00000000..7bd4ed32 --- /dev/null +++ b/MobileGL/MG_State/GLState/RenderbufferState/RenderbufferState.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include +#include "RenderbufferObject.h" + +namespace MobileGL { + namespace MG_State { + namespace GLState { + class RenderbufferState { + public: + RenderbufferState(); + + SharedPtr GetRenderbufferObject(Uint index); + Vector GenerateNames(Uint number); + SharedPtr CreateRenderbufferObject(Uint index); + BindingSlot& GetBindingSlot(RenderbufferTarget target); + void MarkRenderbufferObjectForDeletion(Uint index); + Bool ValidateName(Uint index) const; + Bool ValidateRenderbufferObject(Uint index) const; + + private: + UnorderedMap> m_renderbufferObjects; + IndexGenerator m_indexGenerator; + Array, static_cast(RenderbufferTarget::RenderbufferTargetCount)> + m_bindingSlots; + }; + } // namespace GLState + } // namespace MG_State +} // namespace MobileGL \ No newline at end of file