diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index c73c0cd298de..363d6d928bd6 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -253,47 +253,50 @@ bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_mes // Some core profile drivers elide certain extensions from GL_EXTENSIONS/etc. // glewExperimental allows us to force GLEW to search for the pointers anyway. - if (gl_extensions.IsCoreContext) - glewExperimental = true; + glewExperimental = true; if (GLEW_OK != glewInit()) { *error_message = "Failed to initialize GLEW."; return false; } // Unfortunately, glew will generate an invalid enum error, ignore. - if (gl_extensions.IsCoreContext) - glGetError(); + glGetError(); int contextFlags = g_Config.bGfxDebugOutput ? WGL_CONTEXT_DEBUG_BIT_ARB : 0; - HGLRC m_hrc = NULL; + HGLRC m_hrc = nullptr; // Alright, now for the modernity. First try a 4.4, then 4.3, context, if that fails try 3.3. // I can't seem to find a way that lets you simply request the newest version available. if (wglewIsSupported("WGL_ARB_create_context") == 1) { - for (int minor = 5; minor >= 0 && m_hrc == NULL; --minor) { - const int attribs4x[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, 4, - WGL_CONTEXT_MINOR_VERSION_ARB, minor, + for (int tryCore = 1; tryCore >= 0 && m_hrc == nullptr; --tryCore) { + SetGLCoreContext(tryCore == 1); + + for (int minor = 6; minor >= 0 && m_hrc == nullptr; --minor) { + const int attribs4x[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, 4, + WGL_CONTEXT_MINOR_VERSION_ARB, minor, + WGL_CONTEXT_FLAGS_ARB, contextFlags, + WGL_CONTEXT_PROFILE_MASK_ARB, gl_extensions.IsCoreContext ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + 0 + }; + m_hrc = wglCreateContextAttribsARB(hDC, 0, attribs4x); + } + const int attribs33[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGL_CONTEXT_MINOR_VERSION_ARB, 3, WGL_CONTEXT_FLAGS_ARB, contextFlags, WGL_CONTEXT_PROFILE_MASK_ARB, gl_extensions.IsCoreContext ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0 }; - m_hrc = wglCreateContextAttribsARB(hDC, 0, attribs4x); + if (!m_hrc) + m_hrc = wglCreateContextAttribsARB(hDC, 0, attribs33); } - const int attribs33[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, 3, - WGL_CONTEXT_MINOR_VERSION_ARB, 3, - WGL_CONTEXT_FLAGS_ARB, contextFlags, - WGL_CONTEXT_PROFILE_MASK_ARB, gl_extensions.IsCoreContext ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, - 0 - }; - if (!m_hrc) - m_hrc = wglCreateContextAttribsARB(hDC, 0, attribs33); + if (!m_hrc) { // Fall back m_hrc = hRC; } else { // Switch to the new ARB context. - wglMakeCurrent(NULL, NULL); + wglMakeCurrent(nullptr, nullptr); wglDeleteContext(hRC); wglMakeCurrent(hDC, m_hrc); } diff --git a/ext/native/base/PCMain.cpp b/ext/native/base/PCMain.cpp index ad4244bf1d95..9bf98b097823 100644 --- a/ext/native/base/PCMain.cpp +++ b/ext/native/base/PCMain.cpp @@ -439,16 +439,6 @@ int main(int argc, char *argv[]) { } } -#ifdef __APPLE__ - // Make sure to request a somewhat modern GL context at least - the - // latest supported by MacOSX (really, really sad...) - // Requires SDL 2.0 - // We really should upgrade to SDL 2.0 soon. - //SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); -#endif - #ifdef USING_EGL if (EGL_Open()) return 1; @@ -590,22 +580,68 @@ int main(int argc, char *argv[]) { if (g_Config.bFullScreen) mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; - g_Screen = SDL_CreateWindow(app_name_nice.c_str(), SDL_WINDOWPOS_UNDEFINED_DISPLAY(getDisplayNumber()),\ - SDL_WINDOWPOS_UNDEFINED, pixel_xres, pixel_yres, mode); + int x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(getDisplayNumber()); + int y = SDL_WINDOWPOS_UNDEFINED; + + struct GLVersionPair { + int major; + int minor; + }; + GLVersionPair attemptVersions[] = { + {4, 6}, {4, 5}, {4, 4}, {4, 3}, {4, 2}, {4, 1}, {4, 0}, + {3, 3}, {3, 2}, {3, 1}, {3, 0}, + }; + + SDL_GLContext glContext = nullptr; + for (size_t i = 0; i < ARRAY_SIZE(attemptVersions); ++i) { + const auto &ver = attemptVersions[i]; + // Make sure to request a somewhat modern GL context at least - the + // latest supported by MacOS X (really, really sad...) + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, ver.major); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, ver.minor); + SetGLCoreContext(true); + + g_Screen = SDL_CreateWindow(app_name_nice.c_str(), x,y, pixel_xres, pixel_yres, mode); + if (g_Screen == nullptr) { + NativeShutdown(); + fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError()); + SDL_Quit(); + return 2; + } + + glContext = SDL_GL_CreateContext(g_Screen); + if (glContext != nullptr) { + // Victory, got one. + break; + } - if (g_Screen == NULL) { - NativeShutdown(); - fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError()); - SDL_Quit(); - return 2; + // Let's keep trying. To be safe, destroy the window - docs say needed to change profile. + // in practice, it doesn't seem to matter, but maybe it differs by platform. + SDL_DestroyWindow(g_Screen); } - SDL_GLContext glContext = SDL_GL_CreateContext(g_Screen); - if (glContext == NULL) { - NativeShutdown(); - fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError()); - SDL_Quit(); - return 2; + if (glContext == nullptr) { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SetGLCoreContext(false); + + g_Screen = SDL_CreateWindow(app_name_nice.c_str(), x,y, pixel_xres, pixel_yres, mode); + if (g_Screen == nullptr) { + NativeShutdown(); + fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError()); + SDL_Quit(); + return 2; + } + + glContext = SDL_GL_CreateContext(g_Screen); + if (glContext == nullptr) { + NativeShutdown(); + fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError()); + SDL_Quit(); + return 2; + } } #ifdef USING_EGL