Qt 使用ShaderEffect的fragmentShader属性在QML CircularGaugeStyle中逆时针着色

Qt 使用ShaderEffect的fragmentShader属性在QML CircularGaugeStyle中逆时针着色,qt,qml,shader,qtquick2,opengl-3,Qt,Qml,Shader,Qtquick2,Opengl 3,我想在QML中创建一个CircularGauge,其中指针逆时针移动,着色器从+145度绘制到指针位置 我为CircularGauge的style属性实现了一个CircularGaugeStyle。我使用以下代码在仪表上产生着色器效果: background: Canvas { onPaint: { var ctx = getContext("2d"); ctx.reset(); paintBackground(ctx)

我想在QML中创建一个CircularGauge,其中指针逆时针移动,着色器从+145度绘制到指针位置

我为CircularGauge的style属性实现了一个CircularGaugeStyle。我使用以下代码在仪表上产生着色器效果:

background: Canvas {
    onPaint: {
        var ctx = getContext("2d");
        ctx.reset();
        paintBackground(ctx);
    }

    ShaderEffect {
        id: gauge
        anchors.fill: parent

        opacity: 0.75

        // Angles measured clockwise from up, in range -pi to pi
        property real angleBase: -2.53073
        property real angle: degToRad(needleRotation)

        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.55<=r && r<=0.95) {
              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;
              }
            }
          }"
      }
}
使基准角为+145度

if (0.55<=r && r<=0.95) { // the area in gauge that should be painted
  highp float a=atan2(d.y,-d.x); //getting the other side of the angle (pi/2 - theta)
  if (a>=angleBase && angle>=a) { //since we want to draw from +2.5 to needle position (in radians)
    highp float p=(angleBase-a)/(angleBase-angle);
    gl_FragColor = vec4(0.0,0.0,p,p) * qt_Opacity;
  }
}
如果(0.55=a){//,因为我们要从+2.5绘制到针位置(弧度)
highp float p=(角度基准-a)/(角度基准角度);
gl_FragColor=vec4(0.0,0.0,p,p)*qt_不透明度;
}
}
以下是着色器按时钟运行时的输出图像:


将代码更改为逆时针绘制不起作用。我做错了什么?我对计算atan2的理解是否不正确?

这完全取决于当前角度的计算方式

在您的应用程序中,0°似乎位于顶部。保持-145°(-2.53073)的角度

在原始代码中,角度(
a
)由
a=atan2(d.x,-d.y)计算。如果要围绕y轴翻转,则新计算为:

highpvec2d=coord*2.0-vec2(1.0);
highp float r=长度(d);

如果(0.55这完全取决于当前<代码>角度
的计算方式

在应用程序中,0°似乎位于顶部。保持-145°(-2.53073)的角度

在原始代码中,角度(
a
)由
a=atan2(d.x,-d.y);
计算。如果要绕y轴翻转角度,则新计算为:

highpvec2d=coord*2.0-vec2(1.0);
highp float r=长度(d);

如果(0.55)围绕y轴翻转,保持一切不变没有任何帮助。执行此操作后,着色器开始从量规中的标记3顺时针和逆时针绘制,具体取决于指针的位置。我希望从0(+2.5)开始绘制指针位置。尝试a=atan2(-d.x,-d.y),似乎指针和着色器区域端点之间存在奇怪的差异滞后/超前。着色器绘制从-2.5开始,这是正确的,但当指针为0时绘制到市场5,依此类推。下面是一个小表指针:0,着色器末端:5,指针:1,着色器末端:4,指针:2,着色器末端:3,指针:3,着色器末端:2,…因此当需要时e为0时,额外拉伸180度,当针为2时,角度为30度(针旋转)是QML对象CircularGauge的内部属性,该属性表示从MinAngle到maxAngle最大值的相对角度。此处MinAngle设置为-145度,maxAngle为+145度。因此,alpha是针相对于-145的位置。如果
alpha
在范围内,则标记0处的角度为290度,位置5处的角度为0度[0290]然后你必须从alpha中减去145:
(angleBase我很抱歉我的最后一行是错误的,这造成了混乱。正如我提到的,范围是-145到+145。所以在最右的角度是145度,最左的角度是-145度,0位于市场2和3之间的中心。所以它不是0到290,而是从-145到+145。很抱歉再次造成混乱。翻转ty轴保持一切不变没有任何帮助。完成后,着色器将根据指针的位置从量规中的标记3顺时针和逆时针开始绘制。我希望从0(+2.5)开始绘制指针位置。尝试a=atan2(-d.x,-d.y),似乎指针和着色器区域端点之间存在奇怪的差异滞后/超前。着色器绘制从-2.5开始,这是正确的,但当指针为0时绘制到市场5,依此类推。下面是一个小表指针:0,着色器末端:5,指针:1,着色器末端:4,指针:2,着色器末端:3,指针:3,着色器末端:2,…因此当需要时e为0时,额外拉伸180度,当针为2时,角度为30度(针旋转)是QML对象CircularGauge的内部属性,该属性表示从MinAngle到maxAngle最大值的相对角度。此处MinAngle设置为-145度,maxAngle为+145度。因此,alpha是针相对于-145的位置。如果
alpha
在范围内,则标记0处的角度为290度,位置5处的角度为0度[0290]然后你必须从alpha中减去145:
(angleBase我很抱歉我的最后一行是错误的,这造成了混乱。正如我所提到的,范围是-145到+145。所以在最右的角度是145度,最左的角度是-145度,0位于市场2和3之间的中心。所以它不是0到290,而是从-145到+145。再次抱歉造成混乱。
if (0.55<=r && r<=0.95) { // the area in gauge that should be painted
  highp float a=atan2(d.y,-d.x); //getting the other side of the angle (pi/2 - theta)
  if (a>=angleBase && angle>=a) { //since we want to draw from +2.5 to needle position (in radians)
    highp float p=(angleBase-a)/(angleBase-angle);
    gl_FragColor = vec4(0.0,0.0,p,p) * qt_Opacity;
  }
}
property real angleBase: -2.53073