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