src/video/win32/SDL_win32opengl.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 24 Mar 2009 10:43:53 +0000
changeset 3100 7dc982143c06
parent 3057 089a77aebb7d
child 3105 cdeee9f9b14b
permissions -rw-r--r--
Date: Sun, 22 Mar 2009 12:52:29 +0000
From: Luke Benstead
Subject: OpenGL 3.0 Context Creation

I've attached a patch which implements OpenGL 3.x context creation on
the latest SVN. I've added two options to SDL_GL_SetAttribute, these
are SDL_GL_CONTEXT_MAJOR_VERSION and SDL_GL_CONTEXT_MINOR_VERSION.
These default to 2 and 1 respectively. If the major version is less
than 3 then the current context creation method is used, otherwise the
appropriate new context creation function is called (depending on the
platform).

Sample code:

if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("Unable to initialize SDL: %s\n", SDL_GetError());
return 1;
}

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); //Without these 2 lines, SDL will create a GL 2.x context
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

SDL_Surface* screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL | SDL_FULLSCREEN );


I've implemented context creation on both Win32 and X and run basic
tests on both. This patch doesn't provide access to all the options
allowed by the new context creation (e.g. shared contexts, forward
compatible contexts) but they can be added pretty easily.
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@3100
   515
        wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) 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@3100
   528
            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: */