Merge remote-tracking branch 'origin/5.14' into 5.15

Change-Id: I5a5b1d497430afdd0fe11933832a2477a7efbe30
This commit is contained in:
Qt Forward Merge Bot 2019-12-14 03:05:15 +01:00
commit e77c85a200
24 changed files with 278 additions and 79 deletions

49
dist/changes-5.14.0 vendored Normal file
View File

@ -0,0 +1,49 @@
Qt 5.14 introduces many new features and improvements as well as bugfixes
over the 5.13.x series. For more details, refer to the online documentation
included in this distribution. The documentation is also available online:
https://doc.qt.io/qt-5/index.html
The Qt version 5.14 series is binary compatible with the 5.13.x series.
Applications compiled for 5.13 will continue to run with 5.14.
Some of the changes listed in this file include issue tracking numbers
corresponding to tasks in the Qt Bug Tracker:
https://bugreports.qt.io/
Each of these identifiers can be entered in the bug tracker to obtain more
information about a particular change.
****************************************************************************
* Qt3DExtras *
****************************************************************************
- QDistanceFieldGlyphCache:
* make sure the change arbiter of atlas for QText2DEntity can be set
when traversing node tree, and add new auto test for this.
****************************************************************************
* Qt3DRender *
****************************************************************************
- QNoPicking: control picking execution in the FrameGraph
- Textures: internal data sharing removed
- QSortPolicy can now sort by Texture
- QPickEvent adds property for picked entity
- QImageTextureDataFunctor:
* return a invalid image data when url is invalid to ensure the property
of GLTexture will not be set to NoFormat
****************************************************************************
* UNSPECIFIED *
****************************************************************************
- Add basic support for KTX container format.
- Add worldMatrix property on QTransform
- Added SubtreeEnabler to allow easing enabling
and disabling of frame graph subtrees.
- [QTBUG-74977] Scene3D add compositingMode property. Allows underlay
rendering.
- Introduce Scene3DView to render multiple distinct 3D scenes

View File

@ -33,5 +33,5 @@ void main()
FP float maxAlpha = threshold + range;
FP float distVal = texture2D(distanceFieldTexture, texCoord).r;
gl_FragColor = color * smoothstep(minAlpha, maxAlpha, distVal);
gl_FragColor = vec4(color.rgb, color.a * smoothstep(minAlpha, maxAlpha, distVal));
}

View File

@ -34,6 +34,6 @@ void main()
float maxAlpha = threshold + range;
float distVal = texture(distanceFieldTexture, texCoord).r;
fragColor = color * smoothstep(minAlpha, maxAlpha, distVal);
fragColor = vec4(color.rgb, color.a * smoothstep(minAlpha, maxAlpha, distVal));
gl_FragDepth = gl_FragCoord.z - zValue * 0.00001;
}

View File

@ -217,9 +217,6 @@ struct RenderData {
void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs)
{
if (runs.isEmpty())
return;
// For each distinct texture, we need a separate DistanceFieldTextRenderer,
// for which we need vertex and index data
QHash<Qt3DRender::QAbstractTexture*, RenderData> renderData;
@ -294,6 +291,11 @@ void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs)
}
}
// de-ref all glyphs for previous QGlyphRuns
for (int i = 0; i < m_currentGlyphRuns.size(); i++)
m_glyphCache->derefGlyphs(m_currentGlyphRuns[i]);
m_currentGlyphRuns = runs;
// make sure we have the correct number of DistanceFieldTextRenderers
// TODO: we might keep one renderer at all times, so we won't delete and
// re-allocate one every time the text changes from an empty to a non-empty string
@ -314,11 +316,6 @@ void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs)
for (auto it = renderData.begin(); it != renderData.end(); ++it) {
m_renderers[rendererIdx++]->setGlyphData(it.key(), it.value().vertex, it.value().index);
}
// de-ref all glyphs for previous QGlyphRuns
for (int i = 0; i < m_currentGlyphRuns.size(); i++)
m_glyphCache->derefGlyphs(m_currentGlyphRuns[i]);
m_currentGlyphRuns = runs;
}
void QText2DEntityPrivate::clearCurrentGlyphRuns()

View File

@ -433,12 +433,26 @@ void Scene3DItem::applyRootEntityChange()
bool Scene3DItem::needsRender()
{
// We need the dirty flag which is connected to the change arbiter
// receiving updates to know whether something in the scene has changed
// Ideally we would use shouldRender() alone but given that it becomes true
// only after the arbiter has sync the changes and might be reset before
// process jobs is completed, we cannot fully rely on it. It would require
// splitting processFrame in 2 parts.
// We only use it for cases where Qt3D render may require several loops of
// the simulation to fully process a frame (e.g shaders are loaded in frame
// n and we can only build render commands for the new shader at frame n +
// This is where renderer->shouldRender() comes into play as it knows
// whether some states remain dirty or not (even after processFrame is
// called)
auto renderAspectPriv = static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect));
const bool dirty = m_dirty
|| (renderAspectPriv
&& renderAspectPriv->m_renderer
&& renderAspectPriv->m_renderer->settings()
&& renderAspectPriv->m_renderer->settings()->renderPolicy() == QRenderSettings::Always);
&& renderAspectPriv->m_renderer->shouldRender());
m_dirty = false;
return dirty;
}
@ -468,10 +482,6 @@ void Scene3DItem::onBeforeSync()
if (!isVisible() && dontRenderWhenHidden)
return;
// Has anything in the 3D scene actually changed that requires us to render?
if (!needsRender())
return;
Q_ASSERT(QThread::currentThread() == thread());
// Since we are in manual mode, trigger jobs for the next frame
@ -512,6 +522,7 @@ void Scene3DItem::onBeforeSync()
// start rendering before this function has been called
// We add in a safety to skip such frames as this could otherwise
// make Qt3D enter a locked state
m_renderer->setSkipFrame(!needsRender());
m_renderer->allowRender();
// Note: it's too early to request an update at this point as

View File

@ -161,6 +161,7 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp
, m_forceRecreate(false)
, m_shouldRender(false)
, m_dirtyViews(false)
, m_skipFrame(false)
, m_allowRendering(0)
, m_compositingMode(Scene3DItem::FBO)
{
@ -278,6 +279,19 @@ void Scene3DRenderer::beforeSynchronize()
// We could otherwise enter a deadlock state
if (!m_allowRendering.tryAcquire(std::max(m_allowRendering.available(), 1)))
return;
// In the case of OnDemand rendering, we still need to get to this
// point to ensure we have processed jobs for all aspects.
// We also still need to call render() to allow proceeding with the
// next frame. However it won't be performing any 3d rendering at all
// so we do it here and return early. This prevents a costly QtQuick
// SceneGraph update for nothing
if (m_skipFrame) {
m_skipFrame = false;
static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->renderSynchronous(false);
return;
}
m_shouldRender = true;
// Check size / multisampling
@ -360,6 +374,11 @@ void Scene3DRenderer::setCompositingMode(Scene3DItem::CompositingMode mode)
m_compositingMode = mode;
}
void Scene3DRenderer::setSkipFrame(bool skip)
{
m_skipFrame = skip;
}
// Main Thread, Render Thread locked
void Scene3DRenderer::setScene3DViews(const QVector<Scene3DView *> views)
{

View File

@ -87,7 +87,7 @@ public:
void setCleanerHelper(Scene3DCleaner *cleaner);
void allowRender();
void setCompositingMode(Scene3DItem::CompositingMode mode);
void setSkipFrame(bool skip);
void setScene3DViews(const QVector<Scene3DView *> views);
public Q_SLOTS:
@ -119,6 +119,7 @@ private:
bool m_forceRecreate;
bool m_shouldRender;
bool m_dirtyViews;
bool m_skipFrame;
QSemaphore m_allowRendering;
Scene3DItem::CompositingMode m_compositingMode;
QVector<Scene3DView *> m_views;

View File

@ -144,7 +144,7 @@ void QQuaternionAnimation::setType(Type type)
switch (type) {
case Nlerp:
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC(-Wcast-function-type)
QT_WARNING_DISABLE_GCC("-Wcast-function-type")
d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&q_quaternionNlerpInterpolator);
QT_WARNING_POP
break;

View File

@ -152,7 +152,7 @@ public:
#if defined(QT_BUILD_INTERNAL)
virtual void clearDirtyBits(BackendNodeDirtySet changes) = 0;
#endif
virtual bool shouldRender() = 0;
virtual bool shouldRender() const = 0;
virtual void skipNextFrame() = 0;
virtual void jobsDone(Qt3DCore::QAspectManager *manager) = 0;

View File

@ -74,6 +74,8 @@ struct BufferInfo
, count(0)
, byteStride(0)
, byteOffset(0)
, restartEnabled(false)
, restartIndexValue(-1)
{}
QByteArray data;
@ -82,6 +84,8 @@ struct BufferInfo
uint count;
uint byteStride;
uint byteOffset;
bool restartEnabled;
int restartIndexValue;
};

View File

@ -135,34 +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];
ndx[0] = indices[0];
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]) {
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]);
}
}
}
}

View File

@ -153,6 +153,10 @@ void traverseTriangleStripIndexed(index *indices,
uint ndx[3];
Vector3D abc[3];
while (i < indexInfo.count - 2) {
if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i + 2])) {
i += 3;
continue;
}
bool degenerate = false;
for (uint u = 0; u < 3; ++u) {
ndx[u] = indices[i + u];
@ -216,6 +220,11 @@ void traverseTriangleFanIndexed(index *indices,
ndx[0] = indices[0];
uint i = 1;
while (i < indexInfo.count - 1) {
if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i + 1])) {
ndx[0] = indices[i + 2];
i += 3;
continue;
}
for (uint u = 0; u < 2; ++u) {
ndx[u + 1] = indices[i + u];
uint idx = ndx[u + 1] * verticesStride;
@ -224,7 +233,7 @@ void traverseTriangleFanIndexed(index *indices,
}
}
visitor->visit(ndx[2], abc[2], ndx[1], abc[1], ndx[0], abc[0]);
i += 1;
++i;
}
}

View File

@ -149,6 +149,8 @@ void visitPrimitives(NodeManagers *manager, const GeometryRenderer *renderer, Vi
indexBufferInfo.byteOffset = indexAttribute->byteOffset();
indexBufferInfo.byteStride = indexAttribute->byteStride();
indexBufferInfo.count = indexAttribute->count();
indexBufferInfo.restartEnabled = renderer->primitiveRestartEnabled();
indexBufferInfo.restartIndexValue = renderer->restartIndexValue();
IndexExecutor executor;
executor.m_vertexBufferInfo = vertexBufferInfo;

View File

@ -115,12 +115,18 @@ QDirectionalLight::QDirectionalLight(QDirectionalLightPrivate &dd, QNode *parent
/*!
\qmlproperty vector3d Qt3D.Render::DirectionalLight::worldDirection
Specifies the world direction of the directional light
Specifies the world direction of the directional light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
/*!
\property Qt3DRender::QDirectionalLight::worldDirection
Specifies the world direction of the directional light
Specifies the world direction of the directional light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
void QDirectionalLight::setWorldDirection(const QVector3D &direction)
{

View File

@ -158,6 +158,9 @@ QEnvironmentLight::~QEnvironmentLight()
Holds the current environment irradiance map texture.
By default, the environment irradiance texture is null.
\note The exact meaning and use of this property is up to the
material implementation.
*/
/*!
@ -166,6 +169,9 @@ QEnvironmentLight::~QEnvironmentLight()
Holds the current environment irradiance map texture.
By default, the environment irradiance texture is null.
\note The exact meaning and use of this property is up to the
material implementation.
*/
QAbstractTexture *QEnvironmentLight::irradiance() const
{
@ -179,6 +185,9 @@ QAbstractTexture *QEnvironmentLight::irradiance() const
Holds the current environment specular map texture.
By default, the environment specular texture is null.
\note The exact meaning and use of this property is up to the
material implementation.
*/
/*!
@ -187,6 +196,9 @@ QAbstractTexture *QEnvironmentLight::irradiance() const
Holds the current environment specular map texture.
By default, the environment specular texture is null.
\note The exact meaning and use of this property is up to the
material implementation.
*/
QAbstractTexture *QEnvironmentLight::specular() const
{

View File

@ -135,12 +135,18 @@ QPointLight::QPointLight(QPointLightPrivate &dd, QNode *parent)
/*!
\qmlproperty float Qt3D.Render::PointLight::constantAttenuation
Specifies the constant attenuation of the point light
Specifies the constant attenuation of the point light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
/*!
\property Qt3DRender::QPointLight::constantAttenuation
Specifies the constant attenuation of the point light
Specifies the constant attenuation of the point light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
float QPointLight::constantAttenuation() const
{
@ -159,12 +165,18 @@ void QPointLight::setConstantAttenuation(float value)
/*!
\qmlproperty float Qt3D.Render::PointLight::linearAttenuation
Specifies the linear attenuation of the point light
Specifies the linear attenuation of the point light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
/*!
\property Qt3DRender::QPointLight::linearAttenuation
Specifies the linear attenuation of the point light
Specifies the linear attenuation of the point light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
float QPointLight::linearAttenuation() const
{
@ -183,12 +195,18 @@ void QPointLight::setLinearAttenuation(float value)
/*!
\qmlproperty float Qt3D.Render::PointLight::quadraticAttenuation
Specifies the quadratic attenuation of the point light
Specifies the quadratic attenuation of the point light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
/*!
\property Qt3DRender::QPointLight::quadraticAttenuation
Specifies the quadratic attenuation of the point light
Specifies the quadratic attenuation of the point light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
float QPointLight::quadraticAttenuation() const
{

View File

@ -140,12 +140,18 @@ QSpotLight::QSpotLight(QSpotLightPrivate &dd, QNode *parent)
/*!
\qmlproperty float Qt3D.Render::SpotLight::constantAttenuation
Specifies the constant attenuation of the spot light
Specifies the constant attenuation of the spot light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
/*!
\property Qt3DRender::QSpotLight::constantAttenuation
Specifies the constant attenuation of the spot light
Specifies the constant attenuation of the spot light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
float QSpotLight::constantAttenuation() const
{
@ -164,12 +170,18 @@ void QSpotLight::setConstantAttenuation(float value)
/*!
\qmlproperty float Qt3D.Render::SpotLight::linearAttenuation
Specifies the linear attenuation of the spot light
Specifies the linear attenuation of the spot light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
/*!
\property Qt3DRender::QSpotLight::linearAttenuation
Specifies the linear attenuation of the spot light
Specifies the linear attenuation of the spot light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
float QSpotLight::linearAttenuation() const
{
@ -188,12 +200,18 @@ void QSpotLight::setLinearAttenuation(float value)
/*!
\qmlproperty float Qt3D.Render::SpotLight::quadraticAttenuation
Specifies the quadratic attenuation of the spot light
Specifies the quadratic attenuation of the spot light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
/*!
\property Qt3DRender::QSpotLight::quadraticAttenuation
Specifies the quadratic attenuation of the spot light
Specifies the quadratic attenuation of the spot light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
float QSpotLight::quadraticAttenuation() const
{
@ -212,12 +230,18 @@ void QSpotLight::setQuadraticAttenuation(float value)
/*!
\qmlproperty vector3d Qt3D.Render::SpotLight::localDirection
Specifies the local direction of the spot light
Specifies the local direction of the spot light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
/*!
\property Qt3DRender::QSpotLight::localDirection
Specifies the local direction of the spot light
Specifies the local direction of the spot light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
QVector3D QSpotLight::localDirection() const
{
@ -227,12 +251,18 @@ QVector3D QSpotLight::localDirection() const
/*!
\qmlproperty float Qt3D.Render::SpotLight::cutOffAngle
Specifies the cut off angle of the spot light
Specifies the cut off angle of the spot light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
/*!
\property Qt3DRender::QSpotLight::cutOffAngle
Specifies the cut off angle of the spot light
Specifies the cut off angle of the spot light.
\note The exact meaning and use of this property is up to the
material implementation.
*/
float QSpotLight::cutOffAngle() const
{

View File

@ -1730,12 +1730,11 @@ void Renderer::clearDirtyBits(BackendNodeDirtySet changes)
}
#endif
bool Renderer::shouldRender()
bool Renderer::shouldRender() const
{
// Only render if something changed during the last frame, or the last frame
// was not rendered successfully (or render-on-demand is disabled)
return (m_settings->renderPolicy() == QRenderSettings::Always
|| m_renderThread == nullptr // <==> we use Scene3D
|| m_dirtyBits.marked != 0
|| m_dirtyBits.remaining != 0
|| !m_lastFrameCorrect.loadRelaxed());

View File

@ -206,7 +206,7 @@ public:
#if defined(QT_BUILD_INTERNAL)
void clearDirtyBits(BackendNodeDirtySet changes) override;
#endif
bool shouldRender() override;
bool shouldRender() const override;
void skipNextFrame() override;
void jobsDone(Qt3DCore::QAspectManager *manager) override;

View File

@ -282,6 +282,7 @@ RenderView::RenderView()
RenderView::~RenderView()
{
delete m_stateSet;
}
namespace {
@ -686,11 +687,9 @@ EntityRenderCommandData RenderView::buildDrawRenderCommands(const QVector<Entity
case QAttribute::DrawIndirectAttribute:
indirectAttribute = attribute;
break;
case QAttribute::VertexAttribute: {
if (command.m_activeAttributes.contains(attribute->nameId()))
estimatedCount = std::max(int(attribute->count()), estimatedCount);
case QAttribute::VertexAttribute:
estimatedCount = std::max(int(attribute->count()), estimatedCount);
break;
}
default:
Q_UNREACHABLE();
break;

View File

@ -146,6 +146,10 @@ private Q_SLOTS:
void shouldNotCrashInNormalStartupShutdownSequence()
{
#ifdef Q_OS_MACOS
QSKIP("Test frequently times out. See QTBUG-80660.");
#endif
// GIVEN
// An initialized aspect engine...
QAspectEngine engine;

View File

@ -55,7 +55,7 @@ public:
void doRender(bool swapBuffers) override { Q_UNUSED(swapBuffers) }
void cleanGraphicsResources() override {}
bool isRunning() const override { return true; }
bool shouldRender() override { return true; }
bool shouldRender() const override { return true; }
void skipNextFrame() override {}
void jobsDone(Qt3DCore::QAspectManager *manager) override { Q_UNUSED(manager) }
QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() override { return QVector<Qt3DCore::QAspectJobPtr>(); }

View File

@ -426,12 +426,15 @@ private Q_SLOTS:
simulateInitializationSync(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:
simulateInitializationSync(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()

View File

@ -454,7 +454,7 @@ private Q_SLOTS:
simulateInitializationSync(dataBuffer.data(), backendBuffer);
QByteArray indexData;
indexData.resize(sizeof(uint) * 3 * 4);
indexData.resize(sizeof(uint) * 4 * 4);
uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
iDataPtr[0] = 0;
iDataPtr[1] = 1;
@ -468,6 +468,10 @@ private Q_SLOTS:
iDataPtr[9] = 4;
iDataPtr[10] = 3;
iDataPtr[11] = 2;
iDataPtr[12] = static_cast<uint>(-1);
iDataPtr[13] = 0;
iDataPtr[14] = 1;
iDataPtr[15] = 2;
indexDataBuffer->setData(indexData);
Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
@ -486,7 +490,7 @@ private Q_SLOTS:
indexAttribute->setBuffer(indexDataBuffer.data());
indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(3*4);
indexAttribute->setCount(4*4);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
geometry->addAttribute(positionAttribute.data());
@ -494,6 +498,8 @@ private Q_SLOTS:
geometryRenderer->setGeometry(geometry);
geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::TriangleStrip);
geometryRenderer->setPrimitiveRestartEnabled(true);
geometryRenderer->setRestartIndexValue(-1);
Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
backendAttribute->setRenderer(&renderer);
@ -516,7 +522,7 @@ private Q_SLOTS:
visitor.apply(backendRenderer, Qt3DCore::QNodeId());
// THEN
QVERIFY(visitor.triangleCount() == 8);
QCOMPARE(visitor.triangleCount(), 9U);
QVERIFY(visitor.verifyTriangle(0, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
QVERIFY(visitor.verifyTriangle(1, 3,2,1, Vector3D(0,0,1), Vector3D(0,1,0), Vector3D(1,0,0)));
QVERIFY(visitor.verifyTriangle(2, 4,3,2, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(0,1,0)));
@ -525,6 +531,7 @@ private Q_SLOTS:
QVERIFY(visitor.verifyTriangle(5, 4,0,1, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(1,0,0)));
QVERIFY(visitor.verifyTriangle(6, 3,4,0, Vector3D(0,0,1), Vector3D(1,0,0), Vector3D(0,0,1)));
QVERIFY(visitor.verifyTriangle(7, 2,3,4, Vector3D(0,1,0), Vector3D(0,0,1), Vector3D(1,0,0)));
QVERIFY(visitor.verifyTriangle(8, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
}
void testVisitTriangleFan()
@ -643,7 +650,7 @@ private Q_SLOTS:
simulateInitializationSync(dataBuffer.data(), backendBuffer);
QByteArray indexData;
indexData.resize(sizeof(uint) * 3 * 2);
indexData.resize(sizeof(uint) * 10);
uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
iDataPtr[0] = 0;
iDataPtr[1] = 1;
@ -651,6 +658,10 @@ private Q_SLOTS:
iDataPtr[3] = 3;
iDataPtr[4] = 4;
iDataPtr[5] = 5;
iDataPtr[6] = static_cast<uint>(-1);
iDataPtr[7] = 0;
iDataPtr[8] = 1;
iDataPtr[9] = 2;
indexDataBuffer->setData(indexData);
Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
@ -669,7 +680,7 @@ private Q_SLOTS:
indexAttribute->setBuffer(indexDataBuffer.data());
indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(3*2);
indexAttribute->setCount(10);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
geometry->addAttribute(positionAttribute.data());
@ -677,6 +688,8 @@ private Q_SLOTS:
geometryRenderer->setGeometry(geometry);
geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::TriangleFan);
geometryRenderer->setPrimitiveRestartEnabled(true);
geometryRenderer->setRestartIndexValue(-1);
Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
backendAttribute->setRenderer(&renderer);
@ -699,11 +712,12 @@ private Q_SLOTS:
visitor.apply(backendRenderer, Qt3DCore::QNodeId());
// THEN
QVERIFY(visitor.triangleCount() == 4);
QCOMPARE(visitor.triangleCount(), 5U);
QVERIFY(visitor.verifyTriangle(0, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
QVERIFY(visitor.verifyTriangle(1, 3,2,0, Vector3D(0,0,1), Vector3D(0,1,0), Vector3D(0,0,1)));
QVERIFY(visitor.verifyTriangle(2, 4,3,0, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(0,0,1)));
QVERIFY(visitor.verifyTriangle(3, 5,4,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
QVERIFY(visitor.verifyTriangle(4, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
}
void testVisitTrianglesAdjacency()