📄 s_texsample.h
字号:
/* * These values are used in the fixed-point arithmetic used * for linear filtering. */#define WEIGHT_SCALE 65536.0F#define WEIGHT_SHIFT 16/* * Compute the remainder of a divided by b, but be careful with * negative values so that GL_REPEAT mode works right. */static INLINE GLintrepeat_remainder(GLint a, GLint b){ if (a >= 0) return a % b; else return (a + 1) % b + b - 1;}/* * Used to compute texel locations for linear sampling. * Input: * wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER * S = texcoord in [0,1] * SIZE = width (or height or depth) of texture * Output: * U = texcoord in [0, width] * I0, I1 = two nearest texel indexes */#define COMPUTE_LINEAR_TEXEL_LOCATIONS(wrapMode, S, U, SIZE, I0, I1) \{ \ if (wrapMode == GL_REPEAT) { \ U = S * SIZE - 0.5F; \ if (tObj->_IsPowerOfTwo) { \ I0 = IFLOOR(U) & (SIZE - 1); \ I1 = (I0 + 1) & (SIZE - 1); \ } \ else { \ I0 = repeat_remainder(IFLOOR(U), SIZE); \ I1 = repeat_remainder(I0 + 1, SIZE); \ } \ } \ else if (wrapMode == GL_CLAMP_TO_EDGE) { \ if (S <= 0.0F) \ U = 0.0F; \ else if (S >= 1.0F) \ U = (GLfloat) SIZE; \ else \ U = S * SIZE; \ U -= 0.5F; \ I0 = IFLOOR(U); \ I1 = I0 + 1; \ if (I0 < 0) \ I0 = 0; \ if (I1 >= (GLint) SIZE) \ I1 = SIZE - 1; \ } \ else if (wrapMode == GL_CLAMP_TO_BORDER) { \ const GLfloat min = -1.0F / (2.0F * SIZE); \ const GLfloat max = 1.0F - min; \ if (S <= min) \ U = min * SIZE; \ else if (S >= max) \ U = max * SIZE; \ else \ U = S * SIZE; \ U -= 0.5F; \ I0 = IFLOOR(U); \ I1 = I0 + 1; \ } \ else if (wrapMode == GL_MIRRORED_REPEAT) { \ const GLint flr = IFLOOR(S); \ if (flr & 1) \ U = 1.0F - (S - (GLfloat) flr); /* flr is odd */ \ else \ U = S - (GLfloat) flr; /* flr is even */ \ U = (U * SIZE) - 0.5F; \ I0 = IFLOOR(U); \ I1 = I0 + 1; \ if (I0 < 0) \ I0 = 0; \ if (I1 >= (GLint) SIZE) \ I1 = SIZE - 1; \ } \ else if (wrapMode == GL_MIRROR_CLAMP_EXT) { \ U = (GLfloat) fabs(S); \ if (U >= 1.0F) \ U = (GLfloat) SIZE; \ else \ U *= SIZE; \ U -= 0.5F; \ I0 = IFLOOR(U); \ I1 = I0 + 1; \ } \ else if (wrapMode == GL_MIRROR_CLAMP_TO_EDGE_EXT) { \ U = (GLfloat) fabs(S); \ if (U >= 1.0F) \ U = (GLfloat) SIZE; \ else \ U *= SIZE; \ U -= 0.5F; \ I0 = IFLOOR(U); \ I1 = I0 + 1; \ if (I0 < 0) \ I0 = 0; \ if (I1 >= (GLint) SIZE) \ I1 = SIZE - 1; \ } \ else if (wrapMode == GL_MIRROR_CLAMP_TO_BORDER_EXT) { \ const GLfloat min = -1.0F / (2.0F * SIZE); \ const GLfloat max = 1.0F - min; \ U = (GLfloat) fabs(S); \ if (U <= min) \ U = min * SIZE; \ else if (U >= max) \ U = max * SIZE; \ else \ U *= SIZE; \ U -= 0.5F; \ I0 = IFLOOR(U); \ I1 = I0 + 1; \ } \ else { \ ASSERT(wrapMode == GL_CLAMP); \ if (S <= 0.0F) \ U = 0.0F; \ else if (S >= 1.0F) \ U = (GLfloat) SIZE; \ else \ U = S * SIZE; \ U -= 0.5F; \ I0 = IFLOOR(U); \ I1 = I0 + 1; \ } \}/* * Used to compute texel location for nearest sampling. */#define COMPUTE_NEAREST_TEXEL_LOCATION(wrapMode, S, SIZE, I) \{ \ if (wrapMode == GL_REPEAT) { \ /* s limited to [0,1) */ \ /* i limited to [0,size-1] */ \ I = IFLOOR(S * SIZE); \ if (tObj->_IsPowerOfTwo) \ I &= (SIZE - 1); \ else \ I = repeat_remainder(I, SIZE); \ } \ else if (wrapMode == GL_CLAMP_TO_EDGE) { \ /* 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; \ if (S < min) \ I = 0; \ else if (S > max) \ I = SIZE - 1; \ else \ I = IFLOOR(S * SIZE); \ } \ else if (wrapMode == GL_CLAMP_TO_BORDER) { \ /* s limited to [min,max] */ \ /* i limited to [-1, size] */ \ const GLfloat min = -1.0F / (2.0F * SIZE); \ const GLfloat max = 1.0F - min; \ if (S <= min) \ I = -1; \ else if (S >= max) \ I = SIZE; \ else \ I = IFLOOR(S * SIZE); \ } \ else if (wrapMode == GL_MIRRORED_REPEAT) { \ const GLfloat min = 1.0F / (2.0F * SIZE); \ const GLfloat max = 1.0F - min; \ const GLint flr = IFLOOR(S); \ GLfloat u; \ if (flr & 1) \ u = 1.0F - (S - (GLfloat) flr); /* flr is odd */ \ else \ u = S - (GLfloat) flr; /* flr is even */ \ if (u < min) \ I = 0; \ else if (u > max) \ I = SIZE - 1; \ else \ I = IFLOOR(u * SIZE); \ } \ else if (wrapMode == GL_MIRROR_CLAMP_EXT) { \ /* s limited to [0,1] */ \ /* i limited to [0,size-1] */ \ const GLfloat u = (GLfloat) fabs(S); \ if (u <= 0.0F) \ I = 0; \ else if (u >= 1.0F) \ I = SIZE - 1; \ else \ I = IFLOOR(u * SIZE); \ } \ else if (wrapMode == 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 = (GLfloat) fabs(S); \ if (u < min) \ I = 0; \ else if (u > max) \ I = SIZE - 1; \ else \ I = IFLOOR(u * SIZE); \ } \ else if (wrapMode == 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 = (GLfloat) fabs(S); \ if (u < min) \ I = -1; \ else if (u > max) \ I = SIZE; \ else \ I = IFLOOR(u * SIZE); \ } \ else { \ ASSERT(wrapMode == 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); \ } \}/* 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); \}/* * Compute linear mipmap levels for given lambda. */#define COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level) \{ \ if (lambda < 0.0F) \ level = tObj->BaseLevel; \ else if (lambda > tObj->_MaxLambda) \ level = (GLint) (tObj->BaseLevel + tObj->_MaxLambda); \ else \ level = (GLint) (tObj->BaseLevel + lambda); \}/* * Compute nearest mipmap level for given lambda. */#define COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level) \{ \ GLfloat l; \ 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; \}/* * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes * see 1-pixel bands of improperly weighted linear-sampled texels. 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#if 000/* * Get texture palette entry. */static voidpalette_sample(const GLcontext *ctx, const struct gl_texture_object *tObj, GLint index, GLchan rgba[4] ){ const GLchan *palette; GLenum format; if (ctx->Texture.SharedPalette) { ASSERT(ctx->Texture.Palette.Type != GL_FLOAT); palette = (const GLchan *) ctx->Texture.Palette.Table; format = ctx->Texture.Palette.Format; } else { ASSERT(tObj->Palette.Type != GL_FLOAT); palette = (const GLchan *) tObj->Palette.Table; format = tObj->Palette.Format; } switch (format) { case GL_ALPHA: rgba[ACOMP] = palette[index]; return; case GL_LUMINANCE: case GL_INTENSITY: rgba[RCOMP] = palette[index]; return; case GL_LUMINANCE_ALPHA: rgba[RCOMP] = palette[(index << 1) + 0]; rgba[ACOMP] = palette[(index << 1) + 1]; return; case GL_RGB: rgba[RCOMP] = palette[index * 3 + 0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -