📄 s_texfilter.c
字号:
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 + -