/** * 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; }
/** * \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; }