src/video/windows/SDL_windowsopengl.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 07 Mar 2011 14:06:46 -0800
changeset 5446 6ac8b0ac645e
parent 5262 b530ef003506
child 5535 96594ac5fd1a
permissions -rw-r--r--
Fixed bug 1161 (Setting GL_ACCELERATED_VISUAL to 1 forces software rendering in Windows XP)

Jesse Anders 2011-03-05 23:30:09 PST

It seems that in Windows XP, setting SDL_GL_ACCELERATED_VISUAL to 1 actually
disables hardware acceleration and puts OpenGL in software mode.

In the source code, the corresponding WGL attribute is first set here:

*iAttr++ = WGL_ACCELERATION_ARB;
*iAttr++ = WGL_FULL_ACCELERATION_ARB;

Later, this code:

if (_this->gl_config.accelerated >= 0) {
*iAttr++ = WGL_ACCELERATION_ARB;
*iAttr++ =
(_this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB :
WGL_NO_ACCELERATION_ARB);
}

Sets it again if SDL_GL_ACCELERATED_VISUAL has a value other than the default.

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