summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2004-05-06 20:28:26 +0000
committerBrian Paul <[email protected]>2004-05-06 20:28:26 +0000
commit4ab8b77520f77a7a28a688c7599c917703f1a5e7 (patch)
tree1c858e72ec1f21009ab143389f9545bc42daf9a6
parent122910070360b5044b768f08c742f871a5579bfa (diff)
fix rectangle texture clamping and border-related code
-rw-r--r--src/mesa/swrast/s_texture.c95
1 files changed, 72 insertions, 23 deletions
diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c
index 22d193381ba..6a4b7f7303b 100644
--- a/src/mesa/swrast/s_texture.c
+++ b/src/mesa/swrast/s_texture.c
@@ -2171,7 +2171,10 @@ sample_nearest_rect(GLcontext *ctx, GLuint texUnit,
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) );
+ /* Note: we use width-1, not what the spec says, but it actually
+ * does work correctly.
+ */
+ col = IFLOOR( CLAMP(texcoords[i][0], 0.0F, width - 1) );
}
else if (tObj->WrapS == GL_CLAMP_TO_EDGE) {
col = IFLOOR( CLAMP(texcoords[i][0], 0.5F, width - 0.5F) );
@@ -2180,7 +2183,7 @@ sample_nearest_rect(GLcontext *ctx, GLuint texUnit,
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) );
+ row = IFLOOR( CLAMP(texcoords[i][1], 0.0F, height - 1) );
}
else if (tObj->WrapT == GL_CLAMP_TO_EDGE) {
row = IFLOOR( CLAMP(texcoords[i][1], 0.5F, height - 0.5F) );
@@ -2189,10 +2192,10 @@ sample_nearest_rect(GLcontext *ctx, GLuint texUnit,
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->FetchTexelc(img, col, row, 0, rgba[i]);
+ if (col < 0 || col > width_minus_1 || row < 0 || row > height_minus_1)
+ COPY_CHAN4(rgba[i], tObj->_BorderChan);
+ else
+ img->FetchTexelc(img, col, row, 0, rgba[i]);
}
}
@@ -2224,45 +2227,91 @@ sample_linear_rect(GLcontext *ctx, GLuint texUnit,
/* XXX lots of opportunity for optimization in this loop */
for (i = 0; i < n; i++) {
GLfloat frow, fcol;
- GLint row0, col0, row1, col1;
+ GLint i0, j0, i1, j1;
GLchan t00[4], t01[4], t10[4], t11[4];
GLfloat a, b, w00, w01, w10, w11;
+ GLuint useBorderColor = 0;
/* NOTE: we DO NOT use [0, 1] texture coordinates! */
if (tObj->WrapS == GL_CLAMP) {
- fcol = CLAMP(texcoords[i][0], 0.0F, width);
+ /* clamping to width-1 looks wrong, but it's really correct */
+ fcol = CLAMP(texcoords[i][0], 0.0F, width_minus_1);
+ i0 = IFLOOR(fcol);
+ i1 = i0 + 1;
}
else if (tObj->WrapS == GL_CLAMP_TO_EDGE) {
fcol = CLAMP(texcoords[i][0], 0.5F, width - 0.5F);
+ i0 = IFLOOR(fcol);
+ i1 = i0 + 1;
+ if (i1 > width_minus_1)
+ i1 = width_minus_1;
}
- else {
+ else { /* GL_CLAMP_TO_BORDER */
+#if 0
+ /* literal reading of GL_NV_texture_rectangle spec */
fcol = CLAMP(texcoords[i][0], -0.5F, width + 0.5F);
+ i0 = IFLOOR(fcol);
+ i1 = i0 + 1;
+#else
+ /* Note: this produces results that matches NVIDIA, but it's not
+ * exactly what the GL_NV_texture_rectangle specifies!
+ */
+ fcol = texcoords[i][0];
+ i0 = IFLOOR(fcol);
+ i1 = i0 + 1;
+#endif
+
}
if (tObj->WrapT == GL_CLAMP) {
- frow = CLAMP(texcoords[i][1], 0.0F, height);
+ frow = CLAMP(texcoords[i][1], 0.0F, height_minus_1);
+ j0 = IFLOOR(frow);
+ j1 = j0 + 1;
}
else if (tObj->WrapT == GL_CLAMP_TO_EDGE) {
frow = CLAMP(texcoords[i][1], 0.5F, height - 0.5F);
+ j0 = IFLOOR(frow);
+ j1 = j0 + 1;
+ if (j1 > height_minus_1)
+ j1 = height_minus_1;
}
- else {
+ else { /* GL_CLAMP_TO_BORDER */
+#if 0
frow = CLAMP(texcoords[i][1], -0.5F, height + 0.5F);
+ j0 = IFLOOR(frow);
+ j1 = j0 + 1;
+#else
+ frow = texcoords[i][1];
+ j0 = IFLOOR(frow);
+ j1 = j0 + 1;
+#endif
}
/* 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);
+ if (i0 < 0 || i0 > width_minus_1) useBorderColor |= I0BIT;
+ if (i1 < 0 || i1 > width_minus_1) useBorderColor |= I1BIT;
+ if (j0 < 0 || j0 > height_minus_1) useBorderColor |= J0BIT;
+ if (j1 < 0 || j1 > height_minus_1) useBorderColor |= J1BIT;
/* get four texel samples */
- img->FetchTexelc(img, col0, row0, 0, t00);
- img->FetchTexelc(img, col1, row0, 0, t10);
- img->FetchTexelc(img, col0, row1, 0, t01);
- img->FetchTexelc(img, col1, row1, 0, t11);
+ if (useBorderColor & (I0BIT | J0BIT))
+ COPY_CHAN4(t00, tObj->_BorderChan);
+ else
+ img->FetchTexelc(img, i0, j0, 0, t00);
+
+ if (useBorderColor & (I1BIT | J0BIT))
+ COPY_CHAN4(t10, tObj->_BorderChan);
+ else
+ img->FetchTexelc(img, i1, j0, 0, t10);
+
+ if (useBorderColor & (I0BIT | J1BIT))
+ COPY_CHAN4(t01, tObj->_BorderChan);
+ else
+ img->FetchTexelc(img, i0, j1, 0, t01);
+
+ if (useBorderColor & (I1BIT | J1BIT))
+ COPY_CHAN4(t11, tObj->_BorderChan);
+ else
+ img->FetchTexelc(img, i1, j1, 0, t11);
/* compute sample weights */
a = FRAC(fcol);