AllegroGL  0.4.4
alleggl.c
Go to the documentation of this file.
1 /* This code is (C) AllegroGL contributors, and double licensed under
2  * the GPL and zlib licenses. See gpl.txt or zlib.txt for details.
3  */
11 #include <string.h>
12 #include <stdlib.h>
13 
14 #include "alleggl.h"
15 #include "allglint.h"
16 
17 #include <allegro/internal/aintern.h>
18 #ifdef ALLEGRO_MACOSX
19 #include <OpenGL/glu.h>
20 #else
21 #include <GL/glu.h>
22 #endif
23 
24 #define PREFIX_I "agl INFO: "
25 #define PREFIX_E "agl ERROR: "
26 #define PREFIX_L "agl LOG: "
27 
28 
29 /* Structs containing the current driver state */
30 struct allegro_gl_driver *__allegro_gl_driver = NULL;
31 struct allegro_gl_display_info allegro_gl_display_info;
32 
33 /* Settings required/suggested */
34 int __allegro_gl_required_settings, __allegro_gl_suggested_settings;
35 
36 /* Valid context state */
37 int __allegro_gl_valid_context = 0;
38 
39 
40 /* Operation to enable while blitting. */
41 int __allegro_gl_blit_operation;
42 
43 
44 char allegro_gl_error[AGL_ERROR_SIZE] = EMPTY_STRING;
45 
46 BLIT_BETWEEN_FORMATS_FUNC __blit_between_formats8;
47 BLIT_BETWEEN_FORMATS_FUNC __blit_between_formats15;
48 BLIT_BETWEEN_FORMATS_FUNC __blit_between_formats16;
49 BLIT_BETWEEN_FORMATS_FUNC __blit_between_formats24;
50 BLIT_BETWEEN_FORMATS_FUNC __blit_between_formats32;
51 
52 
53 
63 
64 
65 
66 /* Allegro GFX_DRIVER list handling */
67 static _DRIVER_INFO our_driver_list[] = {
68 #ifdef GFX_OPENGL_WINDOWED
69  {GFX_OPENGL_WINDOWED, &gfx_allegro_gl_windowed, FALSE},
70 #endif
71 #ifdef GFX_OPENGL_FULLSCREEN
72  {GFX_OPENGL_FULLSCREEN, &gfx_allegro_gl_fullscreen, FALSE},
73 #endif
74  {GFX_OPENGL, &gfx_allegro_gl_default, FALSE},
75  {0, NULL, FALSE}
76 };
77 
78 
79 
80 static _DRIVER_INFO *our_gfx_drivers(void)
81 {
82  return our_driver_list;
83 }
84 
85 
86 
87 _DRIVER_INFO *(*saved_gfx_drivers) (void) = NULL;
88 
89 
90 
91 static _DRIVER_INFO *list_saved_gfx_drivers(void)
92 {
93  return _gfx_driver_list;
94 }
95 
96 
97 
98 static BITMAP *allegro_gl_default_gfx_init(int w, int h, int vw, int vh, int depth);
99 
100 
101 
102 GFX_DRIVER gfx_allegro_gl_default =
103 {
104  GFX_OPENGL,
105  EMPTY_STRING,
106  EMPTY_STRING,
107  "AllegroGL Default Driver",
108  allegro_gl_default_gfx_init,
109  NULL,
110  NULL,
111  NULL, //_xwin_vsync,
112  NULL,
113  NULL, NULL, NULL,
114  NULL, /* create_video_bitmap */
115  NULL,
116  NULL, NULL, /* No show/request video bitmaps */
117  NULL, NULL,
118  NULL, NULL, NULL, NULL,
119  NULL,
120  NULL, NULL,
121  NULL, /* set_blender_mode */
122  NULL, /* No fetch_mode_list */
123  0, 0,
124  0,
125  0, 0,
126  0,
127  0,
128  FALSE /* Windowed mode */
129 };
130 
131 
132 
176 /* void allegro_gl_clear_settings(void) */
194 {
195  memset(&allegro_gl_display_info, 0, sizeof allegro_gl_display_info);
196 
197  __allegro_gl_required_settings = __allegro_gl_suggested_settings = 0;
198 
199  /* Pick sensible defaults */
200  allegro_gl_display_info.fullscreen = 1;
201  allegro_gl_display_info.rmethod = 1;
202  allegro_gl_display_info.doublebuffered = 1;
203  allegro_gl_display_info.vidmem_policy = AGL_KEEP;
204  __allegro_gl_suggested_settings =
206 }
207 
208 
209 
210 /* void allegro_gl_set(int option, int value) */
274 void allegro_gl_set(int option, int value)
275 {
276  switch (option) {
277  /* Options stating importance of other options */
278  case AGL_REQUIRE:
279  __allegro_gl_required_settings |= value;
280  __allegro_gl_suggested_settings &= ~value;
281  break;
282  case AGL_SUGGEST:
283  __allegro_gl_suggested_settings |= value;
284  __allegro_gl_required_settings &= ~value;
285  break;
286  case AGL_DONTCARE:
287  __allegro_gl_required_settings &= ~value;
288  __allegro_gl_suggested_settings &= ~value;
289  break;
290 
291  /* Options configuring the mode set */
292  case AGL_ALLEGRO_FORMAT:
293  allegro_gl_display_info.allegro_format = value;
294  break;
295  case AGL_RED_DEPTH:
296  allegro_gl_display_info.pixel_size.rgba.r = value;
297  break;
298  case AGL_GREEN_DEPTH:
299  allegro_gl_display_info.pixel_size.rgba.g = value;
300  break;
301  case AGL_BLUE_DEPTH:
302  allegro_gl_display_info.pixel_size.rgba.b = value;
303  break;
304  case AGL_ALPHA_DEPTH:
305  allegro_gl_display_info.pixel_size.rgba.a = value;
306  break;
307  case AGL_COLOR_DEPTH:
308  switch (value) {
309  case 8:
314  break;
315  case 15:
320  break;
321  case 16:
326  break;
327  case 24:
328  case 32:
332  allegro_gl_set(AGL_ALPHA_DEPTH, value-24);
333  break;
334  }
335  allegro_gl_display_info.colour_depth = value;
336  break;
337  case AGL_ACC_RED_DEPTH:
338  allegro_gl_display_info.accum_size.rgba.r = value;
339  break;
340  case AGL_ACC_GREEN_DEPTH:
341  allegro_gl_display_info.accum_size.rgba.g = value;
342  break;
343  case AGL_ACC_BLUE_DEPTH:
344  allegro_gl_display_info.accum_size.rgba.b = value;
345  break;
346  case AGL_ACC_ALPHA_DEPTH:
347  allegro_gl_display_info.accum_size.rgba.a = value;
348  break;
349 
350  case AGL_DOUBLEBUFFER:
351  allegro_gl_display_info.doublebuffered = value;
352  break;
353  case AGL_STEREO:
354  allegro_gl_display_info.stereo = value;
355  break;
356  case AGL_AUX_BUFFERS:
357  allegro_gl_display_info.aux_buffers = value;
358  break;
359  case AGL_Z_DEPTH:
360  allegro_gl_display_info.depth_size = value;
361  break;
362  case AGL_STENCIL_DEPTH:
363  allegro_gl_display_info.stencil_size = value;
364  break;
365 
366  case AGL_WINDOW_X:
367  allegro_gl_display_info.x = value;
368  break;
369  case AGL_WINDOW_Y:
370  allegro_gl_display_info.y = value;
371  break;
372 
373  case AGL_RENDERMETHOD:
374  allegro_gl_display_info.rmethod = value;
375  break;
376 
377  case AGL_FULLSCREEN:
378  allegro_gl_display_info.fullscreen = value;
379  break;
380 
381  case AGL_WINDOWED:
382  allegro_gl_display_info.fullscreen = !value;
383  break;
385  if ((value == AGL_KEEP) || (value == AGL_RELEASE))
386  allegro_gl_display_info.vidmem_policy = value;
387  break;
388  case AGL_SAMPLE_BUFFERS:
389  allegro_gl_display_info.sample_buffers = value;
390  break;
391  case AGL_SAMPLES:
392  allegro_gl_display_info.samples = value;
393  break;
394  case AGL_FLOAT_COLOR:
395  allegro_gl_display_info.float_color = value;
396  break;
397  case AGL_FLOAT_Z:
398  allegro_gl_display_info.float_depth = value;
399  break;
400  }
401 }
402 
403 
404 
421 int allegro_gl_get(int option)
422 {
423  switch (option) {
424  /* Options stating importance of other options */
425  case AGL_REQUIRE:
426  return __allegro_gl_required_settings;
427  case AGL_SUGGEST:
428  return __allegro_gl_suggested_settings;
429  case AGL_DONTCARE:
430  return ~0 & ~(__allegro_gl_required_settings |
431  __allegro_gl_suggested_settings);
432 
433  /* Options configuring the mode set */
434  case AGL_ALLEGRO_FORMAT:
435  return allegro_gl_display_info.allegro_format;
436  case AGL_RED_DEPTH:
437  return allegro_gl_display_info.pixel_size.rgba.r;
438  case AGL_GREEN_DEPTH:
439  return allegro_gl_display_info.pixel_size.rgba.g;
440  case AGL_BLUE_DEPTH:
441  return allegro_gl_display_info.pixel_size.rgba.b;
442  case AGL_ALPHA_DEPTH:
443  return allegro_gl_display_info.pixel_size.rgba.a;
444  case AGL_COLOR_DEPTH:
445  return allegro_gl_display_info.pixel_size.rgba.r
446  + allegro_gl_display_info.pixel_size.rgba.g
447  + allegro_gl_display_info.pixel_size.rgba.b
448  + allegro_gl_display_info.pixel_size.rgba.a;
449  case AGL_ACC_RED_DEPTH:
450  return allegro_gl_display_info.accum_size.rgba.r;
451  case AGL_ACC_GREEN_DEPTH:
452  return allegro_gl_display_info.accum_size.rgba.g;
453  case AGL_ACC_BLUE_DEPTH:
454  return allegro_gl_display_info.accum_size.rgba.b;
455  case AGL_ACC_ALPHA_DEPTH:
456  return allegro_gl_display_info.accum_size.rgba.a;
457  case AGL_DOUBLEBUFFER:
458  return allegro_gl_display_info.doublebuffered;
459  case AGL_STEREO:
460  return allegro_gl_display_info.stereo;
461  case AGL_AUX_BUFFERS:
462  return allegro_gl_display_info.aux_buffers;
463  case AGL_Z_DEPTH:
464  return allegro_gl_display_info.depth_size;
465  case AGL_STENCIL_DEPTH:
466  return allegro_gl_display_info.stencil_size;
467  case AGL_WINDOW_X:
468  return allegro_gl_display_info.x;
469  case AGL_WINDOW_Y:
470  return allegro_gl_display_info.y;
471  case AGL_FULLSCREEN:
472  return allegro_gl_display_info.fullscreen;
473  case AGL_WINDOWED:
474  return !allegro_gl_display_info.fullscreen;
476  return allegro_gl_display_info.vidmem_policy;
477  case AGL_SAMPLE_BUFFERS:
478  return allegro_gl_display_info.sample_buffers;
479  case AGL_SAMPLES:
480  return allegro_gl_display_info.samples;
481  case AGL_FLOAT_COLOR:
482  return allegro_gl_display_info.float_color;
483  case AGL_FLOAT_Z:
484  return allegro_gl_display_info.float_depth;
485  }
486  return -1;
487 }
488 
489 
490 
491 /* Builds a string corresponding to the options set in 'opt'
492  * and writes in the config file
493  */
494 static void build_settings(int opt, char *section, char *name) {
495  char buf[2048];
496 
497  usetc(buf, 0);
498 
499  if (opt & AGL_ALLEGRO_FORMAT)
500  ustrcat(buf, "allegro_format ");
501  if (opt & AGL_RED_DEPTH)
502  ustrcat(buf, "red_depth ");
503  if (opt & AGL_GREEN_DEPTH)
504  ustrcat(buf, "green_depth ");
505  if (opt & AGL_BLUE_DEPTH)
506  ustrcat(buf, "blue_depth ");
507  if (opt & AGL_ALPHA_DEPTH)
508  ustrcat(buf, "alpha_depth ");
509  if (opt & AGL_COLOR_DEPTH)
510  ustrcat(buf, "color_depth ");
511  if (opt & AGL_ACC_RED_DEPTH)
512  ustrcat(buf, "accum_red_depth ");
513  if (opt & AGL_ACC_GREEN_DEPTH)
514  ustrcat(buf, "accum_green_depth ");
515  if (opt & AGL_ACC_BLUE_DEPTH)
516  ustrcat(buf, "accum_blue_depth ");
517  if (opt & AGL_ACC_ALPHA_DEPTH)
518  ustrcat(buf, "accum_alpha_depth ");
519  if (opt & AGL_DOUBLEBUFFER)
520  ustrcat(buf, "double_buffer ");
521  if (opt & AGL_STEREO)
522  ustrcat(buf, "stereo_display ");
523  if (opt & AGL_AUX_BUFFERS)
524  ustrcat(buf, "aux_buffers ");
525  if (opt & AGL_Z_DEPTH)
526  ustrcat(buf, "z_depth ");
527  if (opt & AGL_STENCIL_DEPTH)
528  ustrcat(buf, "stencil_depth ");
529  if (opt & AGL_WINDOW_X)
530  ustrcat(buf, "window_x ");
531  if (opt & AGL_WINDOW_Y)
532  ustrcat(buf, "window_y ");
533  if (opt & AGL_FULLSCREEN)
534  ustrcat(buf, "fullscreen ");
535  if (opt & AGL_WINDOWED)
536  ustrcat(buf, "windowed ");
537  if (opt & AGL_VIDEO_MEMORY_POLICY)
538  ustrcat(buf, "video_memory_policy ");
539  if (opt & AGL_SAMPLE_BUFFERS)
540  ustrcat(buf, "sample_buffers ");
541  if (opt & AGL_SAMPLES)
542  ustrcat(buf, "samples ");
543  if (opt & AGL_FLOAT_COLOR)
544  ustrcat(buf, "float_color ");
545  if (opt & AGL_FLOAT_Z)
546  ustrcat(buf, "float_depth ");
547 
548  set_config_string(section, name, buf);
549 }
550 
551 
552 
553 /* void allegro_gl_save_settings() */
561 
562  char *section = "OpenGL";
564 
565  if (save & AGL_ALLEGRO_FORMAT)
566  set_config_int(section, "allegro_format",
567  allegro_gl_get(AGL_ALLEGRO_FORMAT));
568  if (save & AGL_RED_DEPTH)
569  set_config_int(section, "red_depth",
570  allegro_gl_get(AGL_RED_DEPTH));
571  if (save & AGL_GREEN_DEPTH)
572  set_config_int(section, "green_depth",
573  allegro_gl_get(AGL_GREEN_DEPTH));
574  if (save & AGL_BLUE_DEPTH)
575  set_config_int(section, "blue_depth",
576  allegro_gl_get(AGL_BLUE_DEPTH));
577  if (save & AGL_ALPHA_DEPTH)
578  set_config_int(section, "alpha_depth",
579  allegro_gl_get(AGL_ALPHA_DEPTH));
580  if (save & AGL_COLOR_DEPTH)
581  set_config_int(section, "color_depth",
582  allegro_gl_get(AGL_COLOR_DEPTH));
583  if (save & AGL_ACC_RED_DEPTH)
584  set_config_int(section, "accum_red_depth",
585  allegro_gl_get(AGL_ACC_RED_DEPTH));
586  if (save & AGL_ACC_GREEN_DEPTH)
587  set_config_int(section, "accum_green_depth",
588  allegro_gl_get(AGL_ACC_GREEN_DEPTH));
589  if (save & AGL_ACC_BLUE_DEPTH)
590  set_config_int(section, "accum_blue_depth",
591  allegro_gl_get(AGL_ACC_BLUE_DEPTH));
592  if (save & AGL_ACC_ALPHA_DEPTH)
593  set_config_int(section, "accum_alpha_depth",
594  allegro_gl_get(AGL_ACC_ALPHA_DEPTH));
595  if (save & AGL_DOUBLEBUFFER)
596  set_config_int(section, "double_buffer",
597  allegro_gl_get(AGL_DOUBLEBUFFER));
598  if (save & AGL_STEREO)
599  set_config_int(section, "stereo_display",
600  allegro_gl_get(AGL_STEREO));
601  if (save & AGL_AUX_BUFFERS)
602  set_config_int(section, "aux_buffers",
603  allegro_gl_get(AGL_AUX_BUFFERS));
604  if (save & AGL_Z_DEPTH)
605  set_config_int(section, "z_depth",
606  allegro_gl_get(AGL_Z_DEPTH));
607  if (save & AGL_STENCIL_DEPTH)
608  set_config_int(section, "stencil_depth",
609  allegro_gl_get(AGL_STENCIL_DEPTH));
610  if (save & AGL_WINDOW_X)
611  set_config_int(section, "window_x",
612  allegro_gl_get(AGL_WINDOW_X));
613  if (save & AGL_WINDOW_Y)
614  set_config_int(section, "window_y",
615  allegro_gl_get(AGL_WINDOW_Y));
616  if (save & AGL_FULLSCREEN)
617  set_config_int(section, "fullscreen",
618  allegro_gl_get(AGL_FULLSCREEN));
619  if (save & AGL_WINDOWED)
620  set_config_int(section, "windowed",
621  allegro_gl_get(AGL_WINDOWED));
622  if (save & AGL_VIDEO_MEMORY_POLICY)
623  set_config_int(section, "video_memory_policy",
624  allegro_gl_get(AGL_VIDEO_MEMORY_POLICY));
625  if (save & AGL_SAMPLE_BUFFERS)
626  set_config_int(section, "sample_buffers",
627  allegro_gl_get(AGL_SAMPLE_BUFFERS));
628  if (save & AGL_SAMPLES)
629  set_config_int(section, "samples",
630  allegro_gl_get(AGL_SAMPLES));
631  if (save & AGL_FLOAT_COLOR)
632  set_config_int(section, "float_color",
633  allegro_gl_get(AGL_FLOAT_COLOR));
634  if (save & AGL_FLOAT_Z)
635  set_config_int(section, "float_depth",
636  allegro_gl_get(AGL_FLOAT_Z));
637 
638  if (save & AGL_REQUIRE)
639  build_settings(allegro_gl_get(AGL_REQUIRE), section, "require");
640  if (save & AGL_SUGGEST)
641  build_settings(allegro_gl_get(AGL_SUGGEST), section, "suggest");
642 }
643 
644 
645 
646 /* Parses an input string to read settings */
647 static void agl_parse_section(int sec, char *section, char *name) {
648  const char *end;
649  char *buf;
650  char *ptr;
651  int strsize;
652  int opt = 0;
653 
654  end = get_config_string(section, name, "");
655  strsize = ustrsizez(end);
656 
657  buf = (char*)malloc(sizeof(char) * strsize);
658 
659  if (!buf) {
660  TRACE(PREFIX_E "parse_section: Ran out of memory "
661  "while trying to allocate %i bytes!",
662  (int)sizeof(char) * strsize);
663  return;
664  }
665 
666  memcpy(buf, end, strsize);
667  end = buf + strsize;
668  ptr = buf;
669 
670  while (ptr < end) {
671  char *s = ustrtok_r(ptr, " ;|+", &ptr);
672 
673  if (!ustrcmp(s, "allegro_format"))
674  opt |= AGL_ALLEGRO_FORMAT;
675  if (!ustrcmp(s, "red_depth"))
676  opt |= AGL_RED_DEPTH;
677  if (!ustrcmp(s, "green_depth"))
678  opt |= AGL_GREEN_DEPTH;
679  if (!ustrcmp(s, "blue_depth"))
680  opt |= AGL_BLUE_DEPTH;
681  if (!ustrcmp(s, "alpha_depth"))
682  opt |= AGL_ALPHA_DEPTH;
683  if (!ustrcmp(s, "color_depth"))
684  opt |= AGL_COLOR_DEPTH;
685  if (!ustrcmp(s, "accum_red_depth"))
686  opt |= AGL_ACC_RED_DEPTH;
687  if (!ustrcmp(s, "accum_green_depth"))
688  opt |= AGL_ACC_GREEN_DEPTH;
689  if (!ustrcmp(s, "accum_blue_depth"))
690  opt |= AGL_ACC_BLUE_DEPTH;
691  if (!ustrcmp(s, "accum_alpha_depth"))
692  opt |= AGL_ACC_ALPHA_DEPTH;
693  if (!ustrcmp(s, "double_buffer"))
694  opt |= AGL_DOUBLEBUFFER;
695  if (!ustrcmp(s, "stereo_display"))
696  opt |= AGL_STEREO;
697  if (!ustrcmp(s, "aux_buffers"))
698  opt |= AGL_AUX_BUFFERS;
699  if (!ustrcmp(s, "z_depth"))
700  opt |= AGL_Z_DEPTH;
701  if (!ustrcmp(s, "stencil_depth"))
702  opt |= AGL_STENCIL_DEPTH;
703  if (!ustrcmp(s, "window_x"))
704  opt |= AGL_WINDOW_X;
705  if (!ustrcmp(s, "window_y"))
706  opt |= AGL_WINDOW_Y;
707  if (!ustrcmp(s, "fullscreen"))
708  opt |= AGL_FULLSCREEN;
709  if (!ustrcmp(s, "windowed"))
710  opt |= AGL_WINDOWED;
711  if (!ustrcmp(s, "video_memory_policy"))
713  if (!ustrcmp(s, "sample_buffers"))
714  opt |= AGL_SAMPLE_BUFFERS;
715  if (!ustrcmp(s, "samples"))
716  opt |= AGL_SAMPLES;
717  if (!ustrcmp(s, "float_color"))
718  opt |= AGL_FLOAT_COLOR;
719  if (!ustrcmp(s, "float_depth"))
720  opt |= AGL_FLOAT_Z;
721  }
722 
723  free(buf);
724 
725  allegro_gl_set(sec, opt);
726 }
727 
728 
729 
730 /* void allegro_gl_load_settings() */
742 
743  int set;
744  char *section = "OpenGL";
745 
746  set = get_config_int(section, "allegro_format", -1);
747  if (set != -1)
749  set = get_config_int(section, "red_depth", -1);
750  if (set != -1)
752  set = get_config_int(section, "green_depth", -1);
753  if (set != -1)
755  set = get_config_int(section, "blue_depth", -1);
756  if (set != -1)
758  set = get_config_int(section, "alpha_depth", -1);
759  if (set != -1)
761  set = get_config_int(section, "color_depth", -1);
762  if (set != -1)
764  set = get_config_int(section, "accum_red_depth", -1);
765  if (set != -1)
767  set = get_config_int(section, "accum_green_depth", -1);
768  if (set != -1)
770  set = get_config_int(section, "accum_blue_depth", -1);
771  if (set != -1)
773  set = get_config_int(section, "accum_alpha_depth", -1);
774  if (set != -1)
776  set = get_config_int(section, "double_buffer", -1);
777  if (set != -1)
779  set = get_config_int(section, "stereo_display", -1);
780  if (set != -1)
782  set = get_config_int(section, "aux_buffers", -1);
783  if (set != -1)
785  set = get_config_int(section, "z_depth", -1);
786  if (set != -1)
788  set = get_config_int(section, "stencil_depth", -1);
789  if (set != -1)
791  set = get_config_int(section, "window_x", -1);
792  if (set != -1)
794  set = get_config_int(section, "window_y", -1);
795  if (set != -1)
797  set = get_config_int(section, "fullscreen", -1);
798  if (set != -1)
800  set = get_config_int(section, "windowed", -1);
801  if (set != -1)
803  set = get_config_int(section, "video_memory_policy", -1);
804  if (set != -1)
806  set = get_config_int(section, "sample_buffers", -1);
807  if (set != -1)
809  set = get_config_int(section, "samples", -1);
810  if (set != -1)
812  set = get_config_int(section, "float_color", -1);
813  if (set != -1)
815  set = get_config_int(section, "float_depth", -1);
816  if (set != -1)
818 
819  agl_parse_section(AGL_REQUIRE, section, "require");
820  agl_parse_section(AGL_SUGGEST, section, "suggest");
821 }
822 
823 
824 
825 /* int install_allegro_gl(void) */
837 {
838  if (!system_driver)
839  return -1;
840 
841  if (atexit(remove_allegro_gl))
842  return -1;
843 
844  if (system_driver->gfx_drivers)
845  saved_gfx_drivers = system_driver->gfx_drivers;
846  else
847  saved_gfx_drivers = list_saved_gfx_drivers;
848 
849  system_driver->gfx_drivers = our_gfx_drivers;
850 
852 
853  /* Save and replace old blit_between_formats methods */
854 #ifdef ALLEGRO_COLOR8
855  __blit_between_formats8 = __linear_vtable8.blit_between_formats;
856  __linear_vtable8.blit_between_formats =
857  allegro_gl_memory_blit_between_formats;
858 #endif
859 #ifdef ALLEGRO_COLOR16
860  __blit_between_formats15 = __linear_vtable15.blit_between_formats;
861  __linear_vtable15.blit_between_formats =
862  allegro_gl_memory_blit_between_formats;
863  __blit_between_formats16 = __linear_vtable16.blit_between_formats;
864  __linear_vtable16.blit_between_formats
865  = allegro_gl_memory_blit_between_formats;
866 #endif
867 #ifdef ALLEGRO_COLOR24
868  __blit_between_formats24 = __linear_vtable24.blit_between_formats;
869  __linear_vtable24.blit_between_formats
870  = allegro_gl_memory_blit_between_formats;
871 #endif
872 #ifdef ALLEGRO_COLOR32
873  __blit_between_formats32 = __linear_vtable32.blit_between_formats;
874  __linear_vtable32.blit_between_formats
875  = allegro_gl_memory_blit_between_formats;
876 #endif
877 
878  usetc(allegro_gl_error, 0);
879 
880  return 0;
881 }
882 
883 
884 
885 /* void remove_allegro_gl(void) */
895 {
896  if ((!system_driver) || (!saved_gfx_drivers))
897  return;
898 
899  if (saved_gfx_drivers == &list_saved_gfx_drivers)
900  system_driver->gfx_drivers = NULL;
901  else
902  system_driver->gfx_drivers = saved_gfx_drivers;
903 
904  /* This function may be called twice (once by a user explicit call
905  * and once again at exit since the function is registered with at_exit)
906  * In order to prevent crashes, 'saved_gfx_drivers' is set to NULL
907  */
908  saved_gfx_drivers = NULL;
909 
910  /* Restore the blit_between_formats methods */
911  #ifdef ALLEGRO_COLOR8
912  __linear_vtable8.blit_between_formats = __blit_between_formats8;
913  #endif
914  #ifdef ALLEGRO_COLOR16
915  __linear_vtable15.blit_between_formats = __blit_between_formats15;
916  __linear_vtable16.blit_between_formats = __blit_between_formats16;
917  #endif
918  #ifdef ALLEGRO_COLOR24
919  __linear_vtable24.blit_between_formats = __blit_between_formats24;
920  #endif
921  #ifdef ALLEGRO_COLOR32
922  __linear_vtable32.blit_between_formats = __blit_between_formats32;
923  #endif
924 }
925 
926 
927 
928 /* void allegro_gl_flip(void) */
951 void allegro_gl_flip(void)
952 {
953  __allegro_gl_driver->flip();
954 }
955 
956 
957 
958 /* float allegro_gl_opengl_version() */
972 
973  const char *str;
974 
975  if (!__allegro_gl_valid_context)
976  return 0.0f;
977 
978  str = (const char*)glGetString(GL_VERSION);
979 
980  if ((strncmp(str, "1.0 ", 4) == 0) || (strncmp(str, "1.0.0 ", 6) == 0))
981  return 1.0;
982  if ((strncmp(str, "1.1 ", 4) == 0) || (strncmp(str, "1.1.0 ", 6) == 0))
983  return 1.1;
984  if ((strncmp(str, "1.2 ", 4) == 0) || (strncmp(str, "1.2.0 ", 6) == 0))
985  return 1.2;
986  if ((strncmp(str, "1.2.1 ", 6) == 0))
987  return 1.21;
988  if ((strncmp(str, "1.2.2 ", 6) == 0))
989  return 1.22;
990  if ((strncmp(str, "1.3 ", 4) == 0) || (strncmp(str, "1.3.0 ", 6) == 0))
991  return 1.3;
992  if ((strncmp(str, "1.4 ", 4) == 0) || (strncmp(str, "1.4.0 ", 6) == 0))
993  return 1.4;
994  if ((strncmp(str, "1.5 ", 4) == 0) || (strncmp(str, "1.5.0 ", 6) == 0))
995  return 1.5;
996  if ((strncmp(str, "2.0 ", 4) == 0) || (strncmp(str, "2.0.0 ", 6) == 0))
997  return 2.0;
998  if ((strncmp(str, "2.1 ", 4) == 0) || (strncmp(str, "2.1.0 ", 6) == 0))
999  return 2.1;
1000  if ((strncmp(str, "3.0 ", 4) == 0) || (strncmp(str, "3.0.0 ", 6) == 0))
1001  return 3.0;
1002 
1003  /* The OpenGL driver does not return a version
1004  * number. However it probably supports at least OpenGL 1.0
1005  */
1006  if (!str) {
1007  return 1.0;
1008  }
1009 
1010  return atof(str);
1011 }
1012 
1013 
1014 
1015 void __allegro_gl_set_allegro_image_format(int big_endian)
1016 {
1017  /* Sets up Allegro to use OpenGL formats */
1018  _rgb_r_shift_15 = 11;
1019  _rgb_g_shift_15 = 6;
1020  _rgb_b_shift_15 = 1;
1021 
1022  _rgb_r_shift_16 = 11;
1023  _rgb_g_shift_16 = 5;
1024  _rgb_b_shift_16 = 0;
1025 
1026  if (big_endian) {
1027  _rgb_r_shift_24 = 16;
1028  _rgb_g_shift_24 = 8;
1029  _rgb_b_shift_24 = 0;
1030 
1031  _rgb_a_shift_32 = 0;
1032  _rgb_r_shift_32 = 24;
1033  _rgb_g_shift_32 = 16;
1034  _rgb_b_shift_32 = 8;
1035  }
1036  else {
1037  _rgb_r_shift_24 = 0;
1038  _rgb_g_shift_24 = 8;
1039  _rgb_b_shift_24 = 16;
1040 
1041  _rgb_r_shift_32 = 0;
1042  _rgb_g_shift_32 = 8;
1043  _rgb_b_shift_32 = 16;
1044  _rgb_a_shift_32 = 24;
1045  }
1046 
1047  return;
1048 }
1049 
1050 
1051 
1052 /* allegro_gl_default_init:
1053  * Sets a graphics mode according to the mode (fullscreen or windowed)
1054  * requested by the user. If it fails to set up the mode then it tries
1055  * (if available) the other one unless the user has "AGL_REQUIRED" the mode.
1056  */
1057 static BITMAP *allegro_gl_default_gfx_init(int w, int h, int vw, int vh,
1058  int depth)
1059 {
1060  BITMAP* bmp = NULL;
1061 
1062  if (allegro_gl_display_info.fullscreen) {
1063  TRACE(PREFIX_I "default_gfx_init: Trying to set up fullscreen mode.\n");
1064 
1065 #ifdef GFX_OPENGL_FULLSCREEN
1066  /* Looks for fullscreen mode in our_driver_list */
1067  gfx_driver = &gfx_allegro_gl_fullscreen;
1068 
1069  if (__allegro_gl_required_settings & AGL_FULLSCREEN)
1070  /* Fullscreen mode required and found */
1071  return gfx_allegro_gl_fullscreen.init(w, h, vw, vh, depth);
1072  else
1073  bmp = gfx_allegro_gl_fullscreen.init(w, h, vw, vh, depth);
1074 
1075  if (bmp)
1076  /* Fullscreen mode found but not required (probably suggested) */
1077  return bmp;
1078 
1079 #endif /*GFX_OPENGL_FULLSCREEN*/
1080 
1081  /* Fullscreen mode not available but not required :
1082  * let's try windowed mode :
1083  */
1084  TRACE(PREFIX_I "default_gfx_init: Failed to set up fullscreen mode!\n");
1085 #ifdef GFX_OPENGL_WINDOWED
1086  TRACE(PREFIX_I "default_gfx_init: Trying windowed mode...\n");
1087  allegro_gl_display_info.fullscreen = FALSE;
1088  gfx_driver = &gfx_allegro_gl_windowed;
1089  return gfx_allegro_gl_windowed.init(w, h, vw, vh, depth);
1090 #else
1091  return NULL;
1092 #endif /* GFX_OPENGL_WINDOWED */
1093  }
1094  else {
1095  TRACE(PREFIX_I "default_gfx_init: Trying to set up windowed mode...\n");
1096 
1097 #ifdef GFX_OPENGL_WINDOWED
1098  /* Looks for windowed mode in our_driver_list */
1099  gfx_driver = &gfx_allegro_gl_windowed;
1100 
1101  if (__allegro_gl_required_settings & AGL_WINDOWED)
1102  /* Windowed mode required and found */
1103  return gfx_allegro_gl_windowed.init(w, h, vw, vh, depth);
1104  else
1105  bmp = gfx_allegro_gl_windowed.init(w, h, vw, vh, depth);
1106 
1107  if (bmp)
1108  /* Windowed mode found but not required (probably suggested) */
1109  return bmp;
1110 
1111 #endif /* GFX_OPENGL_WINDOWED */
1112 
1113  /* Windowed mode not available but not required :
1114  * let's try fullscreen mode :
1115  */
1116  TRACE(PREFIX_I "default_gfx_init: Failed to set up windowed mode...\n");
1117 #ifdef GFX_OPENGL_FULLSCREEN
1118  TRACE(PREFIX_I "default_gfx_init: Trying fullscreen mode...\n");
1119  allegro_gl_display_info.fullscreen = TRUE;
1120  gfx_driver = &gfx_allegro_gl_fullscreen;
1121  return gfx_allegro_gl_fullscreen.init(w, h, vw, vh, depth);
1122 #else
1123  return NULL;
1124 #endif /*GFX_OPENGL_FULLSCREEN*/
1125  }
1126 }
1127 
1128 
1129 
1130 /* allegro_gl_set_blender_mode (GFX_DRIVER vtable entry):
1131  * Sets the blending mode. Same implementation to all GFX vtables.
1132  */
1133 void allegro_gl_set_blender_mode(int mode, int r, int g, int b, int a) {
1134  __allegro_gl_blit_operation = AGL_OP_BLEND;
1135  /* These blenders do not need any special extensions.
1136  * We specify only pixel arithmetic here. Blend equation and blend
1137  * color (if available) are reset to defualt later.*/
1138  switch (mode) {
1139  case blender_mode_none:
1140  glBlendFunc(GL_ONE, GL_ZERO);
1141  break;
1142  case blender_mode_alpha:
1143  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1144  break;
1145  case blender_mode_invert:
1146  glLogicOp(GL_COPY_INVERTED);
1147  __allegro_gl_blit_operation = AGL_OP_LOGIC_OP;
1148  break;
1149  case blender_mode_multiply:
1150  glBlendFunc(GL_DST_COLOR, GL_ZERO);
1151  break;
1152  }
1153 
1154  if (allegro_gl_opengl_version() >= 1.4 ||
1155  (allegro_gl_opengl_version() >= 1.2 &&
1156  allegro_gl_is_extension_supported("GL_ARB_imaging"))) {
1157  /* We're running a recent version of OpenGL and everything needed is here. */
1158 
1159  glBlendColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f);
1160 
1161  switch (mode) {
1162  case blender_mode_none:
1163  glBlendEquation(GL_FUNC_ADD);
1164  break;
1165  case blender_mode_alpha:
1166  glBlendEquation(GL_FUNC_ADD);
1167  break;
1168  case blender_mode_trans:
1169  glBlendEquation(GL_FUNC_ADD);
1170  glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
1171  break;
1172  case blender_mode_add:
1173  glBlendEquation(GL_FUNC_ADD);
1174  glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE);
1175  break;
1176  case blender_mode_burn:
1177  glBlendEquation(GL_FUNC_SUBTRACT);
1178  glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA);
1179  break;
1180  case blender_mode_dodge:
1181  glBlendEquation(GL_FUNC_ADD);
1182  glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA);
1183  break;
1184  case blender_mode_multiply:
1185  glBlendEquation(GL_FUNC_ADD);
1186  break;
1187  }
1188 
1189  return;
1190  }
1191 
1192  /* Check for presence of glBlendColor() and special parameters to
1193  * glBlendFunc(). */
1194  if (allegro_gl_is_extension_supported("GL_EXT_blend_color")) {
1195  glBlendColorEXT(r / 255.f, g / 255.f, b / 255.f, a / 255.f);
1196 
1197  switch (mode) {
1198  case blender_mode_trans:
1199  glBlendFunc(GL_CONSTANT_ALPHA_EXT, GL_ONE_MINUS_CONSTANT_ALPHA_EXT);
1200  break;
1201  case blender_mode_add:
1202  glBlendFunc(GL_CONSTANT_ALPHA_EXT, GL_ONE);
1203  break;
1204  case blender_mode_burn:
1205  glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA_EXT);
1206  break;
1207  case blender_mode_dodge:
1208  glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA_EXT);
1209  break;
1210  }
1211  }
1212  else if (mode == blender_mode_trans ||
1213  mode == blender_mode_add ||
1214  mode == blender_mode_burn ||
1215  mode == blender_mode_dodge) {
1216  /* glBlendColor() is not available and it is needed by the selected
1217  * bledner. Bail out.*/
1218  return;
1219  }
1220 
1221  /* Check for presence of glBlendEquation(). */
1222  if (allegro_gl_is_extension_supported("GL_EXT_blend_minmax")) {
1223  switch (mode) {
1224  case blender_mode_none:
1225  glBlendEquationEXT(GL_FUNC_ADD_EXT);
1226  break;
1227  case blender_mode_alpha:
1228  glBlendEquationEXT(GL_FUNC_ADD_EXT);
1229  break;
1230  case blender_mode_trans:
1231  glBlendEquationEXT(GL_FUNC_ADD_EXT);
1232  break;
1233  case blender_mode_add:
1234  glBlendEquationEXT(GL_FUNC_ADD_EXT);
1235  break;
1236  case blender_mode_dodge:
1237  glBlendEquationEXT(GL_FUNC_ADD_EXT);
1238  break;
1239  case blender_mode_multiply:
1240  glBlendEquationEXT(GL_FUNC_ADD_EXT);
1241  break;
1242  case blender_mode_burn:
1243  if (allegro_gl_is_extension_supported("GL_EXT_blend_subtract")) {
1244  glBlendEquationEXT(GL_FUNC_SUBTRACT_EXT);
1245  }
1246  else {
1247  /* GL_FUNC_SUBTRACT is not supported and it is needed by the
1248  * selected blender. Bail out. */
1249  return;
1250  }
1251  break;
1252  }
1253  }
1254 }
1255 
1256 
1257 #ifdef DEBUGMODE
1258 #ifdef LOGLEVEL
1259 
1260 void __allegro_gl_log(int level, const char *str)
1261 {
1262  if (level <= LOGLEVEL)
1263  TRACE(PREFIX_L "[%d] %s", level, str);
1264 }
1265 
1266 #endif
1267 #endif
1268 
#define AGL_KEEP
Keep internal texture in video memory.
Definition: alleggl.h:399
#define AGL_SAMPLE_BUFFERS
Define multisample parameters Some OpenGL ICDs expose an extension called GL_ARB_multisample which pr...
Definition: alleggl.h:361
#define GFX_OPENGL_FULLSCREEN
Fullscreen OpenGL graphics driver for Allegro.
Definition: alleggl.h:435
#define AGL_GREEN_DEPTH
Select the green depth of the frame buffer.
Definition: alleggl.h:205
float allegro_gl_opengl_version()
Returns the OpenGL version number of the client (the computer the program is running on)...
Definition: alleggl.c:971
#define AGL_STEREO
Creates seperate left/right buffers for stereo display.
Definition: alleggl.h:269
#define AGL_REQUIRE
Reject other values for these settings.
Definition: alleggl.h:393
#define AGL_DOUBLEBUFFER
Creates a backbuffer if set.
Definition: alleggl.h:260
int install_allegro_gl(void)
Installs the AllegroGL addon to Allegro.
Definition: alleggl.c:836
int allegro_gl_get(int option)
Reads the setting of a configuration option.
Definition: alleggl.c:421
#define AGL_ALPHA_DEPTH
Select the alpha depth of the frame buffer.
Definition: alleggl.h:218
#define AGL_SUGGEST
Prefer the assigned values for these settings.
Definition: alleggl.h:392
#define AGL_SAMPLES
Define multisample samples Set this value to the number of samples that can be accepted in the multis...
Definition: alleggl.h:369
#define AGL_VIDEO_MEMORY_POLICY
Define AllegroGL&#39;s policy relative to video memory usage.
Definition: alleggl.h:337
void allegro_gl_clear_settings(void)
Clear the option settings All settings are set to their default values, and marked as neither suggest...
Definition: alleggl.c:193
#define AGL_FULLSCREEN
Set if you&#39;d like a full screen mode.
Definition: alleggl.h:315
void remove_allegro_gl(void)
Removes the AllegroGL addon.
Definition: alleggl.c:894
#define AGL_ACC_BLUE_DEPTH
Select the blue depth of the accumulator buffer.
Definition: alleggl.h:246
void allegro_gl_flip(void)
Flips the front and back framebuffers.
Definition: alleggl.c:951
#define AGL_ACC_ALPHA_DEPTH
Select the alpha depth of the accumulator buffer.
Definition: alleggl.h:254
void allegro_gl_save_settings(void)
Saves the current settings (as specified by allegro_gl_set()) to the current config file...
Definition: alleggl.c:560
#define AGL_ACC_GREEN_DEPTH
Select the green depth of the accumulator buffer.
Definition: alleggl.h:238
#define AGL_ALLEGRO_FORMAT
Use Allegro-compatible framebuffer.
Definition: alleggl.h:193
void allegro_gl_set(int option, int value)
Sets a configuration option.
Definition: alleggl.c:274
#define AGL_Z_DEPTH
Select the depth of the z-buffer.
Definition: alleggl.h:282
#define AGL_STENCIL_DEPTH
Select the depth of the stencil buffer.
Definition: alleggl.h:291
#define AGL_FLOAT_COLOR
Floating-point Color buffer.
Definition: alleggl.h:375
#define AGL_WINDOW_X
Requests a placement of the window to a specified pixel location.
Definition: alleggl.h:296
#define GFX_OPENGL
Non-specific OpenGL graphics driver for Allegro.
Definition: alleggl.h:437
#define AGL_DONTCARE
Ignore these settings.
Definition: alleggl.h:391
#define AGL_WINDOW_Y
Same as AGL_WINDOW_X, but for the y-axis.
Definition: alleggl.h:300
#define AGL_COLOR_DEPTH
Specify the total color depth of the frame buffer.
Definition: alleggl.h:223
#define AGL_FLOAT_Z
Floating-point Depth buffer.
Definition: alleggl.h:379
#define AGL_AUX_BUFFERS
Creates additional auxiliary buffers.
Definition: alleggl.h:275
#define GFX_OPENGL_WINDOWED
Windowed OpenGL graphics driver for Allegro.
Definition: alleggl.h:433
int allegro_gl_is_extension_supported(AL_CONST char *extension)
This function is an helper to determine whether an OpenGL extension is available or not...
Definition: glext.c:306
#define AGL_ACC_RED_DEPTH
Select the red depth of the accumulator buffer.
Definition: alleggl.h:231
Main header file for AllegroGL.
#define AGL_BLUE_DEPTH
Select the blue depth of the frame buffer.
Definition: alleggl.h:211
BITMAP * allegro_gl_screen
Direct-mode GL `screen&#39; bitmap.
Definition: alleggl.c:62
#define AGL_WINDOWED
Set if you&#39;d like a windowed mode.
Definition: alleggl.h:320
#define AGL_RED_DEPTH
Select the red depth of the frame buffer.
Definition: alleggl.h:199
#define AGL_RELEASE
Release video memory occupied by internal texture.
Definition: alleggl.h:400
#define AGL_RENDERMETHOD
Set it if you&#39;d like AllegroGL to pay special attention on whether hardware acceleration is present o...
Definition: alleggl.h:310
void allegro_gl_load_settings(void)
Loads the settings from the current config file, in the section [OpenGL].
Definition: alleggl.c:741