Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  * Version:  6.5.2
  4.  *
  5.  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included
  15.  * in all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  21.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. /**
  26.  * \file swrast/s_alpha.c
  27.  * \brief Functions to apply alpha test.
  28.  */
  29.  
  30. #include "main/glheader.h"
  31. #include "main/context.h"
  32. #include "main/colormac.h"
  33. #include "main/macros.h"
  34.  
  35. #include "s_alpha.h"
  36. #include "s_context.h"
  37.  
  38.  
  39. #define ALPHA_TEST(ALPHA, LOOP_CODE)            \
  40. do {                                            \
  41.    switch (ctx->Color.AlphaFunc) {              \
  42.       case GL_LESS:                             \
  43.          for (i = 0; i < n; i++) {              \
  44.             mask[i] &= (ALPHA < ref);           \
  45.             LOOP_CODE;                          \
  46.          }                                      \
  47.          break;                                 \
  48.       case GL_LEQUAL:                           \
  49.          for (i = 0; i < n; i++) {              \
  50.             mask[i] &= (ALPHA <= ref);          \
  51.             LOOP_CODE;                          \
  52.          }                                      \
  53.          break;                                 \
  54.       case GL_GEQUAL:                           \
  55.          for (i = 0; i < n; i++) {              \
  56.             mask[i] &= (ALPHA >= ref);          \
  57.             LOOP_CODE;                          \
  58.          }                                      \
  59.          break;                                 \
  60.       case GL_GREATER:                          \
  61.          for (i = 0; i < n; i++) {              \
  62.             mask[i] &= (ALPHA > ref);           \
  63.             LOOP_CODE;                          \
  64.          }                                      \
  65.          break;                                 \
  66.       case GL_NOTEQUAL:                         \
  67.          for (i = 0; i < n; i++) {              \
  68.             mask[i] &= (ALPHA != ref);          \
  69.             LOOP_CODE;                          \
  70.          }                                      \
  71.          break;                                 \
  72.       case GL_EQUAL:                            \
  73.          for (i = 0; i < n; i++) {              \
  74.             mask[i] &= (ALPHA == ref);          \
  75.             LOOP_CODE;                          \
  76.          }                                      \
  77.          break;                                 \
  78.       default:                                  \
  79.          _mesa_problem(ctx, "Invalid alpha test in _swrast_alpha_test" ); \
  80.          return 0;                              \
  81.    }                                            \
  82. } while (0)
  83.  
  84.  
  85.  
  86. /**
  87.  * Perform the alpha test for an array of pixels.
  88.  * For pixels that fail the test, mask[i] will be set to 0.
  89.  * \return  0 if all pixels in the span failed the alpha test,
  90.  *          1 if one or more pixels passed the alpha test.
  91.  */
  92. GLint
  93. _swrast_alpha_test(const struct gl_context *ctx, SWspan *span)
  94. {
  95.    const GLuint n = span->end;
  96.    GLubyte *mask = span->array->mask;
  97.    GLuint i;
  98.  
  99.    if (ctx->Color.AlphaFunc == GL_ALWAYS) {
  100.       /* do nothing */
  101.       return 1;
  102.    }
  103.    else if (ctx->Color.AlphaFunc == GL_NEVER) {
  104.       /* All pixels failed - caller should check for this return value and
  105.        * act accordingly.
  106.        */
  107.       span->writeAll = GL_FALSE;
  108.       return 0;
  109.    }
  110.  
  111.    if (span->arrayMask & SPAN_RGBA) {
  112.       /* Use array's alpha values */
  113.       if (span->array->ChanType == GL_UNSIGNED_BYTE) {
  114.          GLubyte (*rgba)[4] = span->array->rgba8;
  115.          GLubyte ref;
  116.          CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
  117.          ALPHA_TEST(rgba[i][ACOMP], ;);
  118.       }
  119.       else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
  120.          GLushort (*rgba)[4] = span->array->rgba16;
  121.          GLushort ref;
  122.          CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef);
  123.          ALPHA_TEST(rgba[i][ACOMP], ;);
  124.       }
  125.       else {
  126.          GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
  127.          const GLfloat ref = ctx->Color.AlphaRef;
  128.          ALPHA_TEST(rgba[i][ACOMP], ;);
  129.       }
  130.    }
  131.    else {
  132.       /* Interpolate alpha values */
  133.       ASSERT(span->interpMask & SPAN_RGBA);
  134.       if (span->array->ChanType == GL_UNSIGNED_BYTE) {
  135.          const GLfixed alphaStep = span->alphaStep;
  136.          GLfixed alpha = span->alpha;
  137.          GLubyte ref;
  138.          CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
  139.          ALPHA_TEST(FixedToInt(alpha), alpha += alphaStep);
  140.       }
  141.       else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
  142.          const GLfixed alphaStep = span->alphaStep;
  143.          GLfixed alpha = span->alpha;
  144.          GLushort ref;
  145.          CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef);
  146.          ALPHA_TEST(FixedToInt(alpha), alpha += alphaStep);
  147.       }
  148.       else {
  149.          const GLfloat alphaStep = FixedToFloat(span->alphaStep);
  150.          GLfloat alpha = FixedToFloat(span->alpha);
  151.          const GLfloat ref = ctx->Color.AlphaRef;
  152.          ALPHA_TEST(alpha, alpha += alphaStep);
  153.       }
  154.    }
  155.  
  156.    span->writeAll = GL_FALSE;
  157.  
  158.    /* XXX examine mask[] values? */
  159.    return 1;
  160. }
  161.