aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2002-02-15 16:32:06 +0000
committerBrian Paul <[email protected]>2002-02-15 16:32:06 +0000
commit4182cf60d96a077a66675e89694529b5f9e4b329 (patch)
treec2782ab1c645d9bba43de21873e069c3f7b22520
parentc9ceef41fe89f5ba6e16ec51c1f9b7bfd8119c64 (diff)
Finished up GL_ARB_depth_texture and GL_ARB_shadow.
-rw-r--r--src/mesa/main/extensions.c6
-rw-r--r--src/mesa/main/texobj.c19
-rw-r--r--src/mesa/main/texstate.c27
-rw-r--r--src/mesa/swrast/s_texture.c697
4 files changed, 390 insertions, 359 deletions
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index ee8eb4f5383..8054360fd29 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -1,10 +1,10 @@
-/* $Id: extensions.c,v 1.68 2001/12/14 02:50:01 brianp Exp $ */
+/* $Id: extensions.c,v 1.69 2002/02/15 16:32:06 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -56,7 +56,7 @@ static struct {
const char *name;
int flag_offset;
} default_extensions[] = {
- { OFF, "GL_ARB_depth_texture", F(SGIX_depth_texture) },
+ { OFF, "GL_ARB_depth_texture", F(ARB_depth_texture) },
{ OFF, "GL_ARB_imaging", F(ARB_imaging) },
{ OFF, "GL_ARB_multisample", F(ARB_multisample) },
{ OFF, "GL_ARB_multitexture", F(ARB_multitexture) },
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index a8a27ef3ed9..39f65940b5d 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -1,10 +1,10 @@
-/* $Id: texobj.c,v 1.51 2001/12/04 23:44:56 brianp Exp $ */
+/* $Id: texobj.c,v 1.52 2002/02/15 16:32:06 brianp Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 4.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -84,7 +84,7 @@ _mesa_alloc_texture_object( struct gl_shared_state *shared,
obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX; /* SGIX_shadow */
obj->CompareMode = GL_LUMINANCE; /* ARB_shadow */
obj->CompareFunc = GL_LEQUAL; /* ARB_shadow */
- obj->CompareResult = GL_LUMINANCE; /* ARB_shadow */
+ obj->DepthMode = GL_LUMINANCE; /* ARB_depth_texture */
obj->ShadowAmbient = 0; /* ARB/SGIX_shadow_ambient */
_mesa_init_colortable(&obj->Palette);
@@ -360,6 +360,11 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
t->Complete = GL_FALSE;
return;
}
+ if (t->Image[i]->Format == GL_DEPTH_COMPONENT) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
+ return;
+ }
if (t->Image[i]->Width2 != width) {
t->Complete = GL_FALSE;
incomplete(t, "3D Image[i] bad width");
@@ -393,6 +398,12 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
height /= 2;
}
if (i >= minLevel && i <= maxLevel) {
+ /* Don't support GL_DEPTH_COMPONENT for cube maps */
+ if (t->Image[i]->Format == GL_DEPTH_COMPONENT) {
+ t->Complete = GL_FALSE;
+ incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
+ return;
+ }
/* check that we have images defined */
if (!t->Image[i] || !t->NegX[i] ||
!t->PosY[i] || !t->NegY[i] ||
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index a8c70f0a4c5..19e8984ad96 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -1,4 +1,4 @@
-/* $Id: texstate.c,v 1.63 2002/01/09 02:14:29 brianp Exp $ */
+/* $Id: texstate.c,v 1.64 2002/02/15 16:32:06 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -46,7 +46,6 @@
#ifndef GL_TEXTURE_COMPARE_MODE_ARB
#define GL_TEXTURE_COMPARE_MODE_ARB 0x9990
#define GL_TEXTURE_COMPARE_FUNC_ARB 0x9991
-#define GL_TEXTURE_COMPARE_RESULT_ARB 0x9992
#define GL_COMPARE_R_TO_TEXTURE_ARB 0x9993
#endif
@@ -1109,7 +1108,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
case GL_TEXTURE_COMPARE_MODE_ARB:
if (ctx->Extensions.ARB_shadow) {
const GLenum mode = (GLenum) params[0];
- if (mode == GL_LUMINANCE || mode == GL_COMPARE_R_TO_TEXTURE_ARB) {
+ if (mode == GL_NONE || mode == GL_COMPARE_R_TO_TEXTURE_ARB) {
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texObj->CompareMode = params[0];
}
@@ -1144,23 +1143,23 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
return;
}
break;
- case GL_TEXTURE_COMPARE_RESULT_ARB:
- if (ctx->Extensions.ARB_shadow) {
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ if (ctx->Extensions.ARB_depth_texture) {
const GLenum result = (GLenum) params[0];
if (result == GL_LUMINANCE || result == GL_INTENSITY
|| result == GL_ALPHA) {
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
- texObj->CompareResult = params[0];
+ texObj->DepthMode = params[0];
}
else {
_mesa_error(ctx, GL_INVALID_ENUM,
- "glTexParameter(bad GL_TEXTURE_COMPARE_RESULT_ARB)");
+ "glTexParameter(bad GL_DEPTH_TEXTURE_MODE_ARB)");
return;
}
}
else {
_mesa_error(ctx, GL_INVALID_ENUM,
- "glTexParameter(pname=GL_TEXTURE_COMPARE_RESULT_ARB)");
+ "glTexParameter(pname=GL_DEPTH_TEXTURE_MODE_ARB)");
return;
}
break;
@@ -1504,9 +1503,9 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
return;
}
break;
- case GL_TEXTURE_COMPARE_RESULT_ARB:
- if (ctx->Extensions.ARB_shadow) {
- *params = (GLfloat) obj->CompareResult;
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ if (ctx->Extensions.ARB_depth_texture) {
+ *params = (GLfloat) obj->DepthMode;
return;
}
break;
@@ -1633,9 +1632,9 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
return;
}
break;
- case GL_TEXTURE_COMPARE_RESULT_ARB:
- if (ctx->Extensions.ARB_shadow) {
- *params = (GLint) obj->CompareResult;
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ if (ctx->Extensions.ARB_depth_texture) {
+ *params = (GLint) obj->DepthMode;
return;
}
break;
diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c
index 206508559f0..0f1c5cdc968 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.50 2002/02/15 03:41:47 brianp Exp $ */
+/* $Id: s_texture.c,v 1.51 2002/02/15 16:32:06 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -1753,6 +1753,336 @@ sample_lambda_cube( GLcontext *ctx, GLuint texUnit,
}
+/*
+ * Sample a shadow/depth texture.
+ */
+static void
+sample_depth_texture( GLcontext *ctx, GLuint unit,
+ const struct gl_texture_object *tObj, GLuint n,
+ GLfloat texcoords[][4], const GLfloat lambda[],
+ GLchan texel[][4] )
+{
+ const GLint baseLevel = tObj->BaseLevel;
+ const struct gl_texture_image *texImage = tObj->Image[baseLevel];
+ const GLuint width = texImage->Width;
+ const GLuint height = texImage->Height;
+ const GLchan ambient = tObj->ShadowAmbient;
+ GLboolean lequal, gequal;
+ GLchan result;
+
+ (void) unit;
+
+ ASSERT(tObj->Image[tObj->BaseLevel]->Format == GL_DEPTH_COMPONENT);
+ ASSERT(tObj->Dimensions == 1 || tObj->Dimensions == 2);
+
+ /* XXXX if tObj->MinFilter != tObj->MagFilter, we're ignoring lambda */
+
+ /* XXX this could be precomputed and saved in the texture object */
+ if (tObj->CompareFlag) {
+ /* GL_SGIX_shadow */
+ if (tObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
+ lequal = GL_TRUE;
+ gequal = GL_FALSE;
+ }
+ else {
+ ASSERT(tObj->CompareOperator == GL_TEXTURE_GEQUAL_R_SGIX);
+ lequal = GL_FALSE;
+ gequal = GL_TRUE;
+ }
+ }
+ else if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
+ /* GL_ARB_shadow */
+ if (tObj->CompareFunc == GL_LEQUAL) {
+ lequal = GL_TRUE;
+ gequal = GL_FALSE;
+ }
+ else {
+ ASSERT(tObj->CompareFunc == GL_GEQUAL);
+ lequal = GL_FALSE;
+ gequal = GL_TRUE;
+ }
+ }
+ else {
+ lequal = gequal = GL_FALSE;
+ }
+
+ if (tObj->MagFilter == GL_NEAREST) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLfloat depthSample;
+ GLint col, row;
+ 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);
+
+ if (lequal) {
+ if (texcoords[i][2] <= depthSample)
+ result = CHAN_MAX;
+ else
+ result = ambient;
+ }
+ else if (gequal) {
+ if (texcoords[i][2] >= depthSample)
+ result = CHAN_MAX;
+ else
+ result = ambient;
+ }
+ else {
+ /* no comparison */
+ CLAMPED_FLOAT_TO_CHAN(result, depthSample);
+ }
+
+ switch (tObj->DepthMode) {
+ case GL_LUMINANCE:
+ texel[i][RCOMP] = result;
+ texel[i][GCOMP] = result;
+ texel[i][BCOMP] = result;
+ texel[i][ACOMP] = CHAN_MAX;
+ break;
+ case GL_INTENSITY:
+ texel[i][RCOMP] = result;
+ texel[i][GCOMP] = result;
+ texel[i][BCOMP] = result;
+ texel[i][ACOMP] = result;
+ break;
+ case GL_ALPHA:
+ texel[i][RCOMP] = 0;
+ texel[i][GCOMP] = 0;
+ texel[i][BCOMP] = 0;
+ texel[i][ACOMP] = result;
+ break;
+ default:
+ _mesa_problem(ctx, "Bad depth texture mode");
+ }
+ }
+ }
+ else {
+ GLuint i;
+ ASSERT(tObj->MagFilter == GL_LINEAR);
+ for (i = 0; i < n; i++) {
+ GLfloat depth00, depth01, depth10, depth11;
+ GLint i0, i1, j0, j1;
+ GLfloat u, v;
+ GLuint useBorderTexel;
+
+ 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);
+
+ useBorderTexel = 0;
+ if (texImage->Border) {
+ i0 += texImage->Border;
+ i1 += texImage->Border;
+ j0 += texImage->Border;
+ j1 += texImage->Border;
+ }
+ else {
+ if (i0 < 0 || i0 >= (GLint) width) useBorderTexel |= I0BIT;
+ if (i1 < 0 || i1 >= (GLint) width) useBorderTexel |= I1BIT;
+ if (j0 < 0 || j0 >= (GLint) height) useBorderTexel |= J0BIT;
+ if (j1 < 0 || j1 >= (GLint) height) useBorderTexel |= J1BIT;
+ }
+
+ /* get four depth samples from the texture */
+ if (useBorderTexel & (I0BIT | J0BIT)) {
+ depth00 = 1.0;
+ }
+ else {
+ depth00 = *((const GLfloat *) texImage->Data + j0 * width + i0);
+ }
+ if (useBorderTexel & (I1BIT | J0BIT)) {
+ depth10 = 1.0;
+ }
+ else {
+ depth10 = *((const GLfloat *) texImage->Data + j0 * width + i1);
+ }
+ if (useBorderTexel & (I0BIT | J1BIT)) {
+ depth01 = 1.0;
+ }
+ else {
+ depth01 = *((const GLfloat *) texImage->Data + j1 * width + i0);
+ }
+ if (useBorderTexel & (I1BIT | J1BIT)) {
+ depth11 = 1.0;
+ }
+ else {
+ depth11 = *((const GLfloat *) texImage->Data + j1 * width + i1);
+ }
+
+ if (0) {
+ /* compute a single weighted depth sample and do one comparison */
+ const GLfloat a = FRAC(u + 1.0F);
+ const GLfloat b = FRAC(v + 1.0F);
+ const GLfloat w00 = (1.0F - a) * (1.0F - b);
+ const GLfloat w10 = ( a) * (1.0F - b);
+ const GLfloat w01 = (1.0F - a) * ( b);
+ const GLfloat w11 = ( a) * ( b);
+ const GLfloat depthSample = w00 * depth00 + w10 * depth10
+ + w01 * depth01 + w11 * depth11;
+ if ((depthSample <= texcoords[i][2] && lequal) ||
+ (depthSample >= texcoords[i][2] && gequal)) {
+ result = ambient;
+ }
+ else {
+ result = CHAN_MAX;
+ }
+ }
+ else {
+ /* Do four depth/R comparisons and compute a weighted result.
+ * If this touches on somebody's I.P., I'll remove this code
+ * upon request.
+ */
+ const GLfloat d = (CHAN_MAXF - (GLfloat) ambient) * 0.25F;
+ GLfloat luminance = CHAN_MAXF;
+ if (lequal) {
+ if (depth00 <= texcoords[i][2]) luminance -= d;
+ if (depth01 <= texcoords[i][2]) luminance -= d;
+ if (depth10 <= texcoords[i][2]) luminance -= d;
+ if (depth11 <= texcoords[i][2]) luminance -= d;
+ result = (GLchan) luminance;
+ }
+ else if (gequal) {
+ if (depth00 >= texcoords[i][2]) luminance -= d;
+ if (depth01 >= texcoords[i][2]) luminance -= d;
+ if (depth10 >= texcoords[i][2]) luminance -= d;
+ if (depth11 >= texcoords[i][2]) luminance -= d;
+ result = (GLchan) luminance;
+ }
+ else {
+ /* no comparison, just bilinear sampling */
+ const GLfloat a = FRAC(u + 1.0F);
+ const GLfloat b = FRAC(v + 1.0F);
+ const GLfloat w00 = (1.0F - a) * (1.0F - b);
+ const GLfloat w10 = ( a) * (1.0F - b);
+ const GLfloat w01 = (1.0F - a) * ( b);
+ const GLfloat w11 = ( a) * ( b);
+ const GLfloat depthSample = w00 * depth00 + w10 * depth10
+ + w01 * depth01 + w11 * depth11;
+ CLAMPED_FLOAT_TO_CHAN(result, depthSample);
+ }
+ }
+
+ switch (tObj->DepthMode) {
+ case GL_LUMINANCE:
+ texel[i][RCOMP] = result;
+ texel[i][GCOMP] = result;
+ texel[i][BCOMP] = result;
+ texel[i][ACOMP] = CHAN_MAX;
+ break;
+ case GL_INTENSITY:
+ texel[i][RCOMP] = result;
+ texel[i][GCOMP] = result;
+ texel[i][BCOMP] = result;
+ texel[i][ACOMP] = result;
+ break;
+ case GL_ALPHA:
+ texel[i][RCOMP] = 0;
+ texel[i][GCOMP] = 0;
+ texel[i][BCOMP] = 0;
+ texel[i][ACOMP] = result;
+ break;
+ default:
+ _mesa_problem(ctx, "Bad depth texture mode");
+ }
+ } /* for */
+ } /* if filter */
+}
+
+
+#if 0
+/*
+ * Experimental depth texture sampling function.
+ */
+static void
+sample_depth_texture2(const GLcontext *ctx,
+ const struct gl_texture_unit *texUnit,
+ GLuint n, GLfloat texcoords[][4],
+ GLchan texel[][4])
+{
+ const struct gl_texture_object *texObj = texUnit->_Current;
+ const GLint baseLevel = texObj->BaseLevel;
+ const struct gl_texture_image *texImage = texObj->Image[baseLevel];
+ const GLuint width = texImage->Width;
+ const GLuint height = texImage->Height;
+ const GLchan ambient = texObj->ShadowAmbient;
+ GLboolean lequal, gequal;
+
+ if (texObj->Dimensions != 2) {
+ _mesa_problem(ctx, "only 2-D depth textures supported at this time");
+ return;
+ }
+
+ if (texObj->MinFilter != texObj->MagFilter) {
+ _mesa_problem(ctx, "mipmapped depth textures not supported at this time");
+ return;
+ }
+
+ /* XXX the GL_SGIX_shadow extension spec doesn't say what to do if
+ * GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object
+ * isn't a depth texture.
+ */
+ if (texImage->Format != GL_DEPTH_COMPONENT) {
+ _mesa_problem(ctx,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture");
+ return;
+ }
+
+ if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
+ lequal = GL_TRUE;
+ gequal = GL_FALSE;
+ }
+ else {
+ lequal = GL_FALSE;
+ gequal = GL_TRUE;
+ }
+
+ {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLint K = 3;
+ GLint col, row, ii, jj, imin, imax, jmin, jmax, samples, count;
+ GLfloat w;
+ GLchan lum;
+ COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, texcoords[i][0],
+ width, col);
+ COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, texcoords[i][1],
+ height, row);
+
+ imin = col - K;
+ imax = col + K;
+ jmin = row - K;
+ jmax = row + K;
+
+ if (imin < 0) imin = 0;
+ if (imax >= width) imax = width - 1;
+ if (jmin < 0) jmin = 0;
+ if (jmax >= height) jmax = height - 1;
+
+ samples = (imax - imin + 1) * (jmax - jmin + 1);
+ count = 0;
+ for (jj = jmin; jj <= jmax; jj++) {
+ for (ii = imin; ii <= imax; ii++) {
+ GLfloat depthSample = *((const GLfloat *) texImage->Data
+ + jj * width + ii);
+ if ((depthSample <= r[i] && lequal) ||
+ (depthSample >= r[i] && gequal)) {
+ count++;
+ }
+ }
+ }
+
+ w = (GLfloat) count / (GLfloat) samples;
+ w = CHAN_MAXF - w * (CHAN_MAXF - (GLfloat) ambient);
+ lum = (GLint) w;
+
+ texel[i][RCOMP] = lum;
+ texel[i][GCOMP] = lum;
+ texel[i][BCOMP] = lum;
+ texel[i][ACOMP] = CHAN_MAX;
+ }
+ }
+}
+#endif
+
+
static void
null_sample_func( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
@@ -1777,11 +2107,12 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- if (!t->Complete) {
- swrast->TextureSample[texUnit] = null_sample_func;
+ if (!t->Complete) {
+ swrast->TextureSample[texUnit] = null_sample_func;
}
else {
- GLboolean needLambda = (GLboolean) (t->MinFilter != t->MagFilter);
+ const GLboolean needLambda = (GLboolean) (t->MinFilter != t->MagFilter);
+ const GLenum format = t->Image[t->BaseLevel]->Format;
if (needLambda) {
/* Compute min/mag filter threshold */
@@ -1797,27 +2128,33 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
switch (t->Dimensions) {
case 1:
- if (needLambda) {
+ if (format == GL_DEPTH_COMPONENT) {
+ swrast->TextureSample[texUnit] = sample_depth_texture;
+ }
+ else if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_1d;
}
- else if (t->MinFilter==GL_LINEAR) {
+ else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_1d;
}
else {
- ASSERT(t->MinFilter==GL_NEAREST);
+ ASSERT(t->MinFilter == GL_NEAREST);
swrast->TextureSample[texUnit] = sample_nearest_1d;
}
break;
case 2:
- if (needLambda) {
+ if (format == GL_DEPTH_COMPONENT) {
+ swrast->TextureSample[texUnit] = sample_depth_texture;
+ }
+ else if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_2d;
}
- else if (t->MinFilter==GL_LINEAR) {
+ else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_2d;
}
else {
GLint baseLevel = t->BaseLevel;
- ASSERT(t->MinFilter==GL_NEAREST);
+ ASSERT(t->MinFilter == GL_NEAREST);
if (t->WrapS == GL_REPEAT &&
t->WrapT == GL_REPEAT &&
t->Image[baseLevel]->Border == 0 &&
@@ -1838,11 +2175,11 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_3d;
}
- else if (t->MinFilter==GL_LINEAR) {
+ else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_3d;
}
else {
- ASSERT(t->MinFilter==GL_NEAREST);
+ ASSERT(t->MinFilter == GL_NEAREST);
swrast->TextureSample[texUnit] = sample_nearest_3d;
}
break;
@@ -1850,11 +2187,11 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_cube;
}
- else if (t->MinFilter==GL_LINEAR) {
+ else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_cube;
}
else {
- ASSERT(t->MinFilter==GL_NEAREST);
+ ASSERT(t->MinFilter == GL_NEAREST);
swrast->TextureSample[texUnit] = sample_nearest_cube;
}
break;
@@ -2344,8 +2681,8 @@ apply_texture( const GLcontext *ctx,
format = texUnit->_Current->Image[baseLevel]->Format;
- if (format==GL_COLOR_INDEX || format==GL_DEPTH_COMPONENT) {
- format = GL_RGBA; /* XXXX a hack! */
+ if (format == GL_COLOR_INDEX || format == GL_DEPTH_COMPONENT) {
+ format = GL_RGBA; /* a bit of a hack */
}
switch (texUnit->EnvMode) {
@@ -2668,327 +3005,6 @@ apply_texture( const GLcontext *ctx,
/*
- * Sample a shadow/depth texture.
- * Input: ctx - context
- * texUnit - the texture unit
- * n - number of samples
- * s,t,r - array [n] of texture coordinates
- * In/Out: rgba - array [n] of texel colors.
- */
-static void
-sample_depth_texture(const GLcontext *ctx,
- const struct gl_texture_unit *texUnit,
- GLuint n, GLfloat texcoords[][4],
- GLchan texel[][4])
-{
- const struct gl_texture_object *texObj = texUnit->_Current;
- const GLint baseLevel = texObj->BaseLevel;
- const struct gl_texture_image *texImage = texObj->Image[baseLevel];
- const GLuint width = texImage->Width;
- const GLuint height = texImage->Height;
- const GLchan ambient = texObj->ShadowAmbient;
- GLboolean lequal, gequal;
- GLchan result;
-
- ASSERT(texObj->Image[texObj->BaseLevel]->Format == GL_DEPTH_COMPONENT);
-
- if (texObj->Dimensions != 2) {
- _mesa_problem(ctx, "only 2-D depth textures supported at this time");
- return;
- }
-
- if (texObj->MinFilter != texObj->MagFilter) {
- _mesa_problem(ctx, "mipmapped depth textures not supported at this time");
- return;
- }
-
- /* XXX this could be precomputed */
- if (texObj->CompareFlag) {
- /* GL_SGIX_shadow */
- if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
- lequal = GL_TRUE;
- gequal = GL_FALSE;
- }
- else {
- ASSERT(texObj->CompareOperator == GL_TEXTURE_GEQUAL_R_SGIX);
- lequal = GL_FALSE;
- gequal = GL_TRUE;
- }
- }
- else if (texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
- /* GL_ARB_shadow */
- if (texObj->CompareFunc == GL_LEQUAL) {
- lequal = GL_TRUE;
- gequal = GL_FALSE;
- }
- else {
- ASSERT(texObj->CompareFunc == GL_GEQUAL);
- lequal = GL_FALSE;
- gequal = GL_TRUE;
- }
- }
- else {
- /* Treat this depth texture as a luminance texture */
- _mesa_warning(ctx,
- "Treating GL_DEPTH_COMPONENT as GL_LUMINANCE not implemented yet");
- return;
- }
-
- if (texObj->MagFilter == GL_NEAREST) {
- GLuint i;
- for (i = 0; i < n; i++) {
- GLfloat depthSample;
- GLint col, row;
- COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, texcoords[i][0], width, col);
- COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, texcoords[i][1], height, row);
- depthSample = *((const GLfloat *) texImage->Data + row * width + col);
- if ((texcoords[i][2] <= depthSample && lequal) ||
- (texcoords[i][2] >= depthSample && gequal)) {
- result = CHAN_MAX;
- }
- else {
- result = ambient;
- }
-
- switch (texObj->CompareResult) {
- case GL_LUMINANCE:
- texel[i][RCOMP] = result;
- texel[i][GCOMP] = result;
- texel[i][BCOMP] = result;
- texel[i][ACOMP] = CHAN_MAX;
- break;
- case GL_INTENSITY:
- texel[i][RCOMP] = result;
- texel[i][GCOMP] = result;
- texel[i][BCOMP] = result;
- texel[i][ACOMP] = result;
- break;
- case GL_ALPHA:
- texel[i][RCOMP] = 0;
- texel[i][GCOMP] = 0;
- texel[i][BCOMP] = 0;
- texel[i][ACOMP] = result;
- break;
- default:
- _mesa_problem(ctx, "Bad texture compare result value");
- }
- }
- }
- else {
- GLuint i;
- ASSERT(texObj->MagFilter == GL_LINEAR);
- for (i = 0; i < n; i++) {
- GLfloat depth00, depth01, depth10, depth11;
- GLint i0, i1, j0, j1;
- GLfloat u, v;
- GLuint useBorderTexel;
-
- COMPUTE_LINEAR_TEXEL_LOCATIONS(texObj->WrapS, texcoords[i][0], u, width, i0, i1);
- COMPUTE_LINEAR_TEXEL_LOCATIONS(texObj->WrapT, texcoords[i][1], v, height,j0, j1);
-
- useBorderTexel = 0;
- if (texImage->Border) {
- i0 += texImage->Border;
- i1 += texImage->Border;
- j0 += texImage->Border;
- j1 += texImage->Border;
- }
- else {
- if (i0 < 0 || i0 >= (GLint) width) useBorderTexel |= I0BIT;
- if (i1 < 0 || i1 >= (GLint) width) useBorderTexel |= I1BIT;
- if (j0 < 0 || j0 >= (GLint) height) useBorderTexel |= J0BIT;
- if (j1 < 0 || j1 >= (GLint) height) useBorderTexel |= J1BIT;
- }
-
- /* get four depth samples from the texture */
- if (useBorderTexel & (I0BIT | J0BIT)) {
- depth00 = 1.0;
- }
- else {
- depth00 = *((const GLfloat *) texImage->Data + j0 * width + i0);
- }
- if (useBorderTexel & (I1BIT | J0BIT)) {
- depth10 = 1.0;
- }
- else {
- depth10 = *((const GLfloat *) texImage->Data + j0 * width + i1);
- }
- if (useBorderTexel & (I0BIT | J1BIT)) {
- depth01 = 1.0;
- }
- else {
- depth01 = *((const GLfloat *) texImage->Data + j1 * width + i0);
- }
- if (useBorderTexel & (I1BIT | J1BIT)) {
- depth11 = 1.0;
- }
- else {
- depth11 = *((const GLfloat *) texImage->Data + j1 * width + i1);
- }
-
- if (0) {
- /* compute a single weighted depth sample and do one comparison */
- const GLfloat a = FRAC(u + 1.0F);
- const GLfloat b = FRAC(v + 1.0F);
- const GLfloat w00 = (1.0F - a) * (1.0F - b);
- const GLfloat w10 = ( a) * (1.0F - b);
- const GLfloat w01 = (1.0F - a) * ( b);
- const GLfloat w11 = ( a) * ( b);
- const GLfloat depthSample = w00 * depth00 + w10 * depth10
- + w01 * depth01 + w11 * depth11;
- if ((depthSample <= texcoords[i][2] && lequal) ||
- (depthSample >= texcoords[i][2] && gequal)) {
- result = ambient;
- }
- else {
- result = CHAN_MAX;
- }
- }
- else {
- /* Do four depth/R comparisons and compute a weighted result.
- * If this touches on somebody's I.P., I'll remove this code
- * upon request.
- */
- const GLfloat d = (CHAN_MAXF - (GLfloat) ambient) * 0.25F;
- GLfloat luminance = CHAN_MAXF;
- if (lequal) {
- if (depth00 <= texcoords[i][2]) luminance -= d;
- if (depth01 <= texcoords[i][2]) luminance -= d;
- if (depth10 <= texcoords[i][2]) luminance -= d;
- if (depth11 <= texcoords[i][2]) luminance -= d;
- }
- else {
- if (depth00 >= texcoords[i][2]) luminance -= d;
- if (depth01 >= texcoords[i][2]) luminance -= d;
- if (depth10 >= texcoords[i][2]) luminance -= d;
- if (depth11 >= texcoords[i][2]) luminance -= d;
- }
- result = (GLchan) luminance;
- }
-
- switch (texObj->CompareResult) {
- case GL_LUMINANCE:
- texel[i][RCOMP] = result;
- texel[i][GCOMP] = result;
- texel[i][BCOMP] = result;
- texel[i][ACOMP] = CHAN_MAX;
- break;
- case GL_INTENSITY:
- texel[i][RCOMP] = result;
- texel[i][GCOMP] = result;
- texel[i][BCOMP] = result;
- texel[i][ACOMP] = result;
- break;
- case GL_ALPHA:
- texel[i][RCOMP] = 0;
- texel[i][GCOMP] = 0;
- texel[i][BCOMP] = 0;
- texel[i][ACOMP] = result;
- break;
- default:
- _mesa_problem(ctx, "Bad texture compare result value");
- }
- } /* for */
- } /* if filter */
-}
-
-
-#if 0
-/*
- * Experimental depth texture sampling function.
- */
-static void
-sample_depth_texture2(const GLcontext *ctx,
- const struct gl_texture_unit *texUnit,
- GLuint n, GLfloat texcoords[][4],
- GLchan texel[][4])
-{
- const struct gl_texture_object *texObj = texUnit->_Current;
- const GLint baseLevel = texObj->BaseLevel;
- const struct gl_texture_image *texImage = texObj->Image[baseLevel];
- const GLuint width = texImage->Width;
- const GLuint height = texImage->Height;
- const GLchan ambient = texObj->ShadowAmbient;
- GLboolean lequal, gequal;
-
- if (texObj->Dimensions != 2) {
- _mesa_problem(ctx, "only 2-D depth textures supported at this time");
- return;
- }
-
- if (texObj->MinFilter != texObj->MagFilter) {
- _mesa_problem(ctx, "mipmapped depth textures not supported at this time");
- return;
- }
-
- /* XXX the GL_SGIX_shadow extension spec doesn't say what to do if
- * GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object
- * isn't a depth texture.
- */
- if (texImage->Format != GL_DEPTH_COMPONENT) {
- _mesa_problem(ctx,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture");
- return;
- }
-
- if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
- lequal = GL_TRUE;
- gequal = GL_FALSE;
- }
- else {
- lequal = GL_FALSE;
- gequal = GL_TRUE;
- }
-
- {
- GLuint i;
- for (i = 0; i < n; i++) {
- const GLint K = 3;
- GLint col, row, ii, jj, imin, imax, jmin, jmax, samples, count;
- GLfloat w;
- GLchan lum;
- COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, texcoords[i][0],
- width, col);
- COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, texcoords[i][1],
- height, row);
-
- imin = col - K;
- imax = col + K;
- jmin = row - K;
- jmax = row + K;
-
- if (imin < 0) imin = 0;
- if (imax >= width) imax = width - 1;
- if (jmin < 0) jmin = 0;
- if (jmax >= height) jmax = height - 1;
-
- samples = (imax - imin + 1) * (jmax - jmin + 1);
- count = 0;
- for (jj = jmin; jj <= jmax; jj++) {
- for (ii = imin; ii <= imax; ii++) {
- GLfloat depthSample = *((const GLfloat *) texImage->Data
- + jj * width + ii);
- if ((depthSample <= r[i] && lequal) ||
- (depthSample >= r[i] && gequal)) {
- count++;
- }
- }
- }
-
- w = (GLfloat) count / (GLfloat) samples;
- w = CHAN_MAXF - w * (CHAN_MAXF - (GLfloat) ambient);
- lum = (GLint) w;
-
- texel[i][RCOMP] = lum;
- texel[i][GCOMP] = lum;
- texel[i][BCOMP] = lum;
- texel[i][ACOMP] = CHAN_MAX;
- }
- }
-}
-#endif
-
-
-/*
* Apply a unit of texture mapping to the incoming fragments.
*/
void
@@ -3027,17 +3043,22 @@ _swrast_texture_fragments( GLcontext *ctx, GLuint texUnit, GLuint n,
}
/* Sample the texture. */
+#if 000
if (curObj->Image[curObj->BaseLevel]->Format == GL_DEPTH_COMPONENT) {
/* depth texture */
- sample_depth_texture(ctx, textureUnit, n, texcoords, texel);
+ sample_depth_texture(ctx, texUnit, textureUnit->_Current,
+ n, texcoords, lambda, texel);
}
else {
/* color texture */
+#endif
SWRAST_CONTEXT(ctx)->TextureSample[texUnit]( ctx, texUnit,
textureUnit->_Current,
n, texcoords,
lambda, texel );
+#if 0
}
+#endif
apply_texture( ctx, textureUnit, n, primary_rgba,
(const GLchan (*)[4]) texel, rgba );
}