Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquick3drenderoutputprovider.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
7
8#include "private/qquick3dobject_p.h"
9
10#include <QtQuick3DRuntimeRender/private/qssglayerrenderdata_p.h>
11
12#include <ssg/qssgrenderextensions.h>
13#include <ssg/qssgrenderhelpers.h>
14#include <ssg/qssgrendercontextcore.h>
15#include <ssg/qssgrhicontext.h>
16#include <ssg/qquick3dextensionhelpers.h>
17
19
45
47 : m_ext(ext)
48{
49
50}
51
56
58{
59 // Update the extension ID.
60 // NOTE: This needs to be done on each call, the extension object may have changed.
61 // If the extension is destroyed (m_ext == nullptr), we cannot proceed and should return false!
62 m_extensionId = m_ext ? QQuick3DExtensionHelpers::getExtensionId(*m_ext) : QSSGExtensionId::Invalid;
63 if (QQuick3DExtensionHelpers::isNull(m_extensionId))
64 return false;
65
66 const bool wasDirty = m_isDirty;
67
68 switch (m_sourceType) {
70 // Nothing to do
71 m_isDirty = false;
72 break;
74 {
75 // Make sure we schedule the pass to run this frame
76 data.scheduleRenderResults(QSSGFrameData::RenderResults(m_builtInPass));
77
78 // Check if a texture exists for the result already
79 QSSGFrameData::Result extResult = data.getRenderResult(m_builtInPass);
80 if (extResult.texture) {
81 QSSGRenderExtensionHelpers::registerRenderResult(data, m_extensionId, extResult.texture);
82 m_isDirty = false;
83
84 }
85 // No "else" in this case since its likely the texture for the pass doesn't exist yet, try again in prepareRender.
86 }
87 break;
89 {
90 if (userPassId != QSSGResourceId::Invalid) {
91 // Make sure we schedule the pass to run this frame
92 data.scheduleRenderResults(userPassId);
93
94 // Check if a texture exists for the result already
95 QSSGFrameData::Result extResult = data.getRenderResult(userPassId, attachmentSelector);
96 if (extResult.texture) {
97 // Associate the texture with this extension and expose it so it can be used.
98 QSSGRenderExtensionHelpers::registerRenderResult(data, m_extensionId, extResult.texture);
99 m_isDirty = false;
100
101 }
102 }
103 // No "else" in this case since its likely the texture for the pass doesn't exist yet, try again in prepareRender.
104 }
105 break;
106 }
107
108 return wasDirty;
109}
110
112{
113 // If no id is set prepareData() should return false and this should not be called!
114 Q_ASSERT(!QQuick3DExtensionHelpers::isNull(m_extensionId));
115
116 QSSGFrameData::Result extResult;
118 extResult = data.getRenderResult(m_builtInPass);
119 else if (m_sourceType == SourceType::UserPass && userPassId != QSSGResourceId::Invalid)
120 extResult = data.getRenderResult(userPassId, attachmentSelector);
121
122 if (userPassId != QSSGResourceId::Invalid) {
123 if (extResult.texture) {
124 QSSGRenderExtensionHelpers::registerRenderResult(data, m_extensionId, extResult.texture);
125 m_isDirty = false;
126 }
127 }
128}
129
131{
132 // Nothing to render
133}
134
136{
137 // Nothing to reset
138}
139
140
141/*!
142 \qmltype RenderOutputProvider
143 \nativetype QQuick3DRenderOutputProvider
144 \inqmlmodule QtQuick3D.Helpers
145 \inherits TextureProviderExtension
146 \since 6.11
147 \brief Used as a bridge to access textures provided in passes.
148
149 This type is used to provide textures that are generated by passes in the rendering pipeline.
150
151 Some example of when this is useful is when you want to access the depth texture generated by the ZPrePass,
152 or the ambient occlusion texture generated by the SSAO pass. This type can be used to access these generated
153 textures and use them in materials or effects.
154
155 \qml
156 Texture {
157 textureProvider: RenderOutputProvider {
158 // Specify the pass buffer texture you want to access
159 textureSource: RenderOutputProvider.DepthTexture
160 }
161 }
162 \endqml
163
164 \sa QQuick3DTextureProviderExtension, QSSGRenderExtension
165*/
166
167QQuick3DRenderOutputProvider::QQuick3DRenderOutputProvider(QQuick3DObject *parent)
168 : QQuick3DTextureProviderExtension(parent)
169{
170 update();
171}
172
173QSSGRenderGraphObject *QQuick3DRenderOutputProvider::updateSpatialNode(QSSGRenderGraphObject *node)
174{
175 // Create new node if needed
176 if (!node)
177 node = new QSSGRenderOutputProviderExtension(this);
178
179 QQuick3DTextureProviderExtension::updateSpatialNode(node);
180
181 QSSGRenderOutputProviderExtension *providerNode = static_cast<QSSGRenderOutputProviderExtension *>(node);
182
183 providerNode->m_isDirty = (m_dirtyAttributes != 0);
184
185 if (m_dirtyAttributes & TextureSourceDirty) {
186 switch (m_textureSource) {
187 case QQuick3DRenderOutputProvider::TextureSource::None:
188 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::None;
189 // m_builtInPass is not used in this case
190 break;
191 case QQuick3DRenderOutputProvider::TextureSource::UserPassTexture:
192 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::UserPass;
193 break;
194 case QQuick3DRenderOutputProvider::TextureSource::AoTexture:
195 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::BuiltInPass;
196 providerNode->m_builtInPass = QSSGFrameData::RenderResult::AoTexture;
197 break;
198 case QQuick3DRenderOutputProvider::TextureSource::DepthTexture:
199 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::BuiltInPass;
200 providerNode->m_builtInPass = QSSGFrameData::RenderResult::DepthTexture;
201 break;
202 case QQuick3DRenderOutputProvider::TextureSource::ScreenTexture:
203 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::BuiltInPass;
204 providerNode->m_builtInPass = QSSGFrameData::RenderResult::ScreenTexture;
205 break;
206 case QQuick3DRenderOutputProvider::TextureSource::NormalTexture:
207 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::BuiltInPass;
208 providerNode->m_builtInPass = QSSGFrameData::RenderResult::NormalTexture;
209 break;
210 case QQuick3DRenderOutputProvider::TextureSource::MotionVectorTexture:
211 providerNode->m_sourceType = QSSGRenderOutputProviderExtension::SourceType::BuiltInPass;
212 providerNode->m_builtInPass = QSSGFrameData::RenderResult::MotionVectorTexture;
213 break;
214 }
215 }
216
217 if (m_dirtyAttributes & UserPassTextureDirty) {
218 // m_builtInPass is not used in this case
219 QSSGResourceId userPassId = m_renderPass ? QQuick3DExtensionHelpers::getResourceId(*m_renderPass) : QSSGResourceId::Invalid;
220 providerNode->userPassId = userPassId;
221 providerNode->attachmentSelector = QSSGFrameData::AttachmentSelector(m_attachmentSelector);
222 }
223
224 m_dirtyAttributes = 0;
225
226 return node;
227}
228
229void QQuick3DRenderOutputProvider::markAllDirty()
230{
231 m_dirtyAttributes = AllDirty;
232 QQuick3DTextureProviderExtension::markAllDirty();
233}
234
235void QQuick3DRenderOutputProvider::markDirty(QQuick3DRenderOutputProvider::DirtyType type)
236{
237 if (!(m_dirtyAttributes & quint32(type))) {
238 m_dirtyAttributes |= quint32(type);
239 update();
240 }
241}
242
243/*!
244 \qmlproperty RenderOutputProvider::TextureSource textureSource
245 This property holds which pass buffer texture to use.
246
247 \value RenderOutputProvider.None No texture source is selected.
248 \value RenderOutputProvider.UserPassTexture A user defined pass. If this is used to access a user defined pass.
249 \value RenderOutputProvider.AoTexture The ambient occlusion texture created by QtQuick3D's AO pass.
250 \value RenderOutputProvider.DepthTexture The depth texture created by QtQuick3D's Depth map pass.
251 \value RenderOutputProvider.ScreenTexture The texture containing the rendered scene.
252 \value RenderOutputProvider.NormalTexture The normal texture created by QtQuick3D's Normal map pass.
253 \value RenderOutputProvider.MotionVectorTexture The motion vector texture created by QtQuick3D's Motion Vector pass.
254 */
255
256QQuick3DRenderOutputProvider::TextureSource QQuick3DRenderOutputProvider::textureSource() const
257{
258 return m_textureSource;
259}
260
261void QQuick3DRenderOutputProvider::setTextureSource(TextureSource newTextureSource)
262{
263 if (m_textureSource == newTextureSource)
264 return;
265 m_textureSource = newTextureSource;
266 emit textureSourceChanged();
267 markDirty(TextureSourceDirty);
268}
269
270/*!
271 \qmlproperty RenderPass renderPass
272 This property holds the user defined render pass to use when accessing a user defined pass texture.
273
274 When this property is set, the \l textureSource property is automatically set to \value RenderOutputProvider.UserPassTexture.
275
276 \sa textureSource, RenderPass
277*/
278
279QQuick3DRenderPass *QQuick3DRenderOutputProvider::renderPass() const
280{
281 return m_renderPass;
282}
283
284void QQuick3DRenderOutputProvider::setRenderPass(QQuick3DRenderPass *newRenderPass)
285{
286 if (m_renderPass == newRenderPass)
287 return;
288
289 QQuick3DObjectPrivate::attachWatcher(this, &QQuick3DRenderOutputProvider::setRenderPass, newRenderPass, m_renderPass);
290
291 m_renderPass = newRenderPass;
292
293 setTextureSource(m_renderPass ? TextureSource::UserPassTexture : TextureSource::None);
294
295 markDirty(UserPassTextureDirty);
296
297 emit renderPassChanged();
298}
299
300/*!
301 \qmlproperty RenderOutputProvider::AttachmentSelector attachmentSelector
302 This property holds which attachment to use when accessing a user defined pass texture.
303
304 There are multiple attachments possible when using a user defined render pass,
305 starting from \value RenderOutputProvider.Attachment0 up to \value RenderOutputProvider.Attachment3.
306*/
307
308QQuick3DRenderOutputProvider::AttachmentSelector QQuick3DRenderOutputProvider::attachmentSelector() const
309{
310 return m_attachmentSelector;
311}
312
313void QQuick3DRenderOutputProvider::setAttachmentSelector(AttachmentSelector newAttachmentSelector)
314{
315 if (m_attachmentSelector == newAttachmentSelector)
316 return;
317 m_attachmentSelector = newAttachmentSelector;
318 emit attachmentSelectorChanged();
319}
320
321QT_END_NAMESPACE
QSSGFrameData::AttachmentSelector attachmentSelector
QSSGRenderOutputProviderExtension(QQuick3DRenderOutputProvider *ext)
void prepareRender(QSSGFrameData &data) override
Prepare data for rendering.
bool prepareData(QSSGFrameData &data) override
Called after scene data is collected, but before any render data or rendering in the current frame ha...
QPointer< QQuick3DRenderOutputProvider > m_ext
void render(QSSGFrameData &data) override
Record the render pass.
void resetForFrame() override
Called each time a new frame starts.
Combined button and popup list for selecting options.