mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
OpenXR - Stereo without multiview added
This commit is contained in:
parent
5e2ecb5ebb
commit
1df1d79b9e
@ -5,6 +5,8 @@
|
||||
#include "Common/Thread/ThreadUtil.h"
|
||||
#include "Common/VR/PPSSPPVR.h"
|
||||
|
||||
#include "Core/Config.h"
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "Common/MemoryUtil.h"
|
||||
#include "Common/Math/math_util.h"
|
||||
@ -233,15 +235,7 @@ bool GLRenderManager::ThreadFrame() {
|
||||
INFO_LOG(G3D, "Running first frame (%d)", threadFrame_);
|
||||
firstFrame = false;
|
||||
}
|
||||
|
||||
if (IsVRBuild()) {
|
||||
if (PreVRRender()) {
|
||||
Run(threadFrame_);
|
||||
PostVRRender();
|
||||
}
|
||||
} else {
|
||||
Run(threadFrame_);
|
||||
}
|
||||
Run(threadFrame_);
|
||||
|
||||
VLOG("PULL: Finished frame %d", threadFrame_);
|
||||
} while (!nextFrame);
|
||||
@ -564,8 +558,7 @@ void GLRenderManager::EndSubmitFrame(int frame) {
|
||||
}
|
||||
|
||||
// Render thread
|
||||
void GLRenderManager::Run(int frame) {
|
||||
BeginSubmitFrame(frame);
|
||||
void GLRenderManager::Render(int frame) {
|
||||
|
||||
FrameData &frameData = frameData_[frame];
|
||||
|
||||
@ -584,6 +577,7 @@ void GLRenderManager::Run(int frame) {
|
||||
}
|
||||
|
||||
queueRunner_.RunSteps(stepsOnThread, skipGLCalls_);
|
||||
|
||||
stepsOnThread.clear();
|
||||
|
||||
if (!skipGLCalls_) {
|
||||
@ -591,8 +585,30 @@ void GLRenderManager::Run(int frame) {
|
||||
iter->MapDevice(bufferStrategy_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (frameData.type) {
|
||||
// Render thread
|
||||
void GLRenderManager::Run(int frame) {
|
||||
BeginSubmitFrame(frame);
|
||||
|
||||
if (IsVRBuild()) {
|
||||
if (PreVRRender()) {
|
||||
int passes = 1;
|
||||
if (!IsMultiviewSupported() && g_Config.bEnableStereo) {
|
||||
passes = 2;
|
||||
}
|
||||
for (int i = 0; i < passes; i++) {
|
||||
PreVRFrameRender(i);
|
||||
Render(frame);
|
||||
PostVRFrameRender();
|
||||
}
|
||||
PostVRRender();
|
||||
}
|
||||
} else {
|
||||
Render(frame);
|
||||
}
|
||||
|
||||
switch (frameData_[frame].type) {
|
||||
case GLRRunType::END:
|
||||
EndSubmitFrame(frame);
|
||||
break;
|
||||
|
@ -377,6 +377,7 @@ public:
|
||||
void BeginFrame();
|
||||
// Can run on a different thread!
|
||||
void Finish();
|
||||
void Render(int frame);
|
||||
void Run(int frame);
|
||||
|
||||
// Zaps queued up commands. Use if you know there's a risk you've queued up stuff that has already been deleted. Can happen during in-game shutdown.
|
||||
|
@ -225,7 +225,7 @@ bool PreVRRender() {
|
||||
VR_SetConfig(VR_CONFIG_VIEWPORT_VALID, true);
|
||||
}
|
||||
|
||||
if (VR_BeginFrame(VR_GetEngine())) {
|
||||
if (VR_InitFrame(VR_GetEngine())) {
|
||||
|
||||
// Decide if the scene is 3D or not
|
||||
if (g_Config.bEnableVR && !VR_GetConfig(VR_CONFIG_FORCE_2D) && (VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) > 15)) {
|
||||
@ -245,9 +245,21 @@ bool PreVRRender() {
|
||||
}
|
||||
|
||||
void PostVRRender() {
|
||||
VR_FinishFrame(VR_GetEngine());
|
||||
}
|
||||
|
||||
void PreVRFrameRender(int fboIndex) {
|
||||
VR_BeginFrame(VR_GetEngine(), fboIndex);
|
||||
}
|
||||
|
||||
void PostVRFrameRender() {
|
||||
VR_EndFrame(VR_GetEngine());
|
||||
}
|
||||
|
||||
int GetVRFBOIndex() {
|
||||
return VR_GetConfig(VR_CONFIG_CURRENT_FBO);
|
||||
}
|
||||
|
||||
bool IsMultiviewSupported() {
|
||||
return false;
|
||||
}
|
||||
|
@ -17,6 +17,9 @@ void UpdateVRScreenKey(const KeyInput &key);
|
||||
void BindVRFramebuffer();
|
||||
bool PreVRRender();
|
||||
void PostVRRender();
|
||||
void PreVRFrameRender(int fboIndex);
|
||||
void PostVRFrameRender();
|
||||
int GetVRFBOIndex();
|
||||
bool IsMultiviewSupported();
|
||||
bool IsFlatVRScene();
|
||||
bool Is2DVRObject(float* projMatrix, bool ortho);
|
||||
@ -37,6 +40,9 @@ inline void UpdateVRScreenKey(const KeyInput &key) {}
|
||||
inline void BindVRFramebuffer() {}
|
||||
inline bool PreVRRender() { return false; }
|
||||
inline void PostVRRender() {}
|
||||
inline void PreVRFrameRender(int fboIndex) {}
|
||||
inline void PostVRFrameRender() {}
|
||||
inline int GetVRFBOIndex() { return 0; }
|
||||
inline bool IsMultiviewSupported() { return false; }
|
||||
inline bool IsFlatVRScene() { return true; }
|
||||
inline bool Is2DVRObject(float* projMatrix, bool ortho) { return false; }
|
||||
|
@ -92,7 +92,6 @@ typedef struct {
|
||||
typedef struct {
|
||||
int Width;
|
||||
int Height;
|
||||
bool Multiview;
|
||||
uint32_t TextureSwapChainLength;
|
||||
uint32_t TextureSwapChainIndex;
|
||||
ovrSwapChain ColorSwapChain;
|
||||
@ -104,7 +103,8 @@ typedef struct {
|
||||
} ovrFramebuffer;
|
||||
|
||||
typedef struct {
|
||||
ovrFramebuffer FrameBuffer;
|
||||
bool Multiview;
|
||||
ovrFramebuffer FrameBuffer[ovrMaxNumEyes];
|
||||
} ovrRenderer;
|
||||
|
||||
typedef struct {
|
||||
|
@ -47,12 +47,10 @@ bool ovrFramebuffer_Create(XrSession session, ovrFramebuffer* frameBuffer, int w
|
||||
|
||||
frameBuffer->Width = width;
|
||||
frameBuffer->Height = height;
|
||||
frameBuffer->Multiview = multiview;
|
||||
|
||||
if (strstr((const char*)glGetString(GL_EXTENSIONS), "GL_OVR_multiview2") == nullptr)
|
||||
{
|
||||
ALOGE("OpenGL implementation does not support GL_OVR_multiview2 extension.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
typedef void (*PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR)(GLenum, GLenum, GLuint, GLint, GLint, GLsizei);
|
||||
@ -60,7 +58,6 @@ bool ovrFramebuffer_Create(XrSession session, ovrFramebuffer* frameBuffer, int w
|
||||
if (!glFramebufferTextureMultiviewOVR)
|
||||
{
|
||||
ALOGE("Can not get proc address for glFramebufferTextureMultiviewOVR.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
XrSwapchainCreateInfo swapChainCreateInfo;
|
||||
@ -200,15 +197,24 @@ ovrRenderer
|
||||
*/
|
||||
|
||||
void ovrRenderer_Clear(ovrRenderer* renderer) {
|
||||
ovrFramebuffer_Clear(&renderer->FrameBuffer);
|
||||
for (int i = 0; i < ovrMaxNumEyes; i++) {
|
||||
ovrFramebuffer_Clear(&renderer->FrameBuffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ovrRenderer_Create(XrSession session, ovrRenderer* renderer, int width, int height, bool multiview) {
|
||||
ovrFramebuffer_Create(session, &renderer->FrameBuffer, width, height, multiview);
|
||||
renderer->Multiview = multiview;
|
||||
int instances = renderer->Multiview ? 1 : ovrMaxNumEyes;
|
||||
for (int i = 0; i < instances; i++) {
|
||||
ovrFramebuffer_Create(session, &renderer->FrameBuffer[i], width, height, multiview);
|
||||
}
|
||||
}
|
||||
|
||||
void ovrRenderer_Destroy(ovrRenderer* renderer) {
|
||||
ovrFramebuffer_Destroy(&renderer->FrameBuffer);
|
||||
int instances = renderer->Multiview ? 1 : ovrMaxNumEyes;
|
||||
for (int i = 0; i < instances; i++) {
|
||||
ovrFramebuffer_Destroy(&renderer->FrameBuffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -235,7 +235,7 @@ void VR_ClearFrameBuffer( int width, int height) {
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
}
|
||||
|
||||
bool VR_BeginFrame( engine_t* engine ) {
|
||||
bool VR_InitFrame( engine_t* engine ) {
|
||||
GLboolean stageBoundsDirty = GL_TRUE;
|
||||
if (ovrApp_HandleXrEvents(&engine->appState)) {
|
||||
VR_Recenter(engine);
|
||||
@ -304,16 +304,21 @@ bool VR_BeginFrame( engine_t* engine ) {
|
||||
|
||||
engine->appState.LayerCount = 0;
|
||||
memset(engine->appState.Layers, 0, sizeof(ovrCompositorLayer_Union) * ovrMaxLayerCount);
|
||||
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer;
|
||||
ovrFramebuffer_Acquire(frameBuffer);
|
||||
ovrFramebuffer_SetCurrent(frameBuffer);
|
||||
VR_ClearFrameBuffer(frameBuffer->ColorSwapChain.Width, frameBuffer->ColorSwapChain.Height);
|
||||
return true;
|
||||
}
|
||||
|
||||
void VR_BeginFrame( engine_t* engine, int fboIndex ) {
|
||||
vrConfig[VR_CONFIG_CURRENT_FBO] = fboIndex;
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[fboIndex];
|
||||
ovrFramebuffer_Acquire(frameBuffer);
|
||||
ovrFramebuffer_SetCurrent(frameBuffer);
|
||||
VR_ClearFrameBuffer(frameBuffer->ColorSwapChain.Width, frameBuffer->ColorSwapChain.Height);
|
||||
}
|
||||
|
||||
void VR_EndFrame( engine_t* engine ) {
|
||||
|
||||
int fboIndex = vrConfig[VR_CONFIG_CURRENT_FBO];
|
||||
|
||||
// Clear the alpha channel, other way OpenXR would not transfer the framebuffer fully
|
||||
VR_BindFramebuffer(engine);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
@ -322,9 +327,8 @@ void VR_EndFrame( engine_t* engine ) {
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
// Show mouse cursor
|
||||
int vrMode = vrConfig[VR_CONFIG_MODE];
|
||||
int size = vrConfig[VR_CONFIG_MOUSE_SIZE];
|
||||
if ((vrMode == VR_MODE_FLAT_SCREEN) && (size > 0)) {
|
||||
if ((vrConfig[VR_CONFIG_MODE] == VR_MODE_FLAT_SCREEN) && (size > 0)) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(vrConfig[VR_CONFIG_MOUSE_X], vrConfig[VR_CONFIG_MOUSE_Y], size, size);
|
||||
glViewport(vrConfig[VR_CONFIG_MOUSE_X], vrConfig[VR_CONFIG_MOUSE_Y], size, size);
|
||||
@ -333,21 +337,27 @@ void VR_EndFrame( engine_t* engine ) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer;
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[fboIndex];
|
||||
//ovrFramebuffer_Resolve(frameBuffer);
|
||||
ovrFramebuffer_Release(frameBuffer);
|
||||
ovrFramebuffer_SetNone();
|
||||
}
|
||||
|
||||
void VR_FinishFrame( engine_t* engine ) {
|
||||
|
||||
int vrMode = vrConfig[VR_CONFIG_MODE];
|
||||
XrCompositionLayerProjectionView projection_layer_elements[2] = {};
|
||||
if ((vrMode == VR_MODE_MONO_6DOF) || (vrMode == VR_MODE_STEREO_6DOF)) {
|
||||
vrConfig[VR_CONFIG_MENU_YAW] = (int)hmdorientation.y;
|
||||
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
int imageLayer = eye;
|
||||
int imageLayer = engine->appState.Renderer.Multiview ? eye : 0;
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[0];
|
||||
XrFovf fov = projections[eye].fov;
|
||||
if (vrMode == VR_MODE_MONO_6DOF) {
|
||||
fov = projections[0].fov;
|
||||
imageLayer = 0;
|
||||
} else if (!engine->appState.Renderer.Multiview) {
|
||||
frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
|
||||
}
|
||||
|
||||
memset(&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView));
|
||||
@ -376,15 +386,15 @@ void VR_EndFrame( engine_t* engine ) {
|
||||
} else if (vrMode == VR_MODE_FLAT_SCREEN) {
|
||||
|
||||
// Build the cylinder layer
|
||||
int width = engine->appState.Renderer.FrameBuffer.ColorSwapChain.Width;
|
||||
int height = engine->appState.Renderer.FrameBuffer.ColorSwapChain.Height;
|
||||
int width = engine->appState.Renderer.FrameBuffer[0].ColorSwapChain.Width;
|
||||
int height = engine->appState.Renderer.FrameBuffer[0].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;
|
||||
cylinder_layer.space = engine->appState.CurrentSpace;
|
||||
cylinder_layer.eyeVisibility = XR_EYE_VISIBILITY_BOTH;
|
||||
memset(&cylinder_layer.subImage, 0, sizeof(XrSwapchainSubImage));
|
||||
cylinder_layer.subImage.swapchain = engine->appState.Renderer.FrameBuffer.ColorSwapChain.Handle;
|
||||
cylinder_layer.subImage.swapchain = engine->appState.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;
|
||||
@ -425,8 +435,12 @@ void VR_EndFrame( engine_t* engine ) {
|
||||
endFrameInfo.layers = layers;
|
||||
|
||||
OXR(xrEndFrame(engine->appState.Session, &endFrameInfo));
|
||||
frameBuffer->TextureSwapChainIndex++;
|
||||
frameBuffer->TextureSwapChainIndex %= frameBuffer->TextureSwapChainLength;
|
||||
int instances = engine->appState.Renderer.Multiview ? 1 : ovrMaxNumEyes;
|
||||
for (int i = 0; i < instances; i++) {
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[instances];
|
||||
frameBuffer->TextureSwapChainIndex++;
|
||||
frameBuffer->TextureSwapChainIndex %= frameBuffer->TextureSwapChainLength;
|
||||
}
|
||||
}
|
||||
|
||||
int VR_GetConfig( VRConfig config ) {
|
||||
@ -439,7 +453,8 @@ void VR_SetConfig( VRConfig config, int value) {
|
||||
|
||||
void VR_BindFramebuffer(engine_t *engine) {
|
||||
if (!initialized) return;
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer;
|
||||
int fboIndex = vrConfig[VR_CONFIG_CURRENT_FBO];
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[fboIndex];
|
||||
unsigned int swapchainIndex = frameBuffer->TextureSwapChainIndex;
|
||||
unsigned int glFramebuffer = frameBuffer->FrameBuffers[swapchainIndex];
|
||||
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, glFramebuffer));
|
||||
|
@ -18,6 +18,8 @@ enum VRConfig {
|
||||
VR_CONFIG_MOUSE_SIZE, VR_CONFIG_MOUSE_X, VR_CONFIG_MOUSE_Y,
|
||||
//viewport setup
|
||||
VR_CONFIG_VIEWPORT_WIDTH, VR_CONFIG_VIEWPORT_HEIGHT, VR_CONFIG_VIEWPORT_VALID,
|
||||
//render status
|
||||
VR_CONFIG_CURRENT_FBO,
|
||||
|
||||
//end
|
||||
VR_CONFIG_MAX
|
||||
@ -41,8 +43,10 @@ void VR_GetResolution( engine_t* engine, int *pWidth, int *pHeight );
|
||||
void VR_InitRenderer( engine_t* engine, bool multiview );
|
||||
void VR_DestroyRenderer( engine_t* engine );
|
||||
|
||||
bool VR_BeginFrame( engine_t* engine );
|
||||
bool VR_InitFrame( engine_t* engine );
|
||||
void VR_BeginFrame( engine_t* engine, int fboIndex );
|
||||
void VR_EndFrame( engine_t* engine );
|
||||
void VR_FinishFrame( engine_t* engine );
|
||||
|
||||
int VR_GetConfig( VRConfig config );
|
||||
void VR_SetConfig( VRConfig config, int value);
|
||||
|
@ -410,7 +410,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu
|
||||
if (IsMultiviewSupported()) {
|
||||
render_->SetUniformM4x4Stereo("u_proj", &u_proj, leftEyeMatrix.m, rightEyeMatrix.m);
|
||||
} else {
|
||||
render_->SetUniformM4x4(&u_proj, leftEyeMatrix.m);
|
||||
render_->SetUniformM4x4(&u_proj, GetVRFBOIndex() == 0 ? leftEyeMatrix.m : rightEyeMatrix.m);
|
||||
}
|
||||
} else {
|
||||
Matrix4x4 flippedMatrix;
|
||||
@ -537,7 +537,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu
|
||||
if (IsMultiviewSupported()) {
|
||||
render_->SetUniformM4x4Stereo("u_view", &u_view, leftEyeView, rightEyeView);
|
||||
} else {
|
||||
render_->SetUniformM4x4(&u_view, leftEyeView);
|
||||
render_->SetUniformM4x4(&u_view, GetVRFBOIndex() == 0 ? leftEyeView : rightEyeView);
|
||||
}
|
||||
} else {
|
||||
SetMatrix4x3(render_, &u_view, gstate.viewMatrix);
|
||||
|
@ -1120,10 +1120,8 @@ void GameSettingsScreen::CreateViews() {
|
||||
vrSettings->Add(new CheckBox(&g_Config.bEnableVR, vr->T("Enable virtual reality")));
|
||||
CheckBox *vr6DoF = vrSettings->Add(new CheckBox(&g_Config.bEnable6DoF, vr->T("Enable 6 degrees of freedom movement")));
|
||||
vr6DoF->SetEnabledPtr(&g_Config.bEnableVR);
|
||||
if (IsMultiviewSupported()) {
|
||||
CheckBox *vrStereo = vrSettings->Add(new CheckBox(&g_Config.bEnableStereo, vr->T("Enable stereoscopic vision")));
|
||||
vrStereo->SetEnabledPtr(&g_Config.bEnableVR);
|
||||
}
|
||||
CheckBox *vrStereo = vrSettings->Add(new CheckBox(&g_Config.bEnableStereo, vr->T("Enable stereoscopic vision")));
|
||||
vrStereo->SetEnabledPtr(&g_Config.bEnableVR);
|
||||
PopupSliderChoice *vrFieldOfView = vrSettings->Add(new PopupSliderChoice(&g_Config.iFieldOfViewPercentage, 100, 150, vr->T("Field of view scale", "Headset's field of view scale"), 10, screenManager(), vr->T("% of native FoV")));
|
||||
vrFieldOfView->SetEnabledPtr(&g_Config.bEnableVR);
|
||||
vrSettings->Add(new PopupSliderChoice(&g_Config.iCanvasDistance, 1, 10, vr->T("Distance to 2D menus and scenes", "Distance to 2D menus and scenes"), 1, screenManager(), ""));
|
||||
|
Loading…
Reference in New Issue
Block a user