首页 > 解决方案 > 为什么缩放矩阵会导致顶点退出 QQuickItem 的边界?

问题描述

我试图了解 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++ 代码中直接应用于顶点的缩放图:

正确的图形:缩放应用于 C++ 代码中的顶点

我需要了解的是:

标签: c++qtopenglmatrixqquickitem

解决方案


推荐阅读