summaryrefslogtreecommitdiff
path: root/src/mesa/swrast/s_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/swrast/s_texture.c')
-rw-r--r--src/mesa/swrast/s_texture.c216
1 files changed, 206 insertions, 10 deletions
diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c
index 97a8447c30..ab8b00abee 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);
}
}