Browse Source

Mesh: fixed attribute stride computation.

The stride was computed always for resulting GLSL type (e.g. vec4) even
if the data were of anoother type (e.g. std::uint8_t[4]). The code is
exceptionally ugly now, time to wrap it with unit tests.
pull/7/head
Vladimír Vondruš 13 years ago
parent
commit
a9d25c995f
  1. 81
      src/AbstractShaderProgram.cpp
  2. 22
      src/AbstractShaderProgram.h
  3. 8
      src/Mesh.h

81
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<GLfloat>::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<GLint>::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<GLdouble>::size(GLint components, DataType dataType) {
switch(dataType) {
case DataType::Double:
return 8*components;
}
CORRADE_INTERNAL_ASSERT(false);
return 0;
}
std::size_t Attribute<Math::Vector<4, GLfloat>>::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
}

22
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<T>::size(Implementation::Attribute<T>::components(), _dataType);
}
/** @brief Data options */
inline constexpr DataOptions dataOptions() const { return _dataOptions; }
@ -1093,24 +1098,25 @@ template<> struct Attribute<GLfloat> {
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<GLfloat>::DataOptions)
template<std::size_t vectorSize> struct Attribute<Math::Vector<vectorSize, GLfloat>>: public Attribute<GLfloat> {
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<std::size_t cols, std::size_t rows> struct Attribute<Math::RectangularMatrix<cols, rows, GLfloat>>: public Attribute<GLfloat> {
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<std::size_t matrixSize> struct Attribute<Math::Matrix<matrixSize, GLfloat>>: public Attribute<GLfloat> {
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<Math::Vector<4, GLfloat>> {
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<GLint> {
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<GLuint> {
@ -1194,6 +1202,9 @@ template<> struct Attribute<GLuint> {
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<GLint>::size(components, dataType);
}
};
template<std::size_t size> struct Attribute<Math::Vector<size, GLint>>: public Attribute<GLint> {
@ -1218,6 +1229,7 @@ template<> struct Attribute<GLdouble> {
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<std::size_t cols, std::size_t rows> struct Attribute<Math::RectangularMatrix<cols, rows, GLdouble>>: public Attribute<GLdouble> {

8
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<T>::count()*TypeTraits<T>::size()*_vertexCount, attributes...);
addVertexBufferInternal(buffer, offset+attribute.dataSize()*_vertexCount, attributes...);
}
template<class ...T> 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<GLuint location, class T, class ...U> inline static GLsizei strideOfInterleaved(const AbstractShaderProgram::Attribute<location, T>&, const U&... attributes) {
return TypeTraits<T>::count()*TypeTraits<T>::size() + strideOfInterleaved(attributes...);
template<GLuint location, class T, class ...U> inline static GLsizei strideOfInterleaved(const AbstractShaderProgram::Attribute<location, T>& attribute, const U&... attributes) {
return attribute.dataSize() + strideOfInterleaved(attributes...);
}
template<class ...T> 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<T>::count()*TypeTraits<T>::size(), stride, attributes...);
addInterleavedVertexBufferInternal(buffer, offset+attribute.dataSize(), stride, attributes...);
}
template<class ...T> inline void addInterleavedVertexBufferInternal(Buffer* buffer, GLintptr offset, GLsizei stride, GLintptr gap, const T&... attributes) {
/* Add the gap to offset for next attribute */

Loading…
Cancel
Save