AllegroGL 0.4.4
|
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