More work on inplace vs copy draw.

This commit is contained in:
treeform 2020-11-20 21:16:37 -08:00
parent cebc052903
commit c1cfbe0336
2 changed files with 34 additions and 16 deletions

View file

@ -288,6 +288,9 @@ proc draw*(destImage: Image, srcImage: Image, mat: Mat4, blendMode = Normal) =
color = blendMode.mix(destRgba, srcRgba) color = blendMode.mix(destRgba, srcRgba)
destImage.setRgbaUnsafe(x, y, color) 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 = func translate*(v: Vec2): Mat3 =
result[0, 0] = 1 result[0, 0] = 1
result[1, 1] = 1 result[1, 1] = 1
@ -295,25 +298,40 @@ func translate*(v: Vec2): Mat3 =
result[2, 1] = v.y result[2, 1] = v.y
result[2, 2] = 1 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. ## Draws one image onto another using matrix with color blending.
result = newImage(destImage.width, destImage.height) result = newImage(destImage.width, destImage.height)
for y in 0 .. result.width: for y in 0 ..< destImage.width:
for x in 0 .. result.height: for x in 0 ..< destImage.height:
let srcPos = mat * vec2(x.float32, y.float32) 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) var srcRgba = rgba(0, 0, 0, 0)
if srcImage.inside(srcPos.x.floor.int, srcPos.y.floor.int): if srcImage.inside(srcPos.x.floor.int, srcPos.y.floor.int):
srcRgba = srcImage.getRgbaSmooth(srcPos.x - 0.5, srcPos.y - 0.5) srcRgba = srcImage.getRgbaSmooth(srcPos.x - 0.5, srcPos.y - 0.5)
if blendMode.hasEffect(srcRgba): if blendMode.hasEffect(srcRgba):
destRgba = blendMode.mix(destRgba, srcRgba) rgba = blendMode.mix(destRgba, srcRgba)
result.setRgbaUnsafe(x, y, destRgba) result.setRgbaUnsafe(x, y, rgba)
proc draw*(destImage: Image, srcImage: Image, pos = vec2(0, 0), blendMode = Normal) = proc copyDraw*(destImage: Image, srcImage: Image, pos = vec2(0, 0), blendMode = Normal): Image =
destImage.draw(srcImage, translate(vec3(pos.x, pos.y, 0)), blendMode) destImage.copyDraw(srcImage, translate(-pos), blendMode)
proc gpuDraw*(destImage: Image, srcImage: Image, pos = vec2(0, 0), blendMode = Normal): Image = proc inplaceDraw*(destImage: Image, srcImage: Image, mat: Mat3, blendMode = Normal) =
destImage.gpuDraw(srcImage, translate(-pos), blendMode) ## 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 ## Thoughts
## single draw function that takes a matrix ## single draw function that takes a matrix

View file

@ -5,7 +5,7 @@ block:
a.fill(rgba(255, 0, 0, 255)) a.fill(rgba(255, 0, 0, 255))
var b = newImage(100, 100) var b = newImage(100, 100)
b.fill(rgba(0, 255, 0, 255)) 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()) writeFile("tests/images/inplaceDraw.bmp", a.encodeBmp())
block: block:
@ -13,28 +13,28 @@ block:
a.fill(rgba(255, 0, 0, 255)) a.fill(rgba(255, 0, 0, 255))
var b = newImage(100, 100) var b = newImage(100, 100)
b.fill(rgba(0, 255, 0, 255)) 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()) writeFile("tests/images/copyDraw.bmp", c.encodeBmp())
timeIt "inplaceDraw": timeIt "inplaceDraw":
var tmp = 0 var tmp = 0
for i in 0 ..< 1000: for i in 0 ..< 100000:
var a = newImage(100, 100) var a = newImage(100, 100)
a.fill(rgba(255, 0, 0, 255)) a.fill(rgba(255, 0, 0, 255))
var b = newImage(100, 100) var b = newImage(100, 100)
b.fill(rgba(0, 255, 0, 255)) 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 tmp += a.width * a.height
echo tmp echo tmp
timeIt "copyDraw": timeIt "copyDraw":
var tmp = 0 var tmp = 0
for i in 0 ..< 1000: for i in 0 ..< 100000:
var a = newImage(100, 100) var a = newImage(100, 100)
a.fill(rgba(255, 0, 0, 255)) a.fill(rgba(255, 0, 0, 255))
var b = newImage(100, 100) var b = newImage(100, 100)
b.fill(rgba(0, 255, 0, 255)) 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 tmp += c.width * c.height
echo tmp echo tmp