diff options
author | Brian Paul <[email protected]> | 2005-01-12 04:01:08 +0000 |
---|---|---|
committer | Brian Paul <[email protected]> | 2005-01-12 04:01:08 +0000 |
commit | a9e34c68ac0538699a144f67d3ce83ccb8f49be9 (patch) | |
tree | ae9f6d8f3dd361ecc4303e7e19dbe6c9330ee726 /src/mesa/main | |
parent | 591b72b6a9718e908b11c7c2fd3bbf9e5b432677 (diff) |
Some initial work for OpenGL 2.0: glStencilFunc/Op/MaskSeparate() functions.
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/dd.h | 11 | ||||
-rw-r--r-- | src/mesa/main/dlist.c | 80 | ||||
-rw-r--r-- | src/mesa/main/state.c | 5 | ||||
-rw-r--r-- | src/mesa/main/stencil.c | 174 | ||||
-rw-r--r-- | src/mesa/main/stencil.h | 16 |
5 files changed, 280 insertions, 6 deletions
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 2b1131bc414..f7f7eacf060 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -7,7 +7,7 @@ * Mesa 3-D graphics library * Version: 6.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -676,7 +676,16 @@ struct dd_function_table { void (*StencilMask)(GLcontext *ctx, GLuint mask); /** Set stencil test actions */ void (*StencilOp)(GLcontext *ctx, GLenum fail, GLenum zfail, GLenum zpass); + /** Set active stencil face (GL_EXT_stencil_two_side) */ void (*ActiveStencilFace)(GLcontext *ctx, GLuint face); + /** OpenGL 2.0 two-sided StencilFunc */ + void (*StencilFuncSeparate)(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask); + /** OpenGL 2.0 two-sided StencilMask */ + void (*StencilMaskSeparate)(GLcontext *ctx, GLenum face, GLuint mask); + /** OpenGL 2.0 two-sided StencilOp */ + void (*StencilOpSeparate)(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass); /** Control the generation of texture coordinates */ void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, const GLfloat *params); diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 8ef5269cd89..beacf5b1f99 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -322,6 +322,10 @@ typedef enum { /* GL_ATI_fragment_shader */ OPCODE_BIND_FRAGMENT_SHADER_ATI, OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI, + /* OpenGL 2.0 */ + OPCODE_STENCIL_FUNC_SEPARATE, + OPCODE_STENCIL_OP_SEPARATE, + OPCODE_STENCIL_MASK_SEPARATE, /* Vertex attributes -- fallback for when optimized display * list build isn't active. @@ -799,6 +803,11 @@ _mesa_init_lists( void ) InstSize[OPCODE_BIND_FRAGMENT_SHADER_ATI] = 2; InstSize[OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI] = 6; #endif + /* OpenGL 2.0 */ + InstSize[OPCODE_STENCIL_FUNC_SEPARATE] = 5; + InstSize[OPCODE_STENCIL_MASK_SEPARATE] = 3; + InstSize[OPCODE_STENCIL_OP_SEPARATE] = 5; + InstSize[OPCODE_ATTR_1F_NV] = 3; InstSize[OPCODE_ATTR_2F_NV] = 4; InstSize[OPCODE_ATTR_3F_NV] = 5; @@ -3259,6 +3268,61 @@ static void GLAPIENTRY save_StencilOp( GLenum fail, GLenum zfail, GLenum zpass ) } +static void GLAPIENTRY +save_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_FUNC_SEPARATE, 4); + if (n) { + n[1].e = face; + n[2].e = func; + n[3].i = ref; + n[4].ui = mask; + } + if (ctx->ExecuteFlag) { + ctx->Exec->StencilFuncSeparate(face, func, ref, mask); + } +} + + +static void GLAPIENTRY +save_StencilMaskSeparate(GLenum face, GLuint mask) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION(ctx, OPCODE_STENCIL_MASK_SEPARATE, 2); + if (n) { + n[1].e = face; + n[2].ui = mask; + } + if (ctx->ExecuteFlag) { + ctx->Exec->StencilMaskSeparate(face, mask); + } +} + + +static void GLAPIENTRY +save_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_STENCIL_OP_SEPARATE, 4 ); + if (n) { + n[1].e = face; + n[2].e = fail; + n[3].e = zfail; + n[4].e = zpass; + } + if (ctx->ExecuteFlag) { + ctx->Exec->StencilOpSeparate(face, fail, zfail, zpass); + } +} + + static void GLAPIENTRY save_TexEnvfv( GLenum target, GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); @@ -4567,7 +4631,7 @@ static void GLAPIENTRY save_DepthBoundsEXT( GLclampd zmin, GLclampd zmax ) GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); - n = ALLOC_INSTRUCTION( ctx, OPCODE_ACTIVE_STENCIL_FACE_EXT, 2 ); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DEPTH_BOUNDS_EXT, 2 ); if (n) { n[1].f = (GLfloat) zmin; n[2].f = (GLfloat) zmax; @@ -6052,6 +6116,15 @@ execute_list( GLcontext *ctx, GLuint list ) case OPCODE_STENCIL_OP: (*ctx->Exec->StencilOp)( n[1].e, n[2].e, n[3].e ); break; + case OPCODE_STENCIL_FUNC_SEPARATE: + ctx->Exec->StencilFuncSeparate( n[1].e, n[2].e, n[3].i, n[4].ui ); + break; + case OPCODE_STENCIL_MASK_SEPARATE: + ctx->Exec->StencilMaskSeparate( n[1].e, n[2].ui ); + break; + case OPCODE_STENCIL_OP_SEPARATE: + ctx->Exec->StencilOpSeparate( n[1].e, n[2].e, n[3].e, n[4].e ); + break; case OPCODE_TEXENV: { GLfloat params[4]; @@ -7628,6 +7701,11 @@ _mesa_init_dlist_table( struct _glapi_table *table ) table->TexImage3D = save_TexImage3D; table->TexSubImage3D = save_TexSubImage3D; + /* GL 2.0 */ + table->StencilFuncSeparate = save_StencilFuncSeparate; + table->StencilMaskSeparate = save_StencilMaskSeparate; + table->StencilOpSeparate = save_StencilOpSeparate; + /* GL_ARB_imaging */ /* Not all are supported */ table->BlendColor = save_BlendColor; diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 64bb02cf01e..886a571eb8d 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -382,6 +382,11 @@ _mesa_init_exec_table(struct _glapi_table *exec) exec->SeparableFilter2D = _mesa_SeparableFilter2D; #endif + /* OpenGL 2.0 */ + exec->StencilFuncSeparate = _mesa_StencilFuncSeparate; + exec->StencilMaskSeparate = _mesa_StencilMaskSeparate; + exec->StencilOpSeparate = _mesa_StencilOpSeparate; + /* 2. GL_EXT_blend_color */ #if 0 /* exec->BlendColorEXT = _mesa_BlendColorEXT; */ diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c index 8c89e8cc13c..dfda4aa8fda 100644 --- a/src/mesa/main/stencil.c +++ b/src/mesa/main/stencil.c @@ -5,9 +5,9 @@ /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 6.3 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -244,6 +244,7 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) } + #if _HAVE_FULL_GL /* GL_EXT_stencil_two_side */ void GLAPIENTRY @@ -264,6 +265,175 @@ _mesa_ActiveStencilFaceEXT(GLenum face) #endif + +/** + * OpenGL 2.0 function. + * \todo Make StencilOp() call this function. And eventually remove the + * ctx->Driver.StencilOp function and use ctx->Driver.StencilOpSeparate + * instead. + */ +void GLAPIENTRY +_mesa_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { + _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(face)"); + return; + } + + switch (fail) { + case GL_KEEP: + case GL_ZERO: + case GL_REPLACE: + case GL_INCR: + case GL_DECR: + case GL_INVERT: + break; + case GL_INCR_WRAP_EXT: + case GL_DECR_WRAP_EXT: + if (ctx->Extensions.EXT_stencil_wrap) { + break; + } + /* FALL-THROUGH */ + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(fail)"); + return; + } + switch (zfail) { + case GL_KEEP: + case GL_ZERO: + case GL_REPLACE: + case GL_INCR: + case GL_DECR: + case GL_INVERT: + break; + case GL_INCR_WRAP_EXT: + case GL_DECR_WRAP_EXT: + if (ctx->Extensions.EXT_stencil_wrap) { + break; + } + /* FALL-THROUGH */ + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zfail)"); + return; + } + switch (zpass) { + case GL_KEEP: + case GL_ZERO: + case GL_REPLACE: + case GL_INCR: + case GL_DECR: + case GL_INVERT: + break; + case GL_INCR_WRAP_EXT: + case GL_DECR_WRAP_EXT: + if (ctx->Extensions.EXT_stencil_wrap) { + break; + } + /* FALL-THROUGH */ + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zpass)"); + return; + } + + FLUSH_VERTICES(ctx, _NEW_STENCIL); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + ctx->Stencil.FailFunc[0] = fail; + ctx->Stencil.ZFailFunc[0] = zfail; + ctx->Stencil.ZPassFunc[0] = zpass; + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + ctx->Stencil.FailFunc[1] = fail; + ctx->Stencil.ZFailFunc[1] = zfail; + ctx->Stencil.ZPassFunc[1] = zpass; + } + + if (ctx->Driver.StencilOpSeparate) { + ctx->Driver.StencilOpSeparate(ctx, face, fail, zfail, zpass); + } +} + + +/* OpenGL 2.0 */ +void GLAPIENTRY +_mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) +{ + GET_CURRENT_CONTEXT(ctx); + GLint maxref; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { + _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(face)"); + return; + } + + switch (func) { + case GL_NEVER: + case GL_LESS: + case GL_LEQUAL: + case GL_GREATER: + case GL_GEQUAL: + case GL_EQUAL: + case GL_NOTEQUAL: + case GL_ALWAYS: + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(func)"); + return; + } + + maxref = (1 << STENCIL_BITS) - 1; + ref = (GLstencil) CLAMP(ref, 0, maxref); + + FLUSH_VERTICES(ctx, _NEW_STENCIL); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + ctx->Stencil.Function[0] = func; + ctx->Stencil.Ref[0] = ref; + ctx->Stencil.ValueMask[0] = (GLstencil) mask; + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + ctx->Stencil.Function[1] = func; + ctx->Stencil.Ref[1] = ref; + ctx->Stencil.ValueMask[1] = (GLstencil) mask; + } + + if (ctx->Driver.StencilFuncSeparate) { + ctx->Driver.StencilFuncSeparate(ctx, face, func, ref, mask); + } +} + + +/* OpenGL 2.0 */ +void GLAPIENTRY +_mesa_StencilMaskSeparate(GLenum face, GLuint mask) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { + _mesa_error(ctx, GL_INVALID_ENUM, "glStencilaMaskSeparate(face)"); + return; + } + + FLUSH_VERTICES(ctx, _NEW_STENCIL); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + ctx->Stencil.WriteMask[0] = (GLstencil) mask; + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + ctx->Stencil.WriteMask[1] = (GLstencil) mask; + } + + if (ctx->Driver.StencilMaskSeparate) { + ctx->Driver.StencilMaskSeparate(ctx, face, mask); + } +} + + /** * Initialize the context stipple state. * diff --git a/src/mesa/main/stencil.h b/src/mesa/main/stencil.h index 5620d14c730..ec2927cfd20 100644 --- a/src/mesa/main/stencil.h +++ b/src/mesa/main/stencil.h @@ -5,9 +5,9 @@ /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 6.3 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -55,6 +55,18 @@ extern void GLAPIENTRY _mesa_ActiveStencilFaceEXT(GLenum face); +extern void GLAPIENTRY +_mesa_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); + + +extern void GLAPIENTRY +_mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); + + +extern void GLAPIENTRY +_mesa_StencilMaskSeparate(GLenum face, GLuint mask); + + extern void _mesa_init_stencil( GLcontext * ctx ); |