Atlas - wgl_context.c

Home / ext / glfw / src Lines: 1 | Size: 26768 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1//======================================================================== 2// GLFW 3.5 WGL - www.glfw.org 3//------------------------------------------------------------------------ 4// Copyright (c) 2002-2006 Marcus Geelnard 5// Copyright (c) 2006-2019 Camilla Löwy <[email protected]> 6// 7// This software is provided 'as-is', without any express or implied 8// warranty. In no event will the authors be held liable for any damages 9// arising from the use of this software. 10// 11// Permission is granted to anyone to use this software for any purpose, 12// including commercial applications, and to alter it and redistribute it 13// freely, subject to the following restrictions: 14// 15// 1. The origin of this software must not be misrepresented; you must not 16// claim that you wrote the original software. If you use this software 17// in a product, an acknowledgment in the product documentation would 18// be appreciated but is not required. 19// 20// 2. Altered source versions must be plainly marked as such, and must not 21// be misrepresented as being the original software. 22// 23// 3. This notice may not be removed or altered from any source 24// distribution. 25// 26//======================================================================== 27 28#include "internal.h" 29 30#if defined(_GLFW_WIN32) 31 32#include <stdlib.h> 33#include <assert.h> 34 35// Return the value corresponding to the specified attribute 36// 37static int findPixelFormatAttribValueWGL(const int* attribs, 38 int attribCount, 39 const int* values, 40 int attrib) 41{ 42 int i; 43 44 for (i = 0; i < attribCount; i++) 45 { 46 if (attribs[i] == attrib) 47 return values[i]; 48 } 49 50 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 51 "WGL: Unknown pixel format attribute requested"); 52 return 0; 53} 54 55#define ADD_ATTRIB(a) \ 56{ \ 57 assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \ 58 attribs[attribCount++] = a; \ 59} 60#define FIND_ATTRIB_VALUE(a) \ 61 findPixelFormatAttribValueWGL(attribs, attribCount, values, a) 62 63// Return a list of available and usable framebuffer configs 64// 65static int choosePixelFormatWGL(_GLFWwindow* window, 66 const _GLFWctxconfig* ctxconfig, 67 const _GLFWfbconfig* fbconfig) 68{ 69 _GLFWfbconfig* usableConfigs; 70 const _GLFWfbconfig* closest; 71 int i, pixelFormat, nativeCount, usableCount = 0, attribCount = 0; 72 int attribs[40]; 73 int values[sizeof(attribs) / sizeof(attribs[0])]; 74 75 nativeCount = DescribePixelFormat(window->context.wgl.dc, 76 1, 77 sizeof(PIXELFORMATDESCRIPTOR), 78 NULL); 79 80 if (_glfw.wgl.ARB_pixel_format) 81 { 82 ADD_ATTRIB(WGL_SUPPORT_OPENGL_ARB); 83 ADD_ATTRIB(WGL_DRAW_TO_WINDOW_ARB); 84 ADD_ATTRIB(WGL_PIXEL_TYPE_ARB); 85 ADD_ATTRIB(WGL_ACCELERATION_ARB); 86 ADD_ATTRIB(WGL_RED_BITS_ARB); 87 ADD_ATTRIB(WGL_RED_SHIFT_ARB); 88 ADD_ATTRIB(WGL_GREEN_BITS_ARB); 89 ADD_ATTRIB(WGL_GREEN_SHIFT_ARB); 90 ADD_ATTRIB(WGL_BLUE_BITS_ARB); 91 ADD_ATTRIB(WGL_BLUE_SHIFT_ARB); 92 ADD_ATTRIB(WGL_ALPHA_BITS_ARB); 93 ADD_ATTRIB(WGL_ALPHA_SHIFT_ARB); 94 ADD_ATTRIB(WGL_DEPTH_BITS_ARB); 95 ADD_ATTRIB(WGL_STENCIL_BITS_ARB); 96 ADD_ATTRIB(WGL_ACCUM_BITS_ARB); 97 ADD_ATTRIB(WGL_ACCUM_RED_BITS_ARB); 98 ADD_ATTRIB(WGL_ACCUM_GREEN_BITS_ARB); 99 ADD_ATTRIB(WGL_ACCUM_BLUE_BITS_ARB); 100 ADD_ATTRIB(WGL_ACCUM_ALPHA_BITS_ARB); 101 ADD_ATTRIB(WGL_AUX_BUFFERS_ARB); 102 ADD_ATTRIB(WGL_STEREO_ARB); 103 ADD_ATTRIB(WGL_DOUBLE_BUFFER_ARB); 104 105 if (_glfw.wgl.ARB_multisample) 106 ADD_ATTRIB(WGL_SAMPLES_ARB); 107 108 if (ctxconfig->client == GLFW_OPENGL_API) 109 { 110 if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB) 111 ADD_ATTRIB(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); 112 } 113 else 114 { 115 if (_glfw.wgl.EXT_colorspace) 116 ADD_ATTRIB(WGL_COLORSPACE_EXT); 117 } 118 119 // NOTE: In a Parallels VM WGL_ARB_pixel_format returns fewer pixel formats than 120 // DescribePixelFormat, violating the guarantees of the extension spec 121 // HACK: Iterate through the minimum of both counts 122 123 const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB; 124 int extensionCount; 125 126 if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc, 127 1, 0, 1, &attrib, &extensionCount)) 128 { 129 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 130 "WGL: Failed to retrieve pixel format attribute"); 131 return 0; 132 } 133 134 nativeCount = _glfw_min(nativeCount, extensionCount); 135 } 136 137 usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig)); 138 139 for (i = 0; i < nativeCount; i++) 140 { 141 _GLFWfbconfig* u = usableConfigs + usableCount; 142 pixelFormat = i + 1; 143 144 if (_glfw.wgl.ARB_pixel_format) 145 { 146 // Get pixel format attributes through "modern" extension 147 148 if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc, 149 pixelFormat, 0, 150 attribCount, 151 attribs, values)) 152 { 153 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 154 "WGL: Failed to retrieve pixel format attributes"); 155 156 _glfw_free(usableConfigs); 157 return 0; 158 } 159 160 if (!FIND_ATTRIB_VALUE(WGL_SUPPORT_OPENGL_ARB) || 161 !FIND_ATTRIB_VALUE(WGL_DRAW_TO_WINDOW_ARB)) 162 { 163 continue; 164 } 165 166 if (FIND_ATTRIB_VALUE(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) 167 continue; 168 169 if (FIND_ATTRIB_VALUE(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) 170 continue; 171 172 if (FIND_ATTRIB_VALUE(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer) 173 continue; 174 175 u->redBits = FIND_ATTRIB_VALUE(WGL_RED_BITS_ARB); 176 u->greenBits = FIND_ATTRIB_VALUE(WGL_GREEN_BITS_ARB); 177 u->blueBits = FIND_ATTRIB_VALUE(WGL_BLUE_BITS_ARB); 178 u->alphaBits = FIND_ATTRIB_VALUE(WGL_ALPHA_BITS_ARB); 179 180 u->depthBits = FIND_ATTRIB_VALUE(WGL_DEPTH_BITS_ARB); 181 u->stencilBits = FIND_ATTRIB_VALUE(WGL_STENCIL_BITS_ARB); 182 183 u->accumRedBits = FIND_ATTRIB_VALUE(WGL_ACCUM_RED_BITS_ARB); 184 u->accumGreenBits = FIND_ATTRIB_VALUE(WGL_ACCUM_GREEN_BITS_ARB); 185 u->accumBlueBits = FIND_ATTRIB_VALUE(WGL_ACCUM_BLUE_BITS_ARB); 186 u->accumAlphaBits = FIND_ATTRIB_VALUE(WGL_ACCUM_ALPHA_BITS_ARB); 187 188 u->auxBuffers = FIND_ATTRIB_VALUE(WGL_AUX_BUFFERS_ARB); 189 u->stereo = FIND_ATTRIB_VALUE(WGL_STEREO_ARB); 190 191 if (_glfw.wgl.ARB_multisample) 192 u->samples = FIND_ATTRIB_VALUE(WGL_SAMPLES_ARB); 193 194 if (ctxconfig->client == GLFW_OPENGL_API) 195 { 196 if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB) 197 u->sRGB = FIND_ATTRIB_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); 198 } 199 else 200 { 201 if (_glfw.wgl.EXT_colorspace) 202 { 203 if (FIND_ATTRIB_VALUE(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT) 204 u->sRGB = true; 205 } 206 } 207 } 208 else 209 { 210 // Get pixel format attributes through legacy PFDs 211 212 PIXELFORMATDESCRIPTOR pfd; 213 214 if (!DescribePixelFormat(window->context.wgl.dc, 215 pixelFormat, 216 sizeof(PIXELFORMATDESCRIPTOR), 217 &pfd)) 218 { 219 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 220 "WGL: Failed to describe pixel format"); 221 222 _glfw_free(usableConfigs); 223 return 0; 224 } 225 226 if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || 227 !(pfd.dwFlags & PFD_SUPPORT_OPENGL)) 228 { 229 continue; 230 } 231 232 if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && 233 (pfd.dwFlags & PFD_GENERIC_FORMAT)) 234 { 235 continue; 236 } 237 238 if (pfd.iPixelType != PFD_TYPE_RGBA) 239 continue; 240 241 if (!!(pfd.dwFlags & PFD_DOUBLEBUFFER) != fbconfig->doublebuffer) 242 continue; 243 244 u->redBits = pfd.cRedBits; 245 u->greenBits = pfd.cGreenBits; 246 u->blueBits = pfd.cBlueBits; 247 u->alphaBits = pfd.cAlphaBits; 248 249 u->depthBits = pfd.cDepthBits; 250 u->stencilBits = pfd.cStencilBits; 251 252 u->accumRedBits = pfd.cAccumRedBits; 253 u->accumGreenBits = pfd.cAccumGreenBits; 254 u->accumBlueBits = pfd.cAccumBlueBits; 255 u->accumAlphaBits = pfd.cAccumAlphaBits; 256 257 u->auxBuffers = pfd.cAuxBuffers; 258 u->stereo = (pfd.dwFlags & PFD_STEREO); 259 } 260 261 u->handle = pixelFormat; 262 usableCount++; 263 } 264 265 if (!usableCount) 266 { 267 _glfwInputError(GLFW_API_UNAVAILABLE, 268 "WGL: The driver does not appear to support OpenGL"); 269 270 _glfw_free(usableConfigs); 271 return 0; 272 } 273 274 closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount); 275 if (!closest) 276 { 277 _glfwInputError(GLFW_FORMAT_UNAVAILABLE, 278 "WGL: Failed to find a suitable pixel format"); 279 280 _glfw_free(usableConfigs); 281 return 0; 282 } 283 284 pixelFormat = (int) closest->handle; 285 _glfw_free(usableConfigs); 286 287 return pixelFormat; 288} 289 290#undef ADD_ATTRIB 291#undef FIND_ATTRIB_VALUE 292 293static void makeContextCurrentWGL(_GLFWwindow* window) 294{ 295 if (window) 296 { 297 if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle)) 298 _glfwPlatformSetTls(&_glfw.contextSlot, window); 299 else 300 { 301 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 302 "WGL: Failed to make context current"); 303 _glfwPlatformSetTls(&_glfw.contextSlot, NULL); 304 } 305 } 306 else 307 { 308 if (!wglMakeCurrent(NULL, NULL)) 309 { 310 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 311 "WGL: Failed to clear current context"); 312 } 313 314 _glfwPlatformSetTls(&_glfw.contextSlot, NULL); 315 } 316} 317 318static void swapBuffersWGL(_GLFWwindow* window) 319{ 320 if (!window->monitor) 321 { 322 // HACK: Use DwmFlush when desktop composition is enabled on Windows 7 323 if (!IsWindows8OrGreater()) 324 { 325 BOOL enabled = FALSE; 326 327 if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled) 328 { 329 int count = abs(window->context.wgl.interval); 330 while (count--) 331 DwmFlush(); 332 } 333 } 334 } 335 336 SwapBuffers(window->context.wgl.dc); 337} 338 339static void swapIntervalWGL(int interval) 340{ 341 _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); 342 assert(window != NULL); 343 344 window->context.wgl.interval = interval; 345 346 if (!window->monitor) 347 { 348 // HACK: Disable WGL swap interval when desktop composition is enabled on 349 // Windows 7 to avoid interfering with DWM vsync 350 if (!IsWindows8OrGreater()) 351 { 352 BOOL enabled = FALSE; 353 354 if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled) 355 interval = 0; 356 } 357 } 358 359 if (_glfw.wgl.EXT_swap_control) 360 wglSwapIntervalEXT(interval); 361} 362 363static int extensionSupportedWGL(const char* extension) 364{ 365 const char* extensions = NULL; 366 367 if (_glfw.wgl.GetExtensionsStringARB) 368 extensions = wglGetExtensionsStringARB(wglGetCurrentDC()); 369 else if (_glfw.wgl.GetExtensionsStringEXT) 370 extensions = wglGetExtensionsStringEXT(); 371 372 if (!extensions) 373 return GLFW_FALSE; 374 375 return _glfwStringInExtensionString(extension, extensions); 376} 377 378static GLFWglproc getProcAddressWGL(const char* procname) 379{ 380 const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname); 381 if (proc) 382 return proc; 383 384 return (GLFWglproc) _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, procname); 385} 386 387static void destroyContextWGL(_GLFWwindow* window) 388{ 389 if (window->context.wgl.handle) 390 { 391 wglDeleteContext(window->context.wgl.handle); 392 window->context.wgl.handle = NULL; 393 } 394} 395 396GLFWbool _glfwInitWGL(void) 397{ 398 PIXELFORMATDESCRIPTOR pfd; 399 HGLRC prc, rc; 400 HDC pdc, dc; 401 402 if (_glfw.wgl.instance) 403 return GLFW_TRUE; 404 405 _glfw.wgl.instance = _glfwPlatformLoadModule("opengl32.dll"); 406 if (!_glfw.wgl.instance) 407 { 408 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 409 "WGL: Failed to load opengl32.dll"); 410 return GLFW_FALSE; 411 } 412 413 _glfw.wgl.CreateContext = (PFN_wglCreateContext) 414 _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglCreateContext"); 415 _glfw.wgl.DeleteContext = (PFN_wglDeleteContext) 416 _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglDeleteContext"); 417 _glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress) 418 _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetProcAddress"); 419 _glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC) 420 _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetCurrentDC"); 421 _glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext) 422 _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetCurrentContext"); 423 _glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent) 424 _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglMakeCurrent"); 425 _glfw.wgl.ShareLists = (PFN_wglShareLists) 426 _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglShareLists"); 427 428 // NOTE: A dummy context has to be created for opengl32.dll to load the 429 // OpenGL ICD, from which we can then query WGL extensions 430 // NOTE: This code will accept the Microsoft GDI ICD; accelerated context 431 // creation failure occurs during manual pixel format enumeration 432 433 dc = GetDC(_glfw.win32.helperWindowHandle); 434 435 ZeroMemory(&pfd, sizeof(pfd)); 436 pfd.nSize = sizeof(pfd); 437 pfd.nVersion = 1; 438 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; 439 pfd.iPixelType = PFD_TYPE_RGBA; 440 pfd.cColorBits = 24; 441 442 if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd)) 443 { 444 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 445 "WGL: Failed to set pixel format for dummy context"); 446 return GLFW_FALSE; 447 } 448 449 rc = wglCreateContext(dc); 450 if (!rc) 451 { 452 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 453 "WGL: Failed to create dummy context"); 454 return GLFW_FALSE; 455 } 456 457 pdc = wglGetCurrentDC(); 458 prc = wglGetCurrentContext(); 459 460 if (!wglMakeCurrent(dc, rc)) 461 { 462 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 463 "WGL: Failed to make dummy context current"); 464 wglMakeCurrent(pdc, prc); 465 wglDeleteContext(rc); 466 return GLFW_FALSE; 467 } 468 469 // NOTE: Functions must be loaded first as they're needed to retrieve the 470 // extension string that tells us whether the functions are supported 471 _glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) 472 wglGetProcAddress("wglGetExtensionsStringEXT"); 473 _glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) 474 wglGetProcAddress("wglGetExtensionsStringARB"); 475 _glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) 476 wglGetProcAddress("wglCreateContextAttribsARB"); 477 _glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) 478 wglGetProcAddress("wglSwapIntervalEXT"); 479 _glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) 480 wglGetProcAddress("wglGetPixelFormatAttribivARB"); 481 482 // NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not 483 // checked below as we are already using them 484 _glfw.wgl.ARB_multisample = 485 extensionSupportedWGL("WGL_ARB_multisample"); 486 _glfw.wgl.ARB_framebuffer_sRGB = 487 extensionSupportedWGL("WGL_ARB_framebuffer_sRGB"); 488 _glfw.wgl.EXT_framebuffer_sRGB = 489 extensionSupportedWGL("WGL_EXT_framebuffer_sRGB"); 490 _glfw.wgl.ARB_create_context = 491 extensionSupportedWGL("WGL_ARB_create_context"); 492 _glfw.wgl.ARB_create_context_profile = 493 extensionSupportedWGL("WGL_ARB_create_context_profile"); 494 _glfw.wgl.EXT_create_context_es2_profile = 495 extensionSupportedWGL("WGL_EXT_create_context_es2_profile"); 496 _glfw.wgl.ARB_create_context_robustness = 497 extensionSupportedWGL("WGL_ARB_create_context_robustness"); 498 _glfw.wgl.ARB_create_context_no_error = 499 extensionSupportedWGL("WGL_ARB_create_context_no_error"); 500 _glfw.wgl.EXT_swap_control = 501 extensionSupportedWGL("WGL_EXT_swap_control"); 502 _glfw.wgl.EXT_colorspace = 503 extensionSupportedWGL("WGL_EXT_colorspace"); 504 _glfw.wgl.ARB_pixel_format = 505 extensionSupportedWGL("WGL_ARB_pixel_format"); 506 _glfw.wgl.ARB_context_flush_control = 507 extensionSupportedWGL("WGL_ARB_context_flush_control"); 508 509 wglMakeCurrent(pdc, prc); 510 wglDeleteContext(rc); 511 return GLFW_TRUE; 512} 513 514void _glfwTerminateWGL(void) 515{ 516 _glfwPlatformFreeModule(_glfw.wgl.instance); 517 _glfw.wgl.instance = NULL; 518} 519 520#define SET_ATTRIB(a, v) \ 521{ \ 522 assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \ 523 attribs[index++] = a; \ 524 attribs[index++] = v; \ 525} 526 527GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, 528 const _GLFWctxconfig* ctxconfig, 529 const _GLFWfbconfig* fbconfig) 530{ 531 int attribs[40]; 532 int pixelFormat; 533 PIXELFORMATDESCRIPTOR pfd; 534 HGLRC share = NULL; 535 536 if (ctxconfig->share) 537 share = ctxconfig->share->context.wgl.handle; 538 539 window->context.wgl.dc = GetDC(window->win32.handle); 540 if (!window->context.wgl.dc) 541 { 542 _glfwInputError(GLFW_PLATFORM_ERROR, 543 "WGL: Failed to retrieve DC for window"); 544 return GLFW_FALSE; 545 } 546 547 pixelFormat = choosePixelFormatWGL(window, ctxconfig, fbconfig); 548 if (!pixelFormat) 549 return GLFW_FALSE; 550 551 if (!DescribePixelFormat(window->context.wgl.dc, 552 pixelFormat, sizeof(pfd), &pfd)) 553 { 554 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 555 "WGL: Failed to retrieve PFD for selected pixel format"); 556 return GLFW_FALSE; 557 } 558 559 if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd)) 560 { 561 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 562 "WGL: Failed to set selected pixel format"); 563 return GLFW_FALSE; 564 } 565 566 if (ctxconfig->client == GLFW_OPENGL_API) 567 { 568 if (ctxconfig->forward) 569 { 570 if (!_glfw.wgl.ARB_create_context) 571 { 572 _glfwInputError(GLFW_VERSION_UNAVAILABLE, 573 "WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable"); 574 return GLFW_FALSE; 575 } 576 } 577 578 if (ctxconfig->profile) 579 { 580 if (!_glfw.wgl.ARB_create_context_profile) 581 { 582 _glfwInputError(GLFW_VERSION_UNAVAILABLE, 583 "WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable"); 584 return GLFW_FALSE; 585 } 586 } 587 } 588 else 589 { 590 if (!_glfw.wgl.ARB_create_context || 591 !_glfw.wgl.ARB_create_context_profile || 592 !_glfw.wgl.EXT_create_context_es2_profile) 593 { 594 _glfwInputError(GLFW_API_UNAVAILABLE, 595 "WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable"); 596 return GLFW_FALSE; 597 } 598 } 599 600 if (_glfw.wgl.ARB_create_context) 601 { 602 int index = 0, mask = 0, flags = 0; 603 604 if (ctxconfig->client == GLFW_OPENGL_API) 605 { 606 if (ctxconfig->forward) 607 flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; 608 609 if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) 610 mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB; 611 else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) 612 mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; 613 } 614 else 615 mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT; 616 617 if (ctxconfig->debug) 618 flags |= WGL_CONTEXT_DEBUG_BIT_ARB; 619 620 if (ctxconfig->robustness) 621 { 622 if (_glfw.wgl.ARB_create_context_robustness) 623 { 624 if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) 625 { 626 SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, 627 WGL_NO_RESET_NOTIFICATION_ARB); 628 } 629 else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) 630 { 631 SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, 632 WGL_LOSE_CONTEXT_ON_RESET_ARB); 633 } 634 635 flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; 636 } 637 } 638 639 if (ctxconfig->release) 640 { 641 if (_glfw.wgl.ARB_context_flush_control) 642 { 643 if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) 644 { 645 SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, 646 WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); 647 } 648 else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) 649 { 650 SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, 651 WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); 652 } 653 } 654 } 655 656 if (ctxconfig->noerror) 657 { 658 if (_glfw.wgl.ARB_create_context_no_error) 659 SET_ATTRIB(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, true); 660 } 661 662 // NOTE: Only request an explicitly versioned context when necessary, as 663 // explicitly requesting version 1.0 does not always return the 664 // highest version supported by the driver 665 if (ctxconfig->major != 1 || ctxconfig->minor != 0) 666 { 667 SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); 668 SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); 669 } 670 671 if (flags) 672 SET_ATTRIB(WGL_CONTEXT_FLAGS_ARB, flags); 673 674 if (mask) 675 SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, mask); 676 677 SET_ATTRIB(0, 0); 678 679 window->context.wgl.handle = 680 wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs); 681 if (!window->context.wgl.handle) 682 { 683 const DWORD error = GetLastError(); 684 685 if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB)) 686 { 687 if (ctxconfig->client == GLFW_OPENGL_API) 688 { 689 _glfwInputError(GLFW_VERSION_UNAVAILABLE, 690 "WGL: Driver does not support OpenGL version %i.%i", 691 ctxconfig->major, 692 ctxconfig->minor); 693 } 694 else 695 { 696 _glfwInputError(GLFW_VERSION_UNAVAILABLE, 697 "WGL: Driver does not support OpenGL ES version %i.%i", 698 ctxconfig->major, 699 ctxconfig->minor); 700 } 701 } 702 else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB)) 703 { 704 _glfwInputError(GLFW_VERSION_UNAVAILABLE, 705 "WGL: Driver does not support the requested OpenGL profile"); 706 } 707 else if (error == (0xc0070000 | ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB)) 708 { 709 _glfwInputError(GLFW_INVALID_VALUE, 710 "WGL: The share context is not compatible with the requested context"); 711 } 712 else 713 { 714 if (ctxconfig->client == GLFW_OPENGL_API) 715 { 716 _glfwInputError(GLFW_VERSION_UNAVAILABLE, 717 "WGL: Failed to create OpenGL context"); 718 } 719 else 720 { 721 _glfwInputError(GLFW_VERSION_UNAVAILABLE, 722 "WGL: Failed to create OpenGL ES context"); 723 } 724 } 725 726 return GLFW_FALSE; 727 } 728 } 729 else 730 { 731 window->context.wgl.handle = wglCreateContext(window->context.wgl.dc); 732 if (!window->context.wgl.handle) 733 { 734 _glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE, 735 "WGL: Failed to create OpenGL context"); 736 return GLFW_FALSE; 737 } 738 739 if (share) 740 { 741 if (!wglShareLists(share, window->context.wgl.handle)) 742 { 743 _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, 744 "WGL: Failed to enable sharing with specified OpenGL context"); 745 return GLFW_FALSE; 746 } 747 } 748 } 749 750 window->context.makeCurrent = makeContextCurrentWGL; 751 window->context.swapBuffers = swapBuffersWGL; 752 window->context.swapInterval = swapIntervalWGL; 753 window->context.extensionSupported = extensionSupportedWGL; 754 window->context.getProcAddress = getProcAddressWGL; 755 window->context.destroy = destroyContextWGL; 756 757 return GLFW_TRUE; 758} 759 760#undef SET_ATTRIB 761 762GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) 763{ 764 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 765 766 if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32) 767 { 768 _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, 769 "WGL: Platform not initialized"); 770 return NULL; 771 } 772 773 _GLFWwindow* window = (_GLFWwindow*) handle; 774 assert(window != NULL); 775 776 if (window->context.source != GLFW_NATIVE_CONTEXT_API) 777 { 778 _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); 779 return NULL; 780 } 781 782 return window->context.wgl.handle; 783} 784 785#endif // _GLFW_WIN32 786 787
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.