LOTS of changes, building upon Klaus's work.
[mesa.git] / src / mesa / swrast / s_alpha.c
1 /* $Id: s_alpha.c,v 1.6 2002/01/27 18:32:03 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 #include "glheader.h"
29 #include "context.h"
30 #include "colormac.h"
31 #include "macros.h"
32 #include "mmath.h"
33
34 #include "s_alpha.h"
35
36
37 /*
38 * Apply the alpha test to a span of pixels.
39 * In: rgba - array of pixels
40 * In/Out: span -
41 * Return: 0 = all pixels in the span failed the alpha test.
42 * 1 = one or more pixels passed the alpha test.
43 */
44 GLint
45 _mesa_alpha_test( const GLcontext *ctx, struct sw_span *span,
46 CONST GLchan rgba[][4])
47 {
48 GLuint i;
49 const GLchan ref = ctx->Color.AlphaRef;
50 GLubyte *mask = span->mask;
51
52 ASSERT (span->filledAlpha == GL_TRUE || (span->arrayMask & SPAN_RGBA));
53
54 /* switch cases ordered from most frequent to less frequent */
55 switch (ctx->Color.AlphaFunc) {
56 case GL_LESS:
57 for (i=span->start; i<span->end; i++) {
58 mask[i] &= (rgba[i][ACOMP] < ref);
59 }
60 break;
61 case GL_LEQUAL:
62 for (i=span->start; i<span->end; i++)
63 mask[i] &= (rgba[i][ACOMP] <= ref);
64 break;
65 case GL_GEQUAL:
66 for (i=span->start; i<span->end; i++) {
67 mask[i] &= (rgba[i][ACOMP] >= ref);
68 }
69 break;
70 case GL_GREATER:
71 for (i=span->start; i<span->end; i++) {
72 mask[i] &= (rgba[i][ACOMP] > ref);
73 }
74 break;
75 case GL_NOTEQUAL:
76 for (i=span->start; i<span->end; i++) {
77 mask[i] &= (rgba[i][ACOMP] != ref);
78 }
79 break;
80 case GL_EQUAL:
81 for (i=span->start; i<span->end; i++) {
82 mask[i] &= (rgba[i][ACOMP] == ref);
83 }
84 break;
85 case GL_ALWAYS:
86 /* do nothing */
87 return 1;
88 case GL_NEVER:
89 /* caller should check for zero! */
90 return 0;
91 default:
92 _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
93 return 0;
94 }
95
96 #if 0
97 /* XXXX This causes conformance failures!!!! */
98 while ((span->start <= span->end) &&
99 (mask[span->start] == 0))
100 span->start ++;
101
102 while ((span->end >= span->start) &&
103 (mask[span->end] == 0))
104 span->end --;
105 #endif
106 span->writeAll = GL_FALSE;
107
108 if (span->start >= span->end)
109 return 0;
110 else
111 return 1;
112 }
113
114
115 /*
116 * Apply the alpha test to a span of pixels.
117 * In: rgba - array of pixels
118 * In/Out: mask - current pixel mask. Pixels which fail the alpha test
119 * will set the corresponding mask flag to 0.
120 * Return: 0 = all pixels in the span failed the alpha test.
121 * 1 = one or more pixels passed the alpha test.
122 */
123 GLint
124 _old_alpha_test( const GLcontext *ctx,
125 GLuint n, CONST GLchan rgba[][4], GLubyte mask[] )
126 {
127 GLuint i;
128 const GLchan ref = ctx->Color.AlphaRef;
129
130 /* switch cases ordered from most frequent to less frequent */
131 switch (ctx->Color.AlphaFunc) {
132 case GL_LESS:
133 for (i=0;i<n;i++) {
134 mask[i] &= (rgba[i][ACOMP] < ref);
135 }
136 return 1;
137 case GL_LEQUAL:
138 for (i=0;i<n;i++)
139 mask[i] &= (rgba[i][ACOMP] <= ref);
140 return 1;
141 case GL_GEQUAL:
142 for (i=0;i<n;i++) {
143 mask[i] &= (rgba[i][ACOMP] >= ref);
144 }
145 return 1;
146 case GL_GREATER:
147 for (i=0;i<n;i++) {
148 mask[i] &= (rgba[i][ACOMP] > ref);
149 }
150 return 1;
151 case GL_NOTEQUAL:
152 for (i=0;i<n;i++) {
153 mask[i] &= (rgba[i][ACOMP] != ref);
154 }
155 return 1;
156 case GL_EQUAL:
157 for (i=0;i<n;i++) {
158 mask[i] &= (rgba[i][ACOMP] == ref);
159 }
160 return 1;
161 case GL_ALWAYS:
162 /* do nothing */
163 return 1;
164 case GL_NEVER:
165 /* caller should check for zero! */
166 return 0;
167 default:
168 _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
169 return 0;
170 }
171 /* Never get here */
172 /*return 1;*/
173 }