src/video/windows/SDL_windowsopengl.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 31 Oct 2011 05:56:58 -0400
changeset 6044 35448a5ea044
parent 5644 f74f1a736dd9
child 6138 4c64952a58fb
permissions -rw-r--r--
Lots of fixes importing SDL source wholesale into a new iOS project
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2011 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_windowsvideo.h"
    26 
    27 /* WGL implementation of SDL OpenGL support */
    28 
    29 #if SDL_VIDEO_OPENGL_WGL
    30 #include "SDL_opengl.h"
    31 
    32 #define DEFAULT_OPENGL "OPENGL32.DLL"
    33 
    34 #ifndef WGL_ARB_create_context
    35 #define WGL_ARB_create_context
    36 #define WGL_CONTEXT_MAJOR_VERSION_ARB   0x2091
    37 #define WGL_CONTEXT_MINOR_VERSION_ARB   0x2092
    38 #define WGL_CONTEXT_LAYER_PLANE_ARB     0x2093
    39 #define WGL_CONTEXT_FLAGS_ARB           0x2093
    40 #define WGL_CONTEXT_DEBUG_BIT_ARB       0x0001
    41 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB  0x0002
    42 #endif
    43 
    44 typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
    45                                                             HGLRC
    46                                                             hShareContext,
    47                                                             const int
    48                                                             *attribList);
    49 
    50 int
    51 WIN_GL_LoadLibrary(_THIS, const char *path)
    52 {
    53     LPTSTR wpath;
    54     HANDLE handle;
    55 
    56     if (path == NULL) {
    57         path = SDL_getenv("SDL_OPENGL_LIBRARY");
    58     }
    59     if (path == NULL) {
    60         path = DEFAULT_OPENGL;
    61     }
    62     wpath = WIN_UTF8ToString(path);
    63     _this->gl_config.dll_handle = LoadLibrary(wpath);
    64     SDL_free(wpath);
    65     if (!_this->gl_config.dll_handle) {
    66         char message[1024];
    67         SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")",
    68                      path);
    69         WIN_SetError(message);
    70         return -1;
    71     }
    72     SDL_strlcpy(_this->gl_config.driver_path, path,
    73                 SDL_arraysize(_this->gl_config.driver_path));
    74 
    75     /* Allocate OpenGL memory */
    76     _this->gl_data =
    77         (struct SDL_GLDriverData *) SDL_calloc(1,
    78                                                sizeof(struct
    79                                                       SDL_GLDriverData));
    80     if (!_this->gl_data) {
    81         SDL_OutOfMemory();
    82         return -1;
    83     }
    84 
    85     /* Load function pointers */
    86     handle = _this->gl_config.dll_handle;
    87     _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
    88         GetProcAddress(handle, "wglGetProcAddress");
    89     _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
    90         GetProcAddress(handle, "wglCreateContext");
    91     _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
    92         GetProcAddress(handle, "wglDeleteContext");
    93     _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
    94         GetProcAddress(handle, "wglMakeCurrent");
    95     _this->gl_data->wglSwapIntervalEXT = (void (WINAPI *) (int))
    96         GetProcAddress(handle, "wglSwapIntervalEXT");
    97     _this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *) (void))
    98         GetProcAddress(handle, "wglGetSwapIntervalEXT");
    99 
   100     if (!_this->gl_data->wglGetProcAddress ||
   101         !_this->gl_data->wglCreateContext ||
   102         !_this->gl_data->wglDeleteContext ||
   103         !_this->gl_data->wglMakeCurrent) {
   104         SDL_SetError("Could not retrieve OpenGL functions");
   105         SDL_UnloadObject(handle);
   106         return -1;
   107     }
   108 
   109     return 0;
   110 }
   111 
   112 void *
   113 WIN_GL_GetProcAddress(_THIS, const char *proc)
   114 {
   115     void *func;
   116 
   117     /* This is to pick up extensions */
   118     func = _this->gl_data->wglGetProcAddress(proc);
   119     if (!func) {
   120         /* This is probably a normal GL function */
   121         func = GetProcAddress(_this->gl_config.dll_handle, proc);
   122     }
   123     return func;
   124 }
   125 
   126 void
   127 WIN_GL_UnloadLibrary(_THIS)
   128 {
   129     FreeLibrary((HMODULE) _this->gl_config.dll_handle);
   130     _this->gl_config.dll_handle = NULL;
   131 
   132     /* Free OpenGL memory */
   133     SDL_free(_this->gl_data);
   134     _this->gl_data = NULL;
   135 }
   136 
   137 static void
   138 WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd)
   139 {
   140     SDL_zerop(pfd);
   141     pfd->nSize = sizeof(*pfd);
   142     pfd->nVersion = 1;
   143     pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
   144     if (_this->gl_config.double_buffer) {
   145         pfd->dwFlags |= PFD_DOUBLEBUFFER;
   146     }
   147     if (_this->gl_config.stereo) {
   148         pfd->dwFlags |= PFD_STEREO;
   149     }
   150     pfd->iLayerType = PFD_MAIN_PLANE;
   151     pfd->iPixelType = PFD_TYPE_RGBA;
   152     pfd->cRedBits = _this->gl_config.red_size;
   153     pfd->cGreenBits = _this->gl_config.green_size;
   154     pfd->cBlueBits = _this->gl_config.blue_size;
   155     pfd->cAlphaBits = _this->gl_config.alpha_size;
   156     if (_this->gl_config.buffer_size) {
   157         pfd->cColorBits =
   158             _this->gl_config.buffer_size - _this->gl_config.alpha_size;
   159     } else {
   160         pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits);
   161     }
   162     pfd->cAccumRedBits = _this->gl_config.accum_red_size;
   163     pfd->cAccumGreenBits = _this->gl_config.accum_green_size;
   164     pfd->cAccumBlueBits = _this->gl_config.accum_blue_size;
   165     pfd->cAccumAlphaBits = _this->gl_config.accum_alpha_size;
   166     pfd->cAccumBits =
   167         (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits +
   168          pfd->cAccumAlphaBits);
   169     pfd->cDepthBits = _this->gl_config.depth_size;
   170     pfd->cStencilBits = _this->gl_config.stencil_size;
   171 }
   172 
   173 /* Choose the closest pixel format that meets or exceeds the target.
   174    FIXME: Should we weight any particular attribute over any other?
   175 */
   176 static int
   177 WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target)
   178 {
   179     PIXELFORMATDESCRIPTOR pfd;
   180     int count, index, best = 0;
   181     unsigned int dist, best_dist = ~0U;
   182 
   183     count = DescribePixelFormat(hdc, 1, sizeof(pfd), NULL);
   184 
   185     for (index = 1; index <= count; index++) {
   186 
   187         if (!DescribePixelFormat(hdc, index, sizeof(pfd), &pfd)) {
   188             continue;
   189         }
   190 
   191         if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) {
   192             continue;
   193         }
   194 
   195         if (pfd.iLayerType != target->iLayerType) {
   196             continue;
   197         }
   198         if (pfd.iPixelType != target->iPixelType) {
   199             continue;
   200         }
   201 
   202         dist = 0;
   203 
   204         if (pfd.cColorBits < target->cColorBits) {
   205             continue;
   206         } else {
   207             dist += (pfd.cColorBits - target->cColorBits);
   208         }
   209         if (pfd.cRedBits < target->cRedBits) {
   210             continue;
   211         } else {
   212             dist += (pfd.cRedBits - target->cRedBits);
   213         }
   214         if (pfd.cGreenBits < target->cGreenBits) {
   215             continue;
   216         } else {
   217             dist += (pfd.cGreenBits - target->cGreenBits);
   218         }
   219         if (pfd.cBlueBits < target->cBlueBits) {
   220             continue;
   221         } else {
   222             dist += (pfd.cBlueBits - target->cBlueBits);
   223         }
   224         if (pfd.cAlphaBits < target->cAlphaBits) {
   225             continue;
   226         } else {
   227             dist += (pfd.cAlphaBits - target->cAlphaBits);
   228         }
   229         if (pfd.cAccumBits < target->cAccumBits) {
   230             continue;
   231         } else {
   232             dist += (pfd.cAccumBits - target->cAccumBits);
   233         }
   234         if (pfd.cAccumRedBits < target->cAccumRedBits) {
   235             continue;
   236         } else {
   237             dist += (pfd.cAccumRedBits - target->cAccumRedBits);
   238         }
   239         if (pfd.cAccumGreenBits < target->cAccumGreenBits) {
   240             continue;
   241         } else {
   242             dist += (pfd.cAccumGreenBits - target->cAccumGreenBits);
   243         }
   244         if (pfd.cAccumBlueBits < target->cAccumBlueBits) {
   245             continue;
   246         } else {
   247             dist += (pfd.cAccumBlueBits - target->cAccumBlueBits);
   248         }
   249         if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) {
   250             continue;
   251         } else {
   252             dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits);
   253         }
   254         if (pfd.cDepthBits < target->cDepthBits) {
   255             continue;
   256         } else {
   257             dist += (pfd.cDepthBits - target->cDepthBits);
   258         }
   259         if (pfd.cStencilBits < target->cStencilBits) {
   260             continue;
   261         } else {
   262             dist += (pfd.cStencilBits - target->cStencilBits);
   263         }
   264 
   265         if (dist < best_dist) {
   266             best = index;
   267             best_dist = dist;
   268         }
   269     }
   270 
   271     return best;
   272 }
   273 
   274 static SDL_bool
   275 HasExtension(const char *extension, const char *extensions)
   276 {
   277     const char *start;
   278     const char *where, *terminator;
   279 
   280     /* Extension names should not have spaces. */
   281     where = SDL_strchr(extension, ' ');
   282     if (where || *extension == '\0')
   283         return SDL_FALSE;
   284 
   285     if (!extensions)
   286         return SDL_FALSE;
   287 
   288     /* It takes a bit of care to be fool-proof about parsing the
   289      * OpenGL extensions string. Don't be fooled by sub-strings,
   290      * etc. */
   291 
   292     start = extensions;
   293 
   294     for (;;) {
   295         where = SDL_strstr(start, extension);
   296         if (!where)
   297             break;
   298 
   299         terminator = where + SDL_strlen(extension);
   300         if (where == start || *(where - 1) == ' ')
   301             if (*terminator == ' ' || *terminator == '\0')
   302                 return SDL_TRUE;
   303 
   304         start = terminator;
   305     }
   306     return SDL_FALSE;
   307 }
   308 
   309 static void
   310 WIN_GL_InitExtensions(_THIS, HDC hdc)
   311 {
   312     const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
   313     const char *extensions;
   314 
   315     wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC))
   316         _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
   317     if (wglGetExtensionsStringARB) {
   318         extensions = wglGetExtensionsStringARB(hdc);
   319     } else {
   320         extensions = NULL;
   321     }
   322 
   323     /* Check for WGL_ARB_pixel_format */
   324     _this->gl_data->WGL_ARB_pixel_format = 0;
   325     if (HasExtension("WGL_ARB_pixel_format", extensions)) {
   326         _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
   327                                                    (HDC, const int *,
   328                                                     const FLOAT *, UINT,
   329                                                     int *, UINT *))
   330             WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB");
   331         _this->gl_data->wglGetPixelFormatAttribivARB =
   332             (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *))
   333             WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB");
   334 
   335         if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
   336             (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
   337             _this->gl_data->WGL_ARB_pixel_format = 1;
   338         }
   339     }
   340 
   341     /* Check for WGL_EXT_swap_control */
   342     if (HasExtension("WGL_EXT_swap_control", extensions)) {
   343         _this->gl_data->wglSwapIntervalEXT =
   344             WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT");
   345         _this->gl_data->wglGetSwapIntervalEXT =
   346             WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT");
   347     } else {
   348         _this->gl_data->wglSwapIntervalEXT = NULL;
   349         _this->gl_data->wglGetSwapIntervalEXT = NULL;
   350     }
   351 }
   352 
   353 static int
   354 WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs)
   355 {
   356     HWND hwnd;
   357     HDC hdc;
   358     PIXELFORMATDESCRIPTOR pfd;
   359     HGLRC hglrc;
   360     int pixel_format = 0;
   361     unsigned int matching;
   362 
   363     hwnd =
   364         CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
   365                      10, 10, NULL, NULL, SDL_Instance, NULL);
   366     WIN_PumpEvents(_this);
   367 
   368     hdc = GetDC(hwnd);
   369 
   370     WIN_GL_SetupPixelFormat(_this, &pfd);
   371 
   372     SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
   373 
   374     hglrc = _this->gl_data->wglCreateContext(hdc);
   375     if (hglrc) {
   376         _this->gl_data->wglMakeCurrent(hdc, hglrc);
   377 
   378         WIN_GL_InitExtensions(_this, hdc);
   379 
   380         if (_this->gl_data->WGL_ARB_pixel_format) {
   381             _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
   382                                                     1, &pixel_format,
   383                                                     &matching);
   384         }
   385 
   386         _this->gl_data->wglMakeCurrent(NULL, NULL);
   387         _this->gl_data->wglDeleteContext(hglrc);
   388     }
   389     ReleaseDC(hwnd, hdc);
   390     DestroyWindow(hwnd);
   391     WIN_PumpEvents(_this);
   392 
   393     return pixel_format;
   394 }
   395 
   396 int
   397 WIN_GL_SetupWindow(_THIS, SDL_Window * window)
   398 {
   399     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   400     PIXELFORMATDESCRIPTOR pfd;
   401     int pixel_format;
   402     int iAttribs[64];
   403     int *iAttr;
   404     float fAttribs[1] = { 0 };
   405 
   406     WIN_GL_SetupPixelFormat(_this, &pfd);
   407 
   408     /* setup WGL_ARB_pixel_format attribs */
   409     iAttr = &iAttribs[0];
   410 
   411     *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
   412     *iAttr++ = GL_TRUE;
   413     *iAttr++ = WGL_RED_BITS_ARB;
   414     *iAttr++ = _this->gl_config.red_size;
   415     *iAttr++ = WGL_GREEN_BITS_ARB;
   416     *iAttr++ = _this->gl_config.green_size;
   417     *iAttr++ = WGL_BLUE_BITS_ARB;
   418     *iAttr++ = _this->gl_config.blue_size;
   419 
   420     if (_this->gl_config.alpha_size) {
   421         *iAttr++ = WGL_ALPHA_BITS_ARB;
   422         *iAttr++ = _this->gl_config.alpha_size;
   423     }
   424 
   425     *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
   426     *iAttr++ = _this->gl_config.double_buffer;
   427 
   428     *iAttr++ = WGL_DEPTH_BITS_ARB;
   429     *iAttr++ = _this->gl_config.depth_size;
   430 
   431     if (_this->gl_config.stencil_size) {
   432         *iAttr++ = WGL_STENCIL_BITS_ARB;
   433         *iAttr++ = _this->gl_config.stencil_size;
   434     }
   435 
   436     if (_this->gl_config.accum_red_size) {
   437         *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
   438         *iAttr++ = _this->gl_config.accum_red_size;
   439     }
   440 
   441     if (_this->gl_config.accum_green_size) {
   442         *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
   443         *iAttr++ = _this->gl_config.accum_green_size;
   444     }
   445 
   446     if (_this->gl_config.accum_blue_size) {
   447         *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
   448         *iAttr++ = _this->gl_config.accum_blue_size;
   449     }
   450 
   451     if (_this->gl_config.accum_alpha_size) {
   452         *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
   453         *iAttr++ = _this->gl_config.accum_alpha_size;
   454     }
   455 
   456     if (_this->gl_config.stereo) {
   457         *iAttr++ = WGL_STEREO_ARB;
   458         *iAttr++ = GL_TRUE;
   459     }
   460 
   461     if (_this->gl_config.multisamplebuffers) {
   462         *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
   463         *iAttr++ = _this->gl_config.multisamplebuffers;
   464     }
   465 
   466     if (_this->gl_config.multisamplesamples) {
   467         *iAttr++ = WGL_SAMPLES_ARB;
   468         *iAttr++ = _this->gl_config.multisamplesamples;
   469     }
   470 
   471     if (_this->gl_config.accelerated >= 0) {
   472         *iAttr++ = WGL_ACCELERATION_ARB;
   473         *iAttr++ = (_this->gl_config.accelerated ? WGL_FULL_ACCELERATION_ARB :
   474                                                    WGL_NO_ACCELERATION_ARB);
   475     }
   476 
   477     *iAttr = 0;
   478 
   479     /* Choose and set the closest available pixel format */
   480     pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
   481     if (!pixel_format) {
   482         pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd);
   483     }
   484     if (!pixel_format) {
   485         SDL_SetError("No matching GL pixel format available");
   486         return -1;
   487     }
   488     if (!SetPixelFormat(hdc, pixel_format, &pfd)) {
   489         WIN_SetError("SetPixelFormat()");
   490         return (-1);
   491     }
   492     return 0;
   493 }
   494 
   495 SDL_GLContext
   496 WIN_GL_CreateContext(_THIS, SDL_Window * window)
   497 {
   498     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   499     HGLRC context;
   500 
   501     if (_this->gl_config.major_version < 3) {
   502         context = _this->gl_data->wglCreateContext(hdc);
   503     } else {
   504         PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
   505         HGLRC temp_context = _this->gl_data->wglCreateContext(hdc);
   506         if (!temp_context) {
   507             SDL_SetError("Could not create GL context");
   508             return NULL;
   509         }
   510 
   511         /* Make the context current */
   512         if (WIN_GL_MakeCurrent(_this, window, temp_context) < 0) {
   513             WIN_GL_DeleteContext(_this, temp_context);
   514             return NULL;
   515         }
   516 
   517         wglCreateContextAttribsARB =
   518             (PFNWGLCREATECONTEXTATTRIBSARBPROC) _this->gl_data->
   519             wglGetProcAddress("wglCreateContextAttribsARB");
   520         if (!wglCreateContextAttribsARB) {
   521             SDL_SetError("GL 3.x is not supported");
   522             context = temp_context;
   523         } else {
   524             int attribs[] = {
   525                 WGL_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version,
   526                 WGL_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version,
   527                 0
   528             };
   529             /* Create the GL 3.x context */
   530             context = wglCreateContextAttribsARB(hdc, 0, attribs);
   531             /* Delete the GL 2.x context */
   532             _this->gl_data->wglDeleteContext(temp_context);
   533         }
   534     }
   535 
   536     if (!context) {
   537         WIN_SetError("Could not create GL context");
   538         return NULL;
   539     }
   540 
   541     if (WIN_GL_MakeCurrent(_this, window, context) < 0) {
   542         WIN_GL_DeleteContext(_this, context);
   543         return NULL;
   544     }
   545 
   546     WIN_GL_InitExtensions(_this, hdc);
   547 
   548     return context;
   549 }
   550 
   551 int
   552 WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   553 {
   554     HDC hdc;
   555     int status;
   556 
   557     if (window) {
   558         hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   559     } else {
   560         hdc = NULL;
   561     }
   562     if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) {
   563         WIN_SetError("wglMakeCurrent()");
   564         status = -1;
   565     } else {
   566         status = 0;
   567     }
   568     return status;
   569 }
   570 
   571 int
   572 WIN_GL_SetSwapInterval(_THIS, int interval)
   573 {
   574     if (_this->gl_data->wglSwapIntervalEXT) {
   575         _this->gl_data->wglSwapIntervalEXT(interval);
   576         return 0;
   577     } else {
   578         SDL_Unsupported();
   579         return -1;
   580     }
   581 }
   582 
   583 int
   584 WIN_GL_GetSwapInterval(_THIS)
   585 {
   586     if (_this->gl_data->wglGetSwapIntervalEXT) {
   587         return _this->gl_data->wglGetSwapIntervalEXT();
   588     } else {
   589         SDL_Unsupported();
   590         return -1;
   591     }
   592 }
   593 
   594 void
   595 WIN_GL_SwapWindow(_THIS, SDL_Window * window)
   596 {
   597     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   598 
   599     SwapBuffers(hdc);
   600 }
   601 
   602 void
   603 WIN_GL_DeleteContext(_THIS, SDL_GLContext context)
   604 {
   605     _this->gl_data->wglDeleteContext((HGLRC) context);
   606 }
   607 
   608 #endif /* SDL_VIDEO_OPENGL_WGL */
   609 
   610 #endif /* SDL_VIDEO_DRIVER_WINDOWS */
   611 
   612 /* vi: set ts=4 sw=4 expandtab: */