📄 s_texture.c
字号:
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 */
#if CHAN_TYPE == GL_FLOAT
rgba[0] = lerp_3d(a, b, c,
t000[0], t100[0], t010[0], t110[0],
t001[0], t101[0], t011[0], t111[0]);
rgba[1] = lerp_3d(a, b, c,
t000[1], t100[1], t010[1], t110[1],
t001[1], t101[1], t011[1], t111[1]);
rgba[2] = lerp_3d(a, b, c,
t000[2], t100[2], t010[2], t110[2],
t001[2], t101[2], t011[2], t111[2]);
rgba[3] = lerp_3d(a, b, c,
t000[3], t100[3], t010[3], t110[3],
t001[3], t101[3], t011[3], t111[3]);
#elif CHAN_TYPE == GL_UNSIGNED_SHORT
rgba[0] = (GLchan) (lerp_3d(a, b, c,
t000[0], t100[0], t010[0], t110[0],
t001[0], t101[0], t011[0], t111[0]) + 0.5F);
rgba[1] = (GLchan) (lerp_3d(a, b, c,
t000[1], t100[1], t010[1], t110[1],
t001[1], t101[1], t011[1], t111[1]) + 0.5F);
rgba[2] = (GLchan) (lerp_3d(a, b, c,
t000[2], t100[2], t010[2], t110[2],
t001[2], t101[2], t011[2], t111[2]) + 0.5F);
rgba[3] = (GLchan) (lerp_3d(a, b, c,
t000[3], t100[3], t010[3], t110[3],
t001[3], t101[3], t011[3], t111[3]) + 0.5F);
#else
ASSERT(CHAN_TYPE == GL_UNSIGNED_BYTE);
rgba[0] = ilerp_3d(ia, ib, ic,
t000[0], t100[0], t010[0], t110[0],
t001[0], t101[0], t011[0], t111[0]);
rgba[1] = ilerp_3d(ia, ib, ic,
t000[1], t100[1], t010[1], t110[1],
t001[1], t101[1], t011[1], t111[1]);
rgba[2] = ilerp_3d(ia, ib, ic,
t000[2], t100[2], t010[2], t110[2],
t001[2], t101[2], t011[2], t111[2]);
rgba[3] = ilerp_3d(ia, ib, ic,
t000[3], t100[3], t010[3], t110[3],
t001[3], t101[3], t011[3], t111[3]);
#endif
}
}
static void
sample_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;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
sample_3d_nearest(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
}
}
static void
sample_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;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
sample_3d_linear(ctx, tObj, tObj->Image[0][level], texcoord[i], rgba[i]);
}
}
static void
sample_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;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
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);
rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
}
}
}
static void
sample_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;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
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);
rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
}
}
}
static void
sample_nearest_3d(GLcontext *ctx, GLuint texUnit,
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) texUnit;
(void) lambda;
for (i=0;i<n;i++) {
sample_3d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
static void
sample_linear_3d( GLcontext *ctx, GLuint texUnit,
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) texUnit;
(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 void
sample_lambda_3d( GLcontext *ctx, GLuint texUnit,
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(SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit],
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 struct gl_texture_image **imgArray;
const GLfloat arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz);
GLfloat sc, tc, ma;
if (arx > ary && arx > arz) {
if (rx >= 0.0F) {
imgArray = (const struct gl_texture_image **) texObj->Image[FACE_POS_X];
sc = -rz;
tc = -ry;
ma = arx;
}
else {
imgArray = (const struct gl_texture_image **) texObj->Image[FACE_NEG_X];
sc = rz;
tc = -ry;
ma = arx;
}
}
else if (ary > arx && ary > arz) {
if (ry >= 0.0F) {
imgArray = (const struct gl_texture_image **) texObj->Image[FACE_POS_Y];
sc = rx;
tc = rz;
ma = ary;
}
else {
imgArray = (const struct gl_texture_image **) texObj->Image[FACE_NEG_Y];
sc = rx;
tc = -rz;
ma = ary;
}
}
else {
if (rz > 0.0F) {
imgArray = (const struct gl_texture_image **) texObj->Image[FACE_POS_Z];
sc = rx;
tc = -ry;
ma = arz;
}
else {
imgArray = (const struct gl_texture_image **) texObj->Image[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 imgArray;
}
static void
sample_nearest_cube(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
const GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
GLuint i;
(void) texUnit;
(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 void
sample_linear_cube(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
const GLfloat texcoords[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
(void) texUnit;
(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 void
sample_cube_nearest_mipmap_nearest(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
GLuint n, const GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
(void) texUnit;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
const
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -