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