Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenXR - VR camera on any platform #19389

Merged
merged 1 commit into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions Common/VR/PPSSPPVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,6 @@ bool StartVRRender() {
fov.angleDown += vrView[eye].fov.angleDown / 2.0f;
}
float nearZ = 0.01f;
float fovHack = g_Config.fFieldOfViewPercentage / 200.0f;
float tanAngleLeft = tanf(fov.angleLeft);
float tanAngleRight = tanf(fov.angleRight);
float tanAngleDown = tanf(fov.angleDown);
Expand All @@ -659,7 +658,7 @@ bool StartVRRender() {
M[8] = (tanAngleRight + tanAngleLeft) / (tanAngleRight - tanAngleLeft);
M[9] = (tanAngleUp + tanAngleDown) / (tanAngleUp - tanAngleDown);
M[10] = -1;
M[11] = -(fovHack + fovHack);
M[11] = -1;
M[14] = -(nearZ + nearZ);
if (g_Config.bEnableImmersiveVR) {
M[0] /= 2.0f;
Expand Down Expand Up @@ -724,6 +723,9 @@ bool IsFlatVRGame() {
}

bool IsFlatVRScene() {
if (g_Config.bForceVR && (!vrFlatForced || !g_Config.bManualForceVR)) {
return false;
}
int vrMode = VR_GetConfig(VR_CONFIG_MODE);
return (vrMode == VR_MODE_MONO_SCREEN) || (vrMode == VR_MODE_STEREO_SCREEN);
}
Expand Down Expand Up @@ -804,7 +806,9 @@ void UpdateVRParams(float* projMatrix) {

void UpdateVRProjection(float* projMatrix, float* output) {
for (int i = 0; i < 16; i++) {
if (PSP_CoreParameter().compat.vrCompat().ProjectionHack && ((i == 8) || (i == 9))) {
if (!IsVREnabled()) {
output[i] = projMatrix[i];
} else if (PSP_CoreParameter().compat.vrCompat().ProjectionHack && ((i == 8) || (i == 9))) {
output[i] = 0;
} else if (fabs(projMatrix[i]) > 0) {
output[i] = vrMatrix[VR_PROJECTION_MATRIX][i];
Expand All @@ -815,6 +819,7 @@ void UpdateVRProjection(float* projMatrix, float* output) {
output[i] = 0;
}
}
output[11] *= g_Config.fFieldOfViewPercentage / 100.0f;
}

void UpdateVRView(float* leftEye, float* rightEye) {
Expand Down Expand Up @@ -850,8 +855,11 @@ void UpdateVRViewMatrices() {
}

// Get input
XrPosef invView = XrPosef_Identity();
if (IsVREnabled()) {
invView = vrView[0].pose;
}
bool flatScreen = false;
XrPosef invView = vrView[0].pose;
int vrMode = VR_GetConfig(VR_CONFIG_MODE);
if ((vrMode == VR_MODE_MONO_SCREEN) || (vrMode == VR_MODE_STEREO_SCREEN)) {
invView = XrPosef_Identity();
Expand Down Expand Up @@ -895,15 +903,15 @@ void UpdateVRViewMatrices() {
XrQuaternionf roll = XrQuaternionf_CreateFromVectorAngle({0, 0, 1}, mRoll);
invView.orientation = XrQuaternionf_Multiply(roll, XrQuaternionf_Multiply(pitch, yaw));
if (!VR_GetConfig(VR_CONFIG_REPROJECTION)) {
float axis = vrMirroring[VR_MIRRORING_PITCH] ? -1.0f : 1.0f;
float axis = vrMirroring[VR_MIRRORING_PITCH] ? -1.0f : 1.0f;
invView.orientation = XrQuaternionf_CreateFromVectorAngle({axis, 0, 0}, ToRadians(g_Config.fCameraPitch));
}

float M[16];
XrQuaternionf_ToMatrix4f(&invView.orientation, M);

// Apply 6Dof head movement
if (g_Config.bEnable6DoF && !g_Config.bHeadRotationEnabled) {
if (g_Config.bEnable6DoF && !g_Config.bHeadRotationEnabled && IsVREnabled()) {
M[3] -= vrView[0].pose.position.x * (vrMirroring[VR_MIRRORING_AXIS_X] ? -1.0f : 1.0f) * scale;
M[7] -= vrView[0].pose.position.y * (vrMirroring[VR_MIRRORING_AXIS_Y] ? -1.0f : 1.0f) * scale;
M[11] -= vrView[0].pose.position.z * (vrMirroring[VR_MIRRORING_AXIS_Z] ? -1.0f : 1.0f) * scale;
Expand Down Expand Up @@ -940,7 +948,7 @@ void UpdateVRViewMatrices() {

// Stereoscopy
bool vrStereo = !PSP_CoreParameter().compat.vrCompat().ForceMono && g_Config.bEnableStereo;
if (vrStereo) {
if (vrStereo && IsVREnabled()) {
bool mirrored = vrMirroring[VR_MIRRORING_AXIS_Z] ^ (matrix == VR_VIEW_MATRIX_RIGHT_EYE);
float dx = fabs(vrView[1].pose.position.x - vrView[0].pose.position.x);
float dy = fabs(vrView[1].pose.position.y - vrView[0].pose.position.y);
Expand Down
1 change: 1 addition & 0 deletions Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,7 @@ static const ConfigSetting vrSettings[] = {
ConfigSetting("VREnableStereo", &g_Config.bEnableStereo, false, CfgFlag::PER_GAME),
ConfigSetting("VREnableMotions", &g_Config.bEnableMotions, true, CfgFlag::PER_GAME),
ConfigSetting("VRForce72Hz", &g_Config.bForce72Hz, true, CfgFlag::PER_GAME),
ConfigSetting("VRForce", &g_Config.bForceVR, false, CfgFlag::DEFAULT),
ConfigSetting("VRImmersiveMode", &g_Config.bEnableImmersiveVR, true, CfgFlag::PER_GAME),
ConfigSetting("VRManualForceVR", &g_Config.bManualForceVR, false, CfgFlag::PER_GAME),
ConfigSetting("VRPassthrough", &g_Config.bPassthrough, false, CfgFlag::PER_GAME),
Expand Down
1 change: 1 addition & 0 deletions Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ struct Config {
bool bEnableMotions;
bool bEnableImmersiveVR;
bool bForce72Hz;
bool bForceVR;
bool bManualForceVR;
bool bPassthrough;
bool bRescaleHUD;
Expand Down
2 changes: 1 addition & 1 deletion GPU/Common/VertexShaderGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1307,7 +1307,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
WRITE(p, " }\n");
}

if (vertexRangeCulling && !gstate_c.Use(GPU_USE_VIRTUAL_REALITY)) {
if (vertexRangeCulling) {
WRITE(p, " vec3 projPos = outPos.xyz / outPos.w;\n");
WRITE(p, " float projZ = (projPos.z - u_depthRange.z) * u_depthRange.w;\n");

Expand Down
3 changes: 2 additions & 1 deletion GPU/GLES/GPU_GLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,9 @@ u32 GPU_GLES::CheckGPUFeatures() const {
if ((gl_extensions.IsGLES && !gl_extensions.GLES3) || (!gl_extensions.IsGLES && !gl_extensions.VersionGEThan(1, 3)))
features &= ~GPU_USE_LIGHT_UBERSHADER;

if (IsVREnabled()) {
if (IsVREnabled() || g_Config.bForceVR) {
features |= GPU_USE_VIRTUAL_REALITY;
features &= ~GPU_USE_VS_RANGE_CULLING;
}

if (!gl_extensions.GLES3) {
Expand Down
2 changes: 1 addition & 1 deletion GPU/GLES/ShaderManagerGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ void LinkedShader::UpdateUniforms(const ShaderID &vsid, bool useBufferedRenderin
}
if (dirty & DIRTY_FOGCOLOR) {
SetColorUniform3(render_, &u_fogcolor, gstate.fogcolor);
if (IsVREnabled()) {
if (gstate_c.Use(GPU_USE_VIRTUAL_REALITY)) {
SetVRCompat(VR_COMPAT_FOG_COLOR, gstate.fogcolor);
}
}
Expand Down
58 changes: 36 additions & 22 deletions UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ void GameSettingsScreen::CreateTabs() {
CreateSystemSettings(systemSettings);

int deviceType = System_GetPropertyInt(SYSPROP_DEVICE_TYPE);
if (deviceType == DEVICE_TYPE_VR) {
if ((deviceType == DEVICE_TYPE_VR) || g_Config.bForceVR) {
LinearLayout *vrSettings = AddTab("GameSettingsVR", ms->T("VR"));
CreateVRSettings(vrSettings);
}
Expand Down Expand Up @@ -617,7 +617,7 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) {
auto ms = GetI18NCategory(I18NCat::MAINSETTINGS);

audioSettings->Add(new ItemHeader(ms->T("Audio")));
CheckBox *enableSound = audioSettings->Add(new CheckBox(&g_Config.bEnableSound,a->T("Enable Sound")));
CheckBox *enableSound = audioSettings->Add(new CheckBox(&g_Config.bEnableSound,a->T("Enable Sound")));

#if PPSSPP_PLATFORM(IOS)
CheckBox *respectSilentMode = audioSettings->Add(new CheckBox(&g_Config.bAudioRespectSilentMode, a->T("Respect silent mode")));
Expand Down Expand Up @@ -1280,35 +1280,42 @@ void GameSettingsScreen::CreateVRSettings(UI::ViewGroup *vrSettings) {
using namespace UI;

auto vr = GetI18NCategory(I18NCat::VR);
int deviceType = System_GetPropertyInt(SYSPROP_DEVICE_TYPE);

vrSettings->Add(new ItemHeader(vr->T("Virtual reality")));
vrSettings->Add(new CheckBox(&g_Config.bEnableVR, vr->T("Virtual reality")));
vrSettings->Add(new CheckBox(&g_Config.bEnable6DoF, vr->T("6DoF movement")));
vrSettings->Add(new CheckBox(&g_Config.bEnableStereo, vr->T("Stereoscopic vision (Experimental)")));
vrSettings->Add(new CheckBox(&g_Config.bEnableImmersiveVR, vr->T("Enable immersive mode")));
if (IsPassthroughSupported()) {
vrSettings->Add(new CheckBox(&g_Config.bPassthrough, vr->T("Enable passthrough")));
if (deviceType == DEVICE_TYPE_VR) {
vrSettings->Add(new ItemHeader(vr->T("Virtual reality")));
vrSettings->Add(new CheckBox(&g_Config.bEnableVR, vr->T("Virtual reality")));
vrSettings->Add(new CheckBox(&g_Config.bEnable6DoF, vr->T("6DoF movement")));
vrSettings->Add(new CheckBox(&g_Config.bEnableStereo, vr->T("Stereoscopic vision (Experimental)")));
vrSettings->Add(new CheckBox(&g_Config.bEnableImmersiveVR, vr->T("Enable immersive mode")));
if (IsPassthroughSupported()) {
vrSettings->Add(new CheckBox(&g_Config.bPassthrough, vr->T("Enable passthrough")));
}
vrSettings->Add(new CheckBox(&g_Config.bForce72Hz, vr->T("Force 72Hz update")));
}
vrSettings->Add(new CheckBox(&g_Config.bForce72Hz, vr->T("Force 72Hz update")));

vrSettings->Add(new ItemHeader(vr->T("VR camera")));
vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fCanvasDistance, 1.0f, 15.0f, 12.0f, vr->T("Distance to 2D menus and scenes"), 1.0f, screenManager(), ""));
vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fCanvas3DDistance, 1.0f, 15.0f, 3.0f, vr->T("Distance to 3D scenes when VR disabled"), 1.0f, screenManager(), ""));
if (deviceType == DEVICE_TYPE_VR) {
vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fCanvasDistance, 1.0f, 15.0f, 12.0f, vr->T("Distance to 2D menus and scenes"), 1.0f, screenManager(), ""));
vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fCanvas3DDistance, 1.0f, 15.0f, 3.0f, vr->T("Distance to 3D scenes when VR disabled"), 1.0f, screenManager(), ""));
}
vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fFieldOfViewPercentage, 100.0f, 200.0f, 100.0f, vr->T("Field of view scale"), 10.0f, screenManager(), vr->T("% of native FoV")));
vrSettings->Add(new CheckBox(&g_Config.bRescaleHUD, vr->T("Heads-up display detection")));
PopupSliderChoiceFloat* vrHudScale = vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fHeadUpDisplayScale, 0.0f, 1.5f, 0.3f, vr->T("Heads-up display scale"), 0.1f, screenManager(), ""));
vrHudScale->SetEnabledPtr(&g_Config.bRescaleHUD);
vrSettings->Add(new CheckBox(&g_Config.bManualForceVR, vr->T("Manual switching between flat screen and VR using SCREEN key")));

vrSettings->Add(new ItemHeader(vr->T("Experts only")));
vrSettings->Add(new CheckBox(&g_Config.bHeadRotationEnabled, vr->T("Map HMD rotations on keys instead of VR camera")));
PopupSliderChoiceFloat *vrHeadRotationScale = vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fHeadRotationScale, 0.1f, 10.0f, 5.0f, vr->T("Game camera rotation step per frame"), 0.1f, screenManager(), "°"));
vrHeadRotationScale->SetEnabledPtr(&g_Config.bHeadRotationEnabled);
CheckBox *vrHeadRotationSmoothing = vrSettings->Add(new CheckBox(&g_Config.bHeadRotationSmoothing, vr->T("Game camera uses rotation smoothing")));
vrHeadRotationSmoothing->SetEnabledPtr(&g_Config.bHeadRotationEnabled);
vrSettings->Add(new CheckBox(&g_Config.bEnableMotions, vr->T("Map controller movements to keys")));
PopupSliderChoiceFloat *vrMotions = vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fMotionLength, 0.3f, 1.0f, 0.5f, vr->T("Motion needed to generate action"), 0.1f, screenManager(), vr->T("m")));
vrMotions->SetEnabledPtr(&g_Config.bEnableMotions);
if (deviceType == DEVICE_TYPE_VR) {
vrSettings->Add(new ItemHeader(vr->T("Experts only")));
vrSettings->Add(new CheckBox(&g_Config.bHeadRotationEnabled, vr->T("Map HMD rotations on keys instead of VR camera")));
PopupSliderChoiceFloat *vrHeadRotationScale = vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fHeadRotationScale, 0.1f, 10.0f, 5.0f, vr->T("Game camera rotation step per frame"), 0.1f, screenManager(), "°"));
vrHeadRotationScale->SetEnabledPtr(&g_Config.bHeadRotationEnabled);
CheckBox *vrHeadRotationSmoothing = vrSettings->Add(new CheckBox(&g_Config.bHeadRotationSmoothing, vr->T("Game camera uses rotation smoothing")));
vrHeadRotationSmoothing->SetEnabledPtr(&g_Config.bHeadRotationEnabled);
vrSettings->Add(new CheckBox(&g_Config.bEnableMotions, vr->T("Map controller movements to keys")));
PopupSliderChoiceFloat *vrMotions = vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fMotionLength, 0.3f, 1.0f, 0.5f, vr->T("Motion needed to generate action"), 0.1f, screenManager(), vr->T("m")));
vrMotions->SetEnabledPtr(&g_Config.bEnableMotions);
}
}

UI::EventReturn GameSettingsScreen::OnAutoFrameskip(UI::EventParams &e) {
Expand Down Expand Up @@ -1907,6 +1914,13 @@ void DeveloperToolsScreen::CreateViews() {
list->Add(new CheckBox(&g_Config.bUberShaderFragment, dev->T("Fragment")));
}

// Experimental, allow some VR features without OpenXR
if (GetGPUBackend() == GPUBackend::OPENGL) {
auto vr = GetI18NCategory(I18NCat::VR);
list->Add(new ItemHeader(gr->T("Virtual reality")));
list->Add(new CheckBox(&g_Config.bForceVR, vr->T("VR camera")));
}

// Experimental, will move to main graphics settings later.
bool multiViewSupported = draw->GetDeviceCaps().multiViewSupported;

Expand Down Expand Up @@ -2223,7 +2237,7 @@ UI::EventReturn HostnameSelectScreen::OnDeleteAllClick(UI::EventParams &e) {
UI::EventReturn HostnameSelectScreen::OnEditClick(UI::EventParams& e) {
auto n = GetI18NCategory(I18NCat::NETWORKING);
System_InputBoxGetString(GetRequesterToken(), n->T("proAdhocServer Address:"), addrView_->GetText(), [this](const std::string& value, int) {
addrView_->SetText(value);
addrView_->SetText(value);
});
return UI::EVENT_DONE;
}
Expand Down
4 changes: 2 additions & 2 deletions UI/NativeApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1322,7 +1322,7 @@ bool NativeKey(const KeyInput &key) {
double now = time_now_d();

// VR actions
if (IsVREnabled() && !UpdateVRKeys(key)) {
if ((IsVREnabled() || g_Config.bForceVR) && !UpdateVRKeys(key)) {
return false;
}

Expand Down Expand Up @@ -1372,7 +1372,7 @@ bool NativeKey(const KeyInput &key) {

void NativeAxis(const AxisInput *axes, size_t count) {
// VR actions
if (IsVREnabled() && !UpdateVRAxis(axes, count)) {
if ((IsVREnabled() || g_Config.bForceVR) && !UpdateVRAxis(axes, count)) {
return;
}

Expand Down