diff options
author | Miikka Heikkinen <miikka.heikkinen@theqtcompany.com> | 2015-08-10 14:33:14 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@theqtcompany.com> | 2015-08-20 09:49:18 +0000 |
commit | 3f4d7a755585f1b79c7e9675220b8210f10f358e (patch) | |
tree | 50e4e4faef56413bede418bcf495ca7fe41677ba /src | |
parent | 04f30db289225e700fe99c163f53f0dd7e920caf (diff) | |
download | qtdeclarative-3f4d7a755585f1b79c7e9675220b8210f10f358e.tar.gz |
Add possibility to mirror ShaderEffectSource generated textures
Using textures generated by ShaderEffectSource items (or Item.layer)
with custom OpenGL code was non-intuitive due to mismatching coordinate
systems, so added a possibility to control the generated texture
orientation.
[ChangeLog][QtQuick][ShaderEffectSource] Added possibility to mirror
generated OpenGL texture.
Change-Id: I7c03d8b6fbfc43d69812c15d244200fb8e7c7bb9
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquickitem.cpp | 31 | ||||
-rw-r--r-- | src/quick/items/qquickitem_p.h | 6 | ||||
-rw-r--r-- | src/quick/items/qquickitemsmodule.cpp | 1 | ||||
-rw-r--r-- | src/quick/items/qquickshadereffectsource.cpp | 34 | ||||
-rw-r--r-- | src/quick/items/qquickshadereffectsource_p.h | 13 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgadaptationlayer_p.h | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultlayer.cpp | 25 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultlayer_p.h | 10 |
8 files changed, 121 insertions, 1 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 32c3e651dd..0c9ee4fe73 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -7488,6 +7488,7 @@ QQuickItemLayer::QQuickItemLayer(QQuickItem *item) , m_effectComponent(0) , m_effect(0) , m_effectSource(0) + , m_textureMirroring(QQuickShaderEffectSource::MirrorVertically) { } @@ -7559,6 +7560,7 @@ void QQuickItemLayer::activate() m_effectSource->setMipmap(m_mipmap); m_effectSource->setWrapMode(m_wrapMode); m_effectSource->setFormat(m_format); + m_effectSource->setTextureMirroring(m_textureMirroring); if (m_effectComponent) activateEffect(); @@ -7812,6 +7814,35 @@ void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode) } /*! + \qmlproperty enumeration QtQuick::Item::layer.textureMirroring + \since 5.6 + + This property defines how the generated OpenGL texture should be mirrored. + The default value is \c{ShaderEffectSource.MirrorVertically}. + Custom mirroring can be useful if the generated texture is directly accessed by custom shaders, + such as those specified by ShaderEffect. If no effect is specified for the layered + item, mirroring has no effect on the UI representation of the item. + + \list + \li ShaderEffectSource.NoMirroring - No mirroring + \li ShaderEffectSource.MirrorHorizontally - The generated texture is flipped along X-axis. + \li ShaderEffectSource.MirrorVertically - The generated texture is flipped along Y-axis. + \endlist + */ + +void QQuickItemLayer::setTextureMirroring(QQuickShaderEffectSource::TextureMirroring mirroring) +{ + if (mirroring == m_textureMirroring) + return; + m_textureMirroring = mirroring; + + if (m_effectSource) + m_effectSource->setTextureMirroring(m_textureMirroring); + + emit textureMirroringChanged(mirroring); +} + +/*! \qmlproperty string QtQuick::Item::layer.samplerName Holds the name of the effect's source texture property. diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 5e0246c32e..942b51bf68 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -143,6 +143,7 @@ class QQuickItemLayer : public QObject, public QQuickItemChangeListener Q_PROPERTY(QQuickShaderEffectSource::Format format READ format WRITE setFormat NOTIFY formatChanged) Q_PROPERTY(QByteArray samplerName READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QQmlComponent *effect READ effect WRITE setEffect NOTIFY effectChanged) + Q_PROPERTY(QQuickShaderEffectSource::TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged) public: QQuickItemLayer(QQuickItem *item); ~QQuickItemLayer(); @@ -177,6 +178,9 @@ public: QQmlComponent *effect() const { return m_effectComponent; } void setEffect(QQmlComponent *effect); + QQuickShaderEffectSource::TextureMirroring textureMirroring() const { return m_textureMirroring; } + void setTextureMirroring(QQuickShaderEffectSource::TextureMirroring mirroring); + QQuickShaderEffectSource *effectSource() const { return m_effectSource; } void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &) Q_DECL_OVERRIDE; @@ -200,6 +204,7 @@ Q_SIGNALS: void smoothChanged(bool smooth); void formatChanged(QQuickShaderEffectSource::Format format); void sourceRectChanged(const QRectF &sourceRect); + void textureMirroringChanged(QQuickShaderEffectSource::TextureMirroring mirroring); private: friend class QQuickTransformAnimatorJob; @@ -223,6 +228,7 @@ private: QQmlComponent *m_effectComponent; QQuickItem *m_effect; QQuickShaderEffectSource *m_effectSource; + QQuickShaderEffectSource::TextureMirroring m_textureMirroring; }; class Q_QUICK_PRIVATE_EXPORT QQuickItemPrivate : public QObjectPrivate diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 4df1ef038c..62e0adcb0a 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -273,6 +273,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickFlow, 6>(uri, 2, 6, "Flow"); qmlRegisterUncreatableType<QQuickEnterKeyAttached, 6>(uri, 2, 6, "EnterKey", QQuickEnterKeyAttached::tr("EnterKey is only available via attached properties")); + qmlRegisterType<QQuickShaderEffectSource, 1>(uri, 2, 6, "ShaderEffectSource"); } static void initResources() diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index bf69fe4277..2effc0d0ae 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -189,6 +189,7 @@ QQuickShaderEffectSource::QQuickShaderEffectSource(QQuickItem *parent) , m_mipmap(false) , m_recursive(false) , m_grab(true) + , m_textureMirroring(MirrorVertically) { setFlag(ItemHasContents); } @@ -543,6 +544,37 @@ void QQuickShaderEffectSource::setRecursive(bool enabled) } /*! + \qmlproperty enumeration QtQuick::ShaderEffectSource::textureMirroring + \since 5.6 + + This property defines how the generated OpenGL texture should be mirrored. + The default value is \c{ShaderEffectSource.MirrorVertically}. + Custom mirroring can be useful if the generated texture is directly accessed by custom shaders, + such as those specified by ShaderEffect. Mirroring has no effect on the UI representation of + the ShaderEffectSource item itself. + + \list + \li ShaderEffectSource.NoMirroring - No mirroring + \li ShaderEffectSource.MirrorHorizontally - The generated texture is flipped along X-axis. + \li ShaderEffectSource.MirrorVertically - The generated texture is flipped along Y-axis. + \endlist +*/ + +QQuickShaderEffectSource::TextureMirroring QQuickShaderEffectSource::textureMirroring() const +{ + return QQuickShaderEffectSource::TextureMirroring(m_textureMirroring); +} + +void QQuickShaderEffectSource::setTextureMirroring(TextureMirroring mirroring) +{ + if (mirroring == QQuickShaderEffectSource::TextureMirroring(m_textureMirroring)) + return; + m_textureMirroring = mirroring; + update(); + emit textureMirroringChanged(); +} + +/*! \qmlmethod QtQuick::ShaderEffectSource::scheduleUpdate() Schedules a re-rendering of the texture for the next frame. @@ -642,6 +674,8 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint m_texture->setRecursive(m_recursive); m_texture->setFormat(GLenum(m_format)); m_texture->setHasMipmaps(m_mipmap); + m_texture->setMirrorHorizontal(m_textureMirroring & MirrorHorizontally); + m_texture->setMirrorVertical(m_textureMirroring & MirrorVertically); if (m_grab) m_texture->scheduleUpdate(); diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h index 94bb315566..629acf0f55 100644 --- a/src/quick/items/qquickshadereffectsource_p.h +++ b/src/quick/items/qquickshadereffectsource_p.h @@ -66,6 +66,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi Q_PROPERTY(bool hideSource READ hideSource WRITE setHideSource NOTIFY hideSourceChanged) Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged) Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged) + Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 1) public: enum WrapMode { @@ -83,6 +84,13 @@ public: }; Q_ENUM(Format) + enum TextureMirroring { + NoMirroring = 0x00, + MirrorHorizontally = 0x01, + MirrorVertically = 0x02 + }; + Q_ENUM(TextureMirroring) + QQuickShaderEffectSource(QQuickItem *parent = 0); ~QQuickShaderEffectSource(); @@ -113,6 +121,9 @@ public: bool recursive() const; void setRecursive(bool enabled); + TextureMirroring textureMirroring() const; + void setTextureMirroring(TextureMirroring mirroring); + bool isTextureProvider() const Q_DECL_OVERRIDE { return true; } QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE; @@ -128,6 +139,7 @@ Q_SIGNALS: void hideSourceChanged(); void mipmapChanged(); void recursiveChanged(); + void textureMirroringChanged(); void scheduledUpdateCompleted(); @@ -157,6 +169,7 @@ private: uint m_mipmap : 1; uint m_recursive : 1; uint m_grab : 1; + uint m_textureMirroring : 2; // Stores TextureMirroring enum }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index 1253711a94..fde3fa06b2 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -195,6 +195,8 @@ public: virtual void setFormat(GLenum format) = 0; virtual void setHasMipmaps(bool mipmap) = 0; virtual void setDevicePixelRatio(qreal ratio) = 0; + virtual void setMirrorHorizontal(bool mirror) = 0; + virtual void setMirrorVertical(bool mirror) = 0; Q_SLOT virtual void markDirtyTexture() = 0; Q_SLOT virtual void invalidated() = 0; diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp index cca0712ece..fa69f911dd 100644 --- a/src/quick/scenegraph/qsgdefaultlayer.cpp +++ b/src/quick/scenegraph/qsgdefaultlayer.cpp @@ -97,6 +97,8 @@ QSGDefaultLayer::QSGDefaultLayer(QSGRenderContext *context) , m_multisamplingChecked(false) , m_multisampling(false) , m_grab(false) + , m_mirrorHorizontal(false) + , m_mirrorVertical(true) { } @@ -259,6 +261,16 @@ void QSGDefaultLayer::setRecursive(bool recursive) m_recursive = recursive; } +void QSGDefaultLayer::setMirrorHorizontal(bool mirror) +{ + m_mirrorHorizontal = mirror; +} + +void QSGDefaultLayer::setMirrorVertical(bool mirror) +{ + m_mirrorVertical = mirror; +} + void QSGDefaultLayer::markDirtyTexture() { m_dirtyTexture = true; @@ -365,7 +377,10 @@ void QSGDefaultLayer::grab() m_renderer->setDeviceRect(m_size); m_renderer->setViewportRect(m_size); - QRectF mirrored(m_rect.left(), m_rect.bottom(), m_rect.width(), -m_rect.height()); + QRectF mirrored(m_mirrorHorizontal ? m_rect.right() : m_rect.left(), + m_mirrorVertical ? m_rect.bottom() : m_rect.top(), + m_mirrorHorizontal ? -m_rect.width() : m_rect.width(), + m_mirrorVertical ? -m_rect.height() : m_rect.height()); m_renderer->setProjectionMatrixToRect(mirrored); m_renderer->setClearColor(Qt::transparent); @@ -428,3 +443,11 @@ QImage QSGDefaultLayer::toImage() const return QImage(); } + +QRectF QSGDefaultLayer::normalizedTextureSubRect() const +{ + return QRectF(m_mirrorHorizontal ? 1 : 0, + m_mirrorVertical ? 0 : 1, + m_mirrorHorizontal ? -1 : 1, + m_mirrorVertical ? 1 : -1); +} diff --git a/src/quick/scenegraph/qsgdefaultlayer_p.h b/src/quick/scenegraph/qsgdefaultlayer_p.h index 0ba7109ef6..7baaed5f67 100644 --- a/src/quick/scenegraph/qsgdefaultlayer_p.h +++ b/src/quick/scenegraph/qsgdefaultlayer_p.h @@ -78,10 +78,18 @@ public: void setDevicePixelRatio(qreal ratio) Q_DECL_OVERRIDE { m_device_pixel_ratio = ratio; } + bool mirrorHorizontal() const { return bool(m_mirrorHorizontal); } + void setMirrorHorizontal(bool mirror) Q_DECL_OVERRIDE; + + bool mirrorVertical() const { return bool(m_mirrorVertical); } + void setMirrorVertical(bool mirror) Q_DECL_OVERRIDE; + void scheduleUpdate() Q_DECL_OVERRIDE; QImage toImage() const Q_DECL_OVERRIDE; + QRectF normalizedTextureSubRect() const Q_DECL_OVERRIDE; + public Q_SLOTS: void markDirtyTexture() Q_DECL_OVERRIDE; void invalidated() Q_DECL_OVERRIDE; @@ -115,6 +123,8 @@ private: uint m_multisamplingChecked : 1; uint m_multisampling : 1; uint m_grab : 1; + uint m_mirrorHorizontal : 1; + uint m_mirrorVertical : 1; }; #endif // QSGDEFAULTLAYER_P_H |