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
4#include "qsgabstractrenderer_p_p.h"
5
6QT_BEGIN_NAMESPACE
7
8/*!
9 \class QSGAbstractRenderer
10 \brief QSGAbstractRenderer gives access to the scene graph nodes and rendering.
11 \inmodule QtQuick
12 \since 5.4
13 \internal
14 */
15
16/*!
17 \enum QSGAbstractRenderer::MatrixTransformFlag
18
19 Used with setProjectionMatrixToRect() to indicate the expectations towards
20 the generated projection matrix.
21
22 \value MatrixTransformFlipY The traditional assumption in Qt Quick is that
23 Y points up in the normalized device coordinate system. There is at least
24 one modern graphics API where this is not the case (Vulkan). This flag can
25 then be used to get a projection that is appropriate for such an API.
26
27 \sa setProjectionMatrixToRect()
28
29 \since 5.14
30 */
31
32/*!
33 \fn void QSGAbstractRenderer::renderScene()
34
35 Renders the scene.
36 */
37
38/*!
39 \fn void QSGAbstractRenderer::sceneGraphChanged()
40
41 This signal is emitted on the first modification of a node in
42 the tree after the last scene render.
43 */
44
45/*!
46 \internal
47 */
48QSGAbstractRendererPrivate::QSGAbstractRendererPrivate()
49 : m_root_node(nullptr)
50 , m_clear_color(Qt::transparent)
51{
52 m_projection_matrix.resize(sz: 1);
53 m_projection_matrix_native_ndc.resize(sz: 1);
54}
55
56/*!
57 \internal
58 */
59QSGAbstractRenderer::QSGAbstractRenderer(QObject *parent)
60 : QObject(*new QSGAbstractRendererPrivate, parent)
61{
62}
63
64/*!
65 \internal
66 */
67QSGAbstractRenderer::~QSGAbstractRenderer()
68{
69}
70
71/*!
72 Sets the \a node as the root of the QSGNode scene
73 that you want to render. You need to provide a \a node
74 before trying to render the scene.
75
76 \note This doesn't take ownership of \a node.
77
78 \sa rootNode()
79*/
80void QSGAbstractRenderer::setRootNode(QSGRootNode *node)
81{
82 Q_D(QSGAbstractRenderer);
83 if (d->m_root_node == node)
84 return;
85 if (d->m_root_node) {
86 d->m_root_node->m_renderers.removeOne(t: this);
87 nodeChanged(node: d->m_root_node, state: QSGNode::DirtyNodeRemoved);
88 }
89 d->m_root_node = node;
90 if (d->m_root_node) {
91 Q_ASSERT(!d->m_root_node->m_renderers.contains(this));
92 d->m_root_node->m_renderers << this;
93 nodeChanged(node: d->m_root_node, state: QSGNode::DirtyNodeAdded);
94 }
95}
96
97/*!
98 Returns the root of the QSGNode scene.
99
100 \sa setRootNode()
101*/
102QSGRootNode *QSGAbstractRenderer::rootNode() const
103{
104 Q_D(const QSGAbstractRenderer);
105 return d->m_root_node;
106}
107
108
109/*!
110 \fn void QSGAbstractRenderer::setDeviceRect(const QSize &size)
111 \overload
112
113 Sets the \a size of the surface being rendered to.
114
115 \sa deviceRect()
116 */
117
118/*!
119 Sets \a rect as the geometry of the surface being rendered to.
120
121 \sa deviceRect()
122 */
123void QSGAbstractRenderer::setDeviceRect(const QRect &rect)
124{
125 Q_D(QSGAbstractRenderer);
126 d->m_device_rect = rect;
127}
128
129/*!
130 Returns the device rect of the surface being rendered to.
131
132 \sa setDeviceRect()
133 */
134QRect QSGAbstractRenderer::deviceRect() const
135{
136 Q_D(const QSGAbstractRenderer);
137 return d->m_device_rect;
138}
139
140/*!
141 \fn void QSGAbstractRenderer::setViewportRect(const QSize &size)
142 \overload
143
144 Sets the \a size of the viewport to render
145 on the surface.
146
147 \sa viewportRect()
148 */
149
150/*!
151 Sets \a rect as the geometry of the viewport to render
152 on the surface.
153
154 \sa viewportRect()
155 */
156void QSGAbstractRenderer::setViewportRect(const QRect &rect)
157{
158 Q_D(QSGAbstractRenderer);
159 d->m_viewport_rect = rect;
160}
161
162/*!
163 Returns the rect of the viewport to render.
164
165 \sa setViewportRect()
166 */
167QRect QSGAbstractRenderer::viewportRect() const
168{
169 Q_D(const QSGAbstractRenderer);
170 return d->m_viewport_rect;
171}
172
173/*!
174 Convenience method that calls setProjectionMatrix() with an
175 orthographic matrix generated from \a rect.
176
177 \note This function assumes that the graphics API uses Y up in its
178 normalized device coordinate system.
179
180 \sa setProjectionMatrix(), projectionMatrix()
181 */
182void QSGAbstractRenderer::setProjectionMatrixToRect(const QRectF &rect)
183{
184 setProjectionMatrixToRect(rect, flags: {}, nativeNDCFlipY: false);
185}
186
187/*!
188 Convenience method that calls setProjectionMatrix() with an
189 orthographic matrix generated from \a rect.
190
191 Set MatrixTransformFlipY in \a flags when the graphics API uses Y down in
192 its normalized device coordinate system (for example, Vulkan).
193
194 \sa setProjectionMatrix(), projectionMatrix()
195
196 \since 5.14
197 */
198void QSGAbstractRenderer::setProjectionMatrixToRect(const QRectF &rect, MatrixTransformFlags flags)
199{
200 setProjectionMatrixToRect(rect, flags, nativeNDCFlipY: flags.testFlag(flag: MatrixTransformFlipY));
201}
202
203/*!
204 Convenience method that calls setProjectionMatrix() with an
205 orthographic matrix generated from \a rect.
206
207 Set MatrixTransformFlipY in \a flags when the graphics API uses Y down in
208 its normalized device coordinate system (for example, Vulkan).
209
210 Convenience method that calls setProjectionMatrixWithNativeNDC() with an
211 orthographic matrix generated from \a rect.
212
213 Set true to \a nativeNDCFlipY to flip the Y axis relative to
214 projection matrix in its normalized device coordinate system.
215
216 \sa setProjectionMatrix(), projectionMatrix()
217 \sa setProjectionMatrixWithNativeNDC(), projectionMatrixWithNativeNDC()
218
219 \since 6.7
220 */
221void QSGAbstractRenderer::setProjectionMatrixToRect(const QRectF &rect, MatrixTransformFlags flags,
222 bool nativeNDCFlipY)
223{
224 const bool flipY = flags.testFlag(flag: MatrixTransformFlipY);
225
226 const float left = rect.x();
227 const float right = rect.x() + rect.width();
228 float bottom = rect.y() + rect.height();
229 float top = rect.y();
230
231 if (flipY)
232 std::swap(a&: top, b&: bottom);
233
234 QMatrix4x4 matrix;
235 matrix.ortho(left, right, bottom, top, nearPlane: 1, farPlane: -1);
236 setProjectionMatrix(matrix, index: 0);
237
238 if (nativeNDCFlipY) {
239 std::swap(a&: top, b&: bottom);
240
241 matrix.setToIdentity();
242 matrix.ortho(left, right, bottom, top, nearPlane: 1, farPlane: -1);
243 }
244 setProjectionMatrixWithNativeNDC(matrix, index: 0);
245}
246
247/*!
248 Use \a matrix to project the QSGNode coordinates onto surface pixels.
249
250 \a index specifies the view index when multiview rendering is in use.
251
252 \sa projectionMatrix(), setProjectionMatrixToRect()
253 */
254void QSGAbstractRenderer::setProjectionMatrix(const QMatrix4x4 &matrix, int index)
255{
256 Q_D(QSGAbstractRenderer);
257 if (d->m_projection_matrix.count() <= index)
258 d->m_projection_matrix.resize(sz: index + 1);
259 d->m_projection_matrix[index] = matrix;
260}
261
262/*!
263 \internal
264 */
265void QSGAbstractRenderer::setProjectionMatrixWithNativeNDC(const QMatrix4x4 &matrix, int index)
266{
267 Q_D(QSGAbstractRenderer);
268 if (d->m_projection_matrix_native_ndc.count() <= index)
269 d->m_projection_matrix_native_ndc.resize(sz: index + 1);
270 d->m_projection_matrix_native_ndc[index] = matrix;
271}
272
273/*!
274 Returns the projection matrix
275
276 \sa setProjectionMatrix(), setProjectionMatrixToRect()
277 */
278QMatrix4x4 QSGAbstractRenderer::projectionMatrix(int index) const
279{
280 Q_D(const QSGAbstractRenderer);
281 return d->m_projection_matrix[index];
282}
283
284int QSGAbstractRenderer::projectionMatrixCount() const
285{
286 Q_D(const QSGAbstractRenderer);
287 return d->m_projection_matrix.count();
288}
289
290int QSGAbstractRenderer::projectionMatrixWithNativeNDCCount() const
291{
292 Q_D(const QSGAbstractRenderer);
293 return d->m_projection_matrix_native_ndc.count();
294}
295
296/*!
297 \internal
298 */
299QMatrix4x4 QSGAbstractRenderer::projectionMatrixWithNativeNDC(int index) const
300{
301 Q_D(const QSGAbstractRenderer);
302 return d->m_projection_matrix_native_ndc[index];
303}
304
305/*!
306 Sets the \a color to clear the framebuffer.
307
308 \sa clearColor()
309 */
310void QSGAbstractRenderer::setClearColor(const QColor &color)
311{
312 Q_D(QSGAbstractRenderer);
313 d->m_clear_color = color;
314}
315
316/*!
317 Returns the color that clears the framebuffer at the beginning
318 of the rendering.
319
320 \sa setClearColor()
321 */
322QColor QSGAbstractRenderer::clearColor() const
323{
324 Q_D(const QSGAbstractRenderer);
325 return d->m_clear_color;
326}
327
328/*!
329 \fn void QSGAbstractRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
330 \internal
331 */
332
333void QSGAbstractRenderer::prepareSceneInline()
334{
335}
336
337void QSGAbstractRenderer::renderSceneInline()
338{
339}
340
341QT_END_NAMESPACE
342
343#include "moc_qsgabstractrenderer_p.cpp"
344

source code of qtdeclarative/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp