mirror of
https://github.com/DrBeef/JKXR.git
synced 2024-11-21 19:51:33 +00:00
Use Quad layer for screen - and get resolution correct
This commit is contained in:
parent
2c00a2a40f
commit
f650a3be1c
4 changed files with 35 additions and 370 deletions
|
@ -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.
|
||||
|
|
|
@ -153,7 +153,7 @@ ovrApp
|
|||
|
||||
typedef union {
|
||||
XrCompositionLayerProjection Projection;
|
||||
XrCompositionLayerCylinderKHR Cylinder;
|
||||
XrCompositionLayerQuad Quad;
|
||||
} ovrCompositorLayer_Union;
|
||||
|
||||
#define GL(func) func;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 );
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue