aboutsummaryrefslogtreecommitdiffstats
path: root/src/imports/shapes/qquickshapegenericrenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imports/shapes/qquickshapegenericrenderer.cpp')
-rw-r--r--src/imports/shapes/qquickshapegenericrenderer.cpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/src/imports/shapes/qquickshapegenericrenderer.cpp b/src/imports/shapes/qquickshapegenericrenderer.cpp
index 5a2f337b51..98ba89dc3d 100644
--- a/src/imports/shapes/qquickshapegenericrenderer.cpp
+++ b/src/imports/shapes/qquickshapegenericrenderer.cpp
@@ -105,6 +105,9 @@ void QQuickShapeGenericStrokeFillNode::activateMaterial(Material m)
case MatRadialGradient:
m_material.reset(QQuickShapeGenericMaterialFactory::createRadialGradient(m_window, this));
break;
+ case MatConicalGradient:
+ m_material.reset(QQuickShapeGenericMaterialFactory::createConicalGradient(m_window, this));
+ break;
default:
qWarning("Unknown material %d", m);
return;
@@ -250,6 +253,10 @@ void QQuickShapeGenericRenderer::setFillGradient(int index, QQuickShapeGradient
d.fillGradient.b = QPointF(g->focalX(), g->focalY());
d.fillGradient.v0 = g->centerRadius();
d.fillGradient.v1 = g->focalRadius();
+ } else if (QQuickShapeConicalGradient *g = qobject_cast<QQuickShapeConicalGradient *>(gradient)) {
+ d.fillGradientActive = ConicalGradient;
+ d.fillGradient.a = QPointF(g->centerX(), g->centerY());
+ d.fillGradient.v0 = g->angle();
} else {
Q_UNREACHABLE();
}
@@ -594,6 +601,9 @@ void QQuickShapeGenericRenderer::updateFillNode(ShapePathData *d, QQuickShapeGen
case RadialGradient:
gradMat = QQuickShapeGenericStrokeFillNode::MatRadialGradient;
break;
+ case ConicalGradient:
+ gradMat = QQuickShapeGenericStrokeFillNode::MatConicalGradient;
+ break;
default:
Q_UNREACHABLE();
}
@@ -717,6 +727,22 @@ QSGMaterial *QQuickShapeGenericMaterialFactory::createRadialGradient(QQuickWindo
return nullptr;
}
+QSGMaterial *QQuickShapeGenericMaterialFactory::createConicalGradient(QQuickWindow *window,
+ QQuickShapeGenericStrokeFillNode *node)
+{
+ QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi();
+
+#if QT_CONFIG(opengl)
+ if (api == QSGRendererInterface::OpenGL)
+ return new QQuickShapeConicalGradientMaterial(node);
+#else
+ Q_UNUSED(node);
+#endif
+
+ qWarning("Conical gradient material: Unsupported graphics API %d", api);
+ return nullptr;
+}
+
#if QT_CONFIG(opengl)
QSGMaterialType QQuickShapeLinearGradientShader::type;
@@ -900,6 +926,89 @@ int QQuickShapeRadialGradientMaterial::compare(const QSGMaterial *other) const
return 0;
}
+QSGMaterialType QQuickShapeConicalGradientShader::type;
+
+QQuickShapeConicalGradientShader::QQuickShapeConicalGradientShader()
+{
+ setShaderSourceFile(QOpenGLShader::Vertex,
+ QStringLiteral(":/qt-project.org/shapes/shaders/conicalgradient.vert"));
+ setShaderSourceFile(QOpenGLShader::Fragment,
+ QStringLiteral(":/qt-project.org/shapes/shaders/conicalgradient.frag"));
+}
+
+void QQuickShapeConicalGradientShader::initialize()
+{
+ QOpenGLShaderProgram *prog = program();
+ m_opacityLoc = prog->uniformLocation("opacity");
+ m_matrixLoc = prog->uniformLocation("matrix");
+ m_angleLoc = prog->uniformLocation("angle");
+ m_translationPointLoc = prog->uniformLocation("translationPoint");
+}
+
+void QQuickShapeConicalGradientShader::updateState(const RenderState &state, QSGMaterial *mat, QSGMaterial *)
+{
+ QQuickShapeConicalGradientMaterial *m = static_cast<QQuickShapeConicalGradientMaterial *>(mat);
+
+ if (state.isOpacityDirty())
+ program()->setUniformValue(m_opacityLoc, state.opacity());
+
+ if (state.isMatrixDirty())
+ program()->setUniformValue(m_matrixLoc, state.combinedMatrix());
+
+ QQuickShapeGenericStrokeFillNode *node = m->node();
+
+ const QPointF centerPoint = node->m_fillGradient.a;
+ const GLfloat angle = -qDegreesToRadians(node->m_fillGradient.v0);
+
+ program()->setUniformValue(m_angleLoc, angle);
+ program()->setUniformValue(m_translationPointLoc, centerPoint);
+
+ const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, QQuickShapeGradient::RepeatSpread);
+ QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey);
+ tx->bind();
+}
+
+char const *const *QQuickShapeConicalGradientShader::attributeNames() const
+{
+ static const char *const attr[] = { "vertexCoord", "vertexColor", nullptr };
+ return attr;
+}
+
+int QQuickShapeConicalGradientMaterial::compare(const QSGMaterial *other) const
+{
+ Q_ASSERT(other && type() == other->type());
+ const QQuickShapeConicalGradientMaterial *m = static_cast<const QQuickShapeConicalGradientMaterial *>(other);
+
+ QQuickShapeGenericStrokeFillNode *a = node();
+ QQuickShapeGenericStrokeFillNode *b = m->node();
+ Q_ASSERT(a && b);
+ if (a == b)
+ return 0;
+
+ const QQuickAbstractPathRenderer::GradientDesc *ga = &a->m_fillGradient;
+ const QQuickAbstractPathRenderer::GradientDesc *gb = &b->m_fillGradient;
+
+ if (int d = ga->a.x() - gb->a.x())
+ return d;
+ if (int d = ga->a.y() - gb->a.y())
+ return d;
+
+ if (int d = ga->v0 - gb->v0)
+ return d;
+
+ if (int d = ga->stops.count() - gb->stops.count())
+ return d;
+
+ for (int i = 0; i < ga->stops.count(); ++i) {
+ if (int d = ga->stops[i].first - gb->stops[i].first)
+ return d;
+ if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
+ return d;
+ }
+
+ return 0;
+}
+
#endif // QT_CONFIG(opengl)
QT_END_NAMESPACE