Finished up GL_ARB_depth_texture and GL_ARB_shadow.
This commit is contained in:
@@ -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) },
|
||||
|
@@ -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] ||
|
||||
|
@@ -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;
|
||||
|
@@ -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) {
|
||||
@@ -2667,327 +3004,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.
|
||||
*/
|
||||
@@ -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 );
|
||||
}
|
||||
|
Reference in New Issue
Block a user