📄 s_texture.c
字号:
static void
sample_nearest_2d( 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_2d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
static void
sample_linear_2d( 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;
if (tObj->WrapS == GL_REPEAT && tObj->WrapT == GL_REPEAT
&& 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 void
opt_sample_rgb_2d( GLcontext *ctx, GLuint texUnit,
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) texUnit;
(void) lambda;
ASSERT(tObj->WrapS==GL_REPEAT);
ASSERT(tObj->WrapT==GL_REPEAT);
ASSERT(img->Border==0);
ASSERT(img->Format==GL_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 void
opt_sample_rgba_2d( GLcontext *ctx, GLuint texUnit,
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) texUnit;
(void) lambda;
ASSERT(tObj->WrapS==GL_REPEAT);
ASSERT(tObj->WrapT==GL_REPEAT);
ASSERT(img->Border==0);
ASSERT(img->Format==GL_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 void
sample_lambda_2d( GLcontext *ctx, GLuint texUnit,
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->Format != GL_COLOR_INDEX)
&& tImg->_IsPowerOfTwo;
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 */
const GLuint m = minEnd - minStart;
switch (tObj->MinFilter) {
case GL_NEAREST:
if (repeatNoBorderPOT) {
switch (tImg->TexFormat->MesaFormat) {
case MESA_FORMAT_RGB:
case MESA_FORMAT_RGB888:
/*case MESA_FORMAT_BGR888:*/
opt_sample_rgb_2d(ctx, texUnit, tObj, m, texcoords + minStart,
NULL, rgba + minStart);
break;
case MESA_FORMAT_RGBA:
case MESA_FORMAT_RGBA8888:
case MESA_FORMAT_ARGB8888:
/*case MESA_FORMAT_ABGR8888:*/
/*case MESA_FORMAT_BGRA8888:*/
opt_sample_rgba_2d(ctx, texUnit, tObj, m, texcoords + minStart,
NULL, rgba + minStart);
break;
default:
sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + minStart,
NULL, rgba + minStart );
}
}
else {
sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + minStart,
NULL, rgba + minStart);
}
break;
case GL_LINEAR:
sample_linear_2d(ctx, texUnit, 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:
case MESA_FORMAT_RGB888:
/*case MESA_FORMAT_BGR888:*/
opt_sample_rgb_2d(ctx, texUnit, tObj, m, texcoords + magStart,
NULL, rgba + magStart);
break;
case MESA_FORMAT_RGBA:
case MESA_FORMAT_RGBA8888:
case MESA_FORMAT_ARGB8888:
/*case MESA_FORMAT_ABGR8888:*/
/*case MESA_FORMAT_BGRA8888:*/
opt_sample_rgba_2d(ctx, texUnit, tObj, m, texcoords + magStart,
NULL, rgba + magStart);
break;
default:
sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + magStart,
NULL, rgba + magStart );
}
}
else {
sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + magStart,
NULL, rgba + magStart);
}
break;
case GL_LINEAR:
sample_linear_2d(ctx, texUnit, 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 void
sample_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 void
sample_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;
GLuint useBorderColor;
GLfloat u, v, w;
(void) ctx;
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);
useBorderColor = 0;
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;
}
{
const GLfloat a = FRAC(u);
const GLfloat b = FRAC(v);
const GLfloat c = FRAC(w);
#if CHAN_TYPE == GL_UNSIGNED_BYTE
const GLint ia = IROUND_POS(a * ILERP_SCALE);
const GLint ib = IROUND_POS(b * ILERP_SCALE);
const GLint ic = IROUND_POS(c * ILERP_SCALE);
#endif
GLchan t000[4], t010[4], t001[4], t011[4];
GLchan t100[4], t110[4], t101[4], t111[4];
/* 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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -