bilinear sampling of depth textures
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: s_texture.c,v 1.12 2001/02/20 16:42:26 brianp Exp $ */
|
/* $Id: s_texture.c,v 1.13 2001/02/26 18:24:37 brianp Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mesa 3-D graphics library
|
* Mesa 3-D graphics library
|
||||||
@@ -49,6 +49,13 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to compute texel locations for linear sampling.
|
* Used to compute texel locations for linear sampling.
|
||||||
|
* Input:
|
||||||
|
* wrapMode = GL_REPEAT, GL_CLAMP or GL_CLAMP_TO_EDGE
|
||||||
|
* S = texcoord in [0,1]
|
||||||
|
* SIZE = width (or height or depth) of texture
|
||||||
|
* Output:
|
||||||
|
* U = texcoord in [0, width]
|
||||||
|
* I0, I1 = two nearest texel indexes
|
||||||
*/
|
*/
|
||||||
#define COMPUTE_LINEAR_TEXEL_LOCATIONS(wrapMode, S, U, SIZE, I0, I1) \
|
#define COMPUTE_LINEAR_TEXEL_LOCATIONS(wrapMode, S, U, SIZE, I0, I1) \
|
||||||
{ \
|
{ \
|
||||||
@@ -2341,12 +2348,12 @@ apply_texture( const GLcontext *ctx,
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Apply a shadow/depth texture to the array of colors.
|
* Sample a shadow/depth texture.
|
||||||
* Input: ctx - context
|
* Input: ctx - context
|
||||||
* texUnit - the texture unit
|
* texUnit - the texture unit
|
||||||
* n - number of colors
|
* n - number of samples
|
||||||
* r - array [n] of texture R coordinates
|
* s,t,r - array [n] of texture coordinates
|
||||||
* In/Out: rgba - array [n] of colors.
|
* In/Out: rgba - array [n] of texel colors.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
sample_depth_texture(const GLcontext *ctx,
|
sample_depth_texture(const GLcontext *ctx,
|
||||||
@@ -2356,10 +2363,31 @@ sample_depth_texture(const GLcontext *ctx,
|
|||||||
GLchan texel[][4])
|
GLchan texel[][4])
|
||||||
{
|
{
|
||||||
const struct gl_texture_object *texObj = texUnit->_Current;
|
const struct gl_texture_object *texObj = texUnit->_Current;
|
||||||
const struct gl_texture_image *texImage = texObj->Image[0]; /* XXX hack */
|
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;
|
const GLchan ambient = texObj->ShadowAmbient;
|
||||||
GLboolean lequal, gequal;
|
GLboolean lequal, gequal;
|
||||||
GLuint i;
|
|
||||||
|
if (texObj->Dimensions != 2) {
|
||||||
|
gl_problem(ctx, "only 2-D depth textures supported at this time");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texObj->MinFilter != texObj->MagFilter) {
|
||||||
|
gl_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) {
|
||||||
|
gl_problem(ctx,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
|
if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
|
||||||
lequal = GL_TRUE;
|
lequal = GL_TRUE;
|
||||||
@@ -2370,35 +2398,229 @@ sample_depth_texture(const GLcontext *ctx,
|
|||||||
gequal = GL_TRUE;
|
gequal = GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(texObj->Dimensions == 2);
|
if (texObj->MagFilter == GL_NEAREST) {
|
||||||
assert(texImage->Format == GL_DEPTH_COMPONENT);
|
GLuint i;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
for (i = 0; i < n; i++) {
|
GLfloat depthSample;
|
||||||
const GLfloat *src;
|
GLint col, row;
|
||||||
GLfloat depthSample;
|
COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, s[i], width, col);
|
||||||
GLint col, row;
|
COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, t[i], height, row);
|
||||||
/* XXX this is a hack - implement proper sampling */
|
depthSample = *((const GLfloat *) texImage->Data + row * width + col);
|
||||||
COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, s[i], texImage->Width, col);
|
if ((depthSample <= r[i] && lequal) ||
|
||||||
COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, t[i], texImage->Height,row);
|
(depthSample >= r[i] && gequal)) {
|
||||||
src = (const GLfloat *) texImage->Data + row * texImage->Width + col;
|
texel[i][RCOMP] = ambient;
|
||||||
depthSample = *src;
|
texel[i][GCOMP] = ambient;
|
||||||
if ((depthSample <= r[i] && lequal) ||
|
texel[i][BCOMP] = ambient;
|
||||||
(depthSample >= r[i] && gequal)) {
|
texel[i][ACOMP] = CHAN_MAX;
|
||||||
texel[i][RCOMP] = ambient;
|
}
|
||||||
texel[i][GCOMP] = ambient;
|
else {
|
||||||
texel[i][BCOMP] = ambient;
|
texel[i][RCOMP] = CHAN_MAX;
|
||||||
texel[i][ACOMP] = CHAN_MAX;
|
texel[i][GCOMP] = CHAN_MAX;
|
||||||
|
texel[i][BCOMP] = CHAN_MAX;
|
||||||
|
texel[i][ACOMP] = CHAN_MAX;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
texel[i][RCOMP] = CHAN_MAX;
|
else {
|
||||||
texel[i][GCOMP] = CHAN_MAX;
|
GLuint i;
|
||||||
texel[i][BCOMP] = CHAN_MAX;
|
ASSERT(texObj->MagFilter == GL_LINEAR);
|
||||||
texel[i][ACOMP] = CHAN_MAX;
|
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, s[i], u, width, i0, i1);
|
||||||
|
COMPUTE_LINEAR_TEXEL_LOCATIONS(texObj->WrapT, t[i], 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 >= width) useBorderTexel |= I0BIT;
|
||||||
|
if (i1 < 0 || i1 >= width) useBorderTexel |= I1BIT;
|
||||||
|
if (j0 < 0 || j0 >= height) useBorderTexel |= J0BIT;
|
||||||
|
if (j1 < 0 || j1 >= 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);
|
||||||
|
const GLfloat b = FRAC(v);
|
||||||
|
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 <= r[i] && lequal) ||
|
||||||
|
(depthSample >= r[i] && gequal)) {
|
||||||
|
texel[i][RCOMP] = ambient;
|
||||||
|
texel[i][GCOMP] = ambient;
|
||||||
|
texel[i][BCOMP] = ambient;
|
||||||
|
texel[i][ACOMP] = CHAN_MAX;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
texel[i][RCOMP] = CHAN_MAX;
|
||||||
|
texel[i][GCOMP] = CHAN_MAX;
|
||||||
|
texel[i][BCOMP] = CHAN_MAX;
|
||||||
|
texel[i][ACOMP] = 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;
|
||||||
|
GLchan lum;
|
||||||
|
if (lequal) {
|
||||||
|
if (depth00 <= r[i]) luminance -= d;
|
||||||
|
if (depth01 <= r[i]) luminance -= d;
|
||||||
|
if (depth10 <= r[i]) luminance -= d;
|
||||||
|
if (depth11 <= r[i]) luminance -= d;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (depth00 >= r[i]) luminance -= d;
|
||||||
|
if (depth01 >= r[i]) luminance -= d;
|
||||||
|
if (depth10 >= r[i]) luminance -= d;
|
||||||
|
if (depth11 >= r[i]) luminance -= d;
|
||||||
|
}
|
||||||
|
lum = (GLchan) luminance;
|
||||||
|
texel[i][RCOMP] = lum;
|
||||||
|
texel[i][GCOMP] = lum;
|
||||||
|
texel[i][BCOMP] = lum;
|
||||||
|
texel[i][ACOMP] = CHAN_MAX;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
* Experimental depth texture sampling function.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sample_depth_texture2(const GLcontext *ctx,
|
||||||
|
const struct gl_texture_unit *texUnit,
|
||||||
|
GLuint n,
|
||||||
|
const GLfloat s[], const GLfloat t[], const GLfloat r[],
|
||||||
|
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) {
|
||||||
|
gl_problem(ctx, "only 2-D depth textures supported at this time");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texObj->MinFilter != texObj->MagFilter) {
|
||||||
|
gl_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) {
|
||||||
|
gl_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, s[i], width, col);
|
||||||
|
COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, t[i], 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.
|
* Apply a unit of texture mapping to the incoming fragments.
|
||||||
|
Reference in New Issue
Block a user