Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Scrolling Background in QtQuick
QtWS25 Last Chance

Scrolling Background in QtQuick

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
10 Posts 5 Posters 3.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    rmds
    wrote on last edited by
    #1

    Hey Guys,

    Im trying to get an image to scroll horizontally tiled indefinitely in the back ground. Here is what I currently have

    import QtQuick 2.0
    
    Item {
        anchors.fill: parent
    
        // *** Background image ***
        Image {
            id: backgroundImage
            width: parent.width
            height: parent.height
            source: "images/diver_background_sea.png"
            //anchors.fill: parent
            //fillMode: Image.TileHorizontally
            //cache: false
            mirror: true
            //horizontalAlignment: Image.AlignLeft
            /* Parallax Scrolling
            x: ­gameView.width/8.0 – boardFlickable.contentX/4.0
            y: ­gameView.height/8.0 – boardFlickable.contentY/4.0
            */
            NumberAnimation on x {
                duration: 6000000
                to: -80000
            }
        }
    }
    

    When the image reaches the edge the background shows up, I would like it so that instead of the background showing up the image would just be tiled horizontally forever. I tried setting tiled Horizontally but it only tiled once.

    1 Reply Last reply
    0
    • timdayT Offline
      timdayT Offline
      timday
      wrote on last edited by timday
      #2

      I don't think animating x is doing what you think it is... it's actually moving the image item around. Tiling doesn't tile the image pixels outside the Image item into the surrounding area, so you get to see the background.

      One possible solution might be to use a layer.effect to modify how pixels are mapped from image to screen:

      import QtQuick 2.7
      
      Rectangle {
        width: 400
        height: 300
        color: 'black'
      
        Image {
          anchors.fill: parent
          source: 'http://www.placecage.com/c/200/300'
          fillMode: Image.Tile
          layer.enabled: true
          layer.wrapMode: ShaderEffectSource.Repeat
          layer.effect: ShaderEffect {
            NumberAnimation on displacement {
              duration: 2500
              from: 0.0
              to: 1.0
              loops: Animation.Infinite
            }
            property variant displacement: 0.0
            fragmentShader: "
              uniform highp float displacement;
              uniform lowp sampler2D source;
              uniform lowp float qt_Opacity; // inherited opacity of this item
              varying highp vec2 qt_TexCoord0;
              void main() {
                gl_FragColor = qt_Opacity*texture2D(source,qt_TexCoord0-vec2(displacement,0.0));
              }"
          }
        }
      }
      

      (runs in Qt 5.9.1's qmlscene). Not sure if that's overkill and there's a simpler way. (I did try something using sourceRect instead of layer but it seems to be applied on the wrong side of the tiling to be useful).

      1 Reply Last reply
      2
      • R Offline
        R Offline
        rmds
        wrote on last edited by
        #3

        Thanks for the quick reply. That was what my goal was when I used animating x, was to move the image around but wrapped around.

        I just tried your code with my image and it worked great!
        Just a question using my image or the sample image it doesn't line up correctly a certain point. Is there anyway to fix this?

        Also I would like to mirror the image then tile is this possible with the shaders?

        timdayT 1 Reply Last reply
        0
        • R rmds

          Thanks for the quick reply. That was what my goal was when I used animating x, was to move the image around but wrapped around.

          I just tried your code with my image and it worked great!
          Just a question using my image or the sample image it doesn't line up correctly a certain point. Is there anyway to fix this?

          Also I would like to mirror the image then tile is this possible with the shaders?

          timdayT Offline
          timdayT Offline
          timday
          wrote on last edited by
          #4

          @rmds Not sure what you mean about it not lining up correctly at a certain point... there is some mention in the docs about layer.wrapMode: ShaderEffectSource.Repeat might need a power-of-two sized image on some HW.... I'd be surprised to run into that restriction still on modern HW though.

          To make a background using alternating regular & mirrored images, that's easily done with Image's mirror property:

          import QtQuick 2.7
          
          Rectangle {
            width: 400
            height: 300
            color: 'black'
          
            Row {
              anchors.fill: parent
          
              Image {
                source: 'http://www.placecage.com/c/200/300'
                fillMode: Image.Tile
              }
              Image {
                source: 'http://www.placecage.com/c/200/300'
                fillMode: Image.Tile
                mirror: true
              }
              
              layer.enabled: true
              layer.wrapMode: ShaderEffectSource.Repeat
              layer.effect: ShaderEffect {
                NumberAnimation on displacement {
                  duration: 2500
                  from: 0.0
                  to: 1.0
                  loops: Animation.Infinite
                }
                property variant displacement: 0.0
                fragmentShader: "
                  uniform highp float displacement;
                  uniform lowp sampler2D source;
                  uniform lowp float qt_Opacity; // inherited opacity of this item
                  varying highp vec2 qt_TexCoord0;
                  void main() {
                    gl_FragColor = qt_Opacity*texture2D(source,qt_TexCoord0-vec2(displacement,0.0));
                  }"
              }
            }
          }
          

          The same effect could probably also be achieved in the original version by using a more complex expression in the shader, but repeating the pair of images seems a simple enough enough.

          1 Reply Last reply
          1
          • R Offline
            R Offline
            rmds
            wrote on last edited by rmds
            #5

            Hey Tim

            I tried your mirroring example and it works how ever I still get the problem mentioned earlier.

            If you look at the image below, in red you the image over laps with itself at a certain point, how do I prevent this? Thats what I meant by the not lining up correctly at a certain point (ignore the screen tearing)
            alt text

            I tried it with an image which the size was 1024x1024 (power of 2) and same result

            Thanks for the additional examples

            timdayT 1 Reply Last reply
            0
            • R rmds

              Hey Tim

              I tried your mirroring example and it works how ever I still get the problem mentioned earlier.

              If you look at the image below, in red you the image over laps with itself at a certain point, how do I prevent this? Thats what I meant by the not lining up correctly at a certain point (ignore the screen tearing)
              alt text

              I tried it with an image which the size was 1024x1024 (power of 2) and same result

              Thanks for the additional examples

              timdayT Offline
              timdayT Offline
              timday
              wrote on last edited by
              #6

              @rmds Strange... it didn't do that for me. What graphics hardware are you using? I forget which machine I was running my code on... but it was probably an NVidia card or relatively recent Intel embedded graphics.

              1 Reply Last reply
              0
              • R Offline
                R Offline
                rmds
                wrote on last edited by
                #7

                I tried it on a machine with a Nvidia GeForce 310, and on a virtual machine running on another machine running an i7-6600u (laptop). Same result on both

                Y 1 Reply Last reply
                0
                • GTDevG Offline
                  GTDevG Offline
                  GTDev
                  wrote on last edited by
                  #8

                  Hi,
                  You can also have a look at V-Play Engine for qt-based mobile app and game development.

                  It offers a ParallaxScrollingBackground component which can create endless loops by mirroring an image, or by alternating two images.

                  import VPlay 2.0
                  
                  GameWindow {
                  
                    ParallaxScrollingBackground {
                      movementVelocity: Qt.point(10,0)
                      sourceImage: Qt.resolvedUrl("../assets/vplay-logo.png")
                    }
                  
                  }
                  

                  Best,
                  GTDev

                  Senior Developer at Felgo - https://felgo.com/qt

                  Develop mobile Apps for iOS & Android with Qt
                  Felgo is an official Qt Technology Partner

                  1 Reply Last reply
                  0
                  • R rmds

                    I tried it on a machine with a Nvidia GeForce 310, and on a virtual machine running on another machine running an i7-6600u (laptop). Same result on both

                    Y Offline
                    Y Offline
                    Yohan07
                    wrote on last edited by Yohan07
                    #9

                    @rmds Try this :

                        import QtQuick 2.13
                        import QtQuick.Window 2.13
                    
                        Window {
                          id: root
                          visible: true
                          width: 800
                          height: 600
                          title: qsTr("Scrolling background !")
                    
                        Row { 
                        // don't use anchors.fill !
                    
                        Image {
                            source: "http://www.placecage.com/c/200/300"
                            fillMode: Image.PreserveAspectFit
                        }
                    
                        layer.enabled: true
                        layer.wrapMode: ShaderEffectSource.Repeat
                        layer.effect: ShaderEffect {
                            NumberAnimation on displacement { duration: 2500; from: 1.0; to: 0.0; loops: Animation.Infinite }
                            property variant displacement: 0.0
                            fragmentShader: "
                            uniform highp float displacement;
                                uniform lowp sampler2D source;
                                uniform lowp float qt_Opacity;
                                varying highp vec2 qt_TexCoord0;
                                void main() {
                                  gl_FragColor = qt_Opacity*texture2D(source,qt_TexCoord0-vec2(displacement,0.0));
                            }"
                        } // End ShaderEffect
                     } // End Row
                     } // End Window
                    
                    MarkkyboyM 1 Reply Last reply
                    1
                    • Y Yohan07

                      @rmds Try this :

                          import QtQuick 2.13
                          import QtQuick.Window 2.13
                      
                          Window {
                            id: root
                            visible: true
                            width: 800
                            height: 600
                            title: qsTr("Scrolling background !")
                      
                          Row { 
                          // don't use anchors.fill !
                      
                          Image {
                              source: "http://www.placecage.com/c/200/300"
                              fillMode: Image.PreserveAspectFit
                          }
                      
                          layer.enabled: true
                          layer.wrapMode: ShaderEffectSource.Repeat
                          layer.effect: ShaderEffect {
                              NumberAnimation on displacement { duration: 2500; from: 1.0; to: 0.0; loops: Animation.Infinite }
                              property variant displacement: 0.0
                              fragmentShader: "
                              uniform highp float displacement;
                                  uniform lowp sampler2D source;
                                  uniform lowp float qt_Opacity;
                                  varying highp vec2 qt_TexCoord0;
                                  void main() {
                                    gl_FragColor = qt_Opacity*texture2D(source,qt_TexCoord0-vec2(displacement,0.0));
                              }"
                          } // End ShaderEffect
                       } // End Row
                       } // End Window
                      
                      MarkkyboyM Offline
                      MarkkyboyM Offline
                      Markkyboy
                      wrote on last edited by
                      #10

                      @Yohan07 - yes, this works with some very minor adjustments, very useful! :)

                      Don't just sit there standing around, pick up a shovel and sweep up!

                      I live by the sea, not in it.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved