我试图了解 QQuickItem 中 OpenGL ES 矢量着色器的行为。
我从“图形”示例开始,然后尝试将任意最小值和最大值的样本缩放到 QQuickItem 范围内(以实现简单的、GPU 加速的 y 轴自动缩放)。我认为缩放矩阵会有所帮助。
着色器采用一对(重合)顶点并为每个奇数顶点添加一个偏移量到 Y 轴(因此属性 t)。线条被绘制为 GL_TRIANGLE_STRIP 以模拟刻度线(简单的解决方案,即使它在垂直线的情况下留下间隙)。
这是我试图使场景尽可能简单的尝试。我在顶点着色器中添加了一个缩放矩阵(一半 x 和 y)。
attribute highp vec4 pos;
attribute highp float t;
uniform lowp float size;
uniform highp mat4 qt_Matrix;
mat4 mx = mat4(0.5,0,0,0, 0,0.5,0,0, 0,0,1,0, 0,0,0,1);
varying lowp float vT;
void main(void)
{
vec4 adjustedPos = pos;
adjustedPos.y += (t * size);
// Added transformation
adjustedPos = mx * adjustedPos;
gl_Position = qt_Matrix * adjustedPos;
vT = t;
}
我将修复顶点位置传递给 updateGeometry() 函数 (linenode.cpp),因此传递给着色器的第一个顶点对位于 (0, 0) 处,如下所示:
void LineNode::updateGeometry(const QRectF &bounds, const QList<qreal> &samples)
{
m_geometry.allocate(4);
LineVertex *v = (LineVertex *) m_geometry.vertexData();
v[0].set(0, 0, 0);
v[1].set(0, 0, 1);
v[2].set(bounds.width(), bounds.height(), 0);
v[3].set(bounds.width(), bounds.height(), 1);
markDirty(QSGNode::DirtyGeometry);
}
几何图形正确缩放,但在整个窗口区域内。如下图所示,比例线出现平移。据我了解,如果将缩放矩阵 mx 应用于 (0, 0),则位置将保持不变,因此在使用 qt_Matrix 转换后,该线的第一个点将位于 Item 的左上角。
我怀疑位于 (0, 0) 的顶点已传递给着色器,但我无法在文档中找到详细信息。在这种情况下,我不明白让 qt_Matrix 执行上下文到项目转换的意义。
顺便说一句,如果我将一半的坐标作为顶点传递给 updateGeometry(),则图形会正确缩放。
没有变换矩阵的图:
在顶点着色器中应用变换矩阵的图形:
在 C++ 代码中直接应用于顶点的缩放图:
我需要了解的是:
- 为什么这条线没有在项目坐标内缩放?
- 我有什么错误的假设吗?
- 如果传递给着色器的顶点被平移,我如何在保持 QQuickItem 边界的同时缩放 (x, y) 对?