Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
57 pj 1
/* $Id: s_alpha.c,v 1.1 2003-02-28 11:49:40 pj 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
}