diff options
author | Liang Qi <liang.qi@qt.io> | 2016-11-26 12:51:54 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-11-28 09:57:44 +0100 |
commit | a2c6c81f5c67390629a313ff7ba985d0967ca1fa (patch) | |
tree | e812286604ff3b34fe6678e145590b739de6d72b | |
parent | 4f46ccc4517a52b152d36e7734c2042e06ea8de3 (diff) | |
parent | 1c52a489c1eed52107cdde28890ca230424bd85b (diff) |
Merge remote-tracking branch 'origin/5.7' into 5.8
Conflicts:
src/input/backend/updateaxisactionjob.cpp
src/render/renderstates/qalphacoverage.cpp
src/render/renderstates/qclipplane.cpp
src/render/renderstates/qdithering.cpp
src/render/renderstates/qseamlesscubemap.cpp
src/render/renderstates/qstenciltest.cpp
Change-Id: I5b279d30bbbb06af5e8ee9fc47e9794b78a567f5
66 files changed, 3025 insertions, 1472 deletions
diff --git a/examples/qt3d/deferred-renderer-cpp/deferred-renderer-cpp.pro b/examples/qt3d/deferred-renderer-cpp/deferred-renderer-cpp.pro deleted file mode 100644 index f9f239f24..000000000 --- a/examples/qt3d/deferred-renderer-cpp/deferred-renderer-cpp.pro +++ /dev/null @@ -1,33 +0,0 @@ -!include( ../examples.pri ) { - error( "Couldn't find the examples.pri file!" ) -} - -QT += 3dcore 3drender 3dinput 3dextras - -HEADERS += \ - gbuffer.h \ - deferredrenderer.h \ - finaleffect.h \ - sceneeffect.h \ - pointlightblock.h - -SOURCES += \ - main.cpp \ - gbuffer.cpp \ - deferredrenderer.cpp \ - finaleffect.cpp \ - sceneeffect.cpp \ - pointlightblock.cpp - -RESOURCES += \ - deferred-renderer-cpp.qrc - -OTHER_FILES += \ - geometry_gl2.vert \ - geometry_gl2.frag \ - geometry_gl3.frag \ - geometry_gl3.vert \ - final_gl2.vert \ - final_gl2.frag \ - final_gl3.frag \ - final_gl3.vert diff --git a/examples/qt3d/deferred-renderer-cpp/deferred-renderer-cpp.qrc b/examples/qt3d/deferred-renderer-cpp/deferred-renderer-cpp.qrc deleted file mode 100644 index 0e38e39ca..000000000 --- a/examples/qt3d/deferred-renderer-cpp/deferred-renderer-cpp.qrc +++ /dev/null @@ -1,12 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>geometry_gl2.frag</file> - <file>geometry_gl2.vert</file> - <file>geometry_gl3.frag</file> - <file>geometry_gl3.vert</file> - <file>final_gl2.frag</file> - <file>final_gl2.vert</file> - <file>final_gl3.frag</file> - <file>final_gl3.vert</file> - </qresource> -</RCC> diff --git a/examples/qt3d/deferred-renderer-cpp/doc/src/deferred-renderer-cpp.qdoc b/examples/qt3d/deferred-renderer-cpp/doc/src/deferred-renderer-cpp.qdoc deleted file mode 100644 index 610270316..000000000 --- a/examples/qt3d/deferred-renderer-cpp/doc/src/deferred-renderer-cpp.qdoc +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example deferred-renderer-cpp - \title Qt 3D: Deferred Renderer C++ Example - \ingroup qt3d-examples-cpp - \brief A C++ application that demonstrates rendering to an intermediate - G-buffer. - - \e {Deferred Renderer} demonstrates using a two pass rendering method. - First, all the meshes in the scene are drawn using the same shader that will - output the following values for each fragment: world normal vector, color, - depth, and world position vector. - - Each of these values will be stored in a texture, which together form what - is called the G-buffer. Nothing is drawn onscreen during the first pass, but - rather drawn into the G-buffer ready for later use. - - Once all the meshes have been drawn, the G-buffer is filled with all the - meshes that can currently be seen by the camera. The second render pass is - then used to render the scene to the back buffer with the final color - shading by reading the values from the G-buffer textures and outputting a - color onto a full screen quad. - - For more information, see \l{Deferred Renderer}. - - \include examples-run.qdocinc -*/ diff --git a/examples/qt3d/deferred-renderer-cpp/final_gl2.frag b/examples/qt3d/deferred-renderer-cpp/final_gl2.frag deleted file mode 100644 index f384a2df4..000000000 --- a/examples/qt3d/deferred-renderer-cpp/final_gl2.frag +++ /dev/null @@ -1,36 +0,0 @@ -#version 110 - -uniform sampler2D color; -uniform sampler2D position; -uniform sampler2D normal; -uniform vec2 winSize; - -struct PointLight -{ - vec3 position; - vec3 direction; - vec4 color; - float intensity; -}; - -const int lightCount = 3; -uniform struct -{ - PointLight lights[lightCount]; -} pointLights; - -void main() -{ - vec2 texCoord = gl_FragCoord.xy / winSize; - vec4 col = texture2D(color, texCoord); - vec3 pos = texture2D(position, texCoord).xyz; - vec3 norm = texture2D(normal, texCoord).xyz; - - vec4 lightColor; - for (int i = 0; i < 3; i++) { - vec3 s = normalize(pointLights.lights[i].position - pos); - lightColor += pointLights.lights[i].color * (pointLights.lights[i].intensity * max(dot(s, norm), 0.0)); - } - lightColor /= float(lightCount); - gl_FragColor = col * lightColor; -} diff --git a/examples/qt3d/deferred-renderer-cpp/final_gl2.vert b/examples/qt3d/deferred-renderer-cpp/final_gl2.vert deleted file mode 100644 index a907e10ca..000000000 --- a/examples/qt3d/deferred-renderer-cpp/final_gl2.vert +++ /dev/null @@ -1,9 +0,0 @@ -#version 110 - -attribute vec4 vertexPosition; -uniform mat4 modelMatrix; - -void main() -{ - gl_Position = modelMatrix * vertexPosition; -} diff --git a/examples/qt3d/deferred-renderer-cpp/final_gl3.frag b/examples/qt3d/deferred-renderer-cpp/final_gl3.frag deleted file mode 100644 index 88abd5cb1..000000000 --- a/examples/qt3d/deferred-renderer-cpp/final_gl3.frag +++ /dev/null @@ -1,37 +0,0 @@ -#version 140 - -uniform sampler2D color; -uniform sampler2D position; -uniform sampler2D normal; -uniform vec2 winSize; - -out vec4 fragColor; - -struct PointLight -{ - vec3 position; - vec3 direction; - vec4 color; - float intensity; -}; - -const int lightCount = 3; -uniform PointLightBlock { - PointLight lights[lightCount]; -}; - -void main() -{ - vec2 texCoord = gl_FragCoord.xy / winSize; - vec4 col = texture(color, texCoord); - vec3 pos = texture(position, texCoord).xyz; - vec3 norm = texture(normal, texCoord).xyz; - - vec4 lightColor; - for (int i = 0; i < 3; i++) { - vec3 s = normalize(lights[i].position - pos); - lightColor += lights[i].color * (lights[i].intensity * max(dot(s, norm), 0.0)); - } - lightColor /= float(lightCount); - fragColor = col * lightColor; -} diff --git a/examples/qt3d/deferred-renderer-cpp/final_gl3.vert b/examples/qt3d/deferred-renderer-cpp/final_gl3.vert deleted file mode 100644 index 60410d34d..000000000 --- a/examples/qt3d/deferred-renderer-cpp/final_gl3.vert +++ /dev/null @@ -1,9 +0,0 @@ -#version 140 - -in vec4 vertexPosition; -uniform mat4 modelMatrix; - -void main() -{ - gl_Position = modelMatrix * vertexPosition; -} diff --git a/examples/qt3d/deferred-renderer-cpp/finaleffect.cpp b/examples/qt3d/deferred-renderer-cpp/finaleffect.cpp deleted file mode 100644 index 63c821caa..000000000 --- a/examples/qt3d/deferred-renderer-cpp/finaleffect.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "finaleffect.h" - -#include <Qt3DRender/QGraphicsApiFilter> -#include <Qt3DRender/QShaderProgram> -#include <QUrl> - -FinalEffect::FinalEffect(Qt3DCore::QNode *parent) - : Qt3DRender::QEffect(parent) - , m_gl3Technique(new Qt3DRender::QTechnique()) - , m_gl2Technique(new Qt3DRender::QTechnique()) - , m_gl2Pass(new Qt3DRender::QRenderPass()) - , m_gl3Pass(new Qt3DRender::QRenderPass()) - , m_passCriterion(new Qt3DRender::QFilterKey(this)) -{ - m_gl3Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL); - m_gl3Technique->graphicsApiFilter()->setMajorVersion(3); - m_gl3Technique->graphicsApiFilter()->setMinorVersion(1); - m_gl3Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile); - - m_gl2Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL); - m_gl2Technique->graphicsApiFilter()->setMajorVersion(2); - m_gl2Technique->graphicsApiFilter()->setMinorVersion(0); - m_gl2Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::NoProfile); - - m_passCriterion->setName(QStringLiteral("pass")); - m_passCriterion->setValue(QStringLiteral("final")); - - Qt3DRender::QShaderProgram *gl3Shader = new Qt3DRender::QShaderProgram(); - gl3Shader->setVertexShaderCode(gl3Shader->loadSource(QUrl(QStringLiteral("qrc:/final_gl3.vert")))); - gl3Shader->setFragmentShaderCode(gl3Shader->loadSource(QUrl(QStringLiteral("qrc:/final_gl3.frag")))); - - m_gl3Pass->addFilterKey(m_passCriterion); - m_gl3Pass->setShaderProgram(gl3Shader); - m_gl3Technique->addRenderPass(m_gl3Pass); - - Qt3DRender::QShaderProgram *gl2Shader = new Qt3DRender::QShaderProgram(); - gl2Shader->setVertexShaderCode(gl2Shader->loadSource(QUrl(QStringLiteral("qrc:/final_gl2.vert")))); - gl2Shader->setFragmentShaderCode(gl2Shader->loadSource(QUrl(QStringLiteral("qrc:/final_gl2.frag")))); - - m_gl2Pass->addFilterKey(m_passCriterion); - m_gl2Pass->setShaderProgram(gl2Shader); - m_gl2Technique->addRenderPass(m_gl2Pass); - - addTechnique(m_gl3Technique); - addTechnique(m_gl2Technique); -} - -QList<Qt3DRender::QFilterKey *> FinalEffect::passCriteria() const -{ - return QList<Qt3DRender::QFilterKey *>() << m_passCriterion; -} diff --git a/examples/qt3d/deferred-renderer-cpp/finaleffect.h b/examples/qt3d/deferred-renderer-cpp/finaleffect.h deleted file mode 100644 index 69a1b126c..000000000 --- a/examples/qt3d/deferred-renderer-cpp/finaleffect.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef FINALEFFECT_H -#define FINALEFFECT_H - -#include <Qt3DRender/QEffect> -#include <Qt3DRender/QTechnique> - -class FinalEffect : public Qt3DRender::QEffect -{ -public: - explicit FinalEffect(Qt3DCore::QNode *parent = 0); - - QList<Qt3DRender::QFilterKey *> passCriteria() const; - inline Qt3DRender::QTechnique *gl3Technique() const { return m_gl3Technique; } - inline Qt3DRender::QTechnique *gl2Technique() const { return m_gl2Technique; } - -private : - Qt3DRender::QTechnique *m_gl3Technique; - Qt3DRender::QTechnique *m_gl2Technique; - Qt3DRender::QRenderPass *m_gl2Pass; - Qt3DRender::QRenderPass *m_gl3Pass; - Qt3DRender::QFilterKey *m_passCriterion; -}; - -#endif // FINALEFFECT_H diff --git a/examples/qt3d/deferred-renderer-cpp/gbuffer.cpp b/examples/qt3d/deferred-renderer-cpp/gbuffer.cpp deleted file mode 100644 index 984dbb1f2..000000000 --- a/examples/qt3d/deferred-renderer-cpp/gbuffer.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "gbuffer.h" - -GBuffer::GBuffer(Qt3DCore::QNode *parent) - : Qt3DRender::QRenderTarget(parent) -{ - const Qt3DRender::QAbstractTexture::TextureFormat formats[AttachmentsCount] = { - Qt3DRender::QAbstractTexture::RGBA32F, - Qt3DRender::QAbstractTexture::RGB32F, - Qt3DRender::QAbstractTexture::RGB16F, - Qt3DRender::QAbstractTexture::D32F - }; - - const Qt3DRender::QRenderTargetOutput::AttachmentPoint attachmentPoints[AttachmentsCount] = { - Qt3DRender::QRenderTargetOutput::Color0, - Qt3DRender::QRenderTargetOutput::Color1, - Qt3DRender::QRenderTargetOutput::Color2, - Qt3DRender::QRenderTargetOutput::Depth - }; - - for (int i = 0; i < AttachmentsCount; i++) { - Qt3DRender::QRenderTargetOutput *output = new Qt3DRender::QRenderTargetOutput(this); - - m_textures[i] = new Qt3DRender::QTexture2D(); - m_textures[i]->setFormat(formats[i]); - m_textures[i]->setWidth(1024); - m_textures[i]->setHeight(1024); - m_textures[i]->setGenerateMipMaps(false); - m_textures[i]->setWrapMode(Qt3DRender::QTextureWrapMode(Qt3DRender::QTextureWrapMode::ClampToEdge)); - m_textures[i]->setMinificationFilter(Qt3DRender::QAbstractTexture::Linear); - m_textures[i]->setMagnificationFilter(Qt3DRender::QAbstractTexture::Linear); - - output->setTexture(m_textures[i]); - output->setAttachmentPoint(attachmentPoints[i]); - addOutput(output); - } -} - -Qt3DRender::QAbstractTexture *GBuffer::colorTexture() const -{ - return m_textures[Color]; -} - -Qt3DRender::QAbstractTexture *GBuffer::positionTexture() const -{ - return m_textures[Position]; -} - -Qt3DRender::QAbstractTexture *GBuffer::normalTexture() const -{ - return m_textures[Normal]; -} - -Qt3DRender::QAbstractTexture *GBuffer::depthTexture() const -{ - return m_textures[Depth]; -} diff --git a/examples/qt3d/deferred-renderer-cpp/gbuffer.h b/examples/qt3d/deferred-renderer-cpp/gbuffer.h deleted file mode 100644 index dab8b6752..000000000 --- a/examples/qt3d/deferred-renderer-cpp/gbuffer.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GBUFFER_H -#define GBUFFER_H - -#include <Qt3DRender/QRenderTarget> -#include <Qt3DRender/qtexture.h> -#include <Qt3DRender/QRenderTargetOutput> - -class GBuffer : public Qt3DRender::QRenderTarget -{ -public: - explicit GBuffer(Qt3DCore::QNode *parent = 0); - - enum Attachments { - Color = 0, - Position, - Normal, - Depth, - AttachmentsCount - }; - - Qt3DRender::QAbstractTexture *colorTexture() const; - Qt3DRender::QAbstractTexture *positionTexture() const; - Qt3DRender::QAbstractTexture *normalTexture() const; - Qt3DRender::QAbstractTexture *depthTexture() const; - -private: - Qt3DRender::QAbstractTexture *m_textures[AttachmentsCount]; - Qt3DRender::QRenderTargetOutput *m_attachments[AttachmentsCount]; -}; - -#endif // GBUFFER_H diff --git a/examples/qt3d/deferred-renderer-cpp/geometry_gl2.frag b/examples/qt3d/deferred-renderer-cpp/geometry_gl2.frag deleted file mode 100644 index 0e7776f15..000000000 --- a/examples/qt3d/deferred-renderer-cpp/geometry_gl2.frag +++ /dev/null @@ -1,12 +0,0 @@ -#version 110 - -varying vec4 color0; -varying vec3 position0; -varying vec3 normal0; - -void main() -{ - gl_FragData[0] = color0; - gl_FragData[1] = vec4(position0, 0); - gl_FragData[2] = vec4(normal0, 0); -} diff --git a/examples/qt3d/deferred-renderer-cpp/geometry_gl2.vert b/examples/qt3d/deferred-renderer-cpp/geometry_gl2.vert deleted file mode 100644 index 72d5345f1..000000000 --- a/examples/qt3d/deferred-renderer-cpp/geometry_gl2.vert +++ /dev/null @@ -1,21 +0,0 @@ -#version 110 - -attribute vec4 vertexPosition; -attribute vec3 vertexNormal; - -varying vec4 color0; -varying vec3 position0; -varying vec3 normal0; - -uniform mat4 mvp; -uniform mat4 modelView; -uniform mat3 modelViewNormal; -uniform vec4 meshColor; - -void main() -{ - color0 = meshColor; - position0 = vec3(modelView * vertexPosition); - normal0 = normalize(modelViewNormal * vertexNormal); - gl_Position = mvp * vertexPosition; -} diff --git a/examples/qt3d/deferred-renderer-cpp/geometry_gl3.frag b/examples/qt3d/deferred-renderer-cpp/geometry_gl3.frag deleted file mode 100644 index 7d9c7d64e..000000000 --- a/examples/qt3d/deferred-renderer-cpp/geometry_gl3.frag +++ /dev/null @@ -1,16 +0,0 @@ -#version 140 - -in vec4 color0; -in vec3 position0; -in vec3 normal0; - -out vec4 color; -out vec3 position; -out vec3 normal; - -void main() -{ - color = color0; - position = position0; - normal = normal0; -} diff --git a/examples/qt3d/deferred-renderer-cpp/geometry_gl3.vert b/examples/qt3d/deferred-renderer-cpp/geometry_gl3.vert deleted file mode 100644 index d3e302d16..000000000 --- a/examples/qt3d/deferred-renderer-cpp/geometry_gl3.vert +++ /dev/null @@ -1,21 +0,0 @@ -#version 140 - -in vec4 vertexPosition; -in vec3 vertexNormal; - -out vec4 color0; -out vec3 position0; -out vec3 normal0; - -uniform mat4 mvp; -uniform mat4 modelView; -uniform mat3 modelViewNormal; -uniform vec4 meshColor; - -void main() -{ - color0 = meshColor; - position0 = vec3(modelView * vertexPosition); - normal0 = normalize(modelViewNormal * vertexNormal); - gl_Position = mvp * vertexPosition; -} diff --git a/examples/qt3d/deferred-renderer-cpp/pointlightblock.cpp b/examples/qt3d/deferred-renderer-cpp/pointlightblock.cpp deleted file mode 100644 index 36bab9966..000000000 --- a/examples/qt3d/deferred-renderer-cpp/pointlightblock.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "pointlightblock.h" - -PointLightBlock::PointLightBlock(Qt3DCore::QNode *parent) - : Qt3DRender::QShaderData(parent) -{ - -} - -PointLightBlock::~PointLightBlock() -{ -} - -QVector<Qt3DRender::QAbstractLight *> PointLightBlock::lights() const -{ - return m_lights; -} - -void PointLightBlock::addLight(Qt3DRender::QAbstractLight *light) -{ - m_lights.append(light); - emit lightsChanged(); -} - diff --git a/examples/qt3d/deferred-renderer-cpp/pointlightblock.h b/examples/qt3d/deferred-renderer-cpp/pointlightblock.h deleted file mode 100644 index 9c93528c8..000000000 --- a/examples/qt3d/deferred-renderer-cpp/pointlightblock.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef POINTLIGHTBLOCK_H -#define POINTLIGHTBLOCK_H - -#include <Qt3DRender/QAbstractLight> -#include <Qt3DRender/QShaderData> - -class PointLightBlock : public Qt3DRender::QShaderData -{ - Q_OBJECT - Q_PROPERTY(QVector<Qt3DRender::QAbstractLight *> lights READ lights NOTIFY lightsChanged) -public: - explicit PointLightBlock(Qt3DCore::QNode *parent = 0); - ~PointLightBlock(); - - QVector<Qt3DRender::QAbstractLight *> lights() const; - void addLight(Qt3DRender::QAbstractLight *light); - -Q_SIGNALS: - void lightsChanged(); - -private: - QVector<Qt3DRender::QAbstractLight *> m_lights; -}; - -#endif // POINTLIGHTBLOCK_H diff --git a/examples/qt3d/deferred-renderer-cpp/sceneeffect.cpp b/examples/qt3d/deferred-renderer-cpp/sceneeffect.cpp deleted file mode 100644 index bdb6ea76e..000000000 --- a/examples/qt3d/deferred-renderer-cpp/sceneeffect.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "sceneeffect.h" - -#include <Qt3DRender/QGraphicsApiFilter> -#include <Qt3DRender/QShaderProgram> -#include <QUrl> - -SceneEffect::SceneEffect(Qt3DCore::QNode *parent) - : Qt3DRender::QEffect(parent) - , m_gl3Technique(new Qt3DRender::QTechnique()) - , m_gl2Technique(new Qt3DRender::QTechnique()) - , m_gl2Pass(new Qt3DRender::QRenderPass()) - , m_gl3Pass(new Qt3DRender::QRenderPass()) - , m_passCriterion(new Qt3DRender::QFilterKey(this)) -{ - - m_gl3Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::NoProfile); - m_gl3Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL); - m_gl3Technique->graphicsApiFilter()->setMajorVersion(3); - m_gl3Technique->graphicsApiFilter()->setMinorVersion(3); - - m_gl2Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL); - m_gl2Technique->graphicsApiFilter()->setMajorVersion(2); - m_gl2Technique->graphicsApiFilter()->setMinorVersion(0); - m_gl2Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::NoProfile); - - - m_passCriterion->setName(QStringLiteral("pass")); - m_passCriterion->setValue(QStringLiteral("geometry")); - - Qt3DRender::QShaderProgram *gl3Shader = new Qt3DRender::QShaderProgram(); - gl3Shader->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/geometry_gl3.vert")))); - gl3Shader->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/geometry_gl3.frag")))); - - m_gl3Pass->addFilterKey(m_passCriterion); - m_gl3Pass->setShaderProgram(gl3Shader); - m_gl3Technique->addRenderPass(m_gl3Pass); - - Qt3DRender::QShaderProgram *gl2Shader = new Qt3DRender::QShaderProgram(); - gl2Shader->setVertexShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/geometry_gl2.vert")))); - gl2Shader->setFragmentShaderCode(Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/geometry_gl2.frag")))); - - m_gl2Pass->addFilterKey(m_passCriterion); - m_gl2Pass->setShaderProgram(gl2Shader); - m_gl2Technique->addRenderPass(m_gl2Pass); - - addTechnique(m_gl3Technique); - addTechnique(m_gl2Technique); -} - -QList<Qt3DRender::QFilterKey *> SceneEffect::passCriteria() const -{ - return QList<Qt3DRender::QFilterKey *>() << m_passCriterion; -} diff --git a/examples/qt3d/deferred-renderer-cpp/sceneeffect.h b/examples/qt3d/deferred-renderer-cpp/sceneeffect.h deleted file mode 100644 index eb361c273..000000000 --- a/examples/qt3d/deferred-renderer-cpp/sceneeffect.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SCENEEFFECT_H -#define SCENEEFFECT_H - -#include <Qt3DRender/QEffect> -#include <Qt3DRender/QTechnique> - -class SceneEffect : public Qt3DRender::QEffect -{ -public: - explicit SceneEffect(Qt3DCore::QNode *parent = 0); - - QList<Qt3DRender::QFilterKey *> passCriteria() const; - -private: - Qt3DRender::QTechnique *m_gl3Technique; - Qt3DRender::QTechnique *m_gl2Technique; - Qt3DRender::QRenderPass *m_gl2Pass; - Qt3DRender::QRenderPass *m_gl3Pass; - Qt3DRender::QFilterKey *m_passCriterion; -}; - -#endif // SCENEEFFECT_H diff --git a/src/core/resources/qframeallocator.cpp b/src/core/resources/qframeallocator.cpp index ff15dadf6..61a82a2b4 100644 --- a/src/core/resources/qframeallocator.cpp +++ b/src/core/resources/qframeallocator.cpp @@ -147,25 +147,30 @@ void QFixedFrameAllocator::init(uint blockSize, uchar pageSize) void *QFixedFrameAllocator::allocate() { - Q_ASSERT(m_blockSize && m_nbrBlock); - if (m_lastAllocatedChunck == nullptr || - m_lastAllocatedChunck->m_blocksAvailable == 0) { - int i = 0; - for (; i < m_chunks.size(); i++) { - if (m_chunks[i].m_blocksAvailable > 0) { - m_lastAllocatedChunck = m_chunks.begin() + i; - break; - } - } - if (i == m_chunks.size()) { - m_chunks.resize(m_chunks.size() + 1); - QFrameChunk &newChunk = m_chunks.last(); - newChunk.init(m_blockSize, m_nbrBlock); - m_lastAllocatedChunck = &newChunk; - m_lastFreedChunck = m_lastAllocatedChunck; + Q_ASSERT(m_blockSize); + return scan().allocate(m_blockSize); +} + +QFrameChunk &QFixedFrameAllocator::scan() +{ + Q_ASSERT(m_blockSize); + Q_ASSERT(m_nbrBlock); + + if (m_lastAllocatedChunck && m_lastAllocatedChunck->m_blocksAvailable) + return *m_lastAllocatedChunck; + + for (int i = 0; i < m_chunks.size(); i++) { + if (m_chunks[i].m_blocksAvailable > 0) { + m_lastAllocatedChunck = m_chunks.begin() + i; + return *m_lastAllocatedChunck; } } - return m_lastAllocatedChunck->allocate(m_blockSize); + m_chunks.resize(m_chunks.size() + 1); + QFrameChunk &newChunk = m_chunks.last(); + newChunk.init(m_blockSize, m_nbrBlock); + m_lastAllocatedChunck = &newChunk; + m_lastFreedChunck = &newChunk; + return newChunk; } void QFixedFrameAllocator::deallocate(void *ptr) diff --git a/src/core/resources/qframeallocator_p_p.h b/src/core/resources/qframeallocator_p_p.h index b49def87a..bf4e0a2b1 100644 --- a/src/core/resources/qframeallocator_p_p.h +++ b/src/core/resources/qframeallocator_p_p.h @@ -96,6 +96,9 @@ public: inline uint blockSize() const { return m_blockSize; } private: + QFrameChunk &scan(); + +private: uint m_blockSize; uchar m_nbrBlock; QVector<QFrameChunk> m_chunks; diff --git a/src/doc/src/qt3d-index.qdoc b/src/doc/src/qt3d-index.qdoc index 55d0607f9..f14909cec 100644 --- a/src/doc/src/qt3d-index.qdoc +++ b/src/doc/src/qt3d-index.qdoc @@ -78,7 +78,7 @@ A Qt Quick application requires also additional dependencies: \badcode - QT += 3dcore 3drenderer 3dinput qml quick 3dquick + QT += 3dcore 3drender 3dinput 3dlogic 3dextras qml quick 3dquick \endcode \section1 Overview diff --git a/src/plugins/sceneparsers/gltf/gltfparser.cpp b/src/plugins/sceneparsers/gltf/gltfparser.cpp new file mode 100644 index 000000000..e42ebb510 --- /dev/null +++ b/src/plugins/sceneparsers/gltf/gltfparser.cpp @@ -0,0 +1,1560 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gltfparser.h" + +#include <QtCore/QDir> +#include <QtCore/QFileInfo> +#include <QtCore/QJsonArray> +#include <QtCore/QJsonObject> + +#include <QtGui/QVector2D> + +#include <Qt3DCore/QCameraLens> +#include <Qt3DCore/QEntity> +#include <Qt3DCore/QTransform> + +#include <Qt3DRender/private/qurlhelper_p.h> + +#include <Qt3DRender/QAlphaCoverage> +#include <Qt3DRender/QBlendEquation> +#include <Qt3DRender/QBlendStateSeparate> +#include <Qt3DRender/QColorMask> +#include <Qt3DRender/QCullFace> +#include <Qt3DRender/QDepthMask> +#include <Qt3DRender/QDepthTest> +#include <Qt3DRender/QEffect> +#include <Qt3DRender/QFrontFace> +#include <Qt3DRender/QGeometry> +#include <Qt3DRender/QGeometryRenderer> +#include <Qt3DRender/QMaterial> +#include <Qt3DRender/QGraphicsApiFilter> +#include <Qt3DRender/QParameter> +#include <Qt3DRender/QParameterMapping> +#include <Qt3DRender/QPolygonOffset> +#include <Qt3DRender/QRenderState> +#include <Qt3DRender/QScissorTest> +#include <Qt3DRender/QShaderProgram> +#include <Qt3DRender/QTechnique> +#include <Qt3DRender/QTexture> + +#include <Qt3DRender/QPhongMaterial> +#include <Qt3DRender/QDiffuseMapMaterial> +#include <Qt3DRender/QDiffuseSpecularMapMaterial> +#include <Qt3DRender/QNormalDiffuseMapMaterial> +#include <Qt3DRender/QNormalDiffuseSpecularMapMaterial> + +QT_BEGIN_NAMESPACE + +using namespace Qt3DCore; + +namespace Qt3DRender { + +Q_LOGGING_CATEGORY(GLTFParserLog, "Qt3D.GLTFParser") + +namespace { + +const QString KEY_CAMERA = QStringLiteral("camera"); +const QString KEY_CAMERAS = QStringLiteral("cameras"); +const QString KEY_SCENES = QStringLiteral("scenes"); +const QString KEY_NODES = QStringLiteral("nodes"); +const QString KEY_MESHES = QStringLiteral("meshes"); +const QString KEY_CHILDREN = QStringLiteral("children"); +const QString KEY_MATRIX = QStringLiteral("matrix"); +const QString KEY_ROTATION = QStringLiteral("rotation"); +const QString KEY_SCALE = QStringLiteral("scale"); +const QString KEY_TRANSLATION = QStringLiteral("translation"); +const QString KEY_TYPE = QStringLiteral("type"); +const QString KEY_PERSPECTIVE =QStringLiteral("perspective"); +const QString KEY_NAME = QStringLiteral("name"); +const QString KEY_COUNT = QStringLiteral("count"); +const QString KEY_YFOV = QStringLiteral("yfov"); +const QString KEY_ZNEAR = QStringLiteral("znear"); +const QString KEY_ZFAR = QStringLiteral("zfar"); +const QString KEY_MATERIALS = QStringLiteral("materials"); +const QString KEY_EXTENSIONS = QStringLiteral("extensions"); +const QString KEY_COMMON_MAT = QStringLiteral("KHR_materials_common"); +const QString KEY_TECHNIQUE = QStringLiteral("technique"); +const QString KEY_VALUES = QStringLiteral("values"); +const QString KEY_BUFFERS = QStringLiteral("buffers"); +const QString KEY_SHADERS = QStringLiteral("shaders"); +const QString KEY_PROGRAMS = QStringLiteral("programs"); +const QString KEY_PROGRAM = QStringLiteral("program"); +const QString KEY_TECHNIQUES = QStringLiteral("techniques"); +const QString KEY_ACCESSORS = QStringLiteral("accessors"); +const QString KEY_IMAGES = QStringLiteral("images"); +const QString KEY_TEXTURES = QStringLiteral("textures"); +const QString KEY_SCENE = QStringLiteral("scene"); +const QString KEY_BUFFER = QStringLiteral("buffer"); +const QString KEY_TARGET = QStringLiteral("target"); +const QString KEY_BYTE_OFFSET = QStringLiteral("byteOffset"); +const QString KEY_BYTE_LENGTH = QStringLiteral("byteLength"); +const QString KEY_BYTE_STRIDE = QStringLiteral("byteStride"); +const QString KEY_PRIMITIVES = QStringLiteral("primitives"); +const QString KEY_MODE = QStringLiteral("mode"); +const QString KEY_MATERIAL = QStringLiteral("material"); +const QString KEY_ATTRIBUTES = QStringLiteral("attributes"); +const QString KEY_INDICES = QStringLiteral("indices"); +const QString KEY_URI = QStringLiteral("uri"); +const QString KEY_FORMAT = QStringLiteral("format"); +const QString KEY_PASSES = QStringLiteral("passes"); +const QString KEY_SOURCE = QStringLiteral("source"); +const QString KEY_SAMPLER = QStringLiteral("sampler"); +const QString KEY_SAMPLERS = QStringLiteral("samplers"); +const QString KEY_SEMANTIC = QStringLiteral("semantic"); +const QString KEY_STATES = QStringLiteral("states"); +const QString KEY_UNIFORMS = QStringLiteral("uniforms"); +const QString KEY_PARAMETERS = QStringLiteral("parameters"); +const QString KEY_WRAP_S = QStringLiteral("wrapS"); +const QString KEY_MIN_FILTER = QStringLiteral("minFilter"); +const QString KEY_MAG_FILTER = QStringLiteral("magFilter"); + +const QString KEY_INSTANCE_TECHNIQUE = QStringLiteral("instanceTechnique"); +const QString KEY_INSTANCE_PROGRAM = QStringLiteral("instanceProgram"); +const QString KEY_BUFFER_VIEWS = QStringLiteral("bufferViews"); +const QString KEY_BUFFER_VIEW = QStringLiteral("bufferView"); +const QString KEY_VERTEX_SHADER = QStringLiteral("vertexShader"); +const QString KEY_FRAGMENT_SHADER = QStringLiteral("fragmentShader"); +const QString KEY_INTERNAL_FORMAT = QStringLiteral("internalFormat"); +const QString KEY_COMPONENT_TYPE = QStringLiteral("componentType"); +const QString KEY_ASPECT_RATIO = QStringLiteral("aspect_ratio"); +const QString KEY_VALUE = QStringLiteral("value"); +const QString KEY_ENABLE = QStringLiteral("enable"); +const QString KEY_FUNCTIONS = QStringLiteral("functions"); +const QString KEY_TECHNIQUE_CORE = QStringLiteral("techniqueCore"); +const QString KEY_TECHNIQUE_GL2 = QStringLiteral("techniqueGL2"); + +} // of anonymous namespace + +GLTFParser::GLTFParser() : QAbstractSceneParser(), + m_parseDone(false) +{ +} + +GLTFParser::~GLTFParser() +{ + +} + +void GLTFParser::setBasePath(const QString& path) +{ + m_basePath = path; +} + +bool GLTFParser::setJSON(const QJsonDocument &json ) +{ + if ( !json.isObject() ) { + return false; + } + + m_json = json; + m_parseDone = false; + + cleanup(); + + return true; +} + +/*! + * Sets the \a path used by the parser to load the scene file. + * If the file is valid, parsing is automatically triggered. + */ +void GLTFParser::setSource(const QUrl &source) +{ + const QString path = QUrlHelper::urlToLocalFileOrQrc(source); + QFile f(path); + if (Q_UNLIKELY(!f.open(QIODevice::ReadOnly))) { + qCWarning(GLTFParserLog) << "cannot open " << path << ": " << f.errorString(); + return; + } + + QByteArray jsonData = f.readAll(); + QJsonDocument sceneDocument = QJsonDocument::fromBinaryData(jsonData); + if (sceneDocument.isNull()) + sceneDocument = QJsonDocument::fromJson(jsonData); + + if (!setJSON(sceneDocument)) { + qCWarning(GLTFParserLog) << "not a JSON document"; + return; + } + + setBasePath(QFileInfo(path).dir().absolutePath()); +} + +/*! + * Returns true if the extension of \a path is supported by the + * GLTF parser. + */ +bool GLTFParser::isExtensionSupported(const QUrl &source) const +{ + const QString path = QUrlHelper::urlToLocalFileOrQrc(source); + return GLTFParser::isGLTFPath(path); +} + +Qt3DCore::QEntity* GLTFParser::node(const QString &id) +{ + QJsonObject nodes = m_json.object().value(KEY_NODES).toObject(); + if (!nodes.contains(id)) { + qCWarning(GLTFParserLog) << "unknown node" << id << "in GLTF file" << m_basePath; + return NULL; + } + + QJsonObject jsonObj = nodes.value(id).toObject(); + QEntity* result = Q_NULLPTR; + + // Qt3D has a limitation that a QEntity can only have 1 mesh and 1 material component + // So if the node has only 1 mesh, we only create 1 QEntity + // Otherwise if there are n meshes, there is 1 QEntity, with n children for each mesh/material combo + if (jsonObj.contains(KEY_MESHES)) { + QVector<QEntity *> entities; + + Q_FOREACH (QJsonValue mesh, jsonObj.value(KEY_MESHES).toArray()) { + if (!m_meshDict.contains(mesh.toString())) { + qCWarning(GLTFParserLog) << "node" << id << "references unknown mesh" << mesh.toString(); + continue; + } + + Q_FOREACH (QGeometryRenderer *geometryRenderer, m_meshDict.values(mesh.toString())) { + QEntity *entity = new QEntity; + entity->addComponent(geometryRenderer); + QMaterial *mat = material(m_meshMaterialDict[geometryRenderer]); + if (mat) + entity->addComponent(mat); + entities.append(entity); + } + + } + + if (entities.count() == 1) { + result = entities.first(); + } else { + result = new QEntity; + Q_FOREACH (QEntity *entity, entities) { + entity->setParent(result); + } + } + } + + //If the entity contains no meshes, results will still be null here + if (result == Q_NULLPTR) + result = new QEntity; + + if ( jsonObj.contains(KEY_CHILDREN) ) { + Q_FOREACH (QJsonValue c, jsonObj.value(KEY_CHILDREN).toArray()) { + QEntity* child = node(c.toString()); + if (!child) + continue; + child->setParent(result); + } + } + + renameFromJson(jsonObj, result); + + + // Node Transforms + Qt3DCore::QTransform *trans = Q_NULLPTR; + if ( jsonObj.contains(KEY_MATRIX) ) { + QMatrix4x4 m(Qt::Uninitialized); + + QJsonArray matrixValues = jsonObj.value(KEY_MATRIX).toArray(); + for (int i=0; i<16; ++i) { + double v = matrixValues.at( i ).toDouble(); + m(i % 4, i >> 2) = v; + } + + // ADD MATRIX TRANSFORM COMPONENT TO ENTITY + if (trans == Q_NULLPTR) + trans = new Qt3DCore::QTransform; + trans->setMatrix(m); + } + + // Rotation quaternion + if (jsonObj.contains(KEY_ROTATION)) { + if (trans == Q_NULLPTR) + trans = new Qt3DCore::QTransform; + + QJsonArray quaternionValues = jsonObj.value(KEY_ROTATION).toArray(); + QQuaternion quaternion(quaternionValues[0].toDouble(), + quaternionValues[1].toDouble(), + quaternionValues[2].toDouble(), + quaternionValues[3].toDouble()); + trans->setRotation(quaternion); + } + + // Translation + if (jsonObj.contains(KEY_TRANSLATION)) { + if (trans == Q_NULLPTR) + trans = new Qt3DCore::QTransform; + + QJsonArray translationValues = jsonObj.value(KEY_TRANSLATION).toArray(); + trans->setTranslation(QVector3D(translationValues[0].toDouble(), + translationValues[1].toDouble(), + translationValues[2].toDouble())); + } + + // Scale + if (jsonObj.contains(KEY_SCALE)) { + if (trans == Q_NULLPTR) + trans = new Qt3DCore::QTransform; + + QJsonArray scaleValues = jsonObj.value(KEY_SCALE).toArray(); + trans->setScale3D(QVector3D(scaleValues[0].toDouble(), + scaleValues[1].toDouble(), + scaleValues[2].toDouble())); + } + + // Add the Transform component + if (trans != Q_NULLPTR) + result->addComponent(trans); + + if ( jsonObj.contains(KEY_CAMERA) ) { + QCameraLens* cam = camera( jsonObj.value(KEY_CAMERA).toString() ); + if (!cam) { + qCWarning(GLTFParserLog) << "failed to build camera:" << jsonObj.value(KEY_CAMERA) + << "on node" << id; + } else { + result->addComponent(cam); + } + } // of have camera attribute + + return result; +} + +Qt3DCore::QEntity* GLTFParser::scene(const QString &id) +{ + parse(); + + QJsonObject scenes = m_json.object().value(KEY_SCENES).toObject(); + if (!scenes.contains(id)) { + if (!id.isNull()) + qCWarning(GLTFParserLog) << "GLTF: no such scene" << id << "in file" << m_basePath; + return defaultScene(); + } + + QJsonObject sceneObj = scenes.value(id).toObject(); + QEntity* sceneEntity = new QEntity; + Q_FOREACH (QJsonValue nnv, sceneObj.value(KEY_NODES).toArray()) { + QString nodeName = nnv.toString(); + QEntity* child = node(nodeName); + if (!child) + continue; + child->setParent(sceneEntity); + } + + return sceneEntity; +} + +GLTFParser::BufferData::BufferData() + : length(0) + , data(Q_NULLPTR) +{ +} + +GLTFParser::BufferData::BufferData(QJsonObject json) +{ + path = json.value(KEY_URI).toString(); + length = json.value(KEY_BYTE_LENGTH).toInt(); + data = Q_NULLPTR; +} + +GLTFParser::ParameterData::ParameterData() : + type(0) +{ + +} + +GLTFParser::ParameterData::ParameterData(QJsonObject json) +{ + type = json.value(KEY_TYPE).toInt(); + semantic = json.value(KEY_SEMANTIC).toString(); +} + +GLTFParser::AccessorData::AccessorData() + : type(QAttribute::Float) + , dataSize(0) + , count(0) + , offset(0) + , stride(0) +{ + +} + +GLTFParser::AccessorData::AccessorData(const QJsonObject &json) +{ + bufferViewName = json.value(KEY_BUFFER_VIEW).toString(); + offset = 0; + stride = 0; + int componentType = json.value(KEY_COMPONENT_TYPE).toInt(); + type = accessorTypeFromJSON(componentType); + count = json.value(KEY_COUNT).toInt(); + dataSize = accessorDataSizeFromJson(json.value(KEY_TYPE).toString()); + + if ( json.contains(KEY_BYTE_OFFSET)) + offset = json.value(KEY_BYTE_OFFSET).toInt(); + if ( json.contains(KEY_BYTE_STRIDE)) + stride = json.value(KEY_BYTE_STRIDE).toInt(); +} + +bool GLTFParser::isGLTFPath(const QString& path) +{ + QFileInfo finfo(path); + if (!finfo.exists()) + return false; + + // might need to detect other things in the future, but would + // prefer to avoid doing a full parse. + QString suffix = finfo.suffix().toLower(); + return (suffix == QStringLiteral("json") || suffix == QStringLiteral("gltf") || suffix == QStringLiteral("qgltf")); +} + +void GLTFParser::renameFromJson(const QJsonObject &json, QObject * const object) +{ + if ( json.contains(KEY_NAME) ) + object->setObjectName( json.value(KEY_NAME).toString() ); +} + +QString GLTFParser::standardUniformNamefromSemantic(const QString &semantic) +{ + //Standard Uniforms + //if (semantic == QStringLiteral("LOCAL")); + if (semantic == QStringLiteral("MODEL")) + return QStringLiteral("modelMatrix"); + if (semantic == QStringLiteral("VIEW")) + return QStringLiteral("viewMatrix"); + if (semantic == QStringLiteral("PROJECTION")) + return QStringLiteral("projectionMatrix"); + if (semantic == QStringLiteral("MODELVIEW")) + return QStringLiteral("modelView"); + if (semantic == QStringLiteral("MODELVIEWPROJECTION")) + return QStringLiteral("modelViewProjection"); + if (semantic == QStringLiteral("MODELINVERSE")) + return QStringLiteral("inverseModelMatrix"); + if (semantic == QStringLiteral("VIEWINVERSE")) + return QStringLiteral("inverViewMatrix"); + if (semantic == QStringLiteral("PROJECTIONINVERSE")) + return QStringLiteral("inverseProjectionMatrix"); + if (semantic == QStringLiteral("MODELVIEWPROJECTIONINVERSE")) + return QStringLiteral("inverseModelViewProjection"); + if (semantic == QStringLiteral("MODELINVERSETRANSPOSE")) + return QStringLiteral("modelNormalMatrix"); + if (semantic == QStringLiteral("MODELVIEWINVERSETRANSPOSE")) + return QStringLiteral("modelViewNormal"); + if (semantic == QStringLiteral("VIEWPORT")) + return QStringLiteral("viewportMatrix"); + + return QString(); +} + +QString GLTFParser::standardAttributeNameFromSemantic(const QString &semantic) +{ + //Standard Attributes + if (semantic.startsWith(QStringLiteral("POSITION"))) + return QAttribute::defaultPositionAttributeName(); + if (semantic.startsWith(QStringLiteral("NORMAL"))) + return QAttribute::defaultNormalAttributeName(); + if (semantic.startsWith(QStringLiteral("TEXCOORD"))) + return QAttribute::defaultTextureCoordinateAttributeName(); + if (semantic.startsWith(QStringLiteral("COLOR"))) + return QAttribute::defaultColorAttributeName(); + if (semantic.startsWith(QStringLiteral("TANGENT"))) + return QAttribute::defaultTangentAttributeName(); + +// if (semantic.startsWith(QStringLiteral("JOINT"))); +// if (semantic.startsWith(QStringLiteral("JOINTMATRIX"))); +// if (semantic.startsWith(QStringLiteral("WEIGHT"))); + + return QString(); +} + +QParameter *GLTFParser::parameterFromTechnique(QTechnique *technique, const QString ¶meterName) +{ + Q_FOREACH (QParameter *parameter, technique->parameters()) { + if (parameter->name() == parameterName) { + return parameter; + } + } + + return Q_NULLPTR; +} + +Qt3DCore::QEntity* GLTFParser::defaultScene() +{ + if (m_defaultScene.isEmpty()) { + qCWarning(GLTFParserLog) << Q_FUNC_INFO << "no default scene"; + return NULL; + } + + return scene(m_defaultScene); +} + +QMaterial *GLTFParser::materialWithCustomShader(const QString &id, const QJsonObject &jsonObj) +{ + //Default ES2 Technique + QString techniqueName = jsonObj.value(KEY_TECHNIQUE).toString(); + if (!m_techniques.contains(techniqueName)) { + qCWarning(GLTFParserLog) << "unknown technique" << techniqueName + << "for material" << id << "in GLTF file" << m_basePath; + return NULL; + } + QTechnique *technique = m_techniques.value(techniqueName); + technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES); + technique->graphicsApiFilter()->setMajorVersion(2); + technique->graphicsApiFilter()->setMinorVersion(0); + technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile); + + + //Optional Core technique + QTechnique *coreTechnique = Q_NULLPTR; + QTechnique *gl2Technique = Q_NULLPTR; + QString coreTechniqueName = jsonObj.value(KEY_TECHNIQUE_CORE).toString(); + if (!coreTechniqueName.isNull()) { + if (!m_techniques.contains(coreTechniqueName)) { + qCWarning(GLTFParserLog) << "unknown technique" << coreTechniqueName + << "for material" << id << "in GLTF file" << m_basePath; + } else { + coreTechnique = m_techniques.value(coreTechniqueName); + coreTechnique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); + coreTechnique->graphicsApiFilter()->setMajorVersion(3); + coreTechnique->graphicsApiFilter()->setMinorVersion(1); + coreTechnique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile); + } + } + //Optional GL2 technique + QString gl2TechniqueName = jsonObj.value(KEY_TECHNIQUE_GL2).toString(); + if (!gl2TechniqueName.isNull()) { + if (!m_techniques.contains(gl2TechniqueName)) { + qCWarning(GLTFParserLog) << "unknown technique" << gl2TechniqueName + << "for material" << id << "in GLTF file" << m_basePath; + } else { + gl2Technique = m_techniques.value(gl2TechniqueName); + gl2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); + gl2Technique->graphicsApiFilter()->setMajorVersion(2); + gl2Technique->graphicsApiFilter()->setMinorVersion(0); + gl2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile); + } + } + + + // glTF doesn't deal in effects, but we need a trivial one to wrap + // up our techniques + // However we need to create a unique effect for each material instead + // of caching because QMaterial does not keep up with effects + // its not the parent of. + QEffect* effect = new QEffect; + effect->setObjectName(techniqueName); + effect->addTechnique(technique); + if (coreTechnique != Q_NULLPTR) + effect->addTechnique(coreTechnique); + if (gl2Technique != Q_NULLPTR) + effect->addTechnique(gl2Technique); + + QMaterial* mat = new QMaterial; + mat->setEffect(effect); + + renameFromJson(jsonObj, mat); + + QJsonObject values = jsonObj.value(KEY_VALUES).toObject(); + Q_FOREACH (QString vName, values.keys()) { + QParameter *param = parameterFromTechnique(technique, vName); + + if (param == Q_NULLPTR && coreTechnique != Q_NULLPTR) { + param = parameterFromTechnique(coreTechnique, vName); + } + + if (param == Q_NULLPTR && gl2Technique != Q_NULLPTR) { + param = parameterFromTechnique(gl2Technique, vName); + } + + if (param == Q_NULLPTR) { + qCWarning(GLTFParserLog) << "unknown parameter:" << vName << "in technique" << techniqueName + << "processing material" << id; + continue; + } + + ParameterData paramData = m_parameterDataDict.value(param); + QVariant var = parameterValueFromJSON(paramData.type, values.value(vName)); + + mat->addParameter(new QParameter(param->name(), var)); + } // of material technique-instance values iteration + + return mat; +} + +static inline QVariant vec4ToRgb(const QVariant &vec4Var) +{ + const QVector4D v = vec4Var.value<QVector4D>(); + return QVariant(QColor::fromRgbF(v.x(), v.y(), v.z())); +} + +QMaterial *GLTFParser::commonMaterial(const QJsonObject &jsonObj) +{ + QVariantHash params; + bool hasDiffuseMap = false; + bool hasSpecularMap = false; + bool hasNormalMap = false; + + QJsonObject values = jsonObj.value(KEY_VALUES).toObject(); + Q_FOREACH (const QString &vName, values.keys()) { + const QJsonValue val = values.value(vName); + QVariant var; + QString propertyName = vName; + if (vName == QStringLiteral("ambient") && val.isArray()) { + var = vec4ToRgb(parameterValueFromJSON(GL_FLOAT_VEC4, val)); + } else if (vName == QStringLiteral("diffuse")) { + if (val.isString()) { + var = parameterValueFromJSON(GL_SAMPLER_2D, val); + hasDiffuseMap = true; + } else if (val.isArray()) { + var = vec4ToRgb(parameterValueFromJSON(GL_FLOAT_VEC4, val)); + } + } else if (vName == QStringLiteral("specular")) { + if (val.isString()) { + var = parameterValueFromJSON(GL_SAMPLER_2D, val); + hasSpecularMap = true; + } else if (val.isArray()) { + var = vec4ToRgb(parameterValueFromJSON(GL_FLOAT_VEC4, val)); + } + } else if (vName == QStringLiteral("shininess") && val.isDouble()) { + var = parameterValueFromJSON(GL_FLOAT, val); + } else if (vName == QStringLiteral("normalmap") && val.isString()) { + var = parameterValueFromJSON(GL_SAMPLER_2D, val); + propertyName = QStringLiteral("normal"); + hasNormalMap = true; + } else if (vName == QStringLiteral("transparency")) { + qCWarning(GLTFParserLog) << "Semi-transparent common materials are not currently supported, ignoring alpha"; + } + if (var.isValid()) + params[propertyName] = var; + } + + QMaterial *mat = Q_NULLPTR; + if (hasNormalMap) { + if (hasSpecularMap) { + mat = new QNormalDiffuseSpecularMapMaterial; + } else { + if (hasDiffuseMap) + mat = new QNormalDiffuseMapMaterial; + else + qCWarning(GLTFParserLog) << "Common material with normal and specular maps needs a diffuse map as well"; + } + } else { + if (hasSpecularMap) { + if (hasDiffuseMap) + mat = new QDiffuseSpecularMapMaterial; + else + qCWarning(GLTFParserLog) << "Common material with specular map needs a diffuse map as well"; + } else if (hasDiffuseMap) { + mat = new QDiffuseMapMaterial; + } else { + mat = new QPhongMaterial; + } + } + + if (mat) { + for (QVariantHash::const_iterator it = params.constBegin(), itEnd = params.constEnd(); it != itEnd; ++it) + mat->setProperty(it.key().toUtf8(), it.value()); + } else { + qCWarning(GLTFParserLog) << "Could not find a suitable built-in material for KHR_materials_common"; + } + + return mat; +} + +QMaterial* GLTFParser::material(const QString &id) +{ + if (m_materialCache.contains(id)) + return m_materialCache.value(id); + + QJsonObject mats = m_json.object().value(KEY_MATERIALS).toObject(); + if (!mats.contains(id)) { + qCWarning(GLTFParserLog) << "unknown material" << id << "in GLTF file" << m_basePath; + return NULL; + } + + QJsonObject jsonObj = mats.value(id).toObject(); + + QMaterial *mat = Q_NULLPTR; + + // Prefer common materials over custom shaders. + if (jsonObj.contains(KEY_EXTENSIONS)) { + QJsonObject extensions = jsonObj.value(KEY_EXTENSIONS).toObject(); + if (extensions.contains(KEY_COMMON_MAT)) + mat = commonMaterial(extensions.value(KEY_COMMON_MAT).toObject()); + } + + if (!mat) + mat = materialWithCustomShader(id, jsonObj); + + m_materialCache[id] = mat; + return mat; +} + +QCameraLens* GLTFParser::camera(const QString &id) const +{ + QJsonObject cams = m_json.object().value(KEY_CAMERAS).toObject(); + if (!cams.contains(id)) { + qCWarning(GLTFParserLog) << "unknown camera" << id << "in GLTF file" << m_basePath; + return Q_NULLPTR; + } + + QJsonObject jsonObj = cams.value(id).toObject(); + QString camTy = jsonObj.value(KEY_TYPE).toString(); + + if (camTy == QStringLiteral("perspective")) { + if (!jsonObj.contains(KEY_PERSPECTIVE)) { + qCWarning(GLTFParserLog) << "camera:" << id << "missing 'perspective' object"; + return Q_NULLPTR; + } + + QJsonObject pObj = jsonObj.value(KEY_PERSPECTIVE).toObject(); + double aspectRatio = pObj.value(KEY_ASPECT_RATIO).toDouble(); + double yfov = pObj.value(KEY_YFOV).toDouble(); + double frustumNear = pObj.value(KEY_ZNEAR).toDouble(); + double frustumFar = pObj.value(KEY_ZFAR).toDouble(); + + QCameraLens* result = new QCameraLens; + result->setPerspectiveProjection(yfov, aspectRatio, frustumNear, frustumFar); + return result; + } else if (camTy == QStringLiteral("orthographic")) { + qCWarning(GLTFParserLog) << Q_FUNC_INFO << "implement me"; + + return Q_NULLPTR; + } else { + qCWarning(GLTFParserLog) << "camera:" << id << "has unsupported type:" << camTy; + return Q_NULLPTR; + } +} + + +void GLTFParser::parse() +{ + if (m_parseDone) + return; + + QJsonObject buffers = m_json.object().value(KEY_BUFFERS).toObject(); + Q_FOREACH (QString nm, buffers.keys()) { + processJSONBuffer( nm, buffers.value(nm).toObject() ); + } + + QJsonObject views = m_json.object().value(KEY_BUFFER_VIEWS).toObject(); + loadBufferData(); + Q_FOREACH (QString nm, views.keys()) { + processJSONBufferView( nm, views.value(nm).toObject() ); + } + unloadBufferData(); + + QJsonObject shaders = m_json.object().value(KEY_SHADERS).toObject(); + Q_FOREACH (QString nm, shaders.keys()) { + processJSONShader( nm, shaders.value(nm).toObject() ); + } + + QJsonObject programs = m_json.object().value(KEY_PROGRAMS).toObject(); + Q_FOREACH (QString nm, programs.keys()) { + processJSONProgram( nm, programs.value(nm).toObject() ); + } + + QJsonObject techniques = m_json.object().value(KEY_TECHNIQUES).toObject(); + Q_FOREACH (QString nm, techniques.keys()) { + processJSONTechnique( nm, techniques.value(nm).toObject() ); + } + + QJsonObject attrs = m_json.object().value(KEY_ACCESSORS).toObject(); + Q_FOREACH (QString nm, attrs.keys()) { + processJSONAccessor( nm, attrs.value(nm).toObject() ); + } + + QJsonObject meshes = m_json.object().value(KEY_MESHES).toObject(); + Q_FOREACH (QString nm, meshes.keys()) { + processJSONMesh( nm, meshes.value(nm).toObject() ); + } + + QJsonObject images = m_json.object().value(KEY_IMAGES).toObject(); + Q_FOREACH (QString nm, images.keys()) { + processJSONImage( nm, images.value(nm).toObject() ); + } + + QJsonObject textures = m_json.object().value(KEY_TEXTURES).toObject(); + Q_FOREACH (QString nm, textures.keys()) { + processJSONTexture(nm, textures.value(nm).toObject() ); + } + + m_defaultScene = m_json.object().value(KEY_SCENE).toString(); + m_parseDone = true; +} + +void GLTFParser::cleanup() +{ + m_meshDict.clear(); + m_meshMaterialDict.clear(); + m_accessorDict.clear(); + //Check for Materials with no parent + Q_FOREACH (QMaterial *material, m_materialCache.values()) { + if (material->parent() == Q_NULLPTR) + delete material; + } + m_materialCache.clear(); + m_bufferDatas.clear(); + m_buffers.clear(); + m_shaderPaths.clear(); + //Check for ShaderPrograms with no parent + Q_FOREACH (QShaderProgram *program, m_programs.values()) { + if (program->parent() == Q_NULLPTR) + delete program; + } + m_programs.clear(); + //Check for Techniques with no parent + Q_FOREACH (QTechnique *technique, m_techniques.values()) { + if (technique->parent() == Q_NULLPTR) + delete technique; + } + m_techniques.clear(); + //Check for Textures with no parent + Q_FOREACH (QAbstractTextureProvider *texture, m_textures.values()) { + if (texture->parent() == Q_NULLPTR) + delete texture; + } + m_textures.clear(); + m_imagePaths.clear(); + m_defaultScene.clear(); + m_parameterDataDict.clear(); +} + +void GLTFParser::processJSONBuffer(const QString &id, const QJsonObject& json) +{ + // simply cache buffers for lookup by buffer-views + m_bufferDatas[id] = BufferData(json); +} + +void GLTFParser::processJSONBufferView(const QString &id, const QJsonObject& json) +{ + QString bufName = json.value(KEY_BUFFER).toString(); + if (!m_bufferDatas.contains(bufName)) { + qCWarning(GLTFParserLog) << "unknown buffer:" << bufName << "processing view:" << id; + return; + } + + int target = json.value(KEY_TARGET).toInt(); + QBuffer::BufferType ty(QBuffer::VertexBuffer); + + switch (target) { + case GL_ARRAY_BUFFER: ty = QBuffer::VertexBuffer; break; + case GL_ELEMENT_ARRAY_BUFFER: ty = QBuffer::IndexBuffer; break; + default: + qCWarning(GLTFParserLog) << Q_FUNC_INFO << "buffer" << id << "unsupported target:" << target; + return; + } + + quint64 offset = 0; + if (json.contains(KEY_BYTE_OFFSET)) { + offset = json.value(KEY_BYTE_OFFSET).toInt(); + qCDebug(GLTFParserLog) << "bv:" << id << "has offset:" << offset; + } + + quint64 len = json.value(KEY_BYTE_LENGTH).toInt(); + + QByteArray bytes(m_bufferDatas[bufName].data->mid(offset, len)); + if (bytes.count() != (int) len) { + qCWarning(GLTFParserLog) << "failed to read sufficient bytes from:" << m_bufferDatas[bufName].path + << "for view" << id; + } + + QBuffer *b(new QBuffer(ty)); + b->setData(bytes); + m_buffers[id] = b; +} + +void GLTFParser::processJSONShader(const QString &id, const QJsonObject &jsonObject) +{ + // shaders are trivial for the moment, defer the real work + // to the program section + QString path = jsonObject.value(KEY_URI).toString(); + + QFileInfo info(m_basePath, path); + if (!info.exists()) { + qCWarning(GLTFParserLog) << "can't find shader" << id << "from path" << path; + return; + } + + m_shaderPaths[id] = info.absoluteFilePath(); +} + +void GLTFParser::processJSONProgram(const QString &id, const QJsonObject &jsonObject) +{ + QShaderProgram* prog = new QShaderProgram; + prog->setObjectName(id); + + QString fragName = jsonObject.value(KEY_FRAGMENT_SHADER).toString(), + vertName = jsonObject.value(KEY_VERTEX_SHADER).toString(); + if (!m_shaderPaths.contains(fragName) || !m_shaderPaths.contains(vertName)) { + qCWarning(GLTFParserLog) << Q_FUNC_INFO << "program:" << id << "missing shader:" + << fragName << vertName; + return; + } + + prog->setFragmentShaderCode(QShaderProgram::loadSource(QUrl::fromLocalFile(m_shaderPaths[fragName]))); + prog->setVertexShaderCode(QShaderProgram::loadSource(QUrl::fromLocalFile(m_shaderPaths[vertName]))); + m_programs[id] = prog; +} + +void GLTFParser::processJSONTechnique(const QString &id, const QJsonObject &jsonObject ) +{ + QTechnique *t = new QTechnique; + t->setObjectName(id); + + // Parameters + QHash<QString, QParameter*> paramDict; + QJsonObject params = jsonObject.value(KEY_PARAMETERS).toObject(); + Q_FOREACH (QString pname, params.keys()) { + QJsonObject po = params.value(pname).toObject(); + + //QString semantic = po.value(KEY_SEMANTIC).toString(); + QParameter *p = new QParameter(t); + p->setName(pname); + m_parameterDataDict.insert(p, ParameterData(po)); + + //If the parameter has default value, set it + QJsonValue value = po.value(KEY_VALUE); + if (!value.isUndefined()) { + int dataType = po.value(KEY_TYPE).toInt(); + p->setValue(parameterValueFromJSON(dataType, value)); + } + + t->addParameter(p); + + paramDict[pname] = p; + } // of parameters iteration + + // Program + QString programName = jsonObject.value(KEY_PROGRAM).toString(); + if (!m_programs.contains(programName)) { + qCWarning(GLTFParserLog) << Q_FUNC_INFO << "technique" << id + << ": missing program" << programName; + } + + QRenderPass* pass = new QRenderPass; + pass->setShaderProgram(m_programs[programName]); + + // Attributes + QJsonObject attrs = jsonObject.value(KEY_ATTRIBUTES).toObject(); + Q_FOREACH ( QString shaderAttributeName, attrs.keys() ) { + QString pname = attrs.value(shaderAttributeName).toString(); + QParameter *parameter = paramDict.value(pname, Q_NULLPTR); + QString attributeName = pname; + if (parameter == Q_NULLPTR) { + qCWarning(GLTFParserLog) << Q_FUNC_INFO << "attribute " << pname + << "defined in instanceProgram but not as parameter"; + continue; + } + //Check if the parameter has a standard attribute semantic + QString standardAttributeName = standardAttributeNameFromSemantic(m_parameterDataDict[parameter].semantic); + if (!standardAttributeName.isNull()) { + attributeName = standardAttributeName; + t->removeParameter(parameter); + m_parameterDataDict.remove(parameter); + delete parameter; + } + + pass->addBinding(new QParameterMapping(attributeName, shaderAttributeName, QParameterMapping::Attribute)); + } // of program-instance attributes + + // Uniforms + QJsonObject uniforms = jsonObject.value(KEY_UNIFORMS).toObject(); + Q_FOREACH (QString shaderUniformName, uniforms.keys()) { + QString pname = uniforms.value(shaderUniformName).toString(); + QParameter *parameter = paramDict.value(pname, Q_NULLPTR); + if (parameter == Q_NULLPTR) { + qCWarning(GLTFParserLog) << Q_FUNC_INFO << "uniform " << pname + << "defined in instanceProgram but not as parameter"; + continue; + } + //Check if the parameter has a standard uniform semantic + QString standardUniformName = standardUniformNamefromSemantic(m_parameterDataDict[parameter].semantic); + if (standardUniformName.isNull()) { + pass->addBinding(new QParameterMapping(pname, shaderUniformName, QParameterMapping::Uniform)); + } else { + pass->addBinding(new QParameterMapping(standardUniformName, shaderUniformName, QParameterMapping::StandardUniform)); + t->removeParameter(parameter); + m_parameterDataDict.remove(parameter); + delete parameter; + } + } // of program-instance uniforms + + + // States + QJsonObject states = jsonObject.value(KEY_STATES).toObject(); + + //Process states to enable + QJsonArray enableStatesArray = states.value(KEY_ENABLE).toArray(); + QVector<int> enableStates; + Q_FOREACH (QJsonValue enableValue, enableStatesArray) { + enableStates.append(enableValue.toInt()); + } + + //Process the list of state functions + QJsonObject functions = states.value(KEY_FUNCTIONS).toObject(); + Q_FOREACH (QString functionName, functions.keys()) { + int enableStateType = 0; + QRenderState *renderState = buildState(functionName, functions.value(functionName), enableStateType); + if (renderState != Q_NULLPTR) { + //Remove the need to set a default state values for enableStateType + enableStates.removeOne(enableStateType); + pass->addRenderState(renderState); + } + } + + //Create render states with default values for any remaining enable states + Q_FOREACH (int enableState, enableStates) { + QRenderState *renderState = buildStateEnable(enableState); + if (renderState != Q_NULLPTR) + pass->addRenderState(renderState); + } + + + t->addPass(pass); + + m_techniques[id] = t; +} + +void GLTFParser::processJSONAccessor( const QString &id, const QJsonObject& json ) +{ + m_accessorDict[id] = AccessorData(json); +} + +void GLTFParser::processJSONMesh(const QString &id, const QJsonObject &json) +{ + QJsonArray primitivesArray = json.value(KEY_PRIMITIVES).toArray(); + Q_FOREACH (QJsonValue primitiveValue, primitivesArray) { + QJsonObject primitiveObject = primitiveValue.toObject(); + int type = primitiveObject.value(KEY_MODE).toInt(); + QString material = primitiveObject.value(KEY_MATERIAL).toString(); + + if ( material.isEmpty()) { + qCWarning(GLTFParserLog) << "malformed primitive on " << id << ", missing material value" + << material; + continue; + } + + QGeometryRenderer *geometryRenderer = new QGeometryRenderer; + QGeometry *meshGeometry = new QGeometry(geometryRenderer); + + //Set Primitive Type + geometryRenderer->setPrimitiveType(static_cast<QGeometryRenderer::PrimitiveType>(type)); + + //Save Material for mesh + m_meshMaterialDict[geometryRenderer] = material; + + QJsonObject attrs = primitiveObject.value(KEY_ATTRIBUTES).toObject(); + Q_FOREACH (QString attrName, attrs.keys()) { + QString k = attrs.value(attrName).toString(); + if (!m_accessorDict.contains(k)) { + qCWarning(GLTFParserLog) << "unknown attribute accessor:" << k << "on mesh" << id; + continue; + } + + QString attributeName = standardAttributeNameFromSemantic(attrName); + if (attributeName.isEmpty()) + attributeName = attrName; + + //Get buffer handle for accessor + QBuffer *buffer = m_buffers.value(m_accessorDict[k].bufferViewName, Q_NULLPTR); + if (buffer == Q_NULLPTR) { + qCWarning(GLTFParserLog) << "unknown buffer-view:" << m_accessorDict[k].bufferViewName << "processing accessor:" << id; + continue; + } + + QAttribute *attribute = new QAttribute(buffer, + attributeName, + m_accessorDict[k].type, + m_accessorDict[k].dataSize, + m_accessorDict[k].count, + m_accessorDict[k].offset, + m_accessorDict[k].stride); + attribute->setAttributeType(QAttribute::VertexAttribute); + meshGeometry->addAttribute(attribute); + } + + if ( primitiveObject.contains(KEY_INDICES)) { + QString k = primitiveObject.value(KEY_INDICES).toString(); + if (!m_accessorDict.contains(k)) { + qCWarning(GLTFParserLog) << "unknown index accessor:" << k << "on mesh" << id; + } else { + //Get buffer handle for accessor + QBuffer *buffer = m_buffers.value(m_accessorDict[k].bufferViewName, Q_NULLPTR); + if (buffer == Q_NULLPTR) { + qCWarning(GLTFParserLog) << "unknown buffer-view:" << m_accessorDict[k].bufferViewName << "processing accessor:" << id; + continue; + } + + QAttribute *attribute = new QAttribute(buffer, + m_accessorDict[k].type, + m_accessorDict[k].dataSize, + m_accessorDict[k].count, + m_accessorDict[k].offset, + m_accessorDict[k].stride); + attribute->setAttributeType(QAttribute::IndexAttribute); + meshGeometry->addAttribute(attribute); + } + } // of has indices + + geometryRenderer->setGeometry(meshGeometry); + + m_meshDict.insert( id, geometryRenderer); + } // of primitives iteration +} + +void GLTFParser::processJSONImage(const QString &id, const QJsonObject &jsonObject) +{ + QString path = jsonObject.value(KEY_URI).toString(); + QFileInfo info(m_basePath, path); + if (!info.exists()) { + qCWarning(GLTFParserLog) << "can't find image" << id << "from path" << path; + return; + } + + m_imagePaths[id] = info.absoluteFilePath(); +} + +void GLTFParser::processJSONTexture(const QString &id, const QJsonObject &jsonObject) +{ + int target = jsonObject.value(KEY_TARGET).toInt(GL_TEXTURE_2D); + //TODO: support other targets that GL_TEXTURE_2D (though the spec doesn't support anything else) + if (target != GL_TEXTURE_2D) { + qCWarning(GLTFParserLog) << "unsupported texture target: " << target; + return; + } + + QTexture2D* tex = new QTexture2D; + + // TODO: Choose suitable internal format - may vary on OpenGL context type + //int pixelFormat = jsonObj.value(KEY_FORMAT).toInt(GL_RGBA); + int internalFormat = jsonObject.value(KEY_INTERNAL_FORMAT).toInt(GL_RGBA); + + tex->setFormat(static_cast<QAbstractTextureProvider::TextureFormat>(internalFormat)); + + QString samplerId = jsonObject.value(KEY_SAMPLER).toString(); + QString source = jsonObject.value(KEY_SOURCE).toString(); + if (!m_imagePaths.contains(source)) { + qCWarning(GLTFParserLog) << "texture" << id << "references missing image" << source; + return; + } + + QTextureImage *texImage = new QTextureImage(tex); + texImage->setSource(QUrl::fromLocalFile(m_imagePaths[source])); + tex->addTextureImage(texImage); + + QJsonObject samplersDict(m_json.object().value(KEY_SAMPLERS).toObject()); + if (!samplersDict.contains(samplerId)) { + qCWarning(GLTFParserLog) << "texture" << id << "references unknown sampler" << samplerId; + return; + } + + QJsonObject sampler = samplersDict.value(samplerId).toObject(); + + tex->setWrapMode(QTextureWrapMode(static_cast<QTextureWrapMode::WrapMode>(sampler.value(KEY_WRAP_S).toInt()))); + tex->setMinificationFilter(static_cast<QAbstractTextureProvider::Filter>(sampler.value(KEY_MIN_FILTER).toInt())); + if (tex->minificationFilter() == QAbstractTextureProvider::NearestMipMapLinear || + tex->minificationFilter() == QAbstractTextureProvider::LinearMipMapNearest || + tex->minificationFilter() == QAbstractTextureProvider::NearestMipMapNearest || + tex->minificationFilter() == QAbstractTextureProvider::LinearMipMapLinear) { + + tex->setGenerateMipMaps(true); + } + tex->setMagnificationFilter(static_cast<QAbstractTextureProvider::Filter>(sampler.value(KEY_MAG_FILTER).toInt())); + + m_textures[id] = tex; +} + +void GLTFParser::loadBufferData() +{ + Q_FOREACH (QString bufferName, m_bufferDatas.keys()) { + if (m_bufferDatas[bufferName].data == Q_NULLPTR) { + QFile* bufferFile = resolveLocalData(m_bufferDatas[bufferName].path); + QByteArray *data = new QByteArray(bufferFile->readAll()); + m_bufferDatas[bufferName].data = data; + delete bufferFile; + } + } +} + +void GLTFParser::unloadBufferData() +{ + Q_FOREACH (QString bufferName, m_bufferDatas.keys()) { + QByteArray *data = m_bufferDatas[bufferName].data; + delete data; + } +} + +QFile *GLTFParser::resolveLocalData(QString path) const +{ + QDir d(m_basePath); + Q_ASSERT(d.exists()); + + QString absPath = d.absoluteFilePath(path); + QFile* f = new QFile(absPath); + f->open(QIODevice::ReadOnly); + return f; +} + +QVariant GLTFParser::parameterValueFromJSON(int type, const QJsonValue &value) const +{ + if (value.isBool()) { + if (type == GL_BOOL) + return QVariant(static_cast<GLboolean>(value.toBool())); + } else if (value.isString()) { + if (type == GL_SAMPLER_2D) { + //Textures are special because we need to do a lookup to return the + //QAbstractTextureProvider + QString textureId = value.toString(); + if (!m_textures.contains(textureId)) { + qCWarning(GLTFParserLog) << "unknown texture" << textureId; + return QVariant(); + } else { + return QVariant::fromValue(m_textures.value(textureId)); + } + } + } else if (value.isDouble()) { + switch (type) { + case GL_BYTE: + return QVariant(static_cast<GLbyte>(value.toInt())); + case GL_UNSIGNED_BYTE: + return QVariant(static_cast<GLubyte>(value.toInt())); + case GL_SHORT: + return QVariant(static_cast<GLshort>(value.toInt())); + case GL_UNSIGNED_SHORT: + return QVariant(static_cast<GLushort>(value.toInt())); + case GL_INT: + return QVariant(static_cast<GLint>(value.toInt())); + case GL_UNSIGNED_INT: + return QVariant(static_cast<GLuint>(value.toInt())); + case GL_FLOAT: + return QVariant(static_cast<GLfloat>(value.toDouble())); + } + } else if (value.isArray()) { + + QJsonArray valueArray = value.toArray(); + + QVector2D vector2D; + QVector3D vector3D; + QVector4D vector4D; + QVector<float> dataMat2(4, 0.0f); + QVector<float> dataMat3(9, 0.0f); + + switch (type) { + case GL_BYTE: + return QVariant(static_cast<GLbyte>(valueArray.first().toInt())); + case GL_UNSIGNED_BYTE: + return QVariant(static_cast<GLubyte>(valueArray.first().toInt())); + case GL_SHORT: + return QVariant(static_cast<GLshort>(valueArray.first().toInt())); + case GL_UNSIGNED_SHORT: + return QVariant(static_cast<GLushort>(valueArray.first().toInt())); + case GL_INT: + return QVariant(static_cast<GLint>(valueArray.first().toInt())); + case GL_UNSIGNED_INT: + return QVariant(static_cast<GLuint>(valueArray.first().toInt())); + case GL_FLOAT: + return QVariant(static_cast<GLfloat>(valueArray.first().toDouble())); + case GL_FLOAT_VEC2: + vector2D.setX(static_cast<GLfloat>(valueArray.at(0).toDouble())); + vector2D.setY(static_cast<GLfloat>(valueArray.at(1).toDouble())); + return QVariant(vector2D); + case GL_FLOAT_VEC3: + vector3D.setX(static_cast<GLfloat>(valueArray.at(0).toDouble())); + vector3D.setY(static_cast<GLfloat>(valueArray.at(1).toDouble())); + vector3D.setZ(static_cast<GLfloat>(valueArray.at(2).toDouble())); + return QVariant(vector3D); + case GL_FLOAT_VEC4: + vector4D.setX(static_cast<GLfloat>(valueArray.at(0).toDouble())); + vector4D.setY(static_cast<GLfloat>(valueArray.at(1).toDouble())); + vector4D.setZ(static_cast<GLfloat>(valueArray.at(2).toDouble())); + vector4D.setW(static_cast<GLfloat>(valueArray.at(3).toDouble())); + return QVariant(vector4D); + case GL_INT_VEC2: + vector2D.setX(static_cast<GLint>(valueArray.at(0).toInt())); + vector2D.setY(static_cast<GLint>(valueArray.at(1).toInt())); + return QVariant(vector2D); + case GL_INT_VEC3: + vector3D.setX(static_cast<GLint>(valueArray.at(0).toInt())); + vector3D.setY(static_cast<GLint>(valueArray.at(1).toInt())); + vector3D.setZ(static_cast<GLint>(valueArray.at(2).toInt())); + return QVariant(vector3D); + case GL_INT_VEC4: + vector4D.setX(static_cast<GLint>(valueArray.at(0).toInt())); + vector4D.setY(static_cast<GLint>(valueArray.at(1).toInt())); + vector4D.setZ(static_cast<GLint>(valueArray.at(2).toInt())); + vector4D.setW(static_cast<GLint>(valueArray.at(3).toInt())); + return QVariant(vector4D); + case GL_BOOL: + return QVariant(static_cast<GLboolean>(valueArray.first().toBool())); + case GL_BOOL_VEC2: + vector2D.setX(static_cast<GLboolean>(valueArray.at(0).toBool())); + vector2D.setY(static_cast<GLboolean>(valueArray.at(1).toBool())); + return QVariant(vector2D); + case GL_BOOL_VEC3: + vector3D.setX(static_cast<GLboolean>(valueArray.at(0).toBool())); + vector3D.setY(static_cast<GLboolean>(valueArray.at(1).toBool())); + vector3D.setZ(static_cast<GLboolean>(valueArray.at(2).toBool())); + return QVariant(vector3D); + case GL_BOOL_VEC4: + vector4D.setX(static_cast<GLboolean>(valueArray.at(0).toBool())); + vector4D.setY(static_cast<GLboolean>(valueArray.at(1).toBool())); + vector4D.setZ(static_cast<GLboolean>(valueArray.at(2).toBool())); + vector4D.setW(static_cast<GLboolean>(valueArray.at(3).toBool())); + return QVariant(vector4D); + case GL_FLOAT_MAT2: + //Matrix2x2 is in Row Major ordering (so we need to convert) + dataMat2[0] = static_cast<GLfloat>(valueArray.at(0).toDouble()); + dataMat2[1] = static_cast<GLfloat>(valueArray.at(2).toDouble()); + dataMat2[2] = static_cast<GLfloat>(valueArray.at(1).toDouble()); + dataMat2[3] = static_cast<GLfloat>(valueArray.at(3).toDouble()); + return QVariant::fromValue(QMatrix2x2(dataMat2.constData())); + case GL_FLOAT_MAT3: + //Matrix3x3 is in Row Major ordering (so we need to convert) + dataMat3[0] = static_cast<GLfloat>(valueArray.at(0).toDouble()); + dataMat3[1] = static_cast<GLfloat>(valueArray.at(3).toDouble()); + dataMat3[2] = static_cast<GLfloat>(valueArray.at(6).toDouble()); + dataMat3[3] = static_cast<GLfloat>(valueArray.at(1).toDouble()); + dataMat3[4] = static_cast<GLfloat>(valueArray.at(4).toDouble()); + dataMat3[5] = static_cast<GLfloat>(valueArray.at(7).toDouble()); + dataMat3[6] = static_cast<GLfloat>(valueArray.at(2).toDouble()); + dataMat3[7] = static_cast<GLfloat>(valueArray.at(5).toDouble()); + dataMat3[8] = static_cast<GLfloat>(valueArray.at(8).toDouble()); + return QVariant::fromValue(QMatrix3x3(dataMat3.constData())); + case GL_FLOAT_MAT4: + //Matrix4x4 is Column Major ordering + return QVariant(QMatrix4x4(static_cast<GLfloat>(valueArray.at(0).toDouble()), + static_cast<GLfloat>(valueArray.at(1).toDouble()), + static_cast<GLfloat>(valueArray.at(2).toDouble()), + static_cast<GLfloat>(valueArray.at(3).toDouble()), + static_cast<GLfloat>(valueArray.at(4).toDouble()), + static_cast<GLfloat>(valueArray.at(5).toDouble()), + static_cast<GLfloat>(valueArray.at(6).toDouble()), + static_cast<GLfloat>(valueArray.at(7).toDouble()), + static_cast<GLfloat>(valueArray.at(8).toDouble()), + static_cast<GLfloat>(valueArray.at(9).toDouble()), + static_cast<GLfloat>(valueArray.at(10).toDouble()), + static_cast<GLfloat>(valueArray.at(11).toDouble()), + static_cast<GLfloat>(valueArray.at(12).toDouble()), + static_cast<GLfloat>(valueArray.at(13).toDouble()), + static_cast<GLfloat>(valueArray.at(14).toDouble()), + static_cast<GLfloat>(valueArray.at(15).toDouble()))); + case GL_SAMPLER_2D: + return QVariant(valueArray.at(0).toString()); + } + } + return QVariant(); +} + +QAttribute::DataType GLTFParser::accessorTypeFromJSON(int componentType) +{ + if (componentType == GL_BYTE) { + return QAttribute::Byte; + } else if (componentType == GL_UNSIGNED_BYTE) { + return QAttribute::UnsignedByte; + } else if (componentType == GL_SHORT) { + return QAttribute::Short; + } else if (componentType == GL_UNSIGNED_SHORT) { + return QAttribute::UnsignedShort; + } else if (componentType == GL_UNSIGNED_INT) { + return QAttribute::UnsignedInt; + } else if (componentType == GL_FLOAT) { + return QAttribute::Float; + } + + //There shouldn't be an invalid case here + qCWarning(GLTFParserLog) << "unsupported accessor type" << componentType; + return QAttribute::Float; +} + +uint GLTFParser::accessorDataSizeFromJson(const QString &type) +{ + QString typeName = type.toUpper(); + if (typeName == "SCALAR") + return 1; + if (typeName == "VEC2") + return 2; + if (typeName == "VEC3") + return 3; + if (typeName == "VEC4") + return 4; + if (typeName == "MAT2") + return 4; + if (typeName == "MAT3") + return 9; + if (typeName == "MAT4") + return 16; + + return 0; +} + +QRenderState *GLTFParser::buildStateEnable(int state) +{ + int type = 0; + //By calling buildState with QJsonValue(), a Render State with + //default values is created. + + if (state == GL_BLEND) { + //It doesn't make sense to handle this state alone + return Q_NULLPTR; + } + + if (state == GL_CULL_FACE) { + return buildState(QStringLiteral("cullFace"), QJsonValue(), type); + } + + if (state == GL_DEPTH_TEST) { + return buildState(QStringLiteral("depthFunc"), QJsonValue(), type); + } + + if (state == GL_POLYGON_OFFSET_FILL) { + return buildState(QStringLiteral("polygonOffset"), QJsonValue(), type); + } + + if (state == GL_SAMPLE_ALPHA_TO_COVERAGE) { + return new QAlphaCoverage(); + } + + if (state == GL_SCISSOR_TEST) { + return buildState(QStringLiteral("scissor"), QJsonValue(), type); + } + + qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << state; + + return Q_NULLPTR; +} + +QRenderState* GLTFParser::buildState(const QString& functionName, const QJsonValue &value, int &type) +{ + type = -1; + QJsonArray values = value.toArray(); + + if (functionName == QStringLiteral("blendColor")) { + type = GL_BLEND; + //TODO: support render state blendColor + qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName; + return Q_NULLPTR; + } + + if (functionName == QStringLiteral("blendEquationSeparate")) { + type = GL_BLEND; + //TODO: support settings blendEquation alpha + QBlendEquation *blendEquation = new QBlendEquation; + blendEquation->setMode((QBlendEquation::BlendMode)values.at(0).toInt(GL_FUNC_ADD)); + return blendEquation; + } + + if (functionName == QStringLiteral("blendFuncSeparate")) { + type = GL_BLEND; + QBlendStateSeparate *blendState = new QBlendStateSeparate; + blendState->setSrcRGB((QBlendState::Blending)values.at(0).toInt(GL_ONE)); + blendState->setSrcAlpha((QBlendState::Blending)values.at(1).toInt(GL_ONE)); + blendState->setDstRGB((QBlendState::Blending)values.at(2).toInt(GL_ZERO)); + blendState->setDstAlpha((QBlendState::Blending)values.at(3).toInt(GL_ZERO)); + return blendState; + } + + if (functionName == QStringLiteral("colorMask")) { + QColorMask *colorMask = new QColorMask; + colorMask->setRed(values.at(0).toBool(true)); + colorMask->setGreen(values.at(1).toBool(true)); + colorMask->setBlue(values.at(2).toBool(true)); + colorMask->setAlpha(values.at(3).toBool(true)); + return colorMask; + } + + if (functionName == QStringLiteral("cullFace")) { + type = GL_CULL_FACE; + QCullFace *cullFace = new QCullFace; + cullFace->setMode((QCullFace::CullingMode)values.at(0).toInt(GL_BACK)); + return cullFace; + } + + if (functionName == QStringLiteral("depthFunc")) { + type = GL_DEPTH_TEST; + QDepthTest *depthTest = new QDepthTest; + depthTest->setFunc((QDepthTest::DepthFunc)values.at(0).toInt(GL_LESS)); + return depthTest; + } + + if (functionName == QStringLiteral("depthMask")) { + QDepthMask *depthMask = new QDepthMask; + depthMask->setMask(values.at(0).toBool(true)); + } + + if (functionName == QStringLiteral("depthRange")) { + //TODO: support render state depthRange + qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName; + return Q_NULLPTR; + } + + if (functionName == QStringLiteral("frontFace")) { + QFrontFace *frontFace = new QFrontFace; + frontFace->setDirection((QFrontFace::FaceDir)values.at(0).toInt(GL_CCW)); + return frontFace; + } + + if (functionName == QStringLiteral("lineWidth")) { + //TODO: support render state lineWidth + qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName; + return Q_NULLPTR; + } + + if (functionName == QStringLiteral("polygonOffset")) { + type = GL_POLYGON_OFFSET_FILL; + QPolygonOffset *polygonOffset = new QPolygonOffset; + polygonOffset->setFactor((float)values.at(0).toDouble(0.0f)); + polygonOffset->setUnits((float)values.at(1).toDouble(0.0f)); + return polygonOffset; + } + + if (functionName == QStringLiteral("scissor")) { + type = GL_SCISSOR_TEST; + QScissorTest *scissorTest = new QScissorTest; + scissorTest->setLeft(values.at(0).toDouble(0.0f)); + scissorTest->setBottom(values.at(1).toDouble(0.0f)); + scissorTest->setWidth(values.at(2).toDouble(0.0f)); + scissorTest->setHeight(values.at(3).toDouble(0.0f)); + return scissorTest; + } + + qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName; + return Q_NULLPTR; +} + +} // namespace Qt3DRender + +QT_END_NAMESPACE diff --git a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp index 3eb89efe7..28416d894 100644 --- a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp +++ b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp @@ -219,7 +219,7 @@ void Qt3DQuick3DRenderPlugin::registerTypes(const char *uri) Qt3DRender::Quick::registerExtendedType<Qt3DRender::QViewport, Qt3DRender::Render::Quick::Quick3DViewport>("QViewport", "Qt3D.Render/Viewport", uri, 2, 0, "Viewport"); Qt3DRender::Quick::registerExtendedType<Qt3DRender::QRenderTargetSelector, Qt3DRender::Render::Quick::Quick3DRenderTargetSelector>("QRenderTargetSelector", "Qt3D.Render/RenderTargetSelector", uri, 2, 0, "RenderTargetSelector"); qmlRegisterType<Qt3DRender::QClearBuffers>(uri, 2, 0, "ClearBuffers"); - qmlRegisterUncreatableType<Qt3DRender::QFrameGraphNode>(uri, 2, 0, "FrameGraphNode", QStringLiteral("FrameGraphNode is a base class")); + qmlRegisterType<Qt3DRender::QFrameGraphNode>(uri, 2, 0, "FrameGraphNode"); Qt3DRender::Quick::registerExtendedType<Qt3DRender::QRenderStateSet, Qt3DRender::Render::Quick::Quick3DStateSet>("QRenderStateSet", "Qt3D.Render/RenderStateSet", uri, 2, 0, "RenderStateSet"); qmlRegisterType<Qt3DRender::QNoDraw>(uri, 2, 0, "NoDraw"); qmlRegisterType<Qt3DRender::QFrustumCulling>(uri, 2, 0, "FrustumCulling"); diff --git a/src/quick3d/quick3d/items/quick3dnodeinstantiator.cpp b/src/quick3d/quick3d/items/quick3dnodeinstantiator.cpp index b95290a3c..ce69e471a 100644 --- a/src/quick3d/quick3d/items/quick3dnodeinstantiator.cpp +++ b/src/quick3d/quick3d/items/quick3dnodeinstantiator.cpp @@ -148,7 +148,7 @@ void Quick3DNodeInstantiatorPrivate::_q_createdItem(int idx, QObject *item) Q_Q(Quick3DNodeInstantiator); if (m_objects.contains(item)) //Case when it was created synchronously in regenerate return; - static_cast<QNode *>(item)->setParent(q); + static_cast<QNode *>(item)->setParent(q->parentNode()); m_objects.insert(idx, item); if (m_objects.count() == 1) q->objectChanged(); @@ -247,10 +247,10 @@ Quick3DNodeInstantiator::Quick3DNodeInstantiator(QNode *parent) } /*! - \qmlsignal Qt3D.Core::NodeInstantiator::objectAdded(int index, QtObject node) + \qmlsignal Qt3D.Core::NodeInstantiator::objectAdded(int index, QtObject object) This signal is emitted when a node is added to the NodeInstantiator. The \a index - parameter holds the index which the node has been given, and the \a node + parameter holds the index which the node has been given, and the \a object parameter holds the \l Node that has been added. The corresponding handler is \c onNodeAdded. diff --git a/src/render/framegraph/qdispatchcompute.cpp b/src/render/framegraph/qdispatchcompute.cpp index abb4d7bdb..ca656c114 100644 --- a/src/render/framegraph/qdispatchcompute.cpp +++ b/src/render/framegraph/qdispatchcompute.cpp @@ -44,12 +44,18 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - \class Qt3DRender::QDispatchCompute - \inmodule Qt3DRender - \since 5.7 - \ingroup framegraph + \class Qt3DRender::QDispatchCompute + \inmodule Qt3DRender + \since 5.7 + \ingroup framegraph + \brief FrameGraph node to issue work for the compute shader on GPU - \brief Allows a glDispatchCompute call to be issued to do work in a compute shader on the GPU. + A Qt3DRender::QDispatchCompute allows work to be issued for the compute shader to + run on the GPU. The workGroupX, workGroupY and workGroupZ properties specify the work group + sizes for the compute shader invocation. QComputeCommand components need to be added + to entities to instruct Qt3D to select the materials and geometry from the entities + for the compute invocation. The work group sizes for the shader invocation will be + the maximum of the work group sizes specified in QDispatchCompute and QComputeCommand. */ @@ -59,11 +65,33 @@ namespace Qt3DRender { \instantiates Qt3DRender::QDispatchCompute \inherits FrameGraphNode \since 5.7 - \qmlabstract Allows a glDispatchCompute call to be issued to do work in a compute shader on the GPU. + \brief FrameGraph node to issue work for the compute shader on GPU + + A DispatchCompute allows work to be issued for the compute shader to run on the GPU. + The workGroupX, workGroupY and workGroupZ properties specify the work group sizes for + the compute shader invocation. ComputeCommand components need to be added + to entities to instruct Qt3D to select the materials and geometry from the entities + for the compute invocation. The work group sizes for the shader invocation will be + the maximum of the work group sizes specified in DispatchCompute and ComputeCommand. */ /*! - The constructor creates an instance with the specified \a parent. + \qmlproperty int DispatchCompute::workGroupX + Specifies X workgroup size. + */ + +/*! + \qmlproperty int DispatchCompute::workGroupY + Specifies Y workgroup size. + */ + +/*! + \qmlproperty int DispatchCompute::workGroupZ + Specifies Z workgroup size. + */ + +/*! + The constructor creates an instance with the specified \a parent. */ QDispatchCompute::QDispatchCompute(Qt3DCore::QNode *parent) : QFrameGraphNode(*new QDispatchComputePrivate(), parent) diff --git a/src/render/framegraph/qframegraphnode.cpp b/src/render/framegraph/qframegraphnode.cpp index c60c859ac..36a9f737a 100644 --- a/src/render/framegraph/qframegraphnode.cpp +++ b/src/render/framegraph/qframegraphnode.cpp @@ -56,8 +56,10 @@ QFrameGraphNodePrivate::QFrameGraphNodePrivate() \brief Base class of all FrameGraph configuration nodes. - This is an abstract class so it cannot be instanced directly - but rather through one of its subclasses. + This class is rarely instanced directly since it doesn't provide + any frame graph specific behavior, although it can be convenient + to use for grouping other nodes together in dynamic frame graphs. + The actual behavior comes from the subclasses. The subclasses are: \table @@ -112,8 +114,10 @@ QFrameGraphNodePrivate::QFrameGraphNodePrivate() \since 5.5 \brief Base class of all FrameGraph configuration nodes. - This is an abstract class so it cannot be instanced directly - but rather through one of its subclasses. + This class is rarely instanced directly since it doesn't provide + any frame graph specific behavior, although it can be convenient + to use for grouping other nodes together in dynamic frame graphs. + The actual behavior comes from the subclasses. The subclasses are: \table diff --git a/src/render/framegraph/qfrustumculling.cpp b/src/render/framegraph/qfrustumculling.cpp index 5ba96926e..1d95892b3 100644 --- a/src/render/framegraph/qfrustumculling.cpp +++ b/src/render/framegraph/qfrustumculling.cpp @@ -43,13 +43,20 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - \class Qt3DRender::QFrustumCulling - \inmodule Qt3DRender - \since 5.7 - \ingroup framegraph + \class Qt3DRender::QFrustumCulling + \inmodule Qt3DRender + \since 5.7 + \ingroup framegraph + \brief Enable frustum culling for the FrameGraph + + A QFrustumCulling class enables frustum culling of the drawable entities based on + the camera view and QGeometry bounds of the entities. If QFrustumCulling is present in + the FrameGraph, only the entities whose QGeometry bounds intersect with the camera + frustum, i.e. the view of the camera, are drawn. If QFrustumCulling is not present, + all drawable entities will be drawn. The camera is selected by a QCameraSelector + frame graph node in the current hierarchy. Frustum culling can save a lot of GPU + processing time when the rendered scene is complex. - \brief If present, only tries to draw entities that are in the view of the camera. - The camera is selected by a QCameraSelector frame graph node in the current hierarchy. \sa QCameraSelector */ @@ -59,13 +66,21 @@ namespace Qt3DRender { \instantiates Qt3DRender::QFrustumCulling \inherits FrameGraphNode \since 5.7 - \qmlabstract If present, only tries to draw entities that are in the view of the camera. - The camera is selected by a CameraSelector frame graph node in the current hierarchy + \brief Enable frustum culling for the FrameGraph + + A FrustumCulling type enables frustum culling of the drawable entities based on + the camera view and Geometry bounds of the entities. If FrustumCulling is present in + the FrameGraph, only the entities whose Geometry bounds intersect with the camera + frustum, i.e. the view of the camera, are drawn. If FrustumCulling is not present, + all drawable entities will be drawn. The camera is selected by a CameraSelector + frame graph node in the current hierarchy. Frustum culling can save a lot of GPU + processing time when the rendered scene is complex. + \sa CameraSelector */ /*! - The constructor creates an instance with the specified \a parent. + The constructor creates an instance with the specified \a parent. */ QFrustumCulling::QFrustumCulling(Qt3DCore::QNode *parent) : QFrameGraphNode(parent) diff --git a/src/render/framegraph/qrendertargetselector.cpp b/src/render/framegraph/qrendertargetselector.cpp index a413bbf56..f129d6e1e 100644 --- a/src/render/framegraph/qrendertargetselector.cpp +++ b/src/render/framegraph/qrendertargetselector.cpp @@ -49,23 +49,38 @@ using namespace Qt3DCore; namespace Qt3DRender { /*! - * \class Qt3DRender::QRenderTargetSelector - * \inmodule Qt3DRender - * \brief Provides a way of specifying a render target - * \since 5.7 - * - * \inherits Qt3DRender::QFrameGraphNode - * + \class Qt3DRender::QRenderTargetSelector + \inmodule Qt3DRender + \since 5.7 + \brief Provides a way of specifying a render target + + A Qt3DRender::QRenderTargetSelector is used to select active Qt3DRender::QRenderTarget + for the FrameGraph. When QRenderTargetSelector is present in the FrameGraph, + the rendering is directed into QTexture objects or draw buffers instead of the surface + specified in the Qt3DRender::QRenderSurfaceSelector. A render buffer is automatically + generated for an attachment point if drawBuffers contain attachment point that any + output in the QRenderTarget do not specify. If the drawBuffers is empty, + the renderer will default to using all the outputs in QRenderTarget. */ /*! - * \qmltype RenderTargetSelector - * \inqmlmodule Qt3D.Render - * \since 5.7 - * \ingroup - * \instantiates Qt3DRender::QRenderTargetSelector - * \brief RenderTargetSelector - * + \qmltype RenderTargetSelector + \inqmlmodule Qt3D.Render + \since 5.7 + \instantiates Qt3DRender::QRenderTargetSelector + \inherits FrameGraphNode + \brief Provides a way of specifying a render target + + A RenderTargetSelector is used to select active RenderTarget + for the FrameGraph. When RenderTargetSelector is present in the FrameGraph, + the rendering is directed into Texture objects or draw buffers instead of the surface + specified in the RenderSurfaceSelector. + */ +/*! + \qmlproperty list<variant> RenderTargetSelector::drawBuffers + Holds the list of draw buffers enabled for the RenderTarget. + + \sa Qt3DRender::QRenderTargetOutput::AttachmentPoint */ QRenderTargetSelectorPrivate::QRenderTargetSelectorPrivate() @@ -75,7 +90,7 @@ QRenderTargetSelectorPrivate::QRenderTargetSelectorPrivate() } /*! - * Constructs QRenderTargetSelector with given \a parent. + Constructs QRenderTargetSelector with given \a parent. */ QRenderTargetSelector::QRenderTargetSelector(QNode *parent) : QFrameGraphNode(*new QRenderTargetSelectorPrivate, parent) @@ -88,13 +103,13 @@ QRenderTargetSelector::~QRenderTargetSelector() } /*! - * \property QRenderTargetSelector::target - * Specifies the target to be rendered + \property QRenderTargetSelector::target + Holds the current render target */ -/*! \qmlproperty QWindow Qt3D.Render::RenderTargetSelector::target - * - * the target to be rendered +/*! \qmlproperty RenderTarget Qt3D.Render::RenderTargetSelector::target + + Holds the current render target */ void QRenderTargetSelector::setTarget(QRenderTarget *target) { @@ -124,15 +139,13 @@ QRenderTarget *QRenderTargetSelector::target() const } /*! - * \internal - * Sets the draw buffers \a buffers to be used. The draw buffers should be - * matching the Qt3DRender::QRenderTargetOutput::RenderAttachmentType - * defined in the attachments of the Qt3DRender::QRenderTarget associated to the - * Qt3DRender::QRenderTargetSelector instance. - * - * \note At render time, if no draw buffer has been specified, the renderer will - * default to using all the attachments' draw buffers. - * + Sets the draw \a buffers to be used. The draw buffers should be + matching the Qt3DRender::QRenderTargetOutput::AttachmentPoint + defined in the attachments of the Qt3DRender::QRenderTarget associated to the + Qt3DRender::QRenderTargetSelector instance. + + \note At render time, if no draw buffer has been specified, the renderer will + default to using all the attachments' draw buffers. */ void QRenderTargetSelector::setOutputs(const QVector<QRenderTargetOutput::AttachmentPoint> &buffers) { @@ -150,7 +163,7 @@ void QRenderTargetSelector::setOutputs(const QVector<QRenderTargetOutput::Attach } /*! - * Returns the list of draw buffers for the current Qt3DRender::QRenderTargetSelector instance. + \return the list of draw buffers for the current Qt3DRender::QRenderTargetSelector instance. */ QVector<QRenderTargetOutput::AttachmentPoint> QRenderTargetSelector::outputs() const { diff --git a/src/render/frontend/qcomputecommand.cpp b/src/render/frontend/qcomputecommand.cpp index 0bd2f629b..c36e4039c 100644 --- a/src/render/frontend/qcomputecommand.cpp +++ b/src/render/frontend/qcomputecommand.cpp @@ -45,10 +45,61 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * \class Qt3DRender::QComputeCommand - * \brief The QComputerCommand class - * \since 5.7 - * \inmodule Qt3DRender + \class Qt3DRender::QComputeCommand + \since 5.7 + \inmodule Qt3DRender + \brief QComponent to issue work for the compute shader on GPU + + A Qt3DRender::QComputeCommand is used to issue work for the compute shader. + The compute shader is specified in the QMaterial component of the same entity the + QComputeCommand is added to. The workGroupX, workGroupY and workGroupZ properties + specify the work group sizes for the compute shader invocation. Qt3DRender::QDispatchCompute + node needs to be present in the FrameGraph to actually issue the commands. + */ + +/*! + \qmltype ComputeCommand + \since 5.7 + \inmodule Qt3DRender + \inherits Component3D + \instantiates Qt3DRender::QComputeCommand + \brief Component to issue work for the compute shader on GPU + + A ComputeCommand is used to issue work for the compute shader. + The compute shader is specified in the Material component of the same entity the + ComputeCommand is added to. The workGroupX, workGroupY and workGroupZ properties + specify the work group sizes for the compute shader invocation. DispatchCompute + node needs to be present in the FrameGraph to actually issue the commands. + */ + +/*! + \qmlproperty int ComputeCommand::workGroupX + Specifies X workgroup size. + */ + +/*! + \qmlproperty int ComputeCommand::workGroupY + Specifies Y workgroup size. + */ + +/*! + \qmlproperty int ComputeCommand::workGroupZ + Specifies Z workgroup size. + */ + +/*! + \property QComputeCommand::workGroupX + Specifies X workgroup size. + */ + +/*! + \property QComputeCommand::workGroupY + Specifies Y workgroup size. + */ + +/*! + \property QComputeCommand::workGroupZ + Specifies Z workgroup size. */ QComputeCommandPrivate::QComputeCommandPrivate() @@ -60,9 +111,8 @@ QComputeCommandPrivate::QComputeCommandPrivate() } /*! - * The constructor creates a new Qt3DRender::QComputeCommand instance with the - * specified \a parent. - * \param parent + The constructor creates a new Qt3DRender::QComputeCommand instance with the + specified \a parent. */ QComputeCommand::QComputeCommand(Qt3DCore::QNode *parent) : Qt3DCore::QComponent(*new QComputeCommandPrivate, parent) @@ -74,27 +124,18 @@ QComputeCommand::~QComputeCommand() { } -/*! - * \return the workgroup size for the first dimension. - */ int QComputeCommand::workGroupX() const { Q_D(const QComputeCommand); return d->m_workGroupX; } -/*! - * \return the workgroup size for the second dimension. - */ int QComputeCommand::workGroupY() const { Q_D(const QComputeCommand); return d->m_workGroupY; } -/*! - * \return the workgroup size for the third dimension. - */ int QComputeCommand::workGroupZ() const { Q_D(const QComputeCommand); @@ -102,8 +143,7 @@ int QComputeCommand::workGroupZ() const } /*! - * Sets the workgroup for the first dimension to \a workGroupX. - * \param workGroupX + Sets the workgroup for the first dimension to \a workGroupX. */ void QComputeCommand::setWorkGroupX(int workGroupX) { @@ -115,8 +155,7 @@ void QComputeCommand::setWorkGroupX(int workGroupX) } /*! - * Sets the workgroup for the second dimension to \a workGroupY. - * \param workGroupY + Sets the workgroup for the second dimension to \a workGroupY. */ void QComputeCommand::setWorkGroupY(int workGroupY) { @@ -128,8 +167,7 @@ void QComputeCommand::setWorkGroupY(int workGroupY) } /*! - * Sets the workgroup for the third dimension to \a workGroupZ. - * \param workGroupZ + Sets the workgroup for the third dimension to \a workGroupZ. */ void QComputeCommand::setWorkGroupZ(int workGroupZ) { diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index c25de9654..1952a55c2 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -211,6 +211,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType<QTechnique>(QSharedPointer<Render::TechniqueFunctor>::create(m_renderer, m_nodeManagers)); // Framegraph + q->registerBackendType<QFrameGraphNode>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::FrameGraphNode, QFrameGraphNode> >::create(m_renderer, m_nodeManagers->frameGraphManager())); q->registerBackendType<QCameraSelector>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::CameraSelector, QCameraSelector> >::create(m_renderer, m_nodeManagers->frameGraphManager())); q->registerBackendType<QClearBuffers>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ClearBuffers, QClearBuffers> >::create(m_renderer, m_nodeManagers->frameGraphManager())); q->registerBackendType<QDispatchCompute>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::DispatchCompute, QDispatchCompute> >::create(m_renderer, m_nodeManagers->frameGraphManager())); @@ -360,7 +361,7 @@ QVector<Qt3DCore::QAspectJobPtr> QRenderAspect::jobsToExecute(qint64 time) // QChangeArbiter::syncChanges() that happens just before the render aspect is // asked for jobs to execute (this function). If that is the case, the RenderSettings will // be null and we should not generate any jobs. - if (d->m_renderer != nullptr && d->m_renderer->isRunning() && d->m_renderer->settings()) { + if (d->m_renderer->isRunning() && d->m_renderer->settings()) { // don't spawn any jobs, if the renderer decides to skip this frame if (!d->m_renderer->shouldRender()) { d->m_renderer->skipNextFrame(); diff --git a/src/render/frontend/qrendertarget.cpp b/src/render/frontend/qrendertarget.cpp index 44414e904..bdf8b5fa1 100644 --- a/src/render/frontend/qrendertarget.cpp +++ b/src/render/frontend/qrendertarget.cpp @@ -51,13 +51,40 @@ using namespace Qt3DCore; namespace Qt3DRender { /*! - * \class Qt3DRender::QRenderTarget - * \brief The QRenderTarget class encapsulates a target (usually a frame buffer - * object) which the renderer can render into. - * \since 5.7 - * \inmodule Qt3DRender + \class Qt3DRender::QRenderTarget + \brief The QRenderTarget class encapsulates a target (usually a frame buffer + object) which the renderer can render into. + \since 5.7 + \inmodule Qt3DRender + + A Qt3DRender::QRenderTarget comprises of Qt3DRender::QRenderTargetOutput objects, + which specify the the buffers the render target is rendering to. The user can + specify MRT(Multiple Render Targets) by attaching multiple textures to different + attachment points. The results are undefined if the user tries to attach multiple + textures to the same attachment point. At render time, only the draw buffers specified + in the Qt3DRender::QRenderTargetSelector are used. + + */ +/*! + \qmltype RenderTarget + \brief The RenderTarget class encapsulates a target (usually a frame buffer + object) which the renderer can render into. + \since 5.7 + \inmodule Qt3D.Render + \instantiates Qt3DRender::QRenderTarget + + A RenderTarget comprises of RenderTargetOutput objects, which specify the the buffers + the render target is rendering to. The user can specify MRT(Multiple Render Targets) + by attaching multiple textures to different attachment points. The results are undefined + if the user tries to attach multiple textures to the same attachment point. At render + time, only the draw buffers specified in the RenderTargetSelector are used. */ +/*! + \qmlproperty list<RenderTargetOutput> RenderTarget::attachments + Holds the attachments for the RenderTarget. +*/ + /*! \internal */ QRenderTargetPrivate::QRenderTargetPrivate() : QComponentPrivate() @@ -65,8 +92,8 @@ QRenderTargetPrivate::QRenderTargetPrivate() } /*! - * The constructor creates a new QRenderTarget::QRenderTarget instance with - * the specified \a parent. + The constructor creates a new QRenderTarget::QRenderTarget instance with + the specified \a parent. */ QRenderTarget::QRenderTarget(QNode *parent) : QComponent(*new QRenderTargetPrivate, parent) @@ -85,8 +112,7 @@ QRenderTarget::QRenderTarget(QRenderTargetPrivate &dd, QNode *parent) } /*! - * Adds a chosen output via \a output. - * \param output + Adds a chosen output via \a output. */ void QRenderTarget::addOutput(QRenderTargetOutput *output) { @@ -109,8 +135,7 @@ void QRenderTarget::addOutput(QRenderTargetOutput *output) } /*! - * Removes a chosen output via \a output. - * \param output + Removes a chosen output via \a output. */ void QRenderTarget::removeOutput(QRenderTargetOutput *output) { @@ -127,7 +152,7 @@ void QRenderTarget::removeOutput(QRenderTargetOutput *output) } /*! - * \return the chosen outputs. + \return the chosen outputs. */ QVector<QRenderTargetOutput *> QRenderTarget::outputs() const { diff --git a/src/render/frontend/qrendertargetoutput.cpp b/src/render/frontend/qrendertargetoutput.cpp index 55b788a23..6d65ec08e 100644 --- a/src/render/frontend/qrendertargetoutput.cpp +++ b/src/render/frontend/qrendertargetoutput.cpp @@ -47,13 +47,141 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * \class Qt3DRender::QRenderTargetOutput - * \brief The QRenderTargetOutput class allows the specification of an attachment - * of a render target (whether it is a color texture, a depth texture, etc... ). - * \since 5.7 - * \inmodule Qt3DRender + \class Qt3DRender::QRenderTargetOutput + \brief The QRenderTargetOutput class allows the specification of an attachment + of a render target (whether it is a color texture, a depth texture, etc... ). + \since 5.7 + \inmodule Qt3DRender + + A QRenderTargetOutput specifies the attachment point and parameters for texture + that is attached to render target. In addition to the attachment point, texture + miplevel, layer and cubemap face can be specified. The texture attached to the + QRenderTargetOutput must be compatible with the given parameters. + */ + +/*! + \qmltype RenderTargetOutput + \brief The RenderTargetOutput type allows the specification of an attachment + of a render target (whether it is a color texture, a depth texture, etc... ). + \since 5.7 + \inmodule Qt3D.Render + \inherits Node + \instantiates Qt3DRender::QRenderTargetOutput + + A RenderTargetOutput specifies the attachment point and parameters for texture + that is attached to render target. In addition to the attachment point, texture + miplevel, layer and cubemap face can be specified. The texture attached to the + RenderTargetOutput must be compatible with the given parameters. */ +/*! + \enum QRenderTargetOutput::AttachmentPoint + + This enumeration specifies the values for the attachment point. + + \value Color0 Color attachment point at index 0 + \value Color1 Color attachment point at index 1 + \value Color2 Color attachment point at index 2 + \value Color3 Color attachment point at index 3 + \value Color4 Color attachment point at index 4 + \value Color5 Color attachment point at index 5 + \value Color6 Color attachment point at index 6 + \value Color7 Color attachment point at index 7 + \value Color8 Color attachment point at index 8 + \value Color9 Color attachment point at index 9 + \value Color10 Color attachment point at index 10 + \value Color11 Color attachment point at index 11 + \value Color12 Color attachment point at index 12 + \value Color13 Color attachment point at index 13 + \value Color14 Color attachment point at index 14 + \value Color15 Color attachment point at index 15 + \value Depth Depth attachment point + \value Stencil Stencil attachment point + \value DepthStencil DepthStencil attachment point +*/ + +/*! + \qmlproperty enumeration RenderTargetOutput::attachmentPoint + Holds the attachment point of the RenderTargetOutput. + \list + \li RenderTargetOutput.Color0 + \li RenderTargetOutput.Color1 + \li RenderTargetOutput.Color2 + \li RenderTargetOutput.Color3 + \li RenderTargetOutput.Color4 + \li RenderTargetOutput.Color5 + \li RenderTargetOutput.Color6 + \li RenderTargetOutput.Color7 + \li RenderTargetOutput.Color8 + \li RenderTargetOutput.Color9 + \li RenderTargetOutput.Color10 + \li RenderTargetOutput.Color11 + \li RenderTargetOutput.Color12 + \li RenderTargetOutput.Color13 + \li RenderTargetOutput.Color14 + \li RenderTargetOutput.Color15 + \li RenderTargetOutput.Depth + \li RenderTargetOutput.Stencil + \li RenderTargetOutput.DepthStencil + \endlist + + \sa Qt3DRender::QRenderTargetOutput::AttachmentPoint +*/ + +/*! + \qmlproperty Texture RenderTargetOutput::texture + Holds the texture attached to the attachment point. +*/ + +/*! + \qmlproperty int RenderTargetOutput::mipLevel + Holds the miplevel of the attached texture the rendering is directed to. +*/ + +/*! + \qmlproperty int RenderTargetOutput::layer + Holds the layer of the attached texture the rendering is directed to. +*/ + +/*! + \qmlproperty enumeration RenderTargetOutput::face + Holds the face of the attached cubemap texture the rendering is directed to. + \list + \li Texture.CubeMapPositiveX + \li Texture.CubeMapNegativeX + \li Texture.CubeMapPositiveY + \li Texture.CubeMapNegativeY + \li Texture.CubeMapPositiveZ + \li Texture.CubeMapNegativeZ + \endlist + \sa Qt3DRender::QAbstractTexture::CubeMapFace +*/ + +/*! + \property QRenderTargetOutput::attachmentPoint + Holds the attachment point of the QRenderTargetOutput. +*/ + +/*! + \property QRenderTargetOutput::texture + Holds the texture attached to the attachment point. +*/ + +/*! + \property QRenderTargetOutput::mipLevel + Holds the miplevel of the attached texture the rendering is directed to. +*/ + +/*! + \property QRenderTargetOutput::layer + Holds the layer of the attached texture the rendering is directed to. +*/ + +/*! + \property QRenderTargetOutput::face + Holds the face of the attached cubemap texture the rendering is directed to. +*/ + /*! \internal */ QRenderTargetOutputPrivate::QRenderTargetOutputPrivate() : QNodePrivate() @@ -66,9 +194,8 @@ QRenderTargetOutputPrivate::QRenderTargetOutputPrivate() } /*! - * The constructor creates a new QRenderTargetOutput::QRenderTargetOutput instance - * with the specified \a parent. - * \param parent + The constructor creates a new QRenderTargetOutput::QRenderTargetOutput instance + with the specified \a parent. */ QRenderTargetOutput::QRenderTargetOutput(QNode *parent) : QNode(*new QRenderTargetOutputPrivate, parent) @@ -86,10 +213,6 @@ QRenderTargetOutput::QRenderTargetOutput(QRenderTargetOutputPrivate &dd, QNode * { } -/*! - * Sets the attachment point to \a attachmentPoint. - * \param attachmentPoint - */ void QRenderTargetOutput::setAttachmentPoint(QRenderTargetOutput::AttachmentPoint attachmentPoint) { Q_D(QRenderTargetOutput); @@ -99,9 +222,6 @@ void QRenderTargetOutput::setAttachmentPoint(QRenderTargetOutput::AttachmentPoin } } -/*! - * \return the current attachment point. - */ QRenderTargetOutput::AttachmentPoint QRenderTargetOutput::attachmentPoint() const { Q_D(const QRenderTargetOutput); @@ -130,19 +250,12 @@ void QRenderTargetOutput::setTexture(QAbstractTexture *texture) } } -/*! - * \return the current texture. - */ QAbstractTexture *QRenderTargetOutput::texture() const { Q_D(const QRenderTargetOutput); return d->m_texture; } -/*! - * Sets the required mip level to \a level. - * \param level - */ void QRenderTargetOutput::setMipLevel(int level) { Q_D(QRenderTargetOutput); @@ -152,19 +265,12 @@ void QRenderTargetOutput::setMipLevel(int level) } } -/*! - * \return the current mip level. - */ int QRenderTargetOutput::mipLevel() const { Q_D(const QRenderTargetOutput); return d->m_mipLevel; } -/*! - * Sets the required layer to \a layer. - * \param layer - */ void QRenderTargetOutput::setLayer(int layer) { Q_D(QRenderTargetOutput); @@ -174,19 +280,12 @@ void QRenderTargetOutput::setLayer(int layer) } } -/*! - * \return the current layer. - */ int QRenderTargetOutput::layer() const { Q_D(const QRenderTargetOutput); return d->m_layer; } -/*! - * Sets the required cubemap face to \a face. - * \param face - */ void QRenderTargetOutput::setFace(QAbstractTexture::CubeMapFace face) { Q_D(QRenderTargetOutput); @@ -196,9 +295,6 @@ void QRenderTargetOutput::setFace(QAbstractTexture::CubeMapFace face) } } -/*! - * \return the current cubemap face. - */ QAbstractTexture::CubeMapFace QRenderTargetOutput::face() const { Q_D(const QRenderTargetOutput); diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp index 2713de85b..8c0803a79 100644 --- a/src/render/graphicshelpers/graphicscontext.cpp +++ b/src/render/graphicshelpers/graphicscontext.cpp @@ -1334,7 +1334,7 @@ void GraphicsContext::specifyAttribute(const Attribute *attribute, Buffer *buffe VAOVertexAttribute attr; attr.bufferHandle = glBufferHandle; attr.bufferType = bufferType; - attr.location = (location >= 0 ? location + i : location); + attr.location = location + i; attr.dataType = attributeDataType; attr.byteOffset = attribute->byteOffset() + (i * attrCount * typeSize); attr.vertexSize = attribute->vertexSize() / attrCount; diff --git a/src/render/io/objloader.cpp b/src/render/io/objloader.cpp index d9610172f..686a9d5f0 100644 --- a/src/render/io/objloader.cpp +++ b/src/render/io/objloader.cpp @@ -60,10 +60,18 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { +struct Entry +{ + int start; + int size; +}; +QT3D_DECLARE_TYPEINFO(Qt3DRender, Entry, Q_PRIMITIVE_TYPE) + /* * A helper class to split a QByteArray and access its sections without * additional memory allocations. */ + class ByteArraySplitter { public: @@ -118,17 +126,10 @@ public: return ByteArraySplitter(m_input + m_entries[index].start, m_input + m_entries[index].start + m_entries[index].size, delimiter, splitBehavior); } - struct Entry - { - int start; - int size; - }; - private: QVarLengthArray<Entry, 16> m_entries; const char *m_input; }; -QT3D_DECLARE_TYPEINFO(Qt3DRender, ByteArraySplitter::Entry, Q_PRIMITIVE_TYPE) inline uint qHash(const FaceIndices &faceIndices) { diff --git a/src/render/jobs/renderviewjobutils.cpp b/src/render/jobs/renderviewjobutils.cpp index 5141bea28..d6dcd7f30 100644 --- a/src/render/jobs/renderviewjobutils.cpp +++ b/src/render/jobs/renderviewjobutils.cpp @@ -92,6 +92,9 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN FrameGraphNode::FrameGraphNodeType type = node->nodeType(); if (node->isEnabled()) switch (type) { + case FrameGraphNode::InvalidNodeType: + // A base FrameGraphNode, can be used for grouping purposes + break; case FrameGraphNode::CameraSelector: // Can be set only once and we take camera nearest to the leaf node if (!rv->renderCameraLens()) { diff --git a/src/render/renderstates/qalphacoverage.cpp b/src/render/renderstates/qalphacoverage.cpp index 7d68160d9..428454040 100644 --- a/src/render/renderstates/qalphacoverage.cpp +++ b/src/render/renderstates/qalphacoverage.cpp @@ -46,14 +46,41 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * \class Qt3DRender::QAlphaCoverage - * \brief A QAlphaCoverage class - * \inmodule Qt3DRender - * \since 5.7 - * \ingroup renderstates + \class Qt3DRender::QAlphaCoverage + \since 5.7 + \ingroup renderstates + \inmodule Qt3DRender + \brief Enable alpha-to-coverage multisampling mode + + A Qt3DRender::QAlphaCoverage class enables alpha-to-coverage multisampling mode. + When enabled, the fragment alpha value is used as a coverage for the sample + and combined with fragment coverage value. Qt3DRender::QAlphaCoverage does + nothing if multisampling is disabled. Alpha-to-coverage is most useful when + order independent blending is required, for example when rendering leaves, + grass and other rich vegetation. + + \sa Qt3DRender::QMultiSampleAntiAliasing + */ + +/*! + \qmltype AlphaCoverage + \since 5.7 + \ingroup renderstates + \inqmlmodule Qt3D.Render + \instantiates Qt3DRender::QAlphaCoverage + \inherits RenderState + \brief Enable alpha-to-coverage multisampling mode + + An AlphaCoverage type enables alpha-to-coverage multisampling mode. + When enabled, the fragment alpha value is used as a coverage for the sample + and combined with fragment coverage value. AlphaCoverage does nothing if + multisampling is disabled. Alpha-to-coverage is most useful when + order independent blending is required, for example when rendering leaves, + grass and other rich vegetation. + + \sa MultiSampleAntiAliasing */ -/*! \internal */ class QAlphaCoveragePrivate : public QRenderStatePrivate { public : @@ -65,8 +92,8 @@ public : }; /*! - * The constructor creates a new QAlphaCoverage::QAlphaCoverage instance - * with the specified \a parent. + The constructor creates a new QAlphaCoverage::QAlphaCoverage instance + with the specified \a parent. */ QAlphaCoverage::QAlphaCoverage(QNode *parent) : QRenderState(*new QAlphaCoveragePrivate, parent) diff --git a/src/render/renderstates/qalphatest.cpp b/src/render/renderstates/qalphatest.cpp index 2341c1039..81227d499 100644 --- a/src/render/renderstates/qalphatest.cpp +++ b/src/render/renderstates/qalphatest.cpp @@ -38,17 +38,6 @@ ** ****************************************************************************/ -/*! - * \class QAlphaTest - * \brief The QAlphaTest class is an OpenGL helper. - * \since 5.7 - * \ingroup renderstates - * - * As the OpenGL documentation explains; The alpha test discards a fragment - * conditional on the outcome of a comparison between the incoming fragment's - * alpha value and a constant value. - */ - #include "qalphatest.h" #include "qalphatest_p.h" #include <Qt3DRender/private/qrenderstatecreatedchange_p.h> @@ -57,6 +46,80 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { +/*! + \class Qt3DRender::QAlphaTest + \brief The QAlphaTest class specify alpha reference test + \since 5.7 + \inmodule Qt3DRender + \ingroup renderstates + + As the OpenGL documentation explains; The alpha test discards a fragment + conditional on the outcome of a comparison between the incoming fragment's + alpha value and a constant reference value. + */ + +/*! + \qmltype AlphaTest + \brief The AlphaTest class specify alpha reference test + \since 5.7 + \inqmlmodule Qt3D.Render + \inherits RenderState + \instantiates Qt3DRender::QAlphaTest + \ingroup renderstates + + As the OpenGL documentation explains; The alpha test discards a fragment + conditional on the outcome of a comparison between the incoming fragment's + alpha value and a constant reference value. + */ + +/*! + \enum Qt3DRender::QAlphaTest::AlphaFunction + + Enumeration for the alpha function values + \value Never Never pass alpha test + \value Always Always pass alpha test + \value Less Pass alpha test if fragment alpha is less than reference value + \value LessOrEqual Pass alpha test if fragment alpha is less than or equal to reference value + \value Equal Pass alpha test if fragment alpha is equal to reference value + \value GreaterOrEqual Pass alpha test if fragment alpha is greater than or equal to reference value + \value Greater Pass alpha test if fragment alpha is greater than reference value + \value NotEqual Pass alpha test if fragment alpha is not equal to reference value +*/ + +/*! + \qmlproperty enumeration AlphaTest::alphaFunction + Holds the alpha function used by the alpha test. Default is AlphaTest.Never. + \list + \li AlphaTest.Never + \li AlphaTest.Always + \li AlphaTest.Less + \li AlphaTest.LessOrEqual + \li AlphaTest.Equal + \li AlphaTest.GreaterOrEqual + \li AlphaTest.Greater + \li AlphaTest.NotEqual + \endlist + \sa Qt3DRender::QAlphaTest::AlphaFunction +*/ + +/*! + \qmlproperty real AlphaTest::referenceValue + Holds the reference value used by the alpha test. Default is 0.0. + When set, the value is clamped between 0 and 1. +*/ + +/*! + \property QAlphaTest::alphaFunction + Holds the alpha function used by the alpha test. Default is Never. +*/ + +/*! + \property QAlphaTest::referenceValue + Holds the reference value used by the alpha test. Default is 0.0. + When set, the value is clamped between 0 and 1. +*/ + + QAlphaTest::QAlphaTest(QNode *parent) : QRenderState(*new QAlphaTestPrivate, parent) { @@ -67,19 +130,12 @@ QAlphaTest::~QAlphaTest() { } -/*! - * \return the current alpha test function. - */ QAlphaTest::AlphaFunction QAlphaTest::alphaFunction() const { Q_D(const QAlphaTest); return d->m_alphaFunction; } -/*! - * Sets the alpha test function to \a alphaFunction. - * \param alphaFunction - */ void QAlphaTest::setAlphaFunction(QAlphaTest::AlphaFunction alphaFunction) { Q_D(QAlphaTest); @@ -89,18 +145,12 @@ void QAlphaTest::setAlphaFunction(QAlphaTest::AlphaFunction alphaFunction) } } -/*! - * \return a float value between 0 and 1. - */ float QAlphaTest::referenceValue() const { Q_D(const QAlphaTest); return d->m_referenceValue; } -/*! - * Sets the reference value which is clamped between 0 and 1 to \a referenceValue. - */ void QAlphaTest::setReferenceValue(float referenceValue) { Q_D(QAlphaTest); diff --git a/src/render/renderstates/qclipplane.cpp b/src/render/renderstates/qclipplane.cpp index 197a0c5a3..19053c147 100644 --- a/src/render/renderstates/qclipplane.cpp +++ b/src/render/renderstates/qclipplane.cpp @@ -55,7 +55,8 @@ namespace Qt3DRender { By default, OpenGL supports up to 8 additional clipping planes. Qt3DCore::QClipPlane allows to enable one of these additional planes. These planes can then be manipulated in the shaders using gl_ClipDistance[i] - where i varies between 0 and 8. + where i varies between 0 and 7. The underlying implementation may support more + than 8 clip planes, but it is not guaranteed. */ /*! @@ -70,9 +71,44 @@ namespace Qt3DRender { By default, OpenGL supports up to 8 additional clipping planes. ClipPlane allows to enable one of these additional planes. These planes can then be manipulated in the shaders using gl_ClipDistance[i] where i varies between - 0 and 8. + 0 and 7. The underlying implementation may support more than 8 clip planes, + but it is not guaranteed. */ +/*! + \qmlproperty int ClipPlane::planeIndex + Holds the index of the plane. + \note Usually between 0-7. +*/ + +/*! + \qmlproperty vector3d ClipPlane::normal + Holds the normal of the plane. +*/ + +/*! + \qmlproperty real ClipPlane::distance + Holds the distance of the plane from the world origin. +*/ + + +/*! + \property QClipPlane::planeIndex + Holds the index of the plane. + \note Usually between 0-7. +*/ + +/*! + \property QClipPlane::normal + Holds the normal of the plane. +*/ + +/*! + \property QClipPlane::distance + Holds the distance of the plane from the world origin. +*/ + + QClipPlane::QClipPlane(QNode *parent) : QRenderState(*new QClipPlanePrivate(), parent) { @@ -83,10 +119,6 @@ QClipPlane::~QClipPlane() { } -/*! - * Returns the index of the clip plane. - * \note usually between 0-7 - */ int QClipPlane::planeIndex() const { Q_D(const QClipPlane); @@ -105,10 +137,6 @@ float QClipPlane::distance() const return d->m_distance; } -/*! - * Sets the index of the clip plane to \a planeIndex - * \note above 7, support is not garanteed - */ void QClipPlane::setPlaneIndex(int planeIndex) { Q_D(QClipPlane); diff --git a/src/render/renderstates/qcolormask.cpp b/src/render/renderstates/qcolormask.cpp index 71819db94..fde09d7b0 100644 --- a/src/render/renderstates/qcolormask.cpp +++ b/src/render/renderstates/qcolormask.cpp @@ -48,7 +48,22 @@ namespace Qt3DRender { /*! \class Qt3DRender::QColorMask \inmodule Qt3DRender + \since 5.7 + \brief Allows specifying which color components should be written to the + currently bound frame buffer. + By default, the property for each color component (red, green, blue, alpha) + is set to \c true which means they will be written to the frame buffer. + Setting any of the color component to \c false will prevent it from being + written into the frame buffer. + */ + +/*! + \qmltype ColorMask + \inqmlmodule Qt3D.Render + \since 5.7 + \inherits RenderState + \instantiates Qt3DRender::QColorMask \brief Allows specifying which color components should be written to the currently bound frame buffer. @@ -58,6 +73,26 @@ namespace Qt3DRender { written into the frame buffer. */ +/*! + \qmlproperty bool ColorMask::redMasked + Holds whether red color component should be written to the frame buffer. +*/ + +/*! + \qmlproperty bool ColorMask::greenMasked + Holds whether green color component should be written to the frame buffer. +*/ + +/*! + \qmlproperty bool ColorMask::blueMasked + Holds whether blue color component should be written to the frame buffer. +*/ + +/*! + \qmlproperty bool ColorMask::alphaMasked + Holds whether alpha component should be written to the frame buffer. +*/ + /*! Constructs a new Qt3DCore::QColorMask instance with \a parent as parent. @@ -97,7 +132,7 @@ bool QColorMask::isAlphaMasked() const } /*! - \property Qt3DRender::QColorMask::red + \property QColorMask::redMasked Holds whether the red color component should be written to the frame buffer. */ void QColorMask::setRedMasked(bool redMasked) @@ -110,7 +145,7 @@ void QColorMask::setRedMasked(bool redMasked) } /*! - \property Qt3DRender::QColorMask::green + \property QColorMask::greenMasked Holds whether the green color component should be written to the frame buffer. */ void QColorMask::setGreenMasked(bool greenMasked) @@ -123,7 +158,7 @@ void QColorMask::setGreenMasked(bool greenMasked) } /*! - \property Qt3DRender::QColorMask::blue + \property QColorMask::blueMasked Holds whether the blue color component should be written to the frame buffer. */ void QColorMask::setBlueMasked(bool blueMasked) @@ -136,7 +171,7 @@ void QColorMask::setBlueMasked(bool blueMasked) } /*! - \property Qt3DRender::QColorMask::alphaMasked + \property QColorMask::alphaMasked Holds whether the alphaMasked component should be written to the frame buffer. */ void QColorMask::setAlphaMasked(bool alphaMasked) diff --git a/src/render/renderstates/qcullface.cpp b/src/render/renderstates/qcullface.cpp index 2b8a7f8e0..e96346287 100644 --- a/src/render/renderstates/qcullface.cpp +++ b/src/render/renderstates/qcullface.cpp @@ -38,18 +38,7 @@ ** ****************************************************************************/ -/*! - * \class QCullFace - * \brief The QCullFace class specifies whether front or back face culling - * are enabled - * \since 5.7 - * \ingroup renderstates - * - * QCullFace sets whether the front or back facets are culled. - * Facets include triangles, quadrilaterals, polygons and rectangles. - * - * \sa QFrontFace - */ + #include "qcullface.h" #include "qcullface_p.h" #include <Qt3DRender/private/qrenderstatecreatedchange_p.h> @@ -59,7 +48,57 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * Constructs a new QCullFace::QCullFace instance with \a parent as parent. + \class Qt3DRender::QCullFace + \brief The QCullFace class specifies whether front or back face culling + are enabled + \since 5.7 + \inmodule Qt3DRender + \ingroup renderstates + + QCullFace sets whether the front or back facets are culled. + Facets include triangles, quadrilaterals, polygons and rectangles. + + \sa QFrontFace + */ + +/*! + \qmltype CullFace + \brief The CullFace type specifies whether front or back face culling + are enabled + \since 5.7 + \inqmlmodule Qt3D.Render + \instantiates Qt3DRender::QCullFace + \inherits RenderState + \ingroup renderstates + + CullFace sets whether the front or back facets are culled. + Facets include triangles, quadrilaterals, polygons and rectangles. + + \sa FrontFace + */ + +/*! + \enum Qt3DRender::QCullFace::CullingMode + + This enumeration specifies values for the culling mode. + \value NoCulling culling is disabled + \value Front Culling is enabled for front facing polygons + \value Back Culling is enabled for back facing polygons + \value FrontAndBack Culling is enabled for all polygons, points and lines are drawn. +*/ + +/*! + \qmlproperty enumeration CullFace::mode + Holds the culling mode used by CullFace. Default is set to QCullFace.Back. +*/ + +/*! + \property QCullFace::mode + Holds the culling mode used by QCullFace. Default is set to QCullFace.Back. +*/ + +/*! + Constructs a new QCullFace::QCullFace instance with \a parent as parent. */ QCullFace::QCullFace(QNode *parent) : QRenderState(*new QCullFacePrivate, parent) @@ -71,19 +110,12 @@ QCullFace::~QCullFace() { } -/*! - * \return which culling mode is currently enabled. - */ QCullFace::CullingMode QCullFace::mode() const { Q_D(const QCullFace); return d->m_mode; } -/*! - * Sets which faces to cull to \a mode. Default is set to back. - * \param mode - */ void QCullFace::setMode(QCullFace::CullingMode mode) { Q_D(QCullFace); diff --git a/src/render/renderstates/qdepthtest.cpp b/src/render/renderstates/qdepthtest.cpp index c2299f810..7e67ba5ba 100644 --- a/src/render/renderstates/qdepthtest.cpp +++ b/src/render/renderstates/qdepthtest.cpp @@ -38,14 +38,6 @@ ** ****************************************************************************/ -/*! - * \class QDepthTest - * \brief The QDepthTest class tests the fragment shader's depth value against - * the depth of a sample being written to. - * \since 5.7 - * \ingroup renderstates - * - */ #include "qdepthtest.h" #include "qdepthtest_p.h" #include <Qt3DRender/private/qrenderstatecreatedchange_p.h> @@ -55,7 +47,79 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * The constructor creates a new QDepthTest::QDepthTest instance with the specified \a parent. + \class Qt3DRender::QDepthTest + \brief The QDepthTest class tests the fragment shader's depth value against + the depth of a sample being written to. + \since 5.7 + \inmodule Qt3DRender + \ingroup renderstates + + A QDepthTest class is used to enable depth testing with a given depth test function. + The depth test enables writing fragment color values when the depth test passes, and + reject fragments which fail the test. The depth test uses the depth function to + test the fragments depth value to the value against z-buffer. If the underlying surface + does not have z-buffer, then QDepthTest does nothing. + + \sa QAlphaTest, QStencilTest + */ + +/*! + \qmltype DepthTest + \brief The DepthTest type tests the fragment shader's depth value against + the depth of a sample being written to. + \since 5.7 + \inqmlmodule Qt3D.Render + \inherits RenderState + \instantiates Qt3DRender::QDepthTest + \ingroup renderstates + + A DepthTest type is used to enable depth testing with a given depth test function. + The depth test enables writing fragment color values when the depth test passes, and + reject fragments which fail the test. The depth test uses the depth function to + test the fragments depth value to the value against z-buffer. If the underlying surface + does not have z-buffer, the DepthTest does nothing. + + \sa AlphaTest, StencilTest + */ + +/*! + \enum Qt3DRender::QDepthTest::DepthFunction + + Enumeration for the depth function values + \value Never Never pass depth test + \value Always Always pass depth test + \value Less Pass depth test if fragment depth is less than z-buffer value + \value LessOrEqual Pass depth test if fragment depth is less than or equal to z-buffer value + \value Equal Pass depth test if fragment depth is equal to z-buffer value + \value GreaterOrEqual Pass depth test if fragment depth is greater than or equal to z-buffer value + \value Greater Pass depth test if fragment depth is greater than z-buffer value + \value NotEqual Pass depth test if fragment depth is not equal to z-buffer value +*/ + +/*! + \qmlproperty enumeration DepthTest::depthFunction + Holds the current function used by depth test. The default is DepthTest.Never. + \list + \li DepthTest.Never + \li DepthTest.Always + \li DepthTest.Less + \li DepthTest.LessOrEqual + \li DepthTest.Equal + \li DepthTest.GreaterOrEqual + \li DepthTest.Greater + \li DepthTest.NotEqual + \endlist + \sa Qt3DRender::QDepthTest::DepthFunction +*/ + +/*! + \property QDepthTest::depthFunction + Holds the current function used by depth test. The default is Never. +*/ + + +/*! + The constructor creates a new QDepthTest::QDepthTest instance with the specified \a parent. */ QDepthTest::QDepthTest(QNode *parent) : QRenderState(*new QDepthTestPrivate, parent) @@ -67,19 +131,12 @@ QDepthTest::~QDepthTest() { } -/*! - * \return the current enabled depth function. - */ QDepthTest::DepthFunction QDepthTest::depthFunction() const { Q_D(const QDepthTest); return d->m_depthFunction; } -/*! - * Sets the depth function being enabled to \a depthFunction - * \param depthFunction - */ void QDepthTest::setDepthFunction(QDepthTest::DepthFunction depthFunction) { Q_D(QDepthTest); diff --git a/src/render/renderstates/qdithering.cpp b/src/render/renderstates/qdithering.cpp index cecf817d9..102cfa0ff 100644 --- a/src/render/renderstates/qdithering.cpp +++ b/src/render/renderstates/qdithering.cpp @@ -48,14 +48,31 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * \class Qt3DRender::QDithering - * \brief The QDithering class - * \inmodule Qt3DRender - * \since 5.7 - * \ingroup renderstates + \class Qt3DRender::QDithering + \since 5.7 + \inmodule Qt3DRender + \brief Enable dithering + + A Qt3DRender::QDithering class enables dithering. Dithering adds noise to the + color values to randomize quantization error in order to prevent large scale + patterns in the final image, such as banding. Dithering is most useful when + rendering to a surface with low color bit depth, such as RGB565 or RGBA4444. + */ + +/*! + \qmltype Dithering + \since 5.7 + \inqmlmodule Qt3D.Render + \inherits RenderState + \instantiates Qt3DRender::QDithering + \brief Enable dithering + + A Dithering type enables dithering. Dithering adds noise to the + color values to randomize quantization error in order to prevent large scale + patterns in the final image, such as banding. Dithering is most useful when + rendering to a surface with low color bit depth, such as RGB565 or RGBA4444. */ -/*! \internal */ class QDitheringPrivate : public QRenderStatePrivate { public: @@ -67,8 +84,8 @@ public: }; /*! - * The constructor creates a new QDithering::QDithering instance with - * the specified \a parent. + The constructor creates a new QDithering::QDithering instance with + the specified \a parent. */ QDithering::QDithering(QNode *parent) : QRenderState(*new QDitheringPrivate, parent) diff --git a/src/render/renderstates/qfrontface.cpp b/src/render/renderstates/qfrontface.cpp index 016f27370..a814be82f 100644 --- a/src/render/renderstates/qfrontface.cpp +++ b/src/render/renderstates/qfrontface.cpp @@ -38,13 +38,6 @@ ** ****************************************************************************/ -/*! - * \class QFrontFace - * \brief The QFrontFace class defines front and back facing polygons. - * \since 5.7 - * \ingroup renderstates - * - */ #include "qfrontface.h" #include "qfrontface_p.h" #include <Qt3DRender/private/qrenderstatecreatedchange_p.h> @@ -54,8 +47,52 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * The constructor creates a new QFrontFace::QFrontFace instance with the - * specified \a parent + \class Qt3DRender::QFrontFace + \brief The QFrontFace class defines front and back facing polygons. + \since 5.7 + \ingroup renderstates + \inmodule Qt3DRender + + A Qt3DRender::QFrontFace sets the winding direction of the front facing polygons. + + \sa QCullFace + */ + +/*! + \qmltype FrontFace + \brief The FrontFace type defines front and back facing polygons. + \since 5.7 + \ingroup renderstates + \inqmlmodule Qt3D.Render + \inherits RenderState + \instantiates Qt3DRender::QFrontFace + + A FrontFace sets the winding direction of the front facing polygons. + + \sa CullFace + */ + +/*! + \enum QFrontFace::WindingDirection + + This enumeration specifies the winding direction values. + \value ClockWise Clockwise polygons are front facing. + \value CounterClockWise Counter clockwise polygons are front facing. +*/ + +/*! + \qmlproperty enumeration FrontFace::direction + Holds the winding direction of the front facing polygons. Default is FrontFace.Clockwise. +*/ + +/*! + \property QFrontFace::direction + Holds the winding direction of the front facing polygons. Default is Clockwise. +*/ + +/*! + The constructor creates a new QFrontFace::QFrontFace instance with the + specified \a parent */ QFrontFace::QFrontFace(QNode *parent) : QRenderState(*new QFrontFacePrivate, parent) @@ -67,19 +104,12 @@ QFrontFace::~QFrontFace() { } -/*! - * \return the current winding direction - */ QFrontFace::WindingDirection QFrontFace::direction() const { Q_D(const QFrontFace); return d->m_direction; } -/*! - * Sets the winding direction to \a direction - * \param direction - */ void QFrontFace::setDirection(QFrontFace::WindingDirection direction) { Q_D(QFrontFace); diff --git a/src/render/renderstates/qmultisampleantialiasing.cpp b/src/render/renderstates/qmultisampleantialiasing.cpp index ae398cd0d..923fc435e 100644 --- a/src/render/renderstates/qmultisampleantialiasing.cpp +++ b/src/render/renderstates/qmultisampleantialiasing.cpp @@ -47,13 +47,29 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * \class QMultiSampleAntiAliasing - * \brief The QMultiSampleAntiAliasing class - * \since 5.7 - * \ingroup renderstates + \class Qt3DRender::QMultiSampleAntiAliasing + \brief Enable multisample antialiasing + \since 5.7 + \ingroup renderstates + \inmodule Qt3DRender + + A Qt3DRender::QMultiSampleAntiAliasing class enables multisample antialiasing. + The render target must have been allocated with multisampling enabled. + */ + +/*! + \qmltype MultiSampleAntiAliasing + \brief Enable multisample antialiasing + \since 5.7 + \ingroup renderstates + \inqmlmodule Qt3D.Render + \inherits RenderState + \instantiates Qt3DRender::QMultiSampleAntiAliasing + + A MultiSampleAntiAliasing type enables multisample antialiasing. + The render target must have been allocated with multisampling enabled. */ -/*! \internal */ class QMultiSampleAntiAliasingPrivate : public QRenderStatePrivate { public: @@ -66,8 +82,8 @@ public: }; /*! - * The constructor creates a new QMultiSampleAntiAliasing::QMultiSampleAntiAliasing - * instance with the specified \a parent. + The constructor creates a new QMultiSampleAntiAliasing::QMultiSampleAntiAliasing + instance with the specified \a parent. */ QMultiSampleAntiAliasing::QMultiSampleAntiAliasing(QNode *parent) : QRenderState(*new QMultiSampleAntiAliasingPrivate, parent) diff --git a/src/render/renderstates/qnodepthmask.cpp b/src/render/renderstates/qnodepthmask.cpp index b508f60b3..f0376cfb6 100644 --- a/src/render/renderstates/qnodepthmask.cpp +++ b/src/render/renderstates/qnodepthmask.cpp @@ -48,13 +48,31 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * \class QNoDepthMask - * \brief The QNoDepthMask class - * \since 5.7 - * \ingroup renderstates + \class Qt3DRender::QNoDepthMask + \brief Disable depth write + \since 5.7 + \ingroup renderstates + \inmodule Qt3DRender + + A Qt3DRender::QNoDepthMask class disables fragment depth write to depth buffer. + + \sa Qt3DRender::QDepthTest + */ + +/*! + \qmltype NoDepthMask + \brief Disable depth write + \since 5.7 + \ingroup renderstates + \inqmlmodule Qt3D.Render + \inherits RenderState + \instantiates Qt3DRender::QNoDepthMask + + A NoDepthMask type disables fragment depth write to depth buffer. + + \sa Qt3DRender::QDepthTest */ -/*! \internal */ class QNoDepthMaskPrivate : public QRenderStatePrivate { public: @@ -67,8 +85,8 @@ public: }; /*! - * the constructor creates a new QNoDepthMask::QNoDepthMask instance with - * the specified \a parent. + The constructor creates a new QNoDepthMask::QNoDepthMask instance with + the specified \a parent. */ QNoDepthMask::QNoDepthMask(QNode *parent) : QRenderState(*new QNoDepthMaskPrivate, parent) diff --git a/src/render/renderstates/qpointsize.cpp b/src/render/renderstates/qpointsize.cpp index 03c37bc4b..10687f8f2 100644 --- a/src/render/renderstates/qpointsize.cpp +++ b/src/render/renderstates/qpointsize.cpp @@ -48,6 +48,7 @@ namespace Qt3DRender { /*! \class Qt3DRender::QPointSize \inmodule Qt3DRender + \since 5.7 \brief Specifies the size of rasterized points. May either be set statically or by shader programs. @@ -59,6 +60,8 @@ namespace Qt3DRender { /*! \qmltype PointSize + \since 5.7 + \inherits RenderState \instantiates Qt3DRender::QPointSize \inqmlmodule Qt3D.Render @@ -72,12 +75,29 @@ namespace Qt3DRender { */ /*! - \qmlproperty float Qt3D.Render::QPointSize::value + \enum Qt3DRender::QPointSize::SizeMode + + This enumeration specifies values for the size mode. + \value Fixed The point size is by the QPointSize::value. + \value Programmable The point size value must be set in shader +*/ +/*! + \qmlproperty real PointSize::value + Specifies the point size value to be used. +*/ + +/*! + \qmlproperty enumeration PointSize::sizeMode + Specifies the sizeMode to be used. +*/ + +/*! + \property QPointSize::value Specifies the point size value to be used. */ /*! - \qmlproperty QPointSize::SizeMode Qt3D.Render::QPointSize::sizeMode + \property QPointSize::sizeMode Specifies the sizeMode to be used. */ diff --git a/src/render/renderstates/qpolygonoffset.cpp b/src/render/renderstates/qpolygonoffset.cpp index d9703ab4b..0d397f159 100644 --- a/src/render/renderstates/qpolygonoffset.cpp +++ b/src/render/renderstates/qpolygonoffset.cpp @@ -37,14 +37,6 @@ ** ****************************************************************************/ -/*! - * \class QPolygonOffset - * \brief The QPolygonOffset class sets the scale and steps to calculate depth - * values for polygon offsets. - * \since 5.7 - * \ingroup renderstates - * - */ #include "qpolygonoffset.h" #include "qpolygonoffset_p.h" #include <Qt3DRender/private/qrenderstatecreatedchange_p.h> @@ -54,8 +46,58 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * The constructor creates a new QPolygonOffset::QPolygonOffset instance - * with the specified \a parent + \class Qt3DRender::QPolygonOffset + \brief The QPolygonOffset class sets the scale and steps to calculate depth + values for polygon offsets. + \since 5.7 + \inmodule Qt3DRender + \ingroup renderstates + + A QPolygonOffset class adds an offset to the fragment depth value prior to + depth test and depth write. The offset can be used to avoid z-fighting when + rendering polygons with very close depth values such as decals. + */ + +/*! + \qmltype PolygonOffset + \brief The PolygonOffset type sets the scale and steps to calculate depth + values for polygon offsets. + \since 5.7 + \inqmlmodule Qt3D.Render + \ingroup renderstates + \inherits RenderState + \instantiates Qt3DRender::QPolygonOffset + + A PolygonOffset type adds an offset to the fragment depth value prior to + depth test and depth write. The offset can be used to avoid z-fighting when + rendering polygons with very close depth values such as decals. + */ + +/*! + \qmlproperty real PolygonOffset::scaleFactor + Holds the scale factor used to create a variable depth offset for + each polygon. Default value is 0. +*/ + +/*! + \qmlproperty real PolygonOffset::depthSteps + Holds the units that create constant depth offsets. Default value is 0. +*/ + +/*! + \property QPolygonOffset::scaleFactor + Holds the scale factor used to create a variable depth offset for + each polygon. Default value is 0. +*/ + +/*! + \property QPolygonOffset::depthSteps + Holds the units that create constant depth offsets. Default value is 0. +*/ + +/*! + The constructor creates a new QPolygonOffset::QPolygonOffset instance + with the specified \a parent */ QPolygonOffset::QPolygonOffset(QNode *parent) : QRenderState(*new QPolygonOffsetPrivate, parent) @@ -67,20 +109,12 @@ QPolygonOffset::~QPolygonOffset() { } -/*! - * \return the current scale factor. - */ float QPolygonOffset::scaleFactor() const { Q_D(const QPolygonOffset); return d->m_scaleFactor; } -/*! - * Sets the scale factor used to create a variable depth offset for - * each polygon, to \a scaleFactor. Default value is 0. - * \param scaleFactor - */ void QPolygonOffset::setScaleFactor(float scaleFactor) { Q_D(QPolygonOffset); @@ -90,19 +124,12 @@ void QPolygonOffset::setScaleFactor(float scaleFactor) } } -/*! - * \return the current depth steps. - */ float QPolygonOffset::depthSteps() const { Q_D(const QPolygonOffset); return d->m_depthSteps; } -/*! - * Sets the units that create constant depth offsets, to depthSteps. - * \param depthSteps - */ void QPolygonOffset::setDepthSteps(float depthSteps) { Q_D(QPolygonOffset); diff --git a/src/render/renderstates/qrenderstate.cpp b/src/render/renderstates/qrenderstate.cpp index 974d8f602..e49292dbd 100644 --- a/src/render/renderstates/qrenderstate.cpp +++ b/src/render/renderstates/qrenderstate.cpp @@ -47,10 +47,26 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * \class QRenderState - * \brief The QRenderState class - * \since 5.7 - * \ingroup renderstates + \class Qt3DRender::QRenderState + \brief An abstract base class for all render states + \since 5.7 + \ingroup renderstates + \inmodule Qt3DRender + + A Qt3DRender::QRenderState class is abstract base class for all render states. + One can not instantiate QRenderState directly, but through its subclasses. + */ + +/*! + \qmltype RenderState + \brief An abstract base type for all render states + \since 5.7 + \inherits Node + \instantiates Qt3DRender::QRenderState + \ingroup renderstates + + A RenderState type is abstract base class for all render states. + One can not instantiate RenderState directly, but through its subclasses. */ /*! \internal */ diff --git a/src/render/renderstates/qscissortest.cpp b/src/render/renderstates/qscissortest.cpp index e363ba54d..718978b7a 100644 --- a/src/render/renderstates/qscissortest.cpp +++ b/src/render/renderstates/qscissortest.cpp @@ -38,15 +38,6 @@ ** ****************************************************************************/ -/*! - * \class QScissorTest - * \brief The QScissorTest class discards fragments that fall outside of a - * certain rectangular portion of the screen. - * \since 5.7 - * \ingroup renderstates - * - */ - #include "qscissortest.h" #include "qscissortest_p.h" #include <Qt3DRender/private/qrenderstatecreatedchange_p.h> @@ -56,8 +47,76 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * The constructor creates a new QScissorTest::QScissorTest instance with the - * specified \a parent + \class Qt3DRender::QScissorTest + \brief The QScissorTest class discards fragments that fall outside of a + certain rectangular portion of the screen. + \since 5.7 + \ingroup renderstates + \inmodule Qt3DRender + + A QScissorTest class enables scissor test, which discards fragments outside + the rectangular area of the screen specified by the left, bottom, width and + height properties. + */ + +/*! + \qmltype ScissorTest + \brief The ScissorTest type discards fragments that fall outside of a + certain rectangular portion of the screen. + \since 5.7 + \ingroup renderstates + \inqmlmodule Qt3D.Render + \instantiates Qt3DRender::QScissorTest + \inherits RenderState + + A ScissorTest type enables scissor test, which discards fragments outside + the rectangular area of the screen specified by the left, bottom, width and + height properties. + */ + +/*! + \qmlproperty int ScissorTest::left + Holds the left coordinate of the scissor box. +*/ + +/*! + \qmlproperty int ScissorTest::bottom + Holds the bottom coordinate of the scissor box. +*/ + +/*! + \qmlproperty int ScissorTest::width + Holds the width of the scissor box. +*/ + +/*! + \qmlproperty int ScissorTest::height + Holds the height of the scissor box. +*/ + +/*! + \property QScissorTest::left + Holds the left coordinate of the scissor box. +*/ + +/*! + \property QScissorTest::bottom + Holds the bottom coordinate of the scissor box. +*/ + +/*! + \property QScissorTest::width + Holds the width of the scissor box. +*/ + +/*! + \property QScissorTest::height + Holds the height of the scissor box. +*/ + +/*! + The constructor creates a new QScissorTest::QScissorTest instance with the + specified \a parent */ QScissorTest::QScissorTest(QNode *parent) : QRenderState(*new QScissorTestPrivate, parent) @@ -69,19 +128,12 @@ QScissorTest::~QScissorTest() { } -/*! - * \return the left of the scissor box - */ int QScissorTest::left() const { Q_D(const QScissorTest); return d->m_left; } -/*! - * Sets the left of the scissor box to \a setLeft - * \param left - */ void QScissorTest::setLeft(int left) { Q_D(QScissorTest); @@ -91,19 +143,12 @@ void QScissorTest::setLeft(int left) } } -/*! - * \return the bottom of the scrissor box - */ int QScissorTest::bottom() const { Q_D(const QScissorTest); return d->m_bottom; } -/*! - * Sets the bottom of the scissor box to \a bottom - * \param bottom - */ void QScissorTest::setBottom(int bottom) { Q_D(QScissorTest); @@ -113,19 +158,12 @@ void QScissorTest::setBottom(int bottom) } } -/*! - * \return the width of the scissor box - */ int QScissorTest::width() const { Q_D(const QScissorTest); return d->m_width; } -/*! - * Sets the width of the scissor box to \a width - * \param width - */ void QScissorTest::setWidth(int width) { Q_D(QScissorTest); @@ -135,19 +173,12 @@ void QScissorTest::setWidth(int width) } } -/*! - * \return the height of the scissor box - */ int QScissorTest::height() const { Q_D(const QScissorTest); return d->m_height; } -/*! - * Sets the height of the scissor box to \a height - * \param height - */ void QScissorTest::setHeight(int height) { Q_D(QScissorTest); diff --git a/src/render/renderstates/qseamlesscubemap.cpp b/src/render/renderstates/qseamlesscubemap.cpp index cc72f34ad..860b36450 100644 --- a/src/render/renderstates/qseamlesscubemap.cpp +++ b/src/render/renderstates/qseamlesscubemap.cpp @@ -47,16 +47,28 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * \class Qt3DRender::QSeamlessCubemap - * \brief Enables seamless cubemap texture filtering. - * \inmodule Qt3DRender - * \since 5.7 - * \ingroup renderstates - * When present in a state set, enables the seamless cubemap texture filtering - * as provided by the GL_ARB_seamless_cubemap extension (if available). + \class Qt3DRender::QSeamlessCubemap + \brief Enables seamless cubemap texture filtering. + \since 5.7 + \inmodule Qt3DRender + + When present in a state set, enables the seamless cubemap texture filtering + as provided by the GL_ARB_seamless_cubemap extension (if available). */ -/*! \internal */ +/*! + \qmltype SeamlessCubemap + \brief Enables seamless cubemap texture filtering. + \since 5.7 + \inqmlmodule Qt3D.Render + \instantiates Qt3DRender::QSeamlessCubemap + \inherits RenderState + + When present in a state set, enables the seamless cubemap texture filtering + as provided by the GL_ARB_seamless_cubemap extension (if available). + */ + + class QSeamlessCubemapPrivate : public QRenderStatePrivate { public: @@ -69,8 +81,8 @@ public: }; /*! - * The constructor creates a new QSeamlessCubemap::QSeamlessCubemap instance - * with the specified \a parent. + The constructor creates a new QSeamlessCubemap::QSeamlessCubemap instance + with the specified \a parent. */ QSeamlessCubemap::QSeamlessCubemap(QNode *parent) : QRenderState(*new QSeamlessCubemapPrivate, parent) diff --git a/src/render/renderstates/qstencilmask.cpp b/src/render/renderstates/qstencilmask.cpp index 64cffbe8a..1b9b2cd10 100644 --- a/src/render/renderstates/qstencilmask.cpp +++ b/src/render/renderstates/qstencilmask.cpp @@ -37,15 +37,6 @@ ** ****************************************************************************/ -/*! - * \class QStencilMask - * \brief The QStencilMask class controls the front and back writing of - * individual bits in the stencil planes. - * \since 5.7 - * \ingroup renderstates - * - */ - #include "qstencilmask.h" #include "qstencilmask_p.h" #include <Qt3DRender/private/qrenderstatecreatedchange_p.h> @@ -55,8 +46,61 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * The constructor creates a new QStencilMask::QStencilMask instance with the - * specified \a parent. + \class Qt3DRender::QStencilMask + \brief The QStencilMask class controls the front and back writing of + individual bits in the stencil planes. + \since 5.7 + \ingroup renderstates + \inmodule Qt3DRender + + A Qt3DRender::QStencilMask class specifies a write mask for the stencil values + after the stencil test. Mask can be specified separately for the front-facing + and back-facing polygons. The fragment stencil value is and'd with the mask + before it is written to the stencil buffer. + + \sa Qt3DRender::QStencilTest + */ + +/*! + \qmltype StencilMask + \brief The StencilMask type controls the front and back writing of + individual bits in the stencil planes. + \since 5.7 + \ingroup renderstates + \inqmlmodule Qt3D.Render + \instantiates Qt3DRender::QStencilMask + \inherits RenderState + + A StencilMask type specifies the mask for the stencil test. Mask can be specified + separately for the front-facing and back-facing polygons. The stencil test reference + value and stencil buffer value gets and'd with the mask prior to applying stencil function. + + \sa StencilTest + */ + +/*! + \qmlproperty int StencilMask::frontOutputMask + Holds the write mask for the fragment stencil values for front-facing polygons. +*/ + +/*! + \qmlproperty int StencilMask::backOutputMask + Holds the write mask for the fragment stencil values for back-facing polygons. +*/ + +/*! + \property QStencilMask::frontOutputMask + Holds the write mask for the fragment stencil values for front-facing polygons. +*/ + +/*! + \property QStencilMask::backOutputMask + Holds the write mask for the fragment stencil values for back-facing polygons. +*/ + +/*! + The constructor creates a new QStencilMask::QStencilMask instance with the + specified \a parent. */ QStencilMask::QStencilMask(QNode *parent) : QRenderState(*new QStencilMaskPrivate(), parent) @@ -68,10 +112,6 @@ QStencilMask::~QStencilMask() { } -/*! - * Sets the front output mask to \a mask. - * \param mask - */ void QStencilMask::setFrontOutputMask(uint mask) { Q_D(QStencilMask); @@ -81,10 +121,6 @@ void QStencilMask::setFrontOutputMask(uint mask) } } -/*! - * Sets the back output mask to \a mask. - * \param mask - */ void QStencilMask::setBackOutputMask(uint mask) { Q_D(QStencilMask); @@ -94,18 +130,12 @@ void QStencilMask::setBackOutputMask(uint mask) } } -/*! - * \return the front output mask. - */ uint QStencilMask::frontOutputMask() const { Q_D(const QStencilMask); return d->m_frontOutputMask; } -/*! - * \return the back output mask. - */ uint QStencilMask::backOutputMask() const { Q_D(const QStencilMask); diff --git a/src/render/renderstates/qstenciloperation.cpp b/src/render/renderstates/qstenciloperation.cpp index 0b3842c53..7a5b113d8 100644 --- a/src/render/renderstates/qstenciloperation.cpp +++ b/src/render/renderstates/qstenciloperation.cpp @@ -37,14 +37,6 @@ ** ****************************************************************************/ -/*! - * \class QStencilOperation - * \brief The QStencilOperation class allows the selection of either the front - * or back sides. - * \since 5.7 - * \ingroup renderstates - */ - #include "qstenciloperation.h" #include "qstenciloperation_p.h" #include "qstenciloperationarguments.h" @@ -55,8 +47,58 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * The constructor creates a new QStencilOperation::QStencilOperation instance with - * the specified \a parent. + \class Qt3DRender::QStencilOperation + \brief The QStencilOperation class specifies stencil operation + \since 5.7 + \ingroup renderstates + \inmodule Qt3DRender + + A Qt3DRender::QStencilOperation class specifies the stencil operations + for the front- and back-facing polygons. The stencil operation control + what is done to fragment when the stencil and depth test pass or fail. + + \sa Qt3DRender::QStencilTest + */ + +/*! + \qmltype StencilOperation + \brief The StencilOperation type specifies stencil operation + \since 5.7 + \ingroup renderstates + \inqmlmodule Qt3D.Render + \inherits RenderState + \instantiates Qt3DRender::QStencilOperation + + A StencilOperation type specifies the stencil operations + for the front- and back-facing polygons. The stencil operation control + what is done to fragment when the stencil and depth test pass or fail. + + \sa StencilTest + */ + +/*! + \qmlproperty StencilOperationArguments StencilOperation::front + Holds the stencil operation arguments for front-facing polygons. +*/ + +/*! + \qmlproperty StencilOperationArguments StencilOperation::back + Holds the stencil operation arguments for back-facing polygons. +*/ + +/*! + \property QStencilOperation::front + Holds the stencil operation arguments for front-facing polygons. +*/ + +/*! + \property QStencilOperation::back + Holds the stencil operation arguments for back-facing polygons. +*/ + +/*! + The constructor creates a new QStencilOperation::QStencilOperation instance with + the specified \a parent. */ QStencilOperation::QStencilOperation(QNode *parent) : QRenderState(*new QStencilOperationPrivate(), parent) @@ -68,18 +110,12 @@ QStencilOperation::~QStencilOperation() { } -/*! - * \return the front fragments. - */ QStencilOperationArguments *QStencilOperation::front() const { Q_D(const QStencilOperation); return d->m_front; } -/*! - * \return the back fragments. - */ QStencilOperationArguments *QStencilOperation::back() const { Q_D(const QStencilOperation); diff --git a/src/render/renderstates/qstenciloperationarguments.cpp b/src/render/renderstates/qstenciloperationarguments.cpp index a7b1192be..f5d0c1f4f 100644 --- a/src/render/renderstates/qstenciloperationarguments.cpp +++ b/src/render/renderstates/qstenciloperationarguments.cpp @@ -37,15 +37,6 @@ ** ****************************************************************************/ -/*! - * \class QStencilOperationArguments - * \brief The QStencilOperationArguments class sets the actions to be taken - * when stencil and depth tests fail. - * \since 5.7 - * \ingroup renderstates - * - */ - #include "qstenciloperationarguments.h" #include "qstenciloperationarguments_p.h" @@ -54,8 +45,123 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * The constructor creates a new QStencilOperationArguments::QStencilOperationArguments - * instance with the specified \a mode and \a parent. + \class Qt3DRender::QStencilOperationArguments + \brief The QStencilOperationArguments class sets the actions to be taken + when stencil and depth tests fail. + \since 5.7 + \ingroup renderstates + \inmodule Qt3DRender + + The Qt3DRender::QStencilOperationArguments class specifies the arguments for + the stencil operations. + + \sa Qt3DRender::QStencilOperation + */ + +/*! + \qmltype StencilOperationArguments + \brief The StencilOperationArguments type sets the actions to be taken + when stencil and depth tests fail. + \since 5.7 + \ingroup renderstates + \inqmlmodule Qt3D.Render + \instantiates Qt3DRender::QStencilOperationArguments + \inherits QtObject + + The StencilOperationArguments type specifies the arguments for the stencil operations. + + \sa StencilOperation + */ + +/*! + \enum Qt3DRender::QStencilOperationArguments::FaceMode + This enumeration holds the values for stencil operation argument face modes + \value Front Arguments are applied to front-facing polygons. + \value Back Arguments are applied to back-facing polygons. + \value FrontAndBack Arguments are applied to both front- and back-facing polygons. +*/ + +/*! + \enum Qt3DRender::QStencilOperationArguments::Operation + This enumeration holds the values for stencil operation. + \value Zero Set stencil value to zero. + \value Keep Keep current stencil value. + \value Replace Replace with the masked fragment stencil value. + \value Increment Increment current value with saturation. + \value Decrement Decrement current value with saturation. + \value IncrementWrap Increment current value with wrap. + \value DecrementWrap Decrement current value with wrap. + \value Invert Invert the current value. +*/ + +/*! + \qmlproperty enumeration StencilOperationArguments::faceMode + Holds the faces the arguments are applied to. + \list + \li StencilOperationArguments.Front + \li StencilOperationArguments.Back + \li StencilOperationArguments.FrontAndBack + \endlist + \sa Qt3DRender::QStencilOperationArguments::FaceMode + \readonly +*/ + +/*! + \qmlproperty enumeration StencilOperationArguments::stencilTestFailureOperation + Holds the stencil test operation for when the stencil test fails. + Default is StencilOperationArguments.Keep. + \list + \li StencilOperationArguments.Zero + \li StencilOperationArguments.Keep + \li StencilOperationArguments.Replace + \li StencilOperationArguments.Increment + \li StencilOperationArguments.Decrement + \li StencilOperationArguments.IncrementWrap + \li StencilOperationArguments.DecrementWrap + \li StencilOperationArguments.Inverter + \endlist + \sa Qt3DRender::QStencilOperationArguments::Operation +*/ + +/*! + \qmlproperty enumeration StencilOperationArguments::depthTestFailureOperation + Holds the stencil test operation for when the stencil test passes, but + depth test fails. Default is StencilOperationArguments.Keep. + \sa StencilOperationArguments::stencilTestFailureOperation, Qt3DRender::QStencilOperationArguments::Operation +*/ + +/*! + \qmlproperty enumeration StencilOperationArguments::allTestsPassOperation + Holds the stencil test operation for when depth and stencil test pass. Default is StencilOperationArguments.Keep. + \sa StencilOperationArguments::stencilTestFailureOperation, Qt3DRender::QStencilOperationArguments::Operation +*/ + +/*! + \property QStencilOperationArguments::faceMode + Holds the faces the arguments are applied to. + \readonly +*/ + +/*! + \property QStencilOperationArguments::stencilTestFailureOperation + Holds the stencil test operation for when the stencil test fails. + Default is StencilOperationArguments.Keep. +*/ + +/*! + \property QStencilOperationArguments::depthTestFailureOperation + Holds the stencil test operation for when the stencil test passes, but + depth test fails. Default is StencilOperationArguments.Keep. +*/ + +/*! + \property QStencilOperationArguments::allTestsPassOperation + Holds the stencil test operation for when depth and stencil test pass. Default is StencilOperationArguments.Keep. +*/ + +/*! + The constructor creates a new QStencilOperationArguments::QStencilOperationArguments + instance with the specified \a mode and \a parent. */ QStencilOperationArguments::QStencilOperationArguments(FaceMode mode, QObject *parent) : QObject(*new QStencilOperationArgumentsPrivate(mode), parent) @@ -67,19 +173,12 @@ QStencilOperationArguments::~QStencilOperationArguments() { } -/*! - * \return the current face mode. - */ QStencilOperationArguments::FaceMode QStencilOperationArguments::faceMode() const { Q_D(const QStencilOperationArguments); return d->m_face; } -/*! - * Sets the stencil action when a test fails, to operation. - * \param operation - */ void QStencilOperationArguments::setStencilTestFailureOperation(QStencilOperationArguments::Operation operation) { Q_D(QStencilOperationArguments); @@ -89,19 +188,12 @@ void QStencilOperationArguments::setStencilTestFailureOperation(QStencilOperatio } } -/*! - * \return the current stencil test failure operation. - */ QStencilOperationArguments::Operation QStencilOperationArguments::stencilTestFailureOperation() const { Q_D(const QStencilOperationArguments); return d->m_stencilTestFailureOperation; } -/*! - * Sets the action when the depth test fails, to operation. - * \param operation - */ void QStencilOperationArguments::setDepthTestFailureOperation(QStencilOperationArguments::Operation operation) { Q_D(QStencilOperationArguments); @@ -111,19 +203,12 @@ void QStencilOperationArguments::setDepthTestFailureOperation(QStencilOperationA } } -/*! - * \return the current depth test failure operation. - */ QStencilOperationArguments::Operation QStencilOperationArguments::depthTestFailureOperation() const { Q_D(const QStencilOperationArguments); return d->m_depthTestFailureOperation; } -/*! - * Sets the action when both the depth and stencil tests fail, to operation. - * \param operation - */ void QStencilOperationArguments::setAllTestsPassOperation(QStencilOperationArguments::Operation operation) { Q_D(QStencilOperationArguments); @@ -133,9 +218,6 @@ void QStencilOperationArguments::setAllTestsPassOperation(QStencilOperationArgum } } -/*! - * \return the current failure operation for when both tests fail. - */ QStencilOperationArguments::Operation QStencilOperationArguments::allTestsPassOperation() const { Q_D(const QStencilOperationArguments); diff --git a/src/render/renderstates/qstenciltest.cpp b/src/render/renderstates/qstenciltest.cpp index 7cbff2769..f1e42f1e3 100644 --- a/src/render/renderstates/qstenciltest.cpp +++ b/src/render/renderstates/qstenciltest.cpp @@ -48,16 +48,60 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * \class Qt3DRender::QStencilTest - * \brief The QStencilTest class - * \inmodule Qt3DRender - * \ingroup renderstates - * \since 5.7 + \class Qt3DRender::QStencilTest + \since 5.7 + \ingroup renderstates + \inmodule Qt3DRender + \brief The QStencilTest class specifies arguments for the stecil test + + A Qt3DRender::QStencilTest class specifies argument for the stencil test. + The stencil test comprises of three arguments: stencil test function, + stencil test mask and stencil reference value. QStencilTest allows these + arguments to be set for both front- and back-facing polygons separately. + + \sa Qt3DRender::QStencilMask, Qt3DRender::QStencilOperation */ /*! - * The constructor creates a new QStencilTest::QStencilTest instance with - * the specified \a parent. + \qmltype StencilTest + \since 5.7 + \ingroup renderstates + \inqmlmodule Qt3D.Render + \brief The StencilTest type specifies arguments for the stecil test + \inherits RenderState + \instantiates Qt3DRender::QStencilTest + + A StencilTest type specifies argument for the stencil test. + The stencil test comprises of three arguments: stencil test function, + stencil test mask and stencil reference value. StencilTest allows these + arguments to be set for both front- and back-facing polygons separately. + + \sa StencilMask, StencilOperation + */ + +/*! + \qmlproperty StencilTestArguments StencilTest::front + Holds the stencil test arguments for front-facing polygons. +*/ + +/*! + \qmlproperty StencilTestArguments StencilTest::back + Holds the stencil test arguments for back-facing polygons. +*/ + +/*! + \property QStencilTest::front + Holds the stencil test arguments for front-facing polygons. +*/ + +/*! + \property QStencilTest::back + Holds the stencil test arguments for back-facing polygons. +*/ + +/*! + The constructor creates a new QStencilTest::QStencilTest instance with + the specified \a parent. */ QStencilTest::QStencilTest(QNode *parent) : QRenderState(*new QStencilTestPrivate, parent) @@ -69,18 +113,12 @@ QStencilTest::~QStencilTest() { } -/*! - * \return the stencil test for the front - */ QStencilTestArguments *QStencilTest::front() const { Q_D(const QStencilTest); return d->m_front; } -/*! - * \return the stencil test for the back - */ QStencilTestArguments *QStencilTest::back() const { Q_D(const QStencilTest); diff --git a/src/render/renderstates/qstenciltestarguments.cpp b/src/render/renderstates/qstenciltestarguments.cpp index 1e618e372..ae1fd1111 100644 --- a/src/render/renderstates/qstenciltestarguments.cpp +++ b/src/render/renderstates/qstenciltestarguments.cpp @@ -45,15 +45,113 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { /*! - * \class QStencilTestArguments - * \brief The QStencilTestArguments class - * \since 5.7 - * \ingroup renderstates + \class Qt3DRender::QStencilTestArguments + \brief The QStencilTestArguments class specifies arguments for stencil test + \since 5.7 + \ingroup renderstates + \inmodule Qt3DRender + + The Qt3DRender::QStencilTestArguments class specifies the arguments for + the stencil test. + */ + +/*! + \qmltype StencilTestArguments + \brief The StencilTestArguments type specifies arguments for stencil test + \since 5.7 + \ingroup renderstates + \inqmlmodule Qt3D.Render + \instantiates Qt3DRender::QStencilTestArguments + \inherits QtObject + + The StencilTestArguments type specifies the arguments for + the stencil test. */ /*! - * The constructor creates a new QStencilTestArguments::QStencilTestArguments - * instance with the specified \a face and \a parent. + \enum Qt3DRender::QStencilTestArguments::StencilFaceMode + This enumeration holds the values for stencil test arguments face modes + \value Front Arguments are applied to front-facing polygons. + \value Back Arguments are applied to back-facing polygons. + \value FrontAndBack Arguments are applied to both front- and back-facing polygons. +*/ + +/*! + \enum Qt3DRender::QStencilTestArguments::StencilFunction + + Enumeration for the stencil function values + \value Never Never pass stencil test + \value Always Always pass stencil test + \value Less Pass stencil test if fragment stencil is less than reference value + \value LessOrEqual Pass stencil test if fragment stencil is less than or equal to reference value + \value Equal Pass stencil test if fragment stencil is equal to reference value + \value GreaterOrEqual Pass stencil test if fragment stencil is greater than or equal to reference value + \value Greater Pass stencil test if fragment stencil is greater than reference value + \value NotEqual Pass stencil test if fragment stencil is not equal to reference value +*/ + +/*! + \qmlproperty enumeration StencilTestArguments::faceMode + Holds the faces the arguments are applied to. + \list + \li StencilTestArguments.Front + \li StencilTestArguments.Back + \li StencilTestArguments.FrontAndBack + \endlist + \sa Qt3DRender::QStencilTestArguments::StencilFaceMode + \readonly +*/ + +/*! + \qmlproperty int StencilTestArguments::comparisonMask + Holds the stencil test comparison mask. Default is all zeroes. +*/ + +/*! + \qmlproperty int StencilTestArguments::referenceValue + Holds the stencil test reference value. Default is zero. +*/ + +/*! + \qmlproperty enumeration StencilTestArguments::stencilFunction + Holds the stencil test function. Default is StencilTestArguments.Never. + \list + \li StencilTestArguments.Never + \li StencilTestArguments.Always + \li StencilTestArguments.Less + \li StencilTestArguments.LessOrEqual + \li StencilTestArguments.Equal + \li StencilTestArguments.GreaterOrEqual + \li StencilTestArguments.Greater + \li StencilTestArguments.NotEqual + \endlist +*/ + +/*! + \property QStencilTestArguments::faceMode + Holds the faces the arguments are applied to. + \readonly +*/ + +/*! + \property QStencilTestArguments::comparisonMask + Holds the stencil test comparison mask. Default is all zeroes. +*/ + +/*! + \property QStencilTestArguments::referenceValue + Holds the stencil test reference value. Default is zero. +*/ + +/*! + \property QStencilTestArguments::stencilFunction + Holds the stencil test function. Default is Never. + \sa Qt3DRender::QStencilTestArguments::StencilFunction +*/ + +/*! + The constructor creates a new QStencilTestArguments::QStencilTestArguments + instance with the specified \a face and \a parent. */ QStencilTestArguments::QStencilTestArguments(QStencilTestArguments::StencilFaceMode face, QObject *parent) : QObject(*new QStencilTestArgumentsPrivate(face), parent) @@ -65,19 +163,12 @@ QStencilTestArguments::~QStencilTestArguments() { } -/*! - * \return the current comparison mask. - */ uint QStencilTestArguments::comparisonMask() const { Q_D(const QStencilTestArguments); return d->m_comparisonMask; } -/*! - * Sets the comparison mask. - * \param comparisonMask - */ void QStencilTestArguments::setComparisonMask(uint comparisonMask) { Q_D(QStencilTestArguments); @@ -87,19 +178,12 @@ void QStencilTestArguments::setComparisonMask(uint comparisonMask) } } -/*! - * \return the current reference value. - */ int QStencilTestArguments::referenceValue() const { Q_D(const QStencilTestArguments); return d->m_referenceValue; } -/*! - * Sets the reference value. - * \param referenceValue - */ void QStencilTestArguments::setReferenceValue(int referenceValue) { Q_D(QStencilTestArguments); @@ -109,19 +193,12 @@ void QStencilTestArguments::setReferenceValue(int referenceValue) } } -/*! - * \return the current stencil function. - */ QStencilTestArguments::StencilFunction QStencilTestArguments::stencilFunction() const { Q_D(const QStencilTestArguments); return d->m_stencilFunction; } -/*! - * Sets the stencil function. - * \param stencilFunction - */ void QStencilTestArguments::setStencilFunction(QStencilTestArguments::StencilFunction stencilFunction) { Q_D(QStencilTestArguments); @@ -131,9 +208,6 @@ void QStencilTestArguments::setStencilFunction(QStencilTestArguments::StencilFun } } -/*! - * \return the current face mode. - */ QStencilTestArguments::StencilFaceMode QStencilTestArguments::faceMode() const { Q_D(const QStencilTestArguments); diff --git a/src/render/renderstates/statevariant_p.h b/src/render/renderstates/statevariant_p.h index f2a631d2e..e13599e75 100644 --- a/src/render/renderstates/statevariant_p.h +++ b/src/render/renderstates/statevariant_p.h @@ -87,17 +87,17 @@ struct StateVariant u_Data() { // Assumes the above types don't need to have their ctor called - memset(this, 0, sizeof(u_Data)); + memset(static_cast<void *>(this), 0, sizeof(u_Data)); } u_Data(const u_Data &other) { - memcpy(this, &other, sizeof(u_Data)); + memcpy(static_cast<void *>(this), static_cast<const void *>(&other), sizeof(u_Data)); } u_Data& operator=(const u_Data &other) { - memcpy(this, &other, sizeof(u_Data)); + memcpy(static_cast<void *>(this), static_cast<const void *>(&other), sizeof(u_Data)); return *this; } @@ -121,7 +121,7 @@ struct StateVariant #if !defined(_MSC_VER) || (_MSC_VER > 1800) // all union members start at the same memory address // so we can just write into whichever we want - memcpy(&(v.data), &state, sizeof(state)); + memcpy(static_cast<void *>(&v.data), static_cast<const void *>(&state), sizeof(state)); #else v.m_impl.reset(new GenericState(state)); #endif diff --git a/sync.profile b/sync.profile index 3c23a8b8d..ec14bbc37 100644 --- a/sync.profile +++ b/sync.profile @@ -14,16 +14,3 @@ # Force generation of camel case headers for classes inside Qt3D* namespaces $publicclassregexp = "Qt3D.*::.+"; - -# Module dependencies. -# Every module that is required to build this module should have one entry. -# Each of the module version specifiers can take one of the following values: -# - A specific Git revision. -# - any git symbolic ref resolvable from the module's repository (e.g. "refs/heads/master" to track master branch) -# -%dependencies = ( - "qtbase" => "", - "qtxmlpatterns" => "", - "qtdeclarative" => "", - "qtimageformats" => "", -); diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/data/createMultiple.qml b/tests/auto/quick3d/quick3dnodeinstantiator/data/createMultiple.qml index 67c1e4fe7..c1f3b21ed 100644 --- a/tests/auto/quick3d/quick3dnodeinstantiator/data/createMultiple.qml +++ b/tests/auto/quick3d/quick3dnodeinstantiator/data/createMultiple.qml @@ -1,10 +1,12 @@ import QtQml 2.1 import Qt3D.Core 2.0 -NodeInstantiator { - model: 10 - delegate: Entity { - property bool success: true - property int idx: index +Entity { + NodeInstantiator { + model: 10 + delegate: Entity { + property bool success: true + property int idx: index + } } } diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/data/createNone.qml b/tests/auto/quick3d/quick3dnodeinstantiator/data/createNone.qml index 736a02b45..eef31cb8c 100644 --- a/tests/auto/quick3d/quick3dnodeinstantiator/data/createNone.qml +++ b/tests/auto/quick3d/quick3dnodeinstantiator/data/createNone.qml @@ -1,13 +1,15 @@ import QtQml 2.1 import Qt3D.Core 2.0 -NodeInstantiator { - model: 0 - property bool success: true - Entity { +Entity { + NodeInstantiator { + model: 0 property bool success: true - property int idx: index + Entity { + property bool success: true + property int idx: index + } + onObjectChanged: success = false;//Don't create intermediate objects + onCountChanged: success = false;//Don't create intermediate objects } - onObjectChanged: success = false;//Don't create intermediate objects - onCountChanged: success = false;//Don't create intermediate objects } diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/data/createSingle.qml b/tests/auto/quick3d/quick3dnodeinstantiator/data/createSingle.qml index 630da9940..5a79d6105 100644 --- a/tests/auto/quick3d/quick3dnodeinstantiator/data/createSingle.qml +++ b/tests/auto/quick3d/quick3dnodeinstantiator/data/createSingle.qml @@ -1,9 +1,11 @@ import QtQml 2.1 import Qt3D.Core 2.0 -NodeInstantiator { - Entity { - property bool success: true - property int idx: index +Entity { + NodeInstantiator { + Entity { + property bool success: true + property int idx: index + } } } diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/data/inactive.qml b/tests/auto/quick3d/quick3dnodeinstantiator/data/inactive.qml index 178229059..8ae6994db 100644 --- a/tests/auto/quick3d/quick3dnodeinstantiator/data/inactive.qml +++ b/tests/auto/quick3d/quick3dnodeinstantiator/data/inactive.qml @@ -1,10 +1,12 @@ import QtQml 2.1 import Qt3D.Core 2.0 -NodeInstantiator { - active: false - Entity { - property bool success: true - property int idx: index +Entity { + NodeInstantiator { + active: false + Entity { + property bool success: true + property int idx: index + } } } diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/data/stringModel.qml b/tests/auto/quick3d/quick3dnodeinstantiator/data/stringModel.qml index 431c1ebd8..5aa4d399a 100644 --- a/tests/auto/quick3d/quick3dnodeinstantiator/data/stringModel.qml +++ b/tests/auto/quick3d/quick3dnodeinstantiator/data/stringModel.qml @@ -1,10 +1,12 @@ import QtQml 2.1 import Qt3D.Core 2.0 -NodeInstantiator { - model: ["alpha", "beta", "gamma", "delta"] - delegate: Entity { - property bool success: index == 1 ? datum.length == 4 : datum.length == 5 - property string datum: modelData +Entity { + NodeInstantiator { + model: ["alpha", "beta", "gamma", "delta"] + delegate: Entity { + property bool success: index == 1 ? datum.length == 4 : datum.length == 5 + property string datum: modelData + } } } diff --git a/tests/auto/quick3d/quick3dnodeinstantiator/tst_quick3dnodeinstantiator.cpp b/tests/auto/quick3d/quick3dnodeinstantiator/tst_quick3dnodeinstantiator.cpp index fd7f0eb0c..acaba6690 100644 --- a/tests/auto/quick3d/quick3dnodeinstantiator/tst_quick3dnodeinstantiator.cpp +++ b/tests/auto/quick3d/quick3dnodeinstantiator/tst_quick3dnodeinstantiator.cpp @@ -60,7 +60,9 @@ void tst_quick3dnodeinstantiator::createNone() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("createNone.qml")); - Quick3DNodeInstantiator *instantiator = qobject_cast<Quick3DNodeInstantiator*>(component.create()); + const auto root = qobject_cast<Qt3DCore::QNode*>(component.create()); + QVERIFY(root != 0); + const auto instantiator = root->findChild<Quick3DNodeInstantiator*>(); QVERIFY(instantiator != 0); QCOMPARE(instantiator->isActive(), true); QCOMPARE(instantiator->count(), 0); @@ -72,7 +74,9 @@ void tst_quick3dnodeinstantiator::createSingle() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("createSingle.qml")); - Quick3DNodeInstantiator *instantiator = qobject_cast<Quick3DNodeInstantiator*>(component.create()); + const auto root = qobject_cast<Qt3DCore::QNode*>(component.create()); + QVERIFY(root != 0); + const auto instantiator = root->findChild<Quick3DNodeInstantiator*>(); QVERIFY(instantiator != 0); QCOMPARE(instantiator->isActive(), true); QCOMPARE(instantiator->count(), 1); @@ -80,7 +84,7 @@ void tst_quick3dnodeinstantiator::createSingle() QObject *object = instantiator->object(); QVERIFY(object); - QCOMPARE(object->parent(), instantiator); + QCOMPARE(object->parent(), root); QCOMPARE(object->property("success").toBool(), true); QCOMPARE(object->property("idx").toInt(), 0); } @@ -89,7 +93,9 @@ void tst_quick3dnodeinstantiator::createMultiple() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("createMultiple.qml")); - Quick3DNodeInstantiator *instantiator = qobject_cast<Quick3DNodeInstantiator*>(component.create()); + const auto root = qobject_cast<Qt3DCore::QNode*>(component.create()); + QVERIFY(root != 0); + const auto instantiator = root->findChild<Quick3DNodeInstantiator*>(); QVERIFY(instantiator != 0); QCOMPARE(instantiator->isActive(), true); QCOMPARE(instantiator->count(), 10); @@ -97,7 +103,7 @@ void tst_quick3dnodeinstantiator::createMultiple() for (int i = 0; i < 10; i++) { QObject *object = instantiator->objectAt(i); QVERIFY(object); - QCOMPARE(object->parent(), instantiator); + QCOMPARE(object->parent(), root); QCOMPARE(object->property("success").toBool(), true); QCOMPARE(object->property("idx").toInt(), i); } @@ -107,7 +113,9 @@ void tst_quick3dnodeinstantiator::stringModel() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("stringModel.qml")); - Quick3DNodeInstantiator *instantiator = qobject_cast<Quick3DNodeInstantiator*>(component.create()); + const auto root = qobject_cast<Qt3DCore::QNode*>(component.create()); + QVERIFY(root != 0); + const auto instantiator = root->findChild<Quick3DNodeInstantiator*>(); QVERIFY(instantiator != 0); QCOMPARE(instantiator->isActive(), true); QCOMPARE(instantiator->count(), 4); @@ -115,7 +123,7 @@ void tst_quick3dnodeinstantiator::stringModel() for (int i = 0; i < 4; i++) { QObject *object = instantiator->objectAt(i); QVERIFY(object); - QCOMPARE(object->parent(), instantiator); + QCOMPARE(object->parent(), root); QCOMPARE(object->property("success").toBool(), true); } } @@ -124,7 +132,9 @@ void tst_quick3dnodeinstantiator::activeProperty() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("inactive.qml")); - Quick3DNodeInstantiator *instantiator = qobject_cast<Quick3DNodeInstantiator*>(component.create()); + const auto root = qobject_cast<Qt3DCore::QNode*>(component.create()); + QVERIFY(root != 0); + const auto instantiator = root->findChild<Quick3DNodeInstantiator*>(); QVERIFY(instantiator != 0); QSignalSpy activeSpy(instantiator, SIGNAL(activeChanged())); QSignalSpy countSpy(instantiator, SIGNAL(countChanged())); @@ -150,7 +160,7 @@ void tst_quick3dnodeinstantiator::activeProperty() QObject *object = instantiator->object(); QVERIFY(object); - QCOMPARE(object->parent(), instantiator); + QCOMPARE(object->parent(), root); QCOMPARE(object->property("success").toBool(), true); QCOMPARE(object->property("idx").toInt(), 0); } @@ -159,7 +169,9 @@ void tst_quick3dnodeinstantiator::intModelChange() { QQmlEngine engine; QQmlComponent component(&engine, testFileUrl("createMultiple.qml")); - Quick3DNodeInstantiator *instantiator = qobject_cast<Quick3DNodeInstantiator*>(component.create()); + const auto root = qobject_cast<Qt3DCore::QNode*>(component.create()); + QVERIFY(root != 0); + const auto instantiator = root->findChild<Quick3DNodeInstantiator*>(); QVERIFY(instantiator != 0); QSignalSpy activeSpy(instantiator, SIGNAL(activeChanged())); QSignalSpy countSpy(instantiator, SIGNAL(countChanged())); @@ -183,7 +195,7 @@ void tst_quick3dnodeinstantiator::intModelChange() for (int i = 0; i < 2; i++) { QObject *object = instantiator->objectAt(i); QVERIFY(object); - QCOMPARE(object->parent(), instantiator); + QCOMPARE(object->parent(), root); QCOMPARE(object->property("success").toBool(), true); QCOMPARE(object->property("idx").toInt(), i); } diff --git a/tests/manual/deferred-renderer-cpp/doc/src/deferred-renderer-cpp.qdoc b/tests/manual/deferred-renderer-cpp/doc/src/deferred-renderer-cpp.qdoc index 65311e77f..610270316 100644 --- a/tests/manual/deferred-renderer-cpp/doc/src/deferred-renderer-cpp.qdoc +++ b/tests/manual/deferred-renderer-cpp/doc/src/deferred-renderer-cpp.qdoc @@ -29,4 +29,25 @@ \example deferred-renderer-cpp \title Qt 3D: Deferred Renderer C++ Example \ingroup qt3d-examples-cpp + \brief A C++ application that demonstrates rendering to an intermediate + G-buffer. + + \e {Deferred Renderer} demonstrates using a two pass rendering method. + First, all the meshes in the scene are drawn using the same shader that will + output the following values for each fragment: world normal vector, color, + depth, and world position vector. + + Each of these values will be stored in a texture, which together form what + is called the G-buffer. Nothing is drawn onscreen during the first pass, but + rather drawn into the G-buffer ready for later use. + + Once all the meshes have been drawn, the G-buffer is filled with all the + meshes that can currently be seen by the camera. The second render pass is + then used to render the scene to the back buffer with the final color + shading by reading the values from the G-buffer textures and outputting a + color onto a full screen quad. + + For more information, see \l{Deferred Renderer}. + + \include examples-run.qdocinc */ diff --git a/tools/qgltf/qgltf.pro b/tools/qgltf/qgltf.pro index a19f2e91c..df6dfa202 100644 --- a/tools/qgltf/qgltf.pro +++ b/tools/qgltf/qgltf.pro @@ -1,5 +1,4 @@ option(host_build) -!cross_compile:load(qt_build_paths) # Qt3D is free of Q_FOREACH - make sure it stays that way: DEFINES *= QT_NO_FOREACH |