diff options
Diffstat (limited to 'src/quick/scenegraph/qsgdefaultspritenode.cpp')
-rw-r--r-- | src/quick/scenegraph/qsgdefaultspritenode.cpp | 77 |
1 files changed, 74 insertions, 3 deletions
diff --git a/src/quick/scenegraph/qsgdefaultspritenode.cpp b/src/quick/scenegraph/qsgdefaultspritenode.cpp index 8761d99c1f..4d4d9f6971 100644 --- a/src/quick/scenegraph/qsgdefaultspritenode.cpp +++ b/src/quick/scenegraph/qsgdefaultspritenode.cpp @@ -84,6 +84,7 @@ public: QQuickSpriteMaterial::QQuickSpriteMaterial() { setFlag(Blending, true); + setFlag(SupportsRhiShader, true); } QQuickSpriteMaterial::~QQuickSpriteMaterial() @@ -91,10 +92,10 @@ QQuickSpriteMaterial::~QQuickSpriteMaterial() delete texture; } -class SpriteMaterialData : public QSGMaterialShader +class SpriteMaterialShader : public QSGMaterialShader { public: - SpriteMaterialData() + SpriteMaterialShader() { setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/scenegraph/shaders/sprite.vert")); setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/sprite.frag")); @@ -135,9 +136,79 @@ public: int m_animPos_id; }; +class SpriteMaterialRhiShader : public QSGMaterialRhiShader +{ +public: + SpriteMaterialRhiShader(); + + bool updateUniformData(const RenderState &state, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; + void updateSampledImage(const RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; +}; + +SpriteMaterialRhiShader::SpriteMaterialRhiShader() +{ + setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/sprite.vert.qsb")); + setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/sprite.frag.qsb")); +} + +bool SpriteMaterialRhiShader::updateUniformData(const RenderState &state, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) +{ +#ifdef QT_NO_DEBUG + Q_UNUSED(oldMaterial); +#endif + Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type()); + QQuickSpriteMaterial *mat = static_cast<QQuickSpriteMaterial *>(newMaterial); + + bool changed = false; + QByteArray *buf = state.uniformData(); + Q_ASSERT(buf->size() >= 96); + + if (state.isMatrixDirty()) { + const QMatrix4x4 m = state.combinedMatrix(); + memcpy(buf->data(), m.constData(), 64); + changed = true; + } + + float animPosAndData[7] = { mat->animX1, mat->animY1, mat->animX2, mat->animY2, + mat->animW, mat->animH, mat->animT }; + memcpy(buf->data() + 64, animPosAndData, 28); + changed = true; + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(buf->data() + 92, &opacity, 4); + changed = true; + } + + return changed; +} + +void SpriteMaterialRhiShader::updateSampledImage(const RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) +{ + if (binding != 1) + return; + +#ifdef QT_NO_DEBUG + Q_UNUSED(oldMaterial); +#endif + Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type()); + QQuickSpriteMaterial *mat = static_cast<QQuickSpriteMaterial *>(newMaterial); + + QSGTexture *t = mat->texture; + t->updateRhiTexture(state.rhi(), state.resourceUpdateBatch()); + *texture = t; +} + QSGMaterialShader *QQuickSpriteMaterial::createShader() const { - return new SpriteMaterialData; + if (flags().testFlag(RhiShaderWanted)) + return new SpriteMaterialRhiShader; + else + return new SpriteMaterialShader; } static QSGGeometry::Attribute Sprite_Attributes[] = { |