Qt 使用ShaderEffect的fragmentShader属性在QML CircularGaugeStyle中逆时针着色
我想在QML中创建一个CircularGauge,其中指针逆时针移动,着色器从+145度绘制到指针位置 我为CircularGauge的style属性实现了一个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)
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