From 68f84a0c445defc23c2508420734365502134549 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 23 Nov 2018 07:57:40 +0100 Subject: Renderer: drawArraysInstancedBaseInstance parameters were swapped FirstVertex and FirstInstance parameters were swapped making any draw call that requires baseInstance or baseVertex unusable. Change-Id: Icf52f96981d8868bec4c6888bd129ed6e43d39e9 Task-number: QTBUG-71994 Reviewed-by: Sean Harmer --- src/render/geometry/qgeometryrenderer.cpp | 4 ++-- src/render/renderers/opengl/renderer/renderer.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/render/geometry/qgeometryrenderer.cpp b/src/render/geometry/qgeometryrenderer.cpp index b8572cded..6bff3462f 100644 --- a/src/render/geometry/qgeometryrenderer.cpp +++ b/src/render/geometry/qgeometryrenderer.cpp @@ -136,13 +136,13 @@ QGeometryRendererPrivate::~QGeometryRendererPrivate() /*! \qmlproperty int GeometryRenderer::firstInstance - Holds the first vertex. + Holds the base instance. */ /*! \qmlproperty int GeometryRenderer::firstVertex - Holds the base instance. + Holds the first vertex. */ /*! diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index 7aa39aa40..cbc5fb80d 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -1877,14 +1877,14 @@ void Renderer::performDraw(RenderCommand *command) reinterpret_cast(quintptr(command->m_indexAttributeByteOffset)), command->m_instanceCount, command->m_indexOffset, - command->m_firstVertex); + command->m_firstInstance); } else { Profiling::GLTimeRecorder recorder(Profiling::DrawArray); m_submissionContext->drawArraysInstancedBaseInstance(command->m_primitiveType, - command->m_firstInstance, + command->m_firstVertex, command->m_primitiveCount, command->m_instanceCount, - command->m_firstVertex); + command->m_firstInstance); } } -- cgit v1.2.3 From 9745006dadf5685f4ff82c6234938e19b9402801 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 30 Nov 2018 10:37:29 +0100 Subject: Reset last selected picker when releasing out of viewport Change-Id: Iec70e84024caf879358183fee34638def5038aef Task-number: QTBUG-72160 Reviewed-by: Mike Krus --- src/render/jobs/pickboundingvolumejob.cpp | 8 +- .../tst_pickboundingvolumejob.cpp | 88 ++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp index 2f1eb4cd8..2050b8772 100644 --- a/src/render/jobs/pickboundingvolumejob.cpp +++ b/src/render/jobs/pickboundingvolumejob.cpp @@ -232,8 +232,14 @@ bool PickBoundingVolumeJob::runHelper() for (const PickingUtils::ViewportCameraAreaDetails &vca : vcaDetails) { PickingUtils::HitList sphereHits; QRay3D ray = rayForViewportAndCamera(vca, event.first, event.second.pos()); - if (!ray.isValid()) + if (!ray.isValid()) { + // An invalid rays is when we've lost our surface or the mouse + // has moved out of the viewport In case of a button released + // outside of the viewport, we still want to notify the + // lastCurrent entity about this. + dispatchPickEvents(event.second, PickingUtils::HitList(), eventButton, eventButtons, eventModifiers, allHitsRequested); continue; + } PickingUtils::HierarchicalEntityPicker entityPicker(ray); if (entityPicker.collectHits(m_manager, m_node)) { diff --git a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp index b86df05a4..60b60eb6e 100644 --- a/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp +++ b/tests/auto/render/pickboundingvolumejob/tst_pickboundingvolumejob.cpp @@ -861,6 +861,94 @@ private Q_SLOTS: arbiter.events.clear(); } + void checkDispatchReleaseEventOnLastPickerWhenMovingOutOfViewport() + { + // GIVEN + QmlSceneReader sceneReader(QUrl("qrc:/testscene_dragenabled.qml")); + QScopedPointer root(qobject_cast(sceneReader.root())); + QVERIFY(root); + + QList renderSettings = root->findChildren(); + QCOMPARE(renderSettings.size(), 1); + Qt3DRender::QPickingSettings *settings = renderSettings.first()->pickingSettings(); + + settings->setPickMethod(Qt3DRender::QPickingSettings::TrianglePicking); + settings->setPickResultMode(Qt3DRender::QPickingSettings::NearestPick); + settings->setFaceOrientationPickingMode(Qt3DRender::QPickingSettings::FrontAndBackFace); + + QScopedPointer test(new Qt3DRender::TestAspect(root.data())); + TestArbiter arbiter; + + // Runs Required jobs + runRequiredJobs(test.data()); + + // THEN + QList pickers = root->findChildren(); + QCOMPARE(pickers.size(), 2); + + Qt3DRender::QObjectPicker *picker1 = nullptr; + if (pickers.first()->objectName() == QLatin1String("Picker1")) + picker1 = pickers.first(); + else + picker1 = pickers.last(); + + Qt3DRender::Render::ObjectPicker *backendPicker1 = test->nodeManagers()->objectPickerManager()->lookupResource(picker1->id()); + QVERIFY(backendPicker1); + Qt3DCore::QBackendNodePrivate::get(backendPicker1)->setArbiter(&arbiter); + + // WHEN -> Pressed on object + Qt3DRender::Render::PickBoundingVolumeJob pickBVJob; + initializePickBoundingVolumeJob(&pickBVJob, test.data()); + + QList> events; + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonPress, QPointF(207.0f, 303.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); + pickBVJob.setMouseEvents(events); + bool earlyReturn = !pickBVJob.runHelper(); + + // THEN -> Pressed + QVERIFY(!earlyReturn); + QVERIFY(backendPicker1->isPressed()); + QCOMPARE(arbiter.events.count(), 1); + Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast(); + QCOMPARE(change->propertyName(), "pressed"); + Qt3DRender::QPickEventPtr pickEvent = change->value().value(); + QVERIFY(pickEvent); + QVERIFY(!Qt3DRender::QPickEventPrivate::get(pickEvent.data())->m_entity.isNull()); + QVERIFY(pickEvent.dynamicCast()); + + arbiter.events.clear(); + + // WHEN -> Releasing out of the viewport + events.clear(); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(10000.0f, 10000.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); + pickBVJob.setMouseEvents(events); + earlyReturn = !pickBVJob.runHelper(); + + // THEN -> Should have received released event + QVERIFY(!earlyReturn); + QVERIFY(!backendPicker1->isPressed()); + QCOMPARE(arbiter.events.count(), 1); + change = arbiter.events.first().staticCast(); + QCOMPARE(change->propertyName(), "released"); + pickEvent = change->value().value(); + QVERIFY(pickEvent); + QVERIFY(Qt3DRender::QPickEventPrivate::get(pickEvent.data())->m_entity.isNull()); + + arbiter.events.clear(); + + // WHEN -> Releasing out of the viewport + events.clear(); + events.push_back({nullptr, QMouseEvent(QMouseEvent::MouseButtonRelease, QPointF(10000.0f, 10000.0f), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier)}); + pickBVJob.setMouseEvents(events); + earlyReturn = !pickBVJob.runHelper(); + + // THEN -> Should have received nothing + QCOMPARE(arbiter.events.count(), 0); + } + void checkDispatchHoverEvent_data() { generateAllPickingSettingsCombinations(); -- cgit v1.2.3