00001
00005 #include <string.h>
00006
00007 #include "alleggl.h"
00008 #include "allglint.h"
00009
00010 #include <allegro/internal/aintern.h>
00011
00012 #ifdef ALLEGRO_MACOSX
00013 #include <OpenGL/glu.h>
00014 #else
00015 #include <GL/glu.h>
00016 #endif
00017
00018 static GLint allegro_gl_opengl_internal_texture_format = -1;
00019 static int allegro_gl_use_mipmapping_for_textures = 0;
00020 int __allegro_gl_use_alpha = FALSE;
00021 int __allegro_gl_flip_texture = TRUE;
00022 GLint __allegro_gl_texture_read_format[5];
00023 GLint __allegro_gl_texture_components[5];
00024
00025
00026
00027
00038 GLint __allegro_gl_get_texture_format_ex(BITMAP *bmp, int flags) {
00039
00040 if (!bmp) {
00041 return -1;
00042 }
00043
00044 switch (bitmap_color_depth(bmp)) {
00045 case 32:
00046 if (flags
00047 & (AGL_TEXTURE_HAS_ALPHA | AGL_TEXTURE_FORCE_ALPHA_INTERNAL)) {
00048 return GL_RGBA8;
00049 }
00050 else {
00051 return GL_RGB8;
00052 }
00053 case 8:
00054 return GL_INTENSITY8;
00055 case 15:
00056 if (flags & AGL_TEXTURE_FORCE_ALPHA_INTERNAL) {
00057 return GL_RGB5_A1;
00058 }
00059 else {
00060 return GL_RGB5;
00061 }
00062 case 16:
00063 case 24:
00064 if (flags & AGL_TEXTURE_FORCE_ALPHA_INTERNAL) {
00065 return GL_RGBA8;
00066 }
00067 else {
00068 return GL_RGB8;
00069 }
00070 default:
00071 return -1;
00072 }
00073
00074 return -1;
00075 }
00076
00077
00078
00079
00096 GLint allegro_gl_get_texture_format(BITMAP *bmp) {
00097
00098 if (bmp && allegro_gl_opengl_internal_texture_format == -1) {
00099 return __allegro_gl_get_texture_format_ex(bmp,
00100 __allegro_gl_use_alpha ? AGL_TEXTURE_FORCE_ALPHA_INTERNAL : 0);
00101 }
00102
00103 return allegro_gl_opengl_internal_texture_format;
00104 }
00105
00106
00107
00108
00130 GLint allegro_gl_set_texture_format(GLint format) {
00131
00132 GLint old = allegro_gl_opengl_internal_texture_format;
00133 allegro_gl_opengl_internal_texture_format = format;
00134 return old;
00135 }
00136
00137
00138
00139
00159 GLenum __allegro_gl_get_bitmap_type(BITMAP *bmp, int flags) {
00160
00161 int c = bitmap_color_depth(bmp);
00162
00163 switch (c) {
00164
00165 case 8:
00166 return __allegro_gl_texture_read_format[0];
00167
00168 case 15:
00169 return __allegro_gl_texture_read_format[1];
00170
00171 case 16:
00172 return __allegro_gl_texture_read_format[2];
00173
00174 case 24:
00175 return __allegro_gl_texture_read_format[3];
00176
00177 case 32:
00178 return __allegro_gl_texture_read_format[4];
00179
00180 default:
00181 TRACE("** ERROR ** get_bitmap_type: unhandled bitmap depth: %d\n",
00182 c);
00183 return -1;
00184 }
00185 }
00186
00187
00188
00189
00203 GLenum __allegro_gl_get_bitmap_color_format(BITMAP *bmp, int flags) {
00204
00205 int c = bitmap_color_depth(bmp);
00206
00207 switch (c) {
00208
00209 case 8:
00210 if (flags & AGL_TEXTURE_ALPHA_ONLY) {
00211 return GL_ALPHA;
00212 }
00213 else {
00214 return __allegro_gl_texture_components[0];
00215 }
00216
00217 case 15:
00218 if (flags & AGL_TEXTURE_FORCE_ALPHA_INTERNAL) {
00219 return GL_RGBA;
00220 }
00221 else {
00222 return __allegro_gl_texture_components[1];
00223 }
00224
00225 case 16:
00226 return __allegro_gl_texture_components[2];
00227
00228 case 24:
00229 return __allegro_gl_texture_components[3];
00230
00231 case 32:
00232 if (flags & (AGL_TEXTURE_HAS_ALPHA
00233 | AGL_TEXTURE_FORCE_ALPHA_INTERNAL)) {
00234 return GL_RGBA;
00235 }
00236 else {
00237 return __allegro_gl_texture_components[4];
00238 }
00239
00240 default:
00241 TRACE("** ERROR ** get_bitmap_color_format: unhandled bitmap "
00242 "depth: %d\n", c);
00243 return -1;
00244 }
00245 }
00246
00247
00248
00249
00263 int allegro_gl_use_mipmapping(int enable) {
00264
00265 int old = allegro_gl_use_mipmapping_for_textures;
00266 allegro_gl_use_mipmapping_for_textures = enable;
00267 return old;
00268 }
00269
00270
00271
00272
00287 int allegro_gl_use_alpha_channel(int enable) {
00288
00289 int old = __allegro_gl_use_alpha;
00290 __allegro_gl_use_alpha = enable;
00291 return old;
00292 }
00293
00294
00295
00296
00312 int allegro_gl_flip_texture(int enable) {
00313
00314 int old = __allegro_gl_flip_texture;
00315 __allegro_gl_flip_texture = enable;
00316 return old;
00317 }
00318
00319
00320
00321
00343 int allegro_gl_check_texture_ex(int flags, BITMAP *bmp,
00344 GLint internal_format) {
00345
00346 return (allegro_gl_make_texture_ex(flags | AGL_TEXTURE_CHECK_VALID_INTERNAL,
00347 bmp, internal_format) ? TRUE : FALSE);
00348 }
00349
00350
00351
00352
00353 static int __allegro_gl_convert_flags(int flags) {
00354
00355 flags |= AGL_TEXTURE_RESCALE;
00356
00357 if (allegro_gl_use_mipmapping_for_textures) {
00358 flags |= AGL_TEXTURE_MIPMAP;
00359 }
00360 if (__allegro_gl_use_alpha) {
00361 flags |= AGL_TEXTURE_HAS_ALPHA;
00362 }
00363 if (__allegro_gl_flip_texture) {
00364 flags |= AGL_TEXTURE_FLIP;
00365 }
00366
00367 if (allegro_gl_opengl_internal_texture_format == GL_ALPHA4
00368 || allegro_gl_opengl_internal_texture_format == GL_ALPHA8
00369 || allegro_gl_opengl_internal_texture_format == GL_ALPHA12
00370 || allegro_gl_opengl_internal_texture_format == GL_ALPHA16
00371 || allegro_gl_opengl_internal_texture_format == GL_ALPHA
00372 || allegro_gl_opengl_internal_texture_format == GL_INTENSITY4
00373 || allegro_gl_opengl_internal_texture_format == GL_INTENSITY8
00374 || allegro_gl_opengl_internal_texture_format == GL_INTENSITY12
00375 || allegro_gl_opengl_internal_texture_format == GL_INTENSITY16
00376 || allegro_gl_opengl_internal_texture_format == GL_INTENSITY
00377 || allegro_gl_opengl_internal_texture_format == 1) {
00378 flags |= AGL_TEXTURE_ALPHA_ONLY;
00379 }
00380
00381 return flags;
00382 }
00383
00384
00385
00386
00405 int allegro_gl_check_texture(BITMAP *bmp) {
00406
00407 int flags = __allegro_gl_convert_flags(0);
00408
00409 return allegro_gl_check_texture_ex(flags, bmp,
00410 allegro_gl_opengl_internal_texture_format);
00411 }
00412
00413
00414
00415
00416 static int log2i(int n) {
00417
00418 int k;
00419
00420 if (n < 1) {
00421 return -1;
00422 }
00423
00424 k = 0;
00425 while (n >>= 1) {
00426 k++;
00427 }
00428
00429 return k;
00430 }
00431
00432
00433
00434
00444 BITMAP *__allegro_gl_munge_bitmap(int flags, BITMAP *bmp, int x, int y,
00445 int w, int h, GLint *type, GLint *format) {
00446
00447 BITMAP *ret = 0, *temp = 0;
00448
00449 int need_rescale = 0;
00450 int need_alpha = 0;
00451 int need_flip = 0;
00452 int depth = bitmap_color_depth(bmp);
00453 int force_copy = 0;
00454
00455 const int old_w = w, old_h = h;
00456
00457 if (flags & AGL_TEXTURE_RESCALE) {
00458
00459
00460
00461
00462
00463
00464 if (!allegro_gl_extensions_GL.ARB_texture_non_power_of_two
00465 && ((w & (w - 1)) || (h & (h - 1)))) {
00466 w = __allegro_gl_make_power_of_2(w);
00467 h = __allegro_gl_make_power_of_2(h);
00468 TRACE("* Note * munge_bitmap: Rescaling bitmap from "
00469 "%ix%i to %ix%i due to non-power-of-2 source size.\n",
00470 old_w, old_h, w, h);
00471 need_rescale = 1;
00472 }
00473
00474
00475 if (w > allegro_gl_info.max_texture_size) {
00476 w = allegro_gl_info.max_texture_size;
00477 TRACE("* Note * munge_bitmap: Rescaling bitmap from "
00478 "%ix%i to %ix%i due to max supported size exceed.\n",
00479 old_w, old_h, w, h);
00480 need_rescale = 1;
00481 }
00482
00483 if (h > allegro_gl_info.max_texture_size) {
00484 h = allegro_gl_info.max_texture_size;
00485 TRACE("* Note * munge_bitmap: Rescaling bitmap from "
00486 "%ix%i to %ix%i due to max supported size exceed.\n",
00487 old_w, old_h, w, h);
00488 need_rescale = 1;
00489 }
00490
00491
00492
00493
00494
00495
00496
00497 if (allegro_gl_info.is_voodoo && (flags & AGL_TEXTURE_MIPMAP)
00498 && (w > 32 || h > 32)) {
00499
00500 w = MIN(32, w);
00501 h = MIN(32, h);
00502
00503 TRACE("* Note * munge_bitmap: Rescaling bitmap from "
00504 "%ix%i to %ix%i due to Voodoo driver bug.\n",
00505 old_w, old_h, w, h);
00506 need_rescale = 1;
00507 }
00508 }
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 if ( allegro_gl_info.is_matrox_g200 && (flags & AGL_TEXTURE_MIPMAP)) {
00521 int wl = log2i(w);
00522 int hl = log2i(h);
00523
00524 if (w != h && MAX(wl, hl) > 3 && depth < 24
00525 && !(flags & AGL_TEXTURE_ALPHA_ONLY)) {
00526 TRACE("* Note * munge_bitmap: G200 path in use.\n");
00527 depth = 24;
00528 }
00529 }
00530
00531
00532 if (flags & AGL_TEXTURE_FLIP) {
00533 need_flip = 1;
00534 }
00535
00536
00537
00538
00539 if (*type == -1) {
00540 TRACE("** Warning ** munge_bitmap: using temporary 24bpp bitmap\n");
00541 depth = 24;
00542 }
00543
00544
00545
00546
00547
00548 if ((flags & AGL_TEXTURE_MASKED) && !(flags & AGL_TEXTURE_ALPHA_ONLY)) {
00549 need_alpha = 1;
00550
00551 switch (depth) {
00552 case 15:
00553 if (!allegro_gl_extensions_GL.EXT_packed_pixels) {
00554 depth = 32;
00555 }
00556 break;
00557 case 8:
00558 case 16:
00559 case 24:
00560 case 32:
00561 depth = 32;
00562 break;
00563 }
00564 force_copy = 1;
00565 }
00566
00567
00568
00569
00570
00571 if (allegro_gl_info.is_matrox_g200 && !(flags & AGL_TEXTURE_MASKED)
00572 && !(flags & AGL_TEXTURE_HAS_ALPHA) && depth == 32) {
00573 TRACE("* Note * munge_bitmap: G200 path in use.\n");
00574 depth = 24;
00575 force_copy = 1;
00576 }
00577
00578
00579
00580 if (depth != bitmap_color_depth(bmp) || force_copy) {
00581
00582 TRACE("* Note * munge_bitmap: Need to perform depth conversion from %i "
00583 "to %i bpp.\n", bitmap_color_depth(bmp), depth);
00584
00585 temp = create_bitmap_ex(depth, bmp->w, bmp->h);
00586
00587 if (!temp) {
00588 TRACE("** ERROR ** munge_bitmap: Unable to create temporary bitmap "
00589 "%ix%ix%i\n", bmp->w, bmp->h, depth);
00590 return NULL;
00591 }
00592
00593
00594
00595 if (bitmap_color_depth(bmp) == 8 && depth > 8) {
00596 int i, j;
00597 for (j = 0; j < bmp->h; j++) {
00598 for (i = 0; i < bmp->w; i++) {
00599 int c = _getpixel(bmp, i, j);
00600 putpixel(temp, i, j, makecol_depth(depth, c, c, c));
00601 }
00602 }
00603 }
00604 else {
00605 blit(bmp, temp, 0, 0, 0, 0, bmp->w, bmp->h);
00606 }
00607 bmp = temp;
00608
00609 *format = __allegro_gl_get_bitmap_color_format(bmp, flags);
00610 *type = __allegro_gl_get_bitmap_type(bmp, flags);
00611 }
00612
00613
00614
00615
00616 if (!need_rescale && !need_alpha && !need_flip) {
00617
00618 TRACE("* Note * munge_bitmap: No need for munging - returning %p\n",
00619 temp);
00620
00621
00622 if (temp) {
00623 return temp;
00624 }
00625 return NULL;
00626 }
00627
00628 ret = create_bitmap_ex(depth, w, h);
00629
00630 if (!ret) {
00631 TRACE("** ERROR ** munge_bitmap: Unable to create result bitmap "
00632 "%ix%ix%i\n", w, h, depth);
00633 goto error;
00634 }
00635
00636
00637
00638 if (flags & AGL_TEXTURE_CHECK_VALID_INTERNAL) {
00639 if (temp) {
00640 destroy_bitmap(temp);
00641 }
00642 return ret;
00643 }
00644
00645
00646
00647
00648
00649
00650
00651 if (need_flip) {
00652 int i;
00653 TRACE("* Note * munge_bitmap: Flipping bitmap.\n");
00654 for (i = 0; i < bmp->h/2; i++) {
00655 unsigned char *l = bmp->line[i];
00656 bmp->line[i] = bmp->line[bmp->h - i - 1];
00657 bmp->line[bmp->h - i - 1] = l;
00658 }
00659 }
00660
00661
00662 if (need_rescale) {
00663 TRACE("* Note * munge_bitmap: Rescaling bitmap.\n");
00664 stretch_blit(bmp, ret, x, y, old_w, old_h, 0, 0, ret->w, ret->h);
00665 }
00666 else {
00667 TRACE("* Note * munge_bitmap: Copying bitmap.\n");
00668 blit(bmp, ret, x, y, 0, 0, w, h);
00669 }
00670
00671
00672 if (need_flip && !temp) {
00673 int i;
00674 TRACE("* Note * munge_bitmap: Unflipping bitmap.\n");
00675 for (i = 0; i < bmp->h/2; i++) {
00676 unsigned char *l = bmp->line[i];
00677 bmp->line[i] = bmp->line[bmp->h - i - 1];
00678 bmp->line[bmp->h - i - 1] = l;
00679 }
00680 }
00681
00682
00683 if (need_alpha) {
00684 int i, j;
00685 int mask = bitmap_mask_color(ret);
00686
00687
00688 int alpha = (-1) ^ makecol_depth(depth, 255, 255, 255);
00689
00690 TRACE("* Note * munge_bitmap: Inserting alpha channel.\n");
00691
00692 for (j = 0; j < h; j++) {
00693 for (i = 0; i < w; i++) {
00694 int pix;
00695
00696 switch (depth) {
00697 case 32:
00698 pix = _getpixel32(ret, i, j);
00699
00700 if (pix == mask) {
00701 pix = 0;
00702 }
00703 else if ((flags & AGL_TEXTURE_HAS_ALPHA) == 0) {
00704 int r, g, b;
00705 r = getr32(pix);
00706 g = getg32(pix);
00707 b = getb32(pix);
00708 pix = makeacol32(r, g, b, 255);
00709 }
00710 _putpixel32(ret, i, j, pix);
00711 break;
00712 case 15:
00713 pix = _getpixel16(ret, i, j);
00714
00715 if (pix == mask) {
00716 pix = 0;
00717 }
00718 else {
00719 pix |= alpha;
00720 }
00721
00722 _putpixel16(temp, i, j, pix);
00723 break;
00724 default:
00725
00726 ASSERT(0);
00727 }
00728 }
00729 }
00730 }
00731
00732
00733 error:
00734 if (temp) {
00735 destroy_bitmap(temp);
00736 }
00737
00738 return ret;
00739 }
00740
00741
00742
00743
00744
00745 static GLuint do_texture_upload(BITMAP *bmp, GLuint tex, GLint internal_format,
00746 GLint format, GLint type, int flags) {
00747
00748 int bytes_per_pixel = BYTES_PER_PIXEL(bitmap_color_depth(bmp));
00749 GLint saved_row_length;
00750 GLint saved_alignment;
00751 GLenum target = GL_TEXTURE_2D;
00752
00753 glBindTexture(target, tex);
00754
00755
00756
00757 if (flags & AGL_TEXTURE_CHECK_VALID_INTERNAL) {
00758
00759
00760
00761 if (allegro_gl_info.is_mesa_driver) {
00762 AGL_LOG(1, "* Note * check_texture: Mesa driver detected: "
00763 "PROXY_TEXTURE_2D tests are skipped\n");
00764 return tex;
00765 }
00766 else {
00767 glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internal_format,
00768 bmp->w, bmp->h, 0, format, type, NULL);
00769
00770 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0,
00771 GL_TEXTURE_COMPONENTS, &internal_format);
00772
00773 return (internal_format ? tex : 0);
00774 }
00775 }
00776
00777
00778
00779 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00780 glGetIntegerv(GL_UNPACK_ALIGNMENT, &saved_alignment);
00781 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00782
00783 TRACE("* Note * do_texture_upload: Making texture: bpp: %i\n",
00784 bitmap_color_depth(bmp));
00785
00786
00787 if (flags & AGL_TEXTURE_MIPMAP) {
00788
00789 if (allegro_gl_extensions_GL.SGIS_generate_mipmap) {
00790
00791
00792
00793 glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
00794 glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
00795 TRACE("* Note * do_texture_upload: Using SGIS_generate_mipmap for "
00796 "mipmap generation.\n");
00797 }
00798 else if (allegro_gl_info.is_matrox_g200
00799 && (flags & AGL_TEXTURE_MIPMAP) && (bitmap_color_depth(bmp) >= 24
00800 || bitmap_color_depth(bmp) == 8)
00801 && (bmp->w != bmp->h)) {
00802
00803
00804
00805
00806 TRACE("* Note * do_texture_upload: Using GLU for mipmaps.\n");
00807 glPixelStorei(GL_UNPACK_ROW_LENGTH, bmp->h > 1
00808 ? (bmp->line[1] - bmp->line[0]) / bytes_per_pixel
00809 : bmp->w);
00810 glPixelStorei(GL_UNPACK_ROW_LENGTH,
00811 (bmp->line[1] - bmp->line[0]) / bytes_per_pixel);
00812 gluBuild2DMipmaps(GL_TEXTURE_2D, internal_format, bmp->w, bmp->h,
00813 format, type, bmp->line[0]);
00814 }
00815 else {
00816 int w = bmp->w;
00817 int h = bmp->h;
00818 int depth = bitmap_color_depth(bmp);
00819
00820
00821
00822
00823
00824
00825 BITMAP *temp = create_bitmap_ex(depth, w / 2, h / 2);
00826
00827
00828
00829
00830 int num_levels = log2i(MAX(bmp->w, bmp->h));
00831
00832 int i, x, y;
00833
00834 BITMAP *src, *dest;
00835
00836 TRACE("* Note * do_texture_upload: Using Allegro for "
00837 "mipmap generation.\n");
00838
00839 if (!temp) {
00840 TRACE("** ERROR ** do_texture_upload: Unable to create "
00841 "temporary bitmap sized %ix%ix%i for mipmap generation!",
00842 w / 2, h / 2, depth);
00843 tex = 0;
00844 goto end;
00845 }
00846
00847 src = bmp;
00848 dest = temp;
00849
00850 for (i = 1; i <= num_levels; i++) {
00851
00852 for (y = 0; y < h; y += 2) {
00853 for (x = 0; x < w; x += 2) {
00854
00855 int r, g, b, a;
00856 int pix[4];
00857 int avg;
00858
00859 pix[0] = getpixel(src, x, y);
00860 pix[1] = getpixel(src, x + 1, y);
00861 pix[2] = getpixel(src, x, y + 1);
00862 pix[3] = getpixel(src, x + 1, y + 1);
00863
00864 if (w == 1) {
00865 pix[1] = pix[0];
00866 pix[3] = pix[2];
00867 }
00868 if (h == 1) {
00869 pix[2] = pix[0];
00870 pix[3] = pix[1];
00871 }
00872
00873 if (flags & AGL_TEXTURE_ALPHA_ONLY) {
00874 avg = (pix[0] + pix[1] + pix[2] + pix[3] + 2) / 4;
00875 }
00876 else {
00877 r = (getr_depth(depth, pix[0])
00878 + getr_depth(depth, pix[1])
00879 + getr_depth(depth, pix[2])
00880 + getr_depth(depth, pix[3]) + 2) / 4;
00881 g = (getg_depth(depth, pix[0])
00882 + getg_depth(depth, pix[1])
00883 + getg_depth(depth, pix[2])
00884 + getg_depth(depth, pix[3]) + 2) / 4;
00885 b = (getb_depth(depth, pix[0])
00886 + getb_depth(depth, pix[1])
00887 + getb_depth(depth, pix[2])
00888 + getb_depth(depth, pix[3]) + 2) / 4;
00889 a = (geta_depth(depth, pix[0])
00890 + geta_depth(depth, pix[1])
00891 + geta_depth(depth, pix[2])
00892 + geta_depth(depth, pix[3]) + 2) / 4;
00893
00894 avg = makeacol_depth(depth, r, g, b, a);
00895 }
00896
00897 putpixel(dest, x / 2, y / 2, avg);
00898 }
00899 }
00900 src = temp;
00901
00902
00903
00904
00905 w = MAX(w / 2, 1);
00906 h = MAX(h / 2, 1);
00907
00908 TRACE("* Note * do_texture_upload: Unpack row length: %i.\n",
00909 (temp->h > 1)
00910 ? (temp->line[1] - temp->line[0]) / bytes_per_pixel
00911 : temp->w);
00912
00913 glPixelStorei(GL_UNPACK_ROW_LENGTH, temp->h > 1
00914 ? (temp->line[1] - temp->line[0]) / bytes_per_pixel
00915 : temp->w);
00916
00917 glTexImage2D(GL_TEXTURE_2D, i, internal_format,
00918 w, h, 0, format, type, temp->line[0]);
00919
00920 TRACE("* Note * do_texture_upload: Mipmap level: %i, "
00921 "size: %i x %i\n", i, w, h);
00922
00923 TRACE("* Note * do_texture_upload: Uploaded texture: level %i, "
00924 "internalformat: 0x%x, %ix%i, format: 0x%x, type: 0x%x."
00925 "\n", i, internal_format, bmp->w, bmp->h, format, type);
00926 }
00927
00928 destroy_bitmap(temp);
00929 }
00930 }
00931
00932 glPixelStorei(GL_UNPACK_ROW_LENGTH, (bmp->h > 1)
00933 ? (bmp->line[1] - bmp->line[0]) / bytes_per_pixel
00934 : bmp->w);
00935
00936 TRACE("* Note * do_texture_upload: Unpack row length: %i.\n",
00937 (bmp->h > 1) ? (bmp->line[1] - bmp->line[0]) / bytes_per_pixel
00938 : bmp->w);
00939
00940
00941 glGetError();
00942 glTexImage2D(GL_TEXTURE_2D, 0, internal_format,
00943 bmp->w, bmp->h, 0, format, type, bmp->line[0]);
00944
00945 TRACE("* Note * do_texture_upload: Uploaded texture: level 0, "
00946 "internalformat: 0x%x, %ix%i, format: 0x%x, type: 0x%x.\n",
00947 internal_format, bmp->w, bmp->h, format, type);
00948
00949 TRACE("* Note * do_texture_upload: GL Error code: 0x%x\n", glGetError());
00950
00951 if (!(flags & AGL_TEXTURE_MIPMAP)) {
00952 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00953 }
00954
00955 end:
00956
00957 glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00958 glPixelStorei(GL_UNPACK_ALIGNMENT, saved_alignment);
00959
00960 return tex;
00961 }
00962
00963
00964
00965
01011 GLuint allegro_gl_make_texture_ex(int flags, BITMAP *bmp, GLint internal_format)
01012 {
01013 GLuint tex = 0, ret = 0;
01014 BITMAP *temp = NULL;
01015 GLint type;
01016 GLint format;
01017 GLint old_tex;
01018
01019
01020 #ifdef DEBUGMODE
01021 char buf[1024] = "";
01022 # define PFLAG(name) if (flags & name) strcat(buf, #name "|");
01023 PFLAG(AGL_TEXTURE_MIPMAP);
01024 PFLAG(AGL_TEXTURE_HAS_ALPHA);
01025 PFLAG(AGL_TEXTURE_FLIP);
01026 PFLAG(AGL_TEXTURE_MASKED);
01027 PFLAG(AGL_TEXTURE_RESCALE);
01028 PFLAG(AGL_TEXTURE_ALPHA_ONLY);
01029 # undef PFLAG
01030
01031 TRACE("* Note * make_texture_ex: flags: %s, bitmap %ix%i, %i bpp. ", buf,
01032 bmp ? bmp->w : 0, bmp ? bmp->h : 0,
01033 bmp ? bitmap_color_depth(bmp) : 0);
01034 if (internal_format == -1) {
01035 TRACE("internalformat: AUTO\n");
01036 }
01037 else {
01038 TRACE("internalformat: 0x%x\n", (int)internal_format);
01039 }
01040 #endif
01041
01042
01043 if (!__allegro_gl_valid_context)
01044 return 0;
01045
01046 if (!bmp) {
01047 return 0;
01048 }
01049
01050 glGetIntegerv(GL_TEXTURE_2D_BINDING, &old_tex);
01051
01052
01053
01054 if ((bmp->w > 32 || bmp->h > 32) && (allegro_gl_info.is_voodoo)) {
01055
01056 if (!(flags & AGL_TEXTURE_RESCALE)) {
01057 TRACE("* Note * make_texture_ex: Voodoo card detected && texture "
01058 "size > 32 texels && no rescaling. Disabling mipmaps.\n");
01059 flags &= ~AGL_TEXTURE_MIPMAP;
01060 }
01061 }
01062
01063
01064 if (bmp->w > allegro_gl_info.max_texture_size
01065 || bmp->h > allegro_gl_info.max_texture_size) {
01066 if ((flags & AGL_TEXTURE_RESCALE) == 0) {
01067 TRACE("* Note * make_texture_ex: Max texture size exceeded but no "
01068 "rescaling allowed. Returning 0 (unsupported).\n");
01069 return 0;
01070 }
01071 }
01072
01073
01074 if (((bmp->w & (bmp->w - 1)) || (bmp->h & (bmp->h - 1)))
01075 && !(flags & AGL_TEXTURE_RESCALE)
01076 && !allegro_gl_extensions_GL.ARB_texture_non_power_of_two) {
01077 TRACE("* Note * make_texture_ex: Non-power-of-2 sized bitmap provided, "
01078 "no rescaling allowed, and ARB_texture_non_power_of_two "
01079 "unsupported. Returning 0 (unsupported).\n");
01080 return 0;
01081 }
01082
01083
01084
01085 format = __allegro_gl_get_bitmap_color_format(bmp, flags);
01086 type = __allegro_gl_get_bitmap_type(bmp, flags);
01087
01088 if (flags & AGL_TEXTURE_ALPHA_ONLY) {
01089 type = GL_UNSIGNED_BYTE;
01090 if (internal_format == GL_ALPHA || internal_format == GL_ALPHA4
01091 || internal_format == GL_ALPHA8) {
01092 format = GL_ALPHA;
01093 }
01094 else if (internal_format == GL_INTENSITY
01095 || internal_format == GL_INTENSITY4
01096 || internal_format == GL_INTENSITY8) {
01097 format = GL_RED;
01098 }
01099 else if (internal_format == GL_LUMINANCE
01100 || internal_format == GL_LUMINANCE4
01101 || internal_format == GL_LUMINANCE8) {
01102 format = GL_LUMINANCE;
01103 }
01104
01105
01106 if (bitmap_color_depth(bmp) != 8) {
01107 return 0;
01108 }
01109 }
01110
01111 if (flags & AGL_TEXTURE_MASKED) {
01112 flags |= AGL_TEXTURE_FORCE_ALPHA_INTERNAL;
01113 }
01114
01115 TRACE("* Note * make_texture_ex: Preselected texture format: 0x%x, "
01116 "type: 0x%x\n", format, type);
01117
01118
01119 temp = __allegro_gl_munge_bitmap(flags, bmp, 0, 0, bmp->w, bmp->h,
01120 &type, &format);
01121 if (temp) {
01122 bmp = temp;
01123 }
01124
01125 if (internal_format == -1) {
01126 internal_format = __allegro_gl_get_texture_format_ex(bmp, flags);
01127 TRACE("* Note * make_texture_ex: Picked internalformat: 0x%x\n",
01128 (int)internal_format);
01129 }
01130
01131 if (internal_format == -1) {
01132 TRACE("** ERROR ** make_texture_ex: Invalid internal format!: "
01133 "0x%x\n", (int)internal_format);
01134 goto end;
01135 }
01136
01137 TRACE("* Note * make_texture_ex: dest format=%04x, source format=0x%x, "
01138 "type=0x%x\n", (int)internal_format, (int)format, (int)type);
01139
01140
01141
01142
01143
01144
01145
01146 if (allegro_gl_info.is_ati_radeon_7000 && (flags & AGL_TEXTURE_MIPMAP)
01147 && internal_format == GL_RGB8
01148 && allegro_gl_extensions_GL.SGIS_generate_mipmap) {
01149
01150 int i, j;
01151 int depth = bitmap_color_depth(bmp);
01152
01153 TRACE("* Note * make_texture_ex: ATI Radeon 7000 detected, mipmapping "
01154 "used, SGIS_generate_mipmap available and selected "
01155 "internalformat is GL_RGB8 but format is GL_RGBA. Working around "
01156 "ATI driver bug by upgrading bitmap to 32-bpp and using GL_RGBA8 "
01157 "instead.\n");
01158
01159 if (depth == 32) {
01160
01161
01162 if (!temp) {
01163 temp = create_bitmap_ex(depth, bmp->w, bmp->h);
01164 if (!temp) {
01165 TRACE("** ERROR ** make_texture_ex: Unable to allocate "
01166 "memory for temporary bitmap (Radeon 7000 path)!\n");
01167 goto end;
01168 }
01169 blit(bmp, temp, 0, 0, 0, 0, bmp->w, bmp->h);
01170 bmp = temp;
01171 }
01172
01173
01174
01175
01176
01177
01178
01179 for (j = 0; j < bmp->h; j++) {
01180 for (i = 0; i < bmp->w; i++) {
01181 int pix = _getpixel32(bmp, i, j);
01182 _putpixel32(bmp, i, j,
01183 makeacol32(getr32(pix), getg32(pix), getb32(pix), 255));
01184 }
01185 }
01186 }
01187 internal_format = GL_RGBA8;
01188 }
01189
01190
01191
01192 glGenTextures(1, &tex);
01193 if (!tex) {
01194 TRACE("** ERROR ** make_texture_ex: Unable to create GL texture!\n");
01195 goto end;
01196 }
01197
01198 ret = do_texture_upload(bmp, tex, internal_format, format, type, flags);
01199
01200 end:
01201 if (temp) {
01202 destroy_bitmap(temp);
01203 }
01204
01205 if (!ret && tex) {
01206 glDeleteTextures(1, &tex);
01207 }
01208
01209 glBindTexture(GL_TEXTURE_2D, old_tex);
01210
01211 return tex;
01212 }
01213
01214
01215
01216
01217
01218
01227 GLuint allegro_gl_make_texture(BITMAP *bmp) {
01228
01229 int flags = __allegro_gl_convert_flags(0);
01230
01231 return allegro_gl_make_texture_ex(flags, bmp,
01232 allegro_gl_opengl_internal_texture_format);
01233 }
01234
01235
01236
01237
01246 GLuint allegro_gl_make_masked_texture(BITMAP *bmp) {
01247
01248 int flags = __allegro_gl_convert_flags(AGL_TEXTURE_MASKED);
01249
01250 return allegro_gl_make_texture_ex(flags, bmp,
01251 allegro_gl_opengl_internal_texture_format);
01252 }
01253
01254
01255
01256
01257
01278 GLenum allegro_gl_get_bitmap_type(BITMAP *bmp) {
01279
01280 int flags = __allegro_gl_convert_flags(0);
01281 return __allegro_gl_get_bitmap_type(bmp, flags);
01282 }
01283
01284
01285
01286
01301 GLenum allegro_gl_get_bitmap_color_format(BITMAP *bmp) {
01302
01303 int flags = __allegro_gl_convert_flags(0);
01304 return __allegro_gl_get_bitmap_color_format(bmp, flags);
01305 }
01306