Mercurial > sdl-ios-xcode
diff src/video/wincommon/SDL_wingl.c @ 0:74212992fb08
Initial revision
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Thu, 26 Apr 2001 16:45:43 +0000 |
parents | |
children | e8157fcb3114 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/wincommon/SDL_wingl.c Thu Apr 26 16:45:43 2001 +0000 @@ -0,0 +1,287 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* WGL implementation of SDL OpenGL support */ + +#include <windows.h> + +#include "SDL_error.h" +#include "SDL_lowvideo.h" +#include "SDL_wingl_c.h" + +#ifdef HAVE_OPENGL +#define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL" +#endif + + +int WIN_GL_SetupWindow(_THIS) +{ + int retval; +#ifdef HAVE_OPENGL + int pixel_format; + + /* load the gl driver from a default path */ + if ( ! this->gl_config.driver_loaded ) { + /* no driver has been loaded, use default (ourselves) */ + if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) { + return(-1); + } + } + + /* Get the window device context for our OpenGL drawing */ + GL_hdc = GetDC(SDL_Window); + if ( GL_hdc == NULL ) { + SDL_SetError("Unable to get DC for SDL_Window"); + return(-1); + } + + /* Set up the pixel format descriptor with our needed format */ + memset(&GL_pfd, 0, sizeof(GL_pfd)); + GL_pfd.nSize = sizeof(GL_pfd); + GL_pfd.nVersion = 1; + GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL); + if ( this->gl_config.double_buffer ) { + GL_pfd.dwFlags |= PFD_DOUBLEBUFFER; + } + GL_pfd.iPixelType = PFD_TYPE_RGBA; + GL_pfd.cColorBits = this->gl_config.buffer_size; + GL_pfd.cRedBits = this->gl_config.red_size; + GL_pfd.cGreenBits = this->gl_config.green_size; + GL_pfd.cBlueBits = this->gl_config.blue_size; + GL_pfd.cAlphaBits = this->gl_config.alpha_size; + GL_pfd.cAccumRedBits = this->gl_config.accum_red_size; + GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size; + GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size; + GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size; + GL_pfd.cAccumBits = + (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits + + GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits); + GL_pfd.cDepthBits = this->gl_config.depth_size; + GL_pfd.cStencilBits = this->gl_config.stencil_size; + + /* Choose and set the closest available pixel format */ + pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd); + if ( !pixel_format ) { + SDL_SetError("No matching GL pixel format available"); + return(-1); + } + if( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) { + SDL_SetError("Unable to set HDC pixel format"); + return(-1); + } + DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd); + + GL_hrc = this->gl_data->wglCreateContext(GL_hdc); + if( GL_hrc == NULL ) { + SDL_SetError("Unable to create GL context"); + return(-1); + } + gl_active = 1; +#else + SDL_SetError("WIN driver not configured with OpenGL"); +#endif + if ( gl_active ) { + retval = 0; + } else { + retval = -1; + } + return(retval); +} + +void WIN_GL_ShutDown(_THIS) +{ +#ifdef HAVE_OPENGL + /* Clean up OpenGL */ + if ( GL_hrc ) { + this->gl_data->wglMakeCurrent(NULL, NULL); + this->gl_data->wglDeleteContext(GL_hrc); + GL_hrc = NULL; + } + if ( GL_hdc ) { + ReleaseDC(SDL_Window, GL_hdc); + GL_hdc = NULL; + } + gl_active = 0; + + WIN_GL_UnloadLibrary(this); +#endif /* HAVE_OPENGL */ +} + +#ifdef HAVE_OPENGL + +/* Make the current context active */ +int WIN_GL_MakeCurrent(_THIS) +{ + int retval; + + retval = 0; + if ( ! this->gl_data->wglMakeCurrent(GL_hdc, GL_hrc) ) { + SDL_SetError("Unable to make GL context current"); + retval = -1; + } + return(retval); +} + +/* Get attribute data from glX. */ +int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) +{ + int retval; + + retval = 0; + switch( attrib ) { + case SDL_GL_RED_SIZE: + *value = GL_pfd.cRedBits; + break; + case SDL_GL_GREEN_SIZE: + *value = GL_pfd.cGreenBits; + break; + case SDL_GL_BLUE_SIZE: + *value = GL_pfd.cBlueBits; + break; + case SDL_GL_ALPHA_SIZE: + *value = GL_pfd.cAlphaBits; + break; + case SDL_GL_DOUBLEBUFFER: + if ( GL_pfd.dwFlags & PFD_DOUBLEBUFFER ) { + *value = 1; + } else { + *value = 0; + } + break; + case SDL_GL_BUFFER_SIZE: + *value = GL_pfd.cColorBits; + break; + case SDL_GL_DEPTH_SIZE: + *value = GL_pfd.cDepthBits; + break; + case SDL_GL_STENCIL_SIZE: + *value = GL_pfd.cStencilBits; + break; + case SDL_GL_ACCUM_RED_SIZE: + *value = GL_pfd.cAccumRedBits; + break; + case SDL_GL_ACCUM_GREEN_SIZE: + *value = GL_pfd.cAccumGreenBits; + break; + case SDL_GL_ACCUM_BLUE_SIZE: + *value = GL_pfd.cAccumBlueBits; + break; + case SDL_GL_ACCUM_ALPHA_SIZE: + *value = GL_pfd.cAccumAlphaBits; + break; + default: + retval = -1; + break; + } + return retval; +} + +void WIN_GL_SwapBuffers(_THIS) +{ + SwapBuffers(GL_hdc); +} + +#endif /* HAVE_OPENGL */ + +#ifdef HAVE_OPENGL + +void WIN_GL_UnloadLibrary(_THIS) +{ + if ( this->gl_config.driver_loaded ) { + FreeLibrary((HMODULE)this->gl_config.dll_handle); + + this->gl_data->wglGetProcAddress = NULL; + this->gl_data->wglCreateContext = NULL; + this->gl_data->wglDeleteContext = NULL; + this->gl_data->wglMakeCurrent = NULL; + + this->gl_config.dll_handle = NULL; + this->gl_config.driver_loaded = 0; + } +} + +/* Passing a NULL path means load pointers from the application */ +int WIN_GL_LoadLibrary(_THIS, const char* path) +{ + HMODULE handle; + + if ( gl_active ) { + SDL_SetError("OpenGL context already created"); + return -1; + } + + if ( path == NULL ) { + path = DEFAULT_GL_DRIVER_PATH; + } + handle = LoadLibrary(path); + if ( handle == NULL ) { + SDL_SetError("Could not load OpenGL library"); + return -1; + } + + /* Unload the old driver and reset the pointers */ + WIN_GL_UnloadLibrary(this); + + /* Load new function pointers */ + this->gl_data->wglGetProcAddress = (void * (WINAPI *)(const char *)) + GetProcAddress(handle, "wglGetProcAddress"); + this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC)) + GetProcAddress(handle, "wglCreateContext"); + this->gl_data->wglDeleteContext = (BOOL (WINAPI *)(HGLRC)) + GetProcAddress(handle, "wglDeleteContext"); + this->gl_data->wglMakeCurrent = (BOOL (WINAPI *)(HDC, HGLRC)) + GetProcAddress(handle, "wglMakeCurrent"); + + if ( (this->gl_data->wglGetProcAddress == NULL) || + (this->gl_data->wglCreateContext == NULL) || + (this->gl_data->wglDeleteContext == NULL) || + (this->gl_data->wglMakeCurrent == NULL) ) { + SDL_SetError("Could not retrieve OpenGL functions"); + FreeLibrary(handle); + return -1; + } + + this->gl_config.dll_handle = handle; + strcpy(this->gl_config.driver_path, path); + this->gl_config.driver_loaded = 1; + return 0; +} + +void *WIN_GL_GetProcAddress(_THIS, const char* proc) +{ + void *func; + + /* This is to pick up extensions */ + func = this->gl_data->wglGetProcAddress(proc); + if ( ! func ) { + /* This is probably a normal GL function */ + func = GetProcAddress(this->gl_config.dll_handle, proc); + } + return func; +} + +#endif /* HAVE_OPENGL */