diff options
Diffstat (limited to 'src/imports/shapes')
-rw-r--r-- | src/imports/shapes/plugin.cpp | 1 | ||||
-rw-r--r-- | src/imports/shapes/qquickshape.cpp | 83 | ||||
-rw-r--r-- | src/imports/shapes/qquickshape_p.h | 30 | ||||
-rw-r--r-- | src/imports/shapes/qquickshapegenericrenderer.cpp | 109 | ||||
-rw-r--r-- | src/imports/shapes/qquickshapegenericrenderer_p.h | 49 | ||||
-rw-r--r-- | src/imports/shapes/qquickshapenvprrenderer.cpp | 58 | ||||
-rw-r--r-- | src/imports/shapes/qquickshapenvprrenderer_p.h | 1 | ||||
-rw-r--r-- | src/imports/shapes/qquickshapesoftwarerenderer.cpp | 4 | ||||
-rw-r--r-- | src/imports/shapes/shaders/conicalgradient.frag | 19 | ||||
-rw-r--r-- | src/imports/shapes/shaders/conicalgradient.vert | 13 | ||||
-rw-r--r-- | src/imports/shapes/shaders/conicalgradient_core.frag | 22 | ||||
-rw-r--r-- | src/imports/shapes/shaders/conicalgradient_core.vert | 15 | ||||
-rw-r--r-- | src/imports/shapes/shapes.qrc | 4 |
13 files changed, 403 insertions, 5 deletions
diff --git a/src/imports/shapes/plugin.cpp b/src/imports/shapes/plugin.cpp index 186e182192..239ef78e55 100644 --- a/src/imports/shapes/plugin.cpp +++ b/src/imports/shapes/plugin.cpp @@ -67,6 +67,7 @@ public: qmlRegisterUncreatableType<QQuickShapeGradient>(uri, 1, 0, "ShapeGradient", QQuickShapeGradient::tr("ShapeGradient is an abstract base class")); qmlRegisterType<QQuickShapeLinearGradient>(uri, 1, 0, "LinearGradient"); qmlRegisterType<QQuickShapeRadialGradient>(uri, 1, 0, "RadialGradient"); + qmlRegisterType<QQuickShapeConicalGradient>(uri, 1, 0, "ConicalGradient"); } }; diff --git a/src/imports/shapes/qquickshape.cpp b/src/imports/shapes/qquickshape.cpp index b6174fb177..1ed61ff476 100644 --- a/src/imports/shapes/qquickshape.cpp +++ b/src/imports/shapes/qquickshape.cpp @@ -1296,6 +1296,89 @@ void QQuickShapeRadialGradient::setFocalRadius(qreal v) } } +/*! + \qmltype ConicalGradient + \instantiates QQuickShapeConicalGradient + \inqmlmodule QtQuick.Shapes + \ingroup qtquick-paths + \ingroup qtquick-views + \inherits ShapeGradient + \brief Conical gradient + \since 5.10 + + Conical gradients interpolate colors counter-clockwise around a center + point in Shape items. + + \note The \l{ShapeGradient.spread}{spread mode} setting has no effect for + conical gradients. + + \note ConicalGradient is only supported in combination with Shape items. It + is not compatible with \l Rectangle, as that only supports \l Gradient. + + \sa QConicalGradient + */ + +QQuickShapeConicalGradient::QQuickShapeConicalGradient(QObject *parent) + : QQuickShapeGradient(parent) +{ +} + +/*! + \qmlproperty real QtQuick.Shapes::ConicalGradient::centerX + \qmlproperty real QtQuick.Shapes::ConicalGradient::centerY + + These properties define the center point of the conical gradient. + */ + +qreal QQuickShapeConicalGradient::centerX() const +{ + return m_centerPoint.x(); +} + +void QQuickShapeConicalGradient::setCenterX(qreal v) +{ + if (m_centerPoint.x() != v) { + m_centerPoint.setX(v); + emit centerXChanged(); + emit updated(); + } +} + +qreal QQuickShapeConicalGradient::centerY() const +{ + return m_centerPoint.y(); +} + +void QQuickShapeConicalGradient::setCenterY(qreal v) +{ + if (m_centerPoint.y() != v) { + m_centerPoint.setY(v); + emit centerYChanged(); + emit updated(); + } +} + +/*! + \qmlproperty real QtQuick.Shapes::ConicalGradient::angle + + This property defines the start angle for the conical gradient. The value + is in degrees (0-360). + */ + +qreal QQuickShapeConicalGradient::angle() const +{ + return m_angle; +} + +void QQuickShapeConicalGradient::setAngle(qreal v) +{ + if (m_angle != v) { + m_angle = v; + emit angleChanged(); + emit updated(); + } +} + #if QT_CONFIG(opengl) // contexts sharing with each other get the same cache instance diff --git a/src/imports/shapes/qquickshape_p.h b/src/imports/shapes/qquickshape_p.h index b6943db37c..27b02bc962 100644 --- a/src/imports/shapes/qquickshape_p.h +++ b/src/imports/shapes/qquickshape_p.h @@ -167,6 +167,36 @@ private: qreal m_focalRadius = 0; }; +class QQuickShapeConicalGradient : public QQuickShapeGradient +{ + Q_OBJECT + Q_PROPERTY(qreal centerX READ centerX WRITE setCenterX NOTIFY centerXChanged) + Q_PROPERTY(qreal centerY READ centerY WRITE setCenterY NOTIFY centerYChanged) + Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) + Q_CLASSINFO("DefaultProperty", "stops") + +public: + QQuickShapeConicalGradient(QObject *parent = nullptr); + + qreal centerX() const; + void setCenterX(qreal v); + + qreal centerY() const; + void setCenterY(qreal v); + + qreal angle() const; + void setAngle(qreal v); + +signals: + void centerXChanged(); + void centerYChanged(); + void angleChanged(); + +private: + QPointF m_centerPoint; + qreal m_angle = 0; +}; + class QQuickShapePath : public QQuickPath { Q_OBJECT 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 diff --git a/src/imports/shapes/qquickshapegenericrenderer_p.h b/src/imports/shapes/qquickshapegenericrenderer_p.h index 2561116f81..32cec798ec 100644 --- a/src/imports/shapes/qquickshapegenericrenderer_p.h +++ b/src/imports/shapes/qquickshapegenericrenderer_p.h @@ -210,7 +210,8 @@ public: enum Material { MatSolidColor, MatLinearGradient, - MatRadialGradient + MatRadialGradient, + MatConicalGradient }; void activateMaterial(Material m); @@ -242,6 +243,7 @@ public: static QSGMaterial *createVertexColor(QQuickWindow *window); static QSGMaterial *createLinearGradient(QQuickWindow *window, QQuickShapeGenericStrokeFillNode *node); static QSGMaterial *createRadialGradient(QQuickWindow *window, QQuickShapeGenericStrokeFillNode *node); + static QSGMaterial *createConicalGradient(QQuickWindow *window, QQuickShapeGenericStrokeFillNode *node); }; #if QT_CONFIG(opengl) @@ -343,6 +345,51 @@ private: QQuickShapeGenericStrokeFillNode *m_node; }; +class QQuickShapeConicalGradientShader : public QSGMaterialShader +{ +public: + QQuickShapeConicalGradientShader(); + + void initialize() override; + void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override; + char const *const *attributeNames() const override; + + static QSGMaterialType type; + +private: + int m_opacityLoc = -1; + int m_matrixLoc = -1; + int m_angleLoc = -1; + int m_translationPointLoc = -1; +}; + +class QQuickShapeConicalGradientMaterial : public QSGMaterial +{ +public: + QQuickShapeConicalGradientMaterial(QQuickShapeGenericStrokeFillNode *node) + : m_node(node) + { + setFlag(Blending | RequiresFullMatrix); + } + + QSGMaterialType *type() const override + { + return &QQuickShapeConicalGradientShader::type; + } + + int compare(const QSGMaterial *other) const override; + + QSGMaterialShader *createShader() const override + { + return new QQuickShapeConicalGradientShader; + } + + QQuickShapeGenericStrokeFillNode *node() const { return m_node; } + +private: + QQuickShapeGenericStrokeFillNode *m_node; +}; + #endif // QT_CONFIG(opengl) QT_END_NAMESPACE diff --git a/src/imports/shapes/qquickshapenvprrenderer.cpp b/src/imports/shapes/qquickshapenvprrenderer.cpp index a08da2f3fe..27a0d6ca96 100644 --- a/src/imports/shapes/qquickshapenvprrenderer.cpp +++ b/src/imports/shapes/qquickshapenvprrenderer.cpp @@ -42,6 +42,7 @@ #include <QOpenGLFramebufferObject> #include <QOpenGLShaderProgram> #include <QOpenGLBuffer> +#include <qmath.h> #include <private/qquickpath_p_p.h> QT_BEGIN_NAMESPACE @@ -138,6 +139,10 @@ void QQuickShapeNvprRenderer::setFillGradient(int index, QQuickShapeGradient *gr 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(); } @@ -536,6 +541,37 @@ QQuickNvprMaterialManager::MaterialDesc *QQuickNvprMaterialManager::activateMate Q_ASSERT(mtl.uniLoc[4] >= 0); mtl.uniLoc[5] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "translationPoint"); Q_ASSERT(mtl.uniLoc[5] >= 0); + } else if (m == MatConicalGradient) { + static const char *fragSrc = + "#version 310 es\n" + "precision highp float;\n" + "#define INVERSE_2PI 0.1591549430918953358\n" + "uniform sampler2D gradTab;\n" + "uniform float opacity;\n" + "uniform float angle;\n" + "uniform vec2 translationPoint;\n" + "layout(location = 0) in vec2 uv;\n" + "out vec4 fragColor;\n" + "void main() {\n" + " vec2 coord = uv - translationPoint;\n" + " float t;\n" + " if (abs(coord.y) == abs(coord.x))\n" + " t = (atan(-coord.y + 0.002, coord.x) + angle) * INVERSE_2PI;\n" + " else\n" + " t = (atan(-coord.y, coord.x) + angle) * INVERSE_2PI;\n" + " fragColor = texture(gradTab, vec2(t - floor(t), 0.5)) * opacity;\n" + "}\n"; + if (!m_nvpr->createFragmentOnlyPipeline(fragSrc, &mtl.ppl, &mtl.prg)) { + qWarning("NVPR: Failed to create shader pipeline for conical gradient"); + return nullptr; + } + Q_ASSERT(mtl.ppl && mtl.prg); + mtl.uniLoc[1] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "opacity"); + Q_ASSERT(mtl.uniLoc[1] >= 0); + mtl.uniLoc[2] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "angle"); + Q_ASSERT(mtl.uniLoc[2] >= 0); + mtl.uniLoc[3] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "translationPoint"); + Q_ASSERT(mtl.uniLoc[3] >= 0); } else { Q_UNREACHABLE(); } @@ -593,10 +629,7 @@ void QQuickShapeNvprRenderNode::renderFill(ShapePathRenderData *d) { QQuickNvprMaterialManager::MaterialDesc *mtl = nullptr; if (d->fillGradientActive) { - const QQuickShapeGradientCache::Key cacheKey(d->fillGradient.stops, d->fillGradient.spread); - QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey); - tx->bind(); - + QQuickShapeGradient::SpreadMode spread = d->fillGradient.spread; if (d->fillGradientActive == QQuickAbstractPathRenderer::LinearGradient) { mtl = mtlmgr.activateMaterial(QQuickNvprMaterialManager::MatLinearGradient); // uv = vec2(coeff[0] * x + coeff[1] * y + coeff[2], coeff[3] * x + coeff[4] * y + coeff[5]) @@ -624,9 +657,26 @@ void QQuickShapeNvprRenderNode::renderFill(ShapePathRenderData *d) f->glProgramUniform1f(mtl->prg, mtl->uniLoc[3], centerRadius); f->glProgramUniform1f(mtl->prg, mtl->uniLoc[4], focalRadius); f->glProgramUniform2f(mtl->prg, mtl->uniLoc[5], focalPoint.x(), focalPoint.y()); + } else if (d->fillGradientActive == QQuickAbstractPathRenderer::ConicalGradient) { + mtl = mtlmgr.activateMaterial(QQuickNvprMaterialManager::MatConicalGradient); + // same old + GLfloat coeff[6] = { 1, 0, 0, + 0, 1, 0 }; + nvpr.programPathFragmentInputGen(mtl->prg, 0, GL_OBJECT_LINEAR_NV, 2, coeff); + + const QPointF centerPoint = d->fillGradient.a; + const GLfloat angle = -qDegreesToRadians(d->fillGradient.v0); + + f->glProgramUniform1f(mtl->prg, mtl->uniLoc[2], angle); + f->glProgramUniform2f(mtl->prg, mtl->uniLoc[3], centerPoint.x(), centerPoint.y()); + + spread = QQuickShapeGradient::RepeatSpread; } else { Q_UNREACHABLE(); } + const QQuickShapeGradientCache::Key cacheKey(d->fillGradient.stops, spread); + QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey); + tx->bind(); } else { mtl = mtlmgr.activateMaterial(QQuickNvprMaterialManager::MatSolid); f->glProgramUniform4f(mtl->prg, mtl->uniLoc[0], diff --git a/src/imports/shapes/qquickshapenvprrenderer_p.h b/src/imports/shapes/qquickshapenvprrenderer_p.h index b3d92dbdbc..f6c9fc169e 100644 --- a/src/imports/shapes/qquickshapenvprrenderer_p.h +++ b/src/imports/shapes/qquickshapenvprrenderer_p.h @@ -137,6 +137,7 @@ public: MatSolid, MatLinearGradient, MatRadialGradient, + MatConicalGradient, NMaterials }; diff --git a/src/imports/shapes/qquickshapesoftwarerenderer.cpp b/src/imports/shapes/qquickshapesoftwarerenderer.cpp index 15803dcf0a..ed13afbc7e 100644 --- a/src/imports/shapes/qquickshapesoftwarerenderer.cpp +++ b/src/imports/shapes/qquickshapesoftwarerenderer.cpp @@ -160,6 +160,10 @@ void QQuickShapeSoftwareRenderer::setFillGradient(int index, QQuickShapeGradient g->focalX(), g->focalY(), g->focalRadius()); setupPainterGradient(&painterGradient, *g); d.brush = QBrush(painterGradient); + } else if (QQuickShapeConicalGradient *g = qobject_cast<QQuickShapeConicalGradient *>(gradient)) { + QConicalGradient painterGradient(g->centerX(), g->centerY(), g->angle()); + setupPainterGradient(&painterGradient, *g); + d.brush = QBrush(painterGradient); } else { d.brush = QBrush(d.fillColor); } diff --git a/src/imports/shapes/shaders/conicalgradient.frag b/src/imports/shapes/shaders/conicalgradient.frag new file mode 100644 index 0000000000..af5fdd5ee0 --- /dev/null +++ b/src/imports/shapes/shaders/conicalgradient.frag @@ -0,0 +1,19 @@ +#define INVERSE_2PI 0.1591549430918953358 + +uniform sampler2D gradTabTexture; +uniform lowp float opacity; + +uniform highp float angle; + +varying highp vec2 coord; + +void main() +{ + highp float t; + if (abs(coord.y) == abs(coord.x)) + t = (atan(-coord.y + 0.002, coord.x) + angle) * INVERSE_2PI; + else + t = (atan(-coord.y, coord.x) + angle) * INVERSE_2PI; + gl_FragColor = texture2D(gradTabTexture, vec2(t - floor(t), 0.5)) * opacity; + +} diff --git a/src/imports/shapes/shaders/conicalgradient.vert b/src/imports/shapes/shaders/conicalgradient.vert new file mode 100644 index 0000000000..3350b0675a --- /dev/null +++ b/src/imports/shapes/shaders/conicalgradient.vert @@ -0,0 +1,13 @@ +attribute vec4 vertexCoord; +attribute vec4 vertexColor; + +uniform mat4 matrix; +uniform vec2 translationPoint; + +varying vec2 coord; + +void main() +{ + coord = vertexCoord.xy - translationPoint; + gl_Position = matrix * vertexCoord; +} diff --git a/src/imports/shapes/shaders/conicalgradient_core.frag b/src/imports/shapes/shaders/conicalgradient_core.frag new file mode 100644 index 0000000000..e18b80159a --- /dev/null +++ b/src/imports/shapes/shaders/conicalgradient_core.frag @@ -0,0 +1,22 @@ +#version 150 core + +#define INVERSE_2PI 0.1591549430918953358 + +uniform sampler2D gradTabTexture; +uniform float opacity; + +uniform float angle; + +in vec2 coord; + +out vec4 fragColor; + +void main() +{ + float t; + if (abs(coord.y) == abs(coord.x)) + t = (atan(-coord.y + 0.002, coord.x) + angle) * INVERSE_2PI; + else + t = (atan(-coord.y, coord.x) + angle) * INVERSE_2PI; + fragColor = texture(gradTabTexture, vec2(t - floor(t), 0.5)) * opacity; +} diff --git a/src/imports/shapes/shaders/conicalgradient_core.vert b/src/imports/shapes/shaders/conicalgradient_core.vert new file mode 100644 index 0000000000..f94a56401b --- /dev/null +++ b/src/imports/shapes/shaders/conicalgradient_core.vert @@ -0,0 +1,15 @@ +#version 150 core + +in vec4 vertexCoord; +in vec4 vertexColor; + +uniform mat4 matrix; +uniform vec2 translationPoint; + +out vec2 coord; + +void main() +{ + coord = vertexCoord.xy - translationPoint; + gl_Position = matrix * vertexCoord; +} diff --git a/src/imports/shapes/shapes.qrc b/src/imports/shapes/shapes.qrc index 92912ede48..f139861693 100644 --- a/src/imports/shapes/shapes.qrc +++ b/src/imports/shapes/shapes.qrc @@ -12,5 +12,9 @@ <file>shaders/radialgradient.frag</file> <file>shaders/radialgradient_core.vert</file> <file>shaders/radialgradient_core.frag</file> + <file>shaders/conicalgradient.vert</file> + <file>shaders/conicalgradient.frag</file> + <file>shaders/conicalgradient_core.vert</file> + <file>shaders/conicalgradient_core.frag</file> </qresource> </RCC> |