AllegroGL 0.4.4
|
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 /* allegro_gl_video_draw_sprite_ex: 01453 * draw_sprite_ex() overload for video -> video and memory -> video drawing 01454 * 01455 * When mode is DRAW_SPRITE_TRANS: 01456 * FIXME: Broken if the bitmap was split into multiple textures. 01457 * FIXME: Doesn't apply flipping to the memory copy 01458 */ 01459 static void allegro_gl_video_draw_sprite_ex(BITMAP *bmp, BITMAP *sprite, 01460 int x, int y, int mode, int flip) { 01461 int matrix_mode; 01462 int lflip = 0; 01463 01464 /* convert allegro's flipping flags to AGL's flags */ 01465 switch (flip) { 01466 case DRAW_SPRITE_NO_FLIP: 01467 lflip = FALSE; 01468 break; 01469 case DRAW_SPRITE_V_FLIP: 01470 lflip = AGL_V_FLIP; 01471 break; 01472 case DRAW_SPRITE_H_FLIP: 01473 lflip = AGL_H_FLIP; 01474 break; 01475 case DRAW_SPRITE_VH_FLIP: 01476 lflip = AGL_V_FLIP | AGL_H_FLIP; 01477 break; 01478 } 01479 01480 switch (mode) { 01481 case DRAW_SPRITE_NORMAL: 01482 do_masked_blit_video(sprite, bmp, 0, 0, x, y, 01483 sprite->w, sprite->h, lflip, FALSE); 01484 break; 01485 case DRAW_SPRITE_TRANS: 01486 if (lflip) { 01487 glGetIntegerv(GL_MATRIX_MODE, &matrix_mode); 01488 glMatrixMode(GL_MODELVIEW); 01489 glPushMatrix(); 01490 01491 glTranslatef(x, y, 0.f); 01492 glScalef((lflip&AGL_H_FLIP) ? -1 : 1, (lflip&AGL_V_FLIP)? -1 : 1, 1); 01493 glTranslatef(-x, -y, 0); 01494 glTranslatef((lflip&AGL_H_FLIP) ? -sprite->w : 0, 01495 (lflip&AGL_V_FLIP) ? -sprite->h : 0, 0); 01496 } 01497 01498 allegro_gl_video_draw_trans_rgba_sprite(bmp, sprite, x, y); 01499 01500 if (lflip) { 01501 glPopMatrix(); 01502 glMatrixMode(matrix_mode); 01503 } 01504 break; 01505 case DRAW_SPRITE_LIT: 01506 /* not implemented */ 01507 break; 01508 } 01509 } 01510 01511 01512 01513 static void allegro_gl_video_clear_to_color(BITMAP *bmp, int color) { 01514 AGL_VIDEO_BITMAP *vid = bmp->extra; 01515 01516 if (vid->fbo) { 01517 static GLint v[4]; 01518 static double allegro_gl_projection_matrix[16]; 01519 static double allegro_gl_modelview_matrix[16]; 01520 01521 glGetIntegerv(GL_VIEWPORT, &v[0]); 01522 glMatrixMode(GL_MODELVIEW); 01523 glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix); 01524 glMatrixMode(GL_PROJECTION); 01525 glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix); 01526 01527 while (vid) { 01528 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo); 01529 01530 glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h); 01531 glMatrixMode(GL_PROJECTION); 01532 glLoadIdentity(); 01533 gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h); 01534 glMatrixMode(GL_MODELVIEW); 01535 01536 allegro_gl_screen_clear_to_color(bmp, color); 01537 clear_to_color(vid->memory_copy, color); 01538 vid = vid->next; 01539 } 01540 01541 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 01542 01543 glViewport(v[0], v[1], v[2], v[3]); 01544 glMatrixMode(GL_PROJECTION); 01545 glLoadMatrixd(allegro_gl_projection_matrix); 01546 glMatrixMode(GL_MODELVIEW); 01547 glLoadMatrixd(allegro_gl_modelview_matrix); 01548 } 01549 else { 01550 allegro_gl_video_rectfill(bmp, 0, 0, bmp->w, bmp->h, color); 01551 } 01552 } 01553 01554 01555 01556 /* FIXME: Doesn't work when FBO is not available. 01557 * FIXME: Doesn't care for segmented video bitmaps. 01558 */ 01559 static void allegro_gl_video_draw_color_glyph(struct BITMAP *bmp, 01560 struct BITMAP *sprite, int x, int y, int color, int bg) 01561 { 01562 AGL_VIDEO_BITMAP *vid = bmp->extra; 01563 01564 static GLint v[4]; 01565 static double allegro_gl_projection_matrix[16]; 01566 static double allegro_gl_modelview_matrix[16]; 01567 01568 if (!vid->fbo) 01569 return; 01570 01571 glGetIntegerv(GL_VIEWPORT, &v[0]); 01572 glMatrixMode(GL_MODELVIEW); 01573 glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix); 01574 glMatrixMode(GL_PROJECTION); 01575 glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix); 01576 01577 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo); 01578 01579 glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h); 01580 glMatrixMode(GL_PROJECTION); 01581 glLoadIdentity(); 01582 gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h); 01583 glMatrixMode(GL_MODELVIEW); 01584 01585 allegro_gl_screen_draw_color_glyph_ex(bmp, sprite, x, y, color, bg, 0); 01586 01587 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 01588 01589 glViewport(v[0], v[1], v[2], v[3]); 01590 glMatrixMode(GL_PROJECTION); 01591 glLoadMatrixd(allegro_gl_projection_matrix); 01592 glMatrixMode(GL_MODELVIEW); 01593 glLoadMatrixd(allegro_gl_modelview_matrix); 01594 01595 vid->memory_copy->vtable->draw_character(vid->memory_copy, sprite, x, y, color, bg); 01596 } 01597 01598 01599 01600 static void allegro_gl_video_draw_256_sprite(BITMAP *bmp, BITMAP *sprite, 01601 int x, int y) { 01602 allegro_gl_video_draw_color_glyph(bmp, sprite, x, y, -1, _textmode); 01603 } 01604 01605 01606 01607 static void allegro_gl_video_draw_character(BITMAP *bmp, BITMAP *sprite, 01608 int x, int y, int color, int bg) { 01609 allegro_gl_video_draw_color_glyph(bmp, sprite, x, y, color, bg); 01610 } 01611 01612 01613 01614 /* FIXME: Doesn't work when FBO is not available. 01615 * FIXME: Doesn't care for segmented video bitmaps. 01616 */ 01617 static void allegro_gl_video_draw_glyph(struct BITMAP *bmp, 01618 AL_CONST struct FONT_GLYPH *glyph, int x, int y, 01619 int color, int bg) { 01620 AGL_VIDEO_BITMAP *vid = bmp->extra; 01621 01622 static GLint v[4]; 01623 static double allegro_gl_projection_matrix[16]; 01624 static double allegro_gl_modelview_matrix[16]; 01625 01626 if (!vid->fbo) 01627 return; 01628 01629 glGetIntegerv(GL_VIEWPORT, &v[0]); 01630 glMatrixMode(GL_MODELVIEW); 01631 glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix); 01632 glMatrixMode(GL_PROJECTION); 01633 glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix); 01634 01635 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo); 01636 01637 glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h); 01638 glMatrixMode(GL_PROJECTION); 01639 glLoadIdentity(); 01640 gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h); 01641 glMatrixMode(GL_MODELVIEW); 01642 01643 allegro_gl_screen_draw_glyph_ex(bmp, glyph, x, y, color, bg, 1); 01644 01645 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 01646 01647 glViewport(v[0], v[1], v[2], v[3]); 01648 glMatrixMode(GL_PROJECTION); 01649 glLoadMatrixd(allegro_gl_projection_matrix); 01650 glMatrixMode(GL_MODELVIEW); 01651 glLoadMatrixd(allegro_gl_modelview_matrix); 01652 01653 vid->memory_copy->vtable->draw_glyph(vid->memory_copy, glyph, x, y, color, bg); 01654 } 01655 01656 01657 01658 static void allegro_gl_video_polygon3d_f(BITMAP *bmp, int type, BITMAP *texture, 01659 int vc, V3D_f *vtx[]) 01660 { 01661 AGL_VIDEO_BITMAP *vid = bmp->extra; 01662 01663 /* Switch to software mode is using polygon type that isn't supported by 01664 allegro_gl_screen_polygon3d_f. */ 01665 int use_fbo = (type == POLYTYPE_FLAT) || 01666 (type == POLYTYPE_GRGB) || 01667 (type == POLYTYPE_GCOL) || 01668 (type == POLYTYPE_ATEX) || 01669 (type == POLYTYPE_PTEX) || 01670 (type == POLYTYPE_ATEX_TRANS) || 01671 (type == POLYTYPE_PTEX_TRANS); 01672 01673 if (vid->fbo && use_fbo) { 01674 static GLint v[4]; 01675 static double allegro_gl_projection_matrix[16]; 01676 static double allegro_gl_modelview_matrix[16]; 01677 01678 glGetIntegerv(GL_VIEWPORT, &v[0]); 01679 glMatrixMode(GL_MODELVIEW); 01680 glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix); 01681 glMatrixMode(GL_PROJECTION); 01682 glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix); 01683 01684 while (vid) { 01685 BITMAP *mem_texture; 01686 01687 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo); 01688 01689 glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h); 01690 glMatrixMode(GL_PROJECTION); 01691 glLoadIdentity(); 01692 gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h); 01693 glMatrixMode(GL_MODELVIEW); 01694 01695 allegro_gl_screen_polygon3d_f(bmp, type, texture, vc, vtx); 01696 01697 if (is_video_bitmap(texture)) { 01698 AGL_VIDEO_BITMAP *vbmp = texture->extra; 01699 mem_texture = vbmp->memory_copy; 01700 } 01701 else { 01702 mem_texture = texture; 01703 } 01704 polygon3d_f(vid->memory_copy, type, mem_texture, vc, vtx); 01705 01706 vid = vid->next; 01707 } 01708 01709 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 01710 01711 glViewport(v[0], v[1], v[2], v[3]); 01712 glMatrixMode(GL_PROJECTION); 01713 glLoadMatrixd(allegro_gl_projection_matrix); 01714 glMatrixMode(GL_MODELVIEW); 01715 glLoadMatrixd(allegro_gl_modelview_matrix); 01716 } 01717 else { 01718 int i; 01719 AGL_VIDEO_BITMAP *vid; 01720 01721 vid = bmp->extra; 01722 01723 if (is_sub_bitmap(bmp)) { 01724 for (i = 0; i < vc; ++i) { 01725 vtx[i]->x += bmp->x_ofs; 01726 vtx[i]->y += bmp->y_ofs; 01727 } 01728 } 01729 01730 while (vid) { 01731 BITMAP *mem_texture; 01732 int _y1, _y2, _x1, _x2; 01733 BITMAP *vbmp = vid->memory_copy; 01734 01735 _x1 = 9999; 01736 for (i = 0; i < vc; ++i) 01737 if (vtx[i]->x < _x1) _x1 = vtx[i]->x; 01738 01739 _x2 = -9999; 01740 for (i = 0; i < vc; ++i) 01741 if (vtx[i]->x > _x2) _x2 = vtx[i]->x; 01742 01743 _y1 = 9999; 01744 for (i = 0; i < vc; ++i) 01745 if (vtx[i]->y < _y1) _y1 = vtx[i]->y; 01746 01747 _y2 = -9999; 01748 for (i = 0; i < vc; ++i) 01749 if (vtx[i]->y > _y2) _y2 = vtx[i]->y; 01750 01751 if (vid->x_ofs > _x2 || vid->y_ofs > _y2 01752 || vid->x_ofs + vbmp->w <= _x1 01753 || vid->y_ofs + vbmp->h <= _y1) { 01754 01755 vid = vid->next; 01756 continue; 01757 } 01758 01759 _x1 = MAX(0, _x1 - vid->x_ofs); 01760 _x2 = (_x2 - (vid->x_ofs + vbmp->w) > 0) ? vbmp->w - 1: _x2 - vid->x_ofs; 01761 _y1 = MAX(0, _y1 - vid->y_ofs); 01762 _y2 = (_x2 - (vid->y_ofs + vbmp->h) > 0) ? vbmp->h - 1: _y2 - vid->y_ofs; 01763 01764 if (is_video_bitmap(texture)) { 01765 AGL_VIDEO_BITMAP *tex = texture->extra; 01766 mem_texture = tex->memory_copy; 01767 } 01768 else { 01769 mem_texture = texture; 01770 } 01771 polygon3d_f(vid->memory_copy, type, mem_texture, vc, vtx); 01772 01773 update_texture_memory(vid, _x1, _y1, _x2, _y2); 01774 01775 vid = vid->next; 01776 } 01777 } 01778 01779 return; 01780 } 01781 01782 01783 01784 static void allegro_gl_video_polygon3d(BITMAP *bmp, int type, BITMAP *texture, 01785 int vc, V3D *vtx[]) 01786 { 01787 int i; 01788 V3D_f **vtx_f = malloc(vc * sizeof(struct V3D_f*)); 01789 if (!vtx_f) 01790 return; 01791 01792 for (i = 0; i < vc; i++) { 01793 vtx_f[i] = malloc(sizeof(struct V3D_f)); 01794 if (!vtx_f[i]) { 01795 int k; 01796 for (k = 0; k < i; k++) 01797 free(vtx_f[k]); 01798 free(vtx_f); 01799 return; 01800 } 01801 vtx_f[i]->c = vtx[i]->c; 01802 vtx_f[i]->u = fixtof(vtx[i]->u); 01803 vtx_f[i]->v = fixtof(vtx[i]->v); 01804 vtx_f[i]->x = fixtof(vtx[i]->x); 01805 vtx_f[i]->y = fixtof(vtx[i]->y); 01806 vtx_f[i]->z = fixtof(vtx[i]->z); 01807 } 01808 01809 allegro_gl_video_polygon3d_f(bmp, type, texture, vc, vtx_f); 01810 01811 for (i = 0; i < vc; i++) 01812 free(vtx_f[i]); 01813 free(vtx_f); 01814 } 01815 01816 01817 01818 static void allegro_gl_video_triangle3d(BITMAP *bmp, int type, BITMAP *texture, 01819 V3D *v1, V3D *v2, V3D *v3) 01820 { 01821 V3D *vtx[3]; 01822 vtx[0] = v1; 01823 vtx[1] = v2; 01824 vtx[2] = v3; 01825 01826 allegro_gl_video_polygon3d(bmp, type, texture, 3, vtx); 01827 } 01828 01829 01830 01831 static void allegro_gl_video_triangle3d_f(BITMAP *bmp, int type, BITMAP *texture, 01832 V3D_f *v1, V3D_f *v2, V3D_f *v3) 01833 { 01834 V3D_f *vtx_f[3]; 01835 vtx_f[0] = v1; 01836 vtx_f[1] = v2; 01837 vtx_f[2] = v3; 01838 01839 allegro_gl_video_polygon3d_f(bmp, type, texture, 3, vtx_f); 01840 } 01841 01842 01843 01844 static void allegro_gl_video_quad3d(BITMAP *bmp, int type, BITMAP *texture, 01845 V3D *v1, V3D *v2, V3D *v3, V3D *v4) 01846 { 01847 V3D *vtx[4]; 01848 vtx[0] = v1; 01849 vtx[1] = v2; 01850 vtx[2] = v3; 01851 vtx[3] = v4; 01852 01853 allegro_gl_video_polygon3d(bmp, type, texture, 4, vtx); 01854 } 01855 01856 01857 01858 static void allegro_gl_video_quad3d_f(BITMAP *bmp, int type, BITMAP *texture, 01859 V3D_f *v1, V3D_f *v2, V3D_f *v3, V3D_f *v4) 01860 { 01861 V3D_f *vtx_f[4]; 01862 vtx_f[0] = v1; 01863 vtx_f[1] = v2; 01864 vtx_f[2] = v3; 01865 vtx_f[3] = v4; 01866 01867 allegro_gl_video_polygon3d_f(bmp, type, texture, 4, vtx_f); 01868 } 01869 01870 01871 01872 static void dummy_unwrite_bank(void) 01873 { 01874 } 01875 01876 01877 01878 static GFX_VTABLE allegro_gl_video_vtable = { 01879 0, 01880 0, 01881 dummy_unwrite_bank, //void *unwrite_bank; /* C function on some machines, asm on i386 */ 01882 NULL, //AL_METHOD(void, set_clip, (struct BITMAP *bmp)); 01883 allegro_gl_video_acquire, 01884 allegro_gl_video_release, 01885 NULL, //AL_METHOD(struct BITMAP *, create_sub_bitmap, (struct BITMAP *parent, int x, int y, int width, int height)); 01886 allegro_gl_created_sub_bitmap, 01887 allegro_gl_video_getpixel, 01888 allegro_gl_video_putpixel, 01889 allegro_gl_video_vline, 01890 allegro_gl_video_hline, 01891 allegro_gl_video_hline, 01892 allegro_gl_video_line, 01893 allegro_gl_video_line, 01894 allegro_gl_video_rectfill, 01895 allegro_gl_video_triangle, 01896 allegro_gl_video_draw_sprite, 01897 allegro_gl_video_draw_256_sprite, 01898 allegro_gl_video_draw_sprite_v_flip, 01899 allegro_gl_video_draw_sprite_h_flip, 01900 allegro_gl_video_draw_sprite_vh_flip, 01901 allegro_gl_video_draw_trans_rgba_sprite, 01902 allegro_gl_video_draw_trans_rgba_sprite, 01903 NULL, //AL_METHOD(void, draw_lit_sprite, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color)); 01904 NULL, //AL_METHOD(void, allegro_gl_video_draw_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y)); 01905 NULL, //AL_METHOD(void, draw_trans_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y)); 01906 NULL, //AL_METHOD(void, draw_trans_rgba_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y)); 01907 NULL, //AL_METHOD(void, draw_lit_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y, int color)); 01908 allegro_gl_video_draw_character, 01909 allegro_gl_video_draw_glyph, 01910 allegro_gl_video_blit_from_memory, 01911 allegro_gl_video_blit_to_memory, 01912 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)); 01913 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)); 01914 allegro_gl_screen_blit_to_self, /* Video bitmaps use same method as screen */ 01915 allegro_gl_screen_blit_to_self, /* ..._forward */ 01916 allegro_gl_screen_blit_to_self, /* ..._backward */ 01917 allegro_gl_memory_blit_between_formats, 01918 allegro_gl_video_masked_blit, 01919 allegro_gl_video_clear_to_color, 01920 allegro_gl_video_pivot_scaled_sprite_flip, 01921 allegro_gl_video_do_stretch_blit, 01922 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)); 01923 NULL, //AL_METHOD(void, draw_sprite_end, (void)); 01924 NULL, //AL_METHOD(void, blit_end, (void)); 01925 _soft_polygon, //AL_METHOD(void, polygon, (struct BITMAP *bmp, int vertices, AL_CONST int *points, int color)); 01926 _soft_rect, //AL_METHOD(void, rect, (struct BITMAP *bmp, int x1, int y1, int x2, int y2, int color)); 01927 _soft_circle, //AL_METHOD(void, circle, (struct BITMAP *bmp, int x, int y, int radius, int color)); 01928 _soft_circlefill, //AL_METHOD(void, circlefill, (struct BITMAP *bmp, int x, int y, int radius, int color)); 01929 _soft_ellipse, //AL_METHOD(void, ellipse, (struct BITMAP *bmp, int x, int y, int rx, int ry, int color)); 01930 _soft_ellipsefill, //AL_METHOD(void, ellipsefill, (struct BITMAP *bmp, int x, int y, int rx, int ry, int color)); 01931 _soft_arc, //AL_METHOD(void, arc, (struct BITMAP *bmp, int x, int y, fixed ang1, fixed ang2, int r, int color)); 01932 _soft_spline, //AL_METHOD(void, spline, (struct BITMAP *bmp, AL_CONST int points[8], int color)); 01933 _soft_floodfill, //AL_METHOD(void, floodfill, (struct BITMAP *bmp, int x, int y, int color)); 01934 allegro_gl_video_polygon3d, 01935 allegro_gl_video_polygon3d_f, 01936 allegro_gl_video_triangle3d, 01937 allegro_gl_video_triangle3d_f, 01938 allegro_gl_video_quad3d, 01939 allegro_gl_video_quad3d_f, 01940 allegro_gl_video_draw_sprite_ex 01941 }; 01942