diff options
184 files changed, 6467 insertions, 1356 deletions
diff --git a/.qmake.conf b/.qmake.conf index a2a0d4189..aefa1e701 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,3 +1,3 @@ load(qt_build_config) -MODULE_VERSION = 5.7.1 +MODULE_VERSION = 5.8.0 diff --git a/config.tests/assimp/assimp.pro b/config.tests/assimp/assimp.pro index 920c451c4..712986c17 100644 --- a/config.tests/assimp/assimp.pro +++ b/config.tests/assimp/assimp.pro @@ -1,6 +1,6 @@ SOURCES += main.cpp -unix:!contains(QT_CONFIG, no-pkg-config) { +unix:qtConfig(pkg-config) { CONFIG += link_pkgconfig PKGCONFIG += assimp } else { diff --git a/examples/qt3d/anaglyph-rendering/main.qml b/examples/qt3d/anaglyph-rendering/main.qml index 3510850a2..89e5c3664 100644 --- a/examples/qt3d/anaglyph-rendering/main.qml +++ b/examples/qt3d/anaglyph-rendering/main.qml @@ -86,7 +86,6 @@ Entity { // Skybox SkyboxEntity { - cameraPosition: stereoCamera.position baseName: "qrc:/assets/cubemaps/miramar/miramar" extension: ".webp" } diff --git a/examples/qt3d/compute-particles/ComputeFrameGraph.qml b/examples/qt3d/compute-particles/ComputeFrameGraph.qml index 9a84f246f..ffdeb7567 100644 --- a/examples/qt3d/compute-particles/ComputeFrameGraph.qml +++ b/examples/qt3d/compute-particles/ComputeFrameGraph.qml @@ -65,7 +65,7 @@ Viewport { // Compute Pass DispatchCompute { - workGroupX: 1024; workGroupY: 1; workGroupZ: 1 + workGroupX: 50; workGroupY: 1; workGroupZ: 1 TechniqueFilter { matchAll: [ FilterKey { name: "type"; value: "compute"} @@ -1,4 +1,4 @@ -requires(contains(QT_CONFIG, opengl)) +requires(qtConfig(opengl)) load(configure) qtCompileTest(assimp) diff --git a/src/3rdparty/assimp/assimp.pri b/src/3rdparty/assimp/assimp.pri index ad72816d8..d3282fb56 100644 --- a/src/3rdparty/assimp/assimp.pri +++ b/src/3rdparty/assimp/assimp.pri @@ -10,12 +10,10 @@ CONFIG -= precompile_header win32:DEFINES+=_CRT_SECURE_NO_WARNINGS -contains(QT_CONFIG, system-zlib):!if(cross_compile:host_build) { - if (unix|mingw): LIBS += -lz - else: LIBS += zdll.lib -} else { +qtConfig(system-zlib):!if(cross_compile:host_build): \ + QMAKE_USE_PRIVATE += zlib +else: \ QT_PRIVATE += zlib-private -} DEFINES += ASSIMP_BUILD_NO_OWN_ZLIB ASSIMP_BUILD_NO_COMPRESSED_IFC ASSIMP_BUILD_NO_Q3BSP_IMPORTER diff --git a/src/3rdparty/assimp/assimp_dependency.pri b/src/3rdparty/assimp/assimp_dependency.pri index 4fe0df54e..f1a109f10 100644 --- a/src/3rdparty/assimp/assimp_dependency.pri +++ b/src/3rdparty/assimp/assimp_dependency.pri @@ -1,5 +1,5 @@ config_assimp:!if(cross_compile:host_build) { - unix:!contains(QT_CONFIG, no-pkg-config) { + unix:qtConfig(pkg-config) { CONFIG += link_pkgconfig PKGCONFIG_PRIVATE += assimp } else { diff --git a/src/core/core.pro b/src/core/core.pro index 02cd8cc80..d7205f08a 100644 --- a/src/core/core.pro +++ b/src/core/core.pro @@ -24,6 +24,4 @@ include(transforms/transforms.pri) include(resources/resources.pri) include(services/services.pri) -!contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL - load(qt_module) diff --git a/src/core/jobs/qaspectjob_p.h b/src/core/jobs/qaspectjob_p.h index 1069ba0b9..c54240a4e 100644 --- a/src/core/jobs/qaspectjob_p.h +++ b/src/core/jobs/qaspectjob_p.h @@ -126,7 +126,10 @@ public: #else -#define SET_JOB_RUN_STAT_TYPE(job, type, instance) +#define SET_JOB_RUN_STAT_TYPE(job, type, instance) \ + Q_UNUSED(job) \ + Q_UNUSED(type) \ + Q_UNUSED(instance) #endif diff --git a/src/extras/defaults/qfirstpersoncameracontroller.cpp b/src/extras/defaults/qfirstpersoncameracontroller.cpp index 973566a3c..19446d3ba 100644 --- a/src/extras/defaults/qfirstpersoncameracontroller.cpp +++ b/src/extras/defaults/qfirstpersoncameracontroller.cpp @@ -173,6 +173,10 @@ void QFirstPersonCameraControllerPrivate::init() QObject::connect(m_frameAction, SIGNAL(triggered(float)), q, SLOT(_q_onTriggered(float))); + // Disable the logical device when the entity is disabled + QObject::connect(q, &Qt3DCore::QEntity::enabledChanged, + m_logicalDevice, &Qt3DInput::QLogicalDevice::setEnabled); + q->addComponent(m_frameAction); q->addComponent(m_logicalDevice); } diff --git a/src/extras/defaults/qforwardrenderer.cpp b/src/extras/defaults/qforwardrenderer.cpp index 32c4a2968..d556b58d3 100644 --- a/src/extras/defaults/qforwardrenderer.cpp +++ b/src/extras/defaults/qforwardrenderer.cpp @@ -40,6 +40,7 @@ #include "qforwardrenderer.h" #include "qforwardrenderer_p.h" +#include <Qt3DCore/qentity.h> #include <Qt3DRender/qviewport.h> #include <Qt3DRender/qcameraselector.h> #include <Qt3DRender/qclearbuffers.h> @@ -128,10 +129,11 @@ QForwardRenderer::QForwardRenderer(QNode *parent) : QTechniqueFilter(*new QForwardRendererPrivate, parent) { Q_D(QForwardRenderer); - QObject::connect(d->m_clearBuffer, SIGNAL(clearColorChanged(const QColor &)), this, SIGNAL(clearColorChanged(const QColor &))); - QObject::connect(d->m_viewport, SIGNAL(normalizedRectChanged(const QRectF &)), this, SIGNAL(viewportRectChanged(const QRectF &))); - QObject::connect(d->m_cameraSelector, SIGNAL(cameraChanged(Qt3DCore::QEntity *)), this, SIGNAL(cameraChanged(Qt3DCore::QEntity *))); - QObject::connect(d->m_surfaceSelector, SIGNAL(surfaceChanged(QObject *)), this, SIGNAL(surfaceChanged(QObject *))); + QObject::connect(d->m_clearBuffer, &QClearBuffers::clearColorChanged, this, &QForwardRenderer::clearColorChanged); + QObject::connect(d->m_viewport, &QViewport::normalizedRectChanged, this, &QForwardRenderer::viewportRectChanged); + QObject::connect(d->m_cameraSelector, &QCameraSelector::cameraChanged, this, &QForwardRenderer::cameraChanged); + QObject::connect(d->m_surfaceSelector, &QRenderSurfaceSelector::surfaceChanged, this, &QForwardRenderer::surfaceChanged); + QObject::connect(d->m_surfaceSelector, &QRenderSurfaceSelector::externalRenderTargetSizeChanged, this, &QForwardRenderer::externalRenderTargetSizeChanged); d->init(); } @@ -163,6 +165,12 @@ void QForwardRenderer::setSurface(QObject *surface) d->m_surfaceSelector->setSurface(surface); } +void QForwardRenderer::setExternalRenderTargetSize(const QSize &size) +{ + Q_D(QForwardRenderer); + d->m_surfaceSelector->setExternalRenderTargetSize(size); +} + /*! \qmlproperty rect ForwardRenderer::viewportRect @@ -233,6 +241,12 @@ QObject *QForwardRenderer::surface() const return d->m_surfaceSelector->surface(); } +QSize QForwardRenderer::externalRenderTargetSize() const +{ + Q_D(const QForwardRenderer); + return d->m_surfaceSelector->externalRenderTargetSize(); +} + } // namespace Qt3DExtras QT_END_NAMESPACE diff --git a/src/extras/defaults/qforwardrenderer.h b/src/extras/defaults/qforwardrenderer.h index a744b3caf..01f50f452 100644 --- a/src/extras/defaults/qforwardrenderer.h +++ b/src/extras/defaults/qforwardrenderer.h @@ -60,6 +60,7 @@ class QT3DEXTRASSHARED_EXPORT QForwardRenderer : public Qt3DRender::QTechniqueFi Q_PROPERTY(QRectF viewportRect READ viewportRect WRITE setViewportRect NOTIFY viewportRectChanged) Q_PROPERTY(QColor clearColor READ clearColor WRITE setClearColor NOTIFY clearColorChanged) Q_PROPERTY(Qt3DCore::QEntity *camera READ camera WRITE setCamera NOTIFY cameraChanged) + Q_PROPERTY(QSize externalRenderTargetSize READ externalRenderTargetSize WRITE setExternalRenderTargetSize NOTIFY externalRenderTargetSizeChanged) public: explicit QForwardRenderer(Qt3DCore::QNode *parent = nullptr); ~QForwardRenderer(); @@ -68,18 +69,21 @@ public: QColor clearColor() const; Qt3DCore::QEntity *camera() const; QObject *surface() const; + QSize externalRenderTargetSize() const; public Q_SLOTS: void setViewportRect(const QRectF &viewportRect); void setClearColor(const QColor &clearColor); void setCamera(Qt3DCore::QEntity *camera); void setSurface(QObject * surface); + void setExternalRenderTargetSize(const QSize &size); Q_SIGNALS: void viewportRectChanged(const QRectF &viewportRect); void clearColorChanged(const QColor &clearColor); void cameraChanged(Qt3DCore::QEntity *camera); void surfaceChanged(QObject *surface); + void externalRenderTargetSizeChanged(const QSize &size); private: Q_DECLARE_PRIVATE(QForwardRenderer) diff --git a/src/extras/defaults/qorbitcameracontroller.cpp b/src/extras/defaults/qorbitcameracontroller.cpp index d8f468ed0..e340941a8 100644 --- a/src/extras/defaults/qorbitcameracontroller.cpp +++ b/src/extras/defaults/qorbitcameracontroller.cpp @@ -219,6 +219,10 @@ void QOrbitCameraControllerPrivate::init() QObject::connect(m_frameAction, SIGNAL(triggered(float)), q, SLOT(_q_onTriggered(float))); + // Disable the logical device when the entity is disabled + QObject::connect(q, &Qt3DCore::QEntity::enabledChanged, + m_logicalDevice, &Qt3DInput::QLogicalDevice::setEnabled); + q->addComponent(m_frameAction); q->addComponent(m_logicalDevice); } diff --git a/src/extras/defaults/qskyboxentity.cpp b/src/extras/defaults/qskyboxentity.cpp index 2e755f385..f4b26ae9e 100644 --- a/src/extras/defaults/qskyboxentity.cpp +++ b/src/extras/defaults/qskyboxentity.cpp @@ -40,7 +40,6 @@ #include "qskyboxentity.h" #include "qskyboxentity_p.h" -#include <Qt3DCore/qtransform.h> #include <Qt3DRender/qfilterkey.h> #include <Qt3DRender/qeffect.h> #include <Qt3DRender/qtexture.h> @@ -76,7 +75,6 @@ QSkyboxEntityPrivate::QSkyboxEntityPrivate() , m_es2RenderPass(new QRenderPass()) , m_gl3RenderPass(new QRenderPass()) , m_mesh(new QCuboidMesh()) - , m_transform(new Qt3DCore::QTransform()) , m_textureParameter(new QParameter(QStringLiteral("skyboxTexture"), m_skyboxTexture)) , m_posXImage(new QTextureImage()) , m_posYImage(new QTextureImage()) @@ -173,7 +171,6 @@ void QSkyboxEntityPrivate::init() q_func()->addComponent(m_mesh); q_func()->addComponent(m_material); - q_func()->addComponent(m_transform); } /*! @@ -266,28 +263,6 @@ QString QSkyboxEntity::extension() const return d->m_extension; } -/*! - * Sets the camera position to \a cameraPosition. - */ -void QSkyboxEntity::setCameraPosition(const QVector3D &cameraPosition) -{ - Q_D(QSkyboxEntity); - if (cameraPosition != d->m_position) { - d->m_position = cameraPosition; - d->m_transform->setTranslation(d->m_position); - emit cameraPositionChanged(cameraPosition); - } -} - -/*! - * Returns the camera position. - */ -QVector3D QSkyboxEntity::cameraPosition() const -{ - Q_D(const QSkyboxEntity); - return d->m_position; -} - } // namespace Qt3DExtras QT_END_NAMESPACE diff --git a/src/extras/defaults/qskyboxentity.h b/src/extras/defaults/qskyboxentity.h index 8cb279e1a..a11d2f0a0 100644 --- a/src/extras/defaults/qskyboxentity.h +++ b/src/extras/defaults/qskyboxentity.h @@ -62,13 +62,9 @@ public: void setExtension(const QString &extension); QString extension() const; - void setCameraPosition(const QVector3D &cameraPosition); - QVector3D cameraPosition() const; - Q_SIGNALS: void sourceDirectoryChanged(const QString &path); void extensionChanged(const QString &extension); - void cameraPositionChanged(const QVector3D &cameraPosition); private: Q_DECLARE_PRIVATE(QSkyboxEntity) diff --git a/src/extras/defaults/qskyboxentity_p.h b/src/extras/defaults/qskyboxentity_p.h index 565caa66d..effe97fce 100644 --- a/src/extras/defaults/qskyboxentity_p.h +++ b/src/extras/defaults/qskyboxentity_p.h @@ -56,10 +56,6 @@ QT_BEGIN_NAMESPACE -namespace Qt3DCore { -class QTransform; -} - namespace Qt3DRender { class QFilterKey; @@ -101,7 +97,6 @@ class QSkyboxEntityPrivate : public Qt3DCore::QEntityPrivate Qt3DRender::QRenderPass *m_es2RenderPass; Qt3DRender::QRenderPass *m_gl3RenderPass; QCuboidMesh *m_mesh; - Qt3DCore::QTransform *m_transform; Qt3DRender::QParameter *m_textureParameter; Qt3DRender::QTextureImage *m_posXImage; Qt3DRender:: QTextureImage *m_posYImage; diff --git a/src/extras/geometries/qconegeometry.cpp b/src/extras/geometries/qconegeometry.cpp index 6e6cceda3..9db7e2b46 100644 --- a/src/extras/geometries/qconegeometry.cpp +++ b/src/extras/geometries/qconegeometry.cpp @@ -373,16 +373,16 @@ void QConeGeometryPrivate::init() + m_slices * (m_hasTopEndcap + m_hasBottomEndcap); // endcaps m_positionAttribute->setName(QAttribute::defaultPositionAttributeName()); - m_positionAttribute->setDataType(QAttribute::Float); - m_positionAttribute->setDataSize(3); + m_positionAttribute->setVertexBaseType(QAttribute::Float); + m_positionAttribute->setVertexSize(3); m_positionAttribute->setAttributeType(QAttribute::VertexAttribute); m_positionAttribute->setBuffer(m_vertexBuffer); m_positionAttribute->setByteStride(stride); m_positionAttribute->setCount(nVerts); m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName()); - m_texCoordAttribute->setDataType(QAttribute::Float); - m_texCoordAttribute->setDataSize(2); + m_texCoordAttribute->setVertexBaseType(QAttribute::Float); + m_texCoordAttribute->setVertexSize(2); m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute); m_texCoordAttribute->setBuffer(m_vertexBuffer); m_texCoordAttribute->setByteStride(stride); @@ -390,8 +390,8 @@ void QConeGeometryPrivate::init() m_texCoordAttribute->setCount(nVerts); m_normalAttribute->setName(QAttribute::defaultNormalAttributeName()); - m_normalAttribute->setDataType(QAttribute::Float); - m_normalAttribute->setDataSize(3); + m_normalAttribute->setVertexBaseType(QAttribute::Float); + m_normalAttribute->setVertexSize(3); m_normalAttribute->setAttributeType(QAttribute::VertexAttribute); m_normalAttribute->setBuffer(m_vertexBuffer); m_normalAttribute->setByteStride(stride); @@ -399,7 +399,7 @@ void QConeGeometryPrivate::init() m_normalAttribute->setCount(nVerts); m_indexAttribute->setAttributeType(QAttribute::IndexAttribute); - m_indexAttribute->setDataType(QAttribute::UnsignedShort); + m_indexAttribute->setVertexBaseType(QAttribute::UnsignedShort); m_indexAttribute->setBuffer(m_indexBuffer); m_indexAttribute->setCount(faces * 3); diff --git a/src/extras/geometries/qcuboidgeometry.cpp b/src/extras/geometries/qcuboidgeometry.cpp index 4e644b24a..0f7b5220f 100644 --- a/src/extras/geometries/qcuboidgeometry.cpp +++ b/src/extras/geometries/qcuboidgeometry.cpp @@ -510,16 +510,16 @@ void QCuboidGeometryPrivate::init() const int indexCount = 2 * (yzIndices + xzIndices + xyIndices); m_positionAttribute->setName(QAttribute::defaultPositionAttributeName()); - m_positionAttribute->setDataType(QAttribute::Float); - m_positionAttribute->setDataSize(3); + m_positionAttribute->setVertexBaseType(QAttribute::Float); + m_positionAttribute->setVertexSize(3); m_positionAttribute->setAttributeType(QAttribute::VertexAttribute); m_positionAttribute->setBuffer(m_vertexBuffer); m_positionAttribute->setByteStride(stride); m_positionAttribute->setCount(nVerts); m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName()); - m_texCoordAttribute->setDataType(QAttribute::Float); - m_texCoordAttribute->setDataSize(2); + m_texCoordAttribute->setVertexBaseType(QAttribute::Float); + m_texCoordAttribute->setVertexSize(2); m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute); m_texCoordAttribute->setBuffer(m_vertexBuffer); m_texCoordAttribute->setByteStride(stride); @@ -527,8 +527,8 @@ void QCuboidGeometryPrivate::init() m_texCoordAttribute->setCount(nVerts); m_normalAttribute->setName(QAttribute::defaultNormalAttributeName()); - m_normalAttribute->setDataType(QAttribute::Float); - m_normalAttribute->setDataSize(3); + m_normalAttribute->setVertexBaseType(QAttribute::Float); + m_normalAttribute->setVertexSize(3); m_normalAttribute->setAttributeType(QAttribute::VertexAttribute); m_normalAttribute->setBuffer(m_vertexBuffer); m_normalAttribute->setByteStride(stride); @@ -536,8 +536,8 @@ void QCuboidGeometryPrivate::init() m_normalAttribute->setCount(nVerts); m_tangentAttribute->setName(QAttribute::defaultTangentAttributeName()); - m_tangentAttribute->setDataType(QAttribute::Float); - m_tangentAttribute->setDataSize(4); + m_tangentAttribute->setVertexBaseType(QAttribute::Float); + m_tangentAttribute->setVertexSize(4); m_tangentAttribute->setAttributeType(QAttribute::VertexAttribute); m_tangentAttribute->setBuffer(m_vertexBuffer); m_tangentAttribute->setByteStride(stride); @@ -545,7 +545,7 @@ void QCuboidGeometryPrivate::init() m_tangentAttribute->setCount(nVerts); m_indexAttribute->setAttributeType(QAttribute::IndexAttribute); - m_indexAttribute->setDataType(QAttribute::UnsignedShort); + m_indexAttribute->setVertexBaseType(QAttribute::UnsignedShort); m_indexAttribute->setBuffer(m_indexBuffer); m_indexAttribute->setCount(indexCount); diff --git a/src/extras/geometries/qcylindergeometry.cpp b/src/extras/geometries/qcylindergeometry.cpp index c80b45dfa..136258162 100644 --- a/src/extras/geometries/qcylindergeometry.cpp +++ b/src/extras/geometries/qcylindergeometry.cpp @@ -296,16 +296,16 @@ void QCylinderGeometryPrivate::init() const int faces = (m_slices * 2) * (m_rings - 1) + (m_slices * 2); m_positionAttribute->setName(QAttribute::defaultPositionAttributeName()); - m_positionAttribute->setDataType(QAttribute::Float); - m_positionAttribute->setDataSize(3); + m_positionAttribute->setVertexBaseType(QAttribute::Float); + m_positionAttribute->setVertexSize(3); m_positionAttribute->setAttributeType(QAttribute::VertexAttribute); m_positionAttribute->setBuffer(m_vertexBuffer); m_positionAttribute->setByteStride(stride); m_positionAttribute->setCount(nVerts); m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName()); - m_texCoordAttribute->setDataType(QAttribute::Float); - m_texCoordAttribute->setDataSize(2); + m_texCoordAttribute->setVertexBaseType(QAttribute::Float); + m_texCoordAttribute->setVertexSize(2); m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute); m_texCoordAttribute->setBuffer(m_vertexBuffer); m_texCoordAttribute->setByteStride(stride); @@ -313,8 +313,8 @@ void QCylinderGeometryPrivate::init() m_texCoordAttribute->setCount(nVerts); m_normalAttribute->setName(QAttribute::defaultNormalAttributeName()); - m_normalAttribute->setDataType(QAttribute::Float); - m_normalAttribute->setDataSize(3); + m_normalAttribute->setVertexBaseType(QAttribute::Float); + m_normalAttribute->setVertexSize(3); m_normalAttribute->setAttributeType(QAttribute::VertexAttribute); m_normalAttribute->setBuffer(m_vertexBuffer); m_normalAttribute->setByteStride(stride); @@ -322,7 +322,7 @@ void QCylinderGeometryPrivate::init() m_normalAttribute->setCount(nVerts); m_indexAttribute->setAttributeType(QAttribute::IndexAttribute); - m_indexAttribute->setDataType(QAttribute::UnsignedShort); + m_indexAttribute->setVertexBaseType(QAttribute::UnsignedShort); m_indexAttribute->setBuffer(m_indexBuffer); m_indexAttribute->setCount(faces * 3); diff --git a/src/extras/geometries/qplanegeometry.cpp b/src/extras/geometries/qplanegeometry.cpp index b7395b67e..74c90cf1b 100644 --- a/src/extras/geometries/qplanegeometry.cpp +++ b/src/extras/geometries/qplanegeometry.cpp @@ -481,16 +481,16 @@ void QPlaneGeometryPrivate::init() const int faces = 2 * (m_meshResolution.width() - 1) * (m_meshResolution.height() - 1); m_positionAttribute->setName(QAttribute::defaultPositionAttributeName()); - m_positionAttribute->setDataType(QAttribute::Float); - m_positionAttribute->setDataSize(3); + m_positionAttribute->setVertexBaseType(QAttribute::Float); + m_positionAttribute->setVertexSize(3); m_positionAttribute->setAttributeType(QAttribute::VertexAttribute); m_positionAttribute->setBuffer(m_vertexBuffer); m_positionAttribute->setByteStride(stride); m_positionAttribute->setCount(nVerts); m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName()); - m_texCoordAttribute->setDataType(QAttribute::Float); - m_texCoordAttribute->setDataSize(2); + m_texCoordAttribute->setVertexBaseType(QAttribute::Float); + m_texCoordAttribute->setVertexSize(2); m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute); m_texCoordAttribute->setBuffer(m_vertexBuffer); m_texCoordAttribute->setByteStride(stride); @@ -498,8 +498,8 @@ void QPlaneGeometryPrivate::init() m_texCoordAttribute->setCount(nVerts); m_normalAttribute->setName(QAttribute::defaultNormalAttributeName()); - m_normalAttribute->setDataType(QAttribute::Float); - m_normalAttribute->setDataSize(3); + m_normalAttribute->setVertexBaseType(QAttribute::Float); + m_normalAttribute->setVertexSize(3); m_normalAttribute->setAttributeType(QAttribute::VertexAttribute); m_normalAttribute->setBuffer(m_vertexBuffer); m_normalAttribute->setByteStride(stride); @@ -507,8 +507,8 @@ void QPlaneGeometryPrivate::init() m_normalAttribute->setCount(nVerts); m_tangentAttribute->setName(QAttribute::defaultTangentAttributeName()); - m_tangentAttribute->setDataType(QAttribute::Float); - m_tangentAttribute->setDataSize(4); + m_tangentAttribute->setVertexBaseType(QAttribute::Float); + m_tangentAttribute->setVertexSize(4); m_tangentAttribute->setAttributeType(QAttribute::VertexAttribute); m_tangentAttribute->setBuffer(m_vertexBuffer); m_tangentAttribute->setByteStride(stride); @@ -516,7 +516,7 @@ void QPlaneGeometryPrivate::init() m_tangentAttribute->setCount(nVerts); m_indexAttribute->setAttributeType(QAttribute::IndexAttribute); - m_indexAttribute->setDataType(QAttribute::UnsignedShort); + m_indexAttribute->setVertexBaseType(QAttribute::UnsignedShort); m_indexAttribute->setBuffer(m_indexBuffer); // Each primitive has 3 vertives diff --git a/src/extras/geometries/qspheregeometry.cpp b/src/extras/geometries/qspheregeometry.cpp index 5d64d0f35..277d4fcb9 100644 --- a/src/extras/geometries/qspheregeometry.cpp +++ b/src/extras/geometries/qspheregeometry.cpp @@ -262,16 +262,16 @@ void QSphereGeometryPrivate::init() const int faces = (m_slices * 2) * (m_rings - 2) + (2 * m_slices); m_positionAttribute->setName(QAttribute::defaultPositionAttributeName()); - m_positionAttribute->setDataType(QAttribute::Float); - m_positionAttribute->setDataSize(3); + m_positionAttribute->setVertexBaseType(QAttribute::Float); + m_positionAttribute->setVertexSize(3); m_positionAttribute->setAttributeType(QAttribute::VertexAttribute); m_positionAttribute->setBuffer(m_vertexBuffer); m_positionAttribute->setByteStride(stride); m_positionAttribute->setCount(nVerts); m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName()); - m_texCoordAttribute->setDataType(QAttribute::Float); - m_texCoordAttribute->setDataSize(2); + m_texCoordAttribute->setVertexBaseType(QAttribute::Float); + m_texCoordAttribute->setVertexSize(2); m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute); m_texCoordAttribute->setBuffer(m_vertexBuffer); m_texCoordAttribute->setByteStride(stride); @@ -279,8 +279,8 @@ void QSphereGeometryPrivate::init() m_texCoordAttribute->setCount(nVerts); m_normalAttribute->setName(QAttribute::defaultNormalAttributeName()); - m_normalAttribute->setDataType(QAttribute::Float); - m_normalAttribute->setDataSize(3); + m_normalAttribute->setVertexBaseType(QAttribute::Float); + m_normalAttribute->setVertexSize(3); m_normalAttribute->setAttributeType(QAttribute::VertexAttribute); m_normalAttribute->setBuffer(m_vertexBuffer); m_normalAttribute->setByteStride(stride); @@ -288,8 +288,8 @@ void QSphereGeometryPrivate::init() m_normalAttribute->setCount(nVerts); m_tangentAttribute->setName(QAttribute::defaultTangentAttributeName()); - m_tangentAttribute->setDataType(QAttribute::Float); - m_tangentAttribute->setDataSize(4); + m_tangentAttribute->setVertexBaseType(QAttribute::Float); + m_tangentAttribute->setVertexSize(4); m_tangentAttribute->setAttributeType(QAttribute::VertexAttribute); m_tangentAttribute->setBuffer(m_vertexBuffer); m_tangentAttribute->setByteStride(stride); @@ -297,7 +297,7 @@ void QSphereGeometryPrivate::init() m_tangentAttribute->setCount(nVerts); m_indexAttribute->setAttributeType(QAttribute::IndexAttribute); - m_indexAttribute->setDataType(QAttribute::UnsignedShort); + m_indexAttribute->setVertexBaseType(QAttribute::UnsignedShort); m_indexAttribute->setBuffer(m_indexBuffer); m_indexAttribute->setCount(faces * 3); diff --git a/src/extras/geometries/qtorusgeometry.cpp b/src/extras/geometries/qtorusgeometry.cpp index 09a69a45a..801281110 100644 --- a/src/extras/geometries/qtorusgeometry.cpp +++ b/src/extras/geometries/qtorusgeometry.cpp @@ -222,16 +222,16 @@ void QTorusGeometryPrivate::init() const int faces = (m_slices * 2) * m_rings; m_positionAttribute->setName(QAttribute::defaultPositionAttributeName()); - m_positionAttribute->setDataType(QAttribute::Float); - m_positionAttribute->setDataSize(3); + m_positionAttribute->setVertexBaseType(QAttribute::Float); + m_positionAttribute->setVertexSize(3); m_positionAttribute->setAttributeType(QAttribute::VertexAttribute); m_positionAttribute->setBuffer(m_vertexBuffer); m_positionAttribute->setByteStride(stride); m_positionAttribute->setCount(nVerts); m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName()); - m_texCoordAttribute->setDataType(QAttribute::Float); - m_texCoordAttribute->setDataSize(2); + m_texCoordAttribute->setVertexBaseType(QAttribute::Float); + m_texCoordAttribute->setVertexSize(2); m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute); m_texCoordAttribute->setBuffer(m_vertexBuffer); m_texCoordAttribute->setByteStride(stride); @@ -239,8 +239,8 @@ void QTorusGeometryPrivate::init() m_texCoordAttribute->setCount(nVerts); m_normalAttribute->setName(QAttribute::defaultNormalAttributeName()); - m_normalAttribute->setDataType(QAttribute::Float); - m_normalAttribute->setDataSize(3); + m_normalAttribute->setVertexBaseType(QAttribute::Float); + m_normalAttribute->setVertexSize(3); m_normalAttribute->setAttributeType(QAttribute::VertexAttribute); m_normalAttribute->setBuffer(m_vertexBuffer); m_normalAttribute->setByteStride(stride); @@ -248,7 +248,7 @@ void QTorusGeometryPrivate::init() m_normalAttribute->setCount(nVerts); m_indexAttribute->setAttributeType(QAttribute::IndexAttribute); - m_indexAttribute->setDataType(QAttribute::UnsignedShort); + m_indexAttribute->setVertexBaseType(QAttribute::UnsignedShort); m_indexAttribute->setBuffer(m_indexBuffer); m_indexAttribute->setCount(faces * 3); diff --git a/src/extras/shaders/es2/skybox.vert b/src/extras/shaders/es2/skybox.vert index e2de1d88b..3a9fb1beb 100644 --- a/src/extras/shaders/es2/skybox.vert +++ b/src/extras/shaders/es2/skybox.vert @@ -1,12 +1,14 @@ attribute vec3 vertexPosition; varying vec3 texCoord0; -uniform mat4 mvp; -uniform mat4 inverseProjectionMatrix; -uniform mat4 inverseModelView; +uniform mat4 modelMatrix; +uniform mat4 viewMatrix; +uniform mat4 projectionMatrix; void main() { texCoord0 = vertexPosition.xyz; - gl_Position = vec4(mvp * vec4(vertexPosition, 1.0)).xyww; + // Converting the viewMatrix to a mat3, then back to a mat4 + // removes the translation component from it + gl_Position = vec4(projectionMatrix * mat4(mat3(viewMatrix)) * modelMatrix * vec4(vertexPosition, 1.0)).xyww; } diff --git a/src/extras/shaders/gl3/skybox.vert b/src/extras/shaders/gl3/skybox.vert index 17bb2b00b..b5b0c0617 100644 --- a/src/extras/shaders/gl3/skybox.vert +++ b/src/extras/shaders/gl3/skybox.vert @@ -3,12 +3,14 @@ in vec3 vertexPosition; out vec3 texCoord0; -uniform mat4 mvp; -uniform mat4 inverseProjectionMatrix; -uniform mat4 inverseModelView; +uniform mat4 modelMatrix; +uniform mat4 viewMatrix; +uniform mat4 projectionMatrix; void main() { texCoord0 = vertexPosition.xyz; - gl_Position = vec4(mvp * vec4(vertexPosition, 1.0)).xyww; + // Converting the viewMatrix to a mat3, then back to a mat4 + // removes the translation component from it + gl_Position = vec4(projectionMatrix * mat4(mat3(viewMatrix)) * modelMatrix * vec4(vertexPosition, 1.0)).xyww; } diff --git a/src/input/backend/inputhandler.cpp b/src/input/backend/inputhandler.cpp index 82b017b1c..fe2a04bd7 100644 --- a/src/input/backend/inputhandler.cpp +++ b/src/input/backend/inputhandler.cpp @@ -249,6 +249,7 @@ QVector<Qt3DCore::QAspectJobPtr> InputHandler::mouseJobs() MouseDevice *controller = m_mouseDeviceManager->data(cHandle); controller->updateMouseEvents(mouseEvents); + controller->updateWheelEvents(wheelEvents); // Event dispacthing job if (!mouseEvents.isEmpty() || !wheelEvents.empty()) { // Send the events to the mouse handlers that have for sourceDevice controller diff --git a/src/input/backend/logicaldevice_p.h b/src/input/backend/logicaldevice_p.h index a7fdcd0ef..38d4e2dd5 100644 --- a/src/input/backend/logicaldevice_p.h +++ b/src/input/backend/logicaldevice_p.h @@ -62,7 +62,7 @@ namespace Input { class LogicalDeviceManager; -class LogicalDevice : public Qt3DCore::QBackendNode +class Q_AUTOTEST_EXPORT LogicalDevice : public Qt3DCore::QBackendNode { public: LogicalDevice(); @@ -71,7 +71,6 @@ public: inline QVector<Qt3DCore::QNodeId> axes() const { return m_axes; } inline QVector<Qt3DCore::QNodeId> actions() const { return m_actions; } -protected: void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; private: diff --git a/src/input/backend/mousedevice.cpp b/src/input/backend/mousedevice.cpp index a2f106d94..e649824a4 100644 --- a/src/input/backend/mousedevice.cpp +++ b/src/input/backend/mousedevice.cpp @@ -84,7 +84,10 @@ float MouseDevice::axisValue(int axisIdentifier) const return m_mouseState.xAxis; case QMouseDevice::Y: return m_mouseState.yAxis; - break; + case QMouseDevice::WheelX: + return m_mouseState.wXAxis; + case QMouseDevice::WheelY: + return m_mouseState.wYAxis; default: break; } @@ -106,6 +109,19 @@ bool MouseDevice::isButtonPressed(int buttonIdentifier) const return false; } +void MouseDevice::updateWheelEvents(const QList<QT_PREPEND_NAMESPACE (QWheelEvent)> &events) +{ + // Reset axis values before we accumulate new values for this frame + m_mouseState.wXAxis = 0.0f; + m_mouseState.wYAxis = 0.0f; + if (!events.isEmpty()) { + for (const QT_PREPEND_NAMESPACE(QWheelEvent) &e : events) { + m_mouseState.wXAxis += m_sensitivity * e.angleDelta().x(); + m_mouseState.wYAxis += m_sensitivity * e.angleDelta().y(); + } + } +} + void MouseDevice::updateMouseEvents(const QList<QT_PREPEND_NAMESPACE(QMouseEvent)> &events) { // Reset axis values before we accumulate new values for this frame diff --git a/src/input/backend/mousedevice_p.h b/src/input/backend/mousedevice_p.h index 723945554..02a6d916e 100644 --- a/src/input/backend/mousedevice_p.h +++ b/src/input/backend/mousedevice_p.h @@ -76,6 +76,7 @@ public: bool isButtonPressed(int buttonIdentifier) const Q_DECL_OVERRIDE; void updateMouseEvents(const QList<QT_PREPEND_NAMESPACE(QMouseEvent)> &events); + void updateWheelEvents(const QList<QT_PREPEND_NAMESPACE(QWheelEvent)> &events); protected: void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; @@ -90,6 +91,8 @@ private: MouseState() : xAxis(0.0f) , yAxis(0.0f) + , wXAxis(0.0f) + , wYAxis(0.0f) , leftPressed(false) , rightPressed(false) , centerPressed(false) @@ -97,6 +100,8 @@ private: float xAxis; float yAxis; + float wXAxis; + float wYAxis; bool leftPressed; bool rightPressed; bool centerPressed; diff --git a/src/input/backend/updateaxisactionjob.cpp b/src/input/backend/updateaxisactionjob.cpp index 0cbd325c9..bbd36228e 100644 --- a/src/input/backend/updateaxisactionjob.cpp +++ b/src/input/backend/updateaxisactionjob.cpp @@ -80,6 +80,10 @@ void UpdateAxisActionJob::run() // Note: we assume axis/action are not really shared: // there's no benefit in sharing those when it comes to computing LogicalDevice *device = m_handler->logicalDeviceManager()->data(m_handle); + + if (!device->isEnabled()) + return; + updateAction(device); updateAxis(device); } diff --git a/src/input/frontend/frontend.pri b/src/input/frontend/frontend.pri index 93b3e0839..67c93d2b9 100644 --- a/src/input/frontend/frontend.pri +++ b/src/input/frontend/frontend.pri @@ -43,7 +43,9 @@ HEADERS += \ $$PWD/qinputsequence_p.h \ $$PWD/qinputchord_p.h \ $$PWD/qphysicaldevicecreatedchange.h \ - $$PWD/qphysicaldevicecreatedchange_p.h + $$PWD/qphysicaldevicecreatedchange_p.h \ + $$PWD/qaxisaccumulator.h \ + $$PWD/qaxisaccumulator_p.h SOURCES += \ @@ -71,7 +73,8 @@ SOURCES += \ $$PWD/qinputchord.cpp \ $$PWD/qinputsequence.cpp \ $$PWD/qinputsettings.cpp \ - $$PWD/qphysicaldevicecreatedchange.cpp + $$PWD/qphysicaldevicecreatedchange.cpp \ + $$PWD/qaxisaccumulator.cpp qtHaveModule(gamepad) { QT += gamepad diff --git a/src/input/frontend/qaxisaccumulator.cpp b/src/input/frontend/qaxisaccumulator.cpp new file mode 100644 index 000000000..d205bce16 --- /dev/null +++ b/src/input/frontend/qaxisaccumulator.cpp @@ -0,0 +1,274 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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 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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qaxisaccumulator.h" +#include "qaxisaccumulator_p.h" +#include <Qt3DInput/qaxis.h> +#include <Qt3DCore/qnodecreatedchange.h> +#include <Qt3DCore/qpropertyupdatedchange.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DInput { + +/*! + Constructs a new QAxisAccumulator instance with \a parent. + \class Qt3DInput::QAxisAccumulator + \inmodule Qt3DInput + \inherits Qt3DCore::QNode + \brief QAxisAccumulator processes velocity or acceleration data from a QAxis. + \since 5.8 + + A Qt3DInput::QAxis reports the current position of an axis on an input + device. When the axis is returned to its neutral position the value of that + axis returns to 0. Often, it is required to have the input from an axis + control a variable in other ways, for example treating the value from the + Qt3DInput::QAxis as a velocity (first derivative with respect to time) or + as an acceleration (second derivative with respect to time). This can be + done with user code or with a Qt3DLogic::QFrameAction but those approached + are not ideal as they add more work to the main thread and are inherently + imperative. The Qt3DInput::QAxisAccumulator class allows for this common + task to be performed on the Qt 3D backend and be specified in a declarative + manner. +*/ + +/*! + \qmltype AxisAccumulator + \inqmlmodule Qt3D.Input + \instantiates Qt3DInput::QAxisAccumulator + \brief QML frontend for the Qt3DInput::QAxisAccumulator C++ class. + \since 5.8 + + An Axis reports the current position of an axis on an input device. When the + axis is returned to its neutral position the value of that axis returns to 0. + Often, it is required to have the input from an axis control a variable in + other ways, for example treating the value from the Axis as a velocity (first + derivative with respect to time) or as an acceleration (second derivative with + respect to time). This can be done with user code or with a FrameAction but + those approached are not ideal as they add more work to the main thread and + are inherently imperative. The AxisAccumulator class allows for this common + task to be performed on the Qt 3D backend and be specified in a declarative + manner. +*/ + +/*! + \qmlproperty int Qt3D.Inpit::Axis::value + \readonly + + Holds the value accumulated from the sourceAxis. +*/ + +/*! + * \enum Qt3DInput::QAxisAccumulator::SourceAxisType + * + * \value Velocity + * \value Acceleration + */ + +/*! \internal */ +QAxisAccumulatorPrivate::QAxisAccumulatorPrivate() + : Qt3DCore::QNodePrivate() + , m_sourceAxis(nullptr) + , m_sourceAxisType(QAxisAccumulator::Velocity) + , m_scale(1.0f) + , m_value(0.0f) +{ +} + +/*! \internal */ +void QAxisAccumulatorPrivate::setValue(float value) +{ + if (value != m_value) { + m_value = value; + q_func()->valueChanged(m_value); + } +} + +/*! + Constructs a new QAxisAccumulator instance with parent \a parent. + */ +QAxisAccumulator::QAxisAccumulator(Qt3DCore::QNode *parent) + : Qt3DCore::QNode(*new QAxisAccumulatorPrivate, parent) +{ +} + +/*! \internal */ +QAxisAccumulator::~QAxisAccumulator() +{ +} + +/*! + \qmlproperty Axis Qt3D.Input::AxisAccumulator::sourceAxis + + The Axis for which the accumulator should integrate axis values. + */ + +/*! + \return QAxis for which the accumulator should integrate axis values. + */ +QAxis *QAxisAccumulator::sourceAxis() const +{ + Q_D(const QAxisAccumulator); + return d->m_sourceAxis; +} + +/*! + \qmlproperty SourceAxisType Qt3D.Input::AxisAccumulator::sourceAxisType + + The sourceAxisType property specifies how the accumulator treats the values + from the source axis. + */ + +/*! + \return how the accumulator treats the value of the sourceAxis. + */ +QAxisAccumulator::SourceAxisType QAxisAccumulator::sourceAxisType() const +{ + Q_D(const QAxisAccumulator); + return d->m_sourceAxisType; +} + +/*! + \qmlproperty real Qt3D.Input::AxisAccumulator::value + + The accumulated (integrated) value. + */ + +/*! + \return the accumulated (integrated) value. + */ +float QAxisAccumulator::value() const +{ + Q_D(const QAxisAccumulator); + return d->m_value; +} + +/*! + \qmlproperty real Qt3D.Input::AxisAccumulator::value + + The amount to scale the axis value by when accumulating. This can be + thought of as the maximum velocity or acceleration the axis can + control. + */ + +/*! + The amount to scale the axis value by when accumulating. This can be + thought of as the maximum velocity or acceleration the axis can + control. + + \return the amount the input axis values are scaled by. + */ +float QAxisAccumulator::scale() const +{ + Q_D(const QAxisAccumulator); + return d->m_scale; +} + +/*! + Sets the source axis from which the accumulator should receive values from to + \a sourceAxis. How these values are treated is controlled by the sourceAxisType + and scale properties. + */ +void QAxisAccumulator::setSourceAxis(QAxis *sourceAxis) +{ + Q_D(QAxisAccumulator); + if (d->m_sourceAxis == sourceAxis) + return; + + if (d->m_sourceAxis) + d->unregisterDestructionHelper(d->m_sourceAxis); + + if (sourceAxis && !sourceAxis->parent()) + sourceAxis->setParent(this); + d->m_sourceAxis = sourceAxis; + + // Ensures proper bookkeeping + if (d->m_sourceAxis) + d->registerDestructionHelper(d->m_sourceAxis, &QAxisAccumulator::setSourceAxis, d->m_sourceAxis); + + emit sourceAxisChanged(sourceAxis); +} + +/*! + Sets how the accumulator treats the values originating from the source axis. + */ +void QAxisAccumulator::setSourceAxisType(QAxisAccumulator::SourceAxisType sourceAxisType) +{ + Q_D(QAxisAccumulator); + if (d->m_sourceAxisType == sourceAxisType) + return; + + d->m_sourceAxisType = sourceAxisType; + emit sourceAxisTypeChanged(sourceAxisType); +} + +void QAxisAccumulator::setScale(float scale) +{ + Q_D(QAxisAccumulator); + if (d->m_scale == scale) + return; + + d->m_scale = scale; + emit scaleChanged(scale); +} + +/*! \internal */ +void QAxisAccumulator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) +{ + Q_D(QAxisAccumulator); + auto e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change); + if (e->type() == Qt3DCore::PropertyUpdated && e->propertyName() == QByteArrayLiteral("value")) + d->setValue(e->value().toFloat()); +} + +/*! \internal */ +Qt3DCore::QNodeCreatedChangeBasePtr QAxisAccumulator::createNodeCreationChange() const +{ + auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QAxisAccumulatorData>::create(this); + auto &data = creationChange->data; + Q_D(const QAxisAccumulator); + data.sourceAxisId = qIdForNode(d->m_sourceAxis); + data.sourceAxisType = d->m_sourceAxisType; + data.scale = d->m_scale; + return creationChange; +} + +} // namespace Qt3DInput + +QT_END_NAMESPACE diff --git a/src/input/frontend/qaxisaccumulator.h b/src/input/frontend/qaxisaccumulator.h new file mode 100644 index 000000000..c62e4c35f --- /dev/null +++ b/src/input/frontend/qaxisaccumulator.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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 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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DINPUT_QAXISACCUMULATOR_H +#define QT3DINPUT_QAXISACCUMULATOR_H + +#include <Qt3DInput/qt3dinput_global.h> +#include <Qt3DCore/qnode.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DInput { + +class QAxis; +class QAxisAccumulatorPrivate; + +class QT3DINPUTSHARED_EXPORT QAxisAccumulator : public Qt3DCore::QNode +{ + Q_OBJECT + Q_PROPERTY(Qt3DInput::QAxis *sourceAxis READ sourceAxis WRITE setSourceAxis NOTIFY sourceAxisChanged) + Q_PROPERTY(SourceAxisType sourceAxisType READ sourceAxisType WRITE setSourceAxisType NOTIFY sourceAxisTypeChanged) + Q_PROPERTY(float scale READ scale WRITE setScale NOTIFY scaleChanged) + Q_PROPERTY(float value READ value NOTIFY valueChanged) + +public: + enum SourceAxisType { + Velocity, + Acceleration + }; + Q_ENUM(SourceAxisType) + + QAxisAccumulator(Qt3DCore::QNode *parent = nullptr); + ~QAxisAccumulator(); + + Qt3DInput::QAxis *sourceAxis() const; + SourceAxisType sourceAxisType() const; + float value() const; + float scale() const; + +public Q_SLOTS: + void setSourceAxis(Qt3DInput::QAxis *sourceAxis); + void setSourceAxisType(QAxisAccumulator::SourceAxisType sourceAxisType); + void setScale(float scale); + +Q_SIGNALS: + void sourceAxisChanged(Qt3DInput::QAxis *sourceAxis); + void sourceAxisTypeChanged(QAxisAccumulator::SourceAxisType sourceAxisType); + void valueChanged(float value); + void scaleChanged(float scale); + +protected: + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE; + +private: + Q_DECLARE_PRIVATE(QAxisAccumulator) + Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE; +}; + +} // namespace Qt3DInput + +QT_END_NAMESPACE + +#endif // QT3DINPUT_QAXISACCUMULATOR_H diff --git a/src/input/frontend/qaxisaccumulator_p.h b/src/input/frontend/qaxisaccumulator_p.h new file mode 100644 index 000000000..a07284009 --- /dev/null +++ b/src/input/frontend/qaxisaccumulator_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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 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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DINPUT_QAXISACCUMULATOR_P_H +#define QT3DINPUT_QAXISACCUMULATOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DCore/private/qnode_p.h> +#include <Qt3DInput/qaxisaccumulator.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DInput { + +class QAxisAccumulatorPrivate : public Qt3DCore::QNodePrivate +{ +public: + QAxisAccumulatorPrivate(); + + Q_DECLARE_PUBLIC(QAxisAccumulator) + + void setValue(float value); + + QAxis *m_sourceAxis; + QAxisAccumulator::SourceAxisType m_sourceAxisType; + float m_scale; + float m_value; +}; + +struct QAxisAccumulatorData +{ + Qt3DCore::QNodeId sourceAxisId; + QAxisAccumulator::SourceAxisType sourceAxisType; + float scale; +}; + +} // Qt3DInput + +QT_END_NAMESPACE + +#endif // QT3DINPUT_QAXISACCUMULATOR_P_H diff --git a/src/input/frontend/qinputaspect.cpp b/src/input/frontend/qinputaspect.cpp index 342998556..d0e91a362 100644 --- a/src/input/frontend/qinputaspect.cpp +++ b/src/input/frontend/qinputaspect.cpp @@ -189,11 +189,12 @@ QAbstractPhysicalDevice *QInputAspect::createPhysicalDevice(const QString &name) { Q_D(QInputAspect); const auto integrations = d->m_inputHandler->inputDeviceIntegrations(); + QAbstractPhysicalDevice *device = nullptr; for (Qt3DInput::QInputDeviceIntegration *integration : integrations) { - if (auto dev = integration->createPhysicalDevice(name)) - return dev; + if ((device = integration->createPhysicalDevice(name)) != nullptr) + break; } - return nullptr; + return device; } /*! diff --git a/src/input/frontend/qmousedevice.cpp b/src/input/frontend/qmousedevice.cpp index bbf42b793..56d3731ce 100644 --- a/src/input/frontend/qmousedevice.cpp +++ b/src/input/frontend/qmousedevice.cpp @@ -91,6 +91,8 @@ QMouseDevicePrivate::QMouseDevicePrivate() \value X \value Y + \value WheelX + \value WheelY \sa Qt3DInput::QAnalogAxisInput::setAxis */ @@ -125,12 +127,11 @@ QMouseDevice::~QMouseDevice() /*! \return the axis count. - \note Currently always returns 2. + \note Currently always returns 4. */ int QMouseDevice::axisCount() const { - // TO DO: we could have mouse wheel later on - return 2; + return 4; } /*! @@ -152,7 +153,9 @@ QStringList QMouseDevice::axisNames() const { return QStringList() << QStringLiteral("X") - << QStringLiteral("Y"); + << QStringLiteral("Y") + << QStringLiteral("WheelX") + << QStringLiteral("WheelY"); } /*! @@ -177,6 +180,10 @@ int QMouseDevice::axisIdentifier(const QString &name) const return X; else if (name == QLatin1String("Y")) return Y; + else if (name == QLatin1String("WheelX")) + return WheelX; + else if (name == QLatin1String("WheelY")) + return WheelY; return -1; } diff --git a/src/input/frontend/qmousedevice.h b/src/input/frontend/qmousedevice.h index fe43c6c84..7a1f6332a 100644 --- a/src/input/frontend/qmousedevice.h +++ b/src/input/frontend/qmousedevice.h @@ -63,7 +63,9 @@ public: enum Axis { X, - Y + Y, + WheelX, + WheelY }; Q_ENUM(Axis) diff --git a/src/plugins/sceneparsers/assimp/assimpio.cpp b/src/plugins/sceneparsers/assimp/assimpio.cpp index b2638563f..cc40fd1f7 100644 --- a/src/plugins/sceneparsers/assimp/assimpio.cpp +++ b/src/plugins/sceneparsers/assimp/assimpio.cpp @@ -212,8 +212,8 @@ QAttribute *createAttribute(QBuffer *buffer, QAttribute *attribute = QAbstractNodeFactory::createNode<QAttribute>("QAttribute"); attribute->setBuffer(buffer); attribute->setName(name); - attribute->setDataType(vertexBaseType); - attribute->setDataSize(vertexSize); + attribute->setVertexBaseType(vertexBaseType); + attribute->setVertexSize(vertexSize); attribute->setCount(count); attribute->setByteOffset(byteOffset); attribute->setByteStride(byteStride); @@ -231,8 +231,8 @@ QAttribute *createAttribute(QBuffer *buffer, { QAttribute *attribute = QAbstractNodeFactory::createNode<QAttribute>("QAttribute"); attribute->setBuffer(buffer); - attribute->setDataType(vertexBaseType); - attribute->setDataSize(vertexSize); + attribute->setVertexBaseType(vertexBaseType); + attribute->setVertexSize(vertexSize); attribute->setCount(count); attribute->setByteOffset(byteOffset); attribute->setByteStride(byteStride); diff --git a/src/quick3d/imports/core/qt3dquick3dcoreplugin.h b/src/quick3d/imports/core/qt3dquick3dcoreplugin.h index 48c7fd136..a9b215c4a 100644 --- a/src/quick3d/imports/core/qt3dquick3dcoreplugin.h +++ b/src/quick3d/imports/core/qt3dquick3dcoreplugin.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE class Qt3DQuick3DCorePlugin : public QQmlExtensionPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: Qt3DQuick3DCorePlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { initResources(); } void registerTypes(const char *uri) Q_DECL_OVERRIDE; diff --git a/src/quick3d/imports/extras/defaults/qml/FirstPersonCameraController.qml b/src/quick3d/imports/extras/defaults/qml/FirstPersonCameraController.qml index a21679008..1003c0ea0 100644 --- a/src/quick3d/imports/extras/defaults/qml/FirstPersonCameraController.qml +++ b/src/quick3d/imports/extras/defaults/qml/FirstPersonCameraController.qml @@ -86,6 +86,7 @@ Entity { components: [ LogicalDevice { + enabled: root.enabled actions: [ Action { id: leftMouseButtonAction diff --git a/src/quick3d/imports/extras/defaults/qml/ForwardRenderer.qml b/src/quick3d/imports/extras/defaults/qml/ForwardRenderer.qml index 0cd5bcaa6..b7ad3188c 100644 --- a/src/quick3d/imports/extras/defaults/qml/ForwardRenderer.qml +++ b/src/quick3d/imports/extras/defaults/qml/ForwardRenderer.qml @@ -46,6 +46,8 @@ TechniqueFilter { property alias clearColor: clearBuffer.clearColor property alias viewportRect: viewport.normalizedRect property alias window: surfaceSelector.surface + property alias externalRenderTargetSize: surfaceSelector.externalRenderTargetSize + property alias frustumCulling: frustumCulling.enabled // Select the forward rendering Technique of any used Effect matchAll: [ FilterKey { name: "renderingStyle"; value: "forward" } ] @@ -62,6 +64,7 @@ TechniqueFilter { CameraSelector { id : cameraSelector FrustumCulling { + id: frustumCulling ClearBuffers { id: clearBuffer clearColor: "white" diff --git a/src/quick3d/imports/extras/defaults/qml/OrbitCameraController.qml b/src/quick3d/imports/extras/defaults/qml/OrbitCameraController.qml index 1f5fa5a7a..ae8869473 100644 --- a/src/quick3d/imports/extras/defaults/qml/OrbitCameraController.qml +++ b/src/quick3d/imports/extras/defaults/qml/OrbitCameraController.qml @@ -97,6 +97,7 @@ Entity { components: [ LogicalDevice { + enabled: root.enabled actions: [ Action { id: leftMouseButtonAction diff --git a/src/quick3d/imports/extras/defaults/qml/SkyboxEntity.qml b/src/quick3d/imports/extras/defaults/qml/SkyboxEntity.qml index 9fcf8559f..45cef47b7 100644 --- a/src/quick3d/imports/extras/defaults/qml/SkyboxEntity.qml +++ b/src/quick3d/imports/extras/defaults/qml/SkyboxEntity.qml @@ -42,8 +42,6 @@ import Qt3D.Render 2.0 import Qt3D.Extras 2.0 Entity { - - property alias cameraPosition: transform.translation; property string baseName: ""; property string extension: ".png" @@ -82,10 +80,6 @@ Entity { xyMeshResolution: Qt.size(2, 2) } - Transform { - id: transform - } - Material { id: skyboxMaterial parameters: Parameter { name: "skyboxTexture"; value: skyboxTexture} @@ -152,6 +146,6 @@ Entity { } } - components: [cuboidMesh, skyboxMaterial, transform] + components: [cuboidMesh, skyboxMaterial] } diff --git a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.h b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.h index 8421c6eb4..f5ea6a7f1 100644 --- a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.h +++ b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.h @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE class Qt3DQuick3DExtrasPlugin : public QQmlExtensionPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: Qt3DQuick3DExtrasPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { initResources(); } void registerTypes(const char *uri) Q_DECL_OVERRIDE; diff --git a/src/quick3d/imports/input/qt3dquick3dinputplugin.h b/src/quick3d/imports/input/qt3dquick3dinputplugin.h index d644614e7..8a54eaa53 100644 --- a/src/quick3d/imports/input/qt3dquick3dinputplugin.h +++ b/src/quick3d/imports/input/qt3dquick3dinputplugin.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE class Qt3DQuick3DInputPlugin : public QQmlExtensionPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: Qt3DQuick3DInputPlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) { initResources(); } void registerTypes(const char *uri) Q_DECL_OVERRIDE; diff --git a/src/quick3d/imports/logic/qt3dquick3dlogicplugin.h b/src/quick3d/imports/logic/qt3dquick3dlogicplugin.h index 203bc41b2..a0d95c597 100644 --- a/src/quick3d/imports/logic/qt3dquick3dlogicplugin.h +++ b/src/quick3d/imports/logic/qt3dquick3dlogicplugin.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE class Qt3DQuick3DLogicPlugin : public QQmlExtensionPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: Qt3DQuick3DLogicPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } void registerTypes(const char *uri) Q_DECL_OVERRIDE; diff --git a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp index c82ad7b1d..3eb89efe7 100644 --- a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp +++ b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp @@ -100,6 +100,7 @@ #include <Qt3DRender/qcamera.h> #include <Qt3DRender/qrendersettings.h> #include <Qt3DRender/qpickingsettings.h> +#include <Qt3DRender/qrendercapture.h> #include <Qt3DQuickRender/private/quick3dlayerfilter_p.h> #include <Qt3DQuickRender/private/quick3dtechnique_p.h> #include <Qt3DQuickRender/private/quick3dmaterial_p.h> @@ -186,7 +187,8 @@ void Qt3DQuick3DRenderPlugin::registerTypes(const char *uri) // Geometry qmlRegisterType<Qt3DRender::QAttribute>(uri, 2, 0, "Attribute"); - Qt3DRender::Quick::registerExtendedType<Qt3DRender::QBuffer, Qt3DRender::Render::Quick::Quick3DBuffer>("QBuffer", "Qt3D.Render/Buffer", uri, 2, 0, "Buffer"); + qmlRegisterUncreatableType<Qt3DRender::QBuffer>(uri, 2, 0, "BufferBase", QStringLiteral("Use Quick3DBuffer in QML")); + qmlRegisterType<Qt3DRender::Render::Quick::Quick3DBuffer>(uri, 2, 0, "Buffer"); Qt3DRender::Quick::registerExtendedType<Qt3DRender::QGeometry, Qt3DRender::Render::Quick::Quick3DGeometry>("QGeometry", "Qt3D.Render/Geometry", uri, 2, 0, "Geometry"); qmlRegisterType<Qt3DRender::QGeometryRenderer>(uri, 2, 0, "GeometryRenderer"); @@ -222,6 +224,8 @@ void Qt3DQuick3DRenderPlugin::registerTypes(const char *uri) qmlRegisterType<Qt3DRender::QNoDraw>(uri, 2, 0, "NoDraw"); qmlRegisterType<Qt3DRender::QFrustumCulling>(uri, 2, 0, "FrustumCulling"); qmlRegisterType<Qt3DRender::QDispatchCompute>(uri, 2, 0, "DispatchCompute"); + qmlRegisterType<Qt3DRender::QRenderCapture>(uri, 2, 0, "RenderCapture"); + qmlRegisterUncreatableType<Qt3DRender::QRenderCaptureReply>(uri, 2, 0, "RenderCaptureReply", QStringLiteral("RenderCaptureReply is only instantiated by RenderCapture")); // RenderTarget qmlRegisterType<Qt3DRender::QRenderTargetOutput>(uri, 2, 0, "RenderTargetOutput"); diff --git a/src/quick3d/imports/render/qt3dquick3drenderplugin.h b/src/quick3d/imports/render/qt3dquick3drenderplugin.h index 53235fdb9..181965fe1 100644 --- a/src/quick3d/imports/render/qt3dquick3drenderplugin.h +++ b/src/quick3d/imports/render/qt3dquick3drenderplugin.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE class Qt3DQuick3DRenderPlugin : public QQmlExtensionPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: Qt3DQuick3DRenderPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } void registerTypes(const char *uri) Q_DECL_OVERRIDE; diff --git a/src/quick3d/imports/scene3d/qtquickscene3dplugin.h b/src/quick3d/imports/scene3d/qtquickscene3dplugin.h index 773feb296..df85b4cd7 100644 --- a/src/quick3d/imports/scene3d/qtquickscene3dplugin.h +++ b/src/quick3d/imports/scene3d/qtquickscene3dplugin.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE class QtQuickScene3DPlugin : public QQmlExtensionPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: QtQuickScene3DPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } void registerTypes(const char *uri) Q_DECL_OVERRIDE; diff --git a/src/quick3d/quick3d/quick3d.pro b/src/quick3d/quick3d/quick3d.pro index affb3b352..fc3ef19ee 100644 --- a/src/quick3d/quick3d/quick3d.pro +++ b/src/quick3d/quick3d/quick3d.pro @@ -28,8 +28,6 @@ SOURCES += \ qqmlaspectengine.cpp \ qquaternionanimation.cpp -!contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL - # otherwise mingw headers do not declare common functions like ::strcasecmp win32-g++*:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x diff --git a/src/quick3d/quick3dextras/quick3dextras.pro b/src/quick3d/quick3dextras/quick3dextras.pro index 489200a0c..e0e339e8a 100644 --- a/src/quick3d/quick3dextras/quick3dextras.pro +++ b/src/quick3d/quick3dextras/quick3dextras.pro @@ -21,8 +21,6 @@ HEADERS += \ qt3dquickextras_global.h \ qt3dquickwindow.h -!contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL - # otherwise mingw headers do not declare common functions like ::strcasecmp win32-g++*:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x diff --git a/src/quick3d/quick3dinput/quick3dinput.pro b/src/quick3d/quick3dinput/quick3dinput.pro index 3aa0dedcf..661a7f792 100644 --- a/src/quick3d/quick3dinput/quick3dinput.pro +++ b/src/quick3d/quick3dinput/quick3dinput.pro @@ -23,8 +23,6 @@ HEADERS += \ qt3dquickinput_global.h \ qt3dquickinputnodefactory_p.h -!contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL - # otherwise mingw headers do not declare common functions like ::strcasecmp win32-g++*:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x diff --git a/src/quick3d/quick3drender/items/quick3dbuffer.cpp b/src/quick3d/quick3drender/items/quick3dbuffer.cpp index 73292a3b5..5701adf07 100644 --- a/src/quick3d/quick3drender/items/quick3dbuffer.cpp +++ b/src/quick3d/quick3drender/items/quick3dbuffer.cpp @@ -37,9 +37,10 @@ ** ****************************************************************************/ -#include "quick3dbuffer_p.h" -#include <QQmlEngine> #include <QJSValue> +#include <QQmlEngine> + +#include "quick3dbuffer_p.h" #include <QtQml/private/qqmlengine_p.h> #include <QtQml/private/qjsvalue_p.h> #include <QtQml/private/qv4typedarray_p.h> @@ -57,12 +58,12 @@ namespace { const int jsValueTypeId = qMetaTypeId<QJSValue>(); } -Quick3DBuffer::Quick3DBuffer(QObject *parent) - : QObject(parent) +Quick3DBuffer::Quick3DBuffer(Qt3DCore::QNode *parent) + : Qt3DRender::QBuffer(QBuffer::VertexBuffer, parent) , m_engine(nullptr) , m_v4engine(nullptr) { - QObject::connect(parentBuffer(), &Qt3DRender::QBuffer::dataChanged, this, &Quick3DBuffer::bufferDataChanged); + QObject::connect(this, &Qt3DRender::QBuffer::dataChanged, this, &Quick3DBuffer::bufferDataChanged); } QByteArray Quick3DBuffer::convertToRawData(const QJSValue &jsValue) @@ -83,16 +84,26 @@ QByteArray Quick3DBuffer::convertToRawData(const QJSValue &jsValue) QVariant Quick3DBuffer::bufferData() const { - return QVariant::fromValue(parentBuffer()->data()); + return QVariant::fromValue(data()); } void Quick3DBuffer::setBufferData(const QVariant &bufferData) { if (bufferData.userType() == QMetaType::QByteArray) { - parentBuffer()->setData(bufferData.toByteArray()); + QBuffer::setData(bufferData.toByteArray()); + } else if (bufferData.userType() == jsValueTypeId) { + QJSValue jsValue = bufferData.value<QJSValue>(); + QBuffer::setData(convertToRawData(jsValue)); + } +} + +void Quick3DBuffer::updateData(int offset, const QVariant &bufferData) +{ + if (bufferData.userType() == QMetaType::QByteArray) { + QBuffer::updateData(offset, bufferData.toByteArray()); } else if (bufferData.userType() == jsValueTypeId) { QJSValue jsValue = bufferData.value<QJSValue>(); - parentBuffer()->setData(convertToRawData(jsValue)); + QBuffer::updateData(offset, convertToRawData(jsValue)); } } diff --git a/src/quick3d/quick3drender/items/quick3dbuffer_p.h b/src/quick3d/quick3drender/items/quick3dbuffer_p.h index 512e6936c..c5cb39cdf 100644 --- a/src/quick3d/quick3drender/items/quick3dbuffer_p.h +++ b/src/quick3d/quick3drender/items/quick3dbuffer_p.h @@ -69,17 +69,19 @@ namespace Render { namespace Quick { -class QT3DQUICKRENDERSHARED_PRIVATE_EXPORT Quick3DBuffer : public QObject +class QT3DQUICKRENDERSHARED_PRIVATE_EXPORT Quick3DBuffer : public Qt3DRender::QBuffer { Q_OBJECT Q_PROPERTY(QVariant data READ bufferData WRITE setBufferData NOTIFY bufferDataChanged) public: - explicit Quick3DBuffer(QObject *parent = nullptr); - inline QBuffer *parentBuffer() const { return qobject_cast<QBuffer *>(parent()); } + explicit Quick3DBuffer(Qt3DCore::QNode *parent = nullptr); QVariant bufferData() const; void setBufferData(const QVariant &bufferData); +public Q_SLOTS: + void updateData(int offset, const QVariant &bytes); + Q_SIGNALS: void bufferDataChanged(); diff --git a/src/quick3d/quick3drender/items/quick3dparameter.cpp b/src/quick3d/quick3drender/items/quick3dparameter.cpp index 22b6bba96..783f152c1 100644 --- a/src/quick3d/quick3drender/items/quick3dparameter.cpp +++ b/src/quick3d/quick3drender/items/quick3dparameter.cpp @@ -37,11 +37,11 @@ ** ****************************************************************************/ -#include "quick3dparameter_p_p.h" - #include <QJSValue> #include <QJSValueIterator> +#include "quick3dparameter_p_p.h" + QT_BEGIN_NAMESPACE namespace Qt3DRender { diff --git a/src/quick3d/quick3drender/items/quick3dshaderdata.cpp b/src/quick3d/quick3drender/items/quick3dshaderdata.cpp index e5901e8fb..dbf351695 100644 --- a/src/quick3d/quick3drender/items/quick3dshaderdata.cpp +++ b/src/quick3d/quick3drender/items/quick3dshaderdata.cpp @@ -37,12 +37,12 @@ ** ****************************************************************************/ -#include "quick3dshaderdata_p.h" -#include <private/qshaderdata_p.h> - #include <Qt3DQuickRender/private/quick3dshaderdataarray_p.h> #include <QMetaProperty> +#include "quick3dshaderdata_p.h" +#include <private/qshaderdata_p.h> + QT_BEGIN_NAMESPACE namespace Qt3DRender { diff --git a/src/quick3d/quick3drender/quick3drender.pro b/src/quick3d/quick3drender/quick3drender.pro index 959834870..3079bc494 100644 --- a/src/quick3d/quick3drender/quick3drender.pro +++ b/src/quick3d/quick3drender/quick3drender.pro @@ -22,8 +22,6 @@ HEADERS += \ qt3dquickrender_global_p.h \ qt3dquickrender_global.h -!contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL - # otherwise mingw headers do not declare common functions like ::strcasecmp win32-g++*:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x diff --git a/src/render/backend/commandexecuter.cpp b/src/render/backend/commandexecuter.cpp index 92f44c511..2f13b27ea 100644 --- a/src/render/backend/commandexecuter.cpp +++ b/src/render/backend/commandexecuter.cpp @@ -251,13 +251,9 @@ QJsonObject parameterPackToJson(const Render::ShaderParameterPack &pack) for (auto it = uniforms.cbegin(), end = uniforms.cend(); it != end; ++it) { QJsonObject uniformObj; uniformObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(it.key())); - const Render::QUniformValue::UniformType type = it.value().type(); - uniformObj.insert(QLatin1String("value"), - type == Render::QUniformValue::Value - ? typeToJsonValue(it.value().value()) - : typeToJsonValue(it.value().textureId())); + const Render::UniformValue::ValueType type = it.value().valueType(); uniformObj.insert(QLatin1String("type"), - type == Render::QUniformValue::Value + type == Render::UniformValue::ScalarValue ? QLatin1String("value") : QLatin1String("texture")); uniformsArray.push_back(uniformObj); diff --git a/src/render/backend/platformsurfacefilter_p.h b/src/render/backend/platformsurfacefilter_p.h index e95c45d67..ec10327fe 100644 --- a/src/render/backend/platformsurfacefilter_p.h +++ b/src/render/backend/platformsurfacefilter_p.h @@ -82,7 +82,6 @@ public: template<class T> void setSurface(T *surface) { - Q_ASSERT(surface); if (m_obj == surface) return; diff --git a/src/render/backend/render-backend.pri b/src/render/backend/render-backend.pri index 256cba78e..a55a72d8b 100644 --- a/src/render/backend/render-backend.pri +++ b/src/render/backend/render-backend.pri @@ -7,7 +7,6 @@ HEADERS += \ $$PWD/renderthread_p.h \ $$PWD/renderconfiguration_p.h \ $$PWD/renderer_p.h \ - $$PWD/quniformvalue_p.h \ $$PWD/renderview_p.h \ $$PWD/rendercommand_p.h \ $$PWD/renderqueue_p.h \ @@ -36,13 +35,14 @@ HEADERS += \ $$PWD/stringtoint_p.h \ $$PWD/backendnode_p.h \ $$PWD/rendertargetoutput_p.h \ - $$PWD/commandexecuter_p.h + $$PWD/commandexecuter_p.h \ + $$PWD/uniform_p.h \ + $$PWD/shaderparameterpack_p.h SOURCES += \ $$PWD/renderthread.cpp \ $$PWD/renderconfiguration.cpp \ $$PWD/renderer.cpp \ - $$PWD/quniformvalue.cpp \ $$PWD/renderview.cpp \ $$PWD/rendercommand.cpp \ $$PWD/renderqueue.cpp \ @@ -66,5 +66,7 @@ SOURCES += \ $$PWD/rendertargetoutput.cpp \ $$PWD/attachmentpack.cpp \ $$PWD/commandexecuter.cpp \ - $$PWD/openglvertexarrayobject.cpp + $$PWD/openglvertexarrayobject.cpp \ + $$PWD/uniform.cpp \ + $$PWD/shaderparameterpack.cpp diff --git a/src/render/backend/rendercommand_p.h b/src/render/backend/rendercommand_p.h index dc65ac7ed..012cdbe9a 100644 --- a/src/render/backend/rendercommand_p.h +++ b/src/render/backend/rendercommand_p.h @@ -53,7 +53,7 @@ // #include <qglobal.h> -#include <Qt3DRender/private/quniformvalue_p.h> +#include <Qt3DRender/private/shaderparameterpack_p.h> #include <Qt3DRender/private/handle_types_p.h> #include <Qt3DRender/qgeometryrenderer.h> #include <QOpenGLShaderProgram> diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index 49f2f4434..7f53d3c99 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -79,6 +79,7 @@ #include <Qt3DRender/private/openglvertexarrayobject_p.h> #include <Qt3DRender/private/platformsurfacefilter_p.h> #include <Qt3DRender/private/loadbufferjob_p.h> +#include <Qt3DRender/private/rendercapture_p.h> #include <Qt3DRender/qcameralens.h> #include <Qt3DCore/private/qeventfilterservice_p.h> @@ -158,6 +159,7 @@ Renderer::Renderer(QRenderAspect::RenderType type) , m_expandBoundingVolumeJob(Render::ExpandBoundingVolumeJobPtr::create()) , m_calculateBoundingVolumeJob(Render::CalculateBoundingVolumeJobPtr::create()) , m_updateWorldBoundingVolumeJob(Render::UpdateWorldBoundingVolumeJobPtr::create()) + , m_sendRenderCaptureJob(Render::SendRenderCaptureJobPtr::create(this)) #ifdef QT3D_JOBS_RUN_STATS , m_commandExecuter(new Qt3DRender::Debug::CommandExecuter(this)) #endif @@ -224,6 +226,7 @@ void Renderer::setNodeManagers(NodeManagers *managers) m_calculateBoundingVolumeJob->setManagers(m_nodesManager); m_pickBoundingVolumeJob->setManagers(m_nodesManager); m_updateWorldBoundingVolumeJob->setManager(m_nodesManager->renderNodesManager()); + m_sendRenderCaptureJob->setManagers(m_nodesManager); } NodeManagers *Renderer::nodeManagers() const @@ -902,6 +905,14 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren // executeCommands takes care of restoring the stateset to the value // of gc->currentContext() at the moment it was called (either // renderViewStateSet or m_defaultRenderStateSet) + if (!renderView->renderCaptureNodeId().isNull()) { + QSize size = m_graphicsContext->renderTargetSize(renderView->surfaceSize() * renderView->devicePixelRatio()); + QImage image = m_graphicsContext->readFramebuffer(size); + Render::RenderCapture *renderCapture = + static_cast<Render::RenderCapture*>(m_nodesManager->frameGraphManager()->lookupNode(renderView->renderCaptureNodeId())); + renderCapture->addRenderCapture(image); + addRenderCaptureSendRequest(renderView->renderCaptureNodeId()); + } frameElapsed = timer.elapsed() - frameElapsed; qCDebug(Rendering) << Q_FUNC_INFO << "Submitted Renderview " << i + 1 << "/" << renderViewsCount << "in " << frameElapsed << "ms"; @@ -996,6 +1007,7 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs() renderBinJobs.push_back(m_calculateBoundingVolumeJob); renderBinJobs.push_back(m_worldTransformJob); renderBinJobs.push_back(m_cleanupJob); + renderBinJobs.push_back(m_sendRenderCaptureJob); renderBinJobs.append(bufferJobs); // Traverse the current framegraph. For each leaf node create a @@ -1263,6 +1275,17 @@ const GraphicsApiFilterData *Renderer::contextInfo() const return m_graphicsContext->contextInfo(); } +void Renderer::addRenderCaptureSendRequest(Qt3DCore::QNodeId nodeId) +{ + if (!m_pendingRenderCaptureSendRequests.contains(nodeId)) + m_pendingRenderCaptureSendRequests.push_back(nodeId); +} + +const QVector<Qt3DCore::QNodeId> Renderer::takePendingRenderCaptureSendRequests() +{ + return std::move(m_pendingRenderCaptureSendRequests); +} + // Returns a vector of jobs to be performed for dirty buffers // 1 dirty buffer == 1 job, all job can be performed in parallel QVector<Qt3DCore::QAspectJobPtr> Renderer::createRenderBufferJobs() const diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h index 3e6ef6ffc..ffc60273a 100644 --- a/src/render/backend/renderer_p.h +++ b/src/render/backend/renderer_p.h @@ -54,7 +54,7 @@ #include <Qt3DRender/qrenderaspect.h> #include <Qt3DRender/qtechnique.h> -#include <Qt3DRender/private/quniformvalue_p.h> +#include <Qt3DRender/private/shaderparameterpack_p.h> #include <Qt3DRender/private/handle_types_p.h> #include <Qt3DRender/private/abstractrenderer_p.h> #include <Qt3DCore/qaspectjob.h> @@ -69,6 +69,7 @@ #include <Qt3DRender/private/framecleanupjob_p.h> #include <Qt3DRender/private/updateworldboundingvolumejob_p.h> #include <Qt3DRender/private/platformsurfacefilter_p.h> +#include <Qt3DRender/private/sendrendercapturejob_p.h> #include <QHash> #include <QMatrix4x4> @@ -210,6 +211,8 @@ public: QList<QMouseEvent> pendingPickingEvents() const; + void addRenderCaptureSendRequest(Qt3DCore::QNodeId nodeId); + const QVector<Qt3DCore::QNodeId> takePendingRenderCaptureSendRequests(); void enqueueRenderView(RenderView *renderView, int submitOrder); bool isReadyToSubmit(); @@ -284,6 +287,9 @@ private: ExpandBoundingVolumeJobPtr m_expandBoundingVolumeJob; CalculateBoundingVolumeJobPtr m_calculateBoundingVolumeJob; UpdateWorldBoundingVolumeJobPtr m_updateWorldBoundingVolumeJob; + SendRenderCaptureJobPtr m_sendRenderCaptureJob; + + QVector<Qt3DCore::QNodeId> m_pendingRenderCaptureSendRequests; void performDraw(RenderCommand *command); void performCompute(const RenderView *rv, RenderCommand *command); diff --git a/src/render/backend/rendersettings.cpp b/src/render/backend/rendersettings.cpp index 3df95c753..2cd2b1d07 100644 --- a/src/render/backend/rendersettings.cpp +++ b/src/render/backend/rendersettings.cpp @@ -56,6 +56,7 @@ RenderSettings::RenderSettings() , m_renderPolicy(QRenderSettings::OnDemand) , m_pickMethod(QPickingSettings::BoundingVolumePicking) , m_pickResultMode(QPickingSettings::NearestPick) + , m_faceOrientationPickingMode(QPickingSettings::FrontFace) , m_activeFrameGraph() { } @@ -68,6 +69,7 @@ void RenderSettings::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePt m_renderPolicy = data.renderPolicy; m_pickMethod = data.pickMethod; m_pickResultMode = data.pickResultMode; + m_faceOrientationPickingMode = data.faceOrientationPickingMode; } void RenderSettings::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) @@ -78,6 +80,8 @@ void RenderSettings::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_pickMethod = propertyChange->value().value<QPickingSettings::PickMethod>(); else if (propertyChange->propertyName() == QByteArrayLiteral("pickResult")) m_pickResultMode = propertyChange->value().value<QPickingSettings::PickResultMode>(); + else if (propertyChange->propertyName() == QByteArrayLiteral("faceOrientationPickingMode")) + m_faceOrientationPickingMode = propertyChange->value().value<QPickingSettings::FaceOrientationPickingMode>(); else if (propertyChange->propertyName() == QByteArrayLiteral("activeFrameGraph")) m_activeFrameGraph = propertyChange->value().value<QNodeId>(); else if (propertyChange->propertyName() == QByteArrayLiteral("renderPolicy")) diff --git a/src/render/backend/rendersettings_p.h b/src/render/backend/rendersettings_p.h index f95ec9645..37771c40b 100644 --- a/src/render/backend/rendersettings_p.h +++ b/src/render/backend/rendersettings_p.h @@ -62,7 +62,7 @@ namespace Render { class AbstractRenderer; -class RenderSettings : public BackendNode +class Q_AUTOTEST_EXPORT RenderSettings : public BackendNode { public: RenderSettings(); @@ -73,6 +73,7 @@ public: QRenderSettings::RenderPolicy renderPolicy() const { return m_renderPolicy; } QPickingSettings::PickMethod pickMethod() const { return m_pickMethod; } QPickingSettings::PickResultMode pickResultMode() const { return m_pickResultMode; } + QPickingSettings::FaceOrientationPickingMode faceOrientationPickingMode() const { return m_faceOrientationPickingMode; } private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; @@ -80,6 +81,7 @@ private: QRenderSettings::RenderPolicy m_renderPolicy; QPickingSettings::PickMethod m_pickMethod; QPickingSettings::PickResultMode m_pickResultMode; + QPickingSettings::FaceOrientationPickingMode m_faceOrientationPickingMode; Qt3DCore::QNodeId m_activeFrameGraph; }; diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp index 64f8bacca..df165e2d0 100644 --- a/src/render/backend/renderview.cpp +++ b/src/render/backend/renderview.cpp @@ -65,7 +65,7 @@ #include <Qt3DRender/private/viewportnode_p.h> #include <Qt3DRender/private/buffermanager_p.h> #include <Qt3DRender/private/geometryrenderermanager_p.h> - +#include <Qt3DRender/private/rendercapture_p.h> #include <Qt3DRender/private/stringtoint_p.h> #include <Qt3DCore/qentity.h> #include <QtGui/qsurface.h> @@ -133,80 +133,80 @@ RenderView::StandardUniformsPFuncsHash RenderView::initializeStandardUniformSett return setters; } -QUniformValue RenderView::modelMatrix(const QMatrix4x4 &model) const +UniformValue RenderView::modelMatrix(const QMatrix4x4 &model) const { - return QUniformValue(QVariant::fromValue(model)); + return UniformValue(model); } -QUniformValue RenderView::viewMatrix(const QMatrix4x4 &) const +UniformValue RenderView::viewMatrix(const QMatrix4x4 &) const { - return QUniformValue(QVariant::fromValue(m_data.m_viewMatrix)); + return UniformValue(m_data.m_viewMatrix); } -QUniformValue RenderView::projectionMatrix(const QMatrix4x4 &) const +UniformValue RenderView::projectionMatrix(const QMatrix4x4 &) const { - return QUniformValue(QVariant::fromValue(m_data.m_renderCameraLens->projection())); + return UniformValue(m_data.m_renderCameraLens->projection()); } -QUniformValue RenderView::modelViewMatrix(const QMatrix4x4 &model) const +UniformValue RenderView::modelViewMatrix(const QMatrix4x4 &model) const { - return QUniformValue(QVariant::fromValue(m_data.m_viewMatrix * model)); + return UniformValue(m_data.m_viewMatrix * model); } -QUniformValue RenderView::viewProjectionMatrix(const QMatrix4x4 &model) const +UniformValue RenderView::viewProjectionMatrix(const QMatrix4x4 &model) const { Q_UNUSED(model); - return QUniformValue(QVariant::fromValue(m_data.m_renderCameraLens->projection() * m_data.m_viewMatrix)); + return UniformValue(m_data.m_renderCameraLens->projection() * m_data.m_viewMatrix); } -QUniformValue RenderView::modelViewProjectionMatrix(const QMatrix4x4 &model) const +UniformValue RenderView::modelViewProjectionMatrix(const QMatrix4x4 &model) const { - return QUniformValue(QVariant::fromValue(m_data.m_viewProjectionMatrix * model)); + return UniformValue(m_data.m_viewProjectionMatrix * model); } -QUniformValue RenderView::inverseModelMatrix(const QMatrix4x4 &model) const +UniformValue RenderView::inverseModelMatrix(const QMatrix4x4 &model) const { - return QUniformValue(QVariant::fromValue(model.inverted())); + return UniformValue(model.inverted()); } -QUniformValue RenderView::inverseViewMatrix(const QMatrix4x4 &) const +UniformValue RenderView::inverseViewMatrix(const QMatrix4x4 &) const { - return QUniformValue(QVariant::fromValue(m_data.m_viewMatrix.inverted())); + return UniformValue(m_data.m_viewMatrix.inverted()); } -QUniformValue RenderView::inverseProjectionMatrix(const QMatrix4x4 &) const +UniformValue RenderView::inverseProjectionMatrix(const QMatrix4x4 &) const { QMatrix4x4 projection; if (m_data.m_renderCameraLens) projection = m_data.m_renderCameraLens->projection(); - return QUniformValue(QVariant::fromValue(projection.inverted())); + return UniformValue(projection.inverted()); } -QUniformValue RenderView::inverseModelViewMatrix(const QMatrix4x4 &model) const +UniformValue RenderView::inverseModelViewMatrix(const QMatrix4x4 &model) const { - return QUniformValue(QVariant::fromValue((m_data.m_viewMatrix * model).inverted())); + return UniformValue((m_data.m_viewMatrix * model).inverted()); } -QUniformValue RenderView::inverseViewProjectionMatrix(const QMatrix4x4 &model) const +UniformValue RenderView::inverseViewProjectionMatrix(const QMatrix4x4 &model) const { Q_UNUSED(model); const auto viewProjectionMatrix = m_data.m_renderCameraLens->projection() * m_data.m_viewMatrix; - return QUniformValue(QVariant::fromValue(viewProjectionMatrix.inverted())); + return UniformValue(viewProjectionMatrix.inverted()); } -QUniformValue RenderView::inverseModelViewProjectionMatrix(const QMatrix4x4 &model) const +UniformValue RenderView::inverseModelViewProjectionMatrix(const QMatrix4x4 &model) const { - return QUniformValue(QVariant::fromValue((m_data.m_viewProjectionMatrix * model).inverted(0))); + return UniformValue((m_data.m_viewProjectionMatrix * model).inverted(0)); } -QUniformValue RenderView::modelNormalMatrix(const QMatrix4x4 &model) const +UniformValue RenderView::modelNormalMatrix(const QMatrix4x4 &model) const { - return QUniformValue(QVariant::fromValue(model.normalMatrix())); + return UniformValue(model.normalMatrix()); } -QUniformValue RenderView::modelViewNormalMatrix(const QMatrix4x4 &model) const +UniformValue RenderView::modelViewNormalMatrix(const QMatrix4x4 &model) const { - return QUniformValue(QVariant::fromValue((m_data.m_viewMatrix * model).normalMatrix())); + return UniformValue((m_data.m_viewMatrix * model).normalMatrix()); } // TODO: Move this somewhere global where GraphicsContext::setViewport() can use it too @@ -218,38 +218,38 @@ static QRectF resolveViewport(const QRectF &fractionalViewport, const QSize &sur fractionalViewport.height() * surfaceSize.height()); } -QUniformValue RenderView::viewportMatrix(const QMatrix4x4 &model) const +UniformValue RenderView::viewportMatrix(const QMatrix4x4 &model) const { // TODO: Can we avoid having to pass the model matrix in to these functions? Q_UNUSED(model); QMatrix4x4 viewportMatrix; viewportMatrix.viewport(resolveViewport(m_viewport, m_surfaceSize)); - return QUniformValue(QVariant::fromValue(viewportMatrix)); + return UniformValue(viewportMatrix); } -QUniformValue RenderView::inverseViewportMatrix(const QMatrix4x4 &model) const +UniformValue RenderView::inverseViewportMatrix(const QMatrix4x4 &model) const { Q_UNUSED(model); QMatrix4x4 viewportMatrix; viewportMatrix.viewport(resolveViewport(m_viewport, m_surfaceSize)); QMatrix4x4 inverseViewportMatrix = viewportMatrix.inverted(); - return QUniformValue(QVariant::fromValue(inverseViewportMatrix)); + return UniformValue(inverseViewportMatrix); } -QUniformValue RenderView::time(const QMatrix4x4 &model) const +UniformValue RenderView::time(const QMatrix4x4 &model) const { Q_UNUSED(model); qint64 time = m_renderer->time(); float t = time / 1000000000.0f; - return QUniformValue(QVariant(t)); + return UniformValue(t); } -QUniformValue RenderView::eyePosition(const QMatrix4x4 &model) const +UniformValue RenderView::eyePosition(const QMatrix4x4 &model) const { Q_UNUSED(model); - return QUniformValue(QVariant::fromValue(m_data.m_eyePos)); + return UniformValue(m_data.m_eyePos); } RenderView::RenderView() @@ -326,7 +326,7 @@ void RenderView::sort() // sharing the same material (shader) are rendered, we can't have the case // where two uniforms, referencing the same texture eventually have 2 different // texture unit values - const QUniformValue refValue = cachedUniforms.value(it.key()); + const UniformValue refValue = cachedUniforms.value(it.key()); if (it.value() == refValue) { it = uniforms.erase(it); } else { @@ -532,27 +532,24 @@ void RenderView::updateMatrices() } } -void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, const QVariant &value) const +void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const { - Texture *tex = nullptr; // At this point a uniform value can only be a scalar type // or a Qt3DCore::QNodeId corresponding to a Texture // ShaderData/Buffers would be handled as UBO/SSBO and would therefore // not be in the default uniform block - if (static_cast<QMetaType::Type>(value.userType()) == qNodeIdTypeId) { - // Speed up conversion to avoid using QVariant::value() - const Qt3DCore::QNodeId texId = variant_value<Qt3DCore::QNodeId>(value); + if (value.valueType() == UniformValue::NodeId) { + Texture *tex = nullptr; + const Qt3DCore::QNodeId texId = *value.constData<Qt3DCore::QNodeId>(); if ((tex = m_manager->textureManager()->lookupResource(texId)) != nullptr) { uniformPack.setTexture(nameId, tex->peerId()); - //TextureUniform *texUniform = m_allocator->allocate<TextureUniform>(); - QUniformValue texUniform; - texUniform.setType(QUniformValue::TextureSampler); - texUniform.setTextureId(tex->peerId()); - uniformPack.setUniform(nameId, texUniform); + UniformValue::Texture textureValue; + textureValue.nodeId = texId; + uniformPack.setUniform(nameId, UniformValue(textureValue)); } } else { - uniformPack.setUniform(nameId, QUniformValue(value)); + uniformPack.setUniform(nameId, value); } } @@ -564,14 +561,14 @@ void RenderView::setStandardUniformValue(ShaderParameterPack &uniformPack, int g void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack, Shader *shader, const ShaderUniformBlock &block, - const QVariant &value) const + const UniformValue &value) const { Q_UNUSED(shader) - if (static_cast<QMetaType::Type>(value.userType()) == qNodeIdTypeId) { + if (value.valueType() == UniformValue::NodeId) { Buffer *buffer = nullptr; - if ((buffer = m_manager->bufferManager()->lookupResource(variant_value<Qt3DCore::QNodeId>(value))) != nullptr) { + if ((buffer = m_manager->bufferManager()->lookupResource(*value.constData<Qt3DCore::QNodeId>())) != nullptr) { BlockToUBO uniformBlockUBO; uniformBlockUBO.m_blockIndex = block.m_index; uniformBlockUBO.m_bufferID = buffer->peerId(); @@ -634,12 +631,12 @@ void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack, void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack, Shader *shader, const ShaderStorageBlock &block, - const QVariant &value) const + const UniformValue &value) const { Q_UNUSED(shader) - if (static_cast<QMetaType::Type>(value.userType()) == qNodeIdTypeId) { + if (value.valueType() == UniformValue::NodeId) { Buffer *buffer = nullptr; - if ((buffer = m_manager->bufferManager()->lookupResource(variant_value<Qt3DCore::QNodeId>(value))) != nullptr) { + if ((buffer = m_manager->bufferManager()->lookupResource(*value.constData<Qt3DCore::QNodeId>())) != nullptr) { BlockToSSBO shaderStorageBlock; shaderStorageBlock.m_blockIndex = block.m_index; shaderStorageBlock.m_bufferID = buffer->peerId(); @@ -666,8 +663,9 @@ void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &unif QHash<int, QVariant>::const_iterator activeValuesIt = builder->activeUniformNamesToValue.constBegin(); const QHash<int, QVariant>::const_iterator activeValuesEnd = builder->activeUniformNamesToValue.constEnd(); + // TO DO: Make the ShaderData store UniformValue while (activeValuesIt != activeValuesEnd) { - setUniformValue(uniformPack, activeValuesIt.key(), activeValuesIt.value()); + setUniformValue(uniformPack, activeValuesIt.key(), UniformValue::fromVariant(activeValuesIt.value())); ++activeValuesIt; } } @@ -767,10 +765,10 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass, } else if (shaderStorageBlockNamesIds.indexOf(it->nameId) != -1) { // Parameters is a SSBO setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlockForBlockNameId(it->nameId), it->value); } else { // Parameter is a struct - const QVariant &v = it->value; + const UniformValue &v = it->value; ShaderData *shaderData = nullptr; - if (static_cast<QMetaType::Type>(v.userType()) == qNodeIdTypeId && - (shaderData = m_manager->shaderDataManager()->lookupResource(variant_value<Qt3DCore::QNodeId>(v))) != nullptr) { + if (v.valueType() == UniformValue::NodeId && + (shaderData = m_manager->shaderDataManager()->lookupResource(*v.constData<Qt3DCore::QNodeId>())) != nullptr) { // Try to check if we have a struct or array matching a QShaderData parameter setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, StringToInt::lookupString(it->nameId)); } @@ -795,6 +793,7 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass, if (lightIdx == MAX_LIGHTS) break; + // Note: implicit conversion of values to UniformValue setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[lightIdx], worldPos); setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[lightIdx], int(QAbstractLight::PointLight)); setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[lightIdx], QVector3D(1.0f, 1.0f, 1.0f)); @@ -813,9 +812,10 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass, } if (uniformNamesIds.contains(LIGHT_COUNT_NAME_ID)) - setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, qMax(1, lightIdx)); + setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, UniformValue(qMax(1, lightIdx))); if (activeLightSources.isEmpty()) { + // Note: implicit conversion of values to UniformValue setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[0], QVector3D(10.0f, 10.0f, 0.0f)); setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[0], int(QAbstractLight::PointLight)); setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[0], QVector3D(1.0f, 1.0f, 1.0f)); diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h index 7be9903f6..41b0192c0 100644 --- a/src/render/backend/renderview_p.h +++ b/src/render/backend/renderview_p.h @@ -214,6 +214,9 @@ public: void updateMatrices(); + inline void setRenderCaptureNodeId(const Qt3DCore::QNodeId nodeId) Q_DECL_NOTHROW { m_renderCaptureNodeId = nodeId; } + inline const Qt3DCore::QNodeId renderCaptureNodeId() const Q_DECL_NOTHROW { return m_renderCaptureNodeId; } + // Helps making the size of RenderView smaller // Contains all the data needed for the actual building of the RenderView // But that aren't used later by the Renderer @@ -244,6 +247,8 @@ private: mutable QThreadStorage<UniformBlockValueBuilder*> m_localData; + Qt3DCore::QNodeId m_renderCaptureNodeId; + Renderer *m_renderer; NodeManagers *m_manager; QSize m_surfaceSize; @@ -274,39 +279,39 @@ private: QHash<Qt3DCore::QNodeId, QVector<RenderPassParameterData>> m_parameters; - typedef QHash<int, QUniformValue (RenderView::*)(const QMatrix4x4& model) const> StandardUniformsPFuncsHash; + typedef QHash<int, UniformValue (RenderView::*)(const QMatrix4x4& model) const> StandardUniformsPFuncsHash; static StandardUniformsPFuncsHash ms_standardUniformSetters; static StandardUniformsPFuncsHash initializeStandardUniformSetters(); - QUniformValue modelMatrix(const QMatrix4x4& model) const; - QUniformValue viewMatrix(const QMatrix4x4&) const; - QUniformValue projectionMatrix(const QMatrix4x4 &) const; - QUniformValue modelViewMatrix(const QMatrix4x4 &model) const; - QUniformValue viewProjectionMatrix(const QMatrix4x4 &model) const; - QUniformValue modelViewProjectionMatrix(const QMatrix4x4 &model) const; - QUniformValue inverseModelMatrix(const QMatrix4x4 &model) const; - QUniformValue inverseViewMatrix(const QMatrix4x4 &) const; - QUniformValue inverseProjectionMatrix(const QMatrix4x4 &) const; - QUniformValue inverseModelViewMatrix(const QMatrix4x4 &model) const; - QUniformValue inverseViewProjectionMatrix(const QMatrix4x4 &model) const; - QUniformValue inverseModelViewProjectionMatrix(const QMatrix4x4 &model) const; - QUniformValue modelNormalMatrix(const QMatrix4x4 &model) const; - QUniformValue modelViewNormalMatrix(const QMatrix4x4 &model) const; - QUniformValue viewportMatrix(const QMatrix4x4 &model) const; - QUniformValue inverseViewportMatrix(const QMatrix4x4 &model) const; - QUniformValue time(const QMatrix4x4 &model) const; - QUniformValue eyePosition(const QMatrix4x4 &model) const; - - void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const QVariant &value) const; + UniformValue modelMatrix(const QMatrix4x4& model) const; + UniformValue viewMatrix(const QMatrix4x4&) const; + UniformValue projectionMatrix(const QMatrix4x4 &) const; + UniformValue modelViewMatrix(const QMatrix4x4 &model) const; + UniformValue viewProjectionMatrix(const QMatrix4x4 &model) const; + UniformValue modelViewProjectionMatrix(const QMatrix4x4 &model) const; + UniformValue inverseModelMatrix(const QMatrix4x4 &model) const; + UniformValue inverseViewMatrix(const QMatrix4x4 &) const; + UniformValue inverseProjectionMatrix(const QMatrix4x4 &) const; + UniformValue inverseModelViewMatrix(const QMatrix4x4 &model) const; + UniformValue inverseViewProjectionMatrix(const QMatrix4x4 &model) const; + UniformValue inverseModelViewProjectionMatrix(const QMatrix4x4 &model) const; + UniformValue modelNormalMatrix(const QMatrix4x4 &model) const; + UniformValue modelViewNormalMatrix(const QMatrix4x4 &model) const; + UniformValue viewportMatrix(const QMatrix4x4 &model) const; + UniformValue inverseViewportMatrix(const QMatrix4x4 &model) const; + UniformValue time(const QMatrix4x4 &model) const; + UniformValue eyePosition(const QMatrix4x4 &model) const; + + void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const; void setStandardUniformValue(ShaderParameterPack &uniformPack, int glslNameId, int nameId, const QMatrix4x4 &worldTransform) const; void setUniformBlockValue(ShaderParameterPack &uniformPack, Shader *shader, const ShaderUniformBlock &block, - const QVariant &value) const; + const UniformValue &value) const; void setShaderStorageValue(ShaderParameterPack &uniformPack, Shader *shader, const ShaderStorageBlock &block, - const QVariant &value) const; + const UniformValue &value) const; void setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack, Shader *shader, ShaderData *shaderData, diff --git a/src/render/backend/quniformvalue.cpp b/src/render/backend/shaderparameterpack.cpp index 09327c213..01a977aee 100644 --- a/src/render/backend/quniformvalue.cpp +++ b/src/render/backend/shaderparameterpack.cpp @@ -37,7 +37,7 @@ ** ****************************************************************************/ -#include "quniformvalue_p.h" +#include "shaderparameterpack_p.h" #include <Qt3DRender/private/graphicscontext_p.h> #include <Qt3DRender/private/texture_p.h> @@ -55,42 +55,12 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -void QUniformValue::apply(GraphicsContext *ctx, const ShaderUniform &description) const -{ - switch (m_type) { - case Value: - ctx->bindUniform(m_var, description); - break; - - case TextureSampler: - // We assume that the texture has been successfully bound and attache to a texture unit - if (m_textureIdUnit.m_textureUnit != -1) { - ctx->bindUniform(m_textureIdUnit.m_textureUnit, description); -#if defined(QT3D_RENDER_ASPECT_OPENGL_DEBUG) - int err = ctx->openGLContext()->functions()->glGetError(); - if (err) { - qCWarning(Render::Backend, "Error %d after setting uniform \"%s\" at location %d", - err, qUtf8Printable(description.m_name), description.m_location); - } -#endif - } else { - qCWarning(Render::Backend, "Invalid texture unit supplied for \"%s\"", - qUtf8Printable(description.m_nameId)); - } - break; - - default: - break; - } -} - - ShaderParameterPack::~ShaderParameterPack() { m_uniforms.clear(); } -void ShaderParameterPack::setUniform(const int glslNameId, const QUniformValue &val) +void ShaderParameterPack::setUniform(const int glslNameId, const UniformValue &val) { m_uniforms.insert(glslNameId, val); } diff --git a/src/render/backend/quniformvalue_p.h b/src/render/backend/shaderparameterpack_p.h index fb8158d84..c0ab05e57 100644 --- a/src/render/backend/quniformvalue_p.h +++ b/src/render/backend/shaderparameterpack_p.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef QT3DRENDER_RENDER_QUNIFORMVALUE_H -#define QT3DRENDER_RENDER_QUNIFORMVALUE_H +#ifndef QT3DRENDER_RENDER_SHADERPARAMETERPACK_P_H +#define QT3DRENDER_RENDER_SHADERPARAMETERPACK_P_H // // W A R N I N G @@ -58,6 +58,7 @@ #include <Qt3DCore/qnodeid.h> #include <Qt3DRender/private/renderlogging_p.h> #include <Qt3DRender/private/shadervariables_p.h> +#include <Qt3DRender/private/uniform_p.h> QT_BEGIN_NAMESPACE @@ -72,118 +73,6 @@ namespace Render { class GraphicsContext; -class QUniformValue -{ -public: - enum UniformType { - Value, - TextureSampler, - Unknown - }; - - QUniformValue() - : m_type(Unknown) - , m_var() - { - } - - explicit QUniformValue(const QVariant &var, UniformType type = Value) - : m_type(type) - , m_var(var) - { - } - - void setType(UniformType type) Q_DECL_NOTHROW { m_type = type; } - UniformType type() const Q_DECL_NOTHROW { return m_type; } - bool isTexture() const Q_DECL_NOTHROW { return m_type == TextureSampler; } - - void setValue(const QVariant &value) - { - Q_ASSERT(m_type == Value); - m_var = value; - } - - QVariant value() const - { - Q_ASSERT(m_type == Value); - return m_var; - } - - void setTextureUnit(int textureUnit) - { - Q_ASSERT(m_type == TextureSampler); - m_textureIdUnit.m_textureUnit = textureUnit; - } - - int textureUnit() const - { - Q_ASSERT(m_type == TextureSampler); - return m_textureIdUnit.m_textureUnit; - } - - void setTextureId(Qt3DCore::QNodeId textureId) - { - Q_ASSERT(m_type == TextureSampler); - m_textureIdUnit.m_textureId = textureId; - } - - Qt3DCore::QNodeId textureId() const - { - Q_ASSERT(m_type == TextureSampler); - return m_textureIdUnit.m_textureId; - } - - bool operator ==(const QUniformValue &other) - { - if (other.m_type != m_type) - return false; - - switch (m_type) { - case Value: - return other.m_var == m_var; - case TextureSampler: - return other.m_textureIdUnit == m_textureIdUnit; - default: - break; - } - return false; - } - - bool operator !=(const QUniformValue &other) - { - return !operator ==(other); - } - - void apply(GraphicsContext *ctx, const ShaderUniform &description) const; - -protected: - struct TextureIdUnit { - Qt3DCore::QNodeId m_textureId; - int m_textureUnit; - - TextureIdUnit() - : m_textureId() - , m_textureUnit(-1) - {} - - bool operator == (const TextureIdUnit &other) const Q_DECL_NOTHROW - { - return (other.m_textureId == m_textureId) && (other.m_textureUnit == m_textureUnit); - } - - bool operator !=(const TextureIdUnit &other) const Q_DECL_NOTHROW - { - return !operator ==(other); - } - }; - - // TODO: Replace QVariant with our own union of GLSL types as we don't - // need the full flexibility of QVariant on the backend - UniformType m_type; - QVariant m_var; - TextureIdUnit m_textureIdUnit; -}; - struct BlockToUBO { int m_blockIndex; Qt3DCore::QNodeId m_bufferID; @@ -199,14 +88,14 @@ struct BlockToSSBO { QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, BlockToSSBO, Q_PRIMITIVE_TYPE) -typedef QHash<int, QUniformValue> PackUniformHash; +typedef QHash<int, UniformValue> PackUniformHash; class ShaderParameterPack { public: ~ShaderParameterPack(); - void setUniform(const int glslNameId, const QUniformValue &val); + void setUniform(const int glslNameId, const UniformValue &val); void setTexture(const int glslNameId, Qt3DCore::QNodeId id); void setUniformBuffer(BlockToUBO blockToUBO); void setShaderStorageBuffer(BlockToSSBO blockToSSBO); @@ -214,7 +103,7 @@ public: inline PackUniformHash &uniforms() { return m_uniforms; } inline const PackUniformHash &uniforms() const { return m_uniforms; } - QUniformValue uniform(const int glslNameId) const { return m_uniforms.value(glslNameId); } + UniformValue uniform(const int glslNameId) const { return m_uniforms.value(glslNameId); } struct NamedTexture { @@ -249,4 +138,4 @@ QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, ShaderParameterPack::NamedTexture, Q QT_END_NAMESPACE -#endif // QT3DRENDER_RENDER_QUNIFORMVALUE_H +#endif // QT3DRENDER_RENDER_SHADERPARAMETERPACK_P_H diff --git a/src/render/backend/uniform.cpp b/src/render/backend/uniform.cpp new file mode 100644 index 000000000..3bc1f78ce --- /dev/null +++ b/src/render/backend/uniform.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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 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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "uniform_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { +namespace Render { + +namespace { + +const int qNodeIdTypeId = qMetaTypeId<Qt3DCore::QNodeId>(); + +} + +UniformValue UniformValue::fromVariant(const QVariant &variant) +{ + // Texture/Buffer case + if (variant.userType() == qNodeIdTypeId) + return UniformValue(variant.value<Qt3DCore::QNodeId>()); + + UniformValue v; + switch (variant.userType()) { + case QMetaType::Bool: + v.m_data.ivec[0] = variant.toBool(); + break; + case QMetaType::Int: + case QMetaType::UInt: + case QMetaType::Long: + case QMetaType::LongLong: + case QMetaType::Short: + case QMetaType::ULong: + case QMetaType::ULongLong: + case QMetaType::UShort: + case QMetaType::Char: + case QMetaType::UChar: + v.m_data.ivec[0] = variant.toInt(); + break; + case QMetaType::Float: + case QMetaType::Double: // Convert double to floats + v.m_data.fvec[0] = variant.toFloat(); + break; + case QMetaType::QPoint: { + const QPoint p = variant.toPoint(); + v.m_data.ivec[0] = p.x(); + v.m_data.ivec[1] = p.y(); + break; + } + case QMetaType::QSize: { + const QSize s = variant.toSize(); + v.m_data.ivec[0] = s.width(); + v.m_data.ivec[1] = s.height(); + break; + } + case QMetaType::QRect: { + const QRect r = variant.toRect(); + v.m_data.ivec[0] = r.x(); + v.m_data.ivec[1] = r.y(); + v.m_data.ivec[2] = r.width(); + v.m_data.ivec[3] = r.height(); + break; + } + case QMetaType::QSizeF: { + const QSizeF s = variant.toSize(); + v.m_data.fvec[0] = s.width(); + v.m_data.fvec[1] = s.height(); + break; + } + case QMetaType::QPointF: { + const QPointF p = variant.toPointF(); + v.m_data.fvec[0] = p.x(); + v.m_data.fvec[1] = p.y(); + break; + } + case QMetaType::QRectF: { + const QRectF r = variant.toRect(); + v.m_data.fvec[0] = r.x(); + v.m_data.fvec[1] = r.y(); + v.m_data.fvec[2] = r.width(); + v.m_data.fvec[3] = r.height(); + break; + } + case QMetaType::QVector2D: { + const QVector2D vec2 = variant.value<QVector2D>(); + v.m_data.fvec[0] = vec2.x(); + v.m_data.fvec[1] = vec2.y(); + break; + } + case QMetaType::QVector3D: { + const QVector3D vec3 = variant.value<QVector3D>(); + v.m_data.fvec[0] = vec3.x(); + v.m_data.fvec[1] = vec3.y(); + v.m_data.fvec[2] = vec3.z(); + break; + } + case QMetaType::QVector4D: { + const QVector4D vec4 = variant.value<QVector4D>(); + v.m_data.fvec[0] = vec4.x(); + v.m_data.fvec[1] = vec4.y(); + v.m_data.fvec[2] = vec4.z(); + v.m_data.fvec[3] = vec4.w(); + break; + } + case QMetaType::QColor: { + const QColor col = variant.value<QColor>(); + v.m_data.fvec[0] = col.redF(); + v.m_data.fvec[1] = col.greenF(); + v.m_data.fvec[2] = col.blueF(); + v.m_data.fvec[3] = col.alphaF(); + break; + } + case QMetaType::QMatrix4x4: { + const QMatrix4x4 mat44 = variant.value<QMatrix4x4>(); + // Use constData because we want column-major layout + memcpy(v.data<float>(), mat44.constData(), sizeof(16 * sizeof(float))); + break; + } + default: + Q_UNREACHABLE(); + } + return v; +} + +} // namespace Render +} // namespace Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/backend/uniform_p.h b/src/render/backend/uniform_p.h new file mode 100644 index 000000000..aa4b06bf9 --- /dev/null +++ b/src/render/backend/uniform_p.h @@ -0,0 +1,208 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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 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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DRENDER_RENDER_UNIFORM_P_H +#define QT3DRENDER_RENDER_UNIFORM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qt3drender_global.h> +#include <Qt3DCore/qnodeid.h> + +#include <QMatrix4x4> +#include <QVector2D> +#include <QVector3D> +#include <QColor> + +#include <QDebug> +#include <string.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { +namespace Render { + +enum UniformType { + Float = 0, + Vec2, + Vec3, + Vec4, + Double, + DVec2, + DVec3, + DVec4, + Int, + IVec2, + IVec3, + IVec4, + UInt, + UIVec2, + UIVec3, + UIVec4, + Bool, + BVec2, + BVec3, + BVec4, + Mat2, + Mat3, + Mat4, + Mat2x3, + Mat3x2, + Mat2x4, + Mat4x2, + Mat3x4, + Mat4x3, + Sampler, + Unknown +}; + +class Q_AUTOTEST_EXPORT UniformValue +{ +public: + enum ValueType { + ScalarValue, + NodeId, + TextureValue, + BufferValue + }; + + struct Texture { + int textureId = 0; // Set first so that glUniform1iv will work + Qt3DCore::QNodeId nodeId; + }; + + // UniformValue implicitely converts doubles to floats to ensure + // correct rendering behavior for the cases where Qt3D parameters created from + // a double or QVariant(double) are used to fill uniform values that in reality + // should be floats. This occur especially with QML where qreal might be double + // and not float. Otherwise, at when filling the uniforms, calling constData<float> + // on something that contains a double will result in wrong values + + UniformValue() {} + UniformValue(int i) { m_data.ivec[0] = i; } + UniformValue(uint i) { m_data.ivec[0] = i; } + UniformValue(float f) { m_data.fvec[0] = f; } + UniformValue(double d) { m_data.fvec[0] = d; } // Double to float conversion + UniformValue(bool b) { m_data.ivec[0] = b; } + UniformValue(const QVector2D &vec2) { memcpy(&m_data, &vec2, sizeof(QVector2D)); } + UniformValue(const QVector3D &vec3) { memcpy(&m_data, &vec3, sizeof(QVector3D)); } + UniformValue(const QVector4D &vec4) { memcpy(&m_data, &vec4, sizeof(QVector4D)); } + + UniformValue(const QMatrix3x3 &mat33) + { + // Use constData because we want column-major layout + memcpy(&m_data, mat33.constData(), 9 * sizeof(float)); + } + + UniformValue(const QMatrix4x4 &mat44) + { + // Use constData because we want column-major layout + memcpy(&m_data, mat44.constData(), 16 * sizeof(float)); + } + + // For nodes which will later be replaced by a Texture or Buffer + UniformValue(Qt3DCore::QNodeId id) + { + m_valueType = NodeId; + memcpy(&m_data, &id, sizeof(Qt3DCore::QNodeId)); + } + + // For textures + UniformValue(UniformValue::Texture t) + { + m_valueType = TextureValue; + memcpy(&m_data, &t, sizeof(Texture)); + } + + ValueType valueType() const { return m_valueType; } + + static UniformValue fromVariant(const QVariant &variant); + + template<typename T> + const T *constData() const + { + return reinterpret_cast<const T *>(&m_data); + } + + template<typename T> + T *data() + { + return reinterpret_cast<T *>(&m_data); + } + + bool operator==(const UniformValue &other) const + { + return memcmp(&m_data, &other.m_data, sizeof(u_Uniform)) == 0; + } + + bool operator!=(const UniformValue &other) const + { + return !(*this == other); + } +private: + union u_Uniform { + int ivec[4]; // store uint/ints/bools + float fvec[16]; // for matrix4 (note: we could have a special case for matrices) + + u_Uniform() + { + memset(this, 0, sizeof(u_Uniform)); + } + } m_data; + + ValueType m_valueType = ScalarValue; +}; + +} // namespace Render +} // namespace Qt3DRender + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(Qt3DRender::Render::UniformType) + +#endif // QT3DRENDER_RENDER_UNIFORM_P_H diff --git a/src/render/framegraph/framegraph.pri b/src/render/framegraph/framegraph.pri index 1e4ca3a60..d40da198f 100644 --- a/src/render/framegraph/framegraph.pri +++ b/src/render/framegraph/framegraph.pri @@ -41,7 +41,10 @@ HEADERS += \ $$PWD/qrendersurfaceselector.h \ $$PWD/qrendersurfaceselector_p.h \ $$PWD/rendersurfaceselector_p.h \ - $$PWD/qdispatchcompute_p.h + $$PWD/qdispatchcompute_p.h \ + $$PWD/qrendercapture.h \ + $$PWD/qrendercapture_p.h \ + $$PWD/rendercapture_p.h SOURCES += \ $$PWD/cameraselectornode.cpp \ @@ -72,4 +75,6 @@ SOURCES += \ $$PWD/qdispatchcompute.cpp \ $$PWD/dispatchcompute.cpp \ $$PWD/qrendersurfaceselector.cpp \ - $$PWD/rendersurfaceselector.cpp + $$PWD/rendersurfaceselector.cpp \ + $$PWD/qrendercapture.cpp \ + $$PWD/rendercapture.cpp diff --git a/src/render/framegraph/framegraphnode.cpp b/src/render/framegraph/framegraphnode.cpp index cfdf9834f..5d1df3a8c 100644 --- a/src/render/framegraph/framegraphnode.cpp +++ b/src/render/framegraph/framegraphnode.cpp @@ -53,8 +53,9 @@ FrameGraphNode::FrameGraphNode() { } -FrameGraphNode::FrameGraphNode(FrameGraphNodeType nodeType) - : m_nodeType(nodeType) +FrameGraphNode::FrameGraphNode(FrameGraphNodeType nodeType, QBackendNode::Mode mode) + : BackendNode(mode) + , m_nodeType(nodeType) , m_manager(nullptr) { } diff --git a/src/render/framegraph/framegraphnode_p.h b/src/render/framegraph/framegraphnode_p.h index 62f8d645d..c6e58823b 100644 --- a/src/render/framegraph/framegraphnode_p.h +++ b/src/render/framegraph/framegraphnode_p.h @@ -89,7 +89,8 @@ public: FrustumCulling, Lighting, ComputeDispatch, - Surface + Surface, + RenderCapture }; FrameGraphNodeType nodeType() const { return m_nodeType; } @@ -107,7 +108,7 @@ public: QVector<FrameGraphNode *> children() const; protected: - FrameGraphNode(FrameGraphNodeType nodeType); + FrameGraphNode(FrameGraphNodeType nodeType, QBackendNode::Mode mode = QBackendNode::ReadOnly); void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_OVERRIDE; private: diff --git a/src/render/framegraph/qrendercapture.cpp b/src/render/framegraph/qrendercapture.cpp new file mode 100644 index 000000000..c4a42ff8a --- /dev/null +++ b/src/render/framegraph/qrendercapture.cpp @@ -0,0 +1,290 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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 <Qt3DRender/qrendercapture.h> +#include <Qt3DRender/private/qrendercapture_p.h> +#include <Qt3DCore/QSceneChange> +#include <Qt3DCore/QPropertyUpdatedChange> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +/*! + * \class Qt3DRender::QRenderCapture + * \inmodule Qt3DRender + * + * \brief Frame graph node for render capture + * + * The QRenderCapture is used to capture rendering into an image at any render stage. + * Capturing must be initiated by the user and one image is returned per capture request. + * User can issue multiple render capture requests simultaniously, but only one request + * is served per QRenderCapture instance per frame. + * + * \since 5.8 + */ + +/*! + * \qmltype RenderCapture + * \instantiates Qt3DRender::QRenderCapture + * \inherits FrameGraphNode + * \inqmlmodule Qt3D.Render + * \since 5.8 + * \brief Capture rendering + */ + +/*! + * \class Qt3DRender::QRenderCaptureReply + * \inmodule Qt3DRender + * + * \brief Receives the result of render capture request. + * + * An object, which receives the image from QRenderCapture::requestCapture. + * + * \since 5.8 + */ + +/*! + * \qmltype RenderCaptureReply + * \instantiates Qt3DRender::QRenderCaptureReply + * \inherits QObject + * \inqmlmodule Qt3D.Render + * \since 5.8 + * \brief Receives render capture result. + */ + +/*! + * \qmlproperty variant Qt3D.Render::RenderCaptureReply::image + * + * Holds the image, which was produced as a result of render capture. + */ + +/*! + * \qmlproperty int Qt3D.Render::RenderCaptureReply::captureId + * + * Holds the captureId, which was passed to the renderCapture. + */ + +/*! + * \qmlproperty bool Qt3D.Render::RenderCaptureReply::complete + * + * Holds the complete state of the render capture. + */ + +/*! + * \qmlmethod void Qt3D.Render::RenderCaptureReply::saveToFile(fileName) + * + * Saves the render capture result as an image to \a fileName. + */ + +/*! + * \qmlmethod RenderCaptureReply Qt3D.Render::RenderCapture::requestCapture(int captureId) + * + * Used to request render capture. User can specify a \a captureId to identify + * the request. The requestId does not have to be unique. Only one render capture result + * is produced per requestCapture call even if the frame graph has multiple leaf nodes. + * The function returns a QRenderCaptureReply object, which receives the captured image + * when it is done. The user is reponsible for deallocating the returned object. + */ + +/*! + * \internal + */ +QRenderCaptureReplyPrivate::QRenderCaptureReplyPrivate() + : QObjectPrivate() + , m_captureId(0) + , m_complete(false) +{ + +} + +/*! + * The constructor creates an instance with the specified \a parent. + */ +QRenderCaptureReply::QRenderCaptureReply(QObject *parent) + : QObject(* new QRenderCaptureReplyPrivate, parent) +{ + +} + +/*! + * \property QRenderCaptureReply::image + * + * Holds the image, which was produced as a result of render capture. + */ +QImage QRenderCaptureReply::image() const +{ + Q_D(const QRenderCaptureReply); + return d->m_image; +} + +/*! + * \property QRenderCaptureReply::captureId + * + * Holds the captureId, which was passed to the renderCapture. + */ +int QRenderCaptureReply::captureId() const +{ + Q_D(const QRenderCaptureReply); + return d->m_captureId; +} + +/*! + * \property QRenderCaptureReply::complete + * + * Holds the complete state of the render capture. + */ +bool QRenderCaptureReply::isComplete() const +{ + Q_D(const QRenderCaptureReply); + return d->m_complete; +} + +/*! + * Saves the render capture result as an image to \a fileName. + */ +void QRenderCaptureReply::saveToFile(const QString &fileName) const +{ + Q_D(const QRenderCaptureReply); + if (d->m_complete) + d->m_image.save(fileName); +} + +/*! + * \internal + */ +QRenderCapturePrivate::QRenderCapturePrivate() + : QFrameGraphNodePrivate() +{ +} + +/*! + * \internal + */ +QRenderCaptureReply *QRenderCapturePrivate::createReply(int captureId) +{ + QRenderCaptureReply *reply = new QRenderCaptureReply(); + reply->d_func()->m_captureId = captureId; + m_waitingReplies.push_back(reply); + return reply; +} + +/*! + * \internal + */ +QRenderCaptureReply *QRenderCapturePrivate::takeReply(int captureId) +{ + QRenderCaptureReply *reply = nullptr; + for (int i = 0; i < m_waitingReplies.size(); ++i) { + if (m_waitingReplies[i]->captureId() == captureId) { + reply = m_waitingReplies[i]; + m_waitingReplies.remove(i); + break; + } + } + return reply; +} + +/*! + * \internal + */ +void QRenderCapturePrivate::setImage(QRenderCaptureReply *reply, const QImage &image) +{ + reply->d_func()->m_complete = true; + reply->d_func()->m_image = image; +} + +/*! + * The constructor creates an instance with the specified \a parent. + */ +QRenderCapture::QRenderCapture(Qt3DCore::QNode *parent) + : QFrameGraphNode(*new QRenderCapturePrivate, parent) +{ +} + +/*! + * Used to request render capture. User can specify a \a captureId to identify + * the request. The requestId does not have to be unique. Only one render capture result + * is produced per requestCapture call even if the frame graph has multiple leaf nodes. + * The function returns a QRenderCaptureReply object, which receives the captured image + * when it is done. The user is reponsible for deallocating the returned object. + */ +QRenderCaptureReply *QRenderCapture::requestCapture(int captureId) +{ + Q_D(QRenderCapture); + QRenderCaptureReply *reply = d->createReply(captureId); + + Qt3DCore::QPropertyUpdatedChangePtr change(new Qt3DCore::QPropertyUpdatedChange(id())); + change->setPropertyName(QByteArrayLiteral("renderCaptureRequest")); + change->setValue(QVariant::fromValue(captureId)); + d->notifyObservers(change); + + return reply; +} + +/*! + * \internal + */ +void QRenderCapture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) +{ + Q_D(QRenderCapture); + Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change); + if (propertyChange->type() == Qt3DCore::PropertyUpdated) { + if (propertyChange->propertyName() == QByteArrayLiteral("renderCaptureData")) { + RenderCaptureDataPtr data = propertyChange->value().value<RenderCaptureDataPtr>(); + QRenderCaptureReply *reply = d->takeReply(data.data()->captureId); + if (reply) { + d->setImage(reply, data.data()->image); + emit reply->completeChanged(true); + } + } + } +} + +/*! + * \internal + */ +Qt3DCore::QNodeCreatedChangeBasePtr QRenderCapture::createNodeCreationChange() const +{ + auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QRenderCaptureInitData>::create(this); + QRenderCaptureInitData &data = creationChange->data; + data.captureId = 0; + return creationChange; +} + +} // Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/framegraph/qrendercapture.h b/src/render/framegraph/qrendercapture.h new file mode 100644 index 000000000..f3be273f3 --- /dev/null +++ b/src/render/framegraph/qrendercapture.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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$ +** +****************************************************************************/ + +#ifndef QRENDERCAPTURE_H +#define QRENDERCAPTURE_H + +#include <Qt3DRender/QFrameGraphNode> +#include <QImage> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QRenderCapturePrivate; +class QRenderCaptureReplyPrivate; + +class QT3DRENDERSHARED_EXPORT QRenderCaptureReply : public QObject +{ + Q_OBJECT + Q_PROPERTY(QImage image READ image CONSTANT) + Q_PROPERTY(int captureId READ captureId CONSTANT) + Q_PROPERTY(bool complete READ isComplete NOTIFY completeChanged) + +public: + + QImage image() const; + int captureId() const; + bool isComplete() const; + + Q_INVOKABLE void saveToFile(const QString &fileName) const; + +Q_SIGNALS: + void completeChanged(bool isComplete); + +private: + Q_DECLARE_PRIVATE(QRenderCaptureReply) + + QRenderCaptureReply(QObject *parent = nullptr); + + friend class QRenderCapturePrivate; +}; + +class QT3DRENDERSHARED_EXPORT QRenderCapture : public QFrameGraphNode +{ + Q_OBJECT +public: + explicit QRenderCapture(Qt3DCore::QNode *parent = nullptr); + + Q_INVOKABLE Qt3DRender::QRenderCaptureReply *requestCapture(int captureId); + +protected: + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE; + +private: + Q_DECLARE_PRIVATE(QRenderCapture) + Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE; +}; + +} // Qt3DRender + +QT_END_NAMESPACE + +#endif // QRENDERCAPTURE_H diff --git a/src/render/framegraph/qrendercapture_p.h b/src/render/framegraph/qrendercapture_p.h new file mode 100644 index 000000000..09d983ede --- /dev/null +++ b/src/render/framegraph/qrendercapture_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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$ +** +****************************************************************************/ + +#ifndef QRENDERCAPTURE_P_H +#define QRENDERCAPTURE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DRender/qrendercapture.h> +#include <Qt3DRender/private/qframegraphnode_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QRenderCapturePrivate : public QFrameGraphNodePrivate +{ +public: + QRenderCapturePrivate(); + QVector<QRenderCaptureReply *> m_waitingReplies; + + QRenderCaptureReply *createReply(int captureId); + QRenderCaptureReply *takeReply(int captureId); + void setImage(QRenderCaptureReply *reply, const QImage &image); + + Q_DECLARE_PUBLIC(QRenderCapture) +}; + +class QRenderCaptureReplyPrivate : public QObjectPrivate +{ +public: + QRenderCaptureReplyPrivate(); + + QImage m_image; + int m_captureId; + bool m_complete; + + Q_DECLARE_PUBLIC(QRenderCaptureReply) +}; + +// used by initializeFromPeer +struct QRenderCaptureInitData +{ + int captureId; +}; + +// used by backend to send render capture to frontend +struct RenderCaptureData +{ + QImage image; + int captureId; +}; + +typedef QSharedPointer<RenderCaptureData> RenderCaptureDataPtr; + +} // Qt3DRender + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(Qt3DRender::RenderCaptureDataPtr) + +#endif // QRENDERCAPTURE_P_H diff --git a/src/render/framegraph/qrendersurfaceselector.cpp b/src/render/framegraph/qrendersurfaceselector.cpp index 27d06e264..905669ff9 100644 --- a/src/render/framegraph/qrendersurfaceselector.cpp +++ b/src/render/framegraph/qrendersurfaceselector.cpp @@ -269,9 +269,8 @@ void QRenderSurfaceSelector::setSurface(QObject *surfaceObject) } }); d->m_screenConn = QObject::connect(window, &QWindow::screenChanged, [=] (QScreen *screen) { - if (screen && surfacePixelRatio() != screen->devicePixelRatio()) { - setSurfacePixelRatio(screen->devicePixelRatio()); - } + if (screen && surfacePixelRatio() != screen->devicePixelRatio()) + setSurfacePixelRatio(screen->devicePixelRatio()); }); } diff --git a/src/render/framegraph/qrendersurfaceselector.h b/src/render/framegraph/qrendersurfaceselector.h index ea8b93e8d..eae221800 100644 --- a/src/render/framegraph/qrendersurfaceselector.h +++ b/src/render/framegraph/qrendersurfaceselector.h @@ -57,7 +57,7 @@ class QT3DRENDERSHARED_EXPORT QRenderSurfaceSelector : public Qt3DRender::QFrame { Q_OBJECT Q_PROPERTY(QObject *surface READ surface WRITE setSurface NOTIFY surfaceChanged) - Q_PROPERTY(QSize externalRenderTargetSize READ externalRenderTargetSize NOTIFY externalRenderTargetSizeChanged) + Q_PROPERTY(QSize externalRenderTargetSize READ externalRenderTargetSize WRITE setExternalRenderTargetSize NOTIFY externalRenderTargetSizeChanged) Q_PROPERTY(float surfacePixelRatio READ surfacePixelRatio WRITE setSurfacePixelRatio NOTIFY surfacePixelRatioChanged) public: @@ -66,12 +66,12 @@ public: QObject *surface() const; QSize externalRenderTargetSize() const; - void setExternalRenderTargetSize(const QSize &size); float surfacePixelRatio() const; public Q_SLOTS: void setSurface(QObject *surfaceObject); void setSurfacePixelRatio(float ratio); + void setExternalRenderTargetSize(const QSize &size); Q_SIGNALS: void surfaceChanged(QObject *surface); diff --git a/src/render/framegraph/rendercapture.cpp b/src/render/framegraph/rendercapture.cpp new file mode 100644 index 000000000..250666939 --- /dev/null +++ b/src/render/framegraph/rendercapture.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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 <Qt3DRender/private/qrendercapture_p.h> +#include <Qt3DRender/private/rendercapture_p.h> +#include <Qt3DCore/qpropertyupdatedchange.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace Render { + +RenderCapture::RenderCapture() + : FrameGraphNode(FrameGraphNode::RenderCapture, QBackendNode::ReadWrite) +{ + +} + +bool RenderCapture::wasCaptureRequested() const +{ + return m_requestedCaptures.size() > 0 && isEnabled(); +} + +void RenderCapture::acknowledgeCaptureRequest() +{ + m_acknowledgedCaptures.push_back(m_requestedCaptures.takeFirst()); +} + +void RenderCapture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) +{ + if (e->type() == Qt3DCore::PropertyUpdated) { + Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(e); + if (propertyChange->propertyName() == QByteArrayLiteral("renderCaptureRequest")) { + QMutexLocker lock(&m_mutex); + m_requestedCaptures.push_back(propertyChange->value().toInt()); + } + } + markDirty(AbstractRenderer::AllDirty); + FrameGraphNode::sceneChangeEvent(e); +} + +// called by render thread +void RenderCapture::addRenderCapture(const QImage &image) +{ + QMutexLocker lock(&m_mutex); + auto data = RenderCaptureDataPtr::create(); + data.data()->captureId = m_acknowledgedCaptures.takeFirst(); + data.data()->image = image; + m_renderCaptureData.push_back(data); +} + +// called by send render capture job thread +void RenderCapture::sendRenderCaptures() +{ + QMutexLocker lock(&m_mutex); + + for (const RenderCaptureDataPtr data : m_renderCaptureData) { + auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); + e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); + e->setPropertyName("renderCaptureData"); + e->setValue(QVariant::fromValue(data)); + notifyObservers(e); + } + m_renderCaptureData.clear(); +} + +} // Render + +} // Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/framegraph/rendercapture_p.h b/src/render/framegraph/rendercapture_p.h new file mode 100644 index 000000000..97bdc9d8b --- /dev/null +++ b/src/render/framegraph/rendercapture_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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$ +** +****************************************************************************/ + +#ifndef RENDERCAPTURE_P_H +#define RENDERCAPTURE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DRender/private/qrendercapture_p.h> +#include <Qt3DRender/private/framegraphnode_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace Render { + +class RenderCapture : public FrameGraphNode +{ +public: + RenderCapture(); + + bool wasCaptureRequested() const; + void acknowledgeCaptureRequest(); + void addRenderCapture(const QImage &image); + void sendRenderCaptures(); + +protected: + virtual void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e); + +private: + + QVector<int> m_requestedCaptures; + QVector<int> m_acknowledgedCaptures; + QVector<RenderCaptureDataPtr> m_renderCaptureData; + QMutex m_mutex; +}; + +} // Render + +} // Qt3DRender + +QT_END_NAMESPACE + +#endif // RENDERCAPTURE_P_H diff --git a/src/render/frontend/qpickingsettings.cpp b/src/render/frontend/qpickingsettings.cpp index e1c403ba3..c1524547c 100644 --- a/src/render/frontend/qpickingsettings.cpp +++ b/src/render/frontend/qpickingsettings.cpp @@ -70,6 +70,7 @@ QPickingSettingsPrivate::QPickingSettingsPrivate() : Qt3DCore::QNodePrivate() , m_pickMethod(QPickingSettings::BoundingVolumePicking) , m_pickResultMode(QPickingSettings::NearestPick) + , m_faceOrientationPickingMode(QPickingSettings::FrontFace) { } @@ -102,6 +103,15 @@ QPickingSettings::PickResultMode QPickingSettings::pickResultMode() const } /*! + * \return the back facing picking flag + */ +QPickingSettings::FaceOrientationPickingMode QPickingSettings::faceOrientationPickingMode() const +{ + Q_D(const QPickingSettings); + return d->m_faceOrientationPickingMode; +} + +/*! * \enum Qt3DRender::QPickingSettings::PickMethod * * Specifies the picking method. @@ -176,6 +186,20 @@ void QPickingSettings::setPickResultMode(QPickingSettings::PickResultMode pickRe emit pickResultModeChanged(pickResultMode); } +/*! + * Sets whether back facing faces are picked or not + * \param faceOrientationPickingMode + */ +void QPickingSettings::setFaceOrientationPickingMode(QPickingSettings::FaceOrientationPickingMode faceOrientationPickingMode) +{ + Q_D(QPickingSettings); + if (d->m_faceOrientationPickingMode == faceOrientationPickingMode) + return; + + d->m_faceOrientationPickingMode = faceOrientationPickingMode; + emit faceOrientationPickingModeChanged(faceOrientationPickingMode); +} + } // namespace Qt3Drender QT_END_NAMESPACE diff --git a/src/render/frontend/qpickingsettings.h b/src/render/frontend/qpickingsettings.h index a530a4b33..ebafcd07f 100644 --- a/src/render/frontend/qpickingsettings.h +++ b/src/render/frontend/qpickingsettings.h @@ -54,6 +54,7 @@ class QT3DRENDERSHARED_EXPORT QPickingSettings : public Qt3DCore::QNode Q_OBJECT Q_PROPERTY(PickMethod pickMethod READ pickMethod WRITE setPickMethod NOTIFY pickMethodChanged) Q_PROPERTY(PickResultMode pickResultMode READ pickResultMode WRITE setPickResultMode NOTIFY pickResultModeChanged) + Q_PROPERTY(FaceOrientationPickingMode faceOrientationPickingMode READ faceOrientationPickingMode WRITE setFaceOrientationPickingMode NOTIFY faceOrientationPickingModeChanged) public: explicit QPickingSettings(Qt3DCore::QNode *parent = nullptr); @@ -71,16 +72,26 @@ public: }; Q_ENUM(PickResultMode) + enum FaceOrientationPickingMode { + FrontFace = 0x01, + BackFace = 0x02, + FrontAndBackFace = 0x03 + }; + Q_ENUM(FaceOrientationPickingMode) + PickMethod pickMethod() const; PickResultMode pickResultMode() const; + FaceOrientationPickingMode faceOrientationPickingMode() const; public Q_SLOTS: void setPickMethod(PickMethod pickMethod); void setPickResultMode(PickResultMode pickResultMode); + void setFaceOrientationPickingMode(FaceOrientationPickingMode faceOrientationPickingMode); Q_SIGNALS: void pickMethodChanged(QPickingSettings::PickMethod pickMethod); void pickResultModeChanged(QPickingSettings::PickResultMode pickResult); + void faceOrientationPickingModeChanged(QPickingSettings::FaceOrientationPickingMode faceOrientationPickingMode); protected: Q_DECLARE_PRIVATE(QPickingSettings) diff --git a/src/render/frontend/qpickingsettings_p.h b/src/render/frontend/qpickingsettings_p.h index 57c989606..039b6a435 100644 --- a/src/render/frontend/qpickingsettings_p.h +++ b/src/render/frontend/qpickingsettings_p.h @@ -65,6 +65,7 @@ public: QPickingSettings::PickMethod m_pickMethod; QPickingSettings::PickResultMode m_pickResultMode; + QPickingSettings::FaceOrientationPickingMode m_faceOrientationPickingMode; }; } // namespace Qt3Drender diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index f6d26fb22..1c6498511 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -76,7 +76,7 @@ #include <Qt3DRender/qcomputecommand.h> #include <Qt3DRender/qrendersurfaceselector.h> #include <Qt3DRender/qrendersettings.h> - +#include <Qt3DRender/qrendercapture.h> #include <Qt3DRender/private/cameraselectornode_p.h> #include <Qt3DRender/private/layerfilternode_p.h> #include <Qt3DRender/private/filterkey_p.h> @@ -119,6 +119,7 @@ #include <Qt3DRender/private/rendersurfaceselector_p.h> #include <Qt3DRender/private/rendersettings_p.h> #include <Qt3DRender/private/backendnode_p.h> +#include <Qt3DRender/private/rendercapture_p.h> #include <Qt3DCore/qentity.h> #include <Qt3DCore/qtransform.h> @@ -223,6 +224,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType<QSortPolicy>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::SortPolicy, QSortPolicy> >::create(m_renderer, m_nodeManagers->frameGraphManager())); q->registerBackendType<QTechniqueFilter>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::TechniqueFilter, QTechniqueFilter> >::create(m_renderer, m_nodeManagers->frameGraphManager())); q->registerBackendType<QViewport>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ViewportNode, QViewport> >::create(m_renderer, m_nodeManagers->frameGraphManager())); + q->registerBackendType<QRenderCapture>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::RenderCapture, QRenderCapture> >::create(m_renderer, m_nodeManagers->frameGraphManager())); // Picking q->registerBackendType<QObjectPicker>(QSharedPointer<Render::NodeFunctor<Render::ObjectPicker, Render::ObjectPickerManager> >::create(m_renderer, m_nodeManagers->objectPickerManager())); @@ -278,6 +280,7 @@ void QRenderAspectPrivate::unregisterBackendTypes() unregisterBackendType<QSortPolicy>(); unregisterBackendType<QTechniqueFilter>(); unregisterBackendType<QViewport>(); + unregisterBackendType<QRenderCapture>(); // Picking unregisterBackendType<QObjectPicker>(); diff --git a/src/render/frontend/qrendersettings.cpp b/src/render/frontend/qrendersettings.cpp index d9ce3c3c9..616c3a64e 100644 --- a/src/render/frontend/qrendersettings.cpp +++ b/src/render/frontend/qrendersettings.cpp @@ -87,6 +87,8 @@ void QRenderSettingsPrivate::init() q, SLOT(_q_onPickingMethodChanged(QPickingSettings::PickMethod))); QObject::connect(&m_pickingSettings, SIGNAL(pickResultModeChanged(QPickingSettings::PickResultMode)), q, SLOT(_q_onPickResultModeChanged(QPickingSettings::PickResultMode))); + QObject::connect(&m_pickingSettings, SIGNAL(faceOrientationPickingModeChanged(QPickingSettings::FaceOrientationPickingMode)), + q, SLOT(_q_onFaceOrientationPickingModeChanged(QPickingSettings::FaceOrientationPickingMode))); } /*! \internal */ @@ -101,6 +103,12 @@ void QRenderSettingsPrivate::_q_onPickResultModeChanged(QPickingSettings::PickRe notifyPropertyChange("pickResultMode", pickResultMode); } +/*! \internal */ +void QRenderSettingsPrivate::_q_onFaceOrientationPickingModeChanged(QPickingSettings::FaceOrientationPickingMode faceOrientationPickingMode) +{ + notifyPropertyChange("faceOrientationPickingMode", faceOrientationPickingMode); +} + QRenderSettings::QRenderSettings(Qt3DCore::QNode *parent) : QRenderSettings(*new QRenderSettingsPrivate, parent) {} @@ -228,6 +236,7 @@ Qt3DCore::QNodeCreatedChangeBasePtr QRenderSettings::createNodeCreationChange() data.renderPolicy = d->m_renderPolicy; data.pickMethod = d->m_pickingSettings.pickMethod(); data.pickResultMode = d->m_pickingSettings.pickResultMode(); + data.faceOrientationPickingMode = d->m_pickingSettings.faceOrientationPickingMode(); return creationChange; } diff --git a/src/render/frontend/qrendersettings.h b/src/render/frontend/qrendersettings.h index 55fe3007a..68e8f8d7f 100644 --- a/src/render/frontend/qrendersettings.h +++ b/src/render/frontend/qrendersettings.h @@ -89,6 +89,7 @@ protected: private: Q_PRIVATE_SLOT(d_func(), void _q_onPickingMethodChanged(QPickingSettings::PickMethod)) Q_PRIVATE_SLOT(d_func(), void _q_onPickResultModeChanged(QPickingSettings::PickResultMode)) + Q_PRIVATE_SLOT(d_func(), void _q_onFaceOrientationPickingModeChanged(QPickingSettings::FaceOrientationPickingMode)) Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE; }; diff --git a/src/render/frontend/qrendersettings_p.h b/src/render/frontend/qrendersettings_p.h index efbd7f8f1..f05124296 100644 --- a/src/render/frontend/qrendersettings_p.h +++ b/src/render/frontend/qrendersettings_p.h @@ -72,6 +72,7 @@ public: void _q_onPickingMethodChanged(QPickingSettings::PickMethod pickMethod); void _q_onPickResultModeChanged(QPickingSettings::PickResultMode pickResultMode); + void _q_onFaceOrientationPickingModeChanged(QPickingSettings::FaceOrientationPickingMode faceOrientationPickingMode); Q_DECLARE_PUBLIC(QRenderSettings) }; @@ -82,6 +83,7 @@ struct QRenderSettingsData QRenderSettings::RenderPolicy renderPolicy; QPickingSettings::PickMethod pickMethod; QPickingSettings::PickResultMode pickResultMode; + QPickingSettings::FaceOrientationPickingMode faceOrientationPickingMode; }; } // namespace Qt3Drender diff --git a/src/render/frontend/qrendertargetoutput.h b/src/render/frontend/qrendertargetoutput.h index 1f78dd279..0f8f11156 100644 --- a/src/render/frontend/qrendertargetoutput.h +++ b/src/render/frontend/qrendertargetoutput.h @@ -58,7 +58,7 @@ class QT3DRENDERSHARED_EXPORT QRenderTargetOutput : public Qt3DCore::QNode Q_PROPERTY(QAbstractTexture *texture READ texture WRITE setTexture NOTIFY textureChanged) Q_PROPERTY(int mipLevel READ mipLevel WRITE setMipLevel NOTIFY mipLevelChanged) Q_PROPERTY(int layer READ layer WRITE setLayer NOTIFY layerChanged) - Q_PROPERTY(QAbstractTexture::CubeMapFace face READ face WRITE setFace NOTIFY faceChanged) + Q_PROPERTY(Qt3DRender::QAbstractTexture::CubeMapFace face READ face WRITE setFace NOTIFY faceChanged) public: enum AttachmentPoint { diff --git a/src/render/geometry/attribute.cpp b/src/render/geometry/attribute.cpp index 85c69cdb7..7e1ea79dd 100644 --- a/src/render/geometry/attribute.cpp +++ b/src/render/geometry/attribute.cpp @@ -53,7 +53,7 @@ namespace Render { Attribute::Attribute() : BackendNode(ReadOnly) , m_nameId(0) - , m_vertexDataType(QAttribute::Float) + , m_vertexBaseType(QAttribute::Float) , m_vertexSize(1) , m_count(0) , m_byteStride(0) @@ -70,7 +70,7 @@ Attribute::~Attribute() void Attribute::cleanup() { - m_vertexDataType = QAttribute::Float; + m_vertexBaseType = QAttribute::Float; m_vertexSize = 1; m_count = 0; m_byteStride = 0; @@ -90,8 +90,8 @@ void Attribute::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &ch m_bufferId = data.bufferId; m_name = data.name; m_nameId = StringToInt::lookupId(m_name); - m_vertexDataType = data.dataType; - m_vertexSize = data.dataSize; + m_vertexBaseType = data.vertexBaseType; + m_vertexSize = data.vertexSize; m_count = data.count; m_byteStride = data.byteStride; m_byteOffset = data.byteOffset; @@ -112,7 +112,7 @@ void Attribute::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_nameId = StringToInt::lookupId(m_name); m_attributeDirty = true; } else if (propertyName == QByteArrayLiteral("vertexBaseType")) { - m_vertexDataType = static_cast<QAttribute::VertexBaseType>(propertyChange->value().value<int>()); + m_vertexBaseType = static_cast<QAttribute::VertexBaseType>(propertyChange->value().value<int>()); m_attributeDirty = true; } else if (propertyName == QByteArrayLiteral("vertexSize")) { m_vertexSize = propertyChange->value().value<uint>(); diff --git a/src/render/geometry/attribute_p.h b/src/render/geometry/attribute_p.h index 6364639dd..1b639f42f 100644 --- a/src/render/geometry/attribute_p.h +++ b/src/render/geometry/attribute_p.h @@ -73,7 +73,7 @@ public: inline Qt3DCore::QNodeId bufferId() const { return m_bufferId; } inline QString name() const { return m_name; } inline int nameId() const { return m_nameId; } - inline QAttribute::VertexBaseType vertexBaseType() const { return m_vertexDataType; } + inline QAttribute::VertexBaseType vertexBaseType() const { return m_vertexBaseType; } inline uint vertexSize() const { return m_vertexSize; } inline uint count() const { return m_count; } inline uint byteStride() const { return m_byteStride; } @@ -89,7 +89,7 @@ private: Qt3DCore::QNodeId m_bufferId; QString m_name; int m_nameId; - QAttribute::VertexBaseType m_vertexDataType; + QAttribute::VertexBaseType m_vertexBaseType; uint m_vertexSize; uint m_count; uint m_byteStride; diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp index 8c897dd2b..aaae9825f 100644 --- a/src/render/geometry/buffer.cpp +++ b/src/render/geometry/buffer.cpp @@ -70,6 +70,7 @@ void Buffer::cleanup() m_type = QBuffer::VertexBuffer; m_usage = QBuffer::StaticDraw; m_data.clear(); + m_bufferUpdates.clear(); m_functor.reset(); m_bufferDirty = false; m_syncData = false; @@ -120,6 +121,10 @@ void Buffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) QByteArray newData = propertyChange->value().value<QByteArray>(); m_bufferDirty |= m_data != newData; m_data = newData; + } else if (propertyName == QByteArrayLiteral("updateData")) { + Qt3DRender::QBufferUpdate updateData = propertyChange->value().value<Qt3DRender::QBufferUpdate>(); + m_bufferUpdates.push_back(updateData); + m_bufferDirty = true; } else if (propertyName == QByteArrayLiteral("type")) { m_type = static_cast<QBuffer::BufferType>(propertyChange->value().value<int>()); m_bufferDirty = true; diff --git a/src/render/geometry/buffer_p.h b/src/render/geometry/buffer_p.h index d6bfe1d8f..d474c1720 100644 --- a/src/render/geometry/buffer_p.h +++ b/src/render/geometry/buffer_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <QtCore> #include <Qt3DRender/private/backendnode_p.h> #include <Qt3DRender/qbuffer.h> #include <Qt3DRender/qbufferdatagenerator.h> @@ -59,6 +60,8 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { +class QBufferUpdate; + namespace Render { class BufferManager; @@ -74,10 +77,10 @@ public: void setManager(BufferManager *manager); void executeFunctor(); - inline QBuffer::BufferType type() const { return m_type; } inline QBuffer::UsageType usage() const { return m_usage; } inline QByteArray data() const { return m_data; } + inline QVector<Qt3DRender::QBufferUpdate> &pendingBufferUpdates() { return m_bufferUpdates; } inline bool isDirty() const { return m_bufferDirty; } inline QBufferDataGeneratorPtr dataGenerator() const { return m_functor; } inline bool isSyncData() const { return m_syncData; } @@ -89,6 +92,7 @@ private: QBuffer::BufferType m_type; QBuffer::UsageType m_usage; QByteArray m_data; + QVector<Qt3DRender::QBufferUpdate> m_bufferUpdates; bool m_bufferDirty; bool m_syncData; QBufferDataGeneratorPtr m_functor; diff --git a/src/render/geometry/qattribute.cpp b/src/render/geometry/qattribute.cpp index 62d8717d0..ef439f2b4 100644 --- a/src/render/geometry/qattribute.cpp +++ b/src/render/geometry/qattribute.cpp @@ -51,8 +51,8 @@ QAttributePrivate::QAttributePrivate() : QNodePrivate() , m_buffer(nullptr) , m_name() - , m_dataType(QAttribute::Float) - , m_dataSize(1) + , m_vertexBaseType(QAttribute::Float) + , m_vertexSize(1) , m_count(0) , m_byteStride(0) , m_byteOffset(0) @@ -138,8 +138,8 @@ QAttribute::QAttribute(QBuffer *buf, VertexBaseType type, uint dataSize, uint co setBuffer(buf); d->m_count = count; d->m_byteOffset = offset; - d->m_dataType = type; - d->m_dataSize = dataSize; + d->m_vertexBaseType = type; + d->m_vertexSize = dataSize; d->m_byteStride = stride; } @@ -156,8 +156,8 @@ QAttribute::QAttribute(QBuffer *buf, const QString &name, VertexBaseType type, u d->m_name = name; d->m_count = count; d->m_byteOffset = offset; - d->m_dataType = type; - d->m_dataSize = dataSize; + d->m_vertexBaseType = type; + d->m_vertexSize = dataSize; d->m_byteStride = stride; } @@ -197,7 +197,7 @@ QString QAttribute::name() const uint QAttribute::vertexSize() const { Q_D(const QAttribute); - return d->m_dataSize; + return d->m_vertexSize; } /*! @@ -208,7 +208,7 @@ uint QAttribute::vertexSize() const QAttribute::VertexBaseType QAttribute::vertexBaseType() const { Q_D(const QAttribute); - return d->m_dataType; + return d->m_vertexBaseType; } /*! @@ -301,27 +301,39 @@ void QAttribute::setName(const QString &name) emit nameChanged(name); } -void QAttribute::setDataType(VertexBaseType type) +void QAttribute::setVertexBaseType(VertexBaseType type) { Q_D(QAttribute); - if (d->m_dataType == type) + if (d->m_vertexBaseType == type) return; - d->m_dataType = type; + d->m_vertexBaseType = type; + emit vertexBaseTypeChanged(type); emit dataTypeChanged(type); } -void QAttribute::setDataSize(uint size) +void QAttribute::setVertexSize(uint size) { Q_D(QAttribute); - if (d->m_dataSize == size) + if (d->m_vertexSize == size) return; Q_ASSERT((size >= 1 && size <= 4) || (size == 9) || (size == 16)); - d->m_dataSize = size; + d->m_vertexSize = size; + emit vertexSizeChanged(size); emit dataSizeChanged(size); } +void QAttribute::setDataType(VertexBaseType type) +{ + setVertexBaseType(type); +} + +void QAttribute::setDataSize(uint size) +{ + setVertexSize(size); +} + void QAttribute::setCount(uint count) { Q_D(QAttribute); @@ -419,8 +431,8 @@ Qt3DCore::QNodeCreatedChangeBasePtr QAttribute::createNodeCreationChange() const Q_D(const QAttribute); data.bufferId = qIdForNode(d->m_buffer); data.name = d->m_name; - data.dataType = d->m_dataType; - data.dataSize = d->m_dataSize; + data.vertexBaseType = d->m_vertexBaseType; + data.vertexSize = d->m_vertexSize; data.count = d->m_count; data.byteStride = d->m_byteStride; data.byteOffset = d->m_byteOffset; diff --git a/src/render/geometry/qattribute.h b/src/render/geometry/qattribute.h index e6b525dc4..e907c64e1 100644 --- a/src/render/geometry/qattribute.h +++ b/src/render/geometry/qattribute.h @@ -58,8 +58,8 @@ class QT3DRENDERSHARED_EXPORT QAttribute : public Qt3DCore::QNode Q_OBJECT Q_PROPERTY(Qt3DRender::QBuffer *buffer READ buffer WRITE setBuffer NOTIFY bufferChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) - Q_PROPERTY(VertexBaseType vertexBaseType READ vertexBaseType WRITE setDataType NOTIFY dataTypeChanged) - Q_PROPERTY(uint vertexSize READ vertexSize WRITE setDataSize NOTIFY dataSizeChanged) + Q_PROPERTY(VertexBaseType vertexBaseType READ vertexBaseType WRITE setVertexBaseType NOTIFY vertexBaseTypeChanged) + Q_PROPERTY(uint vertexSize READ vertexSize WRITE setVertexSize NOTIFY vertexSizeChanged) Q_PROPERTY(uint count READ count WRITE setCount NOTIFY countChanged) Q_PROPERTY(uint byteStride READ byteStride WRITE setByteStride NOTIFY byteStrideChanged) Q_PROPERTY(uint byteOffset READ byteOffset WRITE setByteOffset NOTIFY byteOffsetChanged) @@ -111,8 +111,10 @@ public: public Q_SLOTS: void setBuffer(QBuffer *buffer); void setName(const QString &name); - void setDataType(VertexBaseType type); - void setDataSize(uint size); + void setVertexBaseType(VertexBaseType type); + void setVertexSize(uint size); + QT_DEPRECATED void setDataType(VertexBaseType type); + QT_DEPRECATED void setDataSize(uint size); void setCount(uint count); void setByteStride(uint byteStride); void setByteOffset(uint byteOffset); @@ -122,6 +124,8 @@ public Q_SLOTS: Q_SIGNALS: void bufferChanged(QBuffer *buffer); void nameChanged(const QString &name); + void vertexBaseTypeChanged(VertexBaseType vertexBaseType); + void vertexSizeChanged(uint vertexSize); void dataTypeChanged(VertexBaseType vertexBaseType); void dataSizeChanged(uint vertexSize); void countChanged(uint count); diff --git a/src/render/geometry/qattribute_p.h b/src/render/geometry/qattribute_p.h index 8731e3195..d3385345a 100644 --- a/src/render/geometry/qattribute_p.h +++ b/src/render/geometry/qattribute_p.h @@ -71,8 +71,8 @@ public: QBuffer *m_buffer; QString m_name; - QAttribute::VertexBaseType m_dataType; - uint m_dataSize; + QAttribute::VertexBaseType m_vertexBaseType; + uint m_vertexSize; uint m_count; uint m_byteStride; uint m_byteOffset; @@ -84,8 +84,8 @@ struct QAttributeData { Qt3DCore::QNodeId bufferId; QString name; - QAttribute::VertexBaseType dataType; - uint dataSize; + QAttribute::VertexBaseType vertexBaseType; + uint vertexSize; uint count; uint byteStride; uint byteOffset; diff --git a/src/render/geometry/qbuffer.cpp b/src/render/geometry/qbuffer.cpp index e79ebcd24..e63798027 100644 --- a/src/render/geometry/qbuffer.cpp +++ b/src/render/geometry/qbuffer.cpp @@ -195,7 +195,7 @@ void QBuffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) */ void QBuffer::setData(const QByteArray &bytes) { - Q_D(QBuffer); + Q_D(QBuffer); if (bytes != d->m_data) { d->m_data = bytes; Qt3DCore::QNodePrivate::get(this)->notifyPropertyChange("data", QVariant::fromValue(d->m_data)); @@ -204,6 +204,30 @@ void QBuffer::setData(const QByteArray &bytes) } /*! + * \Update the data. + */ +void QBuffer::updateData(int offset, const QByteArray &bytes) +{ + Q_D(QBuffer); + Q_ASSERT(offset >= 0 && (offset + bytes.size()) <= d->m_data.size()); + + // Update data + d->m_data.replace(offset, bytes.size(), bytes); + const bool blocked = blockNotifications(true); + emit dataChanged(d->m_data); + blockNotifications(blocked); + + QBufferUpdate updateData; + updateData.offset = offset; + updateData.data = bytes; + + auto e = QPropertyUpdatedChangePtr::create(id()); + e->setPropertyName("updateData"); + e->setValue(QVariant::fromValue(updateData)); + notifyObservers(e); +} + +/*! * \return the data. */ QByteArray QBuffer::data() const diff --git a/src/render/geometry/qbuffer.h b/src/render/geometry/qbuffer.h index ba5877e6e..cf8bdcfb9 100644 --- a/src/render/geometry/qbuffer.h +++ b/src/render/geometry/qbuffer.h @@ -44,6 +44,7 @@ #include <Qt3DRender/qt3drender_global.h> #include <QSharedPointer> + QT_BEGIN_NAMESPACE namespace Qt3DRender { @@ -98,6 +99,8 @@ public: void setDataGenerator(const QBufferDataGeneratorPtr &functor); QBufferDataGeneratorPtr dataGenerator() const; + Q_INVOKABLE void updateData(int offset, const QByteArray &bytes); + public Q_SLOTS: void setType(BufferType type); void setUsage(UsageType usage); diff --git a/src/render/geometry/qbuffer_p.h b/src/render/geometry/qbuffer_p.h index 1c1f20db6..7759a279f 100644 --- a/src/render/geometry/qbuffer_p.h +++ b/src/render/geometry/qbuffer_p.h @@ -85,8 +85,15 @@ struct QBufferData bool syncData; }; +struct QBufferUpdate +{ + int offset; + QByteArray data; +}; + } // namespace Qt3DRender QT_END_NAMESPACE +Q_DECLARE_METATYPE(Qt3DRender::QBufferUpdate) #endif // QT3DRENDER_QBUFFER_P_H diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp index 3a67db729..4c2d902f1 100644 --- a/src/render/graphicshelpers/graphicscontext.cpp +++ b/src/render/graphicshelpers/graphicscontext.cpp @@ -57,6 +57,7 @@ #include <Qt3DRender/private/buffermanager_p.h> #include <Qt3DRender/private/managers_p.h> #include <Qt3DRender/private/attachmentpack_p.h> +#include <Qt3DRender/private/qbuffer_p.h> #include <QOpenGLShaderProgram> #if !defined(QT_OPENGL_ES_2) @@ -79,6 +80,8 @@ QT_BEGIN_NAMESPACE +extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); + namespace { QOpenGLShader::ShaderType shaderType(Qt3DRender::QShaderProgram::ShaderType type) @@ -286,9 +289,8 @@ void GraphicsContext::endDrawing(bool swapBuffers) decayTextureScores(); } -void GraphicsContext::setViewport(const QRectF &viewport, const QSize &surfaceSize) +QSize GraphicsContext::renderTargetSize(const QSize &surfaceSize) const { - m_viewport = viewport; QSize renderTargetSize; if (m_activeFBO != m_defaultFBO) { // For external FBOs we may not have a m_renderTargets entry. @@ -317,7 +319,7 @@ void GraphicsContext::setViewport(const QRectF &viewport, const QSize &surfaceSi // Assumes texture level 0 and GL_TEXTURE_2D target renderTargetSize = m_glHelper->getTextureDimensions(attachment0Name, GL_TEXTURE_2D); else - return; + return renderTargetSize; } } else { renderTargetSize = m_surface->size(); @@ -326,9 +328,16 @@ void GraphicsContext::setViewport(const QRectF &viewport, const QSize &surfaceSi renderTargetSize *= dpr; } } + return renderTargetSize; +} + +void GraphicsContext::setViewport(const QRectF &viewport, const QSize &surfaceSize) +{ + m_viewport = viewport; + QSize size = renderTargetSize(surfaceSize); // Check that the returned size is before calling glViewport - if (renderTargetSize.isEmpty()) + if (size.isEmpty()) return; // Qt3D 0------------------> 1 OpenGL 1^ @@ -339,10 +348,10 @@ void GraphicsContext::setViewport(const QRectF &viewport, const QSize &surfaceSi // 1 0---------------------> 1 // The Viewport is defined between 0 and 1 which allows us to automatically // scale to the size of the provided window surface - m_gl->functions()->glViewport(m_viewport.x() * renderTargetSize.width(), - (1.0 - m_viewport.y() - m_viewport.height()) * renderTargetSize.height(), - m_viewport.width() * renderTargetSize.width(), - m_viewport.height() * renderTargetSize.height()); + m_gl->functions()->glViewport(m_viewport.x() * size.width(), + (1.0 - m_viewport.y() - m_viewport.height()) * size.height(), + m_viewport.width() * size.width(), + m_viewport.height() * size.height()); } void GraphicsContext::releaseOpenGL() @@ -870,11 +879,6 @@ void GraphicsContext::bindFragOutputs(GLuint shader, const QHash<QString, int> & m_glHelper->bindFragDataLocation(shader, outputs); } -void GraphicsContext::bindUniform(const QVariant &v, const ShaderUniform &description) -{ - m_glHelper->bindUniform(v, description); -} - void GraphicsContext::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) { m_glHelper->bindUniformBlock(programId, uniformBlockIndex, uniformBlockBinding); @@ -1075,12 +1079,12 @@ void GraphicsContext::setParameters(ShaderParameterPack ¶meterPack) for (int i = 0; i < parameterPack.textures().size(); ++i) { const ShaderParameterPack::NamedTexture &namedTex = parameterPack.textures().at(i); Texture *t = manager->lookupResource<Texture, TextureManager>(namedTex.texId); - // TO DO : Rework the way textures are loaded if (t != nullptr) { int texUnit = activateTexture(TextureScopeMaterial, t); if (uniformValues.contains(namedTex.glslNameId)) { - QUniformValue &texUniform = uniformValues[namedTex.glslNameId]; - texUniform.setTextureUnit(texUnit); + UniformValue &texUniform = uniformValues[namedTex.glslNameId]; + Q_ASSERT(texUniform.valueType() == UniformValue::TextureValue); + texUniform.data<UniformValue::Texture>()->textureId = texUnit; } } } @@ -1136,8 +1140,7 @@ void GraphicsContext::setParameters(ShaderParameterPack ¶meterPack) for (const ShaderUniform &uniform : activeUniforms) { // We can use [] as we are sure the the uniform wouldn't // be un activeUniforms if there wasn't a matching value - const QUniformValue &value = values[uniform.m_nameId]; - value.apply(this, uniform); + applyUniform(uniform, values[uniform.m_nameId]); } } @@ -1167,6 +1170,109 @@ void GraphicsContext::disableAttribute(const GraphicsContext::VAOVertexAttribute prog->disableAttributeArray(attr.location); } +void GraphicsContext::applyUniform(const ShaderUniform &description, const UniformValue &v) +{ + const UniformType type = m_glHelper->uniformTypeFromGLType(description.m_type); + + switch (type) { + case UniformType::Float: + applyUniformHelper<UniformType::Float>(description.m_location, v); + break; + case UniformType::Vec2: + applyUniformHelper<UniformType::Vec2>(description.m_location, v); + break; + case UniformType::Vec3: + applyUniformHelper<UniformType::Vec3>(description.m_location, v); + break; + case UniformType::Vec4: + applyUniformHelper<UniformType::Vec4>(description.m_location, v); + break; + + case UniformType::Double: + applyUniformHelper<UniformType::Double>(description.m_location, v); + break; + case UniformType::DVec2: + applyUniformHelper<UniformType::DVec2>(description.m_location, v); + break; + case UniformType::DVec3: + applyUniformHelper<UniformType::DVec3>(description.m_location, v); + break; + case UniformType::DVec4: + applyUniformHelper<UniformType::DVec4>(description.m_location, v); + break; + + case UniformType::Sampler: + case UniformType::Int: + applyUniformHelper<UniformType::Int>(description.m_location, v); + break; + case UniformType::IVec2: + applyUniformHelper<UniformType::IVec2>(description.m_location, v); + break; + case UniformType::IVec3: + applyUniformHelper<UniformType::IVec3>(description.m_location, v); + break; + case UniformType::IVec4: + applyUniformHelper<UniformType::IVec4>(description.m_location, v); + break; + + case UniformType::UInt: + applyUniformHelper<UniformType::Int>(description.m_location, v); + break; + case UniformType::UIVec2: + applyUniformHelper<UniformType::IVec2>(description.m_location, v); + break; + case UniformType::UIVec3: + applyUniformHelper<UniformType::IVec3>(description.m_location, v); + break; + case UniformType::UIVec4: + applyUniformHelper<UniformType::IVec4>(description.m_location, v); + break; + + case UniformType::Bool: + applyUniformHelper<UniformType::Bool>(description.m_location, v); + break; + case UniformType::BVec2: + applyUniformHelper<UniformType::BVec2>(description.m_location, v); + break; + case UniformType::BVec3: + applyUniformHelper<UniformType::BVec3>(description.m_location, v); + break; + case UniformType::BVec4: + applyUniformHelper<UniformType::BVec4>(description.m_location, v); + break; + + case UniformType::Mat2: + applyUniformHelper<UniformType::Mat2>(description.m_location, v); + break; + case UniformType::Mat3: + applyUniformHelper<UniformType::Mat3>(description.m_location, v); + break; + case UniformType::Mat4: + applyUniformHelper<UniformType::Mat4>(description.m_location, v); + break; + case UniformType::Mat2x3: + applyUniformHelper<UniformType::Mat2x3>(description.m_location, v); + break; + case UniformType::Mat3x2: + applyUniformHelper<UniformType::Mat3x2>(description.m_location, v); + break; + case UniformType::Mat2x4: + applyUniformHelper<UniformType::Mat2x4>(description.m_location, v); + break; + case UniformType::Mat4x2: + applyUniformHelper<UniformType::Mat4x2>(description.m_location, v); + case UniformType::Mat3x4: + applyUniformHelper<UniformType::Mat3x4>(description.m_location, v); + break; + case UniformType::Mat4x3: + applyUniformHelper<UniformType::Mat4x3>(description.m_location, v); + break; + + default: + break; + } +} + // Note: needs to be called while VAO is bound void GraphicsContext::specifyAttribute(const Attribute *attribute, Buffer *buffer, int location) { @@ -1297,10 +1403,26 @@ void GraphicsContext::uploadDataToGLBuffer(Buffer *buffer, GLBuffer *b, bool rel { if (!bindGLBuffer(b, bufferTypeToGLBufferType(buffer->type()))) qCWarning(Render::Io) << Q_FUNC_INFO << "buffer bind failed"; - const int bufferSize = buffer->data().size(); - // TO DO: Handle usage pattern and sub data updates - b->allocate(this, bufferSize, false); // orphan the buffer - b->allocate(this, buffer->data().constData(), bufferSize, false); + // If the buffer is dirty (hence being called here) + // there are two possible cases + // * setData was called changing the whole data or functor (or the usage pattern) + // * partial buffer updates where received + + // Note: we assume the case where both setData/functor and updates are called to be a misuse + // with unexpected behavior + const QVector<Qt3DRender::QBufferUpdate> updates = std::move(buffer->pendingBufferUpdates()); + if (!updates.empty()) { + for (const Qt3DRender::QBufferUpdate &update : updates) { + // TO DO: based on the number of updates .., it might make sense to + // sometime use glMapBuffer rather than glBufferSubData + b->update(this, update.data.constData(), update.data.size(), update.offset); + } + } else { + const int bufferSize = buffer->data().size(); + // TO DO: Handle usage pattern + b->allocate(this, bufferSize, false); // orphan the buffer + b->allocate(this, buffer->data().constData(), bufferSize, false); + } if (releaseBuffer) { b->release(this); if (bufferTypeToGLBufferType(buffer->type()) == GLBuffer::ArrayBuffer) @@ -1426,6 +1548,43 @@ GLint GraphicsContext::glDataTypeFromAttributeDataType(QAttribute::VertexBaseTyp return GL_FLOAT; } +QImage GraphicsContext::readFramebuffer(QSize size) +{ + // todo: own implementation + return qt_gl_read_framebuffer(size, true, true); +} + +QT3D_UNIFORM_TYPE_IMPL(UniformType::Float, float, glUniform1fv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::Vec2, float, glUniform2fv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::Vec3, float, glUniform3fv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::Vec4, float, glUniform4fv) + +// OpenGL expects int* as values for booleans +QT3D_UNIFORM_TYPE_IMPL(UniformType::Bool, int, glUniform1iv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::BVec2, int, glUniform2iv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::BVec3, int, glUniform3iv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::BVec4, int, glUniform4iv) + +QT3D_UNIFORM_TYPE_IMPL(UniformType::Int, int, glUniform1iv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::IVec2, int, glUniform2iv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::IVec3, int, glUniform3iv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::IVec4, int, glUniform4iv) + +QT3D_UNIFORM_TYPE_IMPL(UniformType::UInt, uint, glUniform1uiv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::UIVec2, uint, glUniform2uiv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::UIVec3, uint, glUniform3uiv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::UIVec4, uint, glUniform4uiv) + +QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat2, float, glUniformMatrix2fv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat3, float, glUniformMatrix3fv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat4, float, glUniformMatrix4fv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat2x3, float, glUniformMatrix2x3fv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat3x2, float, glUniformMatrix3x2fv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat2x4, float, glUniformMatrix2x4fv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat4x2, float, glUniformMatrix4x2fv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat3x4, float, glUniformMatrix3x4fv) +QT3D_UNIFORM_TYPE_IMPL(UniformType::Mat4x3, float, glUniformMatrix4x3fv) + } // namespace Render } // namespace Qt3DRender of namespace diff --git a/src/render/graphicshelpers/graphicscontext_p.h b/src/render/graphicshelpers/graphicscontext_p.h index cc63a03b6..647db9e47 100644 --- a/src/render/graphicshelpers/graphicscontext_p.h +++ b/src/render/graphicshelpers/graphicscontext_p.h @@ -59,7 +59,8 @@ #include <QColor> #include <QMatrix4x4> #include <QBitArray> -#include <Qt3DRender/private/quniformvalue_p.h> +#include <QImage> +#include <Qt3DRender/private/shaderparameterpack_p.h> #include <Qt3DRender/qclearbuffers.h> #include <Qt3DRender/private/shader_p.h> #include <Qt3DRender/private/glbuffer_p.h> @@ -67,6 +68,7 @@ #include <Qt3DRender/private/handle_types_p.h> #include <Qt3DRender/private/qgraphicsapifilter_p.h> #include <Qt3DRender/private/shadercache_p.h> +#include <Qt3DRender/private/uniform_p.h> QT_BEGIN_NAMESPACE @@ -140,6 +142,8 @@ public: void executeCommand(const RenderCommand *command); + QSize renderTargetSize(const QSize &surfaceSize) const; + /** * @brief activeShader * @return @@ -184,7 +188,6 @@ public: void bindBufferBase(GLenum target, GLuint bindingIndex, GLuint buffer); void bindFragOutputs(GLuint shader, const QHash<QString, int> &outputs); void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding); - void bindUniform(const QVariant &v, const ShaderUniform &description); void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding); void blendEquation(GLenum mode); void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor); @@ -227,6 +230,8 @@ public: bool supportsDrawBuffersBlend() const; bool supportsVAO() const { return m_supportsVAO; } + QImage readFramebuffer(QSize size); + private: void initialize(); @@ -310,8 +315,59 @@ private: void enableAttribute(const VAOVertexAttribute &attr); void disableAttribute(const VAOVertexAttribute &attr); + + void applyUniform(const ShaderUniform &description, const UniformValue &v); + + template<UniformType> + void applyUniformHelper(int, const UniformValue &) const + { + Q_ASSERT_X(false, Q_FUNC_INFO, "Uniform: Didn't provide specialized apply() implementation"); + } }; +#define QT3D_UNIFORM_TYPE_PROTO(UniformTypeEnum, BaseType, Func) \ +template<> \ +void GraphicsContext::applyUniformHelper<UniformTypeEnum>(int location, const UniformValue &value) const; + +#define QT3D_UNIFORM_TYPE_IMPL(UniformTypeEnum, BaseType, Func) \ + template<> \ + void GraphicsContext::applyUniformHelper<UniformTypeEnum>(int location, const UniformValue &value) const \ +{ \ + m_glHelper->Func(location, 1, value.constData<BaseType>()); \ +} + + +QT3D_UNIFORM_TYPE_PROTO(UniformType::Float, float, glUniform1fv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec2, float, glUniform2fv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec3, float, glUniform3fv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::Vec4, float, glUniform4fv) + +// OpenGL expects int* as values for booleans +QT3D_UNIFORM_TYPE_PROTO(UniformType::Bool, int, glUniform1iv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec2, int, glUniform2iv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec3, int, glUniform3iv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::BVec4, int, glUniform4iv) + +QT3D_UNIFORM_TYPE_PROTO(UniformType::Int, int, glUniform1iv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec2, int, glUniform2iv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec3, int, glUniform3iv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::IVec4, int, glUniform4iv) + +QT3D_UNIFORM_TYPE_PROTO(UniformType::UInt, uint, glUniform1uiv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec2, uint, glUniform2uiv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec3, uint, glUniform3uiv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::UIVec4, uint, glUniform4uiv) + +QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2, float, glUniformMatrix2fv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3, float, glUniformMatrix3fv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4, float, glUniformMatrix4fv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2x3, float, glUniformMatrix2x3fv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3x2, float, glUniformMatrix3x2fv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat2x4, float, glUniformMatrix2x4fv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4x2, float, glUniformMatrix4x2fv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat3x4, float, glUniformMatrix3x4fv) +QT3D_UNIFORM_TYPE_PROTO(UniformType::Mat4x3, float, glUniformMatrix4x3fv) + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/graphicshelpers/graphicshelperes2.cpp b/src/render/graphicshelpers/graphicshelperes2.cpp index b09e33291..3a268cb5f 100644 --- a/src/render/graphicshelpers/graphicshelperes2.cpp +++ b/src/render/graphicshelpers/graphicshelperes2.cpp @@ -359,108 +359,6 @@ void GraphicsHelperES2::drawBuffers(GLsizei, const int *) qWarning() << "drawBuffers is not supported by ES 2.0"; } -void GraphicsHelperES2::bindUniform(const QVariant &v, const ShaderUniform &description) -{ - switch (description.m_type) { - - case GL_FLOAT: - m_funcs->glUniform1fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 1)); - break; - - case GL_FLOAT_VEC2: - m_funcs->glUniform2fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2)); - break; - - case GL_FLOAT_VEC3: - m_funcs->glUniform3fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3)); - break; - - case GL_FLOAT_VEC4: - m_funcs->glUniform4fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4)); - break; - - case GL_FLOAT_MAT2: - m_funcs->glUniformMatrix2fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4)); - break; - - case GL_FLOAT_MAT3: - m_funcs->glUniformMatrix3fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9)); - break; - - case GL_FLOAT_MAT4: - m_funcs->glUniformMatrix4fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16)); - break; - - case GL_INT: - m_funcs->glUniform1iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1)); - break; - - case GL_INT_VEC2: - m_funcs->glUniform2iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2)); - break; - - case GL_INT_VEC3: - m_funcs->glUniform3iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3)); - break; - - case GL_INT_VEC4: - m_funcs->glUniform4iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4)); - break; - - case GL_BOOL: - m_funcs->glUniform1iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1)); - break; - - case GL_BOOL_VEC2: - m_funcs->glUniform2iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2)); - break; - - case GL_BOOL_VEC3: - m_funcs->glUniform3iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3)); - break; - - case GL_BOOL_VEC4: - m_funcs->glUniform4iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4)); - break; - - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: { - Q_ASSERT(description.m_size == 1); - m_funcs->glUniform1i(description.m_location, v.toInt()); - break; - } - - // ES 3.0+ - case GL_SAMPLER_3D: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_2D_ARRAY: - case GL_SAMPLER_2D_ARRAY_SHADOW: - qWarning() << Q_FUNC_INFO << "ES 3.0 uniform type" << description.m_type << "for" - << description.m_name << "is not supported in ES 2.0"; - break; - - default: - qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name; - break; - } -} - void GraphicsHelperES2::bindFragDataLocation(GLuint , const QHash<QString, int> &) { qCritical() << "bindFragDataLocation is not supported by ES 2.0"; @@ -655,6 +553,154 @@ void GraphicsHelperES2::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) qWarning() << "Compute Shaders are not supported by ES 2.0 (since ES 3.1)"; } +void GraphicsHelperES2::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform1fv(location, count, values); +} + +void GraphicsHelperES2::glUniform2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform2fv(location, count, values); +} + +void GraphicsHelperES2::glUniform3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform3fv(location, count, values); +} + +void GraphicsHelperES2::glUniform4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform4fv(location, count, values); +} + +void GraphicsHelperES2::glUniform1iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform1iv(location, count, values); +} + +void GraphicsHelperES2::glUniform2iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform2iv(location, count, values); +} + +void GraphicsHelperES2::glUniform3iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform3iv(location, count, values); +} + +void GraphicsHelperES2::glUniform4iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform4iv(location, count, values); +} + +void GraphicsHelperES2::glUniform1uiv(GLint , GLsizei , const GLuint *) +{ + qWarning() << "glUniform1uiv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniform2uiv(GLint , GLsizei , const GLuint *) +{ + qWarning() << "glUniform2uiv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniform3uiv(GLint , GLsizei , const GLuint *) +{ + qWarning() << "glUniform3uiv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniform4uiv(GLint , GLsizei , const GLuint *) +{ + qWarning() << "glUniform4uiv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix2fv(location, count, false, values); +} + +void GraphicsHelperES2::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix3fv(location, count, false, values); +} + +void GraphicsHelperES2::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix4fv(location, count, false, values); +} + +void GraphicsHelperES2::glUniformMatrix2x3fv(GLint , GLsizei , const GLfloat *) +{ + qWarning() << "glUniformMatrix2x3fv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniformMatrix3x2fv(GLint , GLsizei , const GLfloat *) +{ + qWarning() << "glUniformMatrix3x2fv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniformMatrix2x4fv(GLint , GLsizei , const GLfloat *) +{ + qWarning() << "glUniformMatrix2x4fv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniformMatrix4x2fv(GLint , GLsizei , const GLfloat *) +{ + qWarning() << "glUniformMatrix4x2fv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniformMatrix3x4fv(GLint , GLsizei , const GLfloat *) +{ + qWarning() << "glUniformMatrix3x4fv not supported by ES 2"; +} + +void GraphicsHelperES2::glUniformMatrix4x3fv(GLint , GLsizei , const GLfloat *) +{ + qWarning() << "glUniformMatrix4x3fv not supported by ES 2"; +} + +UniformType GraphicsHelperES2::uniformTypeFromGLType(GLenum type) +{ + switch (type) { + case GL_FLOAT: + return UniformType::Float; + case GL_FLOAT_VEC2: + return UniformType::Vec2; + case GL_FLOAT_VEC3: + return UniformType::Vec3; + case GL_FLOAT_VEC4: + return UniformType::Vec4; + case GL_FLOAT_MAT2: + return UniformType::Mat2; + case GL_FLOAT_MAT3: + return UniformType::Mat3; + case GL_FLOAT_MAT4: + return UniformType::Mat4; + case GL_INT: + return UniformType::Int; + case GL_INT_VEC2: + return UniformType::IVec2; + case GL_INT_VEC3: + return UniformType::IVec3; + case GL_INT_VEC4: + return UniformType::IVec4; + case GL_BOOL: + return UniformType::Bool; + case GL_BOOL_VEC2: + return UniformType::BVec2; + case GL_BOOL_VEC3: + return UniformType::BVec3; + case GL_BOOL_VEC4: + return UniformType::BVec4; + + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: + return UniformType::Sampler; + default: + Q_UNREACHABLE(); + return UniformType::Float; + } +} + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/graphicshelpers/graphicshelperes2_p.h b/src/render/graphicshelpers/graphicshelperes2_p.h index df8f148a9..52d68f691 100644 --- a/src/render/graphicshelpers/graphicshelperes2_p.h +++ b/src/render/graphicshelpers/graphicshelperes2_p.h @@ -74,7 +74,6 @@ public: void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE; void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE; void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE; - void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE; void blendEquation(GLenum mode) Q_DECL_OVERRIDE; void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) Q_DECL_OVERRIDE; void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) Q_DECL_OVERRIDE; @@ -118,6 +117,34 @@ public: uint uniformByteSize(const ShaderUniform &description) Q_DECL_OVERRIDE; void useProgram(GLuint programId) Q_DECL_OVERRIDE; void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE; + + void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + + void glUniform1iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform2iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform3iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform4iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + + void glUniform1uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform2uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform3uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform4uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + + void glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + + UniformType uniformTypeFromGLType(GLenum glType) Q_DECL_OVERRIDE; + protected: QOpenGLFunctions *m_funcs; }; diff --git a/src/render/graphicshelpers/graphicshelperes3.cpp b/src/render/graphicshelpers/graphicshelperes3.cpp index fe39d9d3f..eb492e98d 100644 --- a/src/render/graphicshelpers/graphicshelperes3.cpp +++ b/src/render/graphicshelpers/graphicshelperes3.cpp @@ -150,20 +150,17 @@ void GraphicsHelperES3::drawBuffers(GLsizei n, const int *bufs) m_extraFuncs->glDrawBuffers(n, drawBufs.constData()); } -void GraphicsHelperES3::bindUniform(const QVariant &v, const ShaderUniform &description) +UniformType GraphicsHelperES3::uniformTypeFromGLType(GLenum glType) { - switch (description.m_type) { + switch (glType) { case GL_SAMPLER_3D: case GL_SAMPLER_2D_SHADOW: case GL_SAMPLER_CUBE_SHADOW: case GL_SAMPLER_2D_ARRAY: case GL_SAMPLER_2D_ARRAY_SHADOW: - Q_ASSERT(description.m_size == 1); - m_funcs->glUniform1i(description.m_location, v.toInt()); - break; + return UniformType::Sampler; default: - GraphicsHelperES2::bindUniform(v, description); - break; + return GraphicsHelperES2::uniformTypeFromGLType(glType); } } diff --git a/src/render/graphicshelpers/graphicshelperes3_p.h b/src/render/graphicshelpers/graphicshelperes3_p.h index e5bb51c53..2844c140d 100644 --- a/src/render/graphicshelpers/graphicshelperes3_p.h +++ b/src/render/graphicshelpers/graphicshelperes3_p.h @@ -67,12 +67,14 @@ public: // QGraphicHelperInterface interface virtual void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE; - virtual void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE; virtual void drawBuffers(GLsizei n, const int *bufs) Q_DECL_OVERRIDE; virtual void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) Q_DECL_OVERRIDE; virtual void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) Q_DECL_OVERRIDE; virtual bool supportsFeature(Feature feature) const Q_DECL_OVERRIDE; virtual void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE; + + UniformType uniformTypeFromGLType(GLenum glType) Q_DECL_OVERRIDE; + protected: QOpenGLExtraFunctions *m_extraFuncs = Q_NULLPTR; }; diff --git a/src/render/graphicshelpers/graphicshelpergl2.cpp b/src/render/graphicshelpers/graphicshelpergl2.cpp index a8f6ce510..1315b4ab8 100644 --- a/src/render/graphicshelpers/graphicshelpergl2.cpp +++ b/src/render/graphicshelpers/graphicshelpergl2.cpp @@ -58,7 +58,7 @@ GraphicsHelperGL2::GraphicsHelperGL2() } void GraphicsHelperGL2::initializeHelper(QOpenGLContext *context, - QAbstractOpenGLFunctions *functions) + QAbstractOpenGLFunctions *functions) { Q_UNUSED(context); m_funcs = static_cast<QOpenGLFunctions_2_0*>(functions); @@ -95,9 +95,9 @@ void GraphicsHelperGL2::drawElementsInstancedBaseVertexBaseInstance(GLenum primi } void GraphicsHelperGL2::drawArraysInstanced(GLenum primitiveType, - GLint first, - GLsizei count, - GLsizei instances) + GLint first, + GLsizei count, + GLsizei instances) { for (GLint i = 0; i < instances; i++) drawArrays(primitiveType, @@ -116,10 +116,10 @@ void GraphicsHelperGL2::drawArraysInstancedBaseInstance(GLenum primitiveType, GL } void GraphicsHelperGL2::drawElements(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLint baseVertex) + GLsizei primitiveCount, + GLint indexType, + void *indices, + GLint baseVertex) { if (baseVertex != 0) qWarning() << "glDrawElementsBaseVertex is not supported with OpenGL 2"; @@ -131,8 +131,8 @@ void GraphicsHelperGL2::drawElements(GLenum primitiveType, } void GraphicsHelperGL2::drawArrays(GLenum primitiveType, - GLint first, - GLsizei count) + GLint first, + GLsizei count) { m_funcs->glDrawArrays(primitiveType, first, @@ -211,7 +211,7 @@ QVector<ShaderStorageBlock> GraphicsHelperGL2::programShaderStorageBlocks(GLuint } void GraphicsHelperGL2::vertexAttribDivisor(GLuint index, - GLuint divisor) + GLuint divisor) { Q_UNUSED(index); Q_UNUSED(divisor); @@ -358,98 +358,6 @@ void GraphicsHelperGL2::bindFragDataLocation(GLuint, const QHash<QString, int> & qCritical() << "bindFragDataLocation is not supported by GL 2.0"; } -void GraphicsHelperGL2::bindUniform(const QVariant &v, const ShaderUniform &description) -{ - switch (description.m_type) { - - case GL_FLOAT: - m_funcs->glUniform1fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 1)); - break; - - case GL_FLOAT_VEC2: - m_funcs->glUniform2fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2)); - break; - - case GL_FLOAT_VEC3: - m_funcs->glUniform3fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3)); - break; - - case GL_FLOAT_VEC4: - m_funcs->glUniform4fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4)); - break; - - case GL_FLOAT_MAT2: - m_funcs->glUniformMatrix2fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4)); - break; - - case GL_FLOAT_MAT3: - m_funcs->glUniformMatrix3fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9)); - break; - - case GL_FLOAT_MAT4: - m_funcs->glUniformMatrix4fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16)); - break; - - case GL_INT: - m_funcs->glUniform1iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1)); - break; - - case GL_INT_VEC2: - m_funcs->glUniform2iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2)); - break; - - case GL_INT_VEC3: - m_funcs->glUniform3iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3)); - break; - - case GL_INT_VEC4: - m_funcs->glUniform4iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4)); - break; - - case GL_BOOL: - m_funcs->glUniform1iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1)); - break; - - case GL_BOOL_VEC2: - m_funcs->glUniform2iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2)); - break; - - case GL_BOOL_VEC3: - m_funcs->glUniform3iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3)); - break; - - case GL_BOOL_VEC4: - m_funcs->glUniform4iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4)); - break; - - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: { - Q_ASSERT(description.m_size == 1); - m_funcs->glUniform1i(description.m_location, v.toInt()); - break; - } - - default: - qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name; - break; - } -} - void GraphicsHelperGL2::bindFrameBufferObject(GLuint frameBufferId) { if (m_fboFuncs != nullptr) @@ -550,10 +458,17 @@ uint GraphicsHelperGL2::uniformByteSize(const ShaderUniform &description) case GL_INT: case GL_FLOAT: + case GL_SAMPLER_1D: + case GL_SAMPLER_1D_SHADOW: case GL_SAMPLER_2D: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_3D: case GL_SAMPLER_CUBE: rawByteSize = 4; break; + + default: + Q_UNREACHABLE(); } return arrayStride ? rawByteSize * arrayStride : rawByteSize; @@ -663,6 +578,159 @@ void GraphicsHelperGL2::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) qWarning() << "Compute Shaders are not supported by OpenGL 2.0 (since OpenGL 4.3)"; } +void GraphicsHelperGL2::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform1fv(location, count, values); +} + +void GraphicsHelperGL2::glUniform2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform2fv(location, count, values); +} + +void GraphicsHelperGL2::glUniform3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform3fv(location, count, values); +} + +void GraphicsHelperGL2::glUniform4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform4fv(location, count, values); +} + +void GraphicsHelperGL2::glUniform1iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform1iv(location, count, values); +} + +void GraphicsHelperGL2::glUniform2iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform2iv(location, count, values); +} + +void GraphicsHelperGL2::glUniform3iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform3iv(location, count, values); +} + +void GraphicsHelperGL2::glUniform4iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform4iv(location, count, values); +} + +void GraphicsHelperGL2::glUniform1uiv(GLint , GLsizei , const GLuint *) +{ + qWarning() << "glUniform1uiv not supported by GL 2"; +} + +void GraphicsHelperGL2::glUniform2uiv(GLint , GLsizei , const GLuint *) +{ + qWarning() << "glUniform2uiv not supported by GL 2"; +} + +void GraphicsHelperGL2::glUniform3uiv(GLint , GLsizei , const GLuint *) +{ + qWarning() << "glUniform3uiv not supported by GL 2"; +} + +void GraphicsHelperGL2::glUniform4uiv(GLint , GLsizei , const GLuint *) +{ + qWarning() << "glUniform4uiv not supported by GL 2"; +} + +void GraphicsHelperGL2::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix2fv(location, count, false, values); +} + +void GraphicsHelperGL2::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix3fv(location, count, false, values); +} + +void GraphicsHelperGL2::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix4fv(location, count, false, values); +} + +void GraphicsHelperGL2::glUniformMatrix2x3fv(GLint , GLsizei , const GLfloat *) +{ + qWarning() << "glUniformMatrix2x3fv not supported by GL 2"; +} + +void GraphicsHelperGL2::glUniformMatrix3x2fv(GLint , GLsizei , const GLfloat *) +{ + qWarning() << "glUniformMatrix3x2fv not supported by GL 2"; +} + +void GraphicsHelperGL2::glUniformMatrix2x4fv(GLint , GLsizei , const GLfloat *) +{ + qWarning() << "glUniformMatrix2x4fv not supported by GL 2"; +} + +void GraphicsHelperGL2::glUniformMatrix4x2fv(GLint , GLsizei , const GLfloat *) +{ + qWarning() << "glUniformMatrix4x2fv not supported by GL 2"; +} + +void GraphicsHelperGL2::glUniformMatrix3x4fv(GLint , GLsizei , const GLfloat *) +{ + qWarning() << "glUniformMatrix3x4fv not supported by GL 2"; +} + +void GraphicsHelperGL2::glUniformMatrix4x3fv(GLint , GLsizei , const GLfloat *) +{ + qWarning() << "glUniformMatrix4x3fv not supported by GL 2"; +} + +UniformType GraphicsHelperGL2::uniformTypeFromGLType(GLenum type) +{ + switch (type) { + case GL_FLOAT: + return UniformType::Float; + case GL_FLOAT_VEC2: + return UniformType::Vec2; + case GL_FLOAT_VEC3: + return UniformType::Vec3; + case GL_FLOAT_VEC4: + return UniformType::Vec4; + case GL_FLOAT_MAT2: + return UniformType::Mat2; + case GL_FLOAT_MAT3: + return UniformType::Mat3; + case GL_FLOAT_MAT4: + return UniformType::Mat4; + case GL_INT: + return UniformType::Int; + case GL_INT_VEC2: + return UniformType::IVec2; + case GL_INT_VEC3: + return UniformType::IVec3; + case GL_INT_VEC4: + return UniformType::IVec4; + case GL_BOOL: + return UniformType::Bool; + case GL_BOOL_VEC2: + return UniformType::BVec2; + case GL_BOOL_VEC3: + return UniformType::BVec3; + case GL_BOOL_VEC4: + return UniformType::BVec4; + + case GL_SAMPLER_1D: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_2D: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_3D: + return UniformType::Sampler; + + default: + Q_UNREACHABLE(); + return UniformType::Float; + } +} + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/graphicshelpers/graphicshelpergl2_p.h b/src/render/graphicshelpers/graphicshelpergl2_p.h index 719f9c92c..0352c77d3 100644 --- a/src/render/graphicshelpers/graphicshelpergl2_p.h +++ b/src/render/graphicshelpers/graphicshelpergl2_p.h @@ -63,7 +63,7 @@ class QOpenGLExtension_ARB_framebuffer_object; namespace Qt3DRender { namespace Render { -class GraphicsHelperGL2 : public GraphicsHelperInterface +class Q_AUTOTEST_EXPORT GraphicsHelperGL2 : public GraphicsHelperInterface { public: GraphicsHelperGL2(); @@ -76,7 +76,6 @@ public: void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE; void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE; void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE; - void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE; void blendEquation(GLenum mode) Q_DECL_OVERRIDE; void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) Q_DECL_OVERRIDE; void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) Q_DECL_OVERRIDE; @@ -121,6 +120,33 @@ public: void useProgram(GLuint programId) Q_DECL_OVERRIDE; void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE; + void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + + void glUniform1iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform2iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform3iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform4iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + + void glUniform1uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform2uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform3uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform4uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + + void glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + + UniformType uniformTypeFromGLType(GLenum glType) Q_DECL_OVERRIDE; + private: QOpenGLFunctions_2_0 *m_funcs; QOpenGLExtension_ARB_framebuffer_object *m_fboFuncs; diff --git a/src/render/graphicshelpers/graphicshelpergl3.cpp b/src/render/graphicshelpers/graphicshelpergl3.cpp index 549c665c3..da1b95db8 100644 --- a/src/render/graphicshelpers/graphicshelpergl3.cpp +++ b/src/render/graphicshelpers/graphicshelpergl3.cpp @@ -410,182 +410,6 @@ void GraphicsHelperGL3::bindFragDataLocation(GLuint shader, const QHash<QString, m_funcs->glBindFragDataLocation(shader, it.value(), it.key().toStdString().c_str()); } -void GraphicsHelperGL3::bindUniform(const QVariant &v, const ShaderUniform &description) -{ - switch (description.m_type) { - - case GL_FLOAT: - m_funcs->glUniform1fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 1)); - break; - - case GL_FLOAT_VEC2: - m_funcs->glUniform2fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2)); - break; - - case GL_FLOAT_VEC3: - m_funcs->glUniform3fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3)); - break; - - case GL_FLOAT_VEC4: - m_funcs->glUniform4fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4)); - break; - - case GL_FLOAT_MAT2: - m_funcs->glUniformMatrix2fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4)); - break; - - case GL_FLOAT_MAT2x3: - m_funcs->glUniformMatrix2x3fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6)); - break; - - case GL_FLOAT_MAT2x4: - m_funcs->glUniformMatrix2x4fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8)); - break; - - case GL_FLOAT_MAT3: - m_funcs->glUniformMatrix3fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9)); - break; - - case GL_FLOAT_MAT3x2: - m_funcs->glUniformMatrix3x2fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6)); - break; - - case GL_FLOAT_MAT3x4: - m_funcs->glUniformMatrix3x4fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12)); - break; - - case GL_FLOAT_MAT4: - m_funcs->glUniformMatrix4fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16)); - break; - - case GL_FLOAT_MAT4x2: - m_funcs->glUniformMatrix4x2fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8)); - break; - - case GL_FLOAT_MAT4x3: - m_funcs->glUniformMatrix4x3fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12)); - break; - - case GL_INT: - m_funcs->glUniform1iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1)); - break; - - case GL_INT_VEC2: - m_funcs->glUniform2iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2)); - break; - - case GL_INT_VEC3: - m_funcs->glUniform3iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3)); - break; - - case GL_INT_VEC4: - m_funcs->glUniform4iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4)); - break; - - case GL_UNSIGNED_INT: - m_funcs->glUniform1uiv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 1)); - break; - - case GL_UNSIGNED_INT_VEC2: - m_funcs->glUniform2uiv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 2)); - break; - - case GL_UNSIGNED_INT_VEC3: - m_funcs->glUniform3uiv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 3)); - break; - - case GL_UNSIGNED_INT_VEC4: - m_funcs->glUniform4uiv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 4)); - break; - - case GL_BOOL: - m_funcs->glUniform1iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1)); - break; - - case GL_BOOL_VEC2: - m_funcs->glUniform2iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2)); - break; - - case GL_BOOL_VEC3: - m_funcs->glUniform3iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3)); - break; - - case GL_BOOL_VEC4: - m_funcs->glUniform4iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4)); - break; - - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_BUFFER: - case GL_SAMPLER_2D_RECT: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_2D_RECT: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_2D_RECT: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_1D_ARRAY_SHADOW: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: { - Q_ASSERT(description.m_size == 1); - m_funcs->glUniform1i(description.m_location, v.toInt()); - break; - } - - default: - qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name; - break; - } -} - void GraphicsHelperGL3::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) { m_funcs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding); @@ -1034,6 +858,193 @@ void GraphicsHelperGL3::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) qWarning() << "Compute Shaders are not supported by OpenGL 3.0 (since OpenGL 4.3)"; } +void GraphicsHelperGL3::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform1fv(location, count, values); +} + +void GraphicsHelperGL3::glUniform2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform2fv(location, count, values); +} + +void GraphicsHelperGL3::glUniform3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform3fv(location, count, values); +} + +void GraphicsHelperGL3::glUniform4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform4fv(location, count, values); +} + +void GraphicsHelperGL3::glUniform1iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform1iv(location, count, values); +} + +void GraphicsHelperGL3::glUniform2iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform2iv(location, count, values); +} + +void GraphicsHelperGL3::glUniform3iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform3iv(location, count, values); +} + +void GraphicsHelperGL3::glUniform4iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform4iv(location, count, values); +} + +void GraphicsHelperGL3::glUniform1uiv(GLint location, GLsizei count, const GLuint *values) +{ + m_funcs->glUniform1uiv(location, count, values); +} + +void GraphicsHelperGL3::glUniform2uiv(GLint location, GLsizei count, const GLuint *values) +{ + m_funcs->glUniform2uiv(location, count, values); +} + +void GraphicsHelperGL3::glUniform3uiv(GLint location, GLsizei count, const GLuint *values) +{ + m_funcs->glUniform3uiv(location, count, values); +} + +void GraphicsHelperGL3::glUniform4uiv(GLint location, GLsizei count, const GLuint *values) +{ + m_funcs->glUniform4uiv(location, count, values); +} + +void GraphicsHelperGL3::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix2fv(location, count, false, values); +} + +void GraphicsHelperGL3::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix3fv(location, count, false, values); +} + +void GraphicsHelperGL3::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix4fv(location, count, false, values); +} + +void GraphicsHelperGL3::glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix2x3fv(location, count, false, values); +} + +void GraphicsHelperGL3::glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix3x2fv(location, count, false, values); +} + +void GraphicsHelperGL3::glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix2x4fv(location, count, false, values); +} + +void GraphicsHelperGL3::glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix4x2fv(location, count, false, values); +} + +void GraphicsHelperGL3::glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix3x4fv(location, count, false, values); +} + +void GraphicsHelperGL3::glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix4x3fv(location, count, false, values); +} + +UniformType GraphicsHelperGL3::uniformTypeFromGLType(GLenum type) +{ + switch (type) { + case GL_FLOAT: + return UniformType::Float; + case GL_FLOAT_VEC2: + return UniformType::Vec2; + case GL_FLOAT_VEC3: + return UniformType::Vec3; + case GL_FLOAT_VEC4: + return UniformType::Vec4; + case GL_FLOAT_MAT2: + return UniformType::Mat2; + case GL_FLOAT_MAT3: + return UniformType::Mat3; + case GL_FLOAT_MAT4: + return UniformType::Mat4; + case GL_FLOAT_MAT2x3: + return UniformType::Mat2x3; + case GL_FLOAT_MAT3x2: + return UniformType::Mat3x2; + case GL_FLOAT_MAT2x4: + return UniformType::Mat2x4; + case GL_FLOAT_MAT4x2: + return UniformType::Mat4x2; + case GL_FLOAT_MAT3x4: + return UniformType::Mat3x4; + case GL_FLOAT_MAT4x3: + return UniformType::Mat4x3; + case GL_INT: + return UniformType::Int; + case GL_INT_VEC2: + return UniformType::IVec2; + case GL_INT_VEC3: + return UniformType::IVec3; + case GL_INT_VEC4: + return UniformType::IVec4; + case GL_BOOL: + return UniformType::Bool; + case GL_BOOL_VEC2: + return UniformType::BVec2; + case GL_BOOL_VEC3: + return UniformType::BVec3; + case GL_BOOL_VEC4: + return UniformType::BVec4; + + case GL_SAMPLER_1D: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_2D: + case GL_SAMPLER_2D_RECT: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_2D_RECT_SHADOW: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_CUBE_SHADOW: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_ARRAY_SHADOW: + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_SAMPLER_3D: + case GL_INT_SAMPLER_1D: + case GL_INT_SAMPLER_2D: + case GL_INT_SAMPLER_3D: + case GL_INT_SAMPLER_CUBE: + case GL_INT_SAMPLER_1D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE: + case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_1D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + return UniformType::Sampler; + default: + Q_UNREACHABLE(); + return UniformType::Float; + } +} + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/graphicshelpers/graphicshelpergl3_3.cpp b/src/render/graphicshelpers/graphicshelpergl3_3.cpp index fe257ce27..53b89bdef 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_3.cpp +++ b/src/render/graphicshelpers/graphicshelpergl3_3.cpp @@ -76,6 +76,10 @@ GraphicsHelperGL3_3::GraphicsHelperGL3_3() { } +GraphicsHelperGL3_3::~GraphicsHelperGL3_3() +{ +} + void GraphicsHelperGL3_3::initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) { @@ -383,6 +387,7 @@ bool GraphicsHelperGL3_3::supportsFeature(GraphicsHelperInterface::Feature featu case PrimitiveRestart: case RenderBufferDimensionRetrieval: case TextureDimensionRetrieval: + case BindableFragmentOutputs: return true; case Tessellation: return !m_tessFuncs.isNull(); @@ -407,182 +412,6 @@ void GraphicsHelperGL3_3::bindFragDataLocation(GLuint shader, const QHash<QStrin m_funcs->glBindFragDataLocation(shader, it.value(), it.key().toStdString().c_str()); } -void GraphicsHelperGL3_3::bindUniform(const QVariant &v, const ShaderUniform &description) -{ - switch (description.m_type) { - - case GL_FLOAT: - m_funcs->glUniform1fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 1)); - break; - - case GL_FLOAT_VEC2: - m_funcs->glUniform2fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2)); - break; - - case GL_FLOAT_VEC3: - m_funcs->glUniform3fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3)); - break; - - case GL_FLOAT_VEC4: - m_funcs->glUniform4fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4)); - break; - - case GL_FLOAT_MAT2: - m_funcs->glUniformMatrix2fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4)); - break; - - case GL_FLOAT_MAT2x3: - m_funcs->glUniformMatrix2x3fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6)); - break; - - case GL_FLOAT_MAT2x4: - m_funcs->glUniformMatrix2x4fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8)); - break; - - case GL_FLOAT_MAT3: - m_funcs->glUniformMatrix3fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9)); - break; - - case GL_FLOAT_MAT3x2: - m_funcs->glUniformMatrix3x2fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6)); - break; - - case GL_FLOAT_MAT3x4: - m_funcs->glUniformMatrix3x4fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12)); - break; - - case GL_FLOAT_MAT4: - m_funcs->glUniformMatrix4fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16)); - break; - - case GL_FLOAT_MAT4x2: - m_funcs->glUniformMatrix4x2fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8)); - break; - - case GL_FLOAT_MAT4x3: - m_funcs->glUniformMatrix4x3fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12)); - break; - - case GL_INT: - m_funcs->glUniform1iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1)); - break; - - case GL_INT_VEC2: - m_funcs->glUniform2iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2)); - break; - - case GL_INT_VEC3: - m_funcs->glUniform3iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3)); - break; - - case GL_INT_VEC4: - m_funcs->glUniform4iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4)); - break; - - case GL_UNSIGNED_INT: - m_funcs->glUniform1uiv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 1)); - break; - - case GL_UNSIGNED_INT_VEC2: - m_funcs->glUniform2uiv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 2)); - break; - - case GL_UNSIGNED_INT_VEC3: - m_funcs->glUniform3uiv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 3)); - break; - - case GL_UNSIGNED_INT_VEC4: - m_funcs->glUniform4uiv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 4)); - break; - - case GL_BOOL: - m_funcs->glUniform1iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1)); - break; - - case GL_BOOL_VEC2: - m_funcs->glUniform2iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2)); - break; - - case GL_BOOL_VEC3: - m_funcs->glUniform3iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3)); - break; - - case GL_BOOL_VEC4: - m_funcs->glUniform4iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4)); - break; - - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_BUFFER: - case GL_SAMPLER_2D_RECT: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_2D_RECT: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_2D_RECT: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_1D_ARRAY_SHADOW: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: { - Q_ASSERT(description.m_size == 1); - m_funcs->glUniform1i(description.m_location, v.toInt()); - break; - } - - default: - qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name; - break; - } -} - void GraphicsHelperGL3_3::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) { m_funcs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding); @@ -1033,6 +862,205 @@ void GraphicsHelperGL3_3::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) qWarning() << "Compute Shaders are not supported by OpenGL 3.3 (since OpenGL 4.3)"; } +void GraphicsHelperGL3_3::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform1fv(location, count, values); +} + +void GraphicsHelperGL3_3::glUniform2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform2fv(location, count, values); +} + +void GraphicsHelperGL3_3::glUniform3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform3fv(location, count, values); +} + +void GraphicsHelperGL3_3::glUniform4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform4fv(location, count, values); +} + +void GraphicsHelperGL3_3::glUniform1iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform1iv(location, count, values); +} + +void GraphicsHelperGL3_3::glUniform2iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform2iv(location, count, values); +} + +void GraphicsHelperGL3_3::glUniform3iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform3iv(location, count, values); +} + +void GraphicsHelperGL3_3::glUniform4iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform4iv(location, count, values); +} + +void GraphicsHelperGL3_3::glUniform1uiv(GLint location, GLsizei count, const GLuint *values) +{ + m_funcs->glUniform1uiv(location, count, values); +} + +void GraphicsHelperGL3_3::glUniform2uiv(GLint location, GLsizei count, const GLuint *values) +{ + m_funcs->glUniform2uiv(location, count, values); +} + +void GraphicsHelperGL3_3::glUniform3uiv(GLint location, GLsizei count, const GLuint *values) +{ + m_funcs->glUniform3uiv(location, count, values); +} + +void GraphicsHelperGL3_3::glUniform4uiv(GLint location, GLsizei count, const GLuint *values) +{ + m_funcs->glUniform4uiv(location, count, values); +} + +void GraphicsHelperGL3_3::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix2fv(location, count, false, values); +} + +void GraphicsHelperGL3_3::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix3fv(location, count, false, values); +} + +void GraphicsHelperGL3_3::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix4fv(location, count, false, values); +} + +void GraphicsHelperGL3_3::glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix2x3fv(location, count, false, values); +} + +void GraphicsHelperGL3_3::glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix3x2fv(location, count, false, values); +} + +void GraphicsHelperGL3_3::glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix2x4fv(location, count, false, values); +} + +void GraphicsHelperGL3_3::glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix4x2fv(location, count, false, values); +} + +void GraphicsHelperGL3_3::glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix3x4fv(location, count, false, values); +} + +void GraphicsHelperGL3_3::glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix4x3fv(location, count, false, values); +} + +UniformType GraphicsHelperGL3_3::uniformTypeFromGLType(GLenum type) +{ + switch (type) { + case GL_FLOAT: + return UniformType::Float; + case GL_FLOAT_VEC2: + return UniformType::Vec2; + case GL_FLOAT_VEC3: + return UniformType::Vec3; + case GL_FLOAT_VEC4: + return UniformType::Vec4; + case GL_FLOAT_MAT2: + return UniformType::Mat2; + case GL_FLOAT_MAT3: + return UniformType::Mat3; + case GL_FLOAT_MAT4: + return UniformType::Mat4; + case GL_FLOAT_MAT2x3: + return UniformType::Mat2x3; + case GL_FLOAT_MAT3x2: + return UniformType::Mat3x2; + case GL_FLOAT_MAT2x4: + return UniformType::Mat2x4; + case GL_FLOAT_MAT4x2: + return UniformType::Mat4x2; + case GL_FLOAT_MAT3x4: + return UniformType::Mat3x4; + case GL_FLOAT_MAT4x3: + return UniformType::Mat4x3; + case GL_INT: + return UniformType::Int; + case GL_INT_VEC2: + return UniformType::IVec2; + case GL_INT_VEC3: + return UniformType::IVec3; + case GL_INT_VEC4: + return UniformType::IVec4; + case GL_UNSIGNED_INT: + return UniformType::UInt; + case GL_UNSIGNED_INT_VEC2: + return UniformType::UIVec2; + case GL_UNSIGNED_INT_VEC3: + return UniformType::UIVec3; + case GL_UNSIGNED_INT_VEC4: + return UniformType::UIVec4; + case GL_BOOL: + return UniformType::Bool; + case GL_BOOL_VEC2: + return UniformType::BVec2; + case GL_BOOL_VEC3: + return UniformType::BVec3; + case GL_BOOL_VEC4: + return UniformType::BVec4; + + case GL_SAMPLER_BUFFER: + case GL_SAMPLER_1D: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_1D_ARRAY: + case GL_SAMPLER_2D: + case GL_SAMPLER_2D_RECT: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_2D_RECT_SHADOW: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_CUBE_SHADOW: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_ARRAY_SHADOW: + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_SAMPLER_3D: + case GL_INT_SAMPLER_BUFFER: + case GL_INT_SAMPLER_1D: + case GL_INT_SAMPLER_2D: + case GL_INT_SAMPLER_3D: + case GL_INT_SAMPLER_CUBE: + case GL_INT_SAMPLER_1D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE: + case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_BUFFER: + case GL_UNSIGNED_INT_SAMPLER_1D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + return UniformType::Sampler; + default: + Q_UNREACHABLE(); + return UniformType::Float; + } +} + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/graphicshelpers/graphicshelpergl3_3_p.h b/src/render/graphicshelpers/graphicshelpergl3_3_p.h index bb6946a20..bbea8806a 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_3_p.h +++ b/src/render/graphicshelpers/graphicshelpergl3_3_p.h @@ -64,10 +64,11 @@ class QOpenGLExtension_ARB_tessellation_shader; namespace Qt3DRender { namespace Render { -class GraphicsHelperGL3_3 : public GraphicsHelperInterface +class Q_AUTOTEST_EXPORT GraphicsHelperGL3_3 : public GraphicsHelperInterface { public: GraphicsHelperGL3_3(); + ~GraphicsHelperGL3_3(); // QGraphicHelperInterface interface void alphaTest(GLenum mode1, GLenum mode2) Q_DECL_OVERRIDE; @@ -77,7 +78,6 @@ public: void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE; void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE; void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE; - void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE; void blendEquation(GLenum mode) Q_DECL_OVERRIDE; void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) Q_DECL_OVERRIDE; void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) Q_DECL_OVERRIDE; @@ -122,6 +122,33 @@ public: void useProgram(GLuint programId) Q_DECL_OVERRIDE; void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE; + void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + + void glUniform1iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform2iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform3iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform4iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + + void glUniform1uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform2uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform3uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform4uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + + void glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + + UniformType uniformTypeFromGLType(GLenum glType) Q_DECL_OVERRIDE; + private: QOpenGLFunctions_3_3_Core *m_funcs; QScopedPointer<QOpenGLExtension_ARB_tessellation_shader> m_tessFuncs; diff --git a/src/render/graphicshelpers/graphicshelpergl3_p.h b/src/render/graphicshelpers/graphicshelpergl3_p.h index 721078130..3cc58bd26 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_p.h +++ b/src/render/graphicshelpers/graphicshelpergl3_p.h @@ -77,7 +77,6 @@ public: void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE; void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE; void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE; - void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE; void blendEquation(GLenum mode) Q_DECL_OVERRIDE; void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) Q_DECL_OVERRIDE; void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) Q_DECL_OVERRIDE; @@ -122,6 +121,33 @@ public: void useProgram(GLuint programId) Q_DECL_OVERRIDE; void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE; + void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + + void glUniform1iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform2iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform3iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform4iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + + void glUniform1uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform2uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform3uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform4uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + + void glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + + UniformType uniformTypeFromGLType(GLenum glType) Q_DECL_OVERRIDE; + private: QOpenGLFunctions_3_2_Core *m_funcs; QScopedPointer<QOpenGLExtension_ARB_tessellation_shader> m_tessFuncs; diff --git a/src/render/graphicshelpers/graphicshelpergl4.cpp b/src/render/graphicshelpers/graphicshelpergl4.cpp index 6d7a3b5b1..230b02a63 100644 --- a/src/render/graphicshelpers/graphicshelpergl4.cpp +++ b/src/render/graphicshelpers/graphicshelpergl4.cpp @@ -266,6 +266,210 @@ void GraphicsHelperGL4::vertexAttribDivisor(GLuint index, GLuint divisor) m_funcs->glVertexAttribDivisor(index, divisor); } +void GraphicsHelperGL4::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform1fv(location, count, values); +} + +void GraphicsHelperGL4::glUniform2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform2fv(location, count, values); +} + +void GraphicsHelperGL4::glUniform3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform3fv(location, count, values); +} + +void GraphicsHelperGL4::glUniform4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniform4fv(location, count, values); +} + +void GraphicsHelperGL4::glUniform1iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform1iv(location, count, values); +} + +void GraphicsHelperGL4::glUniform2iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform2iv(location, count, values); +} + +void GraphicsHelperGL4::glUniform3iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform3iv(location, count, values); +} + +void GraphicsHelperGL4::glUniform4iv(GLint location, GLsizei count, const GLint *values) +{ + m_funcs->glUniform4iv(location, count, values); +} + +void GraphicsHelperGL4::glUniform1uiv(GLint location, GLsizei count, const GLuint *values) +{ + m_funcs->glUniform1uiv(location, count, values); +} + +void GraphicsHelperGL4::glUniform2uiv(GLint location, GLsizei count, const GLuint *values) +{ + m_funcs->glUniform2uiv(location, count, values); +} + +void GraphicsHelperGL4::glUniform3uiv(GLint location, GLsizei count, const GLuint *values) +{ + m_funcs->glUniform3uiv(location, count, values); +} + +void GraphicsHelperGL4::glUniform4uiv(GLint location, GLsizei count, const GLuint *values) +{ + m_funcs->glUniform4uiv(location, count, values); +} + +void GraphicsHelperGL4::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix2fv(location, count, false, values); +} + +void GraphicsHelperGL4::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix3fv(location, count, false, values); +} + +void GraphicsHelperGL4::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix4fv(location, count, false, values); +} + +void GraphicsHelperGL4::glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix2x3fv(location, count, false, values); +} + +void GraphicsHelperGL4::glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix3x2fv(location, count, false, values); +} + +void GraphicsHelperGL4::glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix2x4fv(location, count, false, values); +} + +void GraphicsHelperGL4::glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix4x2fv(location, count, false, values); +} + +void GraphicsHelperGL4::glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix3x4fv(location, count, false, values); +} + +void GraphicsHelperGL4::glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *values) +{ + m_funcs->glUniformMatrix4x3fv(location, count, false, values); +} + +UniformType GraphicsHelperGL4::uniformTypeFromGLType(GLenum type) +{ + switch (type) { + case GL_FLOAT: + return UniformType::Float; + case GL_FLOAT_VEC2: + return UniformType::Vec2; + case GL_FLOAT_VEC3: + return UniformType::Vec3; + case GL_FLOAT_VEC4: + return UniformType::Vec4; + case GL_FLOAT_MAT2: + return UniformType::Mat2; + case GL_FLOAT_MAT3: + return UniformType::Mat3; + case GL_FLOAT_MAT4: + return UniformType::Mat4; + case GL_FLOAT_MAT2x3: + return UniformType::Mat2x3; + case GL_FLOAT_MAT3x2: + return UniformType::Mat3x2; + case GL_FLOAT_MAT2x4: + return UniformType::Mat2x4; + case GL_FLOAT_MAT4x2: + return UniformType::Mat4x2; + case GL_FLOAT_MAT3x4: + return UniformType::Mat3x4; + case GL_FLOAT_MAT4x3: + return UniformType::Mat4x3; + case GL_INT: + return UniformType::Int; + case GL_INT_VEC2: + return UniformType::IVec2; + case GL_INT_VEC3: + return UniformType::IVec3; + case GL_INT_VEC4: + return UniformType::IVec4; + case GL_UNSIGNED_INT: + return UniformType::UInt; + case GL_UNSIGNED_INT_VEC2: + return UniformType::UIVec2; + case GL_UNSIGNED_INT_VEC3: + return UniformType::UIVec3; + case GL_UNSIGNED_INT_VEC4: + return UniformType::UIVec4; + case GL_BOOL: + return UniformType::Bool; + case GL_BOOL_VEC2: + return UniformType::BVec2; + case GL_BOOL_VEC3: + return UniformType::BVec3; + case GL_BOOL_VEC4: + return UniformType::BVec4; + + case GL_SAMPLER_1D: + case GL_SAMPLER_1D_ARRAY: + case GL_SAMPLER_1D_SHADOW: + case GL_SAMPLER_2D: + case GL_SAMPLER_2D_RECT: + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_2D_RECT_SHADOW: + case GL_SAMPLER_CUBE: + case GL_SAMPLER_CUBE_SHADOW: + case GL_SAMPLER_CUBE_MAP_ARRAY: + case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: + case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_ARRAY_SHADOW: + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_SAMPLER_3D: + case GL_SAMPLER_BUFFER: + case GL_INT_SAMPLER_1D: + case GL_INT_SAMPLER_2D: + case GL_INT_SAMPLER_3D: + case GL_INT_SAMPLER_BUFFER: + case GL_INT_SAMPLER_CUBE: + case GL_INT_SAMPLER_CUBE_MAP_ARRAY: + case GL_INT_SAMPLER_1D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE: + case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_1D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_BUFFER: + case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY: + return UniformType::Sampler; + default: + // TO DO: Add support for Doubles and Images + Q_UNREACHABLE(); + return UniformType::Float; + } +} + void GraphicsHelperGL4::blendEquation(GLenum mode) { m_funcs->glBlendEquation(mode); @@ -375,6 +579,8 @@ bool GraphicsHelperGL4::supportsFeature(GraphicsHelperInterface::Feature feature case MRT: case Tessellation: case UniformBufferObject: + case BindableFragmentOutputs: + case PrimitiveRestart: case RenderBufferDimensionRetrieval: case TextureDimensionRetrieval: case ShaderStorageObject: @@ -402,182 +608,6 @@ void GraphicsHelperGL4::bindFragDataLocation(GLuint shader, const QHash<QString, m_funcs->glBindFragDataLocation(shader, it.value(), it.key().toStdString().c_str()); } -void GraphicsHelperGL4::bindUniform(const QVariant &v, const ShaderUniform &description) -{ - switch (description.m_type) { - - case GL_FLOAT: - m_funcs->glUniform1fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 1)); - break; - - case GL_FLOAT_VEC2: - m_funcs->glUniform2fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2)); - break; - - case GL_FLOAT_VEC3: - m_funcs->glUniform3fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3)); - break; - - case GL_FLOAT_VEC4: - m_funcs->glUniform4fv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4)); - break; - - case GL_FLOAT_MAT2: - m_funcs->glUniformMatrix2fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4)); - break; - - case GL_FLOAT_MAT2x3: - m_funcs->glUniformMatrix2x3fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6)); - break; - - case GL_FLOAT_MAT2x4: - m_funcs->glUniformMatrix2x4fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8)); - break; - - case GL_FLOAT_MAT3: - m_funcs->glUniformMatrix3fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9)); - break; - - case GL_FLOAT_MAT3x2: - m_funcs->glUniformMatrix3x2fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6)); - break; - - case GL_FLOAT_MAT3x4: - m_funcs->glUniformMatrix3x4fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12)); - break; - - case GL_FLOAT_MAT4: - m_funcs->glUniformMatrix4fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16)); - break; - - case GL_FLOAT_MAT4x2: - m_funcs->glUniformMatrix4x2fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8)); - break; - - case GL_FLOAT_MAT4x3: - m_funcs->glUniformMatrix4x3fv(description.m_location, description.m_size, GL_FALSE, - QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12)); - break; - - case GL_INT: - m_funcs->glUniform1iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1)); - break; - - case GL_INT_VEC2: - m_funcs->glUniform2iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2)); - break; - - case GL_INT_VEC3: - m_funcs->glUniform3iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3)); - break; - - case GL_INT_VEC4: - m_funcs->glUniform4iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4)); - break; - - case GL_UNSIGNED_INT: - m_funcs->glUniform1uiv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 1)); - break; - - case GL_UNSIGNED_INT_VEC2: - m_funcs->glUniform2uiv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 2)); - break; - - case GL_UNSIGNED_INT_VEC3: - m_funcs->glUniform3uiv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 3)); - break; - - case GL_UNSIGNED_INT_VEC4: - m_funcs->glUniform4uiv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 4)); - break; - - case GL_BOOL: - m_funcs->glUniform1iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1)); - break; - - case GL_BOOL_VEC2: - m_funcs->glUniform2iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2)); - break; - - case GL_BOOL_VEC3: - m_funcs->glUniform3iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3)); - break; - - case GL_BOOL_VEC4: - m_funcs->glUniform4iv(description.m_location, description.m_size, - QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4)); - break; - - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_BUFFER: - case GL_SAMPLER_2D_RECT: - case GL_INT_SAMPLER_1D: - case GL_INT_SAMPLER_2D: - case GL_INT_SAMPLER_3D: - case GL_INT_SAMPLER_CUBE: - case GL_INT_SAMPLER_BUFFER: - case GL_INT_SAMPLER_2D_RECT: - case GL_UNSIGNED_INT_SAMPLER_1D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_BUFFER: - case GL_UNSIGNED_INT_SAMPLER_2D_RECT: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_CUBE_SHADOW: - case GL_SAMPLER_1D_ARRAY: - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_1D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_1D_ARRAY_SHADOW: - case GL_SAMPLER_2D_ARRAY_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW: - case GL_SAMPLER_2D_MULTISAMPLE: - case GL_INT_SAMPLER_2D_MULTISAMPLE: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: - case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: { - Q_ASSERT(description.m_size == 1); - m_funcs->glUniform1i(description.m_location, v.toInt()); - break; - } - - default: - qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name; - break; - } -} - void GraphicsHelperGL4::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) { m_funcs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding); diff --git a/src/render/graphicshelpers/graphicshelpergl4_p.h b/src/render/graphicshelpers/graphicshelpergl4_p.h index 38a01e271..ad4875f2e 100644 --- a/src/render/graphicshelpers/graphicshelpergl4_p.h +++ b/src/render/graphicshelpers/graphicshelpergl4_p.h @@ -76,7 +76,6 @@ public: void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE; void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE; void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE; - void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE; void blendEquation(GLenum mode) Q_DECL_OVERRIDE; void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) Q_DECL_OVERRIDE; void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) Q_DECL_OVERRIDE; @@ -121,6 +120,33 @@ public: void useProgram(GLuint programId) Q_DECL_OVERRIDE; void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE; + void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + + void glUniform1iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform2iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform3iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + void glUniform4iv(GLint location, GLsizei count, const GLint *value) Q_DECL_OVERRIDE; + + void glUniform1uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform2uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform3uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + void glUniform4uiv(GLint location, GLsizei count, const GLuint *value) Q_DECL_OVERRIDE; + + void glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + void glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) Q_DECL_OVERRIDE; + + UniformType uniformTypeFromGLType(GLenum glType) Q_DECL_OVERRIDE; + private: QOpenGLFunctions_4_3_Core *m_funcs; }; diff --git a/src/render/graphicshelpers/graphicshelperinterface_p.h b/src/render/graphicshelpers/graphicshelperinterface_p.h index 6e7caee6a..1a7199a2c 100644 --- a/src/render/graphicshelpers/graphicshelperinterface_p.h +++ b/src/render/graphicshelpers/graphicshelperinterface_p.h @@ -55,6 +55,7 @@ #include <QOpenGLTexture> #include <QVector> #include <Qt3DRender/private/shadervariables_p.h> +#include <Qt3DRender/private/uniform_p.h> QT_BEGIN_NAMESPACE @@ -87,7 +88,6 @@ public: virtual void bindFrameBufferObject(GLuint frameBufferId) = 0; virtual void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) = 0; virtual void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0; - virtual void bindUniform(const QVariant &v, const ShaderUniform &description) = 0; virtual void blendEquation(GLenum mode) = 0; virtual void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) = 0; virtual void blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) = 0; @@ -131,6 +131,33 @@ public: virtual uint uniformByteSize(const ShaderUniform &description) = 0; virtual void useProgram(GLuint programId) = 0; virtual void vertexAttribDivisor(GLuint index, GLuint divisor) = 0; + + virtual void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) = 0; + virtual void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) = 0; + virtual void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) = 0; + virtual void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) = 0; + + virtual void glUniform1iv(GLint location, GLsizei count, const GLint *value) = 0; + virtual void glUniform2iv(GLint location, GLsizei count, const GLint *value) = 0; + virtual void glUniform3iv(GLint location, GLsizei count, const GLint *value) = 0; + virtual void glUniform4iv(GLint location, GLsizei count, const GLint *value) = 0; + + virtual void glUniform1uiv(GLint location, GLsizei count, const GLuint *value) = 0; + virtual void glUniform2uiv(GLint location, GLsizei count, const GLuint *value) = 0; + virtual void glUniform3uiv(GLint location, GLsizei count, const GLuint *value) = 0; + virtual void glUniform4uiv(GLint location, GLsizei count, const GLuint *value) = 0; + + virtual void glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) = 0; + virtual void glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) = 0; + virtual void glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) = 0; + virtual void glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) = 0; + virtual void glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) = 0; + virtual void glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) = 0; + virtual void glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) = 0; + virtual void glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) = 0; + virtual void glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) = 0; + + virtual UniformType uniformTypeFromGLType(GLenum glType) = 0; }; diff --git a/src/render/jobs/calcboundingvolumejob_p.h b/src/render/jobs/calcboundingvolumejob_p.h index c507f7f2d..cd09aa37b 100644 --- a/src/render/jobs/calcboundingvolumejob_p.h +++ b/src/render/jobs/calcboundingvolumejob_p.h @@ -72,8 +72,6 @@ public: void setRoot(Entity *node); void setManagers(NodeManagers *manager); - -protected: void run() Q_DECL_OVERRIDE; private: diff --git a/src/render/jobs/calcgeometrytrianglevolumes_p.h b/src/render/jobs/calcgeometrytrianglevolumes_p.h index 96c9854d9..4b77d6f5e 100644 --- a/src/render/jobs/calcgeometrytrianglevolumes_p.h +++ b/src/render/jobs/calcgeometrytrianglevolumes_p.h @@ -67,8 +67,6 @@ class Q_AUTOTEST_EXPORT CalcGeometryTriangleVolumes : public Qt3DCore::QAspectJo { public: explicit CalcGeometryTriangleVolumes(const Qt3DCore::QNodeId geometryRendererId, NodeManagers *manager); - -protected: void run() Q_DECL_OVERRIDE; private: diff --git a/src/render/jobs/expandboundingvolumejob_p.h b/src/render/jobs/expandboundingvolumejob_p.h index d20722eb8..2153e3035 100644 --- a/src/render/jobs/expandboundingvolumejob_p.h +++ b/src/render/jobs/expandboundingvolumejob_p.h @@ -69,8 +69,6 @@ public: ExpandBoundingVolumeJob(); void setRoot(Entity *root); - -protected: void run() Q_DECL_OVERRIDE; private: diff --git a/src/render/jobs/filterlayerentityjob.cpp b/src/render/jobs/filterlayerentityjob.cpp index d22b61337..668193fd0 100644 --- a/src/render/jobs/filterlayerentityjob.cpp +++ b/src/render/jobs/filterlayerentityjob.cpp @@ -49,13 +49,9 @@ namespace Qt3DRender { namespace Render { -#ifdef QT3D_JOBS_RUN_STATS namespace { - int layerFilterJobCounter = 0; - } // anonymous -#endif FilterLayerEntityJob::FilterLayerEntityJob() : Qt3DCore::QAspectJob() diff --git a/src/render/jobs/job_common_p.h b/src/render/jobs/job_common_p.h index a24c428eb..3266e0f6d 100644 --- a/src/render/jobs/job_common_p.h +++ b/src/render/jobs/job_common_p.h @@ -83,7 +83,8 @@ namespace JobTypes { FrustumCulling, LightGathering, UpdateWorldBoundingVolume, - FrameSubmissionPart2 + FrameSubmissionPart2, + SendRenderCapture, }; } // JobTypes diff --git a/src/render/jobs/jobs.pri b/src/render/jobs/jobs.pri index a970f2efc..9ad8f9bc0 100644 --- a/src/render/jobs/jobs.pri +++ b/src/render/jobs/jobs.pri @@ -22,7 +22,8 @@ HEADERS += \ $$PWD/frustumcullingjob_p.h \ $$PWD/lightgatherer_p.h \ $$PWD/expandboundingvolumejob_p.h \ - $$PWD/updateworldboundingvolumejob_p.h + $$PWD/updateworldboundingvolumejob_p.h \ + $$PWD/sendrendercapturejob_p.h SOURCES += \ $$PWD/updateworldtransformjob.cpp \ @@ -43,4 +44,5 @@ SOURCES += \ $$PWD/frustumcullingjob.cpp \ $$PWD/lightgatherer.cpp \ $$PWD/expandboundingvolumejob.cpp \ - $$PWD/updateworldboundingvolumejob.cpp + $$PWD/updateworldboundingvolumejob.cpp \ + $$PWD/sendrendercapturejob.cpp diff --git a/src/render/jobs/loadbufferjob_p.h b/src/render/jobs/loadbufferjob_p.h index c7b744310..65262a2f6 100644 --- a/src/render/jobs/loadbufferjob_p.h +++ b/src/render/jobs/loadbufferjob_p.h @@ -64,16 +64,16 @@ namespace Render { class NodeManagers; -class LoadBufferJob : public Qt3DCore::QAspectJob +class Q_AUTOTEST_EXPORT LoadBufferJob : public Qt3DCore::QAspectJob { public: explicit LoadBufferJob(const HBuffer &handle); ~LoadBufferJob(); void setNodeManager(NodeManagers *nodeManagers) { m_nodeManagers = nodeManagers; } + void run() Q_DECL_OVERRIDE; protected: - void run() Q_DECL_OVERRIDE; HBuffer m_handle; NodeManagers *m_nodeManagers; }; diff --git a/src/render/jobs/materialparametergathererjob.cpp b/src/render/jobs/materialparametergathererjob.cpp index f7ee96403..9c7209cec 100644 --- a/src/render/jobs/materialparametergathererjob.cpp +++ b/src/render/jobs/materialparametergathererjob.cpp @@ -52,10 +52,7 @@ namespace Render { namespace { -#ifdef QT3D_JOBS_RUN_STATS int materialParameterGathererCounter = 0; -#endif - const int likelyNumberOfParameters = 24; } // anonymous diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp index 21cf36afc..19f1d2b1c 100644 --- a/src/render/jobs/pickboundingvolumejob.cpp +++ b/src/render/jobs/pickboundingvolumejob.cpp @@ -52,7 +52,6 @@ #include <Qt3DRender/private/sphere_p.h> #include <Qt3DRender/private/geometryrenderer_p.h> #include <Qt3DRender/private/trianglesvisitor_p.h> -#include <Qt3DRender/private/triangleboundingvolume_p.h> #include <Qt3DRender/private/qraycastingservice_p.h> #include <Qt3DRender/private/rendersurfaceselector_p.h> #include <Qt3DRender/private/rendersettings_p.h> @@ -190,23 +189,30 @@ public: typedef QVector<QCollisionQueryResult::Hit> HitList; HitList hits; - CollisionVisitor(NodeManagers* manager, const Entity *root, const QRay3D& ray) : TrianglesVisitor(manager), m_root(root), m_ray(ray), m_triangleIndex(0) { } + CollisionVisitor(NodeManagers* manager, const Entity *root, const QRay3D& ray, QPickingSettings::FaceOrientationPickingMode faceOrientationPickingMode) : TrianglesVisitor(manager), m_root(root), m_ray(ray), m_faceOrientationPickingMode(faceOrientationPickingMode), m_triangleIndex(0) { } private: const Entity *m_root; QRay3D m_ray; - Qt3DRender::QRayCastingService rayCasting; + QPickingSettings::FaceOrientationPickingMode m_faceOrientationPickingMode; uint m_triangleIndex; void visit(uint andx, const QVector3D &a, uint bndx, const QVector3D &b, uint cndx, const QVector3D &c) { - TriangleBoundingVolume volume(m_root->peerId(), a, b, c); - volume = volume.transform(*m_root->worldTransform()); - - QCollisionQueryResult::Hit queryResult = rayCasting.query(m_ray, &volume); - if (queryResult.m_distance > 0.) { - queryResult.m_triangleIndex = m_triangleIndex; + const QMatrix4x4* mat = m_root->worldTransform(); + const QVector3D tA = *mat * a; + const QVector3D tB = *mat * b; + const QVector3D tC = *mat * c; + + float t = 0.f; + QVector3D uvw; + bool intersects = intersectsSegmentTriangle(m_ray, tC, tB, tA, uvw, t); + if (intersects) { + QCollisionQueryResult::Hit queryResult; + queryResult.m_intersection = m_ray.point(t * m_ray.distance()); + queryResult.m_distance = m_ray.projectedDistance(queryResult.m_intersection); + queryResult.m_entityId = m_root->peerId(); queryResult.m_vertexIndex[0] = andx; queryResult.m_vertexIndex[1] = bndx; queryResult.m_vertexIndex[2] = cndx; @@ -215,6 +221,51 @@ private: m_triangleIndex++; } + + // Note: a, b, c in clockwise order + // RealTime Collision Detection page 192 + bool intersectsSegmentTriangle(const QRay3D &ray, + const QVector3D &a, + const QVector3D &b, + const QVector3D &c, + QVector3D &uvw, + float &t) + { + const QVector3D ab = b - a; + const QVector3D ac = c - a; + const QVector3D qp = (ray.origin() - ray.point(ray.distance())); + + const QVector3D n = QVector3D::crossProduct(ab, ac); + const float d = QVector3D::dotProduct(qp, n); + + if (d <= 0.0f && 0 == (m_faceOrientationPickingMode & QPickingSettings::BackFace)) + return false; + + const QVector3D ap = ray.origin() - a; + t = QVector3D::dotProduct(ap, n); + + if (t < 0.0f || t > d) + return false; + + const QVector3D e = QVector3D::crossProduct(qp, ap); + uvw.setY(QVector3D::dotProduct(ac, e)); + + if (uvw.y() < 0.0f || uvw.y() > d) + return false; + + uvw.setZ(-QVector3D::dotProduct(ab, e)); + + if (uvw.z() < 0.0f || uvw.y() + uvw.z() > d) + return false; + + const float ood = 1.0f / d; + t *= ood; + uvw.setY(uvw.y() * ood); + uvw.setZ(uvw.z() * ood); + uvw.setX(1.0f - uvw.y() - uvw.z()); + + return true; + } }; struct AbstractCollisionGathererFunctor @@ -269,6 +320,10 @@ struct EntityCollisionGathererFunctor : public AbstractCollisionGathererFunctor struct TriangleCollisionGathererFunctor : public AbstractCollisionGathererFunctor { + TriangleCollisionGathererFunctor() : AbstractCollisionGathererFunctor(), m_pickBackFacingTriangles(QPickingSettings::FrontFace) { } + + QPickingSettings::FaceOrientationPickingMode m_pickBackFacingTriangles; + result_type pick(QAbstractCollisionQueryService *rayCasting, const Entity *entity) const Q_DECL_OVERRIDE { result_type result; @@ -278,7 +333,7 @@ struct TriangleCollisionGathererFunctor : public AbstractCollisionGathererFuncto return result; if (rayHitsEntity(rayCasting, entity)) { - CollisionVisitor visitor(m_renderer->nodeManagers(), entity, m_ray); + CollisionVisitor visitor(m_renderer->nodeManagers(), entity, m_ray, m_pickBackFacingTriangles); visitor.apply(gRenderer, entity->peerId()); result = visitor.hits; @@ -370,12 +425,71 @@ void PickBoundingVolumeJob::run() ViewportCameraAreaGatherer vcaGatherer; const QVector<ViewportCameraAreaTriplet> vcaTriplets = vcaGatherer.gather(m_renderer->frameGraphRoot()); - EntityGatherer entitiesGatherer(m_node); if (!vcaTriplets.empty()) { + bool hasMoveEvent = false; + bool hasOtherEvent = false; + for (const QMouseEvent &event : mouseEvents) { + const bool isMove = (event.type() == QEvent::MouseMove); + hasMoveEvent |= isMove; + hasOtherEvent |= !isMove; + } + + // We gather when we have a click/release event or a move + // event and a QObjectPicker enabled to receive it + ObjectPicker *lastCurrentPicker = m_manager->objectPickerManager()->data(m_currentPicker); + + // In the case we have a move event, find if we actually have + // an object picker that cares about these + if (!hasOtherEvent) { + // The only way to set lastCurrentPicker is to click + // so we can return since if we're there it means we + // have only move events + if (lastCurrentPicker == nullptr) + return; + + const bool caresAboutMove = (hasMoveEvent && lastCurrentPicker->isDragEnabled()); + // Early return if the current object picker doesn't care about move events + if (!caresAboutMove) + return; + } + + // Gather the entities for the frame + EntityGatherer entitiesGatherer(m_node); + + for (const QMouseEvent &event : mouseEvents) { + QPickEvent::Buttons eventButton = QPickEvent::NoButton; + switch (event.button()) { + case Qt::LeftButton: eventButton = QPickEvent::LeftButton; break; + case Qt::RightButton: eventButton = QPickEvent::RightButton; break; + case Qt::MiddleButton: eventButton = QPickEvent::MiddleButton; break; + case Qt::BackButton: eventButton = QPickEvent::BackButton; break; + default: break; + } + int eventButtons = 0; + if (event.buttons() & Qt::LeftButton) + eventButtons |= QPickEvent::LeftButton; + if (event.buttons() & Qt::RightButton) + eventButtons |= QPickEvent::RightButton; + if (event.buttons() & Qt::MiddleButton) + eventButtons |= QPickEvent::MiddleButton; + if (event.buttons() & Qt::BackButton) + eventButtons |= QPickEvent::BackButton; + int eventModifiers = QPickEvent::NoModifier; + if (event.modifiers() & Qt::ShiftModifier) + eventModifiers |= QPickEvent::ShiftModifier; + if (event.modifiers() & Qt::ControlModifier) + eventModifiers |= QPickEvent::ControlModifier; + if (event.modifiers() & Qt::AltModifier) + eventModifiers |= QPickEvent::AltModifier; + if (event.modifiers() & Qt::MetaModifier) + eventModifiers |= QPickEvent::MetaModifier; + if (event.modifiers() & Qt::KeypadModifier) + eventModifiers |= QPickEvent::KeypadModifier; + m_hoveredPickersToClear = m_hoveredPickers; - ObjectPicker *lastCurrentPicker = m_manager->objectPickerManager()->data(m_currentPicker); + lastCurrentPicker = m_manager->objectPickerManager()->data(m_currentPicker); for (const ViewportCameraAreaTriplet &vca : vcaTriplets) { typedef AbstractCollisionGathererFunctor::result_type HitList; @@ -386,6 +500,7 @@ void PickBoundingVolumeJob::run() TriangleCollisionGathererFunctor gathererFunctor; gathererFunctor.m_renderer = m_renderer; gathererFunctor.m_ray = ray; + gathererFunctor.m_pickBackFacingTriangles = m_renderer->settings()->faceOrientationPickingMode(); sphereHits = QtConcurrent::blockingMappedReduced<HitList>(entitiesGatherer.entities(), gathererFunctor, reducerOp); } else { EntityCollisionGathererFunctor gathererFunctor; @@ -426,9 +541,11 @@ void PickBoundingVolumeJob::run() QPickEventPtr pickEvent; if (m_renderer->settings() && m_renderer->settings()->pickMethod() == QPickingSettings::TrianglePicking) { pickEvent.reset(new QPickTriangleEvent(event.localPos(), hit.m_intersection, localIntersection, hit.m_distance, - hit.m_triangleIndex, hit.m_vertexIndex[0], hit.m_vertexIndex[1], hit.m_vertexIndex[2])); + hit.m_triangleIndex, hit.m_vertexIndex[0], hit.m_vertexIndex[1], hit.m_vertexIndex[2], + eventButton, eventButtons, eventModifiers)); } else { - pickEvent.reset(new QPickEvent(event.localPos(), hit.m_intersection, localIntersection, hit.m_distance)); + pickEvent.reset(new QPickEvent(event.localPos(), hit.m_intersection, localIntersection, hit.m_distance, + eventButton, eventButtons, eventModifiers)); } switch (event.type()) { diff --git a/src/render/jobs/renderviewbuilderjob.cpp b/src/render/jobs/renderviewbuilderjob.cpp index f0cf83e15..fa6218d6f 100644 --- a/src/render/jobs/renderviewbuilderjob.cpp +++ b/src/render/jobs/renderviewbuilderjob.cpp @@ -48,11 +48,9 @@ namespace Qt3DRender { namespace Render { -#ifdef QT3D_JOBS_RUN_STATS namespace { int renderViewInstanceCounter = 0; } // anonymous -#endif RenderViewBuilderJob::RenderViewBuilderJob() : Qt3DCore::QAspectJob(), diff --git a/src/render/jobs/renderviewinitializerjob.cpp b/src/render/jobs/renderviewinitializerjob.cpp index f43f86fac..7bf55be40 100644 --- a/src/render/jobs/renderviewinitializerjob.cpp +++ b/src/render/jobs/renderviewinitializerjob.cpp @@ -61,7 +61,6 @@ int renderViewInstanceCounter = 0; RenderViewInitializerJob::RenderViewInitializerJob() : m_renderer(nullptr) - , m_devicePixelRatio(1.) , m_fgLeaf(nullptr) , m_index(0) , m_renderView(nullptr) @@ -90,8 +89,6 @@ void RenderViewInitializerJob::run() // RenderView should allocate heap resources using only the currentFrameAllocator m_renderView->setRenderer(m_renderer); - m_renderView->setSurfaceSize(m_surfaceSize); - m_renderView->setDevicePixelRatio(m_devicePixelRatio); // Populate the renderview's configuration from the framegraph setRenderViewConfigFromFrameGraphLeafNode(m_renderView, m_fgLeaf); diff --git a/src/render/jobs/renderviewinitializerjob_p.h b/src/render/jobs/renderviewinitializerjob_p.h index dbc80c162..81091183b 100644 --- a/src/render/jobs/renderviewinitializerjob_p.h +++ b/src/render/jobs/renderviewinitializerjob_p.h @@ -73,8 +73,6 @@ public: ~RenderViewInitializerJob(); inline void setRenderer(Renderer *renderer) { m_renderer = renderer; } - inline void setSurfaceSize(const QSize &size) { m_surfaceSize = size; } - inline void setDevicePixelRatio(qreal r) { m_devicePixelRatio = r; } inline RenderView *renderView() const Q_DECL_NOTHROW { return m_renderView; } inline void setFrameGraphLeafNode(FrameGraphNode *fgLeaf) @@ -94,8 +92,6 @@ protected: private: Renderer *m_renderer; - QSize m_surfaceSize; - qreal m_devicePixelRatio; FrameGraphNode *m_fgLeaf; int m_index; RenderView *m_renderView; diff --git a/src/render/jobs/renderviewjobutils.cpp b/src/render/jobs/renderviewjobutils.cpp index 8ffd5ea10..3face7197 100644 --- a/src/render/jobs/renderviewjobutils.cpp +++ b/src/render/jobs/renderviewjobutils.cpp @@ -62,6 +62,7 @@ #include <Qt3DRender/private/statesetnode_p.h> #include <Qt3DRender/private/dispatchcompute_p.h> #include <Qt3DRender/private/rendersurfaceselector_p.h> +#include <Qt3DRender/private/rendercapture_p.h> #include <Qt3DRender/private/stringtoint_p.h> QT_BEGIN_NAMESPACE @@ -220,6 +221,15 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN } break; } + case FrameGraphNode::RenderCapture: { + auto *renderCapture = const_cast<Render::RenderCapture *>( + static_cast<const Render::RenderCapture *>(node)); + if (rv->renderCaptureNodeId().isNull() && renderCapture->wasCaptureRequested()) { + renderCapture->acknowledgeCaptureRequest(); + rv->setRenderCaptureNodeId(renderCapture->peerId()); + } + break; + } default: // Should never get here @@ -381,7 +391,7 @@ void addParametersForIds(ParameterInfoList *params, ParameterManager *manager, Parameter *param = manager->lookupResource(paramId); ParameterInfoList::iterator it = std::lower_bound(params->begin(), params->end(), param->nameId()); if (it == params->end() || it->nameId != param->nameId()) - params->insert(it, ParameterInfo(param->nameId(), param->value())); + params->insert(it, ParameterInfo(param->nameId(), param->uniformValue())); } } @@ -490,7 +500,7 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapStructHelper(Shader } } -ParameterInfo::ParameterInfo(const int nameId, const QVariant &value) +ParameterInfo::ParameterInfo(const int nameId, const UniformValue &value) : nameId(nameId) , value(value) {} diff --git a/src/render/jobs/renderviewjobutils_p.h b/src/render/jobs/renderviewjobutils_p.h index fa133ef4c..c08083494 100644 --- a/src/render/jobs/renderviewjobutils_p.h +++ b/src/render/jobs/renderviewjobutils_p.h @@ -56,6 +56,7 @@ #include <QtCore/qhash.h> #include <QtCore/qvariant.h> #include <QMatrix4x4> +#include <Qt3DRender/private/uniform_p.h> QT_BEGIN_NAMESPACE @@ -107,10 +108,10 @@ Q_AUTOTEST_EXPORT inline T variant_value(const QVariant &v) struct ParameterInfo { - explicit ParameterInfo(const int nameId = -1, const QVariant &value = QVariant()); + explicit ParameterInfo(const int nameId = -1, const UniformValue &value = UniformValue()); int nameId; - QVariant value; + UniformValue value; bool operator<(const int otherNameId) const Q_DECL_NOEXCEPT; bool operator<(const ParameterInfo &other) const Q_DECL_NOEXCEPT; diff --git a/src/render/jobs/sendrendercapturejob.cpp b/src/render/jobs/sendrendercapturejob.cpp new file mode 100644 index 000000000..6dd9387e0 --- /dev/null +++ b/src/render/jobs/sendrendercapturejob.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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 "sendrendercapturejob_p.h" + +#include "Qt3DRender/private/renderer_p.h" +#include "Qt3DRender/private/nodemanagers_p.h" +#include "Qt3DRender/private/rendercapture_p.h" +#include <Qt3DRender/private/job_common_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace Render { + +SendRenderCaptureJob::SendRenderCaptureJob(Renderer *renderer) + : Qt3DCore::QAspectJob() + , m_renderer(renderer) +{ + SET_JOB_RUN_STAT_TYPE(this, JobTypes::SendRenderCapture, 0); +} + +SendRenderCaptureJob::~SendRenderCaptureJob() +{ + +} + +void SendRenderCaptureJob::setManagers(NodeManagers *managers) +{ + m_managers = managers; +} + +void SendRenderCaptureJob::run() +{ + const auto pendingCaptures = m_renderer->takePendingRenderCaptureSendRequests(); + for (Qt3DCore::QNodeId id : pendingCaptures) { + auto *node = static_cast<Qt3DRender::Render::RenderCapture *> + (m_managers->frameGraphManager()->lookupNode(id)); + node->sendRenderCaptures(); + } +} + +} // Render + +} // Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/jobs/sendrendercapturejob_p.h b/src/render/jobs/sendrendercapturejob_p.h new file mode 100644 index 000000000..f1e6b65f2 --- /dev/null +++ b/src/render/jobs/sendrendercapturejob_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** 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$ +** +****************************************************************************/ + +#ifndef SENDRENDERCAPTUREJOB_P_H +#define SENDRENDERCAPTUREJOB_P_H + + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DCore/qaspectjob.h> +#include <Qt3DRender/qt3drender_global.h> +#include <Qt3DRender/private/qt3drender_global_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace Render { + +class NodeManagers; +class Entity; +class Renderer; + +class QT3DRENDERSHARED_PRIVATE_EXPORT SendRenderCaptureJob : public Qt3DCore::QAspectJob +{ +public: + explicit SendRenderCaptureJob(Renderer *renderer); + ~SendRenderCaptureJob(); + + void setManagers(NodeManagers *managers); + +protected: + void run() Q_DECL_FINAL; + +private: + Renderer *m_renderer; + NodeManagers *m_managers; +}; + +typedef QSharedPointer<SendRenderCaptureJob> SendRenderCaptureJobPtr; + +} // namespace Render + +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // SENDRENDERCAPTUREJOB_P_H diff --git a/src/render/jobs/updateworldboundingvolumejob_p.h b/src/render/jobs/updateworldboundingvolumejob_p.h index 06e8f1005..14717eb4e 100644 --- a/src/render/jobs/updateworldboundingvolumejob_p.h +++ b/src/render/jobs/updateworldboundingvolumejob_p.h @@ -68,8 +68,6 @@ public: UpdateWorldBoundingVolumeJob(); inline void setManager(EntityManager *manager) Q_DECL_NOTHROW { m_manager = manager; } - -protected: void run() Q_DECL_OVERRIDE; private: diff --git a/src/render/jobs/updateworldtransformjob_p.h b/src/render/jobs/updateworldtransformjob_p.h index 11c2dce21..70e54b840 100644 --- a/src/render/jobs/updateworldtransformjob_p.h +++ b/src/render/jobs/updateworldtransformjob_p.h @@ -69,8 +69,6 @@ public: UpdateWorldTransformJob(); void setRoot(Entity *root); - -protected: void run() Q_DECL_OVERRIDE; private: diff --git a/src/render/materialsystem/material_p.h b/src/render/materialsystem/material_p.h index b415e2975..fe2707549 100644 --- a/src/render/materialsystem/material_p.h +++ b/src/render/materialsystem/material_p.h @@ -54,7 +54,7 @@ #include <QVariant> #include <Qt3DRender/private/backendnode_p.h> -#include <Qt3DRender/private/quniformvalue_p.h> +#include <Qt3DRender/private/shaderparameterpack_p.h> #include <Qt3DRender/private/parameterpack_p.h> QT_BEGIN_NAMESPACE diff --git a/src/render/materialsystem/parameter.cpp b/src/render/materialsystem/parameter.cpp index b13c0d5ae..2cd026422 100644 --- a/src/render/materialsystem/parameter.cpp +++ b/src/render/materialsystem/parameter.cpp @@ -68,7 +68,7 @@ void Parameter::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &ch const auto &data = typedChange->data; m_name = data.name; m_nameId = StringToInt::lookupId(m_name); - m_value = data.backendValue; + m_uniformValue = UniformValue::fromVariant(data.backendValue); } void Parameter::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) @@ -80,7 +80,7 @@ void Parameter::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) m_name = propertyChange->value().toString(); m_nameId = StringToInt::lookupId(m_name); } else if (propertyChange->propertyName() == QByteArrayLiteral("value")) { - m_value = propertyChange->value(); + m_uniformValue = UniformValue::fromVariant(propertyChange->value()); } markDirty(AbstractRenderer::AllDirty); } @@ -93,14 +93,14 @@ QString Parameter::name() const return m_name; } -QVariant Parameter::value() const +int Parameter::nameId() const Q_DECL_NOTHROW { - return m_value; + return m_nameId; } -int Parameter::nameId() const Q_DECL_NOTHROW +UniformValue Parameter::uniformValue() const { - return m_nameId; + return m_uniformValue; } } // namespace Render diff --git a/src/render/materialsystem/parameter_p.h b/src/render/materialsystem/parameter_p.h index c5c94243d..c6861ca36 100644 --- a/src/render/materialsystem/parameter_p.h +++ b/src/render/materialsystem/parameter_p.h @@ -52,6 +52,7 @@ // #include <Qt3DRender/private/backendnode_p.h> +#include <Qt3DRender/private/uniform_p.h> #include <QVariant> QT_BEGIN_NAMESPACE @@ -72,14 +73,14 @@ public: void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; QString name() const; - QVariant value() const; int nameId() const Q_DECL_NOTHROW; + UniformValue uniformValue() const; private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; QString m_name; - QVariant m_value; + UniformValue m_uniformValue; int m_nameId; }; diff --git a/src/render/materialsystem/shader_p.h b/src/render/materialsystem/shader_p.h index 1382e287e..283e5a94c 100644 --- a/src/render/materialsystem/shader_p.h +++ b/src/render/materialsystem/shader_p.h @@ -52,7 +52,7 @@ // #include <Qt3DRender/private/backendnode_p.h> -#include <Qt3DRender/private/quniformvalue_p.h> +#include <Qt3DRender/private/shaderparameterpack_p.h> #include <Qt3DRender/private/shadervariables_p.h> #include <QMutex> #include <QVector> diff --git a/src/render/picking/qpickevent.cpp b/src/render/picking/qpickevent.cpp index ee9d6e867..c29c13cff 100644 --- a/src/render/picking/qpickevent.cpp +++ b/src/render/picking/qpickevent.cpp @@ -77,16 +77,34 @@ QPickEvent::QPickEvent() \fn Qt3DRender::QPickEvent::QPickEvent(const QPointF &position, const QVector3D &intersection, const QVector3D &localIntersection, float distance) Constructs a new QPickEvent with the given parameters: \a position, \a intersection, \a localIntersection and \a distance */ -QPickEvent::QPickEvent(const QPointF &position, const QVector3D &intersection, const QVector3D &localIntersection, float distance) +// NOTE: remove in Qt6 +QPickEvent::QPickEvent(const QPointF &position, const QVector3D &worldIntersection, const QVector3D &localIntersection, float distance) : QObject(*new QPickEventPrivate()) { Q_D(QPickEvent); d->m_position = position; d->m_distance = distance; - d->m_worldIntersection = intersection; + d->m_worldIntersection = worldIntersection; d->m_localIntersection = localIntersection; } +/*! + \fn Qt3DRender::QPickEvent::QPickEvent(const QPointF &position, const QVector3D &intersection, const QVector3D &localIntersection, float distance) + Constructs a new QPickEvent with the given parameters: \a position, \a intersection, \a localIntersection, \a distance, \a button, \a buttons and \a modifiers + */ +QPickEvent::QPickEvent(const QPointF &position, const QVector3D &worldIntersection, const QVector3D &localIntersection, float distance, QPickEvent::Buttons button, int buttons, int modifiers) + : QObject(*new QPickEventPrivate()) +{ + Q_D(QPickEvent); + d->m_position = position; + d->m_distance = distance; + d->m_worldIntersection = worldIntersection; + d->m_localIntersection = localIntersection; + d->m_button = button; + d->m_buttons = buttons; + d->m_modifiers = modifiers; +} + /*! \internal */ QPickEvent::QPickEvent(QObjectPrivate &dd, QObject *parent) : QObject(dd, parent) @@ -200,6 +218,81 @@ QVector3D QPickEvent::localIntersection() const return d->m_localIntersection; } +/*! + * \enum Qt3DRender::QPickEvent::Buttons + * + * \value LeftButton + * \value RightButton + * \value MiddleButton + * \value BackButton + * \value NoButton + */ + +/*! + \qmlproperty bool Qt3D.Render::PickEvent::button + Specifies mouse button that caused the event +*/ +/*! + \property Qt3DRender::QPickEvent::button + Specifies mouse button that caused the event + */ +/*! + * \brief QPickEvent::button + * \return mouse button that caused the event + */ +QPickEvent::Buttons QPickEvent::button() const +{ + Q_D(const QPickEvent); + return d->m_button; +} + +/*! + \qmlproperty bool Qt3D.Render::PickEvent::buttons + Specifies state of the mouse buttons for the event +*/ +/*! + \property Qt3DRender::QPickEvent::buttons + Specifies state of the mouse buttons for the event + */ +/*! + * \brief QPickEvent::buttons + * \return bitfield to be used to check for mouse buttons that may be accompanying the pick event. + */ +int QPickEvent::buttons() const +{ + Q_D(const QPickEvent); + return d->m_buttons; +} + +/*! + * \enum Qt3DRender::QPickEvent::Modifiers + * + * \value NoModifier + * \value ShiftModifier + * \value ControlModifier + * \value AltModifier + * \value MetaModifier + * \value KeypadModifier + */ + +/*! + \qmlproperty bool Qt3D.Render::PickEvent::modifiers + Specifies state of the mouse buttons for the event +*/ +/*! + \property Qt3DRender::QPickEvent::modifiers + Specifies state of the mouse buttons for the event + */ +/*! + * \brief QPickEvent::modifiers + * \return bitfield to be used to check for keyboard modifiers that may be accompanying the pick event. + */ +int QPickEvent::modifiers() const +{ + Q_D(const QPickEvent); + return d->m_modifiers; +} + } // Qt3DRender QT_END_NAMESPACE diff --git a/src/render/picking/qpickevent.h b/src/render/picking/qpickevent.h index 431fe1927..cd925f7ea 100644 --- a/src/render/picking/qpickevent.h +++ b/src/render/picking/qpickevent.h @@ -62,9 +62,32 @@ class QT3DRENDERSHARED_EXPORT QPickEvent : public QObject Q_PROPERTY(float distance READ distance CONSTANT) Q_PROPERTY(QVector3D localIntersection READ localIntersection CONSTANT) Q_PROPERTY(QVector3D worldIntersection READ worldIntersection CONSTANT) + Q_PROPERTY(Qt3DRender::QPickEvent::Buttons button READ button CONSTANT) + Q_PROPERTY(int buttons READ buttons CONSTANT) + Q_PROPERTY(int modifiers READ modifiers CONSTANT) public: + enum Buttons { + LeftButton = Qt::LeftButton, + RightButton = Qt::RightButton, + MiddleButton = Qt::MiddleButton, + BackButton = Qt::BackButton, + NoButton = Qt::NoButton + }; + Q_ENUM(Buttons) + + enum Modifiers { + NoModifier = Qt::NoModifier, + ShiftModifier = Qt::ShiftModifier, + ControlModifier = Qt::ControlModifier, + AltModifier = Qt::AltModifier, + MetaModifier = Qt::MetaModifier, + KeypadModifier = Qt::KeypadModifier + }; + Q_ENUM(Modifiers) + QPickEvent(); QPickEvent(const QPointF &position, const QVector3D& worldIntersection, const QVector3D& localIntersection, float distance); + QPickEvent(const QPointF &position, const QVector3D& worldIntersection, const QVector3D& localIntersection, float distance, Buttons button, int buttons, int modifiers); ~QPickEvent(); bool isAccepted() const; @@ -77,6 +100,9 @@ public: float distance() const; QVector3D worldIntersection() const; QVector3D localIntersection() const; + Buttons button() const; + int buttons() const; + int modifiers() const; Q_SIGNALS: void acceptedChanged(bool accepted); diff --git a/src/render/picking/qpickevent_p.h b/src/render/picking/qpickevent_p.h index fd9ed36a2..399795619 100644 --- a/src/render/picking/qpickevent_p.h +++ b/src/render/picking/qpickevent_p.h @@ -61,6 +61,9 @@ public: : QObjectPrivate() , m_accepted(true) , m_distance(-1.f) + , m_button(QPickEvent::NoButton) + , m_buttons(QPickEvent::NoButton) + , m_modifiers(QPickEvent::NoModifier) { } @@ -69,6 +72,9 @@ public: QVector3D m_worldIntersection; QVector3D m_localIntersection; float m_distance; + QPickEvent::Buttons m_button; + int m_buttons; + int m_modifiers; }; } // Qt3DRender diff --git a/src/render/picking/qpicktriangleevent.cpp b/src/render/picking/qpicktriangleevent.cpp index b636638e6..50cafb8d9 100644 --- a/src/render/picking/qpicktriangleevent.cpp +++ b/src/render/picking/qpicktriangleevent.cpp @@ -102,14 +102,15 @@ QPickTriangleEvent::QPickTriangleEvent() * \a vertex2Index and * \a vertex3Index */ -QPickTriangleEvent::QPickTriangleEvent(const QPointF &position, const QVector3D &intersection, const QVector3D &localIntersection, float distance, +// NOTE: remove in Qt6 +QPickTriangleEvent::QPickTriangleEvent(const QPointF &position, const QVector3D &worldIntersection, const QVector3D &localIntersection, float distance, uint triangleIndex, uint vertex1Index, uint vertex2Index, uint vertex3Index) : QPickEvent(*new QPickTriangleEventPrivate()) { Q_D(QPickTriangleEvent); d->m_position = position; d->m_distance = distance; - d->m_worldIntersection = intersection; + d->m_worldIntersection = worldIntersection; d->m_localIntersection = localIntersection; d->m_triangleIndex = triangleIndex; d->m_vertex1Index = vertex1Index; @@ -117,6 +118,23 @@ QPickTriangleEvent::QPickTriangleEvent(const QPointF &position, const QVector3D d->m_vertex3Index = vertex3Index; } +QPickTriangleEvent::QPickTriangleEvent(const QPointF &position, const QVector3D &worldIntersection, const QVector3D &localIntersection, float distance, uint triangleIndex, uint vertex1Index, uint vertex2Index, uint vertex3Index, QPickEvent::Buttons button, int buttons, int modifiers) + : QPickEvent(*new QPickTriangleEventPrivate()) +{ + Q_D(QPickTriangleEvent); + d->m_position = position; + d->m_distance = distance; + d->m_worldIntersection = worldIntersection; + d->m_localIntersection = localIntersection; + d->m_triangleIndex = triangleIndex; + d->m_vertex1Index = vertex1Index; + d->m_vertex2Index = vertex2Index; + d->m_vertex3Index = vertex3Index; + d->m_button = button; + d->m_buttons = buttons; + d->m_modifiers = modifiers; +} + /*! \internal */ QPickTriangleEvent::~QPickTriangleEvent() { diff --git a/src/render/picking/qpicktriangleevent.h b/src/render/picking/qpicktriangleevent.h index e60a81dd6..7cafa1aeb 100644 --- a/src/render/picking/qpicktriangleevent.h +++ b/src/render/picking/qpicktriangleevent.h @@ -58,6 +58,8 @@ public: QPickTriangleEvent(); QPickTriangleEvent(const QPointF &position, const QVector3D& worldIntersection, const QVector3D& localIntersection, float distance, uint triangleIndex, uint vertex1Index, uint vertex2Index, uint vertex3Index); + QPickTriangleEvent(const QPointF &position, const QVector3D& worldIntersection, const QVector3D& localIntersection, float distance, + uint triangleIndex, uint vertex1Index, uint vertex2Index, uint vertex3Index, Buttons button, int buttons, int modifiers); ~QPickTriangleEvent(); public: diff --git a/src/render/render.pro b/src/render/render.pro index b3c5fa1ad..267664220 100644 --- a/src/render/render.pro +++ b/src/render/render.pro @@ -34,8 +34,6 @@ HEADERS += \ qt3drender_global.h \ qt3drender_global_p.h -!contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL - # otherwise mingw headers do not declare common functions like ::strcasecmp win32-g++*:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x diff --git a/src/render/texture/qabstracttexture.cpp b/src/render/texture/qabstracttexture.cpp index d7bb33f44..8d151e0eb 100644 --- a/src/render/texture/qabstracttexture.cpp +++ b/src/render/texture/qabstracttexture.cpp @@ -65,6 +65,7 @@ QAbstractTexturePrivate::QAbstractTexturePrivate() , m_comparisonFunction(QAbstractTexture::CompareLessEqual) , m_comparisonMode(QAbstractTexture::CompareNone) , m_layers(1) + , m_samples(1) { } @@ -83,6 +84,26 @@ QAbstractTexturePrivate::QAbstractTexturePrivate() */ /*! + \enum Qt3DRender::QAbstractTexture::CubeMapFace + + This enum identifies the faces of a cube map texture + \value CubeMapPositiveX Specify the positive X face of a cube map + \value CubeMapNegativeX Specify the negative X face of a cube map + \value CubeMapPositiveY Specify the positive Y face of a cube map + \value CubeMapNegativeY Specify the negative Y face of a cube map + \value CubeMapPositiveZ Specify the positive Z face of a cube map + \value CubeMapNegativeZ Specify the negative Z face of a cube map + \value AllFaces Specify all the faces of a cube map + + \note AllFaces should only be used when a behavior needs to be applied to + all the faces of a cubemap. This is the case for example when using a cube + map as a texture attachment. Using AllFaces in the attachment specfication + would result in all faces being bound to the attachment point. On the other + hand, if a specific face is specified, the attachment would only be using + the specified face. +*/ + +/*! * The constructor creates a new QAbstractTexture::QAbstractTexture * instance with the specified \a parent. */ @@ -222,6 +243,36 @@ int QAbstractTexture::layers() const } /*! + \property Qt3DRender::QAbstractTexture::samples + + Holds the number of samples per texel for the texture provider. + By default, the number of samples is 1. + + \note this has a meaning only for texture providers that have multisample + formats. + */ +void QAbstractTexture::setSamples(int samples) +{ + Q_D(QAbstractTexture); + if (d->m_samples != samples) { + d->m_samples = samples; + emit samplesChanged(samples); + } +} + +/*! + \return the number of samples per texel for the texture provider. + + \note this has a meaning only for texture providers that have multisample + formats. + */ +int QAbstractTexture::samples() const +{ + Q_D(const QAbstractTexture); + return d->m_samples; +} + +/*! \property Qt3DRender::QAbstractTexture::format Holds the format of the texture provider. @@ -536,6 +587,7 @@ Qt3DCore::QNodeCreatedChangeBasePtr QAbstractTexture::createNodeCreationChange() data.comparisonMode = d->m_comparisonMode; data.textureImageIds = qIdsForNodes(d->m_textureImages); data.layers = d->m_layers; + data.samples = d->m_samples; data.dataFunctor = d->m_dataFunctor; return creationChange; } diff --git a/src/render/texture/qabstracttexture.h b/src/render/texture/qabstracttexture.h index eb4ad66f8..0f1dc5dfe 100644 --- a/src/render/texture/qabstracttexture.h +++ b/src/render/texture/qabstracttexture.h @@ -72,6 +72,7 @@ class QT3DRENDERSHARED_EXPORT QAbstractTexture : public Qt3DCore::QNode Q_PROPERTY(ComparisonFunction comparisonFunction READ comparisonFunction WRITE setComparisonFunction NOTIFY comparisonFunctionChanged) Q_PROPERTY(ComparisonMode comparisonMode READ comparisonMode WRITE setComparisonMode NOTIFY comparisonModeChanged) Q_PROPERTY(int layers READ layers WRITE setLayers NOTIFY layersChanged) + Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged) public: @@ -244,7 +245,8 @@ public: CubeMapPositiveY = 0x8517, // GL_TEXTURE_CUBE_MAP_POSITIVE_Y CubeMapNegativeY = 0x8518, // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y CubeMapPositiveZ = 0x8519, // GL_TEXTURE_CUBE_MAP_POSITIVE_Z - CubeMapNegativeZ = 0x851A // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + CubeMapNegativeZ = 0x851A, // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + AllFaces }; Q_ENUM(CubeMapFace) @@ -294,6 +296,7 @@ public: int height() const; int depth() const; int layers() const; + int samples() const; QTextureGeneratorPtr dataGenerator() const; public Q_SLOTS: @@ -308,6 +311,7 @@ public Q_SLOTS: void setComparisonFunction(ComparisonFunction function); void setComparisonMode(ComparisonMode mode); void setLayers(int layers); + void setSamples(int samples); Q_SIGNALS: void formatChanged(TextureFormat format); @@ -322,6 +326,7 @@ Q_SIGNALS: void comparisonFunctionChanged(ComparisonFunction comparisonFunction); void comparisonModeChanged(ComparisonMode comparisonMode); void layersChanged(int layers); + void samplesChanged(int samples); protected: explicit QAbstractTexture(Qt3DCore::QNode *parent = nullptr); diff --git a/src/render/texture/qabstracttexture_p.h b/src/render/texture/qabstracttexture_p.h index dca912611..80e939bf9 100644 --- a/src/render/texture/qabstracttexture_p.h +++ b/src/render/texture/qabstracttexture_p.h @@ -84,6 +84,7 @@ public : QAbstractTexture::ComparisonMode m_comparisonMode; QVector<QAbstractTextureImage *> m_textureImages; int m_layers; + int m_samples; QTextureGeneratorPtr m_dataFunctor; }; @@ -106,6 +107,7 @@ struct QAbstractTextureData QAbstractTexture::ComparisonMode comparisonMode; Qt3DCore::QNodeIdVector textureImageIds; int layers; + int samples; QTextureGeneratorPtr dataFunctor; }; diff --git a/src/render/texture/qabstracttextureimage.h b/src/render/texture/qabstracttextureimage.h index 698539ab3..7041483b2 100644 --- a/src/render/texture/qabstracttextureimage.h +++ b/src/render/texture/qabstracttextureimage.h @@ -47,10 +47,6 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { -namespace Render { -class TextureImage; -} - class QAbstractTextureImagePrivate; class QT3DRENDERSHARED_EXPORT QAbstractTextureImage : public Qt3DCore::QNode @@ -84,7 +80,6 @@ protected: private: Q_DECLARE_PRIVATE(QAbstractTextureImage) - friend class Render::TextureImage; Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE; }; diff --git a/src/render/texture/qpaintedtextureimage.cpp b/src/render/texture/qpaintedtextureimage.cpp new file mode 100644 index 000000000..6de253128 --- /dev/null +++ b/src/render/texture/qpaintedtextureimage.cpp @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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 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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpaintedtextureimage.h" +#include "qpaintedtextureimage_p.h" + +#include <QtGui/qpainter.h> +#include <QtGui/qimage.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +QPaintedTextureImagePrivate::QPaintedTextureImagePrivate() + : m_imageSize(256,256) + , m_generation(0) +{ +} + +QPaintedTextureImagePrivate::~QPaintedTextureImagePrivate() +{ +} + +void QPaintedTextureImagePrivate::repaint() +{ + // create or re-allocate QImage with current size + if (m_image.isNull() || (m_image->size() != m_imageSize)) + m_image.reset(new QImage(m_imageSize, QImage::Format_RGBA8888)); + + QPainter painter(m_image.data()); + q_func()->paint(&painter); + painter.end(); + + ++m_generation; + m_currentGenerator.reset(new QPaintedTextureImageDataGenerator(*m_image.data(), m_generation, q_func()->id())); + q_func()->notifyDataGeneratorChanged(); +} + +QPaintedTextureImage::QPaintedTextureImage(Qt3DCore::QNode *parent) + : QAbstractTextureImage(*new QPaintedTextureImagePrivate, parent) +{ +} + +QPaintedTextureImage::~QPaintedTextureImage() +{ +} + +int QPaintedTextureImage::width() const +{ + Q_D(const QPaintedTextureImage); + return d->m_imageSize.width(); +} + +int QPaintedTextureImage::height() const +{ + Q_D(const QPaintedTextureImage); + return d->m_imageSize.height(); +} + +QSize QPaintedTextureImage::size() const +{ + Q_D(const QPaintedTextureImage); + return d->m_imageSize; +} + +void QPaintedTextureImage::setWidth(int w) +{ + if (w < 1) { + qWarning() << "QPaintedTextureImage: Attempting to set invalid width" << w << ". Will be ignored"; + return; + } + setSize(QSize(w, height())); +} + +void QPaintedTextureImage::setHeight(int h) +{ + if (h < 1) { + qWarning() << "QPaintedTextureImage: Attempting to set invalid height" << h << ". Will be ignored"; + return; + } + setSize(QSize(width(), h)); +} + +void QPaintedTextureImage::setSize(QSize size) +{ + Q_D(QPaintedTextureImage); + + if (d->m_imageSize != size) { + if (size.isEmpty()) { + qWarning() << "QPaintedTextureImage: Attempting to set invalid size" << size << ". Will be ignored"; + return; + } + + const bool changeW = d->m_imageSize.width() != size.width(); + const bool changeH = d->m_imageSize.height() != size.height(); + + d->m_imageSize = size; + + if (changeW) + Q_EMIT widthChanged(d->m_imageSize.height()); + if (changeH) + Q_EMIT heightChanged(d->m_imageSize.height()); + + Q_EMIT sizeChanged(d->m_imageSize); + + d->repaint(); + } +} + +void QPaintedTextureImage::update(const QRect &rect) +{ + Q_UNUSED(rect) + Q_D(QPaintedTextureImage); + + d->repaint(); +} + +QTextureImageDataGeneratorPtr QPaintedTextureImage::dataGenerator() const +{ + Q_D(const QPaintedTextureImage); + return d->m_currentGenerator; +} + + +QPaintedTextureImageDataGenerator::QPaintedTextureImageDataGenerator(const QImage &image, int gen, Qt3DCore::QNodeId texId) + : m_image(image) // pixels are implicitly shared, no copying + , m_generation(gen) + , m_paintedTextureImageId(texId) +{ +} + +QPaintedTextureImageDataGenerator::~QPaintedTextureImageDataGenerator() +{ +} + +QTextureImageDataPtr QPaintedTextureImageDataGenerator::operator ()() +{ + QTextureImageDataPtr textureData = QTextureImageDataPtr::create(); + textureData->setImage(m_image); + return textureData; +} + +bool QPaintedTextureImageDataGenerator::operator ==(const QTextureImageDataGenerator &other) const +{ + const QPaintedTextureImageDataGenerator *otherFunctor = functor_cast<QPaintedTextureImageDataGenerator>(&other); + return (otherFunctor != Q_NULLPTR && otherFunctor->m_generation == m_generation && otherFunctor->m_paintedTextureImageId == m_paintedTextureImageId); +} + +} // namespace Qt3DRender + +QT_END_NAMESPACE + diff --git a/src/render/texture/qpaintedtextureimage.h b/src/render/texture/qpaintedtextureimage.h new file mode 100644 index 000000000..ff62da118 --- /dev/null +++ b/src/render/texture/qpaintedtextureimage.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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 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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DRENDER_QPAINTEDTEXTURE_H +#define QT3DRENDER_QPAINTEDTEXTURE_H + +#include <Qt3DRender/qabstracttextureimage.h> + +QT_BEGIN_NAMESPACE + +class QPainter; + +namespace Qt3DRender { + +class QPaintedTextureImagePrivate; + +class QT3DRENDERSHARED_EXPORT QPaintedTextureImage : public QAbstractTextureImage +{ + Q_OBJECT + Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged) + Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged) + Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY sizeChanged) + +public: + explicit QPaintedTextureImage(Qt3DCore::QNode *parent = nullptr); + ~QPaintedTextureImage(); + + int width() const; + int height() const; + QSize size() const; + + void update(const QRect &rect = QRect()); + +public Q_SLOTS: + void setWidth(int w); + void setHeight(int h); + void setSize(QSize size); + +Q_SIGNALS: + void widthChanged(int w); + void heightChanged(int w); + void sizeChanged(QSize size); + +protected: + virtual void paint(QPainter *painter) = 0; + +private: + Q_DECLARE_PRIVATE(QPaintedTextureImage) + + QTextureImageDataGeneratorPtr dataGenerator() const Q_DECL_OVERRIDE; +}; + +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_QPAINTEDTEXTURE_H diff --git a/src/render/texture/qpaintedtextureimage_p.h b/src/render/texture/qpaintedtextureimage_p.h new file mode 100644 index 000000000..4fcaa6c93 --- /dev/null +++ b/src/render/texture/qpaintedtextureimage_p.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:LGPL$ +** 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 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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DRENDER_QPAINTEDTEXTURE_P_H +#define QT3DRENDER_QPAINTEDTEXTURE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DRender/private/qabstracttextureimage_p.h> +#include <Qt3DRender/qtextureimagedatagenerator.h> +#include <Qt3DRender/qpaintedtextureimage.h> + +QT_BEGIN_NAMESPACE + +class QImage; +class QPainter; + +namespace Qt3DRender { + +class QPaintedTextureImagePrivate : public QAbstractTextureImagePrivate +{ +public: + QPaintedTextureImagePrivate(); + ~QPaintedTextureImagePrivate(); + + Q_DECLARE_PUBLIC(QPaintedTextureImage) + + QSize m_imageSize; + QScopedPointer<QImage> m_image; + QTextureImageDataGeneratorPtr m_currentGenerator; + + // gets increased each time the image is re-painted. + // used to distinguish between different generators + quint64 m_generation; + + void repaint(); +}; + +class QPaintedTextureImageDataGenerator : public QTextureImageDataGenerator +{ +public: + QPaintedTextureImageDataGenerator(const QImage &image, int gen, Qt3DCore::QNodeId texId); + ~QPaintedTextureImageDataGenerator(); + + // Will be executed from within a QAspectJob + QTextureImageDataPtr operator ()() Q_DECL_FINAL; + bool operator ==(const QTextureImageDataGenerator &other) const Q_DECL_FINAL; + + QT3D_FUNCTOR(QPaintedTextureImageDataGenerator) + +private: + QImage m_image; + quint64 m_generation; + Qt3DCore::QNodeId m_paintedTextureImageId; +}; + +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_QPAINTEDTEXTURE_P_H diff --git a/src/render/texture/texture.cpp b/src/render/texture/texture.cpp index 387a00b3b..d44ac151c 100644 --- a/src/render/texture/texture.cpp +++ b/src/render/texture/texture.cpp @@ -79,6 +79,7 @@ Texture::Texture() , m_height(1) , m_depth(1) , m_layers(1) + , m_samples(1) , m_mipLevels(1) , m_generateMipMaps(false) , m_target(QAbstractTexture::Target2D) @@ -121,6 +122,7 @@ void Texture::cleanup() m_height = 1; m_depth = 1; m_layers = 1; + m_samples = 1; m_mipLevels = 1; m_generateMipMaps = false; m_target = QAbstractTexture::Target2D; @@ -166,6 +168,7 @@ void Texture::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &chan m_comparisonFunction = data.comparisonFunction; m_comparisonMode = data.comparisonMode; m_layers = data.layers; + m_samples = data.samples; m_dataFunctor = data.dataFunctor; if (m_dataFunctor) addToPendingTextureJobs(); @@ -313,7 +316,12 @@ QOpenGLTexture *Texture::buildGLTexture() glTex->setLayers(m_layers); } - if (m_generateMipMaps) { + if (m_target == QAbstractTexture::Target2DMultisample || + m_target == QAbstractTexture::Target2DMultisampleArray) { + // Set samples count if multisampled texture + // (multisampled textures don't have mipmaps) + glTex->setSamples(m_samples); + } else if (m_generateMipMaps) { glTex->setMipLevels(glTex->maximumMipLevels()); } else { glTex->setAutoMipMapGenerationEnabled(false); @@ -426,6 +434,12 @@ void Texture::setToGLTexture(TextureImage *rImg, QTextureImageData *imgData) // RenderThread void Texture::updateWrapAndFilters() { + // multisample texture targets don't support sampler state + if (m_target == QAbstractTexture::Target2DMultisample || + m_target == QAbstractTexture::Target2DMultisampleArray) { + return; + } + m_gl->setWrapMode(QOpenGLTexture::DirectionS, static_cast<QOpenGLTexture::WrapMode>(m_wrapModeX)); if (m_target != QAbstractTexture::Target1D && m_target != QAbstractTexture::Target1DArray && @@ -533,6 +547,31 @@ void Texture::setLayers(int layers) } } +int Texture::width() const +{ + return m_width; +} + +int Texture::height() const +{ + return m_height; +} + +int Texture::depth() const +{ + return m_depth; +} + +int Texture::layers() const +{ + return m_layers; +} + +int Texture::samples() const +{ + return m_samples; +} + // ChangeArbiter/Aspect Thread void Texture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) { @@ -591,11 +630,16 @@ void Texture::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) QAbstractTexture::ComparisonMode oldComparisonMode = m_comparisonMode; m_comparisonMode = propertyChange->value().value<QAbstractTexture::ComparisonMode>(); m_filtersAndWrapUpdated |= (oldComparisonMode != m_comparisonMode); - } else if (propertyChange->propertyName() == QByteArrayLiteral("maximumLayers")) { + } else if (propertyChange->propertyName() == QByteArrayLiteral("layers")) { const int oldLayers = m_layers; m_layers = propertyChange->value().toInt(); m_isDirty |= (oldLayers != m_layers); + } else if (propertyChange->propertyName() == QByteArrayLiteral("samples")) { + const int oldSamples = m_samples; + m_samples = propertyChange->value().toInt(); + m_isDirty |= (oldSamples != m_samples); } + // TO DO: Handle the textureGenerator change } break; diff --git a/src/render/texture/texture.pri b/src/render/texture/texture.pri index a4d419f07..762811003 100644 --- a/src/render/texture/texture.pri +++ b/src/render/texture/texture.pri @@ -18,7 +18,9 @@ HEADERS += \ $$PWD/qtexturedata.h \ $$PWD/qtextureimagedatagenerator.h \ $$PWD/qtexturegenerator.h \ - $$PWD/qtexture_p.h + $$PWD/qtexture_p.h \ + $$PWD/qpaintedtextureimage.h \ + $$PWD/qpaintedtextureimage_p.h SOURCES += \ $$PWD/qabstracttextureimage.cpp \ @@ -31,4 +33,5 @@ SOURCES += \ $$PWD/qtexture.cpp \ $$PWD/qtextureimagedata.cpp \ $$PWD/qtexturedata.cpp \ - $$PWD/qtexturegenerator.cpp + $$PWD/qtexturegenerator.cpp \ + $$PWD/qpaintedtextureimage.cpp diff --git a/src/render/texture/texture_p.h b/src/render/texture/texture_p.h index f578cfd29..491ac448b 100644 --- a/src/render/texture/texture_p.h +++ b/src/render/texture/texture_p.h @@ -75,7 +75,7 @@ class TextureDataManager; typedef quint64 TextureDNA; -class Texture : public BackendNode +class Q_AUTOTEST_EXPORT Texture : public BackendNode { public: Texture(); @@ -107,6 +107,12 @@ public: void setMipLevels(int mipmapLevels); void setLayers(int layers); + int width() const; + int height() const; + int depth() const; + int layers() const; + int samples() const; + inline QVector<HTextureImage> textureImages() const { return m_textureImages; } inline QAbstractTexture::TextureFormat format() const { return m_format; } inline QAbstractTexture::Target target() const { return m_target; } @@ -134,6 +140,7 @@ private: int m_height; int m_depth; int m_layers; + int m_samples; int m_mipLevels; bool m_generateMipMaps; QAbstractTexture::Target m_target; diff --git a/tests/auto/core/core.pro b/tests/auto/core/core.pro index d8c4395a9..339e9d5a4 100644 --- a/tests/auto/core/core.pro +++ b/tests/auto/core/core.pro @@ -14,7 +14,7 @@ SUBDIRS = \ qscene \ qservicelocator -contains(QT_CONFIG, private_tests) { +qtConfig(private_tests) { SUBDIRS += \ qentity \ qframeallocator \ diff --git a/tests/auto/input/input.pro b/tests/auto/input/input.pro index 37af1fab9..05668c036 100644 --- a/tests/auto/input/input.pro +++ b/tests/auto/input/input.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs -contains(QT_CONFIG, private_tests) { +qtConfig(private_tests) { SUBDIRS += \ qaxis \ qaction \ @@ -16,7 +16,8 @@ contains(QT_CONFIG, private_tests) { actioninput \ analogaxisinput \ buttonaxisinput \ + keyboardhandler \ + qaxisaccumulator \ inputsequence \ - inputchord \ - keyboardhandler + inputchord } diff --git a/tests/auto/input/qaxisaccumulator/qaxisaccumulator.pro b/tests/auto/input/qaxisaccumulator/qaxisaccumulator.pro new file mode 100644 index 000000000..dfc53d12a --- /dev/null +++ b/tests/auto/input/qaxisaccumulator/qaxisaccumulator.pro @@ -0,0 +1,11 @@ +TEMPLATE = app + +TARGET = tst_qaxisaccumulator + +QT += core-private 3dcore 3dcore-private 3dinput 3dinput-private testlib + +CONFIG += testcase + +SOURCES += tst_qaxisaccumulator.cpp + +include(../../render/commons/commons.pri) diff --git a/tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp b/tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp new file mode 100644 index 000000000..a98cf09a9 --- /dev/null +++ b/tests/auto/input/qaxisaccumulator/tst_qaxisaccumulator.cpp @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QTest> +#include <Qt3DCore/private/qnode_p.h> +#include <Qt3DCore/private/qscene_p.h> +#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h> + +#include <Qt3DInput/qaxis.h> +#include <Qt3DInput/qaxisaccumulator.h> +#include <Qt3DInput/private/qaxisaccumulator_p.h> + +#include <Qt3DCore/QPropertyUpdatedChange> +#include <Qt3DCore/QPropertyNodeAddedChange> +#include <Qt3DCore/QPropertyNodeRemovedChange> + +#include "testpostmanarbiter.h" + +class tst_QAxisAccumulator: public Qt3DInput::QAxisAccumulator +{ + Q_OBJECT +public: + tst_QAxisAccumulator() + { + } + +private Q_SLOTS: + + void checkCreationChange_data() + { + QTest::addColumn<QSharedPointer<Qt3DInput::QAxisAccumulator>>("accumulator"); + QTest::addColumn<Qt3DInput::QAxis *>("sourceAxis"); + QTest::addColumn<Qt3DInput::QAxisAccumulator::SourceAxisType>("sourceAxisType"); + QTest::addColumn<float>("scale"); + + { + auto accumulator = QSharedPointer<Qt3DInput::QAxisAccumulator>::create(); + QTest::newRow("defaultConstructed") + << accumulator + << static_cast<Qt3DInput::QAxis *>(nullptr) + << Qt3DInput::QAxisAccumulator::Velocity + << 1.0f; + } + + { + auto accumulator = QSharedPointer<Qt3DInput::QAxisAccumulator>::create(); + Qt3DInput::QAxis *axis = new Qt3DInput::QAxis(); + accumulator->setSourceAxis(axis); + QTest::newRow("withSourceAxis") + << accumulator + << axis + << Qt3DInput::QAxisAccumulator::Velocity + << 1.0f; + } + + { + auto accumulator = QSharedPointer<Qt3DInput::QAxisAccumulator>::create(); + accumulator->setSourceAxisType(Qt3DInput::QAxisAccumulator::Acceleration); + accumulator->setScale(2.5f); + Qt3DInput::QAxis *axis = new Qt3DInput::QAxis(); + accumulator->setSourceAxis(axis); + QTest::newRow("accelerationNonUniformScale") + << accumulator + << axis + << Qt3DInput::QAxisAccumulator::Acceleration + << 2.5f; + } + } + + void checkCreationChange() + { + // GIVEN + QFETCH(QSharedPointer<Qt3DInput::QAxisAccumulator>, accumulator); + QFETCH(Qt3DInput::QAxis *, sourceAxis); + QFETCH(Qt3DInput::QAxisAccumulator::SourceAxisType, sourceAxisType); + QFETCH(float, scale); + + // WHEN + Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(accumulator.data()); + QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges = creationChangeGenerator.creationChanges(); + + // THEN + QCOMPARE(creationChanges.size(), sourceAxis ? 2 : 1); + + const auto creationChangeData = + qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DInput::QAxisAccumulatorData>>(creationChanges.first()); + const Qt3DInput::QAxisAccumulatorData &creationData = creationChangeData->data; + + // THEN + QCOMPARE(accumulator->id(), creationChangeData->subjectId()); + QCOMPARE(accumulator->isEnabled(), creationChangeData->isNodeEnabled()); + QCOMPARE(accumulator->metaObject(), creationChangeData->metaObject()); + if (sourceAxis) + QCOMPARE(sourceAxis->id(), creationData.sourceAxisId); + QCOMPARE(sourceAxisType, creationData.sourceAxisType); + QCOMPARE(scale, creationData.scale); + } + + void checkPropertyUpdates() + { + // GIVEN + TestArbiter arbiter; + QScopedPointer<Qt3DInput::QAxisAccumulator> accumulator(new Qt3DInput::QAxisAccumulator()); + arbiter.setArbiterOnNode(accumulator.data()); + Qt3DInput::QAxis *axis = new Qt3DInput::QAxis; + + // WHEN + accumulator->setSourceAxis(axis); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "sourceAxis"); + QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), axis->id()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + accumulator->setScale(2.0f); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "scale"); + QCOMPARE(change->value().toFloat(), 2.0f); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + accumulator->setSourceAxisType(Qt3DInput::QAxisAccumulator::Acceleration); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "sourceAxisType"); + QCOMPARE(change->value().value<Qt3DInput::QAxisAccumulator::SourceAxisType>(), Qt3DInput::QAxisAccumulator::Acceleration); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + } + + void checkValuePropertyChanged() + { + // GIVEN + QCOMPARE(value(), 0.0f); + + // Note: simulate backend change to frontend + // WHEN + Qt3DCore::QPropertyUpdatedChangePtr valueChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + valueChange->setPropertyName("value"); + valueChange->setValue(383.0f); + sceneChangeEvent(valueChange); + + // THEN + QCOMPARE(value(), 383.0f); + } + + void checkAxisInputBookkeeping() + { + // GIVEN + QScopedPointer<Qt3DInput::QAxisAccumulator> accumulator(new Qt3DInput::QAxisAccumulator); + { + // WHEN + Qt3DInput::QAxis axis; + accumulator->setSourceAxis(&axis); + + // THEN + QCOMPARE(axis.parent(), accumulator.data()); + QCOMPARE(accumulator->sourceAxis(), &axis); + } + + // THEN (Should not crash and parameter be unset) + QVERIFY(accumulator->sourceAxis() == nullptr); + + { + // WHEN + Qt3DInput::QAxisAccumulator someOtherAccumulator; + QScopedPointer<Qt3DInput::QAxis> axis(new Qt3DInput::QAxis(&someOtherAccumulator)); + accumulator->setSourceAxis(axis.data()); + + // THEN + QCOMPARE(axis->parent(), &someOtherAccumulator); + QCOMPARE(accumulator->sourceAxis(), axis.data()); + + // WHEN + accumulator.reset(); + axis.reset(); + + // THEN Should not crash when the input is destroyed (tests for failed removal of destruction helper) + } + } +}; + +QTEST_MAIN(tst_QAxisAccumulator) + +#include "tst_qaxisaccumulator.moc" diff --git a/tests/auto/quick3d/quick3d.pro b/tests/auto/quick3d/quick3d.pro index 782e68500..ea7dd7c58 100644 --- a/tests/auto/quick3d/quick3d.pro +++ b/tests/auto/quick3d/quick3d.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs -contains(QT_CONFIG, private_tests) { +qtConfig(private_tests) { SUBDIRS += \ quick3dnodeinstantiator \ dynamicnodecreation diff --git a/tests/auto/render/attribute/tst_attribute.cpp b/tests/auto/render/attribute/tst_attribute.cpp index b712bd26a..88861e251 100644 --- a/tests/auto/render/attribute/tst_attribute.cpp +++ b/tests/auto/render/attribute/tst_attribute.cpp @@ -50,8 +50,8 @@ private Q_SLOTS: attribute.setCount(427); attribute.setDivisor(305); attribute.setName(QStringLiteral("C3")); - attribute.setDataType(Qt3DRender::QAttribute::UnsignedShort); - attribute.setDataSize(3); + attribute.setVertexBaseType(Qt3DRender::QAttribute::UnsignedShort); + attribute.setVertexSize(3); Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer); buffer.setUsage(Qt3DRender::QBuffer::DynamicCopy); @@ -103,8 +103,8 @@ private Q_SLOTS: attribute.setCount(427); attribute.setDivisor(305); attribute.setName(QStringLiteral("C3")); - attribute.setDataType(Qt3DRender::QAttribute::Double); - attribute.setDataSize(4); + attribute.setVertexBaseType(Qt3DRender::QAttribute::Double); + attribute.setVertexSize(4); Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer); buffer.setUsage(Qt3DRender::QBuffer::DynamicCopy); buffer.setData(QByteArrayLiteral("C7")); diff --git a/tests/auto/render/buffer/tst_buffer.cpp b/tests/auto/render/buffer/tst_buffer.cpp index 0fbd7b0cf..b06425bd7 100644 --- a/tests/auto/render/buffer/tst_buffer.cpp +++ b/tests/auto/render/buffer/tst_buffer.cpp @@ -29,6 +29,7 @@ #include <QtTest/QTest> #include <qbackendnodetester.h> #include <Qt3DRender/private/buffer_p.h> +#include <Qt3DRender/private/qbuffer_p.h> #include <Qt3DRender/private/buffermanager_p.h> #include <Qt3DCore/qpropertyupdatedchange.h> #include <Qt3DCore/private/qbackendnode_p.h> @@ -95,6 +96,7 @@ private Q_SLOTS: // GIVEN Qt3DRender::Render::Buffer renderBuffer; Qt3DRender::Render::BufferManager bufferManager; + TestRenderer renderer; // THEN QCOMPARE(renderBuffer.isDirty(), false); @@ -103,6 +105,7 @@ private Q_SLOTS: QVERIFY(renderBuffer.data().isEmpty()); QVERIFY(renderBuffer.peerId().isNull()); QVERIFY(renderBuffer.dataGenerator().isNull()); + QVERIFY(renderBuffer.pendingBufferUpdates().empty()); // GIVEN Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer); @@ -112,7 +115,26 @@ private Q_SLOTS: // WHEN renderBuffer.setManager(&bufferManager); + renderBuffer.setRenderer(&renderer); simulateInitialization(&buffer, &renderBuffer); + + Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + Qt3DRender::QBufferUpdate updateData; + updateData.offset = 2; + updateData.data = QByteArrayLiteral("LS5"); + updateChange->setValue(QVariant::fromValue(updateData)); + updateChange->setPropertyName("updateData"); + renderBuffer.sceneChangeEvent(updateChange); + + // THEN + QCOMPARE(renderBuffer.type(), Qt3DRender::QBuffer::IndexBuffer); + QCOMPARE(renderBuffer.usage(), Qt3DRender::QBuffer::DynamicCopy); + QCOMPARE(renderBuffer.isDirty(), true); + QCOMPARE(renderBuffer.data(), QByteArrayLiteral("C7")); + QVERIFY(!renderBuffer.dataGenerator().isNull()); + QVERIFY(!renderBuffer.pendingBufferUpdates().empty()); + + // WHEN renderBuffer.cleanup(); // THEN @@ -121,6 +143,7 @@ private Q_SLOTS: QCOMPARE(renderBuffer.usage(), Qt3DRender::QBuffer::StaticDraw); QVERIFY(renderBuffer.data().isEmpty()); QVERIFY(renderBuffer.dataGenerator().isNull()); + QVERIFY(renderBuffer.pendingBufferUpdates().empty()); } void checkPropertyChanges() @@ -174,10 +197,8 @@ private Q_SLOTS: QVERIFY(renderBuffer.isDirty()); renderBuffer.unsetDirty(); - QVERIFY(!renderBuffer.isDirty()); - // WHEN Qt3DRender::QBufferDataGeneratorPtr functor(new TestFunctor(355)); updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); @@ -213,6 +234,23 @@ private Q_SLOTS: QCOMPARE(change->propertyName(), "data"); QCOMPARE(change->value().toByteArray(), QByteArrayLiteral("454")); + arbiter.events.clear(); + + // WHEN + updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + Qt3DRender::QBufferUpdate updateData; + updateData.offset = 2; + updateData.data = QByteArrayLiteral("LS5"); + updateChange->setValue(QVariant::fromValue(updateData)); + updateChange->setPropertyName("updateData"); + renderBuffer.sceneChangeEvent(updateChange); + + // THEN + QVERIFY(!renderBuffer.pendingBufferUpdates().empty()); + QVERIFY(renderBuffer.isDirty()); + + renderBuffer.unsetDirty(); + QVERIFY(!renderBuffer.isDirty()); } }; diff --git a/tests/auto/render/qattribute/tst_qattribute.cpp b/tests/auto/render/qattribute/tst_qattribute.cpp index 18a11fe4f..2f7deaa43 100644 --- a/tests/auto/render/qattribute/tst_qattribute.cpp +++ b/tests/auto/render/qattribute/tst_qattribute.cpp @@ -64,8 +64,8 @@ private Q_SLOTS: customVertex->setByteOffset(305); customVertex->setDivisor(235); customVertex->setName("BB"); - customVertex->setDataType(Qt3DRender::QAttribute::Float); - customVertex->setDataSize(4); + customVertex->setVertexBaseType(Qt3DRender::QAttribute::Float); + customVertex->setVertexSize(4); QTest::newRow("vertex") << customVertex; Qt3DRender::QAttribute *customIndex = new Qt3DRender::QAttribute(); @@ -77,8 +77,8 @@ private Q_SLOTS: customIndex->setByteOffset(327); customIndex->setDivisor(355); customIndex->setName("SB"); - customIndex->setDataType(Qt3DRender::QAttribute::Float); - customIndex->setDataSize(3); + customIndex->setVertexBaseType(Qt3DRender::QAttribute::Float); + customIndex->setVertexSize(3); QTest::newRow("index") << customIndex; } @@ -106,8 +106,8 @@ private Q_SLOTS: QCOMPARE(attribute->byteStride(), cloneData.byteStride); QCOMPARE(attribute->byteOffset(), cloneData.byteOffset); QCOMPARE(attribute->divisor(), cloneData.divisor); - QCOMPARE(attribute->vertexBaseType(), cloneData.dataType); - QCOMPARE(attribute->vertexSize(), cloneData.dataSize); + QCOMPARE(attribute->vertexBaseType(), cloneData.vertexBaseType); + QCOMPARE(attribute->vertexSize(), cloneData.vertexSize); QVERIFY(attribute->attributeType() == cloneData.attributeType); QCOMPARE(attribute->buffer() ? attribute->buffer()->id() : Qt3DCore::QNodeId(), cloneData.bufferId); } @@ -120,7 +120,7 @@ private Q_SLOTS: arbiter.setArbiterOnNode(attribute.data()); // WHEN - attribute->setDataType(Qt3DRender::QAttribute::Double); + attribute->setVertexBaseType(Qt3DRender::QAttribute::Double); QCoreApplication::processEvents(); // THEN @@ -133,7 +133,7 @@ private Q_SLOTS: arbiter.events.clear(); // WHEN - attribute->setDataSize(4); + attribute->setVertexSize(4); QCoreApplication::processEvents(); // THEN diff --git a/tests/auto/render/qbuffer/tst_qbuffer.cpp b/tests/auto/render/qbuffer/tst_qbuffer.cpp index 995593971..a65f27cb6 100644 --- a/tests/auto/render/qbuffer/tst_qbuffer.cpp +++ b/tests/auto/render/qbuffer/tst_qbuffer.cpp @@ -189,6 +189,19 @@ private Q_SLOTS: QCOMPARE(change->value().toBool(), true); arbiter.events.clear(); + + // WHEN + buffer->updateData(1, QByteArrayLiteral("L1")); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + QCOMPARE(buffer->data(), QByteArrayLiteral("ZL1")); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "updateData"); + Qt3DRender::QBufferUpdate updateData = change->value().value<Qt3DRender::QBufferUpdate>(); + QCOMPARE(updateData.offset, 1); + QCOMPARE(updateData.data, QByteArrayLiteral("L1")); } }; diff --git a/tests/auto/render/qrendercapture/qrendercapture.pro b/tests/auto/render/qrendercapture/qrendercapture.pro new file mode 100644 index 000000000..999f95a58 --- /dev/null +++ b/tests/auto/render/qrendercapture/qrendercapture.pro @@ -0,0 +1,11 @@ +TEMPLATE = app + +TARGET = tst_qrendercapture + +QT += core-private 3dcore 3dcore-private 3drender 3drender-private testlib + +CONFIG += testcase + +SOURCES += tst_qrendercapture.cpp + +include(../commons/commons.pri) diff --git a/tests/auto/render/qrendercapture/tst_qrendercapture.cpp b/tests/auto/render/qrendercapture/tst_qrendercapture.cpp new file mode 100644 index 000000000..ef1e9f53c --- /dev/null +++ b/tests/auto/render/qrendercapture/tst_qrendercapture.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QTest> +#include <QtTest/QSignalSpy> +#include <Qt3DCore/private/qnode_p.h> +#include <Qt3DCore/private/qscene_p.h> +#include <Qt3DRender/QRenderCapture> +#include <Qt3DRender/private/qrendercapture_p.h> + +#include "testpostmanarbiter.h" + +class MyRenderCapture : public Qt3DRender::QRenderCapture +{ + Q_OBJECT +public: + MyRenderCapture(Qt3DCore::QNode *parent = nullptr) + : Qt3DRender::QRenderCapture(parent) + {} + + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_FINAL + { + Qt3DRender::QRenderCapture::sceneChangeEvent(change); + } + +private: + friend class tst_QRenderCapture; +}; + +class tst_QRenderCapture : public Qt3DCore::QNode +{ + Q_OBJECT + +private Q_SLOTS: + + void checkCaptureRequest() + { + // GIVEN + TestArbiter arbiter; + QScopedPointer<Qt3DRender::QRenderCapture> renderCapture(new Qt3DRender::QRenderCapture()); + arbiter.setArbiterOnNode(renderCapture.data()); + + // WHEN + QScopedPointer<Qt3DRender::QRenderCaptureReply> reply(renderCapture->requestCapture(12)); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "renderCaptureRequest"); + QCOMPARE(change->subjectId(),renderCapture->id()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + QCOMPARE(change->value().toInt(), 12); + + arbiter.events.clear(); + } + + void checkRenderCaptureReply() + { + // GIVEN + QScopedPointer<MyRenderCapture> renderCapture(new MyRenderCapture()); + QScopedPointer<Qt3DRender::QRenderCaptureReply> reply(renderCapture->requestCapture(52)); + QImage img = QImage(20, 20, QImage::Format_ARGB32); + + // WHEN + Qt3DRender::RenderCaptureDataPtr data = Qt3DRender::RenderCaptureDataPtr::create(); + data.data()->captureId = 52; + data.data()->image = img; + + auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(renderCapture->id()); + e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); + e->setPropertyName("renderCaptureData"); + e->setValue(QVariant::fromValue(data)); + + renderCapture->sceneChangeEvent(e); + + // THEN + QCOMPARE(reply->isComplete(), true); + QCOMPARE(reply->captureId(), 52); + QCOMPARE(reply->image().width(), 20); + QCOMPARE(reply->image().height(), 20); + QCOMPARE(reply->image().format(), QImage::Format_ARGB32); + } +}; + +QTEST_MAIN(tst_QRenderCapture) + +#include "tst_qrendercapture.moc" diff --git a/tests/auto/render/render.pro b/tests/auto/render/render.pro index 9c91e0c6e..69080ea47 100644 --- a/tests/auto/render/render.pro +++ b/tests/auto/render/render.pro @@ -1,12 +1,13 @@ TEMPLATE = subdirs -contains(QT_CONFIG, private_tests) { +qtConfig(private_tests) { SUBDIRS += \ entity \ renderqueue \ renderpass \ qgraphicsutils \ shader \ + texture \ renderviewutils \ renderviews \ material \ @@ -57,5 +58,7 @@ contains(QT_CONFIG, private_tests) { qrendertargetoutput \ qcameralens \ qcomputecommand \ - loadscenejob + loadscenejob \ + qrendercapture \ + uniform } diff --git a/tests/auto/render/texture/texture.pro b/tests/auto/render/texture/texture.pro new file mode 100644 index 000000000..04231844f --- /dev/null +++ b/tests/auto/render/texture/texture.pro @@ -0,0 +1,12 @@ +TEMPLATE = app + +TARGET = tst_texture + +QT += core-private 3dcore 3dcore-private 3drender 3drender-private testlib + +CONFIG += testcase + +SOURCES += tst_texture.cpp + +include(../../core/common/common.pri) +include(../commons/commons.pri) diff --git a/tests/auto/render/texture/tst_texture.cpp b/tests/auto/render/texture/tst_texture.cpp new file mode 100644 index 000000000..5c6bc2b37 --- /dev/null +++ b/tests/auto/render/texture/tst_texture.cpp @@ -0,0 +1,266 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QTest> +#include <qbackendnodetester.h> +#include <Qt3DCore/qdynamicpropertyupdatedchange.h> +#include <Qt3DRender/private/texture_p.h> + +#include "testpostmanarbiter.h" +#include "testrenderer.h" + +class DummyTexture : public Qt3DRender::QAbstractTexture +{ + Q_OBJECT + +public: + explicit DummyTexture(Qt3DCore::QNode *parent = nullptr) + : QAbstractTexture(TargetAutomatic, parent) + { + } +}; + +class tst_RenderTexture : public Qt3DCore::QBackendNodeTester +{ + Q_OBJECT + +private: + template <typename FrontendTextureType, Qt3DRender::QAbstractTexture::Target Target> + void checkPropertyMirroring(); + +private slots: + void checkFrontendPropertyNotifications(); + void checkPropertyMirroring(); + void checkPropertyChanges(); +}; + +void tst_RenderTexture::checkFrontendPropertyNotifications() +{ + // GIVEN + TestArbiter arbiter; + DummyTexture texture; + arbiter.setArbiterOnNode(&texture); + + // WHEN + texture.setWidth(512); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "width"); + QCOMPARE(change->value().value<int>(), 512); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + texture.setWidth(512); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + + // WHEN + texture.setHeight(256); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "height"); + QCOMPARE(change->value().value<int>(), 256); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + texture.setHeight(256); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + + // WHEN + texture.setDepth(128); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "depth"); + QCOMPARE(change->value().value<int>(), 128); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + texture.setDepth(128); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + + // WHEN + texture.setLayers(16); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "layers"); + QCOMPARE(change->value().value<int>(), 16); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + texture.setLayers(16); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + + // WHEN + texture.setSamples(32); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "samples"); + QCOMPARE(change->value().value<int>(), 32); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + texture.setSamples(32); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); +} + +template <typename FrontendTextureType, Qt3DRender::QAbstractTexture::Target Target> +void tst_RenderTexture::checkPropertyMirroring() +{ + // GIVEN + Qt3DRender::Render::Texture backend; + + FrontendTextureType frontend; + frontend.setWidth(256); + frontend.setHeight(128); + frontend.setDepth(16); + frontend.setLayers(8); + frontend.setSamples(32); + + // WHEN + simulateInitialization(&frontend, &backend); + + // THEN + QCOMPARE(backend.peerId(), frontend.id()); + QCOMPARE(backend.target(), Target); + QCOMPARE(backend.width(), frontend.width()); + QCOMPARE(backend.height(), frontend.height()); + QCOMPARE(backend.depth(), frontend.depth()); + QCOMPARE(backend.layers(), frontend.layers()); + QCOMPARE(backend.samples(), frontend.samples()); +} + +void tst_RenderTexture::checkPropertyMirroring() +{ + checkPropertyMirroring<Qt3DRender::QTexture1D, Qt3DRender::QAbstractTexture::Target1D>(); + checkPropertyMirroring<Qt3DRender::QTexture1DArray, Qt3DRender::QAbstractTexture::Target1DArray>(); + checkPropertyMirroring<Qt3DRender::QTexture2D, Qt3DRender::QAbstractTexture::Target2D>(); + checkPropertyMirroring<Qt3DRender::QTexture2DArray, Qt3DRender::QAbstractTexture::Target2DArray>(); + checkPropertyMirroring<Qt3DRender::QTexture3D, Qt3DRender::QAbstractTexture::Target3D>(); + checkPropertyMirroring<Qt3DRender::QTextureCubeMap, Qt3DRender::QAbstractTexture::TargetCubeMap>(); + checkPropertyMirroring<Qt3DRender::QTextureCubeMapArray, Qt3DRender::QAbstractTexture::TargetCubeMapArray>(); + checkPropertyMirroring<Qt3DRender::QTexture2DMultisample, Qt3DRender::QAbstractTexture::Target2DMultisample>(); + checkPropertyMirroring<Qt3DRender::QTexture2DMultisampleArray, Qt3DRender::QAbstractTexture::Target2DMultisampleArray>(); + checkPropertyMirroring<Qt3DRender::QTextureRectangle, Qt3DRender::QAbstractTexture::TargetRectangle>(); + checkPropertyMirroring<Qt3DRender::QTextureBuffer, Qt3DRender::QAbstractTexture::TargetBuffer>(); +} + +void tst_RenderTexture::checkPropertyChanges() +{ + // GIVEN + TestRenderer renderer; + Qt3DRender::Render::Texture backend; + backend.setRenderer(&renderer); + + // WHEN + Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + updateChange->setValue(256); + updateChange->setPropertyName("width"); + backend.sceneChangeEvent(updateChange); + + // THEN + QCOMPARE(backend.width(), 256); + + // WHEN + updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + updateChange->setValue(128); + updateChange->setPropertyName("height"); + backend.sceneChangeEvent(updateChange); + + // THEN + QCOMPARE(backend.height(), 128); + + // WHEN + updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + updateChange->setValue(16); + updateChange->setPropertyName("depth"); + backend.sceneChangeEvent(updateChange); + + // THEN + QCOMPARE(backend.depth(), 16); + + // WHEN + updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + updateChange->setValue(32); + updateChange->setPropertyName("layers"); + backend.sceneChangeEvent(updateChange); + + // THEN + QCOMPARE(backend.layers(), 32); + + // WHEN + updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); + updateChange->setValue(64); + updateChange->setPropertyName("samples"); + backend.sceneChangeEvent(updateChange); + + // THEN + QCOMPARE(backend.samples(), 64); +} + +QTEST_APPLESS_MAIN(tst_RenderTexture) + +#include "tst_texture.moc" diff --git a/tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp b/tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp index 8904ccd25..7647b26e7 100644 --- a/tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp +++ b/tests/auto/render/trianglesextractor/tst_trianglesextractor.cpp @@ -139,8 +139,8 @@ Qt3DRender::QGeometryRenderer *customIndexedGeometryRenderer() Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute(); positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); positionAttribute->setBuffer(vertexDataBuffer); - positionAttribute->setDataType(Qt3DRender::QAttribute::Float); - positionAttribute->setDataSize(3); + positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + positionAttribute->setVertexSize(3); positionAttribute->setByteOffset(0); positionAttribute->setByteStride(9 * sizeof(float)); positionAttribute->setCount(4); @@ -149,8 +149,8 @@ Qt3DRender::QGeometryRenderer *customIndexedGeometryRenderer() Qt3DRender::QAttribute *normalAttribute = new Qt3DRender::QAttribute(); normalAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); normalAttribute->setBuffer(vertexDataBuffer); - normalAttribute->setDataType(Qt3DRender::QAttribute::Float); - normalAttribute->setDataSize(3); + normalAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + normalAttribute->setVertexSize(3); normalAttribute->setByteOffset(3 * sizeof(float)); normalAttribute->setByteStride(9 * sizeof(float)); normalAttribute->setCount(4); @@ -159,8 +159,8 @@ Qt3DRender::QGeometryRenderer *customIndexedGeometryRenderer() Qt3DRender::QAttribute *colorAttribute = new Qt3DRender::QAttribute(); colorAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); colorAttribute->setBuffer(vertexDataBuffer); - colorAttribute->setDataType(Qt3DRender::QAttribute::Float); - colorAttribute->setDataSize(3); + colorAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + colorAttribute->setVertexSize(3); colorAttribute->setByteOffset(6 * sizeof(float)); colorAttribute->setByteStride(9 * sizeof(float)); colorAttribute->setCount(4); @@ -169,8 +169,8 @@ Qt3DRender::QGeometryRenderer *customIndexedGeometryRenderer() Qt3DRender::QAttribute *indexAttribute = new Qt3DRender::QAttribute(); indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); indexAttribute->setBuffer(indexDataBuffer); - indexAttribute->setDataType(Qt3DRender::QAttribute::UnsignedShort); - indexAttribute->setDataSize(1); + indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedShort); + indexAttribute->setVertexSize(1); indexAttribute->setByteOffset(0); indexAttribute->setByteStride(0); indexAttribute->setCount(12); @@ -270,8 +270,8 @@ Qt3DRender::QGeometryRenderer *customNonIndexedGeometryRenderer() Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute(); positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); positionAttribute->setBuffer(vertexDataBuffer); - positionAttribute->setDataType(Qt3DRender::QAttribute::Float); - positionAttribute->setDataSize(3); + positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + positionAttribute->setVertexSize(3); positionAttribute->setByteOffset(0); positionAttribute->setByteStride(9 * sizeof(float)); positionAttribute->setCount(12); @@ -280,8 +280,8 @@ Qt3DRender::QGeometryRenderer *customNonIndexedGeometryRenderer() Qt3DRender::QAttribute *normalAttribute = new Qt3DRender::QAttribute(); normalAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); normalAttribute->setBuffer(vertexDataBuffer); - normalAttribute->setDataType(Qt3DRender::QAttribute::Float); - normalAttribute->setDataSize(3); + normalAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + normalAttribute->setVertexSize(3); normalAttribute->setByteOffset(3 * sizeof(float)); normalAttribute->setByteStride(9 * sizeof(float)); normalAttribute->setCount(12); @@ -290,8 +290,8 @@ Qt3DRender::QGeometryRenderer *customNonIndexedGeometryRenderer() Qt3DRender::QAttribute *colorAttribute = new Qt3DRender::QAttribute(); colorAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); colorAttribute->setBuffer(vertexDataBuffer); - colorAttribute->setDataType(Qt3DRender::QAttribute::Float); - colorAttribute->setDataSize(3); + colorAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + colorAttribute->setVertexSize(3); colorAttribute->setByteOffset(6 * sizeof(float)); colorAttribute->setByteStride(9 * sizeof(float)); colorAttribute->setCount(12); diff --git a/tests/auto/render/uniform/tst_uniform.cpp b/tests/auto/render/uniform/tst_uniform.cpp new file mode 100644 index 000000000..4a7f086e9 --- /dev/null +++ b/tests/auto/render/uniform/tst_uniform.cpp @@ -0,0 +1,292 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QTest> +#include <Qt3DRender/private/uniform_p.h> + +using namespace Qt3DRender; +using namespace Qt3DRender::Render; + +class tst_Uniform : public QObject +{ + Q_OBJECT +private Q_SLOTS: + + void checkInitialState() + { + // GIVEN + UniformValue v; + // THEN + QVERIFY(v.constData<float>()[0] == 0.0f); + QVERIFY(v.constData<float>()[1] == 0.0f); + QVERIFY(v.constData<float>()[2] == 0.0f); + QVERIFY(v.constData<float>()[3] == 0.0f); + } + + void checkDefaultCTors() + { + { + // GIVEN + UniformValue v(883); + // THEN + QCOMPARE(v.constData<int>()[0], 883); + QCOMPARE(v.constData<int>()[1], 0); + QCOMPARE(v.constData<int>()[2], 0); + QCOMPARE(v.constData<int>()[3], 0); + } + { + // GIVEN + UniformValue v(1584U); + // THEN + QCOMPARE(v.constData<uint>()[0], 1584U); + QCOMPARE(v.constData<uint>()[1], 0U); + QCOMPARE(v.constData<uint>()[2], 0U); + QCOMPARE(v.constData<uint>()[3], 0U); + } + { + // GIVEN + UniformValue v(454.0f); + // THEN + QCOMPARE(v.constData<float>()[0], 454.0f); + QCOMPARE(v.constData<float>()[1], 0.0f); + QCOMPARE(v.constData<float>()[2], 0.0f); + QCOMPARE(v.constData<float>()[3], 0.0f); + } + { + // GIVEN + UniformValue v(350.0); + // THEN + // Note: Uniform value does a double -> float conversion + QCOMPARE(v.constData<float>()[0], 350.0f); + QCOMPARE(v.constData<float>()[1], 0.0f); + QCOMPARE(v.constData<float>()[2], 0.0f); + QCOMPARE(v.constData<float>()[3], 0.0f); + } + { + // GIVEN + UniformValue v(true); + // THEN + QCOMPARE(v.constData<bool>()[0], true); + QCOMPARE(v.constData<bool>()[1], false); + QCOMPARE(v.constData<bool>()[2], false); + QCOMPARE(v.constData<bool>()[3], false); + } + { + // GIVEN + UniformValue v(QVector2D(355.0f, 383.0f)); + // THEN + QCOMPARE(v.constData<float>()[0], 355.0f); + QCOMPARE(v.constData<float>()[1], 383.0f); + QCOMPARE(v.constData<float>()[2], 0.0f); + QCOMPARE(v.constData<float>()[3], 0.0f); + } + { + // GIVEN + UniformValue v(QVector3D(572.0f, 355.0f, 383.0f)); + // THEN + QCOMPARE(v.constData<float>()[0], 572.0f); + QCOMPARE(v.constData<float>()[1], 355.0f); + QCOMPARE(v.constData<float>()[2], 383.0f); + QCOMPARE(v.constData<float>()[4], 0.0f); + } + { + // GIVEN + UniformValue v(QVector4D(355.0f, 383.0f, 1340.0f, 1603.0f)); + // THEN + QCOMPARE(v.constData<float>()[0], 355.0f); + QCOMPARE(v.constData<float>()[1], 383.0f); + QCOMPARE(v.constData<float>()[2], 1340.0f); + QCOMPARE(v.constData<float>()[3], 1603.0f); + } + } + + void checkFromVariant() + { + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant(883)); + // THEN + QCOMPARE(v.constData<int>()[0], 883); + QCOMPARE(v.constData<int>()[1], 0); + QCOMPARE(v.constData<int>()[2], 0); + QCOMPARE(v.constData<int>()[3], 0); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant(1584U)); + // THEN + QCOMPARE(v.constData<uint>()[0], 1584U); + QCOMPARE(v.constData<uint>()[1], 0U); + QCOMPARE(v.constData<uint>()[2], 0U); + QCOMPARE(v.constData<uint>()[3], 0U); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant(454.0f)); + // THEN + QCOMPARE(v.constData<float>()[0], 454.0f); + QCOMPARE(v.constData<float>()[1], 0.0f); + QCOMPARE(v.constData<float>()[2], 0.0f); + QCOMPARE(v.constData<float>()[3], 0.0f); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant(350.0)); + // THEN + // Note: Uniform value does a double -> float conversion + QCOMPARE(v.constData<float>()[0], 350.0f); + QCOMPARE(v.constData<float>()[1], 0.0f); + QCOMPARE(v.constData<float>()[2], 0.0f); + QCOMPARE(v.constData<float>()[3], 0.0f); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant(true)); + // THEN + QCOMPARE(v.constData<bool>()[0], true); + QCOMPARE(v.constData<bool>()[1], false); + QCOMPARE(v.constData<bool>()[2], false); + QCOMPARE(v.constData<bool>()[3], false); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant::fromValue(QVector2D(355.0f, 383.0f))); + // THEN + QCOMPARE(v.constData<float>()[0], 355.0f); + QCOMPARE(v.constData<float>()[1], 383.0f); + QCOMPARE(v.constData<float>()[2], 0.0f); + QCOMPARE(v.constData<float>()[3], 0.0f); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant::fromValue(QVector3D(572.0f, 355.0f, 383.0f))); + // THEN + QCOMPARE(v.constData<float>()[0], 572.0f); + QCOMPARE(v.constData<float>()[1], 355.0f); + QCOMPARE(v.constData<float>()[2], 383.0f); + QCOMPARE(v.constData<float>()[3], 0.0f); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant::fromValue(QVector4D(355.0f, 383.0f, 1340.0f, 1603.0f))); + // THEN + QCOMPARE(v.constData<float>()[0], 355.0f); + QCOMPARE(v.constData<float>()[1], 383.0f); + QCOMPARE(v.constData<float>()[2], 1340.0f); + QCOMPARE(v.constData<float>()[3], 1603.0f); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant::fromValue(QPoint(427, 396))); + // THEN + QCOMPARE(v.constData<int>()[0], 427); + QCOMPARE(v.constData<int>()[1], 396); + QCOMPARE(v.constData<int>()[2], 0); + QCOMPARE(v.constData<int>()[3], 0); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant::fromValue(QSize(427, 396))); + // THEN + QCOMPARE(v.constData<int>()[0], 427); + QCOMPARE(v.constData<int>()[1], 396); + QCOMPARE(v.constData<int>()[2], 0); + QCOMPARE(v.constData<int>()[3], 0); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant::fromValue(QRect(427, 396, 454, 1584))); + // THEN + QCOMPARE(v.constData<int>()[0], 427); + QCOMPARE(v.constData<int>()[1], 396); + QCOMPARE(v.constData<int>()[2], 454); + QCOMPARE(v.constData<int>()[3], 1584); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant::fromValue(QPointF(427, 396))); + // THEN + QCOMPARE(v.constData<float>()[0], 427.0f); + QCOMPARE(v.constData<float>()[1], 396.0f); + QCOMPARE(v.constData<float>()[2], 0.0f); + QCOMPARE(v.constData<float>()[3], 0.0f); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant::fromValue(QSizeF(427, 396))); + // THEN + QCOMPARE(v.constData<float>()[0], 427.0f); + QCOMPARE(v.constData<float>()[1], 396.0f); + QCOMPARE(v.constData<float>()[2], 0.0f); + QCOMPARE(v.constData<float>()[3], 0.0f); + } + { + // GIVEN + UniformValue v = UniformValue::fromVariant(QVariant::fromValue(QRectF(427, 396, 454, 1584))); + // THEN + QCOMPARE(v.constData<float>()[0], 427.0f); + QCOMPARE(v.constData<float>()[1], 396.0f); + QCOMPARE(v.constData<float>()[2], 454.0f); + QCOMPARE(v.constData<float>()[3], 1584.0f); + } + } + + void checkComparison() + { + // GIVEN + const UniformValue v1(QVector3D(454.0f, 883.0f, 572.0f)); + UniformValue v2(454.0f); + + // THEN + QVERIFY(!(v1 == v2)); + QVERIFY(v1 != v2); + + // WHEN + v2 = UniformValue::fromVariant(QVector3D(454.0f, 883.0f, 572.0f)); + // THEN + QVERIFY(v1 == v2); + QVERIFY(!(v1 != v2)); + + // WHEN + v2 = UniformValue::fromVariant(QVector3D(454.0f, 883.0f, 572.0f)); + // THEN + QVERIFY(v1 == v2); + QVERIFY(!(v1 != v2)); + + // WHEN + v2 = UniformValue::fromVariant(454.0f); + // THEN + QVERIFY(!(v1 == v2)); + QVERIFY(v1 != v2); + } +}; + + +QTEST_APPLESS_MAIN(tst_Uniform) + +#include "tst_uniform.moc" diff --git a/tests/auto/render/uniform/uniform.pro b/tests/auto/render/uniform/uniform.pro new file mode 100644 index 000000000..44dd0266a --- /dev/null +++ b/tests/auto/render/uniform/uniform.pro @@ -0,0 +1,13 @@ +TEMPLATE = app + +TARGET = tst_uniform + +QT += 3dcore 3dcore-private 3drender 3drender-private testlib + +CONFIG += testcase + +SOURCES += \ + tst_uniform.cpp + +include(../../core/common/common.pri) +include(../commons/commons.pri) diff --git a/tests/benchmarks/render/render.pro b/tests/benchmarks/render/render.pro index c553199e3..f1095a347 100644 --- a/tests/benchmarks/render/render.pro +++ b/tests/benchmarks/render/render.pro @@ -1,5 +1,5 @@ TEMPLATE=subdirs -contains(QT_CONFIG, private_tests) { +qtConfig(private_tests) { SUBDIRS += jobs } diff --git a/tests/manual/custom-mesh-cpp/main.cpp b/tests/manual/custom-mesh-cpp/main.cpp index c11c98ea6..e51321e65 100644 --- a/tests/manual/custom-mesh-cpp/main.cpp +++ b/tests/manual/custom-mesh-cpp/main.cpp @@ -193,8 +193,8 @@ int main(int argc, char* argv[]) Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute(); positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); positionAttribute->setBuffer(vertexDataBuffer); - positionAttribute->setDataType(Qt3DRender::QAttribute::Float); - positionAttribute->setDataSize(3); + positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + positionAttribute->setVertexSize(3); positionAttribute->setByteOffset(0); positionAttribute->setByteStride(9 * sizeof(float)); positionAttribute->setCount(4); @@ -203,8 +203,8 @@ int main(int argc, char* argv[]) Qt3DRender::QAttribute *normalAttribute = new Qt3DRender::QAttribute(); normalAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); normalAttribute->setBuffer(vertexDataBuffer); - normalAttribute->setDataType(Qt3DRender::QAttribute::Float); - normalAttribute->setDataSize(3); + normalAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + normalAttribute->setVertexSize(3); normalAttribute->setByteOffset(3 * sizeof(float)); normalAttribute->setByteStride(9 * sizeof(float)); normalAttribute->setCount(4); @@ -213,8 +213,8 @@ int main(int argc, char* argv[]) Qt3DRender::QAttribute *colorAttribute = new Qt3DRender::QAttribute(); colorAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); colorAttribute->setBuffer(vertexDataBuffer); - colorAttribute->setDataType(Qt3DRender::QAttribute::Float); - colorAttribute->setDataSize(3); + colorAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + colorAttribute->setVertexSize(3); colorAttribute->setByteOffset(6 * sizeof(float)); colorAttribute->setByteStride(9 * sizeof(float)); colorAttribute->setCount(4); @@ -223,8 +223,8 @@ int main(int argc, char* argv[]) Qt3DRender::QAttribute *indexAttribute = new Qt3DRender::QAttribute(); indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); indexAttribute->setBuffer(indexDataBuffer); - indexAttribute->setDataType(Qt3DRender::QAttribute::UnsignedShort); - indexAttribute->setDataSize(1); + indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedShort); + indexAttribute->setVertexSize(1); indexAttribute->setByteOffset(0); indexAttribute->setByteStride(0); indexAttribute->setCount(12); diff --git a/tests/manual/custom-mesh-update-data-cpp/custom-mesh-update-data-cpp.pro b/tests/manual/custom-mesh-update-data-cpp/custom-mesh-update-data-cpp.pro new file mode 100644 index 000000000..f4f7fa440 --- /dev/null +++ b/tests/manual/custom-mesh-update-data-cpp/custom-mesh-update-data-cpp.pro @@ -0,0 +1,8 @@ +!include( ../manual.pri ) { + error( "Couldn't find the examples.pri file!" ) +} + +QT += 3dcore 3drender 3dinput + +SOURCES += \ + main.cpp diff --git a/tests/manual/custom-mesh-update-data-cpp/main.cpp b/tests/manual/custom-mesh-update-data-cpp/main.cpp new file mode 100644 index 000000000..7485dbec5 --- /dev/null +++ b/tests/manual/custom-mesh-update-data-cpp/main.cpp @@ -0,0 +1,304 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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 <QGuiApplication> +#include <QTimer> + +#include <Qt3DCore/QEntity> +#include <Qt3DRender/QCamera> +#include <Qt3DRender/QCameraLens> +#include <Qt3DCore/QTransform> +#include <Qt3DCore/QAspectEngine> + +#include <Qt3DInput/QInputAspect> + +#include <Qt3DRender/QRenderStateSet> +#include <Qt3DRender/QRenderAspect> +#include <Qt3DExtras/QForwardRenderer> +#include <Qt3DExtras/QPerVertexColorMaterial> + +#include <Qt3DRender/QGeometryRenderer> +#include <Qt3DRender/QGeometry> +#include <Qt3DRender/QAttribute> +#include <Qt3DRender/QBuffer> + +#include <QPropertyAnimation> +#include <Qt3DExtras/qt3dwindow.h> +#include <Qt3DExtras/qfirstpersoncameracontroller.h> +#include <qmath.h> + +QByteArray vertexBufferData; +Qt3DRender::QBuffer *vertexDataBuffer; + +class TimerObject: public QObject { + Q_OBJECT + +public: + TimerObject(QObject *parent = 0): QObject(parent) { + } + ~TimerObject() { + } +private slots: + void timeout(); +private: + float angle = 0; +}; + +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc, argv); + Qt3DExtras::Qt3DWindow view; + view.defaultFrameGraph()->setClearColor(QColor::fromRgbF(0.0, 0.5, 1.0, 1.0)); + + // Root entity + Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity(); + + // Camera + Qt3DRender::QCamera *cameraEntity = view.camera(); + + cameraEntity->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f); + cameraEntity->setPosition(QVector3D(50.0f, 20.0f, 40.0f)); + cameraEntity->setUpVector(QVector3D(0, 1, 0)); + cameraEntity->setViewCenter(QVector3D(0, 0, 0)); + + // For camera controls + Qt3DExtras::QFirstPersonCameraController *camController = new Qt3DExtras::QFirstPersonCameraController(rootEntity); + camController->setCamera(cameraEntity); + + // Material + Qt3DRender::QMaterial *material = new Qt3DExtras::QPerVertexColorMaterial(rootEntity); + + // Torus + Qt3DCore::QEntity *customMeshEntity = new Qt3DCore::QEntity(rootEntity); + + // Transform + Qt3DCore::QTransform *transform = new Qt3DCore::QTransform; + transform->setScale(20.0f); + + // Custom Mesh (TetraHedron) + Qt3DRender::QGeometryRenderer *customMeshRenderer = new Qt3DRender::QGeometryRenderer; + Qt3DRender::QGeometry *customGeometry = new Qt3DRender::QGeometry(customMeshRenderer); + + vertexDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, customGeometry); + Qt3DRender::QBuffer *indexDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, customGeometry); + + // vec3 for position + // vec3 for colors + // vec3 for normals + + /* 2 + /|\ + / | \ + / /3\ \ + 0/___\ 1 + */ + + // 4 distinct vertices + vertexBufferData.resize(4 * (3 + 3 + 3) * sizeof(float)); + + // Vertices + QVector3D v0(-1.0f, 0.0f, -1.0f); + QVector3D v1(1.0f, 0.0f, -1.0f); + QVector3D v2(0.0f, 1.0f, 0.0f); + QVector3D v3(0.0f, 0.0f, 1.0f); + + // Faces Normals + QVector3D n023 = QVector3D::normal(v0, v2, v3); + QVector3D n012 = QVector3D::normal(v0, v1, v2); + QVector3D n310 = QVector3D::normal(v3, v1, v0); + QVector3D n132 = QVector3D::normal(v1, v3, v2); + + // Vector Normals + QVector3D n0 = QVector3D(n023 + n012 + n310).normalized(); + QVector3D n1 = QVector3D(n132 + n012 + n310).normalized(); + QVector3D n2 = QVector3D(n132 + n012 + n023).normalized(); + QVector3D n3 = QVector3D(n132 + n310 + n023).normalized(); + + // Colors + QVector3D red(1.0f, 0.0f, 0.0f); + QVector3D green(0.0f, 1.0f, 0.0f); + QVector3D blue(0.0f, 0.0f, 1.0f); + QVector3D white(1.0f, 1.0f, 1.0f); + + QVector<QVector3D> vertices = QVector<QVector3D>() + << v0 << n0 << red + << v1 << n1 << blue + << v2 << n2 << green + << v3 << n3 << white; + + float *rawVertexArray = reinterpret_cast<float *>(vertexBufferData.data()); + int idx = 0; + + Q_FOREACH (const QVector3D &v, vertices) { + rawVertexArray[idx++] = v.x(); + rawVertexArray[idx++] = v.y(); + rawVertexArray[idx++] = v.z(); + } + + // Indices (12) + QByteArray indexBufferData; + indexBufferData.resize(4 * 3 * sizeof(ushort)); + ushort *rawIndexArray = reinterpret_cast<ushort *>(indexBufferData.data()); + + // Front + rawIndexArray[0] = 0; + rawIndexArray[1] = 1; + rawIndexArray[2] = 2; + // Bottom + rawIndexArray[3] = 3; + rawIndexArray[4] = 1; + rawIndexArray[5] = 0; + // Left + rawIndexArray[6] = 0; + rawIndexArray[7] = 2; + rawIndexArray[8] = 3; + // Right + rawIndexArray[9] = 1; + rawIndexArray[10] = 3; + rawIndexArray[11] = 2; + + vertexDataBuffer->setData(vertexBufferData); + indexDataBuffer->setData(indexBufferData); + + // Attributes + Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute(); + positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + positionAttribute->setBuffer(vertexDataBuffer); + positionAttribute->setDataType(Qt3DRender::QAttribute::Float); + positionAttribute->setDataSize(3); + positionAttribute->setByteOffset(0); + positionAttribute->setByteStride(9 * sizeof(float)); + positionAttribute->setCount(4); + positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); + + Qt3DRender::QAttribute *normalAttribute = new Qt3DRender::QAttribute(); + normalAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + normalAttribute->setBuffer(vertexDataBuffer); + normalAttribute->setDataType(Qt3DRender::QAttribute::Float); + normalAttribute->setDataSize(3); + normalAttribute->setByteOffset(3 * sizeof(float)); + normalAttribute->setByteStride(9 * sizeof(float)); + normalAttribute->setCount(4); + normalAttribute->setName(Qt3DRender::QAttribute::defaultNormalAttributeName()); + + Qt3DRender::QAttribute *colorAttribute = new Qt3DRender::QAttribute(); + colorAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); + colorAttribute->setBuffer(vertexDataBuffer); + colorAttribute->setDataType(Qt3DRender::QAttribute::Float); + colorAttribute->setDataSize(3); + colorAttribute->setByteOffset(6 * sizeof(float)); + colorAttribute->setByteStride(9 * sizeof(float)); + colorAttribute->setCount(4); + colorAttribute->setName(Qt3DRender::QAttribute::defaultColorAttributeName()); + + Qt3DRender::QAttribute *indexAttribute = new Qt3DRender::QAttribute(); + indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); + indexAttribute->setBuffer(indexDataBuffer); + indexAttribute->setDataType(Qt3DRender::QAttribute::UnsignedShort); + indexAttribute->setDataSize(1); + indexAttribute->setByteOffset(0); + indexAttribute->setByteStride(0); + indexAttribute->setCount(12); + + customGeometry->addAttribute(positionAttribute); + customGeometry->addAttribute(normalAttribute); + customGeometry->addAttribute(colorAttribute); + customGeometry->addAttribute(indexAttribute); + + customMeshRenderer->setInstanceCount(1); + customMeshRenderer->setIndexOffset(0); + customMeshRenderer->setFirstInstance(0); + customMeshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles); + customMeshRenderer->setGeometry(customGeometry); + // 4 faces of 3 points + customMeshRenderer->setVertexCount(12); + + customMeshEntity->addComponent(customMeshRenderer); + customMeshEntity->addComponent(transform); + customMeshEntity->addComponent(material); + + view.setRootEntity(rootEntity); + view.show(); + + QTimer *timer = new QTimer(); + TimerObject *timerObject = new TimerObject(); + QObject::connect(timer, SIGNAL(timeout()), timerObject, SLOT(timeout())); + timer->start(10); + + return app.exec(); +} + +void TimerObject::timeout() +{ + angle += M_PI / 360.0f; + + QByteArray updateData; + updateData.resize(3*sizeof(float)); + + // Colors + QVector3D c1(qFabs(qCos(angle + M_PI_4)), qFabs(qSin(angle)), qFabs(qCos(angle))); + QVector3D c2(qFabs(qSin(angle)), qFabs(qCos(angle + M_PI_4)), qFabs(qSin(angle + M_PI_4))); + QVector3D c3(qFabs(qSin(angle + M_PI_4)), qFabs(qSin(angle)), qFabs(qCos(angle))); + + QVector<QVector3D> colors = QVector<QVector3D>() << c1 << c2 << c3; + + float *rawVertexArray = reinterpret_cast<float *>(updateData.data()); + + int pos = 6 * sizeof(float); //color offset + Q_FOREACH (const QVector3D &v, colors) { + rawVertexArray[0] = v.x(); + rawVertexArray[1] = v.y(); + rawVertexArray[2] = v.z(); + vertexDataBuffer->updateData(pos,updateData); + pos += 9 * sizeof(float); //stride + } +} + +#include "main.moc" diff --git a/tests/manual/custom-mesh-update-data-qml/custom-mesh-update-data-qml.pro b/tests/manual/custom-mesh-update-data-qml/custom-mesh-update-data-qml.pro new file mode 100644 index 000000000..8581e0b0a --- /dev/null +++ b/tests/manual/custom-mesh-update-data-qml/custom-mesh-update-data-qml.pro @@ -0,0 +1,11 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +QT += 3dcore 3drender 3dinput 3dquick quick 3dquickextras + +SOURCES += \ + main.cpp + +RESOURCES += \ + custom-mesh-update-data-qml.qrc diff --git a/tests/manual/custom-mesh-update-data-qml/custom-mesh-update-data-qml.qrc b/tests/manual/custom-mesh-update-data-qml/custom-mesh-update-data-qml.qrc new file mode 100644 index 000000000..5f6483ac3 --- /dev/null +++ b/tests/manual/custom-mesh-update-data-qml/custom-mesh-update-data-qml.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/custom-mesh-update-data-qml/main.cpp b/tests/manual/custom-mesh-update-data-qml/main.cpp new file mode 100644 index 000000000..41d2f08a5 --- /dev/null +++ b/tests/manual/custom-mesh-update-data-qml/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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 <Qt3DQuickExtras/qt3dquickwindow.h> +#include <QGuiApplication> + +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc, argv); + Qt3DExtras::Quick::Qt3DQuickWindow view; + + view.setSource(QUrl("qrc:/main.qml")); + view.show(); + + return app.exec(); +} diff --git a/tests/manual/custom-mesh-update-data-qml/main.qml b/tests/manual/custom-mesh-update-data-qml/main.qml new file mode 100644 index 000000000..e95c05a26 --- /dev/null +++ b/tests/manual/custom-mesh-update-data-qml/main.qml @@ -0,0 +1,287 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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$ +** +****************************************************************************/ + +import QtQuick 2.2 as QQ2 +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.0 + +Entity { + id: sceneRoot + + Camera { + id: camera + projectionType: CameraLens.PerspectiveProjection + fieldOfView: 45 + aspectRatio: 16/9 + nearPlane : 0.1 + farPlane : 1000.0 + position: Qt.vector3d( 0.0, 0.0, 40.0 ) + upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) + viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 ) + } + + OrbitCameraController { camera: camera } + + components: [ + RenderSettings { + activeFrameGraph: ForwardRenderer { + clearColor: Qt.rgba(0.5, 0.5, 1, 1) + camera: camera + } + }, + // Event Source will be set by the Qt3DQuickWindow + InputSettings { } + ] + + PerVertexColorMaterial { + id: material + } + + function buildVertexBufferData() + { + // Vertices + var v0 = Qt.vector3d(-1.0, 0.0, -1.0) + var v1 = Qt.vector3d(1.0, 0.0, -1.0) + var v2 = Qt.vector3d(0.0, 1.0, 0.0) + var v3 = Qt.vector3d(0.0, 0.0, 1.0) + + // Face Normals + function normal(v0, v1, v2) { + return v1.minus(v0).crossProduct(v2.minus(v0)).normalized(); + } + var n023 = normal(v0, v2, v3) + var n012 = normal(v0, v1, v2) + var n310 = normal(v3, v1, v0) + var n132 = normal(v1, v3, v2) + + // Vector normals + var n0 = n023.plus(n012).plus(n310).normalized() + var n1 = n132.plus(n012).plus(n310).normalized() + var n2 = n132.plus(n012).plus(n023).normalized() + var n3 = n132.plus(n310).plus(n023).normalized() + + // Colors + var red = Qt.vector3d(1.0, 0.0, 0.0) + var green = Qt.vector3d(0.0, 1.0, 0.0) + var blue = Qt.vector3d(0.0, 0.0, 1.0) + var white = Qt.vector3d(1.0, 1.0, 1.0) + + var vertices = [ + v0, n0, red, + v1, n1, blue, + v2, n2, green, + v3, n3, white + ] + + var vertexArray = new Float32Array(4 * (3 + 3 + 3)); + var i = 0; + + vertices.forEach(function(vec3) { + vertexArray[i++] = vec3.x; + vertexArray[i++] = vec3.y; + vertexArray[i++] = vec3.z; + }); + + return vertexArray; + } + + function buildIndexBufferData() + { + var indexArray = new Uint16Array(12); + + // Front + indexArray[0] = 0; + indexArray[1] = 1; + indexArray[2] = 2; + // Bottom + indexArray[3] = 3; + indexArray[4] = 1; + indexArray[5] = 0; + // Left + indexArray[6] = 0; + indexArray[7] = 2; + indexArray[8] = 3; + // Right + indexArray[9] = 1; + indexArray[10] = 3; + indexArray[11] = 2; + + return indexArray; + } + + function updateVertexColor() + { + var angle = colorBufferTimerUpdate.angle + + var c1 = Qt.vector3d(Math.abs(Math.cos(angle + Math.PI * 0.25)), + Math.abs(Math.sin(angle)), + Math.abs(Math.cos(angle))); + var c2 = Qt.vector3d(Math.abs(Math.sin(angle)), + Math.abs(Math.cos(angle + Math.PI * 0.25)), + Math.abs(Math.sin(angle + Math.PI * 0.25))); + var c3 = Qt.vector3d(Math.abs(Math.sin(angle + Math.PI * 0.25)), + Math.abs(Math.sin(angle)), + Math.abs(Math.cos(angle))); + + var cols = [c1, c2, c3]; + + var byteOffset = 6.0 * 4.0 // 6 * sizeof(float) + var stride = 9.0 * 4.0 // 9 * sizeof(float) + var colorArray = new Float32Array(3) + cols.forEach(function(vec3Col) { + colorArray[0] = vec3Col.x + colorArray[1] = vec3Col.y + colorArray[2] = vec3Col.z + vertexBuffer.updateData(byteOffset, colorArray) + byteOffset += stride + }); + + colorBufferTimerUpdate.angle += Math.PI / 360.0; + } + + QQ2.Timer { + id: colorBufferTimerUpdate + interval: 16 + repeat: true + running: true + property real angle: 0 + onTriggered: { + updateVertexColor() + } + } + + GeometryRenderer { + id: customMesh + instanceCount: 1 + indexOffset: 0 + firstInstance: 0 + primitiveType: GeometryRenderer.Triangles + Buffer { + id: vertexBuffer + type: Buffer.VertexBuffer + data: buildVertexBufferData() + } + + Buffer { + id: indexBuffer + type: Buffer.IndexBuffer + data: buildIndexBufferData() + } + geometry: Geometry { + Attribute { + attributeType: Attribute.VertexAttribute + vertexBaseType: Attribute.Float + vertexSize: 3 + byteOffset: 0 + byteStride: 9 * 4 + count: 4 + name: defaultPositionAttributeName() + buffer: vertexBuffer + } + + Attribute { + attributeType: Attribute.VertexAttribute + vertexBaseType: Attribute.Float + vertexSize: 3 + byteOffset: 3 * 4 + byteStride: 9 * 4 + count: 4 + name: defaultNormalAttributeName() + buffer: vertexBuffer + } + + Attribute { + attributeType: Attribute.VertexAttribute + vertexBaseType: Attribute.Float + vertexSize: 3 + byteOffset: 6 * 4 + byteStride: 9 * 4 + count: 4 + name: defaultColorAttributeName() + buffer: vertexBuffer + } + + Attribute { + attributeType: Attribute.IndexAttribute + vertexBaseType: Attribute.UnsignedShort + vertexSize: 1 + byteOffset: 0 + byteStride: 0 + count: 12 + buffer: indexBuffer + } + } + } + + Transform { + id: meshTransform + property real userAngle: 0.0 + scale: 10 + rotation: fromAxisAndAngle(Qt.vector3d(0, 1, 0), userAngle) + } + + QQ2.NumberAnimation { + target: meshTransform + property: "userAngle" + duration: 10000 + from: 0 + to: 360 + + loops: QQ2.Animation.Infinite + running: true + } + + Entity { + id: sphereEntity + components: [ customMesh, material, meshTransform ] + } +} diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 13c5bf5be..5b17f18a2 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -9,6 +9,8 @@ SUBDIRS += \ component-changes \ custom-mesh-cpp \ custom-mesh-qml \ + custom-mesh-update-data-cpp \ + custom-mesh-update-data-qml \ cylinder-cpp \ cylinder-qml \ deferred-renderer-cpp \ @@ -20,6 +22,7 @@ SUBDIRS += \ keyboardinput-qml \ loader-qml \ mouseinput-qml \ + multiplewindows-qml \ picking-qml \ plasma \ scene3d-loader \ @@ -28,7 +31,10 @@ SUBDIRS += \ tessellation-modes \ transforms-qml \ transparency-qml \ - transparency-qml-scene3d \ - multiplewindows-qml + transparency-qml-scene3d -qtHaveModule(widgets): SUBDIRS += assimp-cpp +qtHaveModule(widgets): { + SUBDIRS += \ + assimp-cpp \ + paintedtexture-cpp +} diff --git a/tests/manual/paintedtexture-cpp/main.cpp b/tests/manual/paintedtexture-cpp/main.cpp new file mode 100644 index 000000000..4651acd65 --- /dev/null +++ b/tests/manual/paintedtexture-cpp/main.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 "scene.h" + +#include <QGuiApplication> + +#include <Qt3DCore/qentity.h> +#include <QtGui/QScreen> + +#include <QtWidgets/QApplication> +#include <QtWidgets/QWidget> +#include <QtWidgets/QHBoxLayout> +#include <QtWidgets/QSlider> +#include <QtWidgets/QLabel> +#include <QtWidgets/QPushButton> + +#include <Qt3DRender/qcamera.h> +#include <Qt3DInput/QInputAspect> +#include <Qt3DExtras/qforwardrenderer.h> +#include <Qt3DExtras/qt3dwindow.h> +#include <Qt3DExtras/qfirstpersoncameracontroller.h> + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow(); + view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f))); + QWidget *container = QWidget::createWindowContainer(view); + QSize screenSize = view->screen()->size(); + container->setMinimumSize(QSize(200, 100)); + container->setMaximumSize(screenSize); + + Qt3DInput::QInputAspect *input = new Qt3DInput::QInputAspect; + view->registerAspect(input); + + // Root entity + Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity(); + + // Camera + Qt3DRender::QCamera *cameraEntity = view->camera(); + + cameraEntity->setPosition(QVector3D(0, 0, 20.0f)); + cameraEntity->setUpVector(QVector3D(0, 1, 0)); + cameraEntity->setViewCenter(QVector3D(0, 0, 0)); + + // For camera controls + Qt3DExtras::QFirstPersonCameraController *camController = new Qt3DExtras::QFirstPersonCameraController(rootEntity); + camController->setCamera(cameraEntity); + + // scene + Scene *scene = new Scene(rootEntity); + + // Set root object of the scene + view->setRootEntity(rootEntity); + + // 'Generate New' Button + QPushButton *genNewButton = new QPushButton(); + genNewButton->setText("Generate New"); + QObject::connect(genNewButton, &QPushButton::pressed, scene, &Scene::redrawTexture); + + // current size label + QLabel *sizeLabel = new QLabel(); + sizeLabel->setText(QString("Current Size: 128x128")); + + // 'Change Size' Slider + QSlider *changeSizeSlider = new QSlider(); + changeSizeSlider->setOrientation(Qt::Horizontal); + changeSizeSlider->setMinimum(0); + changeSizeSlider->setMaximum(4); + QObject::connect(changeSizeSlider, &QSlider::valueChanged, [scene, sizeLabel](int value) { + int sz = 128 << value; + scene->setSize(QSize(sz, sz)); + sizeLabel->setText(QString("Current Size: %1x%1").arg(sz)); + }); + + // create widget + QWidget *widget = new QWidget; + widget->setWindowTitle(QStringLiteral("QPaintedTexture Example")); + + QVBoxLayout *hLayout = new QVBoxLayout(widget); + hLayout->addWidget(container, 1); + hLayout->addWidget(genNewButton, 1); + hLayout->addWidget(changeSizeSlider, 1); + hLayout->addWidget(sizeLabel); + + // Show window + widget->show(); + widget->resize(1200, 800); + + return app.exec(); +} diff --git a/tests/manual/paintedtexture-cpp/paintedtexture-cpp.pro b/tests/manual/paintedtexture-cpp/paintedtexture-cpp.pro new file mode 100644 index 000000000..448d90ecd --- /dev/null +++ b/tests/manual/paintedtexture-cpp/paintedtexture-cpp.pro @@ -0,0 +1,12 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +QT += 3dcore 3drender 3dinput 3dextras widgets + +SOURCES += \ + main.cpp \ + scene.cpp + +HEADERS += \ + scene.h diff --git a/tests/manual/paintedtexture-cpp/scene.cpp b/tests/manual/paintedtexture-cpp/scene.cpp new file mode 100644 index 000000000..19bcdbd22 --- /dev/null +++ b/tests/manual/paintedtexture-cpp/scene.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 "scene.h" + +#include <QtCore/QDebug> +#include <QtCore/QTimer> +#include <QtCore/QDateTime> + +#include <QtGui/QPainter> +#include <Qt3DRender/QPaintedTextureImage> +#include <Qt3DRender/QTexture> + +#include <Qt3DExtras/QCuboidMesh> +#include <Qt3DExtras/QDiffuseMapMaterial> + +class MyTextureImage : public Qt3DRender::QPaintedTextureImage +{ +public: + MyTextureImage(int w, int h) + { + setSize(QSize(w, h)); + } + +protected: + void paint(QPainter *painter) + { + int w = painter->device()->width(); + int h = painter->device()->height(); + + // clear to white + painter->fillRect(0, 0, w, h, QColor(255, 255, 255)); + + // draw some text + painter->setPen(QColor(255, 0, 0)); + painter->setFont(QFont("Times", 30, QFont::Normal, true)); + painter->drawText(w / 8, h / 6, QDateTime::currentDateTime().toString()); + + painter->setPen(QPen(QBrush(QColor(0, 0, 0)) ,10)); + painter->setBrush(QColor(0, 0, 255)); + + // draw some circles + for (int i = 0; i < m_circleCount; i++) { + float r = w / 8.f; + float cw = 0.25 * w + 0.5 * h * (i % 2); + float ch = 0.375 * w + 0.375 * h * (i / 2); + painter->drawEllipse(QPointF(cw, ch), r, r); + } + + m_circleCount = (m_circleCount % 4) + 1; + } + + int m_circleCount = 1; +}; + +Scene::Scene(Qt3DCore::QEntity *rootEntity) + : m_rootEntity(rootEntity) +{ + // Cuboid shape data + Qt3DExtras::QCuboidMesh *cuboid = new Qt3DExtras::QCuboidMesh(); + + // CuboidMesh Transform + m_transform = new Qt3DCore::QTransform(); + m_transform->setScale(4.0f);; + + // create texture + m_paintedTextureImage = new MyTextureImage(128, 128); + m_paintedTextureImage->update(); + + Qt3DRender::QTexture2D *tex = new Qt3DRender::QTexture2D(); + tex->addTextureImage(m_paintedTextureImage); + + Qt3DExtras::QDiffuseMapMaterial *mat = new Qt3DExtras::QDiffuseMapMaterial(); + mat->setAmbient(QColor(64, 64, 64)); + mat->setSpecular(QColor(255, 255, 255)); + mat->setDiffuse(tex); + + //Cuboid + m_cuboidEntity = new Qt3DCore::QEntity(m_rootEntity); + m_cuboidEntity->addComponent(cuboid); + m_cuboidEntity->addComponent(mat); + m_cuboidEntity->addComponent(m_transform); + + QTimer *timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, &Scene::updateTimer); + timer->start(50); +} + +Scene::~Scene() +{ +} + +void Scene::redrawTexture() +{ + m_paintedTextureImage->update(); +} + +void Scene::setSize(QSize size) +{ + m_paintedTextureImage->setSize(size); +} + +void Scene::updateTimer() +{ + m_transform->setRotation(QQuaternion::fromAxisAndAngle(0, 1, 0, m_angle)); + m_angle += 0.4f; +} diff --git a/tests/manual/paintedtexture-cpp/scene.h b/tests/manual/paintedtexture-cpp/scene.h new file mode 100644 index 000000000..84d98247d --- /dev/null +++ b/tests/manual/paintedtexture-cpp/scene.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 SCENE_H +#define SCENE_H + +#include <QtCore/QObject> + +#include <Qt3DCore/QEntity> +#include <Qt3DCore/QTransform> +#include <Qt3DRender/QPaintedTextureImage> + +class Scene : public QObject +{ + Q_OBJECT + +public: + explicit Scene(Qt3DCore::QEntity *rootEntity); + ~Scene(); + +public Q_SLOTS: + void redrawTexture(); + void setSize(QSize size); + +private Q_SLOTS: + void updateTimer(); + +private: + Qt3DCore::QEntity *m_rootEntity; + + Qt3DCore::QEntity *m_cuboidEntity; + Qt3DCore::QTransform *m_transform; + Qt3DRender::QPaintedTextureImage *m_paintedTextureImage; + + float m_angle = 0; +}; + +#endif // SCENE_H + diff --git a/tests/manual/picking-qml/main.qml b/tests/manual/picking-qml/main.qml index 8cd55a627..c020d5817 100644 --- a/tests/manual/picking-qml/main.qml +++ b/tests/manual/picking-qml/main.qml @@ -165,7 +165,7 @@ Entity { property bool toggled: false onClicked: { - console.log("Clicked cube 2") + console.log("Clicked cube 2", event.button) toggled = !toggled } } diff --git a/tests/manual/skybox/main.qml b/tests/manual/skybox/main.qml index 13468906c..d89df316e 100644 --- a/tests/manual/skybox/main.qml +++ b/tests/manual/skybox/main.qml @@ -81,7 +81,6 @@ Entity { // So that the camera is rendered always at the same position as the camera SkyboxEntity { - cameraPosition: basicCamera.position baseName: "qrc:/assets/cubemaps/miramar/miramar" extension: ".webp" } diff --git a/tests/manual/tessellation-modes/tessellatedquadmesh.cpp b/tests/manual/tessellation-modes/tessellatedquadmesh.cpp index e98ee8936..5fd1aedb2 100644 --- a/tests/manual/tessellation-modes/tessellatedquadmesh.cpp +++ b/tests/manual/tessellation-modes/tessellatedquadmesh.cpp @@ -79,8 +79,8 @@ public: m_vertexBuffer->setData(positionBytes); m_positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); - m_positionAttribute->setDataType(Qt3DRender::QAttribute::Float); - m_positionAttribute->setDataSize(3); + m_positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); + m_positionAttribute->setVertexSize(3); m_positionAttribute->setCount(nVerts); m_positionAttribute->setByteStride(3 * sizeof(float)); m_positionAttribute->setBuffer(m_vertexBuffer); |