1 /* $Id: s_alpha.c,v 1.8 2002/01/31 00:27:43 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
35 #include "s_context.h"
39 * Apply the alpha test to a span of pixels.
40 * In: rgba - array of pixels
42 * Return: 0 = all pixels in the span failed the alpha test.
43 * 1 = one or more pixels passed the alpha test.
46 _mesa_alpha_test( const GLcontext
*ctx
, struct sw_span
*span
)
48 const GLchan (*rgba
)[4] = (const GLchan (*)[4]) span
->color
.rgba
;
49 const GLchan ref
= ctx
->Color
.AlphaRef
;
50 const GLuint n
= span
->end
;
51 GLubyte
*mask
= span
->mask
;
54 if (span
->arrayMask
& SPAN_RGBA
) {
55 /* Use the array values */
56 switch (ctx
->Color
.AlphaFunc
) {
58 for (i
= 0; i
< n
; i
++)
59 mask
[i
] &= (rgba
[i
][ACOMP
] < ref
);
62 for (i
= 0; i
< n
; i
++)
63 mask
[i
] &= (rgba
[i
][ACOMP
] <= ref
);
66 for (i
= 0; i
< n
; i
++)
67 mask
[i
] &= (rgba
[i
][ACOMP
] >= ref
);
70 for (i
= 0; i
< n
; i
++)
71 mask
[i
] &= (rgba
[i
][ACOMP
] > ref
);
74 for (i
= 0; i
< n
; i
++)
75 mask
[i
] &= (rgba
[i
][ACOMP
] != ref
);
78 for (i
= 0; i
< n
; i
++)
79 mask
[i
] &= (rgba
[i
][ACOMP
] == ref
);
85 /* caller should check for zero! */
86 span
->writeAll
= GL_FALSE
;
89 _mesa_problem( ctx
, "Invalid alpha test in _mesa_alpha_test" );
94 /* Use the interpolation values */
95 #if CHAN_TYPE == GL_FLOAT
96 const GLfloat alphaStep
= span
->alphaStep
;
97 GLfloat alpha
= span
->alpha
;
98 ASSERT(span
->interpMask
& SPAN_RGBA
);
99 switch (ctx
->Color
.AlphaFunc
) {
101 for (i
= 0; i
< n
; i
++) {
102 mask
[i
] &= (alpha
< ref
);
107 for (i
= 0; i
< n
; i
++) {
108 mask
[i
] &= (alpha
<= ref
);
113 for (i
= 0; i
< n
; i
++) {
114 mask
[i
] &= (alpha
>= ref
);
119 for (i
= 0; i
< n
; i
++) {
120 mask
[i
] &= (alpha
> ref
);
125 for (i
= 0; i
< n
; i
++) {
126 mask
[i
] &= (alpha
!= ref
);
131 for (i
= 0; i
< n
; i
++) {
132 mask
[i
] &= (alpha
== ref
);
140 /* caller should check for zero! */
141 span
->writeAll
= GL_FALSE
;
144 _mesa_problem( ctx
, "Invalid alpha test in gl_alpha_test" );
148 /* 8 or 16-bit channel interpolation */
149 const GLfixed alphaStep
= span
->alphaStep
;
150 GLfixed alpha
= span
->alpha
;
151 ASSERT(span
->interpMask
& SPAN_RGBA
);
152 switch (ctx
->Color
.AlphaFunc
) {
154 for (i
= 0; i
< n
; i
++) {
155 mask
[i
] &= (FixedToChan(alpha
) < ref
);
160 for (i
= 0; i
< n
; i
++) {
161 mask
[i
] &= (FixedToChan(alpha
) <= ref
);
166 for (i
= 0; i
< n
; i
++) {
167 mask
[i
] &= (FixedToChan(alpha
) >= ref
);
172 for (i
= 0; i
< n
; i
++) {
173 mask
[i
] &= (FixedToChan(alpha
) > ref
);
178 for (i
= 0; i
< n
; i
++) {
179 mask
[i
] &= (FixedToChan(alpha
) != ref
);
184 for (i
= 0; i
< n
; i
++) {
185 mask
[i
] &= (FixedToChan(alpha
) == ref
);
193 /* caller should check for zero! */
194 span
->writeAll
= GL_FALSE
;
197 _mesa_problem( ctx
, "Invalid alpha test in gl_alpha_test" );
200 #endif /* CHAN_TYPE */
204 /* XXXX This causes conformance failures!!!! */
205 while ((span
->start
<= span
->end
) &&
206 (mask
[span
->start
] == 0))
209 while ((span
->end
>= span
->start
) &&
210 (mask
[span
->end
] == 0))
214 span
->writeAll
= GL_FALSE
;
216 if (span
->start
>= span
->end
)
224 * Apply the alpha test to a span of pixels.
225 * In: rgba - array of pixels
226 * In/Out: mask - current pixel mask. Pixels which fail the alpha test
227 * will set the corresponding mask flag to 0.
228 * Return: 0 = all pixels in the span failed the alpha test.
229 * 1 = one or more pixels passed the alpha test.
232 _old_alpha_test( const GLcontext
*ctx
,
233 GLuint n
, CONST GLchan rgba
[][4], GLubyte mask
[] )
236 const GLchan ref
= ctx
->Color
.AlphaRef
;
238 /* switch cases ordered from most frequent to less frequent */
239 switch (ctx
->Color
.AlphaFunc
) {
242 mask
[i
] &= (rgba
[i
][ACOMP
] < ref
);
247 mask
[i
] &= (rgba
[i
][ACOMP
] <= ref
);
251 mask
[i
] &= (rgba
[i
][ACOMP
] >= ref
);
256 mask
[i
] &= (rgba
[i
][ACOMP
] > ref
);
261 mask
[i
] &= (rgba
[i
][ACOMP
] != ref
);
266 mask
[i
] &= (rgba
[i
][ACOMP
] == ref
);
273 /* caller should check for zero! */
276 _mesa_problem( ctx
, "Invalid alpha test in gl_alpha_test" );