00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Teddy/Graphics/Device.h"
00024
00025
00026
00027 #define GLU_ERROR 100103
00028 #define GLU_INVALID_ENUM 100900
00029 #define GLU_INVALID_VALUE 100901
00030 #define GLU_OUT_OF_MEMORY 100902
00031 #define GLU_INVALID_OPERATION 100904
00032
00033
00034 #include "Teddy/SysSupport/StdMaths.h"
00035 #ifndef SWIG
00036 # include <cassert>
00037 # include <cstdio>
00038 # include <cstdlib>
00039 #endif
00040
00041
00042
00043
00044
00045
00046
00047 #define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
00048
00049
00050
00051 #ifdef EPSILON
00052 #undef EPSILON
00053 #endif
00054 #define EPSILON 0.001
00055
00056
00057
00058 #if defined(__WIN32__) && !defined(OPENSTEP)
00059 void
00060 dummy(GLuint j, GLuint k)
00061 {
00062 }
00063 #else
00064 #define dummy(J, K)
00065 #endif
00066
00067
00068 GLint
00069 glu_ScaleImage(GLenum format,
00070 GLsizei widthin, GLsizei heightin,
00071 GLenum typein, const void *datain,
00072 GLsizei widthout, GLsizei heightout,
00073 GLenum typeout, void **dataoutp)
00074 {
00075 GLint components, i, j, k;
00076 GLfloat *tempin, *tempout;
00077 GLfloat sx, sy;
00078 GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
00079 GLint packrowlength, packalignment, packskiprows, packskippixels;
00080 GLint sizein, sizeout;
00081 GLint rowstride, rowlen;
00082 GLint dataoutsize;
00083 void *dataout;
00084
00085
00086
00087 switch (format) {
00088 case GL_COLOR_INDEX:
00089 case GL_STENCIL_INDEX:
00090 case GL_DEPTH_COMPONENT:
00091 case GL_RED:
00092 case GL_GREEN:
00093 case GL_BLUE:
00094 case GL_ALPHA:
00095 case GL_LUMINANCE:
00096 components = 1;
00097 break;
00098 case GL_LUMINANCE_ALPHA:
00099 components = 2;
00100 break;
00101 case GL_RGB:
00102 #ifdef GL_BGR
00103 case GL_BGR:
00104 #endif
00105 components = 3;
00106 break;
00107 case GL_RGBA:
00108 #ifdef GL_BGRA
00109 case GL_BGRA:
00110 #endif
00111 #ifdef GL_EXT_abgr
00112 case GL_ABGR_EXT:
00113 #endif
00114 components = 4;
00115 break;
00116 default:
00117 return GLU_INVALID_ENUM;
00118 }
00119
00120
00121 switch (typein) {
00122 case GL_UNSIGNED_BYTE:
00123 sizein = sizeof(GLubyte);
00124 break;
00125 case GL_BYTE:
00126 sizein = sizeof(GLbyte);
00127 break;
00128 case GL_UNSIGNED_SHORT:
00129 sizein = sizeof(GLushort);
00130 break;
00131 case GL_SHORT:
00132 sizein = sizeof(GLshort);
00133 break;
00134 case GL_UNSIGNED_INT:
00135 sizein = sizeof(GLuint);
00136 break;
00137 case GL_INT:
00138 sizein = sizeof(GLint);
00139 break;
00140 case GL_FLOAT:
00141 sizein = sizeof(GLfloat);
00142 break;
00143 case GL_BITMAP:
00144
00145 default:
00146 return GL_INVALID_ENUM;
00147 }
00148
00149
00150 switch (typeout) {
00151 case GL_UNSIGNED_BYTE:
00152 sizeout = sizeof(GLubyte);
00153 break;
00154 case GL_BYTE:
00155 sizeout = sizeof(GLbyte);
00156 break;
00157 case GL_UNSIGNED_SHORT:
00158 sizeout = sizeof(GLushort);
00159 break;
00160 case GL_SHORT:
00161 sizeout = sizeof(GLshort);
00162 break;
00163 case GL_UNSIGNED_INT:
00164 sizeout = sizeof(GLuint);
00165 break;
00166 case GL_INT:
00167 sizeout = sizeof(GLint);
00168 break;
00169 case GL_FLOAT:
00170 sizeout = sizeof(GLfloat);
00171 break;
00172 case GL_BITMAP:
00173
00174 default:
00175 return GL_INVALID_ENUM;
00176 }
00177
00178
00179 # if defined( USE_TINY_GL )
00180 unpackrowlength = 0;
00181 unpackalignment = 1;
00182 unpackskiprows = 0;
00183 unpackskippixels = 0;
00184 packrowlength = 0;
00185 packalignment = 1;
00186 packskiprows = 0;
00187 packskippixels = 0;
00188 # else
00189 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpackrowlength);
00190 glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpackalignment);
00191 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &unpackskiprows);
00192 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &unpackskippixels);
00193 glGetIntegerv(GL_PACK_ROW_LENGTH, &packrowlength);
00194 glGetIntegerv(GL_PACK_ALIGNMENT, &packalignment);
00195 glGetIntegerv(GL_PACK_SKIP_ROWS, &packskiprows);
00196 glGetIntegerv(GL_PACK_SKIP_PIXELS, &packskippixels);
00197 # endif
00198
00199
00200 tempin = (GLfloat *) malloc(widthin * heightin
00201 * components * sizeof(GLfloat));
00202 if (!tempin) {
00203 return GLU_OUT_OF_MEMORY;
00204 }
00205 tempout = (GLfloat *) malloc(widthout * heightout
00206 * components * sizeof(GLfloat));
00207 if (!tempout) {
00208 free(tempin);
00209 return GLU_OUT_OF_MEMORY;
00210 }
00211
00212
00213
00214
00215
00216
00217 if (unpackrowlength > 0) {
00218 rowlen = unpackrowlength;
00219 }
00220 else {
00221 rowlen = widthin;
00222 }
00223 if (sizein >= unpackalignment) {
00224 rowstride = components * rowlen;
00225 }
00226 else {
00227 rowstride = unpackalignment / sizein
00228 * CEILING(components * rowlen * sizein, unpackalignment);
00229 }
00230
00231 switch (typein) {
00232 case GL_UNSIGNED_BYTE:
00233 k = 0;
00234 for (i = 0; i < heightin; i++) {
00235 GLubyte *ubptr = (GLubyte *) datain
00236 + i * rowstride
00237 + unpackskiprows * rowstride + unpackskippixels * components;
00238 for (j = 0; j < widthin * components; j++) {
00239 dummy(j, k);
00240 tempin[k++] = (GLfloat) * ubptr++;
00241 }
00242 }
00243 break;
00244 case GL_BYTE:
00245 k = 0;
00246 for (i = 0; i < heightin; i++) {
00247 GLbyte *bptr = (GLbyte *) datain
00248 + i * rowstride
00249 + unpackskiprows * rowstride + unpackskippixels * components;
00250 for (j = 0; j < widthin * components; j++) {
00251 dummy(j, k);
00252 tempin[k++] = (GLfloat) * bptr++;
00253 }
00254 }
00255 break;
00256 case GL_UNSIGNED_SHORT:
00257 k = 0;
00258 for (i = 0; i < heightin; i++) {
00259 GLushort *usptr = (GLushort *) datain
00260 + i * rowstride
00261 + unpackskiprows * rowstride + unpackskippixels * components;
00262 for (j = 0; j < widthin * components; j++) {
00263 dummy(j, k);
00264 tempin[k++] = (GLfloat) * usptr++;
00265 }
00266 }
00267 break;
00268 case GL_SHORT:
00269 k = 0;
00270 for (i = 0; i < heightin; i++) {
00271 GLshort *sptr = (GLshort *) datain
00272 + i * rowstride
00273 + unpackskiprows * rowstride + unpackskippixels * components;
00274 for (j = 0; j < widthin * components; j++) {
00275 dummy(j, k);
00276 tempin[k++] = (GLfloat) * sptr++;
00277 }
00278 }
00279 break;
00280 case GL_UNSIGNED_INT:
00281 k = 0;
00282 for (i = 0; i < heightin; i++) {
00283 GLuint *uiptr = (GLuint *) datain
00284 + i * rowstride
00285 + unpackskiprows * rowstride + unpackskippixels * components;
00286 for (j = 0; j < widthin * components; j++) {
00287 dummy(j, k);
00288 tempin[k++] = (GLfloat) * uiptr++;
00289 }
00290 }
00291 break;
00292 case GL_INT:
00293 k = 0;
00294 for (i = 0; i < heightin; i++) {
00295 GLint *iptr = (GLint *) datain
00296 + i * rowstride
00297 + unpackskiprows * rowstride + unpackskippixels * components;
00298 for (j = 0; j < widthin * components; j++) {
00299 dummy(j, k);
00300 tempin[k++] = (GLfloat) * iptr++;
00301 }
00302 }
00303 break;
00304 case GL_FLOAT:
00305 k = 0;
00306 for (i = 0; i < heightin; i++) {
00307 GLfloat *fptr = (GLfloat *) datain
00308 + i * rowstride
00309 + unpackskiprows * rowstride + unpackskippixels * components;
00310 for (j = 0; j < widthin * components; j++) {
00311 dummy(j, k);
00312 tempin[k++] = *fptr++;
00313 }
00314 }
00315 break;
00316 default:
00317 return GLU_INVALID_ENUM;
00318 }
00319
00320
00321
00322
00323
00324
00325 if (widthout > 1)
00326 sx = (GLfloat) (widthin - 1) / (GLfloat) (widthout - 1);
00327 else
00328 sx = (GLfloat) (widthin - 1);
00329 if (heightout > 1)
00330 sy = (GLfloat) (heightin - 1) / (GLfloat) (heightout - 1);
00331 else
00332 sy = (GLfloat) (heightin - 1);
00333
00334
00335 #ifdef POINT_SAMPLE
00336 for (i = 0; i < heightout; i++) {
00337 GLint ii = i * sy;
00338 for (j = 0; j < widthout; j++) {
00339 GLint jj = j * sx;
00340
00341 GLfloat *src = tempin + (ii * widthin + jj) * components;
00342 GLfloat *dst = tempout + (i * widthout + j) * components;
00343
00344 for (k = 0; k < components; k++) {
00345 *dst++ = *src++;
00346 }
00347 }
00348 }
00349 #else
00350 if (sx < 1.0 && sy < 1.0) {
00351
00352 GLint i0, i1, j0, j1;
00353 GLfloat alpha, beta;
00354 GLfloat *src00, *src01, *src10, *src11;
00355 GLdouble s1, s2;
00356 GLfloat *dst;
00357
00358 for (i = 0; i < heightout; i++) {
00359 i0 = (int)(i * sy);
00360 i1 = i0 + 1;
00361 if (i1 >= heightin)
00362 i1 = heightin - 1;
00363
00364 alpha = i * sy - i0;
00365 for (j = 0; j < widthout; j++) {
00366 j0 = (int)(j * sx);
00367 j1 = j0 + 1;
00368 if (j1 >= widthin)
00369 j1 = widthin - 1;
00370
00371 beta = j * sx - j0;
00372
00373
00374 src00 = tempin + (i0 * widthin + j0) * components;
00375 src01 = tempin + (i0 * widthin + j1) * components;
00376 src10 = tempin + (i1 * widthin + j0) * components;
00377 src11 = tempin + (i1 * widthin + j1) * components;
00378
00379 dst = tempout + (i * widthout + j) * components;
00380
00381 for (k = 0; k < components; k++) {
00382 s1 = *src00++ * (1.0 - beta) + *src01++ * beta;
00383 s2 = *src10++ * (1.0 - beta) + *src11++ * beta;
00384 *dst++ = (float)(s1 * (1.0 - alpha) + s2 * alpha);
00385 }
00386 }
00387 }
00388 }
00389 else {
00390
00391 GLint i0, i1;
00392 GLint j0, j1;
00393 GLint ii, jj;
00394 GLfloat sum, *dst;
00395
00396 for (i = 0; i < heightout; i++) {
00397 i0 = (int)(i * sy);
00398 i1 = i0 + 1;
00399 if (i1 >= heightin)
00400 i1 = heightin - 1;
00401
00402 for (j = 0; j < widthout; j++) {
00403 j0 = (int)(j * sx);
00404 j1 = j0 + 1;
00405 if (j1 >= widthin)
00406 j1 = widthin - 1;
00407
00408
00409 dst = tempout + (i * widthout + j) * components;
00410
00411
00412 for (k = 0; k < components; k++) {
00413 sum = 0.0;
00414 for (ii = i0; ii <= i1; ii++) {
00415 for (jj = j0; jj <= j1; jj++) {
00416 sum += *(tempin + (ii * widthin + jj) * components + k);
00417 }
00418 }
00419 sum /= (j1 - j0 + 1) * (i1 - i0 + 1);
00420 *dst++ = sum;
00421 }
00422 }
00423 }
00424 }
00425 #endif
00426
00427
00428
00429
00430
00431 if (packrowlength > 0) {
00432 rowlen = packrowlength;
00433 }
00434 else {
00435 rowlen = widthout;
00436 }
00437 if (sizeout >= packalignment) {
00438 rowstride = components * rowlen;
00439 }
00440 else {
00441 rowstride = packalignment / sizeout
00442 * CEILING(components * rowlen * sizeout, packalignment);
00443 }
00444
00445 dataoutsize =
00446 (heightout) * rowstride +
00447 packskiprows * rowstride +
00448 packskippixels * components;
00449
00450
00451
00452
00453
00454
00455
00456
00457 switch (typeout) {
00458 case GL_UNSIGNED_BYTE:
00459 dataout = malloc( dataoutsize * sizeof(GLubyte) );
00460 if (!dataout) {
00461 free(tempin);
00462 free(tempout);
00463 return GLU_OUT_OF_MEMORY;
00464 }
00465 k = 0;
00466 for (i = 0; i < heightout; i++) {
00467 GLubyte *ubptr = (GLubyte *) dataout
00468 + i * rowstride
00469 + packskiprows * rowstride + packskippixels * components;
00470 for (j = 0; j < widthout * components; j++) {
00471 dummy(j, k + i);
00472 *ubptr++ = (GLubyte) tempout[k++];
00473 }
00474 }
00475 break;
00476 case GL_BYTE:
00477 dataout = malloc( dataoutsize * sizeof(GLbyte) );
00478 if (!dataout) {
00479 free(tempin);
00480 free(tempout);
00481 return GLU_OUT_OF_MEMORY;
00482 }
00483 k = 0;
00484 for (i = 0; i < heightout; i++) {
00485 GLbyte *bptr = (GLbyte *) dataout
00486 + i * rowstride
00487 + packskiprows * rowstride + packskippixels * components;
00488 for (j = 0; j < widthout * components; j++) {
00489 dummy(j, k + i);
00490 *bptr++ = (GLbyte) tempout[k++];
00491 }
00492 }
00493 break;
00494 case GL_UNSIGNED_SHORT:
00495 dataout = malloc( dataoutsize * sizeof(GLushort) );
00496 if (!dataout) {
00497 free(tempin);
00498 free(tempout);
00499 return GLU_OUT_OF_MEMORY;
00500 }
00501 k = 0;
00502 for (i = 0; i < heightout; i++) {
00503 GLushort *usptr = (GLushort *) dataout
00504 + i * rowstride
00505 + packskiprows * rowstride + packskippixels * components;
00506 for (j = 0; j < widthout * components; j++) {
00507 dummy(j, k + i);
00508 *usptr++ = (GLushort) tempout[k++];
00509 }
00510 }
00511 break;
00512 case GL_SHORT:
00513 dataout = malloc( dataoutsize * sizeof(GLshort) );
00514 if (!dataout) {
00515 free(tempin);
00516 free(tempout);
00517 return GLU_OUT_OF_MEMORY;
00518 }
00519 k = 0;
00520 for (i = 0; i < heightout; i++) {
00521 GLshort *sptr = (GLshort *) dataout
00522 + i * rowstride
00523 + packskiprows * rowstride + packskippixels * components;
00524 for (j = 0; j < widthout * components; j++) {
00525 dummy(j, k + i);
00526 *sptr++ = (GLshort) tempout[k++];
00527 }
00528 }
00529 break;
00530 case GL_UNSIGNED_INT:
00531 dataout = malloc( dataoutsize * sizeof(GLuint) );
00532 if (!dataout) {
00533 free(tempin);
00534 free(tempout);
00535 return GLU_OUT_OF_MEMORY;
00536 }
00537 k = 0;
00538 for (i = 0; i < heightout; i++) {
00539 GLuint *uiptr = (GLuint *) dataout
00540 + i * rowstride
00541 + packskiprows * rowstride + packskippixels * components;
00542 for (j = 0; j < widthout * components; j++) {
00543 dummy(j, k + i);
00544 *uiptr++ = (GLuint) tempout[k++];
00545 }
00546 }
00547 break;
00548 case GL_INT:
00549 dataout = malloc( dataoutsize * sizeof(GLint) );
00550 if (!dataout) {
00551 free(tempin);
00552 free(tempout);
00553 return GLU_OUT_OF_MEMORY;
00554 }
00555 k = 0;
00556 for (i = 0; i < heightout; i++) {
00557 GLint *iptr = (GLint *) dataout
00558 + i * rowstride
00559 + packskiprows * rowstride + packskippixels * components;
00560 for (j = 0; j < widthout * components; j++) {
00561 dummy(j, k + i);
00562 *iptr++ = (GLint) tempout[k++];
00563 }
00564 }
00565 break;
00566 case GL_FLOAT:
00567 dataout = malloc( dataoutsize * sizeof(GLfloat) );
00568 if (!dataout) {
00569 free(tempin);
00570 free(tempout);
00571 return GLU_OUT_OF_MEMORY;
00572 }
00573 k = 0;
00574 for (i = 0; i < heightout; i++) {
00575 GLfloat *fptr = (GLfloat *) dataout
00576 + i * rowstride
00577 + packskiprows * rowstride + packskippixels * components;
00578 for (j = 0; j < widthout * components; j++) {
00579 dummy(j, k + i);
00580 *fptr++ = tempout[k++];
00581 }
00582 }
00583 break;
00584 default:
00585 return GLU_INVALID_ENUM;
00586 }
00587
00588
00589
00590 free(tempin);
00591 free(tempout);
00592 *dataoutp = dataout;
00593
00594 return 0;
00595 }
00596
00597
00598
00599
00600
00601
00602 static GLint
00603 ilog2(GLint n)
00604 {
00605 GLint k;
00606
00607 if (n <= 0)
00608 return 0;
00609 for (k = 0; n >>= 1; k++);
00610 return k;
00611 }
00612
00613
00614
00615
00616
00617
00618 static GLint
00619 round2(GLint n)
00620 {
00621 GLint m;
00622
00623 for (m = 1; m < n; m *= 2);
00624
00625
00626 if (m - n <= n - m / 2) {
00627 return m;
00628 }
00629 else {
00630 return m / 2;
00631 }
00632 }
00633
00634
00635
00636
00637
00638
00639 static GLint
00640 bytes_per_pixel(GLenum format, GLenum type)
00641 {
00642 GLint n, m;
00643
00644 switch (format) {
00645 case GL_COLOR_INDEX:
00646 case GL_STENCIL_INDEX:
00647 case GL_DEPTH_COMPONENT:
00648 case GL_RED:
00649 case GL_GREEN:
00650 case GL_BLUE:
00651 case GL_ALPHA:
00652 case GL_LUMINANCE:
00653 n = 1;
00654 break;
00655 case GL_LUMINANCE_ALPHA:
00656 n = 2;
00657 break;
00658 case GL_RGB:
00659 #ifdef GL_BGR
00660 case GL_BGR:
00661 #endif
00662 n = 3;
00663 break;
00664 case GL_RGBA:
00665 #ifdef GL_BGRA
00666 case GL_BGRA:
00667 #endif
00668 #ifdef GL_EXT_abgr
00669 case GL_ABGR_EXT:
00670 #endif
00671 n = 4;
00672 break;
00673 default:
00674 n = 0;
00675 }
00676
00677 switch (type) {
00678 case GL_UNSIGNED_BYTE:
00679 m = sizeof(GLubyte);
00680 break;
00681 case GL_BYTE:
00682 m = sizeof(GLbyte);
00683 break;
00684 case GL_BITMAP:
00685 m = 1;
00686 break;
00687 case GL_UNSIGNED_SHORT:
00688 m = sizeof(GLushort);
00689 break;
00690 case GL_SHORT:
00691 m = sizeof(GLshort);
00692 break;
00693 case GL_UNSIGNED_INT:
00694 m = sizeof(GLuint);
00695 break;
00696 case GL_INT:
00697 m = sizeof(GLint);
00698 break;
00699 case GL_FLOAT:
00700 m = sizeof(GLfloat);
00701 break;
00702 default:
00703 m = 0;
00704 }
00705
00706 return n * m;
00707 }
00708
00709
00710
00711
00712
00713
00714 GLint
00715 glu_Build1DMipmaps(GLenum target, GLint components,
00716 GLsizei width, GLenum format, GLenum type, const void *data)
00717 {
00718 #ifndef USE_TINY_GL
00719 GLubyte *texture;
00720 GLint levels, max_levels;
00721 GLint new_width, max_width;
00722 GLint i, j, k, l;
00723
00724 if (width < 1)
00725 return GLU_INVALID_VALUE;
00726
00727 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_width);
00728 max_levels = ilog2(max_width) + 1;
00729
00730
00731 levels = ilog2(width) + 1;
00732 if (levels > max_levels) {
00733 levels = max_levels;
00734 }
00735
00736 new_width = 1 << (levels - 1);
00737
00738 texture = (GLubyte *) malloc(new_width * components);
00739 if (!texture) {
00740 return GLU_OUT_OF_MEMORY;
00741 }
00742
00743 if (width != new_width) {
00744
00745 switch (type) {
00746 case GL_UNSIGNED_BYTE:
00747 {
00748 GLubyte *ub_data = (GLubyte *) data;
00749 for (i = 0; i < new_width; i++) {
00750 j = i * width / new_width;
00751 for (k = 0; k < components; k++) {
00752 texture[i * components + k] = ub_data[j * components + k];
00753 }
00754 }
00755 }
00756 break;
00757 default:
00758
00759 return GLU_ERROR;
00760 }
00761 }
00762
00763
00764 for (l = 0; l < levels; l++) {
00765 glTexImage1D(GL_TEXTURE_1D, l, components, new_width, 0,
00766 format, GL_UNSIGNED_BYTE, texture);
00767
00768
00769 new_width = new_width / 2;
00770 for (i = 0; i < new_width; i++) {
00771 for (k = 0; k < components; k++) {
00772 GLint sample1, sample2;
00773 sample1 = (GLint) texture[i * 2 * components + k];
00774 sample2 = (GLint) texture[(i * 2 + 1) * components + k];
00775 texture[i * components + k] = (GLubyte) ((sample1 + sample2) / 2);
00776 }
00777 }
00778 }
00779
00780 free(texture);
00781
00782 return 0;
00783 #else
00784 return GLU_ERROR;
00785 #endif
00786 }
00787
00788
00789
00790 GLint
00791 glu_Build2DMipmaps(GLenum target, GLint components,
00792 GLsizei width, GLsizei height, GLenum format,
00793 GLenum type, const void *data)
00794 {
00795 GLint w, h, maxsize;
00796 void *image, *newimage;
00797 GLint neww, newh, level, bpp;
00798 int error;
00799 GLboolean done;
00800 GLint retval = 0;
00801 GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
00802 GLint packrowlength, packalignment, packskiprows, packskippixels;
00803
00804 if (width < 1 || height < 1)
00805 return GLU_INVALID_VALUE;
00806
00807 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
00808
00809 w = round2(width);
00810 if (w > maxsize) {
00811 w = maxsize;
00812 }
00813 h = round2(height);
00814 if (h > maxsize) {
00815 h = maxsize;
00816 }
00817
00818 bpp = bytes_per_pixel(format, type);
00819 if (bpp == 0) {
00820
00821 return GLU_INVALID_ENUM;
00822 }
00823
00824
00825 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpackrowlength);
00826 glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpackalignment);
00827 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &unpackskiprows);
00828 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &unpackskippixels);
00829 glGetIntegerv(GL_PACK_ROW_LENGTH, &packrowlength);
00830 glGetIntegerv(GL_PACK_ALIGNMENT, &packalignment);
00831 glGetIntegerv(GL_PACK_SKIP_ROWS, &packskiprows);
00832 glGetIntegerv(GL_PACK_SKIP_PIXELS, &packskippixels);
00833
00834
00835 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
00836 glPixelStorei(GL_PACK_ALIGNMENT, 1);
00837 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
00838 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
00839
00840 done = GL_FALSE;
00841
00842 if (w != width || h != height) {
00843
00844
00845
00846
00847
00848
00849 error = glu_ScaleImage(format, width, height, type, data,
00850 w, h, type, &image);
00851 if (error) {
00852 retval = error;
00853 done = GL_TRUE;
00854 }
00855 }
00856 else {
00857 image = (void *) data;
00858 }
00859
00860 level = 0;
00861 while (!done) {
00862 if (image != data) {
00863
00864 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00865 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00866 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
00867 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
00868 }
00869
00870 glTexImage2D(target, level, components, w, h, 0, format, type, image);
00871
00872 if (w == 1 && h == 1)
00873 break;
00874
00875 neww = (w < 2) ? 1 : w / 2;
00876 newh = (h < 2) ? 1 : h / 2;
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890 error = glu_ScaleImage(format, w, h, type, image,
00891 neww, newh, type, &newimage);
00892 if (error) {
00893 retval = error;
00894 done = GL_TRUE;
00895 }
00896
00897 if (image != data) {
00898 free(image);
00899 }
00900 image = newimage;
00901
00902 w = neww;
00903 h = newh;
00904 level++;
00905 }
00906
00907 if (image != data) {
00908 free(image);
00909 }
00910
00911
00912 glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackrowlength);
00913 glPixelStorei(GL_UNPACK_ALIGNMENT, unpackalignment);
00914 glPixelStorei(GL_UNPACK_SKIP_ROWS, unpackskiprows);
00915 glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackskippixels);
00916 glPixelStorei(GL_PACK_ROW_LENGTH, packrowlength);
00917 glPixelStorei(GL_PACK_ALIGNMENT, packalignment);
00918 glPixelStorei(GL_PACK_SKIP_ROWS, packskiprows);
00919 glPixelStorei(GL_PACK_SKIP_PIXELS, packskippixels);
00920
00921 return retval;
00922 }
00923
00924