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. Question about Qt Quick Shader (4.8)
Forum Updated to NodeBB v4.3 + New Features

Question about Qt Quick Shader (4.8)

Scheduled Pinned Locked Moved QML and Qt Quick
4 Posts 2 Posters 2.8k Views 1 Watching
  • 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.
  • H Offline
    H Offline
    hailong
    wrote on last edited by
    #1

    Hi, I want to use Qt Quick shader to generate a Rotating Rectangle animation, I tried the following code at first:
    @import QtQuick 1.1
    import Qt.labs.shaders 1.0
    Item{
    id:container
    width: 800
    height: 800
    Rectangle {id: bookpage;
    color:"yellow"
    width: parent.width/2;
    height: parent.height}
    Rectangle {id: bookpage2;
    color: "green"
    width: parent.width/2;
    height: parent.height}
    ShaderEffectItem {
    width: parent.width/2
    height: parent.height
    meshResolution: Qt.size(10, 10)

        property variant frontSource: ShaderEffectSource { sourceItem: bookpage; hideSource: true }
        property variant backSource: ShaderEffectSource { sourceItem: bookpage2; hideSource: true }
        property real t: 1
    
        SequentialAnimation on t {
            loops: Animation.Infinite
            NumberAnimation { to: 0; duration: 2000; easing.type: Easing.Linear }
            PauseAnimation { duration: 1600 }
            NumberAnimation { to: 1; duration: 2000; easing.type: Easing.Linear }
            PauseAnimation { duration: 1600 }
        }
    
        vertexShader:"
        uniform highp mat4 qt_ModelViewProjectionMatrix;
        attribute highp vec4 qt_Vertex;
        attribute highp vec2 qt_MultiTexCoord0;
        varying highp vec2 qt_TexCoord0;
        uniform highp float t;
    
        void main() {
            const float M_PI = 3.14159265358979323846;
            float rho = t*M_PI;
    
                qt_TexCoord0 = qt_MultiTexCoord0;
                highp vec4 pos = qt_Vertex;
    
                pos.x = pos.x*cos(rho)-pos.z*sin(rho);
                pos.y = pos.y;
                pos.z = pos.x*sin(rho)+pos.z*cos(rho);
                gl_Position =  qt_ModelViewProjectionMatrix * pos;
            }"
        fragmentShader: "
            uniform sampler2D frontSource;
            uniform sampler2D backSource;
            uniform lowp float qt_Opacity;
            varying highp vec2 qt_TexCoord0;
            varying lowp float shade;
            void main() {
                gl_FragColor = (gl_FrontFacing ? texture2D(frontSource, qt_TexCoord0)
                                               : texture2D(backSource, qt_TexCoord0))
                              * qt_Opacity;
            }
        "
    }
    

    }
    @

    But I don't get what I want, the rectangle rotated around the left edge (I think this is because the origin is in the left-top corner of the GLViewport)and can't see the rotation animation(just some quick flash, why? what is the value of qt_Vertex?)

    Then I tried the following code, just change pos "highp vec4 pos = qt_ModelViewProjectionMatrix * qt_Vertex; "
    @
    import QtQuick 1.1
    import Qt.labs.shaders 1.0

    Item{
    id:container
    width: 800
    height: 800
    Rectangle {id: bookpage;
    color:"yellow"
    width: parent.width/2;
    height: parent.height}
    Rectangle {id: bookpage2;
    color: "green"
    width: parent.width/2;
    height: parent.height}
    ShaderEffectItem {
    width: parent.width/2
    height: parent.height
    meshResolution: Qt.size(10, 10)

        property variant frontSource: ShaderEffectSource { sourceItem: bookpage; hideSource: true }
        property variant backSource: ShaderEffectSource { sourceItem: bookpage2; hideSource: true }
        property real t: 1
    
        SequentialAnimation on t {
            loops: Animation.Infinite
            NumberAnimation { to: 0; duration: 2000; easing.type: Easing.Linear }
            PauseAnimation { duration: 1600 }
            NumberAnimation { to: 1; duration: 2000; easing.type: Easing.Linear }
            PauseAnimation { duration: 1600 }
        }
    
        vertexShader:"
        uniform highp mat4 qt_ModelViewProjectionMatrix;
        attribute highp vec4 qt_Vertex;
        attribute highp vec2 qt_MultiTexCoord0;
        varying highp vec2 qt_TexCoord0;
        uniform highp float t;
    
        void main() {
            const float M_PI = 3.14159265358979323846;
            float rho = t*M_PI;
    
                qt_TexCoord0 = qt_MultiTexCoord0;
                highp vec4 pos = qt_ModelViewProjectionMatrix * qt_Vertex;
    
                pos.x = pos.x*cos(rho)-pos.z*sin(rho);
                pos.y = pos.y;
                pos.z = pos.x*sin(rho)+pos.z*cos(rho);
                gl_Position =  pos;
            }"
        fragmentShader: "
            uniform sampler2D frontSource;
            uniform sampler2D backSource;
            uniform lowp float qt_Opacity;
            varying highp vec2 qt_TexCoord0;
            varying lowp float shade;
            void main() {
                gl_FragColor = (gl_FrontFacing ? texture2D(frontSource, qt_TexCoord0)
                                               : texture2D(backSource, qt_TexCoord0))
                              * qt_Opacity;
            }
        "
    }
    

    }

    @

    I got what I want :) (after "qt_ModelViewProjectionMatrix * qt_Vertex", I find the geometry turns into [
    (-1,-1), (1,-1)
    (-1,1) , (1,1)
    ]) so the y axis is in the center of the glwidget so my rectangle rotates around the center of the GLWidget, but why it doesn't flash any more?

    to be continued :)

    1 Reply Last reply
    0
    • H Offline
      H Offline
      hailong
      wrote on last edited by
      #2

      third: I want to add a menu on the left and show the rotating rectangle on the right: this is the code
      @
      import QtQuick 1.1
      import Qt.labs.shaders 1.0
      Item
      {
      width: 900
      height: 800
      Rectangle{
      id:rect
      color : "black"
      width: 100
      height: 800
      }
      Item{
      id:container
      width: 800
      height: 800
      anchors.left: rect.right
      Rectangle {id: bookpage;
      color:"yellow"
      width: parent.width/2;
      height: parent.height}
      Rectangle {id: bookpage2;
      color: "green"
      width: parent.width/2;
      height: parent.height}
      ShaderEffectItem {
      width: parent.width/2
      height: parent.height
      meshResolution: Qt.size(10, 10)

          property variant frontSource: ShaderEffectSource { sourceItem: bookpage; hideSource: true }
          property variant backSource: ShaderEffectSource { sourceItem: bookpage2; hideSource: true }
          property real t: 1
      
          SequentialAnimation on t {
              loops: Animation.Infinite
              NumberAnimation { to: 0; duration: 2000; easing.type: Easing.Linear }
              PauseAnimation { duration: 1600 }
              NumberAnimation { to: 1; duration: 2000; easing.type: Easing.Linear }
              PauseAnimation { duration: 1600 }
          }
      
          vertexShader:"
          uniform highp mat4 qt_ModelViewProjectionMatrix;
          attribute highp vec4 qt_Vertex;
          attribute highp vec2 qt_MultiTexCoord0;
          varying highp vec2 qt_TexCoord0;
          uniform highp float t;
      
          void main() {
              const float M_PI = 3.14159265358979323846;
              float rho = t*M_PI;
      
                  qt_TexCoord0 = qt_MultiTexCoord0;
                  highp vec4 pos = qt_ModelViewProjectionMatrix * qt_Vertex;
      
                  pos.x = pos.x*cos(rho)-pos.z*sin(rho);
                  pos.y = pos.y;
                  pos.z = pos.x*sin(rho)+pos.z*cos(rho);
                  gl_Position =  pos;
              }"
          fragmentShader: "
              uniform sampler2D frontSource;
              uniform sampler2D backSource;
              uniform lowp float qt_Opacity;
              varying highp vec2 qt_TexCoord0;
              varying lowp float shade;
              void main() {
                  gl_FragColor = (gl_FrontFacing ? texture2D(frontSource, qt_TexCoord0)
                                                 : texture2D(backSource, qt_TexCoord0))
                                * qt_Opacity;
              }
          "
      }
      

      }
      }
      @
      but the rotation breaks, seems that the rotating rectangle item can't find the Y axis correctly, I think because qt_ModelViewProjectionMatrix will only map the result to the whole viewport ,and the y axis for the whole viewport is in the center of the GLWidget, but my item's center is not the center of the viewport, so I need to move the rectangle's edge to the center so I can rotate around the y axis then I move the item back, am I right?

      How can I put my rotating rectangle item anywhere I want(I mean to make it a child for an item(call this parent item A) and position it inside Item A) in the glWidget? Can I change the viewport Matrix to the child item area(so the Y axis is in the center of the child item instead of the GLWidget)?
      I am new to 3d programming and opengl and I have tried to solve this for two days, can anyone help me? It is better if you can tell me how to debug shader(just output some value of the shader, eg. the vertex value?)

      1 Reply Last reply
      0
      • H Offline
        H Offline
        hailong
        wrote on last edited by
        #3

        any help?

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SDubitskiy
          wrote on last edited by
          #4

          Hello.


          First, this code

          @pos.x = pos.xcos(rho)-pos.zsin(rho);
          pos.y = pos.y;
          pos.z = pos.xsin(rho)+pos.zcos(rho);
          @

          is incorrect, because pos.x will be modified already by the time you calculate new pos.z.
          You will need to use temporary variables to avoid this.


          Second,
          your code rotates vertices around the origin of coordinate system.
          The trick to rotate things around arbitrary point is three step process:

          1. shift your geometry by {-rotation_origin.x,0,-rotation_origin.z}
          2. rotate
          3. shift your geometry back by {rotation_origin.x,0,rotation_origin.z}

          In your case I would add uniforms for rotation origin:
          @
          uniform highp float rotation_origin_x;
          uniform highp float rotation_origin_z;
          @

          and modify rotation code like this:

          @
          float tmpX = pos.x - rotation_origin_x;
          float tmpZ = pos.z - rotation_origin_z;

          pos.x = tmpXcos(rho)-tmpZsin(rho);
          pos.z = tmpXsin(rho)+tmpZcos(rho);

          pos.x += rotation_origin_x;
          pos.z += rotation_origin_z;
          @

          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