zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_windowsopengl.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4 
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.
8 
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:
12 
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.
20 */
21 #include "SDL_config.h"
22 
23 #if SDL_VIDEO_DRIVER_WINDOWS
24 
25 #include "SDL_assert.h"
26 #include "SDL_windowsvideo.h"
27 
28 /* WGL implementation of SDL OpenGL support */
29 
30 #if SDL_VIDEO_OPENGL_WGL
31 #include "SDL_opengl.h"
32 
33 #define DEFAULT_OPENGL "OPENGL32.DLL"
34 
35 #ifndef WGL_ARB_create_context
36 #define WGL_ARB_create_context
37 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
38 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
39 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
40 #define WGL_CONTEXT_FLAGS_ARB 0x2094
41 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
42 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
43 
44 #ifndef WGL_ARB_create_context_profile
45 #define WGL_ARB_create_context_profile
46 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
47 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
48 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
49 #endif
50 
51 #ifndef WGL_ARB_create_context_robustness
52 #define WGL_ARB_create_context_robustness
53 #define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
54 #define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
55 #define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
56 #define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
57 #endif
58 #endif
59 
60 #ifndef WGL_EXT_create_context_es2_profile
61 #define WGL_EXT_create_context_es2_profile
62 #define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
63 #endif
64 
65 #ifndef WGL_EXT_create_context_es_profile
66 #define WGL_EXT_create_context_es_profile
67 #define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
68 #endif
69 
70 typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
71  HGLRC
73  const int
74  *attribList);
75 
76 int
77 WIN_GL_LoadLibrary(_THIS, const char *path)
78 {
79  LPTSTR wpath;
80  HANDLE handle;
81 
82  if (path == NULL) {
83  path = SDL_getenv("SDL_OPENGL_LIBRARY");
84  }
85  if (path == NULL) {
86  path = DEFAULT_OPENGL;
87  }
88  wpath = WIN_UTF8ToString(path);
89  _this->gl_config.dll_handle = LoadLibrary(wpath);
90  SDL_free(wpath);
91  if (!_this->gl_config.dll_handle) {
92  char message[1024];
93  SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")",
94  path);
95  return WIN_SetError(message);
96  }
99 
100  /* Allocate OpenGL memory */
101  _this->gl_data =
102  (struct SDL_GLDriverData *) SDL_calloc(1,
103  sizeof(struct
105  if (!_this->gl_data) {
106  return SDL_OutOfMemory();
107  }
108 
109  /* Load function pointers */
110  handle = _this->gl_config.dll_handle;
111  _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
112  GetProcAddress(handle, "wglGetProcAddress");
113  _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
114  GetProcAddress(handle, "wglCreateContext");
115  _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
116  GetProcAddress(handle, "wglDeleteContext");
117  _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
118  GetProcAddress(handle, "wglMakeCurrent");
119  _this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
120  GetProcAddress(handle, "wglShareLists");
121 
122  if (!_this->gl_data->wglGetProcAddress ||
123  !_this->gl_data->wglCreateContext ||
124  !_this->gl_data->wglDeleteContext ||
125  !_this->gl_data->wglMakeCurrent) {
126  SDL_UnloadObject(handle);
127  return SDL_SetError("Could not retrieve OpenGL functions");
128  }
129 
130  return 0;
131 }
132 
133 void *
134 WIN_GL_GetProcAddress(_THIS, const char *proc)
135 {
136  void *func;
137 
138  /* This is to pick up extensions */
139  func = _this->gl_data->wglGetProcAddress(proc);
140  if (!func) {
141  /* This is probably a normal GL function */
142  func = GetProcAddress(_this->gl_config.dll_handle, proc);
143  }
144  return func;
145 }
146 
147 void
148 WIN_GL_UnloadLibrary(_THIS)
149 {
150  FreeLibrary((HMODULE) _this->gl_config.dll_handle);
152 
153  /* Free OpenGL memory */
155  _this->gl_data = NULL;
156 }
157 
158 static void
159 WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd)
160 {
161  SDL_zerop(pfd);
162  pfd->nSize = sizeof(*pfd);
163  pfd->nVersion = 1;
164  pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
166  pfd->dwFlags |= PFD_DOUBLEBUFFER;
167  }
168  if (_this->gl_config.stereo) {
169  pfd->dwFlags |= PFD_STEREO;
170  }
171  pfd->iLayerType = PFD_MAIN_PLANE;
172  pfd->iPixelType = PFD_TYPE_RGBA;
173  pfd->cRedBits = _this->gl_config.red_size;
174  pfd->cGreenBits = _this->gl_config.green_size;
175  pfd->cBlueBits = _this->gl_config.blue_size;
176  pfd->cAlphaBits = _this->gl_config.alpha_size;
177  if (_this->gl_config.buffer_size) {
178  pfd->cColorBits =
180  } else {
181  pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits);
182  }
183  pfd->cAccumRedBits = _this->gl_config.accum_red_size;
184  pfd->cAccumGreenBits = _this->gl_config.accum_green_size;
185  pfd->cAccumBlueBits = _this->gl_config.accum_blue_size;
186  pfd->cAccumAlphaBits = _this->gl_config.accum_alpha_size;
187  pfd->cAccumBits =
188  (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits +
189  pfd->cAccumAlphaBits);
190  pfd->cDepthBits = _this->gl_config.depth_size;
191  pfd->cStencilBits = _this->gl_config.stencil_size;
192 }
193 
194 /* Choose the closest pixel format that meets or exceeds the target.
195  FIXME: Should we weight any particular attribute over any other?
196 */
197 static int
198 WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target)
199 {
200  PIXELFORMATDESCRIPTOR pfd;
201  int count, index, best = 0;
202  unsigned int dist, best_dist = ~0U;
203 
204  count = DescribePixelFormat(hdc, 1, sizeof(pfd), NULL);
205 
206  for (index = 1; index <= count; index++) {
207 
208  if (!DescribePixelFormat(hdc, index, sizeof(pfd), &pfd)) {
209  continue;
210  }
211 
212  if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) {
213  continue;
214  }
215 
216  if (pfd.iLayerType != target->iLayerType) {
217  continue;
218  }
219  if (pfd.iPixelType != target->iPixelType) {
220  continue;
221  }
222 
223  dist = 0;
224 
225  if (pfd.cColorBits < target->cColorBits) {
226  continue;
227  } else {
228  dist += (pfd.cColorBits - target->cColorBits);
229  }
230  if (pfd.cRedBits < target->cRedBits) {
231  continue;
232  } else {
233  dist += (pfd.cRedBits - target->cRedBits);
234  }
235  if (pfd.cGreenBits < target->cGreenBits) {
236  continue;
237  } else {
238  dist += (pfd.cGreenBits - target->cGreenBits);
239  }
240  if (pfd.cBlueBits < target->cBlueBits) {
241  continue;
242  } else {
243  dist += (pfd.cBlueBits - target->cBlueBits);
244  }
245  if (pfd.cAlphaBits < target->cAlphaBits) {
246  continue;
247  } else {
248  dist += (pfd.cAlphaBits - target->cAlphaBits);
249  }
250  if (pfd.cAccumBits < target->cAccumBits) {
251  continue;
252  } else {
253  dist += (pfd.cAccumBits - target->cAccumBits);
254  }
255  if (pfd.cAccumRedBits < target->cAccumRedBits) {
256  continue;
257  } else {
258  dist += (pfd.cAccumRedBits - target->cAccumRedBits);
259  }
260  if (pfd.cAccumGreenBits < target->cAccumGreenBits) {
261  continue;
262  } else {
263  dist += (pfd.cAccumGreenBits - target->cAccumGreenBits);
264  }
265  if (pfd.cAccumBlueBits < target->cAccumBlueBits) {
266  continue;
267  } else {
268  dist += (pfd.cAccumBlueBits - target->cAccumBlueBits);
269  }
270  if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) {
271  continue;
272  } else {
273  dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits);
274  }
275  if (pfd.cDepthBits < target->cDepthBits) {
276  continue;
277  } else {
278  dist += (pfd.cDepthBits - target->cDepthBits);
279  }
280  if (pfd.cStencilBits < target->cStencilBits) {
281  continue;
282  } else {
283  dist += (pfd.cStencilBits - target->cStencilBits);
284  }
285 
286  if (dist < best_dist) {
287  best = index;
288  best_dist = dist;
289  }
290  }
291 
292  return best;
293 }
294 
295 static SDL_bool
296 HasExtension(const char *extension, const char *extensions)
297 {
298  const char *start;
299  const char *where, *terminator;
300 
301  /* Extension names should not have spaces. */
302  where = SDL_strchr(extension, ' ');
303  if (where || *extension == '\0')
304  return SDL_FALSE;
305 
306  if (!extensions)
307  return SDL_FALSE;
308 
309  /* It takes a bit of care to be fool-proof about parsing the
310  * OpenGL extensions string. Don't be fooled by sub-strings,
311  * etc. */
312 
313  start = extensions;
314 
315  for (;;) {
316  where = SDL_strstr(start, extension);
317  if (!where)
318  break;
319 
320  terminator = where + SDL_strlen(extension);
321  if (where == start || *(where - 1) == ' ')
322  if (*terminator == ' ' || *terminator == '\0')
323  return SDL_TRUE;
324 
325  start = terminator;
326  }
327  return SDL_FALSE;
328 }
329 
330 static void
331 WIN_GL_InitExtensions(_THIS, HDC hdc)
332 {
333  const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
334  const char *extensions;
335 
336  wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC))
337  _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
339  extensions = wglGetExtensionsStringARB(hdc);
340  } else {
341  extensions = NULL;
342  }
343 
344  /* Check for WGL_ARB_pixel_format */
345  _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_FALSE;
346  if (HasExtension("WGL_ARB_pixel_format", extensions)) {
347  _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
348  (HDC, const int *,
349  const FLOAT *, UINT,
350  int *, UINT *))
351  WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB");
352  _this->gl_data->wglGetPixelFormatAttribivARB =
353  (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *))
354  WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB");
355 
356  if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
357  (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
358  _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_TRUE;
359  }
360  }
361 
362  /* Check for WGL_EXT_swap_control */
363  _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_FALSE;
364  if (HasExtension("WGL_EXT_swap_control", extensions)) {
365  _this->gl_data->wglSwapIntervalEXT =
366  WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT");
367  _this->gl_data->wglGetSwapIntervalEXT =
368  WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT");
369  if (HasExtension("WGL_EXT_swap_control_tear", extensions)) {
370  _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_TRUE;
371  }
372  } else {
373  _this->gl_data->wglSwapIntervalEXT = NULL;
374  _this->gl_data->wglGetSwapIntervalEXT = NULL;
375  }
376 }
377 
378 static int
379 WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs)
380 {
381  HWND hwnd;
382  HDC hdc;
383  PIXELFORMATDESCRIPTOR pfd;
384  HGLRC hglrc;
385  int pixel_format = 0;
386  unsigned int matching;
387 
388  hwnd =
389  CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
390  10, 10, NULL, NULL, SDL_Instance, NULL);
392 
393  hdc = GetDC(hwnd);
394 
395  WIN_GL_SetupPixelFormat(_this, &pfd);
396 
397  SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
398 
399  hglrc = _this->gl_data->wglCreateContext(hdc);
400  if (hglrc) {
401  _this->gl_data->wglMakeCurrent(hdc, hglrc);
402 
403  WIN_GL_InitExtensions(_this, hdc);
404 
405  if (_this->gl_data->HAS_WGL_ARB_pixel_format) {
406  _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
407  1, &pixel_format,
408  &matching);
409  }
410 
411  _this->gl_data->wglMakeCurrent(hdc, NULL);
412  _this->gl_data->wglDeleteContext(hglrc);
413  }
414  ReleaseDC(hwnd, hdc);
415  DestroyWindow(hwnd);
417 
418  return pixel_format;
419 }
420 
421 /* actual work of WIN_GL_SetupWindow() happens here. */
422 static int
423 WIN_GL_SetupWindowInternal(_THIS, SDL_Window * window)
424 {
425  HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
426  PIXELFORMATDESCRIPTOR pfd;
427  int pixel_format = 0;
428  int iAttribs[64];
429  int *iAttr;
430  int *iAccelAttr;
431  float fAttribs[1] = { 0 };
432 
433  WIN_GL_SetupPixelFormat(_this, &pfd);
434 
435  /* setup WGL_ARB_pixel_format attribs */
436  iAttr = &iAttribs[0];
437 
438  *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
439  *iAttr++ = GL_TRUE;
440  *iAttr++ = WGL_RED_BITS_ARB;
441  *iAttr++ = _this->gl_config.red_size;
442  *iAttr++ = WGL_GREEN_BITS_ARB;
443  *iAttr++ = _this->gl_config.green_size;
444  *iAttr++ = WGL_BLUE_BITS_ARB;
445  *iAttr++ = _this->gl_config.blue_size;
446 
447  if (_this->gl_config.alpha_size) {
448  *iAttr++ = WGL_ALPHA_BITS_ARB;
449  *iAttr++ = _this->gl_config.alpha_size;
450  }
451 
452  *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
453  *iAttr++ = _this->gl_config.double_buffer;
454 
455  *iAttr++ = WGL_DEPTH_BITS_ARB;
456  *iAttr++ = _this->gl_config.depth_size;
457 
459  *iAttr++ = WGL_STENCIL_BITS_ARB;
460  *iAttr++ = _this->gl_config.stencil_size;
461  }
462 
464  *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
465  *iAttr++ = _this->gl_config.accum_red_size;
466  }
467 
469  *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
470  *iAttr++ = _this->gl_config.accum_green_size;
471  }
472 
474  *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
475  *iAttr++ = _this->gl_config.accum_blue_size;
476  }
477 
479  *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
480  *iAttr++ = _this->gl_config.accum_alpha_size;
481  }
482 
483  if (_this->gl_config.stereo) {
484  *iAttr++ = WGL_STEREO_ARB;
485  *iAttr++ = GL_TRUE;
486  }
487 
489  *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
490  *iAttr++ = _this->gl_config.multisamplebuffers;
491  }
492 
494  *iAttr++ = WGL_SAMPLES_ARB;
495  *iAttr++ = _this->gl_config.multisamplesamples;
496  }
497 
498  /* We always choose either FULL or NO accel on Windows, because of flaky
499  drivers. If the app didn't specify, we use FULL, because that's
500  probably what they wanted (and if you didn't care and got FULL, that's
501  a perfectly valid result in any case). */
502  *iAttr++ = WGL_ACCELERATION_ARB;
503  iAccelAttr = iAttr;
504  if (_this->gl_config.accelerated) {
505  *iAttr++ = WGL_FULL_ACCELERATION_ARB;
506  } else {
507  *iAttr++ = WGL_NO_ACCELERATION_ARB;
508  }
509 
510  *iAttr = 0;
511 
512  /* Choose and set the closest available pixel format */
513  pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
514 
515  /* App said "don't care about accel" and FULL accel failed. Try NO. */
516  if ( ( !pixel_format ) && ( _this->gl_config.accelerated < 0 ) ) {
517  *iAccelAttr = WGL_NO_ACCELERATION_ARB;
518  pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
519  *iAccelAttr = WGL_FULL_ACCELERATION_ARB; /* if we try again. */
520  }
521  if (!pixel_format) {
522  pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd);
523  }
524  if (!pixel_format) {
525  return SDL_SetError("No matching GL pixel format available");
526  }
527  if (!SetPixelFormat(hdc, pixel_format, &pfd)) {
528  return WIN_SetError("SetPixelFormat()");
529  }
530  return 0;
531 }
532 
533 int
534 WIN_GL_SetupWindow(_THIS, SDL_Window * window)
535 {
536  /* The current context is lost in here; save it and reset it. */
537  SDL_Window *current_win = SDL_GL_GetCurrentWindow();
538  SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();
539  const int retval = WIN_GL_SetupWindowInternal(_this, window);
540  WIN_GL_MakeCurrent(_this, current_win, current_ctx);
541  return retval;
542 }
543 
545 WIN_GL_CreateContext(_THIS, SDL_Window * window)
546 {
547  HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
548  HGLRC context, share_context;
549 
551  share_context = (HGLRC)SDL_GL_GetCurrentContext();
552  } else {
553  share_context = 0;
554  }
555 
556  if (_this->gl_config.major_version < 3 &&
557  _this->gl_config.profile_mask == 0 &&
558  _this->gl_config.flags == 0) {
559  /* Create legacy context */
560  context = _this->gl_data->wglCreateContext(hdc);
561  if( share_context != 0 ) {
562  _this->gl_data->wglShareLists(share_context, context);
563  }
564  } else {
565  PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
566  HGLRC temp_context = _this->gl_data->wglCreateContext(hdc);
567  if (!temp_context) {
568  SDL_SetError("Could not create GL context");
569  return NULL;
570  }
571 
572  /* Make the context current */
573  if (WIN_GL_MakeCurrent(_this, window, temp_context) < 0) {
574  WIN_GL_DeleteContext(_this, temp_context);
575  return NULL;
576  }
577 
578  wglCreateContextAttribsARB =
579  (PFNWGLCREATECONTEXTATTRIBSARBPROC) _this->gl_data->
580  wglGetProcAddress("wglCreateContextAttribsARB");
581  if (!wglCreateContextAttribsARB) {
582  SDL_SetError("GL 3.x is not supported");
583  context = temp_context;
584  } else {
585  /* max 8 attributes plus terminator */
586  int attribs[9] = {
589  0
590  };
591  int iattr = 4;
592 
593  /* SDL profile bits match WGL profile bits */
594  if( _this->gl_config.profile_mask != 0 ) {
595  attribs[iattr++] = WGL_CONTEXT_PROFILE_MASK_ARB;
596  attribs[iattr++] = _this->gl_config.profile_mask;
597  }
598 
599  /* SDL flags match WGL flags */
600  if( _this->gl_config.flags != 0 ) {
601  attribs[iattr++] = WGL_CONTEXT_FLAGS_ARB;
602  attribs[iattr++] = _this->gl_config.flags;
603  }
604 
605  attribs[iattr++] = 0;
606 
607  /* Create the GL 3.x context */
608  context = wglCreateContextAttribsARB(hdc, share_context, attribs);
609  /* Delete the GL 2.x context */
610  _this->gl_data->wglDeleteContext(temp_context);
611  }
612  }
613 
614  if (!context) {
615  WIN_SetError("Could not create GL context");
616  return NULL;
617  }
618 
619  if (WIN_GL_MakeCurrent(_this, window, context) < 0) {
620  WIN_GL_DeleteContext(_this, context);
621  return NULL;
622  }
623 
624  WIN_GL_InitExtensions(_this, hdc);
625 
626  return context;
627 }
628 
629 int
630 WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
631 {
632  HDC hdc;
633 
634  if (!_this->gl_data) {
635  return SDL_SetError("OpenGL not initialized");
636  }
637 
638  /* sanity check that higher level handled this. */
639  SDL_assert(window || (!window && !context));
640 
641  /* Some Windows drivers freak out if hdc is NULL, even when context is
642  NULL, against spec. Since hdc is _supposed_ to be ignored if context
643  is NULL, we either use the current GL window, or do nothing if we
644  already have no current context. */
645  if (!window) {
646  window = SDL_GL_GetCurrentWindow();
647  if (!window) {
649  return 0; /* already done. */
650  }
651  }
652 
653  hdc = ((SDL_WindowData *) window->driverdata)->hdc;
654  if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) {
655  return WIN_SetError("wglMakeCurrent()");
656  }
657  return 0;
658 }
659 
660 int
661 WIN_GL_SetSwapInterval(_THIS, int interval)
662 {
663  if ((interval < 0) && (!_this->gl_data->HAS_WGL_EXT_swap_control_tear)) {
664  return SDL_SetError("Negative swap interval unsupported in this GL");
665  } else if (_this->gl_data->wglSwapIntervalEXT) {
666  if (_this->gl_data->wglSwapIntervalEXT(interval) != TRUE) {
667  return WIN_SetError("wglSwapIntervalEXT()");
668  }
669  } else {
670  return SDL_Unsupported();
671  }
672  return 0;
673 }
674 
675 int
676 WIN_GL_GetSwapInterval(_THIS)
677 {
678  int retval = 0;
679  if (_this->gl_data->wglGetSwapIntervalEXT) {
680  retval = _this->gl_data->wglGetSwapIntervalEXT();
681  }
682  return retval;
683 }
684 
685 void
686 WIN_GL_SwapWindow(_THIS, SDL_Window * window)
687 {
688  HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
689 
690  SwapBuffers(hdc);
691 }
692 
693 void
694 WIN_GL_DeleteContext(_THIS, SDL_GLContext context)
695 {
696  if (!_this->gl_data) {
697  return;
698  }
699  _this->gl_data->wglDeleteContext((HGLRC) context);
700 }
701 
702 #endif /* SDL_VIDEO_OPENGL_WGL */
703 
704 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
705 
706 /* vi: set ts=4 sw=4 expandtab: */
#define GL_TRUE
Definition: gl2.h:51
HINSTANCE SDL_Instance
#define WGL_DOUBLE_BUFFER_ARB
Definition: wglew.h:341
#define WGL_ACCUM_BLUE_BITS_ARB
Definition: wglew.h:356
#define WIN_UTF8ToString(S)
Definition: SDL_windows.h:42
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
GLsizei GLenum GLuint GLuint GLsizei GLchar * message
Definition: glew.h:2540
#define WGL_CONTEXT_MAJOR_VERSION_ARB
Definition: wglew.h:192
#define NULL
Definition: ftobjs.h:61
DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt,...)
Definition: SDL_string.c:1277
GLuint start
Definition: glew.h:1239
SDL_bool
Definition: SDL_stdinc.h:116
#define WGL_FULL_ACCELERATION_ARB
Definition: wglew.h:363
DECLSPEC SDL_Window *SDLCALL SDL_GL_GetCurrentWindow(void)
Get the currently active OpenGL window.
Definition: SDL_video.c:2812
DECLSPEC void SDLCALL SDL_free(void *mem)
#define WGL_SAMPLE_BUFFERS_ARB
Definition: wglew.h:281
LPTSTR SDL_Appname
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:161
HDC hDC
Definition: wglew.h:308
typedef UINT(WINAPI *PFNWGLGETCONTEXTGPUIDAMDPROC)(HGLRC hglrc)
DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c)
Definition: SDL_string.c:575
GLenum func
Definition: SDL_opengl.h:5654
const GLint * attribs
Definition: glew.h:13064
GLsizei const GLchar *const * path
Definition: glew.h:5828
#define WGL_STEREO_ARB
Definition: wglew.h:342
#define WGL_CONTEXT_FLAGS_ARB
Definition: wglew.h:195
#define WGL_GREEN_BITS_ARB
Definition: wglew.h:347
typedef HDC(WINAPI *PFNWGLGETCURRENTREADDCARBPROC)(VOID)
struct SDL_GLDriverData * gl_data
Definition: SDL_sysvideo.h:315
#define WGL_BLUE_BITS_ARB
Definition: wglew.h:349
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
EGLContext EGLenum target
Definition: eglext.h:87
typedef HANDLE(WINAPI *PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC
int
Definition: SDL_systhread.c:37
#define _THIS
GLint GLsizei count
Definition: gl2ext.h:1011
DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle)
Definition: SDL_string.c:612
DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen)
Definition: SDL_string.c:448
char driver_path[256]
Definition: SDL_sysvideo.h:298
#define APIENTRYP
Definition: SDL_opengl.h:123
DECLSPEC void SDLCALL SDL_UnloadObject(void *handle)
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
GLuint index
Definition: glew.h:1800
typedef HGLRC(WINAPI *PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC)(UINT id)
#define WGL_ACCUM_GREEN_BITS_ARB
Definition: wglew.h:355
int share_with_current_context
Definition: SDL_sysvideo.h:295
#define WGL_ACCELERATION_ARB
Definition: wglew.h:328
#define SDL_assert(condition)
Definition: SDL_assert.h:159
DECLSPEC size_t SDLCALL SDL_strlen(const char *str)
Definition: SDL_string.c:389
#define WGL_ACCUM_ALPHA_BITS_ARB
Definition: wglew.h:357
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:83
int WIN_SetError(const char *prefix)
void WIN_PumpEvents(_THIS)
#define WGL_CONTEXT_MINOR_VERSION_ARB
Definition: wglew.h:193
#define WGL_CONTEXT_PROFILE_MASK_ARB
Definition: wglew.h:214
#define WGL_RED_BITS_ARB
Definition: wglew.h:345
HDC HGLRC hglrc
Definition: wglew.h:267
#define SDL_zerop(x)
Definition: SDL_stdinc.h:255
#define WGL_NO_ACCELERATION_ARB
Definition: wglew.h:361
#define WGL_DEPTH_BITS_ARB
Definition: wglew.h:358
DECLSPEC char *SDLCALL SDL_getenv(const char *name)
Definition: SDL_getenv.c:179
#define WGL_STENCIL_BITS_ARB
Definition: wglew.h:359
void * driverdata
Definition: SDL_sysvideo.h:99
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:284
TParseContext * context
#define WGL_ALPHA_BITS_ARB
Definition: wglew.h:351
#define WGL_SAMPLES_ARB
Definition: wglew.h:282
#define WGL_DRAW_TO_WINDOW_ARB
Definition: wglew.h:326
HGLRC const int * attribList
Definition: wglew.h:139
HGLRC hShareContext
Definition: wglew.h:139
struct SDL_VideoDevice::@87 gl_config
#define WGL_ACCUM_RED_BITS_ARB
Definition: wglew.h:354
#define SDL_Unsupported()
Definition: SDL_error.h:53
#define TRUE
Definition: ftobjs.h:53
DECLSPEC SDL_GLContext SDLCALL SDL_GL_GetCurrentContext(void)
Get the currently active OpenGL context.
Definition: SDL_video.c:2822
#define wglGetExtensionsStringARB
Definition: wglew.h:241
#define wglCreateContextAttribsARB
Definition: wglew.h:201
typedef BOOL(WINAPI *PFNWGLSETSTEREOEMITTERSTATE3DLPROC)(HDC hDC