mirror of
https://github.com/amwatson/CitraVR.git
synced 2024-09-20 03:11:40 +02:00
Got proper 6DoF working..
- also allowed depth slider to go to 200% (for 1st person in MK7) - added in the "look down to show" for the lower panel
This commit is contained in:
parent
d4515d120f
commit
e97ca06b3d
7 changed files with 91 additions and 55 deletions
|
@ -387,7 +387,7 @@ public final class SettingsFragmentPresenter {
|
|||
sl.add(new CheckBoxSetting(SettingsFile.KEY_USE_DISK_SHADER_CACHE, Settings.SECTION_RENDERER, R.string.use_disk_shader_cache, R.string.use_disk_shader_cache_description, true, useDiskShaderCache));
|
||||
|
||||
sl.add(new HeaderSetting(null, null, R.string.stereoscopy, 0));
|
||||
sl.add(new SliderSetting(SettingsFile.KEY_FACTOR_3D, Settings.SECTION_RENDERER, R.string.factor3d, R.string.factor3d_description, 0, 100, "%", 50, factor3d));
|
||||
sl.add(new SliderSetting(SettingsFile.KEY_FACTOR_3D, Settings.SECTION_RENDERER, R.string.factor3d, R.string.factor3d_description, 0, 200, "%", 50, factor3d));
|
||||
|
||||
sl.add(new HeaderSetting(null, null, R.string.utility, 0));
|
||||
sl.add(new CheckBoxSetting(SettingsFile.KEY_DUMP_TEXTURES, Settings.SECTION_UTILITY, R.string.dump_textures, R.string.dump_textures_description, false, dumpTextures));
|
||||
|
@ -437,6 +437,7 @@ public final class SettingsFragmentPresenter {
|
|||
sl.add(new SingleChoiceSetting(SettingsFile.KEY_VR_ENVIRONMENT, Settings.SECTION_VR, R.string.vr_background, 0, R.array.vrBackgroundNames, R.array.vrBackgroundValues, VRUtils.getHMDType() == VRUtils.HMDType.QUEST3.getValue() ? 1 : 2, vrEnvironment));
|
||||
sl.add(new CheckBoxSetting(SettingsFile.KEY_VR_EXTRA_PERFORMANCE_MODE, Settings.SECTION_VR, R.string.vr_extra_performance_mode, R.string.vr_extra_performance_mode_description, false, vrExtraPerformanceMode));
|
||||
sl.add(new SingleChoiceSetting(SettingsFile.KEY_VR_CPU_LEVEL, Settings.SECTION_VR, R.string.vr_cpu_level, R.string.vr_cpu_level_description, R.array.vrCpuLevelNames, R.array.vrCpuLevelValues, 3, vrCpuLevel));
|
||||
sl.add(new HeaderSetting(null, null, R.string.immersive_mode, 0));
|
||||
sl.add(new SingleChoiceSetting(SettingsFile.KEY_VR_IMMERSIVE_MODE, Settings.SECTION_VR, R.string.vr_immersive_mode_title, R.string.vr_immersive_mode_description, R.array.vrImmersiveModeNames, R.array.vrImmersiveModeValues, 0, vrImmersiveMode));
|
||||
sl.add(new SliderSetting(SettingsFile.KEY_VR_IMMERSIVE_POSITIONAL_FACTOR, Settings.SECTION_VR, R.string.vr_immersive_pos_factor_title, R.string.vr_immersive_pos_factor_description, 0, 40, "X", 0, vrImmersivePositionalFactor));
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ License : Licensed under GPLv3 or any later version.
|
|||
|
||||
namespace {
|
||||
|
||||
constexpr float lowerPanelScaleFactor = 0.75f;
|
||||
constexpr float defaultLowerPanelScaleFactor = 0.75f;
|
||||
|
||||
const std::vector<float> immersiveLevelFactor = {1.0f, 5.0f, 3.0f};
|
||||
|
||||
|
@ -232,11 +232,10 @@ GameSurfaceLayer::GameSurfaceLayer(const XrVector3f&& position, JNIEnv* env, job
|
|||
env_(env), activityObject_(activityObject)
|
||||
|
||||
{
|
||||
assert(immersiveMode_ == 0 || immersiveMode_ == 1);
|
||||
if (immersiveMode_ > 0) {
|
||||
ALOGI("Using VR immersive mode {}", immersiveMode_);
|
||||
topPanelFromWorld_.position.z = lowerPanelFromWorld_.position.z;
|
||||
lowerPanelFromWorld_.position.y = -1.0f - (0.5f * (immersiveMode_ - 1));
|
||||
lowerPanelFromWorld_.position.y = -1.0f;
|
||||
}
|
||||
const int32_t initializationStatus = Init(activityObject, position, session);
|
||||
if (initializationStatus < 0) {
|
||||
|
@ -335,6 +334,37 @@ void GameSurfaceLayer::Frame(const XrSpace& space, std::vector<XrCompositionLaye
|
|||
layers[layerCount++].mQuad = layer;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This bit is entirely optional, rather than having the panel appear/disappear it emerge in
|
||||
* smoothly, however to achieve it I had to make the scale factor mutable, which I appreciate
|
||||
* might not be following the intention of this class.
|
||||
* If a mutable class member isn't desired, then just drop this bit and use the visibleLowerPanel
|
||||
* variable directly.
|
||||
*/
|
||||
const auto panelZoomSpeed = 0.15f;
|
||||
if (showLowerPanel && lowerPanelScaleFactor < defaultLowerPanelScaleFactor)
|
||||
{
|
||||
if (lowerPanelScaleFactor == 0.0f)
|
||||
{
|
||||
lowerPanelScaleFactor = panelZoomSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
lowerPanelScaleFactor *= 1.0f + panelZoomSpeed;
|
||||
lowerPanelScaleFactor = std::min(lowerPanelScaleFactor, defaultLowerPanelScaleFactor);
|
||||
}
|
||||
}
|
||||
else if (!showLowerPanel && lowerPanelScaleFactor > 0.0f)
|
||||
{
|
||||
lowerPanelScaleFactor /= 1.0f + panelZoomSpeed;
|
||||
if (lowerPanelScaleFactor < panelZoomSpeed)
|
||||
{
|
||||
lowerPanelScaleFactor = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create the Lower Display Panel (flat touchscreen)
|
||||
// When citra is in stereo mode, this panel is also rendered in stereo (i.e.
|
||||
// twice), but the image is mono. Therefore, take the right half of the
|
||||
|
@ -342,7 +372,7 @@ void GameSurfaceLayer::Frame(const XrSpace& space, std::vector<XrCompositionLaye
|
|||
// FIXME we waste rendering time rendering both displays. That said, We also
|
||||
// waste rendering time copying the buffer between runtimes. No time for
|
||||
// that now!
|
||||
if (showLowerPanel)
|
||||
if (lowerPanelScaleFactor > 0.0f)
|
||||
{
|
||||
const uint32_t cropHoriz = 90 * resolutionFactor_;
|
||||
XrCompositionLayerQuad layer = {};
|
||||
|
@ -371,8 +401,8 @@ void GameSurfaceLayer::Frame(const XrSpace& space, std::vector<XrCompositionLaye
|
|||
layer.pose = lowerPanelFromWorld_;
|
||||
const auto scale = GetDensityScaleForSize(panelWidth - cropHoriz, -panelHeight,
|
||||
lowerPanelScaleFactor, resolutionFactor_);
|
||||
layer.size.width = scale.x;
|
||||
layer.size.height = scale.y;
|
||||
layer.size.width = scale.x * lowerPanelScaleFactor;
|
||||
layer.size.height = scale.y * lowerPanelScaleFactor;
|
||||
layers[layerCount++].mQuad = layer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,12 +96,12 @@ public:
|
|||
*
|
||||
* @param space the XrSpace this layer should be positioned with. The
|
||||
* center of the layer is placed in the center of the FOV.
|
||||
* @param headLocation the XrSpaceLocation - the hmd location
|
||||
* @param layers the array of layers to populate
|
||||
* @param layerCount the number of layers in the array
|
||||
* @param visibleLowerPanel whether the lower panel is shown/visible
|
||||
*/
|
||||
void Frame(const XrSpace& space, std::vector<XrCompositionLayer>& layers,
|
||||
uint32_t& layerCount, const bool showLowerPanel) const;
|
||||
uint32_t& layerCount, const bool visibleLowerPanel) const;
|
||||
|
||||
/** Given an origin, direction of a ray,
|
||||
* returns the coordinates of where the ray will intersects
|
||||
|
@ -171,6 +171,11 @@ private:
|
|||
// - Rendering the top-screen and bottom screen separately.
|
||||
const uint32_t immersiveMode_;
|
||||
|
||||
// Used to nicely present the lower panel when in toggleable mode.
|
||||
// Instead of it just appearing instantly, it emerges in a hopefully pleasant
|
||||
// fashion
|
||||
mutable float lowerPanelScaleFactor = 0.0f;
|
||||
|
||||
//============================
|
||||
// JNI objects
|
||||
JNIEnv* env_ = nullptr;
|
||||
|
|
|
@ -487,28 +487,35 @@ private:
|
|||
gOpenXr->headLocation = {XR_TYPE_SPACE_LOCATION};
|
||||
OXR(xrLocateSpace(gOpenXr->viewSpace_, gOpenXr->headSpace_, frameState.predictedDisplayTime, &gOpenXr->headLocation));
|
||||
|
||||
bool showLowerPanel = false;
|
||||
bool showLowerPanel = true;
|
||||
// Push the HMD position through to the Rasterizer to pass on to the VS Uniform
|
||||
if (VideoCore::g_renderer && VideoCore::g_renderer->Rasterizer())
|
||||
{
|
||||
//I am confused... but GetRollInRadians appears to return pitch
|
||||
float pitch = XrMath::Quatf::GetRollInRadians(gOpenXr->headLocation.pose.orientation);
|
||||
|
||||
//Only use position if it is enabled, and the user is not looking at the lower panel
|
||||
if ((VRSettings::values.vr_immersive_positional_factor > 0) && (pitch > -0.35f))
|
||||
{
|
||||
Common::Vec3f position{-gOpenXr->headLocation.pose.position.y,
|
||||
gOpenXr->headLocation.pose.position.x,
|
||||
0.0f}; //gOpenXr->headLocation.pose.position.z}; - For some reason Z doesn't affect the actual Z position!
|
||||
position *= VRSettings::values.vr_immersive_positional_factor;
|
||||
VideoCore::g_renderer->Rasterizer()->SetVRData(position);
|
||||
}
|
||||
else
|
||||
if ((VRSettings::values.vr_immersive_positional_factor == 0) ||
|
||||
(pitch < -0.35f))
|
||||
{
|
||||
//Disable position when looking down at the lower panel
|
||||
Common::Vec3f position = {};
|
||||
VideoCore::g_renderer->Rasterizer()->SetVRData(position);
|
||||
showLowerPanel = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Only use position if it is enabled, and the user is not looking at the lower panel
|
||||
Common::Vec3f position{-gOpenXr->headLocation.pose.position.y,
|
||||
gOpenXr->headLocation.pose.position.x,
|
||||
-gOpenXr->headLocation.pose.position.z};// - For some reason Z doesn't affect the actual Z position!
|
||||
|
||||
ALOGI("gOpenXr->headLocation Position : {}.{}.{}",
|
||||
position.x,
|
||||
position.y,
|
||||
position.z);
|
||||
|
||||
position *= VRSettings::values.vr_immersive_positional_factor;
|
||||
VideoCore::g_renderer->Rasterizer()->SetVRData(position);
|
||||
showLowerPanel = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ struct Values {
|
|||
uint32_t resolution_factor = 0;
|
||||
int32_t vr_environment = 0;
|
||||
int32_t vr_immersive_mode = 0;
|
||||
int32_t vr_immersive_positional_factor = 0;
|
||||
bool extra_performance_mode_enabled = false;
|
||||
} extern values;
|
||||
|
||||
|
|
|
@ -300,6 +300,7 @@
|
|||
<string name="vr_extra_performance_mode">VR Extra Performance Mode</string>
|
||||
<string name="vr_cpu_level">CPU level</string>
|
||||
<string name="vr_cpu_level_description">Higher levels may improve audio/emulation performance, but will drain the battery faster</string>
|
||||
<string name="immersive_mode">Immersive Mode</string>
|
||||
<string name="vr_immersive_mode_title">[WARNING: Graphics Artifacts] Immersive Mode (Experimental)</string>
|
||||
<string name="vr_immersive_mode_description">Extends the top screen around a cylinder for immersive gameplay</string>
|
||||
<string name="vr_immersive_pos_factor_title">Immersive Mode Positional Movement Factor</string>
|
||||
|
|
|
@ -1642,6 +1642,28 @@ do {
|
|||
return out;
|
||||
}
|
||||
|
||||
|
||||
static std::string GenerateGLPositionAndGLClipDistanceBlock(bool use_clip_planes)
|
||||
{
|
||||
std::string out;
|
||||
|
||||
out+= "\n gl_Position = vec4(vtx_pos.x / vr_immersive_mode_factor + vr_position.x, vtx_pos.y / vr_immersive_mode_factor + vr_position.y, -vtx_pos.z - vr_position.z, vtx_pos.w - vr_position.z);\n";
|
||||
|
||||
if (use_clip_planes)
|
||||
{
|
||||
out += R"(
|
||||
gl_ClipDistance[0] = -vtx_pos.z; // fixed PICA clipping plane z <= 0
|
||||
if (enable_clip1) {
|
||||
gl_ClipDistance[1] = dot(clip_coef, vtx_pos);
|
||||
} else {
|
||||
gl_ClipDistance[1] = 0.0;
|
||||
}
|
||||
)";
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string GenerateTrivialVertexShader(bool use_clip_planes, bool separable_shader) {
|
||||
std::string out;
|
||||
if (separable_shader) {
|
||||
|
@ -1684,26 +1706,13 @@ void main() {
|
|||
}
|
||||
)";
|
||||
|
||||
out+= "\ngl_Position = vec4(vtx_pos.x / vr_immersive_mode_factor + vr_position.x, vtx_pos.y / vr_immersive_mode_factor + vr_position.y, -vtx_pos.z - vr_position.z, vtx_pos.w);\n";
|
||||
|
||||
if (use_clip_planes) {
|
||||
out += R"(
|
||||
gl_ClipDistance[0] = -vtx_pos.z; // fixed PICA clipping plane z <= 0
|
||||
if (enable_clip1) {
|
||||
gl_ClipDistance[1] = dot(clip_coef, vtx_pos);
|
||||
} else {
|
||||
gl_ClipDistance[1] = 0.0;
|
||||
}
|
||||
)";
|
||||
}
|
||||
out += GenerateGLPositionAndGLClipDistanceBlock(use_clip_planes);
|
||||
|
||||
out += "}\n";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string_view MakeLoadPrefix(AttribLoadFlags flag) {
|
||||
if (True(flag & AttribLoadFlags::Float)) {
|
||||
return "";
|
||||
|
@ -1805,16 +1814,7 @@ std::string GenerateVertexShader(const Pica::Shader::ShaderSetup& setup, const P
|
|||
out += " vtx_pos.z = 0.f;\n";
|
||||
out += " }\n";
|
||||
|
||||
out+= " gl_Position = vec4(vtx_pos.x / vr_immersive_mode_factor + vr_position.x, vtx_pos.y / vr_immersive_mode_factor + vr_position.y, -vtx_pos.z - vr_position.z, vtx_pos.w);\n";
|
||||
|
||||
if (config.state.use_clip_planes) {
|
||||
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
|
||||
out += " if (enable_clip1) {\n";
|
||||
out += " gl_ClipDistance[1] = dot(clip_coef, vtx_pos);\n";
|
||||
out += " } else {\n";
|
||||
out += " gl_ClipDistance[1] = 0.0;\n";
|
||||
out += " }\n\n";
|
||||
}
|
||||
out += GenerateGLPositionAndGLClipDistanceBlock(config.state.use_clip_planes);
|
||||
|
||||
out += " normquat = GetVertexQuaternion();\n";
|
||||
out += " vec4 vtx_color = vec4(" + semantic(VSOutputAttributes::COLOR_R) + ", " +
|
||||
|
@ -1904,16 +1904,7 @@ struct Vertex {
|
|||
out += " vtx_pos.z = 0.f;\n";
|
||||
out += " }\n";
|
||||
|
||||
out += " gl_Position = vec4(vtx_pos.x / vr_immersive_mode_factor + vr_position.x, vtx_pos.y / vr_immersive_mode_factor + vr_position.y, -vtx_pos.z - vr_position.z, vtx_pos.w);\n";
|
||||
|
||||
if (state.use_clip_planes) {
|
||||
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
|
||||
out += " if (enable_clip1) {\n";
|
||||
out += " gl_ClipDistance[1] = dot(clip_coef, vtx_pos);\n";
|
||||
out += " } else {\n";
|
||||
out += " gl_ClipDistance[1] = 0.0;\n";
|
||||
out += " }\n\n";
|
||||
}
|
||||
out += GenerateGLPositionAndGLClipDistanceBlock(state.use_clip_planes);
|
||||
|
||||
out += " vec4 vtx_quat = GetVertexQuaternion(vtx);\n";
|
||||
out += " normquat = mix(vtx_quat, -vtx_quat, bvec4(quats_opposite));\n\n";
|
||||
|
|
Loading…
Reference in a new issue