diff --git a/src/rendering/gl/renderer/gl_postprocess.cpp b/src/rendering/gl/renderer/gl_postprocess.cpp index 6b8c5c2e6..aa7d7cb19 100644 --- a/src/rendering/gl/renderer/gl_postprocess.cpp +++ b/src/rendering/gl/renderer/gl_postprocess.cpp @@ -121,20 +121,11 @@ void FGLRenderer::BlurScene(float gameinfobluramount) mBuffers->UpdateEffectTextures(); auto vrmode = VRMode::GetVRMode(true); - if (vrmode->mEyeCount == 1) + int eyeCount = vrmode->mEyeCount; + for (int i = 0; i < eyeCount; ++i) { mBuffers->RenderEffect("BlurScene"); - } - else - { - for (int eye_ix = 0; eye_ix < vrmode->mEyeCount; ++eye_ix) - { - FGLDebug::PushGroup("EyeBlur"); - mBuffers->BlitFromEyeTexture(eye_ix); - mBuffers->RenderEffect("BlurScene"); - mBuffers->BlitToEyeTexture(eye_ix); - FGLDebug::PopGroup(); - } + if (eyeCount - i > 1) mBuffers->NextEye(eyeCount); } } @@ -159,13 +150,12 @@ void FGLRenderer::Flush() else { // Render 2D to eye textures - for (int eye_ix = 0; eye_ix < vrmode->mEyeCount; ++eye_ix) + int eyeCount = vrmode->mEyeCount; + for (int eye_ix = 0; eye_ix < eyeCount; ++eye_ix) { - FGLDebug::PushGroup("Eye2D"); - mBuffers->BlitFromEyeTexture(eye_ix); screen->Draw2D(); - mBuffers->BlitToEyeTexture(eye_ix); - FGLDebug::PopGroup(); + if (eyeCount - eye_ix > 1) + mBuffers->NextEye(eyeCount); } screen->Clear2D(); diff --git a/src/rendering/gl/renderer/gl_renderbuffers.cpp b/src/rendering/gl/renderer/gl_renderbuffers.cpp index 4dd9f95be..73c33e961 100644 --- a/src/rendering/gl/renderer/gl_renderbuffers.cpp +++ b/src/rendering/gl/renderer/gl_renderbuffers.cpp @@ -532,7 +532,7 @@ void FGLRenderBuffers::BlitSceneToTexture() // //========================================================================== -void FGLRenderBuffers::BlitToEyeTexture(int eye) +void FGLRenderBuffers::BlitToEyeTexture(int eye, bool allowInvalidate) { CreateEyeBuffers(eye); @@ -540,7 +540,7 @@ void FGLRenderBuffers::BlitToEyeTexture(int eye) glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mEyeFBs[eye].handle); glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); - if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0) + if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0 && allowInvalidate) { GLenum attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT }; glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 2, attachments); @@ -552,7 +552,7 @@ void FGLRenderBuffers::BlitToEyeTexture(int eye) void FGLRenderBuffers::BlitFromEyeTexture(int eye) { - CreateEyeBuffers(eye); + if (mEyeFBs.Size() <= unsigned(eye)) return; glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture].handle); glBindFramebuffer(GL_READ_FRAMEBUFFER, mEyeFBs[eye].handle); @@ -1002,4 +1002,17 @@ void FGLRenderBuffers::RenderEffect(const FString &name) FGLDebug::PopGroup(); } -} \ No newline at end of file + +// Store the current stereo 3D eye buffer, and Load the next one + +int FGLRenderBuffers::NextEye(int eyeCount) +{ + int nextEye = (mCurrentEye + 1) % eyeCount; + if (nextEye == mCurrentEye) return mCurrentEye; + BlitToEyeTexture(mCurrentEye); + mCurrentEye = nextEye; + BlitFromEyeTexture(mCurrentEye); + return mCurrentEye; +} + +} // namespace OpenGLRenderer \ No newline at end of file diff --git a/src/rendering/gl/renderer/gl_renderbuffers.h b/src/rendering/gl/renderer/gl_renderbuffers.h index b4b018516..4b66e7569 100644 --- a/src/rendering/gl/renderer/gl_renderbuffers.h +++ b/src/rendering/gl/renderer/gl_renderbuffers.h @@ -87,9 +87,11 @@ public: void BindOutputFB(); - void BlitToEyeTexture(int eye); + void BlitToEyeTexture(int eye, bool allowInvalidate=true); void BlitFromEyeTexture(int eye); void BindEyeTexture(int eye, int texunit); + int NextEye(int eyeCount); + int & CurrentEye() { return mCurrentEye; } void BindDitherTexture(int texunit); @@ -156,6 +158,7 @@ private: // Eye buffers TArray mEyeTextures; TArray mEyeFBs; + int mCurrentEye = 0; // Shadow map texture PPGLTexture mShadowMapTexture; diff --git a/src/rendering/gl/renderer/gl_scene.cpp b/src/rendering/gl/renderer/gl_scene.cpp index c62203be9..764355d00 100644 --- a/src/rendering/gl/renderer/gl_scene.cpp +++ b/src/rendering/gl/renderer/gl_scene.cpp @@ -163,9 +163,11 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came // Render (potentially) multiple views for stereo 3d // Fixme. The view offsetting should be done with a static table and not require setup of the entire render state for the mode. auto vrmode = VRMode::GetVRMode(mainview && toscreen); - for (int eye_ix = 0; eye_ix < vrmode->mEyeCount; ++eye_ix) + const int eyeCount = vrmode->mEyeCount; + mBuffers->CurrentEye() = 0; // always begin at zero, in case eye count changed + for (int eye_ix = 0; eye_ix < eyeCount; ++eye_ix) { - const auto &eye = vrmode->mEyes[eye_ix]; + const auto &eye = vrmode->mEyes[mBuffers->CurrentEye()]; screen->SetViewportRects(bounds); if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao @@ -218,8 +220,8 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came PostProcess.Unclock(); } di->EndDrawInfo(); - if (vrmode->mEyeCount > 1) - mBuffers->BlitToEyeTexture(eye_ix); + if (eyeCount - eye_ix > 1) + mBuffers->NextEye(eyeCount); } return mainvp.sector; diff --git a/src/rendering/gl/renderer/gl_stereo3d.cpp b/src/rendering/gl/renderer/gl_stereo3d.cpp index 35ea3c914..08cb4fbef 100644 --- a/src/rendering/gl/renderer/gl_stereo3d.cpp +++ b/src/rendering/gl/renderer/gl_stereo3d.cpp @@ -327,6 +327,12 @@ void FGLRenderer::PresentQuadStereo() void FGLRenderer::PresentStereo() { + auto vrmode = VRMode::GetVRMode(true); + const int eyeCount = vrmode->mEyeCount; + // Don't invalidate the bound framebuffer (..., false) + if (eyeCount > 1) + mBuffers->BlitToEyeTexture(mBuffers->CurrentEye(), false); + switch (vr_mode) { default: