1/* 2 * Mesa 3-D graphics library 3 * Version: 6.5.2 4 * 5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/** 26 * \file swrast/s_alpha.c 27 * \brief Functions to apply alpha test. 28 */ 29 30#include "main/glheader.h" 31#include "main/context.h" 32#include "main/colormac.h" 33#include "main/macros.h" 34 35#include "s_alpha.h" 36#include "s_context.h" 37 38 39#define ALPHA_TEST(ALPHA, LOOP_CODE) \ 40do { \ 41 switch (ctx->Color.AlphaFunc) { \ 42 case GL_LESS: \ 43 for (i = 0; i < n; i++) { \ 44 mask[i] &= (ALPHA < ref); \ 45 LOOP_CODE; \ 46 } \ 47 break; \ 48 case GL_LEQUAL: \ 49 for (i = 0; i < n; i++) { \ 50 mask[i] &= (ALPHA <= ref); \ 51 LOOP_CODE; \ 52 } \ 53 break; \ 54 case GL_GEQUAL: \ 55 for (i = 0; i < n; i++) { \ 56 mask[i] &= (ALPHA >= ref); \ 57 LOOP_CODE; \ 58 } \ 59 break; \ 60 case GL_GREATER: \ 61 for (i = 0; i < n; i++) { \ 62 mask[i] &= (ALPHA > ref); \ 63 LOOP_CODE; \ 64 } \ 65 break; \ 66 case GL_NOTEQUAL: \ 67 for (i = 0; i < n; i++) { \ 68 mask[i] &= (ALPHA != ref); \ 69 LOOP_CODE; \ 70 } \ 71 break; \ 72 case GL_EQUAL: \ 73 for (i = 0; i < n; i++) { \ 74 mask[i] &= (ALPHA == ref); \ 75 LOOP_CODE; \ 76 } \ 77 break; \ 78 default: \ 79 _mesa_problem(ctx, "Invalid alpha test in _swrast_alpha_test" ); \ 80 return 0; \ 81 } \ 82} while (0) 83 84 85 86/** 87 * Perform the alpha test for an array of pixels. 88 * For pixels that fail the test, mask[i] will be set to 0. 89 * \return 0 if all pixels in the span failed the alpha test, 90 * 1 if one or more pixels passed the alpha test. 91 */ 92GLint 93_swrast_alpha_test(const struct gl_context *ctx, SWspan *span) 94{ 95 const GLuint n = span->end; 96 GLubyte *mask = span->array->mask; 97 GLuint i; 98 99 if (ctx->Color.AlphaFunc == GL_ALWAYS) { 100 /* do nothing */ 101 return 1; 102 } 103 else if (ctx->Color.AlphaFunc == GL_NEVER) { 104 /* All pixels failed - caller should check for this return value and 105 * act accordingly. 106 */ 107 span->writeAll = GL_FALSE; 108 return 0; 109 } 110 111 if (span->arrayMask & SPAN_RGBA) { 112 /* Use array's alpha values */ 113 if (span->array->ChanType == GL_UNSIGNED_BYTE) { 114 GLubyte (*rgba)[4] = span->array->rgba8; 115 GLubyte ref; 116 CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef); 117 ALPHA_TEST(rgba[i][ACOMP], ;); 118 } 119 else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 120 GLushort (*rgba)[4] = span->array->rgba16; 121 GLushort ref; 122 CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef); 123 ALPHA_TEST(rgba[i][ACOMP], ;); 124 } 125 else { 126 GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 127 const GLfloat ref = ctx->Color.AlphaRef; 128 ALPHA_TEST(rgba[i][ACOMP], ;); 129 } 130 } 131 else { 132 /* Interpolate alpha values */ 133 ASSERT(span->interpMask & SPAN_RGBA); 134 if (span->array->ChanType == GL_UNSIGNED_BYTE) { 135 const GLfixed alphaStep = span->alphaStep; 136 GLfixed alpha = span->alpha; 137 GLubyte ref; 138 CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef); 139 ALPHA_TEST(FixedToInt(alpha), alpha += alphaStep); 140 } 141 else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 142 const GLfixed alphaStep = span->alphaStep; 143 GLfixed alpha = span->alpha; 144 GLushort ref; 145 CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef); 146 ALPHA_TEST(FixedToInt(alpha), alpha += alphaStep); 147 } 148 else { 149 const GLfloat alphaStep = FixedToFloat(span->alphaStep); 150 GLfloat alpha = FixedToFloat(span->alpha); 151 const GLfloat ref = ctx->Color.AlphaRef; 152 ALPHA_TEST(alpha, alpha += alphaStep); 153 } 154 } 155 156 span->writeAll = GL_FALSE; 157 158 /* XXX examine mask[] values? */ 159 return 1; 160} 161