src/video/wincommon/SDL_wingl.c
changeset 0 74212992fb08
child 252 e8157fcb3114
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/video/wincommon/SDL_wingl.c	Thu Apr 26 16:45:43 2001 +0000
     1.3 @@ -0,0 +1,287 @@
     1.4 +/*
     1.5 +    SDL - Simple DirectMedia Layer
     1.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     1.7 +
     1.8 +    This library is free software; you can redistribute it and/or
     1.9 +    modify it under the terms of the GNU Library General Public
    1.10 +    License as published by the Free Software Foundation; either
    1.11 +    version 2 of the License, or (at your option) any later version.
    1.12 +
    1.13 +    This library is distributed in the hope that it will be useful,
    1.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.16 +    Library General Public License for more details.
    1.17 +
    1.18 +    You should have received a copy of the GNU Library General Public
    1.19 +    License along with this library; if not, write to the Free
    1.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.21 +
    1.22 +    Sam Lantinga
    1.23 +    slouken@devolution.com
    1.24 +*/
    1.25 +
    1.26 +#ifdef SAVE_RCSID
    1.27 +static char rcsid =
    1.28 + "@(#) $Id$";
    1.29 +#endif
    1.30 +
    1.31 +/* WGL implementation of SDL OpenGL support */
    1.32 +
    1.33 +#include <windows.h>
    1.34 +
    1.35 +#include "SDL_error.h"
    1.36 +#include "SDL_lowvideo.h"
    1.37 +#include "SDL_wingl_c.h"
    1.38 +
    1.39 +#ifdef HAVE_OPENGL
    1.40 +#define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL"
    1.41 +#endif
    1.42 +
    1.43 +
    1.44 +int WIN_GL_SetupWindow(_THIS)
    1.45 +{
    1.46 +	int retval;
    1.47 +#ifdef HAVE_OPENGL
    1.48 +	int pixel_format;
    1.49 +
    1.50 +	/* load the gl driver from a default path */
    1.51 +	if ( ! this->gl_config.driver_loaded ) {
    1.52 +		/* no driver has been loaded, use default (ourselves) */
    1.53 +		if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) {
    1.54 +			return(-1);
    1.55 +		}
    1.56 +	}
    1.57 +
    1.58 +	/* Get the window device context for our OpenGL drawing */
    1.59 +	GL_hdc = GetDC(SDL_Window);
    1.60 +	if ( GL_hdc == NULL ) {
    1.61 +		SDL_SetError("Unable to get DC for SDL_Window");
    1.62 +		return(-1);
    1.63 +	}
    1.64 +
    1.65 +	/* Set up the pixel format descriptor with our needed format */
    1.66 +	memset(&GL_pfd, 0, sizeof(GL_pfd));
    1.67 +	GL_pfd.nSize = sizeof(GL_pfd);
    1.68 +	GL_pfd.nVersion = 1;
    1.69 +	GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
    1.70 +	if ( this->gl_config.double_buffer ) {
    1.71 +		GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
    1.72 +	}
    1.73 +	GL_pfd.iPixelType = PFD_TYPE_RGBA;
    1.74 +	GL_pfd.cColorBits = this->gl_config.buffer_size;
    1.75 +	GL_pfd.cRedBits = this->gl_config.red_size;
    1.76 +	GL_pfd.cGreenBits = this->gl_config.green_size;
    1.77 +	GL_pfd.cBlueBits = this->gl_config.blue_size;
    1.78 +	GL_pfd.cAlphaBits = this->gl_config.alpha_size;
    1.79 +	GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
    1.80 +	GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
    1.81 +	GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
    1.82 +	GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
    1.83 +	GL_pfd.cAccumBits =
    1.84 +		(GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
    1.85 +		 GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
    1.86 +	GL_pfd.cDepthBits = this->gl_config.depth_size;
    1.87 +	GL_pfd.cStencilBits = this->gl_config.stencil_size;
    1.88 +
    1.89 +	/* Choose and set the closest available pixel format */
    1.90 +	pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
    1.91 +	if ( !pixel_format ) {
    1.92 +		SDL_SetError("No matching GL pixel format available");
    1.93 +		return(-1);
    1.94 +	}
    1.95 +	if( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) {
    1.96 +		SDL_SetError("Unable to set HDC pixel format");
    1.97 +		return(-1);
    1.98 +	}
    1.99 +	DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd);
   1.100 +
   1.101 +	GL_hrc = this->gl_data->wglCreateContext(GL_hdc);
   1.102 +	if( GL_hrc == NULL ) {
   1.103 +		SDL_SetError("Unable to create GL context");
   1.104 +		return(-1);
   1.105 +	}
   1.106 +	gl_active = 1;
   1.107 +#else
   1.108 +	SDL_SetError("WIN driver not configured with OpenGL");
   1.109 +#endif
   1.110 +	if ( gl_active ) {
   1.111 +		retval = 0;
   1.112 +	} else {
   1.113 +		retval = -1;
   1.114 +	}
   1.115 +	return(retval);
   1.116 +}
   1.117 +
   1.118 +void WIN_GL_ShutDown(_THIS)
   1.119 +{
   1.120 +#ifdef HAVE_OPENGL
   1.121 +	/* Clean up OpenGL */
   1.122 +	if ( GL_hrc ) {
   1.123 +		this->gl_data->wglMakeCurrent(NULL, NULL);
   1.124 +		this->gl_data->wglDeleteContext(GL_hrc);
   1.125 +		GL_hrc = NULL;
   1.126 +	}
   1.127 +	if ( GL_hdc ) {
   1.128 +		ReleaseDC(SDL_Window, GL_hdc);
   1.129 +		GL_hdc = NULL;
   1.130 +	}
   1.131 +	gl_active = 0;
   1.132 +
   1.133 +	WIN_GL_UnloadLibrary(this);
   1.134 +#endif /* HAVE_OPENGL */
   1.135 +}
   1.136 +
   1.137 +#ifdef HAVE_OPENGL
   1.138 +
   1.139 +/* Make the current context active */
   1.140 +int WIN_GL_MakeCurrent(_THIS)
   1.141 +{
   1.142 +	int retval;
   1.143 +
   1.144 +	retval = 0;
   1.145 +	if ( ! this->gl_data->wglMakeCurrent(GL_hdc, GL_hrc) ) {
   1.146 +		SDL_SetError("Unable to make GL context current");
   1.147 +		retval = -1;
   1.148 +	}
   1.149 +	return(retval);
   1.150 +}
   1.151 +
   1.152 +/* Get attribute data from glX. */
   1.153 +int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
   1.154 +{
   1.155 +	int retval;
   1.156 +
   1.157 +	retval = 0;
   1.158 +	switch( attrib ) {
   1.159 +	    case SDL_GL_RED_SIZE:
   1.160 +		*value = GL_pfd.cRedBits;
   1.161 +		break;
   1.162 +	    case SDL_GL_GREEN_SIZE:
   1.163 +		*value = GL_pfd.cGreenBits;
   1.164 +		break;
   1.165 +	    case SDL_GL_BLUE_SIZE:
   1.166 +		*value = GL_pfd.cBlueBits;
   1.167 +		break;
   1.168 +	    case SDL_GL_ALPHA_SIZE:
   1.169 +		*value = GL_pfd.cAlphaBits;
   1.170 +		break;
   1.171 +	    case SDL_GL_DOUBLEBUFFER:
   1.172 +		if ( GL_pfd.dwFlags & PFD_DOUBLEBUFFER ) {
   1.173 +			*value = 1;
   1.174 +		} else {
   1.175 +			*value = 0;
   1.176 +		}
   1.177 +		break;
   1.178 +	    case SDL_GL_BUFFER_SIZE:
   1.179 +		*value = GL_pfd.cColorBits;
   1.180 +		break;
   1.181 +	    case SDL_GL_DEPTH_SIZE:
   1.182 +		*value = GL_pfd.cDepthBits;
   1.183 +		break;
   1.184 +	    case SDL_GL_STENCIL_SIZE:
   1.185 +		*value = GL_pfd.cStencilBits;
   1.186 +		break;
   1.187 +	    case SDL_GL_ACCUM_RED_SIZE:
   1.188 +		*value = GL_pfd.cAccumRedBits;
   1.189 +		break;
   1.190 +	    case SDL_GL_ACCUM_GREEN_SIZE:
   1.191 +		*value = GL_pfd.cAccumGreenBits;
   1.192 +		break;
   1.193 +	    case SDL_GL_ACCUM_BLUE_SIZE:
   1.194 +		*value = GL_pfd.cAccumBlueBits;
   1.195 +		break;
   1.196 +	    case SDL_GL_ACCUM_ALPHA_SIZE:
   1.197 +		*value = GL_pfd.cAccumAlphaBits;
   1.198 +		break;
   1.199 +	    default:
   1.200 +		retval = -1;
   1.201 +		break;
   1.202 +	}
   1.203 +	return retval;
   1.204 +}
   1.205 +
   1.206 +void WIN_GL_SwapBuffers(_THIS)
   1.207 +{
   1.208 +	SwapBuffers(GL_hdc);
   1.209 +}
   1.210 +
   1.211 +#endif /* HAVE_OPENGL */
   1.212 +
   1.213 +#ifdef HAVE_OPENGL
   1.214 +
   1.215 +void WIN_GL_UnloadLibrary(_THIS)
   1.216 +{
   1.217 +	if ( this->gl_config.driver_loaded ) {
   1.218 +		FreeLibrary((HMODULE)this->gl_config.dll_handle);
   1.219 +
   1.220 +		this->gl_data->wglGetProcAddress = NULL;
   1.221 +		this->gl_data->wglCreateContext = NULL;
   1.222 +		this->gl_data->wglDeleteContext = NULL;
   1.223 +		this->gl_data->wglMakeCurrent = NULL;
   1.224 +
   1.225 +		this->gl_config.dll_handle = NULL;
   1.226 +		this->gl_config.driver_loaded = 0;
   1.227 +	}
   1.228 +}
   1.229 +
   1.230 +/* Passing a NULL path means load pointers from the application */
   1.231 +int WIN_GL_LoadLibrary(_THIS, const char* path) 
   1.232 +{
   1.233 +	HMODULE handle;
   1.234 +
   1.235 + 	if ( gl_active ) {
   1.236 + 		SDL_SetError("OpenGL context already created");
   1.237 + 		return -1;
   1.238 + 	}
   1.239 +
   1.240 +	if ( path == NULL ) {
   1.241 +		path = DEFAULT_GL_DRIVER_PATH;
   1.242 +	}
   1.243 +	handle = LoadLibrary(path);
   1.244 +	if ( handle == NULL ) {
   1.245 +		SDL_SetError("Could not load OpenGL library");
   1.246 +		return -1;
   1.247 +	}
   1.248 +
   1.249 +	/* Unload the old driver and reset the pointers */
   1.250 +	WIN_GL_UnloadLibrary(this);
   1.251 +
   1.252 +	/* Load new function pointers */
   1.253 +	this->gl_data->wglGetProcAddress = (void * (WINAPI *)(const char *))
   1.254 +		GetProcAddress(handle, "wglGetProcAddress");
   1.255 +	this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC))
   1.256 +		GetProcAddress(handle, "wglCreateContext");
   1.257 +	this->gl_data->wglDeleteContext = (BOOL (WINAPI *)(HGLRC))
   1.258 +		GetProcAddress(handle, "wglDeleteContext");
   1.259 +	this->gl_data->wglMakeCurrent = (BOOL (WINAPI *)(HDC, HGLRC))
   1.260 +		GetProcAddress(handle, "wglMakeCurrent");
   1.261 +
   1.262 +	if ( (this->gl_data->wglGetProcAddress == NULL) ||
   1.263 +	     (this->gl_data->wglCreateContext == NULL) ||
   1.264 +	     (this->gl_data->wglDeleteContext == NULL) ||
   1.265 +	     (this->gl_data->wglMakeCurrent == NULL) ) {
   1.266 +		SDL_SetError("Could not retrieve OpenGL functions");
   1.267 +		FreeLibrary(handle);
   1.268 +		return -1;
   1.269 +	}
   1.270 +
   1.271 +	this->gl_config.dll_handle = handle;
   1.272 +	strcpy(this->gl_config.driver_path, path);
   1.273 +	this->gl_config.driver_loaded = 1;
   1.274 +	return 0;
   1.275 +}
   1.276 +
   1.277 +void *WIN_GL_GetProcAddress(_THIS, const char* proc)
   1.278 +{
   1.279 +	void *func;
   1.280 +
   1.281 +	/* This is to pick up extensions */
   1.282 +	func = this->gl_data->wglGetProcAddress(proc);
   1.283 +	if ( ! func ) {
   1.284 +		/* This is probably a normal GL function */
   1.285 +		func = GetProcAddress(this->gl_config.dll_handle, proc);
   1.286 +	}
   1.287 +	return func;
   1.288 +}
   1.289 +
   1.290 +#endif /* HAVE_OPENGL */