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::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 | */ |
48 | QSGAbstractRendererPrivate::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 | */ |
59 | QSGAbstractRenderer::QSGAbstractRenderer(QObject *parent) |
60 | : QObject(*new QSGAbstractRendererPrivate, parent) |
61 | { |
62 | } |
63 | |
64 | /*! |
65 | \internal |
66 | */ |
67 | QSGAbstractRenderer::~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 | */ |
80 | void 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 | */ |
102 | QSGRootNode *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 | */ |
123 | void 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 | */ |
134 | QRect 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 | */ |
156 | void 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 | */ |
167 | QRect 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 | */ |
182 | void 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 | */ |
198 | void 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 | */ |
221 | void 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 | */ |
254 | void 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 | */ |
265 | void 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 | */ |
278 | QMatrix4x4 QSGAbstractRenderer::projectionMatrix(int index) const |
279 | { |
280 | Q_D(const QSGAbstractRenderer); |
281 | return d->m_projection_matrix[index]; |
282 | } |
283 | |
284 | int QSGAbstractRenderer::projectionMatrixCount() const |
285 | { |
286 | Q_D(const QSGAbstractRenderer); |
287 | return d->m_projection_matrix.count(); |
288 | } |
289 | |
290 | int QSGAbstractRenderer::projectionMatrixWithNativeNDCCount() const |
291 | { |
292 | Q_D(const QSGAbstractRenderer); |
293 | return d->m_projection_matrix_native_ndc.count(); |
294 | } |
295 | |
296 | /*! |
297 | \internal |
298 | */ |
299 | QMatrix4x4 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 | */ |
310 | void 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 | */ |
322 | QColor 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 | |
333 | void QSGAbstractRenderer::prepareSceneInline() |
334 | { |
335 | } |
336 | |
337 | void QSGAbstractRenderer::renderSceneInline() |
338 | { |
339 | } |
340 | |
341 | QT_END_NAMESPACE |
342 | |
343 | #include "moc_qsgabstractrenderer_p.cpp" |
344 | |