summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2018-01-28 16:17:43 +0000
committerMike Krus <mike.krus@kdab.com>2018-01-29 10:20:12 +0000
commite2cc50431284240c32eecbd80b53b1863bec3805 (patch)
treeb59e04a6bb1f759112eb507cd78adf3da8f1f7c4
parent6eb9003e9bb4d09a09ad22d6d7cffdbbe14eb8c9 (diff)
Handle 0 stride vertex data
All examples, even with packed data, set actual vertex size on the attribute. However, convention is to pass 0 for packed data, in which case GL will compute vertex size based on number of coordinates and component data size. Neither the buffer visitor nor the triangle visitor respected this convention and relied on the real size to be set. Now computing the actual stride if it's passed in as 0. Change-Id: I9a65fd7d8d56f181e31faa93389e3fdd1a973c17 Reviewed-by: Paul Lemire <paul.lemire@kdab.com> Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/render/backend/buffervisitor_p.h12
-rw-r--r--src/render/backend/trianglesvisitor.cpp18
-rw-r--r--tests/auto/render/boundingsphere/tst_boundingsphere.cpp91
-rw-r--r--tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp2
4 files changed, 107 insertions, 16 deletions
diff --git a/src/render/backend/buffervisitor_p.h b/src/render/backend/buffervisitor_p.h
index 97851dab0..f7214460f 100644
--- a/src/render/backend/buffervisitor_p.h
+++ b/src/render/backend/buffervisitor_p.h
@@ -171,7 +171,7 @@ protected:
const uint byteStride,
const uint count)
{
- const uint stride = byteStride / sizeof(Coordinate);
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 2;
for (uint ndx = 0; ndx < count; ++ndx) {
visit(ndx, coordinates[0], coordinates[1]);
coordinates += stride;
@@ -185,7 +185,7 @@ protected:
IndexElem *indices,
const uint count)
{
- const uint stride = byteStride / sizeof(Coordinate);
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 2;
for (uint i = 0; i < count; ++i) {
const uint n = stride * indices[i];
visit(i, coordinates[n], coordinates[n + 1]);
@@ -197,7 +197,7 @@ protected:
const uint byteStride,
const uint count)
{
- const uint stride = byteStride / sizeof(Coordinate);
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 3;
for (uint ndx = 0; ndx < count; ++ndx) {
visit(ndx, coordinates[0], coordinates[1], coordinates[2]);
coordinates += stride;
@@ -210,7 +210,7 @@ protected:
IndexElem *indices,
const uint count)
{
- const uint stride = byteStride / sizeof(Coordinate);
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 3;
for (uint i = 0; i < count; ++i) {
const uint n = stride * indices[i];
visit(i, coordinates[n], coordinates[n + 1], coordinates[n + 2]);
@@ -222,7 +222,7 @@ protected:
const uint byteStride,
const uint count)
{
- const uint stride = byteStride / sizeof(Coordinate);
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 4;
for (uint ndx = 0; ndx < count; ++ndx) {
visit(ndx, coordinates[0], coordinates[1], coordinates[2], coordinates[3]);
coordinates += stride;
@@ -235,7 +235,7 @@ protected:
IndexElem *indices,
const uint count)
{
- const uint stride = byteStride / sizeof(Coordinate);
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 4;
for (uint i = 0; i < count; ++i) {
const uint n = stride * indices[i];
visit(i, coordinates[n], coordinates[n + 1], coordinates[n + 2], coordinates[n + 3]);
diff --git a/src/render/backend/trianglesvisitor.cpp b/src/render/backend/trianglesvisitor.cpp
index 036f43fa0..d0b05a0d9 100644
--- a/src/render/backend/trianglesvisitor.cpp
+++ b/src/render/backend/trianglesvisitor.cpp
@@ -84,8 +84,8 @@ void traverseTrianglesIndexed(index *indices,
TrianglesVisitor* visitor)
{
uint i = 0;
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
QVector3D abc[3];
@@ -110,8 +110,8 @@ void traverseTriangles(vertex *vertices,
{
uint i = 0;
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
QVector3D abc[3];
@@ -146,8 +146,8 @@ void traverseTriangleStripIndexed(index *indices,
TrianglesVisitor* visitor)
{
uint i = 0;
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
QVector3D abc[3];
@@ -177,8 +177,8 @@ void traverseTriangleStrip(vertex *vertices,
{
uint i = 0;
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
QVector3D abc[3];
@@ -203,8 +203,8 @@ void traverseTriangleFanIndexed(index *indices,
const BufferInfo &vertexInfo,
TrianglesVisitor* visitor)
{
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
QVector3D abc[3];
@@ -233,8 +233,8 @@ void traverseTriangleFan(vertex *vertices,
const BufferInfo &vertexInfo,
TrianglesVisitor* visitor)
{
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
QVector3D abc[3];
@@ -267,8 +267,8 @@ void traverseTriangleAdjacencyIndexed(index *indices,
TrianglesVisitor* visitor)
{
uint i = 0;
- const uint verticesStride = vertexInfo.byteStride / sizeof(vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(vertex) : maxVerticesDataSize;
uint ndx[3];
QVector3D abc[3];
@@ -293,8 +293,8 @@ void traverseTriangleAdjacency(Vertex *vertices,
{
uint i = 0;
- const uint verticesStride = vertexInfo.byteStride / sizeof(Vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
+ const uint verticesStride = vertexInfo.byteStride ? vertexInfo.byteStride / sizeof(Vertex) : maxVerticesDataSize;
uint ndx[3];
QVector3D abc[3];
@@ -314,7 +314,7 @@ void traverseTriangleAdjacency(Vertex *vertices,
template<typename Coordinate>
QVector4D readCoordinate(const BufferInfo &info, Coordinate *coordinates, uint index)
{
- const uint stride = info.byteStride / sizeof(Coordinate);
+ const uint stride = info.byteStride ? info.byteStride / sizeof(Coordinate) : info.dataSize;
QVector4D ret(0, 0, 0, 1.0f);
coordinates += stride * index;
for (uint e = 0; e < info.dataSize; ++e)
diff --git a/tests/auto/render/boundingsphere/tst_boundingsphere.cpp b/tests/auto/render/boundingsphere/tst_boundingsphere.cpp
index 767df4604..d5248e865 100644
--- a/tests/auto/render/boundingsphere/tst_boundingsphere.cpp
+++ b/tests/auto/render/boundingsphere/tst_boundingsphere.cpp
@@ -329,6 +329,97 @@ private Q_SLOTS:
QVERIFY(int(center.y()) == int(expectedCenter.y()));
QVERIFY(int(center.z()) == int(expectedCenter.z()));
}
+
+ void checkCustomPackedGeometry()
+ {
+ int drawVertexCount = 6;
+ QVector3D expectedCenter(-0.488892f, 0.0192147f, -75.4804f);
+ float expectedRadius = 25.5442f;
+
+ // two triangles with different Z
+ QByteArray vdata;
+ vdata.resize(6 * 3 * sizeof(float));
+ float *vp = reinterpret_cast<float *>(vdata.data());
+ *vp++ = -1.0f;
+ *vp++ = 1.0f;
+ *vp++ = -100.0f;
+ *vp++ = 0.0f;
+ *vp++ = 0.0f;
+ *vp++ = -100.0f;
+ *vp++ = 1.0f;
+ *vp++ = 1.0f;
+ *vp++ = -100.0f;
+
+ *vp++ = -1.0f;
+ *vp++ = -1.0f;
+ *vp++ = -50.0f;
+ *vp++ = 0.0f;
+ *vp++ = 0.0f;
+ *vp++ = -50.0f;
+ *vp++ = 1.0f;
+ *vp++ = -1.0f;
+ *vp++ = -50.0f;
+
+ QScopedPointer<Qt3DCore::QEntity> entity(new Qt3DCore::QEntity);
+ QScopedPointer<Qt3DRender::TestAspect> test(new Qt3DRender::TestAspect(entity.data()));
+ Qt3DRender::QBuffer *vbuffer = new Qt3DRender::QBuffer;
+
+ vbuffer->setData(vdata);
+ Qt3DRender::Render::Buffer *vbufferBackend = test->nodeManagers()->bufferManager()->getOrCreateResource(vbuffer->id());
+ vbufferBackend->setRenderer(test->renderer());
+ vbufferBackend->setManager(test->nodeManagers()->bufferManager());
+ simulateInitialization(vbuffer, vbufferBackend);
+
+ Qt3DRender::QGeometry *g = new Qt3DRender::QGeometry;
+ g->addAttribute(new Qt3DRender::QAttribute);
+
+ const QVector<Qt3DRender::QAttribute *> attrs = g->attributes();
+ Qt3DRender::QAttribute *attr = attrs[0];
+ attr->setBuffer(vbuffer);
+ attr->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
+ attr->setVertexBaseType(Qt3DRender::QAttribute::Float);
+ attr->setVertexSize(3);
+ attr->setCount(6);
+ attr->setByteOffset(0);
+ attr->setByteStride(0);
+
+ Qt3DRender::QGeometryRenderer *gr = new Qt3DRender::QGeometryRenderer;
+ gr->setVertexCount(drawVertexCount);
+ gr->setGeometry(g);
+ entity->addComponent(gr);
+
+ Qt3DRender::Render::Attribute *attr0Backend = test->nodeManagers()->attributeManager()->getOrCreateResource(attrs[0]->id());
+ attr0Backend->setRenderer(test->renderer());
+ simulateInitialization(attrs[0], attr0Backend);
+
+ Qt3DRender::Render::Geometry *gBackend = test->nodeManagers()->geometryManager()->getOrCreateResource(g->id());
+ gBackend->setRenderer(test->renderer());
+ simulateInitialization(g, gBackend);
+
+ Qt3DRender::Render::GeometryRenderer *grBackend = test->nodeManagers()->geometryRendererManager()->getOrCreateResource(gr->id());
+ grBackend->setRenderer(test->renderer());
+ grBackend->setManager(test->nodeManagers()->geometryRendererManager());
+ simulateInitialization(gr, grBackend);
+
+ Qt3DRender::Render::Entity *entityBackend = test->nodeManagers()->renderNodesManager()->getOrCreateResource(entity->id());
+ entityBackend->setRenderer(test->renderer());
+ simulateInitialization(entity.data(), entityBackend);
+
+ Qt3DRender::Render::CalculateBoundingVolumeJob calcBVolume;
+ calcBVolume.setManagers(test->nodeManagers());
+ calcBVolume.setRoot(test->sceneRoot());
+ calcBVolume.run();
+
+ QVector3D center = entityBackend->localBoundingVolume()->center();
+ float radius = entityBackend->localBoundingVolume()->radius();
+ qDebug() << radius << center;
+
+ // truncate and compare integers only
+ QVERIFY(int(radius) == int(expectedRadius));
+ QVERIFY(int(center.x()) == int(expectedCenter.x()));
+ QVERIFY(int(center.y()) == int(expectedCenter.y()));
+ QVERIFY(int(center.z()) == int(expectedCenter.z()));
+ }
};
QTEST_MAIN(tst_BoundingSphere)
diff --git a/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp b/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp
index 1e76751cc..08d06f0ea 100644
--- a/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp
+++ b/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp
@@ -194,7 +194,7 @@ private Q_SLOTS:
positionAttribute->setDataType(Qt3DRender::QAttribute::Float);
positionAttribute->setDataSize(3);
positionAttribute->setCount(6);
- positionAttribute->setByteStride(3*4);
+ positionAttribute->setByteStride(0);
positionAttribute->setByteOffset(0);
positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
geometry->addAttribute(positionAttribute.data());