summaryrefslogtreecommitdiffstats
path: root/src/core/doc/src/qt3d-overview.qdoc
blob: 48788b5c7b447518e72b3e9b8979e937bbdd43fa (plain)
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
/****************************************************************************
**
** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
    \page qt3d-overview.html
    \title Qt3D Overview

    \brief Qt3D provides C++ and QML APIs to incorporate 3D content into Qt
    applications.

    Qt3D provides a fully configurable renderer that enables developers to
    quickly implement any rendering pipeline that they need. Further, Qt3D
    provides a generic framework for near-realtime simulations beyond rendering.

    Qt3D is cleanly separated into a core and any number of \e aspects that can
    implement any functionality they wish. The aspects interact with
    \e components and \e entities to provide some slice of functionality.
    Examples of aspects include physics, audio, collision, artificial
    intelligence (AI), and path finding.

    \section1 Basic 3D Features

    Qt3D is a 3D framework that enables the drawing of 3D shapes and moving
    them around, as well as moving the camera. It supports the following basic
    features:

    \list
        \li 2D and 3D rendering for C++ and Qt Quick applications
        \li Meshes
        \li Materials
        \li Shadows
        \li Shaders
        \li Ambient occlusion
        \li High dynamic range
        \li Deferred rendering
        \li Multitexturing
        \li Instancing
        \li Uniform Buffer Objects
    \endlist

    \section1 Configurable Renderer

    To combine support for both C++ and QML APIs with having a fully
    configurable renderer, the concept of a \e framegraph was introduced.
    While a \e scenegraph is a data-driven description of \e what to render, a
    framegraph is a data-driven description of \e how to render it.

    A framegraph enables developers to choose between a simple forward renderer,
    including a z-fill pass, or using a deferred renderer for example. It also
    gives them control over when to render any transparent objects, and so on.
    Since this is all configured purely from data, it is very easy to modify even
    dynamically at runtime without touching any C++ code. It is possible to
    extend Qt3D by creating your own framegraphs that implement custom
    rendering algorithms.

    \section1 3D Extensions

    Beyond the essentials of displaying 3D content on the screen, Qt3D is
    extensible and flexible enough to act as a host for following types of
    extensions related to the 3D objects:

    \list
        \li Physics simulation
        \li Collision detection
        \li 3D positional audio
        \li Rigid body, skeletal, and morph target animation
        \li Path finding and other AI
        \li Picking
        \li Particles
        \li Object spawning
    \endlist

    \section1 Performance

    Qt3D is designed to perform well and scale up with the number of available
    CPU cores, because modern hardware improves performance by increasing the
    numbers of cores rather than base clock speed. Using multiple cores works
    well, because many tasks are independent of each other. For example, the
    operations performed by a path finding module do not overlap strongly with
    the tasks performed by a renderer, except maybe when rendering debug
    information or statistics.

    \section1 Qt3D Architecture

    The main use cases of Qt3D are simulating objects in near-realtime and
    rendering the state of those objects onto the screen. The Space Invaders
    example contains the following objects:

    \image Space-invaders.jpg

    \list
        \li The player's ground cannon
        \li The ground
        \li The defensive blocks
        \li The enemy space invader ships
        \li The enemy boss flying saucer
        \li The bullets shot by the enemies and the player
    \endlist

    In a traditional C++ design, these types of object would typically be
    implemented as classes arranged in some kind of inheritance tree. Various
    branches in the inheritance tree might add additional functionality to the
    root class for features such as:

    \list
        \li Accepts user input
        \li Plays a sound
        \li Is animated
        \li Collides with other objects
        \li Is drawn on screen
    \endlist

    The types in the Space Invaders example can be classified against these
    features. However, designing an elegant inheritance tree for even such a
    simple example is not easy.

    This approach and other variations on inheritance present a number of
    problems:

    \list
        \li Deep and wide inheritance hierarchies are difficult to understand,
            maintain and extend.
        \li The inheritance taxonomy is set in stone at compile time.
        \li Each level in the class inheritance tree can only classify upon a
            single criteria or axis.
        \li Shared functionality tends to \e {bubble up} the class hierarchy
            over time.
        \li It is impossible to predict what the developers will want to do.
    \endlist

    Extending deep and wide inheritance trees usually requires understanding,
    and agreeing with, the taxonomy used by the original author. Therefore,
    Qt3D places focus on aggregation instead of inheritance as the means of
    imparting functionality onto an instance of an object. Specifically, Qt3D
    implements an Entity Component System (ECS).

    \section2 Using an ECS

    In an ECS, an entity represents a simulated object but by itself is devoid
    of any specific behavior or characteristics. Additional behavior can be
    grafted onto an entity by having the entity aggregate one or more
    components. Each component is a vertical slice of behavior of an object
    type.

    In the Space Invaders example, the ground is an entity with an attached
    component that tells the system that the entity needs rendering and what
    kind of rendering it needs. An enemy space invader ship is another entity
    with attached components that cause the ship to be rendered, but also enable
    it to emit sounds, be collided with, be animated, and be controlled by a
    simple AI.

    The player's ground cannon entity has mostly similar components to the enemy
    space invader ship, except that it does not have the AI component. In its
    place, the cannon has an input component to enable the player to move it
    around and to fire bullets.

    \section2 ECS Backend

    \image ecs-2.png

    The backend of Qt3D implements the \e system part of the ECS paradigm in
    the form of \e aspects. An aspect implements the particular vertical slice
    of the functionality provided to entities by a combination of one or more
    of their aggregated components.

    For example, the renderer aspect looks for entities that have mesh,
    material, and optionally transformation components. If the renderer aspect
    finds such an entity, it knows how to take that data and draw something nice
    from it. If an entity does not have those components, the renderer aspect
    ignores it.

    Qt3D builds custom entities by aggregating components that provide
    additional capabilities. The Qt3D engine uses aspects to process and
    update entities with specific components.

    For example, a physics aspect looks for entities that have some kind of
    collision volume component and another component that specifies other
    properties needed by such simulations like mass, coefficient of friction,
    and so on. An entity that emits sound has a component that specifies it is
    a sound emitter, as well as specifying when and which sounds to play.

    Because ECS uses aggregation rather than inheritance, it is possible to
    dynamically change how an object behaves at runtime simply by adding or
    removing components.

    For example, to enable a player to suddenly run through walls after a
    power-up, that entity's collision volume component can be removed
    temporarily, until the power-up times out. There is no need to create a
    special one-off subclass for \c PlayerWhoRunsThroughWalls.

    \section2 Qt3D ECS Implementation

    Qt3D implements ECS as a simple class hierarchy. The Qt3D base class is
    Qt3D::QNode, which is a subclass of QObject. Qt3D::QNode adds to QObject the ability to
    automatically communicate property changes to aspects and an ID that is
    unique throughout an application. The aspects exist in additional threads
    and Qt3D::QNode simplifies the data transfer between the user-facing objects and
    the aspects.

    Typically, subclasses of Qt3D::QNode provide additional supporting data that is
    referenced by components. For example, the QShaderProgram class specifies
    the GLSL code to be used when rendering a set of entities.

    \image ecs-1.png

    Components in Qt3D are implemented by subclassing Qt3D::QComponent and adding the
    data necessary for the corresponding aspect to do its work. For example, the
    mesh component is used by the renderer aspect to retrieve the per-vertex
    data that should be sent down the OpenGL pipeline.

    Finally, Qt3D::QEntity is simply an object that can aggregate zero or more
    Qt3D::QComponent instances.

    \section1 Extending Qt3D

    Adding functionality to Qt3D, either as part of Qt or specific to your
    own applications to benefit from the multi-threaded back-end consists of the
    following tasks:

    \list
        \li Identify and implement any necessary components and supporting data.
        \li Register the components with the QML engine (only if you use the QML
            API).
        \li Subclass QAbstractAspect and implement the subsystem functionality.
    \endlist

    \section1 Qt3D Task-Based Engine

    In Qt3D, aspects are asked in each frame for a set of \e tasks to execute
    along with the \e dependencies between them. The tasks are distributed
    across all the configured cores by a scheduler to improve performance.

    \section1 Qt3D's Aspects

    By default Qt3D provides the Qt3DRenderer and Qt3DInput aspects. The
    components and other supporting classes provided by these aspects are
    discussed in the documentation for those modules.

    Additional aspects providing more capabilities will be added in future
    versions of Qt3D.