diff options
author | Mike Krus <mike.krus@kdab.com> | 2018-01-28 16:17:43 +0000 |
---|---|---|
committer | Mike Krus <mike.krus@kdab.com> | 2018-01-29 10:20:12 +0000 |
commit | e2cc50431284240c32eecbd80b53b1863bec3805 (patch) | |
tree | b59e04a6bb1f759112eb507cd78adf3da8f1f7c4 | |
parent | 6eb9003e9bb4d09a09ad22d6d7cffdbbe14eb8c9 (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.h | 12 | ||||
-rw-r--r-- | src/render/backend/trianglesvisitor.cpp | 18 | ||||
-rw-r--r-- | tests/auto/render/boundingsphere/tst_boundingsphere.cpp | 91 | ||||
-rw-r--r-- | tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp | 2 |
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()); |