Example #1
0
/**
 * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16)
 * color array.
 */
static inline void
interpolate_int_colors(struct gl_context *ctx, SWspan *span)
{
#if CHAN_BITS != 32
   const GLuint n = span->end;
   GLuint i;

   ASSERT(!(span->arrayMask & SPAN_RGBA));
#endif

   switch (span->array->ChanType) {
#if CHAN_BITS != 32
   case GL_UNSIGNED_BYTE:
      {
         GLubyte (*rgba)[4] = span->array->rgba8;
         if (span->interpMask & SPAN_FLAT) {
            GLubyte color[4];
            color[RCOMP] = FixedToInt(span->red);
            color[GCOMP] = FixedToInt(span->green);
            color[BCOMP] = FixedToInt(span->blue);
            color[ACOMP] = FixedToInt(span->alpha);
            for (i = 0; i < n; i++) {
               COPY_4UBV(rgba[i], color);
            }
         }
         else {
            GLfixed r = span->red;
            GLfixed g = span->green;
            GLfixed b = span->blue;
            GLfixed a = span->alpha;
            GLint dr = span->redStep;
            GLint dg = span->greenStep;
            GLint db = span->blueStep;
            GLint da = span->alphaStep;
            for (i = 0; i < n; i++) {
               rgba[i][RCOMP] = FixedToChan(r);
               rgba[i][GCOMP] = FixedToChan(g);
               rgba[i][BCOMP] = FixedToChan(b);
               rgba[i][ACOMP] = FixedToChan(a);
               r += dr;
               g += dg;
               b += db;
               a += da;
            }
         }
      }
      break;
   case GL_UNSIGNED_SHORT:
      {
         GLushort (*rgba)[4] = span->array->rgba16;
         if (span->interpMask & SPAN_FLAT) {
            GLushort color[4];
            color[RCOMP] = FixedToInt(span->red);
            color[GCOMP] = FixedToInt(span->green);
            color[BCOMP] = FixedToInt(span->blue);
            color[ACOMP] = FixedToInt(span->alpha);
            for (i = 0; i < n; i++) {
               COPY_4V(rgba[i], color);
            }
         }
         else {
            GLushort (*rgba)[4] = span->array->rgba16;
            GLfixed r, g, b, a;
            GLint dr, dg, db, da;
            r = span->red;
            g = span->green;
            b = span->blue;
            a = span->alpha;
            dr = span->redStep;
            dg = span->greenStep;
            db = span->blueStep;
            da = span->alphaStep;
            for (i = 0; i < n; i++) {
               rgba[i][RCOMP] = FixedToChan(r);
               rgba[i][GCOMP] = FixedToChan(g);
               rgba[i][BCOMP] = FixedToChan(b);
               rgba[i][ACOMP] = FixedToChan(a);
               r += dr;
               g += dg;
               b += db;
               a += da;
            }
         }
      }
      break;
#endif
   case GL_FLOAT:
      interpolate_active_attribs(ctx, span, FRAG_BIT_COL);
      break;
   default:
      _mesa_problem(ctx, "bad datatype 0x%x in interpolate_int_colors",
                    span->array->ChanType);
   }
   span->arrayMask |= SPAN_RGBA;
}
Example #2
0
/**
 * \fn GLint _swrast_alpha_test( const GLcontext *ctx, struct sw_span *span )
 * \brief Apply the alpha test to a span of pixels.
 * \return
 *      - "0" = all pixels in the span failed the alpha test.
 *      - "1" = one or more pixels passed the alpha test.
 */
GLint
_swrast_alpha_test( const GLcontext *ctx, struct sw_span *span )
{
   const GLchan (*rgba)[4] = (const GLchan (*)[4]) span->array->rgba;
   GLchan ref;
   const GLuint n = span->end;
   GLubyte *mask = span->array->mask;
   GLuint i;

   CLAMPED_FLOAT_TO_CHAN(ref, ctx->Color.AlphaRef);

   if (span->arrayMask & SPAN_RGBA) {
      /* Use the array values */
      switch (ctx->Color.AlphaFunc) {
         case GL_LESS:
            for (i = 0; i < n; i++)
               mask[i] &= (rgba[i][ACOMP] < ref);
            break;
         case GL_LEQUAL:
            for (i = 0; i < n; i++)
               mask[i] &= (rgba[i][ACOMP] <= ref);
            break;
         case GL_GEQUAL:
            for (i = 0; i < n; i++)
               mask[i] &= (rgba[i][ACOMP] >= ref);
            break;
         case GL_GREATER:
            for (i = 0; i < n; i++)
               mask[i] &= (rgba[i][ACOMP] > ref);
            break;
         case GL_NOTEQUAL:
            for (i = 0; i < n; i++)
               mask[i] &= (rgba[i][ACOMP] != ref);
            break;
         case GL_EQUAL:
            for (i = 0; i < n; i++)
               mask[i] &= (rgba[i][ACOMP] == ref);
            break;
         case GL_ALWAYS:
            /* do nothing */
            return 1;
         case GL_NEVER:
            /* caller should check for zero! */
            span->writeAll = GL_FALSE;
            return 0;
         default:
            _mesa_problem( ctx, "Invalid alpha test in _swrast_alpha_test" );
            return 0;
      }
   }
   else {
      /* Use the interpolation values */
#if CHAN_TYPE == GL_FLOAT
      const GLfloat alphaStep = span->alphaStep;
      GLfloat alpha = span->alpha;
      ASSERT(span->interpMask & SPAN_RGBA);
      switch (ctx->Color.AlphaFunc) {
         case GL_LESS:
            for (i = 0; i < n; i++) {
               mask[i] &= (alpha < ref);
               alpha += alphaStep;
            }
            break;
         case GL_LEQUAL:
            for (i = 0; i < n; i++) {
               mask[i] &= (alpha <= ref);
               alpha += alphaStep;
            }
            break;
         case GL_GEQUAL:
            for (i = 0; i < n; i++) {
               mask[i] &= (alpha >= ref);
               alpha += alphaStep;
            }
            break;
         case GL_GREATER:
            for (i = 0; i < n; i++) {
               mask[i] &= (alpha > ref);
               alpha += alphaStep;
            }
            break;
         case GL_NOTEQUAL:
            for (i = 0; i < n; i++) {
               mask[i] &= (alpha != ref);
               alpha += alphaStep;
            }
            break;
         case GL_EQUAL:
            for (i = 0; i < n; i++) {
               mask[i] &= (alpha == ref);
               alpha += alphaStep;
            }
            break;
         case GL_ALWAYS:
            /* do nothing */
            return 1;
         case GL_NEVER:
            /* caller should check for zero! */
            span->writeAll = GL_FALSE;
            return 0;
         default:
            _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
            return 0;
      }
#else
      /* 8 or 16-bit channel interpolation */
      const GLfixed alphaStep = span->alphaStep;
      GLfixed alpha = span->alpha;
      ASSERT(span->interpMask & SPAN_RGBA);
      switch (ctx->Color.AlphaFunc) {
         case GL_LESS:
            for (i = 0; i < n; i++) {
               mask[i] &= (FixedToChan(alpha) < ref);
               alpha += alphaStep;
            }
            break;
         case GL_LEQUAL:
            for (i = 0; i < n; i++) {
               mask[i] &= (FixedToChan(alpha) <= ref);
               alpha += alphaStep;
            }
            break;
         case GL_GEQUAL:
            for (i = 0; i < n; i++) {
               mask[i] &= (FixedToChan(alpha) >= ref);
               alpha += alphaStep;
            }
            break;
         case GL_GREATER:
            for (i = 0; i < n; i++) {
               mask[i] &= (FixedToChan(alpha) > ref);
               alpha += alphaStep;
            }
            break;
         case GL_NOTEQUAL:
            for (i = 0; i < n; i++) {
               mask[i] &= (FixedToChan(alpha) != ref);
               alpha += alphaStep;
            }
            break;
         case GL_EQUAL:
            for (i = 0; i < n; i++) {
               mask[i] &= (FixedToChan(alpha) == ref);
               alpha += alphaStep;
            }
            break;
         case GL_ALWAYS:
            /* do nothing */
            return 1;
         case GL_NEVER:
            /* caller should check for zero! */
            span->writeAll = GL_FALSE;
            return 0;
         default:
            _mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
            return 0;
      }
#endif /* CHAN_TYPE */
   }

#if 0
   /* XXXX This causes conformance failures!!!! */
   while ((span->start <= span->end)  &&
          (mask[span->start] == 0))
     span->start ++;

   while ((span->end >= span->start)  &&
          (mask[span->end] == 0))
     span->end --;
#endif

   span->writeAll = GL_FALSE;

   if (span->start >= span->end)
     return 0;
   else
     return 1;
}