src/video/win32/SDL_win32opengl.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 03 Apr 2009 17:19:05 +0000
changeset 3105 cdeee9f9b14b
parent 3100 7dc982143c06
child 3139 7f684f249ec9
permissions -rw-r--r--
Fixed bug #721

From michalziulek@gmail.com 2009-03-28 07:43:34 (-) [reply]

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