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