OpenXR multiview integrated

This commit is contained in:
Lubos 2022-04-25 16:48:09 +02:00
parent 5947168966
commit c321b97894
6 changed files with 63 additions and 140 deletions

View file

@ -299,6 +299,8 @@ static void InitOpenGL( void )
// set default state
GL_SetDefaultState();
VR_ReInitRenderer();
}
/*

View file

@ -43,6 +43,7 @@ XrSpace leftControllerAimSpace = XR_NULL_HANDLE;
XrSpace rightControllerAimSpace = XR_NULL_HANDLE;
XrSpace leftControllerGripSpace = XR_NULL_HANDLE;
XrSpace rightControllerGripSpace = XR_NULL_HANDLE;
qboolean inputInitialized = qfalse;
qboolean useSimpleProfile = qfalse;
typedef struct {
@ -635,6 +636,9 @@ XrActionStateVector2f GetActionStateVector2(XrAction action) {
void IN_VRInit( void )
{
if (inputInitialized)
return;
memset(&vr, 0, sizeof(vr));
engine_t *engine = VR_GetEngine();
@ -842,6 +846,7 @@ void IN_VRInit( void )
}
}
}
inputInitialized = qtrue;
}
static void IN_VRController( qboolean isRightController, XrPosef pose )

View file

@ -21,7 +21,6 @@
extern vr_clientinfo_t vr;
XrView* projections;
GLboolean stageSupported = GL_FALSE;
void VR_UpdateStageBounds(ovrApp* pappState) {
XrExtent2Df stageBounds = {};
@ -226,6 +225,7 @@ void VR_InitRenderer( engine_t* engine ) {
OXR(xrEnumerateReferenceSpaces(
engine->appState.Session, numOutputSpaces, &numOutputSpaces, referenceSpaces));
GLboolean stageSupported = GL_FALSE;
for (uint32_t i = 0; i < numOutputSpaces; i++) {
if (referenceSpaces[i] == XR_REFERENCE_SPACE_TYPE_STAGE) {
stageSupported = GL_TRUE;
@ -272,11 +272,18 @@ void VR_InitRenderer( engine_t* engine ) {
engine->appState.ViewConfigurationView[0].recommendedImageRectHeight);
}
void VR_DestroyRenderer( engine_t* engine ) {
void VR_DestroyRenderer( engine_t* engine )
{
ovrRenderer_Destroy(&engine->appState.Renderer);
free(projections);
}
void VR_ReInitRenderer()
{
VR_DestroyRenderer( VR_GetEngine() );
VR_InitRenderer( VR_GetEngine() );
}
void VR_DrawFrame( engine_t* engine ) {
if (vr.weapon_zoomed) {
vr.weapon_zoomLevel += 0.05;
@ -435,6 +442,8 @@ void VR_DrawFrame( engine_t* engine ) {
} else {
// Build the cylinder layer
int width = engine->appState.Renderer.FrameBuffer.ColorSwapChain.Width;
int height = engine->appState.Renderer.FrameBuffer.ColorSwapChain.Height;
XrCompositionLayerCylinderKHR cylinder_layer = {};
cylinder_layer.type = XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR;
cylinder_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
@ -444,16 +453,16 @@ void VR_DrawFrame( engine_t* engine ) {
cylinder_layer.subImage.swapchain = engine->appState.Renderer.FrameBuffer.ColorSwapChain.Handle;
cylinder_layer.subImage.imageRect.offset.x = 0;
cylinder_layer.subImage.imageRect.offset.y = 0;
cylinder_layer.subImage.imageRect.extent.width = engine->appState.Renderer.FrameBuffer.ColorSwapChain.Width;
cylinder_layer.subImage.imageRect.extent.height = engine->appState.Renderer.FrameBuffer.ColorSwapChain.Height;
cylinder_layer.subImage.imageRect.extent.width = width;
cylinder_layer.subImage.imageRect.extent.height = height;
cylinder_layer.subImage.imageArrayIndex = 0;
const XrVector3f axis = {0.0f, 1.0f, 0.0f};
const XrVector3f pos = {xfStageFromHead.position.x, -0.25f, xfStageFromHead.position.z - 1.0f};
const XrVector3f pos = {xfStageFromHead.position.x, -0.25f, xfStageFromHead.position.z - 4.0f};
cylinder_layer.pose.orientation = XrQuaternionf_CreateFromVectorAngle(axis, 0);
cylinder_layer.pose.position = pos;
cylinder_layer.radius = 1.0f;
cylinder_layer.radius = 12.0f;
cylinder_layer.centralAngle = MATH_PI * 0.5f;
cylinder_layer.aspectRatio = 1.0f;
cylinder_layer.aspectRatio = (float)height / width / 0.75f;
engine->appState.Layers[engine->appState.LayerCount++].Cylinder = cylinder_layer;
}

View file

@ -9,6 +9,7 @@ void VR_GetResolution( engine_t* engine, int *pWidth, int *pHeight );
void VR_InitRenderer( engine_t* engine );
void VR_DestroyRenderer( engine_t* engine );
void VR_DrawFrame( engine_t* engine );
void VR_ReInitRenderer();
#endif

View file

@ -18,7 +18,13 @@ Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rig
#include <sys/prctl.h>
#include <assert.h>
const int NUM_MULTI_SAMPLES = 4;
typedef void(GL_APIENTRY* PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)(
GLenum target,
GLenum attachment,
GLuint texture,
GLint level,
GLint baseViewIndex,
GLsizei numViews);
/*
================================================================================
@ -32,7 +38,6 @@ ovrFramebuffer
void ovrFramebuffer_Clear(ovrFramebuffer* frameBuffer) {
frameBuffer->Width = 0;
frameBuffer->Height = 0;
frameBuffer->Multisamples = 0;
frameBuffer->TextureSwapChainLength = 0;
frameBuffer->TextureSwapChainIndex = 0;
frameBuffer->ColorSwapChain.Handle = XR_NULL_HANDLE;
@ -46,70 +51,28 @@ void ovrFramebuffer_Clear(ovrFramebuffer* frameBuffer) {
bool ovrFramebuffer_Create(
XrSession session,
ovrFramebuffer* frameBuffer,
const GLenum colorFormat,
const int width,
const int height,
const int multisamples) {
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT =
(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)eglGetProcAddress(
"glRenderbufferStorageMultisampleEXT");
PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT =
(PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)eglGetProcAddress(
"glFramebufferTexture2DMultisampleEXT");
const int height) {
frameBuffer->Width = width;
frameBuffer->Height = height;
frameBuffer->Multisamples = multisamples;
GLenum requestedGLFormat = colorFormat;
// Get the number of supported formats.
uint32_t numInputFormats = 0;
uint32_t numOutputFormats = 0;
OXR(xrEnumerateSwapchainFormats(session, numInputFormats, &numOutputFormats, NULL));
// Allocate an array large enough to contain the supported formats.
numInputFormats = numOutputFormats;
int64_t* supportedFormats = (int64_t*)malloc(numOutputFormats * sizeof(int64_t));
if (supportedFormats != NULL) {
OXR(xrEnumerateSwapchainFormats(
session, numInputFormats, &numOutputFormats, supportedFormats));
}
// Verify the requested format is supported.
uint64_t selectedFormat = 0;
for (uint32_t i = 0; i < numOutputFormats; i++) {
if (supportedFormats[i] == requestedGLFormat) {
selectedFormat = supportedFormats[i];
break;
}
}
free(supportedFormats);
if (selectedFormat == 0) {
ALOGE("Format not supported");
}
PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glFramebufferTextureMultiviewOVR =
(PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC)eglGetProcAddress(
"glFramebufferTextureMultiviewOVR");
XrSwapchainCreateInfo swapChainCreateInfo;
memset(&swapChainCreateInfo, 0, sizeof(swapChainCreateInfo));
swapChainCreateInfo.type = XR_TYPE_SWAPCHAIN_CREATE_INFO;
swapChainCreateInfo.usageFlags =
XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
swapChainCreateInfo.format = selectedFormat;
swapChainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
swapChainCreateInfo.format = GL_RGBA8;
swapChainCreateInfo.sampleCount = 1;
swapChainCreateInfo.width = width;
swapChainCreateInfo.height = height;
swapChainCreateInfo.faceCount = 1;
swapChainCreateInfo.arraySize = 1;
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;
@ -142,70 +105,32 @@ bool ovrFramebuffer_Create(
// Create the color buffer texture.
const GLuint colorTexture = frameBuffer->ColorSwapChainImage[i].image;
GLenum colorTextureTarget = GL_TEXTURE_2D;
GL(glBindTexture(colorTextureTarget, colorTexture));
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GL(glBindTexture(colorTextureTarget, 0));
GLfloat borderColor[] = {0.0f, 0.0f, 0.0f, 0.0f};
GLenum textureTarget = GL_TEXTURE_2D_ARRAY;
GL(glBindTexture(textureTarget, colorTexture));
GL(glTexParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, borderColor));
GL(glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GL(glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
GL(glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GL(glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GL(glBindTexture(textureTarget, 0));
if (multisamples > 1 && glRenderbufferStorageMultisampleEXT != NULL &&
glFramebufferTexture2DMultisampleEXT != NULL) {
// Create multisampled depth buffer.
GL(glGenRenderbuffers(1, &frameBuffer->DepthBuffers[i]));
GL(glBindRenderbuffer(GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
GL(glRenderbufferStorageMultisampleEXT(
GL_RENDERBUFFER, multisamples, GL_DEPTH_COMPONENT24, width, height));
GL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
// Create depth buffer.
GL(glGenTextures(1, &frameBuffer->DepthBuffers[i]));
GL(glBindTexture(textureTarget, frameBuffer->DepthBuffers[i]));
GL(glTexStorage3D(textureTarget, 1, GL_DEPTH_COMPONENT24, width, height, 2));
GL(glBindTexture(textureTarget, 0));
// Create the frame buffer.
// NOTE: glFramebufferTexture2DMultisampleEXT only works with GL_FRAMEBUFFER.
GL(glGenFramebuffers(1, &frameBuffer->FrameBuffers[i]));
GL(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer->FrameBuffers[i]));
GL(glFramebufferTexture2DMultisampleEXT(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
colorTexture,
0,
multisamples));
GL(glFramebufferRenderbuffer(
GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,
frameBuffer->DepthBuffers[i]));
GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER));
GL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
if (renderFramebufferStatus != GL_FRAMEBUFFER_COMPLETE) {
ALOGE(
"Incomplete frame buffer object: %d", renderFramebufferStatus);
return false;
}
} else {
// Create depth buffer.
GL(glGenRenderbuffers(1, &frameBuffer->DepthBuffers[i]));
GL(glBindRenderbuffer(GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
GL(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height));
GL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
// Create the frame buffer.
GL(glGenFramebuffers(1, &frameBuffer->FrameBuffers[i]));
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer->FrameBuffers[i]));
GL(glFramebufferRenderbuffer(
GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,
frameBuffer->DepthBuffers[i]));
GL(glFramebufferTexture2D(
GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0));
GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
if (renderFramebufferStatus != GL_FRAMEBUFFER_COMPLETE) {
ALOGE(
"Incomplete frame buffer object: %d", renderFramebufferStatus);
return false;
}
// Create the frame buffer.
GL(glGenFramebuffers(1, &frameBuffer->FrameBuffers[i]));
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer->FrameBuffers[i]));
GL(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, frameBuffer->DepthBuffers[i], 0, 0, 2));
GL(glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorTexture, 0, 0, 2));
GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
if (renderFramebufferStatus != GL_FRAMEBUFFER_COMPLETE) {
ALOGE("Incomplete frame buffer object: %d", renderFramebufferStatus);
return false;
}
}
@ -287,10 +212,8 @@ void ovrRenderer_Create(
ovrFramebuffer_Create(
session,
&renderer->FrameBuffer,
GL_RGBA8,
suggestedEyeTextureWidth,
suggestedEyeTextureHeight,
NUM_MULTI_SAMPLES);
suggestedEyeTextureHeight);
}
void ovrRenderer_Destroy(ovrRenderer* renderer) {

View file

@ -25,22 +25,6 @@
#define MATH_PI 3.14159265358979323846f
#if !defined(GL_EXT_multisampled_render_to_texture)
typedef void(GL_APIENTRY* PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(
GLenum target,
GLsizei samples,
GLenum internalformat,
GLsizei width,
GLsizei height);
typedef void(GL_APIENTRY* PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)(
GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture,
GLint level,
GLsizei samples);
#endif
#define ALOGE(...) printf(__VA_ARGS__)
#define ALOGV(...) printf(__VA_ARGS__)
@ -70,7 +54,6 @@ typedef struct {
typedef struct {
int Width;
int Height;
int Multisamples;
uint32_t TextureSwapChainLength;
uint32_t TextureSwapChainIndex;
ovrSwapChain ColorSwapChain;