Use Quad layer for screen - and get resolution correct

This commit is contained in:
Simon 2022-12-09 21:47:29 +00:00
parent 2c00a2a40f
commit f650a3be1c
4 changed files with 35 additions and 370 deletions

View file

@ -900,7 +900,7 @@ void setHMDPosition( float x, float y, float z )
VectorSet(vr.hmdposition, x, y, z);
// if (s_useScreen != JKVR_useScreenLayer())
if (s_useScreen != JKVR_useScreenLayer())
{
s_useScreen = JKVR_useScreenLayer();
@ -1661,9 +1661,6 @@ void VR_LeaveVR( ) {
}
void VR_InitRenderer( ) {
int eyeW, eyeH;
VR_GetResolution(&eyeW, &eyeH);
// Get the viewport configuration info for the chosen viewport configuration type.
gAppState.ViewportConfig.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES;
@ -1854,8 +1851,7 @@ void * AppThreadFunction(void * parm ) {
SS_MULTIPLIER = 1.5f;
}
//Using a symmetrical render target
VR_GetResolution(&m_height, &m_width);
VR_GetResolution(&m_width, &m_height);
gAppState.CpuLevel = CPU_LEVEL;
gAppState.GpuLevel = GPU_LEVEL;
@ -2230,6 +2226,11 @@ void JKVR_UpdateControllers( )
void JKVR_getHMDOrientation() {//Get orientation
if (gAppState.PredictedDisplayTime == 0)
{
return;
}
// Get the HMD pose, predicted for the middle of the time period during which
// the new eye images will be displayed. The number of frames predicted ahead
// depends on the pipeline depth of the engine and the synthesis rate.
@ -2320,47 +2321,19 @@ void JKVR_submitFrame()
vr.fov_x = (fabs(fov.angleLeft) + fabs(fov.angleRight)) * 180.0f / M_PI;
vr.fov_y = (fabs(fov.angleUp) + fabs(fov.angleDown)) * 180.0f / M_PI;
//Projection used for drawing HUD models etc
float hudScale = M_PI * 15.0f / 180.0f;
const ovrMatrix4f monoVRMatrix = ovrMatrix4f_CreateProjectionFov(
-hudScale, hudScale, hudScale, -hudScale, 1.0f, 0.0f );
const ovrMatrix4f projectionMatrix = ovrMatrix4f_CreateProjectionFov(
fov.angleLeft / vr.cgzoommode ? 1.3f : 1.0f,
fov.angleRight / vr.cgzoommode ? 1.3f : 1.0f,
fov.angleUp / vr.cgzoommode ? 1.3f : 1.0f,
fov.angleDown / vr.cgzoommode ? 1.3f : 1.0f,
1.0f, 0.0f );
if (vr.cgzoommode)
{
fov.angleLeft /= 1.3f;
fov.angleRight /= 1.3f;
fov.angleUp /= 1.3f;
fov.angleDown /= 1.3f;
}
gAppState.LayerCount = 0;
memset(gAppState.Layers, 0, sizeof(ovrCompositorLayer_Union) * ovrMaxLayerCount);
XrCompositionLayerProjectionView projection_layer_elements[2] = {};
if (!JKVR_useScreenLayer()) {
/* for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
ovrFramebuffer* frameBuffer = &(gAppState.Renderer.FrameBuffer[eye]);
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 = 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;
projection_layer.layerFlags |= XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT;
projection_layer.space = gAppState.CurrentSpace;
projection_layer.viewCount = ovrMaxNumEyes;
projection_layer.views = projection_layer_elements; */
XrCompositionLayerProjection projection_layer = {};
projection_layer.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION;
projection_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
@ -2395,34 +2368,34 @@ void JKVR_submitFrame()
gAppState.Layers[gAppState.LayerCount++].Projection = projection_layer;
} else {
// Build the cylinder layer
XrCompositionLayerCylinderKHR cylinder_layer = {};
// Build the quad layer
XrCompositionLayerQuad quad_layer = {};
int width = gAppState.Renderer.FrameBuffer[0].ColorSwapChain.Width;
int height = gAppState.Renderer.FrameBuffer[0].ColorSwapChain.Height;
cylinder_layer.type = XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR;
cylinder_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
cylinder_layer.space = gAppState.CurrentSpace;
cylinder_layer.eyeVisibility = XR_EYE_VISIBILITY_BOTH;
memset(&cylinder_layer.subImage, 0, sizeof(XrSwapchainSubImage));
cylinder_layer.subImage.swapchain = gAppState.Renderer.FrameBuffer[0].ColorSwapChain.Handle;
cylinder_layer.subImage.imageRect.offset.x = 0;
cylinder_layer.subImage.imageRect.offset.y = 0;
cylinder_layer.subImage.imageRect.extent.width = width;
cylinder_layer.subImage.imageRect.extent.height = height;
cylinder_layer.subImage.imageArrayIndex = 0;
quad_layer.type = XR_TYPE_COMPOSITION_LAYER_QUAD;
quad_layer.next = NULL;
quad_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
quad_layer.space = gAppState.CurrentSpace;
quad_layer.eyeVisibility = XR_EYE_VISIBILITY_BOTH;
memset(&quad_layer.subImage, 0, sizeof(XrSwapchainSubImage));
quad_layer.subImage.swapchain = gAppState.Renderer.FrameBuffer[0].ColorSwapChain.Handle;
quad_layer.subImage.imageRect.offset.x = 0;
quad_layer.subImage.imageRect.offset.y = 0;
quad_layer.subImage.imageRect.extent.width = width;
quad_layer.subImage.imageRect.extent.height = height;
quad_layer.subImage.imageArrayIndex = 0;
const XrVector3f axis = {0.0f, 1.0f, 0.0f};
XrVector3f pos = {
gAppState.xfStageFromHead.position.x - sin(radians(vr.hmdorientation_snap[YAW])) * 4.0f,
-0.25f,
1.0f,
gAppState.xfStageFromHead.position.z - cos(radians(vr.hmdorientation_snap[YAW])) * 4.0f
};
cylinder_layer.pose.orientation = XrQuaternionf_CreateFromVectorAngle(axis, radians(vr.hmdorientation_snap[YAW]));
cylinder_layer.pose.position = pos;
cylinder_layer.radius = 12.0f;
cylinder_layer.centralAngle = M_PI * 0.5f;
cylinder_layer.aspectRatio = m_width / (float)m_height / 0.75f;
quad_layer.pose.orientation = XrQuaternionf_CreateFromVectorAngle(axis, radians(vr.hmdorientation_snap[YAW]));
quad_layer.pose.position = pos;
XrExtent2Df size = {5.0f, 4.5f};
quad_layer.size = size;
gAppState.Layers[gAppState.LayerCount++].Cylinder = cylinder_layer;
gAppState.Layers[gAppState.LayerCount++].Quad = quad_layer;
}
// Compose the layers for this frame.

View file

@ -153,7 +153,7 @@ ovrApp
typedef union {
XrCompositionLayerProjection Projection;
XrCompositionLayerCylinderKHR Cylinder;
XrCompositionLayerQuad Quad;
} ovrCompositorLayer_Union;
#define GL(func) func;

View file

@ -1,162 +0,0 @@
/************************************************************************************
Filename : VrCompositor.c
*************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/prctl.h> // for prctl( PR_SET_NAME )
#include <android/log.h>
#include <android/window.h> // for AWINDOW_FLAG_KEEP_SCREEN_ON
//OpenXR
#define XR_USE_GRAPHICS_API_OPENGL_ES 1
#define XR_USE_PLATFORM_ANDROID 1
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
#include <jni.h>
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>
#include <openxr/openxr_oculus.h>
#include <openxr/openxr_oculus_helpers.h>
#include "VrCompositor.h"
/*
================================================================================
ovrScene
================================================================================
*/
void ovrScene_Clear( ovrScene * scene )
{
scene->CreatedScene = false;
ovrRenderer_Clear( &scene->CylinderRenderer );
scene->CylinderWidth = 0;
scene->CylinderHeight = 0;
}
bool ovrScene_IsCreated( ovrScene * scene )
{
return scene->CreatedScene;
}
void ovrScene_Create( int width, int height, ovrScene * scene )
{
// Create Cylinder renderer
{
scene->CylinderWidth = width;
scene->CylinderHeight = height;
//Create cylinder renderer
ovrRenderer_Create( width, height, &scene->CylinderRenderer );
}
scene->CreatedScene = true;
}
void ovrScene_Destroy( ovrScene * scene )
{
ovrRenderer_Destroy( &scene->CylinderRenderer );
scene->CreatedScene = false;
}
/*
================================================================================
ovrRenderer
================================================================================
*/
// Assumes landscape cylinder shape.
static ovrMatrix4f CylinderModelMatrix( const int texWidth, const int texHeight,
const ovrVector3f translation,
const float rotateYaw,
const float rotatePitch,
const float radius,
const float density )
{
const ovrMatrix4f scaleMatrix = ovrMatrix4f_CreateScale( radius, radius * (float)texHeight * VRAPI_PI / density, radius / 2 );
const ovrMatrix4f transMatrix = ovrMatrix4f_CreateTranslation( translation.x, translation.y, translation.z );
const ovrMatrix4f rotXMatrix = ovrMatrix4f_CreateRotation( rotateYaw, 0.0f, 0.0f );
const ovrMatrix4f rotYMatrix = ovrMatrix4f_CreateRotation( 0.0f, rotatePitch, 0.0f );
const ovrMatrix4f m0 = ovrMatrix4f_Multiply( &transMatrix, &scaleMatrix );
const ovrMatrix4f m1 = ovrMatrix4f_Multiply( &rotXMatrix, &m0 );
const ovrMatrix4f m2 = ovrMatrix4f_Multiply( &rotYMatrix, &m1 );
return m2;
}
extern cvar_t *vr_screen_dist;
ovrLayerCylinder2 BuildCylinderLayer( ovrRenderer * cylinderRenderer,
const int textureWidth, const int textureHeight,
const ovrTracking2 * tracking, float rotatePitch )
{
ovrLayerCylinder2 layer = vrapi_DefaultLayerCylinder2();
const float fadeLevel = 1.0f;
layer.Header.ColorScale.x =
layer.Header.ColorScale.y =
layer.Header.ColorScale.z =
layer.Header.ColorScale.w = fadeLevel;
layer.Header.SrcBlend = VRAPI_FRAME_LAYER_BLEND_SRC_ALPHA;
layer.Header.DstBlend = VRAPI_FRAME_LAYER_BLEND_ONE_MINUS_SRC_ALPHA;
layer.HeadPose = tracking->HeadPose;
const float density = 15000.0f;
const float rotateYaw = 0.0f;
const float radius = 10.0f;
const ovrVector3f translation = { 0.0f, vr.hmdposition_snap[1]/1.8f, -vr_screen_dist->value };
ovrMatrix4f cylinderTransform =
CylinderModelMatrix( textureWidth, textureHeight, translation,
rotateYaw, rotatePitch, radius, density );
const float circScale = density * 0.5f / textureWidth;
const float circBias = -circScale * ( 0.5f * ( 1.0f - 1.0f / circScale ) );
for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ )
{
ovrFramebuffer * cylinderFrameBuffer = &cylinderRenderer->FrameBuffer[eye];
ovrMatrix4f modelViewMatrix = ovrMatrix4f_Multiply( &tracking->Eye[eye].ViewMatrix, &cylinderTransform );
layer.Textures[eye].TexCoordsFromTanAngles = ovrMatrix4f_Inverse( &modelViewMatrix );
layer.Textures[eye].ColorSwapChain = cylinderFrameBuffer->ColorTextureSwapChain;
layer.Textures[eye].SwapChainIndex = cylinderFrameBuffer->TextureSwapChainIndex;
// Texcoord scale and bias is just a representation of the aspect ratio. The positioning
// of the cylinder is handled entirely by the TexCoordsFromTanAngles matrix.
const float texScaleX = circScale;
const float texBiasX = circBias;
const float texScaleY = -0.5f;
const float texBiasY = texScaleY * ( 0.5f * ( 1.0f - ( 1.0f / texScaleY ) ) );
layer.Textures[eye].TextureMatrix.M[0][0] = texScaleX;
layer.Textures[eye].TextureMatrix.M[0][2] = texBiasX;
layer.Textures[eye].TextureMatrix.M[1][1] = texScaleY;
layer.Textures[eye].TextureMatrix.M[1][2] = -texBiasY;
layer.Textures[eye].TextureRect.width = 1.0f;
layer.Textures[eye].TextureRect.height = 1.0f;
}
return layer;
}

View file

@ -1,146 +0,0 @@
/************************************************************************************
Filename : VrCompositor.h
*************************************************************************************/
#include "VrInput.h"
#define CHECK_GL_ERRORS
#ifdef CHECK_GL_ERRORS
static const char * GlErrorString( GLenum error )
{
switch ( error )
{
case GL_NO_ERROR: return "GL_NO_ERROR";
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
default: return "unknown";
}
}
static void GLCheckErrors( int line )
{
for ( int i = 0; i < 10; i++ )
{
const GLenum error = glGetError();
if ( error == GL_NO_ERROR )
{
break;
}
ALOGE( "GL error on line %d: %s", line, GlErrorString( error ) );
}
}
#define GL( func ) func; GLCheckErrors( __LINE__ );
#else // CHECK_GL_ERRORS
#define GL( func ) func;
#endif // CHECK_GL_ERRORS
/*
================================================================================
ovrFramebuffer
================================================================================
*/
void ovrFramebuffer_SetCurrent( ovrFramebuffer * frameBuffer );
void ovrFramebuffer_Destroy( ovrFramebuffer * frameBuffer );
void ovrFramebuffer_SetNone();
void ovrFramebuffer_Resolve( ovrFramebuffer * frameBuffer );
void ovrFramebuffer_Advance( ovrFramebuffer * frameBuffer );
void ovrFramebuffer_ClearEdgeTexels( ovrFramebuffer * frameBuffer );
void ovrRenderer_Clear( ovrRenderer * renderer );
void ovrRenderer_Create(XrSession session, int width, int height, ovrRenderer * renderer );
void ovrRenderer_Destroy( ovrRenderer * renderer );
/*
================================================================================
ovrGeometry
================================================================================
*/
typedef struct
{
GLuint Index;
GLint Size;
GLenum Type;
GLboolean Normalized;
GLsizei Stride;
const GLvoid * Pointer;
} ovrVertexAttribPointer;
#define MAX_VERTEX_ATTRIB_POINTERS 3
typedef struct
{
GLuint VertexBuffer;
GLuint IndexBuffer;
GLuint VertexArrayObject;
int VertexCount;
int IndexCount;
ovrVertexAttribPointer VertexAttribs[MAX_VERTEX_ATTRIB_POINTERS];
} ovrGeometry;
/*
================================================================================
ovrProgram
================================================================================
*/
#define MAX_PROGRAM_UNIFORMS 8
#define MAX_PROGRAM_TEXTURES 8
typedef struct
{
GLuint Program;
GLuint VertexShader;
GLuint FragmentShader;
// These will be -1 if not used by the program.
GLint UniformLocation[MAX_PROGRAM_UNIFORMS]; // ProgramUniforms[].name
GLint UniformBinding[MAX_PROGRAM_UNIFORMS]; // ProgramUniforms[].name
GLint Textures[MAX_PROGRAM_TEXTURES]; // Texture%i
} ovrProgram;
/*
================================================================================
ovrScene
================================================================================
*/
typedef struct
{
bool CreatedScene;
//Proper renderer for stereo rendering to the cylinder layer
ovrRenderer CylinderRenderer;
int CylinderWidth;
int CylinderHeight;
} ovrScene;
void ovrScene_Clear( ovrScene * scene );
void ovrScene_Create( int width, int height, ovrScene * scene );
void ovrScene_Destroy( ovrScene * scene );