mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-24 21:11:05 +00:00
OpenXR integration fixes
This commit is contained in:
parent
c321b97894
commit
65e2031e95
6 changed files with 128 additions and 51 deletions
|
@ -18,7 +18,9 @@ const char* const requiredExtensionNames[] = {
|
|||
XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME,
|
||||
XR_FB_DISPLAY_REFRESH_RATE_EXTENSION_NAME,
|
||||
XR_FB_SWAPCHAIN_UPDATE_STATE_EXTENSION_NAME,
|
||||
XR_FB_SWAPCHAIN_UPDATE_STATE_OPENGL_ES_EXTENSION_NAME};
|
||||
XR_FB_SWAPCHAIN_UPDATE_STATE_OPENGL_ES_EXTENSION_NAME,
|
||||
XR_FB_FOVEATION_EXTENSION_NAME,
|
||||
XR_FB_FOVEATION_CONFIGURATION_EXTENSION_NAME};
|
||||
const uint32_t numRequiredExtensions =
|
||||
sizeof(requiredExtensionNames) / sizeof(requiredExtensionNames[0]);
|
||||
|
||||
|
|
|
@ -1103,8 +1103,8 @@ static void IN_VRJoystick( qboolean isRightController, float joystickX, float jo
|
|||
else
|
||||
{
|
||||
//Positional movement speed correction for when we are not hitting target framerate
|
||||
//TODO:int refresh = vrapi_GetSystemPropertyInt(&(VR_GetEngine()->java), VRAPI_SYS_PROP_DISPLAY_REFRESH_RATE);
|
||||
int refresh = 72;
|
||||
float refresh;
|
||||
VR_GetEngine()->appState.pfnGetDisplayRefreshRate(VR_GetEngine()->appState.Session, &refresh);
|
||||
float multiplier = (float)((1000.0 / refresh) / (in_vrEventTime - lastframetime));
|
||||
|
||||
float factor = (refresh / 72.0F) * 10.0f; // adjust positional factor based on refresh rate
|
||||
|
|
|
@ -270,6 +270,14 @@ void VR_InitRenderer( engine_t* engine ) {
|
|||
&engine->appState.Renderer,
|
||||
engine->appState.ViewConfigurationView[0].recommendedImageRectWidth,
|
||||
engine->appState.ViewConfigurationView[0].recommendedImageRectHeight);
|
||||
|
||||
ovrRenderer_SetFoveation(
|
||||
&engine->appState.Instance,
|
||||
&engine->appState.Session,
|
||||
&engine->appState.Renderer,
|
||||
XR_FOVEATION_LEVEL_HIGH_FB,
|
||||
0,
|
||||
XR_FOVEATION_DYNAMIC_DISABLED_FB);
|
||||
}
|
||||
|
||||
void VR_DestroyRenderer( engine_t* engine )
|
||||
|
@ -284,6 +292,29 @@ void VR_ReInitRenderer()
|
|||
VR_InitRenderer( VR_GetEngine() );
|
||||
}
|
||||
|
||||
void VR_ClearFrameBuffer( int width, int height)
|
||||
{
|
||||
glEnable( GL_SCISSOR_TEST );
|
||||
glViewport( 0, 0, width, height );
|
||||
|
||||
if (Cvar_VariableIntegerValue("vr_thirdPersonSpectator"))
|
||||
{
|
||||
//Blood red.. ish
|
||||
glClearColor( 0.12f, 0.0f, 0.05f, 1.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
//Black
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
glScissor( 0, 0, width, height );
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
|
||||
glScissor( 0, 0, 0, 0 );
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
}
|
||||
|
||||
void VR_DrawFrame( engine_t* engine ) {
|
||||
if (vr.weapon_zoomed) {
|
||||
vr.weapon_zoomLevel += 0.05;
|
||||
|
@ -375,39 +406,39 @@ void VR_DrawFrame( engine_t* engine ) {
|
|||
vr.fov_y = (fabs(fov.angleUp) + fabs(fov.angleDown)) * 180.0f / M_PI;
|
||||
}
|
||||
|
||||
// Set-up the compositor layers for this frame.
|
||||
// NOTE: Multiple independent layers are allowed, but they need to be added
|
||||
// in a depth consistent order.
|
||||
|
||||
XrCompositionLayerProjectionView projection_layer_elements[2] = {};
|
||||
|
||||
engine->appState.LayerCount = 0;
|
||||
memset(engine->appState.Layers, 0, sizeof(ovrCompositorLayer_Union) * ovrMaxLayerCount);
|
||||
|
||||
if (Cvar_VariableIntegerValue("vr_thirdPersonSpectator"))
|
||||
{
|
||||
//Blood red.. ish
|
||||
glClearColor( 0.12f, 0.0f, 0.05f, 1.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
//Black
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
}
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer;
|
||||
int swapchainIndex = engine->appState.Renderer.FrameBuffer.TextureSwapChainIndex;
|
||||
int glFramebuffer = engine->appState.Renderer.FrameBuffer.FrameBuffers[swapchainIndex];
|
||||
re.SetVRHeadsetParms(projectionMatrix.M, monoVRMatrix.M, glFramebuffer);
|
||||
|
||||
ovrFramebuffer_Acquire(frameBuffer);
|
||||
ovrFramebuffer_SetCurrent(frameBuffer);
|
||||
re.SetVRHeadsetParms(projectionMatrix.M, monoVRMatrix.M,
|
||||
engine->appState.Renderer.FrameBuffer.FrameBuffers[engine->appState.Renderer.FrameBuffer.TextureSwapChainIndex]);
|
||||
VR_ClearFrameBuffer(frameBuffer->ColorSwapChain.Width, frameBuffer->ColorSwapChain.Height);
|
||||
Com_Frame();
|
||||
ovrFramebuffer_Resolve(frameBuffer);
|
||||
ovrFramebuffer_Release(frameBuffer);
|
||||
ovrFramebuffer_SetNone();
|
||||
|
||||
if (!VR_useScreenLayer() && !(cl.snap.ps.pm_flags & PMF_FOLLOW && vr.follow_mode == VRFM_FIRSTPERSON)) {
|
||||
|
||||
XrCompositionLayerProjectionView projection_layer_elements[2] = {};
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer;
|
||||
|
||||
memset(&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView));
|
||||
projection_layer_elements[eye].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
|
||||
projection_layer_elements[eye].pose = XrPosef_Inverse(viewTransform[eye]);
|
||||
projection_layer_elements[eye].fov = projections[eye].fov;
|
||||
|
||||
memset(&projection_layer_elements[eye].subImage, 0, sizeof(XrSwapchainSubImage));
|
||||
projection_layer_elements[eye].subImage.swapchain = frameBuffer->ColorSwapChain.Handle;
|
||||
projection_layer_elements[eye].subImage.imageRect.offset.x = 0;
|
||||
projection_layer_elements[eye].subImage.imageRect.offset.y = 0;
|
||||
projection_layer_elements[eye].subImage.imageRect.extent.width = frameBuffer->ColorSwapChain.Width;
|
||||
projection_layer_elements[eye].subImage.imageRect.extent.height = frameBuffer->ColorSwapChain.Height;
|
||||
projection_layer_elements[eye].subImage.imageArrayIndex = eye;
|
||||
}
|
||||
|
||||
XrCompositionLayerProjection projection_layer = {};
|
||||
projection_layer.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION;
|
||||
projection_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
|
||||
|
@ -416,28 +447,6 @@ void VR_DrawFrame( engine_t* engine ) {
|
|||
projection_layer.viewCount = ovrMaxNumEyes;
|
||||
projection_layer.views = projection_layer_elements;
|
||||
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer;
|
||||
|
||||
memset(
|
||||
&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView));
|
||||
projection_layer_elements[eye].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
|
||||
|
||||
projection_layer_elements[eye].pose = XrPosef_Inverse(viewTransform[eye]);
|
||||
projection_layer_elements[eye].fov = projections[eye].fov;
|
||||
|
||||
memset(&projection_layer_elements[eye].subImage, 0, sizeof(XrSwapchainSubImage));
|
||||
projection_layer_elements[eye].subImage.swapchain =
|
||||
frameBuffer->ColorSwapChain.Handle;
|
||||
projection_layer_elements[eye].subImage.imageRect.offset.x = 0;
|
||||
projection_layer_elements[eye].subImage.imageRect.offset.y = 0;
|
||||
projection_layer_elements[eye].subImage.imageRect.extent.width =
|
||||
frameBuffer->ColorSwapChain.Width;
|
||||
projection_layer_elements[eye].subImage.imageRect.extent.height =
|
||||
frameBuffer->ColorSwapChain.Height;
|
||||
projection_layer_elements[eye].subImage.imageArrayIndex = 0;
|
||||
}
|
||||
|
||||
engine->appState.Layers[engine->appState.LayerCount++].Projection = projection_layer;
|
||||
} else {
|
||||
|
||||
|
@ -481,4 +490,7 @@ void VR_DrawFrame( engine_t* engine ) {
|
|||
endFrameInfo.layers = layers;
|
||||
|
||||
OXR(xrEndFrame(engine->appState.Session, &endFrameInfo));
|
||||
ovrFramebuffer_Resolve(frameBuffer);
|
||||
ovrFramebuffer_Release(frameBuffer);
|
||||
ovrFramebuffer_SetNone();
|
||||
}
|
||||
|
|
|
@ -73,6 +73,12 @@ bool ovrFramebuffer_Create(
|
|||
swapChainCreateInfo.arraySize = 2;
|
||||
swapChainCreateInfo.mipCount = 1;
|
||||
|
||||
// Enable Foveation on this swapchain
|
||||
XrSwapchainCreateInfoFoveationFB swapChainFoveationCreateInfo;
|
||||
memset(&swapChainFoveationCreateInfo, 0, sizeof(swapChainFoveationCreateInfo));
|
||||
swapChainFoveationCreateInfo.type = XR_TYPE_SWAPCHAIN_CREATE_INFO_FOVEATION_FB;
|
||||
swapChainCreateInfo.next = &swapChainFoveationCreateInfo;
|
||||
|
||||
frameBuffer->ColorSwapChain.Width = swapChainCreateInfo.width;
|
||||
frameBuffer->ColorSwapChain.Height = swapChainCreateInfo.height;
|
||||
|
||||
|
@ -220,6 +226,57 @@ void ovrRenderer_Destroy(ovrRenderer* renderer) {
|
|||
ovrFramebuffer_Destroy(&renderer->FrameBuffer);
|
||||
}
|
||||
|
||||
void ovrRenderer_SetFoveation(
|
||||
XrInstance* instance,
|
||||
XrSession* session,
|
||||
ovrRenderer* renderer,
|
||||
XrFoveationLevelFB level,
|
||||
float verticalOffset,
|
||||
XrFoveationDynamicFB dynamic) {
|
||||
PFN_xrCreateFoveationProfileFB pfnCreateFoveationProfileFB;
|
||||
OXR(xrGetInstanceProcAddr(
|
||||
*instance,
|
||||
"xrCreateFoveationProfileFB",
|
||||
(PFN_xrVoidFunction*)(&pfnCreateFoveationProfileFB)));
|
||||
|
||||
PFN_xrDestroyFoveationProfileFB pfnDestroyFoveationProfileFB;
|
||||
OXR(xrGetInstanceProcAddr(
|
||||
*instance,
|
||||
"xrDestroyFoveationProfileFB",
|
||||
(PFN_xrVoidFunction*)(&pfnDestroyFoveationProfileFB)));
|
||||
|
||||
PFN_xrUpdateSwapchainFB pfnUpdateSwapchainFB;
|
||||
OXR(xrGetInstanceProcAddr(
|
||||
*instance, "xrUpdateSwapchainFB", (PFN_xrVoidFunction*)(&pfnUpdateSwapchainFB)));
|
||||
|
||||
XrFoveationLevelProfileCreateInfoFB levelProfileCreateInfo;
|
||||
memset(&levelProfileCreateInfo, 0, sizeof(levelProfileCreateInfo));
|
||||
levelProfileCreateInfo.type = XR_TYPE_FOVEATION_LEVEL_PROFILE_CREATE_INFO_FB;
|
||||
levelProfileCreateInfo.level = level;
|
||||
levelProfileCreateInfo.verticalOffset = verticalOffset;
|
||||
levelProfileCreateInfo.dynamic = dynamic;
|
||||
|
||||
XrFoveationProfileCreateInfoFB profileCreateInfo;
|
||||
memset(&profileCreateInfo, 0, sizeof(profileCreateInfo));
|
||||
profileCreateInfo.type = XR_TYPE_FOVEATION_PROFILE_CREATE_INFO_FB;
|
||||
profileCreateInfo.next = &levelProfileCreateInfo;
|
||||
|
||||
XrFoveationProfileFB foveationProfile;
|
||||
|
||||
pfnCreateFoveationProfileFB(*session, &profileCreateInfo, &foveationProfile);
|
||||
|
||||
XrSwapchainStateFoveationFB foveationUpdateState;
|
||||
memset(&foveationUpdateState, 0, sizeof(foveationUpdateState));
|
||||
foveationUpdateState.type = XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB;
|
||||
foveationUpdateState.profile = foveationProfile;
|
||||
|
||||
pfnUpdateSwapchainFB(
|
||||
renderer->FrameBuffer.ColorSwapChain.Handle,
|
||||
(XrSwapchainStateBaseHeaderFB*)(&foveationUpdateState));
|
||||
|
||||
pfnDestroyFoveationProfileFB(foveationProfile);
|
||||
}
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#endif
|
||||
|
||||
//OpenXR
|
||||
#define XR_EYES_COUNT 2
|
||||
#define XR_USE_GRAPHICS_API_OPENGL_ES 1
|
||||
#define XR_USE_PLATFORM_ANDROID 1
|
||||
#include <EGL/egl.h>
|
||||
|
@ -33,7 +32,7 @@ typedef union {
|
|||
XrCompositionLayerCylinderKHR Cylinder;
|
||||
} ovrCompositorLayer_Union;
|
||||
|
||||
enum { ovrMaxLayerCount = 16 };
|
||||
enum { ovrMaxLayerCount = 1 };
|
||||
enum { ovrMaxNumEyes = 2 };
|
||||
|
||||
#define GL(func) func;
|
||||
|
@ -174,6 +173,13 @@ void ovrRenderer_Create(
|
|||
int suggestedEyeTextureWidth,
|
||||
int suggestedEyeTextureHeight);
|
||||
void ovrRenderer_Destroy(ovrRenderer* renderer);
|
||||
void ovrRenderer_SetFoveation(
|
||||
XrInstance* instance,
|
||||
XrSession* session,
|
||||
ovrRenderer* renderer,
|
||||
XrFoveationLevelFB level,
|
||||
float verticalOffset,
|
||||
XrFoveationDynamicFB dynamic);
|
||||
|
||||
void ovrTrackedController_Clear(ovrTrackedController* controller);
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ int main(int argc, char* argv[]) {
|
|||
VR_InitRenderer(engine);
|
||||
|
||||
qboolean hasFocus = qtrue;
|
||||
qboolean paused = qfalse;
|
||||
qboolean paused = qfalse;
|
||||
while (1) {
|
||||
if (hasFocus != g_HasFocus) {
|
||||
hasFocus = g_HasFocus;
|
||||
|
|
Loading…
Reference in a new issue