00001
00002
00003
00012 #include <string.h>
00013
00014 #include <allegro.h>
00015
00016 #ifdef ALLEGRO_WINDOWS
00017 #include <winalleg.h>
00018 #endif
00019
00020 #include "alleggl.h"
00021 #include "allglint.h"
00022 #include "glvtable.h"
00023 #include <allegro/internal/aintern.h>
00024 #ifdef ALLEGRO_MACOSX
00025 #include <OpenGL/glu.h>
00026 #else
00027 #include <GL/glu.h>
00028 #endif
00029
00030
00031 static GFX_VTABLE allegro_gl_video_vtable;
00032
00033
00034 static int video_bitmap_count = 2;
00035
00036
00037
00038 void allegro_gl_destroy_video_bitmap(BITMAP *bmp);
00039
00040
00041
00042 static int allegro_gl_make_video_bitmap_helper1(int w, int h, int x, int y,
00043 AGL_VIDEO_BITMAP **pvid) {
00044
00045 int is_power_of_2 = (!(w & (w - 1)) && !(h & (h - 1)));
00046
00047 (*pvid) = malloc(sizeof(AGL_VIDEO_BITMAP));
00048
00049 if (!(*pvid))
00050 return -1;
00051
00052 memset(*pvid, 0, sizeof(AGL_VIDEO_BITMAP));
00053
00054
00055 (*pvid)->memory_copy = create_bitmap_ex(32, w, h);
00056
00057 if (!(*pvid)->memory_copy)
00058 return -1;
00059
00060
00061
00062 if ((allegro_gl_extensions_GL.ARB_texture_non_power_of_two || is_power_of_2)
00063 && w <= allegro_gl_info.max_texture_size
00064 && h <= allegro_gl_info.max_texture_size) {
00065 (*pvid)->target = GL_TEXTURE_2D;
00066 }
00067 else {
00068 (*pvid)->target = GL_TEXTURE_RECTANGLE_ARB;
00069 }
00070
00071
00072 (*pvid)->width = w;
00073 (*pvid)->height = h;
00074 (*pvid)->x_ofs = x;
00075 (*pvid)->y_ofs = y;
00076
00077
00078 glGenTextures(1, &((*pvid)->tex));
00079 if (!((*pvid)->tex))
00080 return -1;
00081
00082 glEnable((*pvid)->target);
00083 glBindTexture((*pvid)->target, ((*pvid)->tex));
00084
00085 glTexImage2D((*pvid)->target, 0, GL_RGBA8, w, h,
00086 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
00087
00088
00089 glTexParameteri((*pvid)->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00090 glTexParameteri((*pvid)->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00091
00092
00093 { GLenum clamp = GL_CLAMP_TO_EDGE;
00094 if (!allegro_gl_extensions_GL.SGIS_texture_edge_clamp) {
00095 clamp = GL_CLAMP;
00096 }
00097 glTexParameteri((*pvid)->target, GL_TEXTURE_WRAP_S, clamp);
00098 glTexParameteri((*pvid)->target, GL_TEXTURE_WRAP_T, clamp);
00099 }
00100 glDisable((*pvid)->target);
00101
00102 return 0;
00103 }
00104
00105
00106
00107 static int allegro_gl_make_video_bitmap_helper0(int w, int h, int x, int y,
00108 AGL_VIDEO_BITMAP **pvid) {
00109
00110 int is_power_of_2 = (!(w & (w - 1)) && !(h & (h - 1)));
00111 int texture_rect_available = allegro_gl_extensions_GL.ARB_texture_rectangle
00112 #ifdef ALLEGRO_MACOSX
00113 || allegro_gl_extensions_GL.EXT_texture_rectangle
00114 #endif
00115 || allegro_gl_extensions_GL.NV_texture_rectangle;
00116 GLint max_rect_texture_size = 0;
00117
00118 if (texture_rect_available) {
00119 glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &max_rect_texture_size);
00120 }
00121
00122
00123
00124
00125
00126 if (((allegro_gl_extensions_GL.ARB_texture_non_power_of_two || is_power_of_2)
00127 && w <= allegro_gl_info.max_texture_size
00128 && h <= allegro_gl_info.max_texture_size)
00129 ||
00130 (texture_rect_available && !is_power_of_2
00131 && w <= max_rect_texture_size
00132 && h <= max_rect_texture_size)) {
00133
00134 if (allegro_gl_make_video_bitmap_helper1(w, h, 0, 0, pvid)) {
00135 return -1;
00136 }
00137 }
00138 else if (is_power_of_2) {
00139
00140
00141
00142 int wc, hc;
00143 w = w / 2;
00144 h = h / 2;
00145
00146
00147 if (!w && !h) {
00148 return -1;
00149 }
00150
00151 wc = w ? w : 1;
00152 hc = h ? h : 1;
00153
00154
00155 if (allegro_gl_make_video_bitmap_helper0(wc, hc, 0, 0, pvid)) {
00156 return -1;
00157 }
00158 pvid = &((*pvid)->next);
00159
00160
00161 if (w) {
00162 if (allegro_gl_make_video_bitmap_helper0(w, hc, w, 0, pvid)) {
00163 return -1;
00164 }
00165 pvid = &((*pvid)->next);
00166 }
00167
00168 if (h) {
00169 if (allegro_gl_make_video_bitmap_helper0(wc, h, 0, h, pvid)) {
00170 return -1;
00171 }
00172 pvid = &((*pvid)->next);
00173 }
00174
00175 if (w && h) {
00176 if (allegro_gl_make_video_bitmap_helper0(wc, hc, w, h, pvid)) {
00177 return -1;
00178 }
00179 pvid = &((*pvid)->next);
00180 }
00181 }
00182 else {
00183
00184
00185
00186 return -1;
00187 }
00188 return 0;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 static BITMAP *allegro_gl_make_video_bitmap(BITMAP *bmp) {
00200
00201
00202 AGL_VIDEO_BITMAP **pvid = (AGL_VIDEO_BITMAP**)&bmp->extra;
00203
00204
00205 if (allegro_gl_make_video_bitmap_helper0(bmp->w, bmp->h, 0, 0, pvid)) {
00206 goto agl_error;
00207 }
00208
00209 return bmp;
00210
00211 agl_error:
00212 allegro_gl_destroy_video_bitmap(bmp);
00213 return NULL;
00214 }
00215
00216
00217
00218
00226 BITMAP *allegro_gl_create_video_bitmap(int w, int h) {
00227
00228 BITMAP *bitmap;
00229
00230 bitmap = malloc(sizeof(BITMAP) + sizeof(char *));
00231
00232 if (!bitmap)
00233 return NULL;
00234
00235 bitmap->dat = NULL;
00236 bitmap->w = bitmap->cr = w;
00237 bitmap->h = bitmap->cb = h;
00238 bitmap->clip = TRUE;
00239 bitmap->cl = bitmap->ct = 0;
00240 bitmap->write_bank = bitmap->read_bank = NULL;
00241
00242 bitmap->id = BMP_ID_VIDEO | video_bitmap_count;
00243 bitmap->extra = NULL;
00244 bitmap->x_ofs = 0;
00245 bitmap->y_ofs = 0;
00246 bitmap->seg = _default_ds();
00247 bitmap->line[0] = NULL;
00248
00249 if (!allegro_gl_make_video_bitmap(bitmap)) {
00250 return NULL;
00251 }
00252 video_bitmap_count++;
00253
00254
00255
00256
00257 allegro_gl_video_vtable.color_depth = 32;
00258 allegro_gl_video_vtable.mask_color = makecol32(255, 0, 255);
00259 bitmap->vtable = &allegro_gl_video_vtable;
00260
00261 return bitmap;
00262 }
00263
00264
00265
00266
00271 void allegro_gl_destroy_video_bitmap(BITMAP *bmp) {
00272
00273 AGL_VIDEO_BITMAP *vid = bmp ? bmp->extra : NULL, *next;
00274
00275 if (!bmp)
00276 return;
00277
00278 while (vid) {
00279 if (vid->memory_copy)
00280 destroy_bitmap(vid->memory_copy);
00281
00282 if (vid->tex)
00283 glDeleteTextures(1, &vid->tex);
00284
00285 next = vid->next;
00286 free(vid);
00287 vid = next;
00288 }
00289
00290 free(bmp);
00291
00292 return;
00293 }
00294
00295
00296
00297
00304 static void allegro_gl_video_acquire(struct BITMAP *bmp) {}
00305
00306
00307
00308
00315 static void allegro_gl_video_release(struct BITMAP *bmp) {}
00316
00317
00318
00319 static int allegro_gl_video_getpixel(struct BITMAP *bmp, int x, int y)
00320 {
00321 int pix = -1;
00322 AGL_VIDEO_BITMAP *vid;
00323 AGL_LOG(2, "glvtable.c:allegro_gl_screen_getpixel\n");
00324
00325 if (is_sub_bitmap(bmp)) {
00326 x += bmp->x_ofs;
00327 y += bmp->y_ofs;
00328 }
00329 if (x < bmp->cl || x >= bmp->cr || y < bmp->ct || y >= bmp->cb) {
00330 return -1;
00331 }
00332
00333 vid = bmp->extra;
00334
00335 while (vid) {
00336 if (vid->x_ofs <= x && vid->y_ofs <= y
00337 && vid->x_ofs + vid->memory_copy->w > x
00338 && vid->y_ofs + vid->memory_copy->h > y) {
00339
00340 pix = getpixel(vid->memory_copy, x - vid->x_ofs, y - vid->y_ofs);
00341 break;
00342 }
00343 vid = vid->next;
00344 }
00345
00346 if (pix != -1) {
00347 return makeacol_depth(bitmap_color_depth(screen),
00348 getr_depth(32, pix), getg_depth(32, pix),
00349 getb_depth(32, pix), geta_depth(32, pix));
00350 }
00351
00352 return -1;
00353 }
00354
00355
00356
00357 static void allegro_gl_video_putpixel(struct BITMAP *bmp, int x, int y,
00358 int color) {
00359 GLubyte pixel[4];
00360 AGL_VIDEO_BITMAP *vid;
00361
00362 if (is_sub_bitmap(bmp)) {
00363 x += bmp->x_ofs;
00364 y += bmp->y_ofs;
00365 }
00366 if (x < bmp->cl || x >= bmp->cr || y < bmp->ct || y >= bmp->cb) {
00367 return;
00368 }
00369
00370 split_color(color, &pixel[0], &pixel[1], &pixel[2], &pixel[3],
00371 bitmap_color_depth(screen));
00372 vid = bmp->extra;
00373
00374
00375 while (vid) {
00376 if (vid->x_ofs <= x && vid->y_ofs <= y
00377 && vid->x_ofs + vid->memory_copy->w > x
00378 && vid->y_ofs + vid->memory_copy->h > y) {
00379
00380 putpixel(vid->memory_copy, x, y,
00381 makeacol_depth(32, pixel[0], pixel[1], pixel[2], pixel[3]));
00382
00383 glEnable(vid->target);
00384 glBindTexture(vid->target, vid->tex);
00385 glTexSubImage2D(vid->target, 0, x - vid->x_ofs,
00386 y - vid->y_ofs, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
00387 glBindTexture(vid->target, 0);
00388 glDisable(vid->target);
00389
00390 break;
00391 }
00392 vid = vid->next;
00393 }
00394
00395 return;
00396 }
00397
00398
00399
00400 static void allegro_gl_video_vline(BITMAP *bmp, int x, int y1, int y2,
00401 int color) {
00402
00403 GLubyte pixel[4];
00404 AGL_VIDEO_BITMAP *vid;
00405 GLint saved_row_length;
00406
00407 AGL_LOG(2, "glvtable.c:allegro_gl_video_vline\n");
00408 split_color(color, &pixel[0], &pixel[1], &pixel[2], &pixel[3],
00409 bitmap_color_depth(screen));
00410 vid = bmp->extra;
00411
00412 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00413
00414 if (is_sub_bitmap(bmp)) {
00415 x += bmp->x_ofs;
00416 y1 += bmp->y_ofs;
00417 y2 += bmp->y_ofs;
00418 }
00419 if (x < bmp->cl || x >= bmp->cr) {
00420 return;
00421 }
00422
00423 if (y1 > y2) {
00424 int temp = y1;
00425 y1 = y2;
00426 y2 = temp;
00427 }
00428
00429 if (y1 < bmp->ct) {
00430 y1 = bmp->ct;
00431 }
00432 if (y2 >= bmp->cb) {
00433 y2 = bmp->cb - 1;
00434 }
00435
00436 while (vid) {
00437 BITMAP *vbmp = vid->memory_copy;
00438
00439 int _y1, _y2, _x;
00440 if (vid->x_ofs > x || vid->y_ofs > y2
00441 || vid->x_ofs + vbmp->w <= x
00442 || vid->y_ofs + vbmp->h <= y1) {
00443
00444 vid = vid->next;
00445 continue;
00446 }
00447
00448 _y1 = MAX(y1, vid->y_ofs) - vid->y_ofs;
00449 _y2 = MIN(y2, vid->y_ofs + vbmp->h - 1) - vid->y_ofs;
00450 _x = x - vid->x_ofs;
00451
00452 vline(vbmp, _x, _y1, _y2,
00453 makeacol_depth(32, pixel[0], pixel[1], pixel[2], pixel[3]));
00454
00455 glPixelStorei(GL_UNPACK_ROW_LENGTH,
00456 vbmp->h > 1
00457 ? (vbmp->line[1] - vbmp->line[0]) / 4
00458 : vbmp->w);
00459
00460 glEnable(vid->target);
00461 glBindTexture(vid->target, vid->tex);
00462 glTexSubImage2D(vid->target, 0, _x, _y1, 1, _y2 - _y1 + 1, GL_RGBA,
00463 GL_UNSIGNED_BYTE, vbmp->line[_y1] + _x * 4);
00464 glBindTexture(vid->target, 0);
00465 glDisable(vid->target);
00466
00467 vid = vid->next;
00468 }
00469
00470 glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00471
00472 return;
00473 }
00474
00475
00476
00477 static void allegro_gl_video_hline(BITMAP *bmp, int x1, int y, int x2,
00478 int color) {
00479
00480 GLubyte pixel[4];
00481 AGL_VIDEO_BITMAP *vid;
00482
00483 AGL_LOG(2, "glvtable.c:allegro_gl_video_hline\n");
00484 split_color(color, &pixel[0], &pixel[1], &pixel[2], &pixel[3],
00485 bitmap_color_depth(screen));
00486 vid = bmp->extra;
00487
00488 if (is_sub_bitmap(bmp)) {
00489 x1 += bmp->x_ofs;
00490 x2 += bmp->x_ofs;
00491 y += bmp->y_ofs;
00492 }
00493
00494 if (y < bmp->ct || y >= bmp->cb) {
00495 return;
00496 }
00497
00498 if (x1 > x2) {
00499 int temp = x1;
00500 x1 = x2;
00501 x2 = temp;
00502 }
00503
00504 if (x1 < bmp->cl) {
00505 x1 = bmp->cl;
00506 }
00507 if (x2 >= bmp->cr) {
00508 x2 = bmp->cr - 1;
00509 }
00510
00511 while (vid) {
00512 BITMAP *vbmp = vid->memory_copy;
00513
00514 int _x1, _x2, _y;
00515 if (vid->y_ofs > y || vid->x_ofs > x2
00516 || vid->x_ofs + vbmp->w <= x1
00517 || vid->y_ofs + vbmp->h <= y) {
00518
00519 vid = vid->next;
00520 continue;
00521 }
00522
00523 _x1 = MAX(x1, vid->x_ofs) - vid->x_ofs;
00524 _x2 = MIN(x2, vid->x_ofs + vbmp->w - 1) - vid->x_ofs;
00525 _y = y - vid->y_ofs;
00526
00527 hline(vbmp, _x1, _y, _x2,
00528 makeacol_depth(32, pixel[0], pixel[1], pixel[2], pixel[3]));
00529
00530 glPixelStorei(GL_UNPACK_ROW_LENGTH,
00531 vbmp->h > 1
00532 ? (vbmp->line[1] - vbmp->line[0]) / 4
00533 : vbmp->w);
00534
00535 glEnable(vid->target);
00536 glBindTexture(vid->target, vid->tex);
00537 glTexSubImage2D(vid->target, 0, _x1, _y, _x2 - _x1 + 1, 1, GL_RGBA,
00538 GL_UNSIGNED_BYTE, vbmp->line[_y] + _x1 * 4);
00539 glBindTexture(vid->target, 0);
00540 glDisable(vid->target);
00541
00542 vid = vid->next;
00543 }
00544
00545 return;
00546 }
00547
00548
00549
00550 static void allegro_gl_video_line(struct BITMAP *bmp, int x1, int y1, int x2,
00551 int y2, int color) {
00552
00553
00554 do_line(bmp, x1, y1, x2, y2, color, allegro_gl_video_putpixel);
00555
00556 return;
00557 }
00558
00559
00560
00561 static void allegro_gl_video_rectfill(struct BITMAP *bmp, int x1, int y1,
00562 int x2, int y2, int color) {
00563
00564 GLubyte pixel[4];
00565 AGL_VIDEO_BITMAP *vid;
00566 GLint saved_row_length;
00567
00568 AGL_LOG(2, "glvtable.c:allegro_gl_video_rectfill\n");
00569 split_color(color, &pixel[0], &pixel[1], &pixel[2], &pixel[3],
00570 bitmap_color_depth(screen));
00571 vid = bmp->extra;
00572
00573 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00574
00575 if (is_sub_bitmap(bmp)) {
00576 x1 += bmp->x_ofs;
00577 x2 += bmp->x_ofs;
00578 y1 += bmp->y_ofs;
00579 y2 += bmp->y_ofs;
00580 }
00581
00582 if (y1 > y2) {
00583 int temp = y1;
00584 y1 = y2;
00585 y2 = temp;
00586 }
00587
00588 if (x1 > x2) {
00589 int temp = x1;
00590 x1 = x2;
00591 x2 = temp;
00592 }
00593
00594 if (x1 < bmp->cl) {
00595 x1 = bmp->cl;
00596 }
00597 if (x2 >= bmp->cr) {
00598 x2 = bmp->cr - 1;
00599 }
00600 if (y1 < bmp->ct) {
00601 y1 = bmp->ct;
00602 }
00603 if (y1 >= bmp->cb) {
00604 y1 = bmp->cb;
00605 }
00606
00607 while (vid) {
00608 BITMAP *vbmp = vid->memory_copy;
00609
00610 int _y1, _y2, _x1, _x2;
00611 if (vid->x_ofs > x2 || vid->y_ofs > y2
00612 || vid->x_ofs + vbmp->w <= x1
00613 || vid->y_ofs + vbmp->h <= y1) {
00614
00615 vid = vid->next;
00616 continue;
00617 }
00618
00619 _y1 = MAX(y1, vid->y_ofs) - vid->y_ofs;
00620 _y2 = MIN(y2, vid->y_ofs + vbmp->h - 1) - vid->y_ofs;
00621 _x1 = MAX(x1, vid->x_ofs) - vid->x_ofs;
00622 _x2 = MIN(x2, vid->x_ofs + vbmp->w - 1) - vid->x_ofs;
00623
00624 rectfill(vbmp, _x1, _y1, _x2, _y2,
00625 makeacol_depth(32, pixel[0], pixel[1], pixel[2], pixel[3]));
00626
00627 glPixelStorei(GL_UNPACK_ROW_LENGTH,
00628 vbmp->h > 1
00629 ? (vbmp->line[1] - vbmp->line[0]) / 4
00630 : vbmp->w);
00631
00632 glEnable(vid->target);
00633 glBindTexture(vid->target, vid->tex);
00634 glTexSubImage2D(vid->target, 0,
00635 _x1, _y1, _x2 - _x1 + 1, _y2 - _y1 + 1, GL_RGBA,
00636 GL_UNSIGNED_BYTE, vbmp->line[_y1] + _x1 * 4);
00637 glBindTexture(vid->target, 0);
00638 glDisable(vid->target);
00639
00640 vid = vid->next;
00641 }
00642
00643 glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00644
00645 return;
00646 }
00647
00648
00649 #if GET_ALLEGRO_VERSION() >= MAKE_VER(4, 1, 17)
00650 static void allegro_gl_video_triangle(struct BITMAP *bmp, int x1, int y1,
00651 int x2, int y2, int x3, int y3, int color)
00652 #else
00653 static int allegro_gl_video_triangle(struct BITMAP *bmp, int x1, int y1,
00654 int x2, int y2, int x3, int y3, int color)
00655 #endif
00656 {
00657 GLubyte pixel[4];
00658 AGL_VIDEO_BITMAP *vid;
00659 GLint saved_row_length;
00660 int min_y, max_y, min_x, max_x;
00661
00662 AGL_LOG(2, "glvtable.c:allegro_gl_video_triangle\n");
00663 split_color(color, &pixel[0], &pixel[1], &pixel[2], &pixel[3],
00664 bitmap_color_depth(screen));
00665 vid = bmp->extra;
00666
00667 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00668
00669 if (is_sub_bitmap(bmp)) {
00670 x1 += bmp->x_ofs;
00671 x2 += bmp->x_ofs;
00672 x3 += bmp->x_ofs;
00673 y1 += bmp->y_ofs;
00674 y2 += bmp->y_ofs;
00675 y3 += bmp->y_ofs;
00676 }
00677
00678 min_y = MIN(y1, MIN(y2, y3));
00679 min_x = MIN(x1, MIN(x2, x3));
00680 max_y = MAX(y1, MAX(y2, y3));
00681 max_x = MAX(x1, MAX(x2, x3));
00682
00683
00684 while (vid) {
00685 BITMAP *vbmp = vid->memory_copy;
00686
00687 int _y1, _y2, _x1, _x2, _x3, _y3;
00688 if (vid->x_ofs > max_x || vid->y_ofs > max_y
00689 || vid->x_ofs + vbmp->w <= min_x
00690 || vid->y_ofs + vbmp->h <= min_y) {
00691
00692 vid = vid->next;
00693 continue;
00694 }
00695
00696 _y1 = y1 - vid->y_ofs;
00697 _y2 = y2 - vid->y_ofs;
00698 _y3 = y3 - vid->y_ofs;
00699 _x1 = x1 - vid->x_ofs;
00700 _x2 = x2 - vid->x_ofs;
00701 _x3 = x3 - vid->x_ofs;
00702
00703
00704 #if GET_ALLEGRO_VERSION() < MAKE_VER(4, 1, 13)
00705 set_clip(vbmp, bmp->cl - vid->x_ofs, bmp->cr - vid->x_ofs - 1,
00706 bmp->ct - vid->y_ofs, bmp->cb - vid->y_ofs - 1);
00707 #else
00708 set_clip_rect(vbmp,
00709 bmp->cl - vid->x_ofs, bmp->cr - vid->x_ofs - 1,
00710 bmp->ct - vid->y_ofs, bmp->cb - vid->y_ofs - 1);
00711 #endif
00712
00713 triangle(vbmp, _x1, _y1, _x2, _y2, _x3, _y3,
00714 makeacol_depth(32, pixel[0], pixel[1], pixel[2], pixel[3]));
00715
00716 #if GET_ALLEGRO_VERSION() < MAKE_VER(4, 1, 13)
00717 set_clip(vbmp, 0, 0, vbmp->w - 1, vbmp->h - 1);
00718 #else
00719 set_clip_rect(vbmp, 0, 0, vbmp->w - 1, vbmp->h - 1);
00720 #endif
00721
00722 glPixelStorei(GL_UNPACK_ROW_LENGTH,
00723 vbmp->h > 1
00724 ? (vbmp->line[1] - vbmp->line[0]) / 4
00725 : vbmp->w);
00726
00727
00728
00729
00730 _y1 = MAX(0, min_y - vid->y_ofs);
00731 _y2 = MIN(vbmp->h, max_y - vid->y_ofs);
00732 _x1 = MAX(0, min_x - vid->x_ofs);
00733 _x2 = MIN(vbmp->w, max_x - vid->x_ofs);
00734
00735 glEnable(vid->target);
00736 glBindTexture(vid->target, vid->tex);
00737 glTexSubImage2D(vid->target, 0,
00738 _x1, _y1, _x2 - _x1 + 1, _y2 - _y1 + 1, GL_RGBA,
00739 GL_UNSIGNED_BYTE, vbmp->line[_y1] + _x1 * 4);
00740 glBindTexture(vid->target, 0);
00741 glDisable(vid->target);
00742
00743 vid = vid->next;
00744 }
00745
00746 glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00747
00748 #if GET_ALLEGRO_VERSION() < MAKE_VER(4, 1, 17)
00749 return 1;
00750 #endif
00751 }
00752
00753
00754
00755 void allegro_gl_video_blit_from_memory(struct BITMAP *source,
00756 struct BITMAP *dest, int source_x, int source_y,
00757 int dest_x, int dest_y, int width, int height) {
00758
00759 AGL_VIDEO_BITMAP *vid;
00760 BITMAP *dest_parent = dest;
00761 GLint saved_row_length;
00762
00763 AGL_LOG(2, "glvtable.c:allegro_gl_video_blit_from_memory\n");
00764
00765 if (is_sub_bitmap (dest)) {
00766 dest_x += dest->x_ofs;
00767 dest_y += dest->y_ofs;
00768 while (dest_parent->id & BMP_ID_SUB)
00769 dest_parent = (BITMAP *)dest_parent->extra;
00770 }
00771
00772 if (dest_x < dest->cl) {
00773 dest_x = dest->cl;
00774 }
00775 if (dest_y < dest->ct) {
00776 dest_y = dest->ct;
00777 }
00778 if (dest_x + width >= dest->cr) {
00779 width = dest->cr - dest_x;
00780 }
00781 if (dest_y + height >= dest->cb) {
00782 height = dest->cb - dest_y;
00783 }
00784 if (width < 1 || height < 1) {
00785 return;
00786 }
00787
00788 vid = dest_parent->extra;
00789
00790 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00791
00792 while (vid) {
00793 BITMAP *vbmp = vid->memory_copy;
00794
00795 int _x, _y, _w, _h;
00796 if (vid->x_ofs >= dest_x + width || vid->y_ofs >= dest_y + height
00797 || vid->x_ofs + vbmp->w <= dest_x
00798 || vid->y_ofs + vbmp->h <= dest_y) {
00799
00800 vid = vid->next;
00801 continue;
00802 }
00803
00804 _x = MAX (vid->x_ofs, dest_x) - vid->x_ofs;
00805 _w = MIN (vid->x_ofs + vbmp->w, dest_x + width)
00806 - vid->x_ofs - _x;
00807 _y = MAX (vid->y_ofs, dest_y) - vid->y_ofs;
00808 _h = MIN (vid->y_ofs + vbmp->h, dest_y + height)
00809 - vid->y_ofs - _y;
00810
00811 blit(source, vbmp, source_x + vid->x_ofs + _x - dest_x,
00812 source_y + vid->y_ofs + _y - dest_y, _x, _y, _w, _h);
00813
00814 glPixelStorei(GL_UNPACK_ROW_LENGTH,
00815 vbmp->h > 1
00816 ? (vbmp->line[1] - vbmp->line[0]) / 4
00817 : vbmp->w);
00818
00819 glEnable(vid->target);
00820 glBindTexture(vid->target, vid->tex);
00821 glTexSubImage2D(vid->target, 0, _x, _y, _w, _h,
00822 GL_RGBA, GL_UNSIGNED_BYTE, vbmp->line[_y] + _x * 4);
00823 glBindTexture(vid->target, 0);
00824 glDisable(vid->target);
00825
00826 vid = vid->next;
00827 }
00828
00829 glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00830
00831 return;
00832 }
00833
00834
00835
00836 void allegro_gl_video_blit_to_memory(struct BITMAP *source, struct BITMAP *dest,
00837 int source_x, int source_y, int dest_x, int dest_y,
00838 int width, int height) {
00839
00840 AGL_VIDEO_BITMAP *vid;
00841 BITMAP *source_parent = source;
00842
00843 AGL_LOG(2, "glvtable.c:allegro_gl_video_blit_to_memory\n");
00844
00845 if (is_sub_bitmap(source)) {
00846 source_x += source->x_ofs;
00847 source_y += source->y_ofs;
00848 while (source_parent->id & BMP_ID_SUB)
00849 source_parent = (BITMAP *)source_parent->extra;
00850 }
00851
00852 vid = source_parent->extra;
00853
00854 while (vid) {
00855 BITMAP *vbmp = vid->memory_copy;
00856
00857 blit(vbmp, dest, source_x - vbmp->x_ofs, source_y - vbmp->y_ofs,
00858 dest_x + vbmp->x_ofs, dest_y + vbmp->y_ofs,
00859 width - vbmp->x_ofs, height - vbmp->y_ofs);
00860
00861 vid = vid->next;
00862 }
00863
00864 return;
00865 }
00866
00867
00868
00869 static void allegro_gl_video_clear_to_color(BITMAP *bmp, int color) {
00870
00871 AGL_LOG(2, "glvtable.c:allegro_gl_video_clear_to_color\n");
00872
00873 allegro_gl_video_rectfill(bmp, 0, 0, bmp->w, bmp->h, color);
00874
00875 return;
00876 }
00877
00878
00879
00880 static void dummy_unwrite_bank(void)
00881 {
00882 }
00883
00884
00885
00886 static GFX_VTABLE allegro_gl_video_vtable = {
00887 0,
00888 0,
00889 dummy_unwrite_bank,
00890 NULL,
00891 allegro_gl_video_acquire,
00892 allegro_gl_video_release,
00893 NULL,
00894 allegro_gl_created_sub_bitmap,
00895 allegro_gl_video_getpixel,
00896 allegro_gl_video_putpixel,
00897 allegro_gl_video_vline,
00898 allegro_gl_video_hline,
00899 allegro_gl_video_hline,
00900 allegro_gl_video_line,
00901 #if GET_ALLEGRO_VERSION() >= MAKE_VER(4, 1, 13)
00902 allegro_gl_video_line,
00903 #endif
00904 allegro_gl_video_rectfill,
00905 allegro_gl_video_triangle,
00906 NULL,
00907 NULL,
00908 NULL,
00909 NULL,
00910 NULL,
00911 NULL,
00912 NULL,
00913 NULL,
00914 NULL,
00915 NULL,
00916 NULL,
00917 NULL,
00918 NULL,
00919 NULL,
00920 allegro_gl_video_blit_from_memory,
00921 allegro_gl_video_blit_to_memory,
00922 NULL,
00923 NULL,
00924 allegro_gl_screen_blit_to_self,
00925 allegro_gl_screen_blit_to_self,
00926 allegro_gl_screen_blit_to_self,
00927 allegro_gl_memory_blit_between_formats,
00928 NULL,
00929 allegro_gl_video_clear_to_color,
00930 NULL,
00931 #if GET_ALLEGRO_VERSION() >= MAKE_VER(4, 1, 17)
00932 NULL,
00933 NULL,
00934 NULL,
00935 NULL,
00936 _soft_polygon,
00937 _soft_rect,
00938 _soft_circle,
00939 _soft_circlefill,
00940 _soft_ellipse,
00941 _soft_ellipsefill,
00942 _soft_arc,
00943 _soft_spline,
00944 _soft_floodfill,
00945 _soft_polygon3d,
00946 _soft_polygon3d_f,
00947 _soft_triangle3d,
00948 _soft_triangle3d_f,
00949 _soft_quad3d,
00950 _soft_quad3d_f,
00951 #else
00952 NULL,
00953 NULL
00954 #endif
00955 };
00956