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

📄 s_texfilter.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
   ASSERT(tObj->WrapT==GL_REPEAT);   ASSERT(img->Border==0);   ASSERT(img->TexFormat->MesaFormat==MESA_FORMAT_RGB);   ASSERT(img->_IsPowerOfTwo);   for (k=0; k<n; k++) {      GLint i = IFLOOR(texcoords[k][0] * width) & colMask;      GLint j = IFLOOR(texcoords[k][1] * height) & rowMask;      GLint pos = (j << shift) | i;      GLchan *texel = ((GLchan *) img->Data) + 3*pos;      rgba[k][RCOMP] = texel[0];      rgba[k][GCOMP] = texel[1];      rgba[k][BCOMP] = texel[2];   }}/* * Optimized 2-D texture sampling: *    S and T wrap mode == GL_REPEAT *    GL_NEAREST min/mag filter *    No border *    RowStride == Width, *    Format = GL_RGBA */static voidopt_sample_rgba_2d( GLcontext *ctx,                    const struct gl_texture_object *tObj,                    GLuint n, const GLfloat texcoords[][4],                    const GLfloat lambda[], GLchan rgba[][4] ){   const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel];   const GLfloat width = (GLfloat) img->Width;   const GLfloat height = (GLfloat) img->Height;   const GLint colMask = img->Width - 1;   const GLint rowMask = img->Height - 1;   const GLint shift = img->WidthLog2;   GLuint i;   (void) ctx;   (void) lambda;   ASSERT(tObj->WrapS==GL_REPEAT);   ASSERT(tObj->WrapT==GL_REPEAT);   ASSERT(img->Border==0);   ASSERT(img->TexFormat->MesaFormat==MESA_FORMAT_RGBA);   ASSERT(img->_IsPowerOfTwo);   for (i = 0; i < n; i++) {      const GLint col = IFLOOR(texcoords[i][0] * width) & colMask;      const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask;      const GLint pos = (row << shift) | col;      const GLchan *texel = ((GLchan *) img->Data) + (pos << 2);    /* pos*4 */      COPY_CHAN4(rgba[i], texel);   }}/* * Given an array of texture coordinate and lambda (level of detail) * values, return an array of texture sample. */static voidsample_lambda_2d( GLcontext *ctx,                  const struct gl_texture_object *tObj,                  GLuint n, const GLfloat texcoords[][4],                  const GLfloat lambda[], GLchan rgba[][4] ){   const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel];   GLuint minStart, minEnd;  /* texels with minification */   GLuint magStart, magEnd;  /* texels with magnification */   const GLboolean repeatNoBorderPOT = (tObj->WrapS == GL_REPEAT)      && (tObj->WrapT == GL_REPEAT)      && (tImg->Border == 0 && (tImg->Width == tImg->RowStride))      && (tImg->TexFormat->BaseFormat != GL_COLOR_INDEX)      && tImg->_IsPowerOfTwo;   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:         if (repeatNoBorderPOT) {            switch (tImg->TexFormat->MesaFormat) {            case MESA_FORMAT_RGB:               opt_sample_rgb_2d(ctx, tObj, m, texcoords + minStart,                                 NULL, rgba + minStart);               break;            case MESA_FORMAT_RGBA:	       opt_sample_rgba_2d(ctx, tObj, m, texcoords + minStart,                                  NULL, rgba + minStart);               break;            default:               sample_nearest_2d(ctx, tObj, m, texcoords + minStart,                                 NULL, rgba + minStart );            }         }         else {            sample_nearest_2d(ctx, tObj, m, texcoords + minStart,                              NULL, rgba + minStart);         }         break;      case GL_LINEAR:	 sample_linear_2d(ctx, tObj, m, texcoords + minStart,			  NULL, rgba + minStart);         break;      case GL_NEAREST_MIPMAP_NEAREST:         sample_2d_nearest_mipmap_nearest(ctx, tObj, m,                                          texcoords + minStart,                                          lambda + minStart, rgba + minStart);         break;      case GL_LINEAR_MIPMAP_NEAREST:         sample_2d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,                                         lambda + minStart, rgba + minStart);         break;      case GL_NEAREST_MIPMAP_LINEAR:         sample_2d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,                                         lambda + minStart, rgba + minStart);         break;      case GL_LINEAR_MIPMAP_LINEAR:         if (repeatNoBorderPOT)            sample_2d_linear_mipmap_linear_repeat(ctx, tObj, m,                  texcoords + minStart, lambda + minStart, rgba + minStart);         else            sample_2d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,                                        lambda + minStart, rgba + minStart);         break;      default:         _mesa_problem(ctx, "Bad min filter in sample_2d_texture");         return;      }   }   if (magStart < magEnd) {      /* do the magnified texels */      const GLuint m = magEnd - magStart;      switch (tObj->MagFilter) {      case GL_NEAREST:         if (repeatNoBorderPOT) {            switch (tImg->TexFormat->MesaFormat) {            case MESA_FORMAT_RGB:               opt_sample_rgb_2d(ctx, tObj, m, texcoords + magStart,                                 NULL, rgba + magStart);               break;            case MESA_FORMAT_RGBA:	       opt_sample_rgba_2d(ctx, tObj, m, texcoords + magStart,                                  NULL, rgba + magStart);               break;            default:               sample_nearest_2d(ctx, tObj, m, texcoords + magStart,                                 NULL, rgba + magStart );            }         }         else {            sample_nearest_2d(ctx, tObj, m, texcoords + magStart,                              NULL, rgba + magStart);         }         break;      case GL_LINEAR:	 sample_linear_2d(ctx, tObj, m, texcoords + magStart,			  NULL, rgba + magStart);         break;      default:         _mesa_problem(ctx, "Bad mag filter in sample_lambda_2d");      }   }}/**********************************************************************//*                    3-D Texture Sampling Functions                  *//**********************************************************************//* * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. */static voidsample_3d_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 */   const GLint height = img->Height2;   /* without border, power of two */   const GLint depth = img->Depth2;     /* without border, power of two */   GLint i, j, k;   (void) ctx;   COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width,  i);   COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j);   COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapR, texcoord[2], depth,  k);   if (i < 0 || i >= (GLint) img->Width ||       j < 0 || j >= (GLint) img->Height ||       k < 0 || k >= (GLint) img->Depth) {      /* Need this test for GL_CLAMP_TO_BORDER mode */      COPY_CHAN4(rgba, tObj->_BorderChan);   }   else {      img->FetchTexelc(img, i, j, k, rgba);   }}/* * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. */static voidsample_3d_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;   const GLint height = img->Height2;   const GLint depth = img->Depth2;   GLint i0, j0, k0, i1, j1, k1;   GLbitfield useBorderColor = 0x0;   GLfloat u, v, w;   GLfloat a, b, c;   GLchan t000[4], t010[4], t001[4], t011[4];   GLchan t100[4], t110[4], t101[4], t111[4];   COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width,  i0, i1);   COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1);   COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapR, texcoord[2], w, depth,  k0, k1);   if (img->Border) {      i0 += img->Border;      i1 += img->Border;      j0 += img->Border;      j1 += img->Border;      k0 += img->Border;      k1 += img->Border;   }   else {      /* check if sampling texture border color */      if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;      if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;      if (j0 < 0 || j0 >= height)  useBorderColor |= J0BIT;      if (j1 < 0 || j1 >= height)  useBorderColor |= J1BIT;      if (k0 < 0 || k0 >= depth)   useBorderColor |= K0BIT;      if (k1 < 0 || k1 >= depth)   useBorderColor |= K1BIT;   }   /* Fetch texels */   if (useBorderColor & (I0BIT | J0BIT | K0BIT)) {      COPY_CHAN4(t000, tObj->_BorderChan);   }   else {      img->FetchTexelc(img, i0, j0, k0, t000);   }   if (useBorderColor & (I1BIT | J0BIT | K0BIT)) {      COPY_CHAN4(t100, tObj->_BorderChan);   }   else {      img->FetchTexelc(img, i1, j0, k0, t100);   }   if (useBorderColor & (I0BIT | J1BIT | K0BIT)) {      COPY_CHAN4(t010, tObj->_BorderChan);   }   else {      img->FetchTexelc(img, i0, j1, k0, t010);   }   if (useBorderColor & (I1BIT | J1BIT | K0BIT)) {      COPY_CHAN4(t110, tObj->_BorderChan);   }   else {      img->FetchTexelc(img, i1, j1, k0, t110);   }   if (useBorderColor & (I0BIT | J0BIT | K1BIT)) {      COPY_CHAN4(t001, tObj->_BorderChan);   }   else {      img->FetchTexelc(img, i0, j0, k1, t001);   }   if (useBorderColor & (I1BIT | J0BIT | K1BIT)) {      COPY_CHAN4(t101, tObj->_BorderChan);   }   else {      img->FetchTexelc(img, i1, j0, k1, t101);   }   if (useBorderColor & (I0BIT | J1BIT | K1BIT)) {      COPY_CHAN4(t011, tObj->_BorderChan);   }   else {      img->FetchTexelc(img, i0, j1, k1, t011);   }   if (useBorderColor & (I1BIT | J1BIT | K1BIT)) {      COPY_CHAN4(t111, tObj->_BorderChan);   }   else {      img->FetchTexelc(img, i1, j1, k1, t111);   }   /* trilinear interpolation of samples */   a = FRAC(u);   b = FRAC(v);   c = FRAC(w);   lerp_rgba_3d(rgba, a, b, c, t000, t100, t010, t110, t001, t101, t011, t111);}static voidsample_3d_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;   for (i = 0; i < n; i++) {      GLint level = nearest_mipmap_level(tObj, lambda[i]);      sample_3d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);   }}static voidsample_3d_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_3d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);   }}static voidsample_3d_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_3d_nearest(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],                           texcoord[i], rgba[i]);      }      else {         GLchan t0[4], t1[4];  /* texels */         const GLfloat f = FRAC(lambda[i]);         sample_3d_nearest(ctx, tObj, tObj->Image[0][level  ], texcoord[i], t0);         sample_3d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);         lerp_rgba(rgba[i], f, t0, t1);      }   }}static voidsample_3d_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_3d_linear(ctx, tObj, tObj->Image[0][tObj->_MaxLevel],                          texcoord[i], rgba[i]);      }      else {         GLchan t0[4], t1[4];  /* texels */         const GLfloat f = FRAC(lambda[i]);         sample_3d_linear(ctx, tObj, tObj->Image[0][level  ], texcoord[i], t0);         sample_3d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1);         lerp_rgba(rgba[i], f, t0, t1);      }   }}static voidsample_nearest_3d(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_3d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);   }}static voidsample_linear_3d( GLcontext *ctx,                  const struct gl_texture_object *tObj, GLuint n,

⌨️ 快捷键说明

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