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