mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 06:00:25 +02:00
feat: added immersive window support for VR race views
- Introduced a new configuration option for immersive window mode in runtime_config.h. - Updated the parsing and setting functions to handle the immersive window state. - Modified the OpenXR backend to support rendering with the immersive window, blending the race view with the surrounding environment. - Enhanced the settings overlay to allow users to select between immersive, immersive window, and flat screen race views. - Implemented GPU rendering logic for the immersive window mask, ensuring correct visual output in various rendering paths. - Added tests to validate the immersive window functionality and its interaction with existing race view settings.
This commit is contained in:
1 parent
1969dda0bf
commit
1cf9389d69
20 files changed
+917
-53
No files matched your search
@@ -58,6 +58,7 @@ struct RuntimeUserConfig {
|
||||
std::optional<float> vrHudWidthMeters;
|
||||
std::optional<bool> vrHudVirtualScreen;
|
||||
std::optional<bool> vrFlatScreen;
|
||||
std::optional<bool> vrImmersiveWindow;
|
||||
std::optional<bool> vrPassthrough;
|
||||
std::optional<bool> vrStopAtDisplayCopy;
|
||||
std::optional<bool> vrSkipCopyClears;
|
||||
@@ -522,6 +523,11 @@ inline void EnsureConfigFile() {
|
||||
"# first-person camera or hand steering. Changeable live from the\n"
|
||||
"# F10 menu.\n"
|
||||
"flat_screen = false\n"
|
||||
"# The immersive window keeps the stereo race view but shows it\n"
|
||||
"# only through that screen, with the room around it on the\n"
|
||||
"# Quest (black elsewhere). Flat Screen mode wins over it.\n"
|
||||
"# Changeable live from the F10 menu.\n"
|
||||
"immersive_window = false\n"
|
||||
"# EFB replay controls for the per-eye views, changeable live\n"
|
||||
"# from the F10 menu. stop_at_display_copy ends each eye at the\n"
|
||||
"# frame's final GXCopyDisp; skip_copy_clears drops the EFB\n"
|
||||
@@ -778,6 +784,7 @@ inline RuntimeUserConfig ParseConfigDocument(const toml::value& document) {
|
||||
}
|
||||
config.vrHudVirtualScreen = FindConfigValue<bool>(document, "vr", "hud_virtual_screen");
|
||||
config.vrFlatScreen = FindConfigValue<bool>(document, "vr", "flat_screen");
|
||||
config.vrImmersiveWindow = FindConfigValue<bool>(document, "vr", "immersive_window");
|
||||
config.vrPassthrough = FindConfigValue<bool>(document, "vr", "passthrough");
|
||||
config.vrStopAtDisplayCopy = FindConfigValue<bool>(document, "vr", "stop_at_display_copy");
|
||||
config.vrSkipCopyClears = FindConfigValue<bool>(document, "vr", "skip_copy_clears");
|
||||
@@ -1102,6 +1109,11 @@ inline bool SetVrFlatScreen(bool value) {
|
||||
return WriteSetting("vr", "flat_screen", value ? "true" : "false");
|
||||
}
|
||||
|
||||
inline bool SetVrImmersiveWindow(bool value) {
|
||||
Mutable().vrImmersiveWindow = value;
|
||||
return WriteSetting("vr", "immersive_window", value ? "true" : "false");
|
||||
}
|
||||
|
||||
inline bool SetVrPassthrough(bool value) {
|
||||
Mutable().vrPassthrough = value;
|
||||
return WriteSetting("vr", "passthrough", value ? "true" : "false");
|
||||
@@ -1579,10 +1591,41 @@ inline bool VrFlatScreen(bool fallback = false) {
|
||||
return Get().vrFlatScreen.value_or(fallback);
|
||||
}
|
||||
|
||||
// Races in stereo as usual, but seen only through the screen the race's 2D
|
||||
// layer sits on, with the room around it. Flat Screen mode wins over it.
|
||||
inline bool VrImmersiveWindow(bool fallback = false) {
|
||||
return Get().vrImmersiveWindow.value_or(fallback);
|
||||
}
|
||||
|
||||
// The race view the settings present as one choice, kept in the two keys
|
||||
// above so that a file without immersive_window reads as it always did.
|
||||
enum class VrRaceView : int {
|
||||
Immersive = 0,
|
||||
ImmersiveWindow = 1,
|
||||
FlatScreen = 2,
|
||||
};
|
||||
|
||||
inline VrRaceView VrRaceViewOf(const RuntimeUserConfig& config) {
|
||||
if (config.vrFlatScreen.value_or(false)) {
|
||||
return VrRaceView::FlatScreen;
|
||||
}
|
||||
return config.vrImmersiveWindow.value_or(false) ? VrRaceView::ImmersiveWindow : VrRaceView::Immersive;
|
||||
}
|
||||
|
||||
inline VrRaceView GetVrRaceView() {
|
||||
return VrRaceViewOf(Get());
|
||||
}
|
||||
|
||||
inline bool SetVrRaceView(VrRaceView view) {
|
||||
const bool flat = SetVrFlatScreen(view == VrRaceView::FlatScreen);
|
||||
const bool window = SetVrImmersiveWindow(view == VrRaceView::ImmersiveWindow);
|
||||
return flat && window;
|
||||
}
|
||||
|
||||
// The room, through the headset's cameras, around the menu screen and every
|
||||
// other virtual screen, a Flat Screen race included (never an immersive
|
||||
// race). Only the Quest offers it; the launcher's Settings page shows the same
|
||||
// default.
|
||||
// other virtual screen, a Flat Screen race included, and around the immersive
|
||||
// window (never a fully immersive race). Only the Quest offers it; the
|
||||
// launcher's Settings page shows the same default.
|
||||
inline bool VrPassthrough(bool fallback = true) {
|
||||
return Get().vrPassthrough.value_or(fallback);
|
||||
}
|
||||
|
||||
@@ -132,9 +132,15 @@ struct OpenXRPresentation {
|
||||
bool quad_anchored = false;
|
||||
XrPosef quad_pose{{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}};
|
||||
|
||||
// Show the room through the headset's cameras around the virtual screen
|
||||
// (OpenXRPassthrough). Taken when the presentation is handed to the backend,
|
||||
// which starts or pauses the view then; a backend without one ignores it.
|
||||
// Used only by ImmersiveProjection: Aurora left each eye transparent outside
|
||||
// the race's 2D-layer screen (AuroraStereoFrame::window), so the projection
|
||||
// layer is blended by its alpha over whatever is under it.
|
||||
bool immersive_window = false;
|
||||
|
||||
// Show the room through the headset's cameras around the virtual screen or
|
||||
// the immersive window (OpenXRPassthrough). Taken when the presentation is
|
||||
// handed to the backend, which starts or pauses the view then; a backend
|
||||
// without one ignores it.
|
||||
bool passthrough = false;
|
||||
|
||||
OpenXRPanelLayer panel;
|
||||
|
||||
@@ -61,11 +61,19 @@ void OpenXRRequestRecenter() noexcept;
|
||||
void OpenXRSetLeanBackDegrees(float degrees) noexcept;
|
||||
|
||||
// Shows the room through the headset's cameras around the menu screen and every
|
||||
// other virtual screen, never during an immersive race. Only the standalone
|
||||
// (Quest) backend offers it; elsewhere this changes nothing. Callable from any
|
||||
// thread; applied on the XR pacing thread's next frame.
|
||||
// other virtual screen, and around the immersive window, never during a fully
|
||||
// immersive race. Only the standalone (Quest) backend offers it; elsewhere this
|
||||
// changes nothing. Callable from any thread; applied on the XR pacing thread's
|
||||
// next frame.
|
||||
void OpenXRSetPassthrough(bool enabled) noexcept;
|
||||
|
||||
// The immersive window: an immersive race keeps its stereo view but is seen
|
||||
// only through the screen its 2D layer sits on, with the room (or, without
|
||||
// passthrough, black) around it. Callable from any thread; applied to the next
|
||||
// published frame. Flat Screen mode, which keeps races off the immersive path
|
||||
// altogether, makes it moot.
|
||||
void OpenXRSetImmersiveWindow(bool enabled) noexcept;
|
||||
|
||||
// Live scene interpolation at the headset's own display deadlines.
|
||||
// 0 = Off, 1 = Auto, otherwise 72/90/120 as a rendering-rate ceiling.
|
||||
void OpenXRSetFrameInterpolationFps(uint32_t target) noexcept;
|
||||
|
||||
Reference in new issue
Block a user