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