diff --git a/CMakeLists.txt b/CMakeLists.txt index f89503e8..95a55066 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,8 @@ add_library(${CMAKE_PROJECT_NAME} SHARED MobileGL/MG_State/GLState/ErrorState/Error.cpp MobileGL/MG_State/GLState/BufferState/BufferState.cpp MobileGL/MG_State/GLState/BufferState/BufferObject.cpp + MobileGL/MG_State/GLState/VertexArrayState/VertexArrayState.cpp + MobileGL/MG_State/GLState/VertexArrayState/VertexArrayObject.cpp ) target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE diff --git a/MobileGL/Includes.h b/MobileGL/Includes.h index 22bfc91c..b626fa37 100644 --- a/MobileGL/Includes.h +++ b/MobileGL/Includes.h @@ -109,6 +109,8 @@ inline int __android_log_print(int prio, const char* tag, const char* fmt, ...) #include "MG_State/GLState/BufferState/BufferObject.h" #include "MG_State/GLState/BufferState/BufferState.h" +#include "MG_State/GLState/VertexArrayState/VertexArrayObject.h" +#include "MG_State/GLState/VertexArrayState/VertexArrayState.h" /* @INSERTION_POINT:HEADER_FILE_GLIMPL@ */ #include "MG_Impl/GLImpl/Getter/GL_Getter.h" diff --git a/MobileGL/MG_State/GLState/Core.cpp b/MobileGL/MG_State/GLState/Core.cpp index 05bf018f..a606cfcf 100644 --- a/MobileGL/MG_State/GLState/Core.cpp +++ b/MobileGL/MG_State/GLState/Core.cpp @@ -65,6 +65,38 @@ namespace MobileGL { return m_bufferState.ValidateBufferObject(index); } + // VertexArray + Vector GLContext::GenVertexArrayNames(Uint number) { + return m_vertexArrayState.GenerateNames(number); + } + + SharedPtr GLContext::GetVertexArrayObject(Uint index) { + return m_vertexArrayState.GetVertexArrayObject(index); + } + + void GLContext::BindVertexArray(Uint index) { + m_vertexArrayState.Bind(index); + } + + SharedPtr GLContext::CreateVertexArrayObject(Uint index) { + return m_vertexArrayState.CreateVertexArrayObject(index); + } + + void GLContext::MarkVertexArrayForDeletion(Uint index) { + m_vertexArrayState.MarkVertexArrayForDeletion(index); + } + + bool GLContext::ValidateVertexArrayName(Uint index) const { + return m_vertexArrayState.ValidateName(index); + } + + bool GLContext::ValidateVertexArrayObject(Uint index) const { + return m_vertexArrayState.ValidateVertexArrayObject(index); + } + + SharedPtr GLContext::GetBoundVertexArray() { + return m_vertexArrayState.GetBoundVertexArray(); + } } GLState::GLContext* pGLContext; diff --git a/MobileGL/MG_State/GLState/Core.h b/MobileGL/MG_State/GLState/Core.h index 81e36551..f637de26 100644 --- a/MobileGL/MG_State/GLState/Core.h +++ b/MobileGL/MG_State/GLState/Core.h @@ -26,12 +26,25 @@ namespace MobileGL { bool ValidateBufferName(Uint index) const; bool ValidateBufferObject(Uint index) const; + // VertexArray + Vector GenVertexArrayNames(Uint number); + SharedPtr GetVertexArrayObject(Uint index); + void BindVertexArray(Uint index); + SharedPtr CreateVertexArrayObject(Uint index); + void MarkVertexArrayForDeletion(Uint index); + bool ValidateVertexArrayName(Uint index) const; + bool ValidateVertexArrayObject(Uint index) const; + SharedPtr GetBoundVertexArray(); + private: // Error ErrorState m_errorState; // Buffer BufferState m_bufferState; + + // VertexArray + VertexArrayState m_vertexArrayState; }; } diff --git a/MobileGL/MG_State/GLState/VertexArrayState/VertexArrayObject.cpp b/MobileGL/MG_State/GLState/VertexArrayState/VertexArrayObject.cpp new file mode 100644 index 00000000..db0b71c3 --- /dev/null +++ b/MobileGL/MG_State/GLState/VertexArrayState/VertexArrayObject.cpp @@ -0,0 +1,70 @@ +#include "../../../Includes.h" + +namespace MobileGL { + namespace MG_State { + namespace GLState { + VertexArrayObject::VertexArrayObject() { + for (auto& attr : m_attributes) { + attr.Enabled = false; + attr.Size = 4; + attr.Type = DataType::Float32; + attr.Normalized = false; + attr.Stride = 0; + attr.Offset = 0; + attr.Buffer = nullptr; + } + } + + void VertexArrayObject::EnableAttribute(Uint index) { + if (index >= MAX_VERTEX_ATTRIBS) return; + m_attributes[index].Enabled = true; + } + + void VertexArrayObject::DisableAttribute(Uint index) { + if (index >= MAX_VERTEX_ATTRIBS) return; + m_attributes[index].Enabled = false; + } + + bool VertexArrayObject::IsAttributeEnabled(Uint index) const { + if (index >= MAX_VERTEX_ATTRIBS) return false; + return m_attributes[index].Enabled; + } + + void VertexArrayObject::SetAttributeFormat(Uint index, int size, DataType type, + bool normalized, int stride, SizeT offset) { + if (index >= MAX_VERTEX_ATTRIBS) return; + + if (size < 1 || size > 4) { + return; + } + + auto& attr = m_attributes[index]; + attr.Size = size; + attr.Type = type; + attr.Normalized = normalized; + attr.Stride = stride; + attr.Offset = offset; + } + + void VertexArrayObject::BindAttributeBuffer(Uint index, + const SharedPtr& buffer) { + if (index >= MAX_VERTEX_ATTRIBS) return; + m_attributes[index].Buffer = buffer; + } + + void VertexArrayObject::BindElementBuffer(const SharedPtr& buffer) { + m_elementBuffer = buffer; + } + + SharedPtr VertexArrayObject::GetElementBuffer() const { + return m_elementBuffer; + } + + const VertexAttribute& VertexArrayObject::GetAttribute(Uint index) const { + static VertexAttribute emptyAttr; + if (index >= MAX_VERTEX_ATTRIBS) return emptyAttr; + return m_attributes[index]; + } + } + } +} diff --git a/MobileGL/MG_State/GLState/VertexArrayState/VertexArrayObject.h b/MobileGL/MG_State/GLState/VertexArrayState/VertexArrayObject.h new file mode 100644 index 00000000..1a20773e --- /dev/null +++ b/MobileGL/MG_State/GLState/VertexArrayState/VertexArrayObject.h @@ -0,0 +1,41 @@ +#pragma once + +namespace MobileGL { + namespace MG_State { + namespace GLState { + struct VertexAttribute { + bool Enabled = false; + int Size = 4; + DataType Type = DataType::Float32; + bool Normalized = false; + int Stride = 0; + SizeT Offset = 0; + SharedPtr Buffer; + }; + + class VertexArrayObject { + public: + static constexpr int MAX_VERTEX_ATTRIBS = 16; + + VertexArrayObject(); + + void EnableAttribute(Uint index); + void DisableAttribute(Uint index); + bool IsAttributeEnabled(Uint index) const; + + void SetAttributeFormat(Uint index, int size, DataType type, bool normalized, int stride, SizeT offset); + + void BindAttributeBuffer(Uint index, const SharedPtr& buffer); + + void BindElementBuffer(const SharedPtr& buffer); + SharedPtr GetElementBuffer() const; + + const VertexAttribute& GetAttribute(Uint index) const; + + private: + Array m_attributes; + SharedPtr m_elementBuffer; + }; + } + } +} diff --git a/MobileGL/MG_State/GLState/VertexArrayState/VertexArrayState.cpp b/MobileGL/MG_State/GLState/VertexArrayState/VertexArrayState.cpp new file mode 100644 index 00000000..daa0f1ce --- /dev/null +++ b/MobileGL/MG_State/GLState/VertexArrayState/VertexArrayState.cpp @@ -0,0 +1,70 @@ +#include "../../../Includes.h" + +namespace MobileGL { + namespace MG_State { + namespace GLState { + VertexArrayState::VertexArrayState() + : m_indexGenerator(1024, 1) { + } + + SharedPtr VertexArrayState::GetVertexArrayObject(Uint index) { + auto it = m_vertexArrays.find(index); + if (it != m_vertexArrays.end()) { + return it->second; + } + return nullptr; + } + + Vector VertexArrayState::GenerateNames(Uint number) { + Vector arrays(number); + m_indexGenerator.Generate(number, arrays.data()); + return arrays; + } + + void VertexArrayState::Bind(Uint index) { + if (index == 0) { + m_boundVertexArray = nullptr; + return; + } + + auto it = m_vertexArrays.find(index); + if (it != m_vertexArrays.end()) { + m_boundVertexArray = it->second; + } + else { + m_boundVertexArray = nullptr; + } + } + + SharedPtr VertexArrayState::CreateVertexArrayObject(Uint index) { + auto vao = MakeShared(); + m_vertexArrays[index] = vao; + return vao; + } + + void VertexArrayState::MarkVertexArrayForDeletion(Uint index) { + if (m_indexGenerator.IsValid(index)) { + if (m_boundVertexArray && m_vertexArrays.find(index) != m_vertexArrays.end() && + m_vertexArrays[index] == m_boundVertexArray) { + m_boundVertexArray = nullptr; + } + + m_vertexArrays.erase(index); + m_indexGenerator.Delete(index); + } + } + + bool VertexArrayState::ValidateName(Uint index) const { + return m_indexGenerator.IsValid(index); + } + + bool VertexArrayState::ValidateVertexArrayObject(Uint index) const { + return m_vertexArrays.find(index) != m_vertexArrays.end(); + } + + SharedPtr VertexArrayState::GetBoundVertexArray() { + return m_boundVertexArray; + } + } + } +} diff --git a/MobileGL/MG_State/GLState/VertexArrayState/VertexArrayState.h b/MobileGL/MG_State/GLState/VertexArrayState/VertexArrayState.h new file mode 100644 index 00000000..dac66978 --- /dev/null +++ b/MobileGL/MG_State/GLState/VertexArrayState/VertexArrayState.h @@ -0,0 +1,26 @@ +#pragma once + +namespace MobileGL { + namespace MG_State { + namespace GLState { + class VertexArrayState { + public: + VertexArrayState(); + + SharedPtr GetVertexArrayObject(Uint index); + Vector GenerateNames(Uint number); + void Bind(Uint index); + SharedPtr CreateVertexArrayObject(Uint index); + void MarkVertexArrayForDeletion(Uint index); + bool ValidateName(Uint index) const; + bool ValidateVertexArrayObject(Uint index) const; + SharedPtr GetBoundVertexArray(); + + private: + UnorderedMap> m_vertexArrays; + IndexGenerator m_indexGenerator; + SharedPtr m_boundVertexArray; + }; + } + } +}