home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / MesaDLL / stencil.cpp < prev    next >
C/C++ Source or Header  |  2002-10-24  |  6KB  |  215 lines

  1. /* $Id: stencil.c,v 1.29 2002/10/24 23:57:21 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27.  
  28. #include "glheader.h"
  29. #include "imports.h"
  30. #include "context.h"
  31. #include "depth.h"
  32. #include "macros.h"
  33. #include "stencil.h"
  34. #include "mtypes.h"
  35. #include "enable.h"
  36.  
  37.  
  38. void
  39. _mesa_ClearStencil( GLint s )
  40. {
  41.    GET_CURRENT_CONTEXT(ctx);
  42.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  43.  
  44.    if (ctx->Stencil.Clear == (GLstencil) s)
  45.       return;
  46.  
  47.    FLUSH_VERTICES(ctx, _NEW_STENCIL);
  48.    ctx->Stencil.Clear = (GLstencil) s;
  49.  
  50.    if (ctx->Driver.ClearStencil) {
  51.       (*ctx->Driver.ClearStencil)( ctx, s );
  52.    }
  53. }
  54.  
  55.  
  56.  
  57. void
  58. _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask )
  59. {
  60.    GET_CURRENT_CONTEXT(ctx);
  61.    const GLint face = ctx->Stencil.ActiveFace;
  62.    GLint maxref;
  63.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  64.  
  65.    switch (func) {
  66.       case GL_NEVER:
  67.       case GL_LESS:
  68.       case GL_LEQUAL:
  69.       case GL_GREATER:
  70.       case GL_GEQUAL:
  71.       case GL_EQUAL:
  72.       case GL_NOTEQUAL:
  73.       case GL_ALWAYS:
  74.          break;
  75.       default:
  76.          _mesa_error( ctx, GL_INVALID_ENUM, "glStencilFunc" );
  77.          return;
  78.    }
  79.  
  80.    maxref = (1 << STENCIL_BITS) - 1;
  81.    ref = (GLstencil) CLAMP( ref, 0, maxref );
  82.  
  83.    if (ctx->Stencil.Function[face] == func &&
  84.        ctx->Stencil.ValueMask[face] == (GLstencil) mask &&
  85.        ctx->Stencil.Ref[face] == ref)
  86.       return;
  87.  
  88.    FLUSH_VERTICES(ctx, _NEW_STENCIL);
  89.    ctx->Stencil.Function[face] = func;
  90.    ctx->Stencil.Ref[face] = ref;
  91.    ctx->Stencil.ValueMask[face] = (GLstencil) mask;
  92.  
  93.    if (ctx->Driver.StencilFunc) {
  94.       (*ctx->Driver.StencilFunc)( ctx, func, ref, mask );
  95.    }
  96. }
  97.  
  98.  
  99.  
  100. void
  101. _mesa_StencilMask( GLuint mask )
  102. {
  103.    GET_CURRENT_CONTEXT(ctx);
  104.    const GLint face = ctx->Stencil.ActiveFace;
  105.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  106.  
  107.    if (ctx->Stencil.WriteMask[face] == (GLstencil) mask)
  108.       return;
  109.  
  110.    FLUSH_VERTICES(ctx, _NEW_STENCIL);
  111.    ctx->Stencil.WriteMask[face] = (GLstencil) mask;
  112.  
  113.    if (ctx->Driver.StencilMask) {
  114.       (*ctx->Driver.StencilMask)( ctx, mask );
  115.    }
  116. }
  117.  
  118.  
  119.  
  120. void
  121. _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
  122. {
  123.    GET_CURRENT_CONTEXT(ctx);
  124.    const GLint face = ctx->Stencil.ActiveFace;
  125.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  126.  
  127.    switch (fail) {
  128.       case GL_KEEP:
  129.       case GL_ZERO:
  130.       case GL_REPLACE:
  131.       case GL_INCR:
  132.       case GL_DECR:
  133.       case GL_INVERT:
  134.          break;
  135.       case GL_INCR_WRAP_EXT:
  136.       case GL_DECR_WRAP_EXT:
  137.          if (!ctx->Extensions.EXT_stencil_wrap) {
  138.             break;
  139.          }
  140.          /* FALL-THROUGH */
  141.       default:
  142.          _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp");
  143.          return;
  144.    }
  145.    switch (zfail) {
  146.       case GL_KEEP:
  147.       case GL_ZERO:
  148.       case GL_REPLACE:
  149.       case GL_INCR:
  150.       case GL_DECR:
  151.       case GL_INVERT:
  152.          break;
  153.       case GL_INCR_WRAP_EXT:
  154.       case GL_DECR_WRAP_EXT:
  155.          if (ctx->Extensions.EXT_stencil_wrap) {
  156.             break;
  157.          }
  158.          /* FALL-THROUGH */
  159.       default:
  160.          _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp");
  161.          return;
  162.    }
  163.    switch (zpass) {
  164.       case GL_KEEP:
  165.       case GL_ZERO:
  166.       case GL_REPLACE:
  167.       case GL_INCR:
  168.       case GL_DECR:
  169.       case GL_INVERT:
  170.          break;
  171.       case GL_INCR_WRAP_EXT:
  172.       case GL_DECR_WRAP_EXT:
  173.          if (ctx->Extensions.EXT_stencil_wrap) {
  174.             break;
  175.          }
  176.          /* FALL-THROUGH */
  177.       default:
  178.          _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp");
  179.          return;
  180.    }
  181.  
  182.    if (ctx->Stencil.ZFailFunc[face] == zfail &&
  183.        ctx->Stencil.ZPassFunc[face] == zpass &&
  184.        ctx->Stencil.FailFunc[face] == fail)
  185.       return;
  186.  
  187.    FLUSH_VERTICES(ctx, _NEW_STENCIL);
  188.    ctx->Stencil.ZFailFunc[face] = zfail;
  189.    ctx->Stencil.ZPassFunc[face] = zpass;
  190.    ctx->Stencil.FailFunc[face] = fail;
  191.  
  192.    if (ctx->Driver.StencilOp) {
  193.       (*ctx->Driver.StencilOp)(ctx, fail, zfail, zpass);
  194.    }
  195. }
  196.  
  197.  
  198. /* GL_EXT_stencil_two_side */
  199. void
  200. _mesa_ActiveStencilFaceEXT(GLenum face)
  201. {
  202.    GET_CURRENT_CONTEXT(ctx);
  203.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  204.  
  205.    if (face == GL_FRONT || face == GL_BACK) {
  206.       FLUSH_VERTICES(ctx, _NEW_STENCIL);
  207.       ctx->Stencil.ActiveFace = (face == GL_FRONT) ? 0 : 1;
  208.    }
  209.  
  210.    if (ctx->Driver.ActiveStencilFace) {
  211.       (*ctx->Driver.ActiveStencilFace)( ctx, (GLuint) ctx->Stencil.ActiveFace );
  212.    }
  213. }
  214.  
  215.