~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

Viewing changes to src/mesa/swrast/s_alpha.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
1
/*
3
2
 * Mesa 3-D graphics library
4
 
 * Version:  4.1
 
3
 * Version:  6.5.2
5
4
 *
6
 
 * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
 
5
 * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
7
6
 *
8
7
 * Permission is hereby granted, free of charge, to any person obtaining a
9
8
 * copy of this software and associated documentation files (the "Software"),
37
36
#include "s_context.h"
38
37
 
39
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
 
40
86
/**
41
 
 * \fn GLint _swrast_alpha_test( const GLcontext *ctx, struct sw_span *span )
42
 
 * \brief Apply the alpha test to a span of pixels.
43
 
 * \return
44
 
 *      - "0" = all pixels in the span failed the alpha test.
45
 
 *      - "1" = one or more pixels passed the alpha test.
 
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.
46
91
 */
47
92
GLint
48
 
_swrast_alpha_test( const GLcontext *ctx, struct sw_span *span )
 
93
_swrast_alpha_test(const GLcontext *ctx, SWspan *span)
49
94
{
50
 
   const GLchan (*rgba)[4] = (const GLchan (*)[4]) span->array->rgba;
51
 
   GLchan ref;
52
95
   const GLuint n = span->end;
53
96
   GLubyte *mask = span->array->mask;
54
97
   GLuint i;
55
98
 
56
 
   CLAMPED_FLOAT_TO_CHAN(ref, ctx->Color.AlphaRef);
 
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
   }
57
110
 
58
111
   if (span->arrayMask & SPAN_RGBA) {
59
 
      /* Use the array values */
60
 
      switch (ctx->Color.AlphaFunc) {
61
 
         case GL_LESS:
62
 
            for (i = 0; i < n; i++)
63
 
               mask[i] &= (rgba[i][ACOMP] < ref);
64
 
            break;
65
 
         case GL_LEQUAL:
66
 
            for (i = 0; i < n; i++)
67
 
               mask[i] &= (rgba[i][ACOMP] <= ref);
68
 
            break;
69
 
         case GL_GEQUAL:
70
 
            for (i = 0; i < n; i++)
71
 
               mask[i] &= (rgba[i][ACOMP] >= ref);
72
 
            break;
73
 
         case GL_GREATER:
74
 
            for (i = 0; i < n; i++)
75
 
               mask[i] &= (rgba[i][ACOMP] > ref);
76
 
            break;
77
 
         case GL_NOTEQUAL:
78
 
            for (i = 0; i < n; i++)
79
 
               mask[i] &= (rgba[i][ACOMP] != ref);
80
 
            break;
81
 
         case GL_EQUAL:
82
 
            for (i = 0; i < n; i++)
83
 
               mask[i] &= (rgba[i][ACOMP] == ref);
84
 
            break;
85
 
         case GL_ALWAYS:
86
 
            /* do nothing */
87
 
            return 1;
88
 
         case GL_NEVER:
89
 
            /* caller should check for zero! */
90
 
            span->writeAll = GL_FALSE;
91
 
            return 0;
92
 
         default:
93
 
            _mesa_problem( ctx, "Invalid alpha test in _swrast_alpha_test" );
94
 
            return 0;
 
112
      /* Use array's alpha values */
 
113
      if (span->array->ChanType == GL_UNSIGNED_BYTE) {
 
114
         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
 
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->color.sz2.rgba;
 
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->color.sz4.rgba;
 
127
         const GLfloat ref = ctx->Color.AlphaRef;
 
128
         ALPHA_TEST(rgba[i][ACOMP], ;);
95
129
      }
96
130
   }
97
131
   else {
98
 
      /* Use the interpolation values */
99
 
#if CHAN_TYPE == GL_FLOAT
100
 
      const GLfloat alphaStep = span->alphaStep;
101
 
      GLfloat alpha = span->alpha;
102
 
      ASSERT(span->interpMask & SPAN_RGBA);
103
 
      switch (ctx->Color.AlphaFunc) {
104
 
         case GL_LESS:
105
 
            for (i = 0; i < n; i++) {
106
 
               mask[i] &= (alpha < ref);
107
 
               alpha += alphaStep;
108
 
            }
109
 
            break;
110
 
         case GL_LEQUAL:
111
 
            for (i = 0; i < n; i++) {
112
 
               mask[i] &= (alpha <= ref);
113
 
               alpha += alphaStep;
114
 
            }
115
 
            break;
116
 
         case GL_GEQUAL:
117
 
            for (i = 0; i < n; i++) {
118
 
               mask[i] &= (alpha >= ref);
119
 
               alpha += alphaStep;
120
 
            }
121
 
            break;
122
 
         case GL_GREATER:
123
 
            for (i = 0; i < n; i++) {
124
 
               mask[i] &= (alpha > ref);
125
 
               alpha += alphaStep;
126
 
            }
127
 
            break;
128
 
         case GL_NOTEQUAL:
129
 
            for (i = 0; i < n; i++) {
130
 
               mask[i] &= (alpha != ref);
131
 
               alpha += alphaStep;
132
 
            }
133
 
            break;
134
 
         case GL_EQUAL:
135
 
            for (i = 0; i < n; i++) {
136
 
               mask[i] &= (alpha == ref);
137
 
               alpha += alphaStep;
138
 
            }
139
 
            break;
140
 
         case GL_ALWAYS:
141
 
            /* do nothing */
142
 
            return 1;
143
 
         case GL_NEVER:
144
 
            /* caller should check for zero! */
145
 
            span->writeAll = GL_FALSE;
146
 
            return 0;
147
 
         default:
148
 
            _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
149
 
            return 0;
150
 
      }
151
 
#else
152
 
      /* 8 or 16-bit channel interpolation */
153
 
      const GLfixed alphaStep = span->alphaStep;
154
 
      GLfixed alpha = span->alpha;
155
 
      ASSERT(span->interpMask & SPAN_RGBA);
156
 
      switch (ctx->Color.AlphaFunc) {
157
 
         case GL_LESS:
158
 
            for (i = 0; i < n; i++) {
159
 
               mask[i] &= (FixedToChan(alpha) < ref);
160
 
               alpha += alphaStep;
161
 
            }
162
 
            break;
163
 
         case GL_LEQUAL:
164
 
            for (i = 0; i < n; i++) {
165
 
               mask[i] &= (FixedToChan(alpha) <= ref);
166
 
               alpha += alphaStep;
167
 
            }
168
 
            break;
169
 
         case GL_GEQUAL:
170
 
            for (i = 0; i < n; i++) {
171
 
               mask[i] &= (FixedToChan(alpha) >= ref);
172
 
               alpha += alphaStep;
173
 
            }
174
 
            break;
175
 
         case GL_GREATER:
176
 
            for (i = 0; i < n; i++) {
177
 
               mask[i] &= (FixedToChan(alpha) > ref);
178
 
               alpha += alphaStep;
179
 
            }
180
 
            break;
181
 
         case GL_NOTEQUAL:
182
 
            for (i = 0; i < n; i++) {
183
 
               mask[i] &= (FixedToChan(alpha) != ref);
184
 
               alpha += alphaStep;
185
 
            }
186
 
            break;
187
 
         case GL_EQUAL:
188
 
            for (i = 0; i < n; i++) {
189
 
               mask[i] &= (FixedToChan(alpha) == ref);
190
 
               alpha += alphaStep;
191
 
            }
192
 
            break;
193
 
         case GL_ALWAYS:
194
 
            /* do nothing */
195
 
            return 1;
196
 
         case GL_NEVER:
197
 
            /* caller should check for zero! */
198
 
            span->writeAll = GL_FALSE;
199
 
            return 0;
200
 
         default:
201
 
            _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
202
 
            return 0;
203
 
      }
204
 
#endif /* CHAN_TYPE */
 
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 = span->alphaStep;
 
150
         GLfloat alpha = span->alpha;
 
151
         const GLfloat ref = ctx->Color.AlphaRef;
 
152
         ALPHA_TEST(alpha, alpha += alphaStep);
 
153
      }
205
154
   }
206
155
 
207
 
#if 0
208
 
   /* XXXX This causes conformance failures!!!! */
209
 
   while ((span->start <= span->end)  &&
210
 
          (mask[span->start] == 0))
211
 
     span->start ++;
212
 
 
213
 
   while ((span->end >= span->start)  &&
214
 
          (mask[span->end] == 0))
215
 
     span->end --;
216
 
#endif
217
 
 
218
156
   span->writeAll = GL_FALSE;
219
157
 
220
 
   if (span->start >= span->end)
221
 
     return 0;
222
 
   else
223
 
     return 1;
 
158
   /* XXX examine mask[] values? */
 
159
   return 1;
224
160
}