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 */
4 /** \file alleggl.c
5 * \brief Allegro-OpenGL interfacing
6 *
7 * This sorts out having Allegro and the OpenGL library sharing a window,
8 * and generally cooperating. */
9
10
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
54 /**
55 * \ingroup updatemodes
56 * \brief Direct-mode GL `screen' bitmap
57 *
58 * If you draw to this bitmap (using supported Allegro functions) your
59 * calls will be converted into OpenGL equivalents and appear on the
60 * screen (or backbuffer).
61 */
62 BITMAP *allegro_gl_screen;
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
our_gfx_drivers(void)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
list_saved_gfx_drivers(void)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
133 /** \addtogroup settings Option settings
134 *
135 * OpenGL has many options controlling the way a video mode is selected.
136 * AllegroGL has functions to set particular options, and to state whether
137 * choices are merely preferences or are essential.
138 *
139 * Use allegro_gl_set() to set options. All options are integers. The value
140 * you set is, by default, ignored; you must tell AllegroGL how important it
141 * is. There are three levels of importance:
142 *
143 * - #AGL_DONTCARE: ignore this setting
144 * - #AGL_SUGGEST: this setting is a preference but not essential
145 * - #AGL_REQUIRE: this setting is important, so don't set a mode without it
146 *
147 * To specify the importance of a setting,
148 * set #AGL_REQUIRE, #AGL_SUGGEST, or #AGL_DONTCARE to contain that setting's
149 * flag, e.g.
150 *
151 * <pre>
152 * allegro_gl_set(#AGL_COLOR_DEPTH, 16);
153 * allegro_gl_set(#AGL_REQUIRE, #AGL_COLOR_DEPTH);
154 * </pre>
155 *
156 * Rather than calling allegro_gl_set once per setting you want to mark as
157 * required, you can OR the setting flags together:
158 *
159 * <pre>
160 * allegro_gl_set(#AGL_REQUIRE, #AGL_COLOR_DEPTH | #AGL_DOUBLEBUFFER);
161 * </pre>
162 *
163 * This has the same effect as marking the two settings separately.
164 *
165 * After saying that you #AGL_REQUIRE a particular setting, you
166 * can still go back and #AGL_DONTCARE or #AGL_SUGGEST it instead -- nothing
167 * happens until you try to set a graphics mode. At that stage, a mode is
168 * set (or set_gfx_mode() returns failure, if not all required settings could
169 * be satisfied), and you can then retrieve the actual settings used by
170 * calling allegro_gl_get(). Note that this is largely untested; some settings
171 * may not be retrieved properly. Please do let us know if you find any!
172 */
173
174
175
176 /* void allegro_gl_clear_settings(void) */
177 /** \ingroup settings
178 * Clear the option settings
179 * All settings are set to their default values, and marked as
180 * neither suggested not required. The mode setting routines will
181 * now ignore all of the settings other than those which you
182 * explicitly mark with #AGL_SUGGEST or #AGL_REQUIRE.
183 *
184 * \note You should not rely on what the default values actually
185 * are - don't mark settings unless you've also assigned something
186 * to them.
187 *
188 * \note Some settings are turned on by default. #AGL_DOUBLEBUFFER,
189 * #AGL_RENDERMETHOD and #AGL_FULLSCREEN are set to #AGL_SUGGEST.
190 *
191 * \sa allegro_gl_set(), allegro_gl_get()
192 */
allegro_gl_clear_settings(void)193 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 =
205 AGL_FULLSCREEN | AGL_RENDERMETHOD | AGL_DOUBLEBUFFER;
206 }
207
208
209
210 /* void allegro_gl_set(int option, int value) */
211 /** \ingroup settings
212 * Sets a configuration option.
213 * Use this routine to configure the framebuffer, *before*
214 * setting a graphics mode. Options are integer constants, and all
215 * values are effectively integers.
216 *
217 * Three of the options are special. #AGL_SUGGEST and
218 * #AGL_REQUIRE are used to mark which of the other options
219 * are merely suggestions and which are absolute requirements. If
220 * the OpenGL implementation can't provide a feature which you mark
221 * with #AGL_REQUIRE, the call to set_gfx_mode will fail.
222 * If you don't mark an option as either suggested or required, that
223 * option will be ignored (#AGL_DONTCARE).
224 * You can OR (|) together the other constants when using one of
225 * these three options to indicate your preferences for several
226 * settings at one time. Selecting an option as one of the suggestion
227 * modes will remove it from the others. For example, if you first set
228 * the color depth to be required, but then decide that you want it to be
229 * suggested instead, then the option will be removed from the required
230 * settings. Setting any option to #AGL_DONTCARE will remove any previous
231 * setting attributed to it, and default values will be used if necessary.
232 *
233 * The remaining options are:
234 * <pre>
235 * #AGL_ALLEGRO_FORMAT,
236 * #AGL_RED_DEPTH,
237 * #AGL_GREEN_DEPTH,
238 * #AGL_BLUE_DEPTH,
239 * #AGL_ALPHA_DEPTH,
240 * #AGL_COLOR_DEPTH,
241 * #AGL_ACC_RED_DEPTH,
242 * #AGL_ACC_GREEN_DEPTH,
243 * #AGL_ACC_BLUE_DEPTH,
244 * #AGL_ACC_ALPHA_DEPTH,
245 * #AGL_DOUBLEBUFFER,
246 * #AGL_STEREO,
247 * #AGL_AUX_BUFFERS,
248 * #AGL_Z_DEPTH,
249 * #AGL_STENCIL_DEPTH,
250 * #AGL_WINDOW_X,
251 * #AGL_WINDOW_Y,
252 * #AGL_RENDERMETHOD
253 * #AGL_FULLSCREEN
254 * #AGL_WINDOWED
255 * #AGL_VIDEO_MEMORY_POLICY
256 * #AGL_SAMPLE_BUFFERS
257 * #AGL_SAMPLES
258 * #AGL_FLOAT_COLOR
259 * #AGL_FLOAT_Z
260 * </pre>
261 *
262 * \param option Selects which option to change.
263 * \param value The new option value.
264 *
265 * \b Example:
266 * <pre>
267 * allegro_gl_set(#AGL_COLOR_DEPTH, 32);
268 * allegro_gl_set(#AGL_RENDERMETHOD, 1);
269 * allegro_gl_set(#AGL_REQUIRE, #AGL_COLOR_DEPTH | #AGL_RENDERMETHOD);
270 * </pre>
271 *
272 * \sa allegro_gl_get(), allegro_gl_clear_settings()
273 */
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:
310 allegro_gl_set(AGL_RED_DEPTH, 3);
311 allegro_gl_set(AGL_GREEN_DEPTH, 3);
312 allegro_gl_set(AGL_BLUE_DEPTH, 2);
313 allegro_gl_set(AGL_ALPHA_DEPTH, 0);
314 break;
315 case 15:
316 allegro_gl_set(AGL_RED_DEPTH, 5);
317 allegro_gl_set(AGL_GREEN_DEPTH, 5);
318 allegro_gl_set(AGL_BLUE_DEPTH, 5);
319 allegro_gl_set(AGL_ALPHA_DEPTH, 1);
320 break;
321 case 16:
322 allegro_gl_set(AGL_RED_DEPTH, 5);
323 allegro_gl_set(AGL_GREEN_DEPTH, 6);
324 allegro_gl_set(AGL_BLUE_DEPTH, 5);
325 allegro_gl_set(AGL_ALPHA_DEPTH, 0);
326 break;
327 case 24:
328 case 32:
329 allegro_gl_set(AGL_RED_DEPTH, 8);
330 allegro_gl_set(AGL_GREEN_DEPTH, 8);
331 allegro_gl_set(AGL_BLUE_DEPTH, 8);
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;
384 case AGL_VIDEO_MEMORY_POLICY:
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
405 /** \ingroup settings
406 * Reads the setting of a configuration option.
407 *
408 * This routine can be used to read back the configuration of
409 * the framebuffer. You can do this either before setting a graphics
410 * mode to check what configuration you are requesting, or afterwards
411 * to find out what settings were actually used.
412 * For a list of option constants, see documentation for allegro_gl_set().
413 *
414 * \param option The option to have its value returned.
415 *
416 * \return The value of the option selected by the parameter,
417 * or -1 if the option is invalid.
418 *
419 * \sa allegro_gl_set(), allegro_gl_clear_settings()
420 */
allegro_gl_get(int option)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;
475 case AGL_VIDEO_MEMORY_POLICY:
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 */
build_settings(int opt,char * section,char * name)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() */
554 /** \ingroup settings
555 * Saves the current settings (as specified by allegro_gl_set()) to
556 * the current config file, in the section [OpenGL].
557 *
558 * \sa allegro_gl_load_settings()
559 */
allegro_gl_save_settings()560 void allegro_gl_save_settings() {
561
562 char *section = "OpenGL";
563 int save = allegro_gl_get(AGL_REQUIRE) | allegro_gl_get(AGL_SUGGEST);
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 */
agl_parse_section(int sec,char * section,char * name)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"))
712 opt |= AGL_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() */
731 /** \ingroup settings
732 *
733 * Loads the settings from the current config file, in the
734 * section [OpenGL].
735 * Note that this function will not clear any settings currently
736 * set, but will add them up, as if each of the setting were set
737 * manually.
738 *
739 * \sa allegro_gl_save_settings()
740 */
allegro_gl_load_settings()741 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)
748 allegro_gl_set(AGL_ALLEGRO_FORMAT, set);
749 set = get_config_int(section, "red_depth", -1);
750 if (set != -1)
751 allegro_gl_set(AGL_RED_DEPTH, set);
752 set = get_config_int(section, "green_depth", -1);
753 if (set != -1)
754 allegro_gl_set(AGL_GREEN_DEPTH, set);
755 set = get_config_int(section, "blue_depth", -1);
756 if (set != -1)
757 allegro_gl_set(AGL_BLUE_DEPTH, set);
758 set = get_config_int(section, "alpha_depth", -1);
759 if (set != -1)
760 allegro_gl_set(AGL_ALPHA_DEPTH, set);
761 set = get_config_int(section, "color_depth", -1);
762 if (set != -1)
763 allegro_gl_set(AGL_COLOR_DEPTH, set);
764 set = get_config_int(section, "accum_red_depth", -1);
765 if (set != -1)
766 allegro_gl_set(AGL_ACC_RED_DEPTH, set);
767 set = get_config_int(section, "accum_green_depth", -1);
768 if (set != -1)
769 allegro_gl_set(AGL_ACC_GREEN_DEPTH, set);
770 set = get_config_int(section, "accum_blue_depth", -1);
771 if (set != -1)
772 allegro_gl_set(AGL_ACC_BLUE_DEPTH, set);
773 set = get_config_int(section, "accum_alpha_depth", -1);
774 if (set != -1)
775 allegro_gl_set(AGL_ACC_ALPHA_DEPTH, set);
776 set = get_config_int(section, "double_buffer", -1);
777 if (set != -1)
778 allegro_gl_set(AGL_DOUBLEBUFFER, set);
779 set = get_config_int(section, "stereo_display", -1);
780 if (set != -1)
781 allegro_gl_set(AGL_STEREO, set);
782 set = get_config_int(section, "aux_buffers", -1);
783 if (set != -1)
784 allegro_gl_set(AGL_AUX_BUFFERS, set);
785 set = get_config_int(section, "z_depth", -1);
786 if (set != -1)
787 allegro_gl_set(AGL_Z_DEPTH, set);
788 set = get_config_int(section, "stencil_depth", -1);
789 if (set != -1)
790 allegro_gl_set(AGL_STENCIL_DEPTH, set);
791 set = get_config_int(section, "window_x", -1);
792 if (set != -1)
793 allegro_gl_set(AGL_WINDOW_X, set);
794 set = get_config_int(section, "window_y", -1);
795 if (set != -1)
796 allegro_gl_set(AGL_WINDOW_Y, set);
797 set = get_config_int(section, "fullscreen", -1);
798 if (set != -1)
799 allegro_gl_set(AGL_FULLSCREEN, set);
800 set = get_config_int(section, "windowed", -1);
801 if (set != -1)
802 allegro_gl_set(AGL_WINDOWED, set);
803 set = get_config_int(section, "video_memory_policy", -1);
804 if (set != -1)
805 allegro_gl_set(AGL_VIDEO_MEMORY_POLICY, set);
806 set = get_config_int(section, "sample_buffers", -1);
807 if (set != -1)
808 allegro_gl_set(AGL_SAMPLE_BUFFERS, set);
809 set = get_config_int(section, "samples", -1);
810 if (set != -1)
811 allegro_gl_set(AGL_SAMPLES, set);
812 set = get_config_int(section, "float_color", -1);
813 if (set != -1)
814 allegro_gl_set(AGL_FLOAT_COLOR, set);
815 set = get_config_int(section, "float_depth", -1);
816 if (set != -1)
817 allegro_gl_set(AGL_FLOAT_Z, set);
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) */
826 /** \ingroup core
827 *
828 * Installs the AllegroGL addon to Allegro.
829 * Allegro should already be initialized with allegro_init()
830 * or install_allegro().
831 *
832 * \return 0 on success; -1 on failure.
833 *
834 * \see remove_allegro_gl()
835 */
install_allegro_gl(void)836 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
851 allegro_gl_clear_settings();
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) */
886 /** \ingroup core
887 * Removes the AllegroGL addon. You should not call any more OpenGL
888 * or AllegroGL functions after calling this function. Note that
889 * it will be called automatically at program exit, so you don't need
890 * to explicitly do it.
891 *
892 * \see install_allegro_gl()
893 */
remove_allegro_gl(void)894 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) */
929 /** \ingroup core
930 * Flips the front and back framebuffers.
931 *
932 * If you chose, or were given, a double buffered OpenGL mode, you have
933 * access to a front buffer, which is visible on the screen, and also a
934 * back buffer, which is not visible. This routine flips the buffers,
935 * so that the contents of the back buffer is now the contents of the
936 * (visible) front buffer. The contents of the backbuffer is undefined
937 * after the operation.
938 *
939 * Normally in these modes you would do all your drawing to the back
940 * buffer, without the user seeing the image while it's partially drawn,
941 * and then call this function to flip the buffers, allowing the user
942 * to see what you've drawn, now that it's finished, while you proceed to
943 * draw the next frame.
944 *
945 * When drawing to the screen bitmap, you may not be drawing to what user
946 * currently sees on his monitor. It is recommended that you rebuild the
947 * screen every frame, then flip, then draw again.
948 *
949 * \sa allegro_gl_set(), AGL_DOUBLEBUFFER
950 */
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() */
959 /** \ingroup core
960 *
961 * Returns the OpenGL version number of the client
962 * (the computer the program is running on).
963 * "1.0" is returned as 1.0, "1.2.1" is returned as 1.21,
964 * and "1.2.2" as 1.22, etc.
965 *
966 * A valid OpenGL context must exist for this function to work, which
967 * means you may \b not call it before set_gfx_mode(GFX_OPENGL)
968 *
969 * \return The OpenGL ICD/MCD version number.
970 */
allegro_gl_opengl_version()971 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
__allegro_gl_set_allegro_image_format(int big_endian)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 */
allegro_gl_default_gfx_init(int w,int h,int vw,int vh,int depth)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 */
allegro_gl_set_blender_mode(int mode,int r,int g,int b,int a)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
__allegro_gl_log(int level,const char * str)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
1269