00001
00005 #include "alleggl.h"
00006 #include "allglint.h"
00007 #include <string.h>
00008 #ifdef ALLEGRO_MACOSX
00009 #include <OpenGL/glu.h>
00010 #else
00011 #include <GL/glu.h>
00012 #endif
00013
00014 #include <allegro/internal/aintern.h>
00015
00016
00017
00018 #define AGL_API(type, name, args) AGL_##name##_t name;
00019 typedef struct AGL_EXT {
00020 # include "allegrogl/GLext/gl_ext_api.h"
00021 #ifdef ALLEGRO_WINDOWS
00022 # include "allegrogl/GLext/wgl_ext_api.h"
00023 #elif defined ALLEGRO_UNIX
00024 # include "allegrogl/GLext/glx_ext_api.h"
00025 #endif
00026 } AGL_EXT;
00027 #undef AGL_API
00028
00029
00030
00031 struct allegro_gl_info allegro_gl_info;
00032
00033
00034
00048 AGL_EXTENSION_LIST_GL allegro_gl_extensions_GL;
00049
00050
00051
00057 #ifdef ALLEGRO_UNIX
00058 AGL_EXTENSION_LIST_GLX allegro_gl_extensions_GLX;
00059 #endif
00060
00061
00062
00068 #ifdef ALLEGRO_WINDOWS
00069 AGL_EXTENSION_LIST_WGL allegro_gl_extensions_WGL;
00070 #endif
00071
00072
00073
00074
00075 AGL_EXT *agl_extension_table = NULL;
00076
00077
00078 #ifdef ALLEGROGL_GENERIC_DRIVER
00079 #include "GL/amesa.h"
00080 #endif
00081
00082
00083 #ifdef ALLEGROGL_HAVE_DYNAMIC_LINK
00084 #include <dlfcn.h>
00085
00086
00087 static void* __agl_handle = NULL;
00088
00089 typedef void* (*GLXGETPROCADDRESSARBPROC) (const GLubyte*);
00090 static GLXGETPROCADDRESSARBPROC aglXGetProcAddress;
00091 #else
00092
00093 #ifdef ALLEGROGL_GLXGETPROCADDRESSARB
00094 #define aglXGetProcAddress glXGetProcAddressARB
00095 #else
00096 #define aglXGetProcAddress glXGetProcAddress
00097 #endif
00098 #endif
00099
00100
00101 #ifdef ALLEGRO_MACOSX
00102 #undef TRUE
00103 #undef FALSE
00104 #include <Carbon/Carbon.h>
00105 #undef TRUE
00106 #undef FALSE
00107 #define TRUE -1
00108 #define FALSE 0
00109
00110 static CFBundleRef opengl_bundle_ref;
00111 #endif
00112
00113
00114
00115
00116 #define AGL_API(type, name, args) AGL_##name##_t __agl##name = NULL;
00117 # include "allegrogl/GLext/gl_ext_api.h"
00118 #undef AGL_API
00119 #ifdef ALLEGRO_WINDOWS
00120 #define AGL_API(type, name, args) AGL_##name##_t __awgl##name = NULL;
00121 # include "allegrogl/GLext/wgl_ext_api.h"
00122 #undef AGL_API
00123 #elif defined ALLEGRO_UNIX
00124 #define AGL_API(type, name, args) AGL_##name##_t __aglX##name = NULL;
00125 # include "allegrogl/GLext/glx_ext_api.h"
00126 #undef AGL_API
00127 #endif
00128
00129
00130
00131
00132 AGL_EXT* __allegro_gl_create_extensions() {
00133
00134 AGL_EXT *ret = malloc(sizeof(AGL_EXT));
00135
00136 if (!ret) {
00137 return NULL;
00138 }
00139
00140 memset(ret, 0, sizeof(AGL_EXT));
00141
00142 return ret;
00143 }
00144
00145
00146
00147
00148
00149
00150 void __allegro_gl_load_extensions(AGL_EXT *ext) {
00151
00152 #ifdef ALLEGRO_MACOSX
00153 CFStringRef function;
00154 #endif
00155
00156 if (!ext) {
00157 return;
00158 }
00159 #ifdef ALLEGRO_UNIX
00160 if (!aglXGetProcAddress) {
00161 return;
00162 }
00163 #endif
00164
00165 # ifdef ALLEGRO_WINDOWS
00166 # define AGL_API(type, name, args) \
00167 ext->name = (AGL_##name##_t)wglGetProcAddress("gl" #name); \
00168 if (ext->name) { AGL_LOG(2,"gl" #name " successfully loaded\n"); }
00169 # include "allegrogl/GLext/gl_ext_api.h"
00170 # undef AGL_API
00171 # define AGL_API(type, name, args) \
00172 ext->name = (AGL_##name##_t)wglGetProcAddress("wgl" #name); \
00173 if (ext->name) { AGL_LOG(2,"wgl" #name " successfully loaded\n"); }
00174 # include "allegrogl/GLext/wgl_ext_api.h"
00175 # undef AGL_API
00176 # elif defined ALLEGRO_UNIX
00177 # define AGL_API(type, name, args) \
00178 ext->name = (AGL_##name##_t)aglXGetProcAddress("gl" #name); \
00179 if (ext->name) { AGL_LOG(2,"gl" #name " successfully loaded\n"); }
00180 # include "allegrogl/GLext/gl_ext_api.h"
00181 # undef AGL_API
00182 # define AGL_API(type, name, args) \
00183 ext->name = (AGL_##name##_t)aglXGetProcAddress("glX" #name); \
00184 if (ext->name) { AGL_LOG(2,"glX" #name " successfully loaded\n"); }
00185 # include "allegrogl/GLext/glx_ext_api.h"
00186 # undef AGL_API
00187 # elif defined ALLEGRO_MACOSX
00188 # define AGL_API(type, name, args) \
00189 function = CFStringCreateWithCString(kCFAllocatorDefault, "gl" #name, \
00190 kCFStringEncodingASCII); \
00191 if (function) { \
00192 ext->name = (AGL_##name##_t)CFBundleGetFunctionPointerForName( \
00193 opengl_bundle_ref, function); \
00194 CFRelease(function); \
00195 } \
00196 if (ext->name) { AGL_LOG(2,"gl" #name " successfully loaded\n"); }
00197 # include "allegrogl/GLext/gl_ext_api.h"
00198 # undef AGL_API
00199 # endif
00200 }
00201
00202
00203
00204
00205
00206
00207 void __allegro_gl_set_extensions(AGL_EXT *ext) {
00208
00209 if (!ext) {
00210 return;
00211 }
00212
00213 #define AGL_API(type, name, args) __agl##name = ext->name;
00214 # include "allegrogl/GLext/gl_ext_api.h"
00215 #undef AGL_API
00216 #ifdef ALLEGRO_WINDOWS
00217 #define AGL_API(type, name, args) __awgl##name = ext->name;
00218 # include "allegrogl/GLext/wgl_ext_api.h"
00219 #undef AGL_API
00220 #elif defined ALLEGRO_UNIX
00221 #define AGL_API(type, name, args) __aglX##name = ext->name;
00222 # include "allegrogl/GLext/glx_ext_api.h"
00223 #undef AGL_API
00224 #endif
00225 }
00226
00227
00228
00229
00230 void __allegro_gl_destroy_extensions(AGL_EXT *ext) {
00231
00232 if (ext) {
00233 if (ext == agl_extension_table) {
00234 agl_extension_table = NULL;
00235 }
00236 free(ext);
00237 }
00238 }
00239
00240
00241
00242
00243
00244
00245
00246 int __allegro_gl_look_for_an_extension(AL_CONST char *name,
00247 AL_CONST GLubyte * extensions)
00248 {
00249 AL_CONST GLubyte *start;
00250 GLubyte *where, *terminator;
00251
00252
00253 where = (GLubyte *) strchr(name, ' ');
00254 if (where || *name == '\0')
00255 return FALSE;
00256
00257
00258
00259 start = extensions;
00260 for (;;) {
00261 where = (GLubyte *) strstr((AL_CONST char *) start, name);
00262 if (!where)
00263 break;
00264 terminator = where + strlen(name);
00265 if (where == start || *(where - 1) == ' ')
00266 if (*terminator == ' ' || *terminator == '\0')
00267 return TRUE;
00268 start = terminator;
00269 }
00270 return FALSE;
00271 }
00272
00273
00274
00275 #ifdef ALLEGRO_WINDOWS
00276 static AGL_GetExtensionsStringARB_t __wglGetExtensionsStringARB = NULL;
00277 static HDC __hdc = NULL;
00278 #elif defined ALLEGRO_UNIX
00279 #include <xalleg.h>
00280 #endif
00281
00282
00283
00299 int allegro_gl_is_extension_supported(AL_CONST char *extension)
00300 {
00301 int ret;
00302
00303 if (!__allegro_gl_valid_context)
00304 return FALSE;
00305
00306 if (!glGetString(GL_EXTENSIONS))
00307 return FALSE;
00308
00309 ret = __allegro_gl_look_for_an_extension(extension,
00310 glGetString(GL_EXTENSIONS));
00311
00312 #ifdef ALLEGRO_WINDOWS
00313 if (!ret && strncmp(extension, "WGL", 3) == 0) {
00314 if (!__wglGetExtensionsStringARB || __hdc != __allegro_gl_hdc) {
00315 __wglGetExtensionsStringARB = (AGL_GetExtensionsStringARB_t)
00316 wglGetProcAddress("wglGetExtensionsStringARB");
00317 __hdc = __allegro_gl_hdc;
00318 }
00319 if (__wglGetExtensionsStringARB) {
00320 ret = __allegro_gl_look_for_an_extension(extension,
00321 __wglGetExtensionsStringARB(__allegro_gl_hdc));
00322 }
00323 }
00324 #elif defined ALLEGRO_UNIX
00325 if (!ret && strncmp(extension, "GLX", 3) == 0) {
00326 ret = __allegro_gl_look_for_an_extension(extension,
00327 glXQueryExtensionsString(_xwin.display, _xwin.screen));
00328 }
00329 #endif
00330
00331 return ret;
00332 }
00333
00334
00335
00336
00362 void *allegro_gl_get_proc_address(AL_CONST char *name)
00363 {
00364 void *symbol = NULL;
00365 #ifdef ALLEGRO_MACOSX
00366 CFStringRef function;
00367 #endif
00368
00369 if (!__allegro_gl_valid_context)
00370 return NULL;
00371
00372 #ifdef ALLEGROGL_GENERIC_DRIVER
00373
00374
00375
00376 symbol = AMesaGetProcAddress(name);
00377
00378 #elif defined ALLEGRO_WINDOWS
00379
00380
00381
00382
00383
00384 symbol = wglGetProcAddress(name);
00385 #elif defined ALLEGROGL_UNIX
00386 if (aglXGetProcAddress) {
00387
00388
00389
00390
00391 symbol = aglXGetProcAddress(name);
00392 }
00393 #elif defined ALLEGROGL_HAVE_DYNAMIC_LINK
00394 else {
00395
00396
00397
00398 if (__agl_handle) {
00399 symbol = dlsym(__agl_handle, name);
00400 }
00401 }
00402 #elif defined ALLEGRO_MACOSX
00403 function = CFStringCreateWithCString(kCFAllocatorDefault, name,
00404 kCFStringEncodingASCII);
00405 if (function) {
00406 symbol = CFBundleGetFunctionPointerForName(opengl_bundle_ref, function);
00407 CFRelease(function);
00408 }
00409 #else
00410
00411
00412
00413
00414 #endif
00415
00416 if (!symbol) {
00417
00418 #if defined ALLEGROGL_HAVE_DYNAMIC_LINK
00419 if (!aglXGetProcAddress) {
00420 TRACE("** Warning ** get_proc_address: libdl::dlsym: %s\n",
00421 dlerror());
00422 }
00423 #endif
00424
00425 TRACE("** Warning ** get_proc_address : Unable to load symbol %s\n",
00426 name);
00427 }
00428 else {
00429 TRACE("* Note * get_proc_address : Symbol %s successfully loaded\n",
00430 name);
00431 }
00432 return symbol;
00433 }
00434
00435
00436
00437
00438
00439 void __fill_in_info_struct(const char *renderer, struct allegro_gl_info *info) {
00440
00441
00442 if (strstr(renderer, "3Dfx/Voodoo")) {
00443 info->is_voodoo = 1;
00444 }
00445 else if (strstr(renderer, "Matrox G200")) {
00446 info->is_matrox_g200 = 1;
00447 }
00448 else if (strstr(renderer, "RagePRO")) {
00449 info->is_ati_rage_pro = 1;
00450 }
00451 else if (strstr(renderer, "RADEON 7000")) {
00452 info->is_ati_radeon_7000 = 1;
00453 }
00454 else if (strstr(renderer, "Mesa DRI R200")) {
00455 info->is_ati_r200_chip = 1;
00456 }
00457
00458 if ((strncmp(renderer, "3Dfx/Voodoo3 ", 13) == 0)
00459 || (strncmp(renderer, "3Dfx/Voodoo2 ", 13) == 0)
00460 || (strncmp(renderer, "3Dfx/Voodoo ", 12) == 0)) {
00461 info->is_voodoo3_and_under = 1;
00462 }
00463
00464
00465 info->version = allegro_gl_opengl_version();
00466
00467 return;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476 void __allegro_gl_manage_extensions(void)
00477 {
00478 AL_CONST GLubyte *buf;
00479 int i;
00480
00481 #ifdef ALLEGRO_MACOSX
00482 CFURLRef bundle_url;
00483 #endif
00484
00485
00486 #if LOGLEVEL >= 1
00487 AGL_LOG(1, "OpenGL Extensions:\n");
00488 __allegro_gl_print_extensions((AL_CONST char*)
00489 glGetString(GL_EXTENSIONS));
00490 #endif
00491
00492
00493 buf = gluGetString(GLU_VERSION);
00494 TRACE("GLU Version : %s\n\n", buf);
00495
00496 #ifdef ALLEGROGL_HAVE_DYNAMIC_LINK
00497
00498 __agl_handle = dlopen("libGL.so", RTLD_LAZY);
00499 if (__agl_handle) {
00500 aglXGetProcAddress = (GLXGETPROCADDRESSARBPROC) dlsym(__agl_handle,
00501 "glXGetProcAddressARB");
00502 if (!aglXGetProcAddress) {
00503 aglXGetProcAddress = (GLXGETPROCADDRESSARBPROC) dlsym(__agl_handle,
00504 "glXGetProcAddress");
00505 }
00506 }
00507 else {
00508 TRACE("** Warning ** Failed to dlopen libGL.so : %s\n", dlerror());
00509 }
00510 TRACE("glXGetProcAddress Extension: %s\n",
00511 aglXGetProcAddress ? "Supported" : "Unsupported");
00512 #elif defined ALLEGRO_UNIX
00513 #ifdef ALLEGROGL_GLXGETPROCADDRESSARB
00514 TRACE("glXGetProcAddressARB Extension: supported\n");
00515 #else
00516 TRACE("glXGetProcAddress Extension: supported\n");
00517 #endif
00518 #endif
00519
00520 #ifdef ALLEGRO_MACOSX
00521 bundle_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
00522 CFSTR("/System/Library/Frameworks/OpenGL.framework"),
00523 kCFURLPOSIXPathStyle, true);
00524 opengl_bundle_ref = CFBundleCreate(kCFAllocatorDefault, bundle_url);
00525 CFRelease(bundle_url);
00526 #endif
00527
00528 __fill_in_info_struct(glGetString(GL_RENDERER), &allegro_gl_info);
00529
00530
00531 agl_extension_table = __allegro_gl_create_extensions();
00532 __allegro_gl_load_extensions(agl_extension_table);
00533 __allegro_gl_set_extensions(agl_extension_table);
00534
00535 for (i = 0; i < 5; i++) {
00536 __allegro_gl_texture_read_format[i] = -1;
00537 __allegro_gl_texture_components[i] = GL_RGB;
00538 }
00539 __allegro_gl_texture_read_format[3] = GL_UNSIGNED_BYTE;
00540 __allegro_gl_texture_read_format[4] = GL_UNSIGNED_BYTE;
00541 __allegro_gl_texture_components[4] = GL_RGBA;
00542
00543
00544
00545 # define AGL_EXT(name, ver) { \
00546 allegro_gl_extensions_GL.name = \
00547 allegro_gl_is_extension_supported("GL_" #name) \
00548 || (allegro_gl_info.version >= ver && ver > 0); \
00549 }
00550 # include "allegrogl/GLext/gl_ext_list.h"
00551 # undef AGL_EXT
00552
00553 #ifdef ALLEGRO_UNIX
00554 # define AGL_EXT(name, ver) { \
00555 allegro_gl_extensions_GLX.name = \
00556 allegro_gl_is_extension_supported("GLX_" #name) \
00557 || (allegro_gl_info.version >= ver && ver > 0); \
00558 }
00559 # include "allegrogl/GLext/glx_ext_list.h"
00560 # undef AGL_EXT
00561 #elif defined ALLEGRO_WINDOWS
00562 # define AGL_EXT(name, ver) { \
00563 allegro_gl_extensions_WGL.name = \
00564 allegro_gl_is_extension_supported("WGL_" #name) \
00565 || (allegro_gl_info.version >= ver && ver > 0); \
00566 }
00567 # include "allegrogl/GLext/wgl_ext_list.h"
00568 # undef AGL_EXT
00569 #endif
00570
00571
00572 if (allegro_gl_extensions_GL.ARB_multitexture) {
00573 glGetIntegerv(GL_MAX_TEXTURE_UNITS,
00574 (GLint*)&allegro_gl_info.num_texture_units);
00575 }
00576 else {
00577 allegro_gl_info.num_texture_units = 1;
00578 }
00579
00580
00581 glGetIntegerv(GL_MAX_TEXTURE_SIZE,
00582 (GLint*)&allegro_gl_info.max_texture_size);
00583
00584
00585
00586
00587 allegro_gl_extensions_GL.EXT_packed_pixels &= !allegro_gl_info.is_voodoo;
00588
00589
00590 if (allegro_gl_extensions_GL.EXT_packed_pixels) {
00591
00592 AGL_LOG(1, "Packed Pixels formats available\n");
00593
00594
00595
00596 __allegro_gl_texture_read_format[0] = GL_UNSIGNED_BYTE_3_3_2;
00597 __allegro_gl_texture_read_format[1] = GL_UNSIGNED_SHORT_5_5_5_1;
00598 __allegro_gl_texture_read_format[2] = GL_UNSIGNED_SHORT_5_6_5;
00599 }
00600
00601 TRACE("\n");
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611 void __allegro_gl_print_extensions(AL_CONST char * extension)
00612 {
00613 char buf[80];
00614 char* start;
00615
00616 while (*extension != '\0') {
00617 start = buf;
00618 strncpy(buf, extension, 80);
00619 while ((*start != ' ') && (*start != '\0')) {
00620 extension++;
00621 start++;
00622 }
00623 *start = '\0';
00624 extension ++;
00625 TRACE("\t%s\n", buf);
00626 }
00627 TRACE("\n");
00628 }
00629
00630
00631
00632 void __allegro_gl_unmanage_extensions() {
00633 __allegro_gl_destroy_extensions(agl_extension_table);
00634 #ifdef ALLEGRO_MACOSX
00635 CFRelease(opengl_bundle_ref);
00636 #endif
00637 #ifdef ALLEGROGL_HAVE_DYNAMIC_LINK
00638 dlclose(__agl_handle);
00639 #endif
00640 }
00641