00001
00002
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
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
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
00080
00081 (*pvid)->width = w;
00082 (*pvid)->height = h;
00083 (*pvid)->x_ofs = x;
00084 (*pvid)->y_ofs = y;
00085
00086
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
00098 glTexParameteri((*pvid)->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00099 glTexParameteri((*pvid)->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00100
00101
00102
00103
00104
00105
00106 #if 0
00107
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
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
00182
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
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
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
00232 if (!w2 && !h2) {
00233 return -1;
00234 }
00235
00236
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
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
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
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
00279
00280
00281
00282
00283 static BITMAP *allegro_gl_make_video_bitmap(BITMAP *bmp) {
00284
00285
00286 void *ptr = &bmp->extra;
00287 AGL_VIDEO_BITMAP **pvid = (AGL_VIDEO_BITMAP**)ptr;
00288
00289
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
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
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
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
00374
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
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
00437 static void allegro_gl_video_acquire(struct BITMAP *bmp) {}
00438
00439
00440
00441
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
00530
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
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
00855
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
00997
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,
01076 \
01077 screen_blit_from_mem,
01078 \
01079 mem_copy_blit_from_vid,
01080 \
01081 mem_copy_blit_from_mem,
01082 \
01083 vid_and_mem_copy_blit_from_vid,
01084
01085 \
01086 vid_and_mem_copy_blit_from_mem)
01087
01088 \
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
01205
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
01237
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
01250
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
01263
01264
01265
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
01278
01279
01280
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
01293
01294
01295
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
01308
01309
01310
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
01340
01341
01342
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
01349
01350 double scalew = ((double)dest_width) / source_width;
01351 double scaleh = ((double)dest_height) / source_height;
01352
01353 GLint matrix_mode;
01354
01355
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
01412
01413
01414 static void allegro_gl_video_draw_trans_rgba_sprite(BITMAP *bmp,
01415 BITMAP *sprite, int x, int y) {
01416
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
01496
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
01554
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
01603
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,
01803 NULL,
01804 allegro_gl_video_acquire,
01805 allegro_gl_video_release,
01806 NULL,
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,
01825 NULL,
01826 NULL,
01827 NULL,
01828 NULL,
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,
01834 NULL,
01835 allegro_gl_screen_blit_to_self,
01836 allegro_gl_screen_blit_to_self,
01837 allegro_gl_screen_blit_to_self,
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,
01844 NULL,
01845 NULL,
01846 _soft_polygon,
01847 _soft_rect,
01848 _soft_circle,
01849 _soft_circlefill,
01850 _soft_ellipse,
01851 _soft_ellipsefill,
01852 _soft_arc,
01853 _soft_spline,
01854 _soft_floodfill,
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