src/video/wincommon/SDL_wingl.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 24 Jun 2006 02:48:55 +0000
branchSDL-1.3
changeset 1703 a51dfda0ff33
parent 1668 4da1ee79c9af
permissions -rw-r--r--
Merged SDL_GL_SWAP_CONTROL fix from SDL 1.2
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@0
    24
/* WGL implementation of SDL OpenGL support */
slouken@0
    25
slouken@1361
    26
#if SDL_VIDEO_OPENGL
slouken@327
    27
#include "SDL_opengl.h"
slouken@453
    28
#endif
slouken@0
    29
#include "SDL_lowvideo.h"
slouken@0
    30
#include "SDL_wingl_c.h"
slouken@0
    31
slouken@1361
    32
#if SDL_VIDEO_OPENGL
slouken@0
    33
#define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL"
slouken@0
    34
#endif
slouken@0
    35
slouken@373
    36
/* If setting the HDC fails, we may need to recreate the window (MSDN) */
slouken@1662
    37
static int
slouken@1668
    38
WIN_GL_ResetWindow(_THIS)
slouken@373
    39
{
slouken@1662
    40
    int status = 0;
slouken@373
    41
slouken@1662
    42
#ifndef _WIN32_WCE              /* FIXME WinCE needs the UNICODE version of CreateWindow() */
slouken@1662
    43
    /* This doesn't work with DirectX code (see CVS comments) */
slouken@1662
    44
    /* If we were passed a window, then we can't create a new one */
slouken@1668
    45
    if (!SDL_windowid && SDL_strcmp(this->name, "windib") == 0) {
slouken@1662
    46
        /* Save the existing window attributes */
slouken@1662
    47
        LONG style;
slouken@1662
    48
        RECT rect = { 0, 0, 0, 0 };
slouken@1668
    49
        style = GetWindowLong(SDL_Window, GWL_STYLE);
slouken@1668
    50
        GetWindowRect(SDL_Window, &rect);
slouken@1668
    51
        DestroyWindow(SDL_Window);
slouken@1668
    52
        WIN_FlushMessageQueue();
slouken@1523
    53
slouken@1668
    54
        SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
slouken@1668
    55
                                  style,
slouken@1668
    56
                                  rect.left, rect.top,
slouken@1668
    57
                                  (rect.right - rect.left) + 1,
slouken@1668
    58
                                  (rect.top - rect.bottom) + 1,
slouken@1668
    59
                                  NULL, NULL, SDL_Instance, NULL);
slouken@1668
    60
        WIN_FlushMessageQueue();
slouken@1523
    61
slouken@1662
    62
        if (SDL_Window) {
slouken@1668
    63
            this->SetCaption(this, this->wm_title, this->wm_icon);
slouken@1662
    64
        } else {
slouken@1668
    65
            SDL_SetError("Couldn't create window");
slouken@1662
    66
            status = -1;
slouken@1662
    67
        }
slouken@1662
    68
    } else
slouken@373
    69
#endif /* !_WIN32_WCE */
slouken@1662
    70
    {
slouken@1668
    71
        SDL_SetError("Unable to reset window for OpenGL context");
slouken@1662
    72
        status = -1;
slouken@1662
    73
    }
slouken@1662
    74
    return (status);
slouken@373
    75
}
slouken@0
    76
slouken@1361
    77
#if SDL_VIDEO_OPENGL
slouken@1315
    78
slouken@1662
    79
static int
slouken@1668
    80
ExtensionSupported(const char *extension, const char *extensions)
slouken@1315
    81
{
slouken@1662
    82
    const char *start;
slouken@1662
    83
    const char *where, *terminator;
slouken@1315
    84
slouken@1662
    85
    /* Extension names should not have spaces. */
slouken@1668
    86
    where = SDL_strchr(extension, ' ');
slouken@1662
    87
    if (where || *extension == '\0')
slouken@1662
    88
        return 0;
slouken@1315
    89
slouken@1662
    90
    if (!extensions)
slouken@1662
    91
        return 0;
slouken@1315
    92
slouken@1662
    93
    /* It takes a bit of care to be fool-proof about parsing the
slouken@1662
    94
     *      OpenGL extensions string. Don't be fooled by sub-strings,
slouken@1662
    95
     *           etc. */
slouken@1662
    96
slouken@1662
    97
    start = extensions;
slouken@1662
    98
slouken@1662
    99
    for (;;) {
slouken@1668
   100
        where = SDL_strstr(start, extension);
slouken@1662
   101
        if (!where)
slouken@1662
   102
            break;
slouken@1662
   103
slouken@1668
   104
        terminator = where + SDL_strlen(extension);
slouken@1662
   105
        if (where == start || *(where - 1) == ' ')
slouken@1662
   106
            if (*terminator == ' ' || *terminator == '\0')
slouken@1662
   107
                return 1;
slouken@1662
   108
slouken@1662
   109
        start = terminator;
slouken@1662
   110
    }
slouken@1662
   111
slouken@1662
   112
    return 0;
slouken@1315
   113
}
slouken@1315
   114
slouken@1662
   115
static void
slouken@1668
   116
Init_WGL_ARB_extensions(_THIS)
slouken@655
   117
{
slouken@1662
   118
    HWND hwnd;
slouken@1662
   119
    HDC hdc;
slouken@1662
   120
    HGLRC hglrc;
slouken@1662
   121
    int pformat;
slouken@1662
   122
    const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
slouken@1662
   123
    const char *extensions;
slouken@1523
   124
slouken@1668
   125
    hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP | WS_DISABLED,
slouken@1668
   126
                        0, 0, 10, 10, NULL, NULL, SDL_Instance, NULL);
slouken@1668
   127
    WIN_FlushMessageQueue();
slouken@655
   128
slouken@1668
   129
    hdc = GetDC(hwnd);
slouken@655
   130
slouken@1668
   131
    pformat = ChoosePixelFormat(hdc, &GL_pfd);
slouken@1668
   132
    SetPixelFormat(hdc, pformat, &GL_pfd);
slouken@655
   133
slouken@1668
   134
    hglrc = this->gl_data->wglCreateContext(hdc);
slouken@1662
   135
    if (hglrc) {
slouken@1668
   136
        this->gl_data->wglMakeCurrent(hdc, hglrc);
slouken@1662
   137
    }
slouken@655
   138
slouken@1662
   139
    wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC))
slouken@1668
   140
        this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
slouken@1315
   141
slouken@1662
   142
    if (wglGetExtensionsStringARB) {
slouken@1668
   143
        extensions = wglGetExtensionsStringARB(hdc);
slouken@1662
   144
    } else {
slouken@1662
   145
        extensions = NULL;
slouken@1662
   146
    }
slouken@655
   147
slouken@1662
   148
    this->gl_data->WGL_ARB_pixel_format = 0;
slouken@1668
   149
    if (ExtensionSupported("WGL_ARB_pixel_format", extensions)) {
slouken@1668
   150
        this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
slouken@1662
   151
                                                  (HDC, const int *,
slouken@1662
   152
                                                   const FLOAT *, UINT, int *,
slouken@1703
   153
                                                   UINT *))
slouken@1703
   154
            this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB");
slouken@1662
   155
        this->gl_data->wglGetPixelFormatAttribivARB =
slouken@1668
   156
            (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *))
slouken@1668
   157
            this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB");
slouken@1662
   158
slouken@1662
   159
        if ((this->gl_data->wglChoosePixelFormatARB != NULL) &&
slouken@1662
   160
            (this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
slouken@1662
   161
            this->gl_data->WGL_ARB_pixel_format = 1;
slouken@1662
   162
        }
slouken@1662
   163
    }
slouken@1662
   164
slouken@1662
   165
    if (hglrc) {
slouken@1668
   166
        this->gl_data->wglMakeCurrent(NULL, NULL);
slouken@1668
   167
        this->gl_data->wglDeleteContext(hglrc);
slouken@1662
   168
    }
slouken@1668
   169
    ReleaseDC(hwnd, hdc);
slouken@1668
   170
    DestroyWindow(hwnd);
slouken@1668
   171
    WIN_FlushMessageQueue();
slouken@655
   172
}
slouken@1315
   173
slouken@1361
   174
#endif /* SDL_VIDEO_OPENGL */
slouken@655
   175
slouken@1662
   176
int
slouken@1668
   177
WIN_GL_SetupWindow(_THIS)
slouken@0
   178
{
slouken@1662
   179
    int retval;
slouken@1361
   180
#if SDL_VIDEO_OPENGL
slouken@1662
   181
    int i;
slouken@1662
   182
    unsigned int matching;
slouken@1662
   183
    int iAttribs[64];
slouken@1662
   184
    int *iAttr;
slouken@1662
   185
    float fAttribs[1] = { 0 };
slouken@1662
   186
    const GLubyte *(WINAPI * glGetStringFunc) (GLenum);
slouken@1662
   187
    const char *wglext;
slouken@0
   188
slouken@1662
   189
    /* load the gl driver from a default path */
slouken@1662
   190
    if (!this->gl_config.driver_loaded) {
slouken@1662
   191
        /* no driver has been loaded, use default (ourselves) */
slouken@1668
   192
        if (WIN_GL_LoadLibrary(this, NULL) < 0) {
slouken@1662
   193
            return (-1);
slouken@1662
   194
        }
slouken@1662
   195
    }
slouken@0
   196
slouken@1662
   197
    for (i = 0;; ++i) {
slouken@1662
   198
        /* Get the window device context for our OpenGL drawing */
slouken@1668
   199
        GL_hdc = GetDC(SDL_Window);
slouken@1662
   200
        if (GL_hdc == NULL) {
slouken@1668
   201
            SDL_SetError("Unable to get DC for SDL_Window");
slouken@1662
   202
            return (-1);
slouken@1662
   203
        }
slouken@0
   204
slouken@1662
   205
        /* Set up the pixel format descriptor with our needed format */
slouken@1668
   206
        SDL_memset(&GL_pfd, 0, sizeof(GL_pfd));
slouken@1668
   207
        GL_pfd.nSize = sizeof(GL_pfd);
slouken@1662
   208
        GL_pfd.nVersion = 1;
slouken@1662
   209
        GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
slouken@1662
   210
        if (this->gl_config.double_buffer) {
slouken@1662
   211
            GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
slouken@1662
   212
        }
slouken@1662
   213
        if (this->gl_config.stereo) {
slouken@1662
   214
            GL_pfd.dwFlags |= PFD_STEREO;
slouken@1662
   215
        }
slouken@1662
   216
        GL_pfd.iPixelType = PFD_TYPE_RGBA;
slouken@1662
   217
        GL_pfd.cColorBits = this->gl_config.buffer_size;
slouken@1662
   218
        GL_pfd.cRedBits = this->gl_config.red_size;
slouken@1662
   219
        GL_pfd.cGreenBits = this->gl_config.green_size;
slouken@1662
   220
        GL_pfd.cBlueBits = this->gl_config.blue_size;
slouken@1662
   221
        GL_pfd.cAlphaBits = this->gl_config.alpha_size;
slouken@1662
   222
        GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
slouken@1662
   223
        GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
slouken@1662
   224
        GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
slouken@1662
   225
        GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
slouken@1662
   226
        GL_pfd.cAccumBits =
slouken@1662
   227
            (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
slouken@1662
   228
             GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
slouken@1662
   229
        GL_pfd.cDepthBits = this->gl_config.depth_size;
slouken@1662
   230
        GL_pfd.cStencilBits = this->gl_config.stencil_size;
slouken@0
   231
slouken@1662
   232
        /* initialize WGL_ARB_pixel_format */
slouken@1668
   233
        Init_WGL_ARB_extensions(this);
slouken@655
   234
slouken@1662
   235
        /* setup WGL_ARB_pixel_format attribs */
slouken@1662
   236
        iAttr = &iAttribs[0];
slouken@655
   237
slouken@1662
   238
        *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
slouken@1662
   239
        *iAttr++ = GL_TRUE;
slouken@1662
   240
        *iAttr++ = WGL_ACCELERATION_ARB;
slouken@1662
   241
        *iAttr++ = WGL_FULL_ACCELERATION_ARB;
slouken@1662
   242
        *iAttr++ = WGL_RED_BITS_ARB;
slouken@1662
   243
        *iAttr++ = this->gl_config.red_size;
slouken@1662
   244
        *iAttr++ = WGL_GREEN_BITS_ARB;
slouken@1662
   245
        *iAttr++ = this->gl_config.green_size;
slouken@1662
   246
        *iAttr++ = WGL_BLUE_BITS_ARB;
slouken@1662
   247
        *iAttr++ = this->gl_config.blue_size;
slouken@655
   248
slouken@1662
   249
        if (this->gl_config.alpha_size) {
slouken@1662
   250
            *iAttr++ = WGL_ALPHA_BITS_ARB;
slouken@1662
   251
            *iAttr++ = this->gl_config.alpha_size;
slouken@1662
   252
        }
slouken@655
   253
slouken@1662
   254
        *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
slouken@1662
   255
        *iAttr++ = this->gl_config.double_buffer;
slouken@655
   256
slouken@1662
   257
        *iAttr++ = WGL_DEPTH_BITS_ARB;
slouken@1662
   258
        *iAttr++ = this->gl_config.depth_size;
slouken@655
   259
slouken@1662
   260
        if (this->gl_config.stencil_size) {
slouken@1662
   261
            *iAttr++ = WGL_STENCIL_BITS_ARB;
slouken@1662
   262
            *iAttr++ = this->gl_config.stencil_size;
slouken@1662
   263
        }
slouken@655
   264
slouken@1662
   265
        if (this->gl_config.accum_red_size) {
slouken@1662
   266
            *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
slouken@1662
   267
            *iAttr++ = this->gl_config.accum_red_size;
slouken@1662
   268
        }
slouken@655
   269
slouken@1662
   270
        if (this->gl_config.accum_green_size) {
slouken@1662
   271
            *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
slouken@1662
   272
            *iAttr++ = this->gl_config.accum_green_size;
slouken@1662
   273
        }
slouken@655
   274
slouken@1662
   275
        if (this->gl_config.accum_blue_size) {
slouken@1662
   276
            *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
slouken@1662
   277
            *iAttr++ = this->gl_config.accum_blue_size;
slouken@1662
   278
        }
slouken@655
   279
slouken@1662
   280
        if (this->gl_config.accum_alpha_size) {
slouken@1662
   281
            *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
slouken@1662
   282
            *iAttr++ = this->gl_config.accum_alpha_size;
slouken@1662
   283
        }
slouken@655
   284
slouken@1662
   285
        if (this->gl_config.stereo) {
slouken@1662
   286
            *iAttr++ = WGL_STEREO_ARB;
slouken@1662
   287
            *iAttr++ = GL_TRUE;
slouken@1662
   288
        }
slouken@655
   289
slouken@1662
   290
        if (this->gl_config.multisamplebuffers) {
slouken@1662
   291
            *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
slouken@1662
   292
            *iAttr++ = this->gl_config.multisamplebuffers;
slouken@1662
   293
        }
slouken@655
   294
slouken@1662
   295
        if (this->gl_config.multisamplesamples) {
slouken@1662
   296
            *iAttr++ = WGL_SAMPLES_ARB;
slouken@1662
   297
            *iAttr++ = this->gl_config.multisamplesamples;
slouken@1662
   298
        }
slouken@1656
   299
slouken@1662
   300
        if (this->gl_config.accelerated >= 0) {
slouken@1662
   301
            *iAttr++ = WGL_ACCELERATION_ARB;
slouken@1662
   302
            *iAttr++ =
slouken@1662
   303
                (this->gl_config.
slouken@1662
   304
                 accelerated ? WGL_GENERIC_ACCELERATION_ARB :
slouken@1662
   305
                 WGL_NO_ACCELERATION_ARB);
slouken@1662
   306
        }
slouken@655
   307
slouken@1662
   308
        *iAttr = 0;
slouken@0
   309
slouken@1662
   310
        /* Choose and set the closest available pixel format */
slouken@1662
   311
        if (!this->gl_data->WGL_ARB_pixel_format ||
slouken@1668
   312
            !this->gl_data->wglChoosePixelFormatARB(GL_hdc, iAttribs,
slouken@1668
   313
                                                    fAttribs, 1,
slouken@1668
   314
                                                    &pixel_format, &matching)
slouken@1662
   315
            || !matching) {
slouken@1668
   316
            pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
slouken@1662
   317
            this->gl_data->WGL_ARB_pixel_format = 0;
slouken@1662
   318
        }
slouken@1662
   319
        if (!pixel_format) {
slouken@1668
   320
            SDL_SetError("No matching GL pixel format available");
slouken@1662
   321
            return (-1);
slouken@1662
   322
        }
slouken@1668
   323
        if (!SetPixelFormat(GL_hdc, pixel_format, &GL_pfd)) {
slouken@1662
   324
            if (i == 0) {
slouken@1662
   325
                /* First time through, try resetting the window */
slouken@1668
   326
                if (WIN_GL_ResetWindow(this) < 0) {
slouken@1662
   327
                    return (-1);
slouken@1662
   328
                }
slouken@1662
   329
                continue;
slouken@1662
   330
            }
slouken@1668
   331
            SDL_SetError("Unable to set HDC pixel format");
slouken@1662
   332
            return (-1);
slouken@1662
   333
        }
slouken@1662
   334
        /* We either succeeded or failed by this point */
slouken@1662
   335
        break;
slouken@1662
   336
    }
slouken@1668
   337
    DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd);
slouken@1656
   338
slouken@1668
   339
    GL_hrc = this->gl_data->wglCreateContext(GL_hdc);
slouken@1662
   340
    if (GL_hrc == NULL) {
slouken@1668
   341
        SDL_SetError("Unable to create GL context");
slouken@1662
   342
        return (-1);
slouken@1662
   343
    }
slouken@1668
   344
    if (WIN_GL_MakeCurrent(this) < 0) {
slouken@1662
   345
        return (-1);
slouken@1662
   346
    }
slouken@1662
   347
    gl_active = 1;
slouken@1662
   348
slouken@1662
   349
    /* Vsync control under Windows.  Checking glGetString here is
slouken@1662
   350
     * somewhat a documented and reliable hack - it was originally
slouken@1662
   351
     * as a feature added by mistake, but since so many people rely
slouken@1662
   352
     * on it, it will not be removed.  strstr should be safe here.*/
slouken@1668
   353
    glGetStringFunc = WIN_GL_GetProcAddress(this, "glGetString");
slouken@1662
   354
    if (glGetStringFunc) {
slouken@1668
   355
        wglext = (const char *) glGetStringFunc(GL_EXTENSIONS);
slouken@1662
   356
    } else {
slouken@1662
   357
        /* Uh oh, something is seriously wrong here... */
slouken@1662
   358
        wglext = NULL;
slouken@1662
   359
    }
slouken@1703
   360
    if (wglext && SDL_strstr(wglext, "WGL_EXT_swap_control")) {
slouken@1703
   361
        this->gl_data->wglSwapIntervalEXT =
slouken@1703
   362
            WIN_GL_GetProcAddress(this, "wglSwapIntervalEXT");
slouken@1703
   363
        this->gl_data->wglGetSwapIntervalEXT =
slouken@1703
   364
            WIN_GL_GetProcAddress(this, "wglGetSwapIntervalEXT");
slouken@1703
   365
    } else {
slouken@1662
   366
        this->gl_data->wglSwapIntervalEXT = NULL;
slouken@1662
   367
        this->gl_data->wglGetSwapIntervalEXT = NULL;
slouken@1662
   368
    }
slouken@1662
   369
    if (this->gl_config.swap_control >= 0) {
slouken@1662
   370
        if (this->gl_data->wglSwapIntervalEXT) {
slouken@1668
   371
            this->gl_data->wglSwapIntervalEXT(this->gl_config.swap_control);
slouken@1662
   372
        }
slouken@1662
   373
    }
slouken@0
   374
#else
slouken@1668
   375
    SDL_SetError("WIN driver not configured with OpenGL");
slouken@0
   376
#endif
slouken@1662
   377
    if (gl_active) {
slouken@1662
   378
        retval = 0;
slouken@1662
   379
    } else {
slouken@1662
   380
        retval = -1;
slouken@1662
   381
    }
slouken@1662
   382
    return (retval);
slouken@0
   383
}
slouken@0
   384
slouken@1662
   385
void
slouken@1668
   386
WIN_GL_ShutDown(_THIS)
slouken@0
   387
{
slouken@1361
   388
#if SDL_VIDEO_OPENGL
slouken@1662
   389
    /* Clean up OpenGL */
slouken@1662
   390
    if (GL_hrc) {
slouken@1668
   391
        this->gl_data->wglMakeCurrent(NULL, NULL);
slouken@1668
   392
        this->gl_data->wglDeleteContext(GL_hrc);
slouken@1662
   393
        GL_hrc = NULL;
slouken@1662
   394
    }
slouken@1662
   395
    if (GL_hdc) {
slouken@1668
   396
        ReleaseDC(SDL_Window, GL_hdc);
slouken@1662
   397
        GL_hdc = NULL;
slouken@1662
   398
    }
slouken@1662
   399
    gl_active = 0;
slouken@0
   400
slouken@1668
   401
    WIN_GL_UnloadLibrary(this);
slouken@1361
   402
#endif /* SDL_VIDEO_OPENGL */
slouken@0
   403
}
slouken@0
   404
slouken@1361
   405
#if SDL_VIDEO_OPENGL
slouken@0
   406
slouken@0
   407
/* Make the current context active */
slouken@1662
   408
int
slouken@1668
   409
WIN_GL_MakeCurrent(_THIS)
slouken@0
   410
{
slouken@1662
   411
    int retval;
slouken@0
   412
slouken@1662
   413
    retval = 0;
slouken@1668
   414
    if (!this->gl_data->wglMakeCurrent(GL_hdc, GL_hrc)) {
slouken@1668
   415
        SDL_SetError("Unable to make GL context current");
slouken@1662
   416
        retval = -1;
slouken@1662
   417
    }
slouken@1662
   418
    return (retval);
slouken@0
   419
}
slouken@0
   420
slouken@0
   421
/* Get attribute data from glX. */
slouken@1662
   422
int
slouken@1668
   423
WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int *value)
slouken@0
   424
{
slouken@1662
   425
    int retval;
slouken@655
   426
slouken@1662
   427
    if (this->gl_data->WGL_ARB_pixel_format) {
slouken@1662
   428
        int wgl_attrib;
slouken@655
   429
slouken@1662
   430
        switch (attrib) {
slouken@1662
   431
        case SDL_GL_RED_SIZE:
slouken@1662
   432
            wgl_attrib = WGL_RED_BITS_ARB;
slouken@1662
   433
            break;
slouken@1662
   434
        case SDL_GL_GREEN_SIZE:
slouken@1662
   435
            wgl_attrib = WGL_GREEN_BITS_ARB;
slouken@1662
   436
            break;
slouken@1662
   437
        case SDL_GL_BLUE_SIZE:
slouken@1662
   438
            wgl_attrib = WGL_BLUE_BITS_ARB;
slouken@1662
   439
            break;
slouken@1662
   440
        case SDL_GL_ALPHA_SIZE:
slouken@1662
   441
            wgl_attrib = WGL_ALPHA_BITS_ARB;
slouken@1662
   442
            break;
slouken@1662
   443
        case SDL_GL_DOUBLEBUFFER:
slouken@1662
   444
            wgl_attrib = WGL_DOUBLE_BUFFER_ARB;
slouken@1662
   445
            break;
slouken@1662
   446
        case SDL_GL_BUFFER_SIZE:
slouken@1662
   447
            wgl_attrib = WGL_COLOR_BITS_ARB;
slouken@1662
   448
            break;
slouken@1662
   449
        case SDL_GL_DEPTH_SIZE:
slouken@1662
   450
            wgl_attrib = WGL_DEPTH_BITS_ARB;
slouken@1662
   451
            break;
slouken@1662
   452
        case SDL_GL_STENCIL_SIZE:
slouken@1662
   453
            wgl_attrib = WGL_STENCIL_BITS_ARB;
slouken@1662
   454
            break;
slouken@1662
   455
        case SDL_GL_ACCUM_RED_SIZE:
slouken@1662
   456
            wgl_attrib = WGL_ACCUM_RED_BITS_ARB;
slouken@1662
   457
            break;
slouken@1662
   458
        case SDL_GL_ACCUM_GREEN_SIZE:
slouken@1662
   459
            wgl_attrib = WGL_ACCUM_GREEN_BITS_ARB;
slouken@1662
   460
            break;
slouken@1662
   461
        case SDL_GL_ACCUM_BLUE_SIZE:
slouken@1662
   462
            wgl_attrib = WGL_ACCUM_BLUE_BITS_ARB;
slouken@1662
   463
            break;
slouken@1662
   464
        case SDL_GL_ACCUM_ALPHA_SIZE:
slouken@1662
   465
            wgl_attrib = WGL_ACCUM_ALPHA_BITS_ARB;
slouken@1662
   466
            break;
slouken@1662
   467
        case SDL_GL_STEREO:
slouken@1662
   468
            wgl_attrib = WGL_STEREO_ARB;
slouken@1662
   469
            break;
slouken@1662
   470
        case SDL_GL_MULTISAMPLEBUFFERS:
slouken@1662
   471
            wgl_attrib = WGL_SAMPLE_BUFFERS_ARB;
slouken@1662
   472
            break;
slouken@1662
   473
        case SDL_GL_MULTISAMPLESAMPLES:
slouken@1662
   474
            wgl_attrib = WGL_SAMPLES_ARB;
slouken@1662
   475
            break;
slouken@1662
   476
        case SDL_GL_ACCELERATED_VISUAL:
slouken@1662
   477
            wgl_attrib = WGL_ACCELERATION_ARB;
slouken@1703
   478
            this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format,
slouken@1703
   479
                                                        0, 1, &wgl_attrib,
slouken@1668
   480
                                                        value);
slouken@1662
   481
            if (*value == WGL_NO_ACCELERATION_ARB) {
slouken@1662
   482
                *value = SDL_FALSE;
slouken@1662
   483
            } else {
slouken@1662
   484
                *value = SDL_TRUE;
slouken@1662
   485
            }
slouken@1662
   486
            return 0;
slouken@1662
   487
            break;
slouken@1662
   488
        case SDL_GL_SWAP_CONTROL:
slouken@1662
   489
            if (this->gl_data->wglGetSwapIntervalEXT) {
slouken@1703
   490
                *value = this->gl_data->wglGetSwapIntervalEXT();
slouken@1703
   491
                return 0;
slouken@1662
   492
            } else {
slouken@1662
   493
                return -1;
slouken@1662
   494
            }
slouken@1703
   495
            break;
slouken@1662
   496
        default:
slouken@1662
   497
            return (-1);
slouken@1662
   498
        }
slouken@1703
   499
        this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0,
slouken@1703
   500
                                                    1, &wgl_attrib, value);
slouken@0
   501
slouken@1662
   502
        return 0;
slouken@1662
   503
    }
slouken@1662
   504
slouken@1662
   505
    retval = 0;
slouken@1662
   506
    switch (attrib) {
slouken@1662
   507
    case SDL_GL_RED_SIZE:
slouken@1662
   508
        *value = GL_pfd.cRedBits;
slouken@1662
   509
        break;
slouken@1662
   510
    case SDL_GL_GREEN_SIZE:
slouken@1662
   511
        *value = GL_pfd.cGreenBits;
slouken@1662
   512
        break;
slouken@1662
   513
    case SDL_GL_BLUE_SIZE:
slouken@1662
   514
        *value = GL_pfd.cBlueBits;
slouken@1662
   515
        break;
slouken@1662
   516
    case SDL_GL_ALPHA_SIZE:
slouken@1662
   517
        *value = GL_pfd.cAlphaBits;
slouken@1662
   518
        break;
slouken@1662
   519
    case SDL_GL_DOUBLEBUFFER:
slouken@1662
   520
        if (GL_pfd.dwFlags & PFD_DOUBLEBUFFER) {
slouken@1662
   521
            *value = 1;
slouken@1662
   522
        } else {
slouken@1662
   523
            *value = 0;
slouken@1662
   524
        }
slouken@1662
   525
        break;
slouken@1662
   526
    case SDL_GL_BUFFER_SIZE:
slouken@1662
   527
        *value = GL_pfd.cColorBits;
slouken@1662
   528
        break;
slouken@1662
   529
    case SDL_GL_DEPTH_SIZE:
slouken@1662
   530
        *value = GL_pfd.cDepthBits;
slouken@1662
   531
        break;
slouken@1662
   532
    case SDL_GL_STENCIL_SIZE:
slouken@1662
   533
        *value = GL_pfd.cStencilBits;
slouken@1662
   534
        break;
slouken@1662
   535
    case SDL_GL_ACCUM_RED_SIZE:
slouken@1662
   536
        *value = GL_pfd.cAccumRedBits;
slouken@1662
   537
        break;
slouken@1662
   538
    case SDL_GL_ACCUM_GREEN_SIZE:
slouken@1662
   539
        *value = GL_pfd.cAccumGreenBits;
slouken@1662
   540
        break;
slouken@1662
   541
    case SDL_GL_ACCUM_BLUE_SIZE:
slouken@1662
   542
        *value = GL_pfd.cAccumBlueBits;
slouken@1662
   543
        break;
slouken@1662
   544
    case SDL_GL_ACCUM_ALPHA_SIZE:
slouken@1662
   545
        *value = GL_pfd.cAccumAlphaBits;
slouken@1662
   546
        break;
slouken@1662
   547
    case SDL_GL_STEREO:
slouken@1662
   548
        if (GL_pfd.dwFlags & PFD_STEREO) {
slouken@1662
   549
            *value = 1;
slouken@1662
   550
        } else {
slouken@1662
   551
            *value = 0;
slouken@1662
   552
        }
slouken@1662
   553
        break;
slouken@1662
   554
    case SDL_GL_MULTISAMPLEBUFFERS:
slouken@1662
   555
        *value = 0;
slouken@1662
   556
        break;
slouken@1662
   557
    case SDL_GL_MULTISAMPLESAMPLES:
slouken@1662
   558
        *value = 1;
slouken@1662
   559
        break;
slouken@1703
   560
    case SDL_GL_SWAP_CONTROL:
slouken@1703
   561
        if (this->gl_data->wglGetSwapIntervalEXT) {
slouken@1703
   562
            *value = this->gl_data->wglGetSwapIntervalEXT();
slouken@1703
   563
            return 0;
slouken@1703
   564
        } else {
slouken@1703
   565
            return -1;
slouken@1703
   566
        }
slouken@1703
   567
        break;
slouken@1662
   568
    default:
slouken@1662
   569
        retval = -1;
slouken@1662
   570
        break;
slouken@1662
   571
    }
slouken@1662
   572
    return retval;
slouken@0
   573
}
slouken@0
   574
slouken@1662
   575
void
slouken@1668
   576
WIN_GL_SwapBuffers(_THIS)
slouken@0
   577
{
slouken@1668
   578
    SwapBuffers(GL_hdc);
slouken@0
   579
}
slouken@0
   580
slouken@1662
   581
void
slouken@1668
   582
WIN_GL_UnloadLibrary(_THIS)
slouken@0
   583
{
slouken@1662
   584
    if (this->gl_config.driver_loaded) {
slouken@1668
   585
        FreeLibrary((HMODULE) this->gl_config.dll_handle);
slouken@0
   586
slouken@1662
   587
        this->gl_data->wglGetProcAddress = NULL;
slouken@1662
   588
        this->gl_data->wglCreateContext = NULL;
slouken@1662
   589
        this->gl_data->wglDeleteContext = NULL;
slouken@1662
   590
        this->gl_data->wglMakeCurrent = NULL;
slouken@1662
   591
        this->gl_data->wglChoosePixelFormatARB = NULL;
slouken@1662
   592
        this->gl_data->wglGetPixelFormatAttribivARB = NULL;
slouken@1662
   593
        this->gl_data->wglSwapIntervalEXT = NULL;
slouken@1662
   594
        this->gl_data->wglGetSwapIntervalEXT = NULL;
slouken@0
   595
slouken@1662
   596
        this->gl_config.dll_handle = NULL;
slouken@1662
   597
        this->gl_config.driver_loaded = 0;
slouken@1662
   598
    }
slouken@0
   599
}
slouken@0
   600
slouken@0
   601
/* Passing a NULL path means load pointers from the application */
slouken@1662
   602
int
slouken@1668
   603
WIN_GL_LoadLibrary(_THIS, const char *path)
slouken@0
   604
{
slouken@1662
   605
    HMODULE handle;
slouken@0
   606
slouken@1662
   607
    if (gl_active) {
slouken@1668
   608
        SDL_SetError("OpenGL context already created");
slouken@1662
   609
        return -1;
slouken@1662
   610
    }
slouken@0
   611
slouken@1662
   612
    if (path == NULL) {
slouken@1662
   613
        path = DEFAULT_GL_DRIVER_PATH;
slouken@1662
   614
    }
slouken@1668
   615
    handle = LoadLibrary(path);
slouken@1662
   616
    if (handle == NULL) {
slouken@1668
   617
        SDL_SetError("Could not load OpenGL library");
slouken@1662
   618
        return -1;
slouken@1662
   619
    }
slouken@0
   620
slouken@1662
   621
    /* Unload the old driver and reset the pointers */
slouken@1668
   622
    WIN_GL_UnloadLibrary(this);
slouken@0
   623
slouken@1662
   624
    /* Load new function pointers */
slouken@1668
   625
    SDL_memset(this->gl_data, 0, sizeof(*this->gl_data));
slouken@1662
   626
    this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
slouken@1668
   627
        GetProcAddress(handle, "wglGetProcAddress");
slouken@1668
   628
    this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
slouken@1668
   629
        GetProcAddress(handle, "wglCreateContext");
slouken@1668
   630
    this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
slouken@1668
   631
        GetProcAddress(handle, "wglDeleteContext");
slouken@1668
   632
    this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
slouken@1668
   633
        GetProcAddress(handle, "wglMakeCurrent");
slouken@1662
   634
    this->gl_data->wglSwapIntervalEXT = (void (WINAPI *) (int))
slouken@1668
   635
        GetProcAddress(handle, "wglSwapIntervalEXT");
slouken@1662
   636
    this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *) (void))
slouken@1668
   637
        GetProcAddress(handle, "wglGetSwapIntervalEXT");
slouken@0
   638
slouken@1662
   639
    if ((this->gl_data->wglGetProcAddress == NULL) ||
slouken@1662
   640
        (this->gl_data->wglCreateContext == NULL) ||
slouken@1662
   641
        (this->gl_data->wglDeleteContext == NULL) ||
slouken@1662
   642
        (this->gl_data->wglMakeCurrent == NULL)) {
slouken@1668
   643
        SDL_SetError("Could not retrieve OpenGL functions");
slouken@1668
   644
        FreeLibrary(handle);
slouken@1662
   645
        return -1;
slouken@1662
   646
    }
slouken@0
   647
slouken@1662
   648
    this->gl_config.dll_handle = handle;
slouken@1668
   649
    SDL_strlcpy(this->gl_config.driver_path, path,
slouken@1668
   650
                SDL_arraysize(this->gl_config.driver_path));
slouken@1662
   651
    this->gl_config.driver_loaded = 1;
slouken@1662
   652
    return 0;
slouken@0
   653
}
slouken@0
   654
slouken@1662
   655
void *
slouken@1668
   656
WIN_GL_GetProcAddress(_THIS, const char *proc)
slouken@0
   657
{
slouken@1662
   658
    void *func;
slouken@0
   659
slouken@1662
   660
    /* This is to pick up extensions */
slouken@1668
   661
    func = this->gl_data->wglGetProcAddress(proc);
slouken@1662
   662
    if (!func) {
slouken@1662
   663
        /* This is probably a normal GL function */
slouken@1668
   664
        func = GetProcAddress(this->gl_config.dll_handle, proc);
slouken@1662
   665
    }
slouken@1662
   666
    return func;
slouken@0
   667
}
slouken@0
   668
slouken@1361
   669
#endif /* SDL_VIDEO_OPENGL */
slouken@1703
   670
slouken@1662
   671
/* vi: set ts=4 sw=4 expandtab: */