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

📄 s_texfilter.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
                  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_3d_linear(ctx, tObj, image, texcoords[i], rgba[i]);   }}/* * Given an (s,t,r) texture coordinate and lambda (level of detail) value, * return a texture sample. */static voidsample_lambda_3d( GLcontext *ctx,                  const struct gl_texture_object *tObj, GLuint n,                  const GLfloat texcoords[][4], const GLfloat lambda[],                  GLchan rgba[][4] ){   GLuint minStart, minEnd;  /* texels with minification */   GLuint magStart, magEnd;  /* texels with magnification */   GLuint i;   ASSERT(lambda != NULL);   compute_min_mag_ranges(tObj, n, lambda,                          &minStart, &minEnd, &magStart, &magEnd);   if (minStart < minEnd) {      /* do the minified texels */      GLuint m = minEnd - minStart;      switch (tObj->MinFilter) {      case GL_NEAREST:         for (i = minStart; i < minEnd; i++)            sample_3d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],                              texcoords[i], rgba[i]);         break;      case GL_LINEAR:         for (i = minStart; i < minEnd; i++)            sample_3d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],                             texcoords[i], rgba[i]);         break;      case GL_NEAREST_MIPMAP_NEAREST:         sample_3d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,                                          lambda + minStart, rgba + minStart);         break;      case GL_LINEAR_MIPMAP_NEAREST:         sample_3d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,                                         lambda + minStart, rgba + minStart);         break;      case GL_NEAREST_MIPMAP_LINEAR:         sample_3d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,                                         lambda + minStart, rgba + minStart);         break;      case GL_LINEAR_MIPMAP_LINEAR:         sample_3d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,                                        lambda + minStart, rgba + minStart);         break;      default:         _mesa_problem(ctx, "Bad min filter in sample_3d_texture");         return;      }   }   if (magStart < magEnd) {      /* do the magnified texels */      switch (tObj->MagFilter) {      case GL_NEAREST:         for (i = magStart; i < magEnd; i++)            sample_3d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel],                              texcoords[i], rgba[i]);         break;      case GL_LINEAR:         for (i = magStart; i < magEnd; i++)            sample_3d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel],                             texcoords[i], rgba[i]);         break;      default:         _mesa_problem(ctx, "Bad mag filter in sample_3d_texture");         return;      }   }}/**********************************************************************//*                Texture Cube Map Sampling Functions                 *//**********************************************************************//** * Choose one of six sides of a texture cube map given the texture * coord (rx,ry,rz).  Return pointer to corresponding array of texture * images. */static const struct gl_texture_image **choose_cube_face(const struct gl_texture_object *texObj,                 const GLfloat texcoord[4], GLfloat newCoord[4]){   /*      major axis      direction     target                             sc     tc    ma      ----------    -------------------------------    ---    ---   ---       +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx       -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx       +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry       -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry       +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz       -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz   */   const GLfloat rx = texcoord[0];   const GLfloat ry = texcoord[1];   const GLfloat rz = texcoord[2];   const GLfloat arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz);   GLuint face;   GLfloat sc, tc, ma;   if (arx > ary && arx > arz) {      if (rx >= 0.0F) {         face = FACE_POS_X;         sc = -rz;         tc = -ry;         ma = arx;      }      else {         face = FACE_NEG_X;         sc = rz;         tc = -ry;         ma = arx;      }   }   else if (ary > arx && ary > arz) {      if (ry >= 0.0F) {         face = FACE_POS_Y;         sc = rx;         tc = rz;         ma = ary;      }      else {         face = FACE_NEG_Y;         sc = rx;         tc = -rz;         ma = ary;      }   }   else {      if (rz > 0.0F) {         face = FACE_POS_Z;         sc = rx;         tc = -ry;         ma = arz;      }      else {         face = FACE_NEG_Z;         sc = -rx;         tc = -ry;         ma = arz;      }   }   newCoord[0] = ( sc / ma + 1.0F ) * 0.5F;   newCoord[1] = ( tc / ma + 1.0F ) * 0.5F;   return (const struct gl_texture_image **) texObj->Image[face];}static voidsample_nearest_cube(GLcontext *ctx,		    const struct gl_texture_object *tObj, GLuint n,                    const GLfloat texcoords[][4], const GLfloat lambda[],                    GLchan rgba[][4]){   GLuint i;   (void) lambda;   for (i = 0; i < n; i++) {      const struct gl_texture_image **images;      GLfloat newCoord[4];      images = choose_cube_face(tObj, texcoords[i], newCoord);      sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],                        newCoord, rgba[i]);   }}static voidsample_linear_cube(GLcontext *ctx,		   const struct gl_texture_object *tObj, GLuint n,                   const GLfloat texcoords[][4],		   const GLfloat lambda[], GLchan rgba[][4]){   GLuint i;   (void) lambda;   for (i = 0; i < n; i++) {      const struct gl_texture_image **images;      GLfloat newCoord[4];      images = choose_cube_face(tObj, texcoords[i], newCoord);      sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],                       newCoord, rgba[i]);   }}static voidsample_cube_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++) {      const struct gl_texture_image **images;      GLfloat newCoord[4];      GLint level;      images = choose_cube_face(tObj, texcoord[i], newCoord);      /* XXX we actually need to recompute lambda here based on the newCoords.       * But we would need the texcoords of adjacent fragments to compute that       * properly, and we don't have those here.       * For now, do an approximation:  subtracting 1 from the chosen mipmap       * level seems to work in some test cases.       * The same adjustment is done in the next few functions.      */      level = nearest_mipmap_level(tObj, lambda[i]);      level = MAX2(level - 1, 0);      sample_2d_nearest(ctx, tObj, images[level], newCoord, rgba[i]);   }}static voidsample_cube_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++) {      const struct gl_texture_image **images;      GLfloat newCoord[4];      GLint level = nearest_mipmap_level(tObj, lambda[i]);      level = MAX2(level - 1, 0); /* see comment above */      images = choose_cube_face(tObj, texcoord[i], newCoord);      sample_2d_linear(ctx, tObj, images[level], newCoord, rgba[i]);   }}static voidsample_cube_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++) {      const struct gl_texture_image **images;      GLfloat newCoord[4];      GLint level = linear_mipmap_level(tObj, lambda[i]);      level = MAX2(level - 1, 0); /* see comment above */      images = choose_cube_face(tObj, texcoord[i], newCoord);      if (level >= tObj->_MaxLevel) {         sample_2d_nearest(ctx, tObj, images[tObj->_MaxLevel],                           newCoord, rgba[i]);      }      else {         GLchan t0[4], t1[4];  /* texels */         const GLfloat f = FRAC(lambda[i]);         sample_2d_nearest(ctx, tObj, images[level  ], newCoord, t0);         sample_2d_nearest(ctx, tObj, images[level+1], newCoord, t1);         lerp_rgba(rgba[i], f, t0, t1);      }   }}static voidsample_cube_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++) {      const struct gl_texture_image **images;      GLfloat newCoord[4];      GLint level = linear_mipmap_level(tObj, lambda[i]);      level = MAX2(level - 1, 0); /* see comment above */      images = choose_cube_face(tObj, texcoord[i], newCoord);      if (level >= tObj->_MaxLevel) {         sample_2d_linear(ctx, tObj, images[tObj->_MaxLevel],                          newCoord, rgba[i]);      }      else {         GLchan t0[4], t1[4];         const GLfloat f = FRAC(lambda[i]);         sample_2d_linear(ctx, tObj, images[level  ], newCoord, t0);         sample_2d_linear(ctx, tObj, images[level+1], newCoord, t1);         lerp_rgba(rgba[i], f, t0, t1);      }   }}static voidsample_lambda_cube( GLcontext *ctx,		    const struct gl_texture_object *tObj, GLuint n,		    const GLfloat texcoords[][4], const GLfloat lambda[],		    GLchan rgba[][4]){   GLuint minStart, minEnd;  /* texels with minification */   GLuint magStart, magEnd;  /* texels with magnification */   ASSERT(lambda != NULL);   compute_min_mag_ranges(tObj, n, lambda,                          &minStart, &minEnd, &magStart, &magEnd);   if (minStart < minEnd) {      /* do the minified texels */      const GLuint m = minEnd - minStart;      switch (tObj->MinFilter) {      case GL_NEAREST:         sample_nearest_cube(ctx, tObj, m, texcoords + minStart,                             lambda + minStart, rgba + minStart);         break;      case GL_LINEAR:         sample_linear_cube(ctx, tObj, m, texcoords + minStart,                            lambda + minStart, rgba + minStart);         break;      case GL_NEAREST_MIPMAP_NEAREST:         sample_cube_nearest_mipmap_nearest(ctx, tObj, m,                                            texcoords + minStart,                                           lambda + minStart, rgba + minStart);         break;      case GL_LINEAR_MIPMAP_NEAREST:         sample_cube_linear_mipmap_nearest(ctx, tObj, m,                                           texcoords + minStart,                                           lambda + minStart, rgba + minStart);         break;      case GL_NEAREST_MIPMAP_LINEAR:         sample_cube_nearest_mipmap_linear(ctx, tObj, m,                                           texcoords + minStart,                                           lambda + minStart, rgba + minStart);         break;      case GL_LINEAR_MIPMAP_LINEAR:         sample_cube_linear_mipmap_linear(ctx, tObj, m,                                          texcoords + minStart,                                          lambda + minStart, rgba + minStart);         break;      default:         _mesa_problem(ctx, "Bad min filter in sample_lambda_cube");      }   }   if (magStart < magEnd) {      /* do the magnified texels */      const GLuint m = magEnd - magStart;      switch (tObj->MagFilter) {      case GL_NEAREST:         sample_nearest_cube(ctx, tObj, m, texcoords + magStart,                             lambda + magStart, rgba + magStart);         break;      case GL_LINEAR:         sample_linear_cube(ctx, tObj, m, texcoords + magStart,                            lambda + magStart, rgba + magStart);         break;      default:         _mesa_problem(ctx, "Bad mag filter in sample_lambda_cube");      }   }}/**********************************************************************//*               Texture Rectangle Sampling Functions                 *//**********************************************************************//** * Do clamp/wrap for a texture rectangle coord, GL_NEAREST filter mode. */static INLINE GLintclamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max){   if (wrapMode == GL_CLAMP) {      return IFLOOR( CLAMP(coord, 0.0F, max - 1) );   }   else if (wrapMode == GL_CLAMP_TO_EDGE) {      return IFLOOR( CLAMP(coord, 0.5F, max - 0.5F) );   }   else {      return IFLOOR( CLAMP(coord, -0.5F, max + 0.5F) );   }}/* * As above, but GL_LINEAR filtering. */static INLINE voidclamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max,                        GLint *i0out, GLint *i1out){   GLfloat fcol;   GLint i0, i1;   if (wrapMode == GL_CLAMP) 

⌨️ 快捷键说明

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