1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qtquick3dxrglobal_p.h"
5#include "qquick3dxritem_p.h"
6#include "qquick3dxrview_p.h"
7#include <QQuickWindow>
8#include <QQuickItem>
9#include <QLoggingCategory>
10
11#include "qquick3dxrinputmanager_p.h"
12
13QT_BEGIN_NAMESPACE
14
15Q_DECLARE_LOGGING_CATEGORY(lcQuick3DXr);
16
17/*!
18 \qmltype XrView
19 \inherits Node
20 \inqmlmodule QtQuick3D.Xr
21 \brief Sets up the view for an Xr application.
22
23 An XrView sets up the view for an XR application.
24 The following snippet is from the \l{\qxr Simple Example} and shows
25 how to use the type.
26
27 \quotefromfile xr_simple/main.qml
28 \printto XrOrigin
29
30 \section1 Platform notes
31
32 \section2 Meta Quest Devices
33
34 To \l{XrView::passthroughEnabled}{enable passthrough} you need to add the
35 following permisson your app's \c AndroidManifest.xml file:
36
37 \badcode
38 <uses-feature android:name="com.oculus.feature.PASSTHROUGH" android:required="false"/>
39 \endcode
40
41*/
42
43QQuick3DXrView::QQuick3DXrView()
44 : m_xrRuntimeInfo(&m_xrManager)
45{
46 init();
47}
48
49QQuick3DXrView::~QQuick3DXrView()
50{
51 m_inDestructor = true;
52}
53
54/*!
55 \qmlproperty XrOrigin QtQuick3D.Xr::XrView::xrOrigin
56 \brief Holds the active XR origin.
57
58 The XR origin is the point in the scene that is considered the origin of the
59 XR coordinate system. The XR origin is used to position tracked objects like
60 the camera and controllers in the scene. An application can have multiple XrOrigins
61 but only one can be active at a time.
62
63 \note This property must be set for the scene to be rendered in XR.
64
65 \sa XrOrigin
66*/
67
68QQuick3DXrOrigin *QQuick3DXrView::xrOrigin() const
69{
70 return m_xrOrigin;
71}
72
73/*!
74 \qmlproperty SceneEnvironment QtQuick3D.Xr::XrView::environment
75 \summary Holds the SceneEnvironment for the XR view.
76*/
77
78QQuick3DSceneEnvironment *QQuick3DXrView::environment() const
79{
80 return m_xrManager.m_vrViewport ? m_xrManager.m_vrViewport->environment() : nullptr;
81}
82
83QQuick3DViewport *QQuick3DXrView::view3d() const
84{
85 return m_xrManager.m_vrViewport;
86}
87
88/*!
89 \qmlproperty bool QtQuick3D.Xr::XrView::passthroughEnabled
90 \summary Holds whether passthrough is enabled for the XR view.
91*/
92bool QQuick3DXrView::passthroughEnabled() const
93{
94 return m_xrManager.isPassthroughEnabled();
95}
96
97/*!
98 \qmlproperty QQuick3DXrRuntimeInfo QtQuick3D.Xr::XrView::runtimeInfo
99 \summary Provides information about the XR runtime for the XR view.
100*/
101
102QQuick3DXrRuntimeInfo *QQuick3DXrView::runtimeInfo() const
103{
104 return &m_xrRuntimeInfo;
105}
106
107void QQuick3DXrView::setEnvironment(QQuick3DSceneEnvironment *environment)
108{
109 QQuick3DViewport *view = m_xrManager.m_vrViewport;
110
111 // If the view is not created yet, we can't set the environment which means we need to
112 // set it again once the view is created...
113 if (!view) {
114 m_pendingSceneEnvironment = environment;
115 return;
116 }
117
118 auto oldEnvironment = view->environment();
119 if (oldEnvironment == environment)
120 return;
121
122 if (oldEnvironment)
123 disconnect(receiver: oldEnvironment);
124
125 view->setEnvironment(environment);
126
127 // The view will always have an environment, setting the environment to null will just mean the default environment
128 // is used. So querying the environment from the view is always valid (and we should do it here to make sure we're
129 // in sync with the view).
130 environment = view->environment();
131
132 handleClearColorChanged();
133 handleAAChanged();
134
135 connect(sender: environment, signal: &QQuick3DSceneEnvironment::backgroundModeChanged, context: this, slot: &QQuick3DXrView::handleClearColorChanged);
136 connect(sender: environment, signal: &QQuick3DSceneEnvironment::clearColorChanged, context: this, slot: &QQuick3DXrView::handleClearColorChanged);
137 connect(sender: environment, signal: &QQuick3DSceneEnvironment::antialiasingModeChanged, context: this, slot: &QQuick3DXrView::handleAAChanged);
138 connect(sender: environment, signal: &QQuick3DSceneEnvironment::antialiasingQualityChanged, context: this, slot: &QQuick3DXrView::handleAAChanged);
139
140 emit environmentChanged(environment);
141}
142
143/*!
144 \qmlproperty bool QtQuick3D.Xr::XrView::passthroughSupported
145 \summary Indicates whether passthrough is supported for the XR view.
146*/
147
148bool QQuick3DXrView::passthroughSupported() const
149{
150 if (!m_xrManager.isValid())
151 return false;
152
153 return m_xrManager.supportsPassthrough();
154}
155
156void QQuick3DXrView::setPassthroughEnabled(bool enable)
157{
158 if (!m_xrManager.isValid()) {
159 qWarning(msg: "Attempted to set passthrough mode without a valid XR manager");
160 return;
161 }
162
163 // bail if passthrough is not supported
164 if (enable && !m_xrManager.supportsPassthrough()) {
165 qWarning(msg: "Enabling Passthrough is not supported.");
166 return;
167 }
168
169 const bool orgPassthroughEnabled = m_xrManager.isPassthroughEnabled();
170 m_xrManager.setPassthroughEnabled(enable);
171
172 if (orgPassthroughEnabled != m_xrManager.isPassthroughEnabled())
173 emit passthroughEnabledChanged();
174}
175
176/*!
177 \qmlproperty enumeration QtQuick3D.Xr::XrView::fixedFoveation
178 \brief Controls the level of fixed foveated rendering for the XrView.
179 \default XrView.HighFoveation
180
181 Foveated rendering reduces GPU load by reducing image quality (resolution)
182 in areas where the difference is less perceptible to the eye. With fixed
183 foveated rendering, the areas with reduced visual fidelity are fixed and do
184 not change. On some platforms, there is no concept of fixed foveated
185 rendering or control over it. For example, VisionOS-based devices perform
186 dynamic, eye-tracked foveation; thus, the value of this property is
187 ignored in practice. Other devices, such as the Meta Quest 3, only
188 support fixed foveation, which makes this property relevant.
189
190 The value can be one of:
191 \value XrView.NoFoveation 0, no foveation.
192 \value XrView.LowFoveation 1, low foveation.
193 \value XrView.MediumFoveation 2, medium foveation.
194 \value XrView.HighFoveation 3, high foveation.
195
196 Where supported, the default is \c HighFoveation. Therefore, changing this
197 value in applications should be rarely needed in practice.
198*/
199
200QQuick3DXrView::FoveationLevel QQuick3DXrView::fixedFoveation() const
201{
202 return FoveationLevel(m_xrManager.getFixedFoveationLevel());
203}
204
205void QQuick3DXrView::setFixedFoveation(FoveationLevel level)
206{
207 const auto orgFoviationLevel = m_xrManager.getFixedFoveationLevel();
208 m_xrManager.setFixedFoveationLevel(QtQuick3DXr::FoveationLevel(level));
209 if (orgFoviationLevel != m_xrManager.getFixedFoveationLevel())
210 emit fixedFoveationChanged();
211}
212
213/*!
214 \qmlproperty bool QtQuick3D.Xr::XrView::isQuitOnSessionEndEnabled
215 \brief Holds whether the application should quit when the XR session ends.
216*/
217
218bool QQuick3DXrView::isQuitOnSessionEndEnabled() const
219{
220 return m_quitOnSessionEnd;
221}
222
223void QQuick3DXrView::setQuitOnSessionEnd(bool enable)
224{
225 if (m_quitOnSessionEnd == enable)
226 return;
227
228 m_quitOnSessionEnd = enable;
229 emit quitOnSessionEndChanged();
230}
231/*!
232 \qmlproperty RenderStats QtQuick3D.Xr::XrView::renderStats
233 \summary Holds rendering statistics for the XR view.
234*/
235
236QQuick3DRenderStats *QQuick3DXrView::renderStats() const
237{
238 return m_xrManager.m_vrViewport ? m_xrManager.m_vrViewport->renderStats() : nullptr;
239}
240
241void QQuick3DXrView::updateViewportGeometry()
242{
243 auto contentItem = m_xrManager.m_quickWindow->contentItem();
244 auto viewport = m_xrManager.m_vrViewport;
245 if (viewport->height() != contentItem->height())
246 viewport->setHeight(contentItem->height());
247 if (viewport->width() != contentItem->width())
248 viewport->setWidth(contentItem->width());
249 if (viewport->x() != contentItem->x())
250 viewport->setX(contentItem->x());
251 if (viewport->y() != contentItem->y())
252 viewport->setY(contentItem->y());
253}
254
255void QQuick3DXrView::handleSessionEnded()
256{
257 emit sessionEnded();
258 if (m_quitOnSessionEnd)
259 QCoreApplication::quit();
260}
261
262void QQuick3DXrView::handleClearColorChanged()
263{
264 auto env = environment();
265
266 if (env) {
267 if (env->backgroundMode() == QQuick3DSceneEnvironment::Color)
268 m_xrManager.m_quickWindow->setColor(env->clearColor());
269 else if (env->backgroundMode() == QQuick3DSceneEnvironment::Transparent)
270 m_xrManager.m_quickWindow->setColor(Qt::transparent);
271 }
272}
273
274void QQuick3DXrView::handleAAChanged()
275{
276 auto env = environment();
277 int samples = 1;
278 if (env && env->antialiasingMode() == QQuick3DSceneEnvironment::MSAA) {
279 switch (env->antialiasingQuality()) {
280 case QQuick3DSceneEnvironment::Medium:
281 samples = 2;
282 break;
283 case QQuick3DSceneEnvironment::High:
284 samples = 4;
285 break;
286 case QQuick3DSceneEnvironment::VeryHigh:
287 samples = 8;
288 break;
289 }
290 }
291 m_xrManager.setSamples(samples);
292}
293
294bool QQuick3DXrView::init()
295{
296 if (m_isInitialized) {
297 qWarning(msg: "Already initialized!");
298 return false;
299 }
300
301 connect(sender: &m_xrManager, signal: &QQuick3DXrManager::sessionEnded, context: this, slot: &QQuick3DXrView::handleSessionEnded);
302 connect(sender: &m_xrManager, signal: &QQuick3DXrManager::frameReady, context: this, slot: &QQuick3DXrView::frameReady);
303 connect(sender: &m_xrManager, signal: &QQuick3DXrManager::referenceSpaceChanged, context: this, slot: &QQuick3DXrView::referenceSpaceChanged);
304 connect(sender: &m_xrManager, signal: &QQuick3DXrManager::multiViewRenderingEnabledChanged, context: this, slot: &QQuick3DXrView::multiViewRenderingEnabledChanged);
305 connect(sender: &m_xrManager, signal: &QQuick3DXrManager::initialized, context: this, slot: &QQuick3DXrView::init, type: Qt::UniqueConnection);
306
307 if (!m_xrManager.isReady() && !m_xrManager.initialize()) {
308 qCDebug(lcQuick3DXr, "Waiting for XR platform to be initialized");
309
310 return false;
311 }
312
313 if (!m_xrManager.initialize()) {
314 QString errorString = m_xrManager.errorString();
315 if (errorString.isEmpty())
316 errorString = tr(s: "Failed to initialize XR platform");
317 qWarning(msg: "\n%s\n", qPrintable(errorString));
318 QMetaObject::invokeMethod(obj: this, member: "initializeFailed", c: Qt::QueuedConnection, arguments&: errorString);
319 return false;
320 }
321
322 // Create View3D
323 QSSG_CHECK_X(m_xrManager.m_vrViewport == nullptr, "View3D already created!");
324 auto viewport = new QQuick3DViewport(QQuick3DViewport::PrivateInstanceType::XrViewInstance);
325 viewport->setRenderMode(QQuick3DViewport::Underlay);
326 auto contentItem = m_xrManager.m_quickWindow->contentItem();
327 viewport->setParentItem(contentItem);
328 m_xrManager.m_vrViewport = viewport;
329 viewport->setImportScene(this);
330
331 contentItem->forceActiveFocus(reason: Qt::MouseFocusReason);
332
333 connect(sender: contentItem, signal: &QQuickItem::heightChanged, context: this, slot: &QQuick3DXrView::updateViewportGeometry);
334 connect(sender: contentItem, signal: &QQuickItem::widthChanged, context: this, slot: &QQuick3DXrView::updateViewportGeometry);
335 connect(sender: contentItem, signal: &QQuickItem::xChanged, context: this, slot: &QQuick3DXrView::updateViewportGeometry);
336 connect(sender: contentItem, signal: &QQuickItem::yChanged, context: this, slot: &QQuick3DXrView::updateViewportGeometry);
337
338 QQuick3DSceneEnvironment *env = environment();
339 if (env) {
340 connect(sender: env, signal: &QQuick3DSceneEnvironment::backgroundModeChanged, context: this, slot: &QQuick3DXrView::handleClearColorChanged);
341 connect(sender: env, signal: &QQuick3DSceneEnvironment::clearColorChanged, context: this, slot: &QQuick3DXrView::handleClearColorChanged);
342 connect(sender: env, signal: &QQuick3DSceneEnvironment::antialiasingModeChanged, context: this, slot: &QQuick3DXrView::handleAAChanged);
343 connect(sender: env, signal: &QQuick3DSceneEnvironment::antialiasingQualityChanged, context: this, slot: &QQuick3DXrView::handleAAChanged);
344 }
345
346 // NOTE: If we've called async, we need to make sure the environment, etc. is set again
347 setEnvironment(m_pendingSceneEnvironment);
348 m_pendingSceneEnvironment = nullptr;
349
350 m_xrManager.update();
351
352 m_isInitialized = true;
353
354 return m_isInitialized;
355}
356
357/*!
358 \qmlmethod pickResult XrView::rayPick(vector3d origin, vector3d direction)
359
360 This method will \e shoot a ray into the scene starting at \a origin and in
361 \a direction and return information about the nearest intersection with an
362 object in the scene.
363
364 For example, pass the position and forward vector of
365 any object in a scene to see what object is in front of an item. This
366 makes it possible to do picking from any point in the scene.
367 */
368QQuick3DPickResult QQuick3DXrView::rayPick(const QVector3D &origin, const QVector3D &direction) const
369{
370 return m_xrManager.m_vrViewport->rayPick(origin, direction);
371}
372
373/*!
374 \qmlmethod List<pickResult> XrView::rayPickAll(vector3d origin, vector3d direction)
375
376 This method will \e shoot a ray into the scene starting at \a origin and in
377 \a direction and return a list of information about the nearest intersections with
378 objects in the scene.
379 The list is presorted by distance from the origin along the direction
380 vector with the nearest intersections appearing first and the furthest
381 appearing last.
382
383 This can, for instance, be called with the position and forward vector of
384 any object in a scene to see what objects are in front of an item. This
385 makes it possible to do picking from any point in the scene.
386 */
387QList<QQuick3DPickResult> QQuick3DXrView::rayPickAll(const QVector3D &origin, const QVector3D &direction) const
388{
389 return m_xrManager.m_vrViewport->rayPickAll(origin, direction);
390}
391
392/*!
393 \qmlmethod XrView::setTouchpoint(Item target, point position, int pointId, bool pressed)
394
395 Sends a synthetic touch event to \a target, moving the touch point with ID \a pointId to \a position,
396 with \a pressed determining if the point is pressed.
397 Also sends the appropriate touch release event if \a pointId was previously active on a different
398 item.
399*/
400
401void QQuick3DXrView::setTouchpoint(QQuickItem *target, const QPointF &position, int pointId, bool pressed)
402{
403 view3d()->setTouchpoint(target, position, pointId, active: pressed);
404}
405
406// TODO: Maybe do a proper QQuick3DXrViewPrivate instead
407struct QQuick3DXrView::XrTouchState
408{
409 QHash<int, QQuick3DXrItem::TouchState> points;
410};
411
412/*!
413 \qmlmethod vector3d XrView::processTouch(vector3d position, int pointId)
414
415 This method will search for an XrItem near \a position and send a virtual
416 touch event with touch point ID \a pointId if \a position maps to a point
417 on the surface.
418
419 The return value is the offset between \a position and the touched point on
420 the surface. This can be used to prevent a hand model from passing through
421 an XrItem.
422
423 \sa XrHandModel
424
425*/
426
427QVector3D QQuick3DXrView::processTouch(const QVector3D &pos, int pointId)
428{
429 QVector3D offset;
430 if (m_xrItems.isEmpty())
431 return offset;
432
433 if (!m_touchState)
434 m_touchState = new XrTouchState;
435 QQuick3DXrItem::TouchState &state = m_touchState->points[pointId];
436 state.pointId = pointId; // in case it's a new point that was default-constructed
437
438 auto *prevTarget = state.target;
439 bool grabbed = false;
440 if (prevTarget) {
441 grabbed = prevTarget->handleVirtualTouch(view: this, pos, touchState: &state, offset: &offset);
442 }
443 for (auto *item : std::as_const(t&: m_xrItems)) {
444 if (grabbed)
445 break;
446 if (item != prevTarget)
447 grabbed = item->handleVirtualTouch(view: this, pos, touchState: &state, offset: &offset);
448 }
449
450 return offset;
451}
452
453/*!
454 \qmlmethod object XrView::touchpointState(int pointId)
455
456 This method returns the state of the touch point with ID \a pointId.
457 The state is represented by a map from property names to values:
458
459 \table
460 \header
461 \li Key
462 \li Type
463 \li Description
464 \row
465 \li \c grabbed
466 \li \c bool
467 \li Is the point grabbed by an item? If \c false, all other values are \c undefined.
468 \row
469 \li \c target
470 \li XrItem
471 \li The item that is grabbing the touch point.
472 \row
473 \li \c pressed
474 \li \c bool
475 \li Is the touch point pressed?
476 \row
477 \li \c cursorPos
478 \li \c point
479 \li The 2D position of the touch point within \c target
480 \row
481 \li \c touchDistance
482 \li \c real
483 \li The distance from the plane to the touch point. It will be \c 0 if \c pressed is \c true.
484 \endtable
485
486 */
487
488#define Q_TOUCHPOINT_STATE(prop) { QStringLiteral(#prop), QVariant::fromValue(it->prop) }
489QVariantMap QQuick3DXrView::touchpointState(int pointId) const
490{
491 auto constexpr end = QHash<int, QQuick3DXrItem::TouchState>::const_iterator();
492 auto it = m_touchState ? m_touchState->points.constFind(key: pointId) : end;
493
494 if (it == end)
495 return { { QStringLiteral("grabbed"), QVariant::fromValue(value: false) } };
496
497 return { Q_TOUCHPOINT_STATE(target),
498 Q_TOUCHPOINT_STATE(grabbed),
499 Q_TOUCHPOINT_STATE(pressed),
500 Q_TOUCHPOINT_STATE(cursorPos),
501 Q_TOUCHPOINT_STATE(touchDistance) };
502}
503#undef Q_TOUCHPOINT_STATE
504
505/*!
506 \qmlproperty enumeration QtQuick3D.Xr::XrView::referenceSpace
507 \brief Gets or sets the reference space for the XR view.
508
509 It can be one of:
510 \value XrView.ReferenceSpaceUnknown
511 \value XrView.ReferenceSpaceLocal
512 \value XrView.ReferenceSpaceStage
513 \value XrView.ReferenceSpaceLocalFloor
514*/
515
516QQuick3DXrView::ReferenceSpace QQuick3DXrView::referenceSpace() const
517{
518 return ReferenceSpace(m_xrManager.getReferenceSpace());
519}
520
521void QQuick3DXrView::setReferenceSpace(ReferenceSpace newReferenceSpace)
522{
523 m_xrManager.setReferenceSpace(QtQuick3DXr::ReferenceSpace(newReferenceSpace));
524}
525
526bool QQuick3DXrView::depthSubmissionEnabled() const
527{
528 if (!m_xrManager.isValid()) {
529 qWarning(msg: "Attempted to check depth submission mode without a valid XR manager");
530 return false;
531 }
532
533 return m_xrManager.isDepthSubmissionEnabled();
534}
535
536/*!
537 \qmlproperty bool QtQuick3D.Xr::XrView::multiViewRenderingSupported
538
539 \brief This read-only property reports the availability of \l{Multiview Rendering}.
540
541 \sa multiViewRenderingEnabled
542 */
543bool QQuick3DXrView::isMultiViewRenderingSupported() const
544{
545 if (!m_xrManager.isValid())
546 return false;
547
548 return m_xrManager.isMultiViewRenderingSupported();
549}
550
551/*!
552 \qmlproperty bool QtQuick3D.Xr::XrView::multiViewRenderingEnabled
553
554 \brief This is a read-only property that reports if \l{Multiview Rendering} is enabled for the XR view.
555
556 \default true
557
558 This property tells you if multiview rendering is actually in use at run time.
559 When not supported, the value will flip back to \c false.
560
561 Enabling multiview rendering is recommended. It can improve performance and reduce
562 CPU and GPU power usage. It defaults to disabled to ensure maximum
563 compatibility. Developers are encouraged to verify that their application
564 renders as expected with multiViewRenderingEnabled set to \c true and then
565 leave it set afterward.
566
567 \note Certain Qt Quick and Quick 3D features that involve shader code that is
568 provided by the application may need this code to be modified to be multiview
569 compatible. Examples of these are custom 2D and 3D materials and
570 postprocessing effects. The \l {Multiview Rendering} documentation provides
571 more information on this and how to disable multiview rendering.
572
573 \sa multiViewRenderingSupported {Multiview Rendering}
574*/
575bool QQuick3DXrView::multiViewRenderingEnabled() const
576{
577 if (!m_xrManager.isValid())
578 return false;
579
580 return m_xrManager.isMultiViewRenderingEnabled();
581}
582
583void QQuick3DXrView::registerXrItem(QQuick3DXrItem *newXrItem)
584{
585 m_xrItems.append(t: newXrItem);
586}
587
588void QQuick3DXrView::unregisterXrItem(QQuick3DXrItem *xrItem)
589{
590 m_xrItems.removeAll(t: xrItem);
591}
592
593/*!
594 \qmlproperty bool QtQuick3D.Xr::XrView::depthSubmissionEnabled
595 \brief Controls whether submitting the depth buffer to the XR compositor
596 is enabled.
597 \default false
598
599 By default, the depth buffer used by the 3D scene in the XrView is not exposed
600 to the XR compositor. However, in some platforms, depth submission is implicit
601 and cannot be disabled or controlled by the application. An example of this is
602 VisionOS. Changing this property has no effect on those platforms. Elsewhere,
603 with OpenXR in particular, support depends on the OpenXR implementation used
604 at run time.
605
606 It is always safe to set depthSubmissionEnabled to \c true. It will just have
607 no effect when not supported by the underlying stack. To be sure, you can
608 inspect the debug output to see if depth submission is in use.
609 Submitting the depth buffer may improve reprojections that the XR compositor
610 may perform. Reprojection could happen, for example, when the system cannot
611 maintain the target frame rate and thus has to resort to predicting frame
612 contents to improve and stabilize the user's perception of the
613 scene and reduce possible motion sickness. However, the application and
614 Qt have no control over data usage. It could also happen that
615 submitting depth data has no practical effects and is ignored by the
616 underlying XR runtime and compositor.
617
618 In practice, submitting the depth buffer implies rendering into a depth
619 texture provided by the XR runtime instead of the intermediate texture/render buffer
620 created and managed by Qt. Rendering into a depth texture has certain lower-level
621 consequences that can have a performance impact:
622
623 When using \l{QtQuick3D::SceneEnvironment::antialiasingMode}{multisample antialiasing}
624 (MSAA), enabling depth submission implies rendering into a multisample depth
625 texture and resolving the samples into the non-multisample depth texture provided by
626 the XR runtime. Without depth submission,
627 the resolve step would not be necessary. In addition, some 3D APIs
628 do not support resolving multisample depth-stencil data (see
629 the \l{QRhi::ResolveDepthStencil} flag for details). Without this support,
630 attempts to enable depth submission in combination with MSAA are gracefully ignored.
631
632 Even when MSAA is not used, enabling depth submission triggers writing out
633 depth data with 3D APIs that have control over this. The store operation for
634 depth/stencil data is typically indicated by Qt as unnecessary, which can
635 have positive performance impacts on tiled GPU architectures. This is not
636 done with depth submission because depth data must always be written out
637 from Qt's perspective.
638
639 \note We recommended that developers test their applications with depth
640 submission enabled, evaluate the advantages and disadvantages, and make a
641 conscious choice based on their testing if they wish to enable it or not.
642*/
643
644void QQuick3DXrView::setDepthSubmissionEnabled(bool enable)
645{
646 if (!m_xrManager.isValid()) {
647 qWarning(msg: "Attempted to set depth submission mode without a valid XR manager");
648 return;
649 }
650
651 const bool orgDepthSubmission = m_xrManager.isDepthSubmissionEnabled();
652
653 m_xrManager.setDepthSubmissionEnabled(enable);
654
655 if (orgDepthSubmission != m_xrManager.isDepthSubmissionEnabled())
656 emit depthSubmissionEnabledChanged();
657}
658
659void QQuick3DXrView::setMultiViewRenderingEnabled(bool enable)
660{
661 Q_UNUSED(enable);
662 qWarning(msg: "Setting multiViewRenderingEnabled is not supported.");
663}
664
665void QQuick3DXrView::setXROrigin(QQuick3DXrOrigin *newXrOrigin)
666{
667 if (m_xrOrigin == newXrOrigin)
668 return;
669
670 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DXrView::setXROrigin, newO: newXrOrigin, oldO: m_xrOrigin);
671
672 m_xrOrigin = newXrOrigin;
673
674 // Make sure the XrOrigin has a parent item, if it hasn't, we're it.
675 if (m_xrOrigin && !m_xrOrigin->parentItem())
676 m_xrOrigin->setParentItem(this);
677
678 m_xrManager.setXROrigin(m_xrOrigin);
679
680 emit xrOriginChanged();
681}
682
683/*!
684 \qmlsignal XrView::initializeFailed(const QString &errorString)
685
686 Emitted when initialization fails, and there is a new \a errorString
687 describing the failure.
688 */
689
690/*!
691 \qmlsignal XrView::sessionEnded()
692
693 Emitted when the session ends.
694 */
695
696/*!
697 \qmlsignal XrView::frameReady()
698 \internal
699
700 Emitted when a new frame is ready.
701 */
702
703QT_END_NAMESPACE
704

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtquick3d/src/xr/quick3dxr/qquick3dxrview.cpp