diff options
author | Juan José Casafranca <juan.casafranca@kdab.com> | 2017-05-17 20:02:28 +0200 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-08-23 13:04:03 +0000 |
commit | a340ae601a0c2688826c1b91533e19f00eda46d1 (patch) | |
tree | f569006bda20bd64e7cf1f52ed69995d6357aa95 | |
parent | 1bc66d7e267537def4fe7031df9021497350f2d9 (diff) |
BlitFramebuffer framegraph node
This node allows to copy the content from one FBO to another or to screen
Task-number: QTBUG-58162
Change-Id: I6016c46d9d538a012c2f641116ed766dd70ad021
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
43 files changed, 1939 insertions, 6 deletions
diff --git a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp index d0b342429..debc755d8 100644 --- a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp +++ b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp @@ -110,6 +110,7 @@ #include <Qt3DRender/qtexture.h> #include <Qt3DRender/qviewport.h> #include <Qt3DRender/qproximityfilter.h> +#include <Qt3DRender/qblitframebuffer.h> #include <QtGui/qwindow.h> @@ -255,6 +256,7 @@ void Qt3DQuick3DRenderPlugin::registerTypes(const char *uri) qmlRegisterType<Qt3DRender::QBufferCapture>(uri, 2, 9, "BufferCapture"); Qt3DRender::Quick::registerExtendedType<Qt3DRender::QMemoryBarrier, Qt3DRender::Render::Quick::Quick3DMemoryBarrier>("QMemoryBarrier", "Qt3D.Render/MemoryBarrier", uri, 2, 9, "MemoryBarrier"); qmlRegisterType<Qt3DRender::QProximityFilter>(uri, 2, 10, "ProximityFilter"); + qmlRegisterType<Qt3DRender::QBlitFramebuffer>(uri, 2, 10, "BlitFramebuffer"); // RenderTarget qmlRegisterType<Qt3DRender::QRenderTargetOutput>(uri, 2, 0, "RenderTargetOutput"); diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index 099c20c25..da4ad0ae0 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -1227,7 +1227,6 @@ void Renderer::downloadGLBuffers() } } - // Happens in RenderThread context when all RenderViewJobs are done // Returns the id of the last bound FBO Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Render::RenderView *> &renderViews) @@ -1379,6 +1378,22 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren if (renderView->isDownloadBuffersEnable()) downloadGLBuffers(); + // Perform BlitFramebuffer operations + if (renderView->hasBlitFramebufferInfo()) { + const auto &blitFramebufferInfo = renderView->blitFrameBufferInfo(); + const QNodeId inputTargetId = blitFramebufferInfo.sourceRenderTargetId; + const QNodeId outputTargetId = blitFramebufferInfo.destinationRenderTargetId; + const QRect inputRect = blitFramebufferInfo.sourceRect; + const QRect outputRect = blitFramebufferInfo.destinationRect; + const QRenderTargetOutput::AttachmentPoint inputAttachmentPoint = blitFramebufferInfo.sourceAttachmentPoint; + const QRenderTargetOutput::AttachmentPoint outputAttachmentPoint = blitFramebufferInfo.destinationAttachmentPoint; + const QBlitFramebuffer::InterpolationMethod interpolationMethod = blitFramebufferInfo.interpolationMethod; + m_graphicsContext->blitFramebuffer(inputTargetId, outputTargetId, inputRect, outputRect, lastBoundFBOId, + inputAttachmentPoint, outputAttachmentPoint, + interpolationMethod); + } + + frameElapsed = timer.elapsed() - frameElapsed; qCDebug(Rendering) << Q_FUNC_INFO << "Submitted Renderview " << i + 1 << "/" << renderViewsCount << "in " << frameElapsed << "ms"; frameElapsed = timer.elapsed(); diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h index 6b1e52a25..3cf99ec81 100644 --- a/src/render/backend/renderer_p.h +++ b/src/render/backend/renderer_p.h @@ -218,6 +218,11 @@ public: void updateTexture(Texture *texture); void cleanupTexture(const Texture *texture); void downloadGLBuffers(); + void blitFramebuffer(Qt3DCore::QNodeId inputRenderTargetId, + Qt3DCore::QNodeId outputRenderTargetId, + QRect inputRect, + QRect outputRect, + GLuint defaultFramebuffer); void prepareCommandsSubmission(const QVector<RenderView *> &renderViews); bool executeCommandsSubmission(const RenderView *rv); diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp index cded6b804..c372f5c20 100644 --- a/src/render/backend/renderview.cpp +++ b/src/render/backend/renderview.cpp @@ -224,6 +224,7 @@ UniformValue RenderView::standardUniformValue(RenderView::StandardUniform standa RenderView::RenderView() : m_isDownloadBuffersEnable(false) + , m_hasBlitFramebufferInfo(false) , m_renderer(nullptr) , m_devicePixelRatio(1.) , m_viewport(QRectF(0.0f, 0.0f, 1.0f, 1.0f)) @@ -1048,6 +1049,26 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, } } +bool RenderView::hasBlitFramebufferInfo() const +{ + return m_hasBlitFramebufferInfo; +} + +void RenderView::setHasBlitFramebufferInfo(bool hasBlitFramebufferInfo) +{ + m_hasBlitFramebufferInfo = hasBlitFramebufferInfo; +} + +BlitFramebufferInfo RenderView::blitFrameBufferInfo() const +{ + return m_blitFrameBufferInfo; +} + +void RenderView::setBlitFrameBufferInfo(const BlitFramebufferInfo &blitFrameBufferInfo) +{ + m_blitFrameBufferInfo = blitFrameBufferInfo; +} + bool RenderView::isDownloadBuffersEnable() const { return m_isDownloadBuffersEnable; diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h index 5579e8e95..c7d242e44 100644 --- a/src/render/backend/renderview_p.h +++ b/src/render/backend/renderview_p.h @@ -64,6 +64,7 @@ #include <Qt3DRender/private/lightsource_p.h> #include <Qt3DRender/private/qmemorybarrier_p.h> #include <Qt3DRender/private/qrendercapture_p.h> +#include <Qt3DRender/private/qblitframebuffer_p.h> #include <Qt3DCore/private/qframeallocator_p.h> @@ -115,6 +116,17 @@ struct Q_AUTOTEST_EXPORT ClearBufferInfo QVector4D clearColor; }; +struct Q_AUTOTEST_EXPORT BlitFramebufferInfo +{ + Qt3DCore::QNodeId sourceRenderTargetId; + Qt3DCore::QNodeId destinationRenderTargetId; + QRect sourceRect; + QRect destinationRect; + Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint; + Qt3DRender::QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint; + QBlitFramebuffer::InterpolationMethod interpolationMethod; +}; + // This class is kind of analogous to RenderBin but I want to avoid trampling // on that until we get this working @@ -256,6 +268,12 @@ public: bool isDownloadBuffersEnable() const; void setIsDownloadBuffersEnable(bool isDownloadBuffersEnable); + BlitFramebufferInfo blitFrameBufferInfo() const; + void setBlitFrameBufferInfo(const BlitFramebufferInfo &blitFrameBufferInfo); + + bool hasBlitFramebufferInfo() const; + void setHasBlitFramebufferInfo(bool hasBlitFramebufferInfo); + private: void setShaderAndUniforms(RenderCommand *command, RenderPass *pass, @@ -270,6 +288,9 @@ private: QRenderCaptureRequest m_renderCaptureRequest; bool m_isDownloadBuffersEnable; + bool m_hasBlitFramebufferInfo; + BlitFramebufferInfo m_blitFrameBufferInfo; + Renderer *m_renderer; NodeManagers *m_manager; QSize m_surfaceSize; diff --git a/src/render/framegraph/blitframebuffer.cpp b/src/render/framegraph/blitframebuffer.cpp new file mode 100644 index 000000000..70401e6d1 --- /dev/null +++ b/src/render/framegraph/blitframebuffer.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 <Qt3DRender/private/qblitframebuffer_p.h> +#include <Qt3DRender/private/blitframebuffer_p.h> +#include <Qt3DCore/qpropertyupdatedchange.h> + +QT_BEGIN_NAMESPACE + +using namespace Qt3DCore; + +namespace Qt3DRender { +namespace Render { + +BlitFramebuffer::BlitFramebuffer() + : FrameGraphNode(FrameGraphNode::BlitFramebuffer) + , m_sourceRenderTargetId(Qt3DCore::QNodeId()) + , m_destinationRenderTargetId(Qt3DCore::QNodeId()) + , m_sourceRect(QRect()) + , m_destinationRect(QRect()) + , m_sourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color0) + , m_destinationAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color0) + , m_interpolationMethod(Qt3DRender::QBlitFramebuffer::Linear) +{ +} + +void BlitFramebuffer::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) +{ + if (e->type() == PropertyUpdated) { + QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e); + if (propertyChange->propertyName() == QByteArrayLiteral("sourceRenderTarget")) { + m_sourceRenderTargetId = propertyChange->value().value<QNodeId>(); + } else if (propertyChange->propertyName() == QByteArrayLiteral("destinationRenderTarget")) { + m_destinationRenderTargetId = propertyChange->value().value<QNodeId>(); + } else if (propertyChange->propertyName() == QByteArrayLiteral("sourceRect")) { + m_sourceRect = propertyChange->value().value<QRect>(); + } else if (propertyChange->propertyName() == QByteArrayLiteral("destinationRect")) { + m_destinationRect = propertyChange->value().value<QRect>(); + } else if (propertyChange->propertyName() == QByteArrayLiteral("sourceAttachmentPoint")) { + m_sourceAttachmentPoint = propertyChange->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>(); + } else if (propertyChange->propertyName() == QByteArrayLiteral("destinationAttachmentPoint")) { + m_destinationAttachmentPoint = propertyChange->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>(); + } else if (propertyChange->propertyName() == QByteArrayLiteral("interpolationMethod")) { + m_interpolationMethod = propertyChange->value().value<QBlitFramebuffer::InterpolationMethod>(); + } + markDirty(AbstractRenderer::AllDirty); + } + FrameGraphNode::sceneChangeEvent(e); +} + +void BlitFramebuffer::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) +{ + FrameGraphNode::initializeFromPeer(change); + const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QBlitFramebufferData> >(change); + const auto &data = typedChange->data; + m_sourceRect = data.m_sourceRect; + m_destinationRect = data.m_destinationRect; + m_sourceRenderTargetId = data.m_sourceRenderTargetId; + m_destinationRenderTargetId = data.m_destinationRenderTargetId; + m_sourceAttachmentPoint = data.m_sourceAttachmentPoint; + m_destinationAttachmentPoint = data.m_destinationAttachmentPoint; + m_interpolationMethod = data.m_interpolationMethod; +} + +Qt3DRender::QRenderTargetOutput::AttachmentPoint BlitFramebuffer::destinationAttachmentPoint() const +{ + return m_destinationAttachmentPoint; +} + +QBlitFramebuffer::InterpolationMethod BlitFramebuffer::interpolationMethod() const +{ + return m_interpolationMethod; +} + +Qt3DRender::QRenderTargetOutput::AttachmentPoint BlitFramebuffer::sourceAttachmentPoint() const +{ + return m_sourceAttachmentPoint; +} + +QRect BlitFramebuffer::destinationRect() const +{ + return m_destinationRect; +} + +QRect BlitFramebuffer::sourceRect() const +{ + return m_sourceRect; +} + +Qt3DCore::QNodeId BlitFramebuffer::destinationRenderTargetId() const +{ + return m_destinationRenderTargetId; +} + +Qt3DCore::QNodeId BlitFramebuffer::sourceRenderTargetId() const +{ + return m_sourceRenderTargetId; +} + +} // namespace Render +} // namespace Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/framegraph/blitframebuffer_p.h b/src/render/framegraph/blitframebuffer_p.h new file mode 100644 index 000000000..64800d0fa --- /dev/null +++ b/src/render/framegraph/blitframebuffer_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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_BLITFRAMEBUFFER_P_H +#define QT3DRENDER_RENDER_BLITFRAMEBUFFER_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/qblitframebuffer_p.h> +#include <Qt3DRender/private/framegraphnode_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +namespace Render { + +class Q_AUTOTEST_EXPORT BlitFramebuffer : public FrameGraphNode +{ +public: + BlitFramebuffer(); + + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; + + Qt3DCore::QNodeId sourceRenderTargetId() const; + + Qt3DCore::QNodeId destinationRenderTargetId() const; + + QRect sourceRect() const; + + QRect destinationRect() const; + + Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint() const; + + Qt3DRender::QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint() const; + + QBlitFramebuffer::InterpolationMethod interpolationMethod() const; + +private: + void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; + + Qt3DCore::QNodeId m_sourceRenderTargetId; + Qt3DCore::QNodeId m_destinationRenderTargetId; + QRect m_sourceRect; + QRect m_destinationRect; + Qt3DRender::QRenderTargetOutput::AttachmentPoint m_sourceAttachmentPoint; + Qt3DRender::QRenderTargetOutput::AttachmentPoint m_destinationAttachmentPoint; + QBlitFramebuffer::InterpolationMethod m_interpolationMethod; +}; + +} // namespace Render + +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_RENDER_BLITFRAMEBUFFER_H diff --git a/src/render/framegraph/framegraph.pri b/src/render/framegraph/framegraph.pri index 8a2569867..9784a193c 100644 --- a/src/render/framegraph/framegraph.pri +++ b/src/render/framegraph/framegraph.pri @@ -55,7 +55,10 @@ HEADERS += \ $$PWD/memorybarrier_p.h \ $$PWD/qproximityfilter.h \ $$PWD/qproximityfilter_p.h \ - $$PWD/proximityfilter_p.h + $$PWD/proximityfilter_p.h \ + $$PWD/qblitframebuffer.h \ + $$PWD/qblitframebuffer_p.h \ + $$PWD/blitframebuffer_p.h SOURCES += \ $$PWD/cameraselectornode.cpp \ @@ -95,4 +98,6 @@ SOURCES += \ $$PWD/qmemorybarrier.cpp \ $$PWD/memorybarrier.cpp \ $$PWD/qproximityfilter.cpp \ - $$PWD/proximityfilter.cpp + $$PWD/proximityfilter.cpp \ + $$PWD/qblitframebuffer.cpp \ + $$PWD/blitframebuffer.cpp diff --git a/src/render/framegraph/framegraphnode_p.h b/src/render/framegraph/framegraphnode_p.h index fb8671ab8..843ad63a0 100644 --- a/src/render/framegraph/framegraphnode_p.h +++ b/src/render/framegraph/framegraphnode_p.h @@ -100,7 +100,8 @@ public: RenderCapture, BufferCapture, MemoryBarrier, - ProximityFilter + ProximityFilter, + BlitFramebuffer }; FrameGraphNodeType nodeType() const { return m_nodeType; } diff --git a/src/render/framegraph/qblitframebuffer.cpp b/src/render/framegraph/qblitframebuffer.cpp new file mode 100644 index 000000000..505bab96c --- /dev/null +++ b/src/render/framegraph/qblitframebuffer.cpp @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 "qblitframebuffer.h" +#include "qblitframebuffer_p.h" + +#include <Qt3DCore/qpropertyupdatedchange.h> +#include <Qt3DRender/qframegraphnodecreatedchange.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +QBlitFramebufferPrivate::QBlitFramebufferPrivate() + : QFrameGraphNodePrivate() + , m_source(nullptr) + , m_destination(nullptr) + , m_sourceRect(QRect()) + , m_destinationRect(QRect()) + , m_sourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0) + , m_destinationAttachmentPoint(Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0) + , m_interpolationMethod(QBlitFramebuffer::Linear) +{ +} + +QBlitFramebuffer::QBlitFramebuffer(QNode *parent) + : QFrameGraphNode(*new QBlitFramebufferPrivate, parent) +{ + +} + +QBlitFramebuffer::QBlitFramebuffer(QBlitFramebufferPrivate &dd, QNode *parent) + : QFrameGraphNode(dd, parent) +{ +} + +QBlitFramebuffer::~QBlitFramebuffer() +{ + +} + +QRenderTarget *QBlitFramebuffer::source() const +{ + Q_D(const QBlitFramebuffer); + return d->m_source; +} + +QRenderTarget *QBlitFramebuffer::destination() const +{ + Q_D(const QBlitFramebuffer); + return d->m_destination; +} + +QRectF QBlitFramebuffer::sourceRect() const +{ + Q_D(const QBlitFramebuffer); + return d->m_sourceRect; +} + +QRectF QBlitFramebuffer::destinationRect() const +{ + Q_D(const QBlitFramebuffer); + return d->m_destinationRect; +} + +Qt3DRender::QRenderTargetOutput::AttachmentPoint QBlitFramebuffer::sourceAttachmentPoint() const +{ + Q_D(const QBlitFramebuffer); + return d->m_sourceAttachmentPoint; +} + +QRenderTargetOutput::AttachmentPoint QBlitFramebuffer::destinationAttachmentPoint() const +{ + Q_D(const QBlitFramebuffer); + return d->m_destinationAttachmentPoint; +} + +QBlitFramebuffer::InterpolationMethod QBlitFramebuffer::interpolationMethod() const +{ + Q_D(const QBlitFramebuffer); + return d->m_interpolationMethod; +} + +void QBlitFramebuffer::setSource(QRenderTarget *source) +{ + Q_D(QBlitFramebuffer); + if (d->m_source != source) { + d->m_source = source; + emit sourceChanged(); + } +} + +void QBlitFramebuffer::setDestination(QRenderTarget *destination) +{ + Q_D(QBlitFramebuffer); + if (d->m_destination != destination) { + d->m_destination = destination; + emit destinationChanged(); + } +} + +void QBlitFramebuffer::setSourceRect(const QRectF &inputRect) +{ + Q_D(QBlitFramebuffer); + if (d->m_sourceRect != inputRect) { + d->m_sourceRect = inputRect.toRect(); + emit sourceRectChanged(); + } +} + +void QBlitFramebuffer::setDestinationRect(const QRectF &outputRect) +{ + Q_D(QBlitFramebuffer); + if (d->m_destinationRect != outputRect) { + d->m_destinationRect = outputRect.toRect(); + emit destinationRectChanged(); + } +} + +void QBlitFramebuffer::setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint) +{ + Q_D(QBlitFramebuffer); + if (d->m_sourceAttachmentPoint != sourceAttachmentPoint) { + d->m_sourceAttachmentPoint = sourceAttachmentPoint; + emit sourceAttachmentPointChanged(); + } +} + +void QBlitFramebuffer::setDestinationAttachmentPoint(QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint) +{ + Q_D(QBlitFramebuffer); + if (d->m_destinationAttachmentPoint != destinationAttachmentPoint) { + d->m_destinationAttachmentPoint = destinationAttachmentPoint; + emit destinationAttachmentPointChanged(); + } +} + +void QBlitFramebuffer::setInterpolationMethod(QBlitFramebuffer::InterpolationMethod interpolationMethod) +{ + Q_D(QBlitFramebuffer); + if (d->m_interpolationMethod != interpolationMethod) { + d->m_interpolationMethod = interpolationMethod; + emit interpolationMethodChanged(); + } +} + +Qt3DCore::QNodeCreatedChangeBasePtr QBlitFramebuffer::createNodeCreationChange() const +{ + auto creationChange = QFrameGraphNodeCreatedChangePtr<QBlitFramebufferData>::create(this); + auto &data = creationChange->data; + Q_D(const QBlitFramebuffer); + data.m_sourceRect = d->m_sourceRect; + data.m_destinationRect = d->m_destinationRect; + data.m_sourceRenderTargetId = Qt3DCore::qIdForNode(d->m_source); + data.m_destinationRenderTargetId = Qt3DCore::qIdForNode(d->m_destination); + data.m_sourceAttachmentPoint = d->m_sourceAttachmentPoint; + data.m_destinationAttachmentPoint = d->m_destinationAttachmentPoint; + data.m_interpolationMethod = d->m_interpolationMethod; + + return creationChange; +} + +} // namespace Qt3DRender + +QT_END_NAMESPACE diff --git a/src/render/framegraph/qblitframebuffer.h b/src/render/framegraph/qblitframebuffer.h new file mode 100644 index 000000000..75ce4c23a --- /dev/null +++ b/src/render/framegraph/qblitframebuffer.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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_QBLITFRAMEBUFFER_H +#define QT3DRENDER_QBLITFRAMEBUFFER_H + +#include <Qt3DRender/qframegraphnode.h> +#include <Qt3DRender/qrendertargetoutput.h> +#include <QRect> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QBlitFramebufferPrivate; +class QRenderTarget; + +class QT3DRENDERSHARED_EXPORT QBlitFramebuffer : public QFrameGraphNode +{ + Q_OBJECT + Q_PROPERTY(Qt3DRender::QRenderTarget *source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(Qt3DRender::QRenderTarget *destination READ destination WRITE setDestination NOTIFY destinationChanged) + Q_PROPERTY(QRectF sourceRect READ sourceRect WRITE setSourceRect NOTIFY sourceRectChanged) + Q_PROPERTY(QRectF destinationRect READ destinationRect WRITE setDestinationRect NOTIFY destinationRectChanged) + Q_PROPERTY(Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint READ sourceAttachmentPoint WRITE setSourceAttachmentPoint NOTIFY sourceAttachmentPointChanged) + Q_PROPERTY(Qt3DRender::QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint READ destinationAttachmentPoint WRITE setDestinationAttachmentPoint NOTIFY destinationAttachmentPointChanged) + Q_PROPERTY(InterpolationMethod interpolationMethod READ interpolationMethod WRITE setInterpolationMethod NOTIFY interpolationMethodChanged) +public: + enum InterpolationMethod { + Nearest = 0, + Linear, + }; + Q_ENUM(InterpolationMethod) // LCOV_EXCL_LINE + + explicit QBlitFramebuffer(Qt3DCore::QNode *parent = nullptr); + ~QBlitFramebuffer(); + + QRenderTarget *source() const; + QRenderTarget *destination() const; + QRectF sourceRect() const; + QRectF destinationRect() const; + Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint() const; + Qt3DRender::QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint() const; + InterpolationMethod interpolationMethod() const; + + void setSource(QRenderTarget *source); + void setDestination(QRenderTarget *destination); + void setSourceRect(const QRectF &sourceRect); + void setDestinationRect(const QRectF &destinationRect); + void setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint); + void setDestinationAttachmentPoint(Qt3DRender::QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint); + void setInterpolationMethod(InterpolationMethod interpolationMethod); + +Q_SIGNALS: + void sourceChanged(); + void destinationChanged(); + void sourceRectChanged(); + void destinationRectChanged(); + void sourceAttachmentPointChanged(); + void destinationAttachmentPointChanged(); + void interpolationMethodChanged(); + +protected: + explicit QBlitFramebuffer(QBlitFramebufferPrivate &dd, Qt3DCore::QNode *parent = nullptr); + +private: + Q_DECLARE_PRIVATE(QBlitFramebuffer) + Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const Q_DECL_OVERRIDE; +}; + +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_QBLITFRAMEBUFFER_H diff --git a/src/render/framegraph/qblitframebuffer_p.h b/src/render/framegraph/qblitframebuffer_p.h new file mode 100644 index 000000000..8b5dc2165 --- /dev/null +++ b/src/render/framegraph/qblitframebuffer_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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_QBLITFRAMEBUFFER_P_H +#define QT3DRENDER_QBLITFRAMEBUFFER_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 <private/qframegraphnode_p.h> +#include <Qt3DRender/qblitframebuffer.h> + +#include <Qt3DRender/QRenderTarget> +#include <QRect> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QBlitFramebufferPrivate : public QFrameGraphNodePrivate +{ +public: + QBlitFramebufferPrivate(); + + QRenderTarget *m_source; + QRenderTarget *m_destination; + QRect m_sourceRect; + QRect m_destinationRect; + Qt3DRender::QRenderTargetOutput::AttachmentPoint m_sourceAttachmentPoint; + Qt3DRender::QRenderTargetOutput::AttachmentPoint m_destinationAttachmentPoint; + QBlitFramebuffer::InterpolationMethod m_interpolationMethod; + + Q_DECLARE_PUBLIC(QBlitFramebuffer) +}; + +struct QBlitFramebufferData +{ + Qt3DCore::QNodeId m_sourceRenderTargetId; + Qt3DCore::QNodeId m_destinationRenderTargetId; + QRect m_sourceRect; + QRect m_destinationRect; + Qt3DRender::QRenderTargetOutput::AttachmentPoint m_sourceAttachmentPoint; + Qt3DRender::QRenderTargetOutput::AttachmentPoint m_destinationAttachmentPoint; + QBlitFramebuffer::InterpolationMethod m_interpolationMethod; +}; + +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_QBLITFRAMEBUFFER_P_H diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 532e55d0f..10ce15108 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -85,6 +85,7 @@ #include <Qt3DRender/qmemorybarrier.h> #include <Qt3DRender/qproximityfilter.h> #include <Qt3DRender/qshaderprogrambuilder.h> +#include <Qt3DRender/qblitframebuffer.h> #include <Qt3DCore/qarmature.h> #include <Qt3DCore/qjoint.h> #include <Qt3DCore/qskeletonloader.h> @@ -140,6 +141,7 @@ #include <Qt3DRender/private/offscreensurfacehelper_p.h> #include <Qt3DRender/private/memorybarrier_p.h> #include <Qt3DRender/private/shaderbuilder_p.h> +#include <Qt3DRender/private/blitframebuffer_p.h> #include <Qt3DRender/private/armature_p.h> #include <Qt3DRender/private/skeleton_p.h> #include <Qt3DRender/private/joint_p.h> @@ -283,6 +285,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType<QBufferCapture>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::BufferCapture, QBufferCapture> >::create(m_renderer)); q->registerBackendType<QMemoryBarrier>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::MemoryBarrier, QMemoryBarrier> >::create(m_renderer)); q->registerBackendType<QProximityFilter>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ProximityFilter, QProximityFilter> >::create(m_renderer)); + q->registerBackendType<QBlitFramebuffer>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::BlitFramebuffer, QBlitFramebuffer> >::create(m_renderer)); // Picking q->registerBackendType<QObjectPicker>(QSharedPointer<Render::NodeFunctor<Render::ObjectPicker, Render::ObjectPickerManager> >::create(m_renderer)); diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp index f09336243..59b2155d1 100644 --- a/src/render/graphicshelpers/graphicscontext.cpp +++ b/src/render/graphicshelpers/graphicscontext.cpp @@ -1265,6 +1265,16 @@ void GraphicsContext::setParameters(ShaderParameterPack ¶meterPack) } } +void GraphicsContext::readBuffer(GLenum mode) +{ + m_glHelper->readBuffer(mode); +} + +void GraphicsContext::drawBuffer(GLenum mode) +{ + m_glHelper->drawBuffer(mode); +} + void GraphicsContext::enableAttribute(const VAOVertexAttribute &attr) { // Bind buffer within the current VAO @@ -1511,6 +1521,58 @@ bool GraphicsContext::hasGLBufferForBuffer(Buffer *buffer) return (it != m_renderBufferHash.end()); } +void GraphicsContext::blitFramebuffer(Qt3DCore::QNodeId inputRenderTarget, + Qt3DCore::QNodeId outputRenderTarget, + QRect inputRect, QRect outputRect, + uint defaultFboId, + QRenderTargetOutput::AttachmentPoint inputAttachmentPoint, + QRenderTargetOutput::AttachmentPoint outputAttachmentPoint, + QBlitFramebuffer::InterpolationMethod interpolationMethod) +{ + //Find the context side name for the render targets + const GLuint inputFboId = m_renderTargets[inputRenderTarget]; + GLuint outputFboId = defaultFboId; + bool outputBufferIsDefault = true; + if (!outputRenderTarget.isNull() && m_renderTargets.contains(outputRenderTarget)) { + outputFboId = m_renderTargets[outputRenderTarget]; + outputBufferIsDefault = false; + } + + const GLint srcX0 = inputRect.left(); + const GLint srcY0 = inputRect.top(); + const GLint srcX1 = srcX0 + inputRect.width(); + const GLint srcY1 = srcY0 + inputRect.height(); + + const GLint dstX0 = outputRect.left(); + const GLint dstY0 = outputRect.top(); + const GLint dstX1 = dstX0 + outputRect.width(); + const GLint dstY1 = dstY0 + outputRect.height(); + + //Get the last bounded framebuffers + const GLuint lastDrawFboId = boundFrameBufferObject(); + + // Activate input framebuffer for reading + bindFramebuffer(inputFboId, GraphicsHelperInterface::FBORead); + + // Activate output framebuffer for writing + bindFramebuffer(outputFboId, GraphicsHelperInterface::FBODraw); + + //Bind texture + readBuffer(GL_COLOR_ATTACHMENT0 + inputAttachmentPoint); + + if (!outputBufferIsDefault) + drawBuffer(GL_COLOR_ATTACHMENT0 + outputAttachmentPoint); + + // Blit framebuffer + const GLenum mode = interpolationMethod ? GL_NEAREST : GL_LINEAR; + m_glHelper->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + GL_COLOR_BUFFER_BIT, mode); + + // Reset draw buffer + bindFramebuffer(lastDrawFboId, GraphicsHelperInterface::FBOReadAndDraw); +} + void GraphicsContext::memoryBarrier(QMemoryBarrier::Operations barriers) { m_glHelper->memoryBarrier(barriers); diff --git a/src/render/graphicshelpers/graphicscontext_p.h b/src/render/graphicshelpers/graphicscontext_p.h index fcb17ade7..21ec90c58 100644 --- a/src/render/graphicshelpers/graphicscontext_p.h +++ b/src/render/graphicshelpers/graphicscontext_p.h @@ -71,6 +71,7 @@ #include <Qt3DRender/private/shadercache_p.h> #include <Qt3DRender/private/uniform_p.h> #include <Qt3DRender/private/graphicshelperinterface_p.h> +#include <Qt3DRender/private/qblitframebuffer_p.h> #include <qmath.h> QT_BEGIN_NAMESPACE @@ -167,10 +168,20 @@ public: void releaseBuffer(Qt3DCore::QNodeId bufferId); bool hasGLBufferForBuffer(Buffer *buffer); + void blitFramebuffer(Qt3DCore::QNodeId outputRenderTarget, Qt3DCore::QNodeId inputRenderTarget, + QRect inputRect, + QRect outputRect, uint defaultFboId, + QRenderTargetOutput::AttachmentPoint inputAttachmentPoint, + QRenderTargetOutput::AttachmentPoint outputAttachmentPoint, + QBlitFramebuffer::InterpolationMethod interpolationMethod); + void memoryBarrier(QMemoryBarrier::Operations barriers); void setParameters(ShaderParameterPack ¶meterPack); + void readBuffer(GLenum mode); + void drawBuffer(GLenum mode); + /** * @brief glBufferFor - given a client-side (CPU) buffer, provide the * context-specific object. Initial call will create the buffer. diff --git a/src/render/graphicshelpers/graphicshelperes2.cpp b/src/render/graphicshelpers/graphicshelperes2.cpp index a72e6159c..a22d8752a 100644 --- a/src/render/graphicshelpers/graphicshelperes2.cpp +++ b/src/render/graphicshelpers/graphicshelperes2.cpp @@ -283,6 +283,18 @@ void GraphicsHelperES2::vertexAttributePointer(GLenum shaderDataType, } } +void GraphicsHelperES2::readBuffer(GLenum mode) +{ + Q_UNUSED(mode) + qWarning() << "glReadBuffer not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)"; +} + +void GraphicsHelperES2::drawBuffer(GLenum mode) +{ + Q_UNUSED(mode); + qWarning() << "glDrawBuffer is not supported with OpenGL ES 2"; +} + void GraphicsHelperES2::blendEquation(GLenum mode) { m_funcs->glBlendEquation(mode); diff --git a/src/render/graphicshelpers/graphicshelperes2_p.h b/src/render/graphicshelpers/graphicshelperes2_p.h index b93268188..eade3514a 100644 --- a/src/render/graphicshelpers/graphicshelperes2_p.h +++ b/src/render/graphicshelpers/graphicshelperes2_p.h @@ -129,6 +129,8 @@ public: void useProgram(GLuint programId) Q_DECL_OVERRIDE; void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE; void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) Q_DECL_OVERRIDE; + void readBuffer(GLenum mode) Q_DECL_OVERRIDE; + void drawBuffer(GLenum mode) 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; diff --git a/src/render/graphicshelpers/graphicshelperes3.cpp b/src/render/graphicshelpers/graphicshelperes3.cpp index 0ba789c92..813c627b8 100644 --- a/src/render/graphicshelpers/graphicshelperes3.cpp +++ b/src/render/graphicshelpers/graphicshelperes3.cpp @@ -226,6 +226,17 @@ void GraphicsHelperES3::vertexAttributePointer(GLenum shaderDataType, } } +void GraphicsHelperES3::readBuffer(GLenum mode) +{ + m_extraFuncs->glReadBuffer(mode); +} + +void GraphicsHelperES3::drawBuffer(GLenum mode) +{ + Q_UNUSED(mode); + qWarning() << "glDrawBuffer is not supported with OpenGL ES 3"; +} + void GraphicsHelperES3::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) { GLenum attr = GL_COLOR_ATTACHMENT0; diff --git a/src/render/graphicshelpers/graphicshelperes3_p.h b/src/render/graphicshelpers/graphicshelperes3_p.h index 7a460895f..84a906b49 100644 --- a/src/render/graphicshelpers/graphicshelperes3_p.h +++ b/src/render/graphicshelpers/graphicshelperes3_p.h @@ -73,6 +73,8 @@ public: void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) Q_DECL_OVERRIDE; void drawBuffers(GLsizei n, const int *bufs) Q_DECL_OVERRIDE; void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) Q_DECL_OVERRIDE; + virtual void readBuffer(GLenum mode) Q_DECL_OVERRIDE; + virtual void drawBuffer(GLenum mode) Q_DECL_OVERRIDE; void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) Q_DECL_OVERRIDE; char *mapBuffer(GLenum target, GLsizeiptr size) Q_DECL_OVERRIDE; QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) Q_DECL_OVERRIDE; diff --git a/src/render/graphicshelpers/graphicshelpergl2.cpp b/src/render/graphicshelpers/graphicshelpergl2.cpp index 9abc392ee..5444ce749 100644 --- a/src/render/graphicshelpers/graphicshelpergl2.cpp +++ b/src/render/graphicshelpers/graphicshelpergl2.cpp @@ -258,6 +258,16 @@ void GraphicsHelperGL2::vertexAttributePointer(GLenum shaderDataType, } } +void GraphicsHelperGL2::readBuffer(GLenum mode) +{ + m_funcs->glReadBuffer(mode); +} + +void GraphicsHelperGL2::drawBuffer(GLenum mode) +{ + m_funcs->glDrawBuffer(mode); +} + void GraphicsHelperGL2::blendEquation(GLenum mode) { m_funcs->glBlendEquation(mode); diff --git a/src/render/graphicshelpers/graphicshelpergl2_p.h b/src/render/graphicshelpers/graphicshelpergl2_p.h index 3a15af260..1a7af544c 100644 --- a/src/render/graphicshelpers/graphicshelpergl2_p.h +++ b/src/render/graphicshelpers/graphicshelpergl2_p.h @@ -129,6 +129,8 @@ public: void useProgram(GLuint programId) Q_DECL_OVERRIDE; void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE; void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) Q_DECL_OVERRIDE; + void readBuffer(GLenum mode) Q_DECL_OVERRIDE; + void drawBuffer(GLenum mode) 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; diff --git a/src/render/graphicshelpers/graphicshelpergl3_2.cpp b/src/render/graphicshelpers/graphicshelpergl3_2.cpp index 54c46babe..289ae18be 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_2.cpp +++ b/src/render/graphicshelpers/graphicshelpergl3_2.cpp @@ -321,6 +321,16 @@ void GraphicsHelperGL3_2::vertexAttributePointer(GLenum shaderDataType, } } +void GraphicsHelperGL3_2::readBuffer(GLenum mode) +{ + m_funcs->glReadBuffer(mode); +} + +void GraphicsHelperGL3_2::drawBuffer(GLenum mode) +{ + m_funcs->glDrawBuffer(mode); +} + void GraphicsHelperGL3_2::blendEquation(GLenum mode) { m_funcs->glBlendEquation(mode); diff --git a/src/render/graphicshelpers/graphicshelpergl3_2_p.h b/src/render/graphicshelpers/graphicshelpergl3_2_p.h index bebe14ade..adb2942aa 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_2_p.h +++ b/src/render/graphicshelpers/graphicshelpergl3_2_p.h @@ -131,6 +131,8 @@ public: void useProgram(GLuint programId) Q_DECL_OVERRIDE; void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE; void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) Q_DECL_OVERRIDE; + void readBuffer(GLenum mode) Q_DECL_OVERRIDE; + void drawBuffer(GLenum mode) 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; diff --git a/src/render/graphicshelpers/graphicshelpergl3_3.cpp b/src/render/graphicshelpers/graphicshelpergl3_3.cpp index e1ae23e6d..40f8076bb 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_3.cpp +++ b/src/render/graphicshelpers/graphicshelpergl3_3.cpp @@ -308,6 +308,16 @@ void GraphicsHelperGL3_3::vertexAttributePointer(GLenum shaderDataType, } } +void GraphicsHelperGL3_3::readBuffer(GLenum mode) +{ + m_funcs->glReadBuffer(mode); +} + +void GraphicsHelperGL3_3::drawBuffer(GLenum mode) +{ + m_funcs->glDrawBuffer(mode); +} + void GraphicsHelperGL3_3::blendEquation(GLenum mode) { m_funcs->glBlendEquation(mode); diff --git a/src/render/graphicshelpers/graphicshelpergl3_3_p.h b/src/render/graphicshelpers/graphicshelpergl3_3_p.h index e890fd1a4..d36386a73 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_3_p.h +++ b/src/render/graphicshelpers/graphicshelpergl3_3_p.h @@ -131,6 +131,8 @@ public: void useProgram(GLuint programId) Q_DECL_OVERRIDE; void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE; void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) Q_DECL_OVERRIDE; + void readBuffer(GLenum mode) Q_DECL_OVERRIDE; + void drawBuffer(GLenum mode) 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; diff --git a/src/render/graphicshelpers/graphicshelpergl4.cpp b/src/render/graphicshelpers/graphicshelpergl4.cpp index badbaf67d..284970873 100644 --- a/src/render/graphicshelpers/graphicshelpergl4.cpp +++ b/src/render/graphicshelpers/graphicshelpergl4.cpp @@ -387,6 +387,16 @@ void GraphicsHelperGL4::vertexAttributePointer(GLenum shaderDataType, } } +void GraphicsHelperGL4::readBuffer(GLenum mode) +{ + m_funcs->glReadBuffer(mode); +} + +void GraphicsHelperGL4::drawBuffer(GLenum mode) +{ + m_funcs->glDrawBuffer(mode); +} + void GraphicsHelperGL4::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) { m_funcs->glUniform1fv(location, count, values); diff --git a/src/render/graphicshelpers/graphicshelpergl4_p.h b/src/render/graphicshelpers/graphicshelpergl4_p.h index 1effbc9b9..b38d0876c 100644 --- a/src/render/graphicshelpers/graphicshelpergl4_p.h +++ b/src/render/graphicshelpers/graphicshelpergl4_p.h @@ -129,6 +129,8 @@ public: void useProgram(GLuint programId) Q_DECL_OVERRIDE; void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE; void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) Q_DECL_OVERRIDE; + void readBuffer(GLenum mode) Q_DECL_OVERRIDE; + void drawBuffer(GLenum mode) 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; diff --git a/src/render/graphicshelpers/graphicshelperinterface_p.h b/src/render/graphicshelpers/graphicshelperinterface_p.h index 9ded1835e..e41325cb7 100644 --- a/src/render/graphicshelpers/graphicshelperinterface_p.h +++ b/src/render/graphicshelpers/graphicshelperinterface_p.h @@ -152,6 +152,8 @@ public: virtual void useProgram(GLuint programId) = 0; virtual void vertexAttribDivisor(GLuint index, GLuint divisor) = 0; virtual void vertexAttributePointer(GLenum shaderDataType, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) = 0; + virtual void readBuffer(GLenum mode) = 0; + virtual void drawBuffer(GLenum mode) = 0; virtual void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) = 0; virtual void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) = 0; diff --git a/src/render/jobs/renderviewjobutils.cpp b/src/render/jobs/renderviewjobutils.cpp index b35bfdbc6..cf23e572f 100644 --- a/src/render/jobs/renderviewjobutils.cpp +++ b/src/render/jobs/renderviewjobutils.cpp @@ -67,6 +67,7 @@ #include <Qt3DRender/private/stringtoint_p.h> #include <Qt3DRender/private/techniquemanager_p.h> #include <Qt3DRender/private/memorybarrier_p.h> +#include <Qt3DRender/private/blitframebuffer_p.h> QT_BEGIN_NAMESPACE @@ -255,6 +256,22 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN break; } + case FrameGraphNode::BlitFramebuffer: { + const Render::BlitFramebuffer *blitFramebufferNode = + static_cast<const Render::BlitFramebuffer *>(node); + rv->setHasBlitFramebufferInfo(true); + BlitFramebufferInfo bfbInfo; + bfbInfo.sourceRenderTargetId = blitFramebufferNode->sourceRenderTargetId(); + bfbInfo.destinationRenderTargetId = blitFramebufferNode->destinationRenderTargetId(); + bfbInfo.sourceRect = blitFramebufferNode->sourceRect(); + bfbInfo.destinationRect = blitFramebufferNode->destinationRect(); + bfbInfo.sourceAttachmentPoint = blitFramebufferNode->sourceAttachmentPoint(); + bfbInfo.destinationAttachmentPoint = blitFramebufferNode->destinationAttachmentPoint(); + bfbInfo.interpolationMethod = blitFramebufferNode->interpolationMethod(); + rv->setBlitFrameBufferInfo(bfbInfo); + break; + } + default: // Should never get here qCWarning(Backend) << "Unhandled FrameGraphNode type"; diff --git a/tests/auto/render/blitframebuffer/blitframebuffer.pro b/tests/auto/render/blitframebuffer/blitframebuffer.pro new file mode 100644 index 000000000..39531ae9a --- /dev/null +++ b/tests/auto/render/blitframebuffer/blitframebuffer.pro @@ -0,0 +1,12 @@ +TEMPLATE = app + +TARGET = tst_blitframebuffer + +QT += 3dcore 3dcore-private 3drender 3drender-private testlib + +CONFIG += testcase + +SOURCES += tst_blitframebuffer.cpp + +include(../../core/common/common.pri) +include(../commons/commons.pri) diff --git a/tests/auto/render/blitframebuffer/tst_blitframebuffer.cpp b/tests/auto/render/blitframebuffer/tst_blitframebuffer.cpp new file mode 100644 index 000000000..6c70b0e95 --- /dev/null +++ b/tests/auto/render/blitframebuffer/tst_blitframebuffer.cpp @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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/qblitframebuffer.h> +#include <Qt3DRender/private/qblitframebuffer_p.h> +#include <Qt3DRender/private/blitframebuffer_p.h> +#include <Qt3DCore/qpropertyupdatedchange.h> +#include "qbackendnodetester.h" +#include "testrenderer.h" + +class tst_BlitFramebuffer : public Qt3DCore::QBackendNodeTester +{ + Q_OBJECT + +private Q_SLOTS: + + void checkInitialState() + { + // GIVEN + Qt3DRender::Render::BlitFramebuffer backendBlitFramebuffer; + + // THEN + QCOMPARE(backendBlitFramebuffer.nodeType(), Qt3DRender::Render::FrameGraphNode::BlitFramebuffer); + QCOMPARE(backendBlitFramebuffer.isEnabled(), false); + QVERIFY(backendBlitFramebuffer.peerId().isNull()); + QVERIFY(backendBlitFramebuffer.sourceRenderTargetId().isNull()); + QVERIFY(backendBlitFramebuffer.destinationRenderTargetId().isNull()); + QCOMPARE(backendBlitFramebuffer.sourceRect(), QRect()); + QCOMPARE(backendBlitFramebuffer.destinationRect(), QRect()); + QCOMPARE(backendBlitFramebuffer.sourceAttachmentPoint(), Qt3DRender::QRenderTargetOutput::Color0); + QCOMPARE(backendBlitFramebuffer.destinationAttachmentPoint(), Qt3DRender::QRenderTargetOutput::Color0); + QCOMPARE(backendBlitFramebuffer.interpolationMethod(), Qt3DRender::QBlitFramebuffer::Linear); + } + + void checkInitializeFromPeer() + { + // GIVEN + Qt3DRender::QRenderTarget sourceTarget; + Qt3DRender::QRenderTarget destinationTarget; + Qt3DRender::QBlitFramebuffer blitFramebuffer; + blitFramebuffer.setSource(&sourceTarget); + blitFramebuffer.setDestination(&destinationTarget); + blitFramebuffer.setSourceRect(QRect(0,0,1,1)); + blitFramebuffer.setDestinationRect(QRect(0,0,1,1)); + blitFramebuffer.setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1); + blitFramebuffer.setDestinationAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1); + blitFramebuffer.setInterpolationMethod(Qt3DRender::QBlitFramebuffer::Nearest); + + { + // WHEN + Qt3DRender::Render::BlitFramebuffer backendBlitFramebuffer; + simulateInitialization(&blitFramebuffer, &backendBlitFramebuffer); + + // THEN + QCOMPARE(backendBlitFramebuffer.isEnabled(), true); + QCOMPARE(backendBlitFramebuffer.peerId(), blitFramebuffer.id()); + QCOMPARE(backendBlitFramebuffer.sourceRenderTargetId(), sourceTarget.id()); + QCOMPARE(backendBlitFramebuffer.destinationRenderTargetId(), destinationTarget.id()); + QCOMPARE(backendBlitFramebuffer.sourceRect(), QRect(0,0,1,1)); + QCOMPARE(backendBlitFramebuffer.destinationRect(), QRect(0,0,1,1)); + QCOMPARE(backendBlitFramebuffer.sourceAttachmentPoint(), Qt3DRender::QRenderTargetOutput::Color1); + QCOMPARE(backendBlitFramebuffer.destinationAttachmentPoint(), Qt3DRender::QRenderTargetOutput::Color1); + QCOMPARE(backendBlitFramebuffer.interpolationMethod(), Qt3DRender::QBlitFramebuffer::Nearest); + } + { + // WHEN + Qt3DRender::Render::BlitFramebuffer backendBlitFramebuffer; + blitFramebuffer.setEnabled(false); + simulateInitialization(&blitFramebuffer, &backendBlitFramebuffer); + + // THEN + QCOMPARE(backendBlitFramebuffer.peerId(), blitFramebuffer.id()); + QCOMPARE(backendBlitFramebuffer.isEnabled(), false); + } + } + + void checkSceneChangeEvents() + { + // GIVEN + Qt3DRender::Render::BlitFramebuffer backendBlitFramebuffer; + TestRenderer renderer; + backendBlitFramebuffer.setRenderer(&renderer); + + { + // WHEN + const bool newValue = false; + const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); + change->setPropertyName("enabled"); + change->setValue(newValue); + backendBlitFramebuffer.sceneChangeEvent(change); + + // THEN + QCOMPARE(backendBlitFramebuffer.isEnabled(), newValue); + } + { + // WHEN + const Qt3DRender::QRenderTarget sourceRenderTarget; + const Qt3DCore::QNodeId newValue = sourceRenderTarget.id(); + const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); + change->setPropertyName("sourceRenderTarget"); + change->setValue(QVariant::fromValue(newValue)); + backendBlitFramebuffer.sceneChangeEvent(change); + + // THEN + QCOMPARE(backendBlitFramebuffer.sourceRenderTargetId(), newValue); + } + { + // WHEN + const Qt3DRender::QRenderTarget destinationRenderTarget; + const Qt3DCore::QNodeId newValue = destinationRenderTarget.id(); + const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); + change->setPropertyName("destinationRenderTarget"); + change->setValue(QVariant::fromValue(newValue)); + backendBlitFramebuffer.sceneChangeEvent(change); + + // THEN + QCOMPARE(backendBlitFramebuffer.destinationRenderTargetId(), newValue); + } + { + // WHEN + const auto newValue = QRect(0,0,1,1); + const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); + change->setPropertyName("sourceRect"); + change->setValue(QVariant::fromValue(newValue)); + backendBlitFramebuffer.sceneChangeEvent(change); + + // THEN + QCOMPARE(backendBlitFramebuffer.sourceRect(), newValue); + } + { + // WHEN + const auto newValue = QRect(0,0,1,1); + const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); + change->setPropertyName("destinationRect"); + change->setValue(QVariant::fromValue(newValue)); + backendBlitFramebuffer.sceneChangeEvent(change); + + // THEN + QCOMPARE(backendBlitFramebuffer.destinationRect(), newValue); + } + { + // WHEN + const auto newValue = Qt3DRender::QRenderTargetOutput::Color1; + const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); + change->setPropertyName("sourceAttachmentPoint"); + change->setValue(QVariant::fromValue(newValue)); + backendBlitFramebuffer.sceneChangeEvent(change); + + // THEN + QCOMPARE(backendBlitFramebuffer.sourceAttachmentPoint(), newValue); + } + { + // WHEN + const auto newValue = Qt3DRender::QRenderTargetOutput::Color1; + const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); + change->setPropertyName("destinationAttachmentPoint"); + change->setValue(QVariant::fromValue(newValue)); + backendBlitFramebuffer.sceneChangeEvent(change); + + // THEN + QCOMPARE(backendBlitFramebuffer.destinationAttachmentPoint(), newValue); + } + } + +}; + +QTEST_MAIN(tst_BlitFramebuffer) + +#include "tst_blitframebuffer.moc" diff --git a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp index c6719f3bd..292bcfba3 100644 --- a/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp +++ b/tests/auto/render/graphicshelpergl2/tst_graphicshelpergl2.cpp @@ -1506,6 +1506,18 @@ private Q_SLOTS: QCOMPARE(computed, expected); } + void drawBuffer() + { + QSKIP("Initialization failed, OpenGL 2.0 functions not supported"); + // Not supported by GL2 + } + + void readBuffer() + { + QSKIP("Initialization failed, OpenGL 2.0 functions not supported"); + // Not supported by GL2 + } + private: QScopedPointer<QWindow> m_window; QOpenGLContext m_glContext; diff --git a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp index 86a26cfdf..22fdb36a3 100644 --- a/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp +++ b/tests/auto/render/graphicshelpergl3_2/tst_graphicshelpergl3_2.cpp @@ -2115,6 +2115,42 @@ private Q_SLOTS: QCOMPARE(computed, expected); } + void drawBuffer() + { + if (!m_initializationSuccessful) + QSKIP("Initialization failed, OpenGL 3.2 Core functions not supported"); + + m_func->glGetError(); + + // WHEN + m_glHelper.drawBuffer(GL_FRONT); + const GLint error = m_func->glGetError(); + QVERIFY(error == 0); + + // THEN + GLint p; + m_func->glGetIntegerv(GL_DRAW_BUFFER, &p); + QCOMPARE((GLenum)p, GL_FRONT); + } + + void readBuffer() + { + if (!m_initializationSuccessful) + QSKIP("Initialization failed, OpenGL 3.2 Core functions not supported"); + + m_func->glGetError(); + + // WHEN + m_glHelper.readBuffer(GL_FRONT); + + // THEN + const GLint error = m_func->glGetError(); + QVERIFY(error == 0); + GLint p; + m_func->glGetIntegerv(GL_READ_BUFFER, &p); + QCOMPARE((GLenum)p, GL_FRONT); + } + private: QScopedPointer<QWindow> m_window; QOpenGLContext m_glContext; diff --git a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp index 48121ad36..06a3c41cd 100644 --- a/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp +++ b/tests/auto/render/graphicshelpergl3_3/tst_graphicshelpergl3_3.cpp @@ -2215,6 +2215,42 @@ private Q_SLOTS: QCOMPARE(computed, expected); } + void drawBuffer() + { + if (!m_initializationSuccessful) + QSKIP("Initialization failed, OpenGL 3.3 Core functions not supported"); + + m_func->glGetError(); + + // WHEN + m_glHelper.drawBuffer(GL_FRONT); + const GLint error = m_func->glGetError(); + QVERIFY(error == 0); + + // THEN + GLint p; + m_func->glGetIntegerv(GL_DRAW_BUFFER, &p); + QCOMPARE(p, GL_FRONT); + } + + void readBuffer() + { + if (!m_initializationSuccessful) + QSKIP("Initialization failed, OpenGL 3.3 Core functions not supported"); + + m_func->glGetError(); + + // WHEN + m_glHelper.readBuffer(GL_FRONT); + + // THEN + const GLint error = m_func->glGetError(); + QVERIFY(error == 0); + GLint p; + m_func->glGetIntegerv(GL_READ_BUFFER, &p); + QCOMPARE(p, GL_FRONT); + } + private: QScopedPointer<QWindow> m_window; QOpenGLContext m_glContext; diff --git a/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp b/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp index 46897ab49..5a96cf116 100644 --- a/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp +++ b/tests/auto/render/graphicshelpergl4/tst_graphicshelpergl4.cpp @@ -2294,6 +2294,42 @@ private Q_SLOTS: QCOMPARE(computed, expected); } + void drawBuffer() + { + if (!m_initializationSuccessful) + QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); + + m_func->glGetError(); + + // WHEN + m_glHelper.drawBuffer(GL_FRONT); + const GLint error = m_func->glGetError(); + QVERIFY(error == 0); + + // THEN + GLint p; + m_func->glGetIntegerv(GL_DRAW_BUFFER, &p); + QCOMPARE(p, GL_FRONT); + } + + void readBuffer() + { + if (!m_initializationSuccessful) + QSKIP("Initialization failed, OpenGL 4.3 Core functions not supported"); + + m_func->glGetError(); + + // WHEN + m_glHelper.readBuffer(GL_FRONT); + + // THEN + const GLint error = m_func->glGetError(); + QVERIFY(error == 0); + GLint p; + m_func->glGetIntegerv(GL_READ_BUFFER, &p); + QCOMPARE(p, GL_FRONT); + } + private: QScopedPointer<QWindow> m_window; QOpenGLContext m_glContext; diff --git a/tests/auto/render/qblitframebuffer/qblitframebuffer.pro b/tests/auto/render/qblitframebuffer/qblitframebuffer.pro new file mode 100644 index 000000000..219bad3d2 --- /dev/null +++ b/tests/auto/render/qblitframebuffer/qblitframebuffer.pro @@ -0,0 +1,11 @@ +TEMPLATE = app + +TARGET = tst_qblitframebuffer + +QT += core-private 3dcore 3dcore-private 3drender 3drender-private testlib + +CONFIG += testcase + +SOURCES += tst_qblitframebuffer.cpp + +include(../../core/common/common.pri) diff --git a/tests/auto/render/qblitframebuffer/tst_qblitframebuffer.cpp b/tests/auto/render/qblitframebuffer/tst_qblitframebuffer.cpp new file mode 100644 index 000000000..26ef936f6 --- /dev/null +++ b/tests/auto/render/qblitframebuffer/tst_qblitframebuffer.cpp @@ -0,0 +1,338 @@ +/**************************************************************************** +** +** 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: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 <Qt3DRender/QBlitFramebuffer> +#include <Qt3DRender/private/qblitframebuffer_p.h> + +#include "testpostmanarbiter.h" + +class tst_QBlitFrameBuffer: public QObject +{ + Q_OBJECT + +public: + tst_QBlitFrameBuffer() : QObject() + { + qRegisterMetaType<Qt3DRender::QRenderTarget*>(); + } + +private Q_SLOTS: + + void checkCreationData_data() + { + QTest::addColumn<Qt3DRender::QBlitFramebuffer *>("blitFramebuffer"); + + Qt3DRender::QBlitFramebuffer *defaultConstructed = new Qt3DRender::QBlitFramebuffer(); + Qt3DRender::QRenderTarget *sourceRenderTarget = new Qt3DRender::QRenderTarget(); + Qt3DRender::QRenderTarget *destinationRenderTarget = new Qt3DRender::QRenderTarget(); + defaultConstructed->setSource(sourceRenderTarget); + defaultConstructed->setDestination(destinationRenderTarget); + QTest::newRow("defaultConstructed") << defaultConstructed; + } + + void checkInitialState() + { + // GIVEN + Qt3DRender::QBlitFramebuffer blitFramebuffer; + + // THEN + QCOMPARE(blitFramebuffer.source(), nullptr); + QCOMPARE(blitFramebuffer.destination(), nullptr); + QCOMPARE(blitFramebuffer.sourceRect(), QRect()); + QCOMPARE(blitFramebuffer.destinationRect(), QRect()); + QCOMPARE(blitFramebuffer.sourceAttachmentPoint(), Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0); + QCOMPARE(blitFramebuffer.destinationAttachmentPoint(), Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0); + QCOMPARE(blitFramebuffer.interpolationMethod(), Qt3DRender::QBlitFramebuffer::Linear); + } + + void checkCreationData() + { + // GIVEN + QFETCH(Qt3DRender::QBlitFramebuffer *, blitFramebuffer); + + // WHEN + Qt3DCore::QNodeCreatedChangeGenerator creationChangeGenerator(blitFramebuffer); + QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges = creationChangeGenerator.creationChanges(); + + // THEN + QCOMPARE(creationChanges.size(), 1); + + const Qt3DCore::QNodeCreatedChangePtr<Qt3DRender::QBlitFramebufferData> creationChangeData = + qSharedPointerCast<Qt3DCore::QNodeCreatedChange<Qt3DRender::QBlitFramebufferData>>(creationChanges.first()); + const Qt3DRender::QBlitFramebufferData &cloneData = creationChangeData->data; + + // THEN + QCOMPARE(blitFramebuffer->id(), creationChangeData->subjectId()); + QCOMPARE(blitFramebuffer->isEnabled(), creationChangeData->isNodeEnabled()); + QCOMPARE(blitFramebuffer->metaObject(), creationChangeData->metaObject()); + QCOMPARE(blitFramebuffer->source()->id(), cloneData.m_sourceRenderTargetId); + QCOMPARE(blitFramebuffer->destination()->id(), cloneData.m_destinationRenderTargetId); + QCOMPARE(blitFramebuffer->sourceRect(), cloneData.m_sourceRect); + QCOMPARE(blitFramebuffer->destinationRect(), cloneData.m_destinationRect); + QCOMPARE(blitFramebuffer->sourceAttachmentPoint(), cloneData.m_sourceAttachmentPoint); + QCOMPARE(blitFramebuffer->destinationAttachmentPoint(), cloneData.m_destinationAttachmentPoint); + + + delete blitFramebuffer; + } + + void checkPropertyUpdate() + { + // GIVEN + TestArbiter arbiter; + QScopedPointer<Qt3DRender::QBlitFramebuffer> blitFramebuffer(new Qt3DRender::QBlitFramebuffer()); + arbiter.setArbiterOnNode(blitFramebuffer.data()); + + Qt3DRender::QRenderTarget *sourceRenderTarget = new Qt3DRender::QRenderTarget; + Qt3DRender::QRenderTarget *destinationRenderTarget = new Qt3DRender::QRenderTarget; + + // sourceRenderTarget + // WHEN + blitFramebuffer->setSource(sourceRenderTarget); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "source"); + QCOMPARE(change->subjectId(), blitFramebuffer->id()); + QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), sourceRenderTarget->id()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + blitFramebuffer->setSource(sourceRenderTarget); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + + // WHEN + blitFramebuffer->setSource(nullptr); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "source"); + QCOMPARE(change->subjectId(), blitFramebuffer->id()); + QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), Qt3DCore::QNodeId()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // destinationRenderTarget + // WHEN + blitFramebuffer->setDestination(destinationRenderTarget); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "destination"); + QCOMPARE(change->subjectId(), blitFramebuffer->id()); + QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), destinationRenderTarget->id()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + blitFramebuffer->setDestination(destinationRenderTarget); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + + // WHEN + blitFramebuffer->setDestination(nullptr); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "destination"); + QCOMPARE(change->subjectId(), blitFramebuffer->id()); + QCOMPARE(change->value().value<Qt3DCore::QNodeId>(), Qt3DCore::QNodeId()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // sourceRect + // WHEN + blitFramebuffer->setSourceRect(QRect(0,0,1,1)); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "sourceRect"); + QCOMPARE(change->subjectId(), blitFramebuffer->id()); + QCOMPARE(change->value().value<QRect>(), QRect(0,0,1,1)) ; + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + blitFramebuffer->setSourceRect(QRect(0,0,1,1)); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + + // WHEN + blitFramebuffer->setSourceRect(QRect()); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "sourceRect"); + QCOMPARE(change->subjectId(), blitFramebuffer->id()); + QCOMPARE(change->value().value<QRect>(), QRect()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // destinationRect + blitFramebuffer->setDestinationRect(QRect(0,0,1,1)); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "destinationRect"); + QCOMPARE(change->subjectId(), blitFramebuffer->id()); + QCOMPARE(change->value().value<QRect>(), QRect(0,0,1,1)) ; + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + blitFramebuffer->setDestinationRect(QRect(0,0,1,1)); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + + // WHEN + blitFramebuffer->setDestinationRect(QRect()); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "destinationRect"); + QCOMPARE(change->subjectId(), blitFramebuffer->id()); + QCOMPARE(change->value().value<QRect>(), QRect()); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // sourceAttachmentPoint + // WHEN + blitFramebuffer->setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "sourceAttachmentPoint"); + QCOMPARE(change->subjectId(), blitFramebuffer->id()); + QCOMPARE(change->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>(), Qt3DRender::QRenderTargetOutput::Color1); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + blitFramebuffer->setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + + // WHEN + blitFramebuffer->setSourceAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color0); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "sourceAttachmentPoint"); + QCOMPARE(change->subjectId(), blitFramebuffer->id()); + QCOMPARE(change->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>(), Qt3DRender::QRenderTargetOutput::Color0); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // destinationAttachmentPoint + // WHEN + blitFramebuffer->setDestinationAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "destinationAttachmentPoint"); + QCOMPARE(change->subjectId(), blitFramebuffer->id()); + QCOMPARE(change->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>(), Qt3DRender::QRenderTargetOutput::Color1); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + + // WHEN + blitFramebuffer->setDestinationAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color1); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 0); + + // WHEN + blitFramebuffer->setDestinationAttachmentPoint(Qt3DRender::QRenderTargetOutput::Color0); + QCoreApplication::processEvents(); + + // THEN + QCOMPARE(arbiter.events.size(), 1); + change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "destinationAttachmentPoint"); + QCOMPARE(change->subjectId(), blitFramebuffer->id()); + QCOMPARE(change->value().value<Qt3DRender::QRenderTargetOutput::AttachmentPoint>(), Qt3DRender::QRenderTargetOutput::Color0); + QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); + + arbiter.events.clear(); + } +}; + +QTEST_MAIN(tst_QBlitFrameBuffer) + +#include "tst_qblitframebuffer.moc" diff --git a/tests/auto/render/render.pro b/tests/auto/render/render.pro index 7cd5317c7..32a7b35fc 100644 --- a/tests/auto/render/render.pro +++ b/tests/auto/render/render.pro @@ -107,7 +107,9 @@ qtConfig(private_tests) { joint \ qproximityfilter \ proximityfilter \ - proximityfiltering + proximityfiltering \ + qblitframebuffer \ + blitframebuffer QT_FOR_CONFIG = 3dcore-private qtConfig(qt3d-extras) { diff --git a/tests/manual/blitframebuffer-qml/blitframebuffer-qml.pro b/tests/manual/blitframebuffer-qml/blitframebuffer-qml.pro new file mode 100644 index 000000000..c115cbeaf --- /dev/null +++ b/tests/manual/blitframebuffer-qml/blitframebuffer-qml.pro @@ -0,0 +1,14 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +QT += 3dcore 3drender 3dinput 3dquick 3dlogic qml quick 3dquickextras + +SOURCES += \ + main.cpp + +OTHER_FILES += \ + main.qml + +RESOURCES += \ + blitframebuffer-qml.qrc diff --git a/tests/manual/blitframebuffer-qml/blitframebuffer-qml.qrc b/tests/manual/blitframebuffer-qml/blitframebuffer-qml.qrc new file mode 100644 index 000000000..5f6483ac3 --- /dev/null +++ b/tests/manual/blitframebuffer-qml/blitframebuffer-qml.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + </qresource> +</RCC> diff --git a/tests/manual/blitframebuffer-qml/main.cpp b/tests/manual/blitframebuffer-qml/main.cpp new file mode 100644 index 000000000..3d85df6eb --- /dev/null +++ b/tests/manual/blitframebuffer-qml/main.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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; + + + QSurfaceFormat format; + format.setVersion(4, 3); + format.setProfile(QSurfaceFormat::CoreProfile); + format.setDepthBufferSize(24); + format.setSamples(1); + format.setStencilBufferSize(8); + view.setFormat(format); + + view.setSource(QUrl("qrc:/main.qml")); + view.show(); + + return app.exec(); +} diff --git a/tests/manual/blitframebuffer-qml/main.qml b/tests/manual/blitframebuffer-qml/main.qml new file mode 100644 index 000000000..4b3c1915b --- /dev/null +++ b/tests/manual/blitframebuffer-qml/main.qml @@ -0,0 +1,273 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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.10 +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 ) + } + + RenderTarget { + id: intermediateRenderTarget + attachments : [ + RenderTargetOutput { + objectName : "color" + attachmentPoint : RenderTargetOutput.Color0 + texture : Texture2D { + id : colorAttachment0 + width : 1024 + height : 768 + format : Texture.R32F + generateMipMaps : false + magnificationFilter : Texture.Linear + minificationFilter : Texture.Linear + wrapMode { + x: WrapMode.ClampToEdge + y: WrapMode.ClampToEdge + } + } + }, + RenderTargetOutput { + objectName : "color" + attachmentPoint : RenderTargetOutput.Color1 + texture : Texture2D { + id : colorAttachment1 + width : 1024 + height : 1024 + format : Texture.R32F + generateMipMaps : false + magnificationFilter : Texture.Linear + minificationFilter : Texture.Linear + wrapMode { + x: WrapMode.ClampToEdge + y: WrapMode.ClampToEdge + } + } + } + ] + } + + components: [ + RenderSettings { + activeFrameGraph: RenderSurfaceSelector { + Viewport { + RenderTargetSelector { + target: intermediateRenderTarget + NoDraw {} + } + + RenderTargetSelector { + target: RenderTarget { + id: renderTarget + attachments : [ + RenderTargetOutput { + objectName : "color" + attachmentPoint : RenderTargetOutput.Color0 + texture : Texture2D { + id : colorAttachment + width : 1024 + height : 768 + format : Texture.RGBA32F + generateMipMaps : false + magnificationFilter : Texture.Linear + minificationFilter : Texture.Linear + wrapMode { + x: WrapMode.ClampToEdge + y: WrapMode.ClampToEdge + } + } + }, + RenderTargetOutput { + objectName : "depth" + attachmentPoint : RenderTargetOutput.Depth + texture : Texture2D { + id : depthAttachment + width : 1024 + height : 1024 + format : Texture.D32F + generateMipMaps : false + magnificationFilter : Texture.Linear + minificationFilter : Texture.Linear + wrapMode { + x: WrapMode.ClampToEdge + y: WrapMode.ClampToEdge + } + } + } + ] + } + ClearBuffers { + clearColor: "white" + buffers: ClearBuffers.ColorDepthBuffer + CameraSelector { + camera: camera + } + } + } + + NoDraw{ + + BlitFramebuffer { + source: renderTarget + destination: intermediateRenderTarget + sourceRect: Qt.rect(0,0,1024,768) + destinationRect: Qt.rect(0,0,1024,1024) + sourceAttachmentPoint: RenderTargetOutput.Color0 + destinationAttachmentPoint: RenderTargetOutput.Color0 + interpolationMethod: BlitFramebuffer.Linear + } + + BlitFramebuffer { + source: intermediateRenderTarget + sourceRect: Qt.rect(0,0,1024,1024) + destinationRect: Qt.rect(0,0,512,384) + sourceAttachmentPoint: RenderTargetOutput.Color0 + interpolationMethod: BlitFramebuffer.Linear + } + + BlitFramebuffer { + source: renderTarget + sourceRect: Qt.rect(0,0,1024,768) + destinationRect: Qt.rect(0,384,512,384) + sourceAttachmentPoint: RenderTargetOutput.Color0 + interpolationMethod: BlitFramebuffer.Linear + } + + BlitFramebuffer { + source: renderTarget + sourceRect: Qt.rect(128,200,256,256) + destinationRect: Qt.rect(512,384,512,384) + sourceAttachmentPoint: RenderTargetOutput.Color0 + interpolationMethod: BlitFramebuffer.Linear + } + + BlitFramebuffer { + source: renderTarget + sourceRect: Qt.rect(128,200,256,256) + destinationRect: Qt.rect(512,0,512,384) + sourceAttachmentPoint: RenderTargetOutput.Color0 + interpolationMethod: BlitFramebuffer.Nearest + } + } + } + } + } + ] + + PhongMaterial { + id: material + } + + TorusMesh { + id: torusMesh + radius: 5 + minorRadius: 1 + rings: 100 + slices: 20 + } + + Transform { + id: torusTransform + scale3D: Qt.vector3d(1.5, 1, 0.5) + rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 45) + } + + Entity { + id: torusEntity + components: [ torusMesh, material, torusTransform ] + } + + SphereMesh { + id: sphereMesh + radius: 3 + } + + Transform { + id: sphereTransform + property real userAngle: 0.0 + matrix: { + var m = Qt.matrix4x4(); + m.rotate(userAngle, Qt.vector3d(0, 1, 0)); + m.translate(Qt.vector3d(20, 0, 0)); + return m; + } + } + + QQ2.NumberAnimation { + target: sphereTransform + property: "userAngle" + duration: 10000 + from: 0 + to: 360 + + loops: QQ2.Animation.Infinite + running: true + } + + Entity { + id: sphereEntity + components: [ sphereMesh, material, sphereTransform ] + } +} diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 8501a41af..2b13bd896 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -54,7 +54,9 @@ SUBDIRS += \ layerfilter-qml \ skinned-mesh \ proximityfilter \ - rendercapture-qml-fbo + rendercapture-qml-fbo \ + blitframebuffer-qml \ + skinned-mesh qtHaveModule(widgets): { SUBDIRS += \ |