diff --git a/DemoFramework/FslUtil/OpenGLES2/include/FslUtil/OpenGLES2/GLBuffer.hpp b/DemoFramework/FslUtil/OpenGLES2/include/FslUtil/OpenGLES2/GLBuffer.hpp index 0a11c161e6..f17000cfea 100644 --- a/DemoFramework/FslUtil/OpenGLES2/include/FslUtil/OpenGLES2/GLBuffer.hpp +++ b/DemoFramework/FslUtil/OpenGLES2/include/FslUtil/OpenGLES2/GLBuffer.hpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -194,15 +195,32 @@ namespace Fsl::GLES2 SetDataEx(dstIndex, ReadOnlyFlexSpanUtil::AsSpan(bufferData)); } + template + void SetDataFast(const std::size_t dstIndex, const ReadOnlySpan bufferData) + { + SetDataFast(dstIndex, ReadOnlyFlexSpanUtil::AsSpan(bufferData)); + } + + //! @brief Update the given area of the buffer + //! This is the recommended way of updating the content of a buffer both for full and partial updates! + //! @param dstIndex the dst index where the data will be written. + //! @param bufferData the elements that should be written. + //! @note This method does not check for glErrors since its intended for use during rendering. + //! @throws IndexOutOfRangeException if the dstIndex + elementCount exceeds the capacity of the buffer. + //! @throws std::invalid_argument if the bufferData span stride is incompatible with the buffer. + //! @throws UsageErrorException if the object isn't valid + void SetData(const std::size_t dstIndex, const ReadOnlyFlexSpan bufferData); + //! @brief Update the given area of the buffer //! This is the recommended way of updating the content of a buffer both for full and partial updates! + //! This does not unbind the GLBuffer after modification //! @param dstIndex the dst index where the data will be written. //! @param bufferData the elements that should be written. //! @note This method does not check for glErrors since its intended for use during rendering. //! @throws IndexOutOfRangeException if the dstIndex + elementCount exceeds the capacity of the buffer. //! @throws std::invalid_argument if the bufferData span stride is incompatible with the buffer. //! @throws UsageErrorException if the object isn't valid - void SetData(const std::size_t dstIndex, ReadOnlyFlexSpan bufferData); + void SetDataEx(const std::size_t dstIndex, const ReadOnlyFlexSpan bufferData); //! @brief Update the given area of the buffer //! This is the recommended way of updating the content of a buffer both for full and partial updates! @@ -213,7 +231,7 @@ namespace Fsl::GLES2 //! @throws IndexOutOfRangeException if the dstIndex + elementCount exceeds the capacity of the buffer. //! @throws std::invalid_argument if the bufferData span stride is incompatible with the buffer. //! @throws UsageErrorException if the object isn't valid - void SetDataEx(const std::size_t dstIndex, ReadOnlyFlexSpan bufferData); + void SetDataFast(const std::size_t dstIndex, const ReadOnlyFlexSpan bufferData); //! @brief Update the given area of the buffer //! This is the recommended way of updating the content of a buffer both for full and partial updates! diff --git a/DemoFramework/FslUtil/OpenGLES2/include/FslUtil/OpenGLES2/GLVertexBuffer.hpp b/DemoFramework/FslUtil/OpenGLES2/include/FslUtil/OpenGLES2/GLVertexBuffer.hpp index 9197bb89f4..3244712373 100644 --- a/DemoFramework/FslUtil/OpenGLES2/include/FslUtil/OpenGLES2/GLVertexBuffer.hpp +++ b/DemoFramework/FslUtil/OpenGLES2/include/FslUtil/OpenGLES2/GLVertexBuffer.hpp @@ -31,7 +31,7 @@ * ****************************************************************************************************************************************************/ -// Make sure Common.hpp is the first include file (to make the error message as helpful as possible when disabled) +#include #include #include #include @@ -89,6 +89,20 @@ namespace Fsl::GLES2 Reset(pVertices, elementCount, usage); } + //! @brief Create a initialized vertex buffer + GLVertexBuffer(const ReadOnlyFlexSpan vertices, const VertexDeclarationSpan vertexDeclarationSpan, const GLenum usage) + : GLVertexBuffer() + { + Reset(vertices, vertexDeclarationSpan, usage); + } + + //! @brief Create a initialized vertex buffer + GLVertexBuffer(const ReadOnlyFlexVertexSpan vertices, const GLenum usage) + : GLVertexBuffer() + { + Reset(vertices, usage); + } + //! @brief Create a initialized vertex buffer template GLVertexBuffer(const std::array& vertices, const GLenum usage) @@ -126,6 +140,22 @@ namespace Fsl::GLES2 Reset(pVertices, elementCount, T::AsVertexDeclarationSpan(), usage); } + //! @brief Reset the buffer to contain the supplied elements + //! @note This is a very slow operation and its not recommended for updating the content of the buffer (since it creates a new buffer + //! internally) + void Reset(const ReadOnlyFlexSpan vertices, const VertexDeclarationSpan vertexDeclarationSpan, const GLenum usage) + { + Reset(vertices.data(), vertices.size(), vertexDeclarationSpan, usage); + } + + //! @brief Reset the buffer to contain the supplied elements + //! @note This is a very slow operation and its not recommended for updating the content of the buffer (since it creates a new buffer + //! internally) + void Reset(const ReadOnlyFlexVertexSpan vertices, const GLenum usage) + { + Reset(vertices.data(), vertices.size(), vertices.AsVertexDeclarationSpan(), usage); + } + //! @brief Reset the buffer to contain the supplied elements //! @note This is a very slow operation and its not recommended for updating the content of the buffer (since it creates a new buffer //! internally) @@ -166,7 +196,7 @@ namespace Fsl::GLES2 // m_vertexElements.EnableAttribArrays(pAttributeIndices, count); //} - //! @brief Disable all attrib arrays in the supplied index list. + ////! @brief Disable all attrib arrays in the supplied index list. // void DisableAttribArrays(const GLuint* const pAttributeIndices, const std::size_t count) const //{ // m_vertexElements.DisableAttribArrays(pAttributeIndices, count); @@ -184,6 +214,12 @@ namespace Fsl::GLES2 m_vertexElements.DisableAttribArrays(pLinks, count); } + //! @brief Enable all vertex elements listed in the supplied link list binding the to the requested index + void EnableAttribArrays(const ReadOnlySpan links) const + { + m_vertexElements.EnableAttribArrays(links); + } + template void EnableAttribArrays(const std::array& links) const { @@ -196,6 +232,12 @@ namespace Fsl::GLES2 m_vertexElements.EnableAttribArrays(links); } + //! @brief Disable all vertex elements listed in the supplied link + void DisableAttribArrays(const ReadOnlySpan links) const + { + m_vertexElements.DisableAttribArrays(links); + } + //! @brief Disable all vertex elements listed in the supplied link template void DisableAttribArrays(const std::array& links) const diff --git a/DemoFramework/FslUtil/OpenGLES2/include/FslUtil/OpenGLES2/GLVertexElements.hpp b/DemoFramework/FslUtil/OpenGLES2/include/FslUtil/OpenGLES2/GLVertexElements.hpp index 4f89ef7168..1ab50919bf 100644 --- a/DemoFramework/FslUtil/OpenGLES2/include/FslUtil/OpenGLES2/GLVertexElements.hpp +++ b/DemoFramework/FslUtil/OpenGLES2/include/FslUtil/OpenGLES2/GLVertexElements.hpp @@ -31,7 +31,7 @@ * ****************************************************************************************************************************************************/ -// Make sure Common.hpp is the first include file (to make the error message as helpful as possible when disabled) +#include #include #include #include @@ -118,9 +118,15 @@ namespace Fsl::GLES2 //! @brief Enable all vertex elements listed in the supplied link list binding the to the requested index void EnableAttribArrays(const GLVertexAttribLink* const pLinks, const std::size_t count) const; + //! @brief Enable all vertex elements listed in the supplied link list binding the to the requested index + void EnableAttribArrays(const ReadOnlySpan links) const; + //! @brief Disable all vertex elements listed in the supplied link void DisableAttribArrays(const GLVertexAttribLink* const pLinks, const std::size_t count) const; + //! @brief Disable all vertex elements listed in the supplied link + void DisableAttribArrays(const ReadOnlySpan links) const; + template void EnableAttribArrays(const std::array& links) const { diff --git a/DemoFramework/FslUtil/OpenGLES2/source/FslUtil/OpenGLES2/GLBuffer.cpp b/DemoFramework/FslUtil/OpenGLES2/source/FslUtil/OpenGLES2/GLBuffer.cpp index e4b03bba3a..a894a9848b 100644 --- a/DemoFramework/FslUtil/OpenGLES2/source/FslUtil/OpenGLES2/GLBuffer.cpp +++ b/DemoFramework/FslUtil/OpenGLES2/source/FslUtil/OpenGLES2/GLBuffer.cpp @@ -87,7 +87,7 @@ namespace Fsl::GLES2 } } - void GLBuffer::SetData(const std::size_t dstIndex, ReadOnlyFlexSpan bufferData) + void GLBuffer::SetData(const std::size_t dstIndex, const ReadOnlyFlexSpan bufferData) { if (!bufferData.empty()) { @@ -96,7 +96,7 @@ namespace Fsl::GLES2 } } - void GLBuffer::SetDataEx(const std::size_t dstIndex, ReadOnlyFlexSpan bufferData) + void GLBuffer::SetDataEx(const std::size_t dstIndex, const ReadOnlyFlexSpan bufferData) { if (m_elementStride != bufferData.stride()) { @@ -120,6 +120,30 @@ namespace Fsl::GLES2 } } + void GLBuffer::SetDataFast(const std::size_t dstIndex, const ReadOnlyFlexSpan bufferData) + { + if (m_elementStride != bufferData.stride()) + { + throw std::invalid_argument("bufferData is not compatible with GLBuffer"); + } + if ((dstIndex + bufferData.size()) > m_capacity) + { + throw IndexOutOfRangeException("SetData"); + } + if (!IsValid()) + { + throw UsageErrorException("SetData called on invalid buffer"); + } + if (!bufferData.empty()) + { + assert(m_elementStride > 0); + assert(bufferData.data() != nullptr); + glBufferSubData(m_target, UncheckedNumericCast(dstIndex * m_elementStride), UncheckedNumericCast(bufferData.byte_size()), + bufferData.data()); + } + } + + void GLBuffer::SetDataFast(const std::size_t dstIndex, const void* const pElements, const std::size_t elementCount) { if (pElements == nullptr) diff --git a/DemoFramework/FslUtil/OpenGLES2/source/FslUtil/OpenGLES2/GLVertexElements.cpp b/DemoFramework/FslUtil/OpenGLES2/source/FslUtil/OpenGLES2/GLVertexElements.cpp index b2ae87a07e..fde6bdf6fe 100644 --- a/DemoFramework/FslUtil/OpenGLES2/source/FslUtil/OpenGLES2/GLVertexElements.cpp +++ b/DemoFramework/FslUtil/OpenGLES2/source/FslUtil/OpenGLES2/GLVertexElements.cpp @@ -271,8 +271,8 @@ namespace Fsl::GLES2 const ReadOnlySpan vertexElementSpan = SpanUtil::AsReadOnlySpan(m_vertexElements); const auto vertexStride = VertexStride(); - assert(count <= std::numeric_limits::max()); - for (uint32_t i = 0; i < static_cast(count); ++i) + const auto count32 = UncheckedNumericCast(count); + for (uint32_t i = 0; i < count32; ++i) { if (pLinks[i].AttribIndex >= 0) // if present in shader { @@ -283,6 +283,27 @@ namespace Fsl::GLES2 } + void GLVertexElements::EnableAttribArrays(const ReadOnlySpan links) const + { + if (links.size() > std::numeric_limits::max()) + { + throw NotSupportedException("We only support 32bit of elements"); + } + + const ReadOnlySpan vertexElementSpan = SpanUtil::AsReadOnlySpan(m_vertexElements); + const auto vertexStride = VertexStride(); + const auto count32 = UncheckedNumericCast(links.size()); + for (uint32_t i = 0; i < count32; ++i) + { + if (links[i].AttribIndex >= 0) // if present in shader + { + assert(links[i].VertexElementIndex < vertexElementSpan.size()); + EnableAttribArray(vertexElementSpan[links[i].VertexElementIndex], links[i].AttribIndex, vertexStride, vertexElementSpan); + } + } + } + + void GLVertexElements::DisableAttribArrays(const GLVertexAttribLink* const pLinks, const std::size_t count) const { if (pLinks == nullptr) @@ -295,7 +316,8 @@ namespace Fsl::GLES2 } const ReadOnlySpan vertexElementSpan = SpanUtil::AsReadOnlySpan(m_vertexElements); - for (uint32_t i = 0; i < static_cast(count); ++i) + const auto count32 = UncheckedNumericCast(count); + for (uint32_t i = 0; i < count32; ++i) { if (pLinks[i].AttribIndex >= 0) { @@ -305,6 +327,25 @@ namespace Fsl::GLES2 } } + void GLVertexElements::DisableAttribArrays(const ReadOnlySpan links) const + { + if (links.size() > std::numeric_limits::max()) + { + throw NotSupportedException("We only support 32bit of elements"); + } + + const ReadOnlySpan vertexElementSpan = SpanUtil::AsReadOnlySpan(m_vertexElements); + const auto count32 = UncheckedNumericCast(links.size()); + for (uint32_t i = 0; i < count32; ++i) + { + if (links[i].AttribIndex >= 0) + { + assert(links[i].VertexElementIndex < vertexElementSpan.size()); + DisableAttribArray(vertexElementSpan[links[i].VertexElementIndex], links[i].AttribIndex); + } + } + } + void GLVertexElements::SetVertexAttribPointers() const {