diff --git a/Source/Core/Common/GL/GLInterface/AGL.h b/Source/Core/Common/GL/GLInterface/AGL.h index f3c3bd47cf..5f9a138282 100644 --- a/Source/Core/Common/GL/GLInterface/AGL.h +++ b/Source/Core/Common/GL/GLInterface/AGL.h @@ -17,7 +17,7 @@ class cInterfaceAGL : public cInterfaceBase { public: void Swap() override; - bool Create(void* window_handle, bool core) override; + bool Create(void* window_handle, bool stereo, bool core) override; bool MakeCurrent() override; bool ClearCurrent() override; void Shutdown() override; diff --git a/Source/Core/Common/GL/GLInterface/AGL.mm b/Source/Core/Common/GL/GLInterface/AGL.mm index 37fec99440..bdae829cbc 100644 --- a/Source/Core/Common/GL/GLInterface/AGL.mm +++ b/Source/Core/Common/GL/GLInterface/AGL.mm @@ -51,12 +51,15 @@ void cInterfaceAGL::Swap() // Create rendering window. // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() -bool cInterfaceAGL::Create(void* window_handle, bool core) +bool cInterfaceAGL::Create(void* window_handle, bool stereo, bool core) { - NSOpenGLPixelFormatAttribute attr[] = {NSOpenGLPFADoubleBuffer, NSOpenGLPFAOpenGLProfile, - core ? NSOpenGLProfileVersion3_2Core : - NSOpenGLProfileVersionLegacy, - NSOpenGLPFAAccelerated, 0}; + NSOpenGLPixelFormatAttribute attr[] = { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAOpenGLProfile, + core ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy, + NSOpenGLPFAAccelerated, + stereo ? NSOpenGLPFAStereo : static_cast(0), + 0}; NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr]; if (fmt == nil) { diff --git a/Source/Core/Common/GL/GLInterface/BGL.cpp b/Source/Core/Common/GL/GLInterface/BGL.cpp index 7cc9070a49..ed2670efc5 100644 --- a/Source/Core/Common/GL/GLInterface/BGL.cpp +++ b/Source/Core/Common/GL/GLInterface/BGL.cpp @@ -13,7 +13,7 @@ void cInterfaceBGL::Swap() m_gl->SwapBuffers(); } -bool cInterfaceBGL::Create(void* window_handle, bool core) +bool cInterfaceBGL::Create(void* window_handle, bool stereo, bool core) { m_window = static_cast(window_handle); diff --git a/Source/Core/Common/GL/GLInterface/BGL.h b/Source/Core/Common/GL/GLInterface/BGL.h index aeb678f804..b26e5e3fc8 100644 --- a/Source/Core/Common/GL/GLInterface/BGL.h +++ b/Source/Core/Common/GL/GLInterface/BGL.h @@ -14,7 +14,7 @@ class cInterfaceBGL final : public cInterfaceBase public: void Swap() override; void* GetFuncAddress(const std::string& name) override; - bool Create(void* window_handle, bool core) override; + bool Create(void* window_handle, bool stereo, bool core) override; bool MakeCurrent() override; bool ClearCurrent() override; void Shutdown() override; diff --git a/Source/Core/Common/GL/GLInterface/EGL.cpp b/Source/Core/Common/GL/GLInterface/EGL.cpp index 9deb4f20e7..32cd705d73 100644 --- a/Source/Core/Common/GL/GLInterface/EGL.cpp +++ b/Source/Core/Common/GL/GLInterface/EGL.cpp @@ -111,7 +111,7 @@ void cInterfaceEGL::DetectMode() // Create rendering window. // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() -bool cInterfaceEGL::Create(void* window_handle, bool core) +bool cInterfaceEGL::Create(void* window_handle, bool stereo, bool core) { EGLint egl_major, egl_minor; bool supports_core_profile = false; diff --git a/Source/Core/Common/GL/GLInterface/EGL.h b/Source/Core/Common/GL/GLInterface/EGL.h index 2352f9b646..69a351851f 100644 --- a/Source/Core/Common/GL/GLInterface/EGL.h +++ b/Source/Core/Common/GL/GLInterface/EGL.h @@ -38,7 +38,7 @@ public: void SwapInterval(int interval) override; void SetMode(GLInterfaceMode mode) override { s_opengl_mode = mode; } void* GetFuncAddress(const std::string& name) override; - bool Create(void* window_handle, bool core) override; + bool Create(void* window_handle, bool stereo, bool core) override; bool Create(cInterfaceBase* main_context) override; bool MakeCurrent() override; bool ClearCurrent() override; diff --git a/Source/Core/Common/GL/GLInterface/GLX.cpp b/Source/Core/Common/GL/GLInterface/GLX.cpp index d3550c688f..f6fea067ef 100644 --- a/Source/Core/Common/GL/GLInterface/GLX.cpp +++ b/Source/Core/Common/GL/GLInterface/GLX.cpp @@ -43,7 +43,7 @@ void cInterfaceGLX::Swap() // Create rendering window. // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() -bool cInterfaceGLX::Create(void* window_handle, bool core) +bool cInterfaceGLX::Create(void* window_handle, bool stereo, bool core) { dpy = XOpenDisplay(nullptr); int screen = DefaultScreen(dpy); @@ -87,6 +87,8 @@ bool cInterfaceGLX::Create(void* window_handle, bool core) 0, GLX_DOUBLEBUFFER, True, + GLX_STEREO, + stereo ? True : False, None}; int fbcount = 0; GLXFBConfig* fbc = glXChooseFBConfig(dpy, screen, visual_attribs, &fbcount); diff --git a/Source/Core/Common/GL/GLInterface/GLX.h b/Source/Core/Common/GL/GLInterface/GLX.h index 20feba27e0..ae019ccbf9 100644 --- a/Source/Core/Common/GL/GLInterface/GLX.h +++ b/Source/Core/Common/GL/GLInterface/GLX.h @@ -24,7 +24,7 @@ public: void SwapInterval(int Interval) override; void Swap() override; void* GetFuncAddress(const std::string& name) override; - bool Create(void* window_handle, bool core) override; + bool Create(void* window_handle, bool stereo, bool core) override; bool MakeCurrent() override; bool ClearCurrent() override; void Shutdown() override; diff --git a/Source/Core/Common/GL/GLInterface/WGL.cpp b/Source/Core/Common/GL/GLInterface/WGL.cpp index 3e500f5866..4d4647e838 100644 --- a/Source/Core/Common/GL/GLInterface/WGL.cpp +++ b/Source/Core/Common/GL/GLInterface/WGL.cpp @@ -200,7 +200,7 @@ bool cInterfaceWGL::PeekMessages() // Create rendering window. // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() -bool cInterfaceWGL::Create(void* window_handle, bool core) +bool cInterfaceWGL::Create(void* window_handle, bool stereo, bool core) { if (!window_handle) return false; @@ -219,12 +219,14 @@ bool cInterfaceWGL::Create(void* window_handle, bool core) s_backbuffer_width = twidth; s_backbuffer_height = theight; - static constexpr PIXELFORMATDESCRIPTOR pfd = { + const DWORD stereo_flag = stereo ? PFD_STEREO : 0; + static const PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL - PFD_DOUBLEBUFFER, // Must Support Double Buffering + PFD_DOUBLEBUFFER | // Must Support Double Buffering + stereo_flag, // Could Support Quad Buffering PFD_TYPE_RGBA, // Request An RGBA Format 32, // Select Our Color Depth 0, diff --git a/Source/Core/Common/GL/GLInterface/WGL.h b/Source/Core/Common/GL/GLInterface/WGL.h index e6f0ff3c66..efa9655713 100644 --- a/Source/Core/Common/GL/GLInterface/WGL.h +++ b/Source/Core/Common/GL/GLInterface/WGL.h @@ -14,7 +14,7 @@ public: void SwapInterval(int interval) override; void Swap() override; void* GetFuncAddress(const std::string& name) override; - bool Create(void* window_handle, bool core) override; + bool Create(void* window_handle, bool stereo, bool core) override; bool Create(cInterfaceBase* main_context) override; bool MakeCurrent() override; bool ClearCurrent() override; diff --git a/Source/Core/Common/GL/GLInterfaceBase.h b/Source/Core/Common/GL/GLInterfaceBase.h index b19f5698bc..4ffb7f5f53 100644 --- a/Source/Core/Common/GL/GLInterfaceBase.h +++ b/Source/Core/Common/GL/GLInterfaceBase.h @@ -34,7 +34,7 @@ public: virtual void SetMode(GLInterfaceMode mode) { s_opengl_mode = GLInterfaceMode::MODE_OPENGL; } virtual GLInterfaceMode GetMode() { return s_opengl_mode; } virtual void* GetFuncAddress(const std::string& name) { return nullptr; } - virtual bool Create(void* window_handle, bool core = true) { return true; } + virtual bool Create(void* window_handle, bool stereo = false, bool core = true) { return true; } virtual bool Create(cInterfaceBase* main_context) { return true; } virtual bool MakeCurrent() { return true; } virtual bool ClearCurrent() { return true; } diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 494a478501..3282489369 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1196,6 +1196,16 @@ void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, GLuint src_t post_processor->BlitFromTexture(src, leftRc, src_texture, src_width, src_height, 0); post_processor->BlitFromTexture(src, rightRc, src_texture, src_width, src_height, 1); } + else if (g_ActiveConfig.iStereoMode == STEREO_QUADBUFFER) + { + glDrawBuffer(GL_BACK_LEFT); + post_processor->BlitFromTexture(src, dst, src_texture, src_width, src_height, 0); + + glDrawBuffer(GL_BACK_RIGHT); + post_processor->BlitFromTexture(src, dst, src_texture, src_width, src_height, 1); + + glDrawBuffer(GL_BACK); + } else { post_processor->BlitFromTexture(src, dst, src_texture, src_width, src_height, 0); diff --git a/Source/Core/VideoBackends/OGL/main.cpp b/Source/Core/VideoBackends/OGL/main.cpp index f9bf7c069e..c00782ee70 100644 --- a/Source/Core/VideoBackends/OGL/main.cpp +++ b/Source/Core/VideoBackends/OGL/main.cpp @@ -167,7 +167,7 @@ bool VideoBackend::Initialize(void* window_handle) InitInterface(); GLInterface->SetMode(GLInterfaceMode::MODE_DETECT); - if (!GLInterface->Create(window_handle)) + if (!GLInterface->Create(window_handle, g_ActiveConfig.iStereoMode == STEREO_QUADBUFFER)) return false; return true;