AllegroGL: alleggl.c Source File

- Main Page
- Related Pages
- Modules
- Files

- File List
- Globals

# 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     if ((strncmp(str, "3.0 ", 4) == 0) || (strncmp(str, "3.0.0 ", 6) == 0))
    01001         return 3.0;
    01002
    01003     /* The OpenGL driver does not return a version
    01004      * number. However it probably supports at least OpenGL 1.0
    01005      */
    01006     if (!str) {
    01007         return 1.0;
    01008     }
    01009
    01010     return atof(str);
    01011 }
    01012
    01013
    01014
    01015 void __allegro_gl_set_allegro_image_format(int big_endian)
    01016 {
    01017     /* Sets up Allegro to use OpenGL formats */
    01018     _rgb_r_shift_15 = 11;
    01019     _rgb_g_shift_15 = 6;
    01020     _rgb_b_shift_15 = 1;
    01021
    01022     _rgb_r_shift_16 = 11;
    01023     _rgb_g_shift_16 = 5;
    01024     _rgb_b_shift_16 = 0;
    01025
    01026     if (big_endian) {
    01027         _rgb_r_shift_24 = 16;
    01028         _rgb_g_shift_24 = 8;
    01029         _rgb_b_shift_24 = 0;
    01030
    01031         _rgb_a_shift_32 = 0;
    01032         _rgb_r_shift_32 = 24;
    01033         _rgb_g_shift_32 = 16;
    01034         _rgb_b_shift_32 = 8;
    01035     }
    01036     else {
    01037         _rgb_r_shift_24 = 0;
    01038         _rgb_g_shift_24 = 8;
    01039         _rgb_b_shift_24 = 16;
    01040
    01041         _rgb_r_shift_32 = 0;
    01042         _rgb_g_shift_32 = 8;
    01043         _rgb_b_shift_32 = 16;
    01044         _rgb_a_shift_32 = 24;
    01045     }
    01046
    01047     return;
    01048 }
    01049
    01050
    01051
    01052 /* allegro_gl_default_init:
    01053  *  Sets a graphics mode according to the mode (fullscreen or windowed)
    01054  *  requested by the user. If it fails to set up the mode then it tries
    01055  *  (if available) the other one unless the user has "AGL_REQUIRED" the mode.
    01056  */
    01057 static BITMAP *allegro_gl_default_gfx_init(int w, int h, int vw, int vh,
    01058                                                                      int depth)
    01059 {
    01060     BITMAP* bmp = NULL;
    01061
    01062     if (allegro_gl_display_info.fullscreen) {
    01063         TRACE(PREFIX_I "default_gfx_init: Trying to set up fullscreen mode.\n");
    01064
    01065 #ifdef GFX_OPENGL_FULLSCREEN
    01066         /* Looks for fullscreen mode in our_driver_list */
    01067         gfx_driver = &gfx_allegro_gl_fullscreen;
    01068
    01069         if (__allegro_gl_required_settings & AGL_FULLSCREEN)
    01070             /* Fullscreen mode required and found */
    01071             return gfx_allegro_gl_fullscreen.init(w, h, vw, vh, depth);
    01072         else
    01073             bmp = gfx_allegro_gl_fullscreen.init(w, h, vw, vh, depth);
    01074
    01075         if (bmp)
    01076             /* Fullscreen mode found but not required (probably suggested) */
    01077             return bmp;
    01078
    01079 #endif /*GFX_OPENGL_FULLSCREEN*/
    01080
    01081         /* Fullscreen mode not available but not required :
    01082          * let's try windowed mode :
    01083          */
    01084         TRACE(PREFIX_I "default_gfx_init: Failed to set up fullscreen mode!\n");
    01085 #ifdef GFX_OPENGL_WINDOWED
    01086         TRACE(PREFIX_I "default_gfx_init: Trying windowed mode...\n");
    01087         allegro_gl_display_info.fullscreen = FALSE;
    01088         gfx_driver = &gfx_allegro_gl_windowed;
    01089         return gfx_allegro_gl_windowed.init(w, h, vw, vh, depth);
    01090 #else
    01091         return NULL;
    01092 #endif /* GFX_OPENGL_WINDOWED */
    01093     }
    01094     else {
    01095         TRACE(PREFIX_I "default_gfx_init: Trying to set up windowed mode...\n");
    01096
    01097 #ifdef GFX_OPENGL_WINDOWED
    01098         /* Looks for windowed mode in our_driver_list */
    01099         gfx_driver = &gfx_allegro_gl_windowed;
    01100
    01101         if (__allegro_gl_required_settings & AGL_WINDOWED)
    01102             /* Windowed mode required and found */
    01103             return gfx_allegro_gl_windowed.init(w, h, vw, vh, depth);
    01104         else
    01105             bmp = gfx_allegro_gl_windowed.init(w, h, vw, vh, depth);
    01106
    01107         if (bmp)
    01108             /* Windowed mode found but not required (probably suggested) */
    01109             return bmp;
    01110
    01111 #endif /* GFX_OPENGL_WINDOWED */
    01112
    01113         /* Windowed mode not available but not required :
    01114          * let's try fullscreen mode :
    01115          */
    01116         TRACE(PREFIX_I "default_gfx_init: Failed to set up windowed mode...\n");
    01117 #ifdef GFX_OPENGL_FULLSCREEN
    01118         TRACE(PREFIX_I "default_gfx_init: Trying fullscreen mode...\n");
    01119         allegro_gl_display_info.fullscreen = TRUE;
    01120         gfx_driver = &gfx_allegro_gl_fullscreen;
    01121         return gfx_allegro_gl_fullscreen.init(w, h, vw, vh, depth);
    01122 #else
    01123         return NULL;
    01124 #endif /*GFX_OPENGL_FULLSCREEN*/
    01125     }
    01126 }
    01127
    01128
    01129
    01130 /* allegro_gl_set_blender_mode (GFX_DRIVER vtable entry):
    01131  * Sets the blending mode. Same implementation to all GFX vtables.
    01132  */
    01133 void allegro_gl_set_blender_mode(int mode, int r, int g, int b, int a) {
    01134     __allegro_gl_blit_operation = AGL_OP_BLEND;
    01135     /* These blenders do not need any special extensions.
    01136      * We specify only pixel arithmetic here. Blend equation and blend
    01137      * color (if available) are reset to defualt later.*/
    01138     switch (mode) {
    01139         case blender_mode_none:
    01140             glBlendFunc(GL_ONE, GL_ZERO);
    01141         break;
    01142         case blender_mode_alpha:
    01143             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    01144         break;
    01145         case blender_mode_invert:
    01146             glLogicOp(GL_COPY_INVERTED);
    01147             __allegro_gl_blit_operation = AGL_OP_LOGIC_OP;
    01148         break;
    01149         case blender_mode_multiply:
    01150             glBlendFunc(GL_DST_COLOR, GL_ZERO);
    01151         break;
    01152     }
    01153
    01154     if (allegro_gl_opengl_version() >= 1.4 ||
    01155        (allegro_gl_opengl_version() >= 1.2 &&
    01156         allegro_gl_is_extension_supported("GL_ARB_imaging"))) {
    01157         /* We're running a recent version of OpenGL and everything needed is here. */
    01158
    01159         glBlendColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f);
    01160
    01161         switch (mode) {
    01162             case blender_mode_none:
    01163                 glBlendEquation(GL_FUNC_ADD);
    01164             break;
    01165             case blender_mode_alpha:
    01166                 glBlendEquation(GL_FUNC_ADD);
    01167             break;
    01168             case blender_mode_trans:
    01169                 glBlendEquation(GL_FUNC_ADD);
    01170                 glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
    01171             break;
    01172             case blender_mode_add:
    01173                 glBlendEquation(GL_FUNC_ADD);
    01174                 glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE);
    01175             break;
    01176             case blender_mode_burn:
    01177                 glBlendEquation(GL_FUNC_SUBTRACT);
    01178                 glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA);
    01179             break;
    01180             case blender_mode_dodge:
    01181                 glBlendEquation(GL_FUNC_ADD);
    01182                 glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA);
    01183             break;
    01184             case blender_mode_multiply:
    01185                 glBlendEquation(GL_FUNC_ADD);
    01186             break;
    01187         }
    01188
    01189         return;
    01190     }
    01191
    01192     /* Check for presence of glBlendColor() and special parameters to
    01193      * glBlendFunc(). */
    01194     if (allegro_gl_is_extension_supported("GL_EXT_blend_color")) {
    01195         glBlendColorEXT(r / 255.f, g / 255.f, b / 255.f, a / 255.f);
    01196
    01197         switch (mode) {
    01198             case blender_mode_trans:
    01199                 glBlendFunc(GL_CONSTANT_ALPHA_EXT, GL_ONE_MINUS_CONSTANT_ALPHA_EXT);
    01200             break;
    01201             case blender_mode_add:
    01202                 glBlendFunc(GL_CONSTANT_ALPHA_EXT, GL_ONE);
    01203             break;
    01204             case blender_mode_burn:
    01205                 glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA_EXT);
    01206             break;
    01207             case blender_mode_dodge:
    01208                 glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA_EXT);
    01209             break;
    01210         }
    01211     }
    01212     else if (mode == blender_mode_trans ||
    01213              mode == blender_mode_add ||
    01214              mode == blender_mode_burn ||
    01215              mode == blender_mode_dodge) {
    01216         /* glBlendColor() is not available and it is needed by the selected
    01217          * bledner. Bail out.*/
    01218         return;
    01219     }
    01220
    01221     /* Check for presence of glBlendEquation(). */
    01222     if (allegro_gl_is_extension_supported("GL_EXT_blend_minmax")) {
    01223         switch (mode) {
    01224             case blender_mode_none:
    01225                 glBlendEquationEXT(GL_FUNC_ADD_EXT);
    01226             break;
    01227             case blender_mode_alpha:
    01228                 glBlendEquationEXT(GL_FUNC_ADD_EXT);
    01229             break;
    01230             case blender_mode_trans:
    01231                 glBlendEquationEXT(GL_FUNC_ADD_EXT);
    01232             break;
    01233             case blender_mode_add:
    01234                 glBlendEquationEXT(GL_FUNC_ADD_EXT);
    01235             break;
    01236             case blender_mode_dodge:
    01237                 glBlendEquationEXT(GL_FUNC_ADD_EXT);
    01238             break;
    01239             case blender_mode_multiply:
    01240                 glBlendEquationEXT(GL_FUNC_ADD_EXT);
    01241             break;
    01242             case blender_mode_burn:
    01243                 if (allegro_gl_is_extension_supported("GL_EXT_blend_subtract")) {
    01244                     glBlendEquationEXT(GL_FUNC_SUBTRACT_EXT);
    01245                 }
    01246                 else {
    01247                     /* GL_FUNC_SUBTRACT is not supported and it is needed by the
    01248                      * selected blender. Bail out. */
    01249                     return;
    01250                 }
    01251             break;
    01252         }
    01253     }
    01254 }
    01255
    01256
    01257 #ifdef DEBUGMODE
    01258 #ifdef LOGLEVEL
    01259
    01260 void __allegro_gl_log(int level, const char *str)
    01261 {
    01262     if (level <= LOGLEVEL)
    01263         TRACE(PREFIX_L "[%d] %s", level, str);
    01264 }
    01265
    01266 #endif
    01267 #endif
    01268