📄 s_texfilter.c
字号:
sample_linear_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_linear(ctx, tObj, image, texcoords[i], rgba[i]); }}/* * Given an (s) texture coordinate and lambda (level of detail) value, * return a texture sample. * */static voidsample_lambda_1d( 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 */ const GLuint m = minEnd - minStart; switch (tObj->MinFilter) { case GL_NEAREST: for (i = minStart; i < minEnd; i++) sample_1d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel], texcoords[i], rgba[i]); break; case GL_LINEAR: for (i = minStart; i < minEnd; i++) sample_1d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel], texcoords[i], rgba[i]); break; case GL_NEAREST_MIPMAP_NEAREST: sample_1d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart, lambda + minStart, rgba + minStart); break; case GL_LINEAR_MIPMAP_NEAREST: sample_1d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart, lambda + minStart, rgba + minStart); break; case GL_NEAREST_MIPMAP_LINEAR: sample_1d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart, lambda + minStart, rgba + minStart); break; case GL_LINEAR_MIPMAP_LINEAR: sample_1d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart, lambda + minStart, rgba + minStart); break; default: _mesa_problem(ctx, "Bad min filter in sample_1d_texture"); return; } } if (magStart < magEnd) { /* do the magnified texels */ switch (tObj->MagFilter) { case GL_NEAREST: for (i = magStart; i < magEnd; i++) sample_1d_nearest(ctx, tObj, tObj->Image[0][tObj->BaseLevel], texcoords[i], rgba[i]); break; case GL_LINEAR: for (i = magStart; i < magEnd; i++) sample_1d_linear(ctx, tObj, tObj->Image[0][tObj->BaseLevel], texcoords[i], rgba[i]); break; default: _mesa_problem(ctx, "Bad mag filter in sample_1d_texture"); return; } }}/**********************************************************************//* 2-D Texture Sampling Functions *//**********************************************************************//* * Return the texture sample for coordinate (s,t) using GL_NEAREST filter. */static INLINE voidsample_2d_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, const GLfloat texcoord[4], GLchan rgba[]){ const GLint width = img->Width2; /* without border, power of two */ const GLint height = img->Height2; /* without border, power of two */ GLint i, j; (void) ctx; COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i); COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j); /* skip over the border, if any */ i += img->Border; j += img->Border; if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) { /* Need this test for GL_CLAMP_TO_BORDER mode */ COPY_CHAN4(rgba, tObj->_BorderChan); } else { img->FetchTexelc(img, i, j, 0, rgba); }}/** * Return the texture sample for coordinate (s,t) using GL_LINEAR filter. * New sampling code contributed by Lynn Quam <quam@ai.sri.com>. */static INLINE voidsample_2d_linear(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, const GLfloat texcoord[4], GLchan rgba[]){ const GLint width = img->Width2; const GLint height = img->Height2; GLint i0, j0, i1, j1; GLbitfield useBorderColor = 0x0; GLfloat u, v; GLfloat a, b; GLchan t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1); COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1); if (img->Border) { i0 += img->Border; i1 += img->Border; j0 += img->Border; j1 += img->Border; } else { 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; } /* fetch four texel colors */ if (useBorderColor & (I0BIT | J0BIT)) { COPY_CHAN4(t00, tObj->_BorderChan); } else { img->FetchTexelc(img, i0, j0, 0, t00); } if (useBorderColor & (I1BIT | J0BIT)) { COPY_CHAN4(t10, tObj->_BorderChan); } else { img->FetchTexelc(img, i1, j0, 0, t10); } if (useBorderColor & (I0BIT | J1BIT)) { COPY_CHAN4(t01, tObj->_BorderChan); } else { img->FetchTexelc(img, i0, j1, 0, t01); } if (useBorderColor & (I1BIT | J1BIT)) { COPY_CHAN4(t11, tObj->_BorderChan); } else { img->FetchTexelc(img, i1, j1, 0, t11); } a = FRAC(u); b = FRAC(v); lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11);}/* * As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT. * We don't have to worry about the texture border. */static INLINE voidsample_2d_linear_repeat(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, const GLfloat texcoord[4], GLchan rgba[]){ const GLint width = img->Width2; const GLint height = img->Height2; GLint i0, j0, i1, j1; GLfloat u, v; GLfloat a, b; GLchan t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ (void) ctx; ASSERT(tObj->WrapS == GL_REPEAT); ASSERT(tObj->WrapT == GL_REPEAT); ASSERT(img->Border == 0); ASSERT(img->TexFormat->BaseFormat != GL_COLOR_INDEX); ASSERT(img->_IsPowerOfTwo); COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(texcoord[0], u, width, i0, i1); COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(texcoord[1], v, height, j0, j1); img->FetchTexelc(img, i0, j0, 0, t00); img->FetchTexelc(img, i1, j0, 0, t10); img->FetchTexelc(img, i0, j1, 0, t01); img->FetchTexelc(img, i1, j1, 0, t11); a = FRAC(u); b = FRAC(v); lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11);}static voidsample_2d_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_2d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]); }}static voidsample_2d_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_2d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]); }}static voidsample_2d_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_2d_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_2d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); sample_2d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); lerp_rgba(rgba[i], f, t0, t1); } }}/* Trilinear filtering */static voidsample_2d_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_2d_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_2d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); sample_2d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); lerp_rgba(rgba[i], f, t0, t1); } }}static voidsample_2d_linear_mipmap_linear_repeat( 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); ASSERT(tObj->WrapS == GL_REPEAT); ASSERT(tObj->WrapT == GL_REPEAT); for (i = 0; i < n; i++) { GLint level = linear_mipmap_level(tObj, lambda[i]); if (level >= tObj->_MaxLevel) { sample_2d_linear_repeat(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_2d_linear_repeat(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); lerp_rgba(rgba[i], f, t0, t1); } }}static voidsample_nearest_2d( 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_2d_nearest(ctx, tObj, image, texcoords[i], rgba[i]); }}static voidsample_linear_2d( 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; if (tObj->WrapS == GL_REPEAT && tObj->WrapT == GL_REPEAT && image->_IsPowerOfTwo && image->Border == 0) { for (i=0;i<n;i++) { sample_2d_linear_repeat(ctx, tObj, image, texcoords[i], rgba[i]); } } else { for (i=0;i<n;i++) { sample_2d_linear(ctx, tObj, image, texcoords[i], rgba[i]); } }}/* * Optimized 2-D texture sampling: * S and T wrap mode == GL_REPEAT * GL_NEAREST min/mag filter * No border, * RowStride == Width, * Format = GL_RGB */static voidopt_sample_rgb_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 k; (void) ctx; (void) lambda; ASSERT(tObj->WrapS==GL_REPEAT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -