fixed bad clear value
[mesa.git] / src / mesa / swrast / s_alpha.c
1 /* $Id: s_alpha.c,v 1.12 2002/10/04 19:10:12 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 * \file swrast/s_alpha.c
29 * \brief Functions to apply alpha test.
30 */
31
32 #include "glheader.h"
33 #include "context.h"
34 #include "colormac.h"
35 #include "macros.h"
36 #include "mmath.h"
37
38 #include "s_alpha.h"
39 #include "s_context.h"
40
41
42 /**
43 * \fn GLint _mesa_alpha_test( const GLcontext *ctx, struct sw_span *span )
44 * \brief Apply the alpha test to a span of pixels.
45 * \return
46 * - "0" = all pixels in the span failed the alpha test.
47 * - "1" = one or more pixels passed the alpha test.
48 */
49 GLint
50 _mesa_alpha_test( const GLcontext *ctx, struct sw_span *span )
51 {
52 const GLchan (*rgba)[4] = (const GLchan (*)[4]) span->array->rgba;
53 GLchan ref;
54 const GLuint n = span->end;
55 GLubyte *mask = span->array->mask;
56 GLuint i;
57
58 CLAMPED_FLOAT_TO_CHAN(ref, ctx->Color.AlphaRef);
59
60 if (span->arrayMask & SPAN_RGBA) {
61 /* Use the array values */
62 switch (ctx->Color.AlphaFunc) {
63 case GL_LESS:
64 for (i = 0; i < n; i++)
65 mask[i] &= (rgba[i][ACOMP] < ref);
66 break;
67 case GL_LEQUAL:
68 for (i = 0; i < n; i++)
69 mask[i] &= (rgba[i][ACOMP] <= ref);
70 break;
71 case GL_GEQUAL:
72 for (i = 0; i < n; i++)
73 mask[i] &= (rgba[i][ACOMP] >= ref);
74 break;
75 case GL_GREATER:
76 for (i = 0; i < n; i++)
77 mask[i] &= (rgba[i][ACOMP] > ref);
78 break;
79 case GL_NOTEQUAL:
80 for (i = 0; i < n; i++)
81 mask[i] &= (rgba[i][ACOMP] != ref);
82 break;
83 case GL_EQUAL:
84 for (i = 0; i < n; i++)
85 mask[i] &= (rgba[i][ACOMP] == ref);
86 break;
87 case GL_ALWAYS:
88 /* do nothing */
89 return 1;
90 case GL_NEVER:
91 /* caller should check for zero! */
92 span->writeAll = GL_FALSE;
93 return 0;
94 default:
95 _mesa_problem( ctx, "Invalid alpha test in _mesa_alpha_test" );
96 return 0;
97 }
98 }
99 else {
100 /* Use the interpolation values */
101 #if CHAN_TYPE == GL_FLOAT
102 const GLfloat alphaStep = span->alphaStep;
103 GLfloat alpha = span->alpha;
104 ASSERT(span->interpMask & SPAN_RGBA);
105 switch (ctx->Color.AlphaFunc) {
106 case GL_LESS:
107 for (i = 0; i < n; i++) {
108 mask[i] &= (alpha < ref);
109 alpha += alphaStep;
110 }
111 break;
112 case GL_LEQUAL:
113 for (i = 0; i < n; i++) {
114 mask[i] &= (alpha <= ref);
115 alpha += alphaStep;
116 }
117 break;
118 case GL_GEQUAL:
119 for (i = 0; i < n; i++) {
120 mask[i] &= (alpha >= ref);
121 alpha += alphaStep;
122 }
123 break;
124 case GL_GREATER:
125 for (i = 0; i < n; i++) {
126 mask[i] &= (alpha > ref);
127 alpha += alphaStep;
128 }
129 break;
130 case GL_NOTEQUAL:
131 for (i = 0; i < n; i++) {
132 mask[i] &= (alpha != ref);
133 alpha += alphaStep;
134 }
135 break;
136 case GL_EQUAL:
137 for (i = 0; i < n; i++) {
138 mask[i] &= (alpha == ref);
139 alpha += alphaStep;
140 }
141 break;
142 case GL_ALWAYS:
143 /* do nothing */
144 return 1;
145 case GL_NEVER:
146 /* caller should check for zero! */
147 span->writeAll = GL_FALSE;
148 return 0;
149 default:
150 _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
151 return 0;
152 }
153 #else
154 /* 8 or 16-bit channel interpolation */
155 const GLfixed alphaStep = span->alphaStep;
156 GLfixed alpha = span->alpha;
157 ASSERT(span->interpMask & SPAN_RGBA);
158 switch (ctx->Color.AlphaFunc) {
159 case GL_LESS:
160 for (i = 0; i < n; i++) {
161 mask[i] &= (FixedToChan(alpha) < ref);
162 alpha += alphaStep;
163 }
164 break;
165 case GL_LEQUAL:
166 for (i = 0; i < n; i++) {
167 mask[i] &= (FixedToChan(alpha) <= ref);
168 alpha += alphaStep;
169 }
170 break;
171 case GL_GEQUAL:
172 for (i = 0; i < n; i++) {
173 mask[i] &= (FixedToChan(alpha) >= ref);
174 alpha += alphaStep;
175 }
176 break;
177 case GL_GREATER:
178 for (i = 0; i < n; i++) {
179 mask[i] &= (FixedToChan(alpha) > ref);
180 alpha += alphaStep;
181 }
182 break;
183 case GL_NOTEQUAL:
184 for (i = 0; i < n; i++) {
185 mask[i] &= (FixedToChan(alpha) != ref);
186 alpha += alphaStep;
187 }
188 break;
189 case GL_EQUAL:
190 for (i = 0; i < n; i++) {
191 mask[i] &= (FixedToChan(alpha) == ref);
192 alpha += alphaStep;
193 }
194 break;
195 case GL_ALWAYS:
196 /* do nothing */
197 return 1;
198 case GL_NEVER:
199 /* caller should check for zero! */
200 span->writeAll = GL_FALSE;
201 return 0;
202 default:
203 _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
204 return 0;
205 }
206 #endif /* CHAN_TYPE */
207 }
208
209 #if 0
210 /* XXXX This causes conformance failures!!!! */
211 while ((span->start <= span->end) &&
212 (mask[span->start] == 0))
213 span->start ++;
214
215 while ((span->end >= span->start) &&
216 (mask[span->end] == 0))
217 span->end --;
218 #endif
219
220 span->writeAll = GL_FALSE;
221
222 if (span->start >= span->end)
223 return 0;
224 else
225 return 1;
226 }