/** * Clear the color buffer when glColorMask is in effect. */ static void clear_rgba_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb) { const GLint x = ctx->DrawBuffer->_Xmin; const GLint y = ctx->DrawBuffer->_Ymin; const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; GLchan clearColor[4]; GLint i; ASSERT(ctx->Visual.rgbMode); ASSERT(rb->PutRow); CLAMPED_FLOAT_TO_CHAN(clearColor[RCOMP], ctx->Color.ClearColor[0]); CLAMPED_FLOAT_TO_CHAN(clearColor[GCOMP], ctx->Color.ClearColor[1]); CLAMPED_FLOAT_TO_CHAN(clearColor[BCOMP], ctx->Color.ClearColor[2]); CLAMPED_FLOAT_TO_CHAN(clearColor[ACOMP], ctx->Color.ClearColor[3]); for (i = 0; i < height; i++) { GLchan rgba[MAX_WIDTH][4]; GLint j; for (j = 0; j < width; j++) { COPY_CHAN4(rgba[j], clearColor); } _swrast_mask_rgba_array( ctx, rb, width, x, y + i, rgba ); rb->PutRow(ctx, rb, width, x, y + i, rgba, NULL); } }
/** * Update swrast->_FogColor and swrast->_FogEnable values. */ static void _swrast_update_fog_state( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); /* convert fog color to GLchan values */ CLAMPED_FLOAT_TO_CHAN(swrast->_FogColor[RCOMP], ctx->Fog.Color[RCOMP]); CLAMPED_FLOAT_TO_CHAN(swrast->_FogColor[GCOMP], ctx->Fog.Color[GCOMP]); CLAMPED_FLOAT_TO_CHAN(swrast->_FogColor[BCOMP], ctx->Fog.Color[BCOMP]); /* determine if fog is needed, and if so, which fog mode */ swrast->_FogEnabled = GL_FALSE; if (ctx->FragmentProgram._Enabled) { if (ctx->FragmentProgram.Current->Base.Target==GL_FRAGMENT_PROGRAM_ARB) { const struct fragment_program *p = (struct fragment_program *) ctx->FragmentProgram.Current; if (p->FogOption != GL_NONE) { swrast->_FogEnabled = GL_TRUE; swrast->_FogMode = p->FogOption; } } } else if (ctx->Fog.Enabled) { swrast->_FogEnabled = GL_TRUE; swrast->_FogMode = ctx->Fog.Mode; } }
/** * Clear the color buffer when glColorMask is in effect. */ static void clear_rgba_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb) { const GLint x = ctx->DrawBuffer->_Xmin; const GLint y = ctx->DrawBuffer->_Ymin; const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; SWspan span; GLint i; ASSERT(ctx->Visual.rgbMode); ASSERT(rb->PutRow); /* Initialize color span with clear color */ /* XXX optimize for clearcolor == black/zero (bzero) */ INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_RGBA); span.array->ChanType = rb->DataType; if (span.array->ChanType == GL_UNSIGNED_BYTE) { GLubyte clearColor[4]; UNCLAMPED_FLOAT_TO_UBYTE(clearColor[RCOMP], ctx->Color.ClearColor[0]); UNCLAMPED_FLOAT_TO_UBYTE(clearColor[GCOMP], ctx->Color.ClearColor[1]); UNCLAMPED_FLOAT_TO_UBYTE(clearColor[BCOMP], ctx->Color.ClearColor[2]); UNCLAMPED_FLOAT_TO_UBYTE(clearColor[ACOMP], ctx->Color.ClearColor[3]); for (i = 0; i < width; i++) { COPY_4UBV(span.array->rgba[i], clearColor); } } else if (span.array->ChanType == GL_UNSIGNED_SHORT) { GLushort clearColor[4]; UNCLAMPED_FLOAT_TO_USHORT(clearColor[RCOMP], ctx->Color.ClearColor[0]); UNCLAMPED_FLOAT_TO_USHORT(clearColor[GCOMP], ctx->Color.ClearColor[1]); UNCLAMPED_FLOAT_TO_USHORT(clearColor[BCOMP], ctx->Color.ClearColor[2]); UNCLAMPED_FLOAT_TO_USHORT(clearColor[ACOMP], ctx->Color.ClearColor[3]); for (i = 0; i < width; i++) { COPY_4V(span.array->rgba[i], clearColor); } } else { ASSERT(span.array->ChanType == GL_FLOAT); for (i = 0; i < width; i++) { CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][0], ctx->Color.ClearColor[0]); CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][1], ctx->Color.ClearColor[1]); CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][2], ctx->Color.ClearColor[2]); CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][3], ctx->Color.ClearColor[3]); } } /* Note that masking will change the color values, but only the * channels for which the write mask is GL_FALSE. The channels * which which are write-enabled won't get modified. */ for (i = 0; i < height; i++) { span.x = x; span.y = y + i; _swrast_mask_rgba_span(ctx, rb, &span); /* write masked row */ rb->PutRow(ctx, rb, width, x, y + i, span.array->rgba, NULL); } }
void MesaDriver::ClearColor(GLcontext *ctx, const GLfloat color[4]) { MesaDriver *md = (MesaDriver *) ctx->DriverCtx; CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_RCOMP], color[0]); CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_GCOMP], color[1]); CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_BCOMP], color[2]); CLAMPED_FLOAT_TO_CHAN(md->m_clear_color[BE_ACOMP], color[3]); assert(md->m_bglview); }
/* * Clear the color buffer when glColorMask or glIndexMask is in effect. */ static void clear_color_buffer_with_masking( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLint x = ctx->DrawBuffer->_Xmin; const GLint y = ctx->DrawBuffer->_Ymin; const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; if (ctx->Visual.rgbMode) { /* RGBA mode */ GLchan clearColor[4]; GLint i; CLAMPED_FLOAT_TO_CHAN(clearColor[RCOMP], ctx->Color.ClearColor[0]); CLAMPED_FLOAT_TO_CHAN(clearColor[GCOMP], ctx->Color.ClearColor[1]); CLAMPED_FLOAT_TO_CHAN(clearColor[BCOMP], ctx->Color.ClearColor[2]); CLAMPED_FLOAT_TO_CHAN(clearColor[ACOMP], ctx->Color.ClearColor[3]); for (i = 0; i < height; i++) { GLchan rgba[MAX_WIDTH][4]; GLint j; for (j = 0; j < width; j++) { COPY_CHAN4(rgba[j], clearColor); } _swrast_mask_rgba_array( ctx, width, x, y + i, rgba ); (*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i, (CONST GLchan (*)[4]) rgba, NULL ); } } else { /* Color index mode */ GLuint span[MAX_WIDTH]; GLubyte mask[MAX_WIDTH]; GLint i, j; MEMSET( mask, 1, width ); for (i=0;i<height;i++) { for (j=0;j<width;j++) { span[j] = ctx->Color.ClearIndex; } _swrast_mask_index_array( ctx, width, x, y + i, span ); (*swrast->Driver.WriteCI32Span)( ctx, width, x, y + i, span, mask ); } } }
/* * Clear a color buffer without index/channel masking. */ static void clear_color_buffer(GLcontext *ctx) { SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLint x = ctx->DrawBuffer->_Xmin; const GLint y = ctx->DrawBuffer->_Ymin; const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; if (ctx->Visual.rgbMode) { /* RGBA mode */ GLchan clearColor[4]; GLint i; CLAMPED_FLOAT_TO_CHAN(clearColor[RCOMP], ctx->Color.ClearColor[0]); CLAMPED_FLOAT_TO_CHAN(clearColor[GCOMP], ctx->Color.ClearColor[1]); CLAMPED_FLOAT_TO_CHAN(clearColor[BCOMP], ctx->Color.ClearColor[2]); CLAMPED_FLOAT_TO_CHAN(clearColor[ACOMP], ctx->Color.ClearColor[3]); ASSERT(*((GLuint *) &ctx->Color.ColorMask) == 0xffffffff); ASSERT(swrast->Driver.WriteRGBASpan); for (i = 0; i < height; i++) { (*swrast->Driver.WriteMonoRGBASpan)( ctx, width, x, y + i, clearColor, NULL ); } } else { /* Color index mode */ GLint i; ASSERT((ctx->Color.IndexMask & ((1 << ctx->Visual.indexBits) - 1)) == (GLuint) ((1 << ctx->Visual.indexBits) - 1)); ASSERT(swrast->Driver.WriteMonoCISpan); for (i = 0; i < height; i++) { (*swrast->Driver.WriteMonoCISpan)( ctx, width, x, y + i, ctx->Color.ClearIndex, NULL); } } }
/** * \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; }