s_blend.c
来自「mesa-6.5-minigui源码」· C语言 代码 · 共 873 行 · 第 1/2 页
C
873 行
sR = 1.0F - (GLfloat) Rs * rscale; sG = 1.0F - (GLfloat) Gs * gscale; sB = 1.0F - (GLfloat) Bs * bscale; break; default: /* this should never happen */ _mesa_problem(ctx, "Bad blend source RGB factor in do_blend"); return; } /* Source Alpha factor */ switch (ctx->Color.BlendSrcA) { case GL_ZERO: sA = 0.0F; break; case GL_ONE: sA = 1.0F; break; case GL_DST_COLOR: sA = (GLfloat) Ad * ascale; break; case GL_ONE_MINUS_DST_COLOR: sA = 1.0F - (GLfloat) Ad * ascale; break; case GL_SRC_ALPHA: sA = (GLfloat) As * ascale; break; case GL_ONE_MINUS_SRC_ALPHA: sA = 1.0F - (GLfloat) As * ascale; break; case GL_DST_ALPHA: sA =(GLfloat) Ad * ascale; break; case GL_ONE_MINUS_DST_ALPHA: sA = 1.0F - (GLfloat) Ad * ascale; break; case GL_SRC_ALPHA_SATURATE: sA = 1.0; break; case GL_CONSTANT_COLOR: sA = ctx->Color.BlendColor[3]; break; case GL_ONE_MINUS_CONSTANT_COLOR: sA = 1.0F - ctx->Color.BlendColor[3]; break; case GL_CONSTANT_ALPHA: sA = ctx->Color.BlendColor[3]; break; case GL_ONE_MINUS_CONSTANT_ALPHA: sA = 1.0F - ctx->Color.BlendColor[3]; break; case GL_SRC_COLOR: /* GL_NV_blend_square */ sA = (GLfloat) As * ascale; break; case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */ sA = 1.0F - (GLfloat) As * ascale; break; default: /* this should never happen */ sA = 0.0F; _mesa_problem(ctx, "Bad blend source A factor in do_blend"); } /* Dest RGB factor */ switch (ctx->Color.BlendDstRGB) { case GL_ZERO: dR = dG = dB = 0.0F; break; case GL_ONE: dR = dG = dB = 1.0F; break; case GL_SRC_COLOR: dR = (GLfloat) Rs * rscale; dG = (GLfloat) Gs * gscale; dB = (GLfloat) Bs * bscale; break; case GL_ONE_MINUS_SRC_COLOR: dR = 1.0F - (GLfloat) Rs * rscale; dG = 1.0F - (GLfloat) Gs * gscale; dB = 1.0F - (GLfloat) Bs * bscale; break; case GL_SRC_ALPHA: dR = dG = dB = (GLfloat) As * ascale; break; case GL_ONE_MINUS_SRC_ALPHA: dR = dG = dB = 1.0F - (GLfloat) As * ascale; break; case GL_DST_ALPHA: dR = dG = dB = (GLfloat) Ad * ascale; break; case GL_ONE_MINUS_DST_ALPHA: dR = dG = dB = 1.0F - (GLfloat) Ad * ascale; break; case GL_CONSTANT_COLOR: dR = ctx->Color.BlendColor[0]; dG = ctx->Color.BlendColor[1]; dB = ctx->Color.BlendColor[2]; break; case GL_ONE_MINUS_CONSTANT_COLOR: dR = 1.0F - ctx->Color.BlendColor[0]; dG = 1.0F - ctx->Color.BlendColor[1]; dB = 1.0F - ctx->Color.BlendColor[2]; break; case GL_CONSTANT_ALPHA: dR = dG = dB = ctx->Color.BlendColor[3]; break; case GL_ONE_MINUS_CONSTANT_ALPHA: dR = dG = dB = 1.0F - ctx->Color.BlendColor[3]; break; case GL_DST_COLOR: /* GL_NV_blend_square */ dR = (GLfloat) Rd * rscale; dG = (GLfloat) Gd * gscale; dB = (GLfloat) Bd * bscale; break; case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */ dR = 1.0F - (GLfloat) Rd * rscale; dG = 1.0F - (GLfloat) Gd * gscale; dB = 1.0F - (GLfloat) Bd * bscale; break; default: /* this should never happen */ dR = dG = dB = 0.0F; _mesa_problem(ctx, "Bad blend dest RGB factor in do_blend"); } /* Dest Alpha factor */ switch (ctx->Color.BlendDstA) { case GL_ZERO: dA = 0.0F; break; case GL_ONE: dA = 1.0F; break; case GL_SRC_COLOR: dA = (GLfloat) As * ascale; break; case GL_ONE_MINUS_SRC_COLOR: dA = 1.0F - (GLfloat) As * ascale; break; case GL_SRC_ALPHA: dA = (GLfloat) As * ascale; break; case GL_ONE_MINUS_SRC_ALPHA: dA = 1.0F - (GLfloat) As * ascale; break; case GL_DST_ALPHA: dA = (GLfloat) Ad * ascale; break; case GL_ONE_MINUS_DST_ALPHA: dA = 1.0F - (GLfloat) Ad * ascale; break; case GL_CONSTANT_COLOR: dA = ctx->Color.BlendColor[3]; break; case GL_ONE_MINUS_CONSTANT_COLOR: dA = 1.0F - ctx->Color.BlendColor[3]; break; case GL_CONSTANT_ALPHA: dA = ctx->Color.BlendColor[3]; break; case GL_ONE_MINUS_CONSTANT_ALPHA: dA = 1.0F - ctx->Color.BlendColor[3]; break; case GL_DST_COLOR: /* GL_NV_blend_square */ dA = (GLfloat) Ad * ascale; break; case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */ dA = 1.0F - (GLfloat) Ad * ascale; break; default: /* this should never happen */ dA = 0.0F; _mesa_problem(ctx, "Bad blend dest A factor in do_blend"); return; } /* Due to round-off problems we have to clamp against zero. */ /* Optimization: we don't have to do this for all src & dst factors */ if (dA < 0.0F) dA = 0.0F; if (dR < 0.0F) dR = 0.0F; if (dG < 0.0F) dG = 0.0F; if (dB < 0.0F) dB = 0.0F; if (sA < 0.0F) sA = 0.0F; if (sR < 0.0F) sR = 0.0F; if (sG < 0.0F) sG = 0.0F; if (sB < 0.0F) sB = 0.0F; ASSERT( sR <= 1.0 ); ASSERT( sG <= 1.0 ); ASSERT( sB <= 1.0 ); ASSERT( sA <= 1.0 ); ASSERT( dR <= 1.0 ); ASSERT( dG <= 1.0 ); ASSERT( dB <= 1.0 ); ASSERT( dA <= 1.0 ); /* compute blended color */#if CHAN_TYPE == GL_FLOAT if (ctx->Color.BlendEquationRGB==GL_FUNC_ADD) { r = Rs * sR + Rd * dR; g = Gs * sG + Gd * dG; b = Bs * sB + Bd * dB; a = As * sA + Ad * dA; } else if (ctx->Color.BlendEquationRGB==GL_FUNC_SUBTRACT) { r = Rs * sR - Rd * dR; g = Gs * sG - Gd * dG; b = Bs * sB - Bd * dB; a = As * sA - Ad * dA; } else if (ctx->Color.BlendEquationRGB==GL_FUNC_REVERSE_SUBTRACT) { r = Rd * dR - Rs * sR; g = Gd * dG - Gs * sG; b = Bd * dB - Bs * sB; a = Ad * dA - As * sA; } else if (ctx->Color.BlendEquationRGB==GL_MIN) { r = MIN2( Rd, Rs ); g = MIN2( Gd, Gs ); b = MIN2( Bd, Bs ); } else if (ctx->Color.BlendEquationRGB==GL_MAX) { r = MAX2( Rd, Rs ); g = MAX2( Gd, Gs ); b = MAX2( Bd, Bs ); } else { /* should never get here */ r = g = b = 0.0F; /* silence uninitialized var warning */ _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); } if (ctx->Color.BlendEquationA==GL_FUNC_ADD) { a = As * sA + Ad * dA; } else if (ctx->Color.BlendEquationA==GL_FUNC_SUBTRACT) { a = As * sA - Ad * dA; } else if (ctx->Color.BlendEquationA==GL_FUNC_REVERSE_SUBTRACT) { a = Ad * dA - As * sA; } else if (ctx->Color.BlendEquationA==GL_MIN) { a = MIN2( Ad, As ); } else if (ctx->Color.BlendEquationA==GL_MAX) { a = MAX2( Ad, As ); } else { /* should never get here */ a = 0.0F; /* silence uninitialized var warning */ _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); } /* final clamping */ rgba[i][RCOMP] = MAX2( r, 0.0F ); rgba[i][GCOMP] = MAX2( g, 0.0F ); rgba[i][BCOMP] = MAX2( b, 0.0F ); rgba[i][ACOMP] = CLAMP( a, 0.0F, CHAN_MAXF );#else if (ctx->Color.BlendEquationRGB==GL_FUNC_ADD) { r = Rs * sR + Rd * dR + 0.5F; g = Gs * sG + Gd * dG + 0.5F; b = Bs * sB + Bd * dB + 0.5F; } else if (ctx->Color.BlendEquationRGB==GL_FUNC_SUBTRACT) { r = Rs * sR - Rd * dR + 0.5F; g = Gs * sG - Gd * dG + 0.5F; b = Bs * sB - Bd * dB + 0.5F; } else if (ctx->Color.BlendEquationRGB==GL_FUNC_REVERSE_SUBTRACT) { r = Rd * dR - Rs * sR + 0.5F; g = Gd * dG - Gs * sG + 0.5F; b = Bd * dB - Bs * sB + 0.5F; } else if (ctx->Color.BlendEquationRGB==GL_MIN) { r = MIN2( Rd, Rs ); g = MIN2( Gd, Gs ); b = MIN2( Bd, Bs ); } else if (ctx->Color.BlendEquationRGB==GL_MAX) { r = MAX2( Rd, Rs ); g = MAX2( Gd, Gs ); b = MAX2( Bd, Bs ); } else { /* should never get here */ r = g = b = 0.0F; /* silence uninitialized var warning */ _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); } if (ctx->Color.BlendEquationA==GL_FUNC_ADD) { a = As * sA + Ad * dA + 0.5F; } else if (ctx->Color.BlendEquationA==GL_FUNC_SUBTRACT) { a = As * sA - Ad * dA + 0.5F; } else if (ctx->Color.BlendEquationA==GL_FUNC_REVERSE_SUBTRACT) { a = Ad * dA - As * sA + 0.5F; } else if (ctx->Color.BlendEquationA==GL_MIN) { a = MIN2( Ad, As ); } else if (ctx->Color.BlendEquationA==GL_MAX) { a = MAX2( Ad, As ); } else { /* should never get here */ a = 0.0F; /* silence uninitialized var warning */ _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); } /* final clamping */ rgba[i][RCOMP] = (GLchan) (GLint) CLAMP( r, 0.0F, CHAN_MAXF ); rgba[i][GCOMP] = (GLchan) (GLint) CLAMP( g, 0.0F, CHAN_MAXF ); rgba[i][BCOMP] = (GLchan) (GLint) CLAMP( b, 0.0F, CHAN_MAXF ); rgba[i][ACOMP] = (GLchan) (GLint) CLAMP( a, 0.0F, CHAN_MAXF );#endif } }}/* * Analyze current blending parameters to pick fastest blending function. * Result: the ctx->Color.BlendFunc pointer is updated. */void _swrast_choose_blend_func( GLcontext *ctx ){ const GLenum eq = ctx->Color.BlendEquationRGB; const GLenum srcRGB = ctx->Color.BlendSrcRGB; const GLenum dstRGB = ctx->Color.BlendDstRGB; const GLenum srcA = ctx->Color.BlendSrcA; const GLenum dstA = ctx->Color.BlendDstA; if (ctx->Color.BlendEquationRGB != ctx->Color.BlendEquationA) { SWRAST_CONTEXT(ctx)->BlendFunc = blend_general; } else if (eq==GL_MIN) { /* Note: GL_MIN ignores the blending weight factors */#if defined(USE_MMX_ASM) if ( cpu_has_mmx ) { SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_min; } else#endif SWRAST_CONTEXT(ctx)->BlendFunc = blend_min; } else if (eq==GL_MAX) { /* Note: GL_MAX ignores the blending weight factors */#if defined(USE_MMX_ASM) if ( cpu_has_mmx ) { SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_max; } else#endif SWRAST_CONTEXT(ctx)->BlendFunc = blend_max; } else if (srcRGB != srcA || dstRGB != dstA) { SWRAST_CONTEXT(ctx)->BlendFunc = blend_general; } else if (eq==GL_FUNC_ADD && srcRGB==GL_SRC_ALPHA && dstRGB==GL_ONE_MINUS_SRC_ALPHA) {#if defined(USE_MMX_ASM) if ( cpu_has_mmx ) { SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_transparency; } else#endif SWRAST_CONTEXT(ctx)->BlendFunc = blend_transparency; } else if (eq==GL_FUNC_ADD && srcRGB==GL_ONE && dstRGB==GL_ONE) {#if defined(USE_MMX_ASM) if ( cpu_has_mmx ) { SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_add; } else#endif SWRAST_CONTEXT(ctx)->BlendFunc = blend_add; } else if (((eq==GL_FUNC_ADD || eq==GL_FUNC_REVERSE_SUBTRACT) && (srcRGB==GL_ZERO && dstRGB==GL_SRC_COLOR)) || ((eq==GL_FUNC_ADD || eq==GL_FUNC_SUBTRACT) && (srcRGB==GL_DST_COLOR && dstRGB==GL_ZERO))) {#if defined(USE_MMX_ASM) if ( cpu_has_mmx ) { SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_modulate; } else#endif SWRAST_CONTEXT(ctx)->BlendFunc = blend_modulate; } else if (eq==GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) { SWRAST_CONTEXT(ctx)->BlendFunc = blend_noop; } else if (eq==GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) { SWRAST_CONTEXT(ctx)->BlendFunc = blend_replace; } else { SWRAST_CONTEXT(ctx)->BlendFunc = blend_general; }}/* * Apply the blending operator to a span of pixels. * We can handle horizontal runs of pixels (spans) or arrays of x/y * pixel coordinates. */void_swrast_blend_span(GLcontext *ctx, struct gl_renderbuffer *rb, const struct sw_span *span, GLchan rgba[][4]){ GLchan framebuffer[MAX_WIDTH][4]; ASSERT(span->end <= MAX_WIDTH); ASSERT(span->arrayMask & SPAN_RGBA); ASSERT(!ctx->Color._LogicOpEnabled); /* Read span of current frame buffer pixels */ if (span->arrayMask & SPAN_XY) { /* array of x/y pixel coords */ _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y, framebuffer, 4 * sizeof(GLchan)); } else { /* horizontal run of pixels */ _swrast_read_rgba_span(ctx, rb, span->end, span->x, span->y, framebuffer); } SWRAST_CONTEXT(ctx)->BlendFunc( ctx, span->end, span->array->mask, rgba, (const GLchan (*)[4]) framebuffer );}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?