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