diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 8ce3d47e7..0bc0682f0 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -156,6 +156,7 @@ Other Changes: - OpenGL3+GLFW/SDL2/SDL3: allow Wine compatibility by passing empty GLSL version string to ImGui_ImplOpenGL3_Init() to let backend decide of a GLSL version based on actual GL version obtained. (#9427, #6577) [@perminovVS] + - OpenGL3+Win32: rework context creation to allow Wine compatibility. (#9427, #6577) [@perminovVS] - SDL2/SDL3: use `SDL_GetWindowSizeInPixels()` to create frame-buffers. Fixes issues with non-fractional framebuffer size on Wayland. (#8761, #9124) [@billtran1632001] - SDL3+Metal4: added new example. (#9458, #9451) [@AmelieHeinrich] diff --git a/examples/example_win32_opengl3/main.cpp b/examples/example_win32_opengl3/main.cpp index d18ea0bd8..b3a4da9c6 100644 --- a/examples/example_win32_opengl3/main.cpp +++ b/examples/example_win32_opengl3/main.cpp @@ -17,12 +17,13 @@ #include #include #include +#include // Data stored per platform window struct WGL_WindowData { HDC hDC; }; // Data -static HGLRC g_hRC; +static HGLRC g_hRC; // Rendering context static WGL_WindowData g_MainWindow; static int g_Width; static int g_Height; @@ -208,8 +209,57 @@ bool CreateDeviceWGL(HWND hWnd, WGL_WindowData* data) ::ReleaseDC(hWnd, hDc); data->hDC = ::GetDC(hWnd); - if (!g_hRC) - g_hRC = wglCreateContext(data->hDC); + if (g_hRC) + return true; + + // Create legacy context + HGLRC tempRC = wglCreateContext(data->hDC); + if (!tempRC) { ::ReleaseDC(hWnd, data->hDC); return false; } + if (!wglMakeCurrent(data->hDC, tempRC)) + { + wglDeleteContext(tempRC); + ::ReleaseDC(hWnd, data->hDC); + return false; + } + + // Get context version + GLint major = 0, minor = 0; + glGetIntegerv(0x821B, &major); // GL_MAJOR_VERSION + glGetIntegerv(0x821C, &minor); // GL_MINOR_VERSION + const char* gl_version_str = (const char*)glGetString(GL_VERSION); + if (major == 0 && minor == 0) + sscanf_s(gl_version_str, "%d.%d", &major, &minor); // Query GL_VERSION in desktop GL 2.x, the string will start with "." + const GLuint gl_version = (GLuint)(major * 100 + minor * 10); + + // Keep temporary context: already OpenGL 3.0+. + g_hRC = tempRC; + //if (gl_version >= 300) + // return true; + + typedef HGLRC(WINAPI* PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int*); + const PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); + + // GL 3.0 + const int attribs[] = + { + 0x2091, 3, // WGL_CONTEXT_MAJOR_VERSION_ARB + 0x2092, 0, // WGL_CONTEXT_MINOR_VERSION_ARB + 0x9126, 0x0001, // WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB + 0 + }; + HGLRC newRC = nullptr; + if (wglCreateContextAttribsARB) + newRC = wglCreateContextAttribsARB(data->hDC, 0, attribs); + + // If we managed to create 3.0+ context: use that one and destroy the temporary OpenGL 2.x compatibility context. + if (newRC) + { + wglMakeCurrent(nullptr, nullptr); + wglDeleteContext(tempRC); + g_hRC = newRC; + wglMakeCurrent(data->hDC, g_hRC); + } + return true; }