2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_WINDOWS
25 #include "SDL_assert.h"
26 #include "SDL_loadso.h"
27 #include "SDL_windowsvideo.h"
28 #include "SDL_windowsopengles.h"
30 /* WGL implementation of SDL OpenGL support */
32 #if SDL_VIDEO_OPENGL_WGL
33 #include "SDL_opengl.h"
35 #define DEFAULT_OPENGL "OPENGL32.DLL"
37 #ifndef WGL_ARB_create_context
38 #define WGL_ARB_create_context
39 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
40 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
41 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
42 #define WGL_CONTEXT_FLAGS_ARB 0x2094
43 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
44 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
46 #ifndef WGL_ARB_create_context_profile
47 #define WGL_ARB_create_context_profile
48 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
49 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
50 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
53 #ifndef WGL_ARB_create_context_robustness
54 #define WGL_ARB_create_context_robustness
55 #define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
56 #define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
57 #define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
58 #define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
62 #ifndef WGL_EXT_create_context_es2_profile
63 #define WGL_EXT_create_context_es2_profile
64 #define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
67 #ifndef WGL_EXT_create_context_es_profile
68 #define WGL_EXT_create_context_es_profile
69 #define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
72 #ifndef WGL_ARB_framebuffer_sRGB
73 #define WGL_ARB_framebuffer_sRGB
74 #define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
77 #ifndef WGL_ARB_context_flush_control
78 #define WGL_ARB_context_flush_control
79 #define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
80 #define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000
81 #define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
84 typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
91 WIN_GL_LoadLibrary(_THIS, const char *path)
96 path = SDL_getenv("SDL_OPENGL_LIBRARY");
99 path = DEFAULT_OPENGL;
101 _this->gl_config.dll_handle = SDL_LoadObject(path);
102 if (!_this->gl_config.dll_handle) {
105 SDL_strlcpy(_this->gl_config.driver_path, path,
106 SDL_arraysize(_this->gl_config.driver_path));
108 /* Allocate OpenGL memory */
109 _this->gl_data = (struct SDL_GLDriverData *) SDL_calloc(1, sizeof(struct SDL_GLDriverData));
110 if (!_this->gl_data) {
111 return SDL_OutOfMemory();
114 /* Load function pointers */
115 handle = _this->gl_config.dll_handle;
116 _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
117 SDL_LoadFunction(handle, "wglGetProcAddress");
118 _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
119 SDL_LoadFunction(handle, "wglCreateContext");
120 _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
121 SDL_LoadFunction(handle, "wglDeleteContext");
122 _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
123 SDL_LoadFunction(handle, "wglMakeCurrent");
124 _this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
125 SDL_LoadFunction(handle, "wglShareLists");
127 if (!_this->gl_data->wglGetProcAddress ||
128 !_this->gl_data->wglCreateContext ||
129 !_this->gl_data->wglDeleteContext ||
130 !_this->gl_data->wglMakeCurrent) {
131 return SDL_SetError("Could not retrieve OpenGL functions");
138 WIN_GL_GetProcAddress(_THIS, const char *proc)
142 /* This is to pick up extensions */
143 func = _this->gl_data->wglGetProcAddress(proc);
145 /* This is probably a normal GL function */
146 func = GetProcAddress(_this->gl_config.dll_handle, proc);
152 WIN_GL_UnloadLibrary(_THIS)
154 SDL_UnloadObject(_this->gl_config.dll_handle);
155 _this->gl_config.dll_handle = NULL;
157 /* Free OpenGL memory */
158 SDL_free(_this->gl_data);
159 _this->gl_data = NULL;
163 WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd)
166 pfd->nSize = sizeof(*pfd);
168 pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
169 if (_this->gl_config.double_buffer) {
170 pfd->dwFlags |= PFD_DOUBLEBUFFER;
172 if (_this->gl_config.stereo) {
173 pfd->dwFlags |= PFD_STEREO;
175 pfd->iLayerType = PFD_MAIN_PLANE;
176 pfd->iPixelType = PFD_TYPE_RGBA;
177 pfd->cRedBits = _this->gl_config.red_size;
178 pfd->cGreenBits = _this->gl_config.green_size;
179 pfd->cBlueBits = _this->gl_config.blue_size;
180 pfd->cAlphaBits = _this->gl_config.alpha_size;
181 if (_this->gl_config.buffer_size) {
183 _this->gl_config.buffer_size - _this->gl_config.alpha_size;
185 pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits);
187 pfd->cAccumRedBits = _this->gl_config.accum_red_size;
188 pfd->cAccumGreenBits = _this->gl_config.accum_green_size;
189 pfd->cAccumBlueBits = _this->gl_config.accum_blue_size;
190 pfd->cAccumAlphaBits = _this->gl_config.accum_alpha_size;
192 (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits +
193 pfd->cAccumAlphaBits);
194 pfd->cDepthBits = _this->gl_config.depth_size;
195 pfd->cStencilBits = _this->gl_config.stencil_size;
198 /* Choose the closest pixel format that meets or exceeds the target.
199 FIXME: Should we weight any particular attribute over any other?
202 WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target)
204 PIXELFORMATDESCRIPTOR pfd;
205 int count, index, best = 0;
206 unsigned int dist, best_dist = ~0U;
208 count = DescribePixelFormat(hdc, 1, sizeof(pfd), NULL);
210 for (index = 1; index <= count; index++) {
212 if (!DescribePixelFormat(hdc, index, sizeof(pfd), &pfd)) {
216 if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) {
220 if (pfd.iLayerType != target->iLayerType) {
223 if (pfd.iPixelType != target->iPixelType) {
229 if (pfd.cColorBits < target->cColorBits) {
232 dist += (pfd.cColorBits - target->cColorBits);
234 if (pfd.cRedBits < target->cRedBits) {
237 dist += (pfd.cRedBits - target->cRedBits);
239 if (pfd.cGreenBits < target->cGreenBits) {
242 dist += (pfd.cGreenBits - target->cGreenBits);
244 if (pfd.cBlueBits < target->cBlueBits) {
247 dist += (pfd.cBlueBits - target->cBlueBits);
249 if (pfd.cAlphaBits < target->cAlphaBits) {
252 dist += (pfd.cAlphaBits - target->cAlphaBits);
254 if (pfd.cAccumBits < target->cAccumBits) {
257 dist += (pfd.cAccumBits - target->cAccumBits);
259 if (pfd.cAccumRedBits < target->cAccumRedBits) {
262 dist += (pfd.cAccumRedBits - target->cAccumRedBits);
264 if (pfd.cAccumGreenBits < target->cAccumGreenBits) {
267 dist += (pfd.cAccumGreenBits - target->cAccumGreenBits);
269 if (pfd.cAccumBlueBits < target->cAccumBlueBits) {
272 dist += (pfd.cAccumBlueBits - target->cAccumBlueBits);
274 if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) {
277 dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits);
279 if (pfd.cDepthBits < target->cDepthBits) {
282 dist += (pfd.cDepthBits - target->cDepthBits);
284 if (pfd.cStencilBits < target->cStencilBits) {
287 dist += (pfd.cStencilBits - target->cStencilBits);
290 if (dist < best_dist) {
300 HasExtension(const char *extension, const char *extensions)
303 const char *where, *terminator;
305 /* Extension names should not have spaces. */
306 where = SDL_strchr(extension, ' ');
307 if (where || *extension == '\0')
313 /* It takes a bit of care to be fool-proof about parsing the
314 * OpenGL extensions string. Don't be fooled by sub-strings,
320 where = SDL_strstr(start, extension);
324 terminator = where + SDL_strlen(extension);
325 if (where == start || *(where - 1) == ' ')
326 if (*terminator == ' ' || *terminator == '\0')
335 WIN_GL_InitExtensions(_THIS)
337 const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
338 const char *extensions;
342 PIXELFORMATDESCRIPTOR pfd;
344 if (!_this->gl_data) {
349 CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
350 10, 10, NULL, NULL, SDL_Instance, NULL);
354 WIN_PumpEvents(_this);
358 WIN_GL_SetupPixelFormat(_this, &pfd);
360 SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
362 hglrc = _this->gl_data->wglCreateContext(hdc);
366 _this->gl_data->wglMakeCurrent(hdc, hglrc);
368 wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC))
369 _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
370 if (wglGetExtensionsStringARB) {
371 extensions = wglGetExtensionsStringARB(hdc);
376 /* Check for WGL_ARB_pixel_format */
377 _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_FALSE;
378 if (HasExtension("WGL_ARB_pixel_format", extensions)) {
379 _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
383 WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB");
384 _this->gl_data->wglGetPixelFormatAttribivARB =
385 (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *))
386 WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB");
388 if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
389 (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
390 _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_TRUE;
394 /* Check for WGL_EXT_swap_control */
395 _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_FALSE;
396 if (HasExtension("WGL_EXT_swap_control", extensions)) {
397 _this->gl_data->wglSwapIntervalEXT =
398 WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT");
399 _this->gl_data->wglGetSwapIntervalEXT =
400 WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT");
401 if (HasExtension("WGL_EXT_swap_control_tear", extensions)) {
402 _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_TRUE;
405 _this->gl_data->wglSwapIntervalEXT = NULL;
406 _this->gl_data->wglGetSwapIntervalEXT = NULL;
409 /* Check for WGL_EXT_create_context_es2_profile */
410 _this->gl_data->HAS_WGL_EXT_create_context_es2_profile = SDL_FALSE;
411 if (HasExtension("WGL_EXT_create_context_es2_profile", extensions)) {
412 _this->gl_data->HAS_WGL_EXT_create_context_es2_profile = SDL_TRUE;
415 /* Check for GLX_ARB_context_flush_control */
416 if (HasExtension("WGL_ARB_context_flush_control", extensions)) {
417 _this->gl_data->HAS_WGL_ARB_context_flush_control = SDL_TRUE;
420 _this->gl_data->wglMakeCurrent(hdc, NULL);
421 _this->gl_data->wglDeleteContext(hglrc);
422 ReleaseDC(hwnd, hdc);
424 WIN_PumpEvents(_this);
428 WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs)
432 PIXELFORMATDESCRIPTOR pfd;
434 int pixel_format = 0;
435 unsigned int matching;
438 CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
439 10, 10, NULL, NULL, SDL_Instance, NULL);
440 WIN_PumpEvents(_this);
444 WIN_GL_SetupPixelFormat(_this, &pfd);
446 SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
448 hglrc = _this->gl_data->wglCreateContext(hdc);
450 _this->gl_data->wglMakeCurrent(hdc, hglrc);
452 if (_this->gl_data->HAS_WGL_ARB_pixel_format) {
453 _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
458 _this->gl_data->wglMakeCurrent(hdc, NULL);
459 _this->gl_data->wglDeleteContext(hglrc);
461 ReleaseDC(hwnd, hdc);
463 WIN_PumpEvents(_this);
468 /* actual work of WIN_GL_SetupWindow() happens here. */
470 WIN_GL_SetupWindowInternal(_THIS, SDL_Window * window)
472 HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
473 PIXELFORMATDESCRIPTOR pfd;
474 int pixel_format = 0;
478 float fAttribs[1] = { 0 };
480 WIN_GL_SetupPixelFormat(_this, &pfd);
482 /* setup WGL_ARB_pixel_format attribs */
483 iAttr = &iAttribs[0];
485 *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
487 *iAttr++ = WGL_RED_BITS_ARB;
488 *iAttr++ = _this->gl_config.red_size;
489 *iAttr++ = WGL_GREEN_BITS_ARB;
490 *iAttr++ = _this->gl_config.green_size;
491 *iAttr++ = WGL_BLUE_BITS_ARB;
492 *iAttr++ = _this->gl_config.blue_size;
494 if (_this->gl_config.alpha_size) {
495 *iAttr++ = WGL_ALPHA_BITS_ARB;
496 *iAttr++ = _this->gl_config.alpha_size;
499 *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
500 *iAttr++ = _this->gl_config.double_buffer;
502 *iAttr++ = WGL_DEPTH_BITS_ARB;
503 *iAttr++ = _this->gl_config.depth_size;
505 if (_this->gl_config.stencil_size) {
506 *iAttr++ = WGL_STENCIL_BITS_ARB;
507 *iAttr++ = _this->gl_config.stencil_size;
510 if (_this->gl_config.accum_red_size) {
511 *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
512 *iAttr++ = _this->gl_config.accum_red_size;
515 if (_this->gl_config.accum_green_size) {
516 *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
517 *iAttr++ = _this->gl_config.accum_green_size;
520 if (_this->gl_config.accum_blue_size) {
521 *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
522 *iAttr++ = _this->gl_config.accum_blue_size;
525 if (_this->gl_config.accum_alpha_size) {
526 *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
527 *iAttr++ = _this->gl_config.accum_alpha_size;
530 if (_this->gl_config.stereo) {
531 *iAttr++ = WGL_STEREO_ARB;
535 if (_this->gl_config.multisamplebuffers) {
536 *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
537 *iAttr++ = _this->gl_config.multisamplebuffers;
540 if (_this->gl_config.multisamplesamples) {
541 *iAttr++ = WGL_SAMPLES_ARB;
542 *iAttr++ = _this->gl_config.multisamplesamples;
545 if (_this->gl_config.framebuffer_srgb_capable) {
546 *iAttr++ = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
547 *iAttr++ = _this->gl_config.framebuffer_srgb_capable;
550 /* We always choose either FULL or NO accel on Windows, because of flaky
551 drivers. If the app didn't specify, we use FULL, because that's
552 probably what they wanted (and if you didn't care and got FULL, that's
553 a perfectly valid result in any case). */
554 *iAttr++ = WGL_ACCELERATION_ARB;
556 if (_this->gl_config.accelerated) {
557 *iAttr++ = WGL_FULL_ACCELERATION_ARB;
559 *iAttr++ = WGL_NO_ACCELERATION_ARB;
564 /* Choose and set the closest available pixel format */
565 pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
567 /* App said "don't care about accel" and FULL accel failed. Try NO. */
568 if ( ( !pixel_format ) && ( _this->gl_config.accelerated < 0 ) ) {
569 *iAccelAttr = WGL_NO_ACCELERATION_ARB;
570 pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
571 *iAccelAttr = WGL_FULL_ACCELERATION_ARB; /* if we try again. */
574 pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd);
577 return SDL_SetError("No matching GL pixel format available");
579 if (!SetPixelFormat(hdc, pixel_format, &pfd)) {
580 return WIN_SetError("SetPixelFormat()");
586 WIN_GL_SetupWindow(_THIS, SDL_Window * window)
588 /* The current context is lost in here; save it and reset it. */
589 SDL_Window *current_win = SDL_GL_GetCurrentWindow();
590 SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();
591 const int retval = WIN_GL_SetupWindowInternal(_this, window);
592 WIN_GL_MakeCurrent(_this, current_win, current_ctx);
597 WIN_GL_CreateContext(_THIS, SDL_Window * window)
599 HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
600 HGLRC context, share_context;
602 if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES &&
603 !_this->gl_data->HAS_WGL_EXT_create_context_es2_profile) {
604 #if SDL_VIDEO_OPENGL_EGL
605 /* Switch to EGL based functions */
606 WIN_GL_UnloadLibrary(_this);
607 _this->GL_LoadLibrary = WIN_GLES_LoadLibrary;
608 _this->GL_GetProcAddress = WIN_GLES_GetProcAddress;
609 _this->GL_UnloadLibrary = WIN_GLES_UnloadLibrary;
610 _this->GL_CreateContext = WIN_GLES_CreateContext;
611 _this->GL_MakeCurrent = WIN_GLES_MakeCurrent;
612 _this->GL_SetSwapInterval = WIN_GLES_SetSwapInterval;
613 _this->GL_GetSwapInterval = WIN_GLES_GetSwapInterval;
614 _this->GL_SwapWindow = WIN_GLES_SwapWindow;
615 _this->GL_DeleteContext = WIN_GLES_DeleteContext;
617 if (WIN_GLES_LoadLibrary(_this, NULL) != 0) {
621 return WIN_GLES_CreateContext(_this, window);
623 SDL_SetError("SDL not configured with EGL support");
628 if (_this->gl_config.share_with_current_context) {
629 share_context = (HGLRC)SDL_GL_GetCurrentContext();
634 if (_this->gl_config.major_version < 3 &&
635 _this->gl_config.profile_mask == 0 &&
636 _this->gl_config.flags == 0) {
637 /* Create legacy context */
638 context = _this->gl_data->wglCreateContext(hdc);
639 if( share_context != 0 ) {
640 _this->gl_data->wglShareLists(share_context, context);
643 PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
644 HGLRC temp_context = _this->gl_data->wglCreateContext(hdc);
646 SDL_SetError("Could not create GL context");
650 /* Make the context current */
651 if (WIN_GL_MakeCurrent(_this, window, temp_context) < 0) {
652 WIN_GL_DeleteContext(_this, temp_context);
656 wglCreateContextAttribsARB =
657 (PFNWGLCREATECONTEXTATTRIBSARBPROC) _this->gl_data->
658 wglGetProcAddress("wglCreateContextAttribsARB");
659 if (!wglCreateContextAttribsARB) {
660 SDL_SetError("GL 3.x is not supported");
661 context = temp_context;
663 /* max 10 attributes plus terminator */
665 WGL_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version,
666 WGL_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version,
671 /* SDL profile bits match WGL profile bits */
672 if (_this->gl_config.profile_mask != 0) {
673 attribs[iattr++] = WGL_CONTEXT_PROFILE_MASK_ARB;
674 attribs[iattr++] = _this->gl_config.profile_mask;
677 /* SDL flags match WGL flags */
678 if (_this->gl_config.flags != 0) {
679 attribs[iattr++] = WGL_CONTEXT_FLAGS_ARB;
680 attribs[iattr++] = _this->gl_config.flags;
683 /* only set if wgl extension is available */
684 if (_this->gl_data->HAS_WGL_ARB_context_flush_control) {
685 attribs[iattr++] = WGL_CONTEXT_RELEASE_BEHAVIOR_ARB;
686 attribs[iattr++] = _this->gl_config.release_behavior ?
687 WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
688 WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
691 attribs[iattr++] = 0;
693 /* Create the GL 3.x context */
694 context = wglCreateContextAttribsARB(hdc, share_context, attribs);
695 /* Delete the GL 2.x context */
696 _this->gl_data->wglDeleteContext(temp_context);
701 WIN_SetError("Could not create GL context");
705 if (WIN_GL_MakeCurrent(_this, window, context) < 0) {
706 WIN_GL_DeleteContext(_this, context);
714 WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
718 if (!_this->gl_data) {
719 return SDL_SetError("OpenGL not initialized");
722 /* sanity check that higher level handled this. */
723 SDL_assert(window || (!window && !context));
725 /* Some Windows drivers freak out if hdc is NULL, even when context is
726 NULL, against spec. Since hdc is _supposed_ to be ignored if context
727 is NULL, we either use the current GL window, or do nothing if we
728 already have no current context. */
730 window = SDL_GL_GetCurrentWindow();
732 SDL_assert(SDL_GL_GetCurrentContext() == NULL);
733 return 0; /* already done. */
737 hdc = ((SDL_WindowData *) window->driverdata)->hdc;
738 if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) {
739 return WIN_SetError("wglMakeCurrent()");
745 WIN_GL_SetSwapInterval(_THIS, int interval)
747 if ((interval < 0) && (!_this->gl_data->HAS_WGL_EXT_swap_control_tear)) {
748 return SDL_SetError("Negative swap interval unsupported in this GL");
749 } else if (_this->gl_data->wglSwapIntervalEXT) {
750 if (_this->gl_data->wglSwapIntervalEXT(interval) != TRUE) {
751 return WIN_SetError("wglSwapIntervalEXT()");
754 return SDL_Unsupported();
760 WIN_GL_GetSwapInterval(_THIS)
763 if (_this->gl_data->wglGetSwapIntervalEXT) {
764 retval = _this->gl_data->wglGetSwapIntervalEXT();
770 WIN_GL_SwapWindow(_THIS, SDL_Window * window)
772 HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
778 WIN_GL_DeleteContext(_THIS, SDL_GLContext context)
780 if (!_this->gl_data) {
783 _this->gl_data->wglDeleteContext((HGLRC) context);
788 WIN_GL_SetPixelFormatFrom(_THIS, SDL_Window * fromWindow, SDL_Window * toWindow)
790 HDC hfromdc = ((SDL_WindowData *) fromWindow->driverdata)->hdc;
791 HDC htodc = ((SDL_WindowData *) toWindow->driverdata)->hdc;
794 /* get the pixel format of the fromWindow */
795 int pixel_format = GetPixelFormat(hfromdc);
796 PIXELFORMATDESCRIPTOR pfd;
797 SDL_memset(&pfd, 0, sizeof(pfd));
798 DescribePixelFormat(hfromdc, pixel_format, sizeof(pfd), &pfd);
800 /* set the pixel format of the toWindow */
801 result = SetPixelFormat(htodc, pixel_format, &pfd);
803 return result ? SDL_TRUE : SDL_FALSE;
806 #endif /* SDL_VIDEO_OPENGL_WGL */
808 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
810 /* vi: set ts=4 sw=4 expandtab: */