src/video/windows/SDL_windowsopengl.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 10 Jan 2017 08:54:33 -0800
changeset 10806 36f40b8cc979
parent 10737 3406a0f8b041
child 11332 e3797888c6f1
permissions -rw-r--r--
Fixed bugs 2570, 3145, improved OpenGL ES context support on Windows and X11

Mark Callow

The attached patch does the following for the X11 and Windows platforms, the only ones where SDL attempts to use context_create_es_profile:

- Adds SDL_HINT_OPENGL_ES_DRIVER by which the application can
say to use the OpenGL ES driver & EGL rather than the Open GL
driver. (For bug #2570)
- Adds code to {WIN,X11}_GL_InitExtensions to determine the maximum
OpenGL ES version supported by the OpenGL driver (for bug #3145)
- Modifies the test that determines whether to use the OpenGL
driver or the real OpenGL ES driver to take into account the
hint, the requested and supported ES version and whether ES 1.X
is being requested. (For bug #2570 & bug #3145)
- Enables the testgles2 test for __WINDOWS__ and __LINUX__ and adds
the test to the VisualC projects.

With the fix in place I have run testdraw2, testgl and testgles2 without any issues and have run my own apps that use OpenGL, OpenGL ES 3 and OpenGL ES 1.1.
slouken@1913
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
slouken@1913
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@1913
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@1913
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@1913
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@1913
    22
slouken@6044
    23
#if SDL_VIDEO_DRIVER_WINDOWS
slouken@6044
    24
icculus@7553
    25
#include "SDL_assert.h"
slouken@7865
    26
#include "SDL_loadso.h"
slouken@5062
    27
#include "SDL_windowsvideo.h"
gabomdq@8021
    28
#include "SDL_windowsopengles.h"
slouken@10806
    29
#include "SDL_hints.h"
slouken@1913
    30
slouken@1913
    31
/* WGL implementation of SDL OpenGL support */
slouken@1913
    32
slouken@1952
    33
#if SDL_VIDEO_OPENGL_WGL
slouken@1913
    34
#include "SDL_opengl.h"
slouken@1913
    35
slouken@1952
    36
#define DEFAULT_OPENGL "OPENGL32.DLL"
slouken@1913
    37
slouken@3100
    38
#ifndef WGL_ARB_create_context
slouken@3100
    39
#define WGL_ARB_create_context
slouken@3100
    40
#define WGL_CONTEXT_MAJOR_VERSION_ARB   0x2091
slouken@3100
    41
#define WGL_CONTEXT_MINOR_VERSION_ARB   0x2092
slouken@3100
    42
#define WGL_CONTEXT_LAYER_PLANE_ARB     0x2093
kajetan@6380
    43
#define WGL_CONTEXT_FLAGS_ARB           0x2094
slouken@3100
    44
#define WGL_CONTEXT_DEBUG_BIT_ARB       0x0001
slouken@3100
    45
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB  0x0002
slouken@6296
    46
slouken@6296
    47
#ifndef WGL_ARB_create_context_profile
slouken@6296
    48
#define WGL_ARB_create_context_profile
slouken@6296
    49
#define WGL_CONTEXT_PROFILE_MASK_ARB              0x9126
slouken@6296
    50
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB          0x00000001
slouken@6296
    51
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
slouken@6296
    52
#endif
slouken@6296
    53
slouken@6296
    54
#ifndef WGL_ARB_create_context_robustness
slouken@6296
    55
#define WGL_ARB_create_context_robustness
slouken@6296
    56
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB         0x00000004
slouken@6296
    57
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB     0x8256
slouken@6296
    58
#define WGL_NO_RESET_NOTIFICATION_ARB                   0x8261
slouken@6296
    59
#define WGL_LOSE_CONTEXT_ON_RESET_ARB                   0x8252
slouken@6296
    60
#endif
slouken@6296
    61
#endif
slouken@6296
    62
slouken@6296
    63
#ifndef WGL_EXT_create_context_es2_profile
slouken@6296
    64
#define WGL_EXT_create_context_es2_profile
slouken@6296
    65
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT           0x00000004
slouken@3100
    66
#endif
slouken@3100
    67
slouken@6393
    68
#ifndef WGL_EXT_create_context_es_profile
slouken@6393
    69
#define WGL_EXT_create_context_es_profile
slouken@6393
    70
#define WGL_CONTEXT_ES_PROFILE_BIT_EXT            0x00000004
slouken@6393
    71
#endif
slouken@6393
    72
icculus@7853
    73
#ifndef WGL_ARB_framebuffer_sRGB
icculus@7853
    74
#define WGL_ARB_framebuffer_sRGB
icculus@7853
    75
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB                0x20A9
icculus@7853
    76
#endif
icculus@7853
    77
icculus@9413
    78
#ifndef WGL_ARB_context_flush_control
icculus@9413
    79
#define WGL_ARB_context_flush_control
icculus@9413
    80
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB   0x2097
icculus@9413
    81
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB           0x0000
icculus@9413
    82
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB          0x2098
icculus@9413
    83
#endif
icculus@9413
    84
slouken@3139
    85
typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
slouken@3139
    86
                                                            HGLRC
slouken@3139
    87
                                                            hShareContext,
slouken@3139
    88
                                                            const int
slouken@3139
    89
                                                            *attribList);
slouken@1913
    90
slouken@1913
    91
int
slouken@1913
    92
WIN_GL_LoadLibrary(_THIS, const char *path)
slouken@1913
    93
{
slouken@7865
    94
    void *handle;
slouken@1913
    95
slouken@1913
    96
    if (path == NULL) {
slouken@1952
    97
        path = SDL_getenv("SDL_OPENGL_LIBRARY");
slouken@1952
    98
    }
slouken@1952
    99
    if (path == NULL) {
slouken@1952
   100
        path = DEFAULT_OPENGL;
slouken@1913
   101
    }
slouken@7865
   102
    _this->gl_config.dll_handle = SDL_LoadObject(path);
slouken@3057
   103
    if (!_this->gl_config.dll_handle) {
slouken@7865
   104
        return -1;
slouken@1913
   105
    }
slouken@3057
   106
    SDL_strlcpy(_this->gl_config.driver_path, path,
slouken@3057
   107
                SDL_arraysize(_this->gl_config.driver_path));
slouken@3057
   108
slouken@3057
   109
    /* Allocate OpenGL memory */
slouken@7865
   110
    _this->gl_data = (struct SDL_GLDriverData *) SDL_calloc(1, sizeof(struct SDL_GLDriverData));
slouken@3057
   111
    if (!_this->gl_data) {
icculus@7037
   112
        return SDL_OutOfMemory();
slouken@3057
   113
    }
slouken@1913
   114
slouken@1913
   115
    /* Load function pointers */
slouken@3057
   116
    handle = _this->gl_config.dll_handle;
slouken@1913
   117
    _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
slouken@7865
   118
        SDL_LoadFunction(handle, "wglGetProcAddress");
slouken@1913
   119
    _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
slouken@7865
   120
        SDL_LoadFunction(handle, "wglCreateContext");
slouken@1913
   121
    _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
slouken@7865
   122
        SDL_LoadFunction(handle, "wglDeleteContext");
slouken@1913
   123
    _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
slouken@7865
   124
        SDL_LoadFunction(handle, "wglMakeCurrent");
slouken@6393
   125
    _this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
slouken@7865
   126
        SDL_LoadFunction(handle, "wglShareLists");
slouken@1913
   127
slouken@1913
   128
    if (!_this->gl_data->wglGetProcAddress ||
slouken@1913
   129
        !_this->gl_data->wglCreateContext ||
slouken@1913
   130
        !_this->gl_data->wglDeleteContext ||
slouken@1913
   131
        !_this->gl_data->wglMakeCurrent) {
icculus@7037
   132
        return SDL_SetError("Could not retrieve OpenGL functions");
slouken@1913
   133
    }
slouken@1913
   134
slouken@10806
   135
    /* XXX Too sleazy? WIN_GL_InitExtensions looks for certain OpenGL
slouken@10806
   136
       extensions via SDL_GL_DeduceMaxSupportedESProfile. This uses
slouken@10806
   137
       SDL_GL_ExtensionSupported which in turn calls SDL_GL_GetProcAddress.
slouken@10806
   138
       However SDL_GL_GetProcAddress will fail if the library is not
slouken@10806
   139
       loaded; it checks for gl_config.driver_loaded > 0. To avoid this
slouken@10806
   140
       test failing, increment driver_loaded around the call to
slouken@10806
   141
       WIN_GLInitExtensions.
slouken@10806
   142
slouken@10806
   143
       Successful loading of the library is normally indicated by
slouken@10806
   144
       SDL_GL_LoadLibrary incrementing driver_loaded immediately after
slouken@10806
   145
       this function returns 0 to it.
slouken@10806
   146
slouken@10806
   147
       Alternatives to this are:
slouken@10806
   148
       - moving SDL_GL_DeduceMaxSupportedESProfile to both the WIN and
slouken@10806
   149
         X11 platforms while adding a function equivalent to
slouken@10806
   150
         SDL_GL_ExtensionSupported but which directly calls
slouken@10806
   151
         glGetProcAddress(). Having 3 copies of the
slouken@10806
   152
         SDL_GL_ExtensionSupported makes this alternative unattractive.
slouken@10806
   153
       - moving SDL_GL_DeduceMaxSupportedESProfile to a new file shared
slouken@10806
   154
         by the WIN and X11 platforms while adding a function equivalent
slouken@10806
   155
         to SDL_GL_ExtensionSupported. This is unattractive due to the
slouken@10806
   156
         number of project files that will need updating, plus there
slouken@10806
   157
         will be 2 copies of the SDL_GL_ExtensionSupported code.
slouken@10806
   158
       - Add a private equivalent of SDL_GL_ExtensionSupported to
slouken@10806
   159
         SDL_video.c.
slouken@10806
   160
       - Move the call to WIN_GL_InitExtensions back to WIN_CreateWindow
slouken@10806
   161
         and add a flag to gl_data to avoid multiple calls to this
slouken@10806
   162
         expensive function. This is probably the least objectionable
slouken@10806
   163
         alternative if this increment/decrement trick is unacceptable.
slouken@10806
   164
slouken@10806
   165
       Note that the driver_loaded > 0 check needs to remain in
slouken@10806
   166
       SDL_GL_ExtensionSupported and SDL_GL_GetProcAddress as they are
slouken@10806
   167
       public API functions.
slouken@10806
   168
    */
slouken@10806
   169
    ++_this->gl_config.driver_loaded;
slouken@10806
   170
    WIN_GL_InitExtensions(_this);
slouken@10806
   171
    --_this->gl_config.driver_loaded;
slouken@10806
   172
slouken@1913
   173
    return 0;
slouken@1913
   174
}
slouken@1913
   175
slouken@1913
   176
void *
slouken@1913
   177
WIN_GL_GetProcAddress(_THIS, const char *proc)
slouken@1913
   178
{
slouken@1913
   179
    void *func;
slouken@1913
   180
slouken@1913
   181
    /* This is to pick up extensions */
slouken@1913
   182
    func = _this->gl_data->wglGetProcAddress(proc);
slouken@1913
   183
    if (!func) {
slouken@1913
   184
        /* This is probably a normal GL function */
slouken@1913
   185
        func = GetProcAddress(_this->gl_config.dll_handle, proc);
slouken@1913
   186
    }
slouken@1913
   187
    return func;
slouken@1913
   188
}
slouken@1913
   189
slouken@3057
   190
void
slouken@1913
   191
WIN_GL_UnloadLibrary(_THIS)
slouken@1913
   192
{
slouken@7865
   193
    SDL_UnloadObject(_this->gl_config.dll_handle);
slouken@3057
   194
    _this->gl_config.dll_handle = NULL;
slouken@3057
   195
slouken@3057
   196
    /* Free OpenGL memory */
slouken@3057
   197
    SDL_free(_this->gl_data);
slouken@3057
   198
    _this->gl_data = NULL;
slouken@1913
   199
}
slouken@1913
   200
slouken@1913
   201
static void
slouken@1913
   202
WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd)
slouken@1913
   203
{
slouken@1913
   204
    SDL_zerop(pfd);
slouken@1913
   205
    pfd->nSize = sizeof(*pfd);
slouken@1913
   206
    pfd->nVersion = 1;
slouken@1913
   207
    pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
slouken@1913
   208
    if (_this->gl_config.double_buffer) {
slouken@1913
   209
        pfd->dwFlags |= PFD_DOUBLEBUFFER;
slouken@1913
   210
    }
slouken@1913
   211
    if (_this->gl_config.stereo) {
slouken@1913
   212
        pfd->dwFlags |= PFD_STEREO;
slouken@1913
   213
    }
slouken@1913
   214
    pfd->iLayerType = PFD_MAIN_PLANE;
slouken@1913
   215
    pfd->iPixelType = PFD_TYPE_RGBA;
slouken@1913
   216
    pfd->cRedBits = _this->gl_config.red_size;
slouken@1913
   217
    pfd->cGreenBits = _this->gl_config.green_size;
slouken@1913
   218
    pfd->cBlueBits = _this->gl_config.blue_size;
slouken@1913
   219
    pfd->cAlphaBits = _this->gl_config.alpha_size;
slouken@1913
   220
    if (_this->gl_config.buffer_size) {
slouken@1913
   221
        pfd->cColorBits =
slouken@1913
   222
            _this->gl_config.buffer_size - _this->gl_config.alpha_size;
slouken@1913
   223
    } else {
slouken@1913
   224
        pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits);
slouken@1913
   225
    }
slouken@1913
   226
    pfd->cAccumRedBits = _this->gl_config.accum_red_size;
slouken@1913
   227
    pfd->cAccumGreenBits = _this->gl_config.accum_green_size;
slouken@1913
   228
    pfd->cAccumBlueBits = _this->gl_config.accum_blue_size;
slouken@1913
   229
    pfd->cAccumAlphaBits = _this->gl_config.accum_alpha_size;
slouken@1913
   230
    pfd->cAccumBits =
slouken@1913
   231
        (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits +
slouken@1913
   232
         pfd->cAccumAlphaBits);
slouken@1913
   233
    pfd->cDepthBits = _this->gl_config.depth_size;
slouken@1913
   234
    pfd->cStencilBits = _this->gl_config.stencil_size;
slouken@1913
   235
}
slouken@1913
   236
slouken@2150
   237
/* Choose the closest pixel format that meets or exceeds the target.
slouken@2150
   238
   FIXME: Should we weight any particular attribute over any other?
slouken@2150
   239
*/
slouken@2150
   240
static int
slouken@2150
   241
WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target)
slouken@2150
   242
{
slouken@2150
   243
    PIXELFORMATDESCRIPTOR pfd;
slouken@2150
   244
    int count, index, best = 0;
slouken@2150
   245
    unsigned int dist, best_dist = ~0U;
slouken@2150
   246
slouken@2150
   247
    count = DescribePixelFormat(hdc, 1, sizeof(pfd), NULL);
slouken@2150
   248
slouken@2150
   249
    for (index = 1; index <= count; index++) {
slouken@2150
   250
slouken@2150
   251
        if (!DescribePixelFormat(hdc, index, sizeof(pfd), &pfd)) {
slouken@2150
   252
            continue;
slouken@2150
   253
        }
slouken@2150
   254
slouken@2150
   255
        if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) {
slouken@2150
   256
            continue;
slouken@2150
   257
        }
slouken@2150
   258
slouken@2150
   259
        if (pfd.iLayerType != target->iLayerType) {
slouken@2150
   260
            continue;
slouken@2150
   261
        }
slouken@2150
   262
        if (pfd.iPixelType != target->iPixelType) {
slouken@2150
   263
            continue;
slouken@2150
   264
        }
slouken@2150
   265
slouken@2150
   266
        dist = 0;
slouken@2150
   267
slouken@2150
   268
        if (pfd.cColorBits < target->cColorBits) {
slouken@2150
   269
            continue;
slouken@2150
   270
        } else {
slouken@2150
   271
            dist += (pfd.cColorBits - target->cColorBits);
slouken@2150
   272
        }
slouken@2150
   273
        if (pfd.cRedBits < target->cRedBits) {
slouken@2150
   274
            continue;
slouken@2150
   275
        } else {
slouken@2150
   276
            dist += (pfd.cRedBits - target->cRedBits);
slouken@2150
   277
        }
slouken@2150
   278
        if (pfd.cGreenBits < target->cGreenBits) {
slouken@2150
   279
            continue;
slouken@2150
   280
        } else {
slouken@2150
   281
            dist += (pfd.cGreenBits - target->cGreenBits);
slouken@2150
   282
        }
slouken@2150
   283
        if (pfd.cBlueBits < target->cBlueBits) {
slouken@2150
   284
            continue;
slouken@2150
   285
        } else {
slouken@2150
   286
            dist += (pfd.cBlueBits - target->cBlueBits);
slouken@2150
   287
        }
slouken@2150
   288
        if (pfd.cAlphaBits < target->cAlphaBits) {
slouken@2150
   289
            continue;
slouken@2150
   290
        } else {
slouken@2150
   291
            dist += (pfd.cAlphaBits - target->cAlphaBits);
slouken@2150
   292
        }
slouken@2150
   293
        if (pfd.cAccumBits < target->cAccumBits) {
slouken@2150
   294
            continue;
slouken@2150
   295
        } else {
slouken@2150
   296
            dist += (pfd.cAccumBits - target->cAccumBits);
slouken@2150
   297
        }
slouken@2150
   298
        if (pfd.cAccumRedBits < target->cAccumRedBits) {
slouken@2150
   299
            continue;
slouken@2150
   300
        } else {
slouken@2150
   301
            dist += (pfd.cAccumRedBits - target->cAccumRedBits);
slouken@2150
   302
        }
slouken@2150
   303
        if (pfd.cAccumGreenBits < target->cAccumGreenBits) {
slouken@2150
   304
            continue;
slouken@2150
   305
        } else {
slouken@2150
   306
            dist += (pfd.cAccumGreenBits - target->cAccumGreenBits);
slouken@2150
   307
        }
slouken@2150
   308
        if (pfd.cAccumBlueBits < target->cAccumBlueBits) {
slouken@2150
   309
            continue;
slouken@2150
   310
        } else {
slouken@2150
   311
            dist += (pfd.cAccumBlueBits - target->cAccumBlueBits);
slouken@2150
   312
        }
slouken@2150
   313
        if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) {
slouken@2150
   314
            continue;
slouken@2150
   315
        } else {
slouken@2150
   316
            dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits);
slouken@2150
   317
        }
slouken@2150
   318
        if (pfd.cDepthBits < target->cDepthBits) {
slouken@2150
   319
            continue;
slouken@2150
   320
        } else {
slouken@2150
   321
            dist += (pfd.cDepthBits - target->cDepthBits);
slouken@2150
   322
        }
slouken@2150
   323
        if (pfd.cStencilBits < target->cStencilBits) {
slouken@2150
   324
            continue;
slouken@2150
   325
        } else {
slouken@2150
   326
            dist += (pfd.cStencilBits - target->cStencilBits);
slouken@2150
   327
        }
slouken@2150
   328
slouken@2150
   329
        if (dist < best_dist) {
slouken@2150
   330
            best = index;
slouken@2150
   331
            best_dist = dist;
slouken@2150
   332
        }
slouken@2150
   333
    }
slouken@2150
   334
slouken@2150
   335
    return best;
slouken@2150
   336
}
slouken@2150
   337
slouken@1913
   338
static SDL_bool
slouken@1913
   339
HasExtension(const char *extension, const char *extensions)
slouken@1913
   340
{
slouken@1913
   341
    const char *start;
slouken@1913
   342
    const char *where, *terminator;
slouken@1913
   343
slouken@1913
   344
    /* Extension names should not have spaces. */
slouken@1913
   345
    where = SDL_strchr(extension, ' ');
slouken@1913
   346
    if (where || *extension == '\0')
slouken@1913
   347
        return SDL_FALSE;
slouken@1913
   348
slouken@1913
   349
    if (!extensions)
slouken@1913
   350
        return SDL_FALSE;
slouken@1913
   351
slouken@1913
   352
    /* It takes a bit of care to be fool-proof about parsing the
slouken@1913
   353
     * OpenGL extensions string. Don't be fooled by sub-strings,
slouken@1913
   354
     * etc. */
slouken@1913
   355
slouken@1913
   356
    start = extensions;
slouken@1913
   357
slouken@1913
   358
    for (;;) {
slouken@1913
   359
        where = SDL_strstr(start, extension);
slouken@1913
   360
        if (!where)
slouken@1913
   361
            break;
slouken@1913
   362
slouken@1913
   363
        terminator = where + SDL_strlen(extension);
slouken@1913
   364
        if (where == start || *(where - 1) == ' ')
slouken@1913
   365
            if (*terminator == ' ' || *terminator == '\0')
slouken@1913
   366
                return SDL_TRUE;
slouken@1913
   367
slouken@1913
   368
        start = terminator;
slouken@1913
   369
    }
slouken@1913
   370
    return SDL_FALSE;
slouken@1913
   371
}
slouken@1913
   372
gabomdq@8021
   373
void
gabomdq@8021
   374
WIN_GL_InitExtensions(_THIS)
slouken@1913
   375
{
slouken@1913
   376
    const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
slouken@1913
   377
    const char *extensions;
gabomdq@8021
   378
    HWND hwnd;
gabomdq@8021
   379
    HDC hdc;
gabomdq@8021
   380
    HGLRC hglrc;
gabomdq@8021
   381
    PIXELFORMATDESCRIPTOR pfd;
gabomdq@8021
   382
slouken@8735
   383
    if (!_this->gl_data) {
slouken@8735
   384
        return;
slouken@8735
   385
    }
slouken@8735
   386
gabomdq@8021
   387
    hwnd =
gabomdq@8021
   388
        CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
gabomdq@8021
   389
        10, 10, NULL, NULL, SDL_Instance, NULL);
gabomdq@8021
   390
    if (!hwnd) {
gabomdq@8021
   391
        return;
gabomdq@8021
   392
    }
gabomdq@8021
   393
    WIN_PumpEvents(_this);
gabomdq@8021
   394
gabomdq@8021
   395
    hdc = GetDC(hwnd);
gabomdq@8021
   396
gabomdq@8021
   397
    WIN_GL_SetupPixelFormat(_this, &pfd);
gabomdq@8021
   398
gabomdq@8021
   399
    SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
gabomdq@8021
   400
gabomdq@8021
   401
    hglrc = _this->gl_data->wglCreateContext(hdc);
gabomdq@8021
   402
    if (!hglrc) {
gabomdq@8021
   403
        return;
gabomdq@8021
   404
    }
gabomdq@8021
   405
    _this->gl_data->wglMakeCurrent(hdc, hglrc);
slouken@1913
   406
slouken@1913
   407
    wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC))
slouken@1913
   408
        _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
slouken@1913
   409
    if (wglGetExtensionsStringARB) {
slouken@1913
   410
        extensions = wglGetExtensionsStringARB(hdc);
slouken@1913
   411
    } else {
slouken@1913
   412
        extensions = NULL;
slouken@1913
   413
    }
slouken@1913
   414
slouken@1913
   415
    /* Check for WGL_ARB_pixel_format */
icculus@6382
   416
    _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_FALSE;
slouken@1913
   417
    if (HasExtension("WGL_ARB_pixel_format", extensions)) {
slouken@1913
   418
        _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
slouken@1913
   419
                                                   (HDC, const int *,
slouken@1913
   420
                                                    const FLOAT *, UINT,
slouken@1913
   421
                                                    int *, UINT *))
slouken@1913
   422
            WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB");
slouken@1913
   423
        _this->gl_data->wglGetPixelFormatAttribivARB =
slouken@1913
   424
            (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *))
slouken@1913
   425
            WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB");
slouken@1913
   426
slouken@1913
   427
        if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
slouken@1913
   428
            (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
icculus@6382
   429
            _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_TRUE;
slouken@1913
   430
        }
slouken@1913
   431
    }
slouken@1913
   432
slouken@1913
   433
    /* Check for WGL_EXT_swap_control */
icculus@6382
   434
    _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_FALSE;
slouken@1913
   435
    if (HasExtension("WGL_EXT_swap_control", extensions)) {
slouken@1913
   436
        _this->gl_data->wglSwapIntervalEXT =
slouken@1913
   437
            WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT");
slouken@1913
   438
        _this->gl_data->wglGetSwapIntervalEXT =
slouken@1913
   439
            WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT");
icculus@6382
   440
        if (HasExtension("WGL_EXT_swap_control_tear", extensions)) {
icculus@6382
   441
            _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_TRUE;
icculus@6382
   442
        }
slouken@2178
   443
    } else {
slouken@2178
   444
        _this->gl_data->wglSwapIntervalEXT = NULL;
slouken@2178
   445
        _this->gl_data->wglGetSwapIntervalEXT = NULL;
slouken@1913
   446
    }
gabomdq@8021
   447
gabomdq@8021
   448
    /* Check for WGL_EXT_create_context_es2_profile */
gabomdq@8021
   449
    if (HasExtension("WGL_EXT_create_context_es2_profile", extensions)) {
slouken@10806
   450
        SDL_GL_DeduceMaxSupportedESProfile(
slouken@10806
   451
            &_this->gl_data->es_profile_max_supported_version.major,
slouken@10806
   452
            &_this->gl_data->es_profile_max_supported_version.minor
slouken@10806
   453
        );
gabomdq@8021
   454
    }
gabomdq@8021
   455
icculus@9413
   456
    /* Check for GLX_ARB_context_flush_control */
icculus@9413
   457
    if (HasExtension("WGL_ARB_context_flush_control", extensions)) {
icculus@9413
   458
        _this->gl_data->HAS_WGL_ARB_context_flush_control = SDL_TRUE;
icculus@9413
   459
    }
icculus@9413
   460
gabomdq@8021
   461
    _this->gl_data->wglMakeCurrent(hdc, NULL);
gabomdq@8021
   462
    _this->gl_data->wglDeleteContext(hglrc);
gabomdq@8021
   463
    ReleaseDC(hwnd, hdc);
gabomdq@8021
   464
    DestroyWindow(hwnd);
gabomdq@8021
   465
    WIN_PumpEvents(_this);
slouken@2178
   466
}
slouken@1913
   467
slouken@2178
   468
static int
slouken@2178
   469
WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs)
slouken@2178
   470
{
slouken@2178
   471
    HWND hwnd;
slouken@2178
   472
    HDC hdc;
slouken@2180
   473
    PIXELFORMATDESCRIPTOR pfd;
slouken@2178
   474
    HGLRC hglrc;
slouken@2178
   475
    int pixel_format = 0;
slouken@2178
   476
    unsigned int matching;
slouken@2178
   477
slouken@2178
   478
    hwnd =
slouken@2178
   479
        CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
slouken@2178
   480
                     10, 10, NULL, NULL, SDL_Instance, NULL);
slouken@2178
   481
    WIN_PumpEvents(_this);
slouken@2178
   482
slouken@2178
   483
    hdc = GetDC(hwnd);
slouken@2178
   484
slouken@2180
   485
    WIN_GL_SetupPixelFormat(_this, &pfd);
slouken@2180
   486
slouken@2180
   487
    SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
slouken@2180
   488
slouken@2178
   489
    hglrc = _this->gl_data->wglCreateContext(hdc);
slouken@1913
   490
    if (hglrc) {
slouken@2178
   491
        _this->gl_data->wglMakeCurrent(hdc, hglrc);
slouken@2178
   492
icculus@6382
   493
        if (_this->gl_data->HAS_WGL_ARB_pixel_format) {
slouken@2178
   494
            _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
slouken@2178
   495
                                                    1, &pixel_format,
slouken@2178
   496
                                                    &matching);
slouken@2178
   497
        }
slouken@2178
   498
icculus@7553
   499
        _this->gl_data->wglMakeCurrent(hdc, NULL);
slouken@1913
   500
        _this->gl_data->wglDeleteContext(hglrc);
slouken@1913
   501
    }
slouken@1913
   502
    ReleaseDC(hwnd, hdc);
slouken@1913
   503
    DestroyWindow(hwnd);
slouken@1913
   504
    WIN_PumpEvents(_this);
slouken@2178
   505
slouken@2178
   506
    return pixel_format;
slouken@1913
   507
}
slouken@1913
   508
icculus@7559
   509
/* actual work of WIN_GL_SetupWindow() happens here. */
icculus@7559
   510
static int
icculus@7559
   511
WIN_GL_SetupWindowInternal(_THIS, SDL_Window * window)
slouken@1913
   512
{
slouken@1913
   513
    HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
slouken@1913
   514
    PIXELFORMATDESCRIPTOR pfd;
slouken@6296
   515
    int pixel_format = 0;
slouken@1913
   516
    int iAttribs[64];
slouken@1913
   517
    int *iAttr;
icculus@7401
   518
    int *iAccelAttr;
slouken@1913
   519
    float fAttribs[1] = { 0 };
slouken@1913
   520
slouken@1913
   521
    WIN_GL_SetupPixelFormat(_this, &pfd);
slouken@1913
   522
slouken@1913
   523
    /* setup WGL_ARB_pixel_format attribs */
slouken@1913
   524
    iAttr = &iAttribs[0];
slouken@1913
   525
slouken@1913
   526
    *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
slouken@1913
   527
    *iAttr++ = GL_TRUE;
slouken@1913
   528
    *iAttr++ = WGL_RED_BITS_ARB;
slouken@1913
   529
    *iAttr++ = _this->gl_config.red_size;
slouken@1913
   530
    *iAttr++ = WGL_GREEN_BITS_ARB;
slouken@1913
   531
    *iAttr++ = _this->gl_config.green_size;
slouken@1913
   532
    *iAttr++ = WGL_BLUE_BITS_ARB;
slouken@1913
   533
    *iAttr++ = _this->gl_config.blue_size;
slouken@1913
   534
slouken@1913
   535
    if (_this->gl_config.alpha_size) {
slouken@1913
   536
        *iAttr++ = WGL_ALPHA_BITS_ARB;
slouken@1913
   537
        *iAttr++ = _this->gl_config.alpha_size;
slouken@1913
   538
    }
slouken@1913
   539
slouken@1913
   540
    *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
slouken@1913
   541
    *iAttr++ = _this->gl_config.double_buffer;
slouken@1913
   542
slouken@1913
   543
    *iAttr++ = WGL_DEPTH_BITS_ARB;
slouken@1913
   544
    *iAttr++ = _this->gl_config.depth_size;
slouken@1913
   545
slouken@1913
   546
    if (_this->gl_config.stencil_size) {
slouken@1913
   547
        *iAttr++ = WGL_STENCIL_BITS_ARB;
slouken@1913
   548
        *iAttr++ = _this->gl_config.stencil_size;
slouken@1913
   549
    }
slouken@1913
   550
slouken@1913
   551
    if (_this->gl_config.accum_red_size) {
slouken@1913
   552
        *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
slouken@1913
   553
        *iAttr++ = _this->gl_config.accum_red_size;
slouken@1913
   554
    }
slouken@1913
   555
slouken@1913
   556
    if (_this->gl_config.accum_green_size) {
slouken@1913
   557
        *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
slouken@1913
   558
        *iAttr++ = _this->gl_config.accum_green_size;
slouken@1913
   559
    }
slouken@1913
   560
slouken@1913
   561
    if (_this->gl_config.accum_blue_size) {
slouken@1913
   562
        *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
slouken@1913
   563
        *iAttr++ = _this->gl_config.accum_blue_size;
slouken@1913
   564
    }
slouken@1913
   565
slouken@1913
   566
    if (_this->gl_config.accum_alpha_size) {
slouken@1913
   567
        *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
slouken@1913
   568
        *iAttr++ = _this->gl_config.accum_alpha_size;
slouken@1913
   569
    }
slouken@1913
   570
slouken@1913
   571
    if (_this->gl_config.stereo) {
slouken@1913
   572
        *iAttr++ = WGL_STEREO_ARB;
slouken@1913
   573
        *iAttr++ = GL_TRUE;
slouken@1913
   574
    }
slouken@1913
   575
slouken@1913
   576
    if (_this->gl_config.multisamplebuffers) {
slouken@1913
   577
        *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
slouken@1913
   578
        *iAttr++ = _this->gl_config.multisamplebuffers;
slouken@1913
   579
    }
slouken@1913
   580
slouken@1913
   581
    if (_this->gl_config.multisamplesamples) {
slouken@1913
   582
        *iAttr++ = WGL_SAMPLES_ARB;
slouken@1913
   583
        *iAttr++ = _this->gl_config.multisamplesamples;
slouken@1913
   584
    }
slouken@1913
   585
icculus@7853
   586
    if (_this->gl_config.framebuffer_srgb_capable) {
icculus@7853
   587
        *iAttr++ = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
icculus@7853
   588
        *iAttr++ = _this->gl_config.framebuffer_srgb_capable;
icculus@7853
   589
    }
icculus@7853
   590
icculus@7401
   591
    /* We always choose either FULL or NO accel on Windows, because of flaky
icculus@7401
   592
       drivers. If the app didn't specify, we use FULL, because that's
icculus@7401
   593
       probably what they wanted (and if you didn't care and got FULL, that's
icculus@7401
   594
       a perfectly valid result in any case). */
slouken@6296
   595
    *iAttr++ = WGL_ACCELERATION_ARB;
icculus@7401
   596
    iAccelAttr = iAttr;
icculus@7401
   597
    if (_this->gl_config.accelerated) {
icculus@7401
   598
        *iAttr++ = WGL_FULL_ACCELERATION_ARB;
icculus@7401
   599
    } else {
icculus@7401
   600
        *iAttr++ = WGL_NO_ACCELERATION_ARB;
icculus@7401
   601
    }
slouken@1913
   602
slouken@1913
   603
    *iAttr = 0;
slouken@1913
   604
slouken@1913
   605
    /* Choose and set the closest available pixel format */
icculus@7401
   606
    pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
icculus@7401
   607
icculus@7401
   608
    /* App said "don't care about accel" and FULL accel failed. Try NO. */
icculus@7401
   609
    if ( ( !pixel_format ) && ( _this->gl_config.accelerated < 0 ) ) {
icculus@7401
   610
        *iAccelAttr = WGL_NO_ACCELERATION_ARB;
slouken@6296
   611
        pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
icculus@7401
   612
        *iAccelAttr = WGL_FULL_ACCELERATION_ARB;  /* if we try again. */
slouken@6296
   613
    }
slouken@2178
   614
    if (!pixel_format) {
slouken@2150
   615
        pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd);
slouken@1913
   616
    }
slouken@1913
   617
    if (!pixel_format) {
icculus@7037
   618
        return SDL_SetError("No matching GL pixel format available");
slouken@1913
   619
    }
slouken@1913
   620
    if (!SetPixelFormat(hdc, pixel_format, &pfd)) {
icculus@7037
   621
        return WIN_SetError("SetPixelFormat()");
slouken@1913
   622
    }
slouken@1913
   623
    return 0;
slouken@1913
   624
}
slouken@1913
   625
icculus@7559
   626
int
icculus@7559
   627
WIN_GL_SetupWindow(_THIS, SDL_Window * window)
icculus@7559
   628
{
icculus@7559
   629
    /* The current context is lost in here; save it and reset it. */
icculus@7559
   630
    SDL_Window *current_win = SDL_GL_GetCurrentWindow();
icculus@7559
   631
    SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();
icculus@7559
   632
    const int retval = WIN_GL_SetupWindowInternal(_this, window);
icculus@7559
   633
    WIN_GL_MakeCurrent(_this, current_win, current_ctx);
icculus@7559
   634
    return retval;
icculus@7559
   635
}
icculus@7559
   636
slouken@10806
   637
SDL_bool
slouken@10806
   638
WIN_GL_UseEGL(_THIS)
slouken@10806
   639
{
slouken@10806
   640
    SDL_assert(_this->gl_data != NULL);
slouken@10806
   641
    SDL_assert(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES);
slouken@10806
   642
slouken@10806
   643
    return (SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, SDL_FALSE)
slouken@10806
   644
            || _this->gl_config.major_version == 1 /* No WGL extension for OpenGL ES 1.x profiles. */
slouken@10806
   645
            || _this->gl_config.major_version > _this->gl_data->es_profile_max_supported_version.major
slouken@10806
   646
            || (_this->gl_config.major_version == _this->gl_data->es_profile_max_supported_version.major
slouken@10806
   647
                && _this->gl_config.minor_version > _this->gl_data->es_profile_max_supported_version.minor));
slouken@10806
   648
}
slouken@10806
   649
slouken@1913
   650
SDL_GLContext
slouken@1913
   651
WIN_GL_CreateContext(_THIS, SDL_Window * window)
slouken@1913
   652
{
slouken@1913
   653
    HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
slouken@6393
   654
    HGLRC context, share_context;
slouken@1913
   655
slouken@10806
   656
    if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES && WIN_GL_UseEGL(_this)) {
gabomdq@8022
   657
#if SDL_VIDEO_OPENGL_EGL        
gabomdq@8021
   658
        /* Switch to EGL based functions */
gabomdq@8021
   659
        WIN_GL_UnloadLibrary(_this);
gabomdq@8021
   660
        _this->GL_LoadLibrary = WIN_GLES_LoadLibrary;
gabomdq@8021
   661
        _this->GL_GetProcAddress = WIN_GLES_GetProcAddress;
gabomdq@8021
   662
        _this->GL_UnloadLibrary = WIN_GLES_UnloadLibrary;
gabomdq@8021
   663
        _this->GL_CreateContext = WIN_GLES_CreateContext;
gabomdq@8021
   664
        _this->GL_MakeCurrent = WIN_GLES_MakeCurrent;
gabomdq@8021
   665
        _this->GL_SetSwapInterval = WIN_GLES_SetSwapInterval;
gabomdq@8021
   666
        _this->GL_GetSwapInterval = WIN_GLES_GetSwapInterval;
gabomdq@8021
   667
        _this->GL_SwapWindow = WIN_GLES_SwapWindow;
gabomdq@8021
   668
        _this->GL_DeleteContext = WIN_GLES_DeleteContext;
gabomdq@8021
   669
        
gabomdq@8021
   670
        if (WIN_GLES_LoadLibrary(_this, NULL) != 0) {
gabomdq@8021
   671
            return NULL;
gabomdq@8021
   672
        }
gabomdq@8021
   673
        
gabomdq@8021
   674
        return WIN_GLES_CreateContext(_this, window);
gabomdq@8022
   675
#else
philipp@8080
   676
        SDL_SetError("SDL not configured with EGL support");
philipp@8080
   677
        return NULL;
philipp@8080
   678
#endif
gabomdq@8021
   679
    }
gabomdq@8021
   680
slouken@6393
   681
    if (_this->gl_config.share_with_current_context) {
slouken@7412
   682
        share_context = (HGLRC)SDL_GL_GetCurrentContext();
slouken@6393
   683
    } else {
slouken@6393
   684
        share_context = 0;
slouken@6393
   685
    }
slouken@6393
   686
slouken@6393
   687
    if (_this->gl_config.major_version < 3 &&
slouken@8604
   688
        _this->gl_config.profile_mask == 0 &&
slouken@8604
   689
        _this->gl_config.flags == 0) {
slouken@6393
   690
        /* Create legacy context */
slouken@3100
   691
        context = _this->gl_data->wglCreateContext(hdc);
slouken@8604
   692
        if( share_context != 0 ) {
icculus@6406
   693
            _this->gl_data->wglShareLists(share_context, context);
slouken@8604
   694
        }
slouken@3100
   695
    } else {
slouken@3100
   696
        PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
slouken@3100
   697
        HGLRC temp_context = _this->gl_data->wglCreateContext(hdc);
slouken@3100
   698
        if (!temp_context) {
slouken@3139
   699
            SDL_SetError("Could not create GL context");
slouken@3100
   700
            return NULL;
slouken@3100
   701
        }
slouken@3139
   702
slouken@3100
   703
        /* Make the context current */
slouken@3100
   704
        if (WIN_GL_MakeCurrent(_this, window, temp_context) < 0) {
slouken@3100
   705
            WIN_GL_DeleteContext(_this, temp_context);
slouken@3100
   706
            return NULL;
slouken@3100
   707
        }
slouken@3139
   708
slouken@3139
   709
        wglCreateContextAttribsARB =
slouken@3139
   710
            (PFNWGLCREATECONTEXTATTRIBSARBPROC) _this->gl_data->
slouken@3139
   711
            wglGetProcAddress("wglCreateContextAttribsARB");
slouken@3100
   712
        if (!wglCreateContextAttribsARB) {
slouken@3100
   713
            SDL_SetError("GL 3.x is not supported");
slouken@3100
   714
            context = temp_context;
slouken@3100
   715
        } else {
icculus@9413
   716
        /* max 10 attributes plus terminator */
icculus@9413
   717
            int attribs[11] = {
slouken@3100
   718
                WGL_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version,
slouken@3100
   719
                WGL_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version,
slouken@3139
   720
                0
slouken@3100
   721
            };
slime73@9961
   722
            int iattr = 4;
slouken@6296
   723
slime73@9961
   724
            /* SDL profile bits match WGL profile bits */
slime73@9961
   725
            if (_this->gl_config.profile_mask != 0) {
slime73@9961
   726
                attribs[iattr++] = WGL_CONTEXT_PROFILE_MASK_ARB;
slime73@9961
   727
                attribs[iattr++] = _this->gl_config.profile_mask;
slime73@9961
   728
            }
slouken@6296
   729
slime73@9961
   730
            /* SDL flags match WGL flags */
slime73@9961
   731
            if (_this->gl_config.flags != 0) {
slime73@9961
   732
                attribs[iattr++] = WGL_CONTEXT_FLAGS_ARB;
slime73@9961
   733
                attribs[iattr++] = _this->gl_config.flags;
slime73@9961
   734
            }
slouken@6296
   735
slime73@9961
   736
            /* only set if wgl extension is available */
slime73@9961
   737
            if (_this->gl_data->HAS_WGL_ARB_context_flush_control) {
slime73@9961
   738
                attribs[iattr++] = WGL_CONTEXT_RELEASE_BEHAVIOR_ARB;
slime73@9961
   739
                attribs[iattr++] = _this->gl_config.release_behavior ?
icculus@9413
   740
                                    WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
icculus@9413
   741
                                    WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
slime73@9961
   742
            }
icculus@9413
   743
slime73@9961
   744
            attribs[iattr++] = 0;
slouken@6296
   745
slouken@3100
   746
            /* Create the GL 3.x context */
slouken@6393
   747
            context = wglCreateContextAttribsARB(hdc, share_context, attribs);
slouken@3100
   748
            /* Delete the GL 2.x context */
slouken@3105
   749
            _this->gl_data->wglDeleteContext(temp_context);
slouken@3100
   750
        }
slouken@3100
   751
    }
slouken@3139
   752
slouken@2178
   753
    if (!context) {
slouken@3565
   754
        WIN_SetError("Could not create GL context");
slouken@2178
   755
        return NULL;
slouken@2178
   756
    }
slouken@2178
   757
slouken@2178
   758
    if (WIN_GL_MakeCurrent(_this, window, context) < 0) {
slouken@2178
   759
        WIN_GL_DeleteContext(_this, context);
slouken@2178
   760
        return NULL;
slouken@2178
   761
    }
slouken@2178
   762
slouken@2178
   763
    return context;
slouken@1913
   764
}
slouken@1913
   765
slouken@1913
   766
int
slouken@1913
   767
WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
slouken@1913
   768
{
slouken@1913
   769
    HDC hdc;
slouken@1913
   770
slouken@6522
   771
    if (!_this->gl_data) {
icculus@7037
   772
        return SDL_SetError("OpenGL not initialized");
slouken@6522
   773
    }
slouken@6522
   774
icculus@7553
   775
    /* sanity check that higher level handled this. */
icculus@7553
   776
    SDL_assert(window || (!window && !context));
icculus@7553
   777
icculus@7553
   778
    /* Some Windows drivers freak out if hdc is NULL, even when context is
icculus@7553
   779
       NULL, against spec. Since hdc is _supposed_ to be ignored if context
icculus@7553
   780
       is NULL, we either use the current GL window, or do nothing if we
icculus@7553
   781
       already have no current context. */
icculus@7553
   782
    if (!window) {
icculus@7553
   783
        window = SDL_GL_GetCurrentWindow();
icculus@7553
   784
        if (!window) {
icculus@7553
   785
            SDL_assert(SDL_GL_GetCurrentContext() == NULL);
icculus@7553
   786
            return 0;  /* already done. */
icculus@7553
   787
        }
slouken@1913
   788
    }
icculus@7553
   789
icculus@7553
   790
    hdc = ((SDL_WindowData *) window->driverdata)->hdc;
slouken@1913
   791
    if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) {
icculus@7037
   792
        return WIN_SetError("wglMakeCurrent()");
slouken@1913
   793
    }
icculus@7037
   794
    return 0;
slouken@1913
   795
}
slouken@1913
   796
slouken@1913
   797
int
slouken@1913
   798
WIN_GL_SetSwapInterval(_THIS, int interval)
slouken@1913
   799
{
icculus@6382
   800
    if ((interval < 0) && (!_this->gl_data->HAS_WGL_EXT_swap_control_tear)) {
icculus@7037
   801
        return SDL_SetError("Negative swap interval unsupported in this GL");
icculus@6382
   802
    } else if (_this->gl_data->wglSwapIntervalEXT) {
icculus@7037
   803
        if (_this->gl_data->wglSwapIntervalEXT(interval) != TRUE) {
icculus@7037
   804
            return WIN_SetError("wglSwapIntervalEXT()");
icculus@6383
   805
        }
slouken@1913
   806
    } else {
icculus@7037
   807
        return SDL_Unsupported();
slouken@1913
   808
    }
icculus@7037
   809
    return 0;
slouken@1913
   810
}
slouken@1913
   811
slouken@1913
   812
int
slouken@1913
   813
WIN_GL_GetSwapInterval(_THIS)
slouken@1913
   814
{
icculus@6383
   815
    int retval = 0;
slouken@1913
   816
    if (_this->gl_data->wglGetSwapIntervalEXT) {
icculus@6383
   817
        retval = _this->gl_data->wglGetSwapIntervalEXT();
slouken@1913
   818
    }
icculus@6383
   819
    return retval;
slouken@1913
   820
}
slouken@1913
   821
slouken@10690
   822
int
slouken@1913
   823
WIN_GL_SwapWindow(_THIS, SDL_Window * window)
slouken@1913
   824
{
slouken@1913
   825
    HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
slouken@1913
   826
slouken@10690
   827
    if (!SwapBuffers(hdc)) {
slouken@10690
   828
        return WIN_SetError("SwapBuffers()");
slouken@10690
   829
    }
slouken@10690
   830
    return 0;
slouken@1913
   831
}
slouken@1913
   832
slouken@1913
   833
void
slouken@1913
   834
WIN_GL_DeleteContext(_THIS, SDL_GLContext context)
slouken@1913
   835
{
slouken@6522
   836
    if (!_this->gl_data) {
slouken@6522
   837
        return;
slouken@6522
   838
    }
slouken@1936
   839
    _this->gl_data->wglDeleteContext((HGLRC) context);
slouken@1913
   840
}
slouken@1913
   841
slouken@8144
   842
slouken@8144
   843
SDL_bool
slouken@8144
   844
WIN_GL_SetPixelFormatFrom(_THIS, SDL_Window * fromWindow, SDL_Window * toWindow)
slouken@8144
   845
{
slouken@8144
   846
    HDC hfromdc = ((SDL_WindowData *) fromWindow->driverdata)->hdc;
slouken@8144
   847
    HDC htodc = ((SDL_WindowData *) toWindow->driverdata)->hdc;
slouken@8144
   848
    BOOL result;
slouken@8144
   849
slouken@8144
   850
    /* get the pixel format of the fromWindow */
slouken@8144
   851
    int pixel_format = GetPixelFormat(hfromdc);
slouken@8144
   852
    PIXELFORMATDESCRIPTOR pfd;
slouken@8144
   853
    SDL_memset(&pfd, 0, sizeof(pfd));
slouken@8144
   854
    DescribePixelFormat(hfromdc, pixel_format, sizeof(pfd), &pfd);
slouken@8144
   855
slouken@8144
   856
    /* set the pixel format of the toWindow */
slouken@8144
   857
    result = SetPixelFormat(htodc, pixel_format, &pfd);
slouken@8144
   858
slouken@8144
   859
    return result ? SDL_TRUE : SDL_FALSE;
slouken@8144
   860
}
slouken@8144
   861
slouken@1952
   862
#endif /* SDL_VIDEO_OPENGL_WGL */
slouken@1913
   863
slouken@6044
   864
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
slouken@6044
   865
slouken@1913
   866
/* vi: set ts=4 sw=4 expandtab: */