1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQuick module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qsgabstractrenderer_p.h"
41
42QT_BEGIN_NAMESPACE
43
44/*!
45 \class QSGAbstractRenderer
46 \brief QSGAbstractRenderer gives access to the scene graph nodes and rendering of a QSGEngine.
47 \inmodule QtQuick
48 \since 5.4
49
50 A QSGAbstractRenderer created by a QSGEngine allows you to set your QSGNode
51 tree through setRootNode() and control the rendering viewport through
52 setDeviceRect(), setViewportRect() and setProjectionMatrixToRect().
53 You can finally trigger the rendering to the desired framebuffer through
54 renderScene().
55
56 The QSGAbstractRenderer is only available when used with a QSGEngine
57 and isn't exposed when used internally by QQuickWindow.
58
59 \sa QSGEngine, QSGNode
60 */
61
62/*!
63 \enum QSGAbstractRenderer::ClearModeBit
64
65 Used with setClearMode() to indicate which buffer should
66 be cleared before the scene render.
67
68 \value ClearColorBuffer Clear the color buffer using clearColor().
69 \value ClearDepthBuffer Clear the depth buffer.
70 \value ClearStencilBuffer Clear the stencil buffer.
71
72 \sa setClearMode(), setClearColor()
73 */
74
75/*!
76 \enum QSGAbstractRenderer::MatrixTransformFlag
77
78 Used with setProjectionMatrixToRect() to indicate the expectations towards
79 the generated projection matrix.
80
81 \value MatrixTransformFlipY The traditional assumption in Qt Quick is that
82 Y points up in the normalized device coordinate system. There is at least
83 one modern graphics API where this is not the case (Vulkan). This flag can
84 then be used to get a projection that is appropriate for such an API.
85
86 \sa setProjectionMatrixToRect()
87
88 \since 5.14
89 */
90
91/*!
92 \fn void QSGAbstractRenderer::renderScene(GLuint fboId = 0)
93
94 Render the scene to the specified \a fboId
95
96 If \a fboId isn't specified, the scene graph will be rendered
97 to the default framebuffer. You will have to call
98 QOpenGLContext::swapBuffers() yourself afterward.
99
100 The framebuffer specified by \a fboId will be bound automatically.
101
102 \sa QOpenGLContext::swapBuffers(), QOpenGLFramebufferObject::handle()
103 */
104
105/*!
106 \fn void QSGAbstractRenderer::sceneGraphChanged()
107
108 This signal is emitted on the first modification of a node in
109 the tree after the last scene render.
110 */
111
112/*!
113 \internal
114 */
115QSGAbstractRendererPrivate::QSGAbstractRendererPrivate()
116 : m_root_node(nullptr)
117 , m_clear_color(Qt::transparent)
118 , m_clear_mode(QSGAbstractRenderer::ClearColorBuffer | QSGAbstractRenderer::ClearDepthBuffer)
119{
120}
121
122/*!
123 \internal
124 */
125QSGAbstractRenderer::QSGAbstractRenderer(QObject *parent)
126 : QObject(*new QSGAbstractRendererPrivate, parent)
127{
128}
129
130/*!
131 \internal
132 */
133QSGAbstractRenderer::~QSGAbstractRenderer()
134{
135}
136
137/*!
138 Sets the \a node as the root of the QSGNode scene
139 that you want to render. You need to provide a \a node
140 before trying to render the scene.
141
142 \note This doesn't take ownership of \a node.
143
144 \sa rootNode()
145*/
146void QSGAbstractRenderer::setRootNode(QSGRootNode *node)
147{
148 Q_D(QSGAbstractRenderer);
149 if (d->m_root_node == node)
150 return;
151 if (d->m_root_node) {
152 d->m_root_node->m_renderers.removeOne(t: this);
153 nodeChanged(node: d->m_root_node, state: QSGNode::DirtyNodeRemoved);
154 }
155 d->m_root_node = node;
156 if (d->m_root_node) {
157 Q_ASSERT(!d->m_root_node->m_renderers.contains(this));
158 d->m_root_node->m_renderers << this;
159 nodeChanged(node: d->m_root_node, state: QSGNode::DirtyNodeAdded);
160 }
161}
162
163/*!
164 Returns the root of the QSGNode scene.
165
166 \sa setRootNode()
167*/
168QSGRootNode *QSGAbstractRenderer::rootNode() const
169{
170 Q_D(const QSGAbstractRenderer);
171 return d->m_root_node;
172}
173
174
175/*!
176 \fn void QSGAbstractRenderer::setDeviceRect(const QSize &size)
177 \overload
178
179 Sets the \a size of the surface being rendered to.
180
181 \sa deviceRect()
182 */
183
184/*!
185 Sets \a rect as the geometry of the surface being rendered to.
186
187 \sa deviceRect()
188 */
189void QSGAbstractRenderer::setDeviceRect(const QRect &rect)
190{
191 Q_D(QSGAbstractRenderer);
192 d->m_device_rect = rect;
193}
194
195/*!
196 Returns the device rect of the surface being rendered to.
197
198 \sa setDeviceRect()
199 */
200QRect QSGAbstractRenderer::deviceRect() const
201{
202 Q_D(const QSGAbstractRenderer);
203 return d->m_device_rect;
204}
205
206/*!
207 \fn void QSGAbstractRenderer::setViewportRect(const QSize &size)
208 \overload
209
210 Sets the \a size of the viewport to render
211 on the surface.
212
213 \sa viewportRect()
214 */
215
216/*!
217 Sets \a rect as the geometry of the viewport to render
218 on the surface.
219
220 \sa viewportRect()
221 */
222void QSGAbstractRenderer::setViewportRect(const QRect &rect)
223{
224 Q_D(QSGAbstractRenderer);
225 d->m_viewport_rect = rect;
226}
227
228/*!
229 Returns the rect of the viewport to render.
230
231 \sa setViewportRect()
232 */
233QRect QSGAbstractRenderer::viewportRect() const
234{
235 Q_D(const QSGAbstractRenderer);
236 return d->m_viewport_rect;
237}
238
239/*!
240 Convenience method that calls setProjectionMatrix() with an
241 orthographic matrix generated from \a rect.
242
243 \note This function assumes that the graphics API uses Y up in its
244 normalized device coordinate system.
245
246 \sa setProjectionMatrix(), projectionMatrix()
247 */
248void QSGAbstractRenderer::setProjectionMatrixToRect(const QRectF &rect)
249{
250 QMatrix4x4 matrix;
251 matrix.ortho(left: rect.x(),
252 right: rect.x() + rect.width(),
253 bottom: rect.y() + rect.height(),
254 top: rect.y(),
255 nearPlane: 1,
256 farPlane: -1);
257 setProjectionMatrix(matrix);
258 setProjectionMatrixWithNativeNDC(matrix);
259}
260
261/*!
262 Convenience method that calls setProjectionMatrix() with an
263 orthographic matrix generated from \a rect.
264
265 Set MatrixTransformFlipY in \a flags when the graphics API uses Y down in
266 its normalized device coordinate system (for example, Vulkan).
267
268 \sa setProjectionMatrix(), projectionMatrix()
269
270 \since 5.14
271 */
272void QSGAbstractRenderer::setProjectionMatrixToRect(const QRectF &rect, MatrixTransformFlags flags)
273{
274 const bool flipY = flags.testFlag(flag: MatrixTransformFlipY);
275 QMatrix4x4 matrix;
276 matrix.ortho(left: rect.x(),
277 right: rect.x() + rect.width(),
278 bottom: flipY ? rect.y() : rect.y() + rect.height(),
279 top: flipY ? rect.y() + rect.height() : rect.y(),
280 nearPlane: 1,
281 farPlane: -1);
282 setProjectionMatrix(matrix);
283
284 if (flipY) {
285 matrix.setToIdentity();
286 matrix.ortho(left: rect.x(),
287 right: rect.x() + rect.width(),
288 bottom: rect.y() + rect.height(),
289 top: rect.y(),
290 nearPlane: 1,
291 farPlane: -1);
292 }
293 setProjectionMatrixWithNativeNDC(matrix);
294}
295
296/*!
297 Use \a matrix to project the QSGNode coordinates onto surface pixels.
298
299 \sa projectionMatrix(), setProjectionMatrixToRect()
300 */
301void QSGAbstractRenderer::setProjectionMatrix(const QMatrix4x4 &matrix)
302{
303 Q_D(QSGAbstractRenderer);
304 d->m_projection_matrix = matrix;
305}
306
307/*!
308 \internal
309 */
310void QSGAbstractRenderer::setProjectionMatrixWithNativeNDC(const QMatrix4x4 &matrix)
311{
312 Q_D(QSGAbstractRenderer);
313 d->m_projection_matrix_native_ndc = matrix;
314}
315
316/*!
317 Returns the projection matrix
318
319 \sa setProjectionMatrix(), setProjectionMatrixToRect()
320 */
321QMatrix4x4 QSGAbstractRenderer::projectionMatrix() const
322{
323 Q_D(const QSGAbstractRenderer);
324 return d->m_projection_matrix;
325}
326
327/*!
328 \internal
329 */
330QMatrix4x4 QSGAbstractRenderer::projectionMatrixWithNativeNDC() const
331{
332 Q_D(const QSGAbstractRenderer);
333 return d->m_projection_matrix_native_ndc;
334}
335
336/*!
337 Use \a color to clear the framebuffer when clearMode() is
338 set to QSGAbstractRenderer::ClearColorBuffer.
339
340 \sa clearColor(), setClearMode()
341 */
342void QSGAbstractRenderer::setClearColor(const QColor &color)
343{
344 Q_D(QSGAbstractRenderer);
345 d->m_clear_color = color;
346}
347
348/*!
349 Returns the color that clears the framebuffer at the beginning
350 of the rendering.
351
352 \sa setClearColor(), clearMode()
353 */
354QColor QSGAbstractRenderer::clearColor() const
355{
356 Q_D(const QSGAbstractRenderer);
357 return d->m_clear_color;
358}
359
360/*!
361 Defines which attachment of the framebuffer should be cleared
362 before each scene render with the \a mode flag.
363
364 \sa clearMode(), setClearColor()
365 */
366void QSGAbstractRenderer::setClearMode(ClearMode mode)
367{
368 Q_D(QSGAbstractRenderer);
369 d->m_clear_mode = mode;
370}
371
372/*!
373 Flags defining which attachment of the framebuffer will be cleared
374 before each scene render.
375
376 \sa setClearMode(), clearColor()
377 */
378QSGAbstractRenderer::ClearMode QSGAbstractRenderer::clearMode() const
379{
380 Q_D(const QSGAbstractRenderer);
381 return d->m_clear_mode;
382}
383
384/*!
385 \fn void QSGAbstractRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
386 \internal
387 */
388
389QT_END_NAMESPACE
390
391#include "moc_qsgabstractrenderer.cpp"
392

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