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