aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
diff options
context:
space:
mode:
authorAndy Nichols <andy.nichols@qt.io>2016-11-29 15:29:39 +0100
committerAndy Nichols <andy.nichols@qt.io>2016-12-13 15:43:24 +0000
commit0119439c9d25dfd892bbee47068e9d726f4bff97 (patch)
tree71df5718b21cd1471eb6cb4c4eac4c19a691f869 /src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
parent3f57f2b7cc3899af154257a3c858bd23d9f03a62 (diff)
OpenVG: Support rendering paths with non-affine transforms
The current approach to rendering paths (used by Rectangles and Glyph nodes) does not support rendering with non-affine transformations. That is because OpenVG does not support passing a non-affine transformation matrix when rendering paths. So instead when using a non-affine transform we will fallback to rendering to an offscreen VGImage, then rendering that as an image which can have a perspective transform. Change-Id: I01508bcb67b339323cb6400c7ff6d885b62c5e02 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp')
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
index f5890210a9..1afc5ea7ca 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
@@ -73,10 +73,33 @@ void QSGOpenVGRectangleNode::setColor(const QColor &color)
markDirty(DirtyMaterial);
}
+void QSGOpenVGRectangleNode::setTransform(const QOpenVGMatrix &transform)
+{
+ // if there transform matrix is not affine, regenerate the path
+ if (transform.isAffine())
+ m_pathDirty = true;
+ markDirty(DirtyGeometry);
+
+ QSGOpenVGRenderable::setTransform(transform);
+}
+
void QSGOpenVGRectangleNode::render()
{
+ // Set Transform
+ if (transform().isAffine()) {
+ // Use current transform matrix
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadMatrix(transform().constData());
+ } else {
+ // map the path's to handle the perspective matrix
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadIdentity();
+ }
+
if (m_pathDirty) {
vgClearPath(m_rectPath, VG_PATH_CAPABILITY_APPEND_TO);
+
+ if (transform().isAffine()) {
// Create command list
static const VGubyte rectCommands[] = {
VG_MOVE_TO_ABS,
@@ -95,6 +118,34 @@ void QSGOpenVGRectangleNode::render()
coordinates[4] = -m_rect.width();
vgAppendPathData(m_rectPath, 5, rectCommands, coordinates.constData());
+
+ } else {
+ // Pre-transform path
+ static const VGubyte rectCommands[] = {
+ VG_MOVE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_LINE_TO_ABS,
+ VG_CLOSE_PATH
+ };
+
+ QVector<VGfloat> coordinates(8);
+ const QPointF topLeft = transform().map(m_rect.topLeft());
+ const QPointF topRight = transform().map(m_rect.topRight());
+ const QPointF bottomLeft = transform().map(m_rect.bottomLeft());
+ const QPointF bottomRight = transform().map(m_rect.bottomRight());
+ coordinates[0] = bottomLeft.x();
+ coordinates[1] = bottomLeft.y();
+ coordinates[2] = bottomRight.x();
+ coordinates[3] = bottomRight.y();
+ coordinates[4] = topRight.x();
+ coordinates[5] = topRight.y();
+ coordinates[6] = topLeft.x();
+ coordinates[7] = topLeft.y();
+
+ vgAppendPathData(m_rectPath, 5, rectCommands, coordinates.constData());
+ }
+
m_pathDirty = false;
}
@@ -155,6 +206,10 @@ void QSGOpenVGImageNode::render()
vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
}
+ // Set Transform
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(transform().constData());
+
VGImage image = static_cast<VGImage>(m_texture->textureId());
//Apply the TextureCoordinateTransform Flag
@@ -251,6 +306,10 @@ void QSGOpenVGNinePatchNode::render()
vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
}
+ // Set Transform
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(transform().constData());
+
VGImage image = static_cast<VGImage>(m_texture->textureId());
//Draw borderImage