• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
_swrast_alpha_test(const struct gl_context * ctx,SWspan * span)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