public override unsafe void Render( EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, System.Drawing.Rectangle[] rois, int startIndex, int length) { // First we blur the source, and write the result to the destination surface // Then we apply Brightness/Contrast with the input as the dst, and the output as the dst // Third, we apply the Screen blend operation so that dst = dst OVER src ThreeAmountsConfigToken token = (ThreeAmountsConfigToken)parameters; AmountEffectConfigToken blurToken = new AmountEffectConfigToken(token.Amount1); this.blurEffect.Render(blurToken, dstArgs, srcArgs, rois, startIndex, length); BrightnessAndContrastAdjustmentConfigToken bcToken = new BrightnessAndContrastAdjustmentConfigToken(token.Amount2, token.Amount3); this.bcAdjustment.Render(bcToken, dstArgs, dstArgs, rois, startIndex, length); for (int i = startIndex; i < startIndex + length; ++i) { Rectangle roi = rois[i]; for (int y = roi.Top; y < roi.Bottom; ++y) { ColorBgra *dstPtr = dstArgs.Surface.GetPointAddressUnchecked(roi.Left, y); ColorBgra *srcPtr = srcArgs.Surface.GetPointAddressUnchecked(roi.Left, y); screenBlendOp.Apply(dstPtr, srcPtr, dstPtr, roi.Width); } } }
public override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { ThreeAmountsConfigToken token = (ThreeAmountsConfigToken)parameters; int hueDelta = token.Amount1; int satDelta = token.Amount2; int lightness = token.Amount3; // map the range [0,100] -> [0,100] and the range [101,200] -> [103,400] if (satDelta > 100) { satDelta = ((satDelta - 100) * 3) + 100; } UnaryPixelOp op; Surface dst = dstArgs.Surface; Surface src = srcArgs.Surface; if (hueDelta == 0 && satDelta == 100 && lightness == 0) { op = new UnaryPixelOps.Identity(); } else { op = new UnaryPixelOps.HueSaturationLightness(hueDelta, satDelta, lightness); } op.Apply(dst, src, rois, startIndex, length); }
private ThreeAmountsConfigToken(ThreeAmountsConfigToken copyMe) : base(copyMe) { this.amount3 = copyMe.amount3; }
public unsafe override void Render( EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, System.Drawing.Rectangle[] rois, int startIndex, int length) { ThreeAmountsConfigToken token = (ThreeAmountsConfigToken)parameters; Surface dst = dstArgs.Surface; Surface src = srcArgs.Surface; int width = dst.Width; int height = dst.Height; float hw = width / 2.0f; float hh = height / 2.0f; float sin = (float)Math.Sin(token.Amount1 * Math.PI / 180.0); float cos = (float)Math.Cos(token.Amount1 * Math.PI / 180.0); float scale = (float)Math.PI / token.Amount2; float intensity = token.Amount3; intensity = intensity * intensity / 10 * Math.Sign(intensity); int aaLevel = 4; int aaSamples = aaLevel * aaLevel + 1; PointF *aaPoints = stackalloc PointF[aaSamples]; for (int i = 0; i < aaSamples; ++i) { double x = (i * aaLevel) / (double)aaSamples; double y = i / (double)aaSamples; x -= (int)x; // RGSS + rotation to maximize AA quality aaPoints[i] = new PointF((float)(cos * x + sin * y), (float)(cos * y - sin * x)); } for (int n = startIndex; n < startIndex + length; ++n) { Rectangle rect = rois[n]; for (int y = rect.Top; y < rect.Bottom; y++) { float j = y - hh; ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y); for (int x = rect.Left; x < rect.Right; x++) { int b = 0; int g = 0; int r = 0; int a = 0; float i = x - hw; for (int p = 0; p < aaSamples; ++p) { PointF pt = aaPoints[p]; float u = i + pt.X; float v = j - pt.Y; float s = cos * u + sin * v; float t = -sin * u + cos * v; s += intensity * (float)Math.Tan(s * scale); t += intensity * (float)Math.Tan(t * scale); u = cos * s - sin * t; v = sin * s + cos * t; int xSample = (int)(hw + u); int ySample = (int)(hh + v); xSample = (xSample + width) % width; if (xSample < 0) // This makes it a little faster { xSample = (xSample + width) % width; } ySample = (ySample + height) % height; if (ySample < 0) // This makes it a little faster { ySample = (ySample + height) % height; } ColorBgra sample = *src.GetPointAddressUnchecked(xSample, ySample); b += sample.B; g += sample.G; r += sample.R; a += sample.A; } *(dstPtr++) = ColorBgra.FromBgra( (byte)(b / aaSamples), (byte)(g / aaSamples), (byte)(r / aaSamples), (byte)(a / aaSamples)); } } } }