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