00001
00002
00003
00004
00005
00006 #include <stdlib.h>
00007 #include <stdio.h>
00008 #include <assert.h>
00009 #include <string.h>
00010 #include "zbuffer.h"
00011 #include "pnotify.h"
00012
00013 #ifdef DO_PSTATS
00014 int pixel_count_white_untextured;
00015 int pixel_count_flat_untextured;
00016 int pixel_count_smooth_untextured;
00017 int pixel_count_white_textured;
00018 int pixel_count_flat_textured;
00019 int pixel_count_smooth_textured;
00020 int pixel_count_white_perspective;
00021 int pixel_count_flat_perspective;
00022 int pixel_count_smooth_perspective;
00023 int pixel_count_smooth_multitex2;
00024 int pixel_count_smooth_multitex3;
00025 #endif // DO_PSTATS
00026
00027 ZBuffer *
00028 ZB_open(int xsize, int ysize, int mode,
00029 int nb_colors,
00030 unsigned char *color_indexes,
00031 unsigned int *color_table,
00032 void *frame_buffer) {
00033 ZBuffer *zb;
00034 int size;
00035
00036 zb = (ZBuffer *)gl_malloc(sizeof(ZBuffer));
00037 if (zb == NULL)
00038 return NULL;
00039 memset(zb, 0, sizeof(ZBuffer));
00040
00041
00042 xsize = (xsize + 3) & ~3;
00043
00044 zb->xsize = xsize;
00045 zb->ysize = ysize;
00046 zb->mode = mode;
00047 zb->linesize = (xsize * PSZB + 3) & ~3;
00048
00049 switch (mode) {
00050 #ifdef TGL_FEATURE_8_BITS
00051 case ZB_MODE_INDEX:
00052 ZB_initDither(zb, nb_colors, color_indexes, color_table);
00053 break;
00054 #endif
00055 #ifdef TGL_FEATURE_32_BITS
00056 case ZB_MODE_RGBA:
00057 #endif
00058 #ifdef TGL_FEATURE_24_BITS
00059 case ZB_MODE_RGB24:
00060 #endif
00061 case ZB_MODE_5R6G5B:
00062 zb->nb_colors = 0;
00063 break;
00064 default:
00065 goto error;
00066 }
00067
00068 size = zb->xsize * zb->ysize * sizeof(ZPOINT);
00069
00070 zb->zbuf = (ZPOINT *)gl_malloc(size);
00071 if (zb->zbuf == NULL)
00072 goto error;
00073
00074 if (frame_buffer == NULL) {
00075 zb->pbuf = (PIXEL *)gl_malloc(zb->ysize * zb->linesize);
00076 if (zb->pbuf == NULL) {
00077 gl_free(zb->zbuf);
00078 goto error;
00079 }
00080 zb->frame_buffer_allocated = 1;
00081 } else {
00082 zb->frame_buffer_allocated = 0;
00083 zb->pbuf = (PIXEL *)frame_buffer;
00084 }
00085
00086 return zb;
00087 error:
00088 gl_free(zb);
00089 return NULL;
00090 }
00091
00092 void
00093 ZB_close(ZBuffer * zb) {
00094 #ifdef TGL_FEATURE_8_BITS
00095 if (zb->mode == ZB_MODE_INDEX)
00096 ZB_closeDither(zb);
00097 #endif
00098
00099 if (zb->frame_buffer_allocated)
00100 gl_free(zb->pbuf);
00101
00102 gl_free(zb->zbuf);
00103 gl_free(zb);
00104 }
00105
00106 void
00107 ZB_resize(ZBuffer * zb, void *frame_buffer, int xsize, int ysize) {
00108 int size;
00109
00110
00111 xsize = (xsize + 3) & ~3;
00112
00113 zb->xsize = xsize;
00114 zb->ysize = ysize;
00115 zb->linesize = (xsize * PSZB + 3) & ~3;
00116
00117 size = zb->xsize * zb->ysize * sizeof(ZPOINT);
00118 gl_free(zb->zbuf);
00119 zb->zbuf = (ZPOINT *)gl_malloc(size);
00120
00121 if (zb->frame_buffer_allocated)
00122 gl_free(zb->pbuf);
00123
00124 if (frame_buffer == NULL) {
00125 zb->pbuf = (PIXEL *)gl_malloc(zb->ysize * zb->linesize);
00126 zb->frame_buffer_allocated = 1;
00127 } else {
00128 zb->pbuf = (PIXEL *)frame_buffer;
00129 zb->frame_buffer_allocated = 0;
00130 }
00131 }
00132
00133 static void
00134 ZB_copyBuffer(const ZBuffer * zb,
00135 void *buf,
00136 int linesize) {
00137 unsigned char *p1;
00138 PIXEL *q;
00139 int y, n;
00140
00141 q = zb->pbuf;
00142 p1 = (unsigned char *)buf;
00143 n = zb->xsize * PSZB;
00144 for (y = 0; y < zb->ysize; y++) {
00145 memcpy(p1, q, n);
00146 p1 += linesize;
00147 q = (PIXEL *) ((char *) q + zb->linesize);
00148 }
00149 }
00150
00151 static void
00152 ZB_copyBufferNoAlpha(const ZBuffer * zb, void *buf, int linesize) {
00153 const PIXEL *q = zb->pbuf;
00154 PIXEL *p = (PIXEL *)buf;
00155 int xsize = zb->xsize;
00156 for (int y = 0; y < zb->ysize; ++y) {
00157 const PIXEL *q1 = q;
00158 PIXEL *p1 = p;
00159 PIXEL *p2 = p1 + xsize;
00160 while (p1 < p2) {
00161
00162 #ifdef WORDS_BIGENDIAN
00163 *p1 = *q1 | 0x000000ff;
00164 #else
00165 *p1 = *q1 | 0xff000000;
00166 #endif
00167 ++p1;
00168 ++q1;
00169 }
00170 p = (PIXEL *) ((char *) p + linesize);
00171 q = (const PIXEL *) ((const char *) q + zb->linesize);
00172 }
00173 }
00174
00175 #define RGB32_TO_RGB16(v) \
00176 (((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3))
00177
00178
00179 static void ZB_copyFrameBuffer5R6G5B(const ZBuffer * zb,
00180 void *buf, int linesize)
00181 {
00182 PIXEL *q;
00183 unsigned short *p, *p1;
00184 int y, n;
00185
00186 q = zb->pbuf;
00187 p1 = (unsigned short *) buf;
00188
00189 for (y = 0; y < zb->ysize; y++) {
00190 p = p1;
00191 n = zb->xsize >> 2;
00192 do {
00193 p[0] = RGB32_TO_RGB16(q[0]);
00194 p[1] = RGB32_TO_RGB16(q[1]);
00195 p[2] = RGB32_TO_RGB16(q[2]);
00196 p[3] = RGB32_TO_RGB16(q[3]);
00197 q += 4;
00198 p += 4;
00199 } while (--n > 0);
00200 p1 = (unsigned short *)((char *)p1 + linesize);
00201 }
00202 }
00203
00204
00205 static void ZB_copyFrameBufferRGB24(const ZBuffer * zb,
00206 void *buf, int linesize)
00207 {
00208 PIXEL *q;
00209 unsigned char *p, *p1;
00210 int y, n;
00211
00212 fprintf(stderr, "copyFrameBufferRGB24\n");
00213
00214 q = zb->pbuf;
00215 p1 = (unsigned char *) buf;
00216
00217 for (y = 0; y < zb->ysize; y++) {
00218 p = p1;
00219 n = zb->xsize;
00220 do {
00221 p[0] = q[0];
00222 p[1] = q[1];
00223 p[2] = q[2];
00224 q += 4;
00225 p += 3;
00226 } while (--n > 0);
00227 p1 += linesize;
00228 }
00229 }
00230
00231 void
00232 ZB_copyFrameBuffer(const ZBuffer * zb, void *buf,
00233 int linesize) {
00234 switch (zb->mode) {
00235 #ifdef TGL_FEATURE_16_BITS
00236 case ZB_MODE_5R6G5B:
00237 ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
00238 break;
00239 #endif
00240 #ifdef TGL_FEATURE_24_BITS
00241 case ZB_MODE_RGB24:
00242 ZB_copyFrameBufferRGB24(zb, buf, linesize);
00243 break;
00244 #endif
00245 #ifdef TGL_FEATURE_32_BITS
00246 case ZB_MODE_RGBA:
00247 ZB_copyBuffer(zb, buf, linesize);
00248 break;
00249 #endif
00250 default:
00251 assert(0);
00252 }
00253 }
00254
00255 void
00256 ZB_copyFrameBufferNoAlpha(const ZBuffer * zb, void *buf,
00257 int linesize) {
00258 switch (zb->mode) {
00259 #ifdef TGL_FEATURE_16_BITS
00260 case ZB_MODE_5R6G5B:
00261 ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
00262 break;
00263 #endif
00264 #ifdef TGL_FEATURE_24_BITS
00265 case ZB_MODE_RGB24:
00266 ZB_copyFrameBufferRGB24(zb, buf, linesize);
00267 break;
00268 #endif
00269 #ifdef TGL_FEATURE_32_BITS
00270 case ZB_MODE_RGBA:
00271 ZB_copyBufferNoAlpha(zb, buf, linesize);
00272 break;
00273 #endif
00274 default:
00275 assert(0);
00276 }
00277 }
00278
00279
00280
00281 void ZB_zoomFrameBuffer(ZBuffer *dest, int dest_xmin, int dest_ymin, int dest_xsize, int dest_ysize,
00282 const ZBuffer *source, int source_xmin, int source_ymin, int source_xsize, int source_ysize) {
00283 int tyinc = dest->linesize / PSZB;
00284 int fyinc = source->linesize / PSZB;
00285
00286 int fyt = 0;
00287 for (int ty = 0; ty < dest_ysize; ++ty) {
00288 int fy = fyt / dest_ysize;
00289 fyt += source_ysize;
00290
00291 PIXEL *tp = dest->pbuf + dest_xmin + (dest_ymin + ty) * tyinc;
00292 PIXEL *fp = source->pbuf + source_xmin + (source_ymin + fy) * fyinc;
00293 ZPOINT *tz = dest->zbuf + dest_xmin + (dest_ymin + ty) * dest->xsize;
00294 ZPOINT *fz = source->zbuf + source_xmin + (source_ymin + fy) * source->xsize;
00295 int fxt = 0;
00296 for (int tx = 0; tx < dest_xsize; ++tx) {
00297 int fx = fxt / dest_xsize;
00298 fxt += source_xsize;
00299
00300 tp[tx] = fp[fx];
00301 tz[tx] = fz[fx];
00302 }
00303 }
00304 }
00305
00306
00307
00308
00309
00310 void
00311 memset_s(void *adr, int val, int count) {
00312 int i, n, v;
00313 unsigned int *p;
00314 unsigned short *q;
00315
00316 p = (unsigned int *)adr;
00317 v = val | (val << 16);
00318
00319 n = count >> 3;
00320 for (i = 0; i < n; i++) {
00321 p[0] = v;
00322 p[1] = v;
00323 p[2] = v;
00324 p[3] = v;
00325 p += 4;
00326 }
00327
00328 q = (unsigned short *) p;
00329 n = count & 7;
00330 for (i = 0; i < n; i++)
00331 *q++ = val;
00332 }
00333
00334 void
00335 memset_l(void *adr, int val, int count) {
00336 int i, n, v;
00337 unsigned int *p;
00338
00339 p = (unsigned int *)adr;
00340 v = val;
00341 n = count >> 2;
00342 for (i = 0; i < n; i++) {
00343 p[0] = v;
00344 p[1] = v;
00345 p[2] = v;
00346 p[3] = v;
00347 p += 4;
00348 }
00349
00350 n = count & 3;
00351 for (i = 0; i < n; i++)
00352 *p++ = val;
00353 }
00354
00355
00356 void
00357 memset_RGB24(void *adr,int r, int v, int b,long count) {
00358 long i, n;
00359 register long v1,v2,v3,*pt=(long *)(adr);
00360 unsigned char *p,R=(unsigned char)r,V=(unsigned char)v,B=(unsigned char)b;
00361
00362 p=(unsigned char *)adr;
00363 *p++=R;
00364 *p++=V;
00365 *p++=B;
00366 *p++=R;
00367 *p++=V;
00368 *p++=B;
00369 *p++=R;
00370 *p++=V;
00371 *p++=B;
00372 *p++=R;
00373 *p++=V;
00374 *p++=B;
00375 v1=*pt++;
00376 v2=*pt++;
00377 v3=*pt++;
00378 n = count >> 2;
00379 for(i=1;i<n;i++) {
00380 *pt++=v1;
00381 *pt++=v2;
00382 *pt++=v3;
00383 }
00384 }
00385
00386 void
00387 ZB_clear(ZBuffer * zb, int clear_z, ZPOINT z,
00388 int clear_color, unsigned int r, unsigned int g, unsigned int b, unsigned int a) {
00389 unsigned int color;
00390 int y;
00391 PIXEL *pp;
00392
00393 if (clear_z) {
00394 memset(zb->zbuf, 0, zb->xsize * zb->ysize * sizeof(ZPOINT));
00395 }
00396 if (clear_color) {
00397 color = RGBA_TO_PIXEL(r, g, b, a);
00398 pp = zb->pbuf;
00399 for (y = 0; y < zb->ysize; y++) {
00400 memset_l(pp, color, zb->xsize);
00401 pp = (PIXEL *) ((char *) pp + zb->linesize);
00402 }
00403 }
00404 }
00405
00406 void
00407 ZB_clear_viewport(ZBuffer * zb, int clear_z, ZPOINT z,
00408 int clear_color, unsigned int r, unsigned int g, unsigned int b, unsigned int a,
00409 int xmin, int ymin, int xsize, int ysize) {
00410 unsigned int color;
00411 int y;
00412 PIXEL *pp;
00413 ZPOINT *zz;
00414
00415 nassertv(xmin >= 0 && xmin < zb->xsize &&
00416 ymin >= 0 && ymin < zb->ysize &&
00417 xmin + xsize >= 0 && xmin + xsize <= zb->xsize &&
00418 ymin + ysize >= 0 && ymin + ysize <= zb->ysize);
00419
00420 if (clear_z) {
00421 zz = zb->zbuf + xmin + ymin * zb->xsize;
00422 for (y = 0; y < ysize; ++y) {
00423 memset(zz, 0, xsize * sizeof(ZPOINT));
00424 zz += zb->xsize;
00425 }
00426 }
00427 if (clear_color) {
00428 color = RGBA_TO_PIXEL(r, g, b, a);
00429 pp = zb->pbuf + xmin + ymin * (zb->linesize / PSZB);
00430 for (y = 0; y < ysize; ++y) {
00431 memset_l(pp, color, xsize);
00432 pp += zb->xsize;
00433 }
00434 }
00435 }
00436
00437 #define ZB_ST_FRAC_HIGH (1 << ZB_POINT_ST_FRAC_BITS)
00438 #define ZB_ST_FRAC_MASK (ZB_ST_FRAC_HIGH - 1)
00439
00440 #define LINEAR_FILTER_BITSIZE(c1, c2, f, bitsize) \
00441 ((((c2) * (f)) >> bitsize) + (((c1) * ((1 << bitsize) - (f))) >> bitsize))
00442
00443 #define LINEAR_FILTER(c1, c2, f) \
00444 LINEAR_FILTER_BITSIZE(c1, c2, f, ZB_POINT_ST_FRAC_BITS)
00445
00446 #define BILINEAR_FILTER(c1, c2, c3, c4, sf, tf) \
00447 (LINEAR_FILTER(LINEAR_FILTER(c1, c2, sf), LINEAR_FILTER(c3, c4, sf), tf))
00448
00449
00450
00451 PIXEL
00452 lookup_texture_nearest(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx) {
00453 return ZB_LOOKUP_TEXTURE_NEAREST(texture_def, s, t);
00454 }
00455
00456
00457 PIXEL
00458 lookup_texture_bilinear(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx) {
00459 PIXEL p1, p2, p3, p4;
00460 int sf, tf;
00461 int r, g, b, a;
00462
00463 p1 = ZB_LOOKUP_TEXTURE_NEAREST(texture_def, s - ZB_ST_FRAC_HIGH, t - ZB_ST_FRAC_HIGH);
00464 p2 = ZB_LOOKUP_TEXTURE_NEAREST(texture_def, s, t - ZB_ST_FRAC_HIGH);
00465 sf = s & ZB_ST_FRAC_MASK;
00466
00467 p3 = ZB_LOOKUP_TEXTURE_NEAREST(texture_def, s - ZB_ST_FRAC_HIGH, t);
00468 p4 = ZB_LOOKUP_TEXTURE_NEAREST(texture_def, s, t);
00469 tf = t & ZB_ST_FRAC_MASK;
00470
00471 r = BILINEAR_FILTER(PIXEL_R(p1), PIXEL_R(p2), PIXEL_R(p3), PIXEL_R(p4), sf, tf);
00472 g = BILINEAR_FILTER(PIXEL_G(p1), PIXEL_G(p2), PIXEL_G(p3), PIXEL_G(p4), sf, tf);
00473 b = BILINEAR_FILTER(PIXEL_B(p1), PIXEL_B(p2), PIXEL_B(p3), PIXEL_B(p4), sf, tf);
00474 a = BILINEAR_FILTER(PIXEL_A(p1), PIXEL_A(p2), PIXEL_A(p3), PIXEL_A(p4), sf, tf);
00475
00476 return RGBA_TO_PIXEL(r, g, b, a);
00477 }
00478
00479
00480
00481 PIXEL
00482 lookup_texture_mipmap_nearest(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx) {
00483 return ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s, t, level);
00484 }
00485
00486
00487 PIXEL
00488 lookup_texture_mipmap_linear(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx) {
00489 PIXEL p1, p2;
00490 int r, g, b, a;
00491
00492 p1 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s, t, level - 1);
00493 p2 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s, t, level);
00494
00495 unsigned int bitsize = (level - 1) + ZB_POINT_ST_FRAC_BITS;
00496 r = LINEAR_FILTER_BITSIZE(PIXEL_R(p1), PIXEL_R(p2), level_dx, bitsize);
00497 g = LINEAR_FILTER_BITSIZE(PIXEL_G(p1), PIXEL_G(p2), level_dx, bitsize);
00498 b = LINEAR_FILTER_BITSIZE(PIXEL_B(p1), PIXEL_B(p2), level_dx, bitsize);
00499 a = LINEAR_FILTER_BITSIZE(PIXEL_A(p1), PIXEL_A(p2), level_dx, bitsize);
00500
00501 return RGBA_TO_PIXEL(r, g, b, a);
00502 }
00503
00504
00505 PIXEL
00506 lookup_texture_mipmap_bilinear(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx) {
00507 PIXEL p1, p2, p3, p4;
00508 int sf, tf;
00509 int r, g, b, a;
00510
00511 p1 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s - ZB_ST_FRAC_HIGH, t - ZB_ST_FRAC_HIGH, level);
00512 p2 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s, t - ZB_ST_FRAC_HIGH, level);
00513 sf = (s >> level) & ZB_ST_FRAC_MASK;
00514
00515 p3 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s - ZB_ST_FRAC_HIGH, t, level);
00516 p4 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s, t, level);
00517 tf = (t >> level) & ZB_ST_FRAC_MASK;
00518
00519 r = BILINEAR_FILTER(PIXEL_R(p1), PIXEL_R(p2), PIXEL_R(p3), PIXEL_R(p4), sf, tf);
00520 g = BILINEAR_FILTER(PIXEL_G(p1), PIXEL_G(p2), PIXEL_G(p3), PIXEL_G(p4), sf, tf);
00521 b = BILINEAR_FILTER(PIXEL_B(p1), PIXEL_B(p2), PIXEL_B(p3), PIXEL_B(p4), sf, tf);
00522 a = BILINEAR_FILTER(PIXEL_A(p1), PIXEL_A(p2), PIXEL_A(p3), PIXEL_A(p4), sf, tf);
00523
00524 return RGBA_TO_PIXEL(r, g, b, a);
00525 }
00526
00527
00528
00529 PIXEL
00530 lookup_texture_mipmap_trilinear(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx) {
00531 PIXEL p1a, p2a;
00532
00533 {
00534 PIXEL p1, p2, p3, p4;
00535 int sf, tf;
00536 int r, g, b, a;
00537
00538 p1 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s - ZB_ST_FRAC_HIGH, t - ZB_ST_FRAC_HIGH, level - 1);
00539 p2 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s, t - ZB_ST_FRAC_HIGH, level - 1);
00540 sf = (s >> (level - 1)) & ZB_ST_FRAC_MASK;
00541
00542 p3 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s - ZB_ST_FRAC_HIGH, t, level - 1);
00543 p4 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s, t, level - 1);
00544 tf = (t >> (level - 1)) & ZB_ST_FRAC_MASK;
00545
00546 r = BILINEAR_FILTER(PIXEL_R(p1), PIXEL_R(p2), PIXEL_R(p3), PIXEL_R(p4), sf, tf);
00547 g = BILINEAR_FILTER(PIXEL_G(p1), PIXEL_G(p2), PIXEL_G(p3), PIXEL_G(p4), sf, tf);
00548 b = BILINEAR_FILTER(PIXEL_B(p1), PIXEL_B(p2), PIXEL_B(p3), PIXEL_B(p4), sf, tf);
00549 a = BILINEAR_FILTER(PIXEL_A(p1), PIXEL_A(p2), PIXEL_A(p3), PIXEL_A(p4), sf, tf);
00550 p1a = RGBA_TO_PIXEL(r, g, b, a);
00551 }
00552
00553 {
00554 PIXEL p1, p2, p3, p4;
00555 int sf, tf;
00556 int r, g, b, a;
00557
00558 p1 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s - ZB_ST_FRAC_HIGH, t - ZB_ST_FRAC_HIGH, level);
00559 p2 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s, t - ZB_ST_FRAC_HIGH, level);
00560 sf = (s >> level) & ZB_ST_FRAC_MASK;
00561
00562 p3 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s - ZB_ST_FRAC_HIGH, t, level);
00563 p4 = ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s, t, level);
00564 tf = (t >> level) & ZB_ST_FRAC_MASK;
00565
00566 r = BILINEAR_FILTER(PIXEL_R(p1), PIXEL_R(p2), PIXEL_R(p3), PIXEL_R(p4), sf, tf);
00567 g = BILINEAR_FILTER(PIXEL_G(p1), PIXEL_G(p2), PIXEL_G(p3), PIXEL_G(p4), sf, tf);
00568 b = BILINEAR_FILTER(PIXEL_B(p1), PIXEL_B(p2), PIXEL_B(p3), PIXEL_B(p4), sf, tf);
00569 a = BILINEAR_FILTER(PIXEL_A(p1), PIXEL_A(p2), PIXEL_A(p3), PIXEL_A(p4), sf, tf);
00570 p2a = RGBA_TO_PIXEL(r, g, b, a);
00571 }
00572
00573 int r, g, b, a;
00574 unsigned int bitsize = (level - 1) + ZB_POINT_ST_FRAC_BITS;
00575 r = LINEAR_FILTER_BITSIZE(PIXEL_R(p1a), PIXEL_R(p2a), level_dx, bitsize);
00576 g = LINEAR_FILTER_BITSIZE(PIXEL_G(p1a), PIXEL_G(p2a), level_dx, bitsize);
00577 b = LINEAR_FILTER_BITSIZE(PIXEL_B(p1a), PIXEL_B(p2a), level_dx, bitsize);
00578 a = LINEAR_FILTER_BITSIZE(PIXEL_A(p1a), PIXEL_A(p2a), level_dx, bitsize);
00579
00580 return RGBA_TO_PIXEL(r, g, b, a);
00581 }
00582
00583
00584
00585
00586 PIXEL
00587 apply_wrap_general_minfilter(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx) {
00588 s = (*texture_def->tex_wrap_u_func)(s, texture_def->s_max);
00589 t = (*texture_def->tex_wrap_v_func)(t, texture_def->t_max);
00590 return (*texture_def->tex_minfilter_func_impl)(texture_def, s, t, level, level_dx);
00591 }
00592
00593 PIXEL
00594 apply_wrap_general_magfilter(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx) {
00595 s = (*texture_def->tex_wrap_u_func)(s, texture_def->s_max);
00596 t = (*texture_def->tex_wrap_v_func)(t, texture_def->t_max);
00597 return (*texture_def->tex_magfilter_func_impl)(texture_def, s, t, level, level_dx);
00598 }
00599
00600
00601
00602 PIXEL
00603 apply_wrap_border_color_minfilter(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx) {
00604 if (s < 0 || t < 0 || s > texture_def->s_max || t > texture_def->t_max) {
00605 return texture_def->border_color;
00606 }
00607 return (*texture_def->tex_minfilter_func_impl)(texture_def, s, t, level, level_dx);
00608 }
00609
00610 PIXEL
00611 apply_wrap_border_color_magfilter(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx) {
00612 if (s < 0 || t < 0 || s > texture_def->s_max || t > texture_def->t_max) {
00613 return texture_def->border_color;
00614 }
00615 return (*texture_def->tex_magfilter_func_impl)(texture_def, s, t, level, level_dx);
00616 }
00617
00618
00619
00620
00621 PIXEL
00622 apply_wrap_clamp_minfilter(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx) {
00623 s = min(max(s, 0), texture_def->s_max);
00624 t = min(max(t, 0), texture_def->t_max);
00625 return (*texture_def->tex_minfilter_func_impl)(texture_def, s, t, level, level_dx);
00626 }
00627
00628 PIXEL
00629 apply_wrap_clamp_magfilter(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx) {
00630 s = min(max(s, 0), texture_def->s_max);
00631 t = min(max(t, 0), texture_def->t_max);
00632 return (*texture_def->tex_magfilter_func_impl)(texture_def, s, t, level, level_dx);
00633 }
00634
00635 int
00636 texcoord_clamp(int coord, int max_coord) {
00637 return min(max(coord, 0), max_coord);
00638 }
00639
00640 int
00641 texcoord_repeat(int coord, int max_coord) {
00642 return coord;
00643 }
00644
00645 int
00646 texcoord_mirror(int coord, int max_coord) {
00647 if ((coord & ((max_coord << 1) - 1)) > max_coord) {
00648 coord = (max_coord << 1) - coord;
00649 }
00650 return coord;
00651 }
00652
00653 int
00654 texcoord_mirror_once(int coord, int max_coord) {
00655 if (coord > max_coord) {
00656 coord = (max_coord << 1) - coord;
00657 }
00658 return max(coord, 0);
00659 }