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_screen_vtable;
00032 static GLuint __allegro_gl_pool_texture = 0;
00033
00034 static GLuint __allegro_gl_dummy_texture = 0;
00035
00036
00045
00046
00047
00048 int __allegro_gl_make_power_of_2(int x) {
00049 x--;
00050 x |= (x >> 1);
00051 x |= (x >> 2);
00052 x |= (x >> 4);
00053 x |= (x >> 8);
00054 x |= (x >> 16);
00055 x++;
00056 return x;
00057 }
00058
00059
00060
00061 static void __allegro_gl_set_drawing_mode(void) {
00062 switch (_drawing_mode) {
00063 case DRAW_MODE_SOLID:
00064 glDisable(GL_BLEND);
00065 glDisable(GL_COLOR_LOGIC_OP);
00066 break;
00067
00068 case DRAW_MODE_TRANS:
00069 glEnable(GL_BLEND);
00070 break;
00071
00072 case DRAW_MODE_XOR:
00073 glEnable(GL_COLOR_LOGIC_OP);
00074 glLogicOp(GL_XOR);
00075 break;
00076 }
00077 }
00078
00079
00080
00081 static void __allegro_gl_unset_drawing_mode(void) {
00082 switch (_drawing_mode) {
00083 case DRAW_MODE_TRANS:
00084 glDisable(GL_BLEND);
00085 break;
00086
00087 case DRAW_MODE_XOR:
00088 glDisable(GL_LOGIC_OP);
00089 break;
00090 }
00091 }
00092
00093
00094
00095 void split_color(int color, GLubyte *r, GLubyte *g, GLubyte *b, GLubyte *a,
00096 int color_depth)
00097 {
00098 AGL_LOG(2, "glvtable.c:split_color\n");
00099 *r = getr_depth(color_depth, color);
00100 *g = getg_depth(color_depth, color);
00101 *b = getb_depth(color_depth, color);
00102 if (color_depth == 32)
00103 *a = geta_depth(color_depth, color);
00104 else
00105 *a = 255;
00106 }
00107
00108
00109
00110
00111 void allegro_gl_created_sub_bitmap(BITMAP *bmp, BITMAP *parent)
00112 {
00113 bmp->extra = parent;
00114 }
00115
00116
00117
00123 static void allegro_gl_screen_acquire(struct BITMAP *bmp) {}
00124
00125
00126
00127
00133 static void allegro_gl_screen_release(struct BITMAP *bmp) {}
00134
00135
00136
00137 static int allegro_gl_screen_getpixel(struct BITMAP *bmp, int x, int y)
00138 {
00139 GLubyte pixel[3];
00140 AGL_LOG(2, "glvtable.c:allegro_gl_screen_getpixel\n");
00141 if (bmp->clip && (x < bmp->cl || x >= bmp->cr
00142 || y < bmp->ct || y >= bmp->cb)) {
00143 return -1;
00144 }
00145 if (is_sub_bitmap(bmp)) {
00146 x += bmp->x_ofs;
00147 y += bmp->y_ofs;
00148 }
00149 glReadPixels(x, bmp->h - y - 1, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
00150
00151 return makecol_depth(bitmap_color_depth(screen),
00152 pixel[0], pixel[1], pixel[2]);
00153 }
00154
00155
00156
00157 static void allegro_gl_screen_putpixel(struct BITMAP *bmp, int x, int y,
00158 int color)
00159 {
00160 GLubyte r, g, b, a;
00161 AGL_LOG(2, "glvtable.c:allegro_gl_screen_putpixel\n");
00162 split_color(color, &r, &g, &b, &a, bitmap_color_depth(bmp));
00163 if (bmp->clip && (x < bmp->cl || x >= bmp->cr
00164 || y < bmp->ct || y >= bmp->cb)) {
00165 return;
00166 }
00167
00168 if (is_sub_bitmap(bmp)) {
00169 x += bmp->x_ofs;
00170 y += bmp->y_ofs;
00171 }
00172
00173 glColor4ub(r, g, b, a);
00174 __allegro_gl_set_drawing_mode();
00175 glBegin(GL_POINTS);
00176 glVertex2f(x, y);
00177 glEnd();
00178 __allegro_gl_unset_drawing_mode();
00179 }
00180
00181
00182
00183 static void allegro_gl_screen_vline(struct BITMAP *bmp, int x, int y1, int y2,
00184 int color)
00185 {
00186 GLubyte r, g, b, a;
00187 AGL_LOG(2, "glvtable.c:allegro_gl_screen_vline\n");
00188
00189 if (y1 > y2) {
00190 int temp = y1;
00191 y1 = y2;
00192 y2 = temp;
00193 }
00194
00195 if (bmp->clip) {
00196 if ((x < bmp->cl) || (x >= bmp->cr)) {
00197 return;
00198 }
00199 if ((y1 >= bmp->cb) || (y2 < bmp->ct)) {
00200 return;
00201 }
00202 if (y1 < bmp->ct) {
00203 y1 = bmp->ct;
00204 }
00205 if (y2 >= bmp->cb) {
00206 y2 = bmp->cb - 1;
00207 }
00208 }
00209
00210 if (is_sub_bitmap(bmp)) {
00211 x += bmp->x_ofs;
00212 y1 += bmp->y_ofs;
00213 y2 += bmp->y_ofs;
00214 }
00215
00216 split_color(color, &r, &g, &b, &a, bitmap_color_depth(bmp));
00217
00218 glColor4ub(r, g, b, a);
00219 __allegro_gl_set_drawing_mode();
00220 glBegin(GL_LINES);
00221 glVertex2f(x, y1);
00222 glVertex2f(x, y2 + 0.325 * 3);
00223 glEnd();
00224 __allegro_gl_unset_drawing_mode();
00225
00226 return;
00227 }
00228
00229
00230
00231 static void allegro_gl_screen_hline(struct BITMAP *bmp, int x1, int y, int x2,
00232 int color)
00233 {
00234 GLubyte r, g, b, a;
00235 AGL_LOG(2, "glvtable.c:allegro_gl_hline\n");
00236
00237 if (x1 > x2) {
00238 int temp = x1;
00239 x1 = x2;
00240 x2 = temp;
00241 }
00242 if (bmp->clip) {
00243 if ((y < bmp->ct) || (y >= bmp->cb)) {
00244 return;
00245 }
00246 if ((x1 >= bmp->cr) || (x2 < bmp->cl)) {
00247 return;
00248 }
00249 if (x1 < bmp->cl) {
00250 x1 = bmp->cl;
00251 }
00252 if (x2 >= bmp->cr) {
00253 x2 = bmp->cr - 1;
00254 }
00255 }
00256 if (is_sub_bitmap(bmp)) {
00257 x1 += bmp->x_ofs;
00258 x2 += bmp->x_ofs;
00259 y += bmp->y_ofs;
00260 }
00261
00262 split_color(color, &r, &g, &b, &a, bitmap_color_depth(bmp));
00263
00264 glColor4ub(r, g, b, a);
00265 __allegro_gl_set_drawing_mode();
00266 glBegin(GL_LINES);
00267 glVertex2f(x1 - 0.325, y);
00268 glVertex2f(x2 + 0.325 * 2, y);
00269 glEnd();
00270 __allegro_gl_unset_drawing_mode();
00271
00272 return;
00273 }
00274
00275
00276
00277 static void allegro_gl_screen_line(struct BITMAP *bmp, int x1, int y1, int x2,
00278 int y2, int color)
00279 {
00280 GLubyte r, g, b, a;
00281 AGL_LOG(2, "glvtable.c:allegro_gl_screen_line\n");
00282
00283 if (bmp->clip) {
00284 glPushAttrib(GL_SCISSOR_BIT);
00285 glEnable(GL_SCISSOR_TEST);
00286 glScissor(bmp->x_ofs + bmp->cl, SCREEN_H - bmp->y_ofs - bmp->cb,
00287 bmp->cr - bmp->cl, bmp->cb - bmp->ct);
00288 }
00289 if (is_sub_bitmap(bmp)) {
00290 x1 += bmp->x_ofs;
00291 x2 += bmp->x_ofs;
00292 y1 += bmp->y_ofs;
00293 y2 += bmp->y_ofs;
00294 }
00295
00296 split_color(color, &r, &g, &b, &a, bitmap_color_depth(bmp));
00297
00298 glColor4ub(r, g, b, a);
00299 __allegro_gl_set_drawing_mode();
00300 glBegin(GL_LINES);
00301 glVertex2f(x1 + 0.1625, y1 + 0.1625);
00302 glVertex2f(x2 + 0.1625, y2 + 0.1625);
00303 glEnd();
00304
00305
00306 glBegin(GL_POINTS);
00307 glVertex2f(x2 + 0.1625, y2 + 0.1625);
00308 glEnd();
00309 __allegro_gl_unset_drawing_mode();
00310
00311 if (bmp->clip) {
00312 glPopAttrib();
00313 }
00314
00315 return;
00316 }
00317
00318
00319
00320 static void allegro_gl_screen_rectfill(struct BITMAP *bmp, int x1, int y1,
00321 int x2, int y2, int color)
00322 {
00323 GLubyte r, g, b, a;
00324 AGL_LOG(2, "glvtable.c:allegro_gl_screen_rectfill\n");
00325
00326 if (x1 > x2) {
00327 int temp = x1;
00328 x1 = x2;
00329 x2 = temp;
00330 }
00331
00332 if (y1 > y2) {
00333 int temp = y1;
00334 y1 = y2;
00335 y2 = temp;
00336 }
00337
00338 if (bmp->clip) {
00339 if ((x1 >= bmp->cr) || (x2 < bmp->cl)) {
00340 return;
00341 }
00342 if (x1 < bmp->cl) {
00343 x1 = bmp->cl;
00344 }
00345 if (x2 >= bmp->cr) {
00346 x2 = bmp->cr - 1;
00347 }
00348 if ((y1 >= bmp->cb) || (y2 < bmp->ct)) {
00349 return;
00350 }
00351 if (y1 < bmp->ct) {
00352 y1 = bmp->ct;
00353 }
00354 if (y2 >= bmp->cb) {
00355 y2 = bmp->cb - 1;
00356 }
00357 }
00358 if (is_sub_bitmap(bmp)) {
00359 x1 += bmp->x_ofs;
00360 x2 += bmp->x_ofs;
00361 y1 += bmp->y_ofs;
00362 y2 += bmp->y_ofs;
00363 }
00364
00365 split_color(color, &r, &g, &b, &a, bitmap_color_depth(bmp));
00366 glColor4ub(r, g, b, a);
00367 __allegro_gl_set_drawing_mode();
00368 glRecti(x1, y2, x2, y1);
00369 __allegro_gl_unset_drawing_mode();
00370
00371 return;
00372 }
00373
00374
00375
00376 static void allegro_gl_screen_triangle(struct BITMAP *bmp, int x1, int y1,
00377 int x2, int y2, int x3, int y3, int color)
00378 {
00379 GLubyte r, g, b, a;
00380 AGL_LOG(2, "glvtable.c:allegro_gl_screen_triangle\n");
00381
00382 split_color(color, &r, &g, &b, &a, bitmap_color_depth(bmp));
00383
00384 if (bmp->clip) {
00385 glPushAttrib(GL_SCISSOR_BIT);
00386 glEnable(GL_SCISSOR_TEST);
00387 glScissor(bmp->x_ofs + bmp->cl, SCREEN_H - bmp->y_ofs - bmp->cb,
00388 bmp->cr - bmp->cl, bmp->cb - bmp->ct);
00389 }
00390 if (is_sub_bitmap(bmp)) {
00391 x1 += bmp->x_ofs;
00392 y1 += bmp->y_ofs;
00393 x2 += bmp->x_ofs;
00394 y2 += bmp->y_ofs;
00395 x3 += bmp->x_ofs;
00396 y3 += bmp->y_ofs;
00397 }
00398
00399 glColor4ub(r, g, b, a);
00400 __allegro_gl_set_drawing_mode();
00401 glBegin(GL_TRIANGLES);
00402 glVertex2f(x1, y1);
00403 glVertex2f(x2, y2);
00404 glVertex2f(x3, y3);
00405 glEnd();
00406 __allegro_gl_unset_drawing_mode();
00407
00408 if (bmp->clip) {
00409 glPopAttrib();
00410 }
00411 }
00412
00413
00414
00415 #define BITMAP_BLIT_CLIP(source, dest, source_x, source_y, dest_x, dest_y, \
00416 width, height) { \
00417 if (dest->clip) { \
00418 if ((dest_x >= dest->cr) || (dest_y >= dest->cb) \
00419 || (dest_x + width < dest->cl) || (dest_y + height < dest->ct)) { \
00420 width = 0; \
00421 } \
00422 if (dest_x < dest->cl) { \
00423 width += dest_x - dest->cl; \
00424 source_x -= dest_x - dest->cl; \
00425 dest_x = dest->cl; \
00426 } \
00427 if (dest_y < dest->ct) { \
00428 height += dest_y - dest->ct; \
00429 source_y -= dest_y - dest->ct; \
00430 dest_y = dest->ct; \
00431 } \
00432 if (dest_x + width > dest->cr) { \
00433 width = dest->cr - dest_x; \
00434 } \
00435 if (dest_y + height > dest->cb) { \
00436 height = dest->cb - dest_y; \
00437 } \
00438 } \
00439 if (source->clip) { \
00440 if ((source_x >= source->cr) || (source_y >= source->cb) \
00441 || (source_x + width < source->cl) \
00442 || (source_y + height < source->ct)) { \
00443 width = 0; \
00444 } \
00445 if (source_x < source->cl) { \
00446 width += source_x - source->cl; \
00447 dest_x -= source_x - source->cl; \
00448 source_x = source->cl; \
00449 } \
00450 if (source_y < source->ct) { \
00451 height += source_y - source->ct; \
00452 dest_y -= source_y - source->ct; \
00453 source_y = source->ct; \
00454 } \
00455 if (source_x + width > source->cr) { \
00456 width = source->cr - source_x; \
00457 } \
00458 if (source_y + height > source->cb) { \
00459 height = source->cb - source_y; \
00460 } \
00461 } \
00462 }
00463
00464
00465
00466
00467 static void allegro_gl_screen_blit_from_memory(
00468 struct BITMAP *source, struct BITMAP *dest,
00469 int source_x, int source_y, int dest_x, int dest_y, int width, int height)
00470 {
00471 GLfloat saved_zoom_x, saved_zoom_y;
00472 GLint saved_row_length;
00473 BITMAP *temp = NULL;
00474 void *data;
00475 AGL_LOG(2, "glvtable.c:allegro_gl_screen_blit_from_memory\n");
00476
00477 BITMAP_BLIT_CLIP(source, dest, source_x, source_y, dest_x, dest_y,
00478 width, height);
00479
00480 if (width <= 0 || height <= 0) {
00481 return;
00482 }
00483
00484
00485 if (is_sub_bitmap(dest)) {
00486 dest_x += dest->x_ofs;
00487 dest_y += dest->y_ofs;
00488 }
00489
00490
00491
00492
00493
00494 data = source->line[source_y]
00495 + source_x * BYTES_PER_PIXEL(bitmap_color_depth(source));
00496
00497
00498
00499
00500 if (!allegro_gl_extensions_GL.EXT_packed_pixels
00501 && bitmap_color_depth(source) < 24) {
00502 temp = create_bitmap_ex(24, width, height);
00503
00504 if (temp) {
00505 blit(source, temp, source_x, source_y, 0, 0, width, height);
00506 source_x = 0;
00507 source_y = 0;
00508 data = temp->line[0];
00509 }
00510 else {
00511
00512 return;
00513 }
00514 source = temp;
00515 }
00516
00517
00518
00519 glGetFloatv(GL_ZOOM_X, &saved_zoom_x);
00520 glGetFloatv(GL_ZOOM_Y, &saved_zoom_y);
00521 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00522
00523 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00524
00525 glRasterPos2i(dest_x, dest_y);
00526
00527
00528
00529
00530 glPixelZoom (1.0, -1.0);
00531 glPixelStorei(GL_UNPACK_ROW_LENGTH,
00532 (source->line[1] - source->line[0])
00533 / BYTES_PER_PIXEL(source->vtable->color_depth));
00534
00535 glDrawPixels(width, height, __allegro_gl_get_bitmap_color_format(source, 0),
00536 __allegro_gl_get_bitmap_type(source, 0), data);
00537
00538
00539 glPixelZoom(saved_zoom_x, saved_zoom_y);
00540 glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00541
00542 if (temp) {
00543 destroy_bitmap(temp);
00544 }
00545 return;
00546 }
00547
00548
00549
00550 static void allegro_gl_screen_blit_to_memory(
00551 struct BITMAP *source, struct BITMAP *dest,
00552 int source_x, int source_y, int dest_x, int dest_y, int width, int height)
00553 {
00554 GLint saved_row_length;
00555 GLint saved_alignment;
00556 GLint saved_pack_invert;
00557
00558 BITMAP *bmp = NULL;
00559
00560 AGL_LOG(2, "glvtable.c:allegro_gl_screen_blit_to_memory\n");
00561
00562 BITMAP_BLIT_CLIP(source, dest, source_x, source_y, dest_x, dest_y,
00563 width, height);
00564
00565 if (is_sub_bitmap(source)) {
00566 source_x += source->x_ofs;
00567 source_y += source->y_ofs;
00568 }
00569 if (is_sub_bitmap(dest)) {
00570 dest_x += dest->x_ofs;
00571 dest_y += dest->y_ofs;
00572 }
00573
00574 if (width <= 0 || height <= 0) {
00575 return;
00576 }
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 if ( !allegro_gl_extensions_GL.MESA_pack_invert
00588 || (!allegro_gl_extensions_GL.EXT_packed_pixels
00589 && bitmap_color_depth(dest) < 24)) {
00590
00591
00592
00593
00594 if ((!allegro_gl_extensions_GL.EXT_packed_pixels
00595 && bitmap_color_depth(dest) < 24)) {
00596 bmp = create_bitmap_ex(24, width, height);
00597 }
00598 else {
00599 bmp = create_bitmap_ex(bitmap_color_depth(dest), width, height);
00600 }
00601 if (!bmp)
00602 return;
00603 }
00604
00605 glGetIntegerv(GL_PACK_ROW_LENGTH, &saved_row_length);
00606 glGetIntegerv(GL_PACK_ALIGNMENT, &saved_alignment);
00607 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
00608 glPixelStorei(GL_PACK_ALIGNMENT, 1);
00609
00610 if (!allegro_gl_extensions_GL.MESA_pack_invert) {
00611
00612 glReadPixels(source_x, source->h - source_y - height, width, height,
00613 __allegro_gl_get_bitmap_color_format(bmp, 0),
00614 __allegro_gl_get_bitmap_type(bmp, 0), bmp->dat);
00615 }
00616 else {
00617 glGetIntegerv(GL_PACK_INVERT_MESA, &saved_pack_invert);
00618 glPixelStorei(GL_PACK_INVERT_MESA, TRUE);
00619 glPixelStorei(GL_PACK_ROW_LENGTH,
00620 (dest->line[1] - dest->line[0])
00621 / BYTES_PER_PIXEL(dest->vtable->color_depth));
00622
00623 glReadPixels(source_x, source->h - source_y - height, width, height,
00624 __allegro_gl_get_bitmap_color_format(dest, 0),
00625 __allegro_gl_get_bitmap_type(dest, 0), dest->line[0]);
00626
00627 glPixelStorei(GL_PACK_INVERT_MESA, saved_pack_invert);
00628 }
00629
00630 glPixelStorei(GL_PACK_ROW_LENGTH, saved_row_length);
00631 glPixelStorei(GL_PACK_ALIGNMENT, saved_alignment);
00632
00633
00634 if (bmp) {
00635
00636 int y, dy;
00637
00638 for (y = 0, dy = dest_y + height - 1; y < height; y++, dy--) {
00639 blit(bmp, dest, 0, y, dest_x, dy, width, 1);
00640 }
00641
00642 destroy_bitmap(bmp);
00643 }
00644
00645 return;
00646 }
00647
00648
00649
00650
00651 void allegro_gl_screen_blit_to_self (
00652 struct BITMAP *source, struct BITMAP *dest,
00653 int source_x, int source_y, int dest_x, int dest_y, int width, int height)
00654 {
00655 AGL_LOG(2, "glvtable.c:allegro_gl_screen_blit_to_self\n");
00656
00657 BITMAP_BLIT_CLIP(source, dest, source_x, source_y, dest_x, dest_y,
00658 width, height);
00659
00660 if (is_sub_bitmap(source)) {
00661 source_x += source->x_ofs;
00662 source_y += source->y_ofs;
00663 }
00664 if (is_sub_bitmap(dest)) {
00665 dest_x += dest->x_ofs;
00666 dest_y += dest->y_ofs;
00667 }
00668
00669 if (width <= 0 || height <= 0) {
00670 return;
00671 }
00672
00673
00674 if (is_screen_bitmap(source) && is_screen_bitmap(dest)) {
00675 glRasterPos2i(dest_x, dest_y + height - 1);
00676 glCopyPixels(source_x, SCREEN_H - source_y - height, width, height,
00677 GL_COLOR);
00678 }
00679
00680 else if (is_screen_bitmap(dest) && is_video_bitmap(source)) {
00681 AGL_VIDEO_BITMAP *vid;
00682 BITMAP *source_parent = source;
00683 GLfloat current_color[4];
00684
00685 while (source_parent->id & BMP_ID_SUB) {
00686 source_parent = (BITMAP *)source_parent->extra;
00687 }
00688 vid = source_parent->extra;
00689
00690 glGetFloatv(GL_CURRENT_COLOR, current_color);
00691 glColor4ub(255, 255, 255, 255);
00692
00693 while (vid) {
00694 int sx, sy;
00695 int dx, dy;
00696 int w, h;
00697
00698 if (source_x >= vid->x_ofs + vid->memory_copy->w ||
00699 source_y >= vid->y_ofs + vid->memory_copy->h ||
00700 vid->x_ofs >= source_x + width ||
00701 vid->y_ofs >= source_y + height) {
00702 vid = vid->next;
00703 continue;
00704 }
00705
00706 sx = MAX(vid->x_ofs, source_x) - vid->x_ofs;
00707 w = MIN(vid->x_ofs + vid->memory_copy->w, source_x + width)
00708 - vid->x_ofs - sx;
00709 sy = MAX(vid->y_ofs, source_y) - vid->y_ofs;
00710 h = MIN(vid->y_ofs + vid->memory_copy->h, source_y + height)
00711 - vid->y_ofs - sy;
00712
00713 dx = dest_x + vid->x_ofs + sx - source_x;
00714 dy = dest_y + vid->y_ofs + sy - source_y;
00715
00716 glEnable(vid->target);
00717 glBindTexture(vid->target, vid->tex);
00718
00719 if (vid->target == GL_TEXTURE_2D) {
00720 float tx = sx / (float)vid->memory_copy->w;
00721 float ty = sy / (float)vid->memory_copy->h;
00722 float tw = w / (float)vid->memory_copy->w;
00723 float th = h / (float)vid->memory_copy->h;
00724
00725 glBegin(GL_QUADS);
00726 glTexCoord2f(tx, ty);
00727 glVertex2f(dx, dy);
00728 glTexCoord2f(tx, ty + th);
00729 glVertex2f(dx, dy + h);
00730 glTexCoord2f(tx + tw, ty + th);
00731 glVertex2f(dx + w, dy + h);
00732 glTexCoord2f(tx + tw, ty);
00733 glVertex2f(dx + w, dy);
00734 glEnd();
00735 }
00736 else {
00737 glBegin(GL_QUADS);
00738 glTexCoord2i(sx, sy);
00739 glVertex2f(dx, dy);
00740 glTexCoord2i(sx, sy + h);
00741 glVertex2f(dx, dy + h);
00742 glTexCoord2i(sx + w, sy + h);
00743 glVertex2f(dx + w, dy + h);
00744 glTexCoord2i(sx + w, sy);
00745 glVertex2f(dx + w, dy);
00746 glEnd();
00747 }
00748
00749 glBindTexture(vid->target, 0);
00750 glDisable(vid->target);
00751
00752 vid = vid->next;
00753 }
00754
00755 glColor4fv(current_color);
00756 }
00757
00758 else if (is_screen_bitmap(source) && is_video_bitmap(dest)) {
00759
00760 AGL_VIDEO_BITMAP *vid;
00761 BITMAP *source_parent = source;
00762
00763 while (source_parent->id & BMP_ID_SUB) {
00764 source_parent = (BITMAP *)source_parent->extra;
00765 }
00766
00767 vid = dest->extra;
00768
00769 while (vid) {
00770 int sx, sy;
00771 int dx, dy;
00772 int w, h;
00773
00774 if (dest_x >= vid->x_ofs + vid->memory_copy->w ||
00775 dest_y >= vid->y_ofs + vid->memory_copy->h ||
00776 vid->x_ofs >= dest_x + width ||
00777 vid->y_ofs >= dest_y + height) {
00778 vid = vid->next;
00779 continue;
00780 }
00781
00782 dx = MAX(vid->x_ofs, dest_x) - vid->x_ofs;
00783 w = MIN(vid->x_ofs + vid->memory_copy->w, dest_x + width)
00784 - vid->x_ofs - dx;
00785 dy = MAX(vid->y_ofs, dest_y) - vid->y_ofs;
00786 h = MIN(vid->y_ofs + vid->memory_copy->h, dest_y + height)
00787 - vid->y_ofs - dy;
00788
00789 sx = source_x + vid->x_ofs + dx - dest_x;
00790 sy = source_y + vid->y_ofs + dy - dest_y;
00791
00792
00793 allegro_gl_screen_blit_to_memory(source, vid->memory_copy,
00794 sx, sy, dx, dy, w, h);
00795
00796 allegro_gl_video_blit_from_memory(vid->memory_copy, dest, 0, 0,
00797 vid->x_ofs, vid->y_ofs, vid->memory_copy->w, vid->memory_copy->h);
00798
00799 vid = vid->next;
00800 }
00801 }
00802 else if (is_video_bitmap(source) && is_video_bitmap(dest)) {
00803 allegro_gl_video_blit_to_self(source, dest, source_x, source_y,
00804 dest_x, dest_y, width, height);
00805 }
00806 }
00807
00808
00809
00810 void allegro_gl_upload_and_display_texture(struct BITMAP *source,
00811 int source_x, int source_y, int dest_x, int dest_y, int width, int height,
00812 int flip_dir, GLint format, GLint type)
00813 {
00814 float tx, ty;
00815 GLint saved_row_length;
00816 int bytes_per_pixel = BYTES_PER_PIXEL(bitmap_color_depth(source));
00817 int i, j;
00818
00819 glEnable(GL_ALPHA_TEST);
00820 glAlphaFunc(GL_GREATER, 0.0f);
00821
00822 glEnable(GL_TEXTURE_2D);
00823 glBindTexture(GL_TEXTURE_2D, __allegro_gl_pool_texture);
00824
00825 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00826 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00827
00828 glPixelStorei(GL_UNPACK_ROW_LENGTH,
00829 (source->line[1] - source->line[0]) / bytes_per_pixel);
00830
00831 for (i = 0; i <= abs(width) / 256; i++) {
00832 for (j = 0; j <= abs(height) / 256; j++) {
00833
00834 void *data = source->line[source_y + j * 256]
00835 + (source_x + i * 256) * bytes_per_pixel;
00836 int w = abs(width) - i * 256;
00837 int h = abs(height) - j * 256;
00838 int dx = dest_x + i * 256;
00839 int dy = dest_y + j * 256;
00840
00841 w = (w & -256) ? 256 : w;
00842 h = (h & -256) ? 256 : h;
00843
00844 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, type, data);
00845
00846 tx = (float)w / 256.;
00847 ty = (float)h / 256.;
00848
00849 if (flip_dir & AGL_H_FLIP) {
00850 dx = 2*dest_x + width - dx;
00851 w = -w;
00852 }
00853
00854 if (flip_dir & AGL_V_FLIP) {
00855 dy = 2*dest_y + height - dy;
00856 h = -h;
00857 }
00858
00859 if (width < 0) w = -w;
00860 if (height < 0) h = -h;
00861
00862 glBegin(GL_QUADS);
00863 glTexCoord2f(0., 0.);
00864 glVertex2i(dx, dy);
00865 glTexCoord2f(0., ty);
00866 glVertex2i(dx, dy + h);
00867 glTexCoord2f(tx, ty);
00868 glVertex2i(dx + w, dy + h);
00869 glTexCoord2f(tx, 0.);
00870 glVertex2i(dx + w, dy);
00871 glEnd();
00872 }
00873 }
00874
00875
00876 glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00877 glBindTexture(GL_TEXTURE_2D, 0);
00878 glDisable(GL_TEXTURE_2D);
00879 glDisable(GL_ALPHA_TEST);
00880
00881 return;
00882 }
00883
00884
00885
00886 static void do_screen_masked_blit_standard(GLint format, GLint type, struct BITMAP *temp, int source_x, int source_y, int dest_x, int dest_y, int width, int height, int flip_dir, int blit_type)
00887 {
00888 glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT);
00889
00890 if (blit_type & AGL_NO_ROTATION) {
00891 GLint saved_row_length;
00892 float dx = dest_x, dy = dest_y;
00893 GLfloat zoom_x, zoom_y, old_zoom_x, old_zoom_y;
00894
00895 glEnable(GL_ALPHA_TEST);
00896 glAlphaFunc(GL_GREATER, 0.0f);
00897
00898 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00899 glGetFloatv(GL_ZOOM_X, &old_zoom_x);
00900 glGetFloatv(GL_ZOOM_Y, &old_zoom_y);
00901
00902 if (flip_dir & AGL_H_FLIP) {
00903 zoom_x = -1.0f;
00904
00905
00906 dx += abs(width) - 0.5;
00907 }
00908 else {
00909 zoom_x = (float) width / abs(width);
00910 }
00911
00912 if (flip_dir & AGL_V_FLIP) {
00913 zoom_y = 1.0f;
00914 dy += abs(height) - 0.5;
00915 }
00916 else {
00917 zoom_y = -1.0f * width / abs(width);
00918 }
00919
00920 glRasterPos2f(dx, dy);
00921 glPixelZoom(zoom_x, zoom_y);
00922 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00923 glPixelStorei(GL_UNPACK_ROW_LENGTH,
00924 (temp->line[1] - temp->line[0])
00925 / BYTES_PER_PIXEL(bitmap_color_depth(temp)));
00926
00927 glDrawPixels(abs(width), abs(height), format, type, temp->line[0]);
00928
00929 glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00930 glPixelZoom(old_zoom_x, old_zoom_y);
00931 }
00932 else {
00933 allegro_gl_upload_and_display_texture(temp, 0, 0, dest_x, dest_y, width, height,
00934 flip_dir, format, type);
00935 }
00936
00937 glPopAttrib();
00938 }
00939
00940
00941
00942 static void screen_masked_blit_standard(struct BITMAP *source,
00943 int source_x, int source_y, int dest_x, int dest_y, int width, int height,
00944 int flip_dir, int blit_type)
00945 {
00946 BITMAP *temp = NULL;
00947
00948 GLint format, type;
00949
00950 format = __allegro_gl_get_bitmap_color_format(source, AGL_TEXTURE_MASKED);
00951 type = __allegro_gl_get_bitmap_type(source, AGL_TEXTURE_MASKED);
00952
00953 temp = __allegro_gl_munge_bitmap(AGL_TEXTURE_MASKED, source,
00954 source_x, source_y, abs(width), abs(height),
00955 &type, &format);
00956
00957 if (temp) {
00958 source = temp;
00959 }
00960
00961 do_screen_masked_blit_standard(format, type, source, source_x, source_y,
00962 dest_x, dest_y, width, height, flip_dir, blit_type);
00963
00964 if (temp) {
00965 destroy_bitmap(temp);
00966 }
00967
00968 return;
00969 }
00970
00971
00972
00973 static void __allegro_gl_init_nv_register_combiners(BITMAP *bmp)
00974 {
00975 GLfloat mask_color[4];
00976 int depth = bitmap_color_depth(bmp);
00977 int color = bitmap_mask_color(bmp);
00978
00979 mask_color[0] = getr_depth(depth, color) / 255.;
00980 mask_color[1] = getg_depth(depth, color) / 255.;
00981 mask_color[2] = getb_depth(depth, color) / 255.;
00982 mask_color[3] = 0.;
00983
00984 glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, mask_color);
00985 glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 2);
00986 glEnable(GL_REGISTER_COMBINERS_NV);
00987
00988 glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV,
00989 GL_TEXTURE0_ARB, GL_SIGNED_IDENTITY_NV, GL_RGB);
00990 glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV,
00991 GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
00992 glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV,
00993 GL_CONSTANT_COLOR0_NV, GL_SIGNED_IDENTITY_NV, GL_RGB);
00994 glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV,
00995 GL_ZERO, GL_EXPAND_NORMAL_NV, GL_RGB);
00996 glCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, GL_DISCARD_NV,
00997 GL_DISCARD_NV, GL_SPARE0_NV, GL_NONE, GL_NONE,
00998 GL_FALSE, GL_FALSE, GL_FALSE);
00999
01000 glCombinerInputNV(GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV,
01001 GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_RGB);
01002 glCombinerInputNV(GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV,
01003 GL_SPARE0_NV, GL_SIGNED_IDENTITY_NV, GL_RGB);
01004 glCombinerOutputNV(GL_COMBINER1_NV, GL_RGB, GL_SPARE1_NV,
01005 GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
01006 GL_TRUE, GL_FALSE, GL_FALSE);
01007
01008 glFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_TEXTURE0_ARB,
01009 GL_UNSIGNED_IDENTITY_NV, GL_RGB);
01010 glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_ZERO,
01011 GL_UNSIGNED_INVERT_NV, GL_RGB);
01012 glFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_ZERO,
01013 GL_UNSIGNED_IDENTITY_NV, GL_RGB);
01014 glFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_ZERO,
01015 GL_UNSIGNED_IDENTITY_NV, GL_RGB);
01016 glFinalCombinerInputNV(GL_VARIABLE_G_NV, GL_SPARE1_NV,
01017 GL_UNSIGNED_IDENTITY_NV, GL_BLUE);
01018
01019 return;
01020 }
01021
01022
01023
01024 static void screen_masked_blit_nv_register(struct BITMAP *source,
01025 int source_x, int source_y, int dest_x, int dest_y, int width, int height,
01026 int flip_dir, int blit_type)
01027 {
01028 BITMAP *temp = NULL;
01029 GLint type = __allegro_gl_get_bitmap_type(source, 0);
01030 GLint format = __allegro_gl_get_bitmap_color_format(source, 0);
01031
01032 if (type == -1) {
01033 temp = create_bitmap_ex(24, width, height);
01034 if (!temp) {
01035 return;
01036 }
01037 blit(source, temp, source_x, source_y, 0, 0, width, height);
01038 source = temp;
01039 source_x = 0;
01040 source_y = 0;
01041
01042 type = __allegro_gl_get_bitmap_type(source, 0);
01043 format = __allegro_gl_get_bitmap_color_format(source, 0);
01044 }
01045
01046 glPushAttrib(GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT);
01047 __allegro_gl_init_nv_register_combiners(source);
01048
01049 allegro_gl_upload_and_display_texture(source, source_x, source_y, dest_x, dest_y,
01050 width, height, flip_dir, format, type);
01051
01052 glPopAttrib();
01053
01054 if (temp) {
01055 destroy_bitmap(temp);
01056 }
01057 return;
01058 }
01059
01060
01061
01062 static void __allegro_gl_init_combine_textures(BITMAP *bmp)
01063 {
01064 GLubyte mask_color[4];
01065
01066 split_color(bitmap_mask_color(bmp), &mask_color[0], &mask_color[1],
01067 &mask_color[2], &mask_color[3], bitmap_color_depth(bmp));
01068 glColor4ubv(mask_color);
01069
01070 glActiveTexture(GL_TEXTURE0);
01071 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
01072 glEnable(GL_TEXTURE_2D);
01073 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
01074 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
01075 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PRIMARY_COLOR);
01076 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_ONE_MINUS_SRC_COLOR);
01077
01078
01079
01080
01081
01082 glActiveTexture(GL_TEXTURE1);
01083 glEnable(GL_TEXTURE_2D);
01084 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
01085 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGBA_ARB);
01086 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
01087 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
01088
01089
01090
01091 glActiveTexture(GL_TEXTURE2);
01092 glEnable(GL_TEXTURE_2D);
01093 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
01094 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
01095 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
01096 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
01097 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
01098
01099 glActiveTexture(GL_TEXTURE0);
01100
01101 return;
01102 }
01103
01104
01105
01106 static void screen_masked_blit_combine_tex(struct BITMAP *source,
01107 int source_x, int source_y, int dest_x, int dest_y, int width, int height,
01108 int flip_dir, int blit_type)
01109 {
01110 float tx, ty;
01111 BITMAP *temp = NULL;
01112 GLint saved_row_length;
01113 GLint type = __allegro_gl_get_bitmap_type(source, 0);
01114 GLint format = __allegro_gl_get_bitmap_color_format(source, 0);
01115 int bytes_per_pixel;
01116 int i, j;
01117 GLfloat current_color[4];
01118
01119 if (type == -1) {
01120 temp = create_bitmap_ex(24, width, height);
01121 if (!temp)
01122 return;
01123 blit(source, temp, source_x, source_y, 0, 0, width, height);
01124 source = temp;
01125 source_x = 0;
01126 source_y = 0;
01127
01128 type = __allegro_gl_get_bitmap_type(source, 0);
01129 format = __allegro_gl_get_bitmap_color_format(source, 0);
01130 }
01131
01132 glEnable(GL_TEXTURE_2D);
01133 glBindTexture(GL_TEXTURE_2D, __allegro_gl_pool_texture);
01134
01135 glPushAttrib(GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT);
01136 glGetFloatv(GL_CURRENT_COLOR, current_color);
01137 __allegro_gl_init_combine_textures(source);
01138
01139 glActiveTexture(GL_TEXTURE0);
01140 glBindTexture(GL_TEXTURE_2D, __allegro_gl_pool_texture);
01141 glActiveTexture(GL_TEXTURE1);
01142 glBindTexture(GL_TEXTURE_2D, __allegro_gl_pool_texture);
01143 glActiveTexture(GL_TEXTURE2);
01144 glBindTexture(GL_TEXTURE_2D, __allegro_gl_pool_texture);
01145 glActiveTexture(GL_TEXTURE0);
01146
01147 bytes_per_pixel = BYTES_PER_PIXEL(bitmap_color_depth(source));
01148
01149 glEnable(GL_ALPHA_TEST);
01150 glAlphaFunc(GL_GREATER, 0.0f);
01151
01152 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
01153 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
01154
01155 glPixelStorei(GL_UNPACK_ROW_LENGTH,
01156 (source->line[1] - source->line[0]) / bytes_per_pixel);
01157
01158 for (i = 0; i <= width / 256; i++) {
01159 for (j = 0; j <= height / 256; j++) {
01160
01161 void *data = source->line[source_y + j * 256]
01162 + (source_x + i * 256) * bytes_per_pixel;
01163 int w = width - i * 256;
01164 int h = height - j * 256;
01165 int dx = dest_x + i * 256;
01166 int dy = dest_y + j * 256;
01167
01168 w = (w & -256) ? 256 : w;
01169 h = (h & -256) ? 256 : h;
01170
01171 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, type, data);
01172
01173 tx = (float)w / 256.;
01174 ty = (float)h / 256.;
01175
01176 if (flip_dir & AGL_H_FLIP) {
01177 dx = 2*dest_x + width - dx;
01178 w = -w;
01179 }
01180
01181 if (flip_dir & AGL_V_FLIP) {
01182 dy = 2*dest_y + height - dy;
01183 h = -h;
01184 }
01185
01186 glBegin(GL_QUADS);
01187 glMultiTexCoord2f(GL_TEXTURE0, 0., 0.);
01188 glMultiTexCoord2f(GL_TEXTURE1, 0., 0.);
01189 glMultiTexCoord2f(GL_TEXTURE2, 0., 0.);
01190 glVertex2f(dx, dy);
01191 glMultiTexCoord2f(GL_TEXTURE0, 0., ty);
01192 glMultiTexCoord2f(GL_TEXTURE1, 0., ty);
01193 glMultiTexCoord2f(GL_TEXTURE2, 0., ty);
01194 glVertex2f(dx, dy + h);
01195 glMultiTexCoord2f(GL_TEXTURE0, tx, ty);
01196 glMultiTexCoord2f(GL_TEXTURE1, tx, ty);
01197 glMultiTexCoord2f(GL_TEXTURE2, tx, ty);
01198 glVertex2f(dx + w, dy + h);
01199 glMultiTexCoord2f(GL_TEXTURE0, tx, 0.);
01200 glMultiTexCoord2f(GL_TEXTURE1, tx, 0.);
01201 glMultiTexCoord2f(GL_TEXTURE2, tx, 0.);
01202 glVertex2f(dx + w, dy);
01203 glEnd();
01204 }
01205 }
01206
01207
01208 glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
01209 glBindTexture(GL_TEXTURE_2D, 0);
01210 glDisable(GL_TEXTURE_2D);
01211 glPopAttrib();
01212 glColor4fv(current_color);
01213
01214 if (temp) {
01215 destroy_bitmap(temp);
01216 }
01217
01218 return;
01219 }
01220
01221
01222
01223 void do_masked_blit_screen(struct BITMAP *source, struct BITMAP *dest,
01224 int source_x, int source_y, int dest_x, int dest_y, int width, int height,
01225 int flip_dir, int blit_type)
01226 {
01227
01228
01229
01230
01231
01232
01233 if (dest->clip && (blit_type & AGL_NO_ROTATION)) {
01234 if ((dest_x >= dest->cr) || (dest_y >= dest->cb)
01235 || (dest_x + width < dest->cl) || (dest_y + height < dest->ct)) {
01236 return;
01237 }
01238 if (flip_dir & AGL_H_FLIP) {
01239 if (dest_x < dest->cl) {
01240 width += dest_x - dest->cl;
01241 dest_x = dest->cl;
01242 }
01243 if (dest_x + width > dest->cr) {
01244 source_x += dest_x + width - dest->cr;
01245 width = dest->cr - dest_x;
01246 }
01247 }
01248 else {
01249 if (dest_x < dest->cl) {
01250 width += dest_x - dest->cl;
01251 source_x -= dest_x - dest->cl;
01252 dest_x = dest->cl;
01253 }
01254 if (dest_x + width > dest->cr) {
01255 width = dest->cr - dest_x;
01256 }
01257 }
01258 if (flip_dir & AGL_V_FLIP) {
01259 if (dest_y < dest->ct) {
01260 height += dest_y - dest->ct;
01261 dest_y = dest->ct;
01262 }
01263 if (dest_y + height > dest->cb) {
01264 source_y += dest_y + height - dest->cb;
01265 height = dest->cb - dest_y;
01266 }
01267 }
01268 else {
01269 if (dest_y < dest->ct) {
01270 height += dest_y - dest->ct;
01271 source_y -= dest_y - dest->ct;
01272 dest_y = dest->ct;
01273 }
01274 if (dest_y + height > dest->cb) {
01275 height = dest->cb - dest_y;
01276 }
01277 }
01278 }
01279
01280
01281 if (source->clip && (blit_type & AGL_REGULAR_BMP)) {
01282 if ((source_x >= source->cr) || (source_y >= source->cb)
01283 || (source_x + width < source->cl)
01284 || (source_y + height < source->ct)) {
01285 return;
01286 }
01287 if (source_x < source->cl) {
01288 width += source_x - source->cl;
01289 dest_x -= source_x - source->cl;
01290 source_x = source->cl;
01291 }
01292 if (source_y < source->ct) {
01293 height += source_y - source->ct;
01294 dest_y -= source_y - source->ct;
01295 source_y = source->ct;
01296 }
01297 if (source_x + width > source->cr) {
01298 width = source->cr - source_x;
01299 }
01300 if (source_y + height > source->cb) {
01301 height = source->cb - source_y;
01302 }
01303 }
01304 if (is_sub_bitmap(dest)) {
01305 dest_x += dest->x_ofs;
01306 dest_y += dest->y_ofs;
01307 }
01308 if (width <= 0 || height <= 0)
01309 return;
01310
01311
01312 if (!is_video_bitmap(source) && !is_screen_bitmap(source)) {
01313
01314 __allegro_gl_driver->screen_masked_blit(source, source_x, source_y,
01315 dest_x, dest_y, width, height, flip_dir, blit_type);
01316 }
01317
01318 else if (is_video_bitmap(source)) {
01319 AGL_VIDEO_BITMAP *vid;
01320 BITMAP *source_parent = source;
01321
01322 int use_combiners = 0;
01323
01324
01325 if (allegro_gl_extensions_GL.NV_register_combiners
01326 || allegro_gl_info.num_texture_units >= 3) {
01327
01328 use_combiners = 1;
01329
01330 glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT);
01331
01332 if (allegro_gl_extensions_GL.NV_register_combiners) {
01333 __allegro_gl_init_nv_register_combiners(source);
01334 }
01335 else {
01336 __allegro_gl_init_combine_textures(source);
01337 }
01338
01339 glEnable(GL_ALPHA_TEST);
01340 glAlphaFunc(GL_GREATER, 0.0f);
01341 }
01342
01343 while (source_parent->id & BMP_ID_SUB) {
01344 source_parent = (BITMAP *)source_parent->extra;
01345 }
01346 vid = source_parent->extra;
01347
01348 while (vid) {
01349 int sx, sy;
01350 int dx, dy;
01351 int w, h;
01352
01353 if (source_x >= vid->x_ofs + vid->memory_copy->w ||
01354 source_y >= vid->y_ofs + vid->memory_copy->h ||
01355 vid->x_ofs >= source_x + width ||
01356 vid->y_ofs >= source_y + height) {
01357 vid = vid->next;
01358 continue;
01359 }
01360
01361 sx = MAX (vid->x_ofs, source_x) - vid->x_ofs;
01362 w = MIN (vid->x_ofs + vid->memory_copy->w, source_x + width)
01363 - vid->x_ofs - sx;
01364 sy = MAX (vid->y_ofs, source_y) - vid->y_ofs;
01365 h = MIN (vid->y_ofs + vid->memory_copy->h, source_y + height)
01366 - vid->y_ofs - sy;
01367
01368 dx = dest_x + vid->x_ofs + sx - source_x;
01369 dy = dest_y + vid->y_ofs + sy - source_y;
01370
01371 if (flip_dir & AGL_H_FLIP) {
01372 dx = 2*dest_x + width - dx;
01373 w = -w;
01374 }
01375
01376 if (flip_dir & AGL_V_FLIP) {
01377 dy = 2*dest_y + height - dy;
01378 h = -h;
01379 }
01380
01381 if (use_combiners) {
01382 if (allegro_gl_extensions_GL.NV_register_combiners) {
01383 glEnable(vid->target);
01384 glBindTexture(vid->target, vid->tex);
01385 glTexParameteri(vid->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
01386 glTexParameteri(vid->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
01387
01388 if (vid->target == GL_TEXTURE_2D) {
01389 float tx = sx / (float)vid->memory_copy->w;
01390 float ty = sy / (float)vid->memory_copy->h;
01391 float tw = abs(w) / (float)vid->memory_copy->w;
01392 float th = abs(h) / (float)vid->memory_copy->h;
01393
01394 glBegin(GL_QUADS);
01395 glTexCoord2f(tx, ty);
01396 glVertex2f(dx, dy);
01397 glTexCoord2f(tx, ty + th);
01398 glVertex2f(dx, dy + h);
01399 glTexCoord2f(tx + tw, ty + th);
01400 glVertex2f(dx + w, dy + h);
01401 glTexCoord2f(tx + tw, ty);
01402 glVertex2f(dx + w, dy);
01403 glEnd();
01404 }
01405 else {
01406 glBegin(GL_QUADS);
01407 glTexCoord2i(sx, sy);
01408 glVertex2f(dx, dy);
01409 glTexCoord2i(sx, sy + h);
01410 glVertex2f(dx, dy + h);
01411 glTexCoord2i(sx + w, sy + h);
01412 glVertex2f(dx + w, dy + h);
01413 glTexCoord2i(sx + w, sy);
01414 glVertex2f(dx + w, dy);
01415 glEnd();
01416 }
01417
01418 glBindTexture(vid->target, 0);
01419 glDisable(vid->target);
01420 }
01421 else {
01422 glEnable(vid->target);
01423 glActiveTexture(GL_TEXTURE0);
01424 glBindTexture(vid->target, vid->tex);
01425 glActiveTexture(GL_TEXTURE1);
01426 glBindTexture(vid->target, vid->tex);
01427 glActiveTexture(GL_TEXTURE2);
01428 glBindTexture(vid->target, vid->tex);
01429 glActiveTexture(GL_TEXTURE0);
01430 glTexParameteri(vid->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
01431 glTexParameteri(vid->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
01432
01433 if (vid->target == GL_TEXTURE_2D) {
01434 float tx, ty, tw, th;
01435 tx = sx / (float)vid->memory_copy->w;
01436 ty = sy / (float)vid->memory_copy->h;
01437 tw = abs(w) / (float)vid->memory_copy->w;
01438 th = abs(h) / (float)vid->memory_copy->h;
01439
01440 glBegin(GL_QUADS);
01441 glMultiTexCoord2f(GL_TEXTURE0, tx, ty);
01442 glMultiTexCoord2f(GL_TEXTURE1, tx, ty);
01443 glMultiTexCoord2f(GL_TEXTURE2, tx, ty);
01444 glVertex2f(dx, dy);
01445 glMultiTexCoord2f(GL_TEXTURE0, tx, ty + th);
01446 glMultiTexCoord2f(GL_TEXTURE1, tx, ty + th);
01447 glMultiTexCoord2f(GL_TEXTURE2, tx, ty + th);
01448 glVertex2f(dx, dy + h);
01449 glMultiTexCoord2f(GL_TEXTURE0, tx + tw, ty + th);
01450 glMultiTexCoord2f(GL_TEXTURE1, tx + tw, ty + th);
01451 glMultiTexCoord2f(GL_TEXTURE2, tx + tw, ty + th);
01452 glVertex2f(dx + w, dy + h);
01453 glMultiTexCoord2f(GL_TEXTURE0, tx + tw, ty);
01454 glMultiTexCoord2f(GL_TEXTURE1, tx + tw, ty);
01455 glMultiTexCoord2f(GL_TEXTURE2, tx + tw, ty);
01456 glVertex2f(dx + w, dy);
01457 glEnd();
01458 }
01459 else {
01460 glBegin(GL_QUADS);
01461 glMultiTexCoord2i(GL_TEXTURE0, dx, dy);
01462 glMultiTexCoord2i(GL_TEXTURE1, dx, dy);
01463 glMultiTexCoord2i(GL_TEXTURE2, dx, dy);
01464 glVertex2f(dx, dy);
01465 glMultiTexCoord2i(GL_TEXTURE0, dx, dy + h);
01466 glMultiTexCoord2i(GL_TEXTURE1, dx, dy + h);
01467 glMultiTexCoord2i(GL_TEXTURE2, dx, dy + h);
01468 glVertex2f(dx, dy + h);
01469 glMultiTexCoord2i(GL_TEXTURE0, dx + w, dy + h);
01470 glMultiTexCoord2i(GL_TEXTURE1, dx + w, dy + h);
01471 glMultiTexCoord2i(GL_TEXTURE2, dx + w, dy + h);
01472 glVertex2f(dx + w, dy + h);
01473 glMultiTexCoord2i(GL_TEXTURE0, dx + w, dy);
01474 glMultiTexCoord2i(GL_TEXTURE1, dx + w, dy);
01475 glMultiTexCoord2i(GL_TEXTURE2, dx + w, dy);
01476 glVertex2f(dx + w, dy);
01477 glEnd();
01478 }
01479
01480 glBindTexture(vid->target, 0);
01481 glDisable(vid->target);
01482 }
01483 }
01484 else {
01485 screen_masked_blit_standard(vid->memory_copy, sx, sy, dx, dy,
01486 w, h, FALSE, blit_type);
01487 }
01488
01489 vid = vid->next;
01490 }
01491
01492 if (use_combiners) {
01493 glPopAttrib();
01494 }
01495 }
01496 return;
01497 }
01498
01499
01500
01501 static BITMAP* __allegro_gl_convert_rle_sprite(AL_CONST struct RLE_SPRITE *sprite, int trans)
01502 {
01503 BITMAP *temp = NULL;
01504 int y, x, src_depth;
01505 signed long src_mask;
01506
01507 #define DRAW_RLE_8888(bits) \
01508 { \
01509 for (y = 0; y < sprite->h; y++) { \
01510 signed long c = *s++; \
01511 for (x = 0; x < sprite->w;) { \
01512 if (c == src_mask) \
01513 break; \
01514 if (c > 0) { \
01515 \
01516 for (c--; c>=0; c--) { \
01517 unsigned long col = *s++; \
01518 if (bits == 32 && trans) \
01519 _putpixel32(temp, x++, y, makeacol32(getr32(col), getg32(col), getb32(col), geta32(col))); \
01520 else \
01521 _putpixel32(temp, x++, y, makeacol32(getr##bits(col), getg##bits(col), getb##bits(col), 255)); \
01522 } \
01523 } \
01524 else { \
01525 \
01526 hline(temp, x, y, x-c+1, 0); \
01527 x -= c; \
01528 } \
01529 c = *s++; \
01530 } \
01531 } \
01532 }
01533
01534 src_depth = sprite->color_depth;
01535 if (src_depth == 8)
01536 src_mask = 0;
01537 else
01538 src_mask = makecol_depth(src_depth, 255, 0, 255);
01539
01540 temp = create_bitmap_ex(32, sprite->w, sprite->h);
01541 if (!temp) return NULL;
01542
01543
01544 switch(src_depth) {
01545 case 8:
01546 {
01547 signed char *s = (signed char*)sprite->dat;
01548 DRAW_RLE_8888(8);
01549 break;
01550 }
01551 case 15:
01552 {
01553 int16_t *s = (int16_t*)sprite->dat;
01554 DRAW_RLE_8888(15);
01555 break;
01556 }
01557 case 16:
01558 {
01559 int16_t *s = (int16_t*)sprite->dat;
01560 DRAW_RLE_8888(16);
01561 break;
01562 }
01563 case 24:
01564 {
01565 int32_t *s = (int32_t*)sprite->dat;
01566 DRAW_RLE_8888(24);
01567 break;
01568 }
01569 case 32:
01570 {
01571 int32_t *s = (int32_t*)sprite->dat;
01572 DRAW_RLE_8888(32);
01573 break;
01574 }
01575 }
01576
01577 return temp;
01578 }
01579
01580
01581
01582 void allegro_gl_screen_draw_rle_sprite(struct BITMAP *bmp, AL_CONST struct RLE_SPRITE *sprite, int x, int y)
01583 {
01584 BITMAP *temp = NULL, *temp2 = NULL;
01585 int source_x = 0, source_y = 0;
01586 int width = sprite->w, height = sprite->h;
01587
01588 temp = __allegro_gl_convert_rle_sprite(sprite, FALSE);
01589 if (!temp)
01590 return;
01591
01592 BITMAP_BLIT_CLIP(temp, bmp, source_x, source_y, x, y, width, height);
01593
01594 if (is_sub_bitmap(bmp)) {
01595 x += bmp->x_ofs;
01596 y += bmp->y_ofs;
01597 }
01598
01599 if (width <= 0 || height <= 0) {
01600 destroy_bitmap(temp);
01601 return;
01602 }
01603
01604 temp2 = create_sub_bitmap(temp, source_x, source_y, width, height);
01605 if (!temp2) {
01606 destroy_bitmap(temp);
01607 return;
01608 }
01609
01610 do_screen_masked_blit_standard(GL_RGBA,
01611 __allegro_gl_get_bitmap_type(temp2, AGL_TEXTURE_MASKED), temp2,
01612 0, 0, x, y, width, height, FALSE, AGL_NO_ROTATION);
01613
01614 destroy_bitmap(temp2);
01615 destroy_bitmap(temp);
01616 }
01617
01618
01619 static void allegro_gl_screen_draw_trans_rgba_rle_sprite(struct BITMAP *bmp,
01620 AL_CONST struct RLE_SPRITE *sprite, int x, int y) {
01621 BITMAP *temp = NULL, *temp2 = NULL;
01622 int source_x = 0, source_y = 0;
01623 int width = sprite->w, height = sprite->h;
01624
01625 temp = __allegro_gl_convert_rle_sprite(sprite, TRUE);
01626 if (!temp)
01627 return;
01628
01629 BITMAP_BLIT_CLIP(temp, bmp, source_x, source_y, x, y, width, height);
01630
01631 if (is_sub_bitmap(bmp)) {
01632 x += bmp->x_ofs;
01633 y += bmp->y_ofs;
01634 }
01635
01636 if (width <= 0 || height <= 0) {
01637 destroy_bitmap(temp);
01638 return;
01639 }
01640
01641 temp2 = create_sub_bitmap(temp, source_x, source_y, width, height);
01642 if (!temp2) {
01643 destroy_bitmap(temp);
01644 return;
01645 }
01646
01647 if (__allegro_gl_blit_operation == AGL_OP_LOGIC_OP)
01648 glEnable(GL_COLOR_LOGIC_OP);
01649 else
01650 glEnable(GL_BLEND);
01651
01652 allegro_gl_upload_and_display_texture(temp2, 0, 0, x, y, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE);
01653
01654 if (__allegro_gl_blit_operation == AGL_OP_LOGIC_OP)
01655 glDisable(GL_COLOR_LOGIC_OP);
01656 else
01657 glDisable(GL_BLEND);
01658
01659 destroy_bitmap(temp2);
01660 destroy_bitmap(temp);
01661 }
01662
01663
01664
01665 static void allegro_gl_screen_masked_blit(struct BITMAP *source,
01666 struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y,
01667 int width, int height)
01668 {
01669 AGL_LOG(2, "glvtable.c:allegro_gl_screen_masked_blit\n");
01670 do_masked_blit_screen(source, dest, source_x, source_y, dest_x, dest_y,
01671 width, height, FALSE, AGL_REGULAR_BMP | AGL_NO_ROTATION);
01672 }
01673
01674
01675
01676 static void allegro_gl_screen_draw_sprite(struct BITMAP *bmp,
01677 struct BITMAP *sprite, int x, int y)
01678 {
01679 AGL_LOG(2, "glvtable.c:allegro_gl_screen_draw_sprite\n");
01680 do_masked_blit_screen(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
01681 FALSE, AGL_NO_ROTATION);
01682 }
01683
01684
01685
01686 static void allegro_gl_screen_draw_sprite_v_flip(struct BITMAP *bmp,
01687 struct BITMAP *sprite, int x, int y)
01688 {
01689 AGL_LOG(2, "glvtable.c:allegro_gl_screen_draw_sprite_v_flip\n");
01690 do_masked_blit_screen(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
01691 AGL_V_FLIP, AGL_NO_ROTATION);
01692 }
01693
01694
01695
01696 static void allegro_gl_screen_draw_sprite_h_flip(struct BITMAP *bmp,
01697 struct BITMAP *sprite, int x, int y)
01698 {
01699 AGL_LOG(2, "glvtable.c:allegro_gl_screen_draw_sprite_h_flip\n");
01700 do_masked_blit_screen(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
01701 AGL_H_FLIP, AGL_NO_ROTATION);
01702 }
01703
01704
01705
01706 static void allegro_gl_screen_draw_sprite_vh_flip(struct BITMAP *bmp,
01707 struct BITMAP *sprite, int x, int y)
01708 {
01709 AGL_LOG(2, "glvtable.c:allegro_gl_screen_draw_sprite_vh_flip\n");
01710 do_masked_blit_screen(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h,
01711 AGL_V_FLIP | AGL_H_FLIP, AGL_NO_ROTATION);
01712 }
01713
01714
01715
01716 static void allegro_gl_screen_pivot_scaled_sprite_flip(struct BITMAP *bmp,
01717 struct BITMAP *sprite, fixed x, fixed y, fixed cx, fixed cy, fixed angle,
01718 fixed scale, int v_flip)
01719 {
01720 double dscale = fixtof(scale);
01721 GLint matrix_mode;
01722 AGL_LOG(2, "glvtable.c:allegro_gl_screen_pivot_scaled_sprite_flip\n");
01723
01724 #define BIN_2_DEG(x) (-(x) * 180.0 / 128)
01725
01726 glGetIntegerv(GL_MATRIX_MODE, &matrix_mode);
01727 glMatrixMode(GL_MODELVIEW);
01728 glPushMatrix();
01729 glTranslated(fixtof(x), fixtof(y), 0.);
01730 glRotated(BIN_2_DEG(fixtof(angle)), 0., 0., -1.);
01731 glScaled(dscale, dscale, dscale);
01732 glTranslated(-fixtof(x+cx), -fixtof(y+cy), 0.);
01733
01734 do_masked_blit_screen(sprite, bmp, 0, 0, fixtoi(x), fixtoi(y),
01735 sprite->w, sprite->h, v_flip ? AGL_V_FLIP : FALSE, FALSE);
01736 glPopMatrix();
01737 glMatrixMode(matrix_mode);
01738
01739 #undef BIN_2_DEG
01740
01741 return;
01742 }
01743
01744
01745
01746 static void allegro_gl_screen_draw_trans_rgba_sprite(struct BITMAP *bmp,
01747 struct BITMAP *sprite, int x, int y) {
01748
01749 if (__allegro_gl_blit_operation == AGL_OP_LOGIC_OP)
01750 glEnable(GL_COLOR_LOGIC_OP);
01751 else
01752 glEnable(GL_BLEND);
01753
01754
01755 if (is_video_bitmap(sprite)) {
01756 allegro_gl_screen_blit_to_self(sprite, bmp, 0, 0, x, y, sprite->w, sprite->h);
01757 }
01758
01759 else if (is_memory_bitmap(sprite)) {
01760 GLint format = __allegro_gl_get_bitmap_color_format(sprite, AGL_TEXTURE_HAS_ALPHA);
01761 GLint type = __allegro_gl_get_bitmap_type(sprite, 0);
01762 allegro_gl_upload_and_display_texture(sprite, 0, 0, x, y, sprite->w, sprite->h, 0, format, type);
01763 }
01764
01765 if (__allegro_gl_blit_operation == AGL_OP_LOGIC_OP)
01766 glDisable(GL_COLOR_LOGIC_OP);
01767 else
01768 glDisable(GL_BLEND);
01769
01770 return;
01771 }
01772
01773
01774
01775 void allegro_gl_screen_draw_glyph_ex(struct BITMAP *bmp,
01776 AL_CONST struct FONT_GLYPH *glyph, int x, int y,
01777 int color, int bg, int flip)
01778 {
01779 GLubyte r, g, b, a;
01780 int x_offs = 0;
01781 int i;
01782
01783 AGL_LOG(2, "glvtable.c:allegro_gl_screen_draw_glyph_ex\n");
01784
01785 if (bmp->clip) {
01786 glPushAttrib(GL_SCISSOR_BIT);
01787 glEnable(GL_SCISSOR_TEST);
01788 glScissor(bmp->x_ofs + bmp->cl, SCREEN_H - bmp->y_ofs - bmp->cb,
01789 bmp->cr - bmp->cl, bmp->cb - bmp->ct);
01790
01791 if (x < bmp->cl) {
01792 x_offs -= x - bmp->cl;
01793 x = bmp->cl;
01794 }
01795 }
01796 if (is_sub_bitmap(bmp)) {
01797 x += bmp->x_ofs;
01798 y += bmp->y_ofs;
01799 }
01800
01801 if (bg != -1) {
01802 split_color(bg, &r, &g, &b, &a, bitmap_color_depth(bmp));
01803 glColor4ub(r, g, b, a);
01804 glRecti(x, y, x + glyph->w, y + glyph->h);
01805 }
01806
01807 split_color(color, &r, &g, &b, &a, bitmap_color_depth(bmp));
01808 glColor4ub(r, g, b, a);
01809 glRasterPos2i(x, y);
01810 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
01811 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
01812
01813 if (flip) {
01814 for (i = 0; i < glyph->h; i++) {
01815 glBitmap(glyph->w, 1, x_offs, i, 0, 2,
01816 glyph->dat + i * ((glyph->w + 7) / 8));
01817 }
01818 }
01819 else {
01820 for (i = 0; i < glyph->h; i++) {
01821 glBitmap(glyph->w, 1, x_offs, i, 0, 0,
01822 glyph->dat + i * ((glyph->w + 7) / 8));
01823 }
01824 }
01825
01826 if (bmp->clip) {
01827 glPopAttrib();
01828 }
01829
01830 return;
01831 }
01832
01833
01834
01835 static void allegro_gl_screen_draw_glyph(struct BITMAP *bmp,
01836 AL_CONST struct FONT_GLYPH *glyph, int x, int y,
01837 int color, int bg) {
01838 allegro_gl_screen_draw_glyph_ex(bmp, glyph, x, y, color, bg, 0);
01839 }
01840
01841
01842
01843 void allegro_gl_screen_draw_color_glyph_ex(struct BITMAP *bmp,
01844 struct BITMAP *sprite, int x, int y, int color, int bg, int flip)
01845 {
01846
01847
01848
01849
01850 static GLfloat red_map[256];
01851 static GLfloat green_map[256];
01852 static GLfloat blue_map[256];
01853 static GLfloat alpha_map[256];
01854 GLubyte r, g, b, a;
01855 int i;
01856 GLint saved_row_length;
01857 GLint width, height;
01858 int sprite_x = 0, sprite_y = 0;
01859 void *data;
01860 int *table;
01861
01862 width = sprite->w;
01863 height = sprite->h;
01864
01865 if (bmp->clip) {
01866 if ((x >= bmp->cr) || (y >= bmp->cb) || (x + width < bmp->cl)
01867 || (y + height < bmp->ct)) {
01868 return;
01869 }
01870 if (x < bmp->cl) {
01871 width += x - bmp->cl;
01872 sprite_x -= (x - bmp->cl);
01873 x = bmp->cl;
01874 }
01875 if (y < bmp->ct) {
01876 height += y - bmp->ct;
01877 sprite_y -= (y - bmp->ct);
01878 y = bmp->ct;
01879 }
01880 if (x + width > bmp->cr) {
01881 width = bmp->cr - x;
01882 }
01883 if (y + height > bmp->cb) {
01884 height = bmp->cb - y;
01885 }
01886 }
01887 if (is_sub_bitmap(bmp)) {
01888 x += bmp->x_ofs;
01889 y += bmp->y_ofs;
01890 }
01891
01892 data = sprite->line[sprite_y]
01893 + sprite_x * BYTES_PER_PIXEL(bitmap_color_depth(sprite));
01894
01895 if (bg < 0) {
01896 glAlphaFunc(GL_GREATER, 0.0f);
01897 glEnable(GL_ALPHA_TEST);
01898 alpha_map[0] = 0.;
01899 }
01900 else {
01901 split_color(bg, &r, &g, &b, &a, bitmap_color_depth(bmp));
01902 red_map[0] = r / 255.;
01903 green_map[0] = g / 255.;
01904 blue_map[0] = b / 255.;
01905 alpha_map[0] = 1.;
01906 }
01907
01908 if (color < 0) {
01909 table = _palette_expansion_table(bitmap_color_depth(bmp));
01910
01911 for(i = 1; i < 255; i++) {
01912 split_color(table[i], &r, &g, &b, &a, bitmap_color_depth(bmp));
01913 red_map[i] = r / 255.;
01914 green_map[i] = g / 255.;
01915 blue_map[i] = b / 255.;
01916 alpha_map[i] = 1.;
01917 }
01918 }
01919 else {
01920 split_color(color, &r, &g, &b, &a, bitmap_color_depth(bmp));
01921
01922 for(i = 1; i < 255; i++) {
01923 red_map[i] = r / 255.;
01924 green_map[i] = g / 255.;
01925 blue_map[i] = b / 255.;
01926 alpha_map[i] = 1.;
01927 }
01928 }
01929
01930 glPixelMapfv(GL_PIXEL_MAP_I_TO_R, 256, red_map);
01931 glPixelMapfv(GL_PIXEL_MAP_I_TO_G, 256, green_map);
01932 glPixelMapfv(GL_PIXEL_MAP_I_TO_B, 256, blue_map);
01933 glPixelMapfv(GL_PIXEL_MAP_I_TO_A, 256, alpha_map);
01934
01935 glRasterPos2i(x, y);
01936 glPushAttrib(GL_PIXEL_MODE_BIT);
01937 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
01938
01939 glPixelZoom(1.0, flip ? -1.0 : 1.0);
01940 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
01941 glPixelStorei(GL_UNPACK_ROW_LENGTH, sprite->w);
01942 glPixelTransferi(GL_MAP_COLOR, GL_TRUE);
01943
01944 glDrawPixels(width, height, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, data);
01945 glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
01946 glPopAttrib();
01947 if (bg < 0) {
01948 glDisable(GL_ALPHA_TEST);
01949 }
01950
01951 return;
01952 }
01953
01954
01955
01956 static void allegro_gl_screen_draw_color_glyph(struct BITMAP *bmp,
01957 struct BITMAP *sprite, int x, int y, int color, int bg) {
01958 allegro_gl_screen_draw_color_glyph_ex(bmp, sprite, x, y, color, bg, 1);
01959 }
01960
01961
01962
01963 static void allegro_gl_screen_draw_character(struct BITMAP *bmp,
01964 struct BITMAP *sprite, int x, int y, int color, int bg)
01965 {
01966 AGL_LOG(2, "glvtable.c:allegro_gl_screen_draw_character\n");
01967 allegro_gl_screen_draw_color_glyph(bmp, sprite, x, y, color, bg);
01968 }
01969
01970
01971
01972 static void allegro_gl_screen_draw_256_sprite(struct BITMAP *bmp,
01973 struct BITMAP *sprite, int x, int y)
01974 {
01975 AGL_LOG(2, "glvtable.c:allegro_gl_screen_draw_256_sprite\n");
01976 allegro_gl_screen_draw_color_glyph(bmp, sprite, x, y, -1, -1);
01977 }
01978
01979
01980
01981 void allegro_gl_screen_clear_to_color(struct BITMAP *bmp, int color)
01982 {
01983 GLubyte r, g, b, a;
01984 GLfloat old_col[4];
01985
01986 AGL_LOG(2, "glvtable.c:allegro_gl_screen_clear_to_color\n");
01987 split_color(color, &r, &g, &b, &a, bitmap_color_depth(bmp));
01988
01989 glPushAttrib(GL_SCISSOR_BIT);
01990
01991 glGetFloatv(GL_COLOR_CLEAR_VALUE, old_col);
01992 glClearColor(((float) r / 255), ((float) g / 255), ((float) b / 255),
01993 ((float) a / 255));
01994
01995 if (bmp->clip) {
01996 glEnable(GL_SCISSOR_TEST);
01997 glScissor(bmp->x_ofs + bmp->cl, SCREEN_H - bmp->y_ofs - bmp->cb,
01998 bmp->cr - bmp->cl, bmp->cb - bmp->ct);
01999 }
02000 else {
02001 glScissor(0, 0, SCREEN_W, SCREEN_H);
02002 }
02003
02004 __allegro_gl_set_drawing_mode();
02005 glClear(GL_COLOR_BUFFER_BIT);
02006 __allegro_gl_unset_drawing_mode();
02007
02008 glClearColor(old_col[0], old_col[1], old_col[2], old_col[3]);
02009
02010 glPopAttrib();
02011
02012 return;
02013 }
02014
02015
02016
02017
02018 static void allegro_gl_screen_polygon(struct BITMAP *bmp, int vertices,
02019 AL_CONST int *points, int color) {
02020 GLubyte r, g, b, a;
02021 int i;
02022
02023 split_color(color, &r, &g, &b, &a, bitmap_color_depth(bmp));
02024 glColor4ub(r, g, b, a);
02025
02026 glPushAttrib(GL_SCISSOR_BIT);
02027
02028 if (bmp->clip) {
02029 glEnable(GL_SCISSOR_TEST);
02030 glScissor(bmp->x_ofs + bmp->cl, SCREEN_H - bmp->y_ofs - bmp->cb,
02031 bmp->cr - bmp->cl, bmp->cb - bmp->ct);
02032 }
02033 else {
02034 glScissor(0, 0, SCREEN_W, SCREEN_H);
02035 }
02036
02037 __allegro_gl_set_drawing_mode();
02038 glBegin(GL_POLYGON);
02039 for (i = 0; i < vertices*2-1; i+=2) {
02040 if (is_sub_bitmap(bmp)) {
02041 glVertex2f(points[i] + bmp->x_ofs, points[i+1] + bmp->y_ofs);
02042 }
02043 else {
02044 glVertex2f(points[i], points[i+1]);
02045 }
02046 }
02047 glEnd();
02048 __allegro_gl_unset_drawing_mode();
02049
02050 glPopAttrib();
02051 }
02052
02053
02054
02055 static void allegro_gl_screen_rect(struct BITMAP *bmp,
02056 int x1, int y1, int x2, int y2, int color) {
02057 GLubyte r, g, b, a;
02058
02059 split_color(color, &r, &g, &b, &a, bitmap_color_depth(bmp));
02060 glColor4ub(r, g, b, a);
02061
02062 glPushAttrib(GL_SCISSOR_BIT);
02063
02064 if (bmp->clip) {
02065 glEnable(GL_SCISSOR_TEST);
02066 glScissor(bmp->x_ofs + bmp->cl, SCREEN_H - bmp->y_ofs - bmp->cb,
02067 bmp->cr - bmp->cl, bmp->cb - bmp->ct);
02068 }
02069 else {
02070 glScissor(0, 0, SCREEN_W, SCREEN_H);
02071 }
02072 if (is_sub_bitmap(bmp)) {
02073 x1 += bmp->x_ofs;
02074 x2 += bmp->x_ofs;
02075 y1 += bmp->y_ofs;
02076 y2 += bmp->y_ofs;
02077 }
02078
02079 __allegro_gl_set_drawing_mode();
02080 glBegin(GL_LINE_STRIP);
02081 glVertex2f(x1, y1);
02082 glVertex2f(x2, y1);
02083 glVertex2f(x2, y2);
02084 glVertex2f(x1, y2);
02085 glVertex2f(x1, y1);
02086 glEnd();
02087 __allegro_gl_unset_drawing_mode();
02088
02089 glPopAttrib();
02090 }
02091
02092
02093
02094 static void allegro_gl_screen_polygon3d_f(struct BITMAP *bmp, int type,
02095 struct BITMAP *texture, int vc,
02096 V3D_f *vtx[]) {
02097 int i;
02098 int use_z = FALSE;
02099
02100 if (type & POLYTYPE_ZBUF) {
02101 use_z = TRUE;
02102 type &= ~POLYTYPE_ZBUF;
02103 }
02104
02105
02106 if ((type != POLYTYPE_FLAT) && (type != POLYTYPE_GRGB)
02107 && (type != POLYTYPE_GCOL)) {
02108 if (texture && !is_video_bitmap(texture))
02109 _soft_polygon3d_f(bmp, type, texture, vc, vtx);
02110 return;
02111 }
02112
02113 if (bmp->clip) {
02114 glEnable(GL_SCISSOR_TEST);
02115 glScissor(bmp->x_ofs + bmp->cl, SCREEN_H - bmp->y_ofs - bmp->cb,
02116 bmp->cr - bmp->cl, bmp->cb - bmp->ct);
02117 }
02118 else {
02119 glScissor(0, 0, SCREEN_W, SCREEN_H);
02120 }
02121 if (is_sub_bitmap(bmp)) {
02122 for (i = 0; i < vc*2-1; i+=2) {
02123 vtx[i] += bmp->x_ofs;
02124 vtx[i+1] += bmp->y_ofs;
02125 }
02126 }
02127
02128 if (use_z) {
02129 glEnable(GL_DEPTH_TEST);
02130 glDepthFunc(GL_LESS);
02131 glDepthMask(GL_TRUE);
02132 }
02133 else
02134 __allegro_gl_set_drawing_mode();
02135
02136 glBegin(GL_POLYGON);
02137 for (i = 0; i < vc; i++) {
02138 if (type == POLYTYPE_FLAT)
02139 glColor3ub(getr(vtx[0]->c), getg(vtx[0]->c), getb(vtx[0]->c));
02140 else if (type == POLYTYPE_GRGB)
02141 glColor3ub(getr24(vtx[i]->c), getg24(vtx[i]->c), getb24(vtx[i]->c));
02142 else if (type == POLYTYPE_GCOL)
02143 glColor3ub(getr(vtx[i]->c), getg(vtx[i]->c), getb(vtx[i]->c));
02144
02145 if (use_z)
02146 glVertex3f(vtx[i]->x, vtx[i]->y, 1.f / vtx[i]->z);
02147 else
02148 glVertex2f(vtx[i]->x, vtx[i]->y);
02149 }
02150 if (use_z)
02151 glVertex3f(vtx[0]->x, vtx[0]->y, 1.f / vtx[0]->z);
02152 else
02153 glVertex2f(vtx[0]->x, vtx[0]->y);
02154
02155 glEnd();
02156
02157 if (use_z) {
02158 glDisable(GL_DEPTH_TEST);
02159 glDepthMask(GL_FALSE);
02160 }
02161 else
02162 __allegro_gl_unset_drawing_mode();
02163 }
02164
02165
02166
02167 static void allegro_gl_screen_polygon3d(struct BITMAP *bmp, int type,
02168 struct BITMAP *texture, int vc,
02169 V3D *vtx[]) {
02170 int i;
02171 V3D_f **vtx_f = malloc(vc * sizeof(struct V3D_f*));
02172 if (!vtx_f)
02173 return;
02174
02175 for (i = 0; i < vc; i++) {
02176 vtx_f[i] = malloc(sizeof(struct V3D_f));
02177 if (!vtx_f[i]) {
02178 int k;
02179 for (k = 0; k < i; k++)
02180 free(vtx_f[k]);
02181 free(vtx_f);
02182 return;
02183 }
02184 vtx_f[i]->c = vtx[i]->c;
02185 vtx_f[i]->u = fixtof(vtx[i]->u);
02186 vtx_f[i]->v = fixtof(vtx[i]->v);
02187 vtx_f[i]->x = fixtof(vtx[i]->x);
02188 vtx_f[i]->y = fixtof(vtx[i]->y);
02189 vtx_f[i]->z = fixtof(vtx[i]->z);
02190 }
02191
02192 allegro_gl_screen_polygon3d_f(bmp, type, texture, vc, vtx_f);
02193 for (i = 0; i < vc; i++)
02194 free(vtx_f[i]);
02195 free(vtx_f);
02196 }
02197
02198
02199 static void allegro_gl_screen_quad3d_f(struct BITMAP *bmp, int type,
02200 struct BITMAP *texture,
02201 V3D_f *v1, V3D_f *v2, V3D_f *v3, V3D_f *v4) {
02202
02203 V3D_f *vtx_f[4];
02204 vtx_f[0] = v1;
02205 vtx_f[1] = v2;
02206 vtx_f[2] = v3;
02207 vtx_f[3] = v4;
02208
02209 allegro_gl_screen_polygon3d_f(bmp, type, texture, 4, vtx_f);
02210 }
02211
02212
02213
02214 static void allegro_gl_screen_quad3d(struct BITMAP *bmp, int type,
02215 struct BITMAP *texture, V3D *v1, V3D *v2, V3D *v3, V3D *v4) {
02216
02217 V3D *vtx[4];
02218 vtx[0] = v1;
02219 vtx[1] = v2;
02220 vtx[2] = v3;
02221 vtx[3] = v4;
02222
02223 allegro_gl_screen_polygon3d(bmp, type, texture, 4, vtx);
02224 }
02225
02226
02227
02228 static void allegro_gl_screen_triangle3d(struct BITMAP *bmp, int type,
02229 struct BITMAP *texture,
02230 V3D *v1, V3D *v2, V3D *v3) {
02231 V3D *vtx[3];
02232 vtx[0] = v1;
02233 vtx[1] = v2;
02234 vtx[2] = v3;
02235
02236 allegro_gl_screen_polygon3d(bmp, type, texture, 3, vtx);
02237 }
02238
02239
02240
02241 static void allegro_gl_screen_triangle3d_f(struct BITMAP *bmp, int type,
02242 struct BITMAP *texture,
02243 V3D_f *v1, V3D_f *v2, V3D_f *v3) {
02244 V3D_f *vtx_f[3];
02245 vtx_f[0] = v1;
02246 vtx_f[1] = v2;
02247 vtx_f[2] = v3;
02248
02249 allegro_gl_screen_polygon3d_f(bmp, type, texture, 3, vtx_f);
02250 }
02251
02252
02253
02254 void __allegro_gl__glvtable_update_vtable(GFX_VTABLE ** vtable)
02255 {
02256 int maskcolor = (*vtable)->mask_color;
02257 int depth = (*vtable)->color_depth;
02258
02259 AGL_LOG(2, "glvtable.c:__allegro_gl__glvtable_update_vtable\n");
02260 allegro_gl_screen_vtable.color_depth = depth;
02261
02262
02263
02264
02265 allegro_gl_screen_vtable.mask_color =
02266 makecol_depth(depth, getr(maskcolor), getg(maskcolor), getb(maskcolor));
02267
02268 *vtable = &allegro_gl_screen_vtable;
02269
02270 __allegro_gl_driver->screen_masked_blit = screen_masked_blit_standard;
02271 if (allegro_gl_extensions_GL.NV_register_combiners) {
02272 __allegro_gl_driver->screen_masked_blit
02273 = screen_masked_blit_nv_register;
02274 }
02275 else if (allegro_gl_info.num_texture_units >= 3) {
02276 __allegro_gl_driver->screen_masked_blit =
02277 screen_masked_blit_combine_tex;
02278 }
02279 }
02280
02281
02282
02283
02284 static double allegro_gl_projection_matrix[16];
02285 static double allegro_gl_modelview_matrix[16];
02286
02287
02288
02319 void allegro_gl_set_allegro_mode(void)
02320 {
02321 AGL_LOG(2, "glvtable.c:allegro_gl_set_allegro_mode\n");
02322
02323
02324 glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_TRANSFORM_BIT
02325 | GL_POINT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
02326 glDisable(GL_DEPTH_TEST);
02327 glDisable(GL_CULL_FACE);
02328 glDisable(GL_FOG);
02329 glDisable(GL_LIGHTING);
02330 glDisable(GL_BLEND);
02331 glDisable(GL_ALPHA_TEST);
02332 glDepthMask(GL_FALSE);
02333 glEnable(GL_TEXTURE_2D);
02334 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
02335 glPointSize(1.);
02336
02337
02338 if (!__allegro_gl_pool_texture) {
02339 glGenTextures(1, &__allegro_gl_pool_texture);
02340 }
02341
02342 glBindTexture(GL_TEXTURE_2D, __allegro_gl_pool_texture);
02343
02344 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0,
02345 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
02346 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
02347 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
02348
02349 glBindTexture(GL_TEXTURE_2D, 0);
02350 allegro_gl_set_projection();
02351
02352
02353
02354
02355 if (allegro_gl_info.is_ati_rage_pro) {
02356 if (!__allegro_gl_dummy_texture) {
02357 GLubyte tex[4] = {255, 255, 255, 255};
02358 glGenTextures(1, &__allegro_gl_dummy_texture);
02359 glBindTexture(GL_TEXTURE_2D, __allegro_gl_dummy_texture);
02360 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0,
02361 GL_RGBA, GL_UNSIGNED_BYTE, tex);
02362 }
02363 glBindTexture(GL_TEXTURE_2D, __allegro_gl_dummy_texture);
02364 }
02365 #ifdef ALLEGRO_MACOSX
02366
02367
02368
02369 glBegin(GL_POINTS);
02370 glEnd();
02371 #endif
02372 }
02373
02374
02375
02388 void allegro_gl_unset_allegro_mode(void)
02389 {
02390 AGL_LOG(2, "glvtable.c:allegro_gl_unset_allegro_mode\n");
02391
02392 switch(allegro_gl_display_info.vidmem_policy) {
02393 case AGL_KEEP:
02394 break;
02395 case AGL_RELEASE:
02396 if (__allegro_gl_pool_texture) {
02397 glDeleteTextures(1, &__allegro_gl_pool_texture);
02398 __allegro_gl_pool_texture = 0;
02399 }
02400 break;
02401 }
02402 allegro_gl_unset_projection();
02403 glPopAttrib();
02404 }
02405
02406
02407
02437 void allegro_gl_set_projection(void)
02438 {
02439 GLint v[4];
02440 AGL_LOG(2, "glvtable.c:allegro_gl_set_projection\n");
02441
02442
02443 glGetIntegerv(GL_VIEWPORT, &v[0]);
02444 glMatrixMode(GL_MODELVIEW);
02445 glGetDoublev(GL_MODELVIEW_MATRIX, allegro_gl_modelview_matrix);
02446 glLoadIdentity();
02447 glMatrixMode(GL_PROJECTION);
02448 glGetDoublev(GL_PROJECTION_MATRIX, allegro_gl_projection_matrix);
02449 glLoadIdentity();
02450 gluOrtho2D(v[0] - 0.325, v[0] + v[2] - 0.325, v[1] + v[3] - 0.325, v[1] - 0.325);
02451 }
02452
02453
02454
02464 void allegro_gl_unset_projection(void)
02465 {
02466 AGL_LOG(2, "glvtable.c:allegro_gl_unset_projection\n");
02467 glMatrixMode(GL_PROJECTION);
02468 glLoadMatrixd(allegro_gl_projection_matrix);
02469 glMatrixMode(GL_MODELVIEW);
02470 glLoadMatrixd(allegro_gl_modelview_matrix);
02471 }
02472
02473
02474
02475 void allegro_gl_memory_blit_between_formats(struct BITMAP *src,
02476 struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y,
02477 int width, int height)
02478 {
02479 AGL_LOG(2, "AGL::blit_between_formats\n");
02480
02481
02482 if (is_screen_bitmap(src)) {
02483 allegro_gl_screen_blit_to_memory(src, dest, source_x, source_y,
02484 dest_x, dest_y, width, height);
02485 return;
02486 }
02487
02488
02489 if (is_video_bitmap(src)) {
02490 allegro_gl_video_blit_to_memory(src, dest, source_x, source_y,
02491 dest_x, dest_y, width, height);
02492 return;
02493 }
02494
02495
02496 if (is_screen_bitmap(dest)) {
02497 allegro_gl_screen_blit_from_memory(src, dest, source_x, source_y,
02498 dest_x, dest_y, width, height);
02499 return;
02500 }
02501
02502
02503 if (is_video_bitmap(dest)) {
02504 allegro_gl_video_blit_from_memory(src, dest, source_x, source_y,
02505 dest_x, dest_y, width, height);
02506 return;
02507 }
02508
02509 switch(bitmap_color_depth(dest)) {
02510 #ifdef ALLEGRO_COLOR8
02511 case 8:
02512 __blit_between_formats8(src, dest, source_x, source_y,
02513 dest_x, dest_y, width, height);
02514 return;
02515 #endif
02516 #ifdef ALLEGRO_COLOR16
02517 case 15:
02518 __blit_between_formats15(src, dest, source_x, source_y,
02519 dest_x, dest_y, width, height);
02520 return;
02521 case 16:
02522 __blit_between_formats16(src, dest, source_x, source_y,
02523 dest_x, dest_y, width, height);
02524 return;
02525 #endif
02526 #ifdef ALLEGRO_COLOR24
02527 case 24:
02528 __blit_between_formats24(src, dest, source_x, source_y,
02529 dest_x, dest_y, width, height);
02530 return;
02531 #endif
02532 #ifdef ALLEGRO_COLOR32
02533 case 32:
02534 __blit_between_formats32(src, dest, source_x, source_y,
02535 dest_x, dest_y, width, height);
02536 return;
02537 #endif
02538 default:
02539 TRACE("--== ERROR ==-- AGL::blit_between_formats : %i -> %i bpp\n",
02540 bitmap_color_depth(src), bitmap_color_depth(dest));
02541 return;
02542 }
02543 }
02544
02545
02546
02547 static void dummy_unwrite_bank(void)
02548 {
02549 }
02550
02551
02552
02553 static GFX_VTABLE allegro_gl_screen_vtable = {
02554 0,
02555 0,
02556 dummy_unwrite_bank,
02557 NULL,
02558 allegro_gl_screen_acquire,
02559 allegro_gl_screen_release,
02560 NULL,
02561 NULL,
02562 allegro_gl_screen_getpixel,
02563 allegro_gl_screen_putpixel,
02564 allegro_gl_screen_vline,
02565 allegro_gl_screen_hline,
02566 allegro_gl_screen_hline,
02567 allegro_gl_screen_line,
02568 allegro_gl_screen_line,
02569 allegro_gl_screen_rectfill,
02570 allegro_gl_screen_triangle,
02571 allegro_gl_screen_draw_sprite,
02572 allegro_gl_screen_draw_256_sprite,
02573 allegro_gl_screen_draw_sprite_v_flip,
02574 allegro_gl_screen_draw_sprite_h_flip,
02575 allegro_gl_screen_draw_sprite_vh_flip,
02576 allegro_gl_screen_draw_trans_rgba_sprite,
02577 allegro_gl_screen_draw_trans_rgba_sprite,
02578 NULL,
02579 allegro_gl_screen_draw_rle_sprite,
02580 allegro_gl_screen_draw_trans_rgba_rle_sprite,
02581 allegro_gl_screen_draw_trans_rgba_rle_sprite,
02582 NULL,
02583 allegro_gl_screen_draw_character,
02584 allegro_gl_screen_draw_glyph,
02585 allegro_gl_screen_blit_from_memory,
02586 allegro_gl_screen_blit_to_memory,
02587 NULL,
02588 NULL,
02589 allegro_gl_screen_blit_to_self,
02590 allegro_gl_screen_blit_to_self,
02591 allegro_gl_screen_blit_to_self,
02592 allegro_gl_memory_blit_between_formats,
02593 allegro_gl_screen_masked_blit,
02594 allegro_gl_screen_clear_to_color,
02595 allegro_gl_screen_pivot_scaled_sprite_flip,
02596 NULL,
02597 NULL,
02598 NULL,
02599 NULL,
02600 allegro_gl_screen_polygon,
02601 allegro_gl_screen_rect,
02602 _soft_circle,
02603 _soft_circlefill,
02604 _soft_ellipse,
02605 _soft_ellipsefill,
02606 _soft_arc,
02607 _soft_spline,
02608 _soft_floodfill,
02609 allegro_gl_screen_polygon3d,
02610 allegro_gl_screen_polygon3d_f,
02611 allegro_gl_screen_triangle3d,
02612 allegro_gl_screen_triangle3d_f,
02613 allegro_gl_screen_quad3d,
02614 allegro_gl_screen_quad3d_f
02615 };
02616