1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
|
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the Qt3D documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\ingroup qt3d
\ingroup qt3d::scene
\since 4.8
\title Declarative Scenegraph Creation
\page qt3d-declarative-scenegraph.html
\keyword Declarative Scenegraph Scene QML Quick
\brief Basics of scene construction in Qt3D (QML)
Qt3D implements a scene-graph to make rendering more efficient in terms of
both computation and space requirements. Loosely defined, a scene-graph is
a tree-like structure which is used to represent a graphical scene logically.
The variant of a scene-graph at the core of Qt3D's rendering is based on the
QGLSceneNode class and breaks the contents of the scene down into nodes.
\section1 Scene Nodes
Nodes can represent several logical constructs used in rendering. A single
node may include one or more of the following:
\section2 Geometry
Geometry describes the physical structure of an object in 3D space. It does
this in terms of "vertices" which are joined together to form a triangle mesh.
While many simple 3D objects can be represented by a single scene-node, complex
objects such as those found in third party asset interchange formats (.obj,
.3ds, etc) are comprised of multiple geometries stored across a multitude of
scene-nodes. This allows for sub-sections of geometry to be animated, rendered
with different materials and effects, and deconstructed as necessary.
\section2 Materials/Effects
Materials and effects describe how the surfaces of the geometry are rendered
when the scene is drawn. They may describe simple parameters used to describe
the object, such as color, texture images, alpha-blending, and other options.
Alternatively the material may be described by a specific set of shader
programmes in the GL shader-language which perform a custom implementation of
rendering.
Scene nodes can represent one or more materials which are then referenced when
drawing the geometry of this nodes, or its child nodes.
\section2 Transformations
Transformations in the scene-graph describe rotations around the x,y, or z axes,
as well as scaling, translation, or other custom transformations in 3D space.
A transformation node contains one or more transformations which are automatically
applied to the current node, as well as all of its child nodes.
\section2 Additional Parameters
Nodes can also contain additional parameters describing debug information, and
other miscellaneous functions such as whether the node should be rendered, whether
blending is enabled, and so on.
Nodes can also represent picking information which is used for selecting 3D items
with the mouse.
\section1 Scene Graphs in C++
When writing a C++ application the user can create one or more QGLSceneNode based
scene-graphs which can then be rendered each frame by calling the QGLSceneNode::draw()
function.
Scene graphs can be constructed manually by the user one node at a time, or by using
the QGLBuilder to assemble geometries. The Qt3D model loader plug-ins also
create individual scene-graphs which can then be used separately, or inserted into
an existing scene-graph.
Model-loader scene-graphs represent all of the geometries, transformations, materials,
and other elements, which are described in the model interchange file. These nodes can
be manipulated at the code-level at any time to modify or adjust the model as needed.
When the scenegraph is created, Qt3D optimises the drawing order of the scenegraph
somewhat so that all materials of the same type are drawn first, and so on. These
optimisations reduce the amount of context switching required by OpenGL when drawing,
and can substantially improve performance in complicated scenes.
\section1 QML 3D Scene Graphs in Qt3D for Qt 4.x
While C++ allows users to manually construct and manipulate scene-graphs, Qt3D's
extension into QtQuick does not currently allow the same degree of flexibility.
Qt3D for Qt4.x generally used a single small scene-graph for each Item3D. These would
only used shared geometry information if multiple Item3D instances referenced a single
Mesh instance. While sufficient for simple 3D use cases, this method is inherently
inefficient for drawing large/complex scenes. Without a single scenegraph we cannot
optimise the entire 3D scene.
Likewise in this implementation we have only a very limited ability to manipulate the
content of a model file/meh instance. In Qt4.x users are able to specify that an
Item3D contains a specific sub-node of a mesh's scenegraph. This removes the instance
from the tree in the graph which owns it, thereby changing the structure of the
originating model.
This limits our ability to implement specific use-cases.
These problems are addressed in Qt5.
\section1 QML 3D Scene Graphs in Qt3D for Qt 5
In Qt5 the QML implementation of Qt3D substantially improves this situation. Instead
of creating individual scene-graphs for each Mesh/Item3D, the user now creates a single
holistic scenegraph for each viewport. Addition of Item3D elements to a scene creates a
hierarchy of scene-graph branches which are then optimised and drawn in a single call for
the viewport.
Components of a mesh can now be accessed with specific QQuickMesh functions which are
exposed to QML.
The sections below describe the various scenarios in which a user may wish to use sub-components
of a model's scenegraph.
\section2 Scenario 1: Simple Single-Model Rendering
This displays the model "as is" with no changes or alterations.
\code
Mesh {
id: model
source: "bike.3ds"
}
Item3D {
mesh: model
}
\endcode
The output for this, as well as the scenegraphs it produces, can be seen below:
\image scenegraph_scenario_1.png
\section2 Scenario 2: Use a Sub-tree of the Model
This displays a sub-section of the model - in this case the wheel.
\code
Mesh {
id: model
source: "bike.3ds"
}
Item3D {
//Get just the subtree starting at wheel1
mesh: Mesh {scene: model.get(bike.body.wheel1)}
}
\endcode
The output for this, as well as the scenegraphs it produces, can be seen below:
\image scenegraph_scenario_2.png
\section2 Scenario 3: Use an Intermediate Set of Model Nodes
This displays an intermediate (sub)section of the graph but excludes specific nodes/
subtrees.
\code
Mesh {
id: model
source: "bike.3ds"
}
Item3D {
//get the model but exclude the sub-branch beginning at wheel1.
mesh: Mesh {model: model.except(bike.body.wheel1)}
}
\endcode
The output for this, as well as the scenegraphs it produces, can be seen below:
\image scenegraph_scenario_3.png
\section2 Scenario 4: Transform the Model, and a Sub-tree of the Model, Independently
This displays the original model in one Item3D and a sub-tree of the model in another.
The second item applies a transform to the item, which leaves the original model unchanged.
\code
Mesh {
id: model
source: "bike.3ds"
}
Item3D {
mesh: model
}
Item3D {
mesh: Mesh{scene: model.get(bike.body.wheel1)}
x: -5
z: 5
}
\endcode
The output for this, as well as the scenegraphs it produces, can be seen below:
\image scenegraph_scenario_4.png
\section2 Scenario 5: Use a Model, and a set materials on a Sub-tree of the Model, Independently
This displays the original model in one Item3D and a sub-tree of the model in another.
The second item applies an effect to the item, which leaves the original model unchanged.
\code
Mesh {
id: model
source: "bike.3ds"
}
Item3D {
mesh: model
}
Item3D {
mesh: Mesh{scene: model.get(bike.body.wheel1)}
effect: Effect {color: #00FF00}
}
\endcode
The output for this, as well as the scenegraphs it produces, can be seen below:
\image scenegraph_scenario_5.png
\section2 Scenario 6: Set Model materials, and use a Sub-tree of the Model, Independently
This displays an intermediate (sub)section of the graph to which an effect has been
applied but excludes specific nodes subtrees. In a second Item3D it displays a sub-node/
tree which is not affected by the effect on the first item.
\code
Mesh {
id: model
source: "car.3ds"
}
Item3D {
mesh: Mesh{scene: model.except(bike.body.wheel1)}
effect: Effect {color: #FF0000}
}
Item3D {
mesh: model.get(bike.body.wheel1)
}
\endcode
The output for this, as well as the scenegraphs it produces, can be seen below:
\image scenegraph_scenario_7.png
\section2 Scenario 7: Display Model Section, and Transform a Sub-tree of the Model, Independently
This displays an intermediate (sub)section of the graph but excludes specific nodes/
subtrees. In a second Item3D it displays a transformed sub-node/tree which does not affect the
first item.
\code
Mesh {
id: model
source: "car.3ds"
}
Item3D {
mesh: Mesh{scene: model.except(bike.body.wheel1)}
}
Item3D {
mesh: Mesh{scene: model.get(bike.body.wheel1)}
y: -2
}
\endcode
The output for this, as well as the scenegraphs it produces, can be seen below:
\image scenegraph_scenario_7.png
\section2 Scenario 8: Use Unconnected Sub-nodes of a Tree
This displays disparate subtrees of the model as a single item.
\code
Mesh {
id: model
source: "car.3ds"
}
Item3D {
mesh: Mesh{scene: model.get([car.body.wheel1, car.body.wheel2])}
}
\endcode
The output for this, as well as the scenegraphs it produces, can be seen below:
\image scenegraph_scenario_8.png
*/
|