Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsgdefaultspritenode.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include <QtQuick/QSGMaterial>
8
10
11struct SpriteVertex {
12 float x;
13 float y;
14 float tx;
15 float ty;
16};
17
24
26{
27public:
30 QSGMaterialType *type() const override { static QSGMaterialType type; return &type; }
31 QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override;
32
33 QSGTexture *texture = nullptr;
34
35 float animT = 0.0f;
36 float animX1 = 0.0f;
37 float animY1 = 0.0f;
38 float animX2 = 0.0f;
39 float animY2 = 0.0f;
40 float animW = 1.0f;
41 float animH = 1.0f;
42};
43
45{
46 setFlag(Blending, true);
47}
48
50{
51 delete texture;
52}
53
55{
56public:
58
59 bool updateUniformData(RenderState &state,
60 QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
61 void updateSampledImage(RenderState &state, int binding, QSGTexture **texture,
62 QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
63};
64
66{
67 setShaderFileName(VertexStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/sprite.vert.qsb"), viewCount);
68 setShaderFileName(FragmentStage, QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/sprite.frag.qsb"), viewCount);
69}
70
72 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
73{
74#ifdef QT_NO_DEBUG
75 Q_UNUSED(oldMaterial);
76#endif
77 Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type());
78 QQuickSpriteMaterial *mat = static_cast<QQuickSpriteMaterial *>(newMaterial);
79
80 bool changed = false;
81 QByteArray *buf = state.uniformData();
82 Q_ASSERT(buf->size() >= 96);
83
84 const int shaderMatrixCount = newMaterial->viewCount();
85 const int matrixCount = qMin(state.projectionMatrixCount(), shaderMatrixCount);
86 for (int viewIndex = 0; viewIndex < matrixCount; ++viewIndex) {
87 if (state.isMatrixDirty()) {
88 const QMatrix4x4 m = state.combinedMatrix(viewIndex);
89 memcpy(buf->data() + 64 * viewIndex, m.constData(), 64);
90 changed = true;
91 }
92 }
93
94 float animPosAndData[7] = { mat->animX1, mat->animY1, mat->animX2, mat->animY2,
95 mat->animW, mat->animH, mat->animT };
96 memcpy(buf->data() + 64 * shaderMatrixCount, animPosAndData, 28);
97 changed = true;
98
99 if (state.isOpacityDirty()) {
100 const float opacity = state.opacity();
101 memcpy(buf->data() + 64 * shaderMatrixCount + 16 + 12, &opacity, 4);
102 changed = true;
103 }
104
105 return changed;
106}
107
108void SpriteMaterialRhiShader::updateSampledImage(RenderState &state, int binding, QSGTexture **texture,
109 QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
110{
111 if (binding != 1)
112 return;
113
114#ifdef QT_NO_DEBUG
115 Q_UNUSED(oldMaterial);
116#endif
117 Q_ASSERT(oldMaterial == nullptr || newMaterial->type() == oldMaterial->type());
118 QQuickSpriteMaterial *mat = static_cast<QQuickSpriteMaterial *>(newMaterial);
119
120 QSGTexture *t = mat->texture;
121 t->commitTextureOperations(state.rhi(), state.resourceUpdateBatch());
122 *texture = t;
123}
124
125QSGMaterialShader *QQuickSpriteMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
126{
127 Q_UNUSED(renderMode);
128 return new SpriteMaterialRhiShader(viewCount());
129}
130
132 QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType, true), // pos
133 QSGGeometry::Attribute::create(1, 2, QSGGeometry::FloatType), // tex
134};
135
137{
138 2, // Attribute Count
139 (2+2) * sizeof(float),
140 Sprite_Attributes
141};
142
144 : m_material(new QQuickSpriteMaterial)
145 , m_geometryDirty(true)
146 , m_sheetSize(QSize(64, 64))
147{
148 // Setup geometry data
149 m_geometry = new QSGGeometry(Sprite_AttributeSet, 4, 6);
150 m_geometry->setDrawingMode(QSGGeometry::DrawTriangles);
151 quint16 *indices = m_geometry->indexDataAsUShort();
152 indices[0] = 0;
153 indices[1] = 1;
154 indices[2] = 2;
155 indices[3] = 1;
156 indices[4] = 3;
157 indices[5] = 2;
158
159 setGeometry(m_geometry);
160 setMaterial(m_material);
161 setFlag(OwnsGeometry, true);
162 setFlag(OwnsMaterial, true);
163}
164
165void QSGDefaultSpriteNode::setTexture(QSGTexture *texture)
166{
167 m_material->texture = texture;
168 m_geometryDirty = true;
169 markDirty(DirtyMaterial);
170}
171
173{
174 m_material->animT = time;
175 markDirty(DirtyMaterial);
176}
177
178void QSGDefaultSpriteNode::setSourceA(const QPoint &source)
179{
180 if (m_sourceA != source) {
181 m_sourceA = source;
182 m_material->animX1 = static_cast<float>(source.x()) / m_sheetSize.width();
183 m_material->animY1 = static_cast<float>(source.y()) / m_sheetSize.height();
184 markDirty(DirtyMaterial);
185 }
186}
187
188void QSGDefaultSpriteNode::setSourceB(const QPoint &source)
189{
190 if (m_sourceB != source) {
191 m_sourceB = source;
192 m_material->animX2 = static_cast<float>(source.x()) / m_sheetSize.width();
193 m_material->animY2 = static_cast<float>(source.y()) / m_sheetSize.height();
194 markDirty(DirtyMaterial);
195 }
196}
197
198void QSGDefaultSpriteNode::setSpriteSize(const QSize &size)
199{
200 if (m_spriteSize != size) {
201 m_spriteSize = size;
202 m_material->animW = static_cast<float>(size.width()) / m_sheetSize.width();
203 m_material->animH = static_cast<float>(size.height()) / m_sheetSize.height();
204 markDirty(DirtyMaterial);
205 }
206
207}
208
209void QSGDefaultSpriteNode::setSheetSize(const QSize &size)
210{
211 if (m_sheetSize != size) {
212 m_sheetSize = size;
213
214 // Update all dependent properties
215 m_material->animX1 = static_cast<float>(m_sourceA.x()) / m_sheetSize.width();
216 m_material->animY1 = static_cast<float>(m_sourceA.y()) / m_sheetSize.height();
217 m_material->animX2 = static_cast<float>(m_sourceB.x()) / m_sheetSize.width();
218 m_material->animY2 = static_cast<float>(m_sourceB.y()) / m_sheetSize.height();
219 m_material->animW = static_cast<float>(m_spriteSize.width()) / m_sheetSize.width();
220 m_material->animH = static_cast<float>(m_spriteSize.height()) / m_sheetSize.height();
221 markDirty(DirtyMaterial);
222 }
223}
224
225void QSGDefaultSpriteNode::setSize(const QSizeF &size)
226{
227 if (m_size != size) {
228 m_size = size;
229 m_geometryDirty = true;
230 }
231}
232
233void QSGDefaultSpriteNode::setFiltering(QSGTexture::Filtering filtering)
234{
235 m_material->texture->setFiltering(filtering);
236 markDirty(DirtyMaterial);
237}
238
240{
241 if (m_geometryDirty) {
242 updateGeometry();
243 m_geometryDirty = false;
244 }
245}
246
247void QSGDefaultSpriteNode::updateGeometry()
248{
249 if (!m_material->texture)
250 return;
251
252 SpriteVertices *p = (SpriteVertices *) m_geometry->vertexData();
253
254 QRectF texRect = m_material->texture->normalizedTextureSubRect();
255
256 p->v1.tx = texRect.topLeft().x();
257 p->v1.ty = texRect.topLeft().y();
258
259 p->v2.tx = texRect.topRight().x();
260 p->v2.ty = texRect.topRight().y();
261
262 p->v3.tx = texRect.bottomLeft().x();
263 p->v3.ty = texRect.bottomLeft().y();
264
265 p->v4.tx = texRect.bottomRight().x();
266 p->v4.ty = texRect.bottomRight().y();
267
268 p->v1.x = 0;
269 p->v1.y = 0;
270
271 p->v2.x = m_size.width();
272 p->v2.y = 0;
273
274 p->v3.x = 0;
275 p->v3.y = m_size.height();
276
277 p->v4.x = m_size.width();
278 p->v4.y = m_size.height();
279 markDirty(DirtyGeometry);
280}
281
282QT_END_NAMESPACE
QSGMaterialShader * createShader(QSGRendererInterface::RenderMode renderMode) const override
This function returns a new instance of a the QSGMaterialShader implementation used to render geometr...
QSGMaterialType * type() const override
This function is called by the scene graph to query an identifier that is unique to the QSGMaterialSh...
void setTexture(QSGTexture *texture) override
void setSheetSize(const QSize &size) override
void setSourceA(const QPoint &source) override
void setSize(const QSizeF &size) override
void setSpriteSize(const QSize &size) override
void setSourceB(const QPoint &source) override
void setTime(float time) override
void setFiltering(QSGTexture::Filtering filtering) override
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to prepare use of sampled images in the shader,...
Combined button and popup list for selecting options.
static QSGGeometry::Attribute Sprite_Attributes[]
static QSGGeometry::AttributeSet Sprite_AttributeSet