1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt3D module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "qlayerfilter.h" |
41 | #include "qlayerfilter_p.h" |
42 | #include "qlayer.h" |
43 | #include <Qt3DRender/qframegraphnodecreatedchange.h> |
44 | |
45 | QT_BEGIN_NAMESPACE |
46 | |
47 | namespace Qt3DRender { |
48 | |
49 | QLayerFilterPrivate::QLayerFilterPrivate() |
50 | : QFrameGraphNodePrivate() |
51 | , m_filterMode(QLayerFilter::AcceptAnyMatchingLayers) |
52 | { |
53 | } |
54 | |
55 | /*! |
56 | \class Qt3DRender::QLayerFilter |
57 | \inmodule Qt3DRender |
58 | \since 5.5 |
59 | \brief Controls layers drawn in a frame graph branch. |
60 | |
61 | A Qt3DRender::QLayerFilter can be used to instruct the renderer as to |
62 | which layer(s) to draw in that branch of the frame graph. QLayerFilter |
63 | selects which entities to draw based on the QLayer instance(s) added to |
64 | the QLayerFilter and as components to Qt3DCore::QEntity. |
65 | |
66 | QLayerFilter can be configured to select or discard entities with a |
67 | specific \l QLayer depending on the filterMode property. By default, |
68 | entities referencing one of the \l QLayer objects that are also being |
69 | referenced by the \l QLayerFilter are selected (AcceptAnyMatchingLayers). |
70 | |
71 | Within the FrameGraph tree, multiple \l QLayerFilter nodes can be nested |
72 | within a branch going from root to a leaf. In that case the filtering will |
73 | first operate on all entities of the scene using the filtering method |
74 | specified by the first declared \l QLayerFilter. Then the filtered subset |
75 | of entities will be filtered again based on the filtering method set on the |
76 | second \l QLayerFilter declared. This is then repeated until all \l |
77 | QLayerFilter nodes of the branch have been consumed. |
78 | */ |
79 | |
80 | /*! |
81 | \enum QLayerFilter::FilterMode |
82 | |
83 | Specifies the rules for selecting entities to draw. |
84 | |
85 | \value AcceptAnyMatchingLayers |
86 | Accept entities that reference one or more \l QLayer objects added to this |
87 | QLayerFilter. This is the default |
88 | |
89 | \value AcceptAllMatchingLayers |
90 | Accept entities that reference all the \l QLayer objects added to this |
91 | QLayerFilter |
92 | |
93 | \value DiscardAnyMatchingLayers |
94 | Discard entities that reference one or more \l QLayer objects added to this |
95 | QLayerFilter |
96 | |
97 | \value DiscardAllMatchingLayers |
98 | Discard entities that reference all \l QLayer objects added to this |
99 | QLayerFilter |
100 | */ |
101 | |
102 | /*! |
103 | \property Qt3DRender::QLayerFilter::filterMode |
104 | |
105 | Holds the filter mode specifying the entities to select for drawing. |
106 | |
107 | The default value is AcceptMatchingLayers. |
108 | */ |
109 | |
110 | /*! |
111 | \qmltype LayerFilter |
112 | \instantiates Qt3DRender::QLayerFilter |
113 | \inherits FrameGraphNode |
114 | \inqmlmodule Qt3D.Render |
115 | \since 5.5 |
116 | \brief Controls layers drawn in a frame graph branch. |
117 | |
118 | A LayerFilter can be used to instruct the renderer as to which layer(s) |
119 | to draw in that branch of the frame graph. The LayerFilter selects which |
120 | entities to draw based on the \l Layer instances added to the LayerFilter |
121 | and as components to the \l Entity. |
122 | |
123 | The LayerFilter can be configured to select or discard entities with a |
124 | specific \l Layer depending on the filterMode property. By default, |
125 | entities referencing one of the \l Layer objects that are also being |
126 | referenced by the \l LayerFilter are selected (AcceptAnyMatchingLayers). |
127 | |
128 | Within the FrameGraph tree, multiple \l LayerFilter nodes can be nested |
129 | within a branch going from root to a leaf. In that case the filtering will |
130 | first operate on all entities of the scene using the filtering method |
131 | specified by the first declared \l LayerFilter. Then the filtered subset of |
132 | entities will be filtered again based on the filtering method set on the |
133 | second \l LayerFilter declared. This is then repeated until all \l |
134 | LayerFilter nodes of the branch have been consumed. |
135 | */ |
136 | |
137 | /*! |
138 | \qmlproperty list<Layer> Qt3D.Render::LayerFilter::layers |
139 | Holds a list of layers specifying the layers to select for drawing. |
140 | \readonly |
141 | */ |
142 | |
143 | /*! |
144 | \qmlproperty enumeration Qt3DRender::LayerFilter::filterMode |
145 | |
146 | Holds the filter mode specifying the entities to select for drawing. |
147 | |
148 | The default value is \c {LayerFilter.AcceptMatchingLayers}. |
149 | |
150 | \value LayerFilter.AcceptAnyMatchingLayers |
151 | Accept entities that reference one or more \l Layer objects added to this |
152 | LayerFilter. This is the default |
153 | |
154 | \value LayerFilter.AcceptAllMatchingLayers |
155 | Accept entities that reference all the \l Layer objects added to this |
156 | LayerFilter |
157 | |
158 | \value LayerFilter.DiscardAnyMatchingLayers |
159 | Discard entities that reference one or more \l Layer objects added to this |
160 | LayerFilter |
161 | |
162 | \value LayerFilter.DiscardAllMatchingLayers |
163 | Discard entities that reference all \l Layer objects added to this |
164 | LayerFilter |
165 | */ |
166 | |
167 | /*! |
168 | The constructor creates an instance with the specified \a parent. |
169 | */ |
170 | QLayerFilter::QLayerFilter(QNode *parent) |
171 | : QFrameGraphNode(*new QLayerFilterPrivate, parent) |
172 | { |
173 | } |
174 | |
175 | /*! \internal */ |
176 | QLayerFilter::QLayerFilter(QLayerFilterPrivate &dd, QNode *parent) |
177 | : QFrameGraphNode(dd, parent) |
178 | { |
179 | } |
180 | |
181 | /*! \internal */ |
182 | QLayerFilter::~QLayerFilter() |
183 | { |
184 | } |
185 | |
186 | /*! |
187 | Add \a layer to the current list of layers |
188 | */ |
189 | void QLayerFilter::addLayer(QLayer *layer) |
190 | { |
191 | Q_ASSERT(layer); |
192 | Q_D(QLayerFilter); |
193 | if (!d->m_layers.contains(t: layer)) { |
194 | d->m_layers.append(t: layer); |
195 | |
196 | // Ensures proper bookkeeping |
197 | d->registerDestructionHelper(node: layer, func: &QLayerFilter::removeLayer, d->m_layers); |
198 | |
199 | // We need to add it as a child of the current node if it has been declared inline |
200 | // Or not previously added as a child of the current node so that |
201 | // 1) The backend gets notified about it's creation |
202 | // 2) When the current node is destroyed, it gets destroyed as well |
203 | if (!layer->parent()) |
204 | layer->setParent(this); |
205 | |
206 | d->updateNode(node: layer, property: "layer" , change: Qt3DCore::PropertyValueAdded); |
207 | } |
208 | } |
209 | |
210 | /*! |
211 | Remove \a layer from the current list of layers |
212 | */ |
213 | void QLayerFilter::removeLayer(QLayer *layer) |
214 | { |
215 | Q_ASSERT(layer); |
216 | Q_D(QLayerFilter); |
217 | if (!d->m_layers.removeOne(t: layer)) |
218 | return; |
219 | d->updateNode(node: layer, property: "layer" , change: Qt3DCore::PropertyValueRemoved); |
220 | // Remove bookkeeping connection |
221 | d->unregisterDestructionHelper(node: layer); |
222 | } |
223 | |
224 | /*! |
225 | \return the current list of layers |
226 | */ |
227 | QVector<QLayer *> QLayerFilter::layers() const |
228 | { |
229 | Q_D(const QLayerFilter); |
230 | return d->m_layers; |
231 | } |
232 | |
233 | QLayerFilter::FilterMode QLayerFilter::filterMode() const |
234 | { |
235 | Q_D(const QLayerFilter); |
236 | return d->m_filterMode; |
237 | } |
238 | |
239 | void QLayerFilter::setFilterMode(QLayerFilter::FilterMode filterMode) |
240 | { |
241 | Q_D(QLayerFilter); |
242 | if (d->m_filterMode != filterMode) { |
243 | d->m_filterMode = filterMode; |
244 | emit filterModeChanged(filterMode); |
245 | } |
246 | } |
247 | |
248 | Qt3DCore::QNodeCreatedChangeBasePtr QLayerFilter::createNodeCreationChange() const |
249 | { |
250 | auto creationChange = QFrameGraphNodeCreatedChangePtr<QLayerFilterData>::create(arguments: this); |
251 | auto &data = creationChange->data; |
252 | Q_D(const QLayerFilter); |
253 | data.layerIds = qIdsForNodes(nodes: d->m_layers); |
254 | data.filterMode = d->m_filterMode; |
255 | return creationChange; |
256 | } |
257 | |
258 | } // namespace Qt3DRender |
259 | |
260 | QT_END_NAMESPACE |
261 | |