diff --git a/src/AbstractShaderProgram.cpp b/src/AbstractShaderProgram.cpp index 7fe59d747..f16b5b31f 100644 --- a/src/AbstractShaderProgram.cpp +++ b/src/AbstractShaderProgram.cpp @@ -568,4 +568,85 @@ void AbstractShaderProgram::uniformImplementationDSA(GLint location, const Math: } #endif +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + +std::size_t Attribute::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::UnsignedByte: + case DataType::Byte: + return components; + case DataType::UnsignedShort: + case DataType::Short: + case DataType::HalfFloat: + return 2*components; + case DataType::UnsignedInt: + case DataType::Int: + case DataType::Float: + return 4*components; + case DataType::Double: + return 8*components; + } + + CORRADE_INTERNAL_ASSERT(false); + return 0; +} + +std::size_t Attribute::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::UnsignedByte: + case DataType::Byte: + return components; + case DataType::UnsignedShort: + case DataType::Short: + return 2*components; + case DataType::UnsignedInt: + case DataType::Int: + return 4*components; + } + + CORRADE_INTERNAL_ASSERT(false); + return 0; +} + + +std::size_t Attribute::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::Double: + return 8*components; + } + + CORRADE_INTERNAL_ASSERT(false); + return 0; +} + +std::size_t Attribute>::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::UnsignedByte: + case DataType::Byte: + return components; + case DataType::UnsignedShort: + case DataType::Short: + case DataType::HalfFloat: + return 2*components; + case DataType::UnsignedInt: + case DataType::Int: + case DataType::Float: + return 4*components; + case DataType::Double: + return 8*components; + + case DataType::UnsignedInt2101010REV: + case DataType::Int2101010REV: + CORRADE_INTERNAL_ASSERT(components == 4); + return 4; + } + + CORRADE_INTERNAL_ASSERT(false); + return 0; +} + +} +#endif + } diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index fa07f9df0..6ba5e4866 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -436,6 +436,11 @@ class MAGNUM_EXPORT AbstractShaderProgram { /** @brief Type of passed data */ inline constexpr DataType dataType() const { return _dataType; } + /** @brief Size of passed data */ + inline std::size_t dataSize() const { + return Implementation::Attribute::size(Implementation::Attribute::components(), _dataType); + } + /** @brief Data options */ inline constexpr DataOptions dataOptions() const { return _dataOptions; } @@ -1093,24 +1098,25 @@ template<> struct Attribute { static const DataType DefaultDataType = DataType::Float; - inline constexpr static GLint components(DataOptions) { return 1; } + inline constexpr static GLint components(DataOptions = {}) { return 1; } + static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType); inline constexpr static std::size_t vectorCount() { return 1; } }; CORRADE_ENUMSET_OPERATORS(Attribute::DataOptions) template struct Attribute>: public Attribute { - inline constexpr static GLint components(DataOptions) { return vectorSize; } + inline constexpr static GLint components(DataOptions = {}) { return vectorSize; } inline constexpr static std::size_t vectorCount() { return 1; } }; template struct Attribute>: public Attribute { - inline constexpr static GLint components(DataOptions) { return rows; } + inline constexpr static GLint components(DataOptions = {}) { return rows; } inline constexpr static std::size_t vectorCount() { return cols; } }; template struct Attribute>: public Attribute { - inline constexpr static GLint components(DataOptions) { return matrixSize; } + inline constexpr static GLint components(DataOptions = {}) { return matrixSize; } inline constexpr static std::size_t vectorCount() { return matrixSize; } }; @@ -1153,13 +1159,14 @@ template<> struct Attribute> { static const DataType DefaultDataType = DataType::Float; #ifndef MAGNUM_TARGET_GLES - inline constexpr static GLint components(DataOptions options) { + inline constexpr static GLint components(DataOptions options = {}) { return options & DataOption::BGRA ? GL_BGRA : 4; } #else inline constexpr static GLint components(DataOptions) { return 4; } #endif + static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType); inline constexpr static std::size_t vectorCount() { return 1; } }; @@ -1183,6 +1190,7 @@ template<> struct Attribute { static const DataType DefaultDataType = DataType::Int; inline constexpr static GLint components() { return 1; } + static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType); }; template<> struct Attribute { @@ -1194,6 +1202,9 @@ template<> struct Attribute { static const DataType DefaultDataType = DataType::UnsignedInt; inline constexpr static GLint components() { return 1; } + inline static std::size_t size(GLint components, DataType dataType) { + return Attribute::size(components, dataType); + } }; template struct Attribute>: public Attribute { @@ -1218,6 +1229,7 @@ template<> struct Attribute { inline constexpr static GLint components() { return 1; } inline constexpr static std::size_t vectorCount() { return 1; } + static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType); }; template struct Attribute>: public Attribute { diff --git a/src/Mesh.h b/src/Mesh.h index 6c684e661..778ed86cf 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -597,7 +597,7 @@ class MAGNUM_EXPORT Mesh { addVertexAttribute(buffer, attribute, offset, 0); /* Add size of this attribute array to offset for next attribute */ - addVertexBufferInternal(buffer, offset+TypeTraits::count()*TypeTraits::size()*_vertexCount, attributes...); + addVertexBufferInternal(buffer, offset+attribute.dataSize()*_vertexCount, attributes...); } template inline void addVertexBufferInternal(Buffer* buffer, GLintptr offset, GLintptr gap, const T&... attributes) { /* Add the gap to offset for next attribute */ @@ -606,8 +606,8 @@ class MAGNUM_EXPORT Mesh { inline void addVertexBufferInternal(Buffer*, GLintptr) {} /* Computing stride of interleaved vertex attributes */ - template inline static GLsizei strideOfInterleaved(const AbstractShaderProgram::Attribute&, const U&... attributes) { - return TypeTraits::count()*TypeTraits::size() + strideOfInterleaved(attributes...); + template inline static GLsizei strideOfInterleaved(const AbstractShaderProgram::Attribute& attribute, const U&... attributes) { + return attribute.dataSize() + strideOfInterleaved(attributes...); } template inline static GLsizei strideOfInterleaved(GLintptr gap, const T&... attributes) { return gap + strideOfInterleaved(attributes...); @@ -619,7 +619,7 @@ class MAGNUM_EXPORT Mesh { addVertexAttribute(buffer, attribute, offset, stride); /* Add size of this attribute to offset for next attribute */ - addInterleavedVertexBufferInternal(buffer, offset+TypeTraits::count()*TypeTraits::size(), stride, attributes...); + addInterleavedVertexBufferInternal(buffer, offset+attribute.dataSize(), stride, attributes...); } template inline void addInterleavedVertexBufferInternal(Buffer* buffer, GLintptr offset, GLsizei stride, GLintptr gap, const T&... attributes) { /* Add the gap to offset for next attribute */