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 \fn void QSGAbstractRenderer::renderScene(GLuint fboId = 0)
77
78 Render the scene to the specified \a fboId
79
80 If \a fboId isn't specified, the scene graph will be rendered
81 to the default framebuffer. You will have to call
82 QOpenGLContext::swapBuffers() yourself afterward.
83
84 The framebuffer specified by \a fboId will be bound automatically.
85
86 \sa QOpenGLContext::swapBuffers(), QOpenGLFramebufferObject::handle()
87 */
88
89/*!
90 \fn void QSGAbstractRenderer::sceneGraphChanged()
91
92 This signal is emitted on the first modification of a node in
93 the tree after the last scene render.
94 */
95
96/*!
97 \internal
98 */
99QSGAbstractRendererPrivate::QSGAbstractRendererPrivate()
100 : m_root_node(nullptr)
101 , m_clear_color(Qt::transparent)
102 , m_clear_mode(QSGAbstractRenderer::ClearColorBuffer | QSGAbstractRenderer::ClearDepthBuffer)
103{
104}
105
106/*!
107 \internal
108 */
109QSGAbstractRenderer::QSGAbstractRenderer(QObject *parent)
110 : QObject(*new QSGAbstractRendererPrivate, parent)
111{
112}
113
114/*!
115 \internal
116 */
117QSGAbstractRenderer::~QSGAbstractRenderer()
118{
119}
120
121/*!
122 Sets the \a node as the root of the QSGNode scene
123 that you want to render. You need to provide a \a node
124 before trying to render the scene.
125
126 \note This doesn't take ownership of \a node.
127
128 \sa rootNode()
129*/
130void QSGAbstractRenderer::setRootNode(QSGRootNode *node)
131{
132 Q_D(QSGAbstractRenderer);
133 if (d->m_root_node == node)
134 return;
135 if (d->m_root_node) {
136 d->m_root_node->m_renderers.removeOne(this);
137 nodeChanged(d->m_root_node, QSGNode::DirtyNodeRemoved);
138 }
139 d->m_root_node = node;
140 if (d->m_root_node) {
141 Q_ASSERT(!d->m_root_node->m_renderers.contains(this));
142 d->m_root_node->m_renderers << this;
143 nodeChanged(d->m_root_node, QSGNode::DirtyNodeAdded);
144 }
145}
146
147/*!
148 Returns the root of the QSGNode scene.
149
150 \sa setRootNode()
151*/
152QSGRootNode *QSGAbstractRenderer::rootNode() const
153{
154 Q_D(const QSGAbstractRenderer);
155 return d->m_root_node;
156}
157
158
159/*!
160 \fn void QSGAbstractRenderer::setDeviceRect(const QSize &size)
161 \overload
162
163 Sets the \a size of the surface being rendered to.
164
165 \sa deviceRect()
166 */
167
168/*!
169 Sets \a rect as the geometry of the surface being rendered to.
170
171 \sa deviceRect()
172 */
173void QSGAbstractRenderer::setDeviceRect(const QRect &rect)
174{
175 Q_D(QSGAbstractRenderer);
176 d->m_device_rect = rect;
177}
178
179/*!
180 Returns the device rect of the surface being rendered to.
181
182 \sa setDeviceRect()
183 */
184QRect QSGAbstractRenderer::deviceRect() const
185{
186 Q_D(const QSGAbstractRenderer);
187 return d->m_device_rect;
188}
189
190/*!
191 \fn void QSGAbstractRenderer::setViewportRect(const QSize &size)
192 \overload
193
194 Sets the \a size of the viewport to render
195 on the surface.
196
197 \sa viewportRect()
198 */
199
200/*!
201 Sets \a rect as the geometry of the viewport to render
202 on the surface.
203
204 \sa viewportRect()
205 */
206void QSGAbstractRenderer::setViewportRect(const QRect &rect)
207{
208 Q_D(QSGAbstractRenderer);
209 d->m_viewport_rect = rect;
210}
211
212/*!
213 Returns the rect of the viewport to render.
214
215 \sa setViewportRect()
216 */
217QRect QSGAbstractRenderer::viewportRect() const
218{
219 Q_D(const QSGAbstractRenderer);
220 return d->m_viewport_rect;
221}
222
223/*!
224 Convenience method that calls setProjectionMatrix() with an
225 orthographic matrix generated from \a rect.
226
227 \a flipY must be \c true when the graphics API uses Y down in its
228 normalized device coordinate system (for example, Vulkan), \c false
229 otherwise.
230
231 \sa setProjectionMatrix(), projectionMatrix()
232 */
233void QSGAbstractRenderer::setProjectionMatrixToRect(const QRectF &rect, bool flipY)
234{
235 QMatrix4x4 matrix;
236 matrix.ortho(rect.x(),
237 rect.x() + rect.width(),
238 flipY ? rect.y() : rect.y() + rect.height(),
239 flipY ? rect.y() + rect.height() : rect.y(),
240 1,
241 -1);
242 setProjectionMatrix(matrix);
243
244 if (flipY) {
245 matrix.setToIdentity();
246 matrix.ortho(rect.x(),
247 rect.x() + rect.width(),
248 rect.y() + rect.height(),
249 rect.y(),
250 1,
251 -1);
252 }
253 setProjectionMatrixWithNativeNDC(matrix);
254}
255
256/*!
257 Use \a matrix to project the QSGNode coordinates onto surface pixels.
258
259 \sa projectionMatrix(), setProjectionMatrixToRect()
260 */
261void QSGAbstractRenderer::setProjectionMatrix(const QMatrix4x4 &matrix)
262{
263 Q_D(QSGAbstractRenderer);
264 d->m_projection_matrix = matrix;
265}
266
267/*!
268 \internal
269 */
270void QSGAbstractRenderer::setProjectionMatrixWithNativeNDC(const QMatrix4x4 &matrix)
271{
272 Q_D(QSGAbstractRenderer);
273 d->m_projection_matrix_native_ndc = matrix;
274}
275
276/*!
277 Returns the projection matrix
278
279 \sa setProjectionMatrix(), setProjectionMatrixToRect()
280 */
281QMatrix4x4 QSGAbstractRenderer::projectionMatrix() const
282{
283 Q_D(const QSGAbstractRenderer);
284 return d->m_projection_matrix;
285}
286
287/*!
288 \internal
289 */
290QMatrix4x4 QSGAbstractRenderer::projectionMatrixWithNativeNDC() const
291{
292 Q_D(const QSGAbstractRenderer);
293 return d->m_projection_matrix_native_ndc;
294}
295
296/*!
297 Use \a color to clear the framebuffer when clearMode() is
298 set to QSGAbstractRenderer::ClearColorBuffer.
299
300 \sa clearColor(), setClearMode()
301 */
302void QSGAbstractRenderer::setClearColor(const QColor &color)
303{
304 Q_D(QSGAbstractRenderer);
305 d->m_clear_color = color;
306}
307
308/*!
309 Returns the color that clears the framebuffer at the beginning
310 of the rendering.
311
312 \sa setClearColor(), clearMode()
313 */
314QColor QSGAbstractRenderer::clearColor() const
315{
316 Q_D(const QSGAbstractRenderer);
317 return d->m_clear_color;
318}
319
320/*!
321 Defines which attachment of the framebuffer should be cleared
322 before each scene render with the \a mode flag.
323
324 \sa clearMode(), setClearColor()
325 */
326void QSGAbstractRenderer::setClearMode(ClearMode mode)
327{
328 Q_D(QSGAbstractRenderer);
329 d->m_clear_mode = mode;
330}
331
332/*!
333 Flags defining which attachment of the framebuffer will be cleared
334 before each scene render.
335
336 \sa setClearMode(), clearColor()
337 */
338QSGAbstractRenderer::ClearMode QSGAbstractRenderer::clearMode() const
339{
340 Q_D(const QSGAbstractRenderer);
341 return d->m_clear_mode;
342}
343
344/*!
345 \fn void QSGAbstractRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
346 \internal
347 */
348
349QT_END_NAMESPACE
350
351#include "moc_qsgabstractrenderer.cpp"
352