Browse Source

GL_EXT_stencil_two_side extension, not 100% complete yet.

tags/mesa_4_1
Brian Paul 23 years ago
parent
commit
5f60a0b50a

+ 9
- 6
src/mesa/main/attrib.c View File

/* $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:

+ 17
- 8
src/mesa/main/context.c View File

/* $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 */

+ 10
- 1
src/mesa/main/dd.h View File

/* $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,

+ 27
- 1
src/mesa/main/dlist.c View File

/* $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;

+ 16
- 1
src/mesa/main/enable.c View File

/* $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;

+ 3
- 1
src/mesa/main/extensions.c View File

/* $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",

+ 69
- 29
src/mesa/main/get.c View File

/* $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);
} }

+ 33
- 9
src/mesa/main/mtypes.h View File

/* $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;

+ 6
- 1
src/mesa/main/state.c View File

/* $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;

+ 41
- 19
src/mesa/main/stencil.c View File

/* $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 );
}
}


+ 6
- 3
src/mesa/main/stencil.h View File

/* $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

+ 10
- 12
src/mesa/swrast/s_span.c View File

/* $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;
} }

+ 83
- 73
src/mesa/swrast/s_stencil.c View File

/* $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;

+ 2
- 2
src/mesa/swrast/s_stencil.h View File

/* $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);







Loading…
Cancel
Save