From 924aaa3a92a5fbaad525afb1a439a35cdfdda747 Mon Sep 17 00:00:00 2001 From: Christopher Bruns Date: Sat, 10 Sep 2016 12:20:45 -0400 Subject: [PATCH] fixed: Delay setup of quad-buffered stereo 3d mode, in case a useful OpenGL context is not immediately provided. --- src/gl/stereo3d/gl_quadstereo.cpp | 50 ++++++++++++++++++++++++------- src/gl/stereo3d/gl_quadstereo.h | 2 ++ 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/gl/stereo3d/gl_quadstereo.cpp b/src/gl/stereo3d/gl_quadstereo.cpp index cd689d3b5..1388e6944 100644 --- a/src/gl/stereo3d/gl_quadstereo.cpp +++ b/src/gl/stereo3d/gl_quadstereo.cpp @@ -45,17 +45,38 @@ QuadStereo::QuadStereo(double ipdMeters) // Check whether quad-buffered stereo is supported in the current context // We are assuming the OpenGL context is already current at this point, // i.e. this constructor is called "just in time". - GLboolean supportsStereo, supportsBuffered; - glGetBooleanv(GL_STEREO, &supportsStereo); - glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered); - bQuadStereoSupported = supportsStereo && supportsBuffered; - leftEye.bQuadStereoSupported = bQuadStereoSupported; - rightEye.bQuadStereoSupported = bQuadStereoSupported; - eye_ptrs.Push(&leftEye); - // If stereo is not supported, just draw scene once (left eye view only) - if (bQuadStereoSupported) { - eye_ptrs.Push(&rightEye); + // First initialize to mono-ish initial state + bQuadStereoSupported = leftEye.bQuadStereoSupported = rightEye.bQuadStereoSupported = false; + eye_ptrs.Push(&leftEye); // We ALWAYS want to show at least this one view... + // We will possibly advance to true stereo mode in the Setup() method... +} + +// Sometimes the stereo render context is not ready immediately at start up +/* private */ +void QuadStereo::checkInitialRenderContextState() +{ + // Keep trying until we see at least one good OpenGL context to render to + static bool bDecentContextWasFound = false; + if (!bDecentContextWasFound) { + // I'm using a "random" OpenGL call (glGetFramebufferAttachmentParameteriv) + // that appears to correlate with whether the context is ready + GLint attachmentType = GL_NONE; + glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_FRONT_LEFT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentType); + if (attachmentType != GL_NONE) // Finally, a useful OpenGL context + { + // This block will be executed exactly ONCE during a game run + bDecentContextWasFound = true; // now we can stop checking every frame... + // Now check whether this context supports hardware stereo + GLboolean supportsStereo, supportsBuffered; + glGetBooleanv(GL_STEREO, &supportsStereo); + glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered); + bQuadStereoSupported = supportsStereo && supportsBuffered; + leftEye.bQuadStereoSupported = bQuadStereoSupported; + rightEye.bQuadStereoSupported = bQuadStereoSupported; + if (bQuadStereoSupported) + eye_ptrs.Push(&rightEye); // Use the other eye too, if we can do stereo + } } } @@ -81,11 +102,18 @@ void QuadStereo::Present() const { GLRenderer->mBuffers->BindOutputFB(); GLRenderer->ClearBorders(); - GLRenderer->mBuffers->BindEyeTexture(1, 0); + GLRenderer->mBuffers->BindEyeTexture(0, 0); GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true); } } +void QuadStereo::SetUp() const +{ + Stereo3DMode::SetUp(); + // Maybe advance to true stereo mode (ONCE), after the stereo context is finally ready + const_cast(this)->checkInitialRenderContextState(); +} + /* static */ const QuadStereo& QuadStereo::getInstance(float ipd) { diff --git a/src/gl/stereo3d/gl_quadstereo.h b/src/gl/stereo3d/gl_quadstereo.h index d9aa4f435..2c58c88c5 100644 --- a/src/gl/stereo3d/gl_quadstereo.h +++ b/src/gl/stereo3d/gl_quadstereo.h @@ -69,11 +69,13 @@ class QuadStereo : public Stereo3DMode public: QuadStereo(double ipdMeters); void Present() const override; + void SetUp() const override; static const QuadStereo& getInstance(float ipd); private: QuadStereoLeftPose leftEye; QuadStereoRightPose rightEye; bool bQuadStereoSupported; + void checkInitialRenderContextState(); };