alleggl.c

Go to the documentation of this file.
00001 /* This code is (C) AllegroGL contributors, and double licensed under
00002  * the GPL and zlib licenses. See gpl.txt or zlib.txt for details.
00003  */
00011 #include <string.h>
00012 #include <stdlib.h>
00013 
00014 #include "alleggl.h"
00015 #include "allglint.h"
00016 
00017 #include <allegro/internal/aintern.h>
00018 #ifdef ALLEGRO_MACOSX
00019 #include <OpenGL/glu.h>
00020 #else
00021 #include <GL/glu.h>
00022 #endif
00023 
00024 #define PREFIX_I                "agl INFO: "
00025 #define PREFIX_E                "agl ERROR: "
00026 #define PREFIX_L                "agl LOG: "
00027 
00028 
00029 /* Structs containing the current driver state */
00030 struct allegro_gl_driver *__allegro_gl_driver = NULL;
00031 struct allegro_gl_display_info allegro_gl_display_info;
00032 
00033 /* Settings required/suggested */
00034 int __allegro_gl_required_settings, __allegro_gl_suggested_settings;
00035 
00036 /* Valid context state */
00037 int __allegro_gl_valid_context = 0;
00038 
00039 
00040 /* Operation to enable while blitting. */
00041 int __allegro_gl_blit_operation;
00042 
00043 
00044 char allegro_gl_error[AGL_ERROR_SIZE] = EMPTY_STRING;
00045 
00046 BLIT_BETWEEN_FORMATS_FUNC __blit_between_formats8;
00047 BLIT_BETWEEN_FORMATS_FUNC __blit_between_formats15;
00048 BLIT_BETWEEN_FORMATS_FUNC __blit_between_formats16;
00049 BLIT_BETWEEN_FORMATS_FUNC __blit_between_formats24;
00050 BLIT_BETWEEN_FORMATS_FUNC __blit_between_formats32;
00051 
00052 
00053 
00062 BITMAP *allegro_gl_screen;
00063 
00064 
00065 
00066 /* Allegro GFX_DRIVER list handling */
00067 static _DRIVER_INFO our_driver_list[] = {
00068 #ifdef GFX_OPENGL_WINDOWED
00069     {GFX_OPENGL_WINDOWED, &gfx_allegro_gl_windowed, FALSE},
00070 #endif
00071 #ifdef GFX_OPENGL_FULLSCREEN
00072     {GFX_OPENGL_FULLSCREEN, &gfx_allegro_gl_fullscreen, FALSE},
00073 #endif
00074     {GFX_OPENGL, &gfx_allegro_gl_default, FALSE},
00075     {0, NULL, FALSE}
00076 };
00077 
00078 
00079 
00080 static _DRIVER_INFO *our_gfx_drivers(void)
00081 {
00082     return our_driver_list;
00083 }
00084 
00085 
00086 
00087 _DRIVER_INFO *(*saved_gfx_drivers) (void) = NULL;
00088 
00089 
00090 
00091 static _DRIVER_INFO *list_saved_gfx_drivers(void)
00092 {
00093     return _gfx_driver_list;
00094 }
00095 
00096 
00097 
00098 static BITMAP *allegro_gl_default_gfx_init(int w, int h, int vw, int vh, int depth);
00099 
00100 
00101 
00102 GFX_DRIVER gfx_allegro_gl_default =
00103 {
00104    GFX_OPENGL,
00105    EMPTY_STRING,
00106    EMPTY_STRING,
00107    "AllegroGL Default Driver",
00108    allegro_gl_default_gfx_init,
00109    NULL,
00110    NULL,
00111    NULL,               //_xwin_vsync,
00112    NULL,
00113    NULL, NULL, NULL,
00114    NULL,        /* create_video_bitmap */
00115    NULL,
00116    NULL, NULL,  /* No show/request video bitmaps */
00117    NULL, NULL,
00118    NULL, NULL, NULL, NULL,
00119    NULL,
00120    NULL, NULL,
00121    NULL,        /* set_blender_mode */
00122    NULL,        /* No fetch_mode_list */
00123    0, 0,
00124    0,
00125    0, 0,
00126    0,
00127    0,
00128    FALSE        /* Windowed mode */
00129 };
00130 
00131 
00132 
00176 /* void allegro_gl_clear_settings(void) */
00193 void allegro_gl_clear_settings(void)
00194 {
00195     memset(&allegro_gl_display_info, 0, sizeof allegro_gl_display_info);
00196 
00197     __allegro_gl_required_settings = __allegro_gl_suggested_settings = 0;
00198     
00199     /* Pick sensible defaults */
00200     allegro_gl_display_info.fullscreen = 1;
00201     allegro_gl_display_info.rmethod = 1;
00202     allegro_gl_display_info.doublebuffered = 1;
00203     allegro_gl_display_info.vidmem_policy = AGL_KEEP;
00204     __allegro_gl_suggested_settings =
00205                            AGL_FULLSCREEN | AGL_RENDERMETHOD | AGL_DOUBLEBUFFER;
00206 }
00207 
00208 
00209 
00210 /* void allegro_gl_set(int option, int value) */
00274 void allegro_gl_set(int option, int value)
00275 {
00276     switch (option) {
00277             /* Options stating importance of other options */
00278         case AGL_REQUIRE:
00279             __allegro_gl_required_settings |= value;
00280             __allegro_gl_suggested_settings &= ~value;
00281             break;
00282         case AGL_SUGGEST:
00283             __allegro_gl_suggested_settings |= value;
00284             __allegro_gl_required_settings &= ~value;
00285             break;
00286         case AGL_DONTCARE:
00287             __allegro_gl_required_settings &= ~value;
00288             __allegro_gl_suggested_settings &= ~value;
00289             break;
00290 
00291             /* Options configuring the mode set */
00292         case AGL_ALLEGRO_FORMAT:
00293             allegro_gl_display_info.allegro_format = value;
00294             break;
00295         case AGL_RED_DEPTH:
00296             allegro_gl_display_info.pixel_size.rgba.r = value;
00297             break;
00298         case AGL_GREEN_DEPTH:
00299             allegro_gl_display_info.pixel_size.rgba.g = value;
00300             break;
00301         case AGL_BLUE_DEPTH:
00302             allegro_gl_display_info.pixel_size.rgba.b = value;
00303             break;
00304         case AGL_ALPHA_DEPTH:
00305             allegro_gl_display_info.pixel_size.rgba.a = value;
00306             break;
00307         case AGL_COLOR_DEPTH:
00308             switch (value) {
00309                 case 8:
00310                     allegro_gl_set(AGL_RED_DEPTH, 3);
00311                     allegro_gl_set(AGL_GREEN_DEPTH, 3);
00312                     allegro_gl_set(AGL_BLUE_DEPTH, 2);
00313                     allegro_gl_set(AGL_ALPHA_DEPTH, 0);
00314                     break;
00315                 case 15:
00316                     allegro_gl_set(AGL_RED_DEPTH, 5);
00317                     allegro_gl_set(AGL_GREEN_DEPTH, 5);
00318                     allegro_gl_set(AGL_BLUE_DEPTH, 5);
00319                     allegro_gl_set(AGL_ALPHA_DEPTH, 1);
00320                     break;
00321                 case 16:
00322                     allegro_gl_set(AGL_RED_DEPTH, 5);
00323                     allegro_gl_set(AGL_GREEN_DEPTH, 6);
00324                     allegro_gl_set(AGL_BLUE_DEPTH, 5);
00325                     allegro_gl_set(AGL_ALPHA_DEPTH, 0);
00326                     break;
00327                 case 24:
00328                 case 32:
00329                     allegro_gl_set(AGL_RED_DEPTH, 8);
00330                     allegro_gl_set(AGL_GREEN_DEPTH, 8);
00331                     allegro_gl_set(AGL_BLUE_DEPTH, 8);
00332                     allegro_gl_set(AGL_ALPHA_DEPTH, value-24);
00333                     break;
00334             }
00335             allegro_gl_display_info.colour_depth = value;
00336             break;
00337         case AGL_ACC_RED_DEPTH:
00338             allegro_gl_display_info.accum_size.rgba.r = value;
00339             break;
00340         case AGL_ACC_GREEN_DEPTH:
00341             allegro_gl_display_info.accum_size.rgba.g = value;
00342             break;
00343         case AGL_ACC_BLUE_DEPTH:
00344             allegro_gl_display_info.accum_size.rgba.b = value;
00345             break;
00346         case AGL_ACC_ALPHA_DEPTH:
00347             allegro_gl_display_info.accum_size.rgba.a = value;
00348             break;
00349 
00350         case AGL_DOUBLEBUFFER:
00351             allegro_gl_display_info.doublebuffered = value;
00352             break;
00353         case AGL_STEREO:
00354             allegro_gl_display_info.stereo = value;
00355             break;
00356         case AGL_AUX_BUFFERS:
00357             allegro_gl_display_info.aux_buffers = value;
00358             break;
00359         case AGL_Z_DEPTH:
00360             allegro_gl_display_info.depth_size = value;
00361             break;
00362         case AGL_STENCIL_DEPTH:
00363             allegro_gl_display_info.stencil_size = value;
00364             break;
00365 
00366         case AGL_WINDOW_X:
00367             allegro_gl_display_info.x = value;
00368             break;
00369         case AGL_WINDOW_Y:
00370             allegro_gl_display_info.y = value;
00371             break;
00372 
00373         case AGL_RENDERMETHOD:
00374             allegro_gl_display_info.rmethod = value;
00375             break;
00376 
00377         case AGL_FULLSCREEN:
00378             allegro_gl_display_info.fullscreen = value;
00379             break;
00380 
00381         case AGL_WINDOWED:
00382             allegro_gl_display_info.fullscreen = !value;
00383             break;
00384         case AGL_VIDEO_MEMORY_POLICY:
00385             if ((value == AGL_KEEP) || (value == AGL_RELEASE))
00386                 allegro_gl_display_info.vidmem_policy = value;
00387             break;
00388         case AGL_SAMPLE_BUFFERS:
00389             allegro_gl_display_info.sample_buffers = value;
00390             break;
00391         case AGL_SAMPLES:
00392             allegro_gl_display_info.samples = value;
00393             break;
00394         case AGL_FLOAT_COLOR:
00395             allegro_gl_display_info.float_color = value;
00396             break;
00397         case AGL_FLOAT_Z:
00398             allegro_gl_display_info.float_depth = value;
00399             break;
00400     }
00401 }
00402 
00403 
00404 
00421 int allegro_gl_get(int option)
00422 {
00423     switch (option) {
00424             /* Options stating importance of other options */
00425         case AGL_REQUIRE:
00426             return __allegro_gl_required_settings;
00427         case AGL_SUGGEST:
00428             return __allegro_gl_suggested_settings;
00429         case AGL_DONTCARE:
00430             return ~0 & ~(__allegro_gl_required_settings |
00431                           __allegro_gl_suggested_settings);
00432 
00433             /* Options configuring the mode set */
00434         case AGL_ALLEGRO_FORMAT:
00435             return allegro_gl_display_info.allegro_format;
00436         case AGL_RED_DEPTH:
00437             return allegro_gl_display_info.pixel_size.rgba.r;
00438         case AGL_GREEN_DEPTH:
00439             return allegro_gl_display_info.pixel_size.rgba.g;
00440         case AGL_BLUE_DEPTH:
00441             return allegro_gl_display_info.pixel_size.rgba.b;
00442         case AGL_ALPHA_DEPTH:
00443             return allegro_gl_display_info.pixel_size.rgba.a;
00444         case AGL_COLOR_DEPTH:
00445             return allegro_gl_display_info.pixel_size.rgba.r
00446                 + allegro_gl_display_info.pixel_size.rgba.g
00447                 + allegro_gl_display_info.pixel_size.rgba.b
00448                 + allegro_gl_display_info.pixel_size.rgba.a;
00449         case AGL_ACC_RED_DEPTH:
00450             return allegro_gl_display_info.accum_size.rgba.r;
00451         case AGL_ACC_GREEN_DEPTH:
00452             return allegro_gl_display_info.accum_size.rgba.g;
00453         case AGL_ACC_BLUE_DEPTH:
00454             return allegro_gl_display_info.accum_size.rgba.b;
00455         case AGL_ACC_ALPHA_DEPTH:
00456             return allegro_gl_display_info.accum_size.rgba.a;
00457         case AGL_DOUBLEBUFFER:
00458             return allegro_gl_display_info.doublebuffered;
00459         case AGL_STEREO:
00460             return allegro_gl_display_info.stereo;
00461         case AGL_AUX_BUFFERS:
00462             return allegro_gl_display_info.aux_buffers;
00463         case AGL_Z_DEPTH:
00464             return allegro_gl_display_info.depth_size;
00465         case AGL_STENCIL_DEPTH:
00466             return allegro_gl_display_info.stencil_size;
00467         case AGL_WINDOW_X:
00468             return allegro_gl_display_info.x;
00469         case AGL_WINDOW_Y:
00470             return allegro_gl_display_info.y;
00471         case AGL_FULLSCREEN:
00472             return allegro_gl_display_info.fullscreen;
00473         case AGL_WINDOWED:
00474             return !allegro_gl_display_info.fullscreen;
00475         case AGL_VIDEO_MEMORY_POLICY:
00476             return allegro_gl_display_info.vidmem_policy;
00477         case AGL_SAMPLE_BUFFERS:
00478             return allegro_gl_display_info.sample_buffers;
00479         case AGL_SAMPLES:
00480             return allegro_gl_display_info.samples;
00481         case AGL_FLOAT_COLOR:
00482             return allegro_gl_display_info.float_color;
00483         case AGL_FLOAT_Z:
00484             return allegro_gl_display_info.float_depth;
00485     }
00486     return -1;
00487 }
00488 
00489 
00490 
00491 /* Builds a string corresponding to the options set in 'opt'
00492  * and writes in the config file
00493  */
00494 static void build_settings(int opt, char *section, char *name) {
00495     char buf[2048];
00496 
00497     usetc(buf, 0);
00498 
00499     if (opt & AGL_ALLEGRO_FORMAT)
00500         ustrcat(buf, "allegro_format ");
00501     if (opt & AGL_RED_DEPTH)
00502         ustrcat(buf, "red_depth ");
00503     if (opt & AGL_GREEN_DEPTH)
00504         ustrcat(buf, "green_depth ");
00505     if (opt & AGL_BLUE_DEPTH)
00506         ustrcat(buf, "blue_depth ");
00507     if (opt & AGL_ALPHA_DEPTH)
00508         ustrcat(buf, "alpha_depth ");
00509     if (opt & AGL_COLOR_DEPTH)
00510         ustrcat(buf, "color_depth ");
00511     if (opt & AGL_ACC_RED_DEPTH)
00512         ustrcat(buf, "accum_red_depth ");
00513     if (opt & AGL_ACC_GREEN_DEPTH)
00514         ustrcat(buf, "accum_green_depth ");
00515     if (opt & AGL_ACC_BLUE_DEPTH)
00516         ustrcat(buf, "accum_blue_depth ");
00517     if (opt & AGL_ACC_ALPHA_DEPTH)
00518         ustrcat(buf, "accum_alpha_depth ");
00519     if (opt & AGL_DOUBLEBUFFER)
00520         ustrcat(buf, "double_buffer ");
00521     if (opt & AGL_STEREO)
00522         ustrcat(buf, "stereo_display ");
00523     if (opt & AGL_AUX_BUFFERS)
00524         ustrcat(buf, "aux_buffers ");
00525     if (opt & AGL_Z_DEPTH)
00526         ustrcat(buf, "z_depth ");
00527     if (opt & AGL_STENCIL_DEPTH)
00528         ustrcat(buf, "stencil_depth ");
00529     if (opt & AGL_WINDOW_X)
00530         ustrcat(buf, "window_x ");
00531     if (opt & AGL_WINDOW_Y)
00532         ustrcat(buf, "window_y ");
00533     if (opt & AGL_FULLSCREEN)
00534         ustrcat(buf, "fullscreen ");
00535     if (opt & AGL_WINDOWED)
00536         ustrcat(buf, "windowed ");
00537     if (opt & AGL_VIDEO_MEMORY_POLICY)
00538         ustrcat(buf, "video_memory_policy ");
00539     if (opt & AGL_SAMPLE_BUFFERS)
00540         ustrcat(buf, "sample_buffers ");
00541     if (opt & AGL_SAMPLES)
00542         ustrcat(buf, "samples ");
00543     if (opt & AGL_FLOAT_COLOR)
00544         ustrcat(buf, "float_color ");
00545     if (opt & AGL_FLOAT_Z)
00546         ustrcat(buf, "float_depth ");
00547         
00548     set_config_string(section, name, buf);
00549 }
00550 
00551 
00552 
00553 /* void allegro_gl_save_settings() */
00560 void allegro_gl_save_settings() {
00561 
00562     char *section = "OpenGL";
00563     int save = allegro_gl_get(AGL_REQUIRE) | allegro_gl_get(AGL_SUGGEST);
00564     
00565     if (save & AGL_ALLEGRO_FORMAT)
00566         set_config_int(section, "allegro_format",
00567             allegro_gl_get(AGL_ALLEGRO_FORMAT));
00568     if (save & AGL_RED_DEPTH)
00569         set_config_int(section, "red_depth",
00570             allegro_gl_get(AGL_RED_DEPTH));
00571     if (save & AGL_GREEN_DEPTH)
00572         set_config_int(section, "green_depth",
00573             allegro_gl_get(AGL_GREEN_DEPTH));
00574     if (save & AGL_BLUE_DEPTH)
00575         set_config_int(section, "blue_depth",
00576             allegro_gl_get(AGL_BLUE_DEPTH));
00577     if (save & AGL_ALPHA_DEPTH)
00578         set_config_int(section, "alpha_depth",
00579             allegro_gl_get(AGL_ALPHA_DEPTH));
00580     if (save & AGL_COLOR_DEPTH)
00581         set_config_int(section, "color_depth",
00582             allegro_gl_get(AGL_COLOR_DEPTH));
00583     if (save & AGL_ACC_RED_DEPTH)
00584         set_config_int(section, "accum_red_depth",
00585             allegro_gl_get(AGL_ACC_RED_DEPTH));
00586     if (save & AGL_ACC_GREEN_DEPTH)
00587         set_config_int(section, "accum_green_depth",
00588             allegro_gl_get(AGL_ACC_GREEN_DEPTH));
00589     if (save & AGL_ACC_BLUE_DEPTH)
00590         set_config_int(section, "accum_blue_depth",
00591             allegro_gl_get(AGL_ACC_BLUE_DEPTH));
00592     if (save & AGL_ACC_ALPHA_DEPTH)
00593         set_config_int(section, "accum_alpha_depth",
00594             allegro_gl_get(AGL_ACC_ALPHA_DEPTH));
00595     if (save & AGL_DOUBLEBUFFER)
00596         set_config_int(section, "double_buffer",
00597             allegro_gl_get(AGL_DOUBLEBUFFER));
00598     if (save & AGL_STEREO)
00599         set_config_int(section, "stereo_display",
00600             allegro_gl_get(AGL_STEREO));
00601     if (save & AGL_AUX_BUFFERS)
00602         set_config_int(section, "aux_buffers",
00603             allegro_gl_get(AGL_AUX_BUFFERS));
00604     if (save & AGL_Z_DEPTH)
00605         set_config_int(section, "z_depth",
00606             allegro_gl_get(AGL_Z_DEPTH));
00607     if (save & AGL_STENCIL_DEPTH)
00608         set_config_int(section, "stencil_depth",
00609             allegro_gl_get(AGL_STENCIL_DEPTH));
00610     if (save & AGL_WINDOW_X)
00611         set_config_int(section, "window_x",
00612             allegro_gl_get(AGL_WINDOW_X));
00613     if (save & AGL_WINDOW_Y)
00614         set_config_int(section, "window_y",
00615             allegro_gl_get(AGL_WINDOW_Y));
00616     if (save & AGL_FULLSCREEN)
00617         set_config_int(section, "fullscreen",
00618             allegro_gl_get(AGL_FULLSCREEN));
00619     if (save & AGL_WINDOWED)
00620         set_config_int(section, "windowed",
00621             allegro_gl_get(AGL_WINDOWED));
00622     if (save & AGL_VIDEO_MEMORY_POLICY)
00623         set_config_int(section, "video_memory_policy",
00624             allegro_gl_get(AGL_VIDEO_MEMORY_POLICY));
00625     if (save & AGL_SAMPLE_BUFFERS)
00626         set_config_int(section, "sample_buffers",
00627                        allegro_gl_get(AGL_SAMPLE_BUFFERS));
00628     if (save & AGL_SAMPLES)
00629         set_config_int(section, "samples",
00630                        allegro_gl_get(AGL_SAMPLES));
00631     if (save & AGL_FLOAT_COLOR)
00632         set_config_int(section, "float_color",
00633                        allegro_gl_get(AGL_FLOAT_COLOR));
00634     if (save & AGL_FLOAT_Z)
00635         set_config_int(section, "float_depth",
00636                        allegro_gl_get(AGL_FLOAT_Z));
00637 
00638     if (save & AGL_REQUIRE)
00639         build_settings(allegro_gl_get(AGL_REQUIRE), section, "require");
00640     if (save & AGL_SUGGEST)
00641         build_settings(allegro_gl_get(AGL_SUGGEST), section, "suggest");
00642 }
00643 
00644 
00645 
00646 /* Parses an input string to read settings */
00647 static void agl_parse_section(int sec, char *section, char *name) {
00648     const char *end;
00649     char *buf;
00650     char *ptr;
00651     int strsize;
00652     int opt = 0;
00653 
00654     end = get_config_string(section, name, "");
00655     strsize = ustrsizez(end);
00656     
00657     buf = (char*)malloc(sizeof(char) * strsize);
00658     
00659     if (!buf) {
00660         TRACE(PREFIX_E "parse_section: Ran out of memory "
00661               "while trying to allocate %i bytes!",
00662               (int)sizeof(char) * strsize);
00663         return;
00664     }
00665 
00666     memcpy(buf, end, strsize);
00667     end = buf + strsize;
00668     ptr = buf;
00669 
00670     while (ptr < end) {
00671         char *s = ustrtok_r(ptr, " ;|+", &ptr);
00672         
00673         if (!ustrcmp(s, "allegro_format"))
00674             opt |= AGL_ALLEGRO_FORMAT;
00675         if (!ustrcmp(s, "red_depth"))
00676             opt |= AGL_RED_DEPTH;
00677         if (!ustrcmp(s, "green_depth"))
00678             opt |= AGL_GREEN_DEPTH;
00679         if (!ustrcmp(s, "blue_depth"))
00680             opt |= AGL_BLUE_DEPTH;
00681         if (!ustrcmp(s, "alpha_depth"))
00682             opt |= AGL_ALPHA_DEPTH;
00683         if (!ustrcmp(s, "color_depth"))
00684             opt |= AGL_COLOR_DEPTH;
00685         if (!ustrcmp(s, "accum_red_depth"))
00686             opt |= AGL_ACC_RED_DEPTH;
00687         if (!ustrcmp(s, "accum_green_depth"))
00688             opt |= AGL_ACC_GREEN_DEPTH;
00689         if (!ustrcmp(s, "accum_blue_depth"))
00690             opt |= AGL_ACC_BLUE_DEPTH;
00691         if (!ustrcmp(s, "accum_alpha_depth"))
00692             opt |= AGL_ACC_ALPHA_DEPTH;
00693         if (!ustrcmp(s, "double_buffer"))
00694             opt |= AGL_DOUBLEBUFFER;
00695         if (!ustrcmp(s, "stereo_display"))
00696             opt |= AGL_STEREO;
00697         if (!ustrcmp(s, "aux_buffers"))
00698             opt |= AGL_AUX_BUFFERS;
00699         if (!ustrcmp(s, "z_depth"))
00700             opt |= AGL_Z_DEPTH;
00701         if (!ustrcmp(s, "stencil_depth"))
00702             opt |= AGL_STENCIL_DEPTH;
00703         if (!ustrcmp(s, "window_x"))
00704             opt |= AGL_WINDOW_X;
00705         if (!ustrcmp(s, "window_y"))
00706             opt |= AGL_WINDOW_Y;
00707         if (!ustrcmp(s, "fullscreen"))
00708             opt |= AGL_FULLSCREEN;
00709         if (!ustrcmp(s, "windowed"))
00710             opt |= AGL_WINDOWED;
00711         if (!ustrcmp(s, "video_memory_policy"))
00712             opt |= AGL_VIDEO_MEMORY_POLICY;
00713         if (!ustrcmp(s, "sample_buffers"))
00714             opt |= AGL_SAMPLE_BUFFERS;
00715         if (!ustrcmp(s, "samples"))
00716             opt |= AGL_SAMPLES;
00717         if (!ustrcmp(s, "float_color"))
00718             opt |= AGL_FLOAT_COLOR;
00719         if (!ustrcmp(s, "float_depth"))
00720             opt |= AGL_FLOAT_Z;
00721     }
00722     
00723     free(buf);
00724     
00725     allegro_gl_set(sec, opt);
00726 }
00727 
00728 
00729 
00730 /* void allegro_gl_load_settings() */
00741 void allegro_gl_load_settings() {
00742 
00743     int set;
00744     char *section = "OpenGL";
00745     
00746     set = get_config_int(section, "allegro_format", -1);
00747     if (set != -1)
00748         allegro_gl_set(AGL_ALLEGRO_FORMAT, set);
00749     set = get_config_int(section, "red_depth", -1);
00750     if (set != -1)
00751         allegro_gl_set(AGL_RED_DEPTH, set);
00752     set = get_config_int(section, "green_depth", -1);
00753     if (set != -1)
00754         allegro_gl_set(AGL_GREEN_DEPTH, set);
00755     set = get_config_int(section, "blue_depth", -1);
00756     if (set != -1)
00757         allegro_gl_set(AGL_BLUE_DEPTH, set);
00758     set = get_config_int(section, "alpha_depth", -1);
00759     if (set != -1)
00760         allegro_gl_set(AGL_ALPHA_DEPTH, set);
00761     set = get_config_int(section, "color_depth", -1);
00762     if (set != -1)
00763         allegro_gl_set(AGL_COLOR_DEPTH, set);
00764     set = get_config_int(section, "accum_red_depth", -1);
00765     if (set != -1)
00766         allegro_gl_set(AGL_ACC_RED_DEPTH, set);
00767     set = get_config_int(section, "accum_green_depth", -1);
00768     if (set != -1)
00769         allegro_gl_set(AGL_ACC_GREEN_DEPTH, set);
00770     set = get_config_int(section, "accum_blue_depth", -1);
00771     if (set != -1)
00772         allegro_gl_set(AGL_ACC_BLUE_DEPTH, set);
00773     set = get_config_int(section, "accum_alpha_depth", -1);
00774     if (set != -1)
00775         allegro_gl_set(AGL_ACC_ALPHA_DEPTH, set);
00776     set = get_config_int(section, "double_buffer", -1);
00777     if (set != -1)
00778         allegro_gl_set(AGL_DOUBLEBUFFER, set);
00779     set = get_config_int(section, "stereo_display", -1);
00780     if (set != -1)
00781         allegro_gl_set(AGL_STEREO, set);
00782     set = get_config_int(section, "aux_buffers", -1);
00783     if (set != -1)
00784         allegro_gl_set(AGL_AUX_BUFFERS, set);
00785     set = get_config_int(section, "z_depth", -1);
00786     if (set != -1)
00787         allegro_gl_set(AGL_Z_DEPTH, set);
00788     set = get_config_int(section, "stencil_depth", -1);
00789     if (set != -1)
00790         allegro_gl_set(AGL_STENCIL_DEPTH, set);
00791     set = get_config_int(section, "window_x", -1);
00792     if (set != -1)
00793         allegro_gl_set(AGL_WINDOW_X, set);
00794     set = get_config_int(section, "window_y", -1);
00795     if (set != -1)
00796         allegro_gl_set(AGL_WINDOW_Y, set);
00797     set = get_config_int(section, "fullscreen", -1);
00798     if (set != -1)
00799         allegro_gl_set(AGL_FULLSCREEN, set);
00800     set = get_config_int(section, "windowed", -1);
00801     if (set != -1)
00802         allegro_gl_set(AGL_WINDOWED, set);
00803     set = get_config_int(section, "video_memory_policy", -1);
00804     if (set != -1)
00805         allegro_gl_set(AGL_VIDEO_MEMORY_POLICY, set);
00806     set = get_config_int(section, "sample_buffers", -1);
00807     if (set != -1)
00808         allegro_gl_set(AGL_SAMPLE_BUFFERS, set);
00809     set = get_config_int(section, "samples", -1);
00810     if (set != -1)
00811         allegro_gl_set(AGL_SAMPLES, set);
00812     set = get_config_int(section, "float_color", -1);
00813     if (set != -1)
00814         allegro_gl_set(AGL_FLOAT_COLOR, set);
00815     set = get_config_int(section, "float_depth", -1);
00816     if (set != -1)
00817         allegro_gl_set(AGL_FLOAT_Z, set);
00818     
00819     agl_parse_section(AGL_REQUIRE, section, "require");
00820     agl_parse_section(AGL_SUGGEST, section, "suggest");
00821 }
00822 
00823 
00824 
00825 /* int install_allegro_gl(void) */
00836 int install_allegro_gl(void)
00837 {
00838     if (!system_driver)
00839         return -1;
00840 
00841     if (atexit(remove_allegro_gl))
00842         return -1;
00843     
00844     if (system_driver->gfx_drivers)
00845         saved_gfx_drivers = system_driver->gfx_drivers;
00846     else
00847         saved_gfx_drivers = list_saved_gfx_drivers;
00848     
00849     system_driver->gfx_drivers = our_gfx_drivers;
00850 
00851     allegro_gl_clear_settings();
00852 
00853     /* Save and replace old blit_between_formats methods */
00854 #ifdef ALLEGRO_COLOR8
00855     __blit_between_formats8 = __linear_vtable8.blit_between_formats;
00856     __linear_vtable8.blit_between_formats =
00857                                          allegro_gl_memory_blit_between_formats;
00858 #endif
00859 #ifdef ALLEGRO_COLOR16
00860     __blit_between_formats15 = __linear_vtable15.blit_between_formats;
00861     __linear_vtable15.blit_between_formats =
00862                                          allegro_gl_memory_blit_between_formats;
00863     __blit_between_formats16 = __linear_vtable16.blit_between_formats;
00864     __linear_vtable16.blit_between_formats
00865                                        = allegro_gl_memory_blit_between_formats;
00866 #endif
00867 #ifdef ALLEGRO_COLOR24
00868     __blit_between_formats24 = __linear_vtable24.blit_between_formats;
00869     __linear_vtable24.blit_between_formats
00870                                        = allegro_gl_memory_blit_between_formats;
00871 #endif
00872 #ifdef ALLEGRO_COLOR32
00873     __blit_between_formats32 = __linear_vtable32.blit_between_formats;
00874     __linear_vtable32.blit_between_formats
00875                                        = allegro_gl_memory_blit_between_formats;
00876 #endif
00877 
00878     usetc(allegro_gl_error, 0);
00879     
00880     return 0;
00881 }
00882 
00883 
00884 
00885 /* void remove_allegro_gl(void) */
00894 void remove_allegro_gl(void)
00895 {
00896     if ((!system_driver) || (!saved_gfx_drivers))
00897         return;
00898 
00899     if (saved_gfx_drivers == &list_saved_gfx_drivers)
00900         system_driver->gfx_drivers = NULL;
00901     else
00902         system_driver->gfx_drivers = saved_gfx_drivers;
00903 
00904     /* This function may be called twice (once by a user explicit call
00905      * and once again at exit since the function is registered with at_exit)
00906      * In order to prevent crashes, 'saved_gfx_drivers' is set to NULL
00907      */
00908     saved_gfx_drivers = NULL;
00909 
00910     /* Restore the blit_between_formats methods */
00911     #ifdef ALLEGRO_COLOR8
00912     __linear_vtable8.blit_between_formats = __blit_between_formats8;
00913     #endif
00914     #ifdef ALLEGRO_COLOR16
00915     __linear_vtable15.blit_between_formats = __blit_between_formats15;
00916     __linear_vtable16.blit_between_formats = __blit_between_formats16;
00917     #endif
00918     #ifdef ALLEGRO_COLOR24
00919     __linear_vtable24.blit_between_formats = __blit_between_formats24;
00920     #endif
00921     #ifdef ALLEGRO_COLOR32
00922     __linear_vtable32.blit_between_formats = __blit_between_formats32;
00923     #endif
00924 }
00925 
00926 
00927 
00928 /* void allegro_gl_flip(void) */
00951 void allegro_gl_flip(void)
00952 {
00953     __allegro_gl_driver->flip();
00954 }
00955 
00956 
00957 
00958 /* float allegro_gl_opengl_version() */
00971 float allegro_gl_opengl_version() {
00972     
00973     const char *str;
00974     
00975     if (!__allegro_gl_valid_context)
00976         return 0.0f;
00977     
00978     str = (const char*)glGetString(GL_VERSION);
00979 
00980     if ((strncmp(str, "1.0 ", 4) == 0) || (strncmp(str, "1.0.0 ", 6) == 0))
00981         return 1.0;
00982     if ((strncmp(str, "1.1 ", 4) == 0) || (strncmp(str, "1.1.0 ", 6) == 0))
00983         return 1.1;
00984     if ((strncmp(str, "1.2 ", 4) == 0) || (strncmp(str, "1.2.0 ", 6) == 0))
00985         return 1.2;
00986     if ((strncmp(str, "1.2.1 ", 6) == 0))
00987         return 1.21;
00988     if ((strncmp(str, "1.2.2 ", 6) == 0))
00989         return 1.22;
00990     if ((strncmp(str, "1.3 ", 4) == 0) || (strncmp(str, "1.3.0 ", 6) == 0))
00991         return 1.3;
00992     if ((strncmp(str, "1.4 ", 4) == 0) || (strncmp(str, "1.4.0 ", 6) == 0))
00993         return 1.4;
00994     if ((strncmp(str, "1.5 ", 4) == 0) || (strncmp(str, "1.5.0 ", 6) == 0))
00995         return 1.5;
00996     if ((strncmp(str, "2.0 ", 4) == 0) || (strncmp(str, "2.0.0 ", 6) == 0))
00997         return 2.0;
00998     if ((strncmp(str, "2.1 ", 4) == 0) || (strncmp(str, "2.1.0 ", 6) == 0))
00999         return 2.1;
01000 
01001     /* The OpenGL driver does not return a version
01002      * number. However it probably supports at least OpenGL 1.0
01003      */ 
01004     if (!str) {
01005         return 1.0;
01006     }
01007     
01008     return atof(str);
01009 }
01010 
01011 
01012 
01013 void __allegro_gl_set_allegro_image_format(int big_endian)
01014 {
01015     /* Sets up Allegro to use OpenGL formats */
01016     _rgb_r_shift_15 = 11;
01017     _rgb_g_shift_15 = 6;
01018     _rgb_b_shift_15 = 1;
01019 
01020     _rgb_r_shift_16 = 11;
01021     _rgb_g_shift_16 = 5;
01022     _rgb_b_shift_16 = 0;
01023 
01024     if (big_endian) {
01025         _rgb_r_shift_24 = 16;
01026         _rgb_g_shift_24 = 8;
01027         _rgb_b_shift_24 = 0;
01028 
01029         _rgb_a_shift_32 = 0;
01030         _rgb_r_shift_32 = 24;
01031         _rgb_g_shift_32 = 16;
01032         _rgb_b_shift_32 = 8;
01033     }
01034     else {
01035         _rgb_r_shift_24 = 0;
01036         _rgb_g_shift_24 = 8;
01037         _rgb_b_shift_24 = 16;
01038 
01039         _rgb_r_shift_32 = 0;
01040         _rgb_g_shift_32 = 8;
01041         _rgb_b_shift_32 = 16;
01042         _rgb_a_shift_32 = 24;
01043     }
01044 
01045     return;
01046 }
01047 
01048 
01049 
01050 /* allegro_gl_default_init:
01051  *  Sets a graphics mode according to the mode (fullscreen or windowed)
01052  *  requested by the user. If it fails to set up the mode then it tries
01053  *  (if available) the other one unless the user has "AGL_REQUIRED" the mode.
01054  */
01055 static BITMAP *allegro_gl_default_gfx_init(int w, int h, int vw, int vh,
01056                                                                      int depth)
01057 {
01058     BITMAP* bmp = NULL;
01059     
01060     if (allegro_gl_display_info.fullscreen) {
01061         TRACE(PREFIX_I "default_gfx_init: Trying to set up fullscreen mode.\n");
01062         
01063 #ifdef GFX_OPENGL_FULLSCREEN
01064         /* Looks for fullscreen mode in our_driver_list */
01065         gfx_driver = &gfx_allegro_gl_fullscreen;
01066 
01067         if (__allegro_gl_required_settings & AGL_FULLSCREEN)
01068             /* Fullscreen mode required and found */
01069             return gfx_allegro_gl_fullscreen.init(w, h, vw, vh, depth);
01070         else
01071             bmp = gfx_allegro_gl_fullscreen.init(w, h, vw, vh, depth);
01072         
01073         if (bmp)
01074             /* Fullscreen mode found but not required (probably suggested) */
01075             return bmp;
01076 
01077 #endif /*GFX_OPENGL_FULLSCREEN*/
01078 
01079         /* Fullscreen mode not available but not required :
01080          * let's try windowed mode :
01081          */
01082         TRACE(PREFIX_I "default_gfx_init: Failed to set up fullscreen mode!\n");
01083 #ifdef GFX_OPENGL_WINDOWED
01084         TRACE(PREFIX_I "default_gfx_init: Trying windowed mode...\n");
01085         allegro_gl_display_info.fullscreen = FALSE;
01086         gfx_driver = &gfx_allegro_gl_windowed;
01087         return gfx_allegro_gl_windowed.init(w, h, vw, vh, depth);
01088 #else
01089         return NULL;
01090 #endif /* GFX_OPENGL_WINDOWED */
01091     }
01092     else {
01093         TRACE(PREFIX_I "default_gfx_init: Trying to set up windowed mode...\n");
01094         
01095 #ifdef GFX_OPENGL_WINDOWED
01096         /* Looks for windowed mode in our_driver_list */
01097         gfx_driver = &gfx_allegro_gl_windowed;
01098 
01099         if (__allegro_gl_required_settings & AGL_WINDOWED)
01100             /* Windowed mode required and found */
01101             return gfx_allegro_gl_windowed.init(w, h, vw, vh, depth);
01102         else
01103             bmp = gfx_allegro_gl_windowed.init(w, h, vw, vh, depth);
01104         
01105         if (bmp)
01106             /* Windowed mode found but not required (probably suggested) */
01107             return bmp;
01108 
01109 #endif /* GFX_OPENGL_WINDOWED */
01110 
01111         /* Windowed mode not available but not required :
01112          * let's try fullscreen mode :
01113          */
01114         TRACE(PREFIX_I "default_gfx_init: Failed to set up windowed mode...\n");
01115 #ifdef GFX_OPENGL_FULLSCREEN
01116         TRACE(PREFIX_I "default_gfx_init: Trying fullscreen mode...\n");
01117         allegro_gl_display_info.fullscreen = TRUE;
01118         gfx_driver = &gfx_allegro_gl_fullscreen;
01119         return gfx_allegro_gl_fullscreen.init(w, h, vw, vh, depth);
01120 #else
01121         return NULL;
01122 #endif /*GFX_OPENGL_FULLSCREEN*/
01123     }
01124 }
01125 
01126 
01127 
01128 /* allegro_gl_set_blender_mode (GFX_DRIVER vtable entry):
01129  * Sets the blending mode. Same implementation to all GFX vtables.
01130  */
01131 void allegro_gl_set_blender_mode(int mode, int r, int g, int b, int a) {
01132     __allegro_gl_blit_operation = AGL_OP_BLEND;
01133     /* These blenders do not need any special extensions. 
01134      * We specify only pixel arithmetic here. Blend equation and blend
01135      * color (if available) are reset to defualt later.*/
01136     switch (mode) {
01137         case blender_mode_none:
01138             glBlendFunc(GL_ONE, GL_ZERO);
01139         break;
01140         case blender_mode_alpha:
01141             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01142         break;
01143         case blender_mode_invert:
01144             glLogicOp(GL_COPY_INVERTED);
01145             __allegro_gl_blit_operation = AGL_OP_LOGIC_OP;
01146         break;
01147         case blender_mode_multiply:
01148             glBlendFunc(GL_DST_COLOR, GL_ZERO);
01149         break;
01150     }
01151     
01152     if (allegro_gl_opengl_version() >= 1.4 ||
01153        (allegro_gl_opengl_version() >= 1.2 &&
01154         allegro_gl_is_extension_supported("ARB_imaging"))) {
01155         /* We're running a recent version of OpenGL and everything needed is here. */
01156         
01157         glBlendColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f);
01158 
01159         switch (mode) {
01160             case blender_mode_none:
01161                 glBlendEquation(GL_FUNC_ADD);
01162             break;
01163             case blender_mode_alpha:
01164                 glBlendEquation(GL_FUNC_ADD);
01165             break;
01166             case blender_mode_trans:
01167                 glBlendEquation(GL_FUNC_ADD);
01168                 glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
01169             break;
01170             case blender_mode_add:
01171                 glBlendEquation(GL_FUNC_ADD);
01172                 glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE);
01173             break;
01174             case blender_mode_burn:
01175                 glBlendEquation(GL_FUNC_SUBTRACT);
01176                 glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA);
01177             break;
01178             case blender_mode_dodge:
01179                 glBlendEquation(GL_FUNC_ADD);
01180                 glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA);
01181             break;
01182             case blender_mode_multiply:
01183                 glBlendEquation(GL_FUNC_ADD);
01184             break;
01185         }
01186 
01187         return;
01188     }
01189     
01190     /* Check for presence of glBlendColor() and special parameters to
01191      * glBlendFunc(). */
01192     if (allegro_gl_is_extension_supported("GL_EXT_blend_color")) {
01193         glBlendColorEXT(r / 255.f, g / 255.f, b / 255.f, a / 255.f);
01194 
01195         switch (mode) {
01196             case blender_mode_trans:
01197                 glBlendFunc(GL_CONSTANT_ALPHA_EXT, GL_ONE_MINUS_CONSTANT_ALPHA_EXT);
01198             break;
01199             case blender_mode_add:
01200                 glBlendFunc(GL_CONSTANT_ALPHA_EXT, GL_ONE);
01201             break;
01202             case blender_mode_burn:
01203                 glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA_EXT);
01204             break;
01205             case blender_mode_dodge:
01206                 glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA_EXT);
01207             break;
01208         }
01209     }
01210     else if (mode == blender_mode_trans ||
01211              mode == blender_mode_add ||
01212              mode == blender_mode_burn ||
01213              mode == blender_mode_dodge) {
01214         /* glBlendColor() is not available and it is needed by the selected
01215          * bledner. Bail out.*/
01216         return;
01217     }
01218 
01219     /* Check for presence of glBlendEquation(). */
01220     if (allegro_gl_is_extension_supported("GL_EXT_blend_minmax")) {
01221         switch (mode) {
01222             case blender_mode_none:
01223                 glBlendEquationEXT(GL_FUNC_ADD_EXT);
01224             break;
01225             case blender_mode_alpha:
01226                 glBlendEquationEXT(GL_FUNC_ADD_EXT);
01227             break;
01228             case blender_mode_trans:
01229                 glBlendEquationEXT(GL_FUNC_ADD_EXT);
01230             break;
01231             case blender_mode_add:
01232                 glBlendEquationEXT(GL_FUNC_ADD_EXT);
01233             break;
01234             case blender_mode_dodge:
01235                 glBlendEquationEXT(GL_FUNC_ADD_EXT);
01236             break;
01237             case blender_mode_multiply:
01238                 glBlendEquationEXT(GL_FUNC_ADD_EXT);
01239             break;
01240             case blender_mode_burn:
01241                 if (allegro_gl_is_extension_supported("GL_EXT_blend_subtract")) {
01242                     glBlendEquationEXT(GL_FUNC_SUBTRACT_EXT);
01243                 }
01244                 else {
01245                     /* GL_FUNC_SUBTRACT is not supported and it is needed by the
01246                      * selected blender. Bail out. */
01247                     return;
01248                 }
01249             break;
01250         }
01251     }
01252 }
01253 
01254 
01255 #ifdef DEBUGMODE
01256 #ifdef LOGLEVEL
01257 
01258 void __allegro_gl_log(int level, const char *str)
01259 {
01260     if (level <= LOGLEVEL)
01261         TRACE(PREFIX_L "[%d] %s", level, str);
01262 }
01263 
01264 #endif
01265 #endif
01266 

Generated on Sun Nov 11 15:52:54 2007 for AllegroGL by  doxygen 1.5.2