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
00042 void allegro_gl_destroy_video_bitmap(BITMAP *bmp);
00043
00044
00045
00046 static int allegro_gl_make_video_bitmap_helper1(int w, int h, int x, int y,
00047 GLint target, AGL_VIDEO_BITMAP **pvid) {
00048
00049 int internal_format;
00050 int bpp;
00051
00052 if (__allegro_gl_video_bitmap_bpp == -1) {
00053 bpp = bitmap_color_depth(screen);
00054 }
00055 else {
00056 bpp = __allegro_gl_video_bitmap_bpp;
00057 }
00058
00059 (*pvid) = malloc(sizeof(AGL_VIDEO_BITMAP));
00060
00061 if (!(*pvid))
00062 return -1;
00063
00064 memset(*pvid, 0, sizeof(AGL_VIDEO_BITMAP));
00065
00066
00067 (*pvid)->memory_copy = create_bitmap_ex(bpp, w, h);
00068 if (!(*pvid)->memory_copy)
00069 return -1;
00070
00071 (*pvid)->format = __allegro_gl_get_bitmap_color_format((*pvid)->memory_copy, AGL_TEXTURE_HAS_ALPHA);
00072 (*pvid)->type = __allegro_gl_get_bitmap_type((*pvid)->memory_copy, 0);
00073 internal_format = __allegro_gl_get_texture_format_ex((*pvid)->memory_copy, AGL_TEXTURE_HAS_ALPHA);
00074
00075 (*pvid)->target = target;
00076
00077
00078
00079 (*pvid)->width = w;
00080 (*pvid)->height = h;
00081 (*pvid)->x_ofs = x;
00082 (*pvid)->y_ofs = y;
00083
00084
00085 glGenTextures(1, &((*pvid)->tex));
00086 if (!((*pvid)->tex))
00087 return -1;
00088
00089 glEnable((*pvid)->target);
00090 glBindTexture((*pvid)->target, ((*pvid)->tex));
00091
00092 glTexImage2D((*pvid)->target, 0, internal_format, w, h,
00093 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
00094
00095
00096 glTexParameteri((*pvid)->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00097 glTexParameteri((*pvid)->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00098
00099
00100 { GLenum clamp = GL_CLAMP_TO_EDGE;
00101 if (!allegro_gl_extensions_GL.SGIS_texture_edge_clamp) {
00102 clamp = GL_CLAMP;
00103 }
00104 glTexParameteri((*pvid)->target, GL_TEXTURE_WRAP_S, clamp);
00105 glTexParameteri((*pvid)->target, GL_TEXTURE_WRAP_T, clamp);
00106 }
00107
00108 glDisable((*pvid)->target);
00109
00110 if (allegro_gl_extensions_GL.EXT_framebuffer_object) {
00111 glGenFramebuffersEXT(1, &((*pvid)->fbo));
00112 if (!(*pvid)->fbo) {
00113 glDeleteTextures(1, &((*pvid)->tex));
00114 return -1;
00115 }
00116
00117 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (*pvid)->fbo);
00118 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, (*pvid)->target, (*pvid)->tex, 0);
00119 if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {
00120 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00121 glDeleteFramebuffersEXT(1, &((*pvid)->fbo));
00122 glDeleteTextures(1, &((*pvid)->tex));
00123 return -1;
00124 }
00125
00126 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00127 }
00128 else {
00129 (*pvid)->fbo = 0;
00130 }
00131
00132 return 0;
00133 }
00134
00135
00136
00137 static int allegro_gl_make_video_bitmap_helper0(int w, int h, int x, int y,
00138 AGL_VIDEO_BITMAP **pvid) {
00139
00140 int is_power_of_2 = (!(w & (w - 1)) && !(h & (h - 1)));
00141 int texture_rect_available = allegro_gl_extensions_GL.ARB_texture_rectangle
00142 #ifdef ALLEGRO_MACOSX
00143 || allegro_gl_extensions_GL.EXT_texture_rectangle
00144 #endif
00145 || allegro_gl_extensions_GL.NV_texture_rectangle;
00146 GLint max_rect_texture_size = 0;
00147
00148 if (texture_rect_available) {
00149 glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &max_rect_texture_size);
00150 }
00151
00152 if (w <= allegro_gl_info.max_texture_size &&
00153 h <= allegro_gl_info.max_texture_size) {
00154 if (allegro_gl_extensions_GL.ARB_texture_non_power_of_two ||
00155 is_power_of_2) {
00156 if (allegro_gl_make_video_bitmap_helper1(w, h, x, y,
00157 GL_TEXTURE_2D, pvid)) {
00158 return -1;
00159 }
00160 }
00161 else if (texture_rect_available &&
00162 w <= max_rect_texture_size &&
00163 h <= max_rect_texture_size) {
00164 if (allegro_gl_make_video_bitmap_helper1(w, h, x, y,
00165 GL_TEXTURE_RECTANGLE_ARB, pvid)) {
00166 return -1;
00167 }
00168 }
00169 else {
00170
00171
00172 const unsigned int BITS = sizeof(int) * CHAR_BIT;
00173 unsigned int i, j;
00174 unsigned int w1, h1;
00175 unsigned int x1, y1;
00176 unsigned int p1, p2;
00177
00178
00179 y1 = 0;
00180 for (i = 0; i < BITS; i++) {
00181 p1 = 1 << i;
00182 if (h & p1)
00183 h1 = p1;
00184 else
00185 continue;
00186
00187 x1 = 0;
00188 for (j = 0; j < BITS; j++) {
00189 p2 = 1 << j;
00190 if (w & p2)
00191 w1 = p2;
00192 else
00193 continue;
00194
00195 if (allegro_gl_make_video_bitmap_helper0(w1, h1, x + x1,
00196 y + y1, pvid)) {
00197 return -1;
00198 }
00199 do {
00200 pvid = &((*pvid)->next);
00201 } while (*pvid);
00202
00203 x1 += w1;
00204 }
00205
00206 y1 += h1;
00207 }
00208 }
00209 }
00210 else {
00211
00212 int w1, w2, h1, h2;
00213
00214 w2 = w / 2;
00215 w1 = w - w2;
00216
00217 h2 = h / 2;
00218 h1 = h - h2;
00219
00220
00221 if (!w2 && !h2) {
00222 return -1;
00223 }
00224
00225
00226 if (allegro_gl_make_video_bitmap_helper0(w1, h1, x, y, pvid)) {
00227 return -1;
00228 }
00229 do {
00230 pvid = &((*pvid)->next);
00231 } while (*pvid);
00232
00233
00234 if (w2) {
00235 if (allegro_gl_make_video_bitmap_helper0(w2, h1, x + w1, y, pvid)) {
00236 return -1;
00237 }
00238 do {
00239 pvid = &((*pvid)->next);
00240 } while (*pvid);
00241 }
00242
00243 if (h2) {
00244 if (allegro_gl_make_video_bitmap_helper0(w1, h2, x, y + h1, pvid)) {
00245 return -1;
00246 }
00247 do {
00248 pvid = &((*pvid)->next);
00249 } while (*pvid);
00250 }
00251
00252 if (w2 && h2) {
00253 if (allegro_gl_make_video_bitmap_helper0(w2, h2, x + w1, y + h1, pvid)) {
00254 return -1;
00255 }
00256 do {
00257 pvid = &((*pvid)->next);
00258 } while (*pvid);
00259 }
00260 }
00261
00262 return 0;
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272 static BITMAP *allegro_gl_make_video_bitmap(BITMAP *bmp) {
00273
00274
00275 void *ptr = &bmp->extra;
00276 AGL_VIDEO_BITMAP **pvid = (AGL_VIDEO_BITMAP**)ptr;
00277
00278
00279 if (allegro_gl_make_video_bitmap_helper0(bmp->w, bmp->h, 0, 0, pvid)) {
00280 goto agl_error;
00281 }
00282
00283 return bmp;
00284
00285 agl_error:
00286 allegro_gl_destroy_video_bitmap(bmp);
00287 return NULL;
00288 }
00289
00290
00291
00292
00297 void allegro_gl_destroy_video_bitmap(BITMAP *bmp) {
00298
00299 AGL_VIDEO_BITMAP *vid = bmp ? bmp->extra : NULL, *next;
00300
00301 if (!bmp)
00302 return;
00303
00304 while (vid) {
00305 if (vid->memory_copy)
00306 destroy_bitmap(vid->memory_copy);
00307
00308 if (vid->tex)
00309 glDeleteTextures(1, &vid->tex);
00310
00311 if (vid->fbo)
00312 glDeleteFramebuffersEXT(1, &vid->fbo);
00313
00314 next = vid->next;
00315 free(vid);
00316 vid = next;
00317 }
00318
00319 free(bmp->vtable);
00320 free(bmp);
00321
00322 return;
00323 }
00324
00325
00326
00327
00333 BITMAP *allegro_gl_create_video_bitmap(int w, int h) {
00334 GFX_VTABLE *vtable;
00335 BITMAP *bitmap;
00336
00337 bitmap = malloc(sizeof(BITMAP) + sizeof(char *));
00338
00339 if (!bitmap)
00340 return NULL;
00341
00342 bitmap->dat = NULL;
00343 bitmap->w = bitmap->cr = w;
00344 bitmap->h = bitmap->cb = h;
00345 bitmap->clip = TRUE;
00346 bitmap->cl = bitmap->ct = 0;
00347 bitmap->write_bank = bitmap->read_bank = NULL;
00348
00349 bitmap->id = BMP_ID_VIDEO | video_bitmap_count;
00350 bitmap->extra = NULL;
00351 bitmap->x_ofs = 0;
00352 bitmap->y_ofs = 0;
00353 bitmap->seg = _default_ds();
00354 bitmap->line[0] = NULL;
00355
00356 if (!allegro_gl_make_video_bitmap(bitmap)) {
00357 return NULL;
00358 }
00359 video_bitmap_count++;
00360
00361
00362
00363
00364 vtable = malloc(sizeof(struct GFX_VTABLE));
00365 *vtable = allegro_gl_video_vtable;
00366 if (__allegro_gl_video_bitmap_bpp == -1) {
00367 vtable->color_depth = bitmap_color_depth(screen);
00368 }
00369 else {
00370 vtable->color_depth = __allegro_gl_video_bitmap_bpp;
00371 }
00372 switch (vtable->color_depth) {
00373 case 8:
00374 vtable->mask_color = MASK_COLOR_8;
00375 break;
00376 case 15:
00377 vtable->mask_color = MASK_COLOR_15;
00378 break;
00379 case 16:
00380 vtable->mask_color = MASK_COLOR_16;
00381 break;
00382 case 24:
00383 vtable->mask_color = MASK_COLOR_24;
00384 break;
00385 case 32:
00386 vtable->mask_color = MASK_COLOR_32;
00387 break;
00388 }
00389 bitmap->vtable = vtable;
00390
00391 return bitmap;
00392 }
00393
00394
00395
00396
00411 GLint allegro_gl_set_video_bitmap_color_depth(int bpp) {
00412 GLint old_val = __allegro_gl_video_bitmap_bpp;
00413 __allegro_gl_video_bitmap_bpp = bpp;
00414 return old_val;
00415 }
00416
00417
00418
00425 static void allegro_gl_video_acquire(struct BITMAP *bmp) {}
00426
00427
00428
00429
00436 static void allegro_gl_video_release(struct BITMAP *bmp) {}
00437
00438
00439
00440 static int allegro_gl_video_getpixel(struct BITMAP *bmp, int x, int y)
00441 {
00442 int pix = -1;
00443 AGL_VIDEO_BITMAP *vid;
00444 AGL_LOG(2, "glvtable.c:allegro_gl_screen_getpixel\n");
00445
00446 if (is_sub_bitmap(bmp)) {
00447 x += bmp->x_ofs;
00448 y += bmp->y_ofs;
00449 }
00450 if (x < bmp->cl || x >= bmp->cr || y < bmp->ct || y >= bmp->cb) {
00451 return -1;
00452 }
00453
00454 vid = bmp->extra;
00455
00456 while (vid) {
00457 if (vid->x_ofs <= x && vid->y_ofs <= y
00458 && vid->x_ofs + vid->memory_copy->w > x
00459 && vid->y_ofs + vid->memory_copy->h > y) {
00460
00461 pix = getpixel(vid->memory_copy, x - vid->x_ofs, y - vid->y_ofs);
00462 break;
00463 }
00464 vid = vid->next;
00465 }
00466
00467 if (pix != -1) {
00468 return pix;
00469 }
00470
00471 return -1;
00472 }
00473
00474
00475
00476 static void update_texture_memory(AGL_VIDEO_BITMAP *vid, int x1, int y1,
00477 int x2, int y2) {
00478 GLint saved_row_length;
00479 GLint saved_alignment;
00480 GLint type;
00481 GLint format;
00482 int bpp;
00483 BITMAP *temp = NULL;
00484 BITMAP *vbmp = vid->memory_copy;;
00485
00486 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00487 glGetIntegerv(GL_UNPACK_ALIGNMENT, &saved_alignment);
00488
00489 bpp = BYTES_PER_PIXEL(bitmap_color_depth(vid->memory_copy));
00490 format = vid->format;
00491 type = vid->type;
00492
00493
00494
00495
00496 if (!allegro_gl_extensions_GL.EXT_packed_pixels
00497 && bitmap_color_depth(vbmp) < 24) {
00498 temp = create_bitmap_ex(24, vbmp->w, vbmp->h);
00499 if (!temp)
00500 return;
00501
00502 blit(vbmp, temp, 0, 0, 0, 0, temp->w, temp->h);
00503 vbmp = temp;
00504 bpp = BYTES_PER_PIXEL(bitmap_color_depth(vbmp));
00505 format = __allegro_gl_get_bitmap_color_format(vbmp, 0);
00506 type = __allegro_gl_get_bitmap_type(vbmp, 0);
00507 }
00508
00509 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00510 glPixelStorei(GL_UNPACK_ROW_LENGTH,
00511 vbmp->h > 1
00512 ? (vbmp->line[1] - vbmp->line[0]) / bpp
00513 : vbmp->w);
00514
00515 glEnable(vid->target);
00516 glBindTexture(vid->target, vid->tex);
00517 glTexSubImage2D(vid->target, 0,
00518 x1, y1, x2 - x1 + 1, y2 - y1 + 1, format,
00519 type, vbmp->line[y1] + x1 * bpp);
00520 glBindTexture(vid->target, 0);
00521 glDisable(vid->target);
00522
00523 if (temp)
00524 destroy_bitmap(temp);
00525
00526 glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00527 glPixelStorei(GL_UNPACK_ALIGNMENT, saved_alignment);
00528 }
00529
00530
00531
00532 static void allegro_gl_video_putpixel(struct BITMAP *bmp, int x, int y,
00533 int color) {
00534 AGL_VIDEO_BITMAP *vid;
00535
00536 if (is_sub_bitmap(bmp)) {
00537 x += bmp->x_ofs;
00538 y += bmp->y_ofs;
00539 }
00540 if (x < bmp->cl || x >= bmp->cr || y < bmp->ct || y >= bmp->cb) {
00541 return;
00542 }
00543
00544 vid = bmp->extra;
00545
00546 while (vid) {
00547 if (vid->x_ofs <= x && vid->y_ofs <= y
00548 && vid->x_ofs + vid->memory_copy->w > x
00549 && vid->y_ofs + vid->memory_copy->h > y) {
00550
00551 putpixel(vid->memory_copy, x - vid->x_ofs, y - vid->y_ofs, color);
00552 update_texture_memory(vid, x - vid->x_ofs, y - vid->y_ofs, x - vid->x_ofs, y - vid->y_ofs);
00553 break;
00554 }
00555 vid = vid->next;
00556 }
00557
00558 return;
00559 }
00560
00561
00562
00563 static void allegro_gl_video_vline(BITMAP *bmp, int x, int y1, int y2,
00564 int color) {
00565
00566 AGL_VIDEO_BITMAP *vid;
00567
00568 AGL_LOG(2, "glvtable.c:allegro_gl_video_vline\n");
00569 vid = bmp->extra;
00570
00571 if (is_sub_bitmap(bmp)) {
00572 x += bmp->x_ofs;
00573 y1 += bmp->y_ofs;
00574 y2 += bmp->y_ofs;
00575 }
00576 if (x < bmp->cl || x >= bmp->cr) {
00577 return;
00578 }
00579
00580 if (y1 > y2) {
00581 int temp = y1;
00582 y1 = y2;
00583 y2 = temp;
00584 }
00585
00586 if (y1 < bmp->ct) {
00587 y1 = bmp->ct;
00588 }
00589 if (y2 >= bmp->cb) {
00590 y2 = bmp->cb - 1;
00591 }
00592
00593 while (vid) {
00594 BITMAP *vbmp = vid->memory_copy;
00595
00596 int _y1, _y2, _x;
00597 if (vid->x_ofs > x || vid->y_ofs > y2
00598 || vid->x_ofs + vbmp->w <= x
00599 || vid->y_ofs + vbmp->h <= y1) {
00600
00601 vid = vid->next;
00602 continue;
00603 }
00604
00605 _y1 = MAX(y1, vid->y_ofs) - vid->y_ofs;
00606 _y2 = MIN(y2, vid->y_ofs + vbmp->h - 1) - vid->y_ofs;
00607 _x = x - vid->x_ofs;
00608
00609 vline(vbmp, _x, _y1, _y2, color);
00610 update_texture_memory(vid, _x, _y1, _x, _y2);
00611
00612 vid = vid->next;
00613 }
00614
00615 return;
00616 }
00617
00618
00619
00620 static void allegro_gl_video_hline(BITMAP *bmp, int x1, int y, int x2,
00621 int color) {
00622
00623 AGL_VIDEO_BITMAP *vid;
00624
00625 AGL_LOG(2, "glvtable.c:allegro_gl_video_hline\n");
00626 vid = bmp->extra;
00627
00628 if (is_sub_bitmap(bmp)) {
00629 x1 += bmp->x_ofs;
00630 x2 += bmp->x_ofs;
00631 y += bmp->y_ofs;
00632 }
00633
00634 if (y < bmp->ct || y >= bmp->cb) {
00635 return;
00636 }
00637
00638 if (x1 > x2) {
00639 int temp = x1;
00640 x1 = x2;
00641 x2 = temp;
00642 }
00643
00644 if (x1 < bmp->cl) {
00645 x1 = bmp->cl;
00646 }
00647 if (x2 >= bmp->cr) {
00648 x2 = bmp->cr - 1;
00649 }
00650
00651 while (vid) {
00652 BITMAP *vbmp = vid->memory_copy;
00653
00654 int _x1, _x2, _y;
00655 if (vid->y_ofs > y || vid->x_ofs > x2
00656 || vid->x_ofs + vbmp->w <= x1
00657 || vid->y_ofs + vbmp->h <= y) {
00658
00659 vid = vid->next;
00660 continue;
00661 }
00662
00663 _x1 = MAX(x1, vid->x_ofs) - vid->x_ofs;
00664 _x2 = MIN(x2, vid->x_ofs + vbmp->w - 1) - vid->x_ofs;
00665 _y = y - vid->y_ofs;
00666
00667 hline(vbmp, _x1, _y, _x2, color);
00668 update_texture_memory(vid, _x1, _y, _x2, _y);
00669
00670 vid = vid->next;
00671 }
00672
00673 return;
00674 }
00675
00676
00677
00678 static void allegro_gl_video_line(struct BITMAP *bmp, int x1, int y1, int x2,
00679 int y2, int color) {
00680
00681
00682 do_line(bmp, x1, y1, x2, y2, color, allegro_gl_video_putpixel);
00683
00684 return;
00685 }
00686
00687
00688
00689 static void allegro_gl_video_rectfill(struct BITMAP *bmp, int x1, int y1,
00690 int x2, int y2, int color) {
00691
00692 AGL_VIDEO_BITMAP *vid;
00693
00694 AGL_LOG(2, "glvtable.c:allegro_gl_video_rectfill\n");
00695 vid = bmp->extra;
00696
00697 if (is_sub_bitmap(bmp)) {
00698 x1 += bmp->x_ofs;
00699 x2 += bmp->x_ofs;
00700 y1 += bmp->y_ofs;
00701 y2 += bmp->y_ofs;
00702 }
00703
00704 if (y1 > y2) {
00705 int temp = y1;
00706 y1 = y2;
00707 y2 = temp;
00708 }
00709
00710 if (x1 > x2) {
00711 int temp = x1;
00712 x1 = x2;
00713 x2 = temp;
00714 }
00715
00716 if (x1 < bmp->cl) {
00717 x1 = bmp->cl;
00718 }
00719 if (x2 >= bmp->cr) {
00720 x2 = bmp->cr - 1;
00721 }
00722 if (y1 < bmp->ct) {
00723 y1 = bmp->ct;
00724 }
00725 if (y1 >= bmp->cb) {
00726 y1 = bmp->cb - 1;
00727 }
00728
00729 while (vid) {
00730 BITMAP *vbmp = vid->memory_copy;
00731
00732 int _y1, _y2, _x1, _x2;
00733 if (vid->x_ofs > x2 || vid->y_ofs > y2
00734 || vid->x_ofs + vbmp->w <= x1
00735 || vid->y_ofs + vbmp->h <= y1) {
00736
00737 vid = vid->next;
00738 continue;
00739 }
00740
00741 _y1 = MAX(y1, vid->y_ofs) - vid->y_ofs;
00742 _y2 = MIN(y2, vid->y_ofs + vbmp->h - 1) - vid->y_ofs;
00743 _x1 = MAX(x1, vid->x_ofs) - vid->x_ofs;
00744 _x2 = MIN(x2, vid->x_ofs + vbmp->w - 1) - vid->x_ofs;
00745
00746 rectfill(vbmp, _x1, _y1, _x2, _y2, color);
00747
00748 update_texture_memory(vid, _x1, _y1, _x2, _y2);
00749
00750 vid = vid->next;
00751 }
00752
00753 return;
00754 }
00755
00756
00757 static void allegro_gl_video_triangle(struct BITMAP *bmp, int x1, int y1,
00758 int x2, int y2, int x3, int y3, int color)
00759 {
00760 AGL_VIDEO_BITMAP *vid;
00761 int min_y, max_y, min_x, max_x;
00762
00763 AGL_LOG(2, "glvtable.c:allegro_gl_video_triangle\n");
00764 vid = bmp->extra;
00765
00766 if (is_sub_bitmap(bmp)) {
00767 x1 += bmp->x_ofs;
00768 x2 += bmp->x_ofs;
00769 x3 += bmp->x_ofs;
00770 y1 += bmp->y_ofs;
00771 y2 += bmp->y_ofs;
00772 y3 += bmp->y_ofs;
00773 }
00774
00775 min_y = MIN(y1, MIN(y2, y3));
00776 min_x = MIN(x1, MIN(x2, x3));
00777 max_y = MAX(y1, MAX(y2, y3));
00778 max_x = MAX(x1, MAX(x2, x3));
00779
00780 while (vid) {
00781 BITMAP *vbmp = vid->memory_copy;
00782
00783 int _y1, _y2, _x1, _x2, _x3, _y3;
00784 if (vid->x_ofs > max_x || vid->y_ofs > max_y
00785 || vid->x_ofs + vbmp->w <= min_x
00786 || vid->y_ofs + vbmp->h <= min_y) {
00787
00788 vid = vid->next;
00789 continue;
00790 }
00791
00792 _y1 = y1 - vid->y_ofs;
00793 _y2 = y2 - vid->y_ofs;
00794 _y3 = y3 - vid->y_ofs;
00795 _x1 = x1 - vid->x_ofs;
00796 _x2 = x2 - vid->x_ofs;
00797 _x3 = x3 - vid->x_ofs;
00798
00799 set_clip_rect(vbmp, bmp->cl - vid->x_ofs, bmp->ct - vid->y_ofs,
00800 bmp->cr - vid->x_ofs - 1, bmp->cb - vid->y_ofs - 1);
00801
00802 triangle(vbmp, _x1, _y1, _x2, _y2, _x3, _y3, color);
00803
00804 set_clip_rect(vbmp, 0, 0, vbmp->w - 1, vbmp->h - 1);
00805
00806
00807
00808 _y1 = MAX(0, min_y - vid->y_ofs);
00809 _y2 = MIN(vbmp->h - 1, max_y - vid->y_ofs);
00810 _x1 = MAX(0, min_x - vid->x_ofs);
00811 _x2 = MIN(vbmp->w - 1, max_x - vid->x_ofs);
00812
00813 update_texture_memory(vid, _x1, _y1, _x2, _y2);
00814
00815 vid = vid->next;
00816 }
00817 }
00818
00819
00820
00821 static void allegro_gl_video_blit_from_memory_ex(BITMAP *source, BITMAP *dest,
00822 int source_x, int source_y, int dest_x, int dest_y,
00823 int width, int height, int draw_type) {
00824
00825 AGL_VIDEO_BITMAP *vid;
00826 BITMAP *dest_parent = dest;
00827
00828 if (is_sub_bitmap (dest)) {
00829 dest_x += dest->x_ofs;
00830 dest_y += dest->y_ofs;
00831 while (dest_parent->id & BMP_ID_SUB)
00832 dest_parent = (BITMAP *)dest_parent->extra;
00833 }
00834
00835 if (dest_x < dest->cl) {
00836 dest_x = dest->cl;
00837 }
00838 if (dest_y < dest->ct) {
00839 dest_y = dest->ct;
00840 }
00841 if (dest_x + width >= dest->cr) {
00842 width = dest->cr - dest_x;
00843 }
00844 if (dest_y + height >= dest->cb) {
00845 height = dest->cb - dest_y;
00846 }
00847 if (width < 1 || height < 1) {
00848 return;
00849 }
00850
00851 vid = dest_parent->extra;
00852
00853 while (vid) {
00854 BITMAP *vbmp = vid->memory_copy;
00855
00856 int _x, _y, _w, _h, _sx, _sy;
00857 if (vid->x_ofs >= dest_x + width || vid->y_ofs >= dest_y + height
00858 || vid->x_ofs + vbmp->w <= dest_x
00859 || vid->y_ofs + vbmp->h <= dest_y) {
00860
00861 vid = vid->next;
00862 continue;
00863 }
00864
00865 _x = MAX (vid->x_ofs, dest_x) - vid->x_ofs;
00866 _w = MIN (vid->x_ofs + vbmp->w, dest_x + width)
00867 - vid->x_ofs - _x;
00868 _y = MAX (vid->y_ofs, dest_y) - vid->y_ofs;
00869 _h = MIN (vid->y_ofs + vbmp->h, dest_y + height)
00870 - vid->y_ofs - _y;
00871
00872 _sx = source_x + vid->x_ofs + _x - dest_x;
00873 _sy = source_y + vid->y_ofs + _y - dest_y;
00874
00875 if (draw_type == BLIT) {
00876 blit(source, vbmp, _sx, _sy, _x, _y, _w, _h);
00877 }
00878 else if (draw_type == MASKED_BLIT) {
00879 masked_blit(source, vbmp, _sx, _sy, _x, _y, _w, _h);
00880 }
00881 else if (draw_type == TRANS) {
00882 BITMAP *clip = create_sub_bitmap(source, _sx, _sy, _w, _h);
00883 if (!clip)
00884 return;
00885 draw_trans_sprite(vbmp, clip, _x, _y);
00886 destroy_bitmap(clip);
00887 }
00888
00889 update_texture_memory(vid, _x, _y, _x + _w - 1, _y + _h - 1);
00890
00891 vid = vid->next;
00892 }
00893
00894 return;
00895 }
00896
00897
00898 void allegro_gl_video_blit_from_memory(BITMAP *source, BITMAP *dest,
00899 int source_x, int source_y, int dest_x, int dest_y,
00900 int width, int height) {
00901
00902 allegro_gl_video_blit_from_memory_ex(source, dest, source_x, source_y,
00903 dest_x, dest_y, width, height, BLIT);
00904 return;
00905 }
00906
00907
00908
00909 void allegro_gl_video_blit_to_memory(struct BITMAP *source, struct BITMAP *dest,
00910 int source_x, int source_y, int dest_x, int dest_y,
00911 int width, int height) {
00912
00913 AGL_VIDEO_BITMAP *vid;
00914 BITMAP *source_parent = source;
00915
00916 AGL_LOG(2, "glvtable.c:allegro_gl_video_blit_to_memory\n");
00917
00918 if (is_sub_bitmap(source)) {
00919 source_x += source->x_ofs;
00920 source_y += source->y_ofs;
00921 while (source_parent->id & BMP_ID_SUB)
00922 source_parent = (BITMAP *)source_parent->extra;
00923 }
00924
00925 vid = source_parent->extra;
00926
00927 while (vid) {
00928 BITMAP *vbmp = vid->memory_copy;
00929 int x, y, dx, dy, w, h;
00930
00931 x = MAX(source_x, vid->x_ofs) - vid->x_ofs;
00932 y = MAX(source_y, vid->y_ofs) - vid->y_ofs;
00933 w = MIN(vid->x_ofs + vbmp->w, source_x + width) - vid->x_ofs;
00934 h = MIN(vid->y_ofs + vbmp->h, source_y + height) - vid->y_ofs;
00935 dx = MAX(0, vid->x_ofs - source_x) + dest_x;
00936 dy = MAX(0, vid->y_ofs - source_y) + dest_y;
00937
00938 blit(vbmp, dest, x, y, dx, dy, w, h);
00939
00940 vid = vid->next;
00941 }
00942
00943 return;
00944 }
00945
00946
00947
00948
00949
00950
00951 static void __video_update_memory_copy(BITMAP *source, BITMAP *dest,
00952 int source_x, int source_y, int dest_x, int dest_y,
00953 int width, int height, int draw_type) {
00954 AGL_VIDEO_BITMAP *vid;
00955 BITMAP *dest_parent = dest;
00956
00957 if (is_sub_bitmap (dest)) {
00958 dest_x += dest->x_ofs;
00959 dest_y += dest->y_ofs;
00960 while (dest_parent->id & BMP_ID_SUB)
00961 dest_parent = (BITMAP *)dest_parent->extra;
00962 }
00963
00964 if (dest_x < dest->cl) {
00965 dest_x = dest->cl;
00966 }
00967 if (dest_y < dest->ct) {
00968 dest_y = dest->ct;
00969 }
00970 if (dest_x + width >= dest->cr) {
00971 width = dest->cr - dest_x;
00972 }
00973 if (dest_y + height >= dest->cb) {
00974 height = dest->cb - dest_y;
00975 }
00976 if (width < 1 || height < 1) {
00977 return;
00978 }
00979
00980 vid = dest_parent->extra;
00981
00982 while (vid) {
00983 int sx, sy;
00984 BITMAP *vbmp = vid->memory_copy;
00985
00986 int dx, dy, w, h;
00987 if (vid->x_ofs >= dest_x + width || vid->y_ofs >= dest_y + height
00988 || vid->x_ofs + vbmp->w <= dest_x
00989 || vid->y_ofs + vbmp->h <= dest_y) {
00990
00991 vid = vid->next;
00992 continue;
00993 }
00994
00995 dx = MAX (vid->x_ofs, dest_x) - vid->x_ofs;
00996 w = MIN (vid->x_ofs + vbmp->w, dest_x + width)
00997 - vid->x_ofs - dx;
00998 dy = MAX (vid->y_ofs, dest_y) - vid->y_ofs;
00999 h = MIN (vid->y_ofs + vbmp->h, dest_y + height)
01000 - vid->y_ofs - dy;
01001
01002 sx = source_x + vid->x_ofs + dx - dest_x;
01003 sy = source_y + vid->y_ofs + dy - dest_y;
01004
01005 if (draw_type == MASKED_BLIT) {
01006 masked_blit(source, vbmp, sx, sy, dx, dy, w, h);
01007 }
01008 else if (draw_type == BLIT) {
01009 blit(source, vbmp, sx, sy, dx, dy, w, h);
01010 }
01011 else if (draw_type == TRANS) {
01012 BITMAP *clip = create_sub_bitmap(source, sx, sy, w, h);
01013 if (!clip)
01014 return;
01015 draw_trans_sprite(vbmp, clip, dx, dy);
01016 destroy_bitmap(clip);
01017 }
01018
01019 vid = vid->next;
01020 }
01021
01022 return;
01023 }
01024
01025
01026 #define FOR_EACH_TEXTURE_FRAGMENT( \
01027 screen_blit_from_vid, \
01028 screen_blit_from_mem, \
01029 mem_copy_blit_from_vid, \
01030 mem_copy_blit_from_mem, \
01031 vid_and_mem_copy_blit_from_vid, \
01032 vid_and_mem_copy_blit_from_mem) \
01033 \
01034 \
01035 { \
01036 int used_fbo = FALSE; \
01037 \
01038 if (allegro_gl_extensions_GL.EXT_framebuffer_object) { \
01039 int sx, sy; \
01040 int dx, dy; \
01041 int w, h; \
01042 \
01043 AGL_VIDEO_BITMAP *vid; \
01044 \
01045 static GLint v[4]; \
01046 static double allegro_gl_projection_matrix[16]; \
01047 static double allegro_gl_modelview_matrix[16]; \
01048 \
01049 glGetIntegerv(GL_VIEWPORT, &v[0]); \
01050 glMatrixMode(GL_MODELVIEW); \
01051 glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix); \
01052 glMatrixMode(GL_PROJECTION); \
01053 glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix); \
01054 \
01055 vid = dest->extra; \
01056 \
01057 while (vid) { \
01058 if (dest_x >= vid->x_ofs + vid->memory_copy->w || \
01059 dest_y >= vid->y_ofs + vid->memory_copy->h || \
01060 vid->x_ofs >= dest_x + width || \
01061 vid->y_ofs >= dest_y + height) { \
01062 vid = vid->next; \
01063 continue; \
01064 } \
01065 \
01066 dx = MAX(vid->x_ofs, dest_x) - vid->x_ofs; \
01067 w = MIN(vid->x_ofs + vid->memory_copy->w, dest_x + width) \
01068 - vid->x_ofs - dx; \
01069 dy = MAX(vid->y_ofs, dest_y) - vid->y_ofs; \
01070 h = MIN(vid->y_ofs + vid->memory_copy->h, dest_y + height) \
01071 - vid->y_ofs - dy; \
01072 \
01073 sx = source_x + vid->x_ofs + dx - dest_x; \
01074 sy = source_y + vid->y_ofs + dy - dest_y; \
01075 \
01076 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo); \
01077 \
01078 glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h); \
01079 glMatrixMode(GL_PROJECTION); \
01080 glLoadIdentity(); \
01081 gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h); \
01082 glMatrixMode(GL_MODELVIEW); \
01083 \
01084 if (is_memory_bitmap(source)) { \
01085 screen_blit_from_mem; \
01086 } \
01087 else { \
01088 screen_blit_from_vid; \
01089 } \
01090 \
01091 vid = vid->next; \
01092 } \
01093 \
01094 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); \
01095 \
01096 glViewport(v[0], v[1], v[2], v[3]); \
01097 glMatrixMode(GL_PROJECTION); \
01098 glLoadMatrixd(allegro_gl_projection_matrix); \
01099 glMatrixMode(GL_MODELVIEW); \
01100 glLoadMatrixd(allegro_gl_modelview_matrix); \
01101 \
01102 used_fbo = TRUE; \
01103 } \
01104 \
01105 if (is_video_bitmap(source)) { \
01106 int sx, sy; \
01107 int dx, dy; \
01108 int w, h; \
01109 \
01110 AGL_VIDEO_BITMAP *vid; \
01111 vid = source->extra; \
01112 \
01113 while (vid) { \
01114 if (source_x >= vid->x_ofs + vid->memory_copy->w || \
01115 source_y >= vid->y_ofs + vid->memory_copy->h || \
01116 vid->x_ofs >= source_x + width || \
01117 vid->y_ofs >= source_y + height) { \
01118 vid = vid->next; \
01119 continue; \
01120 } \
01121 \
01122 sx = MAX(vid->x_ofs, source_x) - vid->x_ofs; \
01123 w = MIN(vid->x_ofs + vid->memory_copy->w, source_x + width) \
01124 - vid->x_ofs - sx; \
01125 sy = MAX(vid->y_ofs, source_y) - vid->y_ofs; \
01126 h = MIN(vid->y_ofs + vid->memory_copy->h, source_y + height) \
01127 - vid->y_ofs - sy; \
01128 \
01129 dx = dest_x + vid->x_ofs + sx - source_x; \
01130 dy = dest_y + vid->y_ofs + sy - source_y; \
01131 \
01132 if (used_fbo) { \
01133 mem_copy_blit_from_vid; \
01134 } \
01135 else { \
01136 vid_and_mem_copy_blit_from_vid; \
01137 } \
01138 \
01139 vid = vid->next; \
01140 } \
01141 } \
01142 else if (is_memory_bitmap(source)) { \
01143 if (used_fbo) { \
01144 mem_copy_blit_from_mem; \
01145 } \
01146 else { \
01147 vid_and_mem_copy_blit_from_mem; \
01148 } \
01149 } \
01150 }
01151
01152
01153
01154
01155
01156 void allegro_gl_video_blit_to_self(struct BITMAP *source, struct BITMAP *dest,
01157 int source_x, int source_y, int dest_x, int dest_y, int width, int height) {
01158
01159 FOR_EACH_TEXTURE_FRAGMENT (
01160 allegro_gl_screen_blit_to_self(source, screen, sx, sy, dx, dy, w, h),
01161 allegro_gl_screen_blit_to_self(source, screen, sx, sy, dx, dy, w, h),
01162 __video_update_memory_copy(vid->memory_copy, dest, sx, sy, dx, dy, w, h, BLIT),
01163 __video_update_memory_copy(source, dest, source_x, source_y, dest_x, dest_y, width, height, BLIT),
01164 allegro_gl_video_blit_from_memory(vid->memory_copy, dest, sx, sy, dx, dy, w, h),
01165 allegro_gl_video_blit_from_memory(source, dest, source_x, source_y, dest_x, dest_y, width, height)
01166 )
01167 }
01168
01169
01170 static void do_masked_blit_video(struct BITMAP *source, struct BITMAP *dest,
01171 int source_x, int source_y, int dest_x, int dest_y,
01172 int width, int height, int flip_dir, int blit_type) {
01173
01174 FOR_EACH_TEXTURE_FRAGMENT (
01175 do_masked_blit_screen(source, screen, sx, sy, dx, dy, w, h, flip_dir, blit_type),
01176 do_masked_blit_screen(source, screen, sx, sy, dx, dy, w, h, flip_dir, blit_type),
01177 __video_update_memory_copy(vid->memory_copy, dest, sx, sy, dx, dy, w, h, MASKED_BLIT),
01178 __video_update_memory_copy(source, dest, source_x, source_y, dest_x, dest_y, width, height, MASKED_BLIT),
01179 allegro_gl_video_blit_from_memory_ex(vid->memory_copy, dest, sx, sy, dx, dy, w, h, MASKED_BLIT),
01180 allegro_gl_video_blit_from_memory_ex(source, dest, source_x, source_y, dest_x, dest_y, width, height, MASKED_BLIT)
01181 )
01182 }
01183
01184
01185
01186
01187
01188 static void allegro_gl_video_masked_blit(struct BITMAP *source,
01189 struct BITMAP *dest, int source_x, int source_y,
01190 int dest_x, int dest_y, int width, int height) {
01191 do_masked_blit_video(source, dest, source_x, source_y, dest_x, dest_y,
01192 width, height, FALSE, AGL_REGULAR_BMP | AGL_NO_ROTATION);
01193
01194 return;
01195 }
01196
01197
01198
01199
01200
01201 static void allegro_gl_video_draw_sprite(struct BITMAP *bmp,
01202 struct BITMAP *sprite, int x, int y) {
01203
01204 do_masked_blit_video(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
01205 FALSE, AGL_NO_ROTATION);
01206
01207 return;
01208 }
01209
01210
01211
01212
01213
01214
01215
01216 static void allegro_gl_video_draw_sprite_v_flip(struct BITMAP *bmp,
01217 struct BITMAP *sprite, int x, int y) {
01218
01219 do_masked_blit_video(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
01220 AGL_V_FLIP, AGL_NO_ROTATION);
01221
01222 return;
01223 }
01224
01225
01226
01227
01228
01229
01230
01231 static void allegro_gl_video_draw_sprite_h_flip(struct BITMAP *bmp,
01232 struct BITMAP *sprite, int x, int y) {
01233
01234 do_masked_blit_video(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
01235 AGL_H_FLIP, AGL_NO_ROTATION);
01236
01237 return;
01238 }
01239
01240
01241
01242
01243
01244
01245
01246 static void allegro_gl_video_draw_sprite_vh_flip(struct BITMAP *bmp,
01247 struct BITMAP *sprite, int x, int y) {
01248
01249 do_masked_blit_video(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
01250 AGL_V_FLIP | AGL_H_FLIP, AGL_NO_ROTATION);
01251
01252 return;
01253 }
01254
01255
01256
01257
01258
01259
01260
01261 static void allegro_gl_video_pivot_scaled_sprite_flip(struct BITMAP *bmp,
01262 struct BITMAP *sprite, fixed x, fixed y, fixed cx, fixed cy,
01263 fixed angle, fixed scale, int v_flip) {
01264 double dscale = fixtof(scale);
01265 GLint matrix_mode;
01266
01267 #define BIN_2_DEG(x) (-(x) * 180.0 / 128)
01268
01269 glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
01270 glMatrixMode(GL_MODELVIEW);
01271 glPushMatrix();
01272 glTranslated(fixtof(x), fixtof(y), 0.);
01273 glRotated(BIN_2_DEG(fixtof(angle)), 0., 0., -1.);
01274 glScaled(dscale, dscale, dscale);
01275 glTranslated(-fixtof(x+cx), -fixtof(y+cy), 0.);
01276
01277 do_masked_blit_video(sprite, bmp, 0, 0, fixtoi(x), fixtoi(y),
01278 sprite->w, sprite->h, v_flip ? AGL_V_FLIP : FALSE, FALSE);
01279 glPopMatrix();
01280 glMatrixMode(matrix_mode);
01281
01282 #undef BIN_2_DEG
01283
01284 return;
01285 }
01286
01287
01288
01289
01290
01291
01292
01293 static void allegro_gl_video_do_stretch_blit(BITMAP *source, BITMAP *dest,
01294 int source_x, int source_y, int source_width, int source_height,
01295 int dest_x, int dest_y, int dest_width, int dest_height,
01296 int masked) {
01297
01298
01299 double scalew = ((double)dest_width) / source_width;
01300 double scaleh = ((double)dest_height) / source_height;
01301
01302 GLint matrix_mode;
01303
01304
01305 if (dest->clip) {
01306 if ((dest_x >= dest->cr) || (dest_y >= dest->cb)
01307 || (dest_x + dest_width < dest->cl) || (dest_y + dest_height < dest->ct)) {
01308 return;
01309 }
01310 if (dest_x < dest->cl) {
01311 source_x -= (dest_x - dest->cl) / scalew;
01312 dest_x = dest->cl;
01313 }
01314 if (dest_y < dest->ct) {
01315 source_y -= (dest_y - dest->ct) / scaleh;
01316 dest_y = dest->ct;
01317 }
01318 }
01319
01320 glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
01321 glMatrixMode(GL_MODELVIEW);
01322 glPushMatrix();
01323 glTranslated(dest_x, dest_y, 0.);
01324 glScaled(scalew, scaleh, 1.);
01325 glTranslated(-dest_x, -dest_y, 0.);
01326
01327 if (masked) {
01328 if (is_screen_bitmap(dest)) {
01329 do_masked_blit_screen(source, dest, source_x, source_y,
01330 dest_x, dest_y, source_width, source_height,
01331 FALSE, AGL_REGULAR_BMP);
01332 }
01333 else {
01334 do_masked_blit_video(source, dest, source_x, source_y,
01335 dest_x, dest_y, source_width, source_height,
01336 FALSE, AGL_REGULAR_BMP);
01337 }
01338 }
01339 else {
01340 allegro_gl_screen_blit_to_self(source, dest, source_x, source_y,
01341 dest_x, dest_y, source_width, source_height);
01342 }
01343
01344 glPopMatrix();
01345 glMatrixMode(matrix_mode);
01346
01347 return;
01348 }
01349
01350
01351
01352
01353
01354
01355 static void allegro_gl_video_draw_trans_rgba_sprite(BITMAP *bmp,
01356 BITMAP *sprite, int x, int y) {
01357
01358 BITMAP *source = sprite;
01359 BITMAP *dest = bmp;
01360 int dest_x = x;
01361 int dest_y = y;
01362 int source_x = 0;
01363 int source_y = 0;
01364 int width = sprite->w;
01365 int height = sprite->h;
01366 GLint format = __allegro_gl_get_bitmap_color_format(sprite, AGL_TEXTURE_HAS_ALPHA);
01367 GLint type = __allegro_gl_get_bitmap_type(sprite, 0);
01368
01369 if (__allegro_gl_blit_operation == AGL_OP_LOGIC_OP)
01370 glEnable(GL_COLOR_LOGIC_OP);
01371 else
01372 glEnable(GL_BLEND);
01373
01374 FOR_EACH_TEXTURE_FRAGMENT (
01375 allegro_gl_screen_blit_to_self(source, screen, sx, sy, dx, dy, w, h),
01376 allegro_gl_upload_and_display_texture(sprite, sx, sy, dx, dy, w, h, 0, format, type),
01377 __video_update_memory_copy(vid->memory_copy, dest, sx, sy, dx, dy, w, h, TRANS),
01378 __video_update_memory_copy(source, dest, 0, 0, x, y, sprite->w, sprite->h, TRANS),
01379 allegro_gl_video_blit_from_memory_ex(vid->memory_copy, dest, sx, sy, dx, dy, w, h, TRANS),
01380 allegro_gl_video_blit_from_memory_ex(source, dest, 0, 0, x, y, sprite->w, sprite->h, TRANS)
01381 )
01382
01383 if (__allegro_gl_blit_operation == AGL_OP_LOGIC_OP)
01384 glDisable(GL_COLOR_LOGIC_OP);
01385 else
01386 glDisable(GL_BLEND);
01387
01388 return;
01389 }
01390
01391
01392
01393 static void allegro_gl_video_clear_to_color(BITMAP *bmp, int color) {
01394 if (allegro_gl_extensions_GL.EXT_framebuffer_object) {
01395 AGL_VIDEO_BITMAP *vid = bmp->extra;
01396
01397 static GLint v[4];
01398 static double allegro_gl_projection_matrix[16];
01399 static double allegro_gl_modelview_matrix[16];
01400
01401 glGetIntegerv(GL_VIEWPORT, &v[0]);
01402 glMatrixMode(GL_MODELVIEW);
01403 glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);
01404 glMatrixMode(GL_PROJECTION);
01405 glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix);
01406
01407 while (vid) {
01408 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo);
01409
01410 glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h);
01411 glMatrixMode(GL_PROJECTION);
01412 glLoadIdentity();
01413 gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h);
01414 glMatrixMode(GL_MODELVIEW);
01415
01416 allegro_gl_screen_clear_to_color(screen, color);
01417 clear_to_color(vid->memory_copy, color);
01418 vid = vid->next;
01419 }
01420
01421 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
01422
01423 glViewport(v[0], v[1], v[2], v[3]);
01424 glMatrixMode(GL_PROJECTION);
01425 glLoadMatrixd(allegro_gl_projection_matrix);
01426 glMatrixMode(GL_MODELVIEW);
01427 glLoadMatrixd(allegro_gl_modelview_matrix);
01428 }
01429 else {
01430 allegro_gl_video_rectfill(bmp, 0, 0, bmp->w, bmp->h, color);
01431 }
01432
01433 return;
01434 }
01435
01436
01437
01438
01439
01440
01441 static void allegro_gl_video_draw_color_glyph(struct BITMAP *bmp,
01442 struct BITMAP *sprite, int x, int y, int color, int bg)
01443 {
01444 AGL_VIDEO_BITMAP *vid = bmp->extra;
01445
01446 static GLint v[4];
01447 static double allegro_gl_projection_matrix[16];
01448 static double allegro_gl_modelview_matrix[16];
01449
01450 if (allegro_gl_extensions_GL.EXT_framebuffer_object)
01451 return;
01452
01453 glGetIntegerv(GL_VIEWPORT, &v[0]);
01454 glMatrixMode(GL_MODELVIEW);
01455 glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);
01456 glMatrixMode(GL_PROJECTION);
01457 glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix);
01458
01459 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo);
01460
01461 glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h);
01462 glMatrixMode(GL_PROJECTION);
01463 glLoadIdentity();
01464 gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h);
01465 glMatrixMode(GL_MODELVIEW);
01466
01467 allegro_gl_screen_draw_color_glyph_ex(screen, sprite, x, y, color, bg, 0);
01468
01469 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
01470
01471 glViewport(v[0], v[1], v[2], v[3]);
01472 glMatrixMode(GL_PROJECTION);
01473 glLoadMatrixd(allegro_gl_projection_matrix);
01474 glMatrixMode(GL_MODELVIEW);
01475 glLoadMatrixd(allegro_gl_modelview_matrix);
01476
01477 vid->memory_copy->vtable->draw_character(vid->memory_copy, sprite, x, y, color, bg);
01478 }
01479
01480
01481
01482 static void allegro_gl_video_draw_256_sprite(BITMAP *bmp, BITMAP *sprite,
01483 int x, int y) {
01484 allegro_gl_video_draw_color_glyph(bmp, sprite, x, y, -1, _textmode);
01485 }
01486
01487
01488
01489 static void allegro_gl_video_draw_character(BITMAP *bmp, BITMAP *sprite,
01490 int x, int y, int color, int bg) {
01491 allegro_gl_video_draw_color_glyph(bmp, sprite, x, y, color, bg);
01492 }
01493
01494
01495
01496
01497
01498
01499 static void allegro_gl_video_draw_glyph(struct BITMAP *bmp,
01500 AL_CONST struct FONT_GLYPH *glyph, int x, int y,
01501 int color, int bg) {
01502 AGL_VIDEO_BITMAP *vid = bmp->extra;
01503
01504 static GLint v[4];
01505 static double allegro_gl_projection_matrix[16];
01506 static double allegro_gl_modelview_matrix[16];
01507
01508 if (!allegro_gl_extensions_GL.EXT_framebuffer_object)
01509 return;
01510
01511 glGetIntegerv(GL_VIEWPORT, &v[0]);
01512 glMatrixMode(GL_MODELVIEW);
01513 glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);
01514 glMatrixMode(GL_PROJECTION);
01515 glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix);
01516
01517 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, vid->fbo);
01518
01519 glViewport(0, 0, vid->memory_copy->w, vid->memory_copy->h);
01520 glMatrixMode(GL_PROJECTION);
01521 glLoadIdentity();
01522 gluOrtho2D(0, vid->memory_copy->w, 0, vid->memory_copy->h);
01523 glMatrixMode(GL_MODELVIEW);
01524
01525 allegro_gl_screen_draw_glyph_ex(screen, glyph, x, y, color, bg, 1);
01526
01527 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
01528
01529 glViewport(v[0], v[1], v[2], v[3]);
01530 glMatrixMode(GL_PROJECTION);
01531 glLoadMatrixd(allegro_gl_projection_matrix);
01532 glMatrixMode(GL_MODELVIEW);
01533 glLoadMatrixd(allegro_gl_modelview_matrix);
01534
01535 vid->memory_copy->vtable->draw_glyph(vid->memory_copy, glyph, x, y, color, bg);
01536 }
01537
01538
01539
01540 static void dummy_unwrite_bank(void)
01541 {
01542 }
01543
01544
01545
01546 static GFX_VTABLE allegro_gl_video_vtable = {
01547 0,
01548 0,
01549 dummy_unwrite_bank,
01550 NULL,
01551 allegro_gl_video_acquire,
01552 allegro_gl_video_release,
01553 NULL,
01554 allegro_gl_created_sub_bitmap,
01555 allegro_gl_video_getpixel,
01556 allegro_gl_video_putpixel,
01557 allegro_gl_video_vline,
01558 allegro_gl_video_hline,
01559 allegro_gl_video_hline,
01560 allegro_gl_video_line,
01561 allegro_gl_video_line,
01562 allegro_gl_video_rectfill,
01563 allegro_gl_video_triangle,
01564 allegro_gl_video_draw_sprite,
01565 allegro_gl_video_draw_256_sprite,
01566 allegro_gl_video_draw_sprite_v_flip,
01567 allegro_gl_video_draw_sprite_h_flip,
01568 allegro_gl_video_draw_sprite_vh_flip,
01569 allegro_gl_video_draw_trans_rgba_sprite,
01570 allegro_gl_video_draw_trans_rgba_sprite,
01571 NULL,
01572 NULL,
01573 NULL,
01574 NULL,
01575 NULL,
01576 allegro_gl_video_draw_character,
01577 allegro_gl_video_draw_glyph,
01578 allegro_gl_video_blit_from_memory,
01579 allegro_gl_video_blit_to_memory,
01580 NULL,
01581 NULL,
01582 allegro_gl_screen_blit_to_self,
01583 allegro_gl_screen_blit_to_self,
01584 allegro_gl_screen_blit_to_self,
01585 allegro_gl_memory_blit_between_formats,
01586 allegro_gl_video_masked_blit,
01587 allegro_gl_video_clear_to_color,
01588 allegro_gl_video_pivot_scaled_sprite_flip,
01589 allegro_gl_video_do_stretch_blit,
01590 NULL,
01591 NULL,
01592 NULL,
01593 _soft_polygon,
01594 _soft_rect,
01595 _soft_circle,
01596 _soft_circlefill,
01597 _soft_ellipse,
01598 _soft_ellipsefill,
01599 _soft_arc,
01600 _soft_spline,
01601 _soft_floodfill,
01602 _soft_polygon3d,
01603 _soft_polygon3d_f,
01604 _soft_triangle3d,
01605 _soft_triangle3d_f,
01606 _soft_quad3d,
01607 _soft_quad3d_f,
01608 };
01609