📄 s_blend.c
字号:
break; case GL_DST_COLOR: dR = Rd; dG = Gd; dB = Bd; break; case GL_ONE_MINUS_DST_COLOR: dR = 1.0F - Rd; dG = 1.0F - Gd; dB = 1.0F - Bd; break; default: /* this should never happen */ dR = dG = dB = 0.0F; _mesa_problem(ctx, "Bad blend dest RGB factor in blend_general_float"); return; } /* 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 = As; break; case GL_ONE_MINUS_SRC_COLOR: dA = 1.0F - As; break; case GL_SRC_ALPHA: dA = As; break; case GL_ONE_MINUS_SRC_ALPHA: dA = 1.0F - As; break; case GL_DST_ALPHA: dA = Ad; break; case GL_ONE_MINUS_DST_ALPHA: dA = 1.0F - Ad; 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: dA = Ad; break; case GL_ONE_MINUS_DST_COLOR: dA = 1.0F - Ad; break; default: /* this should never happen */ dA = 0.0F; _mesa_problem(ctx, "Bad blend dest A factor in blend_general_float"); return; } /* compute the blended RGB */ switch (ctx->Color.BlendEquationRGB) { case GL_FUNC_ADD: r = Rs * sR + Rd * dR; g = Gs * sG + Gd * dG; b = Bs * sB + Bd * dB; a = As * sA + Ad * dA; break; case GL_FUNC_SUBTRACT: r = Rs * sR - Rd * dR; g = Gs * sG - Gd * dG; b = Bs * sB - Bd * dB; a = As * sA - Ad * dA; break; case GL_FUNC_REVERSE_SUBTRACT: r = Rd * dR - Rs * sR; g = Gd * dG - Gs * sG; b = Bd * dB - Bs * sB; a = Ad * dA - As * sA; break; case GL_MIN: r = MIN2( Rd, Rs ); g = MIN2( Gd, Gs ); b = MIN2( Bd, Bs ); break; case GL_MAX: r = MAX2( Rd, Rs ); g = MAX2( Gd, Gs ); b = MAX2( Bd, Bs ); break; default: /* should never get here */ r = g = b = 0.0F; /* silence uninitialized var warning */ _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); return; } /* compute the blended alpha */ switch (ctx->Color.BlendEquationA) { case GL_FUNC_ADD: a = As * sA + Ad * dA; break; case GL_FUNC_SUBTRACT: a = As * sA - Ad * dA; break; case GL_FUNC_REVERSE_SUBTRACT: a = Ad * dA - As * sA; break; case GL_MIN: a = MIN2( Ad, As ); break; case GL_MAX: a = MAX2( Ad, As ); break; default: /* should never get here */ a = 0.0F; /* silence uninitialized var warning */ _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); return; } /* final clamping */#if 0 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, 1.0F );#else ASSIGN_4V(rgba[i], r, g, b, a);#endif } }}/** * Do any blending operation, any chanType. */static voidblend_general(GLcontext *ctx, GLuint n, const GLubyte mask[], void *src, const void *dst, GLenum chanType){ GLfloat rgbaF[MAX_WIDTH][4], destF[MAX_WIDTH][4]; if (chanType == GL_UNSIGNED_BYTE) { GLubyte (*rgba)[4] = (GLubyte (*)[4]) src; const GLubyte (*dest)[4] = (const GLubyte (*)[4]) dst; GLuint i; /* convert ubytes to floats */ for (i = 0; i < n; i++) { if (mask[i]) { rgbaF[i][RCOMP] = UBYTE_TO_FLOAT(rgba[i][RCOMP]); rgbaF[i][GCOMP] = UBYTE_TO_FLOAT(rgba[i][GCOMP]); rgbaF[i][BCOMP] = UBYTE_TO_FLOAT(rgba[i][BCOMP]); rgbaF[i][ACOMP] = UBYTE_TO_FLOAT(rgba[i][ACOMP]); destF[i][RCOMP] = UBYTE_TO_FLOAT(dest[i][RCOMP]); destF[i][GCOMP] = UBYTE_TO_FLOAT(dest[i][GCOMP]); destF[i][BCOMP] = UBYTE_TO_FLOAT(dest[i][BCOMP]); destF[i][ACOMP] = UBYTE_TO_FLOAT(dest[i][ACOMP]); } } /* do blend */ blend_general_float(ctx, n, mask, rgbaF, destF, chanType); /* convert back to ubytes */ for (i = 0; i < n; i++) { if (mask[i]) { UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][RCOMP], rgbaF[i][RCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][GCOMP], rgbaF[i][GCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][BCOMP], rgbaF[i][BCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][ACOMP], rgbaF[i][ACOMP]); } } } else if (chanType == GL_UNSIGNED_SHORT) { GLushort (*rgba)[4] = (GLushort (*)[4]) src; const GLushort (*dest)[4] = (const GLushort (*)[4]) dst; GLuint i; /* convert ushorts to floats */ for (i = 0; i < n; i++) { if (mask[i]) { rgbaF[i][RCOMP] = USHORT_TO_FLOAT(rgba[i][RCOMP]); rgbaF[i][GCOMP] = USHORT_TO_FLOAT(rgba[i][GCOMP]); rgbaF[i][BCOMP] = USHORT_TO_FLOAT(rgba[i][BCOMP]); rgbaF[i][ACOMP] = USHORT_TO_FLOAT(rgba[i][ACOMP]); destF[i][RCOMP] = USHORT_TO_FLOAT(dest[i][RCOMP]); destF[i][GCOMP] = USHORT_TO_FLOAT(dest[i][GCOMP]); destF[i][BCOMP] = USHORT_TO_FLOAT(dest[i][BCOMP]); destF[i][ACOMP] = USHORT_TO_FLOAT(dest[i][ACOMP]); } } /* do blend */ blend_general_float(ctx, n, mask, rgbaF, destF, chanType); /* convert back to ushorts */ for (i = 0; i < n; i++) { if (mask[i]) { UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], rgbaF[i][RCOMP]); UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], rgbaF[i][GCOMP]); UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], rgbaF[i][BCOMP]); UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], rgbaF[i][ACOMP]); } } } else { blend_general_float(ctx, n, mask, (GLfloat (*)[4]) src, (GLfloat (*)[4]) dst, chanType); }}/** * Analyze current blending parameters to pick fastest blending function. * Result: the ctx->Color.BlendFunc pointer is updated. */void_swrast_choose_blend_func(GLcontext *ctx, GLenum chanType){ SWcontext *swrast = SWRAST_CONTEXT(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->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 && chanType == GL_UNSIGNED_BYTE) { swrast->BlendFunc = _mesa_mmx_blend_min; } else#endif swrast->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 && chanType == GL_UNSIGNED_BYTE) { swrast->BlendFunc = _mesa_mmx_blend_max; } else#endif swrast->BlendFunc = blend_max; } else if (srcRGB != srcA || dstRGB != dstA) { swrast->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 && chanType == GL_UNSIGNED_BYTE) { swrast->BlendFunc = _mesa_mmx_blend_transparency; } else#endif { if (chanType == GL_UNSIGNED_BYTE) swrast->BlendFunc = blend_transparency_ubyte; else if (chanType == GL_UNSIGNED_SHORT) swrast->BlendFunc = blend_transparency_ushort; else swrast->BlendFunc = blend_transparency_float; } } else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ONE) {#if defined(USE_MMX_ASM) if (cpu_has_mmx && chanType == GL_UNSIGNED_BYTE) { swrast->BlendFunc = _mesa_mmx_blend_add; } else#endif swrast->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 && chanType == GL_UNSIGNED_BYTE) { swrast->BlendFunc = _mesa_mmx_blend_modulate; } else#endif swrast->BlendFunc = blend_modulate; } else if (eq == GL_FUNC_ADD && srcRGB == GL_ZERO && dstRGB == GL_ONE) { swrast->BlendFunc = blend_noop; } else if (eq == GL_FUNC_ADD && srcRGB == GL_ONE && dstRGB == GL_ZERO) { swrast->BlendFunc = blend_replace; } else { swrast->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, SWspan *span){ SWcontext *swrast = SWRAST_CONTEXT(ctx); void *rbPixels; ASSERT(span->end <= MAX_WIDTH); ASSERT(span->arrayMask & SPAN_RGBA); ASSERT(rb->DataType == span->array->ChanType); ASSERT(!ctx->Color._LogicOpEnabled); rbPixels = _swrast_get_dest_rgba(ctx, rb, span); swrast->BlendFunc(ctx, span->end, span->array->mask, span->array->rgba, rbPixels, span->array->ChanType);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -