mirror of https://github.com/qt/qt3d.git
Merge remote-tracking branch 'origin/5.14' into 5.15
Change-Id: I5a5b1d497430afdd0fe11933832a2477a7efbe30
This commit is contained in:
commit
e77c85a200
|
|
@ -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
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>(); }
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue