Browse Source

Expose vertex attribute size as vector size + vector count.

Makes it possible to properly compute offset when adding matrix
attributes to mesh. The matrix-related test cases in Mesh test are now
passing. The vector count is now enum value to make it more clear that
that is compile-time constant independent of what was said in
constructor.
pull/51/head
Vladimír Vondruš 13 years ago
parent
commit
5ad98d41ca
  1. 23
      src/AbstractShaderProgram.h
  2. 12
      src/Mesh.h
  3. 102
      src/Test/AbstractShaderProgramTest.cpp

23
src/AbstractShaderProgram.h

@ -1166,7 +1166,14 @@ See @ref AbstractShaderProgram-subclassing for example usage in shaders and
template<UnsignedInt location, class T> class AbstractShaderProgram::Attribute {
public:
enum: UnsignedInt {
Location = location /**< Location to which the attribute is bound */
Location = location, /**< Location to which the attribute is bound */
/**
* Count of vectors in this type
*
* @see @ref vectorSize()
*/
VectorCount = Implementation::Attribute<T>::VectorCount
};
/**
@ -1340,9 +1347,13 @@ template<UnsignedInt location, class T> class AbstractShaderProgram::Attribute {
/** @brief Type of passed data */
constexpr DataType dataType() const { return _dataType; }
/** @brief Size of passed data */
std::size_t dataSize() const {
return Implementation::Attribute<T>::size(GLint(_components)*Implementation::Attribute<T>::vectorCount(), _dataType);
/**
* @brief Size of each vector in passed data
*
* @see @ref VectorCount
*/
UnsignedInt vectorSize() const {
return Implementation::Attribute<T>::size(GLint(_components), _dataType);
}
/** @brief Data options */
@ -1369,7 +1380,7 @@ template<std::size_t cols, std::size_t rows> struct SizedAttribute;
/* Vector attribute sizes */
template<std::size_t cols> struct SizedVectorAttribute {
constexpr static std::size_t vectorCount() { return cols; }
enum: UnsignedInt { VectorCount = UnsignedInt(cols) };
};
template<> struct SizedAttribute<1, 1>: SizedVectorAttribute<1> {
enum class Components: GLint { One = 1 };
@ -1565,7 +1576,7 @@ template<> struct Attribute<Math::Vector<4, Float>> {
};
typedef Containers::EnumSet<DataOption, UnsignedByte> DataOptions;
constexpr static std::size_t vectorCount() { return 1; }
enum: UnsignedInt { VectorCount = 1 };
static std::size_t MAGNUM_EXPORT size(GLint components, DataType dataType);
};

12
src/Mesh.h

@ -655,7 +655,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
/* Computing stride of interleaved vertex attributes */
template<UnsignedInt location, class T, class ...U> inline static GLsizei strideOfInterleaved(const AbstractShaderProgram::Attribute<location, T>& attribute, const U&... attributes) {
return attribute.dataSize() + strideOfInterleaved(attributes...);
return attribute.vectorSize()*AbstractShaderProgram::Attribute<location, T>::VectorCount + strideOfInterleaved(attributes...);
}
template<class ...T> inline static GLsizei strideOfInterleaved(GLintptr gap, const T&... attributes) {
return gap + strideOfInterleaved(attributes...);
@ -667,7 +667,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
addVertexAttribute(buffer, attribute, offset, stride);
/* Add size of this attribute to offset for next attribute */
addVertexBufferInternal(buffer, offset+attribute.dataSize(), stride, attributes...);
addVertexBufferInternal(buffer, offset+attribute.vectorSize()*AbstractShaderProgram::Attribute<location, T>::VectorCount, stride, attributes...);
}
template<class ...T> inline void addVertexBufferInternal(Buffer& buffer, GLintptr offset, GLsizei stride, GLintptr gap, const T&... attributes) {
/* Add the gap to offset for next attribute */
@ -676,14 +676,14 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
inline void addVertexBufferInternal(Buffer&, GLsizei, GLintptr) {}
template<UnsignedInt location, class T> inline void addVertexAttribute(typename std::enable_if<std::is_same<typename Implementation::Attribute<T>::Type, Float>::value, Buffer&>::type buffer, const AbstractShaderProgram::Attribute<location, T>& attribute, GLintptr offset, GLsizei stride) {
for(UnsignedInt i = 0; i != Implementation::Attribute<T>::vectorCount(); ++i)
for(UnsignedInt i = 0; i != AbstractShaderProgram::Attribute<location, T>::VectorCount; ++i)
(this->*attributePointerImplementation)(Attribute{
&buffer,
location+i,
GLint(attribute.components()),
GLenum(attribute.dataType()),
bool(attribute.dataOptions() & AbstractShaderProgram::Attribute<location, T>::DataOption::Normalized),
offset,
offset+i*attribute.vectorSize(),
stride
});
}
@ -702,13 +702,13 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
#ifndef MAGNUM_TARGET_GLES
template<UnsignedInt location, class T> inline void addVertexAttribute(typename std::enable_if<std::is_same<typename Implementation::Attribute<T>::Type, Double>::value, Buffer&>::type buffer, const AbstractShaderProgram::Attribute<location, T>& attribute, GLintptr offset, GLsizei stride) {
for(UnsignedInt i = 0; i != Implementation::Attribute<T>::vectorCount(); ++i)
for(UnsignedInt i = 0; i != AbstractShaderProgram::Attribute<location, T>::VectorCount; ++i)
(this->*attributeLPointerImplementation)(LongAttribute{
&buffer,
location+i,
GLint(attribute.components()),
GLenum(attribute.dataType()),
offset,
offset+i*attribute.vectorSize(),
stride
});
}

102
src/Test/AbstractShaderProgramTest.cpp

@ -44,8 +44,12 @@ class AbstractShaderProgramTest: public TestSuite::Tester {
void attributeVector4();
void attributeVectorBGRA();
void attributeMatrix();
void attributeMatrixDouble();
void attributeMatrixNxN();
#ifndef MAGNUM_TARGET_GLES2
void attributeMatrixMxN();
#endif
void attributeMatrixNxNd();
void attributeMatrixMxNd();
};
AbstractShaderProgramTest::AbstractShaderProgramTest() {
@ -61,38 +65,44 @@ AbstractShaderProgramTest::AbstractShaderProgramTest() {
&AbstractShaderProgramTest::attributeVector4,
&AbstractShaderProgramTest::attributeVectorBGRA,
&AbstractShaderProgramTest::attributeMatrix,
&AbstractShaderProgramTest::attributeMatrixDouble});
&AbstractShaderProgramTest::attributeMatrixNxN,
#ifndef MAGNUM_TARGET_GLES2
&AbstractShaderProgramTest::attributeMatrixMxN,
#endif
&AbstractShaderProgramTest::attributeMatrixNxNd,
&AbstractShaderProgramTest::attributeMatrixMxNd});
}
void AbstractShaderProgramTest::attributeScalar() {
typedef AbstractShaderProgram::Attribute<3, Float> Attribute;
CORRADE_COMPARE(Attribute::Location, 3);
CORRADE_COMPARE(Attribute::VectorCount, 1);
/* Default constructor */
Attribute a;
CORRADE_COMPARE(a.components(), Attribute::Components::One);
CORRADE_VERIFY(!a.dataOptions());
CORRADE_COMPARE(a.dataSize(), 4);
CORRADE_COMPARE(a.vectorSize(), 4);
CORRADE_COMPARE(a.dataType(), Attribute::DataType::Float);
/* Options */
Attribute b(Attribute::DataType::UnsignedShort, Attribute::DataOption::Normalized);
CORRADE_COMPARE(b.dataSize(), 2);
CORRADE_COMPARE(b.vectorSize(), 2);
CORRADE_VERIFY(b.dataOptions() <= Attribute::DataOption::Normalized);
}
void AbstractShaderProgramTest::attributeScalarInt() {
#ifndef MAGNUM_TARGET_GLES2
typedef AbstractShaderProgram::Attribute<3, Int> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 1);
/* Default constructor */
Attribute a;
CORRADE_COMPARE(a.dataSize(), 4);
CORRADE_COMPARE(a.vectorSize(), 4);
/* Options */
Attribute b(Attribute::DataType::Short);
CORRADE_COMPARE(b.dataSize(), 2);
CORRADE_COMPARE(b.vectorSize(), 2);
#else
CORRADE_SKIP("Integer attributes are not available in OpenGL ES 2.");
#endif
@ -101,14 +111,15 @@ void AbstractShaderProgramTest::attributeScalarInt() {
void AbstractShaderProgramTest::attributeScalarUnsignedInt() {
#ifndef MAGNUM_TARGET_GLES2
typedef AbstractShaderProgram::Attribute<3, UnsignedInt> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 1);
/* Default constructor */
Attribute a;
CORRADE_COMPARE(a.dataSize(), 4);
CORRADE_COMPARE(a.vectorSize(), 4);
/* Options */
Attribute b(Attribute::DataType::UnsignedByte);
CORRADE_COMPARE(b.dataSize(), 1);
CORRADE_COMPARE(b.vectorSize(), 1);
#else
CORRADE_SKIP("Integer attributes are not available in OpenGL ES 2.");
#endif
@ -117,10 +128,11 @@ void AbstractShaderProgramTest::attributeScalarUnsignedInt() {
void AbstractShaderProgramTest::attributeScalarDouble() {
#ifndef MAGNUM_TARGET_GLES
typedef AbstractShaderProgram::Attribute<3, Double> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 1);
/* Default constructor */
Attribute a;
CORRADE_COMPARE(a.dataSize(), 8);
CORRADE_COMPARE(a.vectorSize(), 8);
#else
CORRADE_SKIP("Double attributes are not available in OpenGL ES.");
#endif
@ -128,38 +140,40 @@ void AbstractShaderProgramTest::attributeScalarDouble() {
void AbstractShaderProgramTest::attributeVector() {
typedef AbstractShaderProgram::Attribute<3, Vector3> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 1);
/* Default constructor */
Attribute a;
CORRADE_COMPARE(a.components(), Attribute::Components::Three);
CORRADE_COMPARE(a.dataSize(), 3*4);
CORRADE_COMPARE(a.vectorSize(), 3*4);
CORRADE_COMPARE(a.dataType(), Attribute::DataType::Float);
/* Options */
#ifndef MAGNUM_TARGET_GLES
Attribute b(Attribute::Components::Two, Attribute::DataType::Double);
CORRADE_COMPARE(b.components(), Attribute::Components::Two);
CORRADE_COMPARE(b.dataSize(), 2*8);
CORRADE_COMPARE(b.vectorSize(), 2*8);
#else
Attribute b(Attribute::Components::Two, Attribute::DataType::Float);
CORRADE_COMPARE(b.components(), Attribute::Components::Two);
CORRADE_COMPARE(b.dataSize(), 2*4);
CORRADE_COMPARE(b.vectorSize(), 2*4);
#endif
}
void AbstractShaderProgramTest::attributeVectorInt() {
#ifndef MAGNUM_TARGET_GLES2
typedef AbstractShaderProgram::Attribute<3, Vector2i> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 1);
/* Default constructor */
Attribute a;
CORRADE_COMPARE(a.components(), Attribute::Components::Two);
CORRADE_COMPARE(a.dataSize(), 2*4);
CORRADE_COMPARE(a.vectorSize(), 2*4);
CORRADE_COMPARE(a.dataType(), Attribute::DataType::Int);
/* Options */
Attribute b(Attribute::Components::One, Attribute::DataType::Int);
CORRADE_COMPARE(b.dataSize(), 4);
CORRADE_COMPARE(b.vectorSize(), 4);
#else
CORRADE_SKIP("Integer attributes are not available in OpenGL ES 2.");
#endif
@ -168,16 +182,17 @@ void AbstractShaderProgramTest::attributeVectorInt() {
void AbstractShaderProgramTest::attributeVectorUnsignedInt() {
#ifndef MAGNUM_TARGET_GLES2
typedef AbstractShaderProgram::Attribute<3, Vector4ui> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 1);
/* Default constructor */
Attribute a;
CORRADE_COMPARE(a.components(), Attribute::Components::Four);
CORRADE_COMPARE(a.dataSize(), 4*4);
CORRADE_COMPARE(a.vectorSize(), 4*4);
CORRADE_COMPARE(a.dataType(), Attribute::DataType::UnsignedInt);
/* Options */
Attribute b(Attribute::Components::Three, Attribute::DataType::UnsignedShort);
CORRADE_COMPARE(b.dataSize(), 3*2);
CORRADE_COMPARE(b.vectorSize(), 3*2);
#else
CORRADE_SKIP("Integer attributes are not available in OpenGL ES 2.");
#endif
@ -186,16 +201,17 @@ void AbstractShaderProgramTest::attributeVectorUnsignedInt() {
void AbstractShaderProgramTest::attributeVectorDouble() {
#ifndef MAGNUM_TARGET_GLES
typedef AbstractShaderProgram::Attribute<3, Vector2d> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 1);
/* Default constructor */
Attribute a;
CORRADE_COMPARE(a.components(), Attribute::Components::Two);
CORRADE_COMPARE(a.dataSize(), 2*8);
CORRADE_COMPARE(a.vectorSize(), 2*8);
CORRADE_COMPARE(a.dataType(), Attribute::DataType::Double);
/* Options */
Attribute b(Attribute::Components::One);
CORRADE_COMPARE(b.dataSize(), 8);
CORRADE_COMPARE(b.vectorSize(), 8);
#else
CORRADE_SKIP("Double attributes are not available in OpenGL ES.");
#endif
@ -203,47 +219,79 @@ void AbstractShaderProgramTest::attributeVectorDouble() {
void AbstractShaderProgramTest::attributeVector4() {
typedef AbstractShaderProgram::Attribute<3, Vector4> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 1);
/* Custom type */
#ifndef MAGNUM_TARGET_GLES
Attribute a(Attribute::DataType::UnsignedInt2101010Rev);
CORRADE_COMPARE(a.dataSize(), 4);
CORRADE_COMPARE(a.vectorSize(), 4);
#else
Attribute a(Attribute::DataType::HalfFloat);
CORRADE_COMPARE(a.dataSize(), 8);
CORRADE_COMPARE(a.vectorSize(), 8);
#endif
}
void AbstractShaderProgramTest::attributeVectorBGRA() {
#ifndef MAGNUM_TARGET_GLES
typedef AbstractShaderProgram::Attribute<3, Vector4> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 1);
/* BGRA */
Attribute a(Attribute::Components::BGRA);
CORRADE_COMPARE(a.dataSize(), 4*4);
CORRADE_COMPARE(a.vectorSize(), 4*4);
#else
CORRADE_SKIP("BGRA attribute component ordering is not available in OpenGL ES.");
#endif
}
void AbstractShaderProgramTest::attributeMatrix() {
void AbstractShaderProgramTest::attributeMatrixNxN() {
typedef AbstractShaderProgram::Attribute<3, Matrix3> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 3);
/* Default constructor */
Attribute a;
CORRADE_COMPARE(a.components(), Attribute::Components::Three);
CORRADE_COMPARE(a.dataSize(), 3*3*4);
CORRADE_COMPARE(a.vectorSize(), 3*4);
CORRADE_COMPARE(a.dataType(), Attribute::DataType::Float);
}
void AbstractShaderProgramTest::attributeMatrixDouble() {
#ifndef MAGNUM_TARGET_GLES2
void AbstractShaderProgramTest::attributeMatrixMxN() {
typedef AbstractShaderProgram::Attribute<3, Matrix3x4> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 3);
/* Default constructor */
Attribute a;
CORRADE_COMPARE(a.components(), Attribute::Components::Four);
CORRADE_COMPARE(a.vectorSize(), 4*4);
CORRADE_COMPARE(a.dataType(), Attribute::DataType::Float);
}
#endif
void AbstractShaderProgramTest::attributeMatrixNxNd() {
#ifndef MAGNUM_TARGET_GLES
typedef AbstractShaderProgram::Attribute<3, Matrix4d> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 4);
/* Default constructor */
Attribute a;
CORRADE_COMPARE(a.components(), Attribute::Components::Four);
CORRADE_COMPARE(a.dataSize(), 4*4*8);
CORRADE_COMPARE(a.vectorSize(), 4*8);
CORRADE_COMPARE(a.dataType(), Attribute::DataType::Double);
#else
CORRADE_SKIP("Double attributes are not available in OpenGL ES.");
#endif
}
void AbstractShaderProgramTest::attributeMatrixMxNd() {
#ifndef MAGNUM_TARGET_GLES
typedef AbstractShaderProgram::Attribute<3, Matrix4x2d> Attribute;
CORRADE_COMPARE(Attribute::VectorCount, 4);
/* Default constructor */
Attribute a;
CORRADE_COMPARE(a.components(), Attribute::Components::Two);
CORRADE_COMPARE(a.vectorSize(), 2*8);
CORRADE_COMPARE(a.dataType(), Attribute::DataType::Double);
#else
CORRADE_SKIP("Double attributes are not available in OpenGL ES.");

Loading…
Cancel
Save