From c6797affdab3d8e9e5bc0d13073fa41ff219581c Mon Sep 17 00:00:00 2001 From: Johan Thelin Date: Mon, 20 Sep 2021 16:14:49 +0200 Subject: [PATCH] ch10: shaders half done --- .gitignore | 3 + docs/.vuepress/config.js | 4 +- docs/ch10-effects/curtain-effect.md | 150 ++------- docs/ch10-effects/effect-library.md | 97 ------ docs/ch10-effects/fragment-shaders.md | 123 ++----- docs/ch10-effects/opengl-shaders.md | 11 +- docs/ch10-effects/shader-effects.md | 20 -- docs/ch10-effects/shader-elements.md | 121 +------ .../effects/{ => curtain}/CurtainEffect.qml | 46 +-- .../src/effects/curtain/curtain.frag | 54 +++ .../src/effects/curtain/curtain.vert | 66 ++++ .../src/effects/{ => curtain}/curtaindemo.qml | 10 +- .../src/effects/default/default.frag | 45 +++ .../src/effects/default/default.vert | 49 +++ .../defaultshader.qml} | 44 +-- .../src/effects/effects.qmlproject | 19 -- .../src/effects/genie/0/genie0.qml | 58 ++++ .../src/effects/genie/1/genie1.qml | 80 +++++ .../src/effects/genie/1/genie1.vert | 56 +++ .../src/effects/genie/2/genie2.qml | 76 +++++ .../src/effects/genie/2/genie2.vert | 57 ++++ .../src/effects/genie/3/genie3.qml | 114 +++++++ .../src/effects/genie/3/genie3.vert | 59 ++++ .../src/effects/genie/4/genie4.qml | 108 ++++++ .../src/effects/genie/4/genie4.vert | 60 ++++ .../src/effects/{ => genie}/GenieEffect.qml | 0 .../src/effects/genie/demo/GenieEffect.qml | 88 +++++ .../src/effects/genie/demo/geniedemo.qml | 43 +++ .../src/effects/genie/demo/genieeffect.vert | 61 ++++ .../src/effects/{ => genie}/genie.qml | 0 .../src/effects/{ => genie}/genie0.qml | 0 .../src/effects/{ => genie}/genie1.qml | 0 .../src/effects/{ => genie}/genie2.qml | 0 .../src/effects/{ => genie}/genie3.qml | 0 .../src/effects/{ => genie}/genie4.qml | 0 .../src/effects/{ => genie}/geniedemo.qml | 0 .../effects/{ => redlense/1}/redlense1.qml | 8 +- .../src/effects/redlense/2/red1.frag | 45 +++ .../src/effects/redlense/2/red2.frag | 45 +++ .../src/effects/redlense/2/red3.frag | 47 +++ .../2/redlense2.qml} | 64 ++-- docs/ch10-effects/src/effects/redlense2.qml | 112 ------ docs/ch10-effects/vertex-shader.md | 318 ++---------------- docs/ch10-effects/wave-effect.md | 4 + 44 files changed, 1381 insertions(+), 984 deletions(-) delete mode 100644 docs/ch10-effects/effect-library.md delete mode 100644 docs/ch10-effects/shader-effects.md rename docs/ch10-effects/src/effects/{ => curtain}/CurtainEffect.qml (63%) create mode 100644 docs/ch10-effects/src/effects/curtain/curtain.frag create mode 100644 docs/ch10-effects/src/effects/curtain/curtain.vert rename docs/ch10-effects/src/effects/{ => curtain}/curtaindemo.qml (94%) create mode 100644 docs/ch10-effects/src/effects/default/default.frag create mode 100644 docs/ch10-effects/src/effects/default/default.vert rename docs/ch10-effects/src/effects/{fastblur.qml => default/defaultshader.qml} (72%) delete mode 100644 docs/ch10-effects/src/effects/effects.qmlproject create mode 100644 docs/ch10-effects/src/effects/genie/0/genie0.qml create mode 100644 docs/ch10-effects/src/effects/genie/1/genie1.qml create mode 100644 docs/ch10-effects/src/effects/genie/1/genie1.vert create mode 100644 docs/ch10-effects/src/effects/genie/2/genie2.qml create mode 100644 docs/ch10-effects/src/effects/genie/2/genie2.vert create mode 100644 docs/ch10-effects/src/effects/genie/3/genie3.qml create mode 100644 docs/ch10-effects/src/effects/genie/3/genie3.vert create mode 100644 docs/ch10-effects/src/effects/genie/4/genie4.qml create mode 100644 docs/ch10-effects/src/effects/genie/4/genie4.vert rename docs/ch10-effects/src/effects/{ => genie}/GenieEffect.qml (100%) create mode 100644 docs/ch10-effects/src/effects/genie/demo/GenieEffect.qml create mode 100644 docs/ch10-effects/src/effects/genie/demo/geniedemo.qml create mode 100644 docs/ch10-effects/src/effects/genie/demo/genieeffect.vert rename docs/ch10-effects/src/effects/{ => genie}/genie.qml (100%) rename docs/ch10-effects/src/effects/{ => genie}/genie0.qml (100%) rename docs/ch10-effects/src/effects/{ => genie}/genie1.qml (100%) rename docs/ch10-effects/src/effects/{ => genie}/genie2.qml (100%) rename docs/ch10-effects/src/effects/{ => genie}/genie3.qml (100%) rename docs/ch10-effects/src/effects/{ => genie}/genie4.qml (100%) rename docs/ch10-effects/src/effects/{ => genie}/geniedemo.qml (100%) rename docs/ch10-effects/src/effects/{ => redlense/1}/redlense1.qml (95%) create mode 100644 docs/ch10-effects/src/effects/redlense/2/red1.frag create mode 100644 docs/ch10-effects/src/effects/redlense/2/red2.frag create mode 100644 docs/ch10-effects/src/effects/redlense/2/red3.frag rename docs/ch10-effects/src/effects/{defaultshader.qml => redlense/2/redlense2.qml} (67%) delete mode 100644 docs/ch10-effects/src/effects/redlense2.qml diff --git a/.gitignore b/.gitignore index 5210ae07..78e39f13 100644 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,6 @@ examples.tar.gz # Python .venv __pycache__ + +# Qt Shaders +*.qsb diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index adf49961..b2ae3dea 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -181,15 +181,13 @@ function ch10Sidebar() { '/ch09-particles/directed-particles', '/ch09-particles/affecting-particles', '/ch09-particles/particle-groups', - '/ch09-particles/summary', - '/ch10-effects/shader-effects', '/ch10-effects/opengl-shaders', '/ch10-effects/shader-elements', '/ch10-effects/fragment-shaders', '/ch10-effects/wave-effect', '/ch10-effects/vertex-shader', '/ch10-effects/curtain-effect', - '/ch10-effects/effect-library', + '/ch09-particles/summary', ] } } diff --git a/docs/ch10-effects/curtain-effect.md b/docs/ch10-effects/curtain-effect.md index 83935e74..c734fb47 100644 --- a/docs/ch10-effects/curtain-effect.md +++ b/docs/ch10-effects/curtain-effect.md @@ -2,142 +2,34 @@ In the last example for custom shader effects, I would like to bring you the curtain effect. This effect was published first in May 2011 as part of [Qt labs for shader effects](http://labs.qt.nokia.com/2011/05/03/qml-shadereffectitem-on-qgraphicsview/). - - ![image](./assets/curtain.png) At that time I really loved these effects and the curtain effect was my favorite out of them. I just love how the curtain opens and hide the background object. -I took the code and adapted it towards Qt 5, which was straightforward. Also, I did some simplifications to be able to use it better for a showcase. So if you are interested in the full example, please visit the lab’s blog. - -Just a little bot for the background, the curtain is actually an image called *fabric.jpg* and it is the source for a shader effect. The effect uses the vertex shader to swing the curtain and uses the fragment shader to provide some shades. Here is a simple diagram to make you hopefully better understand the code. +For this chapter, the effect has been adapted for Qt 6. It has also been slghtly simplifed to make it a better showcase. +The curtain image is called `fabric.png`. The effect then uses a vertex shader to swing the curtain forth and back and a fragment shader to apply shadows to show how the fabric folds. +The diagram below shows how the shader works. The waves are computed through a sin curve with 7 periods (7\*PI=21.99…). The other part is the swinging. The `topWidht` of the curtain is animated when the curtain is opened or closed. The `bottomWidth` follows the `topWidth` using a `SpringAnimation`. This creates the effect of the bottom part of the curtain swinging freely. The calulated `swing` component is the strengh of the swing based on the y-component of the vertexes. ![image](./assets/curtain_diagram.png) -The waved shades of the curtain are computed through a sin curve with 7 up/downs (7\*PI=21.99…) on the width of the curtain. The other important part is the swing. The *topWidth* of the curtain is animated when the curtain is opened or closed. The *bottomWidth* follows the *topWidth* with a *SpringAnimation*. By this, we create the effect of the swinging bottom part of the curtain. The calculated *swing* provides the strength of this swing interpolated over the y-component of the vertexes. - -The curtain effect is located in the `CurtainEffect.qml` component where the fabric image act as the texture source. There is nothing new on the use of shaders here, only a different way to manipulate the *gl_Position* in the vertex shader and the *gl_FragColor* in the fragment shader. - -```qml -import QtQuick 2.5 - -ShaderEffect { - anchors.fill: parent - - mesh: GridMesh { - resolution: Qt.size(50, 50) - } - - property real topWidth: open?width:20 - property real bottomWidth: topWidth - property real amplitude: 0.1 - property bool open: false - property variant source: effectSource - - Behavior on bottomWidth { - SpringAnimation { - easing.type: Easing.OutElastic; - velocity: 250; mass: 1.5; - spring: 0.5; damping: 0.05 - } - } - - Behavior on topWidth { - NumberAnimation { duration: 1000 } - } - - - ShaderEffectSource { - id: effectSource - sourceItem: effectImage; - hideSource: true - } - - Image { - id: effectImage - anchors.fill: parent - source: "assets/fabric.png" - fillMode: Image.Tile - } - - vertexShader: " - attribute highp vec4 qt_Vertex; - attribute highp vec2 qt_MultiTexCoord0; - uniform highp mat4 qt_Matrix; - varying highp vec2 qt_TexCoord0; - varying lowp float shade; - - uniform highp float topWidth; - uniform highp float bottomWidth; - uniform highp float width; - uniform highp float height; - uniform highp float amplitude; - - void main() { - qt_TexCoord0 = qt_MultiTexCoord0; - - highp vec4 shift = vec4(0.0, 0.0, 0.0, 0.0); - highp float swing = (topWidth - bottomWidth) * (qt_Vertex.y / height); - shift.x = qt_Vertex.x * (width - topWidth + swing) / width; - - shade = sin(21.9911486 * qt_Vertex.x / width); - shift.y = amplitude * (width - topWidth + swing) * shade; - - gl_Position = qt_Matrix * (qt_Vertex - shift); - - shade = 0.2 * (2.0 - shade ) * ((width - topWidth + swing) / width); - } - " - - fragmentShader: " - uniform sampler2D source; - varying highp vec2 qt_TexCoord0; - varying lowp float shade; - void main() { - highp vec4 color = texture2D(source, qt_TexCoord0); - color.rgb *= 1.0 - shade; - gl_FragColor = color; - } - " -} -``` - -The effect is used in the `curtaindemo.qml` file. - -```qml -import QtQuick 2.5 - -Item { - id: root - width: background.width; height: background.height - - - Image { - id: background - anchors.centerIn: parent - source: 'assets/background.png' - } - - Text { - anchors.centerIn: parent - font.pixelSize: 48 - color: '#efefef' - text: 'Qt5 Cadaques' - } - - CurtainEffect { - id: curtain - anchors.fill: parent - } - - MouseArea { - anchors.fill: parent - onClicked: curtain.open = !curtain.open - } -} -``` - -The curtain is opened through a custom *open* property on the curtain effect. We use a *MouseArea* to trigger the opening and closing of the curtain. +The curtain effect is implemed in the `CurtainEffect.qml` file where the fabric image act as the texture source. In the QML code, the `mesh` property is adjusted to make sure that the number of vertixes is increased to give a smoother result. + +<<< @/docs/ch10-effects/src/effects/curtain/CurtainEffect.qml#M1 + +The vertex shader, shown below, reshapes the curtain based on the `topWidth` and `bottomWidth` properies, extrapolating the shift based on the y-coordinate. It also calculates the `shade` value, which is used in the fragment shader. The `shade` property is passed through an additional output in `location` 1. + +<<< @/docs/ch10-effects/src/effects/curtain/curtain.vert#M1 + +In the fragment shader below, the `shade` is picked up as an input in `location` 1 and is then used to calculate the `fragColor`, which is used to draw the pixel in question. + +<<< @/docs/ch10-effects/src/effects/curtain/curtain.frag#M1 + +The combination of QML animations and passing variables from the vertex shader to the fragment shader demonstrates how QML and shaders can be used together to build complex, animated, effects. + +The effect itself is used from the `curtaindemo.qml` file shown below. + +<<< @/docs/ch10-effects/src/effects/curtain/curtaindemo.qml#M1 +The curtain is opened through a custom `open` property on the curtain effect. We use a `MouseArea` to trigger the opening and closing of the curtain when the user clicks or taps the area. diff --git a/docs/ch10-effects/effect-library.md b/docs/ch10-effects/effect-library.md deleted file mode 100644 index 1ef3f812..00000000 --- a/docs/ch10-effects/effect-library.md +++ /dev/null @@ -1,97 +0,0 @@ -# Effect Library - -The graphics effect library is a collection of shader effects. Ready-made by the Qt developers. It’s a great tool-set to be used in your application but also a great source to learn how to build shaders. - -The graphics effects library comes with a so-called manual testbed which is a great tool to interactively discover the different effects. - -The testbed is located under `$QTDIR/qtgraphicaleffects/tests/manual/testbed`. - - - -![image](./assets/graphicseffectstestbed.png) - -The effects library contains ca 20 effects. A list of the effect and a short description can be found below. - -## Graphics Effects List - -* Blend - * **`Blend`** - merges two source items by using a blend mode -* Color - * **`BrightnessContrast`** - adjusts brightness and contrast - * **`Colorize`** - sets color in the HSL color space - * **`ColorOverlay`** - applies a color layer - * **`Desaturate`** - reduces color saturation - * **`GammaAdjust`** - adjusts luminance - * **`HueSaturation`** - adjusts colors in the HSL color space - * **`LevelAdjust`** - adjusts colors in the RGB color space -* Gradient - * **`ConicalGradient`** - draws a conical gradient - * **`LinearGradient`** - draws a linear gradient - * **`RadialGradient`** -draws a radial gradient -* Distortion - * **`Displace`** - moves the pixels of the source item according to the specified displacement source -* Drop Shadow - * **`DropShadow`** - draws a drop shadow - * **`InnerShadow`** - draws an inner shadow -* Blur, - * **`FastBlur`** - applies a fast blur effect - * **`GaussianBlur`** - applies a higher quality blur effect - * **`MaskedBlur`** - applies a varying intensity blur effect - * **`RecursiveBlur`** - "blurs repeatedly, providing a strong blur effect" -* Motion Blur - * **`DirectionalBlur`** - applies a directional motion blur effect - * **`RadialBlur`** - applies a radial motion blur effect - * **`ZoomBlur`** - applies a zoom motion blur effect -* Glow - * **`Glow`** - draws an outer glow effect - * **`RectangularGlow`** - draws a rectangular outer glow effect -Mask - * **`OpacityMask`** - masks the source item with another item - * **`ThresholdMask`** - masks the source item with another item and applies a threshold value - - -Here is a example using the *FastBlur* effect from the *Blur* category: - -```qml -import QtQuick 2.5 -import QtGraphicalEffects 1.0 - -Rectangle { - width: 480; height: 240 - color: '#1e1e1e' - - Row { - anchors.centerIn: parent - spacing: 16 - - Image { - id: sourceImage - source: "assets/tulips.jpg" - width: 200; height: width - sourceSize: Qt.size(parent.width, parent.height) - smooth: true - } - - FastBlur { - width: 200; height: width - source: sourceImage - radius: blurred?32:0 - property bool blurred: false - - Behavior on radius { - NumberAnimation { duration: 1000 } - } - - MouseArea { - id: area - anchors.fill: parent - onClicked: parent.blurred = !parent.blurred - } - } - } -} -``` - -The image to the left is the original image. Clicking the image on the right will toggle blurred property and animated the blur radius from 0 to 32 during 1 second. The image on the left shows the blurred image. - -![image](./assets/fastblur.png) diff --git a/docs/ch10-effects/fragment-shaders.md b/docs/ch10-effects/fragment-shaders.md index f100d6e6..69cbf7d2 100644 --- a/docs/ch10-effects/fragment-shaders.md +++ b/docs/ch10-effects/fragment-shaders.md @@ -1,32 +1,12 @@ # Fragment Shaders -The fragment shader is called for every pixel to be rendered. We will develop a small red lens, which will increase the red color channel value of the image. +The fragment shader is called for every pixel to be rendered. In this chapter, we will develop a small red lens which will increase the red color channel value of the source. ## Setting up the scene First, we set up our scene, with a grid centered in the field and our source image be displayed. -```qml -import QtQuick 2.5 - -Rectangle { - width: 480; height: 240 - color: '#1e1e1e' - - Grid { - anchors.centerIn: parent - spacing: 20 - rows: 2; columns: 4 - Image { - id: sourceImage - width: 80; height: width - source: 'assets/tulips.jpg' - } - } -} -``` - - +<<< @/docs/ch10-effects/src/effects/redlense/1/redlense1.qml#M1 ![image](./assets/redlense1.png) @@ -34,76 +14,35 @@ Rectangle { Next, we will add a shader, which displays a red rectangle by providing for each fragment a red color value. -```qml -fragmentShader: " - uniform lowp float qt_Opacity; - void main() { - gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0) * qt_Opacity; - } -" -``` - -In the fragment shader we simply assign a *vec4(1.0, 0.0, 0.0, 1.0)* which represents a red color with full opacity (alpha=1.0) to the *gl_FragColor* for each fragment. - +<<< @/docs/ch10-effects/src/effects/redlense/2/red1.frag#M1{14-16} +In the fragment shader we simply assign a `vec4(1.0, 0.0, 0.0, 1.0)`, representing the color red with full opacity (alpha=1.0), to the `fragColor` for each fragment, turning each pixel to a solid red. ![image](./assets/redlense2.png) ## A red shader with texture -Now we want to apply the red color to each texture pixel. For this, we need the texture back in the vertex shader. As we don’t do anything else in the vertex shader the default vertex shader is enough for us. - -```qml -ShaderEffect { - id: effect2 - width: 80; height: width - property variant source: sourceImage - visible: root.step>1 - fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform sampler2D source; - uniform lowp float qt_Opacity; - void main() { - gl_FragColor = texture2D(source, qt_TexCoord0) * vec4(1.0, 0.0, 0.0, 1.0) * qt_Opacity; - } - " -} -``` +Now we want to apply the red color to each texture pixel. For this, we need the texture back in the vertex shader. As we don’t do anything else in the vertex shader the default vertex shader is enough for us. We just need to provide a compatible fragment shader. -The full shader contains now back our image source as variant property and we have left out the vertex shader, which if not specified is the default vertex shader. - -In the fragment shader, we pick the texture fragment *texture2D(source, qt_TexCoord0)* and apply the red color to it. +<<< @/docs/ch10-effects/src/effects/redlense/2/red2.frag#M1{14-16} +The full shader contains now back our image source as variant property and we have left out the vertex shader, which if not specified is the default vertex shader. +In the fragment shader, we pick the texture fragment `texture(source, qt_TexCoord0)` and apply the red color to it. ![image](./assets/redlense3.png) ## The red channel property -It’s not really nice to hard code the red channel value, so we would like to control the value from the QML side. For this we add a *redChannel* property to our shader effect and also declare a *uniform lowp float redChannel* inside our fragment shader. That’s all to make a value from the shader code available to the QML side. Very simple. - -```qml -ShaderEffect { - id: effect3 - width: 80; height: width - property variant source: sourceImage - property real redChannel: 0.3 - visible: root.step>2 - fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform sampler2D source; - uniform lowp float qt_Opacity; - uniform lowp float redChannel; - void main() { - gl_FragColor = texture2D(source, qt_TexCoord0) * vec4(redChannel, 1.0, 1.0, 1.0) * qt_Opacity; - } - " -} -``` +It’s not really nice to hard code the red channel value, so we would like to control the value from the QML side. For this we add a *redChannel* property to our shader effect and also declare a `float redChannel` inside the uniform buffer of the fragment shader. That is all that we need to do to make a value from the QML side available to the shader code. -To make the lens really a lens, we change the *vec4* color to be *vec4(redChannel, 1.0, 1.0, 1.0)* so that the other colors are multiplied by 1.0 and only the red portion is multiplied by our *redChannel* variable. +::: tip +Notice that the `redChannel` must come after the implicit `qt_Matrix` and `qt_Opacity` in the uniform buffer, `ubuf`. The order of the parameters after the `qt_` parameters is up to you, but `qt_Matrix` and `qt_Opacity` must come first and in that order. +::: +<<< @/docs/ch10-effects/src/effects/redlense/2/red3.frag#M1{11} +To make the lens really a lens, we change the *vec4* color to be *vec4(redChannel, 1.0, 1.0, 1.0)* so that the other colors are multiplied by 1.0 and only the red portion is multiplied by our *redChannel* variable. ![image](./assets/redlense4.png) @@ -111,34 +50,20 @@ To make the lens really a lens, we change the *vec4* color to be *vec4(redChanne As the *redChannel* property is just a normal property it can also be animated as all properties in QML. So we can use QML properties to animate values on the GPU to influence our shaders. How cool is that! -```qml -ShaderEffect { - id: effect4 - width: 80; height: width - property variant source: sourceImage - property real redChannel: 0.3 - visible: root.step>3 - NumberAnimation on redChannel { - from: 0.0; to: 1.0; loops: Animation.Infinite; duration: 4000 - } - - fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform sampler2D source; - uniform lowp float qt_Opacity; - uniform lowp float redChannel; - void main() { - gl_FragColor = texture2D(source, qt_TexCoord0) * vec4(redChannel, 1.0, 1.0, 1.0) * qt_Opacity; - } - " -} -``` +<<< @/docs/ch10-effects/src/effects/redlense/2/redlense2.qml#M1{7-9} Here the final result. - - ![image](./assets/redlense5.png) The shader effect on the 2nd row is animated from 0.0 to 1.0 with a duration of 4 seconds. So the image goes from no red information (0.0 red) over to a normal image (1.0 red). +## Baking + +Again, we need to bake the shaders. The following commands from the command line does that: + +``` +qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -o red1.frag.qsb red1.frag +qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -o red2.frag.qsb red2.frag +qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -o red3.frag.qsb red3.frag +``` diff --git a/docs/ch10-effects/opengl-shaders.md b/docs/ch10-effects/opengl-shaders.md index 6fa5e267..a65e3066 100644 --- a/docs/ch10-effects/opengl-shaders.md +++ b/docs/ch10-effects/opengl-shaders.md @@ -1,10 +1,11 @@ -# OpenGL Shaders - -OpenGL uses a rendering pipeline split into stages. A simplified OpenGL pipeline would contain a vertex and fragment shader. - +# Graphics Shaders +Graphics is rendered using a _rendering pipeline_ split into stages. There are multiple APIs to control graphics rendering. Qt supports OpenGL, Metal, Vulcan, and Direct3D. Looking at a simplified OpenGL pipeline, we can spot a vertex and fragment shader. These concepts exists for all other rendering pipelines too. ![image](./assets/openglpipeline.png) -The vertex shader receives vertex data and must assign it to the *gl_Position* at the end of the routine. In the next stage, the vertexes are clipped, transformed and rasterized for pixel output. From there the fragments (pixels) arrive in the fragment shader and can further be manipulated and the resulting color needs to be assigned to *gl_FragColor*. The vertex shader is called for each corner point of your polygon (vertex = point in 3D) and is responsible for any 3D manipulation of these points. The fragment (fragment = pixel) shader is called for each pixel and determines the color of that pixel. +In the pipeline, the vertex shader receives vertex data, i.e. the location of the corners of each element that makes up the scene, and calculates a `gl_Position`. This means that the vertex shader can _move_ graphical elements. In the next stage, the vertexes are clipped, transformed and rasterized for pixel output. Then the pixels, also known as _fragments_,are passed through the fragment shader, which calculates the color of each pixel. The resulting color returned through the `gl_FragColor` variable. + +To summarize: the vertex shader is called for each corner point of your polygon (vertex = point in 3D) and is responsible for any 3D manipulation of these points. The fragment (fragment = pixel) shader is called for each pixel and determines the color of that pixel. +As Qt is independent of the underlying rendering API, Qt relies on a standard language for writing shaders. The Qt Shader Tools rely on a _Vulcan-compatible GLSL_. We will look more at this in the examples in this chapter. diff --git a/docs/ch10-effects/shader-effects.md b/docs/ch10-effects/shader-effects.md deleted file mode 100644 index e81d75b6..00000000 --- a/docs/ch10-effects/shader-effects.md +++ /dev/null @@ -1,20 +0,0 @@ -# Shader Effects - -Shaders allow us to create awesome rendering effects on top of the SceneGraph API leveraging directly the power of OpenGL running on the GPU. Shaders are implemented using the ShaderEffect and ShaderEffectSource elements. The shader algorithm itself is implemented using the OpenGL Shading Language. - -Practically it means you mix QML code with shader code. On execution will the shader code be sent over to the GPU and compiled and executed on the GPU. The shader QML elements allow you to interact through properties with the OpenGL shader implementation. - -Let’s first have a look what OpenGL shaders are. - - -::: tip - -Resources - -* [http://doc.qt.io/qt-5/qml-qtquick-shadereffect.html](http://doc.qt.io/qt-5/qml-qtquick-shadereffect.html) -* [http://www.opengl.org/registry/doc/GLSLangSpec.4.20.6.clean.pdf](http://www.opengl.org/registry/doc/GLSLangSpec.4.20.6.clean.pdf) -* [http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf](http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf) -* [http://www.lighthouse3d.com/tutorials/](http://www.lighthouse3d.com/tutorials/) -* [http://wiki.delphigl.com/index.php/Tutorial_glsl](http://wiki.delphigl.com/index.php/Tutorial_glsl) -::: - diff --git a/docs/ch10-effects/shader-elements.md b/docs/ch10-effects/shader-elements.md index efbfdf8e..6d58b85b 100644 --- a/docs/ch10-effects/shader-elements.md +++ b/docs/ch10-effects/shader-elements.md @@ -1,123 +1,36 @@ # Shader Elements -For programming shaders, Qt Quick provides two elements. The ShaderEffectSource and the ShaderEffect. The shader effect applies custom shaders and the shader effect source renders a QML item into a texture and renders it. As shader effect can apply custom shaders to its rectangular shape and can use sources for the shader operation. A source can be an image, which is used as a texture or a shader effect source. - -The default shader uses the source and renders it unmodified. - -```qml -import QtQuick 2.5 - -Rectangle { - width: 480; height: 240 - color: '#1e1e1e' - - Row { - anchors.centerIn: parent - spacing: 20 - Image { - id: sourceImage - width: 80; height: width - source: 'assets/tulips.jpg' - } - ShaderEffect { - id: effect - width: 80; height: width - property variant source: sourceImage - } - ShaderEffect { - id: effect2 - width: 80; height: width - // the source where the effect shall be applied to - property variant source: sourceImage - // default vertex shader code - vertexShader: " - uniform highp mat4 qt_Matrix; - attribute highp vec4 qt_Vertex; - attribute highp vec2 qt_MultiTexCoord0; - varying highp vec2 qt_TexCoord0; - void main() { - qt_TexCoord0 = qt_MultiTexCoord0; - gl_Position = qt_Matrix * qt_Vertex; - }" - // default fragment shader code - fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform sampler2D source; - uniform lowp float qt_Opacity; - void main() { - gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity; - }" - } - } -} -``` +For programming shaders, Qt Quick provides two elements. The `ShaderEffectSource` and the `ShaderEffect`. The shader effect applies custom shaders and the shader effect source renders a QML item into a texture and renders it. As shader effect can apply custom shaders to its rectangular shape and can use sources for the shader operation. A source can be an image, which is used as a texture or a shader effect source. +The default shader uses the source and renders it unmodified. Below, we first see the QML file with two `ShaderEffect` elements. One without any shaders specified, and one explicitly specifying default vertex and fragment shaders. We will look at the shaders shortly. +<<< @/docs/ch10-effects/src/effects/default/defaultshader.qml#M1 ![image](./assets/defaultshader.png) -In the above example, we have a row of 3 images. The first is the real image. The second is rendered using the default shader and the third is rendered using the default shader code for the fragment and vertex extracted from the Qt 5 source code. - -::: tip -If you don’t want to see the source image and only the effected image you can set the *Image* to invisible (\`\` visible: false\`\`). The shader effects will still use the image data just the *Image* element will not be rendered. -::: - -Let’s have a closer look at the shader code. - -```qml -vertexShader: " - uniform highp mat4 qt_Matrix; - attribute highp vec4 qt_Vertex; - attribute highp vec2 qt_MultiTexCoord0; - varying highp vec2 qt_TexCoord0; - void main() { - qt_TexCoord0 = qt_MultiTexCoord0; - gl_Position = qt_Matrix * qt_Vertex; - } -" -``` - -Both shaders are from the Qt side a string bound to the *vertexShader* and *fragmentShader* property. Every shader code has to have a *main() { … }* function, which is executed by the GPU. Variable starting with *qt_* are provided by default by Qt already. - -Here a short rundown on the variables: +In the above example, we have a row of 3 images. The first is the real image. The second is rendered using the default shader and the third is rendered using the shader code for the fragment and vertex as shown below. Let's have a look at the shaders. -* **`uniform`** - value does not change during processing -* **`attribute`** - linkage to external data -* **`varying`** - shared value between shaders -* **`highp`** - high precision value -* **`lowp`** - low precision value -* **`mat4`** - 4x4 float matrix -* **`vec2`** - 2 dim float vector -* **`sampler2D`** - 2D texture -* **`float`** - floating scalar +The vertex shader takes the texture coordinate, `qt_MultiTexCoord0`, and propagates it to the `qt_TexCoord0` variable. It also takes the `qt_Vertex` position and multiplies it with Qt's transformation matrix, `ubuf.qt_Matrix`, and returns it through the `gl_Position` variable. This leaves the texture and vertex position on the screen unmodified. -A better reference is the [OpenGL ES 2.0 API Quick Reference Card](http://www.khronos.org/opengles/sdk/docs/reference_cards/OpenGL-ES-2_0-Reference-card.pdf) +<<< @/docs/ch10-effects/src/effects/default/default.vert#M1 -Now we might be better able to understand what the variable is: +The fragment shader takes the texture from the `source` 2D sampler, i.e. the texture, at the coordinate `qt_TexCoord0` and multiplies it with the Qt opacity, `ubuf.qt_Opacity` to calculate the `fragColor` which is the color to be used for the pixel. +<<< @/docs/ch10-effects/src/effects/default/default.frag#M1 -* **`qt_Matrix`**: model-view-projection matrix -* **`qt_Vertex`**: current vertex position -* **`qt_MultiTexCoord0`**: texture coordinate -* **`qt_TexCoord0`**: shared texture coordinate +Notice that these two shaders can serve as the boilerplate code for your own shaders. The variables, locations and bindings, are what Qt expects. You can read more about the exact details of this on the [Shader Effect Documentation](https://doc-snapshots.qt.io/qt6-6.2/qml-qtquick-shadereffect.html#details). -So we have available the projection matrix, the current vertex and the texture coordinate. The texture coordinate relates to the texture given as the source. In the *main()* function we store the texture coordinate for later use in the fragment shader. Every vertex shader needs to assign the *gl_Position* this is done using here by multiplying the project matrix with the vertex, our point in 3D. +Before we can use the shaders, they need to be baked. If the shaders are a part of a larger Qt project and included as resources, this can be automated. However, when working with the shaders and a `qml`-file, we need to explicitly bake them by hand. This is done using the following two commands: -The fragment shader receives our texture coordinate from the vertex shader and also the texture from our QML source property. It shall be noted how easy it is to pass a variable between the shader code and QML. Beautiful. Additional we have the opacity of the shader effect available as *qt_Opacity*. Every fragment shader needs to assign the *gl_FragColor* variable, this is done in the default shader code by picking the pixel from the source texture and multiplying it with the opacity. - -```qml -fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform sampler2D source; - uniform lowp float qt_Opacity; - void main() { - gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity; - } -" +``` +qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -o default.frag.qsb default.frag +qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -b -o default.vert.qsb default.vert ``` -During the next examples, we will be playing around with some simple shader mechanics. First, we concentrate on the fragment shader and then we will come back to the vertex shader. +The `qsb` tool is located in the `bin` directory of your Qt 6 installation. ::: tip -In the example above, the shader code is written inline in a string inside the QML code. This is supported for OpenGL, but for other platforms a pre-compiled byte code version of the shader is expected. To import such a shader, simply replace the shader code with a filename referring the the pre-compiled byte code. +If you don’t want to see the source image and only the effected image you can set the *Image* to invisible (\`\` visible: false\`\`). The shader effects will still use the image data just the *Image* element will not be rendered. ::: + +In the next examples, we will be playing around with some simple shader mechanics. First, we concentrate on the fragment shader and then we will come back to the vertex shader. diff --git a/docs/ch10-effects/src/effects/CurtainEffect.qml b/docs/ch10-effects/src/effects/curtain/CurtainEffect.qml similarity index 63% rename from docs/ch10-effects/src/effects/CurtainEffect.qml rename to docs/ch10-effects/src/effects/curtain/CurtainEffect.qml index c87a3226..0b92a986 100644 --- a/docs/ch10-effects/src/effects/CurtainEffect.qml +++ b/docs/ch10-effects/src/effects/curtain/CurtainEffect.qml @@ -25,8 +25,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// M1>> -import QtQuick 2.5 +// #region M1 +import QtQuick ShaderEffect { anchors.fill: parent @@ -63,46 +63,12 @@ ShaderEffect { Image { id: effectImage anchors.fill: parent - source: "assets/fabric.png" + source: "../assets/fabric.png" fillMode: Image.Tile } - vertexShader: " - attribute highp vec4 qt_Vertex; - attribute highp vec2 qt_MultiTexCoord0; - uniform highp mat4 qt_Matrix; - varying highp vec2 qt_TexCoord0; - varying lowp float shade; + vertexShader: "curtain.vert.qsb" - uniform highp float topWidth; - uniform highp float bottomWidth; - uniform highp float width; - uniform highp float height; - uniform highp float amplitude; - - void main() { - qt_TexCoord0 = qt_MultiTexCoord0; - - highp vec4 shift = vec4(0.0, 0.0, 0.0, 0.0); - highp float swing = (topWidth - bottomWidth) * (qt_Vertex.y / height); - shift.x = qt_Vertex.x * (width - topWidth + swing) / width; - - shade = sin(21.9911486 * qt_Vertex.x / width); - shift.y = amplitude * (width - topWidth + swing) * shade; - - gl_Position = qt_Matrix * (qt_Vertex - shift); - - shade = 0.2 * (2.0 - shade ) * ((width - topWidth + swing) / width); - }" - - fragmentShader: " - uniform sampler2D source; - varying highp vec2 qt_TexCoord0; - varying lowp float shade; - void main() { - highp vec4 color = texture2D(source, qt_TexCoord0); - color.rgb *= 1.0 - shade; - gl_FragColor = color; - }" + fragmentShader: "curtain.frag.qsb" } -// < 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. + */ + +// #region M1 +#version 440 + +layout(location=0) in vec2 qt_TexCoord0; +layout(location=1) in float shade; + +layout(location=0) out vec4 fragColor; + +layout(std140, binding=0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + + float topWidth; + float bottomWidth; + float width; + float height; + float amplitude; +} ubuf; + +layout(binding=1) uniform sampler2D source; + +void main() { + highp vec4 color = texture(source, qt_TexCoord0); + color.rgb *= 1.0 - shade; + fragColor = color; +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/curtain/curtain.vert b/docs/ch10-effects/src/effects/curtain/curtain.vert new file mode 100644 index 00000000..9bc7456d --- /dev/null +++ b/docs/ch10-effects/src/effects/curtain/curtain.vert @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +// #region M1 +#version 440 + +layout(location=0) in vec4 qt_Vertex; +layout(location=1) in vec2 qt_MultiTexCoord0; + +layout(location=0) out vec2 qt_TexCoord0; +layout(location=1) out float shade; + +layout(std140, binding=0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + + float topWidth; + float bottomWidth; + float width; + float height; + float amplitude; +} ubuf; + +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() { + qt_TexCoord0 = qt_MultiTexCoord0; + + vec4 shift = vec4(0.0, 0.0, 0.0, 0.0); + float swing = (ubuf.topWidth - ubuf.bottomWidth) * (qt_Vertex.y / ubuf.height); + shift.x = qt_Vertex.x * (ubuf.width - ubuf.topWidth + swing) / ubuf.width; + + shade = sin(21.9911486 * qt_Vertex.x / ubuf.width); + shift.y = ubuf.amplitude * (ubuf.width - ubuf.topWidth + swing) * shade; + + gl_Position = ubuf.qt_Matrix * (qt_Vertex - shift); + + shade = 0.2 * (2.0 - shade) * ((ubuf.width - ubuf.topWidth + swing) / ubuf.width); +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/curtaindemo.qml b/docs/ch10-effects/src/effects/curtain/curtaindemo.qml similarity index 94% rename from docs/ch10-effects/src/effects/curtaindemo.qml rename to docs/ch10-effects/src/effects/curtain/curtaindemo.qml index e759fa68..d1c779f1 100644 --- a/docs/ch10-effects/src/effects/curtaindemo.qml +++ b/docs/ch10-effects/src/effects/curtain/curtaindemo.qml @@ -25,8 +25,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// M1>> -import QtQuick 2.5 +// #region M1 +import QtQuick Item { id: root @@ -36,14 +36,14 @@ Item { Image { id: background anchors.centerIn: parent - source: 'assets/background.png' + source: '../assets/background.png' } Text { anchors.centerIn: parent font.pixelSize: 48 color: '#efefef' - text: 'Qt5 Cadaques' + text: 'Qt 6 Book' } CurtainEffect { @@ -56,4 +56,4 @@ Item { onClicked: curtain.open = !curtain.open } } -// < 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. + */ + +// #region M1 +#version 440 + +layout(location=0) in vec2 qt_TexCoord0; + +layout(location=0) out vec4 fragColor; + +layout(std140, binding=0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +} ubuf; + +layout(binding=1) uniform sampler2D source; + +void main() { + fragColor = texture(source, qt_TexCoord0) * ubuf.qt_Opacity; +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/default/default.vert b/docs/ch10-effects/src/effects/default/default.vert new file mode 100644 index 00000000..f6cfcfc2 --- /dev/null +++ b/docs/ch10-effects/src/effects/default/default.vert @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +// #region M1 +#version 440 + +layout(location=0) in vec4 qt_Vertex; +layout(location=1) in vec2 qt_MultiTexCoord0; + +layout(location=0) out vec2 qt_TexCoord0; + +layout(std140, binding=0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +} ubuf; + +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() { + qt_TexCoord0 = qt_MultiTexCoord0; + gl_Position = ubuf.qt_Matrix * qt_Vertex; +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/fastblur.qml b/docs/ch10-effects/src/effects/default/defaultshader.qml similarity index 72% rename from docs/ch10-effects/src/effects/fastblur.qml rename to docs/ch10-effects/src/effects/default/defaultshader.qml index fc3940fe..6ca2d20d 100644 --- a/docs/ch10-effects/src/effects/fastblur.qml +++ b/docs/ch10-effects/src/effects/default/defaultshader.qml @@ -25,9 +25,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// M1>> -import QtQuick 2.5 -import QtGraphicalEffects 1.0 +// #region M1 +import QtQuick Rectangle { width: 480; height: 240 @@ -35,33 +34,24 @@ Rectangle { Row { anchors.centerIn: parent - spacing: 16 - + spacing: 20 Image { id: sourceImage - source: "assets/tulips.jpg" - width: 200; height: width - sourceSize: Qt.size(parent.width, parent.height) - smooth: true + width: 80; height: width + source: '../assets/tulips.jpg' } - - FastBlur { - width: 200; height: width - source: sourceImage - radius: blurred?32:0 - property bool blurred: false - - Behavior on radius { - NumberAnimation { duration: 1000 } - } - - MouseArea { - id: area - anchors.fill: parent - onClicked: parent.blurred = !parent.blurred - } + ShaderEffect { + id: effect + width: 80; height: width + property variant source: sourceImage + } + ShaderEffect { + id: effect2 + width: 80; height: width + property variant source: sourceImage + vertexShader: "default.vert.qsb" + fragmentShader: "default.frag.qsb" } } } -// < 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. + */ + +// #region M1 +import QtQuick + +Rectangle { + width: 480; height: 240 + color: '#1e1e1e' + + Image { + id: sourceImage + width: 160; height: width + source: "../../assets/lighthouse.jpg" + visible: false + } + Rectangle { + width: 160; height: width + anchors.centerIn: parent + color: '#333333' + } + ShaderEffect { + id: genieEffect + width: 160; height: width + anchors.centerIn: parent + property variant source: sourceImage + property bool minimized: false + MouseArea { + anchors.fill: parent + onClicked: genieEffect.minimized = !genieEffect.minimized + } + } +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/genie/1/genie1.qml b/docs/ch10-effects/src/effects/genie/1/genie1.qml new file mode 100644 index 00000000..22899ca9 --- /dev/null +++ b/docs/ch10-effects/src/effects/genie/1/genie1.qml @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +import QtQuick + +Rectangle { + width: 480; height: 240 + color: '#1e1e1e' + + Image { + id: sourceImage + width: 160; height: width + source: "../../assets/lighthouse.jpg" + visible: false + } + Rectangle { + width: 160; height: width + anchors.centerIn: parent + color: '#333333' + } + ShaderEffect { + id: genieEffect + width: 160; height: width + anchors.centerIn: parent + property variant source: sourceImage + property bool minimized: false + + // #region M1 + property real minimize: 0.0 + + SequentialAnimation on minimize { + id: animMinimize + running: genieEffect.minimized + PauseAnimation { duration: 300 } + NumberAnimation { to: 1; duration: 700; easing.type: Easing.InOutSine } + PauseAnimation { duration: 1000 } + } + + SequentialAnimation on minimize { + id: animNormalize + running: !genieEffect.minimized + NumberAnimation { to: 0; duration: 700; easing.type: Easing.InOutSine } + PauseAnimation { duration: 1300 } + } + // #endregion M1 + + vertexShader: "genie1.vert.qsb" + + MouseArea { + anchors.fill: parent + onClicked: parent.minimized = !parent.minimized + } + } + + +} diff --git a/docs/ch10-effects/src/effects/genie/1/genie1.vert b/docs/ch10-effects/src/effects/genie/1/genie1.vert new file mode 100644 index 00000000..2a09fad7 --- /dev/null +++ b/docs/ch10-effects/src/effects/genie/1/genie1.vert @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +// #region M1 +#version 440 + +layout(location=0) in vec4 qt_Vertex; +layout(location=1) in vec2 qt_MultiTexCoord0; + +layout(location=0) out vec2 qt_TexCoord0; + +layout(std140, binding=0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + + float minimize; + float width; + float height; +} ubuf; + +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() { + qt_TexCoord0 = qt_MultiTexCoord0; + vec4 pos = qt_Vertex; + pos.y = mix(qt_Vertex.y, ubuf.height, ubuf.minimize); + pos.x = mix(qt_Vertex.x, ubuf.width, ubuf.minimize); + gl_Position = ubuf.qt_Matrix * pos; +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/genie/2/genie2.qml b/docs/ch10-effects/src/effects/genie/2/genie2.qml new file mode 100644 index 00000000..885514a6 --- /dev/null +++ b/docs/ch10-effects/src/effects/genie/2/genie2.qml @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +import QtQuick 2.5 + +Rectangle { + width: 480; height: 240 + color: "#1e1e1e" + + Image { + id: sourceImage + width: 160; height: width + source: "../../assets/lighthouse.jpg" + visible: false + } + Rectangle { + width: 160; height: width + anchors.centerIn: parent + color: "#333333" + } + ShaderEffect { + id: genieEffect + width: 160; height: width + anchors.centerIn: parent + property variant source: sourceImage + property real minimize: 0.0 + property bool minimized: false + + + SequentialAnimation on minimize { + id: animMinimize + running: genieEffect.minimized + PauseAnimation { duration: 300 } + NumberAnimation { to: 1; duration: 700; easing.type: Easing.InOutSine } + PauseAnimation { duration: 1000 } + } + + SequentialAnimation on minimize { + id: animNormalize + running: !genieEffect.minimized + NumberAnimation { to: 0; duration: 700; easing.type: Easing.InOutSine } + PauseAnimation { duration: 1300 } + } + + vertexShader: "genie2.vert.qsb" + + MouseArea { + anchors.fill: parent + onClicked: parent.minimized = !parent.minimized + } + } +} diff --git a/docs/ch10-effects/src/effects/genie/2/genie2.vert b/docs/ch10-effects/src/effects/genie/2/genie2.vert new file mode 100644 index 00000000..4b666ad8 --- /dev/null +++ b/docs/ch10-effects/src/effects/genie/2/genie2.vert @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +#version 440 + +layout(location=0) in vec4 qt_Vertex; +layout(location=1) in vec2 qt_MultiTexCoord0; + +layout(location=0) out vec2 qt_TexCoord0; + +layout(std140, binding=0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + + float minimize; + float width; + float height; +} ubuf; + +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() { + qt_TexCoord0 = qt_MultiTexCoord0; +// #region M1 + vec4 pos = qt_Vertex; + pos.y = mix(qt_Vertex.y, ubuf.height, ubuf.minimize); + float t = pos.y / ubuf.height; + pos.x = mix(qt_Vertex.x, ubuf.width, t * ubuf.minimize); +// #endregion M1 + gl_Position = ubuf.qt_Matrix * pos; +} diff --git a/docs/ch10-effects/src/effects/genie/3/genie3.qml b/docs/ch10-effects/src/effects/genie/3/genie3.qml new file mode 100644 index 00000000..3198b061 --- /dev/null +++ b/docs/ch10-effects/src/effects/genie/3/genie3.qml @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +import QtQuick + +Rectangle { + width: 480; height: 240 + color: '#1e1e1e' + + Image { + id: sourceImage + width: 160; height: width + source: "../../assets/lighthouse.jpg" + visible: false + } + Rectangle { + width: 160; height: width + anchors.centerIn: parent + color: '#333333' + } + ShaderEffect { + id: genieEffect + width: 160; height: width + anchors.centerIn: parent + property variant source: sourceImage + // adding a mesh + mesh: GridMesh { resolution: Qt.size(16, 16) } + property real minimize: 0.0 + // adding bend + // #region M1 + property real bend: 0.0 + property bool minimized: false + + + // change to parallel animation + ParallelAnimation { + id: animMinimize + running: genieEffect.minimized + SequentialAnimation { + PauseAnimation { duration: 300 } + NumberAnimation { + target: genieEffect; property: 'minimize'; + to: 1; duration: 700; + easing.type: Easing.InOutSine + } + PauseAnimation { duration: 1000 } + } + // adding bend animation + SequentialAnimation { + NumberAnimation { + target: genieEffect; property: 'bend' + to: 1; duration: 700; + easing.type: Easing.InOutSine } + PauseAnimation { duration: 1300 } + } + } + // #endregion M1 + + ParallelAnimation { + id: animNormalize + running: !genieEffect.minimized + SequentialAnimation { + NumberAnimation { + target: genieEffect; property: 'minimize'; + to: 0; duration: 700; + easing.type: Easing.InOutSine + } + PauseAnimation { duration: 1300 } + } + // adding bend animation + SequentialAnimation { + PauseAnimation { duration: 300 } + NumberAnimation { + target: genieEffect; property: 'bend' + to: 0; duration: 700; + easing.type: Easing.InOutSine } + PauseAnimation { duration: 1000 } + } + } + + vertexShader: "genie3.vert.qsb" + + MouseArea { + anchors.fill: parent + onClicked: parent.minimized = !parent.minimized + } + } + + +} diff --git a/docs/ch10-effects/src/effects/genie/3/genie3.vert b/docs/ch10-effects/src/effects/genie/3/genie3.vert new file mode 100644 index 00000000..589b0c2f --- /dev/null +++ b/docs/ch10-effects/src/effects/genie/3/genie3.vert @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +// #region M1 +#version 440 + +layout(location=0) in vec4 qt_Vertex; +layout(location=1) in vec2 qt_MultiTexCoord0; + +layout(location=0) out vec2 qt_TexCoord0; + +layout(std140, binding=0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + + float minimize; + float width; + float height; + float bend; +} ubuf; + +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() { + qt_TexCoord0 = qt_MultiTexCoord0; + vec4 pos = qt_Vertex; + pos.y = mix(qt_Vertex.y, ubuf.height, ubuf.minimize); + float t = pos.y / ubuf.height; + t = (3.0 - 2.0 * t) * t * t; + pos.x = mix(qt_Vertex.x, ubuf.width, t * ubuf.bend); + gl_Position = ubuf.qt_Matrix * pos; +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/genie/4/genie4.qml b/docs/ch10-effects/src/effects/genie/4/genie4.qml new file mode 100644 index 00000000..3c0268b2 --- /dev/null +++ b/docs/ch10-effects/src/effects/genie/4/genie4.qml @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +// M1>> +import QtQuick + +Rectangle { + width: 480; height: 240 + color: '#1e1e1e' + + Image { + id: sourceImage + width: 160; height: width + source: "../../assets/lighthouse.jpg" + visible: false + } + Rectangle { + width: 160; height: width + anchors.centerIn: parent + color: '#333333' + } + ShaderEffect { + id: genieEffect + width: 160; height: width + anchors.centerIn: parent + property variant source: sourceImage + mesh: GridMesh { resolution: Qt.size(10, 10) } + property real minimize: 0.0 + property real bend: 0.0 + property bool minimized: false + property real side: 0.5 + + + ParallelAnimation { + id: animMinimize + running: genieEffect.minimized + SequentialAnimation { + PauseAnimation { duration: 300 } + NumberAnimation { + target: genieEffect; property: 'minimize'; + to: 1; duration: 700; + easing.type: Easing.InOutSine + } + PauseAnimation { duration: 1000 } + } + SequentialAnimation { + NumberAnimation { + target: genieEffect; property: 'bend' + to: 1; duration: 700; + easing.type: Easing.InOutSine } + PauseAnimation { duration: 1300 } + } + } + + ParallelAnimation { + id: animNormalize + running: !genieEffect.minimized + SequentialAnimation { + NumberAnimation { + target: genieEffect; property: 'minimize'; + to: 0; duration: 700; + easing.type: Easing.InOutSine + } + PauseAnimation { duration: 1300 } + } + SequentialAnimation { + PauseAnimation { duration: 300 } + NumberAnimation { + target: genieEffect; property: 'bend' + to: 0; duration: 700; + easing.type: Easing.InOutSine } + PauseAnimation { duration: 1000 } + } + } + + vertexShader: "genie4.vert.qsb" + + MouseArea { + anchors.fill: parent + onClicked: parent.minimized = !parent.minimized + } + } +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/genie/4/genie4.vert b/docs/ch10-effects/src/effects/genie/4/genie4.vert new file mode 100644 index 00000000..8b61af41 --- /dev/null +++ b/docs/ch10-effects/src/effects/genie/4/genie4.vert @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +// #region M1 +#version 440 + +layout(location=0) in vec4 qt_Vertex; +layout(location=1) in vec2 qt_MultiTexCoord0; + +layout(location=0) out vec2 qt_TexCoord0; + +layout(std140, binding=0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + + float minimize; + float width; + float height; + float bend; + float side; +} ubuf; + +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() { + qt_TexCoord0 = qt_MultiTexCoord0; + vec4 pos = qt_Vertex; + pos.y = mix(qt_Vertex.y, ubuf.height, ubuf.minimize); + float t = pos.y / ubuf.height; + t = (3.0 - 2.0 * t) * t * t; + pos.x = mix(qt_Vertex.x, ubuf.side * ubuf.width, t * ubuf.bend); + gl_Position = ubuf.qt_Matrix * pos; +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/GenieEffect.qml b/docs/ch10-effects/src/effects/genie/GenieEffect.qml similarity index 100% rename from docs/ch10-effects/src/effects/GenieEffect.qml rename to docs/ch10-effects/src/effects/genie/GenieEffect.qml diff --git a/docs/ch10-effects/src/effects/genie/demo/GenieEffect.qml b/docs/ch10-effects/src/effects/genie/demo/GenieEffect.qml new file mode 100644 index 00000000..987a9832 --- /dev/null +++ b/docs/ch10-effects/src/effects/genie/demo/GenieEffect.qml @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +// #region M1 +// GenieEffect.qml +import QtQuick + +ShaderEffect { + id: genieEffect + width: 160; height: width + anchors.centerIn: parent + property variant source + mesh: GridMesh { resolution: Qt.size(10, 10) } + property real minimize: 0.0 + property real bend: 0.0 + property bool minimized: false + property real side: 1.0 + + + ParallelAnimation { + id: animMinimize + running: genieEffect.minimized + SequentialAnimation { + PauseAnimation { duration: 300 } + NumberAnimation { + target: genieEffect; property: 'minimize'; + to: 1; duration: 700; + easing.type: Easing.InOutSine + } + PauseAnimation { duration: 1000 } + } + SequentialAnimation { + NumberAnimation { + target: genieEffect; property: 'bend' + to: 1; duration: 700; + easing.type: Easing.InOutSine } + PauseAnimation { duration: 1300 } + } + } + + ParallelAnimation { + id: animNormalize + running: !genieEffect.minimized + SequentialAnimation { + NumberAnimation { + target: genieEffect; property: 'minimize'; + to: 0; duration: 700; + easing.type: Easing.InOutSine + } + PauseAnimation { duration: 1300 } + } + SequentialAnimation { + PauseAnimation { duration: 300 } + NumberAnimation { + target: genieEffect; property: 'bend' + to: 0; duration: 700; + easing.type: Easing.InOutSine } + PauseAnimation { duration: 1000 } + } + } + + vertexShader: "genieeffect.vert.qsb" +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/genie/demo/geniedemo.qml b/docs/ch10-effects/src/effects/genie/demo/geniedemo.qml new file mode 100644 index 00000000..e51496c1 --- /dev/null +++ b/docs/ch10-effects/src/effects/genie/demo/geniedemo.qml @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +// #region M1 +import QtQuick + +Rectangle { + width: 480; height: 240 + color: '#1e1e1e' + + GenieEffect { + source: Image { source: '../../assets/lighthouse.jpg' } + MouseArea { + anchors.fill: parent + onClicked: parent.minimized = !parent.minimized + } + } +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/genie/demo/genieeffect.vert b/docs/ch10-effects/src/effects/genie/demo/genieeffect.vert new file mode 100644 index 00000000..c9cf60fb --- /dev/null +++ b/docs/ch10-effects/src/effects/genie/demo/genieeffect.vert @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +// #region M1 +// genieeffect.vert +#version 440 + +layout(location=0) in vec4 qt_Vertex; +layout(location=1) in vec2 qt_MultiTexCoord0; + +layout(location=0) out vec2 qt_TexCoord0; + +layout(std140, binding=0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + + float minimize; + float width; + float height; + float bend; + float side; +} ubuf; + +out gl_PerVertex { + vec4 gl_Position; +}; + +void main() { + qt_TexCoord0 = qt_MultiTexCoord0; + vec4 pos = qt_Vertex; + pos.y = mix(qt_Vertex.y, ubuf.height, ubuf.minimize); + float t = pos.y / ubuf.height; + t = (3.0 - 2.0 * t) * t * t; + pos.x = mix(qt_Vertex.x, ubuf.side * ubuf.width, t * ubuf.bend); + gl_Position = ubuf.qt_Matrix * pos; +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/genie.qml b/docs/ch10-effects/src/effects/genie/genie.qml similarity index 100% rename from docs/ch10-effects/src/effects/genie.qml rename to docs/ch10-effects/src/effects/genie/genie.qml diff --git a/docs/ch10-effects/src/effects/genie0.qml b/docs/ch10-effects/src/effects/genie/genie0.qml similarity index 100% rename from docs/ch10-effects/src/effects/genie0.qml rename to docs/ch10-effects/src/effects/genie/genie0.qml diff --git a/docs/ch10-effects/src/effects/genie1.qml b/docs/ch10-effects/src/effects/genie/genie1.qml similarity index 100% rename from docs/ch10-effects/src/effects/genie1.qml rename to docs/ch10-effects/src/effects/genie/genie1.qml diff --git a/docs/ch10-effects/src/effects/genie2.qml b/docs/ch10-effects/src/effects/genie/genie2.qml similarity index 100% rename from docs/ch10-effects/src/effects/genie2.qml rename to docs/ch10-effects/src/effects/genie/genie2.qml diff --git a/docs/ch10-effects/src/effects/genie3.qml b/docs/ch10-effects/src/effects/genie/genie3.qml similarity index 100% rename from docs/ch10-effects/src/effects/genie3.qml rename to docs/ch10-effects/src/effects/genie/genie3.qml diff --git a/docs/ch10-effects/src/effects/genie4.qml b/docs/ch10-effects/src/effects/genie/genie4.qml similarity index 100% rename from docs/ch10-effects/src/effects/genie4.qml rename to docs/ch10-effects/src/effects/genie/genie4.qml diff --git a/docs/ch10-effects/src/effects/geniedemo.qml b/docs/ch10-effects/src/effects/genie/geniedemo.qml similarity index 100% rename from docs/ch10-effects/src/effects/geniedemo.qml rename to docs/ch10-effects/src/effects/genie/geniedemo.qml diff --git a/docs/ch10-effects/src/effects/redlense1.qml b/docs/ch10-effects/src/effects/redlense/1/redlense1.qml similarity index 95% rename from docs/ch10-effects/src/effects/redlense1.qml rename to docs/ch10-effects/src/effects/redlense/1/redlense1.qml index 27927e77..976da352 100644 --- a/docs/ch10-effects/src/effects/redlense1.qml +++ b/docs/ch10-effects/src/effects/redlense/1/redlense1.qml @@ -25,8 +25,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// M1>> -import QtQuick 2.5 +// #region M1 +import QtQuick Rectangle { width: 480; height: 240 @@ -39,8 +39,8 @@ Rectangle { Image { id: sourceImage width: 80; height: width - source: 'assets/tulips.jpg' + source: '../../assets/tulips.jpg' } } } -// < 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. + */ + +// #region M1 +#version 440 + +layout(location=0) in vec2 qt_TexCoord0; + +layout(location=0) out vec4 fragColor; + +layout(std140, binding=0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +} ubuf; + +layout(binding=1) uniform sampler2D source; + +void main() { + fragColor = vec4(1.0, 0.0, 0.0, 1.0) * ubuf.qt_Opacity; +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/redlense/2/red2.frag b/docs/ch10-effects/src/effects/redlense/2/red2.frag new file mode 100644 index 00000000..babcd30b --- /dev/null +++ b/docs/ch10-effects/src/effects/redlense/2/red2.frag @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +// #region M1 +#version 440 + +layout(location=0) in vec2 qt_TexCoord0; + +layout(location=0) out vec4 fragColor; + +layout(std140, binding=0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; +} ubuf; + +layout(binding=1) uniform sampler2D source; + +void main() { + fragColor = texture(source, qt_TexCoord0) * vec4(1.0, 0.0, 0.0, 1.0) * ubuf.qt_Opacity; +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/redlense/2/red3.frag b/docs/ch10-effects/src/effects/redlense/2/red3.frag new file mode 100644 index 00000000..4e7bb818 --- /dev/null +++ b/docs/ch10-effects/src/effects/redlense/2/red3.frag @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Juergen Bocklage-Ryannel, Johan Thelin + * All rights reserved. + * + * 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 editors 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 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. + */ + +// #region M1 +#version 440 + +layout(location=0) in vec2 qt_TexCoord0; + +layout(location=0) out vec4 fragColor; + +layout(std140, binding=0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + + float redChannel; +} ubuf; + +layout(binding=1) uniform sampler2D source; + +void main() { + fragColor = texture(source, qt_TexCoord0) * vec4(ubuf.redChannel, 1.0, 1.0, 1.0) * ubuf.qt_Opacity; +} +// #endregion M1 diff --git a/docs/ch10-effects/src/effects/defaultshader.qml b/docs/ch10-effects/src/effects/redlense/2/redlense2.qml similarity index 67% rename from docs/ch10-effects/src/effects/defaultshader.qml rename to docs/ch10-effects/src/effects/redlense/2/redlense2.qml index c929cc33..4ba34ca0 100644 --- a/docs/ch10-effects/src/effects/defaultshader.qml +++ b/docs/ch10-effects/src/effects/redlense/2/redlense2.qml @@ -25,50 +25,62 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// M1>> -import QtQuick 2.5 +import QtQuick Rectangle { + id: root width: 480; height: 240 color: '#1e1e1e' + property int step: 4 - Row { + Grid { anchors.centerIn: parent spacing: 20 + rows: 2; columns: 4 Image { id: sourceImage width: 80; height: width - source: 'assets/tulips.jpg' + source: '../../assets/tulips.jpg' } + ShaderEffect { - id: effect + id: effect1 width: 80; height: width - property variant source: sourceImage + visible: root.step>0 + fragmentShader: "red1.frag.qsb" } + ShaderEffect { id: effect2 width: 80; height: width - // the source where the effect shall be applied to property variant source: sourceImage - // default vertex shader code - vertexShader: " - uniform highp mat4 qt_Matrix; - attribute highp vec4 qt_Vertex; - attribute highp vec2 qt_MultiTexCoord0; - varying highp vec2 qt_TexCoord0; - void main() { - qt_TexCoord0 = qt_MultiTexCoord0; - gl_Position = qt_Matrix * qt_Vertex; - }" - // default fragment shader code - fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform sampler2D source; - uniform lowp float qt_Opacity; - void main() { - gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity; - }" + visible: root.step>1 + fragmentShader: "red2.frag.qsb" } + + ShaderEffect { + id: effect3 + width: 80; height: width + property variant source: sourceImage + property real redChannel: 0.3 + visible: root.step>2 + fragmentShader: "red3.frag.qsb" + } + + // #region M1 + ShaderEffect { + id: effect4 + width: 80; height: width + property variant source: sourceImage + property real redChannel: 0.3 + visible: root.step>3 + NumberAnimation on redChannel { + from: 0.0; to: 1.0; loops: Animation.Infinite; duration: 4000 + } + + fragmentShader: "red3.frag.qsb" + } + // #endregion M1 } + } -// < 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. - */ - -import QtQuick 2.5 - -Rectangle { - id: root - width: 480; height: 240 - color: '#1e1e1e' - property int step: 4 - - Grid { - anchors.centerIn: parent - spacing: 20 - rows: 2; columns: 4 - Image { - id: sourceImage - width: 80; height: width - source: 'assets/tulips.jpg' - } - ShaderEffect { - id: effect1 - width: 80; height: width - visible: root.step>0 - // M1>> - fragmentShader: " - uniform lowp float qt_Opacity; - void main() { - gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0) * qt_Opacity; - }" - // <> - ShaderEffect { - id: effect2 - width: 80; height: width - property variant source: sourceImage - visible: root.step>1 - fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform sampler2D source; - uniform lowp float qt_Opacity; - void main() { - gl_FragColor = texture2D(source, qt_TexCoord0) * vec4(1.0, 0.0, 0.0, 1.0) * qt_Opacity; - }" - } - // <> - ShaderEffect { - id: effect3 - width: 80; height: width - property variant source: sourceImage - property real redChannel: 0.3 - visible: root.step>2 - fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform sampler2D source; - uniform lowp float qt_Opacity; - uniform lowp float redChannel; - void main() { - gl_FragColor = texture2D(source, qt_TexCoord0) * vec4(redChannel, 1.0, 1.0, 1.0) * qt_Opacity; - }" - } - // <> - ShaderEffect { - id: effect4 - width: 80; height: width - property variant source: sourceImage - property real redChannel: 0.3 - visible: root.step>3 - NumberAnimation on redChannel { - from: 0.0; to: 1.0; loops: Animation.Infinite; duration: 4000 - } - - fragmentShader: " - varying highp vec2 qt_TexCoord0; - uniform sampler2D source; - uniform lowp float qt_Opacity; - uniform lowp float redChannel; - void main() { - gl_FragColor = texture2D(source, qt_TexCoord0) * vec4(redChannel, 1.0, 1.0, 1.0) * qt_Opacity; - }" - } - // <