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