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. QML Circular Gauge Styling - Needle trailing colour/glow
QtWS25 Call for Papers

QML Circular Gauge Styling - Needle trailing colour/glow

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
11 Posts 5 Posters 9.4k 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.
  • J Offline
    J Offline
    jars121
    wrote on last edited by jars121
    #1

    G'day,

    I'm playing with circular gauge styling in QML and am wondering how I could implement a glowing colour trailing the needle like in this gauge:

    0_1522221562391_Screen Shot 2018-03-28 at 6.17.44 pm.png

    In essence, the colour starts off with a high opacity, which gradually diminishes with distance away from the needle.

    Thanks!

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

    ShaderEffect is made for this sort of bling

    I got this:

    QML gauge

    from this:

    import QtQuick 2.2
    
    Rectangle {
      id: main
      width: 512
      height: 512
      color: 'black'
    
      // Put some text in the background just to check opacity
      Text {
        x: main.width/6.0-0.5*contentWidth
        y: main.height/2.0-0.5*contentHeight
        text: '30'
        color: 'white'
      }
      Text {
        x: main.width/2.0-0.5*contentWidth
        y: main.height/6.0-0.5*contentHeight
        text: '60'
        color: 'white'
      }
      Text {
        x: 5.0*main.width/6.0-0.5*contentWidth
        y: main.height/2.0-0.5*contentHeight
        text: '90'
        color: 'white'
      }
    
      // Shader effect to provide gradient-based gauge
      ShaderEffect {
        id: gauge
        anchors.fill: parent
    
        opacity: 0.75  // Making it totally opaque on leading edge obscures the number!
    
        // Angles measured clockwise from up, in range -pi to pi
        property real angleBase: -pi*0.75
        property real angle
    
        readonly property real pi: 3.1415926535897932384626433832795
    
        vertexShader: "
          uniform highp mat4 qt_Matrix;
          attribute highp vec4 qt_Vertex;
          attribute highp vec2 qt_MultiTexCoord0;
          varying highp vec2 coord;
          void main() {
            coord = qt_MultiTexCoord0;
            gl_Position = qt_Matrix * qt_Vertex;
          }"
    
        fragmentShader: "
          uniform lowp float qt_Opacity;
          uniform highp float angleBase;
          uniform highp float angle;
          varying highp vec2 coord;
          void main() {
            gl_FragColor = vec4(0.0,0.0,0.0,0.0);
            highp vec2 d=2.0*coord-vec2(1.0,1.0);
            highp float r=length(d);
            if (0.25<=r && r<=0.75) {
              highp float a=atan2(d.x,-d.y);
              if (angleBase<=a && a<=angle) {
                highp float p=(a-angleBase)/(angle-angleBase);
                gl_FragColor = vec4(0.0,0.0,p,p) * qt_Opacity;
              }
            }
          }"
      }
    
      // Animate the gauge position
      SequentialAnimation {
        running: true
        loops: Animation.Infinite
        NumberAnimation {
          from: gauge.angleBase
          to: gauge.angleBase+1.5*gauge.pi
          duration: 1000
          target: gauge
          property: 'angle'
          easing.type: Easing.InOutSine
        }
        NumberAnimation {
          from: gauge.angleBase+1.5*gauge.pi
          to: gauge.angleBase
          duration: 1000
          target: gauge
          property: 'angle'
          easing.type: Easing.InOutSine
        }
      }
    }
    

    Runs in 5.10.1's qmlscene but no reason it shouldn't work in older versions.

    1 Reply Last reply
    0
  • J Offline
    J Offline
    jars121
    wrote on last edited by
    #3

    That looks like exactly what I'm after! Thanks for bringing this functionality to my attention!

    I'll give it a go this evening and report back with any issues.

    1 Reply Last reply
    0
  • J Offline
    J Offline
    jars121
    wrote on last edited by
    #4

    I've taken the exact code presented above and am receiving the following compilation errors:

    QOpenGLShader::compile(Fragment): ERROR: 0:12: Invalid call of undeclared identifier 'atan2'
    ERROR: 0:13: Use of undeclared identifier 'a'
    ERROR: 0:13: Use of undeclared identifier 'a'
    ERROR: 0:14: Use of undeclared identifier 'a'
    ERROR: 0:15: Use of undeclared identifier 'p'
    ERROR: 0:15: Use of undeclared identifier 'p'
    
    *** Problematic Fragment shader source code ***
    #define lowp
    #define mediump
    #define highp
    #line 1
     
                              uniform lowp float qt_Opacity; 
                              uniform highp float angleBase; 
                              uniform highp float angle; 
                              varying highp vec2 coord; 
                              void main() { 
                                gl_FragColor = vec4(0.0,0.0,0.0,0.0); 
                                highp vec2 d=2.0*coord-vec2(1.0,1.0); 
                                highp float r=length(d); 
                                if (0.25<=r && r<=0.75) { 
                                  highp float a=atan2(d.x,-d.y); 
                                  if (angleBase<=a && a<=angle) { 
                                    highp float p=(a-angleBase)/(angle-angleBase); 
                                    gl_FragColor = vec4(0.0,0.0,p,p) * qt_Opacity; 
                                  } 
                                } 
                              }
    
    ***
    QQuickCustomMaterialShader: Shader compilation failed:
    "ERROR: 0:12: Invalid call of undeclared identifier 'atan2'\nERROR: 0:13: Use of undeclared identifier 'a'\nERROR: 0:13: Use of undeclared identifier 'a'\nERROR: 0:14: Use of undeclared identifier 'a'\nERROR: 0:15: Use of undeclared identifier 'p'\nERROR: 0:15: Use of undeclared identifier 'p'\n"
    

    I've never worked with OpenGL before so am struggling somewhat to make sense of the above.

    raven-worxR 1 Reply Last reply
    0
  • raven-worxR Offline
    raven-worxR Offline
    raven-worx Moderators
    replied to jars121 on last edited by
    #5

    @jars121
    why not simply use a conical gradient? (In conjunction with a opacity mask)

    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
    If you have a question please use the forum so others can benefit from the solution in the future

    1 Reply Last reply
    0
  • J Offline
    J Offline
    jars121
    wrote on last edited by
    #6

    @raven-worx that certainly appears to be simpler! I'll have a play with that approach now and report back, thanks!

    1 Reply Last reply
    0
  • J Offline
    J Offline
    jars121
    wrote on last edited by
    #7

    @raven-worx Thanks again, I've got it working almost 100% now!

    Quick question, is there a way to limit/stop the ConicalMask? At the moment the OpacityMask is working nicely, but when the needle is at very low values, the ConicalMask actually appears on the other side of the gauge! I can combat this by shortening the Gradient Stop, but I'd like to have a longer GradientStop, and simply 'turn off' the ConicalGradient at a certain value/angle.

    raven-worxR 1 Reply Last reply
    0
  • raven-worxR Offline
    raven-worxR Offline
    raven-worx Moderators
    replied to jars121 on last edited by
    #8

    @jars121
    i don't quite understand your remaining issue.
    But i think everything should be achievable by setting the gradient stops properly and/or the opacity mask.

    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
    If you have a question please use the forum so others can benefit from the solution in the future

    1 Reply Last reply
    0
  • mranger90M Offline
    mranger90M Offline
    mranger90
    wrote on last edited by
    #9

    I got this working by changing the atan2 calls in the fragment shader to atan.
    This was on an ubunut 16.04 system in a VM.

    timdayT 1 Reply Last reply
    2
  • timdayT Offline
    timdayT Offline
    timday
    replied to mranger90 on last edited by timday
    #10

    @mranger90 Oops sorry for causing confusion... I was on a system with an Nvidia card (and running Debian) when I threw the ShaderEffect version together... and it seems Nvidia do provide an atan2 in their GLSL compiler (perhaps because their old "Cg" precursor language used to have it). Didn't try it anywhere else. GLSL's regular atan with two arguments does indeed seem to do the same thing.

    Have to admit I'd completely forgotten about ConicalGradient! I do like ShaderEffect though... it's QML's magic wand... you can do some really nifty stuff with it e,g https://youtu.be/FM0CbKvYpYI or https://youtu.be/BuTYBBScfMo or https://forum.qt.io/topic/84532/qml-animation-trail-on-object/2 ...

    1 Reply Last reply
    0
  • PientashekP Offline
    PientashekP Offline
    Pientashek
    wrote on last edited by
    #11

    @jars121 Could you put a sample code on how to get this effect using OpacistyMask and ConicalGradient? I am trying to implement this effect but with a poor result..

    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