XR_EXT_spatial_container_self_rendering
Name String
XR_EXT_spatial_container_self_rendering
Typ rozszerzenia
Rozszerzenie instancji
Zarejestrowany numer wewnętrzny
814
Wersja
1
Stan ratyfikacji
Nie ratyfikowano
Zależności rozszerzeń i wersji
XR_EXT_spatial_container
Data ostatniej modyfikacji
2026-08-06
Stan IP
Brak znanych roszczeń dotyczących własności intelektualnej.
Twórcy
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
Przegląd
To rozszerzenie definiuje „samodzielne renderowanie” w przypadku kontenerów przestrzennych. Piksele samodzielnie renderowanego kontenera przestrzennego są generowane przez aplikację i przesyłane do środowiska wykonawczego za pomocą standardowych łańcuchów wymiany i warstw kompozycji OpenXR. Kontenery przestrzenne nie zawsze zajmują wszystkie piksele ekranu, dlatego środowisko wykonawcze informuje aplikacje o zalecanej rozdzielczości i konfiguracji widoku każdego kontenera przestrzennego, aby umożliwić im wydajniejsze renderowanie.
To rozszerzenie w połączeniu z XR_EXT_spatial_container ma oferować superset możliwości konwencjonalnego renderowania warstwy kompozycji OpenXR 1.x. Środowiska wykonawcze OpenXR 1.x, które obsługują renderowanie graficzne i to rozszerzenie, muszą ustawić właściwość XrSystemSpatialContainerPropertiesEXT :: supportsImmersive na wartość „true”, aby wskazać, że obsługują immersyjne kontenery przestrzenne.
Cykl życia renderowania kontenera przestrzennego
Aby używać samodzielnego renderowania w przypadku kontenera przestrzennego, aplikacja ustawia XrSpatialContainerCreateInfoEXT :: graphicsPresentation na XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT podczas wywoływania xrCreateSpatialContainerEXT . Następnie aplikacja może zarządzać tym, czy kontener przestrzenny jest aktywnie renderowany, wywołując funkcje xrBeginSpatialContainerRenderingEXT i xrEndSpatialContainerRenderingEXT. Te funkcje zastępują xrBeginSession i xrEndSession . Nie są to operacje wykonywane na klatkę, takie jak xrBeginFrame i xrEndFrame .
W każdej klatce aplikacja wykonuje te czynności:
- Wywołaj xrWaitFrame i xrBeginFrame . Te funkcje nie mają struktur specyficznych dla kontenera i działają tak samo jak w podstawowej specyfikacji.
- Pobieraj pozycje widoku, parametry projekcji i rekomendacje dotyczące renderowania dla wszystkich kontenerów przestrzennych aktywnie renderowanych za pomocą xrLocateSpatialContainerViewsEXT . W przypadku każdego kontenera przestrzennego środowisko wykonawcze zgłasza, czy jego warstwy kompozycji powinny być renderowane, oraz zalecany sposób renderowania warstw, wypełniając XrSpatialContainerViewStateEXT .
- Renderuj piksele w warstwach kompozycji w normalny sposób. Te operacje nie mają struktur specyficznych dla kontenera.
- Prześlij warstwy kompozycji dla wszystkich kontenerów przestrzennych, które są aktywnie renderowane, wywołując funkcję xrEndFrame i tworząc łańcuch XrSpatialContainerLayerFrameEndInfoEXT .
Zniszczenie uchwytu XrSpatialContainerEXT powoduje jego niejawne usunięcie z aktywnego zestawu renderowania. Aplikacja może zniszczyć kontener przestrzenny, nawet jeśli pomyślnie wywołała funkcję xrBeginSpatialContainerRenderingEXT, która nie jest powiązana z odpowiednim wywołaniem funkcji xrEndSpatialContainerRenderingEXT . Środowisko wykonawcze musi zachowywać się tak, jakby funkcja xrEndSpatialContainerRenderingEXT była wywoływana niejawnie, jeśli jest to konieczne na wczesnym etapie implementacji funkcji xrDestroySpatialContainerEXT, jeśli zwraca ona wartość powodzenia.
Gdy aplikacja otrzyma zdarzenie XrEventDataSpatialContainerClosedEXT dla kontenera w aktywnym zbiorze renderowania, powinna wywołać xrEndSpatialContainerRenderingEXT i zniszczyć uchwyt XrSpatialContainerEXT.
Funkcja xrBeginSpatialContainerRenderingEXT dodaje kontener przestrzenny do aktywnego zestawu renderowania na sesję, co umożliwia aplikacji przesyłanie warstw kompozycji kontenera przestrzennego do xrEndFrame .
XrResult xrBeginSpatialContainerRenderingEXT(
XrSession session,
const XrSpatialContainerBeginInfoEXT* beginInfo);
Opisy parametrów
sessionto XrSession .beginInfoto wskaźnik do struktury XrSpatialContainerBeginInfoEXT.
Aplikacje zwykle wywołują tę funkcję w odpowiedzi na zdarzenie visible-changed z XrEventDataSpatialContainerVisibleChangedEXT :: visible ustawionym na wartość „true”.
Jeśli kontener przestrzenny nie został utworzony za pomocą XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT podczas wywoływania xrCreateSpatialContainerEXT , środowisko wykonawcze musi zwrócić XR_ERROR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_MISSING_EXT .
Jeśli kontener przestrzenny znajduje się już w aktywnym zbiorze renderowania, środowisko wykonawcze musi zwrócić XR_ERROR_SPATIAL_CONTAINER_IS_RENDERING_EXT .
Jeśli funkcja xrBeginSpatialContainerRenderingEXT zostanie wywołana w momencie, gdy aplikacja nie może wywołać funkcji xrWaitFrame (czyli w oknie xrBeginFrame i xrEndFrame), środowisko wykonawcze musi zwrócić XR_ERROR_CALL_ORDER_INVALID.
Prawidłowe użycie (pośrednie)
- Rozszerzenie
XR_EXT_spatial_container_self_renderingmusi być włączone przed wywołaniem xrBeginSpatialContainerRenderingEXT. -
sessionmusi być prawidłowym uchwytem XrSession -
beginInfomusi być wskaźnikiem do prawidłowej struktury XrSpatialContainerBeginInfoEXT
Bezpieczeństwo wątków
- Dostęp do parametru
sessionprzez inne wywołanie xrBeginSpatialContainerRenderingEXT, xrEndSpatialContainerRenderingEXT lub xrEndFrame musi być synchronizowany zewnętrznie.
Kody zwrotu
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
Struktura XrSpatialContainerBeginInfoEXT służy do określania parametrów rozpoczęcia renderowania kontenera przestrzennego.
typedef struct XrSpatialContainerBeginInfoEXT {
XrStructureType type;
const void* next;
XrSpatialContainerEXT spatialContainer;
XrViewConfigurationType primaryViewConfigurationType;
} XrSpatialContainerBeginInfoEXT;
Opis członka
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.spatialContainerto XrSpatialContainerEXT, który ma rozpocząć renderowanie.primaryViewConfigurationTypeto główny typ XrViewConfigurationType, który ma być używany w kontenerze przestrzennym.
primaryViewConfigurationType to konfiguracja widoku, której aplikacja zamierza używać podczas renderowania. Środowisko wykonawcze może zmienić konfigurację widoku na typ z mniejszą liczbą widoków w celu optymalizacji (np. kontener jest bardzo daleko i jest mały, więc stereo jest niezauważalne). Środowisko wykonawcze zwraca szczegółowe informacje o konfiguracji widoku z zanikiem z wywołań xrLocateSpatialContainerViewsEXT .
Prawidłowe użycie (pośrednie)
- Rozszerzenie
XR_EXT_spatial_container_self_renderingmusi być włączone przed użyciem XrSpatialContainerBeginInfoEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CONTAINER_BEGIN_INFO_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur -
spatialContainermusi być prawidłowym uchwytem XrSpatialContainerEXT -
primaryViewConfigurationTypemusi być prawidłową wartością XrViewConfigurationType
Funkcja xrEndSpatialContainerRenderingEXT usuwa kontener przestrzenny z aktywnego zestawu renderowania.
XrResult xrEndSpatialContainerRenderingEXT(
XrSession session,
const XrSpatialContainerEndInfoEXT* endInfo);
Opisy parametrów
sessionto XrSession .endInfoto wskaźnik do struktury XrSpatialContainerEndInfoEXT.
Aplikacje zwykle wywołują tę funkcję w odpowiedzi na zdarzenie visible-changed, gdy parametr XrEventDataSpatialContainerVisibleChangedEXT :: visible ma wartość false.
Jeśli kontener przestrzenny nie znajduje się w aktywnym zbiorze renderowania, środowisko wykonawcze musi zwrócić wartość XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .
Jeśli funkcja xrEndSpatialContainerRenderingEXT zostanie wywołana w momencie, gdy aplikacja nie może wywołać funkcji xrWaitFrame (czyli w okresie między wywołaniami funkcji xrBeginFrame i xrEndFrame), środowisko wykonawcze musi zwrócić XR_ERROR_CALL_ORDER_INVALID.
Prawidłowe użycie (pośrednie)
- Rozszerzenie
XR_EXT_spatial_container_self_renderingmusi być włączone przed wywołaniem xrEndSpatialContainerRenderingEXT. -
sessionmusi być prawidłowym uchwytem XrSession -
endInfomusi być wskaźnikiem do prawidłowej struktury XrSpatialContainerEndInfoEXT
Bezpieczeństwo wątków
- Dostęp do parametru
sessionprzez inne wywołanie xrBeginSpatialContainerRenderingEXT, xrEndSpatialContainerRenderingEXT lub xrEndFrame musi być synchronizowany zewnętrznie.
Kody zwrotu
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
Struktura XrSpatialContainerEndInfoEXT służy do określania parametrów zakończenia renderowania kontenera przestrzennego.
typedef struct XrSpatialContainerEndInfoEXT {
XrStructureType type;
const void* next;
XrSpatialContainerEXT spatialContainer;
} XrSpatialContainerEndInfoEXT;
Opis członka
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.spatialContainerto XrSpatialContainerEXT, który ma zakończyć renderowanie.
Prawidłowe użycie (pośrednie)
- Rozszerzenie
XR_EXT_spatial_container_self_renderingmusi być włączone przed użyciem XrSpatialContainerEndInfoEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CONTAINER_END_INFO_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur -
spatialContainermusi być prawidłowym uchwytem XrSpatialContainerEXT
Lokalizowanie widoków za pomocą xrLocateSpatialContainerViewsEXT
Funkcja xrLocateSpatialContainerViewsEXT lokalizuje widoki dla zestawu kontenerów przestrzennych.
XrResult xrLocateSpatialContainerViewsEXT(
XrSession session,
const XrSpatialContainerViewsLocateInfoEXT* locateInfo,
uint32_t viewStateCount,
XrSpatialContainerViewStateEXT* viewStates,
uint32_t viewCount,
XrView* views);
Opisy parametrów
sessionto XrSession .locateInfoto wskaźnik do struktury XrSpatialContainerViewsLocateInfoEXT.viewStateCountto liczba elementów w tablicyviewStates.viewStatesto wskaźnik do tablicy struktur XrSpatialContainerViewStateEXT, które mają zostać wypełnione przez środowisko wykonawcze.viewCountto liczba elementów w tablicyviews.viewsto wskaźnik do tablicy struktur XrView.
Ta funkcja zastępuje xrLocateViews , umożliwiając aplikacji wysyłanie zapytań o widoki dla wielu kontenerów przestrzennych jednocześnie.
Widoki wszystkich kontenerów przestrzennych są zwracane w jednej tablicy views. Widoki są uporządkowane według indeksu kontenera przestrzennego w tablicy XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos, a następnie według indeksu widoku dla tego kontenera.
Jeśli na przykład aplikacja udostępnia 3 kontenery przestrzenne w XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfos :
- Indeks 0:
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO(1 widok) - Indeks 1:
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO(2 widoki) - Indeks 2:
XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO_WITH_FOVEATED_INSET(4 widoki)
Następnie środowisko wykonawcze musi wypełnić tablicę views 7 widokami:
views[0] to widok kontenera 0.views[1] to widok dla lewego oka w kontenerze 1.views[2] to widok z prawego oka dla kontenera 1.views[3] to widok dla lewego oka w kontenerze 2.views[4] to widok z prawej strony dla kontenera 2.views[5] to widok wstawki lewego oka dla kontenera 2.views[6] to widok wstawki prawego oka dla kontenera 2.
Jeśli wartość viewCount nie jest równa sumie liczby wyświetleń dla każdego typu konfiguracji widoku żądanego przez kontener przestrzenny, środowisko wykonawcze musi zwrócić wartość XR_ERROR_VALIDATION_FAILURE .
Środowisko wykonawcze może w celach optymalizacyjnych zmienić konfigurację widoku na typ z mniejszą liczbą widoków (np. kontener jest bardzo daleko i jest mały, więc stereo jest niezauważalne). Jeśli środowisko wykonawcze zmniejszy konfigurację widoku, musi nadal zwracać pierwotną liczbę widoków dla tego kontenera, wypełniając dodatkowe widoki duplikatami zmniejszonych widoków. Jeśli na przykład XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO zostanie przekształcony w XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO, zarówno indeks 0, jak i indeks 1 będą zawierać pojedynczy widok mono. W związku z tym łączna liczba wyświetleń zwrócona w tablicy views jest niezależna od tego, czy środowisko wykonawcze zdecydowało się na wygaszenie konfiguracji widoku.
Środowisko wykonawcze powinno dostosować każdy zwrócony obiekt XrView :: fov tak, aby ostrosłup ścięty był jak najmniejszy, ale nadal zawierał całe granice odpowiedniego kontenera przestrzennego. Środowiska wykonawcze mogą zwracać niesymetryczne pola widzenia, na przykład jeśli kontener przestrzenny jest ustawiony pod kątem do widoku użytkownika lub jest częściowo zasłonięty przez inny obiekt. Środowiska wykonawcze mogą dowolnie pozycjonować docelową powierzchnię renderowania kontenera przestrzennego. Ze względu na charakter renderowania wielu aplikacji, w którym kontenery przestrzenne są odłączone od użytkownika, środowisko wykonawcze może zwracać wartości XrView, które nie nadają się do renderowania pikseli. Jeśli na przykład kontener przestrzenny nie jest widoczny na ekranie, nie ma prawidłowych wartości, które można ustawić dla XrView :: fov. W takich przypadkach środowiska wykonawcze muszą ustawić XrSpatialContainerViewStateEXT :: shouldSubmitLayers na wartość „false”.
Środowisko wykonawcze zwraca dodatkowe informacje o stanie renderowania poszczególnych kontenerów przestrzennych w tablicy viewStates. Jeśli viewStateCount nie jest równe XrSpatialContainerViewsLocateInfoEXT :: viewLocateInfoCount , środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE .
Gdy środowisko wykonawcze doda do kolejki zdarzenie XrEventDataSpatialContainerClosedEXT dla kontenera przestrzennego, ta funkcja musi zwracać XR_FALSE w XrSpatialContainerViewStateEXT :: shouldSubmitLayers i 0 w XrSpatialContainerViewStateEXT :: viewStateFlags dla odpowiedniego kontenera przestrzennego.
W przypadku kontenerów przestrzennych, których lokalizacja w świecie rzeczywistym aktywnie się zmienia, środowisko wykonawcze powinno uwzględniać ruch kontenera podczas wypełniania pola views, aby zminimalizować artefakty reprojekcji.
Jeśli funkcja xrLocateSpatialContainerViewsEXT zostanie wywołana w przypadku co najmniej 1 kontenera przestrzennego, który nie znajduje się obecnie w aktywnym zbiorze renderowania, środowisko wykonawcze musi zwrócić XR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT .
Prawidłowe użycie (pośrednie)
- Rozszerzenie
XR_EXT_spatial_container_self_renderingmusi być włączone przed wywołaniem xrLocateSpatialContainerViewsEXT. -
sessionmusi być prawidłowym uchwytem XrSession -
locateInfomusi być wskaźnikiem do prawidłowej struktury XrSpatialContainerViewsLocateInfoEXT -
viewStatesmusi być wskaźnikiem do tablicy strukturviewStateCountXrSpatialContainerViewStateEXT -
viewsmusi być wskaźnikiem do tablicy strukturviewCountXrView - Parametr
viewStateCountmusi być większy niż0 - Parametr
viewCountmusi być większy niż0
Kody zwrotu
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
Struktura XrSpatialContainerViewsLocateInfoEXT zawiera parametry do lokalizowania widoków w kolekcji kontenerów przestrzennych.
typedef struct XrSpatialContainerViewsLocateInfoEXT {
XrStructureType type;
const void* next;
XrTime displayTime;
uint32_t viewLocateInfoCount;
const XrSpatialContainerViewLocateInfoEXT* viewLocateInfos;
} XrSpatialContainerViewsLocateInfoEXT;
Opis członka
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.displayTimetoXrTime, w którym znajdują się widoki.viewLocateInfoCountto liczba wpisów w tablicyviewLocateInfos.viewLocateInfosto wskaźnik do tablicy struktur XrSpatialContainerViewLocateInfoEXT.
Prawidłowe użycie (pośrednie)
- Rozszerzenie
XR_EXT_spatial_container_self_renderingmusi być włączone przed użyciem XrSpatialContainerViewsLocateInfoEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CONTAINER_VIEWS_LOCATE_INFO_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur -
viewLocateInfosmusi być wskaźnikiem do tablicy prawidłowych strukturviewLocateInfoCountXrSpatialContainerViewLocateInfoEXT - Parametr
viewLocateInfoCountmusi być większy niż0
Struktura XrSpatialContainerViewLocateInfoEXT zawiera parametry pojedynczego kontenera przestrzennego, dla którego mają zostać zlokalizowane widoki.
typedef struct XrSpatialContainerViewLocateInfoEXT {
XrStructureType type;
const void* next;
XrViewConfigurationType viewConfigurationType;
XrSpace space;
XrSpatialContainerEXT spatialContainer;
} XrSpatialContainerViewLocateInfoEXT;
Opis członka
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.viewConfigurationTypeto XrViewConfigurationType, który ma być używany w przypadku kontenera przestrzennego.spaceto XrSpace, w której znajdują się widoki kontenera przestrzennego.spatialContainerto uchwyt XrSpatialContainerEXT.
Aplikacja może udostępniać dowolną prawidłową przestrzeń XrSpace w space, ale zalecamy, aby udostępniała przestrzeń kontenera przestrzennego dla odpowiedniego elementu XrSpatialContainerEXT określonego w strukturze XrSpatialContainerViewLocateInfoEXT.
Prawidłowe użycie (pośrednie)
- Rozszerzenie
XR_EXT_spatial_container_self_renderingmusi być włączone przed użyciem XrSpatialContainerViewLocateInfoEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CONTAINER_VIEW_LOCATE_INFO_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur -
viewConfigurationTypemusi być prawidłową wartością XrViewConfigurationType -
spacemusi być prawidłowym nickiem XrSpace -
spatialContainermusi być prawidłowym uchwytem XrSpatialContainerEXT - Obie wartości
spaceispatialContainermuszą zostać utworzone, przydzielone lub pobrane z tej samej sesji XrSession.
Struktura XrSpatialContainerViewStateEXT jest wypełniana przez wywołania funkcji xrLocateSpatialContainerViewsEXT z informacjami o przydatności renderowania poszczególnych kontenerów przestrzennych.
typedef struct XrSpatialContainerViewStateEXT {
XrStructureType type;
void* next;
XrViewStateFlags viewStateFlags;
XrViewConfigurationType viewConfigurationType;
XrBool32 shouldSubmitLayers;
XrExtent2Di recommendedImageExtent;
} XrSpatialContainerViewStateEXT;
Opis członka
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.viewStateFlagsto maska bitowa XrViewStateFlags . Te flagi mają ten sam cel co viewStateFlags w podstawowej strukturze XrViewState.viewConfigurationTypeto XrViewConfigurationType, który wskazuje typ konfiguracji widoku używany przez środowisko wykonawcze dla kontenera przestrzennego. Środowiska wykonawcze mogą obniżyć konfigurację widoku do konfiguracji z mniejszą liczbą widoków niż żądana.shouldSubmitLayerstoXrBool32zwracany przez środowisko wykonawcze. JeśliXR_FALSE, aplikacja powinna unikać przesyłania kompozycji dla tego kontenera przestrzennego, ponieważ nie jest on obecnie widoczny lub jest w stanie, w którym renderowanie nie jest wymagane.recommendedImageExtentto struktura XrExtent2Di reprezentująca zalecaną rozdzielczość kontenera przestrzennego.
Podobnie jak w przypadku podstawowej lokalizacji widoku OpenXR, aplikacja musi sprawdzić XrSpatialContainerViewStateEXT :: viewStateFlags, aby upewnić się, że pozycja i orientacja są prawidłowe i śledzone, zanim użyje danych widoku do renderowania.
Aplikacja powinna sprawdzać shouldSubmitLayers i viewConfigurationType, aby nie renderować więcej, niż zaleca środowisko wykonawcze. Gdy wartość shouldSubmitLayers jest fałszywa, aplikacja zmienia sposób renderowania w następujący sposób:
- Aplikacja nie może odczytywać odpowiedniego elementu XrView ::
fov. - Aplikacja nie może odczytywać danych
recommendedImageExtent. - Aplikacja powinna unikać renderowania do łańcuchów wymiany i przesyłania warstw kompozycji dla odpowiedniego kontenera przestrzennego.
- Aplikacja powinna ustawić XrSpatialContainerLayerEXT ::
retainPreviousSubmissionna wartość „true”. Jeśli aplikacja zdecyduje się mimo to przesłać warstwy, środowisko wykonawcze określi, co chce z nimi zrobić (np. może je odrzucić).
recommendedImageExtent jest przeznaczony wyłącznie dla warstw, które będą aktualizowane na podstawie pozycji kontenera lub widoku użytkownika. Podczas aktualizowania warstw treściami, które zależą od pozycji kontenera przestrzennego lub widoku użytkownika (np. zwykłe treści 3D), aplikacja powinna renderować je w tym mniejszym obszarze widocznym zamiast w domyślnym zalecanym rozmiarze widoku. Podczas aktualizowania warstw z treścią, która nie zależy od pozycji kontenera przestrzennego ani widoku użytkownika (np. statyczne warstwy quad), aplikacja może bezpiecznie ignorować te wartości. W przypadku warstw zależnych od widoku recommendedImageExtent to zalecenie dla aplikacji ze środowiska wykonawczego, które ma na celu zminimalizowanie aliasingu i poprawę wydajności renderowania. Aplikacja może przesłać obraz w pełnej rozdzielczości, jeśli jest taka potrzeba.
Wartości XrExtent2Di :: width i XrExtent2Di :: height elementu recommendedImageExtent muszą zawsze być dodatnią liczbą całkowitą mniejszą lub równą wartościom XrViewConfigurationView :: recommendedImageRectWidth i XrViewConfigurationView :: recommendedImageRectHeight elementu XrViewConfigurationView dla konfiguracji widoku głównego kontenera przestrzennego. Aplikacja nie powinna odtwarzać łańcucha wymiany tylko dlatego, że zmieniła się wartość recommendedImageExtent, ponieważ jest to dynamiczna wskazówka dla aplikacji określająca wartość XrSwapchainSubImage :: imageRect do użycia w XrSwapchainSubImage dowolnych przesyłanych warstw kompozycji o pełnej rozdzielczości i może zmieniać się w każdej klatce.
Prawidłowe użycie (pośrednie)
- Rozszerzenie
XR_EXT_spatial_container_self_renderingmusi być włączone przed użyciem XrSpatialContainerViewStateEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CONTAINER_VIEW_STATE_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur -
viewStateFlagsmusi być prawidłową kombinacją wartości XrViewStateFlagBits -
viewStateFlagsnie może być0 -
viewConfigurationTypemusi być prawidłową wartością XrViewConfigurationType
Wyświetl pokój referencyjny
Przestrzeń odniesienia widoku pozostaje niezmieniona, ponieważ znajduje się w OpenXR Core. Podobnie jak w przypadku rdzenia, nie jest on przeznaczony do renderowania.
Przesyłanie warstw za pomocą xrEndFrame
Aby renderować kontenery przestrzenne, aplikacja musi dostarczyć do xrEndFrame listę warstw powiązanych z odpowiednimi kontenerami przestrzennymi. Służy do tego struktura XrSpatialContainerLayerFrameEndInfoEXT.
typedef struct XrSpatialContainerLayerFrameEndInfoEXT {
XrStructureType type;
const void* next;
uint32_t containerLayerCount;
const XrSpatialContainerLayerEXT* containerLayers;
} XrSpatialContainerLayerFrameEndInfoEXT;
Opis członka
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.containerLayerCountto liczba elementów w tablicycontainerLayers.containerLayersto wskaźnik do tablicy struktur XrSpatialContainerLayerEXT.
Tablica containerLayers zawiera element XrSpatialContainerLayerEXT dla każdego kontenera przestrzennego w aktywnym zestawie renderowania (kontenery zarządzane na sesję przez xrBeginSpatialContainerRenderingEXT i xrEndSpatialContainerRenderingEXT). Każdy element XrSpatialContainerLayerEXT zawiera listę wskaźników XrCompositionLayerBaseHeader powiązanych z danym kontenerem przestrzennym. Środowiska wykonawcze mogą tworzyć kontenery w dowolnej kolejności, niezależnie od kolejności containerLayers . Na przykład środowiska wykonawcze mogą tworzyć kontenery na podstawie ich głębokości względem użytkownika, używać kontenera przestrzennego jako warstwy tła lub „przypinać” kontener przestrzenny, tak aby zawsze znajdował się na górze, niezależnie od głębokości. Środowiska wykonawcze mogą tworzyć warstwy kompozytowe przy użyciu różnych strategii dla kontenerów przestrzennych w trybach ograniczonym lub trybie imersji. Na przykład środowiska wykonawcze mogą wstępnie składać warstwy kompozycji każdego ograniczonego kontenera przestrzennego w jedną warstwę stereo quad, która jest łączona ze wszystkimi innymi kontenerami w drugim kroku kompozycji.
XrFrameEndInfo :: displayTime i XrFrameEndInfo :: environmentBlendMode zostaną zastosowane do wszystkich kontenerów przestrzennych dostarczonych w XrSpatialContainerLayerFrameEndInfoEXT .
Gdy ta struktura jest przekazywana do xrEndFrame przez połączenie z XrFrameEndInfo , dodawane są te dodatkowe przypadki błędów na podstawie aktywnego zestawu renderowania:
- Jeśli do kontenera przestrzennego odwołuje się więcej niż 1 element
containerLayers, środowiska wykonawcze muszą zwracaćXR_ERROR_SPATIAL_CONTAINER_DUPLICATE_EXT. - Jeśli element
containerLayersnie odwołuje się do kontenera przestrzennego w aktywnym zestawie renderowania, środowiska wykonawcze muszą zwracaćXR_ERROR_SPATIAL_CONTAINER_MISSING_EXT. - Jeśli kontener przestrzenny, do którego odwołuje się
containerLayers, nie należy do aktywnego zestawu renderowania, środowiska wykonawcze muszą zwracaćXR_ERROR_SPATIAL_CONTAINER_NOT_RENDERING_EXT.
Ponadto, jeśli w aktywnym zestawie renderowania znajdują się kontenery przestrzenne, a ta struktura nie jest połączona z XrFrameEndInfo, środowiska wykonawcze muszą zwracać XR_ERROR_SPATIAL_CONTAINER_MISSING_EXT .
W przypadku wystąpienia dowolnego z powyższych błędów środowisko wykonawcze nie może renderować żadnych treści w żadnym kontenerze przestrzennym.
Jeśli w aktywnym zbiorze renderowania nie ma kontenerów przestrzennych, aplikacja może wywołać xrEndFrame, o ile nie przesyła żadnych warstw kompozycji.
Pamiętaj, że poszczególne łańcuchy wymiany mogą być przesyłane do wielu kontenerów za pomocą warstw w prawidłowej strukturze, np. warstwa quad renderowana za pomocą pojedynczego łańcucha wymiany przesłanego do wielu kontenerów przestrzennych. Ten przypadek jest obsługiwany tak samo jak inne renderowanie: środowisko wykonawcze musi renderować czworokąt we wszystkich takich kontenerach przestrzennych.
Prawidłowe użycie (pośrednie)
- Rozszerzenie
XR_EXT_spatial_container_self_renderingmusi być włączone przed użyciem XrSpatialContainerLayerFrameEndInfoEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CONTAINER_LAYER_FRAME_END_INFO_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur -
containerLayersmusi być wskaźnikiem do tablicy prawidłowych strukturcontainerLayerCountXrSpatialContainerLayerEXT. - Parametr
containerLayerCountmusi być większy niż0
Struktura XrSpatialContainerLayerEXT grupuje standardowe warstwy kompozycji i powiązuje je z określonym kontenerem przestrzennym.
typedef struct XrSpatialContainerLayerEXT {
XrStructureType type;
const void* next;
XrSpatialContainerEXT spatialContainer;
XrBool32 retainPreviousSubmission;
uint32_t layerCount;
const XrCompositionLayerBaseHeader* const* layers;
} XrSpatialContainerLayerEXT;
Opis członka
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.spatialContainerto XrSpatialContainerEXT identyfikujący kontener docelowy.retainPreviousSubmissiontoXrBool32. JeśliXR_TRUE, środowisko wykonawcze zachowa ostatnią przesłaną klatkę dla tego kontenera przestrzennego.layerCountto liczba warstw kompozycji w tablicylayers.layersto wskaźnik do tablicy wskaźników XrCompositionLayerBaseHeader.
Gdy retainPreviousSubmission ma wartość XR_TRUE, środowisko wykonawcze musi ponownie użyć warstw kompozycji i zawartości obrazu łańcucha wymiany, które zostały zablokowane podczas ostatniego wywołania xrEndFrame, gdy retainPreviousSubmission miało wartość XR_FALSE . Wszelkie późniejsze modyfikacje łańcuchów wymiany używanych przez zachowane warstwy nie mogą być odzwierciedlane w wyrenderowanych danych wyjściowych.
W przypadku warstw przesłanych do pojedynczego kontenera przestrzennego (renderowanie wewnątrz kontenera) środowisko wykonawcze musi przestrzegać określonych już reguł dotyczących kolejności kompozycji warstw. Oznacza to, że warstwy w kontenerach muszą być rysowane w takiej samej kolejności, w jakiej są określone, i tworzone za pomocą algorytmu malarskiego.
„Czyszczenie” kontenera przestrzennego odnosi się do usunięcia całej zawartości z kontenera przestrzennego, co powoduje, że w bieżącej klatce nie jest renderowana żadna zawartość tego kontenera. Środowiska wykonawcze muszą traktować to tak, jakby aplikacja przesyłała przezroczystą czerń (wszystkie bity 0) dla każdego piksela w kontenerze. „Zachowanie” kontenera przestrzennego oznacza, że środowisko wykonawcze nadal wyświetla ostatnio przesłany zestaw warstw dla tego kontenera.
W przypadku każdego kontenera przestrzennego aplikacja może określić, czy przesłać nowe warstwy, zachować poprzednie przesłanie czy wyczyścić kontener przestrzenny:
- Aby przesłać nowe warstwy, aplikacja podaje niezerową wartość
layerCounti prawidłowy wskaźniklayers. - Aby wyczyścić kontener przestrzenny, wartość
layerCountdla jego wpisu musi wynosić 0, a wartośćretainPreviousSubmissionmusi wynosićXR_FALSE. - Aby zachować ostatnie przesłane warstwy i obrazy łańcucha wymiany (zachowywanie), wartość
layerCountdla wpisu musi wynosić 0, aretainPreviousSubmissionmusi wynosićXR_TRUE.
To jawne ustawienie dla każdego kontenera zapewnia, że intencja aplikacji jest wyraźnie komunikowana w każdej klatce.
Jeśli retainPreviousSubmission to XR_TRUE, a layerCount nie jest równe 0, środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE .
Jeśli element XrSpatialContainerCompositionLayerViewConfigurationEXT nie jest połączony z elementem XrCompositionLayerProjection, który jest częścią kontenera przestrzennego, środowisko wykonawcze musi zwrócić błąd XR_ERROR_VALIDATION_FAILURE . Ta struktura dotyczy tylko warstw XrCompositionLayerProjection. Jeśli jest połączona z innymi typami warstw (np. warstwami czworokątnymi lub cylindrycznymi), środowisko wykonawcze musi zwrócić XR_ERROR_VALIDATION_FAILURE.
Prawidłowe użycie (pośrednie)
- Rozszerzenie
XR_EXT_spatial_container_self_renderingmusi być włączone przed użyciem XrSpatialContainerLayerEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CONTAINER_LAYER_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur . Zobacz też: XrSpatialContainerLayerVolumeClippingEXT -
spatialContainermusi być prawidłowym uchwytem XrSpatialContainerEXT - Jeśli
layerCountnie jest równe0,layersmusi być wskaźnikiem do tablicy prawidłowych strukturlayerCountopartych na XrCompositionLayerBaseHeader. Zobacz też: XrCompositionLayerCubeKHR , XrCompositionLayerCylinderKHR , XrCompositionLayerEquirect2KHR , XrCompositionLayerEquirectKHR , XrCompositionLayerPassthroughANDROID , XrCompositionLayerPassthroughFB , XrCompositionLayerPassthroughHTC , XrCompositionLayerProjection , XrCompositionLayerQuad
Określanie konfiguracji widoku dla warstw projekcji
Struktura XrSpatialContainerCompositionLayerViewConfigurationEXT służy do określania konfiguracji widoku używanej do renderowania warstwy projekcji kontenera przestrzennego.
typedef struct XrSpatialContainerCompositionLayerViewConfigurationEXT {
XrStructureType type;
const void* next;
XrViewConfigurationType viewConfigurationType;
} XrSpatialContainerCompositionLayerViewConfigurationEXT;
Opis członka
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.viewConfigurationTypeto XrViewConfigurationType, który został użyty do renderowania XrCompositionLayerProjection .
Podczas przesyłania XrCompositionLayerProjection dla kontenera przestrzennego aplikacja musi określić, która konfiguracja widoku została użyta do renderowania warstwy. Jest to konieczne, ponieważ aplikacja może wybrać dla każdej klatki, czy ma renderować z główną konfiguracją widoku kontenera przestrzennego, czy z sugerowaną przez środowisko wykonawcze konfiguracją widoku z zanikiem (jeśli jest dostępna).
Gdy XrSpatialContainerCompositionLayerViewConfigurationEXT jest połączony, aplikacja musi upewnić się, że XrCompositionLayerProjection :: viewCount jest prawidłową liczbą wyświetleń dla XrViewConfigurationType określonego w połączonej strukturze. viewConfigurationType określony w strukturze łańcuchowej musi być XrSpatialContainerBeginInfoEXT :: primaryViewConfigurationType określonym podczas uruchamiania kontenera lub typem konfiguracji widoku zdegradowanego zwróconym przez środowisko wykonawcze w XrSpatialContainerViewStateEXT albo dodatkowymi wartościami włączonymi przez rozszerzenie.
Prawidłowe użycie (pośrednie)
- Rozszerzenie
XR_EXT_spatial_container_self_renderingmusi być włączone przed użyciem XrSpatialContainerCompositionLayerViewConfigurationEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CONTAINER_COMPOSITION_LAYER_VIEW_CONFIGURATION_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur -
viewConfigurationTypemusi być prawidłową wartością XrViewConfigurationType
Zachowanie przycinania pikseli
Aplikacje powinny informować środowisko wykonawcze, czy renderują piksele poza granicami kontenera przestrzennego, przez połączenie XrSpatialContainerLayerVolumeClippingEXT podczas przesyłania warstw kompozycji.
typedef struct XrSpatialContainerLayerVolumeClippingEXT {
XrStructureType type;
const void* next;
XrSpatialContainerVolumeClippingEXT volumeClipping;
} XrSpatialContainerLayerVolumeClippingEXT;
Opis członka
typeto XrStructureType tej struktury.nexttoNULLlub wskaźnik do następnej struktury w łańcuchu struktur.volumeClippingto XrSpatialContainerVolumeClippingEXT zastosowany przez aplikację.
Ta struktura służy jako wskazówka, czy aplikacja renderuje piksele poza granicami kontenera przestrzennego. Gdy kontener przestrzenny jest w trybie imersji, ta wskazówka nie ma znaczenia, ponieważ granice są nieskończone.
W przypadku ograniczonych kontenerów przestrzennych, które korzystają z samodzielnego renderowania, środowisko wykonawcze musi uwzględniać zarówno granice objętości 3D, jak i granice pikseli 2D. Granice objętości 3D są zwracane przez xrGetSpatialContainerBoundsEXT . Granice pikseli 2D to rzutowanie granic objętości 3D na każdy wyświetlacz systemu.
Środowiska wykonawcze muszą odrzucać piksele z obrazów łańcucha wymiany poza granicami pikseli 2D, ale nie mogą odrzucać pikseli, które znajdują się wewnątrz granic pikseli 2D, ale poza granicami objętości 3D. Możliwe są efekty stereo, w których treści wydają się wykraczać poza granice objętości 3D kontenera lub przed nie. Aplikacje mogą odrzucać piksele poza granicami objętości 3D ograniczonego kontenera przestrzennego, aby zmniejszyć paradoksy głębi, i powinny ustawiać wartość volumeClipping na podstawie sposobu, w jaki to robią. Paradoksy głębi często powodują zmęczenie oczu i dyskomfort użytkownika.
Środowiska wykonawcze mogą używać elementu volumeClipping, aby dostosować sposób wyświetlania określonego kontenera przestrzennego. Jeśli na przykład ustawisz wartość XR_SPATIAL_CONTAINER_VOLUME_CLIPPING_STRICT_EXT, środowisko wykonawcze może renderować tylne powierzchnie granic woluminu 3D, co spowodowałoby paradoksy głębi, gdyby kontener przestrzenny rysował piksele za granicami woluminu 3D kontenera.
Przyszłe rozszerzenia mogą umożliwiać przycinanie na podstawie granic objętości 3D, jeśli zostaną przesłane informacje o głębokości.
Prawidłowe użycie (pośrednie)
- Rozszerzenie
XR_EXT_spatial_container_self_renderingmusi być włączone przed użyciem XrSpatialContainerLayerVolumeClippingEXT. -
typemusi mieć wartośćXR_TYPE_SPATIAL_CONTAINER_LAYER_VOLUME_CLIPPING_EXT -
nextmusi mieć wartośćNULLlub być prawidłowym wskaźnikiem do następnej struktury w łańcuchu struktur -
volumeClippingmusi być prawidłową wartością XrSpatialContainerVolumeClippingEXT
Nowe polecenia
- xrBeginSpatialContainerRenderingEXT
- xrEndSpatialContainerRenderingEXT
- xrLocateSpatialContainerViewsEXT
Nowe domy
- XrSpatialContainerBeginInfoEXT
- XrSpatialContainerEndInfoEXT
- XrSpatialContainerLayerEXT
- XrSpatialContainerViewLocateInfoEXT
- XrSpatialContainerViewStateEXT
- XrSpatialContainerViewsLocateInfoEXT
Rozszerzenie XrCompositionLayerProjection :
Rozszerzenie XrFrameEndInfo :
Rozszerzenie XrSpatialContainerLayerEXT :
Nowe stałe typu wyliczeniowego
XR_EXT_SPATIAL_CONTAINER_SELF_RENDERING_EXTENSION_NAMEXR_EXT_spatial_container_self_rendering_SPEC_VERSIONRozszerzenie 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
Rozszerzenie XrSpatialContainerGraphicsPresentationEXT :
XR_SPATIAL_CONTAINER_GRAPHICS_PRESENTATION_SELF_RENDERING_EXT
Rozszerzanie 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
Próbki kodu
// 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));
Historia zmian
Wersja 1, 6 sierpnia 2026 r. (Lachlan Ford)
- Początkowy opis rozszerzenia