⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s_texfilter.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
      {									\         /* s limited to [0,1] */					\         /* i limited to [0,size-1] */					\         const GLfloat u = FABSF(S);					\         if (u <= 0.0F)							\            I = 0;							\         else if (u >= 1.0F)						\            I = SIZE - 1;						\         else								\            I = IFLOOR(u * SIZE);					\      }									\      break;								\   case GL_MIRROR_CLAMP_TO_EDGE_EXT:					\      {									\         /* s limited to [min,max] */					\         /* i limited to [0, size-1] */					\         const GLfloat min = 1.0F / (2.0F * SIZE);			\         const GLfloat max = 1.0F - min;				\         const GLfloat u = FABSF(S);					\         if (u < min)							\            I = 0;							\         else if (u > max)						\            I = SIZE - 1;						\         else								\            I = IFLOOR(u * SIZE);					\      }									\      break;								\   case GL_MIRROR_CLAMP_TO_BORDER_EXT:					\      {									\         /* s limited to [min,max] */					\         /* i limited to [0, size-1] */					\         const GLfloat min = -1.0F / (2.0F * SIZE);			\         const GLfloat max = 1.0F - min;				\         const GLfloat u = FABSF(S);					\         if (u < min)							\            I = -1;							\         else if (u > max)						\            I = SIZE;							\         else								\            I = IFLOOR(u * SIZE);					\      }									\      break;								\   case GL_CLAMP:							\      /* s limited to [0,1] */						\      /* i limited to [0,size-1] */					\      if (S <= 0.0F)							\         I = 0;								\      else if (S >= 1.0F)						\         I = SIZE - 1;							\      else								\         I = IFLOOR(S * SIZE);						\      break;								\   default:								\      _mesa_problem(ctx, "Bad wrap mode");				\      return;								\   }									\}/* Power of two image sizes only */#define COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(S, U, SIZE, I0, I1)	\{									\   U = S * SIZE - 0.5F;							\   I0 = IFLOOR(U) & (SIZE - 1);						\   I1 = (I0 + 1) & (SIZE - 1);						\}/** * For linear interpolation between mipmap levels N and N+1, this function * computes N. */static INLINE GLintlinear_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda){   if (lambda < 0.0F)      return tObj->BaseLevel;   else if (lambda > tObj->_MaxLambda)      return (GLint) (tObj->BaseLevel + tObj->_MaxLambda);   else      return (GLint) (tObj->BaseLevel + lambda);}/** * Compute the nearest mipmap level to take texels from. */static INLINE GLintnearest_mipmap_level(const struct gl_texture_object *tObj, GLfloat lambda){   GLfloat l;   GLint level;   if (lambda <= 0.5F)      l = 0.0F;   else if (lambda > tObj->_MaxLambda + 0.4999F)      l = tObj->_MaxLambda + 0.4999F;   else      l = lambda;   level = (GLint) (tObj->BaseLevel + l + 0.5F);   if (level > tObj->_MaxLevel)      level = tObj->_MaxLevel;   return level;}/* * Note, the FRAC macro has to work perfectly.  Otherwise you'll sometimes * see 1-pixel bands of improperly weighted linear-filtered textures. * The tests/texwrap.c demo is a good test. * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). */#define FRAC(f)  ((f) - IFLOOR(f))/* * Bitflags for texture border color sampling. */#define I0BIT   1#define I1BIT   2#define J0BIT   4#define J1BIT   8#define K0BIT  16#define K1BIT  32/* * The lambda[] array values are always monotonic.  Either the whole span * will be minified, magnified, or split between the two.  This function * determines the subranges in [0, n-1] that are to be minified or magnified. */static INLINE voidcompute_min_mag_ranges(const struct gl_texture_object *tObj,                       GLuint n, const GLfloat lambda[],                       GLuint *minStart, GLuint *minEnd,                       GLuint *magStart, GLuint *magEnd){   GLfloat minMagThresh;   /* we shouldn't be here if minfilter == magfilter */   ASSERT(tObj->MinFilter != tObj->MagFilter);   /* This bit comes from the OpenGL spec: */   if (tObj->MagFilter == GL_LINEAR       && (tObj->MinFilter == GL_NEAREST_MIPMAP_NEAREST ||           tObj->MinFilter == GL_NEAREST_MIPMAP_LINEAR)) {      minMagThresh = 0.5F;   }   else {      minMagThresh = 0.0F;   }#if 0   /* DEBUG CODE: Verify that lambda[] is monotonic.    * We can't really use this because the inaccuracy in the LOG2 function    * causes this test to fail, yet the resulting texturing is correct.    */   if (n > 1) {      GLuint i;      printf("lambda delta = %g\n", lambda[0] - lambda[n-1]);      if (lambda[0] >= lambda[n-1]) { /* decreasing */         for (i = 0; i < n - 1; i++) {            ASSERT((GLint) (lambda[i] * 10) >= (GLint) (lambda[i+1] * 10));         }      }      else { /* increasing */         for (i = 0; i < n - 1; i++) {            ASSERT((GLint) (lambda[i] * 10) <= (GLint) (lambda[i+1] * 10));         }      }   }#endif /* DEBUG */   if (lambda[0] <= minMagThresh && (n <= 1 || lambda[n-1] <= minMagThresh)) {      /* magnification for whole span */      *magStart = 0;      *magEnd = n;      *minStart = *minEnd = 0;   }   else if (lambda[0] > minMagThresh && (n <=1 || lambda[n-1] > minMagThresh)) {      /* minification for whole span */      *minStart = 0;      *minEnd = n;      *magStart = *magEnd = 0;   }   else {      /* a mix of minification and magnification */      GLuint i;      if (lambda[0] > minMagThresh) {         /* start with minification */         for (i = 1; i < n; i++) {            if (lambda[i] <= minMagThresh)               break;         }         *minStart = 0;         *minEnd = i;         *magStart = i;         *magEnd = n;      }      else {         /* start with magnification */         for (i = 1; i < n; i++) {            if (lambda[i] > minMagThresh)               break;         }         *magStart = 0;         *magEnd = i;         *minStart = i;         *minEnd = n;      }   }#if 0   /* Verify the min/mag Start/End values    * We don't use this either (see above)    */   {      GLint i;      for (i = 0; i < n; i++) {         if (lambda[i] > minMagThresh) {            /* minification */            ASSERT(i >= *minStart);            ASSERT(i < *minEnd);         }         else {            /* magnification */            ASSERT(i >= *magStart);            ASSERT(i < *magEnd);         }      }   }#endif}/**********************************************************************//*                    1-D Texture Sampling Functions                  *//**********************************************************************//* * Return the texture sample for coordinate (s) using GL_NEAREST filter. */static voidsample_1d_nearest(GLcontext *ctx,                  const struct gl_texture_object *tObj,                  const struct gl_texture_image *img,                  const GLfloat texcoord[4], GLchan rgba[4]){   const GLint width = img->Width2;  /* without border, power of two */   GLint i;   COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i);   /* skip over the border, if any */   i += img->Border;   if (i < 0 || i >= (GLint) img->Width) {      /* Need this test for GL_CLAMP_TO_BORDER mode */      COPY_CHAN4(rgba, tObj->_BorderChan);   }   else {      img->FetchTexelc(img, i, 0, 0, rgba);   }}/* * Return the texture sample for coordinate (s) using GL_LINEAR filter. */static voidsample_1d_linear(GLcontext *ctx,                 const struct gl_texture_object *tObj,                 const struct gl_texture_image *img,                 const GLfloat texcoord[4], GLchan rgba[4]){   const GLint width = img->Width2;   GLint i0, i1;   GLfloat u;   GLbitfield useBorderColor = 0x0;   GLfloat a;   GLchan t0[4], t1[4];  /* texels */   COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1);   if (img->Border) {      i0 += img->Border;      i1 += img->Border;   }   else {      if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;      if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;   }   /* fetch texel colors */   if (useBorderColor & I0BIT) {      COPY_CHAN4(t0, tObj->_BorderChan);   }   else {      img->FetchTexelc(img, i0, 0, 0, t0);   }   if (useBorderColor & I1BIT) {      COPY_CHAN4(t1, tObj->_BorderChan);   }   else {      img->FetchTexelc(img, i1, 0, 0, t1);   }   a = FRAC(u);   lerp_rgba(rgba, a, t0, t1);}static voidsample_1d_nearest_mipmap_nearest(GLcontext *ctx,                                 const struct gl_texture_object *tObj,                                 GLuint n, const GLfloat texcoord[][4],                                 const GLfloat lambda[], GLchan rgba[][4]){   GLuint i;   ASSERT(lambda != NULL);   for (i = 0; i < n; i++) {      GLint level = nearest_mipmap_level(tObj, lambda[i]);      sample_1d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);   }}static voidsample_1d_linear_mipmap_nearest(GLcontext *ctx,                                const struct gl_texture_object *tObj,                                GLuint n, const GLfloat texcoord[][4],                                const GLfloat lambda[], GLchan rgba[][4]){   GLuint i;   ASSERT(lambda != NULL);   for (i = 0; i < n; i++) {      GLint level = nearest_mipmap_level(tObj, lambda[i]);      sample_1d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);   }}static voidsample_1d_nearest_mipmap_linear(GLcontext *ctx,                                const struct gl_texture_object *tObj,                                GLuint n, const GLfloat texcoord[][4],                                const GLfloat lambda[], GLchan rgba[][4]){   GLuint i;   ASSERT(lambda != NULL);   for (i = 0; i < n; i++) {      GLint level = linear_mipmap_level(tObj, lambda[i]);      if (level >= tObj->_MaxLevel) {         sample_1d_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],                           texcoord[i], rgba[i]);      }      else {         GLchan t0[4], t1[4];         const GLfloat f = FRAC(lambda[i]);         sample_1d_nearest(ctx, tObj, tObj->Image[0][level  ], texcoord[i], t0);         sample_1d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);         lerp_rgba(rgba[i], f, t0, t1);      }   }}static voidsample_1d_linear_mipmap_linear(GLcontext *ctx,                               const struct gl_texture_object *tObj,                               GLuint n, const GLfloat texcoord[][4],                               const GLfloat lambda[], GLchan rgba[][4]){   GLuint i;   ASSERT(lambda != NULL);   for (i = 0; i < n; i++) {      GLint level = linear_mipmap_level(tObj, lambda[i]);      if (level >= tObj->_MaxLevel) {         sample_1d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],                          texcoord[i], rgba[i]);      }      else {         GLchan t0[4], t1[4];         const GLfloat f = FRAC(lambda[i]);         sample_1d_linear(ctx, tObj, tObj->Image[0][level  ], texcoord[i], t0);         sample_1d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);         lerp_rgba(rgba[i], f, t0, t1);      }   }}static voidsample_nearest_1d( GLcontext *ctx,                   const struct gl_texture_object *tObj, GLuint n,                   const GLfloat texcoords[][4], const GLfloat lambda[],                   GLchan rgba[][4] ){   GLuint i;   struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];   (void) lambda;   for (i=0;i<n;i++) {      sample_1d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);   }}static void

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -