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