summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-5.14.049
-rw-r--r--src/extras/shaders/es2/distancefieldtext.frag2
-rw-r--r--src/extras/shaders/gl3/distancefieldtext.frag2
-rw-r--r--src/extras/text/qtext2dentity.cpp13
-rw-r--r--src/quick3d/imports/scene3d/scene3ditem.cpp23
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer.cpp19
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer_p.h3
-rw-r--r--src/quick3d/quick3d/qquaternionanimation.cpp2
-rw-r--r--src/render/backend/abstractrenderer_p.h2
-rw-r--r--src/render/backend/bufferutils_p.h4
-rw-r--r--src/render/backend/segmentsvisitor.cpp52
-rw-r--r--src/render/backend/trianglesvisitor.cpp11
-rw-r--r--src/render/backend/visitorutils_p.h2
-rw-r--r--src/render/lights/qdirectionallight.cpp10
-rw-r--r--src/render/lights/qenvironmentlight.cpp12
-rw-r--r--src/render/lights/qpointlight.cpp30
-rw-r--r--src/render/lights/qspotlight.cpp50
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp3
-rw-r--r--src/render/renderers/opengl/renderer/renderer_p.h2
-rw-r--r--src/render/renderers/opengl/renderer/renderview.cpp7
-rw-r--r--tests/auto/core/qaspectengine/tst_qaspectengine.cpp4
-rw-r--r--tests/auto/render/commons/testrenderer.h2
-rw-r--r--tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp27
-rw-r--r--tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp26
24 files changed, 278 insertions, 79 deletions
diff --git a/dist/changes-5.14.0 b/dist/changes-5.14.0
new file mode 100644
index 000000000..442296db8
--- /dev/null
+++ b/dist/changes-5.14.0
@@ -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
diff --git a/src/extras/shaders/es2/distancefieldtext.frag b/src/extras/shaders/es2/distancefieldtext.frag
index d2db2e306..b7563e397 100644
--- a/src/extras/shaders/es2/distancefieldtext.frag
+++ b/src/extras/shaders/es2/distancefieldtext.frag
@@ -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));
}
diff --git a/src/extras/shaders/gl3/distancefieldtext.frag b/src/extras/shaders/gl3/distancefieldtext.frag
index 23dff8e0f..8e0684adc 100644
--- a/src/extras/shaders/gl3/distancefieldtext.frag
+++ b/src/extras/shaders/gl3/distancefieldtext.frag
@@ -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;
}
diff --git a/src/extras/text/qtext2dentity.cpp b/src/extras/text/qtext2dentity.cpp
index aa4785fe7..897672782 100644
--- a/src/extras/text/qtext2dentity.cpp
+++ b/src/extras/text/qtext2dentity.cpp
@@ -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()
diff --git a/src/quick3d/imports/scene3d/scene3ditem.cpp b/src/quick3d/imports/scene3d/scene3ditem.cpp
index c93d10b64..f824d2c4e 100644
--- a/src/quick3d/imports/scene3d/scene3ditem.cpp
+++ b/src/quick3d/imports/scene3d/scene3ditem.cpp
@@ -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
diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp
index 1e322a615..fafeeedf4 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer.cpp
+++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp
@@ -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)
{
diff --git a/src/quick3d/imports/scene3d/scene3drenderer_p.h b/src/quick3d/imports/scene3d/scene3drenderer_p.h
index 4f3651cd3..08a2c60a3 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer_p.h
+++ b/src/quick3d/imports/scene3d/scene3drenderer_p.h
@@ -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;
diff --git a/src/quick3d/quick3d/qquaternionanimation.cpp b/src/quick3d/quick3d/qquaternionanimation.cpp
index 22cc905f7..933a08ee4 100644
--- a/src/quick3d/quick3d/qquaternionanimation.cpp
+++ b/src/quick3d/quick3d/qquaternionanimation.cpp
@@ -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;
diff --git a/src/render/backend/abstractrenderer_p.h b/src/render/backend/abstractrenderer_p.h
index 518c0809c..8bbfcd548 100644
--- a/src/render/backend/abstractrenderer_p.h
+++ b/src/render/backend/abstractrenderer_p.h
@@ -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;
diff --git a/src/render/backend/bufferutils_p.h b/src/render/backend/bufferutils_p.h
index 2bb35fac6..ea783df0d 100644
--- a/src/render/backend/bufferutils_p.h
+++ b/src/render/backend/bufferutils_p.h
@@ -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;
};
diff --git a/src/render/backend/segmentsvisitor.cpp b/src/render/backend/segmentsvisitor.cpp
index a3a5d059c..d9f2d79ec 100644
--- a/src/render/backend/segmentsvisitor.cpp
+++ b/src/render/backend/segmentsvisitor.cpp
@@ -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]);
+ }
}
}
}
diff --git a/src/render/backend/trianglesvisitor.cpp b/src/render/backend/trianglesvisitor.cpp
index 87ba7bde9..a58f2d20b 100644
--- a/src/render/backend/trianglesvisitor.cpp
+++ b/src/render/backend/trianglesvisitor.cpp
@@ -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;
}
}
diff --git a/src/render/backend/visitorutils_p.h b/src/render/backend/visitorutils_p.h
index 6a5c7b4ff..14183e11b 100644
--- a/src/render/backend/visitorutils_p.h
+++ b/src/render/backend/visitorutils_p.h
@@ -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;
diff --git a/src/render/lights/qdirectionallight.cpp b/src/render/lights/qdirectionallight.cpp
index 13fb78843..51827b644 100644
--- a/src/render/lights/qdirectionallight.cpp
+++ b/src/render/lights/qdirectionallight.cpp
@@ -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)
{
diff --git a/src/render/lights/qenvironmentlight.cpp b/src/render/lights/qenvironmentlight.cpp
index 86ef04f95..977e117db 100644
--- a/src/render/lights/qenvironmentlight.cpp
+++ b/src/render/lights/qenvironmentlight.cpp
@@ -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
{
diff --git a/src/render/lights/qpointlight.cpp b/src/render/lights/qpointlight.cpp
index 2b042c91d..c16291709 100644
--- a/src/render/lights/qpointlight.cpp
+++ b/src/render/lights/qpointlight.cpp
@@ -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
{
diff --git a/src/render/lights/qspotlight.cpp b/src/render/lights/qspotlight.cpp
index eddafbe61..c725a6baf 100644
--- a/src/render/lights/qspotlight.cpp
+++ b/src/render/lights/qspotlight.cpp
@@ -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
{
diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp
index 352067492..1e0f6ba96 100644
--- a/src/render/renderers/opengl/renderer/renderer.cpp
+++ b/src/render/renderers/opengl/renderer/renderer.cpp
@@ -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());
diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h
index 49847196b..d5d2deb31 100644
--- a/src/render/renderers/opengl/renderer/renderer_p.h
+++ b/src/render/renderers/opengl/renderer/renderer_p.h
@@ -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;
diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp
index 3612d8767..c00a92629 100644
--- a/src/render/renderers/opengl/renderer/renderview.cpp
+++ b/src/render/renderers/opengl/renderer/renderview.cpp
@@ -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;
diff --git a/tests/auto/core/qaspectengine/tst_qaspectengine.cpp b/tests/auto/core/qaspectengine/tst_qaspectengine.cpp
index 466e103ec..48443a66f 100644
--- a/tests/auto/core/qaspectengine/tst_qaspectengine.cpp
+++ b/tests/auto/core/qaspectengine/tst_qaspectengine.cpp
@@ -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;
diff --git a/tests/auto/render/commons/testrenderer.h b/tests/auto/render/commons/testrenderer.h
index 8cab7edfc..05ef4c130 100644
--- a/tests/auto/render/commons/testrenderer.h
+++ b/tests/auto/render/commons/testrenderer.h
@@ -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>(); }
diff --git a/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp b/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp
index 4db12136a..fc65d0854 100644
--- a/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp
+++ b/tests/auto/render/segmentvisitor/tst_segmentvisitor.cpp
@@ -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()
diff --git a/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp b/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp
index 8dfda0eea..66f67e08a 100644
--- a/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp
+++ b/tests/auto/render/trianglevisitor/tst_trianglevisitor.cpp
@@ -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()