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 + -
显示快捷键?