Skip to content

Commit

Permalink
Merge pull request #19389 from lvonasek/feature-openxr-anyplatform
Browse files Browse the repository at this point in the history
OpenXR - VR camera on any platform
  • Loading branch information
hrydgard authored Aug 7, 2024
2 parents 5658a3e + 3154a5f commit 1c5512a
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 34 deletions.
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

0 comments on commit 1c5512a

Please sign in to comment.