comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
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$";
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)
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)
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)
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)
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)
204 {
205 SwapBuffers(GL_hdc);
206 }
207
208 #endif /* HAVE_OPENGL */
209
210 #ifdef HAVE_OPENGL
211
212 void WIN_GL_UnloadLibrary(_THIS)
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)
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)
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 */