/// <inheritdoc /> internal override void Apply(float[] scanlineBuffer, int scanlineWidth, int offset, int x, int y) { Guard.MustBeGreaterThanOrEqualTo(scanlineBuffer.Length, offset + scanlineWidth, nameof(scanlineWidth)); using (PinnedBuffer <float> buffer = new PinnedBuffer <float>(scanlineBuffer)) { BufferSpan <float> slice = buffer.Slice(offset); for (int xPos = 0; xPos < scanlineWidth; xPos++) { int targetX = xPos + x; int targetY = y; float opacity = slice[xPos]; if (opacity > Constants.Epsilon) { Vector4 backgroundVector = this.Target[targetX, targetY].ToVector4(); // 2d array index at row/column Vector4 sourceVector = this.patternVector[targetY % this.patternVector.Height, targetX % this.patternVector.Width]; Vector4 finalColor = Vector4BlendTransforms.PremultipliedLerp(backgroundVector, sourceVector, opacity); TColor packed = default(TColor); packed.PackFromVector4(finalColor); this.Target[targetX, targetY] = packed; } } } }
public void WithStartAndLength(int bufferLength, int start, int spanLength) { using (PinnedBuffer <Foo> buffer = new PinnedBuffer <Foo>(bufferLength)) { BufferSpan <Foo> span = buffer.Slice(start, spanLength); Assert.Equal(buffer.Array, span.Array); Assert.Equal(start, span.Start); Assert.Equal(buffer.Pointer + start * Unsafe.SizeOf <Foo>(), span.PointerAtOffset); Assert.Equal(span.Length, spanLength); } }
public void AsBytes() { Foo[] fooz = { new Foo(1, 2), new Foo(3, 4), new Foo(5, 6) }; using (PinnedBuffer <Foo> colorBuf = new PinnedBuffer <Foo>(fooz)) { BufferPointer <Foo> orig = colorBuf.Slice(1); BufferPointer <byte> asBytes = (BufferPointer <byte>)orig; Assert.Equal(asBytes.Offset, sizeof(Foo)); Assert.Equal(orig.PointerAtOffset, asBytes.PointerAtOffset); } }
public void Slice() { Foo[] a = { new Foo() { A = 1, B = 2 }, new Foo() { A = 3, B = 4 } }; using (PinnedBuffer <Foo> buffer = new PinnedBuffer <Foo>(a)) { BufferPointer <Foo> arrayPtr = buffer.Slice(); Assert.Equal(a, arrayPtr.Array); Assert.Equal(0, arrayPtr.Offset); Assert.Equal(buffer.Pointer, arrayPtr.PointerAtOffset); } }
/// <inheritdoc /> internal override void Apply(float[] scanlineBuffer, int scanlineWidth, int offset, int x, int y) { Guard.MustBeGreaterThanOrEqualTo(scanlineBuffer.Length, offset + scanlineWidth, nameof(scanlineWidth)); using (PinnedBuffer <float> buffer = new PinnedBuffer <float>(scanlineBuffer)) { BufferSpan <float> slice = buffer.Slice(offset); for (int xPos = 0; xPos < scanlineWidth; xPos++) { int targetX = xPos + x; int targetY = y; float opacity = slice[xPos]; if (opacity > Constants.Epsilon) { Vector4 backgroundVector = this.Target[targetX, targetY].ToVector4(); Vector4 sourceVector = backgroundVector; float distance = Vector4.DistanceSquared(sourceVector, this.sourceColor); if (distance <= this.threshold) { float lerpAmount = (this.threshold - distance) / this.threshold; sourceVector = Vector4BlendTransforms.PremultipliedLerp( sourceVector, this.targetColor, lerpAmount); Vector4 finalColor = Vector4BlendTransforms.PremultipliedLerp(backgroundVector, sourceVector, opacity); TColor packed = default(TColor); packed.PackFromVector4(finalColor); this.Target[targetX, targetY] = packed; } } } } }