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