src/video/win32/SDL_win32opengl.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 17 Jul 2006 06:47:33 +0000
changeset 1913 83420da906a5
child 1926 307355678142
permissions -rw-r--r--
Implemented Windows OpenGL support
Fixed slowdown enumerating display modes, which was hosing OpenGL as well...
Removed SDL_ from the render driver prefixes
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_win32video.h"
    25 
    26 /* WGL implementation of SDL OpenGL support */
    27 
    28 #if SDL_VIDEO_OPENGL
    29 #include "SDL_opengl.h"
    30 
    31 #define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL"
    32 
    33 
    34 int
    35 WIN_GL_LoadLibrary(_THIS, const char *path)
    36 {
    37     LPTSTR wpath;
    38     HANDLE handle;
    39 
    40     if (_this->gl_config.driver_loaded) {
    41         if (path) {
    42             SDL_SetError("OpenGL library already loaded");
    43             return -1;
    44         } else {
    45             ++_this->gl_config.driver_loaded;
    46             return 0;
    47         }
    48     }
    49     if (path == NULL) {
    50         path = DEFAULT_GL_DRIVER_PATH;
    51     }
    52     wpath = WIN_UTF8ToString(path);
    53     handle = LoadLibrary(wpath);
    54     SDL_free(wpath);
    55     if (!handle) {
    56         char message[1024];
    57         SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")",
    58                      path);
    59         WIN_SetError(message);
    60         return -1;
    61     }
    62 
    63     /* Load function pointers */
    64     _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
    65         GetProcAddress(handle, "wglGetProcAddress");
    66     _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
    67         GetProcAddress(handle, "wglCreateContext");
    68     _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
    69         GetProcAddress(handle, "wglDeleteContext");
    70     _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
    71         GetProcAddress(handle, "wglMakeCurrent");
    72     _this->gl_data->wglSwapIntervalEXT = (void (WINAPI *) (int))
    73         GetProcAddress(handle, "wglSwapIntervalEXT");
    74     _this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *) (void))
    75         GetProcAddress(handle, "wglGetSwapIntervalEXT");
    76 
    77     if (!_this->gl_data->wglGetProcAddress ||
    78         !_this->gl_data->wglCreateContext ||
    79         !_this->gl_data->wglDeleteContext ||
    80         !_this->gl_data->wglMakeCurrent) {
    81         SDL_SetError("Could not retrieve OpenGL functions");
    82         FreeLibrary(handle);
    83         return -1;
    84     }
    85 
    86     _this->gl_config.dll_handle = handle;
    87     SDL_strlcpy(_this->gl_config.driver_path, path,
    88                 SDL_arraysize(_this->gl_config.driver_path));
    89     _this->gl_config.driver_loaded = 1;
    90     return 0;
    91 }
    92 
    93 void *
    94 WIN_GL_GetProcAddress(_THIS, const char *proc)
    95 {
    96     void *func;
    97 
    98     /* This is to pick up extensions */
    99     func = _this->gl_data->wglGetProcAddress(proc);
   100     if (!func) {
   101         /* This is probably a normal GL function */
   102         func = GetProcAddress(_this->gl_config.dll_handle, proc);
   103     }
   104     return func;
   105 }
   106 
   107 static void
   108 WIN_GL_UnloadLibrary(_THIS)
   109 {
   110     if (_this->gl_config.driver_loaded > 0) {
   111         if (--_this->gl_config.driver_loaded > 0) {
   112             return;
   113         }
   114         FreeLibrary((HMODULE) _this->gl_config.dll_handle);
   115         _this->gl_config.dll_handle = NULL;
   116     }
   117 }
   118 
   119 static void
   120 WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd)
   121 {
   122     SDL_zerop(pfd);
   123     pfd->nSize = sizeof(*pfd);
   124     pfd->nVersion = 1;
   125     pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
   126     if (_this->gl_config.double_buffer) {
   127         pfd->dwFlags |= PFD_DOUBLEBUFFER;
   128     }
   129     if (_this->gl_config.stereo) {
   130         pfd->dwFlags |= PFD_STEREO;
   131     }
   132     pfd->iLayerType = PFD_MAIN_PLANE;
   133     pfd->iPixelType = PFD_TYPE_RGBA;
   134     pfd->cRedBits = _this->gl_config.red_size;
   135     pfd->cGreenBits = _this->gl_config.green_size;
   136     pfd->cBlueBits = _this->gl_config.blue_size;
   137     pfd->cAlphaBits = _this->gl_config.alpha_size;
   138     if (_this->gl_config.buffer_size) {
   139         pfd->cColorBits =
   140             _this->gl_config.buffer_size - _this->gl_config.alpha_size;
   141     } else {
   142         pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits);
   143     }
   144     pfd->cAccumRedBits = _this->gl_config.accum_red_size;
   145     pfd->cAccumGreenBits = _this->gl_config.accum_green_size;
   146     pfd->cAccumBlueBits = _this->gl_config.accum_blue_size;
   147     pfd->cAccumAlphaBits = _this->gl_config.accum_alpha_size;
   148     pfd->cAccumBits =
   149         (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits +
   150          pfd->cAccumAlphaBits);
   151     pfd->cDepthBits = _this->gl_config.depth_size;
   152     pfd->cStencilBits = _this->gl_config.stencil_size;
   153 }
   154 
   155 static SDL_bool
   156 HasExtension(const char *extension, const char *extensions)
   157 {
   158     const char *start;
   159     const char *where, *terminator;
   160 
   161     /* Extension names should not have spaces. */
   162     where = SDL_strchr(extension, ' ');
   163     if (where || *extension == '\0')
   164         return SDL_FALSE;
   165 
   166     if (!extensions)
   167         return SDL_FALSE;
   168 
   169     /* It takes a bit of care to be fool-proof about parsing the
   170      * OpenGL extensions string. Don't be fooled by sub-strings,
   171      * etc. */
   172 
   173     start = extensions;
   174 
   175     for (;;) {
   176         where = SDL_strstr(start, extension);
   177         if (!where)
   178             break;
   179 
   180         terminator = where + SDL_strlen(extension);
   181         if (where == start || *(where - 1) == ' ')
   182             if (*terminator == ' ' || *terminator == '\0')
   183                 return SDL_TRUE;
   184 
   185         start = terminator;
   186     }
   187     return SDL_FALSE;
   188 }
   189 
   190 static void
   191 WIN_GL_InitExtensions(_THIS)
   192 {
   193     HWND hwnd;
   194     HDC hdc;
   195     PIXELFORMATDESCRIPTOR pfd;
   196     int pixel_format;
   197     HGLRC hglrc;
   198     const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
   199     const GLubyte *(WINAPI * glGetStringFunc) (GLenum);
   200     const char *extensions;
   201 
   202     hwnd =
   203         CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
   204                      10, 10, NULL, NULL, SDL_Instance, NULL);
   205     WIN_PumpEvents(_this);
   206 
   207     hdc = GetDC(hwnd);
   208 
   209     WIN_GL_SetupPixelFormat(_this, &pfd);
   210     pixel_format = ChoosePixelFormat(hdc, &pfd);
   211     SetPixelFormat(hdc, pixel_format, &pfd);
   212 
   213     hglrc = _this->gl_data->wglCreateContext(hdc);
   214     if (hglrc) {
   215         _this->gl_data->wglMakeCurrent(hdc, hglrc);
   216     }
   217 
   218     wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC))
   219         _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
   220     if (wglGetExtensionsStringARB) {
   221         extensions = wglGetExtensionsStringARB(hdc);
   222     } else {
   223         extensions = NULL;
   224     }
   225 
   226     /* Check for WGL_ARB_pixel_format */
   227     _this->gl_data->WGL_ARB_pixel_format = 0;
   228     if (HasExtension("WGL_ARB_pixel_format", extensions)) {
   229         _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
   230                                                    (HDC, const int *,
   231                                                     const FLOAT *, UINT,
   232                                                     int *, UINT *))
   233             WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB");
   234         _this->gl_data->wglGetPixelFormatAttribivARB =
   235             (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *))
   236             WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB");
   237 
   238         if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
   239             (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
   240             _this->gl_data->WGL_ARB_pixel_format = 1;
   241         }
   242     }
   243 
   244     glGetStringFunc = WIN_GL_GetProcAddress(_this, "glGetString");
   245     if (glGetStringFunc) {
   246         extensions = (const char *) glGetStringFunc(GL_EXTENSIONS);
   247     } else {
   248         /* Uh oh, something is seriously wrong here... */
   249         extensions = NULL;
   250     }
   251 
   252     /* Check for WGL_EXT_swap_control */
   253     if (HasExtension("WGL_EXT_swap_control", extensions)) {
   254         _this->gl_data->wglSwapIntervalEXT =
   255             WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT");
   256         _this->gl_data->wglGetSwapIntervalEXT =
   257             WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT");
   258     }
   259 
   260     if (hglrc) {
   261         _this->gl_data->wglMakeCurrent(NULL, NULL);
   262         _this->gl_data->wglDeleteContext(hglrc);
   263     }
   264     ReleaseDC(hwnd, hdc);
   265     DestroyWindow(hwnd);
   266     WIN_PumpEvents(_this);
   267 }
   268 
   269 static void
   270 WIN_GL_Shutdown(_THIS)
   271 {
   272     if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
   273         return;
   274     }
   275 
   276     WIN_GL_UnloadLibrary(_this);
   277 
   278     SDL_free(_this->gl_data);
   279     _this->gl_data = NULL;
   280 }
   281 
   282 static int
   283 WIN_GL_Initialize(_THIS)
   284 {
   285     if (_this->gl_data) {
   286         ++_this->gl_data->initialized;
   287         return 0;
   288     }
   289 
   290     _this->gl_data =
   291         (struct SDL_GLDriverData *) SDL_calloc(1,
   292                                                sizeof(struct
   293                                                       SDL_GLDriverData));
   294     if (!_this->gl_data) {
   295         SDL_OutOfMemory();
   296         return -1;
   297     }
   298     _this->gl_data->initialized = 1;
   299 
   300     if (WIN_GL_LoadLibrary(_this, NULL) < 0) {
   301         return -1;
   302     }
   303 
   304     /* Initialize extensions */
   305     WIN_GL_InitExtensions(_this);
   306 
   307     return 0;
   308 }
   309 
   310 int
   311 WIN_GL_SetupWindow(_THIS, SDL_Window * window)
   312 {
   313     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   314     PIXELFORMATDESCRIPTOR pfd;
   315     int pixel_format;
   316     unsigned int matching;
   317     int iAttribs[64];
   318     int *iAttr;
   319     float fAttribs[1] = { 0 };
   320 
   321     if (WIN_GL_Initialize(_this) < 0) {
   322         return -1;
   323     }
   324 
   325     WIN_GL_SetupPixelFormat(_this, &pfd);
   326 
   327     /* setup WGL_ARB_pixel_format attribs */
   328     iAttr = &iAttribs[0];
   329 
   330     *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
   331     *iAttr++ = GL_TRUE;
   332     *iAttr++ = WGL_ACCELERATION_ARB;
   333     *iAttr++ = WGL_FULL_ACCELERATION_ARB;
   334     *iAttr++ = WGL_RED_BITS_ARB;
   335     *iAttr++ = _this->gl_config.red_size;
   336     *iAttr++ = WGL_GREEN_BITS_ARB;
   337     *iAttr++ = _this->gl_config.green_size;
   338     *iAttr++ = WGL_BLUE_BITS_ARB;
   339     *iAttr++ = _this->gl_config.blue_size;
   340 
   341     if (_this->gl_config.alpha_size) {
   342         *iAttr++ = WGL_ALPHA_BITS_ARB;
   343         *iAttr++ = _this->gl_config.alpha_size;
   344     }
   345 
   346     *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
   347     *iAttr++ = _this->gl_config.double_buffer;
   348 
   349     *iAttr++ = WGL_DEPTH_BITS_ARB;
   350     *iAttr++ = _this->gl_config.depth_size;
   351 
   352     if (_this->gl_config.stencil_size) {
   353         *iAttr++ = WGL_STENCIL_BITS_ARB;
   354         *iAttr++ = _this->gl_config.stencil_size;
   355     }
   356 
   357     if (_this->gl_config.accum_red_size) {
   358         *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
   359         *iAttr++ = _this->gl_config.accum_red_size;
   360     }
   361 
   362     if (_this->gl_config.accum_green_size) {
   363         *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
   364         *iAttr++ = _this->gl_config.accum_green_size;
   365     }
   366 
   367     if (_this->gl_config.accum_blue_size) {
   368         *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
   369         *iAttr++ = _this->gl_config.accum_blue_size;
   370     }
   371 
   372     if (_this->gl_config.accum_alpha_size) {
   373         *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
   374         *iAttr++ = _this->gl_config.accum_alpha_size;
   375     }
   376 
   377     if (_this->gl_config.stereo) {
   378         *iAttr++ = WGL_STEREO_ARB;
   379         *iAttr++ = GL_TRUE;
   380     }
   381 
   382     if (_this->gl_config.multisamplebuffers) {
   383         *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
   384         *iAttr++ = _this->gl_config.multisamplebuffers;
   385     }
   386 
   387     if (_this->gl_config.multisamplesamples) {
   388         *iAttr++ = WGL_SAMPLES_ARB;
   389         *iAttr++ = _this->gl_config.multisamplesamples;
   390     }
   391 
   392     if (_this->gl_config.accelerated >= 0) {
   393         *iAttr++ = WGL_ACCELERATION_ARB;
   394         *iAttr++ =
   395             (_this->gl_config.
   396              accelerated ? WGL_GENERIC_ACCELERATION_ARB :
   397              WGL_NO_ACCELERATION_ARB);
   398     }
   399 
   400     *iAttr = 0;
   401 
   402     /* Choose and set the closest available pixel format */
   403     if (!_this->gl_data->WGL_ARB_pixel_format
   404         || !_this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
   405                                                     1, &pixel_format,
   406                                                     &matching) || !matching) {
   407         pixel_format = ChoosePixelFormat(hdc, &pfd);
   408     }
   409     if (!pixel_format) {
   410         SDL_SetError("No matching GL pixel format available");
   411         return -1;
   412     }
   413     if (!SetPixelFormat(hdc, pixel_format, &pfd)) {
   414         WIN_SetError("SetPixelFormat()");
   415         return (-1);
   416     }
   417     return 0;
   418 }
   419 
   420 void
   421 WIN_GL_CleanupWindow(_THIS, SDL_Window * window)
   422 {
   423     WIN_GL_Shutdown(_this);
   424 }
   425 
   426 int
   427 WIN_GL_GetWindowAttribute(_THIS, SDL_Window * window, SDL_GLattr attrib,
   428                           int *value)
   429 {
   430     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   431     int pixel_format;
   432 
   433     pixel_format = GetPixelFormat(hdc);
   434 
   435     if (_this->gl_data->WGL_ARB_pixel_format) {
   436         int wgl_attrib;
   437 
   438         switch (attrib) {
   439         case SDL_GL_RED_SIZE:
   440             wgl_attrib = WGL_RED_BITS_ARB;
   441             break;
   442         case SDL_GL_GREEN_SIZE:
   443             wgl_attrib = WGL_GREEN_BITS_ARB;
   444             break;
   445         case SDL_GL_BLUE_SIZE:
   446             wgl_attrib = WGL_BLUE_BITS_ARB;
   447             break;
   448         case SDL_GL_ALPHA_SIZE:
   449             wgl_attrib = WGL_ALPHA_BITS_ARB;
   450             break;
   451         case SDL_GL_DOUBLEBUFFER:
   452             wgl_attrib = WGL_DOUBLE_BUFFER_ARB;
   453             break;
   454         case SDL_GL_BUFFER_SIZE:
   455             wgl_attrib = WGL_COLOR_BITS_ARB;
   456             break;
   457         case SDL_GL_DEPTH_SIZE:
   458             wgl_attrib = WGL_DEPTH_BITS_ARB;
   459             break;
   460         case SDL_GL_STENCIL_SIZE:
   461             wgl_attrib = WGL_STENCIL_BITS_ARB;
   462             break;
   463         case SDL_GL_ACCUM_RED_SIZE:
   464             wgl_attrib = WGL_ACCUM_RED_BITS_ARB;
   465             break;
   466         case SDL_GL_ACCUM_GREEN_SIZE:
   467             wgl_attrib = WGL_ACCUM_GREEN_BITS_ARB;
   468             break;
   469         case SDL_GL_ACCUM_BLUE_SIZE:
   470             wgl_attrib = WGL_ACCUM_BLUE_BITS_ARB;
   471             break;
   472         case SDL_GL_ACCUM_ALPHA_SIZE:
   473             wgl_attrib = WGL_ACCUM_ALPHA_BITS_ARB;
   474             break;
   475         case SDL_GL_STEREO:
   476             wgl_attrib = WGL_STEREO_ARB;
   477             break;
   478         case SDL_GL_MULTISAMPLEBUFFERS:
   479             wgl_attrib = WGL_SAMPLE_BUFFERS_ARB;
   480             break;
   481         case SDL_GL_MULTISAMPLESAMPLES:
   482             wgl_attrib = WGL_SAMPLES_ARB;
   483             break;
   484         case SDL_GL_ACCELERATED_VISUAL:
   485             wgl_attrib = WGL_ACCELERATION_ARB;
   486             _this->gl_data->wglGetPixelFormatAttribivARB(hdc, pixel_format, 0,
   487                                                          1, &wgl_attrib,
   488                                                          value);
   489             if (*value == WGL_NO_ACCELERATION_ARB) {
   490                 *value = SDL_FALSE;
   491             } else {
   492                 *value = SDL_TRUE;
   493             }
   494             return 0;
   495             break;
   496         default:
   497             return (-1);
   498         }
   499         _this->gl_data->wglGetPixelFormatAttribivARB(hdc, pixel_format, 0, 1,
   500                                                      &wgl_attrib, value);
   501         return 0;
   502     } else {
   503         PIXELFORMATDESCRIPTOR pfd;
   504         int retval;
   505 
   506         if (!DescribePixelFormat(hdc, pixel_format, sizeof(pfd), &pfd)) {
   507             WIN_SetError("DescribePixelFormat()");
   508             return -1;
   509         }
   510         retval = 0;
   511         switch (attrib) {
   512         case SDL_GL_RED_SIZE:
   513             *value = pfd.cRedBits;
   514             break;
   515         case SDL_GL_GREEN_SIZE:
   516             *value = pfd.cGreenBits;
   517             break;
   518         case SDL_GL_BLUE_SIZE:
   519             *value = pfd.cBlueBits;
   520             break;
   521         case SDL_GL_ALPHA_SIZE:
   522             *value = pfd.cAlphaBits;
   523             break;
   524         case SDL_GL_DOUBLEBUFFER:
   525             if (pfd.dwFlags & PFD_DOUBLEBUFFER) {
   526                 *value = 1;
   527             } else {
   528                 *value = 0;
   529             }
   530             break;
   531         case SDL_GL_BUFFER_SIZE:
   532             *value = pfd.cColorBits;
   533             break;
   534         case SDL_GL_DEPTH_SIZE:
   535             *value = pfd.cDepthBits;
   536             break;
   537         case SDL_GL_STENCIL_SIZE:
   538             *value = pfd.cStencilBits;
   539             break;
   540         case SDL_GL_ACCUM_RED_SIZE:
   541             *value = pfd.cAccumRedBits;
   542             break;
   543         case SDL_GL_ACCUM_GREEN_SIZE:
   544             *value = pfd.cAccumGreenBits;
   545             break;
   546         case SDL_GL_ACCUM_BLUE_SIZE:
   547             *value = pfd.cAccumBlueBits;
   548             break;
   549         case SDL_GL_ACCUM_ALPHA_SIZE:
   550             *value = pfd.cAccumAlphaBits;
   551             break;
   552         case SDL_GL_STEREO:
   553             if (pfd.dwFlags & PFD_STEREO) {
   554                 *value = 1;
   555             } else {
   556                 *value = 0;
   557             }
   558             break;
   559         case SDL_GL_MULTISAMPLEBUFFERS:
   560             *value = 0;
   561             break;
   562         case SDL_GL_MULTISAMPLESAMPLES:
   563             *value = 1;
   564             break;
   565         default:
   566             retval = -1;
   567             break;
   568         }
   569         return retval;
   570     }
   571 }
   572 
   573 SDL_GLContext
   574 WIN_GL_CreateContext(_THIS, SDL_Window * window)
   575 {
   576     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   577 
   578     return _this->gl_data->wglCreateContext(hdc);
   579 }
   580 
   581 int
   582 WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   583 {
   584     HDC hdc;
   585     int status;
   586 
   587     if (window) {
   588         hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   589     } else {
   590         hdc = NULL;
   591     }
   592     if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) {
   593         WIN_SetError("wglMakeCurrent()");
   594         status = -1;
   595     } else {
   596         status = 0;
   597     }
   598     return status;
   599 }
   600 
   601 int
   602 WIN_GL_SetSwapInterval(_THIS, int interval)
   603 {
   604     if (_this->gl_data->wglSwapIntervalEXT) {
   605         _this->gl_data->wglSwapIntervalEXT(interval);
   606         return 0;
   607     } else {
   608         SDL_Unsupported();
   609         return -1;
   610     }
   611 }
   612 
   613 int
   614 WIN_GL_GetSwapInterval(_THIS)
   615 {
   616     if (_this->gl_data->wglGetSwapIntervalEXT) {
   617         return _this->gl_data->wglGetSwapIntervalEXT();
   618     } else {
   619         SDL_Unsupported();
   620         return -1;
   621     }
   622 }
   623 
   624 void
   625 WIN_GL_SwapWindow(_THIS, SDL_Window * window)
   626 {
   627     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   628 
   629     SwapBuffers(hdc);
   630 }
   631 
   632 void
   633 WIN_GL_DeleteContext(_THIS, SDL_GLContext context)
   634 {
   635     if (context) {
   636         _this->gl_data->wglDeleteContext((HGLRC) context);
   637     }
   638 }
   639 
   640 #endif /* SDL_VIDEO_OPENGL */
   641 
   642 
   643 /* vi: set ts=4 sw=4 expandtab: */