I am trying to understand the behavoir of OpenGL ES vector shader within QQuickItem.
I started with the "graph" example, and then I tried to scale samples of arbitrary minimum and maximum values into the QQuickItem bounds (in order to achieve a simple, GPU accelerated auto-scaling on y axis). I thought a scaling matrix would be of help.
The shader takes a pair of (coincident) vertices and adds an offset for every odd vertex to the Y-axis (hence the attribute t). Lines are drawn as GL_TRIANGLE_STRIP to simulate a tick line (simple solution even if it leaves gaps in case of vertical lines).
This is my attempt to keep the scenario as simple as possible. I added a scaling matrix (half x and y) to the vertex shader.
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;
}
I passed fixes vertex positions into updateGeometry() function (linenode.cpp), so that the first vertex pair passed to the shader is located at (0, 0) as follows:
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);
}
The geometry gets scaled correctly, but within the whole window area. As in the pictures below, the scaled line appears translated. From my understanding, if the scaling matrix mx were applied to (0, 0) the position would remain unchanged, so that the first point of the line would be located at the top left corner of the Item after transformation with qt_Matrix.
I suspect that the vertex located at (0, 0) is passed already translated in to the shader, but I was unable to find details into documentation. And in this case I would not understand the point of having qt_Matrix performing context to Item transformations.
By the way, if I pass half the coordinates as vertices to updateGeometry(), the graph is scaled correctly.
Graph without transformation matrix:
Graph with transformation matrix applied in vertex shader:
Graph with scaling applied directly to vertices in C++ code:
What I need to understand is:
- Why does the line is not getting just scaled within the Item coordinates?
- Am I making any wrong assumption?
- In case the vertex passed to the shader is translated, how could I scale the (x, y) pair while remaining into the QQuickItem bounds?