1 | // Copyright (C) 2017 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 "qscene2d.h" |
5 | #include "qscene2d_p.h" |
6 | #include <private/qrenderaspect_p.h> |
7 | #include "scene2d_p.h" |
8 | #include "scene2dmanager_p.h" |
9 | #include "scene2devent_p.h" |
10 | |
11 | #include <Qt3DCore/qentity.h> |
12 | |
13 | QT_BEGIN_NAMESPACE |
14 | |
15 | using namespace Qt3DCore; |
16 | |
17 | namespace Qt3DRender { |
18 | |
19 | namespace Quick { |
20 | |
21 | /*! |
22 | \namespace Qt3DRender::Quick |
23 | \inmodule Qt3DScene2D |
24 | \brief Internal namespace to import QML types. |
25 | */ |
26 | |
27 | /*! |
28 | \class Qt3DRender::Quick::QScene2D |
29 | \inheaderfile Qt3DQuickScene2D/QScene2D |
30 | \inmodule Qt3DScene2D |
31 | |
32 | \brief This class enables rendering qml into a texture, which then can be |
33 | used as a part of 3D scene. |
34 | |
35 | This class uses QQuickRenderControl to render the given QQuickItem into an |
36 | offscreen surface, which is attached to a texture provided by the user. This allows the |
37 | component to directly render into the texture without intermediate copy and the user to |
38 | freely specify how the texture is used in the 3D scene. |
39 | |
40 | The entities using the QScene2D can be associated with the class to enable interaction |
41 | with the item; if an entity has a QObjectPicker component, the pick events from that picker |
42 | are sent to the QScene2D and converted to mouse events and finally sent to the item. |
43 | |
44 | \note Only mouse events are supported. The item does not support keyboard input. |
45 | |
46 | \since 5.9 |
47 | */ |
48 | |
49 | /*! |
50 | \qmltype Scene2D |
51 | \inqmlmodule QtQuick.Scene2D |
52 | \since 5.9 |
53 | \instantiates Qt3DRender::Quick::QScene2D |
54 | |
55 | \brief This type enables rendering qml into a texture, which then can be |
56 | used as a part of 3D scene. |
57 | |
58 | This object uses RenderControl to render the given Item into an |
59 | offscreen surface, which is attached to a texture provided by the user. This allows the |
60 | component to directly render into the texture without intermediate copy and the user to |
61 | freely specify how the texture is used in the 3D scene. |
62 | |
63 | The entities using the Scene2D can be associated with the type to enable interaction |
64 | with the item; if an entity has an ObjectPicker component, the pick events from that picker |
65 | are sent to the Scene2D and converted to mouse events and finally sent to the item. |
66 | |
67 | \note Only mouse events are supported. The item does not support keyboard input. |
68 | |
69 | Usage: |
70 | \qml |
71 | Entity { |
72 | id: sceneRoot |
73 | |
74 | // specify Scene2D inside the entity hierarchy |
75 | Scene2D { |
76 | // specify output |
77 | output: RenderTargetOutput { |
78 | attachmentPoint: RenderTargetOutput.Color0 |
79 | texture: Texture2D { |
80 | id: textureId |
81 | width: 1024 |
82 | height: 1024 |
83 | format: Texture.RGBA8_UNorm |
84 | } |
85 | } |
86 | // specify entities |
87 | entities: [entityId] |
88 | |
89 | // specify rendered content |
90 | Rectangle { |
91 | color: "red" |
92 | } |
93 | } |
94 | |
95 | Entity { |
96 | id: entityId |
97 | |
98 | property Material material: TextureMaterial { |
99 | texture: textureId |
100 | } |
101 | property ObjectPicker picker: ObjectPicker { |
102 | hoverEnabled: true |
103 | dragEnabled: true |
104 | } |
105 | ... |
106 | |
107 | \endqml |
108 | */ |
109 | |
110 | /*! |
111 | \enum QScene2D::RenderPolicy |
112 | |
113 | This enum type describes types of render policies available. |
114 | \value Continuous The Scene2D is rendering continuously. This is the default render policy. |
115 | \value SingleShot The Scene2D renders to the texture only once after which the resources |
116 | allocated for rendering are released. |
117 | */ |
118 | |
119 | /*! |
120 | \qmlproperty RenderTargetOutput QtQuick.Scene2D::Scene2D::output |
121 | Holds the RenderTargetOutput, which specifies where the Scene2D is rendering to. |
122 | */ |
123 | |
124 | /*! |
125 | \qmlproperty enumeration QtQuick.Scene2D::Scene2D::renderPolicy |
126 | Holds the render policy of this Scene2D. |
127 | |
128 | \list |
129 | \li Continuous The Scene2D is rendering continuously. This is the default render policy. |
130 | \li SingleShot The Scene2D renders to the texture only once after which the resources |
131 | allocated for rendering are released. |
132 | \endlist |
133 | */ |
134 | /*! |
135 | \qmlproperty Item QtQuick.Scene2D::Scene2D::item |
136 | Holds the Item, which is rendered by Scene2D to the texture. |
137 | */ |
138 | |
139 | /*! |
140 | \qmlproperty bool QtQuick.Scene2D::Scene2D::mouseEnabled |
141 | Holds whether mouse events are enabled for the rendered item. The mouse events are |
142 | generated from object picking events of the entities added to the Scene2D. |
143 | Mouse is enabled by default. |
144 | |
145 | \note Events sent to items are delayed by one frame due to object picking |
146 | happening in the backend. |
147 | */ |
148 | /*! |
149 | \qmlproperty list<Entity> QtQuick.Scene2D::Scene2D::entities |
150 | Holds the list of entities which are associated with the Scene2D object. If the |
151 | entities have ObjectPicker, the pick events from that entity are sent to Scene2D |
152 | and converted to mouse events. |
153 | */ |
154 | |
155 | QScene2DPrivate::QScene2DPrivate() |
156 | : Qt3DCore::QNodePrivate() |
157 | , m_renderManager(new Scene2DManager(this)) |
158 | , m_output(nullptr) |
159 | { |
160 | } |
161 | |
162 | QScene2DPrivate::~QScene2DPrivate() |
163 | { |
164 | m_renderManager->cleanup(); |
165 | delete m_renderManager; |
166 | } |
167 | |
168 | |
169 | /*! |
170 | The constructor creates a new QScene2D instance with the specified \a parent. |
171 | */ |
172 | QScene2D::QScene2D(Qt3DCore::QNode *parent) |
173 | : Qt3DCore::QNode(*new QScene2DPrivate, parent) |
174 | { |
175 | #ifdef QT_STATIC |
176 | static bool isInitialized = false; |
177 | if (!isInitialized) { |
178 | Qt3DRender::QRenderAspectPrivate::configurePlugin(QLatin1String("scene2d" )); |
179 | } |
180 | #endif |
181 | } |
182 | |
183 | /*! |
184 | \property QScene2D::item |
185 | Holds the QQuickItem, which is rendered by QScene2D to the texture. |
186 | */ |
187 | QQuickItem* QScene2D::item() const |
188 | { |
189 | Q_D(const QScene2D); |
190 | return d->m_renderManager->m_item; |
191 | } |
192 | |
193 | void QScene2D::setItem(QQuickItem *item) |
194 | { |
195 | Q_D(QScene2D); |
196 | if (d->m_renderManager->m_initialized) { |
197 | qWarning() << "Unable to set item after initialization." ; |
198 | return; |
199 | } |
200 | if (d->m_renderManager->m_item != item) { |
201 | d->m_renderManager->setItem(item); |
202 | emit itemChanged(item); |
203 | } |
204 | } |
205 | |
206 | /*! |
207 | \property QScene2D::renderPolicy |
208 | |
209 | Holds the render policy of this Scene2D. |
210 | */ |
211 | QScene2D::RenderPolicy QScene2D::renderPolicy() const |
212 | { |
213 | Q_D(const QScene2D); |
214 | return d->m_renderManager->m_renderPolicy; |
215 | } |
216 | |
217 | void QScene2D::setRenderPolicy(QScene2D::RenderPolicy renderPolicy) |
218 | { |
219 | Q_D(const QScene2D); |
220 | if (d->m_renderManager->m_renderPolicy != renderPolicy) { |
221 | d->m_renderManager->m_renderPolicy = renderPolicy; |
222 | emit renderPolicyChanged(policy: renderPolicy); |
223 | } |
224 | } |
225 | |
226 | /*! |
227 | \property QScene2D::output |
228 | Holds the QRenderTargetOutput, which specifies where the QScene2D is |
229 | rendering to. |
230 | */ |
231 | Qt3DRender::QRenderTargetOutput *QScene2D::output() const |
232 | { |
233 | Q_D(const QScene2D); |
234 | return d->m_output; |
235 | } |
236 | |
237 | void QScene2D::setOutput(Qt3DRender::QRenderTargetOutput *output) |
238 | { |
239 | Q_D(QScene2D); |
240 | if (d->m_output != output) { |
241 | if (d->m_output) |
242 | d->unregisterDestructionHelper(node: d->m_output); |
243 | d->m_output = output; |
244 | if (output) |
245 | d->registerDestructionHelper(node: output, func: &QScene2D::setOutput, d->m_output); |
246 | emit outputChanged(output); |
247 | } |
248 | } |
249 | |
250 | bool QScene2D::isMouseEnabled() const |
251 | { |
252 | Q_D(const QScene2D); |
253 | return d->m_renderManager->m_mouseEnabled; |
254 | } |
255 | |
256 | /*! |
257 | Retrieve entities associated with the QScene2D. |
258 | */ |
259 | QList<Qt3DCore::QEntity *> QScene2D::entities() const |
260 | { |
261 | Q_D(const QScene2D); |
262 | return d->m_entities; |
263 | } |
264 | |
265 | /*! |
266 | Adds an \a entity to the the QScene2D object. If the entities have QObjectPicker, |
267 | the pick events from that entity are sent to QScene2D and converted to mouse events. |
268 | */ |
269 | void QScene2D::addEntity(Qt3DCore::QEntity *entity) |
270 | { |
271 | Q_D(QScene2D); |
272 | if (!d->m_entities.contains(t: entity)) { |
273 | d->m_entities.append(t: entity); |
274 | |
275 | d->registerDestructionHelper(node: entity, func: &QScene2D::removeEntity, d->m_entities); |
276 | d->update(); |
277 | } |
278 | } |
279 | |
280 | /*! |
281 | Removes an \a entity from the the QScene2D object. |
282 | */ |
283 | void QScene2D::removeEntity(Qt3DCore::QEntity *entity) |
284 | { |
285 | Q_D(QScene2D); |
286 | if (d->m_entities.contains(t: entity)) { |
287 | d->m_entities.removeAll(t: entity); |
288 | |
289 | d->unregisterDestructionHelper(node: entity); |
290 | d->update(); |
291 | } |
292 | } |
293 | |
294 | /*! |
295 | \property QScene2D::mouseEnabled |
296 | Holds whether mouse events are enabled for the rendered item. The mouse events are |
297 | generated from object picking events of the entities added to the QScene2D. |
298 | Mouse is enabled by default. |
299 | |
300 | \note Events are delayed by one frame due to object picking happening in the backend. |
301 | */ |
302 | void QScene2D::setMouseEnabled(bool enabled) |
303 | { |
304 | Q_D(QScene2D); |
305 | if (d->m_renderManager->m_mouseEnabled != enabled) { |
306 | d->m_renderManager->m_mouseEnabled = enabled; |
307 | emit mouseEnabledChanged(enabled); |
308 | } |
309 | } |
310 | |
311 | |
312 | } // namespace Quick |
313 | } // namespace Qt3DRender |
314 | |
315 | QT_END_NAMESPACE |
316 | |
317 | #include "moc_qscene2d.cpp" |
318 | |