src/video/wincommon/SDL_wingl.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. WIN_GL_SetupWindow
  2. WIN_GL_ShutDown
  3. WIN_GL_MakeCurrent
  4. WIN_GL_GetAttribute
  5. WIN_GL_SwapBuffers
  6. WIN_GL_UnloadLibrary
  7. WIN_GL_LoadLibrary
  8. WIN_GL_GetProcAddress

   1 /*
   2     SDL - Simple DirectMedia Layer
   3     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
   4 
   5     This library is free software; you can redistribute it and/or
   6     modify it under the terms of the GNU Library General Public
   7     License as published by the Free Software Foundation; either
   8     version 2 of the License, or (at your option) any later version.
   9 
  10     This library is distributed in the hope that it will be useful,
  11     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13     Library General Public License for more details.
  14 
  15     You should have received a copy of the GNU Library General Public
  16     License along with this library; if not, write to the Free
  17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 
  19     Sam Lantinga
  20     slouken@devolution.com
  21 */
  22 
  23 #ifdef SAVE_RCSID
  24 static char rcsid =
  25  "@(#) $Id: SDL_wingl.c,v 1.1.2.12 2001/02/28 12:35:28 hercules Exp $";
  26 #endif
  27 
  28 /* WGL implementation of SDL OpenGL support */
  29 
  30 #include <windows.h>
  31 
  32 #include "SDL_error.h"
  33 #include "SDL_lowvideo.h"
  34 #include "SDL_wingl_c.h"
  35 
  36 #ifdef HAVE_OPENGL
  37 #define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL"
  38 #endif
  39 
  40 
  41 int WIN_GL_SetupWindow(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
  42 {
  43         int retval;
  44 #ifdef HAVE_OPENGL
  45         int pixel_format;
  46 
  47         /* load the gl driver from a default path */
  48         if ( ! this->gl_config.driver_loaded ) {
  49                 /* no driver has been loaded, use default (ourselves) */
  50                 if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) {
  51                         return(-1);
  52                 }
  53         }
  54 
  55         /* Get the window device context for our OpenGL drawing */
  56         GL_hdc = GetDC(SDL_Window);
  57         if ( GL_hdc == NULL ) {
  58                 SDL_SetError("Unable to get DC for SDL_Window");
  59                 return(-1);
  60         }
  61 
  62         /* Set up the pixel format descriptor with our needed format */
  63         memset(&GL_pfd, 0, sizeof(GL_pfd));
  64         GL_pfd.nSize = sizeof(GL_pfd);
  65         GL_pfd.nVersion = 1;
  66         GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
  67         if ( this->gl_config.double_buffer ) {
  68                 GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
  69         }
  70         GL_pfd.iPixelType = PFD_TYPE_RGBA;
  71         GL_pfd.cColorBits = this->gl_config.buffer_size;
  72         GL_pfd.cRedBits = this->gl_config.red_size;
  73         GL_pfd.cGreenBits = this->gl_config.green_size;
  74         GL_pfd.cBlueBits = this->gl_config.blue_size;
  75         GL_pfd.cAlphaBits = this->gl_config.alpha_size;
  76         GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
  77         GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
  78         GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
  79         GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
  80         GL_pfd.cAccumBits =
  81                 (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
  82                  GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
  83         GL_pfd.cDepthBits = this->gl_config.depth_size;
  84         GL_pfd.cStencilBits = this->gl_config.stencil_size;
  85 
  86         /* Choose and set the closest available pixel format */
  87         pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
  88         if ( !pixel_format ) {
  89                 SDL_SetError("No matching GL pixel format available");
  90                 return(-1);
  91         }
  92         if( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) {
  93                 SDL_SetError("Unable to set HDC pixel format");
  94                 return(-1);
  95         }
  96         DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd);
  97 
  98         GL_hrc = this->gl_data->wglCreateContext(GL_hdc);
  99         if( GL_hrc == NULL ) {
 100                 SDL_SetError("Unable to create GL context");
 101                 return(-1);
 102         }
 103         gl_active = 1;
 104 #else
 105         SDL_SetError("WIN driver not configured with OpenGL");
 106 #endif
 107         if ( gl_active ) {
 108                 retval = 0;
 109         } else {
 110                 retval = -1;
 111         }
 112         return(retval);
 113 }
 114 
 115 void WIN_GL_ShutDown(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
 116 {
 117 #ifdef HAVE_OPENGL
 118         /* Clean up OpenGL */
 119         if ( GL_hrc ) {
 120                 this->gl_data->wglMakeCurrent(NULL, NULL);
 121                 this->gl_data->wglDeleteContext(GL_hrc);
 122                 GL_hrc = NULL;
 123         }
 124         if ( GL_hdc ) {
 125                 ReleaseDC(SDL_Window, GL_hdc);
 126                 GL_hdc = NULL;
 127         }
 128         gl_active = 0;
 129 
 130         WIN_GL_UnloadLibrary(this);
 131 #endif /* HAVE_OPENGL */
 132 }
 133 
 134 #ifdef HAVE_OPENGL
 135 
 136 /* Make the current context active */
 137 int WIN_GL_MakeCurrent(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
 138 {
 139         int retval;
 140 
 141         retval = 0;
 142         if ( ! this->gl_data->wglMakeCurrent(GL_hdc, GL_hrc) ) {
 143                 SDL_SetError("Unable to make GL context current");
 144                 retval = -1;
 145         }
 146         return(retval);
 147 }
 148 
 149 /* Get attribute data from glX. */
 150 int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
     /* [<][>][^][v][top][bottom][index][help] */
 151 {
 152         int retval;
 153 
 154         retval = 0;
 155         switch( attrib ) {
 156             case SDL_GL_RED_SIZE:
 157                 *value = GL_pfd.cRedBits;
 158                 break;
 159             case SDL_GL_GREEN_SIZE:
 160                 *value = GL_pfd.cGreenBits;
 161                 break;
 162             case SDL_GL_BLUE_SIZE:
 163                 *value = GL_pfd.cBlueBits;
 164                 break;
 165             case SDL_GL_ALPHA_SIZE:
 166                 *value = GL_pfd.cAlphaBits;
 167                 break;
 168             case SDL_GL_DOUBLEBUFFER:
 169                 if ( GL_pfd.dwFlags & PFD_DOUBLEBUFFER ) {
 170                         *value = 1;
 171                 } else {
 172                         *value = 0;
 173                 }
 174                 break;
 175             case SDL_GL_BUFFER_SIZE:
 176                 *value = GL_pfd.cColorBits;
 177                 break;
 178             case SDL_GL_DEPTH_SIZE:
 179                 *value = GL_pfd.cDepthBits;
 180                 break;
 181             case SDL_GL_STENCIL_SIZE:
 182                 *value = GL_pfd.cStencilBits;
 183                 break;
 184             case SDL_GL_ACCUM_RED_SIZE:
 185                 *value = GL_pfd.cAccumRedBits;
 186                 break;
 187             case SDL_GL_ACCUM_GREEN_SIZE:
 188                 *value = GL_pfd.cAccumGreenBits;
 189                 break;
 190             case SDL_GL_ACCUM_BLUE_SIZE:
 191                 *value = GL_pfd.cAccumBlueBits;
 192                 break;
 193             case SDL_GL_ACCUM_ALPHA_SIZE:
 194                 *value = GL_pfd.cAccumAlphaBits;
 195                 break;
 196             default:
 197                 retval = -1;
 198                 break;
 199         }
 200         return retval;
 201 }
 202 
 203 void WIN_GL_SwapBuffers(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
 204 {
 205         SwapBuffers(GL_hdc);
 206 }
 207 
 208 #endif /* HAVE_OPENGL */
 209 
 210 #ifdef HAVE_OPENGL
 211 
 212 void WIN_GL_UnloadLibrary(_THIS)
     /* [<][>][^][v][top][bottom][index][help] */
 213 {
 214         if ( this->gl_config.driver_loaded ) {
 215                 FreeLibrary((HMODULE)this->gl_config.dll_handle);
 216 
 217                 this->gl_data->wglGetProcAddress = NULL;
 218                 this->gl_data->wglCreateContext = NULL;
 219                 this->gl_data->wglDeleteContext = NULL;
 220                 this->gl_data->wglMakeCurrent = NULL;
 221 
 222                 this->gl_config.dll_handle = NULL;
 223                 this->gl_config.driver_loaded = 0;
 224         }
 225 }
 226 
 227 /* Passing a NULL path means load pointers from the application */
 228 int WIN_GL_LoadLibrary(_THIS, const char* path) 
     /* [<][>][^][v][top][bottom][index][help] */
 229 {
 230         HMODULE handle;
 231 
 232         if ( gl_active ) {
 233                 SDL_SetError("OpenGL context already created");
 234                 return -1;
 235         }
 236 
 237         if ( path == NULL ) {
 238                 path = DEFAULT_GL_DRIVER_PATH;
 239         }
 240         handle = LoadLibrary(path);
 241         if ( handle == NULL ) {
 242                 SDL_SetError("Could not load OpenGL library");
 243                 return -1;
 244         }
 245 
 246         /* Unload the old driver and reset the pointers */
 247         WIN_GL_UnloadLibrary(this);
 248 
 249         /* Load new function pointers */
 250         this->gl_data->wglGetProcAddress = (void * (WINAPI *)(const char *))
 251                 GetProcAddress(handle, "wglGetProcAddress");
 252         this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC))
 253                 GetProcAddress(handle, "wglCreateContext");
 254         this->gl_data->wglDeleteContext = (BOOL (WINAPI *)(HGLRC))
 255                 GetProcAddress(handle, "wglDeleteContext");
 256         this->gl_data->wglMakeCurrent = (BOOL (WINAPI *)(HDC, HGLRC))
 257                 GetProcAddress(handle, "wglMakeCurrent");
 258 
 259         if ( (this->gl_data->wglGetProcAddress == NULL) ||
 260              (this->gl_data->wglCreateContext == NULL) ||
 261              (this->gl_data->wglDeleteContext == NULL) ||
 262              (this->gl_data->wglMakeCurrent == NULL) ) {
 263                 SDL_SetError("Could not retrieve OpenGL functions");
 264                 FreeLibrary(handle);
 265                 return -1;
 266         }
 267 
 268         this->gl_config.dll_handle = handle;
 269         strcpy(this->gl_config.driver_path, path);
 270         this->gl_config.driver_loaded = 1;
 271         return 0;
 272 }
 273 
 274 void *WIN_GL_GetProcAddress(_THIS, const char* proc)
     /* [<][>][^][v][top][bottom][index][help] */
 275 {
 276         void *func;
 277 
 278         /* This is to pick up extensions */
 279         func = this->gl_data->wglGetProcAddress(proc);
 280         if ( ! func ) {
 281                 /* This is probably a normal GL function */
 282                 func = GetProcAddress(this->gl_config.dll_handle, proc);
 283         }
 284         return func;
 285 }
 286 
 287 #endif /* HAVE_OPENGL */

/* [<][>][^][v][top][bottom][index][help] */