Browse Source

MeshTools: return Containers::Array also from interleave().

pull/34/head
Vladimír Vondruš 13 years ago
parent
commit
4da0f4497f
  1. 27
      src/MeshTools/Interleave.h
  2. 18
      src/MeshTools/Test/InterleaveTest.cpp

27
src/MeshTools/Interleave.h

@ -42,31 +42,31 @@ namespace Implementation {
class Interleave {
public:
Interleave(): _attributeCount(0), _stride(0), _data(nullptr) {}
Interleave(): _attributeCount(0), _stride(0) {}
template<class ...T> std::tuple<std::size_t, std::size_t, char*> operator()(const T&... attributes) {
template<class ...T> std::tuple<std::size_t, std::size_t, Containers::Array<char>> operator()(const T&... attributes) {
/* Compute buffer size and stride */
_attributeCount = attributeCount(attributes...);
Containers::Array<char> data;
if(_attributeCount && _attributeCount != ~std::size_t(0)) {
_stride = stride(attributes...);
/* Create output buffer */
_data = new char[_attributeCount*_stride];
data = Containers::Array<char>(_attributeCount*_stride);
/* Save the data */
write(_data, attributes...);
write(data.begin(), attributes...);
}
return std::make_tuple(_attributeCount, _stride, _data);
return std::make_tuple(_attributeCount, _stride, std::move(data));
}
template<class ...T> void operator()(Mesh& mesh, Buffer& buffer, Buffer::Usage usage, const T&... attributes) {
operator()(attributes...);
Containers::Array<char> data;
std::tie(std::ignore, std::ignore, data) = operator()(attributes...);
mesh.setVertexCount(_attributeCount);
buffer.setData({_data, _attributeCount*_stride}, usage);
delete[] _data;
buffer.setData({data, _attributeCount*_stride}, usage);
}
/* Specialization for only one attribute array */
@ -126,7 +126,6 @@ class Interleave {
std::size_t _attributeCount;
std::size_t _stride;
char* _data;
};
}
@ -146,11 +145,9 @@ std::vector<Vector4> positions;
std::vector<Vector2> textureCoordinates;
std::size_t attributeCount;
std::size_t stride;
char* data;
Containers::Array<char> data;
std::tie(attributeCount, stride, data) = MeshTools::interleave(positions, textureCoordinates);
std::size_t dataSize = attributeCount*stride;
// ...
delete[] data;
@endcode
It's often desirable to align data for one vertex on 32bit boundaries. To
@ -161,7 +158,7 @@ std::vector<GLushort> weights;
std::vector<BasicColor3<GLubyte>> vertexColors;
std::size_t attributeCount;
std::size_t stride;
char* data;
Containers::Array<char> data;
std::tie(attributeCount, stride, data) = MeshTools::interleave(positions, weights, 2, textureCoordinates, 1);
@endcode
This way vertex stride is 24 bytes, without gaps it would be 21 bytes, causing
@ -178,7 +175,7 @@ See also interleave(Mesh*, Buffer*, Buffer::Usage, const T&...),
which writes the interleaved array directly into buffer of given mesh.
*/
/* enable_if to avoid clash with overloaded function below */
template<class T, class ...U> inline typename std::enable_if<!std::is_same<T, Mesh>::value, std::tuple<std::size_t, std::size_t, char*>>::type interleave(const T& first, const U&... next) {
template<class T, class ...U> inline typename std::enable_if<!std::is_same<T, Mesh>::value, std::tuple<std::size_t, std::size_t, Containers::Array<char>>>::type interleave(const T& first, const U&... next) {
return Implementation::Interleave()(first, next...);
}

18
src/MeshTools/Test/InterleaveTest.cpp

@ -84,7 +84,7 @@ void InterleaveTest::strideGaps() {
void InterleaveTest::write() {
std::size_t attributeCount;
std::size_t stride;
char* data;
Containers::Array<char> data;
std::tie(attributeCount, stride, data) = MeshTools::interleave(
std::vector<Byte>{0, 1, 2},
std::vector<Int>{3, 4, 5},
@ -92,28 +92,25 @@ void InterleaveTest::write() {
CORRADE_COMPARE(attributeCount, std::size_t(3));
CORRADE_COMPARE(stride, std::size_t(7));
std::size_t size = attributeCount*stride;
if(!Utility::Endianness::isBigEndian()) {
CORRADE_COMPARE(std::vector<char>(data, data+size), (std::vector<char>{
CORRADE_COMPARE(std::vector<char>(data.begin(), data.end()), (std::vector<char>{
0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00,
0x01, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00,
0x02, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00
}));
} else {
CORRADE_COMPARE(std::vector<char>(data, data+size), (std::vector<char>{
CORRADE_COMPARE(std::vector<char>(data.begin(), data.end()), (std::vector<char>{
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x07,
0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08
}));
}
delete[] data;
}
void InterleaveTest::writeGaps() {
std::size_t attributeCount;
std::size_t stride;
char* data;
Containers::Array<char> data;
std::tie(attributeCount, stride, data) = MeshTools::interleave(
std::vector<Byte>{0, 1, 2}, 3,
std::vector<Int>{3, 4, 5},
@ -121,25 +118,22 @@ void InterleaveTest::writeGaps() {
CORRADE_COMPARE(attributeCount, std::size_t(3));
CORRADE_COMPARE(stride, std::size_t(12));
std::size_t size = attributeCount*stride;
if(!Utility::Endianness::isBigEndian()) {
/* byte, _____________gap, int___________________, short_____, _______gap */
CORRADE_COMPARE(std::vector<char>(data, data+size), (std::vector<char>{
CORRADE_COMPARE(std::vector<char>(data.begin(), data.end()), (std::vector<char>{
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00
}));
} else {
/* byte, _____________gap, ___________________int, _____short, _______gap */
CORRADE_COMPARE(std::vector<char>(data, data+size), (std::vector<char>{
CORRADE_COMPARE(std::vector<char>(data.begin(), data.end()), (std::vector<char>{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00
}));
}
delete[] data;
}
}}}

Loading…
Cancel
Save