Skip to content
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
19 changes: 10 additions & 9 deletions Projects/Android/jni/QzDoom/QzDoom_OpenXR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,17 +323,18 @@ bool VR_GetVRProjection(int eye, float zNear, float zFar, float* projection)

if (strstr(gAppState.OpenXRHMD, "meta") != NULL)
{
XrFovf fov = {};
for (int eye = 0; eye < ovrMaxNumEyes; eye++)
{
fov.angleLeft += gAppState.Projections[eye].fov.angleLeft / 2.0f;
fov.angleRight += gAppState.Projections[eye].fov.angleRight / 2.0f;
fov.angleUp += gAppState.Projections[eye].fov.angleUp / 2.0f;
fov.angleDown += gAppState.Projections[eye].fov.angleDown / 2.0f;
}
// Use this eye's own runtime-reported FOV directly (same as the pico
// branch above) instead of averaging both eyes' angleLeft/angleRight
// into one shared symmetric FOV. That average mixed each eye's
// temporal (outward) angle with the other eye's nasal (inward) angle,
// which only happens to cancel out on headsets whose per-eye FOV is
// already close to left/right-symmetric (e.g. Quest 2). On headsets
// with more pronounced per-eye horizontal asymmetry (e.g. Quest 3's
// pancake lenses), it silently shrank the usable FOV on both outer
// edges, producing visible black bars there.
XrMatrix4x4f_CreateProjectionFov(
&(gAppState.ProjectionMatrices[eye]), GRAPHICS_OPENGL_ES,
fov, zNear, zFar);
gAppState.Projections[eye].fov, zNear, zFar);
}

memcpy(projection, gAppState.ProjectionMatrices[eye].m, 16 * sizeof(float));
Expand Down
15 changes: 7 additions & 8 deletions Projects/Android/jni/QzDoom/TBXR_Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2099,20 +2099,19 @@ void TBXR_submitFrame()

TBXR_updateProjections();

XrFovf fov = {};
XrPosef viewTransform[2];

for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
XrPosef xfHeadFromEye = gAppState.Projections[eye].pose;
XrPosef xfStageFromEye = XrPosef_Multiply(gAppState.xfStageFromHead, xfHeadFromEye);
viewTransform[eye] = XrPosef_Inverse(xfStageFromEye);
fov.angleLeft += gAppState.Projections[eye].fov.angleLeft / 2.0f;
fov.angleRight += gAppState.Projections[eye].fov.angleRight / 2.0f;
fov.angleUp += gAppState.Projections[eye].fov.angleUp / 2.0f;
fov.angleDown += gAppState.Projections[eye].fov.angleDown / 2.0f;
}

fov_y = (fabs(fov.angleUp) + fabs(fov.angleDown)) * 180.0f / M_PI;
// fov_y (QzDoom_GetFOV(), HUD/menu FOV readback only) doesn't need to be
// eye-specific; eye 0's actual vertical extent is a fine approximation.
// It is no longer used to build the per-eye compositor FOV below.
const XrFovf &fov0 = gAppState.Projections[0].fov;
fov_y = (fabs(fov0.angleUp) + fabs(fov0.angleDown)) * 180.0f / M_PI;


gAppState.LayerCount = 0;
Expand All @@ -2134,7 +2133,7 @@ void TBXR_submitFrame()
memset(&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView));
projection_layer_elements[eye].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
projection_layer_elements[eye].pose = gAppState.xfStageFromHead;
projection_layer_elements[eye].fov = fov;
projection_layer_elements[eye].fov = gAppState.Projections[eye].fov;
memset(&projection_layer_elements[eye].subImage, 0, sizeof(XrSwapchainSubImage));
projection_layer_elements[eye].subImage.swapchain =
frameBuffer->ColorSwapChain.Handle;
Expand Down Expand Up @@ -2196,4 +2195,4 @@ void TBXR_submitFrame()
OXR(xrEndFrame(gAppState.Session, &endFrameInfo));

gAppState.FrameSetupRefCount--;
}
}
Loading