videovtb.c

Go to the documentation of this file.
00001 /* This code is (C) AllegroGL contributors, and double licensed under
00002  * the GPL and zlib licenses. See gpl.txt or zlib.txt for details.
00003  */
00009 #include <string.h>
00010 #include <limits.h>
00011 
00012 #include <allegro.h>
00013 
00014 #ifdef ALLEGRO_WINDOWS
00015 #include <winalleg.h>
00016 #endif
00017 
00018 #include "alleggl.h"
00019 #include "allglint.h"
00020 #include "glvtable.h"
00021 #include <allegro/internal/aintern.h>
00022 #ifdef ALLEGRO_MACOSX
00023 #include <OpenGL/glu.h>
00024 #else
00025 #include <GL/glu.h>
00026 #endif
00027 
00028 
00029 #define MASKED_BLIT 1
00030 #define BLIT        2
00031 #define TRANS       3
00032 
00033 
00034 static GFX_VTABLE allegro_gl_video_vtable;
00035 
00036 /* Counter for video bitmaps. screen = 1 */
00037 static int video_bitmap_count = 2;
00038 
00039 static int __allegro_gl_video_bitmap_bpp = -1;
00040 
00041 extern BITMAP *__agl_drawing_pattern_bmp;
00042 BITMAP *old_pattern = NULL;
00043 
00044 void allegro_gl_destroy_video_bitmap(BITMAP *bmp);
00045 
00046 
00047 
00048 static int allegro_gl_make_video_bitmap_helper1(int w, int h, int x, int y,
00049                                    GLint target, AGL_VIDEO_BITMAP **pvid) {
00050 
00051     int internal_format;
00052     int bpp;
00053 
00054     if (__allegro_gl_video_bitmap_bpp == -1) {
00055         bpp = bitmap_color_depth(screen);
00056     }
00057     else {
00058         bpp = __allegro_gl_video_bitmap_bpp;
00059     }
00060 
00061     (*pvid) = malloc(sizeof(AGL_VIDEO_BITMAP));
00062 
00063     if (!(*pvid))
00064         return -1;
00065 
00066     memset(*pvid, 0, sizeof(AGL_VIDEO_BITMAP));
00067 
00068     /* Create associated bitmap */
00069     (*pvid)->memory_copy = create_bitmap_ex(bpp, w, h);
00070     if (!(*pvid)->memory_copy)
00071         return -1;
00072     
00073     (*pvid)->format = __allegro_gl_get_bitmap_color_format((*pvid)->memory_copy, AGL_TEXTURE_HAS_ALPHA);
00074     (*pvid)->type = __allegro_gl_get_bitmap_type((*pvid)->memory_copy, 0);
00075     internal_format = __allegro_gl_get_texture_format_ex((*pvid)->memory_copy, AGL_TEXTURE_HAS_ALPHA);
00076 
00077     (*pvid)->target = target;
00078 
00079     /* Fill in some values in the bitmap to make it act as a subbitmap
00080      */
00081     (*pvid)->width  = w;
00082     (*pvid)->height = h;
00083     (*pvid)->x_ofs = x;
00084     (*pvid)->y_ofs = y;
00085 
00086     /* Make a texture out of it */
00087     glGenTextures(1, &((*pvid)->tex));
00088     if (!((*pvid)->tex))
00089         return -1;
00090 
00091     glEnable((*pvid)->target);
00092     glBindTexture((*pvid)->target, ((*pvid)->tex));
00093 
00094     glTexImage2D((*pvid)->target, 0, internal_format, w, h,
00095                  0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
00096 
00097     /* By default, use the Allegro filtering mode - ie: Nearest */
00098     glTexParameteri((*pvid)->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00099     glTexParameteri((*pvid)->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00100 
00101     /* <mmimica>
00102        Clamping removed because we want video bitmaps that are set for
00103        patterned drawing to be GL_REPEAT (default wrapping mode). Doesn't
00104        seem to break anything.
00105     */
00106 #if 0
00107     /* Clamp to edge */
00108     {
00109         GLenum clamp = GL_CLAMP_TO_EDGE;
00110         if (!allegro_gl_extensions_GL.SGIS_texture_edge_clamp) {
00111             clamp = GL_CLAMP;
00112         }
00113         glTexParameteri((*pvid)->target, GL_TEXTURE_WRAP_S, clamp);
00114         glTexParameteri((*pvid)->target, GL_TEXTURE_WRAP_T, clamp);
00115     }
00116 #endif
00117 
00118     glDisable((*pvid)->target);
00119 
00120     if (allegro_gl_extensions_GL.EXT_framebuffer_object) {
00121         glGenFramebuffersEXT(1, &((*pvid)->fbo));
00122         if (!(*pvid)->fbo) {
00123             glDeleteTextures(1, &((*pvid)->tex));
00124             return -1;
00125         }
00126 
00127         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (*pvid)->fbo);
00128         glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, (*pvid)->target, (*pvid)->tex, 0);
00129         if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
00130             /* Some FBO implementation limitation was hit, will use normal textures. */
00131             glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00132             glDeleteFramebuffersEXT(1, &((*pvid)->fbo));
00133             (*pvid)->fbo = 0;
00134             return 0;
00135         }
00136         
00137         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00138     }
00139     else {
00140         (*pvid)->fbo = 0;
00141     }
00142 
00143     return 0;
00144 }
00145 
00146 
00147 
00148 static int allegro_gl_make_video_bitmap_helper0(int w, int h, int x, int y,
00149                                                 AGL_VIDEO_BITMAP **pvid) {
00150         
00151     int is_power_of_2 = (!(w & (w - 1)) && !(h & (h - 1)));
00152     int texture_rect_available = allegro_gl_extensions_GL.ARB_texture_rectangle
00153 #ifdef ALLEGRO_MACOSX
00154                              || allegro_gl_extensions_GL.EXT_texture_rectangle
00155 #endif
00156                              || allegro_gl_extensions_GL.NV_texture_rectangle;
00157     GLint max_rect_texture_size = 0;
00158 
00159     if (texture_rect_available) {
00160         glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &max_rect_texture_size);
00161     }
00162 
00163     if (w <= allegro_gl_info.max_texture_size &&
00164         h <= allegro_gl_info.max_texture_size) {
00165         if (allegro_gl_extensions_GL.ARB_texture_non_power_of_two ||
00166             is_power_of_2) {
00167             if (allegro_gl_make_video_bitmap_helper1(w, h, x, y,
00168                                             GL_TEXTURE_2D, pvid)) {
00169                 return -1;
00170             }
00171         }
00172         else if (texture_rect_available &&
00173                  w <= max_rect_texture_size &&
00174                  h <= max_rect_texture_size) {
00175             if (allegro_gl_make_video_bitmap_helper1(w, h, x, y,
00176                                             GL_TEXTURE_RECTANGLE_ARB, pvid)) {
00177                 return -1;
00178             }
00179         }
00180         else {
00181             /* NPO2 textures are not suppored by the driver in any way.
00182              * Split the bitmap into smaller POT bitmaps. */
00183             const unsigned int BITS = sizeof(int) * CHAR_BIT;
00184             unsigned int i, j;
00185             unsigned int w1, h1;
00186             unsigned int x1, y1;
00187             unsigned int p1, p2;
00188 
00189             /* Find the POTs using bits. */
00190             y1 = 0;
00191             for (i = 0; i < BITS; i++) {
00192                 p1 = 1 << i;
00193                 if (h & p1)
00194                     h1 = p1;
00195                 else
00196                     continue;
00197 
00198                 x1 = 0;
00199                 for (j = 0; j < BITS; j++) {
00200                     p2 = 1 << j;
00201                     if (w & p2)
00202                         w1 = p2;
00203                     else
00204                         continue;
00205 
00206                     if (allegro_gl_make_video_bitmap_helper0(w1, h1, x + x1,
00207                                                         y + y1, pvid)) {
00208                         return -1;
00209                     }
00210                     do {
00211                         pvid = &((*pvid)->next);
00212                     } while (*pvid);
00213 
00214                     x1 += w1;
00215                 }
00216 
00217                 y1 += h1;
00218             }
00219         }
00220     }
00221     else {
00222         /* Texture is too big to fit. Split it in 4 and try again. */
00223         int w1, w2, h1, h2;
00224 
00225         w2 = w / 2;
00226         w1 = w - w2;
00227 
00228         h2 = h / 2;
00229         h1 = h - h2;
00230 
00231         /* Even a 1x1 texture didn't work? Bail*/
00232         if (!w2 && !h2) {
00233             return -1;
00234         }
00235 
00236         /* Top-left corner */
00237         if (allegro_gl_make_video_bitmap_helper0(w1, h1, x, y, pvid)) {
00238             return -1;
00239         }
00240         do {
00241             pvid = &((*pvid)->next);
00242         } while (*pvid);
00243 
00244         /* Top-right corner */
00245         if (w2) {
00246             if (allegro_gl_make_video_bitmap_helper0(w2, h1, x + w1, y, pvid)) {
00247                 return -1;
00248             }
00249             do {
00250                 pvid = &((*pvid)->next);
00251             } while (*pvid);
00252         }
00253         /* Bottom-left corner */
00254         if (h2) {
00255             if (allegro_gl_make_video_bitmap_helper0(w1, h2, x, y + h1, pvid)) {
00256                 return -1;
00257             }
00258             do {
00259                 pvid = &((*pvid)->next);
00260             } while (*pvid);
00261         }
00262         /* Bottom-right corner */
00263         if (w2 && h2) {
00264             if (allegro_gl_make_video_bitmap_helper0(w2, h2, x + w1, y + h1, pvid)) {
00265                 return -1;
00266             }
00267             do {
00268                 pvid = &((*pvid)->next);
00269             } while (*pvid);
00270         }
00271     }
00272 
00273     return 0;
00274 }
00275 
00276 
00277 
00278 /* Will make a (potentially piece-wise) texture out of the specified bitmap
00279  * Source -must- be a memory bitmap or memory subbitmap (created by Allegro
00280  * only).
00281  *
00282  */
00283 static BITMAP *allegro_gl_make_video_bitmap(BITMAP *bmp) {
00284     
00285     /* Grab a pointer to the bitmap data to patch */
00286     void *ptr = &bmp->extra;
00287     AGL_VIDEO_BITMAP **pvid = (AGL_VIDEO_BITMAP**)ptr;
00288     
00289     /* Convert bitmap to texture */
00290     if (allegro_gl_make_video_bitmap_helper0(bmp->w, bmp->h, 0, 0, pvid)) {
00291         goto agl_error;
00292     }
00293 
00294     return bmp;
00295     
00296 agl_error:
00297     allegro_gl_destroy_video_bitmap(bmp);
00298     return NULL;
00299 }
00300 
00301 
00302 
00303 /* void allegro_gl_destroy_video_bitmap(BITMAP *bmp) */
00308 void allegro_gl_destroy_video_bitmap(BITMAP *bmp) {
00309 
00310     AGL_VIDEO_BITMAP *vid = bmp ? bmp->extra : NULL, *next;
00311     
00312     if (!bmp)
00313         return;
00314     
00315     while (vid) {
00316         if (vid->memory_copy)
00317             destroy_bitmap(vid->memory_copy);
00318     
00319         if (vid->tex)
00320             glDeleteTextures(1, &vid->tex);
00321 
00322         if (vid->fbo)
00323             glDeleteFramebuffersEXT(1, &vid->fbo);
00324                                 
00325         next = vid->next;
00326         free(vid);
00327         vid = next;
00328     }
00329 
00330     free(bmp->vtable);
00331     free(bmp);
00332     
00333     return;
00334 }
00335 
00336 
00337 
00338 /* BITMAP *allegro_gl_create_video_bitmap(int w, int h) */
00344 BITMAP *allegro_gl_create_video_bitmap(int w, int h) {
00345     GFX_VTABLE *vtable;
00346     BITMAP *bitmap;
00347 
00348     bitmap = malloc(sizeof(BITMAP) + sizeof(char *));
00349     
00350     if (!bitmap)
00351         return NULL;
00352 
00353     bitmap->dat = NULL;
00354     bitmap->w = bitmap->cr = w;
00355     bitmap->h = bitmap->cb = h;
00356     bitmap->clip = TRUE;
00357     bitmap->cl = bitmap->ct = 0;
00358     bitmap->write_bank = bitmap->read_bank = NULL;
00359     /* We should keep tracks of allocated bitmaps for the ref counter */
00360     bitmap->id = BMP_ID_VIDEO | video_bitmap_count;
00361     bitmap->extra = NULL;
00362     bitmap->x_ofs = 0;
00363     bitmap->y_ofs = 0;
00364     bitmap->seg = _default_ds();
00365     bitmap->line[0] = NULL;
00366     bitmap->vtable = NULL;
00367 
00368     if (!allegro_gl_make_video_bitmap(bitmap)) {
00369         return NULL;
00370     }
00371     video_bitmap_count++;
00372     
00373     /* XXX <rohannessian> We ought to leave the Allegro values intact
00374      * Avoids bad interaction with correct Allegro programs.
00375      */
00376     vtable = malloc(sizeof(struct GFX_VTABLE));
00377     *vtable = allegro_gl_video_vtable;
00378     if (__allegro_gl_video_bitmap_bpp == -1) {
00379         vtable->color_depth = bitmap_color_depth(screen);
00380     }
00381     else {
00382         vtable->color_depth = __allegro_gl_video_bitmap_bpp;
00383     }
00384     switch (vtable->color_depth) {
00385         case 8:
00386             vtable->mask_color = MASK_COLOR_8;
00387         break;
00388         case 15:
00389             vtable->mask_color = MASK_COLOR_15;
00390         break;
00391         case 16:
00392             vtable->mask_color = MASK_COLOR_16;
00393         break;
00394         case 24:
00395             vtable->mask_color = MASK_COLOR_24;
00396         break;
00397         case 32:
00398             vtable->mask_color = MASK_COLOR_32;
00399         break;
00400     }
00401     bitmap->vtable = vtable;
00402 
00403     return bitmap;
00404 }
00405 
00406 
00407 
00408 /* allegro_gl_set_video_bitmap_color_depth(int bpp) */
00423 GLint allegro_gl_set_video_bitmap_color_depth(int bpp) {
00424     GLint old_val = __allegro_gl_video_bitmap_bpp;
00425     __allegro_gl_video_bitmap_bpp = bpp;
00426     return old_val;
00427 }
00428 
00429 
00430 /* static void allegro_gl_video_acquire(struct BITMAP *bmp) */
00437 static void allegro_gl_video_acquire(struct BITMAP *bmp) {}
00438 
00439 
00440 
00441 /* static void allegro_gl_video_release(struct BITMAP *bmp) */
00448 static void allegro_gl_video_release(struct BITMAP *bmp) {}
00449 
00450 
00451 
00452 static void set_drawing_pattern(void)
00453 {
00454     if (_drawing_pattern && !is_memory_bitmap(_drawing_pattern)) {
00455         old_pattern = _drawing_pattern;
00456         drawing_mode(_drawing_mode, __agl_drawing_pattern_bmp,
00457                      _drawing_x_anchor, _drawing_y_anchor);
00458     }
00459 }
00460 
00461 
00462 
00463 static void unset_drawing_pattern(void)
00464 {
00465     if (old_pattern) {
00466         drawing_mode(_drawing_mode, old_pattern,
00467                      _drawing_x_anchor, _drawing_y_anchor);
00468         old_pattern = NULL;
00469     }
00470 }
00471 
00472 
00473 
00474 static int allegro_gl_video_getpixel(struct BITMAP *bmp, int x, int y)
00475 {
00476     int pix = -1;
00477     AGL_VIDEO_BITMAP *vid;
00478     AGL_LOG(2, "glvtable.c:allegro_gl_screen_getpixel\n");  
00479     
00480     if (is_sub_bitmap(bmp)) {
00481         x += bmp->x_ofs;
00482         y += bmp->y_ofs;
00483     }
00484     if (x < bmp->cl || x >= bmp->cr || y < bmp->ct || y >= bmp->cb) {
00485         return -1;
00486     }
00487 
00488     vid = bmp->extra;
00489     
00490     while (vid) {
00491         if (vid->x_ofs <= x && vid->y_ofs <= y
00492          && vid->x_ofs + vid->memory_copy->w > x
00493          && vid->y_ofs + vid->memory_copy->h > y) {
00494             
00495             pix = getpixel(vid->memory_copy, x - vid->x_ofs, y - vid->y_ofs);
00496             break;
00497         }
00498         vid = vid->next;
00499     }
00500     
00501     if (pix != -1) {
00502         return pix;
00503     }
00504     
00505     return -1;
00506 }
00507 
00508 
00509 
00510 static void update_texture_memory(AGL_VIDEO_BITMAP *vid, int x1, int y1,
00511                                   int x2, int y2) {
00512     GLint saved_row_length;
00513     GLint saved_alignment;
00514     GLint type;
00515     GLint format;
00516     int bpp;
00517     BITMAP *temp = NULL;
00518     BITMAP *vbmp = vid->memory_copy;;
00519 
00520     glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00521     glGetIntegerv(GL_UNPACK_ALIGNMENT, &saved_alignment);
00522 
00523     bpp = BYTES_PER_PIXEL(bitmap_color_depth(vid->memory_copy));
00524     format = vid->format;
00525     type = vid->type;
00526 
00527     glColor4ub(255, 255, 255, 255);
00528 
00529     /* If packed pixels (or GL 1.2) isn't supported, then we need to convert
00530      * the bitmap into something GL can understand - 24-bpp should do it.
00531      */
00532     if (!allegro_gl_extensions_GL.EXT_packed_pixels
00533                                           && bitmap_color_depth(vbmp) < 24) {
00534         temp = create_bitmap_ex(24, vbmp->w, vbmp->h);
00535         if (!temp)
00536             return;
00537 
00538         blit(vbmp, temp, 0, 0, 0, 0, temp->w, temp->h);
00539         vbmp = temp;
00540         bpp = BYTES_PER_PIXEL(bitmap_color_depth(vbmp));
00541         format = __allegro_gl_get_bitmap_color_format(vbmp, 0);
00542         type = __allegro_gl_get_bitmap_type(vbmp, 0);
00543     }
00544 
00545     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00546     glPixelStorei(GL_UNPACK_ROW_LENGTH,
00547                   vbmp->h > 1
00548                  ? (vbmp->line[1] - vbmp->line[0]) / bpp
00549                  : vbmp->w);
00550 
00551     glEnable(vid->target);
00552     glBindTexture(vid->target, vid->tex);
00553     glTexSubImage2D(vid->target, 0,
00554         x1, y1, x2 - x1 + 1, y2 - y1 + 1, format,
00555         type, vbmp->line[y1] + x1 * bpp);
00556     glBindTexture(vid->target, 0);
00557     glDisable(vid->target);
00558 
00559     if (temp)
00560         destroy_bitmap(temp);
00561 
00562     glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00563     glPixelStorei(GL_UNPACK_ALIGNMENT, saved_alignment);
00564 }
00565 
00566 
00567 
00568 static void allegro_gl_video_putpixel(struct BITMAP *bmp, int x, int y,
00569                                       int color) {
00570     AGL_VIDEO_BITMAP *vid;
00571 
00572     if (is_sub_bitmap(bmp)) {
00573         x += bmp->x_ofs;
00574         y += bmp->y_ofs;
00575     }
00576     if (x < bmp->cl || x >= bmp->cr || y < bmp->ct || y >= bmp->cb) {
00577         return;
00578     }
00579 
00580     vid = bmp->extra;
00581 
00582     while (vid) {
00583         if (vid->x_ofs <= x && vid->y_ofs <= y
00584          && vid->x_ofs + vid->memory_copy->w > x
00585          && vid->y_ofs + vid->memory_copy->h > y) {
00586 
00587             set_drawing_pattern();
00588             putpixel(vid->memory_copy, x - vid->x_ofs, y - vid->y_ofs, color);
00589             unset_drawing_pattern();
00590             update_texture_memory(vid, x - vid->x_ofs, y - vid->y_ofs, x - vid->x_ofs, y - vid->y_ofs);
00591             break;
00592         }
00593         vid = vid->next;
00594     }
00595     
00596     return;
00597 }
00598 
00599 
00600 
00601 static void allegro_gl_video_vline(BITMAP *bmp, int x, int y1, int y2,
00602                                    int color) {
00603 
00604     AGL_VIDEO_BITMAP *vid;
00605     
00606     AGL_LOG(2, "glvtable.c:allegro_gl_video_vline\n");
00607     vid = bmp->extra;
00608     
00609     if (is_sub_bitmap(bmp)) {
00610         x  += bmp->x_ofs;
00611         y1 += bmp->y_ofs;
00612         y2 += bmp->y_ofs;
00613     }
00614     if (x < bmp->cl || x >= bmp->cr) {
00615         return;
00616     }
00617     
00618     if (y1 > y2) {
00619         int temp = y1;
00620         y1 = y2;
00621         y2 = temp;
00622     }
00623 
00624     if (y1 < bmp->ct) {
00625         y1 = bmp->ct;
00626     }
00627     if (y2 >= bmp->cb) {
00628         y2 = bmp->cb - 1;
00629     }
00630 
00631     while (vid) {
00632         BITMAP *vbmp = vid->memory_copy;
00633         
00634         int _y1, _y2, _x;
00635         if (vid->x_ofs > x || vid->y_ofs > y2
00636          || vid->x_ofs + vbmp->w <= x
00637          || vid->y_ofs + vbmp->h <= y1) {
00638             
00639             vid = vid->next;
00640             continue;
00641         }
00642         
00643         _y1 = MAX(y1, vid->y_ofs) - vid->y_ofs;
00644         _y2 = MIN(y2, vid->y_ofs + vbmp->h - 1) - vid->y_ofs;
00645         _x = x - vid->x_ofs;
00646 
00647         set_drawing_pattern();
00648         vline(vbmp, _x, _y1, _y2, color);
00649         unset_drawing_pattern();
00650         update_texture_memory(vid, _x, _y1, _x, _y2);
00651 
00652         vid = vid->next;
00653     }
00654     
00655     return;
00656 }
00657 
00658 
00659 
00660 static void allegro_gl_video_hline(BITMAP *bmp, int x1, int y, int x2,
00661                                    int color) {
00662 
00663     AGL_VIDEO_BITMAP *vid;
00664     
00665     AGL_LOG(2, "glvtable.c:allegro_gl_video_hline\n");
00666     vid = bmp->extra;
00667 
00668     if (is_sub_bitmap(bmp)) {
00669         x1 += bmp->x_ofs;
00670         x2 += bmp->x_ofs;
00671         y  += bmp->y_ofs;
00672     }
00673 
00674     if (y < bmp->ct || y >= bmp->cb) {
00675         return;
00676     }
00677     
00678     if (x1 > x2) {
00679         int temp = x1;
00680         x1 = x2;
00681         x2 = temp;
00682     }
00683 
00684     if (x1 < bmp->cl) {
00685         x1 = bmp->cl;
00686     }
00687     if (x2 >= bmp->cr) {
00688         x2 = bmp->cr - 1;
00689     }
00690 
00691     while (vid) {
00692         BITMAP *vbmp = vid->memory_copy;
00693         
00694         int _x1, _x2, _y;
00695         if (vid->y_ofs > y || vid->x_ofs > x2
00696          || vid->x_ofs + vbmp->w <= x1
00697          || vid->y_ofs + vbmp->h <= y) {
00698             
00699             vid = vid->next;
00700             continue;
00701         }
00702         
00703         _x1 = MAX(x1, vid->x_ofs) - vid->x_ofs;
00704         _x2 = MIN(x2, vid->x_ofs + vbmp->w - 1) - vid->x_ofs;
00705         _y = y - vid->y_ofs;
00706 
00707         set_drawing_pattern();
00708         hline(vbmp, _x1, _y, _x2, color);   
00709         unset_drawing_pattern();
00710         update_texture_memory(vid, _x1, _y, _x2, _y);
00711 
00712         vid = vid->next;
00713     }
00714     
00715     return;
00716 }
00717 
00718 
00719 
00720 static void allegro_gl_video_line(struct BITMAP *bmp, int x1, int y1, int x2,
00721                                   int y2, int color) {
00722     
00723     /* Note: very very slow */                      
00724     do_line(bmp, x1, y1, x2, y2, color, allegro_gl_video_putpixel);
00725     
00726     return;
00727 }
00728     
00729 
00730 
00731 static void allegro_gl_video_rectfill(struct BITMAP *bmp, int x1, int y1,
00732                                       int x2, int y2, int color) {
00733 
00734     AGL_VIDEO_BITMAP *vid;
00735 
00736     AGL_LOG(2, "glvtable.c:allegro_gl_video_rectfill\n");
00737     vid = bmp->extra;
00738 
00739     if (is_sub_bitmap(bmp)) {
00740         x1 += bmp->x_ofs;
00741         x2 += bmp->x_ofs;
00742         y1 += bmp->y_ofs;
00743         y2 += bmp->y_ofs;
00744     }
00745     
00746     if (y1 > y2) {
00747         int temp = y1;
00748         y1 = y2;
00749         y2 = temp;
00750     }
00751 
00752     if (x1 > x2) {
00753         int temp = x1;
00754         x1 = x2;
00755         x2 = temp;
00756     }
00757 
00758     if (x1 < bmp->cl) {
00759         x1 = bmp->cl;
00760     }
00761     if (x2 > bmp->cr) {
00762         x2 = bmp->cr;
00763     }
00764     if (y1 < bmp->ct) {
00765         y1 = bmp->ct;
00766     }
00767     if (y1 > bmp->cb) {
00768         y1 = bmp->cb;
00769     }
00770 
00771     while (vid) {
00772         BITMAP *vbmp = vid->memory_copy;
00773         
00774         int _y1, _y2, _x1, _x2;
00775         if (vid->x_ofs > x2 || vid->y_ofs > y2
00776          || vid->x_ofs + vbmp->w <= x1
00777          || vid->y_ofs + vbmp->h <= y1) {
00778             
00779             vid = vid->next;
00780             continue;
00781         }
00782         
00783         _y1 = MAX(y1, vid->y_ofs) - vid->y_ofs;
00784         _y2 = MIN(y2, vid->y_ofs + vbmp->h - 1) - vid->y_ofs;
00785         _x1 = MAX(x1, vid->x_ofs) - vid->x_ofs;
00786         _x2 = MIN(x2, vid->x_ofs + vbmp->w - 1) - vid->x_ofs;
00787 
00788         set_drawing_pattern();
00789         rectfill(vbmp, _x1, _y1, _x2, _y2, color);
00790         unset_drawing_pattern();
00791 
00792         update_texture_memory(vid, _x1, _y1, _x2, _y2);
00793 
00794         vid = vid->next;
00795     }
00796 
00797     return;
00798 }
00799 
00800 
00801 static void allegro_gl_video_triangle(struct BITMAP *bmp, int x1, int y1,
00802                                       int x2, int y2, int x3, int y3, int color)
00803 {   
00804     AGL_VIDEO_BITMAP *vid;
00805     int min_y, max_y, min_x, max_x;
00806 
00807     AGL_LOG(2, "glvtable.c:allegro_gl_video_triangle\n");
00808     vid = bmp->extra;
00809 
00810     if (is_sub_bitmap(bmp)) {
00811         x1 += bmp->x_ofs;
00812         x2 += bmp->x_ofs;
00813         x3 += bmp->x_ofs;
00814         y1 += bmp->y_ofs;
00815         y2 += bmp->y_ofs;
00816         y3 += bmp->y_ofs;
00817     }
00818 
00819     min_y = MIN(y1, MIN(y2, y3));
00820     min_x = MIN(x1, MIN(x2, x3));
00821     max_y = MAX(y1, MAX(y2, y3));
00822     max_x = MAX(x1, MAX(x2, x3));
00823 
00824     while (vid) {
00825         BITMAP *vbmp = vid->memory_copy;
00826         
00827         int _y1, _y2, _x1, _x2, _x3, _y3;
00828         if (vid->x_ofs > max_x || vid->y_ofs > max_y
00829          || vid->x_ofs + vbmp->w <= min_x
00830          || vid->y_ofs + vbmp->h <= min_y) {
00831             
00832             vid = vid->next;
00833             continue;
00834         }
00835         
00836         _y1 = y1 - vid->y_ofs;
00837         _y2 = y2 - vid->y_ofs;
00838         _y3 = y3 - vid->y_ofs;
00839         _x1 = x1 - vid->x_ofs;
00840         _x2 = x2 - vid->x_ofs;
00841         _x3 = x3 - vid->x_ofs;
00842 
00843         set_clip_rect(vbmp, bmp->cl - vid->x_ofs, bmp->ct - vid->y_ofs,
00844                             bmp->cr - vid->x_ofs - 1, bmp->cb - vid->y_ofs - 1);
00845 
00846         set_drawing_pattern();
00847 
00848         triangle(vbmp, _x1, _y1, _x2, _y2, _x3, _y3, color);
00849 
00850         unset_drawing_pattern();
00851 
00852         set_clip_rect(vbmp, 0, 0, vbmp->w - 1, vbmp->h - 1);
00853 
00854         /* Not quite the minimal rectangle occupied by the triangle, but
00855         * pretty close */
00856         _y1 = MAX(0, min_y - vid->y_ofs);
00857         _y2 = MIN(vbmp->h - 1, max_y - vid->y_ofs);
00858         _x1 = MAX(0, min_x - vid->x_ofs);
00859         _x2 = MIN(vbmp->w - 1, max_x - vid->x_ofs);
00860 
00861         update_texture_memory(vid, _x1, _y1, _x2, _y2);
00862 
00863         vid = vid->next;
00864     }
00865 }
00866 
00867 
00868 
00869 static void allegro_gl_video_blit_from_memory_ex(BITMAP *source, BITMAP *dest,
00870                     int source_x, int source_y, int dest_x, int dest_y,
00871                     int width, int height, int draw_type) {
00872 
00873     AGL_VIDEO_BITMAP *vid;
00874     BITMAP *dest_parent = dest;
00875     
00876     if (is_sub_bitmap (dest)) {
00877        dest_x += dest->x_ofs;
00878        dest_y += dest->y_ofs;
00879        while (dest_parent->id & BMP_ID_SUB)
00880           dest_parent = (BITMAP *)dest_parent->extra;
00881     }
00882 
00883     if (dest_x < dest->cl) {
00884         dest_x = dest->cl;
00885     }
00886     if (dest_y < dest->ct) {
00887         dest_y = dest->ct;
00888     }
00889     if (dest_x + width >= dest->cr) {
00890         width = dest->cr - dest_x;
00891     }
00892     if (dest_y + height >= dest->cb) {
00893         height = dest->cb - dest_y;
00894     }
00895     if (width < 1 || height < 1) {
00896         return;
00897     }
00898     
00899     vid = dest_parent->extra;
00900 
00901     while (vid) {
00902         BITMAP *vbmp = vid->memory_copy;
00903 
00904         int _x, _y, _w, _h, _sx, _sy;
00905         if (vid->x_ofs >= dest_x + width || vid->y_ofs >= dest_y + height
00906          || vid->x_ofs + vbmp->w <= dest_x
00907          || vid->y_ofs + vbmp->h <= dest_y) {
00908             
00909             vid = vid->next;
00910             continue;
00911         }
00912 
00913         _x = MAX (vid->x_ofs, dest_x) - vid->x_ofs;
00914         _w = MIN (vid->x_ofs + vbmp->w, dest_x + width)
00915            - vid->x_ofs - _x;
00916         _y = MAX (vid->y_ofs, dest_y) - vid->y_ofs;
00917         _h = MIN (vid->y_ofs + vbmp->h, dest_y + height)
00918            - vid->y_ofs - _y;
00919 
00920         _sx = source_x + vid->x_ofs + _x - dest_x;
00921         _sy = source_y + vid->y_ofs + _y - dest_y;
00922 
00923         if (draw_type == BLIT) {
00924             blit(source, vbmp, _sx, _sy, _x, _y, _w, _h);
00925         }
00926         else if (draw_type == MASKED_BLIT) {
00927             masked_blit(source, vbmp, _sx, _sy, _x, _y, _w, _h);
00928         }
00929         else if (draw_type == TRANS) {
00930             BITMAP *clip = create_sub_bitmap(source, _sx, _sy, _w, _h);
00931             if (!clip)
00932                 return;
00933             draw_trans_sprite(vbmp, clip, _x, _y);
00934             destroy_bitmap(clip);
00935         }
00936 
00937         update_texture_memory(vid, _x, _y, _x + _w - 1, _y + _h - 1);
00938 
00939         vid = vid->next;
00940     }
00941 
00942     return; 
00943 }
00944 
00945 
00946 void allegro_gl_video_blit_from_memory(BITMAP *source, BITMAP *dest,
00947                     int source_x, int source_y, int dest_x, int dest_y,
00948                     int width, int height) {
00949 
00950     allegro_gl_video_blit_from_memory_ex(source, dest, source_x, source_y,
00951                                          dest_x, dest_y, width, height, BLIT);
00952     return;
00953 }
00954 
00955 
00956 
00957 void allegro_gl_video_blit_to_memory(struct BITMAP *source, struct BITMAP *dest,
00958                          int source_x, int source_y, int dest_x, int dest_y,
00959                          int width, int height) {
00960 
00961     AGL_VIDEO_BITMAP *vid;
00962     BITMAP *source_parent = source;
00963     
00964     AGL_LOG(2, "glvtable.c:allegro_gl_video_blit_to_memory\n");
00965     
00966     if (is_sub_bitmap(source)) {
00967        source_x += source->x_ofs;
00968        source_y += source->y_ofs;
00969        while (source_parent->id & BMP_ID_SUB)
00970           source_parent = (BITMAP *)source_parent->extra;
00971     }
00972 
00973     vid = source_parent->extra;
00974     
00975     while (vid) {
00976         BITMAP *vbmp = vid->memory_copy;
00977         int x, y, dx, dy, w, h;
00978 
00979         x = MAX(source_x, vid->x_ofs) - vid->x_ofs;
00980         y = MAX(source_y, vid->y_ofs) - vid->y_ofs;
00981         w = MIN(vid->x_ofs + vbmp->w, source_x + width) - vid->x_ofs;
00982         h = MIN(vid->y_ofs + vbmp->h, source_y + height) - vid->y_ofs;
00983         dx = MAX(0, vid->x_ofs - source_x) + dest_x;
00984         dy = MAX(0, vid->y_ofs - source_y) + dest_y;
00985 
00986         blit(vbmp, dest, x, y, dx, dy, w, h);
00987     
00988         vid = vid->next;
00989     }
00990 
00991     return; 
00992 }
00993 
00994 
00995 
00996 /* Just like allegro_gl_video_blit_from_memory(), except that draws only to the
00997  * memory copy.
00998  */
00999 static void __video_update_memory_copy(BITMAP *source, BITMAP *dest,
01000                             int source_x, int source_y, int dest_x, int dest_y,
01001                             int width, int height, int draw_type) {
01002     AGL_VIDEO_BITMAP *vid;
01003     BITMAP *dest_parent = dest;
01004     
01005     if (is_sub_bitmap (dest)) {
01006        dest_x += dest->x_ofs;
01007        dest_y += dest->y_ofs;
01008        while (dest_parent->id & BMP_ID_SUB)
01009           dest_parent = (BITMAP *)dest_parent->extra;
01010     }
01011 
01012     if (dest_x < dest->cl) {
01013         dest_x = dest->cl;
01014     }
01015     if (dest_y < dest->ct) {
01016         dest_y = dest->ct;
01017     }
01018     if (dest_x + width >= dest->cr) {
01019         width = dest->cr - dest_x;
01020     }
01021     if (dest_y + height >= dest->cb) {
01022         height = dest->cb - dest_y;
01023     }
01024     if (width < 1 || height < 1) {
01025         return;
01026     }
01027     
01028     vid = dest_parent->extra;
01029 
01030     while (vid) {
01031         int sx, sy;
01032         BITMAP *vbmp = vid->memory_copy;
01033 
01034         int dx, dy, w, h;
01035         if (vid->x_ofs >= dest_x + width || vid->y_ofs >= dest_y + height
01036          || vid->x_ofs + vbmp->w <= dest_x
01037          || vid->y_ofs + vbmp->h <= dest_y) {
01038             
01039             vid = vid->next;
01040             continue;
01041         }
01042 
01043         dx = MAX (vid->x_ofs, dest_x) - vid->x_ofs;
01044         w = MIN (vid->x_ofs + vbmp->w, dest_x + width)
01045            - vid->x_ofs - dx;
01046         dy = MAX (vid->y_ofs, dest_y) - vid->y_ofs;
01047         h = MIN (vid->y_ofs + vbmp->h, dest_y + height)
01048            - vid->y_ofs - dy;
01049 
01050         sx = source_x + vid->x_ofs + dx - dest_x;
01051         sy = source_y + vid->y_ofs + dy - dest_y;
01052 
01053         if (draw_type == MASKED_BLIT) {
01054             masked_blit(source, vbmp, sx, sy, dx, dy, w, h);
01055         }
01056         else if (draw_type == BLIT) {
01057             blit(source, vbmp, sx, sy, dx, dy, w, h);
01058         }
01059         else if (draw_type == TRANS) {
01060             BITMAP *clip = create_sub_bitmap(source, sx, sy, w, h);
01061             if (!clip)
01062                 return;
01063             draw_trans_sprite(vbmp, clip, dx, dy);
01064             destroy_bitmap(clip);
01065         }
01066 
01067         vid = vid->next;
01068     }
01069     
01070     return;
01071 }
01072 
01073 
01074 #define FOR_EACH_TEXTURE_FRAGMENT(  \
01075     screen_blit_from_vid,           /* used when dest is FBO to blit to texture 
01076                                        memory from video bitmap */                \
01077     screen_blit_from_mem,           /* used when dest is FBO to blit to texture
01078                                        memory from memory bitmap */               \
01079     mem_copy_blit_from_vid,         /* used to update the memory copy of the
01080                                        dest from the source video bitmap */       \
01081     mem_copy_blit_from_mem,         /* used to update the memory copy of the
01082                                        dest from the source memory bitmap */      \
01083     vid_and_mem_copy_blit_from_vid, /* used when dest is not FBO, draws to both
01084                                        memory copy and texute memory of the dest,
01085                                        from video bitmap source*/                 \
01086     vid_and_mem_copy_blit_from_mem) /* used when dest is not FBO, draws to both
01087                                        memory copy and texute memory of the dest,
01088                                        from memory bitmap source */               \
01089 {                                                          \
01090     int used_fbo = FALSE;                                  \
01091     AGL_VIDEO_BITMAP *vid;                                 \
01092                                                            \
01093     vid = dest->extra;                                     \
01094     if (vid->fbo) {                                        \
01095         int sx, sy;                                        \
01096         int dx, dy;                                        \
01097         int w, h;                                          \
01098                                                            \
01099         static GLint v[4];                                 \
01100         static double allegro_gl_projection_matrix[16];    \
01101         static double allegro_gl_modelview_matrix[16];     \
01102                                                            \
01103         glGetIntegerv(GL_VIEWPORT, &v[0]);                 \
01104         glMatrixMode(GL_MODELVIEW);                        \
01105         glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);   \
01106         glMatrixMode(GL_PROJECTION);                                      \
01107         glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix); \
01108                                                                           \
01109         while (vid) {                                                     \
01110             if (dest_x >= vid->x_ofs + vid->memory_copy->w ||             \
01111                 dest_y >= vid->y_ofs + vid->memory_copy->h ||             \
01112                 vid->x_ofs >= dest_x + width ||          \
01113                 vid->y_ofs >= dest_y + height) {         \
01114                 vid = vid->next;                         \
01115                 continue;                                \
01116             }                                            \
01117                                                          \
01118             dx = MAX(vid->x_ofs, dest_x) - vid->x_ofs;                  \
01119             w = MIN(vid->x_ofs + vid->memory_copy->w, dest_x + width)   \
01120               - vid->x_ofs - dx;                                        \
01121             dy = MAX(vid->y_ofs, dest_y) - vid->y_ofs;                  \
01122             h = MIN(vid->y_ofs + vid->memory_copy->h, dest_y + height)  \
01123               - vid->y_ofs - dy;                                        \
01124                                                                         \
01125             sx = source_x + vid->x_ofs + dx - dest_x;                   \
01126             sy = source_y + vid->y_ofs + dy - dest_y;                   \
01127                                                                         \
01128             glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo);         \
01129                                                                         \
01130             glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h); \
01131             glMatrixMode(GL_PROJECTION);                                \
01132             glLoadIdentity();                                           \
01133             gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h); \
01134             glMatrixMode(GL_MODELVIEW);                                 \
01135                                              \
01136             if (is_memory_bitmap(source)) {  \
01137                 screen_blit_from_mem;        \
01138             }                                \
01139             else {                           \
01140                 screen_blit_from_vid;        \
01141             }                                \
01142                                 \
01143             vid = vid->next;    \
01144         }                       \
01145                                 \
01146         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); \
01147                                                      \
01148         glViewport(v[0], v[1], v[2], v[3]);          \
01149         glMatrixMode(GL_PROJECTION);                 \
01150         glLoadMatrixd(allegro_gl_projection_matrix); \
01151         glMatrixMode(GL_MODELVIEW);                  \
01152         glLoadMatrixd(allegro_gl_modelview_matrix);  \
01153                                           \
01154         used_fbo = TRUE;                  \
01155     }                                     \
01156                                           \
01157     if (is_video_bitmap(source)) {        \
01158         int sx, sy;      \
01159         int dx, dy;      \
01160         int w, h;        \
01161                          \
01162         vid = source->extra;   \
01163                                \
01164         while (vid) {          \
01165             if (source_x >= vid->x_ofs + vid->memory_copy->w ||  \
01166                 source_y >= vid->y_ofs + vid->memory_copy->h ||  \
01167                 vid->x_ofs >= source_x + width ||                \
01168                 vid->y_ofs >= source_y + height) {               \
01169                 vid = vid->next;                                 \
01170                 continue;                                        \
01171             }                                                    \
01172                                                                  \
01173             sx = MAX(vid->x_ofs, source_x) - vid->x_ofs;         \
01174             w = MIN(vid->x_ofs + vid->memory_copy->w, source_x + width)  \
01175               - vid->x_ofs - sx;                                         \
01176             sy = MAX(vid->y_ofs, source_y) - vid->y_ofs;                 \
01177             h = MIN(vid->y_ofs + vid->memory_copy->h, source_y + height) \
01178               - vid->y_ofs - sy;                                         \
01179                                                                          \
01180             dx = dest_x + vid->x_ofs + sx - source_x;  \
01181             dy = dest_y + vid->y_ofs + sy - source_y;  \
01182                                                        \
01183             if (used_fbo) {                            \
01184                 mem_copy_blit_from_vid;                \
01185             }                                          \
01186             else {                                     \
01187                 vid_and_mem_copy_blit_from_vid;        \
01188             }                                  \
01189                                                \
01190             vid = vid->next;                   \
01191         }                                      \
01192     }                                          \
01193     else if (is_memory_bitmap(source)) {       \
01194         if (used_fbo) {                        \
01195             mem_copy_blit_from_mem;            \
01196         }                                      \
01197         else {                                 \
01198             vid_and_mem_copy_blit_from_mem;    \
01199         }                                      \
01200     }                                          \
01201 }
01202 
01203 
01204 /* allegro_gl_video_blit_to_self:
01205  * blit() overload for video -> video blits
01206  */
01207 void allegro_gl_video_blit_to_self(struct BITMAP *source, struct BITMAP *dest,
01208     int source_x, int source_y, int dest_x, int dest_y, int width, int height) {
01209 
01210     FOR_EACH_TEXTURE_FRAGMENT (
01211         allegro_gl_screen_blit_to_self(source, screen, sx, sy, dx, dy, w, h),
01212         allegro_gl_screen_blit_to_self(source, screen, sx, sy, dx, dy, w, h),
01213         __video_update_memory_copy(vid->memory_copy, dest, sx, sy, dx, dy, w, h, BLIT),
01214         __video_update_memory_copy(source, dest, source_x, source_y, dest_x, dest_y, width, height, BLIT),
01215         allegro_gl_video_blit_from_memory(vid->memory_copy, dest, sx, sy, dx, dy, w, h),
01216         allegro_gl_video_blit_from_memory(source, dest, source_x, source_y, dest_x, dest_y, width, height)
01217     )
01218 }
01219 
01220 
01221 static void do_masked_blit_video(struct BITMAP *source, struct BITMAP *dest,
01222             int source_x, int source_y, int dest_x, int dest_y,
01223             int width, int height, int flip_dir, int blit_type) {
01224 
01225     FOR_EACH_TEXTURE_FRAGMENT (
01226         do_masked_blit_screen(source, screen, sx, sy, dx, dy, w, h, flip_dir, blit_type),
01227         do_masked_blit_screen(source, screen, sx, sy, dx, dy, w, h, flip_dir, blit_type),
01228         __video_update_memory_copy(vid->memory_copy, dest, sx, sy, dx, dy, w, h, MASKED_BLIT),
01229         __video_update_memory_copy(source, dest, source_x, source_y, dest_x, dest_y, width, height, MASKED_BLIT),
01230         allegro_gl_video_blit_from_memory_ex(vid->memory_copy, dest, sx, sy, dx, dy, w, h, MASKED_BLIT),
01231         allegro_gl_video_blit_from_memory_ex(source, dest, source_x, source_y, dest_x, dest_y, width, height, MASKED_BLIT)
01232     )
01233 }
01234 
01235 
01236 /* allegro_gl_video_masked_blit:
01237  * masked_blit() overload for video -> video masked blits
01238  */
01239 static void allegro_gl_video_masked_blit(struct BITMAP *source,
01240                 struct BITMAP *dest, int source_x, int source_y,
01241                 int dest_x, int dest_y, int width, int height) {
01242     do_masked_blit_video(source, dest, source_x, source_y, dest_x, dest_y,
01243                          width, height, FALSE, AGL_REGULAR_BMP | AGL_NO_ROTATION);
01244 
01245     return;
01246 }
01247 
01248 
01249 /* allegro_gl_video_draw_sprite:
01250  * draw_sprite() overload for video -> video sprite drawing
01251  */
01252 static void allegro_gl_video_draw_sprite(struct BITMAP *bmp,
01253                         struct BITMAP *sprite, int x, int y) {
01254 
01255     do_masked_blit_video(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
01256                          FALSE, AGL_NO_ROTATION);
01257 
01258     return;
01259 }
01260 
01261 
01262 /* allegro_gl_video_draw_sprite_v_flip:
01263  * draw_sprite_v_flip() overload for video -> video blits
01264  * FIXME: Broken if the bitmap was split into multiple textures.
01265  * FIXME: Doesn't apply rotation and scale to the memory copy
01266  */
01267 static void allegro_gl_video_draw_sprite_v_flip(struct BITMAP *bmp,
01268                         struct BITMAP *sprite, int x, int y) {
01269 
01270     do_masked_blit_video(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
01271                          AGL_V_FLIP, AGL_NO_ROTATION);
01272 
01273     return;
01274 }
01275 
01276 
01277 /* allegro_gl_video_draw_sprite_h_flip:
01278  * draw_sprite_v_flip() overload for video -> video blits
01279  * FIXME: Broken if the bitmap was split into multiple textures.
01280  * FIXME: Doesn't apply rotation and scale to the memory copy
01281  */
01282 static void allegro_gl_video_draw_sprite_h_flip(struct BITMAP *bmp,
01283                         struct BITMAP *sprite, int x, int y) {
01284 
01285     do_masked_blit_video(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
01286                          AGL_H_FLIP, AGL_NO_ROTATION);
01287 
01288     return;
01289 }
01290 
01291 
01292 /* allegro_gl_video_draw_sprite_vh_flip:
01293  * draw_sprite_vh_flip() overload for video -> video blits
01294  * FIXME: Broken if the bitmap was split into multiple textures.
01295  * FIXME: Doesn't apply rotation and scale to the memory copy
01296  */
01297 static void allegro_gl_video_draw_sprite_vh_flip(struct BITMAP *bmp,
01298                         struct BITMAP *sprite, int x, int y) {
01299 
01300     do_masked_blit_video(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
01301                          AGL_V_FLIP | AGL_H_FLIP, AGL_NO_ROTATION);
01302 
01303     return;
01304 }
01305 
01306 
01307 /* allegro_gl_video_pivot_scaled_sprite_flip:
01308  * FIXME: Broken if the bitmap was split into multiple textures.
01309  * FIXME: Doesn't apply rotation and scale to the memory copy
01310  * FIXME: Doesn't work for when FBO is not available.
01311  */
01312 static void allegro_gl_video_pivot_scaled_sprite_flip(struct BITMAP *bmp,
01313             struct BITMAP *sprite, fixed x, fixed y, fixed cx, fixed cy,
01314             fixed angle, fixed scale, int v_flip) {
01315     double dscale = fixtof(scale);
01316     GLint matrix_mode;
01317     
01318 #define BIN_2_DEG(x) (-(x) * 180.0 / 128)
01319     
01320     glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
01321     glMatrixMode(GL_MODELVIEW);
01322     glPushMatrix();
01323     glTranslated(fixtof(x), fixtof(y), 0.);
01324     glRotated(BIN_2_DEG(fixtof(angle)), 0., 0., -1.);
01325     glScaled(dscale, dscale, dscale);
01326     glTranslated(-fixtof(x+cx), -fixtof(y+cy), 0.);
01327     
01328     do_masked_blit_video(sprite, bmp, 0, 0, fixtoi(x), fixtoi(y),
01329                           sprite->w, sprite->h, v_flip ? AGL_V_FLIP : FALSE, FALSE);
01330     glPopMatrix();
01331     glMatrixMode(matrix_mode);
01332 
01333 #undef BIN_2_DEG
01334 
01335     return;
01336 }
01337 
01338 
01339 /* allegro_gl_video_do_stretch_blit:
01340  * overload for all kind of video -> video and video -> screen stretchers
01341  * FIXME: Doesn't apply scale to the memory copy
01342  * FIXME: Doesn't work for video->video when FBO is not available.
01343  */
01344 static void allegro_gl_video_do_stretch_blit(BITMAP *source, BITMAP *dest,
01345                int source_x, int source_y, int source_width, int source_height,
01346                int dest_x, int dest_y, int dest_width, int dest_height,
01347                int masked) {
01348     /* note: src is a video bitmap, dest is not a memory bitmap */
01349 
01350     double scalew = ((double)dest_width) / source_width;
01351     double scaleh = ((double)dest_height) / source_height;
01352     
01353     GLint matrix_mode;
01354 
01355     /* BITMAP_BLIT_CLIP macro from glvtable.c is no good for scaled images. */
01356     if (dest->clip) {
01357         if ((dest_x >= dest->cr) || (dest_y >= dest->cb)
01358          || (dest_x + dest_width < dest->cl) || (dest_y + dest_height < dest->ct)) {
01359             return;
01360         }
01361         if (dest_x < dest->cl) {
01362             source_x -= (dest_x - dest->cl) / scalew;
01363             dest_x = dest->cl;
01364         }
01365         if (dest_y < dest->ct) {
01366             source_y -= (dest_y - dest->ct) / scaleh;
01367             dest_y = dest->ct;
01368         }
01369         if (dest_x + dest_width > dest->cr) {
01370             source_width -= (dest_x + dest_width - dest->cr) / scalew;
01371             dest_width = dest->cr - dest_x;
01372         }
01373         if (dest_y + dest_height > dest->cb) {
01374             source_height -= (dest_y + dest_height - dest->cb) / scaleh;
01375             dest_height = dest->cb - dest_y;
01376         }
01377     }
01378 
01379     glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
01380     glMatrixMode(GL_MODELVIEW);
01381     glPushMatrix();
01382     glTranslated(dest_x, dest_y, 0.);
01383     glScaled(scalew, scaleh, 1.);
01384     glTranslated(-dest_x, -dest_y, 0.);
01385 
01386     if (masked) {
01387         if (is_screen_bitmap(dest)) {
01388             do_masked_blit_screen(source, dest, source_x, source_y,
01389                                   dest_x, dest_y, source_width, source_height,
01390                                   FALSE, AGL_REGULAR_BMP);
01391         }
01392         else {
01393             do_masked_blit_video(source, dest, source_x, source_y,
01394                                  dest_x, dest_y, source_width, source_height,
01395                                  FALSE, AGL_REGULAR_BMP);
01396         }
01397     }
01398     else {
01399         allegro_gl_screen_blit_to_self(source, dest, source_x, source_y,
01400                            dest_x, dest_y, source_width, source_height);
01401     }
01402 
01403     glPopMatrix();
01404     glMatrixMode(matrix_mode);
01405 
01406     return;
01407 }
01408 
01409 
01410 
01411 /* allegro_gl_video_draw_trans_rgba_sprite:
01412  * draw_trans_sprite() overload for video -> video drawing
01413  */
01414 static void allegro_gl_video_draw_trans_rgba_sprite(BITMAP *bmp,
01415                                 BITMAP *sprite, int x, int y) {
01416     /* Adapt variables for FOR_EACH_TEXTURE_FRAGMENT macro. */
01417     BITMAP *source = sprite;
01418     BITMAP *dest = bmp;
01419     int dest_x = x;
01420     int dest_y = y;
01421     int source_x = 0;
01422     int source_y = 0;
01423     int width = sprite->w;
01424     int height = sprite->h;
01425     GLint format = __allegro_gl_get_bitmap_color_format(sprite, AGL_TEXTURE_HAS_ALPHA);
01426     GLint type = __allegro_gl_get_bitmap_type(sprite, 0);
01427 
01428     if (__allegro_gl_blit_operation == AGL_OP_LOGIC_OP)
01429         glEnable(GL_COLOR_LOGIC_OP);
01430     else
01431         glEnable(GL_BLEND);
01432 
01433     FOR_EACH_TEXTURE_FRAGMENT (
01434         allegro_gl_screen_blit_to_self(source, screen, sx, sy, dx, dy, w, h),
01435         allegro_gl_upload_and_display_texture(sprite, sx, sy, dx, dy, w, h, 0, format, type),
01436         __video_update_memory_copy(vid->memory_copy, dest, sx, sy, dx, dy, w, h, TRANS),
01437         __video_update_memory_copy(source, dest, 0, 0, x, y, sprite->w, sprite->h, TRANS),
01438         allegro_gl_video_blit_from_memory_ex(vid->memory_copy, dest, sx, sy, dx, dy, w, h, TRANS),
01439         allegro_gl_video_blit_from_memory_ex(source, dest, 0, 0, x, y, sprite->w, sprite->h, TRANS)
01440     )
01441 
01442     if (__allegro_gl_blit_operation == AGL_OP_LOGIC_OP)
01443         glDisable(GL_COLOR_LOGIC_OP);
01444     else
01445         glDisable(GL_BLEND);
01446 
01447     return;
01448 }
01449 
01450 
01451 
01452 static void allegro_gl_video_clear_to_color(BITMAP *bmp, int color) {
01453     AGL_VIDEO_BITMAP *vid = bmp->extra;
01454 
01455     if (vid->fbo) {
01456         static GLint v[4];
01457         static double allegro_gl_projection_matrix[16];
01458         static double allegro_gl_modelview_matrix[16];
01459 
01460         glGetIntegerv(GL_VIEWPORT, &v[0]);
01461         glMatrixMode(GL_MODELVIEW);
01462         glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);
01463         glMatrixMode(GL_PROJECTION);
01464         glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix);
01465 
01466         while (vid) {
01467             glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo);
01468 
01469             glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h);
01470             glMatrixMode(GL_PROJECTION);
01471             glLoadIdentity();
01472             gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h);
01473             glMatrixMode(GL_MODELVIEW);
01474 
01475             allegro_gl_screen_clear_to_color(bmp, color);
01476             clear_to_color(vid->memory_copy, color);
01477             vid = vid->next;
01478         }
01479 
01480         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
01481     
01482         glViewport(v[0], v[1], v[2], v[3]);
01483         glMatrixMode(GL_PROJECTION);
01484         glLoadMatrixd(allegro_gl_projection_matrix);
01485         glMatrixMode(GL_MODELVIEW);
01486         glLoadMatrixd(allegro_gl_modelview_matrix);
01487     }
01488     else {
01489         allegro_gl_video_rectfill(bmp, 0, 0, bmp->w, bmp->h, color);
01490     }
01491 }
01492 
01493 
01494 
01495 /* FIXME: Doesn't work when FBO is not available.
01496  * FIXME: Doesn't care for segmented video bitmaps.
01497  */
01498 static void allegro_gl_video_draw_color_glyph(struct BITMAP *bmp,
01499     struct BITMAP *sprite, int x, int y, int color, int bg)
01500 {
01501     AGL_VIDEO_BITMAP *vid = bmp->extra;
01502 
01503     static GLint v[4];
01504     static double allegro_gl_projection_matrix[16];
01505     static double allegro_gl_modelview_matrix[16];
01506 
01507     if (!vid->fbo)
01508         return;
01509 
01510     glGetIntegerv(GL_VIEWPORT, &v[0]);
01511     glMatrixMode(GL_MODELVIEW);
01512     glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);
01513     glMatrixMode(GL_PROJECTION);
01514     glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix);
01515 
01516     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo);
01517 
01518     glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h);
01519     glMatrixMode(GL_PROJECTION);
01520     glLoadIdentity();
01521     gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h);
01522     glMatrixMode(GL_MODELVIEW);
01523 
01524     allegro_gl_screen_draw_color_glyph_ex(bmp, sprite, x, y, color, bg, 0);
01525 
01526     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
01527 
01528     glViewport(v[0], v[1], v[2], v[3]);
01529     glMatrixMode(GL_PROJECTION);
01530     glLoadMatrixd(allegro_gl_projection_matrix);
01531     glMatrixMode(GL_MODELVIEW);
01532     glLoadMatrixd(allegro_gl_modelview_matrix);
01533 
01534     vid->memory_copy->vtable->draw_character(vid->memory_copy, sprite, x, y, color, bg);
01535 }
01536 
01537 
01538 
01539 static void allegro_gl_video_draw_256_sprite(BITMAP *bmp, BITMAP *sprite,
01540                                       int x, int y) {
01541     allegro_gl_video_draw_color_glyph(bmp, sprite, x, y, -1, _textmode);
01542 }
01543 
01544 
01545 
01546 static void allegro_gl_video_draw_character(BITMAP *bmp, BITMAP *sprite,
01547                                             int x, int y, int color, int bg) {
01548     allegro_gl_video_draw_color_glyph(bmp, sprite, x, y, color, bg);
01549 }
01550 
01551 
01552 
01553 /* FIXME: Doesn't work when FBO is not available.
01554  * FIXME: Doesn't care for segmented video bitmaps.
01555  */
01556 static void allegro_gl_video_draw_glyph(struct BITMAP *bmp,
01557                                AL_CONST struct FONT_GLYPH *glyph, int x, int y,
01558                                int color, int bg) {
01559     AGL_VIDEO_BITMAP *vid = bmp->extra;
01560 
01561     static GLint v[4];
01562     static double allegro_gl_projection_matrix[16];
01563     static double allegro_gl_modelview_matrix[16];
01564 
01565     if (!vid->fbo)
01566         return;
01567 
01568     glGetIntegerv(GL_VIEWPORT, &v[0]);
01569     glMatrixMode(GL_MODELVIEW);
01570     glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);
01571     glMatrixMode(GL_PROJECTION);
01572     glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix);
01573 
01574     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo);
01575 
01576     glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h);
01577     glMatrixMode(GL_PROJECTION);
01578     glLoadIdentity();
01579     gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h);
01580     glMatrixMode(GL_MODELVIEW);
01581 
01582     allegro_gl_screen_draw_glyph_ex(bmp, glyph, x, y, color, bg, 1);
01583 
01584     glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
01585 
01586     glViewport(v[0], v[1], v[2], v[3]);
01587     glMatrixMode(GL_PROJECTION);
01588     glLoadMatrixd(allegro_gl_projection_matrix);
01589     glMatrixMode(GL_MODELVIEW);
01590     glLoadMatrixd(allegro_gl_modelview_matrix);
01591 
01592     vid->memory_copy->vtable->draw_glyph(vid->memory_copy, glyph, x, y, color, bg);
01593 }
01594 
01595 
01596 
01597 static void allegro_gl_video_polygon3d_f(BITMAP *bmp, int type, BITMAP *texture,
01598                                   int vc, V3D_f *vtx[])
01599 {
01600     AGL_VIDEO_BITMAP *vid = bmp->extra;
01601 
01602     /* Switch to software mode is using polygon type that isn't supported by
01603        allegro_gl_screen_polygon3d_f. */
01604     int use_fbo = (type == POLYTYPE_FLAT) ||
01605                   (type == POLYTYPE_GRGB) ||
01606                   (type == POLYTYPE_GCOL) ||
01607                   (type == POLYTYPE_ATEX) ||
01608                   (type == POLYTYPE_PTEX) ||
01609                   (type == POLYTYPE_ATEX_TRANS) ||
01610                   (type == POLYTYPE_PTEX_TRANS);
01611 
01612     if (vid->fbo && use_fbo) {
01613         static GLint v[4];
01614         static double allegro_gl_projection_matrix[16];
01615         static double allegro_gl_modelview_matrix[16];
01616 
01617         glGetIntegerv(GL_VIEWPORT, &v[0]);
01618         glMatrixMode(GL_MODELVIEW);
01619         glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);
01620         glMatrixMode(GL_PROJECTION);
01621         glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix);
01622 
01623         while (vid) {
01624             BITMAP *mem_texture;
01625 
01626             glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo);
01627 
01628             glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h);
01629             glMatrixMode(GL_PROJECTION);
01630             glLoadIdentity();
01631             gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h);
01632             glMatrixMode(GL_MODELVIEW);
01633 
01634             allegro_gl_screen_polygon3d_f(bmp, type, texture, vc, vtx);
01635 
01636             if (is_video_bitmap(texture)) {
01637                 AGL_VIDEO_BITMAP *vbmp = texture->extra;
01638                 mem_texture = vbmp->memory_copy;
01639             }
01640             else {
01641                 mem_texture = texture;
01642             }
01643             polygon3d_f(vid->memory_copy, type, mem_texture, vc, vtx);
01644 
01645             vid = vid->next;
01646         }
01647 
01648         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
01649     
01650         glViewport(v[0], v[1], v[2], v[3]);
01651         glMatrixMode(GL_PROJECTION);
01652         glLoadMatrixd(allegro_gl_projection_matrix);
01653         glMatrixMode(GL_MODELVIEW);
01654         glLoadMatrixd(allegro_gl_modelview_matrix);
01655     }
01656     else {
01657         int i;
01658         AGL_VIDEO_BITMAP *vid;
01659     
01660         vid = bmp->extra;
01661     
01662         if (is_sub_bitmap(bmp)) {
01663             for (i = 0; i < vc; ++i) {
01664                 vtx[i]->x += bmp->x_ofs;
01665                 vtx[i]->y += bmp->y_ofs;
01666             }
01667         }
01668 
01669         while (vid) {
01670             BITMAP *mem_texture;
01671             int _y1, _y2, _x1, _x2;
01672             BITMAP *vbmp = vid->memory_copy;
01673 
01674             _x1 = 9999;
01675             for (i = 0; i < vc; ++i)
01676                 if (vtx[i]->x < _x1) _x1 = vtx[i]->x;
01677 
01678             _x2 = -9999;
01679             for (i = 0; i < vc; ++i)
01680                 if (vtx[i]->x > _x2) _x2 = vtx[i]->x;
01681 
01682             _y1 = 9999;
01683             for (i = 0; i < vc; ++i)
01684                 if (vtx[i]->y < _y1) _y1 = vtx[i]->y;
01685 
01686             _y2 = -9999;
01687             for (i = 0; i < vc; ++i)
01688                 if (vtx[i]->y > _y2) _y2 = vtx[i]->y;
01689 
01690             if (vid->x_ofs > _x2 || vid->y_ofs > _y2
01691              || vid->x_ofs + vbmp->w <= _x1
01692              || vid->y_ofs + vbmp->h <= _y1) {
01693                 
01694                 vid = vid->next;
01695                 continue;
01696             }
01697             
01698             _x1 = MAX(0, _x1 - vid->x_ofs);
01699             _x2 = (_x2 - (vid->x_ofs + vbmp->w) > 0) ? vbmp->w - 1: _x2 - vid->x_ofs;
01700             _y1 = MAX(0, _y1 - vid->y_ofs);
01701             _y2 = (_x2 - (vid->y_ofs + vbmp->h) > 0) ? vbmp->h - 1: _y2 - vid->y_ofs;
01702 
01703             if (is_video_bitmap(texture)) {
01704                 AGL_VIDEO_BITMAP *tex = texture->extra;
01705                 mem_texture = tex->memory_copy;
01706             }
01707             else {
01708                 mem_texture = texture;
01709             }
01710             polygon3d_f(vid->memory_copy, type, mem_texture, vc, vtx);
01711     
01712             update_texture_memory(vid, _x1, _y1, _x2, _y2);
01713     
01714             vid = vid->next;
01715         }
01716     }
01717 
01718     return;
01719 }
01720 
01721 
01722 
01723 static void allegro_gl_video_polygon3d(BITMAP *bmp, int type, BITMAP *texture,
01724                                 int vc, V3D *vtx[])
01725 {
01726     int i;
01727     V3D_f **vtx_f = malloc(vc * sizeof(struct V3D_f*));
01728     if (!vtx_f)
01729         return;
01730 
01731     for (i = 0; i < vc; i++) {
01732         vtx_f[i] = malloc(sizeof(struct V3D_f));
01733         if (!vtx_f[i]) {
01734             int k;
01735             for (k = 0; k < i; k++)
01736                 free(vtx_f[k]);
01737             free(vtx_f);
01738             return;
01739         }
01740         vtx_f[i]->c = vtx[i]->c;
01741         vtx_f[i]->u = fixtof(vtx[i]->u);
01742         vtx_f[i]->v = fixtof(vtx[i]->v);
01743         vtx_f[i]->x = fixtof(vtx[i]->x);
01744         vtx_f[i]->y = fixtof(vtx[i]->y);
01745         vtx_f[i]->z = fixtof(vtx[i]->z);
01746     }
01747 
01748     allegro_gl_video_polygon3d_f(bmp, type, texture, vc, vtx_f);
01749 
01750     for (i = 0; i < vc; i++)
01751         free(vtx_f[i]);
01752     free(vtx_f);
01753 }
01754 
01755 
01756 
01757 static void allegro_gl_video_triangle3d(BITMAP *bmp, int type, BITMAP *texture,
01758                                         V3D *v1, V3D *v2, V3D *v3)
01759 {
01760     V3D *vtx[3] = {v1, v2, v3};
01761     allegro_gl_video_polygon3d(bmp, type, texture, 3, vtx);
01762 }
01763 
01764 
01765 
01766 static void allegro_gl_video_triangle3d_f(BITMAP *bmp, int type, BITMAP *texture,
01767                                           V3D_f *v1, V3D_f *v2, V3D_f *v3)
01768 {
01769     V3D_f *vtx_f[3] = {v1, v2, v3};
01770     allegro_gl_video_polygon3d_f(bmp, type, texture, 3, vtx_f);
01771 }
01772 
01773 
01774 
01775 static void allegro_gl_video_quad3d(BITMAP *bmp, int type, BITMAP *texture,
01776                                     V3D *v1, V3D *v2, V3D *v3, V3D *v4)
01777 {
01778     V3D *vtx[4] = {v1, v2, v3, v4};
01779     allegro_gl_video_polygon3d(bmp, type, texture, 4, vtx);
01780 }
01781 
01782 
01783 
01784 static void allegro_gl_video_quad3d_f(BITMAP *bmp, int type, BITMAP *texture,
01785                                V3D_f *v1, V3D_f *v2, V3D_f *v3, V3D_f *v4)
01786 {
01787     V3D_f *vtx_f[4] = {v1, v2, v3, v4};
01788     allegro_gl_video_polygon3d_f(bmp, type, texture, 4, vtx_f);
01789 }
01790 
01791 
01792 
01793 static void dummy_unwrite_bank(void)
01794 {
01795 }
01796 
01797 
01798 
01799 static GFX_VTABLE allegro_gl_video_vtable = {
01800     0,
01801     0,
01802     dummy_unwrite_bank,         //void *unwrite_bank;  /* C function on some machines, asm on i386 */
01803     NULL,                       //AL_METHOD(void, set_clip, (struct BITMAP *bmp));
01804     allegro_gl_video_acquire,
01805     allegro_gl_video_release,
01806     NULL,                       //AL_METHOD(struct BITMAP *, create_sub_bitmap, (struct BITMAP *parent, int x, int y, int width, int height));
01807     allegro_gl_created_sub_bitmap,
01808     allegro_gl_video_getpixel,
01809     allegro_gl_video_putpixel,
01810     allegro_gl_video_vline,
01811     allegro_gl_video_hline,
01812     allegro_gl_video_hline,
01813     allegro_gl_video_line,
01814     allegro_gl_video_line,
01815     allegro_gl_video_rectfill,
01816     allegro_gl_video_triangle,
01817     allegro_gl_video_draw_sprite,
01818     allegro_gl_video_draw_256_sprite,
01819     allegro_gl_video_draw_sprite_v_flip,
01820     allegro_gl_video_draw_sprite_h_flip,
01821     allegro_gl_video_draw_sprite_vh_flip,
01822     allegro_gl_video_draw_trans_rgba_sprite,
01823     allegro_gl_video_draw_trans_rgba_sprite,
01824     NULL,                       //AL_METHOD(void, draw_lit_sprite, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color));
01825     NULL,                       //AL_METHOD(void, allegro_gl_video_draw_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y));
01826     NULL,                       //AL_METHOD(void, draw_trans_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y));
01827     NULL,                       //AL_METHOD(void, draw_trans_rgba_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y));
01828     NULL,                       //AL_METHOD(void, draw_lit_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y, int color));
01829     allegro_gl_video_draw_character,
01830     allegro_gl_video_draw_glyph,
01831     allegro_gl_video_blit_from_memory,
01832     allegro_gl_video_blit_to_memory,
01833     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));
01834     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));
01835     allegro_gl_screen_blit_to_self, /* Video bitmaps use same method as screen */
01836     allegro_gl_screen_blit_to_self, /* ..._forward */
01837     allegro_gl_screen_blit_to_self, /* ..._backward */
01838     allegro_gl_memory_blit_between_formats,
01839     allegro_gl_video_masked_blit,
01840     allegro_gl_video_clear_to_color,
01841     allegro_gl_video_pivot_scaled_sprite_flip,
01842     allegro_gl_video_do_stretch_blit,
01843     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));
01844     NULL,                       //AL_METHOD(void, draw_sprite_end, (void));
01845     NULL,                       //AL_METHOD(void, blit_end, (void));
01846     _soft_polygon,              //AL_METHOD(void, polygon, (struct BITMAP *bmp, int vertices, AL_CONST int *points, int color));
01847     _soft_rect,                 //AL_METHOD(void, rect, (struct BITMAP *bmp, int x1, int y1, int x2, int y2, int color));
01848     _soft_circle,               //AL_METHOD(void, circle, (struct BITMAP *bmp, int x, int y, int radius, int color));
01849     _soft_circlefill,           //AL_METHOD(void, circlefill, (struct BITMAP *bmp, int x, int y, int radius, int color));
01850     _soft_ellipse,              //AL_METHOD(void, ellipse, (struct BITMAP *bmp, int x, int y, int rx, int ry, int color));
01851     _soft_ellipsefill,          //AL_METHOD(void, ellipsefill, (struct BITMAP *bmp, int x, int y, int rx, int ry, int color));
01852     _soft_arc,                  //AL_METHOD(void, arc, (struct BITMAP *bmp, int x, int y, fixed ang1, fixed ang2, int r, int color));
01853     _soft_spline,               //AL_METHOD(void, spline, (struct BITMAP *bmp, AL_CONST int points[8], int color));
01854     _soft_floodfill,            //AL_METHOD(void, floodfill, (struct BITMAP *bmp, int x, int y, int color));
01855     allegro_gl_video_polygon3d,
01856     allegro_gl_video_polygon3d_f,
01857     allegro_gl_video_triangle3d,
01858     allegro_gl_video_triangle3d_f,
01859     allegro_gl_video_quad3d,
01860     allegro_gl_video_quad3d_f,
01861 };
01862 

Generated on Sun Nov 11 15:52:55 2007 for AllegroGL by  doxygen 1.5.2