summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2019-12-09 15:10:53 +0000
committerMike Krus <mike.krus@kdab.com>2019-12-13 17:47:44 +0000
commit5746b72615f0c1ab59bf9391195cb795fd76d927 (patch)
treea7693a156d4d9de00015af9a9cbcc9dcfb8d3e53
parenteb375c963d79add7b827ea9f9f40aea44fecd094 (diff)
Fix picking with primitive restart for line loops
Previous fix was not closing the loop on every primitive, just the last one. Task-number: QTBUG-71919 Change-Id: I22d52258477b0c4777118ee36a0b3868da982885 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r--src/render/backend/segmentsvisitor.cpp57
-rw-r--r--tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp27
2 files changed, 52 insertions, 32 deletions
diff --git a/src/render/backend/segmentsvisitor.cpp b/src/render/backend/segmentsvisitor.cpp
index 68deafb15..d9f2d79ec 100644
--- a/src/render/backend/segmentsvisitor.cpp
+++ b/src/render/backend/segmentsvisitor.cpp
@@ -135,39 +135,44 @@ void traverseSegmentStripIndexed(Index *indices,
bool loop)
{
uint i = 0;
+ uint stripStartIndex = 0;
+
const uint verticesStride = vertexInfo.byteStride / sizeof(Vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
uint ndx[2];
Vector3D abc[2];
-
- startLinePrimitive:ndx[0] = indices[i];
- uint idx = ndx[0] * verticesStride;
- for (uint j = 0; j < maxVerticesDataSize; ++j)
- abc[0][j] = vertices[idx + j];
- while (i < indexInfo.count - 1) {
- ndx[1] = indices[i + 1];
- if (ndx[0] != ndx[1]) {
- if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(ndx[1])) {
- i += 2;
- goto startLinePrimitive;
- }
- idx = ndx[1] * verticesStride;
- for (uint j = 0; j < maxVerticesDataSize; ++j)
- abc[1][j] = vertices[idx + j];
- visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
+ while (i < indexInfo.count) {
+ if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i])) {
+ ++i;
+ continue;
}
+ stripStartIndex = i;
+ ndx[0] = indices[stripStartIndex];
+ uint idx = ndx[0] * verticesStride;
+ for (uint j = 0; j < maxVerticesDataSize; ++j)
+ abc[0][j] = vertices[idx + j];
++i;
- ndx[0] = ndx[1];
- abc[0] = abc[1];
- }
- if (loop) {
- ndx[1] = indices[0];
- if (ndx[0] != ndx[1]) {
- idx = ndx[1] * verticesStride;
- for (uint j = 0; j < maxVerticesDataSize; ++j)
- abc[1][j] = vertices[idx + j];
- visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
+ while (i < indexInfo.count && (!indexInfo.restartEnabled || indexInfo.restartIndexValue != static_cast<int>(indices[i]))) {
+ ndx[1] = indices[i];
+ if (ndx[0] != ndx[1]) {
+ idx = ndx[1] * verticesStride;
+ for (uint j = 0; j < maxVerticesDataSize; ++j)
+ abc[1][j] = vertices[idx + j];
+ visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
+ }
+ ++i;
+ ndx[0] = ndx[1];
+ abc[0] = abc[1];
+ }
+ if (loop) {
+ ndx[1] = indices[stripStartIndex];
+ if (ndx[0] != ndx[1]) {
+ idx = ndx[1] * verticesStride;
+ for (uint j = 0; j < maxVerticesDataSize; ++j)
+ abc[1][j] = vertices[idx + j];
+ visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
+ }
}
}
}
diff --git a/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp b/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp
index da420e1ac..427f9c75b 100644
--- a/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp
+++ b/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp
@@ -426,12 +426,15 @@ private Q_SLOTS:
simulateInitialization(dataBuffer.data(), backendBuffer);
QByteArray indexData;
- indexData.resize(sizeof(uint) * 2 * 4);
+ indexData.resize(sizeof(uint) * 7);
uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
iDataPtr[0] = 0;
iDataPtr[1] = 1;
iDataPtr[2] = 2;
iDataPtr[3] = 3;
+ iDataPtr[4] = static_cast<uint>(-1);
+ iDataPtr[5] = 0;
+ iDataPtr[6] = 1;
indexDataBuffer->setData(indexData);
Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
@@ -450,7 +453,7 @@ private Q_SLOTS:
indexAttribute->setBuffer(indexDataBuffer.data());
indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
- indexAttribute->setCount(4);
+ indexAttribute->setCount(7);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
geometry->addAttribute(positionAttribute.data());
@@ -458,6 +461,8 @@ private Q_SLOTS:
geometryRenderer->setGeometry(geometry);
geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineStrip);
+ geometryRenderer->setPrimitiveRestartEnabled(true);
+ geometryRenderer->setRestartIndexValue(-1);
Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
backendAttribute->setRenderer(&renderer);
@@ -480,10 +485,11 @@ private Q_SLOTS:
visitor.apply(backendRenderer, Qt3DCore::QNodeId());
// THEN
- QCOMPARE(visitor.segmentCount(), uint(3));
+ QCOMPARE(visitor.segmentCount(), uint(4));
QVERIFY(visitor.verifySegment(0, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
QVERIFY(visitor.verifySegment(1, 1,2, Vector3D(1,0,0), Vector3D(1,1,0)));
QVERIFY(visitor.verifySegment(2, 2,3, Vector3D(1,1,0), Vector3D(0,1,0)));
+ QVERIFY(visitor.verifySegment(3, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
}
void testVisitLineLoop()
@@ -588,12 +594,16 @@ private Q_SLOTS:
simulateInitialization(dataBuffer.data(), backendBuffer);
QByteArray indexData;
- indexData.resize(sizeof(uint) * 2 * 4);
+ indexData.resize(sizeof(uint) * 8);
uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
iDataPtr[0] = 0;
iDataPtr[1] = 1;
iDataPtr[2] = 2;
iDataPtr[3] = 3;
+ iDataPtr[4] = static_cast<uint>(-1);
+ iDataPtr[5] = 0;
+ iDataPtr[6] = 1;
+ iDataPtr[7] = 2;
indexDataBuffer->setData(indexData);
Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
@@ -612,7 +622,7 @@ private Q_SLOTS:
indexAttribute->setBuffer(indexDataBuffer.data());
indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
- indexAttribute->setCount(4);
+ indexAttribute->setCount(8);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
geometry->addAttribute(positionAttribute.data());
@@ -620,6 +630,8 @@ private Q_SLOTS:
geometryRenderer->setGeometry(geometry);
geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineLoop);
+ geometryRenderer->setPrimitiveRestartEnabled(true);
+ geometryRenderer->setRestartIndexValue(-1);
Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
backendAttribute->setRenderer(&renderer);
@@ -642,11 +654,14 @@ private Q_SLOTS:
visitor.apply(backendRenderer, Qt3DCore::QNodeId());
// THEN
- QCOMPARE(visitor.segmentCount(), uint(4));
+ QCOMPARE(visitor.segmentCount(), uint(7));
QVERIFY(visitor.verifySegment(0, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
QVERIFY(visitor.verifySegment(1, 1,2, Vector3D(1,0,0), Vector3D(1,1,0)));
QVERIFY(visitor.verifySegment(2, 2,3, Vector3D(1,1,0), Vector3D(0,1,0)));
QVERIFY(visitor.verifySegment(3, 3,0, Vector3D(0,1,0), Vector3D(0,0,0)));
+ QVERIFY(visitor.verifySegment(4, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
+ QVERIFY(visitor.verifySegment(5, 1,2, Vector3D(1,0,0), Vector3D(1,1,0)));
+ QVERIFY(visitor.verifySegment(6, 2,0, Vector3D(1,1,0), Vector3D(0,0,0)));
}
void testVisitLineAdjacency()