]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - vid_sdl.c
Sys_Error(): don't leave a dead window covering the OS UI or crash dialog
[xonotic/darkplaces.git] / vid_sdl.c
index 11cc4ac298702aa51f5bbcc2b9afabd8c9d7eba3..065c4607b011026a7ed4f4a4277dd06d319c3f69 100644 (file)
--- a/vid_sdl.c
+++ b/vid_sdl.c
@@ -1570,6 +1570,9 @@ static qbool VID_InitModeGL(viddef_mode_t *mode)
        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);
+       /* Requesting a Core profile and 3.2 minimum is mandatory on macOS and older Mesa drivers.
+        * It works fine on other drivers too except NVIDIA, see HACK below.
+        */
 #endif
 
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, (gl_debug.integer > 0 ? SDL_GL_CONTEXT_DEBUG_FLAG : 0));
@@ -1592,9 +1595,40 @@ static qbool VID_InitModeGL(viddef_mode_t *mode)
                return false;
        }
 
+       GL_InitFunctions();
+
+#if !defined(USE_GLES2) && !defined(MACOSX)
+       // NVIDIA hates the Core profile and limits the version to the minimum we specified.
+       // HACK: to detect NVIDIA we first need a context, fortunately replacing it takes a few milliseconds
+       gl_vendor = (const char *)qglGetString(GL_VENDOR);
+       if (strncmp(gl_vendor, "NVIDIA", 6) == 0)
+       {
+               Con_DPrint("The Way It's Meant To Be Played: replacing OpenGL Core profile with Compatibility profile...\n");
+               SDL_GL_DeleteContext(context);
+               SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
+               context = SDL_GL_CreateContext(window);
+               if (context == NULL)
+               {
+                       Con_Printf(CON_ERROR "Failed to initialize OpenGL context: %s\n", SDL_GetError());
+                       VID_Shutdown();
+                       return false;
+               }
+       }
+#endif
+
        SDL_GL_SetSwapInterval(bound(-1, vid_vsync.integer, 1));
        vid_usingvsync = (vid_vsync.integer != 0);
 
+       vid_hidden = false;
+       vid_activewindow = true;
+       vid_hasfocus = true;
+       vid_usingmouse = false;
+       vid_usinghidecursor = false;
+
+       // clear to black (loading plaque will be seen over this)
+       GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 0);
+       VID_Finish(); // checks vid_hidden
+
        GL_Setup();
 
        // VorteX: set other info
@@ -1604,15 +1638,6 @@ static qbool VID_InitModeGL(viddef_mode_t *mode)
        Cvar_SetQuick(&gl_info_platform, "SDL");
        Cvar_SetQuick(&gl_info_driver, drivername ? drivername : "");
 
-       // clear to black (loading plaque will be seen over this)
-       GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 0);
-
-       vid_hidden = false;
-       vid_activewindow = false;
-       vid_hasfocus = true;
-       vid_usingmouse = false;
-       vid_usinghidecursor = false;
-               
        return true;
 }
 
@@ -1634,6 +1659,8 @@ void VID_Shutdown (void)
        VID_EnableJoystick(false);
        VID_SetMouse(false, false);
 
+       SDL_GL_DeleteContext(context);
+       context = NULL;
        SDL_DestroyWindow(window);
        window = NULL;