XR_EXT_spatial_container_self_rendering
Name String
XR_EXT_spatial_container_self_rendering
Erweiterungstyp
Instanzerweiterung
Registrierte Durchwahl
814
Revision
1
Ratification Status
Nicht ratifiziert
Erweiterungs- und Versionsabhängigkeiten
XR_EXT_spatial_container
Datum der letzten Änderung
2026-08-06
IP-Status
Keine bekannten Ansprüche auf geistiges Eigentum.
Mitwirkende
Lachlan Ford, Google
Andreas Loeve Selvik, Meta Platforms
Adam Gousetis, Meta Platforms
Bjorn Swenson, LÖVR
Cass Everitt, Meta Platforms
Christian Kruse, Meta Platforms
Denny Rönngren, Varjo Technologies
Fredia Huya-Kouadio, Godot Engine
Jakob Bornecrantz, NVIDIA
Jared Finder, Google
Jonathan Wright, Meta Platforms
Jian Zhang, ByteDance
Kurtis Eveleigh, Qualcomm
Mauricio Narvaez, Meta Platforms
Nick Klingensmith, Qualcomm
Nikita Lutsenko, Meta Platforms
Praveen Babu J D, ByteDance
Rylie Pavlik, Collabora
Salar Khan, Google
Shuai Liu, ByteDance
Walter Luh, Meta Platforms
Yin Li, Microsoft
Übersicht
Diese Erweiterung definiert das „Self-Rendering“ für räumliche Container. Die Pixel eines selbst gerenderten räumlichen Containers werden alle von einer App generiert und mithilfe von Standard-OpenXR-Swapchains und ‑Kompositionsebenen an die Laufzeit übermittelt. Da räumliche Container nicht immer alle Pixel eines Bildschirms einnehmen, informiert die Laufzeitumgebung Apps über die empfohlene Auflösung und Ansichtskonfiguration jedes räumlichen Containers, damit Apps effizienter rendern können.
Diese Erweiterung in Kombination mit XR_EXT_spatial_container soll eine Obermenge der Funktionen des herkömmlichen OpenXR 1.x-Core-Composition-Layer-Renderings bieten. OpenXR 1.x-Laufzeiten, die grafisches Rendering und diese Erweiterung unterstützen, müssen XrSystemSpatialContainerPropertiesEXT :: supportsImmersive auf „true“ setzen, um anzugeben, dass sie immersive räumliche Container unterstützen.
Lebenszyklus des Renderings von räumlichen Containern
Wenn eine App das Self-Rendering für einen räumlichen Container verwenden möchte, setzt sie beim Aufruf von xrCreateSpatialContainerEXT XrSpatialContainerCreateInfoEXT :: graphicsPresentation auf XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT. Diese App kann dann verwalten, ob ein räumlicher Container aktiv gerendert wird, indem sie die Funktionen xrBeginSpatialContainerRenderingEXT und xrEndSpatialContainerRenderingEXT aufruft. Diese Funktionen ersetzen xrBeginSession und xrEndSession . Es handelt sich nicht um Vorgänge pro Frame, wie xrBeginFrame und xrEndFrame .
In jedem Frame durchläuft eine App die folgenden Schritte:
- Rufen Sie xrWaitFrame und xrBeginFrame auf. Diese Funktionen haben keine containerspezifischen Strukturen und funktionieren wie in der Kernspezifikation.
- Mit xrLocateSpatialContainerViewsEXT können Sie Ansichtsposen, Projektionsparameter und Rendering-Empfehlungen für alle räumlichen Container abrufen, die aktiv gerendert werden. Für jeden räumlichen Container meldet die Laufzeit, ob die zugehörigen Kompositionsebenen gerendert werden sollten, und empfiehlt eine Methode zum Rendern der Ebenen, indem XrSpatialContainerViewStateEXT ausgefüllt wird.
- Pixel werden normal in Kompositionsebenen gerendert. Diese Vorgänge haben keine containerspezifischen Strukturen.
- Reichen Sie Kompositionsebenen für alle räumlichen Container ein, die aktiv gerendert werden, indem Sie xrEndFrame aufrufen und XrSpatialContainerLayerFrameEndInfoEXT verketten.
Wenn ein XrSpatialContainerEXT-Handle gelöscht wird, wird es implizit aus dem aktiven Render-Set entfernt. Eine App darf einen räumlichen Container zerstören, auch wenn sie einen erfolgreichen Aufruf von xrBeginSpatialContainerRenderingEXT durchgeführt hat, der nicht mit einem entsprechenden Aufruf von xrEndSpatialContainerRenderingEXT verknüpft ist. Die Laufzeit muss sich so verhalten, als ob xrEndSpatialContainerRenderingEXT bei Bedarf früh in der Implementierung von xrDestroySpatialContainerEXT implizit aufgerufen wird, wenn sie erfolgreich zurückgegeben wird.
Wenn eine App ein XrEventDataSpatialContainerClosedEXT-Ereignis für einen Container im aktiven Rendering-Set empfängt, sollte sie xrEndSpatialContainerRenderingEXT aufrufen und das XrSpatialContainerEXT-Handle löschen.
Mit der Funktion xrBeginSpatialContainerRenderingEXT wird der räumliche Container dem aktiven Render-Set pro Sitzung hinzugefügt. So kann eine App Kompositionsebenen für den räumlichen Container an xrEndFrame senden.
XrResult xrBeginSpatialContainerRenderingEXT(
XrSession session,
const XrSpatialContainerBeginInfoEXT* beginInfo);
Parameterbeschreibungen
sessionist die XrSession .beginInfoist ein Zeiger auf eine XrSpatialContainerBeginInfoEXT-Struktur.
Apps rufen diese Funktion in der Regel als Reaktion auf ein „visible-changed“-Ereignis auf, bei dem XrEventDataSpatialContainerVisibleChangedEXT :: visible auf „true“ gesetzt ist.
Wenn der räumliche Container beim Aufruf von xrCreateSpatialContainerEXT nicht mit XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT erstellt wurde, muss die Laufzeit XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT zurückgeben.
Wenn sich der räumliche Container bereits im aktiven Render-Set befindet, muss die Laufzeit XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT zurückgeben.
Wenn xrBeginSpatialContainerRenderingEXT zu einem Zeitpunkt aufgerufen wird, zu dem die App xrWaitFrame nicht aufrufen konnte (also innerhalb des Fensters xrBeginFrame und xrEndFrame), muss die Laufzeit XR_ERROR_CALL_ORDER_INVALID zurückgeben.
Gültige Verwendung (implizit)
- Die Erweiterung
XR_EXT_spatial_container_self_renderingmuss aktiviert werden, bevor xrBeginSpatialContainerRenderingEXT aufgerufen wird. -
sessionmuss ein gültiges XrSession-Handle sein -
beginInfomuss ein Zeiger auf eine gültige XrSpatialContainerBeginInfoEXT-Struktur sein
Threadsicherheit
- Der Zugriff auf den Parameter
sessiondurch einen anderen xrBeginSpatialContainerRenderingEXT-, xrEndSpatialContainerRenderingEXT- oder xrEndFrame-Aufruf muss extern synchronisiert werden.
Rückgabecodes
XR_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_CALL_ORDER_INVALIDXR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_RUNTIME_FAILUREXR_ERROR_SESSION_LOSTXR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXTXR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXTXR_ERROR_VALIDATION_FAILUREXR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED
Die Struktur XrSpatialContainerBeginInfoEXT wird verwendet, um die Parameter für den Beginn des Renderings eines räumlichen Containers anzugeben.
typedef struct XrSpatialContainerBeginInfoEXT {
XrStructureType type;
const void* next;
XrSpatialContainerEXT spatialContainer;
XrViewConfigurationType primaryViewConfigurationType;
} XrSpatialContainerBeginInfoEXT;
Beschreibung des Mitglieds
typeist der XrStructureType dieser Struktur.nextistNULLoder ein Zeiger auf die nächste Struktur in einer Strukturkette.spatialContainerist der XrSpatialContainerEXT, mit dem das Rendering gestartet werden soll.primaryViewConfigurationTypeist der primäre XrViewConfigurationType, der für den räumlichen Container verwendet werden soll.
primaryViewConfigurationType ist die Ansichtskonfiguration, die die App beim Rendern verwenden soll. Die Laufzeit kann die Ansichtskonfiguration zu Optimierungszwecken auf einen Typ mit weniger Ansichten reduzieren (z.B. wenn ein Container sehr weit entfernt und klein ist, sodass Stereo nicht wahrnehmbar ist). Die Laufzeit gibt Details zur veralteten Ansichtskonfiguration aus Aufrufen von xrLocateSpatialContainerViewsEXT zurück.
Gültige Verwendung (implizit)
- Die Erweiterung
XR_EXT_spatial_container_self_renderingmuss aktiviert werden, bevor XrSpatialContainerBeginInfoEXT verwendet werden kann. -
typemussXR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXTsein -
nextmussNULLoder ein gültiger Zeiger auf die nächste Struktur in einer Strukturkette sein. -
spatialContainermuss ein gültiges XrSpatialContainerEXT-Handle sein -
primaryViewConfigurationTypemuss ein gültiger XrViewConfigurationType-Wert sein.
Mit der Funktion xrEndSpatialContainerRenderingEXT wird der räumliche Container aus dem aktiven Rendering-Set entfernt.
XrResult xrEndSpatialContainerRenderingEXT(
XrSession session,
const XrSpatialContainerEndInfoEXT* endInfo);
Parameterbeschreibungen
sessionist die XrSession .endInfoist ein Zeiger auf eine XrSpatialContainerEndInfoEXT-Struktur.
Apps rufen diese Funktion in der Regel als Reaktion auf ein „visible-changed“-Ereignis auf, bei dem XrEventDataSpatialContainerVisibleChangedEXT :: visible auf „false“ gesetzt ist.
Wenn sich der räumliche Container nicht im aktiven Rendering-Set befindet, muss die Laufzeit XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT zurückgeben.
Wenn xrEndSpatialContainerRenderingEXT zu einem Zeitpunkt aufgerufen wird, an dem die App xrWaitFrame nicht aufrufen konnte (also zwischen den Aufrufen von xrBeginFrame und xrEndFrame), muss die Laufzeit XR_ERROR_CALL_ORDER_INVALID zurückgeben.
Gültige Verwendung (implizit)
- Die Erweiterung
XR_EXT_spatial_container_self_renderingmuss aktiviert sein, bevor xrEndSpatialContainerRenderingEXT aufgerufen wird. -
sessionmuss ein gültiges XrSession-Handle sein -
endInfomuss ein Zeiger auf eine gültige XrSpatialContainerEndInfoEXT-Struktur sein
Threadsicherheit
- Der Zugriff auf den Parameter
sessiondurch einen anderen xrBeginSpatialContainerRenderingEXT-, xrEndSpatialContainerRenderingEXT- oder xrEndFrame-Aufruf muss extern synchronisiert werden.
Rückgabecodes
XR_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_CALL_ORDER_INVALIDXR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_RUNTIME_FAILUREXR_ERROR_SESSION_LOSTXR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXTXR_ERROR_VALIDATION_FAILURE
Die Struktur XrSpatialContainerEndInfoEXT wird verwendet, um die Parameter für das Beenden des Renderings eines räumlichen Containers anzugeben.
typedef struct XrSpatialContainerEndInfoEXT {
XrStructureType type;
const void* next;
XrSpatialContainerEXT spatialContainer;
} XrSpatialContainerEndInfoEXT;
Beschreibung des Mitglieds
typeist der XrStructureType dieser Struktur.nextistNULLoder ein Zeiger auf die nächste Struktur in einer Strukturkette.spatialContainerist der XrSpatialContainerEXT, für den das Rendering beendet werden soll.
Gültige Verwendung (implizit)
- Die Erweiterung
XR_EXT_spatial_container_self_renderingmuss aktiviert sein, bevor XrSpatialContainerEndInfoEXT verwendet werden kann. -
typemussXR_TYPE_SPATIAL_CONTAINER_END_INFO_EXTsein -
nextmussNULLoder ein gültiger Zeiger auf die nächste Struktur in einer Strukturkette sein. -
spatialContainermuss ein gültiges XrSpatialContainerEXT-Handle sein
Ansichten über xrLocateSpatialContainerViewsEXT finden
Die Funktion xrLocateSpatialContainerViewsEXT sucht nach Ansichten für eine Reihe von räumlichen Containern.
XrResult xrLocateSpatialContainerViewsEXT(
XrSession session,
const XrSpatialContainerViewsLocateInfoEXT* locateInfo,
uint32_t viewStateCount,
XrSpatialContainerViewStateEXT* viewStates,
uint32_t viewCount,
XrView* views);
Parameterbeschreibungen
sessionist die XrSession .locateInfoist ein Zeiger auf eine XrSpatialContainerViewsLocateInfoEXT-Struktur.viewStateCountist die Anzahl desviewStates-Arrays.viewStatesist ein Zeiger auf ein Array von XrSpatialContainerViewStateEXT-Strukturen, die von der Laufzeit ausgefüllt werden sollen.viewCountist die Anzahl derviews-Arrays.viewsist ein Zeiger auf ein Array von XrView-Strukturen.
Diese Funktion ersetzt xrLocateViews und ermöglicht es einer App, Ansichten für mehrere räumliche Container gleichzeitig abzufragen.
Ansichten für alle räumlichen Container werden im einzelnen views-Array zurückgegeben. Die Ansichten werden nach dem Index des räumlichen Containers im Array XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos und dann nach dem Ansichtsindex für diesen Container sortiert.
Wenn eine App beispielsweise drei räumliche Container in XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos bereitstellt:
- Index 0:
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO(1 Aufruf) - Index 1:
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO(2 Aufrufe) - Index 2:
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO_WITH_FOVEATED_INSET(4 Aufrufe)
Anschließend muss die Laufzeit das Array views mit 7 Ansichten füllen:
views[0] ist die Ansicht für Container 0.views[1] ist die Ansicht für das linke Auge für Container 1.views[2] ist die Ansicht für das rechte Auge für Container 1.views[3] ist die Ansicht für das linke Auge für Container 2.views[4] ist die Ansicht für das rechte Auge für Container 2.views[5] ist die Ansicht des linken Auges für Container 2.views[6] ist die Ansicht des rechten Auges für Container 2.
Wenn viewCount nicht der Summe der Aufrufzahlen für den angeforderten Ansichtskonfigurationstyp jedes räumlichen Containers entspricht, muss die Laufzeit XR_ERROR_VALIDATION_FAILURE zurückgeben.
Die Laufzeit kann die Ansichtskonfiguration zu Optimierungszwecken auf einen Typ mit weniger Ansichten reduzieren (z.B. wenn ein Container sehr weit entfernt und klein ist, sodass Stereo nicht wahrnehmbar ist). Wenn die Laufzeit die Ansichtskonfiguration verfallen lässt, muss die Laufzeit trotzdem die ursprüngliche Anzahl von Ansichten für diesen Container zurückgeben und die zusätzlichen Ansichten mit Duplikaten der verfallenen Ansichten füllen. Wenn beispielsweise XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO auf XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO reduziert wird, enthalten sowohl Index 0 als auch Index 1 die einzelne Mono-Ansicht. Die Gesamtzahl der im Array views zurückgegebenen Ansichten ist daher unabhängig davon, ob die Laufzeitumgebung Ansichtskonfigurationen verfallen lässt oder nicht.
Die Laufzeit sollte jede zurückgegebene XrView :: fov so anpassen, dass der Frustum so klein wie möglich ist, aber dennoch die gesamten Grenzen des entsprechenden räumlichen Containers enthält. Laufzeiten können asymmetrische Sichtfelder zurückgeben, z. B. wenn ein räumlicher Container in einem schrägen Winkel zur Sicht des Nutzers steht oder teilweise von einem anderen Objekt verdeckt wird. Laufzeiten können die Ziel-Rendering-Oberfläche für den räumlichen Container frei positionieren. Aufgrund der Art des Multi-App-Renderings, bei dem räumliche Container vom Nutzer getrennt sind, kann die Laufzeit XrView-Werte zurückgeben, die nicht für das Pixel-Rendering geeignet sind. Wenn der räumliche Container beispielsweise nicht auf dem Bildschirm sichtbar ist, gibt es keine gültigen Werte, auf die XrView :: fov festgelegt werden kann. In solchen Fällen müssen Laufzeiten XrSpatialContainerViewStateEXT :: shouldSubmitLayers auf „false“ setzen.
Die Laufzeit gibt im Array viewStates zusätzliche Informationen zum Renderingstatus pro räumlichem Container zurück. Wenn viewStateCount nicht gleich XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfoCount ist, muss die Laufzeit XR_ERROR_VALIDATION_FAILURE zurückgeben.
Nachdem die Laufzeit ein XrEventDataSpatialContainerClosedEXT-Ereignis für einen räumlichen Container in die Warteschlange gestellt hat, muss diese Funktion XR_FALSE in XrSpatialContainerViewStateEXT :: shouldSubmitLayers und 0 in XrSpatialContainerViewStateEXT :: viewStateFlags für den entsprechenden räumlichen Container zurückgeben.
Bei räumlichen Containern mit sich aktiv ändernden Standorten in der realen Welt sollte die Laufzeit die Bewegung des Containers beim Ausfüllen von views berücksichtigen, um Reprojektionsartefakte zu minimieren.
Wenn xrLocateSpatialContainerViewsEXT für einen oder mehrere räumliche Container aufgerufen wird, die sich derzeit nicht im aktiven Render-Set befinden, muss die Laufzeit XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT zurückgeben.
Gültige Verwendung (implizit)
- Die Erweiterung
XR_EXT_spatial_container_self_renderingmuss aktiviert werden, bevor xrLocateSpatialContainerViewsEXT aufgerufen wird. -
sessionmuss ein gültiges XrSession-Handle sein -
locateInfomuss ein Zeiger auf eine gültige XrSpatialContainerViewsLocateInfoEXT-Struktur sein. -
viewStatesmuss ein Zeiger auf ein Array vonviewStateCountXrSpatialContainerViewStateEXT-Strukturen sein -
viewsmuss ein Zeiger auf ein Array vonviewCountXrView-Strukturen sein. - Der Parameter
viewStateCountmuss größer als0sein. - Der Parameter
viewCountmuss größer als0sein.
Rückgabecodes
XR_SUCCESSXR_SESSION_LOSS_PENDING
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_RUNTIME_FAILUREXR_ERROR_SESSION_LOSTXR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXTXR_ERROR_TIME_INVALIDXR_ERROR_VALIDATION_FAILUREXR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED
Die Struktur XrSpatialContainerViewsLocateInfoEXT enthält die Parameter zum Lokalisieren von Ansichten in einer Sammlung von räumlichen Containern.
typedef struct XrSpatialContainerViewsLocateInfoEXT {
XrStructureType type;
const void* next;
XrTime displayTime;
uint32_t viewLocateInfoCount;
const XrSpatialContainerViewLocateInfoEXT* viewLocateInfos;
} XrSpatialContainerViewsLocateInfoEXT;
Beschreibung des Mitglieds
typeist der XrStructureType dieser Struktur.nextistNULLoder ein Zeiger auf die nächste Struktur in einer Strukturkette.displayTimeist derXrTime, an dem sich die Ansichten befinden.viewLocateInfoCountist die Anzahl der Einträge imviewLocateInfos-Array.viewLocateInfosist ein Zeiger auf ein Array von XrSpatialContainerViewLocateInfoEXT-Strukturen.
Gültige Verwendung (implizit)
- Die Erweiterung
XR_EXT_spatial_container_self_renderingmuss aktiviert sein, bevor XrSpatialContainerViewsLocateInfoEXT verwendet werden kann. -
typemussXR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXTsein -
nextmussNULLoder ein gültiger Zeiger auf die nächste Struktur in einer Strukturkette sein. -
viewLocateInfosmuss ein Zeiger auf ein Array vonviewLocateInfoCountgültigen XrSpatialContainerViewLocateInfoEXT-Strukturen sein - Der Parameter
viewLocateInfoCountmuss größer als0sein.
Die Struktur XrSpatialContainerViewLocateInfoEXT enthält die Parameter für einen einzelnen räumlichen Container, für den Ansichten gefunden werden sollen.
typedef struct XrSpatialContainerViewLocateInfoEXT {
XrStructureType type;
const void* next;
XrViewConfigurationType viewConfigurationType;
XrSpace space;
XrSpatialContainerEXT spatialContainer;
} XrSpatialContainerViewLocateInfoEXT;
Beschreibung des Mitglieds
typeist der XrStructureType dieser Struktur.nextistNULLoder ein Zeiger auf die nächste Struktur in einer Strukturkette.viewConfigurationTypeist ein XrViewConfigurationType, der für den räumlichen Container verwendet werden soll.spaceist der XrSpace, in dem sich die Ansichten des räumlichen Containers befinden.spatialContainerist das XrSpatialContainerEXT-Handle.
Die App kann einen beliebigen gültigen XrSpace in space bereitstellen. Es wird jedoch empfohlen, den räumlichen Containerbereich für den entsprechenden XrSpatialContainerEXT bereitzustellen, der in der Struktur XrSpatialContainerViewLocateInfoEXT angegeben ist.
Gültige Verwendung (implizit)
- Die Erweiterung
XR_EXT_spatial_container_self_renderingmuss aktiviert sein, bevor XrSpatialContainerViewLocateInfoEXT verwendet werden kann. -
typemussXR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXTsein -
nextmussNULLoder ein gültiger Zeiger auf die nächste Struktur in einer Strukturkette sein. -
viewConfigurationTypemuss ein gültiger XrViewConfigurationType-Wert sein. -
spacemuss ein gültiger XrSpace-Alias sein -
spatialContainermuss ein gültiges XrSpatialContainerEXT-Handle sein - Sowohl
spaceals auchspatialContainermüssen aus derselben XrSession erstellt, zugewiesen oder abgerufen worden sein.
Die Struktur XrSpatialContainerViewStateEXT wird durch Aufrufe von xrLocateSpatialContainerViewsEXT mit Informationen zur Rendering-Eignung pro räumlichem Container gefüllt.
typedef struct XrSpatialContainerViewStateEXT {
XrStructureType type;
void* next;
XrViewStateFlags viewStateFlags;
XrViewConfigurationType viewConfigurationType;
XrBool32 shouldSubmitLayers;
XrExtent2Di recommendedImageExtent;
} XrSpatialContainerViewStateEXT;
Beschreibung des Mitglieds
typeist der XrStructureType dieser Struktur.nextistNULLoder ein Zeiger auf die nächste Struktur in einer Strukturkette.viewStateFlagsist eine Bitmaske von XrViewStateFlags . Diese Flags haben denselben Zweck wie die viewStateFlags in der XrViewState-Kernstruktur.viewConfigurationTypeist ein XrViewConfigurationType, der den Ansichtskonfigurationstyp angibt, den die Laufzeit für den räumlichen Container verwendet. Laufzeiten können zu einer Ansichtskonfiguration mit einer geringeren Anzahl von Ansichten als der angeforderten herabgestuft werden.shouldSubmitLayersist einXrBool32, der von der Laufzeit zurückgegeben wird. WennXR_FALSE, sollte die App das Senden von Kompositionen für diesen räumlichen Container vermeiden, da er derzeit nicht sichtbar ist oder sich in einem Zustand befindet, in dem kein Rendering erforderlich ist.recommendedImageExtentist eine XrExtent2Di-Struktur, die die empfohlene Auflösung für den räumlichen Container darstellt.
Wie bei der OpenXR-Kernansichtsposition muss die App XrSpatialContainerViewStateEXT :: viewStateFlags prüfen, um sicherzustellen, dass die Position und Ausrichtung gültig sind und erfasst werden, bevor die Ansichtsdaten für das Rendering verwendet werden.
Die App sollte shouldSubmitLayers und viewConfigurationType prüfen, um zu vermeiden, dass mehr gerendert wird, als von der Laufzeit empfohlen. Wenn shouldSubmitLayers „false“ ist, ändert die App ihr Renderingverhalten so:
- Die App darf die entsprechende XrView ::
fovnicht lesen. - Die App darf
recommendedImageExtentnicht lesen. - Die App sollte das Rendern in Swapchains und das Senden von Kompositionsebenen für den entsprechenden räumlichen Container vermeiden.
- Die App sollte XrSpatialContainerLayerEXT ::
retainPreviousSubmissionauf „true“ setzen. Wenn die App trotzdem Ebenen einreicht, entscheidet die Laufzeit, was mit den Ebenen geschehen soll (z.B. kann die Laufzeit sie verwerfen).
recommendedImageExtent ist explizit für Ebenen vorgesehen, die basierend auf der Containerposition oder der Ansicht des Nutzers aktualisiert werden. Wenn Ebenen mit Inhalten aktualisiert werden, die von der Position des räumlichen Containers oder der Ansicht des Nutzers abhängen (z. B. normale 3D-Inhalte), sollte die App in diesem kleineren Darstellungsbereich statt in der standardmäßig empfohlenen Ansichtsgröße rendern. Wenn Ebenen mit Inhalten aktualisiert werden, die nicht von der Position des räumlichen Containers oder der Ansicht des Nutzers abhängen (z. B. statische Quad-Ebenen), kann die App diese Werte ignorieren. Bei ansichtsabhängigen Ebenen ist recommendedImageExtent eine Empfehlung der Laufzeitumgebung an die App, um Aliasing zu minimieren und die Renderingleistung zu verbessern. Die App kann Bilder in voller Auflösung einreichen, wenn sie möchte.
XrExtent2Di :: width und XrExtent2Di :: height von recommendedImageExtent müssen immer eine positive Ganzzahl sein, die kleiner oder gleich XrViewConfigurationView :: recommendedImageRectWidth und XrViewConfigurationView :: recommendedImageRectHeight von XrViewConfigurationView für die primäre Ansichtskonfiguration des räumlichen Containers ist. Eine App sollte eine Swapchain nicht nur deshalb neu erstellen, weil sich recommendedImageExtent geändert hat. Es handelt sich dabei um einen dynamischen Hinweis für die App, der die XrSwapchainSubImage :: imageRect angibt, die in der XrSwapchainSubImage aller von ihr gesendeten Kompositionsebenen mit voller Auflösung verwendet werden soll, und kann sich bei jedem Frame ändern.
Gültige Verwendung (implizit)
- Die Erweiterung
XR_EXT_spatial_container_self_renderingmuss aktiviert sein, bevor XrSpatialContainerViewStateEXT verwendet werden kann. -
typemussXR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXTsein -
nextmussNULLoder ein gültiger Zeiger auf die nächste Struktur in einer Strukturkette sein. -
viewStateFlagsmuss eine gültige Kombination von XrViewStateFlagBits-Werten sein -
viewStateFlagsdarf nicht0sein -
viewConfigurationTypemuss ein gültiger XrViewConfigurationType-Wert sein.
Referenzbereich ansehen
Der Ansichtsreferenzraum bleibt unverändert, da er sich im OpenXR-Kern befindet. Wie bei der Kernvariante ist sie nicht für das Rendering vorgesehen.
Ebenen über xrEndFrame einreichen
Damit räumliche Container gerendert werden können, muss die App eine Liste der Ebenen, die mit den jeweiligen räumlichen Containern verknüpft sind, an xrEndFrame übergeben. Dies wird über die Struktur XrSpatialContainerLayerFrameEndInfoEXT erreicht.
typedef struct XrSpatialContainerLayerFrameEndInfoEXT {
XrStructureType type;
const void* next;
uint32_t containerLayerCount;
const XrSpatialContainerLayerEXT* containerLayers;
} XrSpatialContainerLayerFrameEndInfoEXT;
Beschreibung des Mitglieds
typeist der XrStructureType dieser Struktur.nextistNULLoder ein Zeiger auf die nächste Struktur in einer Strukturkette.containerLayerCountist die Anzahl der Elemente im ArraycontainerLayers.containerLayersist ein Zeiger auf ein Array von XrSpatialContainerLayerEXT-Strukturen.
Das containerLayers-Array enthält für jeden räumlichen Container im aktiven Rendering-Set (die Container, die pro Sitzung von xrBeginSpatialContainerRenderingEXT und xrEndSpatialContainerRenderingEXT verwaltet werden) einen XrSpatialContainerLayerEXT. Jede XrSpatialContainerLayerEXT enthält eine Liste von XrCompositionLayerBaseHeader-Zeigern, die mit dem jeweiligen räumlichen Container verknüpft sind. Laufzeiten können zusammengesetzte Container in beliebiger Reihenfolge erstellen, unabhängig von der Reihenfolge der containerLayers . Beispielsweise können Laufzeiten Container basierend auf ihrer Tiefe relativ zum Nutzer zusammensetzen, einen räumlichen Container als Hintergrundebene verwenden oder einen räumlichen Container so „anpinnen“, dass er unabhängig von seiner Tiefe immer oben ist. Laufzeiten können Ebenen mit unterschiedlichen Strategien für räumliche Container im begrenzten oder immersiven Modus zusammensetzen. Beispielsweise können Laufzeiten die Kompositionsebenen jedes begrenzten räumlichen Containers in einer einzigen Stereo-Quad-Ebene vorkomponieren, die in einem zweiten Kompositionsschritt mit allen anderen Containern kombiniert wird.
XrFrameEndInfo :: displayTime und XrFrameEndInfo :: environmentBlendMode werden auf alle räumlichen Container angewendet, die in XrSpatialContainerLayerFrameEndInfoEXT angegeben sind.
Wenn diese Struktur an xrEndFrame übergeben wird, indem sie mit XrFrameEndInfo verkettet wird, werden die folgenden zusätzlichen Fehlerfälle basierend auf dem aktiven Rendering-Set hinzugefügt:
- Wenn ein räumlicher Container von mehr als einem Element von
containerLayersreferenziert wird, müssen LaufzeitenXR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXTzurückgeben. - Wenn ein räumlicher Container im aktiven Render-Set nicht von einem Element von
containerLayersreferenziert wird, müssen LaufzeitenXR_ERROR_SPATIAL_CONTAINER_MISSING_EXTzurückgeben. - Wenn ein von
containerLayersreferenzierter räumlicher Container nicht Teil des aktiven Render-Sets ist, müssen LaufzeitenXR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXTzurückgeben.
Wenn sich im aktiven Rendering-Set räumliche Container befinden und diese Struktur nicht mit XrFrameEndInfo verkettet ist, müssen Laufzeiten XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT zurückgeben.
In allen oben genannten Fehlerfällen darf die Laufzeit keine Inhalte für räumliche Container rendern.
Wenn sich keine räumlichen Container im aktiven Rendering-Set befinden, kann eine App xrEndFrame aufrufen, solange sie keine Kompositionsebenen sendet.
Einzelne Swapchains können über Ebenen in einer gültigen Struktur für mehrere Container eingereicht werden, z.B. eine Quad-Ebene, die über eine einzelne Swapchain gerendert und an mehrere räumliche Container gesendet wird. Dieser Fall wird einheitlich mit anderen Renderings behandelt: Die Laufzeit muss das Quad in allen solchen räumlichen Containern rendern.
Gültige Verwendung (implizit)
- Die Erweiterung
XR_EXT_spatial_container_self_renderingmuss aktiviert sein, bevor XrSpatialContainerLayerFrameEndInfoEXT verwendet werden kann. -
typemussXR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXTsein -
nextmussNULLoder ein gültiger Zeiger auf die nächste Struktur in einer Strukturkette sein. -
containerLayersmuss ein Zeiger auf ein Array voncontainerLayerCountgültigen XrSpatialContainerLayerEXT-Strukturen sein - Der Parameter
containerLayerCountmuss größer als0sein.
Die XrSpatialContainerLayerEXT-Struktur gruppiert Standard-Kompositionsebenen und verknüpft sie mit einem bestimmten räumlichen Container.
typedef struct XrSpatialContainerLayerEXT {
XrStructureType type;
const void* next;
XrSpatialContainerEXT spatialContainer;
XrBool32 retainPreviousSubmission;
uint32_t layerCount;
const XrCompositionLayerBaseHeader* const* layers;
} XrSpatialContainerLayerEXT;
Beschreibung des Mitglieds
typeist der XrStructureType dieser Struktur.nextistNULLoder ein Zeiger auf die nächste Struktur in einer Strukturkette.spatialContainerist der XrSpatialContainerEXT, der den Zielcontainer identifiziert.retainPreviousSubmissionist einXrBool32. WennXR_TRUE, behält die Laufzeit den zuletzt gesendeten Frame für diesen räumlichen Container bei.layerCountist die Anzahl der Kompositionsebenen im Arraylayers.layersist ein Zeiger auf ein Array von XrCompositionLayerBaseHeader-Zeigern.
Wenn retainPreviousSubmission den Wert XR_TRUE hat, muss die Laufzeit die Kompositionsebenen und den Inhalt des Swapchain-Bildes wiederverwenden, wie sie während des letzten xrEndFrame-Aufrufs, bei dem retainPreviousSubmission den Wert XR_FALSE hatte, gespeichert wurden. Alle nachfolgenden Änderungen an Swapchains, die von beibehaltenen Ebenen verwendet werden, dürfen nicht in der gerenderten Ausgabe widergespiegelt werden.
Bei Ebenen, die für einen einzelnen räumlichen Container eingereicht werden (Intra-Container-Rendering), muss die Laufzeit die bereits festgelegten Regeln für die Reihenfolge der Ebenenzusammensetzung einhalten. Das bedeutet, dass die Ebenen innerhalb von Containern in derselben Reihenfolge gezeichnet werden müssen, in der sie angegeben sind, und zwar mithilfe des Painter-Algorithmus.
Das „Leeren“ eines räumlichen Containers bezieht sich auf das Entfernen aller Inhalte aus einem räumlichen Container, sodass im aktuellen Frame nichts für diesen Container gerendert wird. Laufzeiten müssen dies so behandeln, als würde die App für jeden Pixel im Container transparentes Schwarz (alle Bits 0) senden. „Beibehalten“ eines räumlichen Containers bedeutet, dass die Laufzeit weiterhin die zuletzt für diesen Container eingereichten Ebenen anzeigt.
Für jeden räumlichen Container kann die App angeben, ob neue Ebenen gesendet, die vorherige Einreichung beibehalten oder der räumliche Container gelöscht werden soll:
- Um neue Ebenen einzureichen, stellt die App einen
layerCount-Wert ungleich null und einen gültigenlayers-Zeiger bereit. - Wenn Sie einen räumlichen Container löschen möchten, muss der
layerCountfür seinen Eintrag 0 undretainPreviousSubmissionmussXR_FALSEsein. - Wenn die zuletzt gesendeten Ebenen und Swapchain-Bilder beibehalten werden sollen, muss
layerCountfür den Eintrag 0 undretainPreviousSubmissionmussXR_TRUEsein.
Durch diese explizite Steuerung pro Container wird sichergestellt, dass die Absicht der App in jedem Frame klar kommuniziert wird.
Wenn retainPreviousSubmission XR_TRUE und layerCount nicht 0 ist, muss die Laufzeit XR_ERROR_VALIDATION_FAILURE zurückgeben.
Wenn XrSpatialContainerCompositionLayerViewConfigurationEXT nicht mit einer XrCompositionLayerProjection verkettet ist, die Teil eines räumlichen Containers ist, muss die Laufzeit XR_ERROR_VALIDATION_FAILURE zurückgeben. Diese Struktur gilt nur für XrCompositionLayerProjection-Ebenen. Wenn sie mit anderen Ebenentypen (z.B. Quad- oder Zylinderebenen) verkettet ist, muss die Laufzeit XR_ERROR_VALIDATION_FAILURE zurückgeben.
Gültige Verwendung (implizit)
- Die Erweiterung
XR_EXT_spatial_container_self_renderingmuss aktiviert sein, bevor XrSpatialContainerLayerEXT verwendet werden kann. -
typemussXR_TYPE_SPATIAL_CONTAINER_LAYER_EXTsein -
nextmussNULLoder ein gültiger Zeiger auf die nächste Struktur in einer Strukturkette sein. Siehe auch: XrSpatialContainerLayerVolumeClippingEXT -
spatialContainermuss ein gültiges XrSpatialContainerEXT-Handle sein - Wenn
layerCountnicht0ist, musslayersein Zeiger auf ein Array vonlayerCountgültigen XrCompositionLayerBaseHeader-basierten Strukturen sein. Siehe auch: XrCompositionLayerCubeKHR , XrCompositionLayerCylinderKHR , XrCompositionLayerEquirect2KHR , XrCompositionLayerEquirectKHR , XrCompositionLayerPassthroughANDROID , XrCompositionLayerPassthroughFB , XrCompositionLayerPassthroughHTC , XrCompositionLayerProjection , XrCompositionLayerQuad
Ansichtskonfiguration für Projektionsebenen angeben
Mit der Struktur XrSpatialContainerCompositionLayerViewConfigurationEXT wird die Ansichtskonfiguration angegeben, die zum Rendern einer Projektionsebene für einen räumlichen Container verwendet wird.
typedef struct XrSpatialContainerCompositionLayerViewConfigurationEXT {
XrStructureType type;
const void* next;
XrViewConfigurationType viewConfigurationType;
} XrSpatialContainerCompositionLayerViewConfigurationEXT;
Beschreibung des Mitglieds
typeist der XrStructureType dieser Struktur.nextistNULLoder ein Zeiger auf die nächste Struktur in einer Strukturkette.viewConfigurationTypeist der XrViewConfigurationType, der zum Rendern der XrCompositionLayerProjection verwendet wurde.
Wenn eine XrCompositionLayerProjection für einen räumlichen Container eingereicht wird, muss die App angeben, welche Ansichtskonfiguration zum Rendern der Ebene verwendet wurde. Das ist erforderlich, weil die App für jeden Frame entscheiden kann, ob sie mit der primären Ansichtskonfiguration des räumlichen Containers oder mit der von der Laufzeit vorgeschlagenen, gegebenenfalls abgeschwächten Ansichtskonfiguration gerendert werden soll.
Wenn XrSpatialContainerCompositionLayerViewConfigurationEXT verkettet ist, muss die App dafür sorgen, dass XrCompositionLayerProjection :: viewCount eine gültige Anzahl von Ansichten für den in der verketteten Struktur angegebenen XrViewConfigurationType ist. Der in der verketteten Struktur angegebene viewConfigurationType muss der XrSpatialContainerBeginInfoEXT :: primaryViewConfigurationType sein, der beim Start des Containers angegeben wurde, oder der von der Laufzeit in XrSpatialContainerViewStateEXT zurückgegebene Typ der veralteten Ansichtskonfiguration oder zusätzliche Werte, die über eine Erweiterung aktiviert wurden.
Gültige Verwendung (implizit)
- Die Erweiterung
XR_EXT_spatial_container_self_renderingmuss aktiviert sein, bevor XrSpatialContainerCompositionLayerViewConfigurationEXT verwendet werden kann. -
typemussXR_TYPE_SPATIAL_CONTAINER_COMPOSITION_LAYER_VIEW_CONFIGURATION_EXTsein -
nextmussNULLoder ein gültiger Zeiger auf die nächste Struktur in einer Strukturkette sein. -
viewConfigurationTypemuss ein gültiger XrViewConfigurationType-Wert sein.
Pixel-Clipping-Verhalten
Apps sollten die Laufzeit darüber informieren, ob sie Pixel außerhalb der Grenzen eines räumlichen Containers rendern oder nicht. Dazu müssen sie beim Senden von Kompositionsebenen XrSpatialContainerLayerVolumeClippingEXT verketten.
typedef struct XrSpatialContainerLayerVolumeClippingEXT {
XrStructureType type;
const void* next;
XrSpatialContainerVolumeClippingEXT volumeClipping;
} XrSpatialContainerLayerVolumeClippingEXT;
Beschreibung des Mitglieds
typeist der XrStructureType dieser Struktur.nextistNULLoder ein Zeiger auf die nächste Struktur in einer Strukturkette.volumeClippingist das XrSpatialContainerVolumeClippingEXT, das die App angewendet hat.
Diese Struktur dient als Hinweis darauf, ob die App Pixel außerhalb der Grenzen eines räumlichen Containers rendert. Wenn sich ein räumlicher Container im immersiven Modus befindet, hat dieser Hinweis keine Bedeutung, da die Grenzen unendlich sind.
Bei begrenzten räumlichen Containern mit Self-Rendering muss die Laufzeit sowohl die 3D-Volumengrenzen als auch die 2D-Pixelgrenzen berücksichtigen. Die 3D-Volumengrenzen werden von xrGetSpatialContainerBoundsEXT zurückgegeben. Die 2D-Pixelgrenzen sind die Projektion der 3D-Volumengrenzen auf jedes Display des Systems.
Laufzeiten müssen Pixel aus Swapchain-Bildern außerhalb der 2D-Pixelgrenzen verwerfen. Laufzeiten dürfen jedoch keine Pixel verwerfen, die sich innerhalb der 2D-Pixelgrenzen, aber außerhalb der 3D-Volumengrenzen befinden. Stereoeffekte, bei denen Inhalte über die 3D-Volumengrenzen des Containers hinaus oder davor zu ragen scheinen, sind möglich. Apps können Pixel außerhalb der 3D-Volumengrenzen eines begrenzten räumlichen Containers verwerfen, um Tiefenparadoxa zu reduzieren, und sollten volumeClipping entsprechend festlegen. Tiefenparadoxa führen oft zu einer Überanstrengung der Augen und Unbehagen bei Nutzern.
Laufzeiten können volumeClipping verwenden, um die Darstellung eines bestimmten räumlichen Containers anzupassen. Wenn beispielsweise XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT festgelegt ist, kann eine Laufzeit die Rückseiten der 3D-Volumengrenzen rendern, was zu Tiefenparadoxen führen würde, wenn der räumliche Container Pixel hinter den 3D-Volumengrenzen des Containers zeichnet.
Zukünftige Erweiterungen könnten das Clipping basierend auf den 3D-Volumengrenzen ermöglichen, wenn Tiefeninformationen übermittelt werden.
Gültige Verwendung (implizit)
- Die Erweiterung
XR_EXT_spatial_container_self_renderingmuss aktiviert sein, bevor XrSpatialContainerLayerVolumeClippingEXT verwendet werden kann. -
typemussXR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXTsein -
nextmussNULLoder ein gültiger Zeiger auf die nächste Struktur in einer Strukturkette sein. -
volumeClippingmuss ein gültiger XrSpatialContainerVolumeClippingEXT-Wert sein
Neue Befehle
- xrBeginSpatialContainerRenderingEXT
- xrEndSpatialContainerRenderingEXT
- xrLocateSpatialContainerViewsEXT
Neue Gebäude
- XrSpatialContainerBeginInfoEXT
- XrSpatialContainerEndInfoEXT
- XrSpatialContainerLayerEXT
- XrSpatialContainerViewLocateInfoEXT
- XrSpatialContainerViewStateEXT
- XrSpatialContainerViewsLocateInfoEXT
Erweiterung von XrCompositionLayerProjection :
Erweiterung von XrFrameEndInfo :
Erweiterung von XrSpatialContainerLayerEXT :
Neue Enum-Konstanten
XR_EXT_SPATIAL_CONTAINER_SELF_RENDERING_EXTENSION_NAMEXR_EXT_spatial_container_self_rendering_SPEC_VERSIONErweiterung von XrResult :
XR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXTXR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXTXR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXTXR_ERROR_SPATIAL_CONTAINER_MISSING_EXTXR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT
Erweiterung von XrSpatialContainerGraphicsPresentationEXT :
XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
Erweiterung von XrStructureType :
XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXTXR_TYPE_SPATIAL_CONTAINER_COMPOSITION_LAYER_VIEW_CONFIGURATION_EXTXR_TYPE_SPATIAL_CONTAINER_END_INFO_EXTXR_TYPE_SPATIAL_CONTAINER_LAYER_EXTXR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXTXR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXTXR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXTXR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXTXR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXT
Codebeispiele
// Example: Complete lifecycle, view location, and frame submission for spatial containers
PFN_xrBeginSpatialContainerRenderingEXT xrBeginSpatialContainerRenderingEXT; // previously initialized
PFN_xrEndSpatialContainerRenderingEXT xrEndSpatialContainerRenderingEXT; // previously initialized
PFN_xrLocateSpatialContainerViewsEXT xrLocateSpatialContainerViewsEXT; // previously initialized
XrSession session; // previously initialized
// We want to update this container
XrSpatialContainerEXT containerA; // previously initialized with XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
XrSpace containerASpace; // previously initialized
// We want to retain this container
XrSpatialContainerEXT containerB; // previously initialized with XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
XrSpace containerBSpace; // previously initialized
// 1. Add to active render set when the app is ready to start submitting layers
XrSpatialContainerBeginInfoEXT beginInfoA {
.type = XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT,
.spatialContainer = containerA,
.primaryViewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
};
CHK_XR(xrBeginSpatialContainerRenderingEXT(session, &beginInfoA));
XrSpatialContainerBeginInfoEXT beginInfoB {
.type = XR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT,
.spatialContainer = containerB,
.primaryViewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
};
CHK_XR(xrBeginSpatialContainerRenderingEXT(session, &beginInfoB));
// ... Frame Loop ...
XrTime displayTime; // returned from xrWaitFrame
const std::vector<XrSpatialContainerEXT> containers = {containerA, containerB};
const std::vector<XrSpace> containerSpaces = {containerASpace, containerBSpace};
uint32_t containerCount = static_cast<uint32_t>(containers.size());
// 2. Setup individual locate info for each container
std::vector<XrSpatialContainerViewLocateInfoEXT> containerLocateInfos(containerCount, {
.type = XR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXT,
});
for (uint32_t i = 0; i < containerCount; ++i) {
containerLocateInfos[i].viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
containerLocateInfos[i].space = containerSpaces[i]; // Recommended to use container's own space
containerLocateInfos[i].spatialContainer = containers[i];
}
// Setup bulk locate info
XrSpatialContainerViewsLocateInfoEXT locateInfo {
.type = XR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXT,
.displayTime = displayTime,
.viewLocateInfoCount = containerCount,
.viewLocateInfos = containerLocateInfos.data(),
};
// Prepare states to be populated by the runtime
std::vector<XrSpatialContainerViewStateEXT> viewStates(containerCount, {
.type = XR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXT,
});
// Call the dedicated locate views function
// We know the required view count is 2 per container for STEREO
const uint32_t viewsPerConfig = 2;
uint32_t totalViewCount = containerCount * viewsPerConfig;
std::vector<XrView> views(totalViewCount, {.type = XR_TYPE_VIEW});
CHK_XR(xrLocateSpatialContainerViewsEXT(session, &locateInfo, containerCount, viewStates.data(), totalViewCount, views.data()));
// Process results
for (uint32_t i = 0; i < containerCount; ++i) {
XrBool32 shouldSubmitLayers = viewStates[i].shouldSubmitLayers;
XrExtent2Di recommendedImageExtent = viewStates[i].recommendedImageExtent;
XrViewConfigurationType viewConfigurationType = viewStates[i].viewConfigurationType;
bool isDecayedToMono = (viewConfigurationType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO);
if (shouldSubmitLayers) {
// App is expected to also verify viewStates[i].viewStateFlags has valid orientation/position bits before rendering
XrView& leftView = views[i * viewsPerConfig];
XrView& rightView = views[i * viewsPerConfig + 1];
// If isDecayedToMono is true, left and right will be identical.
} else {
// Skip layer submission but retain previous submission when calling
// xrEndFrame.
}
}
// 3. Setup projection layer for container A
XrCompositionLayerProjection projectionLayer = {.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION};
// ... standard projection layer setup (space, viewCount, views, etc.) ...
// Specify which view configuration was used to render this specific layer
XrSpatialContainerCompositionLayerViewConfigurationEXT containerViewConfig {
.type = XR_TYPE_SPATIAL_CONTAINER_COMPOSITION_LAYER_VIEW_CONFIGURATION_EXT,
// Even if the runtime decayed to MONO, we indicate what we actually rendered
.viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
};
// Chain it to the projection layer
projectionLayer.next = &containerViewConfig;
const XrCompositionLayerBaseHeader* layersA[1] = {reinterpret_cast<const XrCompositionLayerBaseHeader*>(&projectionLayer)};
// Note: In a real app, you are required to submit ALL active containers in the render set.
XrSpatialContainerLayerVolumeClippingEXT containerClippingA = {
.type = XR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT,
// Set volumeClipping appropriately for the rendering done.
.volumeClipping = XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT,
};
// Setup container A (Update with new pixels)
XrSpatialContainerLayerEXT containerLayerA {
.type = XR_TYPE_SPATIAL_CONTAINER_LAYER_EXT,
.next = &containerClippingA,
.spatialContainer = containerA,
.retainPreviousSubmission = XR_FALSE,
.layerCount = 1,
.layers = layersA,
};
XrSpatialContainerLayerVolumeClippingEXT containerClippingB {
.type = XR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT,
// Set volumeClipping appropriately for the rendering done.
.volumeClipping = XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT,
};
// Setup container B (Explicitly retain previous frame)
XrSpatialContainerLayerEXT containerLayerB {
.type = XR_TYPE_SPATIAL_CONTAINER_LAYER_EXT,
.next = &containerClippingB,
.spatialContainer = containerB,
.retainPreviousSubmission = XR_TRUE,
.layerCount = 0, // Required to be 0 when retaining
.layers = nullptr,
};
// Aggregate all container layers
XrSpatialContainerLayerEXT containerLayers[] = { containerLayerA, containerLayerB };
XrSpatialContainerLayerFrameEndInfoEXT spatialEndInfo {
.type = XR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXT,
.containerLayerCount = 2, // Must equal the number of active containers
.containerLayers = containerLayers,
};
XrFrameEndInfo frameEndInfo {
.type = XR_TYPE_FRAME_END_INFO,
.next = &spatialEndInfo,
.displayTime = displayTime,
.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND,
.layerCount = 0, // MANDATORY: Must be 0 for self rendering extension
};
CHK_XR(xrEndFrame(session, &frameEndInfo));
// ... End Frame Loop ...
// 4. Remove from active render set when the container is destroyed or no longer needs rendering
XrSpatialContainerEndInfoEXT endInfoA {
.type = XR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT,
.spatialContainer = containerA,
};
CHK_XR(xrEndSpatialContainerRenderingEXT(session, &endInfoA));
XrSpatialContainerEndInfoEXT endInfoB {
.type = XR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT,
.spatialContainer = containerB,
};
CHK_XR(xrEndSpatialContainerRenderingEXT(session, &endInfoB));
Versionsverlauf
Version 1, 06.08.2026 (Lachlan Ford)
- Anfängliche Beschreibung der Erweiterung