/* $Id: attrib.c,v 1.70 2002/09/03 18:03:45 brianp Exp $ */ | |||||
/* $Id: attrib.c,v 1.71 2002/09/06 02:56:08 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
GL_POLYGON_STIPPLE); | GL_POLYGON_STIPPLE); | ||||
TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST); | TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST); | ||||
TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST); | TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST); | ||||
/* XXX two-sided stencil */ | |||||
TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled, | TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled, | ||||
GL_MULTISAMPLE_ARB); | GL_MULTISAMPLE_ARB); | ||||
TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage, | TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage, | ||||
break; | break; | ||||
case GL_STENCIL_BUFFER_BIT: | case GL_STENCIL_BUFFER_BIT: | ||||
{ | { | ||||
const GLint face = 0; /* XXX stencil two side */ | |||||
const struct gl_stencil_attrib *stencil; | const struct gl_stencil_attrib *stencil; | ||||
stencil = (const struct gl_stencil_attrib *) attr->data; | stencil = (const struct gl_stencil_attrib *) attr->data; | ||||
_mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); | _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); | ||||
_mesa_ClearStencil(stencil->Clear); | _mesa_ClearStencil(stencil->Clear); | ||||
_mesa_StencilFunc(stencil->Function, stencil->Ref, | |||||
stencil->ValueMask); | |||||
_mesa_StencilMask(stencil->WriteMask); | |||||
_mesa_StencilOp(stencil->FailFunc, stencil->ZFailFunc, | |||||
stencil->ZPassFunc); | |||||
_mesa_StencilFunc(stencil->Function[face], stencil->Ref[face], | |||||
stencil->ValueMask[face]); | |||||
_mesa_StencilMask(stencil->WriteMask[face]); | |||||
_mesa_StencilOp(stencil->FailFunc[face], | |||||
stencil->ZFailFunc[face], | |||||
stencil->ZPassFunc[face]); | |||||
} | } | ||||
break; | break; | ||||
case GL_TRANSFORM_BIT: | case GL_TRANSFORM_BIT: |
/* $Id: context.c,v 1.175 2002/07/09 01:22:50 brianp Exp $ */ | |||||
/* $Id: context.c,v 1.176 2002/09/06 02:56:08 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
/* Stencil group */ | /* Stencil group */ | ||||
ctx->Stencil.Enabled = GL_FALSE; | ctx->Stencil.Enabled = GL_FALSE; | ||||
ctx->Stencil.Function = GL_ALWAYS; | |||||
ctx->Stencil.FailFunc = GL_KEEP; | |||||
ctx->Stencil.ZPassFunc = GL_KEEP; | |||||
ctx->Stencil.ZFailFunc = GL_KEEP; | |||||
ctx->Stencil.Ref = 0; | |||||
ctx->Stencil.ValueMask = STENCIL_MAX; | |||||
ctx->Stencil.TestTwoSide = GL_FALSE; | |||||
ctx->Stencil.ActiveFace = 0; /* 0 = GL_FRONT, 1 = GL_BACK */ | |||||
ctx->Stencil.Function[0] = GL_ALWAYS; | |||||
ctx->Stencil.Function[1] = GL_ALWAYS; | |||||
ctx->Stencil.FailFunc[0] = GL_KEEP; | |||||
ctx->Stencil.FailFunc[1] = GL_KEEP; | |||||
ctx->Stencil.ZPassFunc[0] = GL_KEEP; | |||||
ctx->Stencil.ZPassFunc[1] = GL_KEEP; | |||||
ctx->Stencil.ZFailFunc[0] = GL_KEEP; | |||||
ctx->Stencil.ZFailFunc[1] = GL_KEEP; | |||||
ctx->Stencil.Ref[0] = 0; | |||||
ctx->Stencil.Ref[1] = 0; | |||||
ctx->Stencil.ValueMask[0] = STENCIL_MAX; | |||||
ctx->Stencil.ValueMask[1] = STENCIL_MAX; | |||||
ctx->Stencil.WriteMask[0] = STENCIL_MAX; | |||||
ctx->Stencil.WriteMask[1] = STENCIL_MAX; | |||||
ctx->Stencil.Clear = 0; | ctx->Stencil.Clear = 0; | ||||
ctx->Stencil.WriteMask = STENCIL_MAX; | |||||
/* Texture group */ | /* Texture group */ | ||||
ctx->Texture.CurrentUnit = 0; /* multitexture */ | ctx->Texture.CurrentUnit = 0; /* multitexture */ |
/* $Id: dd.h,v 1.70 2002/07/09 01:22:50 brianp Exp $ */ | |||||
/* $Id: dd.h,v 1.71 2002/09/06 02:56:08 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
*** They're ALSO called by the gl_PopAttrib() function!!! | *** They're ALSO called by the gl_PopAttrib() function!!! | ||||
*** May add more functions like these to the device driver in the future. | *** May add more functions like these to the device driver in the future. | ||||
***/ | ***/ | ||||
#if 1 | |||||
void (*AlphaFunc)(GLcontext *ctx, GLenum func, GLchan ref); | void (*AlphaFunc)(GLcontext *ctx, GLenum func, GLchan ref); | ||||
#else | |||||
void (*AlphaFunc)(GLcontext *ctx, GLenum func, GLfloat ref); | |||||
#endif | |||||
void (*BlendColor)(GLcontext *ctx, const GLfloat color[4]); | void (*BlendColor)(GLcontext *ctx, const GLfloat color[4]); | ||||
void (*BlendEquation)(GLcontext *ctx, GLenum mode); | void (*BlendEquation)(GLcontext *ctx, GLenum mode); | ||||
void (*BlendFunc)(GLcontext *ctx, GLenum sfactor, GLenum dfactor); | void (*BlendFunc)(GLcontext *ctx, GLenum sfactor, GLenum dfactor); | ||||
void (*BlendFuncSeparate)(GLcontext *ctx, | void (*BlendFuncSeparate)(GLcontext *ctx, | ||||
GLenum sfactorRGB, GLenum dfactorRGB, | GLenum sfactorRGB, GLenum dfactorRGB, | ||||
GLenum sfactorA, GLenum dfactorA); | GLenum sfactorA, GLenum dfactorA); | ||||
#if 1 | |||||
void (*ClearColor)(GLcontext *ctx, const GLchan color[4]); | void (*ClearColor)(GLcontext *ctx, const GLchan color[4]); | ||||
#else | |||||
void (*ClearColor)(GLcontext *ctx, const GLfloat color[4]); | |||||
#endif | |||||
void (*ClearDepth)(GLcontext *ctx, GLclampd d); | void (*ClearDepth)(GLcontext *ctx, GLclampd d); | ||||
void (*ClearIndex)(GLcontext *ctx, GLuint index); | void (*ClearIndex)(GLcontext *ctx, GLuint index); | ||||
void (*ClearStencil)(GLcontext *ctx, GLint s); | void (*ClearStencil)(GLcontext *ctx, GLint s); | ||||
void (*StencilFunc)(GLcontext *ctx, GLenum func, GLint ref, GLuint mask); | void (*StencilFunc)(GLcontext *ctx, GLenum func, GLint ref, GLuint mask); | ||||
void (*StencilMask)(GLcontext *ctx, GLuint mask); | void (*StencilMask)(GLcontext *ctx, GLuint mask); | ||||
void (*StencilOp)(GLcontext *ctx, GLenum fail, GLenum zfail, GLenum zpass); | void (*StencilOp)(GLcontext *ctx, GLenum fail, GLenum zfail, GLenum zpass); | ||||
void (*ActiveStencilFace)(GLcontext *ctx, GLuint face); | |||||
void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, | void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, | ||||
const GLfloat *params); | const GLfloat *params); | ||||
void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, | void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, |
/* $Id: dlist.c,v 1.93 2002/08/17 00:26:29 brianp Exp $ */ | |||||
/* $Id: dlist.c,v 1.94 2002/09/06 02:56:08 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
OPCODE_PROGRAM_PARAMETER4F_NV, | OPCODE_PROGRAM_PARAMETER4F_NV, | ||||
OPCODE_PROGRAM_PARAMETERS4FV_NV, | OPCODE_PROGRAM_PARAMETERS4FV_NV, | ||||
OPCODE_TRACK_MATRIX_NV, | OPCODE_TRACK_MATRIX_NV, | ||||
/* GL_EXT_stencil_two_face */ | |||||
OPCODE_ACTIVE_STENCIL_FACE_EXT, | |||||
/* The following three are meta instructions */ | /* The following three are meta instructions */ | ||||
OPCODE_ERROR, /* raise compiled-in error */ | OPCODE_ERROR, /* raise compiled-in error */ | ||||
OPCODE_CONTINUE, | OPCODE_CONTINUE, | ||||
InstSize[OPCODE_PROGRAM_PARAMETER4F_NV] = 7; | InstSize[OPCODE_PROGRAM_PARAMETER4F_NV] = 7; | ||||
InstSize[OPCODE_PROGRAM_PARAMETERS4FV_NV] = 4; | InstSize[OPCODE_PROGRAM_PARAMETERS4FV_NV] = 4; | ||||
InstSize[OPCODE_TRACK_MATRIX_NV] = 5; | InstSize[OPCODE_TRACK_MATRIX_NV] = 5; | ||||
/* GL_EXT_stencil_two_side */ | |||||
InstSize[OPCODE_ACTIVE_STENCIL_FACE_EXT] = 2; | |||||
} | } | ||||
init_flag = 1; | init_flag = 1; | ||||
} | } | ||||
} | } | ||||
/* GL_EXT_stencil_two_face */ | |||||
static void save_ActiveStencilFaceEXT( GLenum face ) | |||||
{ | |||||
GET_CURRENT_CONTEXT(ctx); | |||||
Node *n; | |||||
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); | |||||
n = ALLOC_INSTRUCTION( ctx, OPCODE_ACTIVE_STENCIL_FACE_EXT, 1 ); | |||||
if (n) { | |||||
n[1].e = face; | |||||
} | |||||
if (ctx->ExecuteFlag) { | |||||
#if 0 | |||||
(*ctx->Exec->ActiveStencilFaceEXT)( face ); | |||||
#endif | |||||
} | |||||
} | |||||
/* KW: Compile commands | /* KW: Compile commands | ||||
table->PointParameteriNV = save_PointParameteriNV; | table->PointParameteriNV = save_PointParameteriNV; | ||||
table->PointParameterivNV = save_PointParameterivNV; | table->PointParameterivNV = save_PointParameterivNV; | ||||
/* 268. GL_EXT_stencil_two_side */ | |||||
#if 0 | |||||
table->ActiveStencilFaceEXT = save_ActiveStencilFaceEXT; | |||||
#endif | |||||
/* ARB 1. GL_ARB_multitexture */ | /* ARB 1. GL_ARB_multitexture */ | ||||
table->ActiveTextureARB = save_ActiveTextureARB; | table->ActiveTextureARB = save_ActiveTextureARB; | ||||
table->ClientActiveTextureARB = exec_ClientActiveTextureARB; | table->ClientActiveTextureARB = exec_ClientActiveTextureARB; |
/* $Id: enable.c,v 1.68 2002/06/29 19:48:15 brianp Exp $ */ | |||||
/* $Id: enable.c,v 1.69 2002/09/06 02:56:08 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
/* GL_NV_texture_rectangle */ | /* GL_NV_texture_rectangle */ | ||||
case GL_TEXTURE_RECTANGLE_NV: | case GL_TEXTURE_RECTANGLE_NV: | ||||
CHECK_EXTENSION(NV_texture_rectangle, cap); | |||||
{ | { | ||||
const GLuint curr = ctx->Texture.CurrentUnit; | const GLuint curr = ctx->Texture.CurrentUnit; | ||||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr]; | struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr]; | ||||
} | } | ||||
break; | break; | ||||
/* GL_EXT_stencil_two_side */ | |||||
case GL_STENCIL_TEST_TWO_SIDE_EXT: | |||||
CHECK_EXTENSION(EXT_stencil_two_side, cap); | |||||
if (ctx->Stencil.TestTwoSide == state) | |||||
return; | |||||
FLUSH_VERTICES(ctx, _NEW_STENCIL); | |||||
ctx->Stencil.TestTwoSide = state; | |||||
break; | |||||
default: | default: | ||||
_mesa_error(ctx, GL_INVALID_ENUM, | _mesa_error(ctx, GL_INVALID_ENUM, | ||||
"%s(0x%x)", state ? "glEnable" : "glDisable", cap); | "%s(0x%x)", state ? "glEnable" : "glDisable", cap); | ||||
return (texUnit->Enabled & TEXTURE_RECT_BIT) ? GL_TRUE : GL_FALSE; | return (texUnit->Enabled & TEXTURE_RECT_BIT) ? GL_TRUE : GL_FALSE; | ||||
} | } | ||||
/* GL_EXT_stencil_two_side */ | |||||
case GL_STENCIL_TEST_TWO_SIDE_EXT: | |||||
CHECK_EXTENSION(EXT_stencil_two_side); | |||||
return ctx->Stencil.TestTwoSide; | |||||
default: | default: | ||||
_mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(0x%x)", (int) cap); | _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(0x%x)", (int) cap); | ||||
return GL_FALSE; | return GL_FALSE; |
/* $Id: extensions.c,v 1.77 2002/09/05 21:16:30 brianp Exp $ */ | |||||
/* $Id: extensions.c,v 1.78 2002/09/06 02:56:08 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
{ OFF, "GL_EXT_shadow_funcs", F(EXT_shadow_funcs) }, | { OFF, "GL_EXT_shadow_funcs", F(EXT_shadow_funcs) }, | ||||
{ OFF, "GL_EXT_shared_texture_palette", F(EXT_shared_texture_palette) }, | { OFF, "GL_EXT_shared_texture_palette", F(EXT_shared_texture_palette) }, | ||||
{ OFF, "GL_EXT_stencil_wrap", F(EXT_stencil_wrap) }, | { OFF, "GL_EXT_stencil_wrap", F(EXT_stencil_wrap) }, | ||||
{ OFF, "GL_EXT_stencil_two_side", F(EXT_stencil_two_side) }, | |||||
{ ON, "GL_EXT_texture3D", F(EXT_texture3D) }, | { ON, "GL_EXT_texture3D", F(EXT_texture3D) }, | ||||
{ OFF, "GL_EXT_texture_compression_s3tc", F(EXT_texture_compression_s3tc) }, | { OFF, "GL_EXT_texture_compression_s3tc", F(EXT_texture_compression_s3tc) }, | ||||
{ OFF, "GL_EXT_texture_edge_clamp", F(SGIS_texture_edge_clamp) }, | { OFF, "GL_EXT_texture_edge_clamp", F(SGIS_texture_edge_clamp) }, | ||||
"GL_EXT_secondary_color", | "GL_EXT_secondary_color", | ||||
"GL_EXT_shared_texture_palette", | "GL_EXT_shared_texture_palette", | ||||
"GL_EXT_stencil_wrap", | "GL_EXT_stencil_wrap", | ||||
"GL_EXT_stencil_two_side", | |||||
"GL_EXT_texture_edge_clamp", | "GL_EXT_texture_edge_clamp", | ||||
"GL_EXT_texture_env_add", | "GL_EXT_texture_env_add", | ||||
"GL_EXT_texture_env_combine", | "GL_EXT_texture_env_combine", |
/* $Id: get.c,v 1.88 2002/09/05 21:14:36 brianp Exp $ */ | |||||
/* $Id: get.c,v 1.89 2002/09/06 02:56:08 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
*params = INT_TO_BOOL(ctx->Stencil.Clear); | *params = INT_TO_BOOL(ctx->Stencil.Clear); | ||||
break; | break; | ||||
case GL_STENCIL_FAIL: | case GL_STENCIL_FAIL: | ||||
*params = ENUM_TO_BOOL(ctx->Stencil.FailFunc); | |||||
*params = ENUM_TO_BOOL(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_FUNC: | case GL_STENCIL_FUNC: | ||||
*params = ENUM_TO_BOOL(ctx->Stencil.Function); | |||||
*params = ENUM_TO_BOOL(ctx->Stencil.Function[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_PASS_DEPTH_FAIL: | case GL_STENCIL_PASS_DEPTH_FAIL: | ||||
*params = ENUM_TO_BOOL(ctx->Stencil.ZFailFunc); | |||||
*params = ENUM_TO_BOOL(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_PASS_DEPTH_PASS: | case GL_STENCIL_PASS_DEPTH_PASS: | ||||
*params = ENUM_TO_BOOL(ctx->Stencil.ZPassFunc); | |||||
*params = ENUM_TO_BOOL(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_REF: | case GL_STENCIL_REF: | ||||
*params = INT_TO_BOOL(ctx->Stencil.Ref); | |||||
*params = INT_TO_BOOL(ctx->Stencil.Ref[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_TEST: | case GL_STENCIL_TEST: | ||||
*params = ctx->Stencil.Enabled; | *params = ctx->Stencil.Enabled; | ||||
break; | break; | ||||
case GL_STENCIL_VALUE_MASK: | case GL_STENCIL_VALUE_MASK: | ||||
*params = INT_TO_BOOL(ctx->Stencil.ValueMask); | |||||
*params = INT_TO_BOOL(ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_WRITEMASK: | case GL_STENCIL_WRITEMASK: | ||||
*params = INT_TO_BOOL(ctx->Stencil.WriteMask); | |||||
*params = INT_TO_BOOL(ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STEREO: | case GL_STEREO: | ||||
*params = ctx->Visual.stereoMode; | *params = ctx->Visual.stereoMode; | ||||
*params = INT_TO_BOOL(ctx->Const.MaxTextureRectSize); | *params = INT_TO_BOOL(ctx->Const.MaxTextureRectSize); | ||||
break; | break; | ||||
/* GL_EXT_stencil_two_side */ | |||||
case GL_STENCIL_TEST_TWO_SIDE_EXT: | |||||
CHECK_EXTENSION_B(EXT_stencil_two_side, pname); | |||||
*params = ctx->Stencil.TestTwoSide; | |||||
break; | |||||
case GL_ACTIVE_STENCIL_FACE_EXT: | |||||
CHECK_EXTENSION_B(EXT_stencil_two_side, pname); | |||||
*params = ENUM_TO_BOOL(ctx->Stencil.ActiveFace ? GL_FRONT : GL_BACK); | |||||
break; | |||||
default: | default: | ||||
_mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv(pname=0x%x)", pname); | _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv(pname=0x%x)", pname); | ||||
} | } | ||||
*params = (GLdouble) ctx->Stencil.Clear; | *params = (GLdouble) ctx->Stencil.Clear; | ||||
break; | break; | ||||
case GL_STENCIL_FAIL: | case GL_STENCIL_FAIL: | ||||
*params = ENUM_TO_DOUBLE(ctx->Stencil.FailFunc); | |||||
*params = ENUM_TO_DOUBLE(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_FUNC: | case GL_STENCIL_FUNC: | ||||
*params = ENUM_TO_DOUBLE(ctx->Stencil.Function); | |||||
*params = ENUM_TO_DOUBLE(ctx->Stencil.Function[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_PASS_DEPTH_FAIL: | case GL_STENCIL_PASS_DEPTH_FAIL: | ||||
*params = ENUM_TO_DOUBLE(ctx->Stencil.ZFailFunc); | |||||
*params = ENUM_TO_DOUBLE(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_PASS_DEPTH_PASS: | case GL_STENCIL_PASS_DEPTH_PASS: | ||||
*params = ENUM_TO_DOUBLE(ctx->Stencil.ZPassFunc); | |||||
*params = ENUM_TO_DOUBLE(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_REF: | case GL_STENCIL_REF: | ||||
*params = (GLdouble) ctx->Stencil.Ref; | |||||
*params = (GLdouble) ctx->Stencil.Ref[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STENCIL_TEST: | case GL_STENCIL_TEST: | ||||
*params = (GLdouble) ctx->Stencil.Enabled; | *params = (GLdouble) ctx->Stencil.Enabled; | ||||
break; | break; | ||||
case GL_STENCIL_VALUE_MASK: | case GL_STENCIL_VALUE_MASK: | ||||
*params = (GLdouble) ctx->Stencil.ValueMask; | |||||
*params = (GLdouble) ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STENCIL_WRITEMASK: | case GL_STENCIL_WRITEMASK: | ||||
*params = (GLdouble) ctx->Stencil.WriteMask; | |||||
*params = (GLdouble) ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STEREO: | case GL_STEREO: | ||||
*params = (GLdouble) ctx->Visual.stereoMode; | *params = (GLdouble) ctx->Visual.stereoMode; | ||||
*params = (GLdouble) ctx->Const.MaxTextureRectSize; | *params = (GLdouble) ctx->Const.MaxTextureRectSize; | ||||
break; | break; | ||||
/* GL_EXT_stencil_two_side */ | |||||
case GL_STENCIL_TEST_TWO_SIDE_EXT: | |||||
CHECK_EXTENSION_D(EXT_stencil_two_side, pname); | |||||
*params = (GLdouble) ctx->Stencil.TestTwoSide; | |||||
break; | |||||
case GL_ACTIVE_STENCIL_FACE_EXT: | |||||
CHECK_EXTENSION_D(EXT_stencil_two_side, pname); | |||||
*params = (GLdouble) (ctx->Stencil.ActiveFace ? GL_FRONT : GL_BACK); | |||||
break; | |||||
default: | default: | ||||
_mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev(pname=0x%x)", pname); | _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev(pname=0x%x)", pname); | ||||
} | } | ||||
*params = (GLfloat) ctx->Stencil.Clear; | *params = (GLfloat) ctx->Stencil.Clear; | ||||
break; | break; | ||||
case GL_STENCIL_FAIL: | case GL_STENCIL_FAIL: | ||||
*params = ENUM_TO_FLOAT(ctx->Stencil.FailFunc); | |||||
*params = ENUM_TO_FLOAT(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_FUNC: | case GL_STENCIL_FUNC: | ||||
*params = ENUM_TO_FLOAT(ctx->Stencil.Function); | |||||
*params = ENUM_TO_FLOAT(ctx->Stencil.Function[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_PASS_DEPTH_FAIL: | case GL_STENCIL_PASS_DEPTH_FAIL: | ||||
*params = ENUM_TO_FLOAT(ctx->Stencil.ZFailFunc); | |||||
*params = ENUM_TO_FLOAT(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_PASS_DEPTH_PASS: | case GL_STENCIL_PASS_DEPTH_PASS: | ||||
*params = ENUM_TO_FLOAT(ctx->Stencil.ZPassFunc); | |||||
*params = ENUM_TO_FLOAT(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]); | |||||
break; | break; | ||||
case GL_STENCIL_REF: | case GL_STENCIL_REF: | ||||
*params = (GLfloat) ctx->Stencil.Ref; | |||||
*params = (GLfloat) ctx->Stencil.Ref[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STENCIL_TEST: | case GL_STENCIL_TEST: | ||||
*params = (GLfloat) ctx->Stencil.Enabled; | *params = (GLfloat) ctx->Stencil.Enabled; | ||||
break; | break; | ||||
case GL_STENCIL_VALUE_MASK: | case GL_STENCIL_VALUE_MASK: | ||||
*params = (GLfloat) ctx->Stencil.ValueMask; | |||||
*params = (GLfloat) ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STENCIL_WRITEMASK: | case GL_STENCIL_WRITEMASK: | ||||
*params = (GLfloat) ctx->Stencil.WriteMask; | |||||
*params = (GLfloat) ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STEREO: | case GL_STEREO: | ||||
*params = (GLfloat) ctx->Visual.stereoMode; | *params = (GLfloat) ctx->Visual.stereoMode; | ||||
*params = (GLfloat) ctx->Const.MaxTextureRectSize; | *params = (GLfloat) ctx->Const.MaxTextureRectSize; | ||||
break; | break; | ||||
/* GL_EXT_stencil_two_side */ | |||||
case GL_STENCIL_TEST_TWO_SIDE_EXT: | |||||
CHECK_EXTENSION_F(EXT_stencil_two_side, pname); | |||||
*params = (GLfloat) ctx->Stencil.TestTwoSide; | |||||
break; | |||||
case GL_ACTIVE_STENCIL_FACE_EXT: | |||||
CHECK_EXTENSION_F(EXT_stencil_two_side, pname); | |||||
*params = (GLfloat) (ctx->Stencil.ActiveFace ? GL_FRONT : GL_BACK); | |||||
break; | |||||
default: | default: | ||||
_mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv(0x%x)", pname); | _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv(0x%x)", pname); | ||||
} | } | ||||
*params = (GLint) ctx->Stencil.Clear; | *params = (GLint) ctx->Stencil.Clear; | ||||
break; | break; | ||||
case GL_STENCIL_FAIL: | case GL_STENCIL_FAIL: | ||||
*params = (GLint) ctx->Stencil.FailFunc; | |||||
*params = (GLint) ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STENCIL_FUNC: | case GL_STENCIL_FUNC: | ||||
*params = (GLint) ctx->Stencil.Function; | |||||
*params = (GLint) ctx->Stencil.Function[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STENCIL_PASS_DEPTH_FAIL: | case GL_STENCIL_PASS_DEPTH_FAIL: | ||||
*params = (GLint) ctx->Stencil.ZFailFunc; | |||||
*params = (GLint) ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STENCIL_PASS_DEPTH_PASS: | case GL_STENCIL_PASS_DEPTH_PASS: | ||||
*params = (GLint) ctx->Stencil.ZPassFunc; | |||||
*params = (GLint) ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STENCIL_REF: | case GL_STENCIL_REF: | ||||
*params = (GLint) ctx->Stencil.Ref; | |||||
*params = (GLint) ctx->Stencil.Ref[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STENCIL_TEST: | case GL_STENCIL_TEST: | ||||
*params = (GLint) ctx->Stencil.Enabled; | *params = (GLint) ctx->Stencil.Enabled; | ||||
break; | break; | ||||
case GL_STENCIL_VALUE_MASK: | case GL_STENCIL_VALUE_MASK: | ||||
*params = (GLint) ctx->Stencil.ValueMask; | |||||
*params = (GLint) ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STENCIL_WRITEMASK: | case GL_STENCIL_WRITEMASK: | ||||
*params = (GLint) ctx->Stencil.WriteMask; | |||||
*params = (GLint) ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace]; | |||||
break; | break; | ||||
case GL_STEREO: | case GL_STEREO: | ||||
*params = (GLint) ctx->Visual.stereoMode; | *params = (GLint) ctx->Visual.stereoMode; | ||||
*params = (GLint) ctx->Const.MaxTextureRectSize; | *params = (GLint) ctx->Const.MaxTextureRectSize; | ||||
break; | break; | ||||
/* GL_EXT_stencil_two_side */ | |||||
case GL_STENCIL_TEST_TWO_SIDE_EXT: | |||||
CHECK_EXTENSION_I(EXT_stencil_two_side, pname); | |||||
*params = (GLint) ctx->Stencil.TestTwoSide; | |||||
break; | |||||
case GL_ACTIVE_STENCIL_FACE_EXT: | |||||
CHECK_EXTENSION_I(EXT_stencil_two_side, pname); | |||||
*params = (GLint) (ctx->Stencil.ActiveFace ? GL_FRONT : GL_BACK); | |||||
break; | |||||
default: | default: | ||||
_mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv(pname=0x%x)", pname); | _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv(pname=0x%x)", pname); | ||||
} | } |
/* $Id: mtypes.h,v 1.84 2002/07/09 01:22:50 brianp Exp $ */ | |||||
/* $Id: mtypes.h,v 1.85 2002/09/06 02:56:09 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
struct gl_colorbuffer_attrib { | struct gl_colorbuffer_attrib { | ||||
GLuint ClearIndex; /* Index to use for glClear */ | GLuint ClearIndex; /* Index to use for glClear */ | ||||
#if 1 | |||||
GLchan ClearColor[4]; /* Color to use for glClear */ | GLchan ClearColor[4]; /* Color to use for glClear */ | ||||
#else | |||||
GLclampf ClearColor[4]; /* Color to use for glClear */ | |||||
#endif | |||||
GLuint IndexMask; /* Color index write mask */ | GLuint IndexMask; /* Color index write mask */ | ||||
GLubyte ColorMask[4]; /* Each flag is 0xff or 0x0 */ | GLubyte ColorMask[4]; /* Each flag is 0xff or 0x0 */ | ||||
/* alpha testing */ | /* alpha testing */ | ||||
GLboolean AlphaEnabled; /* Alpha test enabled flag */ | GLboolean AlphaEnabled; /* Alpha test enabled flag */ | ||||
GLenum AlphaFunc; /* Alpha test function */ | GLenum AlphaFunc; /* Alpha test function */ | ||||
#if 1 | |||||
GLchan AlphaRef; /* Alpha ref value as GLchan */ | GLchan AlphaRef; /* Alpha ref value as GLchan */ | ||||
#else | |||||
GLclampf AlphaRef; | |||||
#endif | |||||
/* blending */ | /* blending */ | ||||
GLboolean BlendEnabled; /* Blending enabled flag */ | GLboolean BlendEnabled; /* Blending enabled flag */ | ||||
struct gl_stencil_attrib { | struct gl_stencil_attrib { | ||||
GLboolean Enabled; /* Enabled flag */ | GLboolean Enabled; /* Enabled flag */ | ||||
GLenum Function; /* Stencil function */ | |||||
GLenum FailFunc; /* Fail function */ | |||||
GLenum ZPassFunc; /* Depth buffer pass function */ | |||||
GLenum ZFailFunc; /* Depth buffer fail function */ | |||||
GLstencil Ref; /* Reference value */ | |||||
GLstencil ValueMask; /* Value mask */ | |||||
GLboolean TestTwoSide; /* GL_EXT_stencil_two_side */ | |||||
GLubyte ActiveFace; /* GL_EXT_stencil_two_side (0 or 1) */ | |||||
GLenum Function[2]; /* Stencil function */ | |||||
GLenum FailFunc[2]; /* Fail function */ | |||||
GLenum ZPassFunc[2]; /* Depth buffer pass function */ | |||||
GLenum ZFailFunc[2]; /* Depth buffer fail function */ | |||||
GLstencil Ref[2]; /* Reference value */ | |||||
GLstencil ValueMask[2]; /* Value mask */ | |||||
GLstencil WriteMask[2]; /* Write mask */ | |||||
GLstencil Clear; /* Clear value */ | GLstencil Clear; /* Clear value */ | ||||
GLstencil WriteMask; /* Write mask */ | |||||
}; | }; | ||||
GLenum Target; /* GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ | GLenum Target; /* GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ | ||||
GLfloat Priority; /* in [0,1] */ | GLfloat Priority; /* in [0,1] */ | ||||
GLfloat BorderValues[4]; /* unclamped */ | GLfloat BorderValues[4]; /* unclamped */ | ||||
#if 1 | |||||
/* omit someday */ | |||||
GLchan BorderColor[4]; /* clamped, as GLchan */ | GLchan BorderColor[4]; /* clamped, as GLchan */ | ||||
#endif | |||||
GLenum WrapS; /* Wrap modes are: GL_CLAMP, REPEAT */ | GLenum WrapS; /* Wrap modes are: GL_CLAMP, REPEAT */ | ||||
GLenum WrapT; /* GL_CLAMP_TO_EDGE, and */ | GLenum WrapT; /* GL_CLAMP_TO_EDGE, and */ | ||||
GLenum WrapR; /* GL_CLAMP_TO_BORDER_ARB */ | GLenum WrapR; /* GL_CLAMP_TO_BORDER_ARB */ | ||||
GLfloat MaxAnisotropy; /* GL_EXT_texture_filter_anisotropic */ | GLfloat MaxAnisotropy; /* GL_EXT_texture_filter_anisotropic */ | ||||
GLboolean CompareFlag; /* GL_SGIX_shadow */ | GLboolean CompareFlag; /* GL_SGIX_shadow */ | ||||
GLenum CompareOperator; /* GL_SGIX_shadow */ | GLenum CompareOperator; /* GL_SGIX_shadow */ | ||||
#if 1 | |||||
GLchan ShadowAmbient; /* GL_SGIX/ARB_shadow_ambient */ | GLchan ShadowAmbient; /* GL_SGIX/ARB_shadow_ambient */ | ||||
#else | |||||
GLfloat ShadowAmbient; | |||||
#endif | |||||
GLenum CompareMode; /* GL_ARB_shadow */ | GLenum CompareMode; /* GL_ARB_shadow */ | ||||
GLenum CompareFunc; /* GL_ARB_shadow */ | GLenum CompareFunc; /* GL_ARB_shadow */ | ||||
GLenum DepthMode; /* GL_ARB_depth_texture */ | GLenum DepthMode; /* GL_ARB_depth_texture */ | ||||
GLaccum *Accum; /* array [4*Width*Height] of GLaccum values */ | GLaccum *Accum; /* array [4*Width*Height] of GLaccum values */ | ||||
/* Software alpha planes */ | /* Software alpha planes */ | ||||
#if 1 | |||||
GLchan *FrontLeftAlpha; /* array [Width*Height] of GLubyte */ | GLchan *FrontLeftAlpha; /* array [Width*Height] of GLubyte */ | ||||
GLchan *BackLeftAlpha; /* array [Width*Height] of GLubyte */ | GLchan *BackLeftAlpha; /* array [Width*Height] of GLubyte */ | ||||
GLchan *FrontRightAlpha; /* array [Width*Height] of GLubyte */ | GLchan *FrontRightAlpha; /* array [Width*Height] of GLubyte */ | ||||
GLchan *BackRightAlpha; /* array [Width*Height] of GLubyte */ | GLchan *BackRightAlpha; /* array [Width*Height] of GLubyte */ | ||||
#else | |||||
GLvoid *FrontLeftAlpha; /* array [Width*Height] of GLubyte */ | |||||
GLvoid *BackLeftAlpha; /* array [Width*Height] of GLubyte */ | |||||
GLvoid *FrontRightAlpha; /* array [Width*Height] of GLubyte */ | |||||
GLvoid *BackRightAlpha; /* array [Width*Height] of GLubyte */ | |||||
#endif | |||||
/* Drawing bounds: intersection of window size and scissor box */ | /* Drawing bounds: intersection of window size and scissor box */ | ||||
GLint _Xmin, _Ymin; /* inclusive */ | GLint _Xmin, _Ymin; /* inclusive */ | ||||
GLint _Xmax, _Ymax; /* exclusive */ | GLint _Xmax, _Ymax; /* exclusive */ | ||||
GLboolean EXT_secondary_color; | GLboolean EXT_secondary_color; | ||||
GLboolean EXT_shared_texture_palette; | GLboolean EXT_shared_texture_palette; | ||||
GLboolean EXT_stencil_wrap; | GLboolean EXT_stencil_wrap; | ||||
GLboolean EXT_stencil_two_side; | |||||
GLboolean EXT_texture3D; | GLboolean EXT_texture3D; | ||||
GLboolean EXT_texture_compression_s3tc; | GLboolean EXT_texture_compression_s3tc; | ||||
GLboolean EXT_texture_env_add; | GLboolean EXT_texture_env_add; |
/* $Id: state.c,v 1.89 2002/07/09 01:22:50 brianp Exp $ */ | |||||
/* $Id: state.c,v 1.90 2002/09/06 02:56:09 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
exec->PointParameteriNV = _mesa_PointParameteriNV; | exec->PointParameteriNV = _mesa_PointParameteriNV; | ||||
exec->PointParameterivNV = _mesa_PointParameterivNV; | exec->PointParameterivNV = _mesa_PointParameterivNV; | ||||
/* 268. GL_EXT_stencil_two_side */ | |||||
#if 0 | |||||
exec->ActiveStencilFaceEXT = _mesa_ActiveStencilFaceEXT; | |||||
#endif | |||||
/* ARB 1. GL_ARB_multitexture */ | /* ARB 1. GL_ARB_multitexture */ | ||||
exec->ActiveTextureARB = _mesa_ActiveTextureARB; | exec->ActiveTextureARB = _mesa_ActiveTextureARB; | ||||
exec->ClientActiveTextureARB = _mesa_ClientActiveTextureARB; | exec->ClientActiveTextureARB = _mesa_ClientActiveTextureARB; |
/* $Id: stencil.c,v 1.27 2001/05/09 16:34:09 brianp Exp $ */ | |||||
/* $Id: stencil.c,v 1.28 2002/09/06 02:56:09 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * 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 | * Permission is hereby granted, free of charge, to any person obtaining a | ||||
* copy of this software and associated documentation files (the "Software"), | * copy of this software and associated documentation files (the "Software"), | ||||
_mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) | _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) | ||||
{ | { | ||||
GET_CURRENT_CONTEXT(ctx); | GET_CURRENT_CONTEXT(ctx); | ||||
const GLint face = ctx->Stencil.ActiveFace; | |||||
GLint maxref; | GLint maxref; | ||||
ASSERT_OUTSIDE_BEGIN_END(ctx); | ASSERT_OUTSIDE_BEGIN_END(ctx); | ||||
maxref = (1 << STENCIL_BITS) - 1; | maxref = (1 << STENCIL_BITS) - 1; | ||||
ref = (GLstencil) CLAMP( ref, 0, maxref ); | ref = (GLstencil) CLAMP( ref, 0, maxref ); | ||||
if (ctx->Stencil.Function == func && | |||||
ctx->Stencil.ValueMask == (GLstencil) mask && | |||||
ctx->Stencil.Ref == ref) | |||||
if (ctx->Stencil.Function[face] == func && | |||||
ctx->Stencil.ValueMask[face] == (GLstencil) mask && | |||||
ctx->Stencil.Ref[face] == ref) | |||||
return; | return; | ||||
FLUSH_VERTICES(ctx, _NEW_STENCIL); | FLUSH_VERTICES(ctx, _NEW_STENCIL); | ||||
ctx->Stencil.Function = func; | |||||
ctx->Stencil.Ref = ref; | |||||
ctx->Stencil.ValueMask = (GLstencil) mask; | |||||
ctx->Stencil.Function[face] = func; | |||||
ctx->Stencil.Ref[face] = ref; | |||||
ctx->Stencil.ValueMask[face] = (GLstencil) mask; | |||||
if (ctx->Driver.StencilFunc) { | if (ctx->Driver.StencilFunc) { | ||||
(*ctx->Driver.StencilFunc)( ctx, func, ctx->Stencil.Ref, mask ); | |||||
(*ctx->Driver.StencilFunc)( ctx, func, ref, mask ); | |||||
} | } | ||||
} | } | ||||
_mesa_StencilMask( GLuint mask ) | _mesa_StencilMask( GLuint mask ) | ||||
{ | { | ||||
GET_CURRENT_CONTEXT(ctx); | GET_CURRENT_CONTEXT(ctx); | ||||
const GLint face = ctx->Stencil.ActiveFace; | |||||
ASSERT_OUTSIDE_BEGIN_END(ctx); | ASSERT_OUTSIDE_BEGIN_END(ctx); | ||||
if (ctx->Stencil.WriteMask == (GLstencil) mask) | |||||
return; | |||||
if (ctx->Stencil.WriteMask[face] == (GLstencil) mask) | |||||
return; | |||||
FLUSH_VERTICES(ctx, _NEW_STENCIL); | FLUSH_VERTICES(ctx, _NEW_STENCIL); | ||||
ctx->Stencil.WriteMask = (GLstencil) mask; | |||||
ctx->Stencil.WriteMask[face] = (GLstencil) mask; | |||||
if (ctx->Driver.StencilMask) { | if (ctx->Driver.StencilMask) { | ||||
(*ctx->Driver.StencilMask)( ctx, mask ); | (*ctx->Driver.StencilMask)( ctx, mask ); | ||||
_mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) | _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) | ||||
{ | { | ||||
GET_CURRENT_CONTEXT(ctx); | GET_CURRENT_CONTEXT(ctx); | ||||
const GLint face = ctx->Stencil.ActiveFace; | |||||
ASSERT_OUTSIDE_BEGIN_END(ctx); | ASSERT_OUTSIDE_BEGIN_END(ctx); | ||||
switch (fail) { | switch (fail) { | ||||
return; | return; | ||||
} | } | ||||
if (ctx->Stencil.ZFailFunc == zfail && | |||||
ctx->Stencil.ZPassFunc == zpass && | |||||
ctx->Stencil.FailFunc == fail) | |||||
if (ctx->Stencil.ZFailFunc[face] == zfail && | |||||
ctx->Stencil.ZPassFunc[face] == zpass && | |||||
ctx->Stencil.FailFunc[face] == fail) | |||||
return; | return; | ||||
FLUSH_VERTICES(ctx, _NEW_STENCIL); | FLUSH_VERTICES(ctx, _NEW_STENCIL); | ||||
ctx->Stencil.ZFailFunc = zfail; | |||||
ctx->Stencil.ZPassFunc = zpass; | |||||
ctx->Stencil.FailFunc = fail; | |||||
ctx->Stencil.ZFailFunc[face] = zfail; | |||||
ctx->Stencil.ZPassFunc[face] = zpass; | |||||
ctx->Stencil.FailFunc[face] = fail; | |||||
if (ctx->Driver.StencilOp) { | if (ctx->Driver.StencilOp) { | ||||
(*ctx->Driver.StencilOp)(ctx, fail, zfail, zpass); | (*ctx->Driver.StencilOp)(ctx, fail, zfail, zpass); | ||||
} | } | ||||
} | } | ||||
/* GL_EXT_stencil_two_side */ | |||||
void | |||||
_mesa_ActiveStencilFaceEXT(GLenum face) | |||||
{ | |||||
GET_CURRENT_CONTEXT(ctx); | |||||
ASSERT_OUTSIDE_BEGIN_END(ctx); | |||||
if (face == GL_FRONT || face == GL_BACK) { | |||||
FLUSH_VERTICES(ctx, _NEW_STENCIL); | |||||
ctx->Stencil.ActiveFace = (face == GL_FRONT) ? 0 : 1; | |||||
} | |||||
if (ctx->Driver.ActiveStencilFace) { | |||||
(*ctx->Driver.ActiveStencilFace)( ctx, (GLuint) ctx->Stencil.ActiveFace ); | |||||
} | |||||
} | |||||
/* $Id: stencil.h,v 1.9 2001/03/12 00:48:38 gareth Exp $ */ | |||||
/* $Id: stencil.h,v 1.10 2002/09/06 02:56:09 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * 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 | * Permission is hereby granted, free of charge, to any person obtaining a | ||||
* copy of this software and associated documentation files (the "Software"), | * copy of this software and associated documentation files (the "Software"), | ||||
_mesa_StencilOp( GLenum fail, GLenum zfail, GLenum zpass ); | _mesa_StencilOp( GLenum fail, GLenum zfail, GLenum zpass ); | ||||
extern void | |||||
_mesa_ActiveStencilFaceEXT(GLenum face); | |||||
#endif | #endif |
/* $Id: s_span.c,v 1.46 2002/08/07 00:45:07 brianp Exp $ */ | |||||
/* $Id: s_span.c,v 1.47 2002/09/06 02:56:09 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
{ | { | ||||
GLuint i; | GLuint i; | ||||
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { | for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { | ||||
span->tex[i][0] = ctx->Current.RasterTexCoords[i][0]; | |||||
span->tex[i][1] = ctx->Current.RasterTexCoords[i][1]; | |||||
span->tex[i][2] = ctx->Current.RasterTexCoords[i][2]; | |||||
span->tex[i][3] = ctx->Current.RasterTexCoords[i][3]; | |||||
span->texStepX[i][0] = 0.0; | |||||
span->texStepX[i][1] = 0.0; | |||||
span->texStepX[i][2] = 0.0; | |||||
span->texStepX[i][3] = 0.0; | |||||
COPY_4V(span->tex[i], ctx->Current.RasterTexCoords[i]); | |||||
ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F); | |||||
ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F); | |||||
} | } | ||||
span->interpMask |= SPAN_TEXTURE; | span->interpMask |= SPAN_TEXTURE; | ||||
} | } | ||||
_mesa_span_interpolate_z(ctx, span); | _mesa_span_interpolate_z(ctx, span); | ||||
if (ctx->Stencil.Enabled) { | if (ctx->Stencil.Enabled) { | ||||
if (!_mesa_stencil_and_ztest_span(ctx, span)) { | |||||
const GLuint face = 0; /* XXX stencil two side */ | |||||
if (!_mesa_stencil_and_ztest_span(ctx, span, face)) { | |||||
span->arrayMask = origArrayMask; | span->arrayMask = origArrayMask; | ||||
return; | return; | ||||
} | } | ||||
_mesa_span_interpolate_z(ctx, span); | _mesa_span_interpolate_z(ctx, span); | ||||
if (ctx->Stencil.Enabled) { | if (ctx->Stencil.Enabled) { | ||||
if (!_mesa_stencil_and_ztest_span(ctx, span)) { | |||||
const GLuint face = 0; /* XXX stencil two side */ | |||||
if (!_mesa_stencil_and_ztest_span(ctx, span, face)) { | |||||
span->interpMask = origInterpMask; | span->interpMask = origInterpMask; | ||||
span->arrayMask = origArrayMask; | span->arrayMask = origArrayMask; | ||||
return; | return; | ||||
_mesa_span_interpolate_z(ctx, span); | _mesa_span_interpolate_z(ctx, span); | ||||
if (ctx->Stencil.Enabled) { | if (ctx->Stencil.Enabled) { | ||||
if (!_mesa_stencil_and_ztest_span(ctx, span)) { | |||||
const GLuint face = 0; /* XXX stencil two side */ | |||||
if (!_mesa_stencil_and_ztest_span(ctx, span, face)) { | |||||
span->arrayMask = origArrayMask; | span->arrayMask = origArrayMask; | ||||
return; | return; | ||||
} | } |
/* $Id: s_stencil.c,v 1.25 2002/08/07 00:45:07 brianp Exp $ */ | |||||
/* $Id: s_stencil.c,v 1.26 2002/09/06 02:56:09 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
* Don't touch stencil[i] if mask[i] is zero. | * Don't touch stencil[i] if mask[i] is zero. | ||||
* Input: n - size of stencil array | * Input: n - size of stencil array | ||||
* oper - the stencil buffer operator | * oper - the stencil buffer operator | ||||
* face - 0 or 1 for front or back face operation | |||||
* stencil - array of stencil values | * stencil - array of stencil values | ||||
* mask - array [n] of flag: 1=apply operator, 0=don't apply operator | * mask - array [n] of flag: 1=apply operator, 0=don't apply operator | ||||
* Output: stencil - modified values | * Output: stencil - modified values | ||||
*/ | */ | ||||
static void | static void | ||||
apply_stencil_op( const GLcontext *ctx, GLenum oper, | |||||
apply_stencil_op( const GLcontext *ctx, GLenum oper, GLuint face, | |||||
GLuint n, GLstencil stencil[], const GLubyte mask[] ) | GLuint n, GLstencil stencil[], const GLubyte mask[] ) | ||||
{ | { | ||||
const GLstencil ref = ctx->Stencil.Ref; | |||||
const GLstencil wrtmask = ctx->Stencil.WriteMask; | |||||
const GLstencil invmask = (GLstencil) (~ctx->Stencil.WriteMask); | |||||
const GLstencil ref = ctx->Stencil.Ref[face]; | |||||
const GLstencil wrtmask = ctx->Stencil.WriteMask[face]; | |||||
const GLstencil invmask = (GLstencil) (~wrtmask); | |||||
GLuint i; | GLuint i; | ||||
switch (oper) { | switch (oper) { | ||||
/** | /** | ||||
* Apply stencil test to an array of stencil values (before depth buffering). | * Apply stencil test to an array of stencil values (before depth buffering). | ||||
* Input: n - number of pixels in the array | |||||
* Input: face - 0 or 1 for front or back-face polygons | |||||
* n - number of pixels in the array | |||||
* stencil - array of [n] stencil values | * stencil - array of [n] stencil values | ||||
* mask - array [n] of flag: 0=skip the pixel, 1=stencil the pixel | * mask - array [n] of flag: 0=skip the pixel, 1=stencil the pixel | ||||
* Output: mask - pixels which fail the stencil test will have their | * Output: mask - pixels which fail the stencil test will have their | ||||
* Return: GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed. | * Return: GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed. | ||||
*/ | */ | ||||
static GLboolean | static GLboolean | ||||
do_stencil_test( GLcontext *ctx, GLuint n, GLstencil stencil[], | |||||
do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[], | |||||
GLubyte mask[] ) | GLubyte mask[] ) | ||||
{ | { | ||||
GLubyte fail[MAX_WIDTH]; | GLubyte fail[MAX_WIDTH]; | ||||
GLboolean allfail = GL_FALSE; | GLboolean allfail = GL_FALSE; | ||||
GLuint i; | GLuint i; | ||||
GLstencil r, s; | GLstencil r, s; | ||||
const GLuint valueMask = ctx->Stencil.ValueMask[face]; | |||||
ASSERT(n <= MAX_WIDTH); | ASSERT(n <= MAX_WIDTH); | ||||
* the stencil fail operator is not to be applied | * the stencil fail operator is not to be applied | ||||
* ENDIF | * ENDIF | ||||
*/ | */ | ||||
switch (ctx->Stencil.Function) { | |||||
switch (ctx->Stencil.Function[face]) { | |||||
case GL_NEVER: | case GL_NEVER: | ||||
/* never pass; always fail */ | /* never pass; always fail */ | ||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
allfail = GL_TRUE; | allfail = GL_TRUE; | ||||
break; | break; | ||||
case GL_LESS: | case GL_LESS: | ||||
r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); | |||||
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); | |||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
if (mask[i]) { | if (mask[i]) { | ||||
s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask); | |||||
s = (GLstencil) (stencil[i] & valueMask); | |||||
if (r < s) { | if (r < s) { | ||||
/* passed */ | /* passed */ | ||||
fail[i] = 0; | fail[i] = 0; | ||||
} | } | ||||
break; | break; | ||||
case GL_LEQUAL: | case GL_LEQUAL: | ||||
r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); | |||||
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); | |||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
if (mask[i]) { | if (mask[i]) { | ||||
s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask); | |||||
s = (GLstencil) (stencil[i] & valueMask); | |||||
if (r <= s) { | if (r <= s) { | ||||
/* pass */ | /* pass */ | ||||
fail[i] = 0; | fail[i] = 0; | ||||
} | } | ||||
break; | break; | ||||
case GL_GREATER: | case GL_GREATER: | ||||
r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); | |||||
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); | |||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
if (mask[i]) { | if (mask[i]) { | ||||
s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask); | |||||
s = (GLstencil) (stencil[i] & valueMask); | |||||
if (r > s) { | if (r > s) { | ||||
/* passed */ | /* passed */ | ||||
fail[i] = 0; | fail[i] = 0; | ||||
} | } | ||||
break; | break; | ||||
case GL_GEQUAL: | case GL_GEQUAL: | ||||
r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); | |||||
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); | |||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
if (mask[i]) { | if (mask[i]) { | ||||
s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask); | |||||
s = (GLstencil) (stencil[i] & valueMask); | |||||
if (r >= s) { | if (r >= s) { | ||||
/* passed */ | /* passed */ | ||||
fail[i] = 0; | fail[i] = 0; | ||||
} | } | ||||
break; | break; | ||||
case GL_EQUAL: | case GL_EQUAL: | ||||
r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); | |||||
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); | |||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
if (mask[i]) { | if (mask[i]) { | ||||
s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask); | |||||
s = (GLstencil) (stencil[i] & valueMask); | |||||
if (r == s) { | if (r == s) { | ||||
/* passed */ | /* passed */ | ||||
fail[i] = 0; | fail[i] = 0; | ||||
} | } | ||||
break; | break; | ||||
case GL_NOTEQUAL: | case GL_NOTEQUAL: | ||||
r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); | |||||
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); | |||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
if (mask[i]) { | if (mask[i]) { | ||||
s = (GLstencil) (stencil[i] & ctx->Stencil.ValueMask); | |||||
s = (GLstencil) (stencil[i] & valueMask); | |||||
if (r != s) { | if (r != s) { | ||||
/* passed */ | /* passed */ | ||||
fail[i] = 0; | fail[i] = 0; | ||||
return 0; | return 0; | ||||
} | } | ||||
if (ctx->Stencil.FailFunc != GL_KEEP) { | |||||
apply_stencil_op( ctx, ctx->Stencil.FailFunc, n, stencil, fail ); | |||||
if (ctx->Stencil.FailFunc[face] != GL_KEEP) { | |||||
apply_stencil_op( ctx, ctx->Stencil.FailFunc[face], face, n, stencil, fail ); | |||||
} | } | ||||
return !allfail; | return !allfail; | ||||
* | * | ||||
*/ | */ | ||||
static GLboolean | static GLboolean | ||||
stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span) | |||||
stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face) | |||||
{ | { | ||||
SWcontext *swrast = SWRAST_CONTEXT(ctx); | SWcontext *swrast = SWRAST_CONTEXT(ctx); | ||||
GLstencil stencilRow[MAX_WIDTH]; | GLstencil stencilRow[MAX_WIDTH]; | ||||
* Apply the stencil test to the fragments. | * Apply the stencil test to the fragments. | ||||
* failMask[i] is 1 if the stencil test failed. | * failMask[i] is 1 if the stencil test failed. | ||||
*/ | */ | ||||
if (do_stencil_test( ctx, n, stencil, mask ) == GL_FALSE) { | |||||
if (do_stencil_test( ctx, face, n, stencil, mask ) == GL_FALSE) { | |||||
/* all fragments failed the stencil test, we're done. */ | /* all fragments failed the stencil test, we're done. */ | ||||
span->writeAll = GL_FALSE; | span->writeAll = GL_FALSE; | ||||
return GL_FALSE; | return GL_FALSE; | ||||
/* | /* | ||||
* No depth buffer, just apply zpass stencil function to active pixels. | * No depth buffer, just apply zpass stencil function to active pixels. | ||||
*/ | */ | ||||
apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, mask ); | |||||
apply_stencil_op( ctx, ctx->Stencil.ZPassFunc[face], face, n, stencil, mask ); | |||||
} | } | ||||
else { | else { | ||||
/* | /* | ||||
} | } | ||||
/* apply the pass and fail operations */ | /* apply the pass and fail operations */ | ||||
if (ctx->Stencil.ZFailFunc != GL_KEEP) { | |||||
apply_stencil_op( ctx, ctx->Stencil.ZFailFunc, n, stencil, failmask ); | |||||
if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) { | |||||
apply_stencil_op( ctx, ctx->Stencil.ZFailFunc[face], face, | |||||
n, stencil, failmask ); | |||||
} | } | ||||
if (ctx->Stencil.ZPassFunc != GL_KEEP) { | |||||
apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, passmask ); | |||||
if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) { | |||||
apply_stencil_op( ctx, ctx->Stencil.ZPassFunc[face], face, | |||||
n, stencil, passmask ); | |||||
} | } | ||||
} | } | ||||
static void | static void | ||||
apply_stencil_op_to_pixels( const GLcontext *ctx, | apply_stencil_op_to_pixels( const GLcontext *ctx, | ||||
GLuint n, const GLint x[], const GLint y[], | GLuint n, const GLint x[], const GLint y[], | ||||
GLenum oper, const GLubyte mask[] ) | |||||
GLenum oper, GLuint face, const GLubyte mask[] ) | |||||
{ | { | ||||
const GLstencil ref = ctx->Stencil.Ref; | |||||
const GLstencil wrtmask = ctx->Stencil.WriteMask; | |||||
const GLstencil invmask = (GLstencil) (~ctx->Stencil.WriteMask); | |||||
const GLstencil ref = ctx->Stencil.Ref[face]; | |||||
const GLstencil wrtmask = ctx->Stencil.WriteMask[face]; | |||||
const GLstencil invmask = (GLstencil) (~wrtmask); | |||||
GLuint i; | GLuint i; | ||||
ASSERT(!SWRAST_CONTEXT(ctx)->Driver.WriteStencilSpan); /* software stencil buffer only! */ | ASSERT(!SWRAST_CONTEXT(ctx)->Driver.WriteStencilSpan); /* software stencil buffer only! */ | ||||
* \return GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed. | * \return GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed. | ||||
*/ | */ | ||||
static GLboolean | static GLboolean | ||||
stencil_test_pixels( GLcontext *ctx, GLuint n, | |||||
stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n, | |||||
const GLint x[], const GLint y[], GLubyte mask[] ) | const GLint x[], const GLint y[], GLubyte mask[] ) | ||||
{ | { | ||||
GLubyte fail[MAX_WIDTH]; | GLubyte fail[MAX_WIDTH]; | ||||
GLstencil r, s; | GLstencil r, s; | ||||
GLuint i; | GLuint i; | ||||
GLboolean allfail = GL_FALSE; | GLboolean allfail = GL_FALSE; | ||||
const GLuint valueMask = ctx->Stencil.ValueMask[face]; | |||||
/* software stencil buffer only! */ | /* software stencil buffer only! */ | ||||
ASSERT(ctx->DrawBuffer->UseSoftwareStencilBuffer); | ASSERT(ctx->DrawBuffer->UseSoftwareStencilBuffer); | ||||
* ENDIF | * ENDIF | ||||
*/ | */ | ||||
switch (ctx->Stencil.Function) { | |||||
switch (ctx->Stencil.Function[face]) { | |||||
case GL_NEVER: | case GL_NEVER: | ||||
/* always fail */ | /* always fail */ | ||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
allfail = GL_TRUE; | allfail = GL_TRUE; | ||||
break; | break; | ||||
case GL_LESS: | case GL_LESS: | ||||
r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); | |||||
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); | |||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
if (mask[i]) { | if (mask[i]) { | ||||
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); | GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); | ||||
s = (GLstencil) (*sptr & ctx->Stencil.ValueMask); | |||||
s = (GLstencil) (*sptr & valueMask); | |||||
if (r < s) { | if (r < s) { | ||||
/* passed */ | /* passed */ | ||||
fail[i] = 0; | fail[i] = 0; | ||||
} | } | ||||
break; | break; | ||||
case GL_LEQUAL: | case GL_LEQUAL: | ||||
r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); | |||||
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); | |||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
if (mask[i]) { | if (mask[i]) { | ||||
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); | GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); | ||||
s = (GLstencil) (*sptr & ctx->Stencil.ValueMask); | |||||
s = (GLstencil) (*sptr & valueMask); | |||||
if (r <= s) { | if (r <= s) { | ||||
/* pass */ | /* pass */ | ||||
fail[i] = 0; | fail[i] = 0; | ||||
} | } | ||||
break; | break; | ||||
case GL_GREATER: | case GL_GREATER: | ||||
r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); | |||||
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); | |||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
if (mask[i]) { | if (mask[i]) { | ||||
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); | GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); | ||||
s = (GLstencil) (*sptr & ctx->Stencil.ValueMask); | |||||
s = (GLstencil) (*sptr & valueMask); | |||||
if (r > s) { | if (r > s) { | ||||
/* passed */ | /* passed */ | ||||
fail[i] = 0; | fail[i] = 0; | ||||
} | } | ||||
break; | break; | ||||
case GL_GEQUAL: | case GL_GEQUAL: | ||||
r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); | |||||
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); | |||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
if (mask[i]) { | if (mask[i]) { | ||||
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); | GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); | ||||
s = (GLstencil) (*sptr & ctx->Stencil.ValueMask); | |||||
s = (GLstencil) (*sptr & valueMask); | |||||
if (r >= s) { | if (r >= s) { | ||||
/* passed */ | /* passed */ | ||||
fail[i] = 0; | fail[i] = 0; | ||||
} | } | ||||
break; | break; | ||||
case GL_EQUAL: | case GL_EQUAL: | ||||
r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); | |||||
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); | |||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
if (mask[i]) { | if (mask[i]) { | ||||
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); | GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); | ||||
s = (GLstencil) (*sptr & ctx->Stencil.ValueMask); | |||||
s = (GLstencil) (*sptr & valueMask); | |||||
if (r == s) { | if (r == s) { | ||||
/* passed */ | /* passed */ | ||||
fail[i] = 0; | fail[i] = 0; | ||||
} | } | ||||
break; | break; | ||||
case GL_NOTEQUAL: | case GL_NOTEQUAL: | ||||
r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); | |||||
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); | |||||
for (i=0;i<n;i++) { | for (i=0;i<n;i++) { | ||||
if (mask[i]) { | if (mask[i]) { | ||||
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); | GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]); | ||||
s = (GLstencil) (*sptr & ctx->Stencil.ValueMask); | |||||
s = (GLstencil) (*sptr & valueMask); | |||||
if (r != s) { | if (r != s) { | ||||
/* passed */ | /* passed */ | ||||
fail[i] = 0; | fail[i] = 0; | ||||
return 0; | return 0; | ||||
} | } | ||||
if (ctx->Stencil.FailFunc != GL_KEEP) { | |||||
apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc, fail ); | |||||
if (ctx->Stencil.FailFunc[face] != GL_KEEP) { | |||||
apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc[face], | |||||
face, fail ); | |||||
} | } | ||||
return !allfail; | return !allfail; | ||||
* GL_TRUE - one or more fragments passed the testing | * GL_TRUE - one or more fragments passed the testing | ||||
*/ | */ | ||||
static GLboolean | static GLboolean | ||||
stencil_and_ztest_pixels( GLcontext *ctx, struct sw_span *span ) | |||||
stencil_and_ztest_pixels( GLcontext *ctx, struct sw_span *span, GLuint face ) | |||||
{ | { | ||||
const GLuint n = span->end; | const GLuint n = span->end; | ||||
const GLint *x = span->array->x; | const GLint *x = span->array->x; | ||||
MEMCPY(origMask, mask, n * sizeof(GLubyte)); | MEMCPY(origMask, mask, n * sizeof(GLubyte)); | ||||
(void) do_stencil_test(ctx, n, stencil, mask); | |||||
(void) do_stencil_test(ctx, face, n, stencil, mask); | |||||
if (ctx->Depth.Test == GL_FALSE) { | if (ctx->Depth.Test == GL_FALSE) { | ||||
apply_stencil_op(ctx, ctx->Stencil.ZPassFunc, n, stencil, mask); | |||||
apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face, | |||||
n, stencil, mask); | |||||
} | } | ||||
else { | else { | ||||
_mesa_depth_test_span(ctx, span); | _mesa_depth_test_span(ctx, span); | ||||
if (ctx->Stencil.ZFailFunc != GL_KEEP) { | |||||
if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) { | |||||
GLubyte failmask[MAX_WIDTH]; | GLubyte failmask[MAX_WIDTH]; | ||||
GLuint i; | GLuint i; | ||||
for (i = 0; i < n; i++) { | for (i = 0; i < n; i++) { | ||||
ASSERT(mask[i] == 0 || mask[i] == 1); | ASSERT(mask[i] == 0 || mask[i] == 1); | ||||
failmask[i] = origMask[i] & (mask[i] ^ 1); | failmask[i] = origMask[i] & (mask[i] ^ 1); | ||||
} | } | ||||
apply_stencil_op(ctx, ctx->Stencil.ZFailFunc, | |||||
apply_stencil_op(ctx, ctx->Stencil.ZFailFunc[face], face, | |||||
n, stencil, failmask); | n, stencil, failmask); | ||||
} | } | ||||
if (ctx->Stencil.ZPassFunc != GL_KEEP) { | |||||
if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) { | |||||
GLubyte passmask[MAX_WIDTH]; | GLubyte passmask[MAX_WIDTH]; | ||||
GLuint i; | GLuint i; | ||||
for (i = 0; i < n; i++) { | for (i = 0; i < n; i++) { | ||||
ASSERT(mask[i] == 0 || mask[i] == 1); | ASSERT(mask[i] == 0 || mask[i] == 1); | ||||
passmask[i] = origMask[i] & mask[i]; | passmask[i] = origMask[i] & mask[i]; | ||||
} | } | ||||
apply_stencil_op(ctx, ctx->Stencil.ZPassFunc, | |||||
apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face, | |||||
n, stencil, passmask); | n, stencil, passmask); | ||||
} | } | ||||
} | } | ||||
ASSERT(ctx->DrawBuffer->UseSoftwareStencilBuffer); | ASSERT(ctx->DrawBuffer->UseSoftwareStencilBuffer); | ||||
if (stencil_test_pixels(ctx, n, x, y, mask) == GL_FALSE) { | |||||
if (stencil_test_pixels(ctx, face, n, x, y, mask) == GL_FALSE) { | |||||
/* all fragments failed the stencil test, we're done. */ | /* all fragments failed the stencil test, we're done. */ | ||||
return GL_FALSE; | return GL_FALSE; | ||||
} | } | ||||
if (ctx->Depth.Test==GL_FALSE) { | if (ctx->Depth.Test==GL_FALSE) { | ||||
apply_stencil_op_to_pixels(ctx, n, x, y, | apply_stencil_op_to_pixels(ctx, n, x, y, | ||||
ctx->Stencil.ZPassFunc, mask); | |||||
ctx->Stencil.ZPassFunc[face], face, mask); | |||||
} | } | ||||
else { | else { | ||||
GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH]; | GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH]; | ||||
failmask[i] = oldmask[i] & (mask[i] ^ 1); | failmask[i] = oldmask[i] & (mask[i] ^ 1); | ||||
} | } | ||||
if (ctx->Stencil.ZFailFunc != GL_KEEP) { | |||||
if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) { | |||||
apply_stencil_op_to_pixels(ctx, n, x, y, | apply_stencil_op_to_pixels(ctx, n, x, y, | ||||
ctx->Stencil.ZFailFunc, failmask); | |||||
ctx->Stencil.ZFailFunc[face], | |||||
face, failmask); | |||||
} | } | ||||
if (ctx->Stencil.ZPassFunc != GL_KEEP) { | |||||
if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) { | |||||
apply_stencil_op_to_pixels(ctx, n, x, y, | apply_stencil_op_to_pixels(ctx, n, x, y, | ||||
ctx->Stencil.ZPassFunc, passmask); | |||||
ctx->Stencil.ZPassFunc[face], | |||||
face, passmask); | |||||
} | } | ||||
} | } | ||||
* GL_FALSE = all fragments failed. | * GL_FALSE = all fragments failed. | ||||
*/ | */ | ||||
GLboolean | GLboolean | ||||
_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span) | |||||
_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face) | |||||
{ | { | ||||
if (span->arrayMask & SPAN_XY) | if (span->arrayMask & SPAN_XY) | ||||
return stencil_and_ztest_pixels(ctx, span); | |||||
return stencil_and_ztest_pixels(ctx, span, face); | |||||
else | else | ||||
return stencil_and_ztest_span(ctx, span); | |||||
return stencil_and_ztest_span(ctx, span, face); | |||||
} | } | ||||
if (ctx->Scissor.Enabled) { | if (ctx->Scissor.Enabled) { | ||||
/* clear scissor region only */ | /* clear scissor region only */ | ||||
const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; | const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; | ||||
if (ctx->Stencil.WriteMask != STENCIL_MAX) { | |||||
if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) { | |||||
/* must apply mask to the clear */ | /* must apply mask to the clear */ | ||||
GLint y; | GLint y; | ||||
for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { | for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { | ||||
const GLstencil mask = ctx->Stencil.WriteMask; | |||||
const GLstencil mask = ctx->Stencil.WriteMask[0]; | |||||
const GLstencil invMask = ~mask; | const GLstencil invMask = ~mask; | ||||
const GLstencil clearVal = (ctx->Stencil.Clear & mask); | const GLstencil clearVal = (ctx->Stencil.Clear & mask); | ||||
GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->_Xmin, y ); | GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->_Xmin, y ); | ||||
} | } | ||||
else { | else { | ||||
/* clear whole stencil buffer */ | /* clear whole stencil buffer */ | ||||
if (ctx->Stencil.WriteMask != STENCIL_MAX) { | |||||
if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) { | |||||
/* must apply mask to the clear */ | /* must apply mask to the clear */ | ||||
const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; | const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; | ||||
GLstencil *stencil = ctx->DrawBuffer->Stencil; | GLstencil *stencil = ctx->DrawBuffer->Stencil; | ||||
const GLstencil mask = ctx->Stencil.WriteMask; | |||||
const GLstencil mask = ctx->Stencil.WriteMask[0]; | |||||
const GLstencil invMask = ~mask; | const GLstencil invMask = ~mask; | ||||
const GLstencil clearVal = (ctx->Stencil.Clear & mask); | const GLstencil clearVal = (ctx->Stencil.Clear & mask); | ||||
GLuint i; | GLuint i; | ||||
/* clear scissor region only */ | /* clear scissor region only */ | ||||
const GLint x = ctx->DrawBuffer->_Xmin; | const GLint x = ctx->DrawBuffer->_Xmin; | ||||
const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; | const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; | ||||
if (ctx->Stencil.WriteMask != STENCIL_MAX) { | |||||
if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) { | |||||
/* must apply mask to the clear */ | /* must apply mask to the clear */ | ||||
GLint y; | GLint y; | ||||
for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { | for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { | ||||
const GLstencil mask = ctx->Stencil.WriteMask; | |||||
const GLstencil mask = ctx->Stencil.WriteMask[0]; | |||||
const GLstencil invMask = ~mask; | const GLstencil invMask = ~mask; | ||||
const GLstencil clearVal = (ctx->Stencil.Clear & mask); | const GLstencil clearVal = (ctx->Stencil.Clear & mask); | ||||
GLstencil stencil[MAX_WIDTH]; | GLstencil stencil[MAX_WIDTH]; | ||||
} | } | ||||
else { | else { | ||||
/* clear whole stencil buffer */ | /* clear whole stencil buffer */ | ||||
if (ctx->Stencil.WriteMask != STENCIL_MAX) { | |||||
if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) { | |||||
/* must apply mask to the clear */ | /* must apply mask to the clear */ | ||||
const GLstencil mask = ctx->Stencil.WriteMask; | |||||
const GLstencil mask = ctx->Stencil.WriteMask[0]; | |||||
const GLstencil invMask = ~mask; | const GLstencil invMask = ~mask; | ||||
const GLstencil clearVal = (ctx->Stencil.Clear & mask); | const GLstencil clearVal = (ctx->Stencil.Clear & mask); | ||||
const GLint width = ctx->DrawBuffer->Width; | const GLint width = ctx->DrawBuffer->Width; |
/* $Id: s_stencil.h,v 1.7 2002/03/16 00:53:15 brianp Exp $ */ | |||||
/* $Id: s_stencil.h,v 1.8 2002/09/06 02:56:09 brianp Exp $ */ | |||||
/* | /* | ||||
* Mesa 3-D graphics library | * Mesa 3-D graphics library | ||||
extern GLboolean | extern GLboolean | ||||
_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span); | |||||
_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face); | |||||