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