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