AllegroGL  0.4.4
videovtb.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  */
9 #include <string.h>
10 #include <limits.h>
11 
12 #include <allegro.h>
13 
14 #ifdef ALLEGRO_WINDOWS
15 #include <winalleg.h>
16 #endif
17 
18 #include "alleggl.h"
19 #include "allglint.h"
20 #include "glvtable.h"
21 #include <allegro/internal/aintern.h>
22 #ifdef ALLEGRO_MACOSX
23 #include <OpenGL/glu.h>
24 #else
25 #include <GL/glu.h>
26 #endif
27 
28 
29 #define MASKED_BLIT 1
30 #define BLIT 2
31 #define TRANS 3
32 
33 
34 static GFX_VTABLE allegro_gl_video_vtable;
35 
36 /* Counter for video bitmaps. screen = 1 */
37 static int video_bitmap_count = 2;
38 
39 static int __allegro_gl_video_bitmap_bpp = -1;
40 
41 extern BITMAP *__agl_drawing_pattern_bmp;
42 BITMAP *old_pattern = NULL;
43 
44 void allegro_gl_destroy_video_bitmap(BITMAP *bmp);
45 
46 
47 
48 static int allegro_gl_make_video_bitmap_helper1(int w, int h, int x, int y,
49  GLint target, AGL_VIDEO_BITMAP **pvid) {
50 
51  int internal_format;
52  int bpp;
53 
54  if (__allegro_gl_video_bitmap_bpp == -1) {
55  bpp = bitmap_color_depth(screen);
56  }
57  else {
58  bpp = __allegro_gl_video_bitmap_bpp;
59  }
60 
61  (*pvid) = malloc(sizeof(AGL_VIDEO_BITMAP));
62 
63  if (!(*pvid))
64  return -1;
65 
66  memset(*pvid, 0, sizeof(AGL_VIDEO_BITMAP));
67 
68  /* Create associated bitmap */
69  (*pvid)->memory_copy = create_bitmap_ex(bpp, w, h);
70  if (!(*pvid)->memory_copy)
71  return -1;
72 
73  (*pvid)->format = __allegro_gl_get_bitmap_color_format((*pvid)->memory_copy, AGL_TEXTURE_HAS_ALPHA);
74  (*pvid)->type = __allegro_gl_get_bitmap_type((*pvid)->memory_copy, 0);
75  internal_format = __allegro_gl_get_texture_format_ex((*pvid)->memory_copy, AGL_TEXTURE_HAS_ALPHA);
76 
77  (*pvid)->target = target;
78 
79  /* Fill in some values in the bitmap to make it act as a subbitmap
80  */
81  (*pvid)->width = w;
82  (*pvid)->height = h;
83  (*pvid)->x_ofs = x;
84  (*pvid)->y_ofs = y;
85 
86  /* Make a texture out of it */
87  glGenTextures(1, &((*pvid)->tex));
88  if (!((*pvid)->tex))
89  return -1;
90 
91  glEnable((*pvid)->target);
92  glBindTexture((*pvid)->target, ((*pvid)->tex));
93 
94  glTexImage2D((*pvid)->target, 0, internal_format, w, h,
95  0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
96 
97  /* By default, use the Allegro filtering mode - ie: Nearest */
98  glTexParameteri((*pvid)->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
99  glTexParameteri((*pvid)->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
100 
101  /* <mmimica>
102  Clamping removed because we want video bitmaps that are set for
103  patterned drawing to be GL_REPEAT (default wrapping mode). Doesn't
104  seem to break anything.
105  */
106 #if 0
107  /* Clamp to edge */
108  {
109  GLenum clamp = GL_CLAMP_TO_EDGE;
110  if (!allegro_gl_extensions_GL.SGIS_texture_edge_clamp) {
111  clamp = GL_CLAMP;
112  }
113  glTexParameteri((*pvid)->target, GL_TEXTURE_WRAP_S, clamp);
114  glTexParameteri((*pvid)->target, GL_TEXTURE_WRAP_T, clamp);
115  }
116 #endif
117 
118  glDisable((*pvid)->target);
119 
120  if (allegro_gl_extensions_GL.EXT_framebuffer_object) {
121  glGenFramebuffersEXT(1, &((*pvid)->fbo));
122  if (!(*pvid)->fbo) {
123  glDeleteTextures(1, &((*pvid)->tex));
124  return -1;
125  }
126 
127  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (*pvid)->fbo);
128  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, (*pvid)->target, (*pvid)->tex, 0);
129  if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
130  /* Some FBO implementation limitation was hit, will use normal textures. */
131  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
132  glDeleteFramebuffersEXT(1, &((*pvid)->fbo));
133  (*pvid)->fbo = 0;
134  return 0;
135  }
136 
137  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
138  }
139  else {
140  (*pvid)->fbo = 0;
141  }
142 
143  return 0;
144 }
145 
146 
147 
148 static int allegro_gl_make_video_bitmap_helper0(int w, int h, int x, int y,
149  AGL_VIDEO_BITMAP **pvid) {
150 
151  int is_power_of_2 = (!(w & (w - 1)) && !(h & (h - 1)));
152  int texture_rect_available = allegro_gl_extensions_GL.ARB_texture_rectangle
153 #ifdef ALLEGRO_MACOSX
154  || allegro_gl_extensions_GL.EXT_texture_rectangle
155 #endif
156  || allegro_gl_extensions_GL.NV_texture_rectangle;
157  GLint max_rect_texture_size = 0;
158 
159  if (texture_rect_available) {
160  glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &max_rect_texture_size);
161  }
162 
163  if (w <= allegro_gl_info.max_texture_size &&
164  h <= allegro_gl_info.max_texture_size) {
165  if (allegro_gl_extensions_GL.ARB_texture_non_power_of_two ||
166  is_power_of_2) {
167  if (allegro_gl_make_video_bitmap_helper1(w, h, x, y,
168  GL_TEXTURE_2D, pvid)) {
169  return -1;
170  }
171  }
172  else if (texture_rect_available &&
173  w <= max_rect_texture_size &&
174  h <= max_rect_texture_size) {
175  if (allegro_gl_make_video_bitmap_helper1(w, h, x, y,
176  GL_TEXTURE_RECTANGLE_ARB, pvid)) {
177  return -1;
178  }
179  }
180  else {
181  /* NPO2 textures are not suppored by the driver in any way.
182  * Split the bitmap into smaller POT bitmaps. */
183  const unsigned int BITS = sizeof(int) * CHAR_BIT;
184  unsigned int i, j;
185  unsigned int w1, h1;
186  unsigned int x1, y1;
187  unsigned int p1, p2;
188 
189  /* Find the POTs using bits. */
190  y1 = 0;
191  for (i = 0; i < BITS; i++) {
192  p1 = 1 << i;
193  if (h & p1)
194  h1 = p1;
195  else
196  continue;
197 
198  x1 = 0;
199  for (j = 0; j < BITS; j++) {
200  p2 = 1 << j;
201  if (w & p2)
202  w1 = p2;
203  else
204  continue;
205 
206  if (allegro_gl_make_video_bitmap_helper0(w1, h1, x + x1,
207  y + y1, pvid)) {
208  return -1;
209  }
210  do {
211  pvid = &((*pvid)->next);
212  } while (*pvid);
213 
214  x1 += w1;
215  }
216 
217  y1 += h1;
218  }
219  }
220  }
221  else {
222  /* Texture is too big to fit. Split it in 4 and try again. */
223  int w1, w2, h1, h2;
224 
225  w2 = w / 2;
226  w1 = w - w2;
227 
228  h2 = h / 2;
229  h1 = h - h2;
230 
231  /* Even a 1x1 texture didn't work? Bail*/
232  if (!w2 && !h2) {
233  return -1;
234  }
235 
236  /* Top-left corner */
237  if (allegro_gl_make_video_bitmap_helper0(w1, h1, x, y, pvid)) {
238  return -1;
239  }
240  do {
241  pvid = &((*pvid)->next);
242  } while (*pvid);
243 
244  /* Top-right corner */
245  if (w2) {
246  if (allegro_gl_make_video_bitmap_helper0(w2, h1, x + w1, y, pvid)) {
247  return -1;
248  }
249  do {
250  pvid = &((*pvid)->next);
251  } while (*pvid);
252  }
253  /* Bottom-left corner */
254  if (h2) {
255  if (allegro_gl_make_video_bitmap_helper0(w1, h2, x, y + h1, pvid)) {
256  return -1;
257  }
258  do {
259  pvid = &((*pvid)->next);
260  } while (*pvid);
261  }
262  /* Bottom-right corner */
263  if (w2 && h2) {
264  if (allegro_gl_make_video_bitmap_helper0(w2, h2, x + w1, y + h1, pvid)) {
265  return -1;
266  }
267  do {
268  pvid = &((*pvid)->next);
269  } while (*pvid);
270  }
271  }
272 
273  return 0;
274 }
275 
276 
277 
278 /* Will make a (potentially piece-wise) texture out of the specified bitmap
279  * Source -must- be a memory bitmap or memory subbitmap (created by Allegro
280  * only).
281  *
282  */
283 static BITMAP *allegro_gl_make_video_bitmap(BITMAP *bmp) {
284 
285  /* Grab a pointer to the bitmap data to patch */
286  void *ptr = &bmp->extra;
287  AGL_VIDEO_BITMAP **pvid = (AGL_VIDEO_BITMAP**)ptr;
288 
289  /* Convert bitmap to texture */
290  if (allegro_gl_make_video_bitmap_helper0(bmp->w, bmp->h, 0, 0, pvid)) {
291  goto agl_error;
292  }
293 
294  return bmp;
295 
296 agl_error:
298  return NULL;
299 }
300 
301 
302 
303 /* void allegro_gl_destroy_video_bitmap(BITMAP *bmp) */
309 
310  AGL_VIDEO_BITMAP *vid = bmp ? bmp->extra : NULL, *next;
311 
312  if (!bmp)
313  return;
314 
315  while (vid) {
316  if (vid->memory_copy)
317  destroy_bitmap(vid->memory_copy);
318 
319  if (vid->tex)
320  glDeleteTextures(1, &vid->tex);
321 
322  if (vid->fbo)
323  glDeleteFramebuffersEXT(1, &vid->fbo);
324 
325  next = vid->next;
326  free(vid);
327  vid = next;
328  }
329 
330  free(bmp->vtable);
331  free(bmp);
332 
333  return;
334 }
335 
336 
337 
338 /* BITMAP *allegro_gl_create_video_bitmap(int w, int h) */
344 BITMAP *allegro_gl_create_video_bitmap(int w, int h) {
345  GFX_VTABLE *vtable;
346  BITMAP *bitmap;
347 
348  bitmap = malloc(sizeof(BITMAP) + sizeof(char *));
349 
350  if (!bitmap)
351  return NULL;
352 
353  bitmap->dat = NULL;
354  bitmap->w = bitmap->cr = w;
355  bitmap->h = bitmap->cb = h;
356  bitmap->clip = TRUE;
357  bitmap->cl = bitmap->ct = 0;
358  bitmap->write_bank = bitmap->read_bank = NULL;
359  /* We should keep tracks of allocated bitmaps for the ref counter */
360  bitmap->id = BMP_ID_VIDEO | video_bitmap_count;
361  bitmap->extra = NULL;
362  bitmap->x_ofs = 0;
363  bitmap->y_ofs = 0;
364  bitmap->seg = _default_ds();
365  bitmap->line[0] = NULL;
366  bitmap->vtable = NULL;
367 
368  if (!allegro_gl_make_video_bitmap(bitmap)) {
369  return NULL;
370  }
371  video_bitmap_count++;
372 
373  /* XXX <rohannessian> We ought to leave the Allegro values intact
374  * Avoids bad interaction with correct Allegro programs.
375  */
376  vtable = malloc(sizeof(struct GFX_VTABLE));
377  *vtable = allegro_gl_video_vtable;
378  if (__allegro_gl_video_bitmap_bpp == -1) {
379  vtable->color_depth = bitmap_color_depth(screen);
380  }
381  else {
382  vtable->color_depth = __allegro_gl_video_bitmap_bpp;
383  }
384  switch (vtable->color_depth) {
385  case 8:
386  vtable->mask_color = MASK_COLOR_8;
387  break;
388  case 15:
389  vtable->mask_color = MASK_COLOR_15;
390  break;
391  case 16:
392  vtable->mask_color = MASK_COLOR_16;
393  break;
394  case 24:
395  vtable->mask_color = MASK_COLOR_24;
396  break;
397  case 32:
398  vtable->mask_color = MASK_COLOR_32;
399  break;
400  }
401  bitmap->vtable = vtable;
402 
403  return bitmap;
404 }
405 
406 
407 
408 /* allegro_gl_set_video_bitmap_color_depth(int bpp) */
424  GLint old_val = __allegro_gl_video_bitmap_bpp;
425  __allegro_gl_video_bitmap_bpp = bpp;
426  return old_val;
427 }
428 
429 
430 /* static void allegro_gl_video_acquire(struct BITMAP *bmp) */
437 static void allegro_gl_video_acquire(struct BITMAP *bmp) {}
438 
439 
440 
441 /* static void allegro_gl_video_release(struct BITMAP *bmp) */
448 static void allegro_gl_video_release(struct BITMAP *bmp) {}
449 
450 
451 
452 static void set_drawing_pattern(void)
453 {
454  if (_drawing_pattern && !is_memory_bitmap(_drawing_pattern)) {
455  old_pattern = _drawing_pattern;
456  drawing_mode(_drawing_mode, __agl_drawing_pattern_bmp,
457  _drawing_x_anchor, _drawing_y_anchor);
458  }
459 }
460 
461 
462 
463 static void unset_drawing_pattern(void)
464 {
465  if (old_pattern) {
466  drawing_mode(_drawing_mode, old_pattern,
467  _drawing_x_anchor, _drawing_y_anchor);
468  old_pattern = NULL;
469  }
470 }
471 
472 
473 
474 static int allegro_gl_video_getpixel(struct BITMAP *bmp, int x, int y)
475 {
476  int pix = -1;
477  AGL_VIDEO_BITMAP *vid;
478  AGL_LOG(2, "glvtable.c:allegro_gl_screen_getpixel\n");
479 
480  if (is_sub_bitmap(bmp)) {
481  x += bmp->x_ofs;
482  y += bmp->y_ofs;
483  }
484  if (x < bmp->cl || x >= bmp->cr || y < bmp->ct || y >= bmp->cb) {
485  return -1;
486  }
487 
488  vid = bmp->extra;
489 
490  while (vid) {
491  if (vid->x_ofs <= x && vid->y_ofs <= y
492  && vid->x_ofs + vid->memory_copy->w > x
493  && vid->y_ofs + vid->memory_copy->h > y) {
494 
495  pix = getpixel(vid->memory_copy, x - vid->x_ofs, y - vid->y_ofs);
496  break;
497  }
498  vid = vid->next;
499  }
500 
501  if (pix != -1) {
502  return pix;
503  }
504 
505  return -1;
506 }
507 
508 
509 
510 static void update_texture_memory(AGL_VIDEO_BITMAP *vid, int x1, int y1,
511  int x2, int y2) {
512  GLint saved_row_length;
513  GLint saved_alignment;
514  GLint type;
515  GLint format;
516  int bpp;
517  BITMAP *temp = NULL;
518  BITMAP *vbmp = vid->memory_copy;;
519 
520  glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
521  glGetIntegerv(GL_UNPACK_ALIGNMENT, &saved_alignment);
522 
523  bpp = BYTES_PER_PIXEL(bitmap_color_depth(vid->memory_copy));
524  format = vid->format;
525  type = vid->type;
526 
527  glColor4ub(255, 255, 255, 255);
528 
529  /* If packed pixels (or GL 1.2) isn't supported, then we need to convert
530  * the bitmap into something GL can understand - 24-bpp should do it.
531  */
532  if (!allegro_gl_extensions_GL.EXT_packed_pixels
533  && bitmap_color_depth(vbmp) < 24) {
534  temp = create_bitmap_ex(24, vbmp->w, vbmp->h);
535  if (!temp)
536  return;
537 
538  blit(vbmp, temp, 0, 0, 0, 0, temp->w, temp->h);
539  vbmp = temp;
540  bpp = BYTES_PER_PIXEL(bitmap_color_depth(vbmp));
541  format = __allegro_gl_get_bitmap_color_format(vbmp, 0);
542  type = __allegro_gl_get_bitmap_type(vbmp, 0);
543  }
544 
545  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
546  glPixelStorei(GL_UNPACK_ROW_LENGTH,
547  vbmp->h > 1
548  ? (vbmp->line[1] - vbmp->line[0]) / bpp
549  : vbmp->w);
550 
551  glEnable(vid->target);
552  glBindTexture(vid->target, vid->tex);
553  glTexSubImage2D(vid->target, 0,
554  x1, y1, x2 - x1 + 1, y2 - y1 + 1, format,
555  type, vbmp->line[y1] + x1 * bpp);
556  glBindTexture(vid->target, 0);
557  glDisable(vid->target);
558 
559  if (temp)
560  destroy_bitmap(temp);
561 
562  glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
563  glPixelStorei(GL_UNPACK_ALIGNMENT, saved_alignment);
564 }
565 
566 
567 
568 static void allegro_gl_video_putpixel(struct BITMAP *bmp, int x, int y,
569  int color) {
570  AGL_VIDEO_BITMAP *vid;
571 
572  if (is_sub_bitmap(bmp)) {
573  x += bmp->x_ofs;
574  y += bmp->y_ofs;
575  }
576  if (x < bmp->cl || x >= bmp->cr || y < bmp->ct || y >= bmp->cb) {
577  return;
578  }
579 
580  vid = bmp->extra;
581 
582  while (vid) {
583  if (vid->x_ofs <= x && vid->y_ofs <= y
584  && vid->x_ofs + vid->memory_copy->w > x
585  && vid->y_ofs + vid->memory_copy->h > y) {
586 
587  set_drawing_pattern();
588  putpixel(vid->memory_copy, x - vid->x_ofs, y - vid->y_ofs, color);
589  unset_drawing_pattern();
590  update_texture_memory(vid, x - vid->x_ofs, y - vid->y_ofs, x - vid->x_ofs, y - vid->y_ofs);
591  break;
592  }
593  vid = vid->next;
594  }
595 
596  return;
597 }
598 
599 
600 
601 static void allegro_gl_video_vline(BITMAP *bmp, int x, int y1, int y2,
602  int color) {
603 
604  AGL_VIDEO_BITMAP *vid;
605 
606  AGL_LOG(2, "glvtable.c:allegro_gl_video_vline\n");
607  vid = bmp->extra;
608 
609  if (is_sub_bitmap(bmp)) {
610  x += bmp->x_ofs;
611  y1 += bmp->y_ofs;
612  y2 += bmp->y_ofs;
613  }
614  if (x < bmp->cl || x >= bmp->cr) {
615  return;
616  }
617 
618  if (y1 > y2) {
619  int temp = y1;
620  y1 = y2;
621  y2 = temp;
622  }
623 
624  if (y1 < bmp->ct) {
625  y1 = bmp->ct;
626  }
627  if (y2 >= bmp->cb) {
628  y2 = bmp->cb - 1;
629  }
630 
631  while (vid) {
632  BITMAP *vbmp = vid->memory_copy;
633 
634  int _y1, _y2, _x;
635  if (vid->x_ofs > x || vid->y_ofs > y2
636  || vid->x_ofs + vbmp->w <= x
637  || vid->y_ofs + vbmp->h <= y1) {
638 
639  vid = vid->next;
640  continue;
641  }
642 
643  _y1 = MAX(y1, vid->y_ofs) - vid->y_ofs;
644  _y2 = MIN(y2, vid->y_ofs + vbmp->h - 1) - vid->y_ofs;
645  _x = x - vid->x_ofs;
646 
647  set_drawing_pattern();
648  vline(vbmp, _x, _y1, _y2, color);
649  unset_drawing_pattern();
650  update_texture_memory(vid, _x, _y1, _x, _y2);
651 
652  vid = vid->next;
653  }
654 
655  return;
656 }
657 
658 
659 
660 static void allegro_gl_video_hline(BITMAP *bmp, int x1, int y, int x2,
661  int color) {
662 
663  AGL_VIDEO_BITMAP *vid;
664 
665  AGL_LOG(2, "glvtable.c:allegro_gl_video_hline\n");
666  vid = bmp->extra;
667 
668  if (is_sub_bitmap(bmp)) {
669  x1 += bmp->x_ofs;
670  x2 += bmp->x_ofs;
671  y += bmp->y_ofs;
672  }
673 
674  if (y < bmp->ct || y >= bmp->cb) {
675  return;
676  }
677 
678  if (x1 > x2) {
679  int temp = x1;
680  x1 = x2;
681  x2 = temp;
682  }
683 
684  if (x1 < bmp->cl) {
685  x1 = bmp->cl;
686  }
687  if (x2 >= bmp->cr) {
688  x2 = bmp->cr - 1;
689  }
690 
691  while (vid) {
692  BITMAP *vbmp = vid->memory_copy;
693 
694  int _x1, _x2, _y;
695  if (vid->y_ofs > y || vid->x_ofs > x2
696  || vid->x_ofs + vbmp->w <= x1
697  || vid->y_ofs + vbmp->h <= y) {
698 
699  vid = vid->next;
700  continue;
701  }
702 
703  _x1 = MAX(x1, vid->x_ofs) - vid->x_ofs;
704  _x2 = MIN(x2, vid->x_ofs + vbmp->w - 1) - vid->x_ofs;
705  _y = y - vid->y_ofs;
706 
707  set_drawing_pattern();
708  hline(vbmp, _x1, _y, _x2, color);
709  unset_drawing_pattern();
710  update_texture_memory(vid, _x1, _y, _x2, _y);
711 
712  vid = vid->next;
713  }
714 
715  return;
716 }
717 
718 
719 
720 static void allegro_gl_video_line(struct BITMAP *bmp, int x1, int y1, int x2,
721  int y2, int color) {
722 
723  /* Note: very very slow */
724  do_line(bmp, x1, y1, x2, y2, color, allegro_gl_video_putpixel);
725 
726  return;
727 }
728 
729 
730 
731 static void allegro_gl_video_rectfill(struct BITMAP *bmp, int x1, int y1,
732  int x2, int y2, int color) {
733 
734  AGL_VIDEO_BITMAP *vid;
735 
736  AGL_LOG(2, "glvtable.c:allegro_gl_video_rectfill\n");
737  vid = bmp->extra;
738 
739  if (is_sub_bitmap(bmp)) {
740  x1 += bmp->x_ofs;
741  x2 += bmp->x_ofs;
742  y1 += bmp->y_ofs;
743  y2 += bmp->y_ofs;
744  }
745 
746  if (y1 > y2) {
747  int temp = y1;
748  y1 = y2;
749  y2 = temp;
750  }
751 
752  if (x1 > x2) {
753  int temp = x1;
754  x1 = x2;
755  x2 = temp;
756  }
757 
758  if (x1 < bmp->cl) {
759  x1 = bmp->cl;
760  }
761  if (x2 > bmp->cr) {
762  x2 = bmp->cr;
763  }
764  if (y1 < bmp->ct) {
765  y1 = bmp->ct;
766  }
767  if (y1 > bmp->cb) {
768  y1 = bmp->cb;
769  }
770 
771  while (vid) {
772  BITMAP *vbmp = vid->memory_copy;
773 
774  int _y1, _y2, _x1, _x2;
775  if (vid->x_ofs > x2 || vid->y_ofs > y2
776  || vid->x_ofs + vbmp->w <= x1
777  || vid->y_ofs + vbmp->h <= y1) {
778 
779  vid = vid->next;
780  continue;
781  }
782 
783  _y1 = MAX(y1, vid->y_ofs) - vid->y_ofs;
784  _y2 = MIN(y2, vid->y_ofs + vbmp->h - 1) - vid->y_ofs;
785  _x1 = MAX(x1, vid->x_ofs) - vid->x_ofs;
786  _x2 = MIN(x2, vid->x_ofs + vbmp->w - 1) - vid->x_ofs;
787 
788  set_drawing_pattern();
789  rectfill(vbmp, _x1, _y1, _x2, _y2, color);
790  unset_drawing_pattern();
791 
792  update_texture_memory(vid, _x1, _y1, _x2, _y2);
793 
794  vid = vid->next;
795  }
796 
797  return;
798 }
799 
800 
801 static void allegro_gl_video_triangle(struct BITMAP *bmp, int x1, int y1,
802  int x2, int y2, int x3, int y3, int color)
803 {
804  AGL_VIDEO_BITMAP *vid;
805  int min_y, max_y, min_x, max_x;
806 
807  AGL_LOG(2, "glvtable.c:allegro_gl_video_triangle\n");
808  vid = bmp->extra;
809 
810  if (is_sub_bitmap(bmp)) {
811  x1 += bmp->x_ofs;
812  x2 += bmp->x_ofs;
813  x3 += bmp->x_ofs;
814  y1 += bmp->y_ofs;
815  y2 += bmp->y_ofs;
816  y3 += bmp->y_ofs;
817  }
818 
819  min_y = MIN(y1, MIN(y2, y3));
820  min_x = MIN(x1, MIN(x2, x3));
821  max_y = MAX(y1, MAX(y2, y3));
822  max_x = MAX(x1, MAX(x2, x3));
823 
824  while (vid) {
825  BITMAP *vbmp = vid->memory_copy;
826 
827  int _y1, _y2, _x1, _x2, _x3, _y3;
828  if (vid->x_ofs > max_x || vid->y_ofs > max_y
829  || vid->x_ofs + vbmp->w <= min_x
830  || vid->y_ofs + vbmp->h <= min_y) {
831 
832  vid = vid->next;
833  continue;
834  }
835 
836  _y1 = y1 - vid->y_ofs;
837  _y2 = y2 - vid->y_ofs;
838  _y3 = y3 - vid->y_ofs;
839  _x1 = x1 - vid->x_ofs;
840  _x2 = x2 - vid->x_ofs;
841  _x3 = x3 - vid->x_ofs;
842 
843  set_clip_rect(vbmp, bmp->cl - vid->x_ofs, bmp->ct - vid->y_ofs,
844  bmp->cr - vid->x_ofs - 1, bmp->cb - vid->y_ofs - 1);
845 
846  set_drawing_pattern();
847 
848  triangle(vbmp, _x1, _y1, _x2, _y2, _x3, _y3, color);
849 
850  unset_drawing_pattern();
851 
852  set_clip_rect(vbmp, 0, 0, vbmp->w - 1, vbmp->h - 1);
853 
854  /* Not quite the minimal rectangle occupied by the triangle, but
855  * pretty close */
856  _y1 = MAX(0, min_y - vid->y_ofs);
857  _y2 = MIN(vbmp->h - 1, max_y - vid->y_ofs);
858  _x1 = MAX(0, min_x - vid->x_ofs);
859  _x2 = MIN(vbmp->w - 1, max_x - vid->x_ofs);
860 
861  update_texture_memory(vid, _x1, _y1, _x2, _y2);
862 
863  vid = vid->next;
864  }
865 }
866 
867 
868 
869 static void allegro_gl_video_blit_from_memory_ex(BITMAP *source, BITMAP *dest,
870  int source_x, int source_y, int dest_x, int dest_y,
871  int width, int height, int draw_type) {
872 
873  AGL_VIDEO_BITMAP *vid;
874  BITMAP *dest_parent = dest;
875 
876  if (is_sub_bitmap (dest)) {
877  dest_x += dest->x_ofs;
878  dest_y += dest->y_ofs;
879  while (dest_parent->id & BMP_ID_SUB)
880  dest_parent = (BITMAP *)dest_parent->extra;
881  }
882 
883  if (dest_x < dest->cl) {
884  dest_x = dest->cl;
885  }
886  if (dest_y < dest->ct) {
887  dest_y = dest->ct;
888  }
889  if (dest_x + width >= dest->cr) {
890  width = dest->cr - dest_x;
891  }
892  if (dest_y + height >= dest->cb) {
893  height = dest->cb - dest_y;
894  }
895  if (width < 1 || height < 1) {
896  return;
897  }
898 
899  vid = dest_parent->extra;
900 
901  while (vid) {
902  BITMAP *vbmp = vid->memory_copy;
903 
904  int _x, _y, _w, _h, _sx, _sy;
905  if (vid->x_ofs >= dest_x + width || vid->y_ofs >= dest_y + height
906  || vid->x_ofs + vbmp->w <= dest_x
907  || vid->y_ofs + vbmp->h <= dest_y) {
908 
909  vid = vid->next;
910  continue;
911  }
912 
913  _x = MAX (vid->x_ofs, dest_x) - vid->x_ofs;
914  _w = MIN (vid->x_ofs + vbmp->w, dest_x + width)
915  - vid->x_ofs - _x;
916  _y = MAX (vid->y_ofs, dest_y) - vid->y_ofs;
917  _h = MIN (vid->y_ofs + vbmp->h, dest_y + height)
918  - vid->y_ofs - _y;
919 
920  _sx = source_x + vid->x_ofs + _x - dest_x;
921  _sy = source_y + vid->y_ofs + _y - dest_y;
922 
923  if (draw_type == BLIT) {
924  blit(source, vbmp, _sx, _sy, _x, _y, _w, _h);
925  }
926  else if (draw_type == MASKED_BLIT) {
927  masked_blit(source, vbmp, _sx, _sy, _x, _y, _w, _h);
928  }
929  else if (draw_type == TRANS) {
930  BITMAP *clip = create_sub_bitmap(source, _sx, _sy, _w, _h);
931  if (!clip)
932  return;
933  draw_trans_sprite(vbmp, clip, _x, _y);
934  destroy_bitmap(clip);
935  }
936 
937  update_texture_memory(vid, _x, _y, _x + _w - 1, _y + _h - 1);
938 
939  vid = vid->next;
940  }
941 
942  return;
943 }
944 
945 
946 void allegro_gl_video_blit_from_memory(BITMAP *source, BITMAP *dest,
947  int source_x, int source_y, int dest_x, int dest_y,
948  int width, int height) {
949 
950  allegro_gl_video_blit_from_memory_ex(source, dest, source_x, source_y,
951  dest_x, dest_y, width, height, BLIT);
952  return;
953 }
954 
955 
956 
957 void allegro_gl_video_blit_to_memory(struct BITMAP *source, struct BITMAP *dest,
958  int source_x, int source_y, int dest_x, int dest_y,
959  int width, int height) {
960 
961  AGL_VIDEO_BITMAP *vid;
962  BITMAP *source_parent = source;
963 
964  AGL_LOG(2, "glvtable.c:allegro_gl_video_blit_to_memory\n");
965 
966  if (is_sub_bitmap(source)) {
967  source_x += source->x_ofs;
968  source_y += source->y_ofs;
969  while (source_parent->id & BMP_ID_SUB)
970  source_parent = (BITMAP *)source_parent->extra;
971  }
972 
973  vid = source_parent->extra;
974 
975  while (vid) {
976  BITMAP *vbmp = vid->memory_copy;
977  int x, y, dx, dy, w, h;
978 
979  x = MAX(source_x, vid->x_ofs) - vid->x_ofs;
980  y = MAX(source_y, vid->y_ofs) - vid->y_ofs;
981  w = MIN(vid->x_ofs + vbmp->w, source_x + width) - vid->x_ofs;
982  h = MIN(vid->y_ofs + vbmp->h, source_y + height) - vid->y_ofs;
983  dx = MAX(0, vid->x_ofs - source_x) + dest_x;
984  dy = MAX(0, vid->y_ofs - source_y) + dest_y;
985 
986  blit(vbmp, dest, x, y, dx, dy, w, h);
987 
988  vid = vid->next;
989  }
990 
991  return;
992 }
993 
994 
995 
996 /* Just like allegro_gl_video_blit_from_memory(), except that draws only to the
997  * memory copy.
998  */
999 static void __video_update_memory_copy(BITMAP *source, BITMAP *dest,
1000  int source_x, int source_y, int dest_x, int dest_y,
1001  int width, int height, int draw_type) {
1002  AGL_VIDEO_BITMAP *vid;
1003  BITMAP *dest_parent = dest;
1004 
1005  if (is_sub_bitmap (dest)) {
1006  dest_x += dest->x_ofs;
1007  dest_y += dest->y_ofs;
1008  while (dest_parent->id & BMP_ID_SUB)
1009  dest_parent = (BITMAP *)dest_parent->extra;
1010  }
1011 
1012  if (dest_x < dest->cl) {
1013  dest_x = dest->cl;
1014  }
1015  if (dest_y < dest->ct) {
1016  dest_y = dest->ct;
1017  }
1018  if (dest_x + width >= dest->cr) {
1019  width = dest->cr - dest_x;
1020  }
1021  if (dest_y + height >= dest->cb) {
1022  height = dest->cb - dest_y;
1023  }
1024  if (width < 1 || height < 1) {
1025  return;
1026  }
1027 
1028  vid = dest_parent->extra;
1029 
1030  while (vid) {
1031  int sx, sy;
1032  BITMAP *vbmp = vid->memory_copy;
1033 
1034  int dx, dy, w, h;
1035  if (vid->x_ofs >= dest_x + width || vid->y_ofs >= dest_y + height
1036  || vid->x_ofs + vbmp->w <= dest_x
1037  || vid->y_ofs + vbmp->h <= dest_y) {
1038 
1039  vid = vid->next;
1040  continue;
1041  }
1042 
1043  dx = MAX (vid->x_ofs, dest_x) - vid->x_ofs;
1044  w = MIN (vid->x_ofs + vbmp->w, dest_x + width)
1045  - vid->x_ofs - dx;
1046  dy = MAX (vid->y_ofs, dest_y) - vid->y_ofs;
1047  h = MIN (vid->y_ofs + vbmp->h, dest_y + height)
1048  - vid->y_ofs - dy;
1049 
1050  sx = source_x + vid->x_ofs + dx - dest_x;
1051  sy = source_y + vid->y_ofs + dy - dest_y;
1052 
1053  if (draw_type == MASKED_BLIT) {
1054  masked_blit(source, vbmp, sx, sy, dx, dy, w, h);
1055  }
1056  else if (draw_type == BLIT) {
1057  blit(source, vbmp, sx, sy, dx, dy, w, h);
1058  }
1059  else if (draw_type == TRANS) {
1060  BITMAP *clip = create_sub_bitmap(source, sx, sy, w, h);
1061  if (!clip)
1062  return;
1063  draw_trans_sprite(vbmp, clip, dx, dy);
1064  destroy_bitmap(clip);
1065  }
1066 
1067  vid = vid->next;
1068  }
1069 
1070  return;
1071 }
1072 
1073 
1074 #define FOR_EACH_TEXTURE_FRAGMENT( \
1075  screen_blit_from_vid, /* used when dest is FBO to blit to texture
1076  memory from video bitmap */ \
1077  screen_blit_from_mem, /* used when dest is FBO to blit to texture
1078  memory from memory bitmap */ \
1079  mem_copy_blit_from_vid, /* used to update the memory copy of the
1080  dest from the source video bitmap */ \
1081  mem_copy_blit_from_mem, /* used to update the memory copy of the
1082  dest from the source memory bitmap */ \
1083  vid_and_mem_copy_blit_from_vid, /* used when dest is not FBO, draws to both
1084  memory copy and texute memory of the dest,
1085  from video bitmap source*/ \
1086  vid_and_mem_copy_blit_from_mem) /* used when dest is not FBO, draws to both
1087  memory copy and texute memory of the dest,
1088  from memory bitmap source */ \
1089 { \
1090  int used_fbo = FALSE; \
1091  AGL_VIDEO_BITMAP *vid; \
1092  \
1093  vid = dest->extra; \
1094  if (vid->fbo) { \
1095  int sx, sy; \
1096  int dx, dy; \
1097  int w, h; \
1098  \
1099  static GLint v[4]; \
1100  static double allegro_gl_projection_matrix[16]; \
1101  static double allegro_gl_modelview_matrix[16]; \
1102  \
1103  glGetIntegerv(GL_VIEWPORT, &v[0]); \
1104  glMatrixMode(GL_MODELVIEW); \
1105  glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix); \
1106  glMatrixMode(GL_PROJECTION); \
1107  glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix); \
1108  \
1109  while (vid) { \
1110  if (dest_x >= vid->x_ofs + vid->memory_copy->w || \
1111  dest_y >= vid->y_ofs + vid->memory_copy->h || \
1112  vid->x_ofs >= dest_x + width || \
1113  vid->y_ofs >= dest_y + height) { \
1114  vid = vid->next; \
1115  continue; \
1116  } \
1117  \
1118  dx = MAX(vid->x_ofs, dest_x) - vid->x_ofs; \
1119  w = MIN(vid->x_ofs + vid->memory_copy->w, dest_x + width) \
1120  - vid->x_ofs - dx; \
1121  dy = MAX(vid->y_ofs, dest_y) - vid->y_ofs; \
1122  h = MIN(vid->y_ofs + vid->memory_copy->h, dest_y + height) \
1123  - vid->y_ofs - dy; \
1124  \
1125  sx = source_x + vid->x_ofs + dx - dest_x; \
1126  sy = source_y + vid->y_ofs + dy - dest_y; \
1127  \
1128  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo); \
1129  \
1130  glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h); \
1131  glMatrixMode(GL_PROJECTION); \
1132  glLoadIdentity(); \
1133  gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h); \
1134  glMatrixMode(GL_MODELVIEW); \
1135  \
1136  if (is_memory_bitmap(source)) { \
1137  screen_blit_from_mem; \
1138  } \
1139  else { \
1140  screen_blit_from_vid; \
1141  } \
1142  \
1143  vid = vid->next; \
1144  } \
1145  \
1146  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); \
1147  \
1148  glViewport(v[0], v[1], v[2], v[3]); \
1149  glMatrixMode(GL_PROJECTION); \
1150  glLoadMatrixd(allegro_gl_projection_matrix); \
1151  glMatrixMode(GL_MODELVIEW); \
1152  glLoadMatrixd(allegro_gl_modelview_matrix); \
1153  \
1154  used_fbo = TRUE; \
1155  } \
1156  \
1157  if (is_video_bitmap(source)) { \
1158  int sx, sy; \
1159  int dx, dy; \
1160  int w, h; \
1161  \
1162  vid = source->extra; \
1163  \
1164  while (vid) { \
1165  if (source_x >= vid->x_ofs + vid->memory_copy->w || \
1166  source_y >= vid->y_ofs + vid->memory_copy->h || \
1167  vid->x_ofs >= source_x + width || \
1168  vid->y_ofs >= source_y + height) { \
1169  vid = vid->next; \
1170  continue; \
1171  } \
1172  \
1173  sx = MAX(vid->x_ofs, source_x) - vid->x_ofs; \
1174  w = MIN(vid->x_ofs + vid->memory_copy->w, source_x + width) \
1175  - vid->x_ofs - sx; \
1176  sy = MAX(vid->y_ofs, source_y) - vid->y_ofs; \
1177  h = MIN(vid->y_ofs + vid->memory_copy->h, source_y + height) \
1178  - vid->y_ofs - sy; \
1179  \
1180  dx = dest_x + vid->x_ofs + sx - source_x; \
1181  dy = dest_y + vid->y_ofs + sy - source_y; \
1182  \
1183  if (used_fbo) { \
1184  mem_copy_blit_from_vid; \
1185  } \
1186  else { \
1187  vid_and_mem_copy_blit_from_vid; \
1188  } \
1189  \
1190  vid = vid->next; \
1191  } \
1192  } \
1193  else if (is_memory_bitmap(source)) { \
1194  if (used_fbo) { \
1195  mem_copy_blit_from_mem; \
1196  } \
1197  else { \
1198  vid_and_mem_copy_blit_from_mem; \
1199  } \
1200  } \
1201 }
1202 
1203 
1204 /* allegro_gl_video_blit_to_self:
1205  * blit() overload for video -> video blits
1206  */
1207 void allegro_gl_video_blit_to_self(struct BITMAP *source, struct BITMAP *dest,
1208  int source_x, int source_y, int dest_x, int dest_y, int width, int height) {
1209 
1210  FOR_EACH_TEXTURE_FRAGMENT (
1211  allegro_gl_screen_blit_to_self(source, screen, sx, sy, dx, dy, w, h),
1212  allegro_gl_screen_blit_to_self(source, screen, sx, sy, dx, dy, w, h),
1213  __video_update_memory_copy(vid->memory_copy, dest, sx, sy, dx, dy, w, h, BLIT),
1214  __video_update_memory_copy(source, dest, source_x, source_y, dest_x, dest_y, width, height, BLIT),
1215  allegro_gl_video_blit_from_memory(vid->memory_copy, dest, sx, sy, dx, dy, w, h),
1216  allegro_gl_video_blit_from_memory(source, dest, source_x, source_y, dest_x, dest_y, width, height)
1217  )
1218 }
1219 
1220 
1221 static void do_masked_blit_video(struct BITMAP *source, struct BITMAP *dest,
1222  int source_x, int source_y, int dest_x, int dest_y,
1223  int width, int height, int flip_dir, int blit_type) {
1224 
1225  FOR_EACH_TEXTURE_FRAGMENT (
1226  do_masked_blit_screen(source, screen, sx, sy, dx, dy, w, h, flip_dir, blit_type),
1227  do_masked_blit_screen(source, screen, sx, sy, dx, dy, w, h, flip_dir, blit_type),
1228  __video_update_memory_copy(vid->memory_copy, dest, sx, sy, dx, dy, w, h, MASKED_BLIT),
1229  __video_update_memory_copy(source, dest, source_x, source_y, dest_x, dest_y, width, height, MASKED_BLIT),
1230  allegro_gl_video_blit_from_memory_ex(vid->memory_copy, dest, sx, sy, dx, dy, w, h, MASKED_BLIT),
1231  allegro_gl_video_blit_from_memory_ex(source, dest, source_x, source_y, dest_x, dest_y, width, height, MASKED_BLIT)
1232  )
1233 }
1234 
1235 
1236 /* allegro_gl_video_masked_blit:
1237  * masked_blit() overload for video -> video masked blits
1238  */
1239 static void allegro_gl_video_masked_blit(struct BITMAP *source,
1240  struct BITMAP *dest, int source_x, int source_y,
1241  int dest_x, int dest_y, int width, int height) {
1242  do_masked_blit_video(source, dest, source_x, source_y, dest_x, dest_y,
1243  width, height, FALSE, AGL_REGULAR_BMP | AGL_NO_ROTATION);
1244 
1245  return;
1246 }
1247 
1248 
1249 /* allegro_gl_video_draw_sprite:
1250  * draw_sprite() overload for video -> video sprite drawing
1251  */
1252 static void allegro_gl_video_draw_sprite(struct BITMAP *bmp,
1253  struct BITMAP *sprite, int x, int y) {
1254 
1255  do_masked_blit_video(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
1256  FALSE, AGL_NO_ROTATION);
1257 
1258  return;
1259 }
1260 
1261 
1262 /* allegro_gl_video_draw_sprite_v_flip:
1263  * draw_sprite_v_flip() overload for video -> video blits
1264  * FIXME: Broken if the bitmap was split into multiple textures.
1265  * FIXME: Doesn't apply rotation and scale to the memory copy
1266  */
1267 static void allegro_gl_video_draw_sprite_v_flip(struct BITMAP *bmp,
1268  struct BITMAP *sprite, int x, int y) {
1269 
1270  do_masked_blit_video(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
1271  AGL_V_FLIP, AGL_NO_ROTATION);
1272 
1273  return;
1274 }
1275 
1276 
1277 /* allegro_gl_video_draw_sprite_h_flip:
1278  * draw_sprite_v_flip() overload for video -> video blits
1279  * FIXME: Broken if the bitmap was split into multiple textures.
1280  * FIXME: Doesn't apply rotation and scale to the memory copy
1281  */
1282 static void allegro_gl_video_draw_sprite_h_flip(struct BITMAP *bmp,
1283  struct BITMAP *sprite, int x, int y) {
1284 
1285  do_masked_blit_video(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
1286  AGL_H_FLIP, AGL_NO_ROTATION);
1287 
1288  return;
1289 }
1290 
1291 
1292 /* allegro_gl_video_draw_sprite_vh_flip:
1293  * draw_sprite_vh_flip() overload for video -> video blits
1294  * FIXME: Broken if the bitmap was split into multiple textures.
1295  * FIXME: Doesn't apply rotation and scale to the memory copy
1296  */
1297 static void allegro_gl_video_draw_sprite_vh_flip(struct BITMAP *bmp,
1298  struct BITMAP *sprite, int x, int y) {
1299 
1300  do_masked_blit_video(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
1301  AGL_V_FLIP | AGL_H_FLIP, AGL_NO_ROTATION);
1302 
1303  return;
1304 }
1305 
1306 
1307 /* allegro_gl_video_pivot_scaled_sprite_flip:
1308  * FIXME: Broken if the bitmap was split into multiple textures.
1309  * FIXME: Doesn't apply rotation and scale to the memory copy
1310  * FIXME: Doesn't work for when FBO is not available.
1311  */
1312 static void allegro_gl_video_pivot_scaled_sprite_flip(struct BITMAP *bmp,
1313  struct BITMAP *sprite, fixed x, fixed y, fixed cx, fixed cy,
1314  fixed angle, fixed scale, int v_flip) {
1315  double dscale = fixtof(scale);
1316  GLint matrix_mode;
1317 
1318 #define BIN_2_DEG(x) (-(x) * 180.0 / 128)
1319 
1320  glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
1321  glMatrixMode(GL_MODELVIEW);
1322  glPushMatrix();
1323  glTranslated(fixtof(x), fixtof(y), 0.);
1324  glRotated(BIN_2_DEG(fixtof(angle)), 0., 0., -1.);
1325  glScaled(dscale, dscale, dscale);
1326  glTranslated(-fixtof(x+cx), -fixtof(y+cy), 0.);
1327 
1328  do_masked_blit_video(sprite, bmp, 0, 0, fixtoi(x), fixtoi(y),
1329  sprite->w, sprite->h, v_flip ? AGL_V_FLIP : FALSE, FALSE);
1330  glPopMatrix();
1331  glMatrixMode(matrix_mode);
1332 
1333 #undef BIN_2_DEG
1334 
1335  return;
1336 }
1337 
1338 
1339 /* allegro_gl_video_do_stretch_blit:
1340  * overload for all kind of video -> video and video -> screen stretchers
1341  * FIXME: Doesn't apply scale to the memory copy
1342  * FIXME: Doesn't work for video->video when FBO is not available.
1343  */
1344 static void allegro_gl_video_do_stretch_blit(BITMAP *source, BITMAP *dest,
1345  int source_x, int source_y, int source_width, int source_height,
1346  int dest_x, int dest_y, int dest_width, int dest_height,
1347  int masked) {
1348  /* note: src is a video bitmap, dest is not a memory bitmap */
1349 
1350  double scalew = ((double)dest_width) / source_width;
1351  double scaleh = ((double)dest_height) / source_height;
1352 
1353  GLint matrix_mode;
1354 
1355  /* BITMAP_BLIT_CLIP macro from glvtable.c is no good for scaled images. */
1356  if (dest->clip) {
1357  if ((dest_x >= dest->cr) || (dest_y >= dest->cb)
1358  || (dest_x + dest_width < dest->cl) || (dest_y + dest_height < dest->ct)) {
1359  return;
1360  }
1361  if (dest_x < dest->cl) {
1362  source_x -= (dest_x - dest->cl) / scalew;
1363  dest_x = dest->cl;
1364  }
1365  if (dest_y < dest->ct) {
1366  source_y -= (dest_y - dest->ct) / scaleh;
1367  dest_y = dest->ct;
1368  }
1369  if (dest_x + dest_width > dest->cr) {
1370  source_width -= (dest_x + dest_width - dest->cr) / scalew;
1371  dest_width = dest->cr - dest_x;
1372  }
1373  if (dest_y + dest_height > dest->cb) {
1374  source_height -= (dest_y + dest_height - dest->cb) / scaleh;
1375  dest_height = dest->cb - dest_y;
1376  }
1377  }
1378 
1379  glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
1380  glMatrixMode(GL_MODELVIEW);
1381  glPushMatrix();
1382  glTranslated(dest_x, dest_y, 0.);
1383  glScaled(scalew, scaleh, 1.);
1384  glTranslated(-dest_x, -dest_y, 0.);
1385 
1386  if (masked) {
1387  if (is_screen_bitmap(dest)) {
1388  do_masked_blit_screen(source, dest, source_x, source_y,
1389  dest_x, dest_y, source_width, source_height,
1390  FALSE, AGL_REGULAR_BMP);
1391  }
1392  else {
1393  do_masked_blit_video(source, dest, source_x, source_y,
1394  dest_x, dest_y, source_width, source_height,
1395  FALSE, AGL_REGULAR_BMP);
1396  }
1397  }
1398  else {
1399  allegro_gl_screen_blit_to_self(source, dest, source_x, source_y,
1400  dest_x, dest_y, source_width, source_height);
1401  }
1402 
1403  glPopMatrix();
1404  glMatrixMode(matrix_mode);
1405 
1406  return;
1407 }
1408 
1409 
1410 
1411 /* allegro_gl_video_draw_trans_rgba_sprite:
1412  * draw_trans_sprite() overload for video -> video drawing
1413  */
1414 static void allegro_gl_video_draw_trans_rgba_sprite(BITMAP *bmp,
1415  BITMAP *sprite, int x, int y) {
1416  /* Adapt variables for FOR_EACH_TEXTURE_FRAGMENT macro. */
1417  BITMAP *source = sprite;
1418  BITMAP *dest = bmp;
1419  int dest_x = x;
1420  int dest_y = y;
1421  int source_x = 0;
1422  int source_y = 0;
1423  int width = sprite->w;
1424  int height = sprite->h;
1425  GLint format = __allegro_gl_get_bitmap_color_format(sprite, AGL_TEXTURE_HAS_ALPHA);
1426  GLint type = __allegro_gl_get_bitmap_type(sprite, 0);
1427 
1428  if (__allegro_gl_blit_operation == AGL_OP_LOGIC_OP)
1429  glEnable(GL_COLOR_LOGIC_OP);
1430  else
1431  glEnable(GL_BLEND);
1432 
1433  FOR_EACH_TEXTURE_FRAGMENT (
1434  allegro_gl_screen_blit_to_self(source, screen, sx, sy, dx, dy, w, h),
1435  allegro_gl_upload_and_display_texture(sprite, sx, sy, dx, dy, w, h, 0, format, type),
1436  __video_update_memory_copy(vid->memory_copy, dest, sx, sy, dx, dy, w, h, TRANS),
1437  __video_update_memory_copy(source, dest, 0, 0, x, y, sprite->w, sprite->h, TRANS),
1438  allegro_gl_video_blit_from_memory_ex(vid->memory_copy, dest, sx, sy, dx, dy, w, h, TRANS),
1439  allegro_gl_video_blit_from_memory_ex(source, dest, 0, 0, x, y, sprite->w, sprite->h, TRANS)
1440  )
1441 
1442  if (__allegro_gl_blit_operation == AGL_OP_LOGIC_OP)
1443  glDisable(GL_COLOR_LOGIC_OP);
1444  else
1445  glDisable(GL_BLEND);
1446 
1447  return;
1448 }
1449 
1450 
1451 
1452 /* allegro_gl_video_draw_sprite_ex:
1453  * draw_sprite_ex() overload for video -> video and memory -> video drawing
1454  *
1455  * When mode is DRAW_SPRITE_TRANS:
1456  * FIXME: Broken if the bitmap was split into multiple textures.
1457  * FIXME: Doesn't apply flipping to the memory copy
1458  */
1459 static void allegro_gl_video_draw_sprite_ex(BITMAP *bmp, BITMAP *sprite,
1460  int x, int y, int mode, int flip) {
1461  int matrix_mode;
1462  int lflip = 0;
1463 
1464  /* convert allegro's flipping flags to AGL's flags */
1465  switch (flip) {
1466  case DRAW_SPRITE_NO_FLIP:
1467  lflip = FALSE;
1468  break;
1469  case DRAW_SPRITE_V_FLIP:
1470  lflip = AGL_V_FLIP;
1471  break;
1472  case DRAW_SPRITE_H_FLIP:
1473  lflip = AGL_H_FLIP;
1474  break;
1475  case DRAW_SPRITE_VH_FLIP:
1476  lflip = AGL_V_FLIP | AGL_H_FLIP;
1477  break;
1478  }
1479 
1480  switch (mode) {
1481  case DRAW_SPRITE_NORMAL:
1482  do_masked_blit_video(sprite, bmp, 0, 0, x, y,
1483  sprite->w, sprite->h, lflip, FALSE);
1484  break;
1485  case DRAW_SPRITE_TRANS:
1486  if (lflip) {
1487  glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
1488  glMatrixMode(GL_MODELVIEW);
1489  glPushMatrix();
1490 
1491  glTranslatef(x, y, 0.f);
1492  glScalef((lflip&AGL_H_FLIP) ? -1 : 1, (lflip&AGL_V_FLIP)? -1 : 1, 1);
1493  glTranslatef(-x, -y, 0);
1494  glTranslatef((lflip&AGL_H_FLIP) ? -sprite->w : 0,
1495  (lflip&AGL_V_FLIP) ? -sprite->h : 0, 0);
1496  }
1497 
1498  allegro_gl_video_draw_trans_rgba_sprite(bmp, sprite, x, y);
1499 
1500  if (lflip) {
1501  glPopMatrix();
1502  glMatrixMode(matrix_mode);
1503  }
1504  break;
1505  case DRAW_SPRITE_LIT:
1506  /* not implemented */
1507  break;
1508  }
1509 }
1510 
1511 
1512 
1513 static void allegro_gl_video_clear_to_color(BITMAP *bmp, int color) {
1514  AGL_VIDEO_BITMAP *vid = bmp->extra;
1515 
1516  if (vid->fbo) {
1517  static GLint v[4];
1518  static double allegro_gl_projection_matrix[16];
1519  static double allegro_gl_modelview_matrix[16];
1520 
1521  glGetIntegerv(GL_VIEWPORT, &v[0]);
1522  glMatrixMode(GL_MODELVIEW);
1523  glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);
1524  glMatrixMode(GL_PROJECTION);
1525  glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix);
1526 
1527  while (vid) {
1528  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo);
1529 
1530  glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h);
1531  glMatrixMode(GL_PROJECTION);
1532  glLoadIdentity();
1533  gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h);
1534  glMatrixMode(GL_MODELVIEW);
1535 
1536  allegro_gl_screen_clear_to_color(bmp, color);
1537  clear_to_color(vid->memory_copy, color);
1538  vid = vid->next;
1539  }
1540 
1541  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1542 
1543  glViewport(v[0], v[1], v[2], v[3]);
1544  glMatrixMode(GL_PROJECTION);
1545  glLoadMatrixd(allegro_gl_projection_matrix);
1546  glMatrixMode(GL_MODELVIEW);
1547  glLoadMatrixd(allegro_gl_modelview_matrix);
1548  }
1549  else {
1550  allegro_gl_video_rectfill(bmp, 0, 0, bmp->w, bmp->h, color);
1551  }
1552 }
1553 
1554 
1555 
1556 /* FIXME: Doesn't work when FBO is not available.
1557  * FIXME: Doesn't care for segmented video bitmaps.
1558  */
1559 static void allegro_gl_video_draw_color_glyph(struct BITMAP *bmp,
1560  struct BITMAP *sprite, int x, int y, int color, int bg)
1561 {
1562  AGL_VIDEO_BITMAP *vid = bmp->extra;
1563 
1564  static GLint v[4];
1565  static double allegro_gl_projection_matrix[16];
1566  static double allegro_gl_modelview_matrix[16];
1567 
1568  if (!vid->fbo)
1569  return;
1570 
1571  glGetIntegerv(GL_VIEWPORT, &v[0]);
1572  glMatrixMode(GL_MODELVIEW);
1573  glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);
1574  glMatrixMode(GL_PROJECTION);
1575  glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix);
1576 
1577  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo);
1578 
1579  glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h);
1580  glMatrixMode(GL_PROJECTION);
1581  glLoadIdentity();
1582  gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h);
1583  glMatrixMode(GL_MODELVIEW);
1584 
1585  allegro_gl_screen_draw_color_glyph_ex(bmp, sprite, x, y, color, bg, 0);
1586 
1587  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1588 
1589  glViewport(v[0], v[1], v[2], v[3]);
1590  glMatrixMode(GL_PROJECTION);
1591  glLoadMatrixd(allegro_gl_projection_matrix);
1592  glMatrixMode(GL_MODELVIEW);
1593  glLoadMatrixd(allegro_gl_modelview_matrix);
1594 
1595  vid->memory_copy->vtable->draw_character(vid->memory_copy, sprite, x, y, color, bg);
1596 }
1597 
1598 
1599 
1600 static void allegro_gl_video_draw_256_sprite(BITMAP *bmp, BITMAP *sprite,
1601  int x, int y) {
1602  allegro_gl_video_draw_color_glyph(bmp, sprite, x, y, -1, _textmode);
1603 }
1604 
1605 
1606 
1607 static void allegro_gl_video_draw_character(BITMAP *bmp, BITMAP *sprite,
1608  int x, int y, int color, int bg) {
1609  allegro_gl_video_draw_color_glyph(bmp, sprite, x, y, color, bg);
1610 }
1611 
1612 
1613 
1614 /* FIXME: Doesn't work when FBO is not available.
1615  * FIXME: Doesn't care for segmented video bitmaps.
1616  */
1617 static void allegro_gl_video_draw_glyph(struct BITMAP *bmp,
1618  AL_CONST struct FONT_GLYPH *glyph, int x, int y,
1619  int color, int bg) {
1620  AGL_VIDEO_BITMAP *vid = bmp->extra;
1621 
1622  static GLint v[4];
1623  static double allegro_gl_projection_matrix[16];
1624  static double allegro_gl_modelview_matrix[16];
1625 
1626  if (!vid->fbo)
1627  return;
1628 
1629  glGetIntegerv(GL_VIEWPORT, &v[0]);
1630  glMatrixMode(GL_MODELVIEW);
1631  glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);
1632  glMatrixMode(GL_PROJECTION);
1633  glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix);
1634 
1635  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo);
1636 
1637  glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h);
1638  glMatrixMode(GL_PROJECTION);
1639  glLoadIdentity();
1640  gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h);
1641  glMatrixMode(GL_MODELVIEW);
1642 
1643  allegro_gl_screen_draw_glyph_ex(bmp, glyph, x, y, color, bg, 1);
1644 
1645  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1646 
1647  glViewport(v[0], v[1], v[2], v[3]);
1648  glMatrixMode(GL_PROJECTION);
1649  glLoadMatrixd(allegro_gl_projection_matrix);
1650  glMatrixMode(GL_MODELVIEW);
1651  glLoadMatrixd(allegro_gl_modelview_matrix);
1652 
1653  vid->memory_copy->vtable->draw_glyph(vid->memory_copy, glyph, x, y, color, bg);
1654 }
1655 
1656 
1657 
1658 static void allegro_gl_video_polygon3d_f(BITMAP *bmp, int type, BITMAP *texture,
1659  int vc, V3D_f *vtx[])
1660 {
1661  AGL_VIDEO_BITMAP *vid = bmp->extra;
1662 
1663  /* Switch to software mode is using polygon type that isn't supported by
1664  allegro_gl_screen_polygon3d_f. */
1665  int use_fbo = (type == POLYTYPE_FLAT) ||
1666  (type == POLYTYPE_GRGB) ||
1667  (type == POLYTYPE_GCOL) ||
1668  (type == POLYTYPE_ATEX) ||
1669  (type == POLYTYPE_PTEX) ||
1670  (type == POLYTYPE_ATEX_TRANS) ||
1671  (type == POLYTYPE_PTEX_TRANS);
1672 
1673  if (vid->fbo && use_fbo) {
1674  static GLint v[4];
1675  static double allegro_gl_projection_matrix[16];
1676  static double allegro_gl_modelview_matrix[16];
1677 
1678  glGetIntegerv(GL_VIEWPORT, &v[0]);
1679  glMatrixMode(GL_MODELVIEW);
1680  glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);
1681  glMatrixMode(GL_PROJECTION);
1682  glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix);
1683 
1684  while (vid) {
1685  BITMAP *mem_texture;
1686 
1687  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo);
1688 
1689  glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h);
1690  glMatrixMode(GL_PROJECTION);
1691  glLoadIdentity();
1692  gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h);
1693  glMatrixMode(GL_MODELVIEW);
1694 
1695  allegro_gl_screen_polygon3d_f(bmp, type, texture, vc, vtx);
1696 
1697  if (is_video_bitmap(texture)) {
1698  AGL_VIDEO_BITMAP *vbmp = texture->extra;
1699  mem_texture = vbmp->memory_copy;
1700  }
1701  else {
1702  mem_texture = texture;
1703  }
1704  polygon3d_f(vid->memory_copy, type, mem_texture, vc, vtx);
1705 
1706  vid = vid->next;
1707  }
1708 
1709  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1710 
1711  glViewport(v[0], v[1], v[2], v[3]);
1712  glMatrixMode(GL_PROJECTION);
1713  glLoadMatrixd(allegro_gl_projection_matrix);
1714  glMatrixMode(GL_MODELVIEW);
1715  glLoadMatrixd(allegro_gl_modelview_matrix);
1716  }
1717  else {
1718  int i;
1719  AGL_VIDEO_BITMAP *vid;
1720 
1721  vid = bmp->extra;
1722 
1723  if (is_sub_bitmap(bmp)) {
1724  for (i = 0; i < vc; ++i) {
1725  vtx[i]->x += bmp->x_ofs;
1726  vtx[i]->y += bmp->y_ofs;
1727  }
1728  }
1729 
1730  while (vid) {
1731  BITMAP *mem_texture;
1732  int _y1, _y2, _x1, _x2;
1733  BITMAP *vbmp = vid->memory_copy;
1734 
1735  _x1 = 9999;
1736  for (i = 0; i < vc; ++i)
1737  if (vtx[i]->x < _x1) _x1 = vtx[i]->x;
1738 
1739  _x2 = -9999;
1740  for (i = 0; i < vc; ++i)
1741  if (vtx[i]->x > _x2) _x2 = vtx[i]->x;
1742 
1743  _y1 = 9999;
1744  for (i = 0; i < vc; ++i)
1745  if (vtx[i]->y < _y1) _y1 = vtx[i]->y;
1746 
1747  _y2 = -9999;
1748  for (i = 0; i < vc; ++i)
1749  if (vtx[i]->y > _y2) _y2 = vtx[i]->y;
1750 
1751  if (vid->x_ofs > _x2 || vid->y_ofs > _y2
1752  || vid->x_ofs + vbmp->w <= _x1
1753  || vid->y_ofs + vbmp->h <= _y1) {
1754 
1755  vid = vid->next;
1756  continue;
1757  }
1758 
1759  _x1 = MAX(0, _x1 - vid->x_ofs);
1760  _x2 = (_x2 - (vid->x_ofs + vbmp->w) > 0) ? vbmp->w - 1: _x2 - vid->x_ofs;
1761  _y1 = MAX(0, _y1 - vid->y_ofs);
1762  _y2 = (_x2 - (vid->y_ofs + vbmp->h) > 0) ? vbmp->h - 1: _y2 - vid->y_ofs;
1763 
1764  if (is_video_bitmap(texture)) {
1765  AGL_VIDEO_BITMAP *tex = texture->extra;
1766  mem_texture = tex->memory_copy;
1767  }
1768  else {
1769  mem_texture = texture;
1770  }
1771  polygon3d_f(vid->memory_copy, type, mem_texture, vc, vtx);
1772 
1773  update_texture_memory(vid, _x1, _y1, _x2, _y2);
1774 
1775  vid = vid->next;
1776  }
1777  }
1778 
1779  return;
1780 }
1781 
1782 
1783 
1784 static void allegro_gl_video_polygon3d(BITMAP *bmp, int type, BITMAP *texture,
1785  int vc, V3D *vtx[])
1786 {
1787  int i;
1788  V3D_f **vtx_f = malloc(vc * sizeof(struct V3D_f*));
1789  if (!vtx_f)
1790  return;
1791 
1792  for (i = 0; i < vc; i++) {
1793  vtx_f[i] = malloc(sizeof(struct V3D_f));
1794  if (!vtx_f[i]) {
1795  int k;
1796  for (k = 0; k < i; k++)
1797  free(vtx_f[k]);
1798  free(vtx_f);
1799  return;
1800  }
1801  vtx_f[i]->c = vtx[i]->c;
1802  vtx_f[i]->u = fixtof(vtx[i]->u);
1803  vtx_f[i]->v = fixtof(vtx[i]->v);
1804  vtx_f[i]->x = fixtof(vtx[i]->x);
1805  vtx_f[i]->y = fixtof(vtx[i]->y);
1806  vtx_f[i]->z = fixtof(vtx[i]->z);
1807  }
1808 
1809  allegro_gl_video_polygon3d_f(bmp, type, texture, vc, vtx_f);
1810 
1811  for (i = 0; i < vc; i++)
1812  free(vtx_f[i]);
1813  free(vtx_f);
1814 }
1815 
1816 
1817 
1818 static void allegro_gl_video_triangle3d(BITMAP *bmp, int type, BITMAP *texture,
1819  V3D *v1, V3D *v2, V3D *v3)
1820 {
1821  V3D *vtx[3];
1822  vtx[0] = v1;
1823  vtx[1] = v2;
1824  vtx[2] = v3;
1825 
1826  allegro_gl_video_polygon3d(bmp, type, texture, 3, vtx);
1827 }
1828 
1829 
1830 
1831 static void allegro_gl_video_triangle3d_f(BITMAP *bmp, int type, BITMAP *texture,
1832  V3D_f *v1, V3D_f *v2, V3D_f *v3)
1833 {
1834  V3D_f *vtx_f[3];
1835  vtx_f[0] = v1;
1836  vtx_f[1] = v2;
1837  vtx_f[2] = v3;
1838 
1839  allegro_gl_video_polygon3d_f(bmp, type, texture, 3, vtx_f);
1840 }
1841 
1842 
1843 
1844 static void allegro_gl_video_quad3d(BITMAP *bmp, int type, BITMAP *texture,
1845  V3D *v1, V3D *v2, V3D *v3, V3D *v4)
1846 {
1847  V3D *vtx[4];
1848  vtx[0] = v1;
1849  vtx[1] = v2;
1850  vtx[2] = v3;
1851  vtx[3] = v4;
1852 
1853  allegro_gl_video_polygon3d(bmp, type, texture, 4, vtx);
1854 }
1855 
1856 
1857 
1858 static void allegro_gl_video_quad3d_f(BITMAP *bmp, int type, BITMAP *texture,
1859  V3D_f *v1, V3D_f *v2, V3D_f *v3, V3D_f *v4)
1860 {
1861  V3D_f *vtx_f[4];
1862  vtx_f[0] = v1;
1863  vtx_f[1] = v2;
1864  vtx_f[2] = v3;
1865  vtx_f[3] = v4;
1866 
1867  allegro_gl_video_polygon3d_f(bmp, type, texture, 4, vtx_f);
1868 }
1869 
1870 
1871 
1872 static void dummy_unwrite_bank(void)
1873 {
1874 }
1875 
1876 
1877 
1878 static GFX_VTABLE allegro_gl_video_vtable = {
1879  0,
1880  0,
1881  dummy_unwrite_bank, //void *unwrite_bank; /* C function on some machines, asm on i386 */
1882  NULL, //AL_METHOD(void, set_clip, (struct BITMAP *bmp));
1885  NULL, //AL_METHOD(struct BITMAP *, create_sub_bitmap, (struct BITMAP *parent, int x, int y, int width, int height));
1886  allegro_gl_created_sub_bitmap,
1887  allegro_gl_video_getpixel,
1888  allegro_gl_video_putpixel,
1889  allegro_gl_video_vline,
1890  allegro_gl_video_hline,
1891  allegro_gl_video_hline,
1892  allegro_gl_video_line,
1893  allegro_gl_video_line,
1894  allegro_gl_video_rectfill,
1895  allegro_gl_video_triangle,
1896  allegro_gl_video_draw_sprite,
1897  allegro_gl_video_draw_256_sprite,
1898  allegro_gl_video_draw_sprite_v_flip,
1899  allegro_gl_video_draw_sprite_h_flip,
1900  allegro_gl_video_draw_sprite_vh_flip,
1901  allegro_gl_video_draw_trans_rgba_sprite,
1902  allegro_gl_video_draw_trans_rgba_sprite,
1903  NULL, //AL_METHOD(void, draw_lit_sprite, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color));
1904  NULL, //AL_METHOD(void, allegro_gl_video_draw_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y));
1905  NULL, //AL_METHOD(void, draw_trans_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y));
1906  NULL, //AL_METHOD(void, draw_trans_rgba_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y));
1907  NULL, //AL_METHOD(void, draw_lit_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y, int color));
1908  allegro_gl_video_draw_character,
1909  allegro_gl_video_draw_glyph,
1910  allegro_gl_video_blit_from_memory,
1911  allegro_gl_video_blit_to_memory,
1912  NULL, //AL_METHOD(void, blit_from_system, (struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height));
1913  NULL, //AL_METHOD(void, blit_to_system, (struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height));
1914  allegro_gl_screen_blit_to_self, /* Video bitmaps use same method as screen */
1915  allegro_gl_screen_blit_to_self, /* ..._forward */
1916  allegro_gl_screen_blit_to_self, /* ..._backward */
1917  allegro_gl_memory_blit_between_formats,
1918  allegro_gl_video_masked_blit,
1919  allegro_gl_video_clear_to_color,
1920  allegro_gl_video_pivot_scaled_sprite_flip,
1921  allegro_gl_video_do_stretch_blit,
1922  NULL, //AL_METHOD(void, draw_gouraud_sprite, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int c1, int c2, int c3, int c4));
1923  NULL, //AL_METHOD(void, draw_sprite_end, (void));
1924  NULL, //AL_METHOD(void, blit_end, (void));
1925  _soft_polygon, //AL_METHOD(void, polygon, (struct BITMAP *bmp, int vertices, AL_CONST int *points, int color));
1926  _soft_rect, //AL_METHOD(void, rect, (struct BITMAP *bmp, int x1, int y1, int x2, int y2, int color));
1927  _soft_circle, //AL_METHOD(void, circle, (struct BITMAP *bmp, int x, int y, int radius, int color));
1928  _soft_circlefill, //AL_METHOD(void, circlefill, (struct BITMAP *bmp, int x, int y, int radius, int color));
1929  _soft_ellipse, //AL_METHOD(void, ellipse, (struct BITMAP *bmp, int x, int y, int rx, int ry, int color));
1930  _soft_ellipsefill, //AL_METHOD(void, ellipsefill, (struct BITMAP *bmp, int x, int y, int rx, int ry, int color));
1931  _soft_arc, //AL_METHOD(void, arc, (struct BITMAP *bmp, int x, int y, fixed ang1, fixed ang2, int r, int color));
1932  _soft_spline, //AL_METHOD(void, spline, (struct BITMAP *bmp, AL_CONST int points[8], int color));
1933  _soft_floodfill, //AL_METHOD(void, floodfill, (struct BITMAP *bmp, int x, int y, int color));
1934  allegro_gl_video_polygon3d,
1935  allegro_gl_video_polygon3d_f,
1936  allegro_gl_video_triangle3d,
1937  allegro_gl_video_triangle3d_f,
1938  allegro_gl_video_quad3d,
1939  allegro_gl_video_quad3d_f,
1940  allegro_gl_video_draw_sprite_ex
1941 };
1942 
struct AGL_EXTENSION_LIST_GL allegro_gl_extensions_GL
List of OpenGL extensions supported by AllegroGL.
Definition: glext.c:55
static void allegro_gl_video_acquire(struct BITMAP *bmp)
acquire_bitmap(bmp) overload.
Definition: videovtb.c:437
void allegro_gl_destroy_video_bitmap(BITMAP *bmp)
destroy_video_bitmap() overload.
Definition: videovtb.c:308
Main header file for AllegroGL.
static void allegro_gl_video_release(struct BITMAP *bmp)
release_bitmap(bmp) overload.
Definition: videovtb.c:448
#define AGL_TEXTURE_HAS_ALPHA
Tell AllegroGL that the bitmap had an alpha channel, so it should be preserved when generating the te...
Definition: alleggl.h:526
BITMAP * allegro_gl_create_video_bitmap(int w, int h)
create_video_bitmap() overload.
Definition: videovtb.c:344
GLint allegro_gl_set_video_bitmap_color_depth(int bpp)
Sets the color depth you&#39;d like AllegroGL to use for video bitmaps.
Definition: videovtb.c:423