Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1901 serge 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)		\
40
do {						\
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
 */
92
GLint
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
}