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/x11/SDL_x11gl.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/x11/SDL_x11gl.c')
-rw-r--r-- | apps/plugins/sdl/src/video/x11/SDL_x11gl.c | 577 |
1 files changed, 577 insertions, 0 deletions
diff --git a/apps/plugins/sdl/src/video/x11/SDL_x11gl.c b/apps/plugins/sdl/src/video/x11/SDL_x11gl.c new file mode 100644 index 0000000000..aa5297b674 --- /dev/null +++ b/apps/plugins/sdl/src/video/x11/SDL_x11gl.c | |||
@@ -0,0 +1,577 @@ | |||
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 | #include "SDL_x11video.h" | ||
25 | #include "../../events/SDL_events_c.h" | ||
26 | #include "SDL_x11dga_c.h" | ||
27 | #include "SDL_x11gl_c.h" | ||
28 | |||
29 | #if defined(__IRIX__) | ||
30 | /* IRIX doesn't have a GL library versioning system */ | ||
31 | #define DEFAULT_OPENGL "libGL.so" | ||
32 | #elif defined(__MACOSX__) | ||
33 | #define DEFAULT_OPENGL "/usr/X11R6/lib/libGL.1.dylib" | ||
34 | #elif defined(__QNXNTO__) | ||
35 | #define DEFAULT_OPENGL "libGL.so.3" | ||
36 | #elif defined(__OpenBSD__) | ||
37 | #define DEFAULT_OPENGL "libGL.so.4.0" | ||
38 | #else | ||
39 | #define DEFAULT_OPENGL "libGL.so.1" | ||
40 | #endif | ||
41 | |||
42 | #ifndef GLX_ARB_multisample | ||
43 | #define GLX_ARB_multisample | ||
44 | #define GLX_SAMPLE_BUFFERS_ARB 100000 | ||
45 | #define GLX_SAMPLES_ARB 100001 | ||
46 | #endif | ||
47 | |||
48 | /* GLX_EXT_visual_rating stuff that might not be in the system headers... */ | ||
49 | #ifndef GLX_VISUAL_CAVEAT_EXT | ||
50 | #define GLX_VISUAL_CAVEAT_EXT 0x20 | ||
51 | #endif | ||
52 | #ifndef GLX_NONE_EXT | ||
53 | #define GLX_NONE_EXT 0x8000 | ||
54 | #endif | ||
55 | #ifndef GLX_SLOW_VISUAL_EXT | ||
56 | #define GLX_SLOW_VISUAL_EXT 0x8001 | ||
57 | #endif | ||
58 | #ifndef GLX_NON_CONFORMANT_VISUAL_EXT | ||
59 | #define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D | ||
60 | #endif | ||
61 | |||
62 | |||
63 | #if SDL_VIDEO_OPENGL_GLX | ||
64 | static int glXExtensionSupported(_THIS, const char *extension) | ||
65 | { | ||
66 | const char *extensions; | ||
67 | const char *start; | ||
68 | const char *where, *terminator; | ||
69 | |||
70 | /* Extension names should not have spaces. */ | ||
71 | where = SDL_strchr(extension, ' '); | ||
72 | if ( where || *extension == '\0' ) { | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | extensions = this->gl_data->glXQueryExtensionsString(GFX_Display,SDL_Screen); | ||
77 | /* It takes a bit of care to be fool-proof about parsing the | ||
78 | * OpenGL extensions string. Don't be fooled by sub-strings, etc. | ||
79 | */ | ||
80 | |||
81 | /* http://bugs.debian.org/537487 */ | ||
82 | if (extensions == NULL) { | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | start = extensions; | ||
87 | |||
88 | for (;;) { | ||
89 | where = SDL_strstr(start, extension); | ||
90 | if (!where) break; | ||
91 | |||
92 | terminator = where + strlen(extension); | ||
93 | if (where == start || *(where - 1) == ' ') | ||
94 | if (*terminator == ' ' || *terminator == '\0') return 1; | ||
95 | |||
96 | start = terminator; | ||
97 | } | ||
98 | return 0; | ||
99 | } | ||
100 | #endif /* SDL_VIDEO_OPENGL_GLX */ | ||
101 | |||
102 | XVisualInfo *X11_GL_GetVisual(_THIS) | ||
103 | { | ||
104 | #if SDL_VIDEO_OPENGL_GLX | ||
105 | /* 64 seems nice. */ | ||
106 | int attribs[64]; | ||
107 | int i; | ||
108 | |||
109 | /* load the gl driver from a default path */ | ||
110 | if ( ! this->gl_config.driver_loaded ) { | ||
111 | /* no driver has been loaded, use default (ourselves) */ | ||
112 | if ( X11_GL_LoadLibrary(this, NULL) < 0 ) { | ||
113 | return NULL; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | /* See if we already have a window which we must use */ | ||
118 | if ( SDL_windowid ) { | ||
119 | XWindowAttributes a; | ||
120 | XVisualInfo vi_in; | ||
121 | int out_count; | ||
122 | |||
123 | XGetWindowAttributes(SDL_Display, SDL_Window, &a); | ||
124 | vi_in.screen = SDL_Screen; | ||
125 | vi_in.visualid = XVisualIDFromVisual(a.visual); | ||
126 | glx_visualinfo = XGetVisualInfo(SDL_Display, | ||
127 | VisualScreenMask|VisualIDMask, &vi_in, &out_count); | ||
128 | return glx_visualinfo; | ||
129 | } | ||
130 | |||
131 | /* Setup our GLX attributes according to the gl_config. */ | ||
132 | i = 0; | ||
133 | attribs[i++] = GLX_RGBA; | ||
134 | attribs[i++] = GLX_RED_SIZE; | ||
135 | attribs[i++] = this->gl_config.red_size; | ||
136 | attribs[i++] = GLX_GREEN_SIZE; | ||
137 | attribs[i++] = this->gl_config.green_size; | ||
138 | attribs[i++] = GLX_BLUE_SIZE; | ||
139 | attribs[i++] = this->gl_config.blue_size; | ||
140 | |||
141 | if( this->gl_config.alpha_size ) { | ||
142 | attribs[i++] = GLX_ALPHA_SIZE; | ||
143 | attribs[i++] = this->gl_config.alpha_size; | ||
144 | } | ||
145 | |||
146 | if( this->gl_config.double_buffer ) { | ||
147 | attribs[i++] = GLX_DOUBLEBUFFER; | ||
148 | } | ||
149 | |||
150 | attribs[i++] = GLX_DEPTH_SIZE; | ||
151 | attribs[i++] = this->gl_config.depth_size; | ||
152 | |||
153 | if( this->gl_config.stencil_size ) { | ||
154 | attribs[i++] = GLX_STENCIL_SIZE; | ||
155 | attribs[i++] = this->gl_config.stencil_size; | ||
156 | } | ||
157 | |||
158 | if( this->gl_config.accum_red_size ) { | ||
159 | attribs[i++] = GLX_ACCUM_RED_SIZE; | ||
160 | attribs[i++] = this->gl_config.accum_red_size; | ||
161 | } | ||
162 | |||
163 | if( this->gl_config.accum_green_size ) { | ||
164 | attribs[i++] = GLX_ACCUM_GREEN_SIZE; | ||
165 | attribs[i++] = this->gl_config.accum_green_size; | ||
166 | } | ||
167 | |||
168 | if( this->gl_config.accum_blue_size ) { | ||
169 | attribs[i++] = GLX_ACCUM_BLUE_SIZE; | ||
170 | attribs[i++] = this->gl_config.accum_blue_size; | ||
171 | } | ||
172 | |||
173 | if( this->gl_config.accum_alpha_size ) { | ||
174 | attribs[i++] = GLX_ACCUM_ALPHA_SIZE; | ||
175 | attribs[i++] = this->gl_config.accum_alpha_size; | ||
176 | } | ||
177 | |||
178 | if( this->gl_config.stereo ) { | ||
179 | attribs[i++] = GLX_STEREO; | ||
180 | } | ||
181 | |||
182 | if( this->gl_config.multisamplebuffers ) { | ||
183 | attribs[i++] = GLX_SAMPLE_BUFFERS_ARB; | ||
184 | attribs[i++] = this->gl_config.multisamplebuffers; | ||
185 | } | ||
186 | |||
187 | if( this->gl_config.multisamplesamples ) { | ||
188 | attribs[i++] = GLX_SAMPLES_ARB; | ||
189 | attribs[i++] = this->gl_config.multisamplesamples; | ||
190 | } | ||
191 | |||
192 | if( this->gl_config.accelerated >= 0 && | ||
193 | glXExtensionSupported(this, "GLX_EXT_visual_rating") ) { | ||
194 | attribs[i++] = GLX_VISUAL_CAVEAT_EXT; | ||
195 | attribs[i++] = GLX_NONE_EXT; | ||
196 | } | ||
197 | |||
198 | #ifdef GLX_DIRECT_COLOR /* Try for a DirectColor visual for gamma support */ | ||
199 | if ( !SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) { | ||
200 | attribs[i++] = GLX_X_VISUAL_TYPE; | ||
201 | attribs[i++] = GLX_DIRECT_COLOR; | ||
202 | } | ||
203 | #endif | ||
204 | attribs[i++] = None; | ||
205 | |||
206 | glx_visualinfo = this->gl_data->glXChooseVisual(GFX_Display, | ||
207 | SDL_Screen, attribs); | ||
208 | #ifdef GLX_DIRECT_COLOR | ||
209 | if( !glx_visualinfo && !SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ) { /* No DirectColor visual? Try again.. */ | ||
210 | attribs[i-3] = None; | ||
211 | glx_visualinfo = this->gl_data->glXChooseVisual(GFX_Display, | ||
212 | SDL_Screen, attribs); | ||
213 | } | ||
214 | #endif | ||
215 | if( !glx_visualinfo ) { | ||
216 | SDL_SetError( "Couldn't find matching GLX visual"); | ||
217 | return NULL; | ||
218 | } | ||
219 | /* | ||
220 | printf("Found GLX visual 0x%x\n", glx_visualinfo->visualid); | ||
221 | */ | ||
222 | return glx_visualinfo; | ||
223 | #else | ||
224 | SDL_SetError("X11 driver not configured with OpenGL"); | ||
225 | return NULL; | ||
226 | #endif | ||
227 | } | ||
228 | |||
229 | int X11_GL_CreateWindow(_THIS, int w, int h) | ||
230 | { | ||
231 | int retval; | ||
232 | #if SDL_VIDEO_OPENGL_GLX | ||
233 | XSetWindowAttributes attributes; | ||
234 | unsigned long mask; | ||
235 | unsigned long black; | ||
236 | |||
237 | black = (glx_visualinfo->visual == DefaultVisual(SDL_Display, | ||
238 | SDL_Screen)) | ||
239 | ? BlackPixel(SDL_Display, SDL_Screen) : 0; | ||
240 | attributes.background_pixel = black; | ||
241 | attributes.border_pixel = black; | ||
242 | attributes.colormap = SDL_XColorMap; | ||
243 | mask = CWBackPixel | CWBorderPixel | CWColormap; | ||
244 | |||
245 | SDL_Window = XCreateWindow(SDL_Display, WMwindow, | ||
246 | 0, 0, w, h, 0, glx_visualinfo->depth, | ||
247 | InputOutput, glx_visualinfo->visual, | ||
248 | mask, &attributes); | ||
249 | if ( !SDL_Window ) { | ||
250 | SDL_SetError("Could not create window"); | ||
251 | return -1; | ||
252 | } | ||
253 | retval = 0; | ||
254 | #else | ||
255 | SDL_SetError("X11 driver not configured with OpenGL"); | ||
256 | retval = -1; | ||
257 | #endif | ||
258 | return(retval); | ||
259 | } | ||
260 | |||
261 | int X11_GL_CreateContext(_THIS) | ||
262 | { | ||
263 | int retval; | ||
264 | #if SDL_VIDEO_OPENGL_GLX | ||
265 | |||
266 | /* We do this to create a clean separation between X and GLX errors. */ | ||
267 | XSync( SDL_Display, False ); | ||
268 | glx_context = this->gl_data->glXCreateContext(GFX_Display, | ||
269 | glx_visualinfo, NULL, True); | ||
270 | XSync( GFX_Display, False ); | ||
271 | |||
272 | if ( glx_context == NULL ) { | ||
273 | SDL_SetError("Could not create GL context"); | ||
274 | return(-1); | ||
275 | } | ||
276 | if ( X11_GL_MakeCurrent(this) < 0 ) { | ||
277 | return(-1); | ||
278 | } | ||
279 | gl_active = 1; | ||
280 | |||
281 | if ( !glXExtensionSupported(this, "GLX_SGI_swap_control") ) { | ||
282 | this->gl_data->glXSwapIntervalSGI = NULL; | ||
283 | } | ||
284 | if ( !glXExtensionSupported(this, "GLX_MESA_swap_control") ) { | ||
285 | this->gl_data->glXSwapIntervalMESA = NULL; | ||
286 | } | ||
287 | if ( !glXExtensionSupported(this, "GLX_EXT_swap_control") ) { | ||
288 | this->gl_data->glXSwapIntervalEXT = NULL; | ||
289 | } | ||
290 | |||
291 | if ( this->gl_config.swap_control >= 0 ) { | ||
292 | int rc = -1; | ||
293 | if ( this->gl_data->glXSwapIntervalEXT ) { | ||
294 | rc = this->gl_data->glXSwapIntervalEXT(GFX_Display, SDL_Window, | ||
295 | this->gl_config.swap_control); | ||
296 | } else if ( this->gl_data->glXSwapIntervalMESA ) { | ||
297 | rc = this->gl_data->glXSwapIntervalMESA(this->gl_config.swap_control); | ||
298 | } else if ( this->gl_data->glXSwapIntervalSGI ) { | ||
299 | rc = this->gl_data->glXSwapIntervalSGI(this->gl_config.swap_control); | ||
300 | } | ||
301 | if (rc == 0) { | ||
302 | this->gl_data->swap_interval = this->gl_config.swap_control; | ||
303 | } | ||
304 | } | ||
305 | #else | ||
306 | SDL_SetError("X11 driver not configured with OpenGL"); | ||
307 | #endif | ||
308 | if ( gl_active ) { | ||
309 | retval = 0; | ||
310 | } else { | ||
311 | retval = -1; | ||
312 | } | ||
313 | return(retval); | ||
314 | } | ||
315 | |||
316 | void X11_GL_Shutdown(_THIS) | ||
317 | { | ||
318 | #if SDL_VIDEO_OPENGL_GLX | ||
319 | /* Clean up OpenGL */ | ||
320 | if( glx_context ) { | ||
321 | this->gl_data->glXMakeCurrent(GFX_Display, None, NULL); | ||
322 | |||
323 | if (glx_context != NULL) | ||
324 | this->gl_data->glXDestroyContext(GFX_Display, glx_context); | ||
325 | |||
326 | glx_context = NULL; | ||
327 | } | ||
328 | gl_active = 0; | ||
329 | #endif /* SDL_VIDEO_OPENGL_GLX */ | ||
330 | } | ||
331 | |||
332 | #if SDL_VIDEO_OPENGL_GLX | ||
333 | |||
334 | /* Make the current context active */ | ||
335 | int X11_GL_MakeCurrent(_THIS) | ||
336 | { | ||
337 | int retval; | ||
338 | |||
339 | retval = 0; | ||
340 | if ( ! this->gl_data->glXMakeCurrent(GFX_Display, | ||
341 | SDL_Window, glx_context) ) { | ||
342 | SDL_SetError("Unable to make GL context current"); | ||
343 | retval = -1; | ||
344 | } | ||
345 | XSync( GFX_Display, False ); | ||
346 | |||
347 | /* More Voodoo X server workarounds... Grr... */ | ||
348 | SDL_Lock_EventThread(); | ||
349 | X11_CheckDGAMouse(this); | ||
350 | SDL_Unlock_EventThread(); | ||
351 | |||
352 | return(retval); | ||
353 | } | ||
354 | |||
355 | /* Get attribute data from glX. */ | ||
356 | int X11_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) | ||
357 | { | ||
358 | int retval = -1; | ||
359 | int unsupported = 0; | ||
360 | int glx_attrib = None; | ||
361 | |||
362 | switch( attrib ) { | ||
363 | case SDL_GL_RED_SIZE: | ||
364 | glx_attrib = GLX_RED_SIZE; | ||
365 | break; | ||
366 | case SDL_GL_GREEN_SIZE: | ||
367 | glx_attrib = GLX_GREEN_SIZE; | ||
368 | break; | ||
369 | case SDL_GL_BLUE_SIZE: | ||
370 | glx_attrib = GLX_BLUE_SIZE; | ||
371 | break; | ||
372 | case SDL_GL_ALPHA_SIZE: | ||
373 | glx_attrib = GLX_ALPHA_SIZE; | ||
374 | break; | ||
375 | case SDL_GL_DOUBLEBUFFER: | ||
376 | glx_attrib = GLX_DOUBLEBUFFER; | ||
377 | break; | ||
378 | case SDL_GL_BUFFER_SIZE: | ||
379 | glx_attrib = GLX_BUFFER_SIZE; | ||
380 | break; | ||
381 | case SDL_GL_DEPTH_SIZE: | ||
382 | glx_attrib = GLX_DEPTH_SIZE; | ||
383 | break; | ||
384 | case SDL_GL_STENCIL_SIZE: | ||
385 | glx_attrib = GLX_STENCIL_SIZE; | ||
386 | break; | ||
387 | case SDL_GL_ACCUM_RED_SIZE: | ||
388 | glx_attrib = GLX_ACCUM_RED_SIZE; | ||
389 | break; | ||
390 | case SDL_GL_ACCUM_GREEN_SIZE: | ||
391 | glx_attrib = GLX_ACCUM_GREEN_SIZE; | ||
392 | break; | ||
393 | case SDL_GL_ACCUM_BLUE_SIZE: | ||
394 | glx_attrib = GLX_ACCUM_BLUE_SIZE; | ||
395 | break; | ||
396 | case SDL_GL_ACCUM_ALPHA_SIZE: | ||
397 | glx_attrib = GLX_ACCUM_ALPHA_SIZE; | ||
398 | break; | ||
399 | case SDL_GL_STEREO: | ||
400 | glx_attrib = GLX_STEREO; | ||
401 | break; | ||
402 | case SDL_GL_MULTISAMPLEBUFFERS: | ||
403 | glx_attrib = GLX_SAMPLE_BUFFERS_ARB; | ||
404 | break; | ||
405 | case SDL_GL_MULTISAMPLESAMPLES: | ||
406 | glx_attrib = GLX_SAMPLES_ARB; | ||
407 | break; | ||
408 | case SDL_GL_ACCELERATED_VISUAL: | ||
409 | if ( glXExtensionSupported(this, "GLX_EXT_visual_rating") ) { | ||
410 | glx_attrib = GLX_VISUAL_CAVEAT_EXT; | ||
411 | retval = this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo, glx_attrib, value); | ||
412 | if ( *value == GLX_SLOW_VISUAL_EXT ) { | ||
413 | *value = SDL_FALSE; | ||
414 | } else { | ||
415 | *value = SDL_TRUE; | ||
416 | } | ||
417 | return retval; | ||
418 | } else { | ||
419 | unsupported = 1; | ||
420 | } | ||
421 | break; | ||
422 | case SDL_GL_SWAP_CONTROL: | ||
423 | if ( ( this->gl_data->glXSwapIntervalEXT ) || | ||
424 | ( this->gl_data->glXSwapIntervalMESA ) || | ||
425 | ( this->gl_data->glXSwapIntervalSGI ) ) { | ||
426 | *value = this->gl_data->swap_interval; | ||
427 | return 0; | ||
428 | } else { | ||
429 | unsupported = 1; | ||
430 | } | ||
431 | break; | ||
432 | default: | ||
433 | unsupported = 1; | ||
434 | break; | ||
435 | } | ||
436 | |||
437 | if (unsupported) { | ||
438 | SDL_SetError("OpenGL attribute is unsupported on this system"); | ||
439 | } else { | ||
440 | retval = this->gl_data->glXGetConfig(GFX_Display, glx_visualinfo, glx_attrib, value); | ||
441 | } | ||
442 | return retval; | ||
443 | } | ||
444 | |||
445 | void X11_GL_SwapBuffers(_THIS) | ||
446 | { | ||
447 | this->gl_data->glXSwapBuffers(GFX_Display, SDL_Window); | ||
448 | } | ||
449 | |||
450 | #endif /* SDL_VIDEO_OPENGL_GLX */ | ||
451 | |||
452 | #define OPENGL_REQUIRS_DLOPEN | ||
453 | #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN) | ||
454 | #include <dlfcn.h> | ||
455 | #define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL)) | ||
456 | #define GL_LoadFunction dlsym | ||
457 | #define GL_UnloadObject dlclose | ||
458 | #else | ||
459 | #define GL_LoadObject SDL_LoadObject | ||
460 | #define GL_LoadFunction SDL_LoadFunction | ||
461 | #define GL_UnloadObject SDL_UnloadObject | ||
462 | #endif | ||
463 | |||
464 | void X11_GL_UnloadLibrary(_THIS) | ||
465 | { | ||
466 | #if SDL_VIDEO_OPENGL_GLX | ||
467 | if ( this->gl_config.driver_loaded ) { | ||
468 | |||
469 | GL_UnloadObject(this->gl_config.dll_handle); | ||
470 | |||
471 | this->gl_data->glXGetProcAddress = NULL; | ||
472 | this->gl_data->glXChooseVisual = NULL; | ||
473 | this->gl_data->glXCreateContext = NULL; | ||
474 | this->gl_data->glXDestroyContext = NULL; | ||
475 | this->gl_data->glXMakeCurrent = NULL; | ||
476 | this->gl_data->glXSwapBuffers = NULL; | ||
477 | this->gl_data->glXSwapIntervalSGI = NULL; | ||
478 | this->gl_data->glXSwapIntervalMESA = NULL; | ||
479 | this->gl_data->glXSwapIntervalEXT = NULL; | ||
480 | |||
481 | this->gl_config.dll_handle = NULL; | ||
482 | this->gl_config.driver_loaded = 0; | ||
483 | } | ||
484 | #endif | ||
485 | } | ||
486 | |||
487 | #if SDL_VIDEO_OPENGL_GLX | ||
488 | |||
489 | /* Passing a NULL path means load pointers from the application */ | ||
490 | int X11_GL_LoadLibrary(_THIS, const char* path) | ||
491 | { | ||
492 | void* handle = NULL; | ||
493 | |||
494 | if ( gl_active ) { | ||
495 | SDL_SetError("OpenGL context already created"); | ||
496 | return -1; | ||
497 | } | ||
498 | |||
499 | if ( path == NULL ) { | ||
500 | path = SDL_getenv("SDL_VIDEO_GL_DRIVER"); | ||
501 | if ( path == NULL ) { | ||
502 | path = DEFAULT_OPENGL; | ||
503 | } | ||
504 | } | ||
505 | |||
506 | handle = GL_LoadObject(path); | ||
507 | if ( handle == NULL ) { | ||
508 | #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN) | ||
509 | SDL_SetError("Failed loading %s", path); | ||
510 | #else | ||
511 | /* SDL_LoadObject() will call SDL_SetError() for us. */ | ||
512 | #endif | ||
513 | return -1; | ||
514 | } | ||
515 | |||
516 | /* Unload the old driver and reset the pointers */ | ||
517 | X11_GL_UnloadLibrary(this); | ||
518 | |||
519 | /* Save the handle for X11_GL_GetProcAddress() */ | ||
520 | this->gl_config.dll_handle = handle; | ||
521 | |||
522 | /* Load new function pointers */ | ||
523 | this->gl_data->glXGetProcAddress = | ||
524 | (void *(*)(const GLubyte *)) GL_LoadFunction(handle, "glXGetProcAddressARB"); | ||
525 | this->gl_data->glXChooseVisual = | ||
526 | (XVisualInfo *(*)(Display *, int, int *)) X11_GL_GetProcAddress(this, "glXChooseVisual"); | ||
527 | this->gl_data->glXCreateContext = | ||
528 | (GLXContext (*)(Display *, XVisualInfo *, GLXContext, int)) X11_GL_GetProcAddress(this, "glXCreateContext"); | ||
529 | this->gl_data->glXDestroyContext = | ||
530 | (void (*)(Display *, GLXContext)) X11_GL_GetProcAddress(this, "glXDestroyContext"); | ||
531 | this->gl_data->glXMakeCurrent = | ||
532 | (int (*)(Display *, GLXDrawable, GLXContext)) X11_GL_GetProcAddress(this, "glXMakeCurrent"); | ||
533 | this->gl_data->glXSwapBuffers = | ||
534 | (void (*)(Display *, GLXDrawable)) X11_GL_GetProcAddress(this, "glXSwapBuffers"); | ||
535 | this->gl_data->glXGetConfig = | ||
536 | (int (*)(Display *, XVisualInfo *, int, int *)) X11_GL_GetProcAddress(this, "glXGetConfig"); | ||
537 | this->gl_data->glXQueryExtensionsString = | ||
538 | (const char *(*)(Display *, int)) X11_GL_GetProcAddress(this, "glXQueryExtensionsString"); | ||
539 | this->gl_data->glXSwapIntervalSGI = | ||
540 | (int (*)(int)) X11_GL_GetProcAddress(this, "glXSwapIntervalSGI"); | ||
541 | this->gl_data->glXSwapIntervalMESA = | ||
542 | (GLint (*)(unsigned)) X11_GL_GetProcAddress(this, "glXSwapIntervalMESA"); | ||
543 | this->gl_data->glXSwapIntervalEXT = | ||
544 | (int (*)(Display*,GLXDrawable,int)) X11_GL_GetProcAddress(this, "glXSwapIntervalEXT"); | ||
545 | |||
546 | if ( (this->gl_data->glXChooseVisual == NULL) || | ||
547 | (this->gl_data->glXCreateContext == NULL) || | ||
548 | (this->gl_data->glXDestroyContext == NULL) || | ||
549 | (this->gl_data->glXMakeCurrent == NULL) || | ||
550 | (this->gl_data->glXSwapBuffers == NULL) || | ||
551 | (this->gl_data->glXGetConfig == NULL) || | ||
552 | (this->gl_data->glXQueryExtensionsString == NULL)) { | ||
553 | GL_UnloadObject(this->gl_config.dll_handle); | ||
554 | this->gl_config.dll_handle = NULL; | ||
555 | SDL_SetError("Could not retrieve OpenGL functions"); | ||
556 | return -1; | ||
557 | } | ||
558 | |||
559 | this->gl_config.driver_loaded = 1; | ||
560 | if ( path ) { | ||
561 | SDL_strlcpy(this->gl_config.driver_path, path, | ||
562 | SDL_arraysize(this->gl_config.driver_path)); | ||
563 | } else { | ||
564 | *this->gl_config.driver_path = '\0'; | ||
565 | } | ||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | void *X11_GL_GetProcAddress(_THIS, const char* proc) | ||
570 | { | ||
571 | if ( this->gl_data->glXGetProcAddress ) { | ||
572 | return this->gl_data->glXGetProcAddress((const GLubyte *)proc); | ||
573 | } | ||
574 | return GL_LoadFunction(this->gl_config.dll_handle, proc); | ||
575 | } | ||
576 | |||
577 | #endif /* SDL_VIDEO_OPENGL_GLX */ | ||