From c1cfbe0336a98cc1578538d9d1a7bda3a6d4251d Mon Sep 17 00:00:00 2001 From: treeform Date: Fri, 20 Nov 2020 21:16:37 -0800 Subject: [PATCH] More work on inplace vs copy draw. --- src/pixie/images.nim | 38 ++++++++++++++++++++++++++++---------- tests/benchmark_images.nim | 12 ++++++------ 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/pixie/images.nim b/src/pixie/images.nim index dd32ea3..d791ab5 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -288,6 +288,9 @@ proc draw*(destImage: Image, srcImage: Image, mat: Mat4, blendMode = Normal) = color = blendMode.mix(destRgba, srcRgba) destImage.setRgbaUnsafe(x, y, color) +proc draw*(destImage: Image, srcImage: Image, pos = vec2(0, 0), blendMode = Normal) = + destImage.draw(srcImage, translate(vec3(pos.x, pos.y, 0)), blendMode) + func translate*(v: Vec2): Mat3 = result[0, 0] = 1 result[1, 1] = 1 @@ -295,25 +298,40 @@ func translate*(v: Vec2): Mat3 = result[2, 1] = v.y result[2, 2] = 1 -proc gpuDraw*(destImage: Image, srcImage: Image, mat: Mat3, blendMode = Normal): Image = +proc copyDraw*(destImage: Image, srcImage: Image, mat: Mat3, blendMode = Normal): Image = ## Draws one image onto another using matrix with color blending. result = newImage(destImage.width, destImage.height) - for y in 0 .. result.width: - for x in 0 .. result.height: + for y in 0 ..< destImage.width: + for x in 0 ..< destImage.height: let srcPos = mat * vec2(x.float32, y.float32) - var destRgba = destImage.getRgbaUnsafe(x, y) + let destRgba = destImage.getRgbaUnsafe(x, y) + var rgba = destRgba var srcRgba = rgba(0, 0, 0, 0) if srcImage.inside(srcPos.x.floor.int, srcPos.y.floor.int): srcRgba = srcImage.getRgbaSmooth(srcPos.x - 0.5, srcPos.y - 0.5) if blendMode.hasEffect(srcRgba): - destRgba = blendMode.mix(destRgba, srcRgba) - result.setRgbaUnsafe(x, y, destRgba) + rgba = blendMode.mix(destRgba, srcRgba) + result.setRgbaUnsafe(x, y, rgba) -proc draw*(destImage: Image, srcImage: Image, pos = vec2(0, 0), blendMode = Normal) = - destImage.draw(srcImage, translate(vec3(pos.x, pos.y, 0)), blendMode) +proc copyDraw*(destImage: Image, srcImage: Image, pos = vec2(0, 0), blendMode = Normal): Image = + destImage.copyDraw(srcImage, translate(-pos), blendMode) -proc gpuDraw*(destImage: Image, srcImage: Image, pos = vec2(0, 0), blendMode = Normal): Image = - destImage.gpuDraw(srcImage, translate(-pos), blendMode) +proc inplaceDraw*(destImage: Image, srcImage: Image, mat: Mat3, blendMode = Normal) = + ## Draws one image onto another using matrix with color blending. + for y in 0 ..< destImage.width: + for x in 0 ..< destImage.height: + let srcPos = mat * vec2(x.float32, y.float32) + let destRgba = destImage.getRgbaUnsafe(x, y) + var rgba = destRgba + var srcRgba = rgba(0, 0, 0, 0) + if srcImage.inside(srcPos.x.floor.int, srcPos.y.floor.int): + srcRgba = srcImage.getRgbaSmooth(srcPos.x - 0.5, srcPos.y - 0.5) + if blendMode.hasEffect(srcRgba): + rgba = blendMode.mix(destRgba, srcRgba) + destImage.setRgbaUnsafe(x, y, rgba) + +proc inplaceDraw*(destImage: Image, srcImage: Image, pos = vec2(0, 0), blendMode = Normal) = + destImage.inplaceDraw(srcImage, translate(-pos), blendMode) ## Thoughts ## single draw function that takes a matrix diff --git a/tests/benchmark_images.nim b/tests/benchmark_images.nim index cc69961..ac077d5 100644 --- a/tests/benchmark_images.nim +++ b/tests/benchmark_images.nim @@ -5,7 +5,7 @@ block: a.fill(rgba(255, 0, 0, 255)) var b = newImage(100, 100) b.fill(rgba(0, 255, 0, 255)) - a.draw(b, pos=vec2(25, 25)) + a.inplaceDraw(b, pos=vec2(25, 25)) writeFile("tests/images/inplaceDraw.bmp", a.encodeBmp()) block: @@ -13,28 +13,28 @@ block: a.fill(rgba(255, 0, 0, 255)) var b = newImage(100, 100) b.fill(rgba(0, 255, 0, 255)) - var c = a.gpuDraw(b, pos=vec2(25, 25)) + var c = a.copyDraw(b, pos=vec2(25, 25)) writeFile("tests/images/copyDraw.bmp", c.encodeBmp()) timeIt "inplaceDraw": var tmp = 0 - for i in 0 ..< 1000: + for i in 0 ..< 100000: var a = newImage(100, 100) a.fill(rgba(255, 0, 0, 255)) var b = newImage(100, 100) b.fill(rgba(0, 255, 0, 255)) - a.draw(b, pos=vec2(25, 25)) + a.inplaceDraw(b, pos=vec2(25, 25)) tmp += a.width * a.height echo tmp timeIt "copyDraw": var tmp = 0 - for i in 0 ..< 1000: + for i in 0 ..< 100000: var a = newImage(100, 100) a.fill(rgba(255, 0, 0, 255)) var b = newImage(100, 100) b.fill(rgba(0, 255, 0, 255)) - var c = a.gpuDraw(b, pos=vec2(25, 25)) + var c = a.copyDraw(b, pos=vec2(25, 25)) tmp += c.width * c.height echo tmp