00001
00002
00003
00008 #include <string.h>
00009
00010 #include "alleggl.h"
00011 #include "allglint.h"
00012
00013 #include <allegro/internal/aintern.h>
00014
00015 #ifdef ALLEGRO_MACOSX
00016 #include <OpenGL/glu.h>
00017 #else
00018 #include <GL/glu.h>
00019 #endif
00020
00021 static GLint allegro_gl_opengl_internal_texture_format = -1;
00022 static int allegro_gl_use_mipmapping_for_textures = 0;
00023 int __allegro_gl_use_alpha = FALSE;
00024 int __allegro_gl_flip_texture = TRUE;
00025 GLint __allegro_gl_texture_read_format[5];
00026 GLint __allegro_gl_texture_components[5];
00027
00028 #define PREFIX_I "agl-tex INFO: "
00029 #define PREFIX_W "agl-tex WARNING: "
00030 #define PREFIX_E "agl-tex ERROR: "
00031
00032
00038 char const *__allegro_gl_get_format_description(GLint format)
00039 {
00040 static char str[256];
00041 #define F(s) case s: return #s
00042 switch (format) {
00043 F(GL_ALPHA);
00044 F(GL_ALPHA4);
00045 F(GL_ALPHA8);
00046 F(GL_ALPHA12);
00047 F(GL_ALPHA16);
00048 F(GL_ALPHA16F_ARB);
00049 F(GL_ALPHA32F_ARB);
00050 F(GL_INTENSITY);
00051 F(GL_INTENSITY4);
00052 F(GL_INTENSITY8);
00053 F(GL_INTENSITY12);
00054 F(GL_INTENSITY16);
00055 F(GL_INTENSITY16F_ARB);
00056 F(GL_INTENSITY32F_ARB);
00057 F(GL_LUMINANCE);
00058 F(GL_LUMINANCE4);
00059 F(GL_LUMINANCE8);
00060 F(GL_LUMINANCE12);
00061 F(GL_LUMINANCE16);
00062 F(GL_LUMINANCE16F_ARB);
00063 F(GL_LUMINANCE32F_ARB);
00064 F(GL_LUMINANCE_ALPHA);
00065 F(GL_LUMINANCE4_ALPHA4);
00066 F(GL_LUMINANCE12_ALPHA4);
00067 F(GL_LUMINANCE8_ALPHA8);
00068 F(GL_LUMINANCE6_ALPHA2);
00069 F(GL_LUMINANCE12_ALPHA12);
00070 F(GL_LUMINANCE16_ALPHA16);
00071 F(GL_LUMINANCE_ALPHA16F_ARB);
00072 F(GL_LUMINANCE_ALPHA32F_ARB);
00073 F(GL_RGB);
00074 F(GL_R3_G3_B2);
00075 F(GL_RGB4);
00076 F(GL_RGB5);
00077 F(GL_RGB8);
00078 F(GL_RGB10);
00079 F(GL_RGB12);
00080 F(GL_RGB16);
00081 F(GL_RGB16F_ARB);
00082 F(GL_RGB32F_ARB);
00083 F(GL_RGBA);
00084 F(GL_RGBA2);
00085 F(GL_RGBA4);
00086 F(GL_RGB5_A1);
00087 F(GL_RGBA8);
00088 F(GL_RGB10_A2);
00089 F(GL_RGBA12);
00090 F(GL_RGBA16);
00091 F(GL_RGBA16F_ARB);
00092 F(GL_RGBA32F_ARB);
00093 }
00094 uszprintf(str, sizeof str, "%x", format);
00095 return str;
00096 #undef F
00097 }
00098
00099
00100
00101
00112 GLint __allegro_gl_get_texture_format_ex(BITMAP *bmp, int flags) {
00113
00114 if (!bmp) {
00115 return -1;
00116 }
00117
00118 switch (bitmap_color_depth(bmp)) {
00119 case 32:
00120 if (flags
00121 & (AGL_TEXTURE_HAS_ALPHA | AGL_TEXTURE_FORCE_ALPHA_INTERNAL)) {
00122 return GL_RGBA8;
00123 }
00124 else {
00125 return GL_RGB8;
00126 }
00127 case 8:
00128 return GL_INTENSITY8;
00129 case 15:
00130 if (flags & AGL_TEXTURE_FORCE_ALPHA_INTERNAL) {
00131 return GL_RGB5_A1;
00132 }
00133 else {
00134 return GL_RGB5;
00135 }
00136 case 16:
00137 case 24:
00138 if (flags & AGL_TEXTURE_FORCE_ALPHA_INTERNAL) {
00139 return GL_RGBA8;
00140 }
00141 else {
00142 return GL_RGB8;
00143 }
00144 default:
00145 return -1;
00146 }
00147
00148 return -1;
00149 }
00150
00151
00152
00153
00170 GLint allegro_gl_get_texture_format(BITMAP *bmp) {
00171
00172 if (bmp && allegro_gl_opengl_internal_texture_format == -1) {
00173 return __allegro_gl_get_texture_format_ex(bmp,
00174 __allegro_gl_use_alpha ? AGL_TEXTURE_FORCE_ALPHA_INTERNAL : 0);
00175 }
00176
00177 return allegro_gl_opengl_internal_texture_format;
00178 }
00179
00180
00181
00182
00204 GLint allegro_gl_set_texture_format(GLint format) {
00205
00206 GLint old = allegro_gl_opengl_internal_texture_format;
00207 allegro_gl_opengl_internal_texture_format = format;
00208 return old;
00209 }
00210
00211
00212
00213
00233 GLenum __allegro_gl_get_bitmap_type(BITMAP *bmp, int flags) {
00234
00235 int c = bitmap_color_depth(bmp);
00236
00237 switch (c) {
00238
00239 case 8:
00240 return __allegro_gl_texture_read_format[0];
00241
00242 case 15:
00243 return __allegro_gl_texture_read_format[1];
00244
00245 case 16:
00246 return __allegro_gl_texture_read_format[2];
00247
00248 case 24:
00249 return __allegro_gl_texture_read_format[3];
00250
00251 case 32:
00252 return __allegro_gl_texture_read_format[4];
00253
00254 default:
00255 TRACE(PREFIX_E "get_bitmap_type: unhandled bitmap depth: %d\n",
00256 c);
00257 return -1;
00258 }
00259 }
00260
00261
00262
00263
00277 GLenum __allegro_gl_get_bitmap_color_format(BITMAP *bmp, int flags) {
00278
00279 int c = bitmap_color_depth(bmp);
00280
00281 switch (c) {
00282
00283 case 8:
00284 if (flags & AGL_TEXTURE_ALPHA_ONLY) {
00285 return GL_ALPHA;
00286 }
00287 else {
00288 return __allegro_gl_texture_components[0];
00289 }
00290
00291 case 15:
00292 if (flags & AGL_TEXTURE_FORCE_ALPHA_INTERNAL) {
00293 return GL_RGBA;
00294 }
00295 else {
00296 return __allegro_gl_texture_components[1];
00297 }
00298
00299 case 16:
00300 return __allegro_gl_texture_components[2];
00301
00302 case 24:
00303 return __allegro_gl_texture_components[3];
00304
00305 case 32:
00306 if (flags & (AGL_TEXTURE_HAS_ALPHA
00307 | AGL_TEXTURE_FORCE_ALPHA_INTERNAL)) {
00308 return GL_RGBA;
00309 }
00310 else {
00311 return __allegro_gl_texture_components[4];
00312 }
00313
00314 default:
00315 TRACE(PREFIX_E "get_bitmap_color_format: unhandled bitmap "
00316 "depth: %d\n", c);
00317 return -1;
00318 }
00319 }
00320
00321
00322
00323
00337 int allegro_gl_use_mipmapping(int enable) {
00338
00339 int old = allegro_gl_use_mipmapping_for_textures;
00340 allegro_gl_use_mipmapping_for_textures = enable;
00341 return old;
00342 }
00343
00344
00345
00346
00361 int allegro_gl_use_alpha_channel(int enable) {
00362
00363 int old = __allegro_gl_use_alpha;
00364 __allegro_gl_use_alpha = enable;
00365 return old;
00366 }
00367
00368
00369
00370
00386 int allegro_gl_flip_texture(int enable) {
00387
00388 int old = __allegro_gl_flip_texture;
00389 __allegro_gl_flip_texture = enable;
00390 return old;
00391 }
00392
00393
00394
00395
00417 int allegro_gl_check_texture_ex(int flags, BITMAP *bmp,
00418 GLint internal_format) {
00419
00420 return (allegro_gl_make_texture_ex(flags | AGL_TEXTURE_CHECK_VALID_INTERNAL,
00421 bmp, internal_format) ? TRUE : FALSE);
00422 }
00423
00424
00425
00426
00427 static int __allegro_gl_convert_flags(int flags) {
00428
00429 flags |= AGL_TEXTURE_RESCALE;
00430
00431 if (allegro_gl_use_mipmapping_for_textures) {
00432 flags |= AGL_TEXTURE_MIPMAP;
00433 }
00434 if (__allegro_gl_use_alpha) {
00435 flags |= AGL_TEXTURE_HAS_ALPHA;
00436 }
00437 if (__allegro_gl_flip_texture) {
00438 flags |= AGL_TEXTURE_FLIP;
00439 }
00440
00441 if (allegro_gl_opengl_internal_texture_format == GL_ALPHA4
00442 || allegro_gl_opengl_internal_texture_format == GL_ALPHA8
00443 || allegro_gl_opengl_internal_texture_format == GL_ALPHA12
00444 || allegro_gl_opengl_internal_texture_format == GL_ALPHA16
00445 || allegro_gl_opengl_internal_texture_format == GL_ALPHA
00446 || allegro_gl_opengl_internal_texture_format == GL_INTENSITY4
00447 || allegro_gl_opengl_internal_texture_format == GL_INTENSITY8
00448 || allegro_gl_opengl_internal_texture_format == GL_INTENSITY12
00449 || allegro_gl_opengl_internal_texture_format == GL_INTENSITY16
00450 || allegro_gl_opengl_internal_texture_format == GL_INTENSITY
00451 || allegro_gl_opengl_internal_texture_format == 1) {
00452 flags |= AGL_TEXTURE_ALPHA_ONLY;
00453 }
00454
00455 return flags;
00456 }
00457
00458
00459
00460
00479 int allegro_gl_check_texture(BITMAP *bmp) {
00480
00481 int flags = __allegro_gl_convert_flags(0);
00482
00483 return allegro_gl_check_texture_ex(flags, bmp,
00484 allegro_gl_opengl_internal_texture_format);
00485 }
00486
00487
00488
00489
00490 static int log2i(int n) {
00491
00492 int k;
00493
00494 if (n < 1) {
00495 return -1;
00496 }
00497
00498 k = 0;
00499 while (n >>= 1) {
00500 k++;
00501 }
00502
00503 return k;
00504 }
00505
00506
00507
00508
00518 BITMAP *__allegro_gl_munge_bitmap(int flags, BITMAP *bmp, int x, int y,
00519 int w, int h, GLint *type, GLint *format) {
00520
00521 BITMAP *ret = 0, *temp = 0;
00522
00523 int need_rescale = 0;
00524 int need_alpha = 0;
00525 int need_flip = 0;
00526 int depth = bitmap_color_depth(bmp);
00527 int force_copy = 0;
00528
00529 const int old_w = w, old_h = h;
00530
00531 if (flags & AGL_TEXTURE_RESCALE) {
00532
00533
00534
00535
00536
00537
00538 if (!allegro_gl_extensions_GL.ARB_texture_non_power_of_two
00539 && ((w & (w - 1)) || (h & (h - 1)))) {
00540 w = __allegro_gl_make_power_of_2(w);
00541 h = __allegro_gl_make_power_of_2(h);
00542 TRACE(PREFIX_I "munge_bitmap: Rescaling bitmap from "
00543 "%ix%i to %ix%i due to non-power-of-2 source size.\n",
00544 old_w, old_h, w, h);
00545 need_rescale = 1;
00546 }
00547
00548
00549 if (w > allegro_gl_info.max_texture_size) {
00550 w = allegro_gl_info.max_texture_size;
00551 TRACE(PREFIX_I "munge_bitmap: Rescaling bitmap from "
00552 "%ix%i to %ix%i due to max supported size exceed.\n",
00553 old_w, old_h, w, h);
00554 need_rescale = 1;
00555 }
00556
00557 if (h > allegro_gl_info.max_texture_size) {
00558 h = allegro_gl_info.max_texture_size;
00559 TRACE(PREFIX_I "munge_bitmap: Rescaling bitmap from "
00560 "%ix%i to %ix%i due to max supported size exceed.\n",
00561 old_w, old_h, w, h);
00562 need_rescale = 1;
00563 }
00564
00565
00566
00567
00568
00569
00570
00571 if (allegro_gl_info.is_voodoo && (flags & AGL_TEXTURE_MIPMAP)
00572 && (w > 32 || h > 32)) {
00573
00574 w = MIN(32, w);
00575 h = MIN(32, h);
00576
00577 TRACE(PREFIX_I "munge_bitmap: Rescaling bitmap from "
00578 "%ix%i to %ix%i due to Voodoo driver bug.\n",
00579 old_w, old_h, w, h);
00580 need_rescale = 1;
00581 }
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 if ( allegro_gl_info.is_matrox_g200 && (flags & AGL_TEXTURE_MIPMAP)) {
00595 int wl = log2i(w);
00596 int hl = log2i(h);
00597
00598 if (w != h && MAX(wl, hl) > 3 && depth < 24
00599 && !(flags & AGL_TEXTURE_ALPHA_ONLY)) {
00600 TRACE(PREFIX_I "munge_bitmap: G200 path in use.\n");
00601 depth = 24;
00602 }
00603 }
00604
00605
00606 if (flags & AGL_TEXTURE_FLIP) {
00607 need_flip = 1;
00608 }
00609
00610
00611
00612
00613 if (*type == -1) {
00614 TRACE(PREFIX_W "munge_bitmap: using temporary 24bpp bitmap\n");
00615 depth = 24;
00616 }
00617
00618
00619
00620
00621
00622 if ((flags & AGL_TEXTURE_MASKED) && !(flags & AGL_TEXTURE_ALPHA_ONLY)) {
00623 need_alpha = 1;
00624
00625 switch (depth) {
00626 case 15:
00627 if (!allegro_gl_extensions_GL.EXT_packed_pixels) {
00628 depth = 32;
00629 }
00630 break;
00631 case 8:
00632 case 16:
00633 case 24:
00634 case 32:
00635 depth = 32;
00636 break;
00637 }
00638 force_copy = 1;
00639 }
00640
00641
00642
00643
00644
00645 if (allegro_gl_info.is_matrox_g200 && !(flags & AGL_TEXTURE_MASKED)
00646 && !(flags & AGL_TEXTURE_HAS_ALPHA) && depth == 32) {
00647 TRACE(PREFIX_I "munge_bitmap: G200 path in use.\n");
00648 depth = 24;
00649 force_copy = 1;
00650 }
00651
00652
00653
00654 if (depth != bitmap_color_depth(bmp) || force_copy) {
00655
00656 TRACE(PREFIX_I "munge_bitmap: Need to perform depth conversion from %i "
00657 "to %i bpp.\n", bitmap_color_depth(bmp), depth);
00658
00659 temp = create_bitmap_ex(depth, bmp->w, bmp->h);
00660
00661 if (!temp) {
00662 TRACE(PREFIX_E "munge_bitmap: Unable to create temporary bitmap "
00663 "%ix%ix%i\n", bmp->w, bmp->h, depth);
00664 return NULL;
00665 }
00666
00667
00668
00669 if (bitmap_color_depth(bmp) == 8 && depth > 8) {
00670 int i, j;
00671 for (j = 0; j < bmp->h; j++) {
00672 for (i = 0; i < bmp->w; i++) {
00673 int c = _getpixel(bmp, i, j);
00674 putpixel(temp, i, j, makecol_depth(depth, c, c, c));
00675 }
00676 }
00677 }
00678 else {
00679 blit(bmp, temp, 0, 0, 0, 0, bmp->w, bmp->h);
00680 }
00681 bmp = temp;
00682
00683 *format = __allegro_gl_get_bitmap_color_format(bmp, flags);
00684 *type = __allegro_gl_get_bitmap_type(bmp, flags);
00685 }
00686
00687
00688
00689
00690 if (!need_rescale && !need_alpha && !need_flip) {
00691
00692 TRACE(PREFIX_I "munge_bitmap: No need for munging - returning %p\n",
00693 temp);
00694
00695
00696 if (temp) {
00697 return temp;
00698 }
00699 return NULL;
00700 }
00701
00702 ret = create_bitmap_ex(depth, w, h);
00703
00704 if (!ret) {
00705 TRACE(PREFIX_E "munge_bitmap: Unable to create result bitmap "
00706 "%ix%ix%i\n", w, h, depth);
00707 goto error;
00708 }
00709
00710
00711
00712 if (flags & AGL_TEXTURE_CHECK_VALID_INTERNAL) {
00713 if (temp) {
00714 destroy_bitmap(temp);
00715 }
00716 return ret;
00717 }
00718
00719
00720
00721
00722
00723
00724
00725 if (need_flip) {
00726 int i;
00727 TRACE(PREFIX_I "munge_bitmap: Flipping bitmap.\n");
00728 for (i = 0; i < bmp->h/2; i++) {
00729 unsigned char *l = bmp->line[i];
00730 bmp->line[i] = bmp->line[bmp->h - i - 1];
00731 bmp->line[bmp->h - i - 1] = l;
00732 }
00733 }
00734
00735
00736 if (need_rescale) {
00737 TRACE(PREFIX_I "munge_bitmap: Rescaling bitmap.\n");
00738 stretch_blit(bmp, ret, x, y, old_w, old_h, 0, 0, ret->w, ret->h);
00739 }
00740 else {
00741 TRACE(PREFIX_I "munge_bitmap: Copying bitmap.\n");
00742 blit(bmp, ret, x, y, 0, 0, w, h);
00743 }
00744
00745
00746 if (need_flip && !temp) {
00747 int i;
00748 TRACE(PREFIX_I "munge_bitmap: Unflipping bitmap.\n");
00749 for (i = 0; i < bmp->h/2; i++) {
00750 unsigned char *l = bmp->line[i];
00751 bmp->line[i] = bmp->line[bmp->h - i - 1];
00752 bmp->line[bmp->h - i - 1] = l;
00753 }
00754 }
00755
00756
00757 if (need_alpha) {
00758 int i, j;
00759 int mask = bitmap_mask_color(ret);
00760
00761
00762 int alpha = (-1) ^ makecol_depth(depth, 255, 255, 255);
00763
00764 TRACE(PREFIX_I "munge_bitmap: Inserting alpha channel.\n");
00765
00766 for (j = 0; j < h; j++) {
00767 for (i = 0; i < w; i++) {
00768 int pix;
00769
00770 switch (depth) {
00771 case 32:
00772 pix = _getpixel32(ret, i, j);
00773
00774 if (pix == mask) {
00775 pix = 0;
00776 }
00777 else if ((flags & AGL_TEXTURE_HAS_ALPHA) == 0) {
00778 int r, g, b;
00779 r = getr32(pix);
00780 g = getg32(pix);
00781 b = getb32(pix);
00782 pix = makeacol32(r, g, b, 255);
00783 }
00784 _putpixel32(ret, i, j, pix);
00785 break;
00786 case 15:
00787 pix = _getpixel16(ret, i, j);
00788
00789 if (pix == mask) {
00790 pix = 0;
00791 }
00792 else {
00793 pix |= alpha;
00794 }
00795
00796 _putpixel16(temp, i, j, pix);
00797 break;
00798 default:
00799
00800 ASSERT(0);
00801 }
00802 }
00803 }
00804 }
00805
00806
00807 error:
00808 if (temp) {
00809 destroy_bitmap(temp);
00810 }
00811
00812 return ret;
00813 }
00814
00815
00816
00817
00818
00819 static GLuint do_texture_upload(BITMAP *bmp, GLuint tex, GLint internal_format,
00820 GLint format, GLint type, int flags) {
00821
00822 int bytes_per_pixel = BYTES_PER_PIXEL(bitmap_color_depth(bmp));
00823 GLint saved_row_length;
00824 GLint saved_alignment;
00825 GLenum target = GL_TEXTURE_2D;
00826
00827 glBindTexture(target, tex);
00828
00829
00830
00831 if (flags & AGL_TEXTURE_CHECK_VALID_INTERNAL) {
00832
00833
00834
00835 if (allegro_gl_info.is_mesa_driver) {
00836 AGL_LOG(1, "* Note * check_texture: Mesa driver detected: "
00837 "PROXY_TEXTURE_2D tests are skipped\n");
00838 return tex;
00839 }
00840 else {
00841 glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internal_format,
00842 bmp->w, bmp->h, 0, format, type, NULL);
00843
00844 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0,
00845 GL_TEXTURE_COMPONENTS, &internal_format);
00846
00847 return (internal_format ? tex : 0);
00848 }
00849 }
00850
00851
00852
00853 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00854 glGetIntegerv(GL_UNPACK_ALIGNMENT, &saved_alignment);
00855 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00856
00857 TRACE(PREFIX_I "do_texture_upload: Making texture: bpp: %i\n",
00858 bitmap_color_depth(bmp));
00859
00860
00861 if (flags & AGL_TEXTURE_MIPMAP) {
00862
00863 if (allegro_gl_extensions_GL.SGIS_generate_mipmap) {
00864
00865
00866
00867 glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
00868 glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
00869 TRACE(PREFIX_I "do_texture_upload: Using SGIS_generate_mipmap for "
00870 "mipmap generation.\n");
00871 }
00872 else if (allegro_gl_info.is_matrox_g200
00873 && (flags & AGL_TEXTURE_MIPMAP) && (bitmap_color_depth(bmp) >= 24
00874 || bitmap_color_depth(bmp) == 8)
00875 && (bmp->w != bmp->h)) {
00876
00877
00878
00879
00880 TRACE(PREFIX_I "do_texture_upload: Using GLU for mipmaps.\n");
00881 glPixelStorei(GL_UNPACK_ROW_LENGTH, bmp->h > 1
00882 ? (bmp->line[1] - bmp->line[0]) / bytes_per_pixel
00883 : bmp->w);
00884 glPixelStorei(GL_UNPACK_ROW_LENGTH,
00885 (bmp->line[1] - bmp->line[0]) / bytes_per_pixel);
00886 gluBuild2DMipmaps(GL_TEXTURE_2D, internal_format, bmp->w, bmp->h,
00887 format, type, bmp->line[0]);
00888 }
00889 else {
00890 int w = bmp->w;
00891 int h = bmp->h;
00892 int depth = bitmap_color_depth(bmp);
00893
00894
00895
00896
00897
00898
00899 BITMAP *temp = create_bitmap_ex(depth, w / 2, h / 2);
00900
00901
00902
00903
00904 int num_levels = log2i(MAX(bmp->w, bmp->h));
00905
00906 int i, x, y;
00907
00908 BITMAP *src, *dest;
00909
00910 TRACE(PREFIX_I "do_texture_upload: Using Allegro for "
00911 "mipmap generation.\n");
00912
00913 if (!temp) {
00914 TRACE(PREFIX_E "do_texture_upload: Unable to create "
00915 "temporary bitmap sized %ix%ix%i for mipmap generation!",
00916 w / 2, h / 2, depth);
00917 tex = 0;
00918 goto end;
00919 }
00920
00921 src = bmp;
00922 dest = temp;
00923
00924 for (i = 1; i <= num_levels; i++) {
00925
00926 for (y = 0; y < h; y += 2) {
00927 for (x = 0; x < w; x += 2) {
00928
00929 int r, g, b, a;
00930 int pix[4];
00931 int avg;
00932
00933 pix[0] = getpixel(src, x, y);
00934 pix[1] = getpixel(src, x + 1, y);
00935 pix[2] = getpixel(src, x, y + 1);
00936 pix[3] = getpixel(src, x + 1, y + 1);
00937
00938 if (w == 1) {
00939 pix[1] = pix[0];
00940 pix[3] = pix[2];
00941 }
00942 if (h == 1) {
00943 pix[2] = pix[0];
00944 pix[3] = pix[1];
00945 }
00946
00947 if (flags & AGL_TEXTURE_ALPHA_ONLY) {
00948 avg = (pix[0] + pix[1] + pix[2] + pix[3] + 2) / 4;
00949 }
00950 else {
00951 r = (getr_depth(depth, pix[0])
00952 + getr_depth(depth, pix[1])
00953 + getr_depth(depth, pix[2])
00954 + getr_depth(depth, pix[3]) + 2) / 4;
00955 g = (getg_depth(depth, pix[0])
00956 + getg_depth(depth, pix[1])
00957 + getg_depth(depth, pix[2])
00958 + getg_depth(depth, pix[3]) + 2) / 4;
00959 b = (getb_depth(depth, pix[0])
00960 + getb_depth(depth, pix[1])
00961 + getb_depth(depth, pix[2])
00962 + getb_depth(depth, pix[3]) + 2) / 4;
00963 a = (geta_depth(depth, pix[0])
00964 + geta_depth(depth, pix[1])
00965 + geta_depth(depth, pix[2])
00966 + geta_depth(depth, pix[3]) + 2) / 4;
00967
00968 avg = makeacol_depth(depth, r, g, b, a);
00969 }
00970
00971 putpixel(dest, x / 2, y / 2, avg);
00972 }
00973 }
00974 src = temp;
00975
00976
00977
00978
00979 w = MAX(w / 2, 1);
00980 h = MAX(h / 2, 1);
00981
00982 TRACE(PREFIX_I "do_texture_upload: Unpack row length: %i.\n",
00983 (temp->h > 1)
00984 ? (temp->line[1] - temp->line[0]) / bytes_per_pixel
00985 : temp->w);
00986
00987 glPixelStorei(GL_UNPACK_ROW_LENGTH, temp->h > 1
00988 ? (temp->line[1] - temp->line[0]) / bytes_per_pixel
00989 : temp->w);
00990
00991 glTexImage2D(GL_TEXTURE_2D, i, internal_format,
00992 w, h, 0, format, type, temp->line[0]);
00993
00994 TRACE(PREFIX_I "do_texture_upload: Mipmap level: %i, "
00995 "size: %i x %i\n", i, w, h);
00996
00997 TRACE(PREFIX_I "do_texture_upload: Uploaded texture: level %i, "
00998 "internalformat: %s, %ix%i, format: 0x%x, type: 0x%x."
00999 "\n", i, __allegro_gl_get_format_description(internal_format),
01000 bmp->w, bmp->h, format, type);
01001 }
01002
01003 destroy_bitmap(temp);
01004 }
01005 }
01006
01007 glPixelStorei(GL_UNPACK_ROW_LENGTH, (bmp->h > 1)
01008 ? (bmp->line[1] - bmp->line[0]) / bytes_per_pixel
01009 : bmp->w);
01010
01011 TRACE(PREFIX_I "do_texture_upload: Unpack row length: %i.\n",
01012 (bmp->h > 1) ? (bmp->line[1] - bmp->line[0]) / bytes_per_pixel
01013 : bmp->w);
01014
01015
01016 glGetError();
01017 glTexImage2D(GL_TEXTURE_2D, 0, internal_format,
01018 bmp->w, bmp->h, 0, format, type, bmp->line[0]);
01019
01020 TRACE(PREFIX_I "do_texture_upload: Uploaded texture: level 0, "
01021 "internalformat: %s, %ix%i, format: 0x%x, type: 0x%x.\n",
01022 __allegro_gl_get_format_description(internal_format),
01023 bmp->w, bmp->h, format, type);
01024
01025 TRACE(PREFIX_I "do_texture_upload: GL Error code: 0x%x\n", glGetError());
01026
01027 if (!(flags & AGL_TEXTURE_MIPMAP)) {
01028 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
01029 }
01030
01031 end:
01032
01033 glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
01034 glPixelStorei(GL_UNPACK_ALIGNMENT, saved_alignment);
01035
01036 return tex;
01037 }
01038
01039
01040
01041
01087 GLuint allegro_gl_make_texture_ex(int flags, BITMAP *bmp, GLint internal_format)
01088 {
01089 GLuint tex = 0, ret = 0;
01090 BITMAP *temp = NULL;
01091 GLint type;
01092 GLint format;
01093 GLint old_tex;
01094
01095
01096 #ifdef DEBUGMODE
01097 char buf[1024] = "";
01098 # define PFLAG(name) if (flags & name) strcat(buf, #name "|");
01099 PFLAG(AGL_TEXTURE_MIPMAP);
01100 PFLAG(AGL_TEXTURE_HAS_ALPHA);
01101 PFLAG(AGL_TEXTURE_FLIP);
01102 PFLAG(AGL_TEXTURE_MASKED);
01103 PFLAG(AGL_TEXTURE_RESCALE);
01104 PFLAG(AGL_TEXTURE_ALPHA_ONLY);
01105 # undef PFLAG
01106
01107 TRACE(PREFIX_I "make_texture_ex: flags: %s, bitmap %ix%i, %i bpp.\n", buf,
01108 bmp ? bmp->w : 0, bmp ? bmp->h : 0,
01109 bmp ? bitmap_color_depth(bmp) : 0);
01110 if (internal_format == -1) {
01111 TRACE(PREFIX_I "internalformat: AUTO\n");
01112 }
01113 else {
01114 TRACE(PREFIX_I "internalformat: %s\n",
01115 __allegro_gl_get_format_description(internal_format));
01116 }
01117 #endif
01118
01119
01120 if (!__allegro_gl_valid_context)
01121 return 0;
01122
01123 if (!bmp) {
01124 return 0;
01125 }
01126
01127 glGetIntegerv(GL_TEXTURE_2D_BINDING, &old_tex);
01128
01129
01130
01131 if ((bmp->w > 32 || bmp->h > 32) && (allegro_gl_info.is_voodoo)) {
01132
01133 if (!(flags & AGL_TEXTURE_RESCALE)) {
01134 TRACE(PREFIX_I "make_texture_ex: Voodoo card detected && texture "
01135 "size > 32 texels && no rescaling. Disabling mipmaps.\n");
01136 flags &= ~AGL_TEXTURE_MIPMAP;
01137 }
01138 }
01139
01140
01141 if (bmp->w > allegro_gl_info.max_texture_size
01142 || bmp->h > allegro_gl_info.max_texture_size) {
01143 if ((flags & AGL_TEXTURE_RESCALE) == 0) {
01144 TRACE(PREFIX_I "make_texture_ex: Max texture size exceeded but no "
01145 "rescaling allowed. Returning 0 (unsupported).\n");
01146 return 0;
01147 }
01148 }
01149
01150
01151 if (((bmp->w & (bmp->w - 1)) || (bmp->h & (bmp->h - 1)))
01152 && !(flags & AGL_TEXTURE_RESCALE)
01153 && !allegro_gl_extensions_GL.ARB_texture_non_power_of_two) {
01154 TRACE(PREFIX_I "make_texture_ex: Non-power-of-2 sized bitmap provided, "
01155 "no rescaling allowed, and ARB_texture_non_power_of_two "
01156 "unsupported. Returning 0 (unsupported).\n");
01157 return 0;
01158 }
01159
01160
01161
01162 format = __allegro_gl_get_bitmap_color_format(bmp, flags);
01163 type = __allegro_gl_get_bitmap_type(bmp, flags);
01164
01165 if (flags & AGL_TEXTURE_ALPHA_ONLY) {
01166 type = GL_UNSIGNED_BYTE;
01167 if (internal_format == GL_ALPHA || internal_format == GL_ALPHA4
01168 || internal_format == GL_ALPHA8) {
01169 format = GL_ALPHA;
01170 }
01171 else if (internal_format == GL_INTENSITY
01172 || internal_format == GL_INTENSITY4
01173 || internal_format == GL_INTENSITY8) {
01174 format = GL_RED;
01175 }
01176 else if (internal_format == GL_LUMINANCE
01177 || internal_format == GL_LUMINANCE4
01178 || internal_format == GL_LUMINANCE8) {
01179 format = GL_LUMINANCE;
01180 }
01181
01182
01183 if (bitmap_color_depth(bmp) != 8) {
01184 return 0;
01185 }
01186 }
01187
01188 if (flags & AGL_TEXTURE_MASKED) {
01189 flags |= AGL_TEXTURE_FORCE_ALPHA_INTERNAL;
01190 }
01191
01192 TRACE(PREFIX_I "make_texture_ex: Preselected texture format: %s, "
01193 "type: 0x%x\n", __allegro_gl_get_format_description(format), type);
01194
01195
01196 temp = __allegro_gl_munge_bitmap(flags, bmp, 0, 0, bmp->w, bmp->h,
01197 &type, &format);
01198 if (temp) {
01199 bmp = temp;
01200 }
01201
01202 if (internal_format == -1) {
01203 internal_format = __allegro_gl_get_texture_format_ex(bmp, flags);
01204 TRACE(PREFIX_I "make_texture_ex: Picked internalformat: %s\n",
01205 __allegro_gl_get_format_description(internal_format));
01206 }
01207
01208 if (internal_format == -1) {
01209 TRACE(PREFIX_E "make_texture_ex: Invalid internal format!: "
01210 "%s\n", __allegro_gl_get_format_description(internal_format));
01211 goto end;
01212 }
01213
01214 TRACE(PREFIX_I "make_texture_ex: dest format=%s, source format=%s, "
01215 "type=0x%x\n", __allegro_gl_get_format_description(internal_format),
01216 __allegro_gl_get_format_description(format), (int)type);
01217
01218
01219
01220
01221
01222
01223
01224 if (allegro_gl_info.is_ati_radeon_7000 && (flags & AGL_TEXTURE_MIPMAP)
01225 && internal_format == GL_RGB8
01226 && allegro_gl_extensions_GL.SGIS_generate_mipmap) {
01227
01228 int i, j;
01229 int depth = bitmap_color_depth(bmp);
01230
01231 TRACE(PREFIX_I "make_texture_ex: ATI Radeon 7000 detected, mipmapping "
01232 "used, SGIS_generate_mipmap available and selected "
01233 "internalformat is GL_RGB8 but format is GL_RGBA. Working around "
01234 "ATI driver bug by upgrading bitmap to 32-bpp and using GL_RGBA8 "
01235 "instead.\n");
01236
01237 if (depth == 32) {
01238
01239
01240 if (!temp) {
01241 temp = create_bitmap_ex(depth, bmp->w, bmp->h);
01242 if (!temp) {
01243 TRACE(PREFIX_E "make_texture_ex: Unable to allocate "
01244 "memory for temporary bitmap (Radeon 7000 path)!\n");
01245 goto end;
01246 }
01247 blit(bmp, temp, 0, 0, 0, 0, bmp->w, bmp->h);
01248 bmp = temp;
01249 }
01250
01251
01252
01253
01254
01255
01256
01257 for (j = 0; j < bmp->h; j++) {
01258 for (i = 0; i < bmp->w; i++) {
01259 int pix = _getpixel32(bmp, i, j);
01260 _putpixel32(bmp, i, j,
01261 makeacol32(getr32(pix), getg32(pix), getb32(pix), 255));
01262 }
01263 }
01264 }
01265 internal_format = GL_RGBA8;
01266 }
01267
01268
01269
01270 glGenTextures(1, &tex);
01271 if (!tex) {
01272 TRACE(PREFIX_E "make_texture_ex: Unable to create GL texture!\n");
01273 goto end;
01274 }
01275
01276 ret = do_texture_upload(bmp, tex, internal_format, format, type, flags);
01277
01278 end:
01279 if (temp) {
01280 destroy_bitmap(temp);
01281 }
01282
01283 if (!ret && tex) {
01284 glDeleteTextures(1, &tex);
01285 }
01286
01287 glBindTexture(GL_TEXTURE_2D, old_tex);
01288
01289 return tex;
01290 }
01291
01292
01293
01294
01295
01296
01305 GLuint allegro_gl_make_texture(BITMAP *bmp) {
01306
01307 int flags = __allegro_gl_convert_flags(0);
01308
01309 return allegro_gl_make_texture_ex(flags, bmp,
01310 allegro_gl_opengl_internal_texture_format);
01311 }
01312
01313
01314
01315
01324 GLuint allegro_gl_make_masked_texture(BITMAP *bmp) {
01325
01326 int flags = __allegro_gl_convert_flags(AGL_TEXTURE_MASKED);
01327
01328 return allegro_gl_make_texture_ex(flags, bmp,
01329 allegro_gl_opengl_internal_texture_format);
01330 }
01331
01332
01333
01334
01355 GLenum allegro_gl_get_bitmap_type(BITMAP *bmp) {
01356
01357 int flags = __allegro_gl_convert_flags(0);
01358 return __allegro_gl_get_bitmap_type(bmp, flags);
01359 }
01360
01361
01362
01363
01378 GLenum allegro_gl_get_bitmap_color_format(BITMAP *bmp) {
01379
01380 int flags = __allegro_gl_convert_flags(0);
01381 return __allegro_gl_get_bitmap_color_format(bmp, flags);
01382 }
01383