2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
26 * \file swrast/s_alpha.c
27 * \brief Functions to apply alpha test.
30 #include "main/glheader.h"
31 #include "main/context.h"
32 #include "main/macros.h"
35 #include "s_context.h"
38 #define ALPHA_TEST(ALPHA, LOOP_CODE) \
40 switch (ctx->Color.AlphaFunc) { \
42 for (i = 0; i < n; i++) { \
43 mask[i] &= (ALPHA < ref); \
48 for (i = 0; i < n; i++) { \
49 mask[i] &= (ALPHA <= ref); \
54 for (i = 0; i < n; i++) { \
55 mask[i] &= (ALPHA >= ref); \
60 for (i = 0; i < n; i++) { \
61 mask[i] &= (ALPHA > ref); \
66 for (i = 0; i < n; i++) { \
67 mask[i] &= (ALPHA != ref); \
72 for (i = 0; i < n; i++) { \
73 mask[i] &= (ALPHA == ref); \
78 _mesa_problem(ctx, "Invalid alpha test in _swrast_alpha_test" ); \
86 * Perform the alpha test for an array of pixels.
87 * For pixels that fail the test, mask[i] will be set to 0.
88 * \return 0 if all pixels in the span failed the alpha test,
89 * 1 if one or more pixels passed the alpha test.
92 _swrast_alpha_test(const struct gl_context
*ctx
, SWspan
*span
)
94 const GLuint n
= span
->end
;
95 GLubyte
*mask
= span
->array
->mask
;
98 if (ctx
->Color
.AlphaFunc
== GL_ALWAYS
) {
102 else if (ctx
->Color
.AlphaFunc
== GL_NEVER
) {
103 /* All pixels failed - caller should check for this return value and
106 span
->writeAll
= GL_FALSE
;
110 if (span
->arrayMask
& SPAN_RGBA
) {
111 /* Use array's alpha values */
112 if (span
->array
->ChanType
== GL_UNSIGNED_BYTE
) {
113 GLubyte (*rgba
)[4] = span
->array
->rgba8
;
115 CLAMPED_FLOAT_TO_UBYTE(ref
, ctx
->Color
.AlphaRef
);
116 ALPHA_TEST(rgba
[i
][ACOMP
], ;);
118 else if (span
->array
->ChanType
== GL_UNSIGNED_SHORT
) {
119 GLushort (*rgba
)[4] = span
->array
->rgba16
;
121 CLAMPED_FLOAT_TO_USHORT(ref
, ctx
->Color
.AlphaRef
);
122 ALPHA_TEST(rgba
[i
][ACOMP
], ;);
125 GLfloat (*rgba
)[4] = span
->array
->attribs
[VARYING_SLOT_COL0
];
126 const GLfloat ref
= ctx
->Color
.AlphaRef
;
127 ALPHA_TEST(rgba
[i
][ACOMP
], ;);
131 /* Interpolate alpha values */
132 assert(span
->interpMask
& SPAN_RGBA
);
133 if (span
->array
->ChanType
== GL_UNSIGNED_BYTE
) {
134 const GLfixed alphaStep
= span
->alphaStep
;
135 GLfixed alpha
= span
->alpha
;
137 CLAMPED_FLOAT_TO_UBYTE(ref
, ctx
->Color
.AlphaRef
);
138 ALPHA_TEST(FixedToInt(alpha
), alpha
+= alphaStep
);
140 else if (span
->array
->ChanType
== GL_UNSIGNED_SHORT
) {
141 const GLfixed alphaStep
= span
->alphaStep
;
142 GLfixed alpha
= span
->alpha
;
144 CLAMPED_FLOAT_TO_USHORT(ref
, ctx
->Color
.AlphaRef
);
145 ALPHA_TEST(FixedToInt(alpha
), alpha
+= alphaStep
);
148 const GLfloat alphaStep
= FixedToFloat(span
->alphaStep
);
149 GLfloat alpha
= FixedToFloat(span
->alpha
);
150 const GLfloat ref
= ctx
->Color
.AlphaRef
;
151 ALPHA_TEST(alpha
, alpha
+= alphaStep
);
155 span
->writeAll
= GL_FALSE
;
157 /* XXX examine mask[] values? */