diff options
Diffstat (limited to 'src/mesa/swrast/s_texture.c')
-rw-r--r-- | src/mesa/swrast/s_texture.c | 216 |
1 files changed, 206 insertions, 10 deletions
diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c index 97a8447c306..ab8b00abee0 100644 --- a/src/mesa/swrast/s_texture.c +++ b/src/mesa/swrast/s_texture.c @@ -1,4 +1,4 @@ -/* $Id: s_texture.c,v 1.62 2002/05/02 00:59:20 brianp Exp $ */ +/* $Id: s_texture.c,v 1.63 2002/06/15 03:03:11 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -2016,6 +2016,187 @@ sample_lambda_cube( GLcontext *ctx, GLuint texUnit, } +/**********************************************************************/ +/* Texture Rectangle Sampling Functions */ +/**********************************************************************/ + +static void +sample_nearest_rect(GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, GLuint n, + GLfloat texcoords[][4], const GLfloat lambda[], + GLchan rgba[][4]) +{ + const struct gl_texture_image *img = tObj->Image[0]; + const GLfloat width = (GLfloat) img->Width; + const GLfloat height = (GLfloat) img->Height; + const GLint width_minus_1 = img->Width - 1; + const GLint height_minus_1 = img->Height - 1; + GLuint i; + + (void) texUnit; + (void) lambda; + + ASSERT(tObj->WrapS == GL_CLAMP || + tObj->WrapS == GL_CLAMP_TO_EDGE || + tObj->WrapS == GL_CLAMP_TO_BORDER_ARB); + ASSERT(tObj->WrapT == GL_CLAMP || + tObj->WrapT == GL_CLAMP_TO_EDGE || + tObj->WrapT == GL_CLAMP_TO_BORDER_ARB); + ASSERT(img->Format != GL_COLOR_INDEX); + + /* XXX move Wrap mode tests outside of loops for common cases */ + for (i = 0; i < n; i++) { + GLint row, col; + /* NOTE: we DO NOT use [0, 1] texture coordinates! */ + if (tObj->WrapS == GL_CLAMP) { + col = IFLOOR( CLAMP(texcoords[i][0], 0.0F, width) ); + } + else if (tObj->WrapS == GL_CLAMP_TO_EDGE) { + col = IFLOOR( CLAMP(texcoords[i][0], 0.5F, width - 0.5F) ); + } + else { + col = IFLOOR( CLAMP(texcoords[i][0], -0.5F, width + 0.5F) ); + } + if (tObj->WrapT == GL_CLAMP) { + row = IFLOOR( CLAMP(texcoords[i][1], 0.0F, height) ); + } + else if (tObj->WrapT == GL_CLAMP_TO_EDGE) { + row = IFLOOR( CLAMP(texcoords[i][1], 0.5F, height - 0.5F) ); + } + else { + row = IFLOOR( CLAMP(texcoords[i][1], -0.5F, height + 0.5F) ); + } + + col = CLAMP(col, 0, width_minus_1); + row = CLAMP(row, 0, height_minus_1); + + (*img->FetchTexel)(img, col, row, 0, (GLvoid *) rgba[i]); + } +} + + +static void +sample_linear_rect(GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, GLuint n, + GLfloat texcoords[][4], + const GLfloat lambda[], GLchan rgba[][4]) +{ + const struct gl_texture_image *img = tObj->Image[0]; + const GLfloat width = (GLfloat) img->Width; + const GLfloat height = (GLfloat) img->Height; + const GLint width_minus_1 = img->Width - 1; + const GLint height_minus_1 = img->Height - 1; + GLuint i; + + (void) texUnit; + (void) lambda; + + ASSERT(tObj->WrapS == GL_CLAMP || + tObj->WrapS == GL_CLAMP_TO_EDGE || + tObj->WrapS == GL_CLAMP_TO_BORDER_ARB); + ASSERT(tObj->WrapT == GL_CLAMP || + tObj->WrapT == GL_CLAMP_TO_EDGE || + tObj->WrapT == GL_CLAMP_TO_BORDER_ARB); + ASSERT(img->Format != GL_COLOR_INDEX); + + /* XXX lots of opportunity for optimization in this loop */ + for (i = 0; i < n; i++) { + GLfloat frow, fcol; + GLint row0, col0, row1, col1; + GLchan t00[4], t01[4], t10[4], t11[4]; + GLfloat a, b, w00, w01, w10, w11; + + /* NOTE: we DO NOT use [0, 1] texture coordinates! */ + if (tObj->WrapS == GL_CLAMP) { + fcol = CLAMP(texcoords[i][0], 0.0F, width); + } + else if (tObj->WrapS == GL_CLAMP_TO_EDGE) { + fcol = CLAMP(texcoords[i][0], 0.5F, width - 0.5F); + } + else { + fcol = CLAMP(texcoords[i][0], -0.5F, width + 0.5F); + } + if (tObj->WrapT == GL_CLAMP) { + frow = CLAMP(texcoords[i][1], 0.0F, height); + } + else if (tObj->WrapT == GL_CLAMP_TO_EDGE) { + frow = CLAMP(texcoords[i][1], 0.5F, height - 0.5F); + } + else { + frow = CLAMP(texcoords[i][1], -0.5F, height + 0.5F); + } + + /* compute integer rows/columns */ + col0 = IFLOOR(fcol); + col1 = col0 + 1; + col0 = CLAMP(col0, 0, width_minus_1); + col1 = CLAMP(col1, 0, width_minus_1); + row0 = IFLOOR(frow); + row1 = row0 + 1; + row0 = CLAMP(row0, 0, height_minus_1); + row1 = CLAMP(row1, 0, height_minus_1); + + /* get four texel samples */ + (*img->FetchTexel)(img, col0, row0, 0, (GLvoid *) t00); + (*img->FetchTexel)(img, col1, row0, 0, (GLvoid *) t10); + (*img->FetchTexel)(img, col0, row1, 0, (GLvoid *) t01); + (*img->FetchTexel)(img, col1, row1, 0, (GLvoid *) t11); + + /* compute sample weights */ + a = FRAC(fcol); + b = FRAC(frow); + w00 = (1.0F-a) * (1.0F-b); + w10 = a * (1.0F-b); + w01 = (1.0F-a) * b ; + w11 = a * b ; + + /* compute weighted average of samples */ + rgba[i][0] = w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0]; + rgba[i][1] = w00 * t00[1] + w10 * t10[1] + w01 * t01[1] + w11 * t11[1]; + rgba[i][2] = w00 * t00[2] + w10 * t10[2] + w01 * t01[2] + w11 * t11[2]; + rgba[i][3] = w00 * t00[3] + w10 * t10[3] + w01 * t01[3] + w11 * t11[3]; + } +} + + +static void +sample_lambda_rect( GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, GLuint n, + GLfloat texcoords[][4], const GLfloat lambda[], + GLchan rgba[][4]) +{ + GLuint minStart, minEnd, magStart, magEnd; + + /* We only need lambda to decide between minification and magnification. + * There is no mipmapping with rectangular textures. + */ + compute_min_mag_ranges(SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit], + n, lambda, &minStart, &minEnd, &magStart, &magEnd); + + if (minStart < minEnd) { + if (tObj->MinFilter == GL_NEAREST) { + sample_nearest_rect( ctx, texUnit, tObj, minEnd - minStart, + texcoords + minStart, NULL, rgba + minStart); + } + else { + sample_linear_rect( ctx, texUnit, tObj, minEnd - minStart, + texcoords + minStart, NULL, rgba + minStart); + } + } + if (magStart < magEnd) { + if (tObj->MagFilter == GL_NEAREST) { + sample_nearest_rect( ctx, texUnit, tObj, magEnd - magStart, + texcoords + magStart, NULL, rgba + magStart); + } + else { + sample_linear_rect( ctx, texUnit, tObj, magEnd - magStart, + texcoords + magStart, NULL, rgba + magStart); + } + } +} + + + /* * Sample a shadow/depth texture. */ @@ -2036,7 +2217,9 @@ sample_depth_texture( GLcontext *ctx, GLuint unit, (void) unit; ASSERT(tObj->Image[tObj->BaseLevel]->Format == GL_DEPTH_COMPONENT); - ASSERT(tObj->Dimensions == 1 || tObj->Dimensions == 2); + ASSERT(tObj->Target == GL_TEXTURE_1D || + tObj->Target == GL_TEXTURE_2D || + tObj->Target == GL_TEXTURE_RECTANGLE_NV); /* XXXX if tObj->MinFilter != tObj->MagFilter, we're ignoring lambda */ @@ -2064,6 +2247,7 @@ sample_depth_texture( GLcontext *ctx, GLuint unit, for (i = 0; i < n; i++) { GLfloat depthSample; GLint col, row; + /* XXX fix for texture rectangle! */ COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0], width, col); COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoords[i][1], height, row); depthSample = *((const GLfloat *) texImage->Data + row * width + col); @@ -2134,6 +2318,7 @@ sample_depth_texture( GLcontext *ctx, GLuint unit, GLfloat u, v; GLuint useBorderTexel; + /* XXX fix for texture rectangle! */ COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoords[i][0], u, width, i0, i1); COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoords[i][1], v, height,j0, j1); @@ -2317,7 +2502,7 @@ sample_depth_texture2(const GLcontext *ctx, const GLchan ambient = texObj->ShadowAmbient; GLboolean lequal, gequal; - if (texObj->Dimensions != 2) { + if (texObj->Target != GL_TEXTURE_2D) { _mesa_problem(ctx, "only 2-D depth textures supported at this time"); return; } @@ -2435,8 +2620,8 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit, } } - switch (t->Dimensions) { - case 1: + switch (t->Target) { + case GL_TEXTURE_1D: if (format == GL_DEPTH_COMPONENT) { swrast->TextureSample[texUnit] = sample_depth_texture; } @@ -2451,7 +2636,7 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit, swrast->TextureSample[texUnit] = sample_nearest_1d; } break; - case 2: + case GL_TEXTURE_2D: if (format == GL_DEPTH_COMPONENT) { swrast->TextureSample[texUnit] = sample_depth_texture; } @@ -2480,7 +2665,7 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit, swrast->TextureSample[texUnit] = sample_nearest_2d; } break; - case 3: + case GL_TEXTURE_3D: if (needLambda) { swrast->TextureSample[texUnit] = sample_lambda_3d; } @@ -2492,7 +2677,7 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit, swrast->TextureSample[texUnit] = sample_nearest_3d; } break; - case 6: /* cube map */ + case GL_TEXTURE_CUBE_MAP_ARB: if (needLambda) { swrast->TextureSample[texUnit] = sample_lambda_cube; } @@ -2504,8 +2689,20 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit, swrast->TextureSample[texUnit] = sample_nearest_cube; } break; + case GL_TEXTURE_RECTANGLE_NV: + if (needLambda) { + swrast->TextureSample[texUnit] = sample_lambda_rect; + } + else if (t->MinFilter == GL_LINEAR) { + swrast->TextureSample[texUnit] = sample_linear_rect; + } + else { + ASSERT(t->MinFilter == GL_NEAREST); + swrast->TextureSample[texUnit] = sample_nearest_rect; + } + break; default: - _mesa_problem(ctx, "invalid dimensions in _swrast_choose_texture_sample_func"); + _mesa_problem(ctx, "invalid target in _swrast_choose_texture_sample_func"); } } } @@ -2640,7 +2837,6 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, return; argRGB[j] = (const GLchan (*)[4]) (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan))); - printf("unit %d from unit %d\n", unit, srcUnit); } } |