mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-24 21:11:05 +00:00
OpenXR multiview integrated
This commit is contained in:
parent
5947168966
commit
c321b97894
6 changed files with 63 additions and 140 deletions
|
@ -299,6 +299,8 @@ static void InitOpenGL( void )
|
|||
|
||||
// set default state
|
||||
GL_SetDefaultState();
|
||||
|
||||
VR_ReInitRenderer();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue