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