Rename draw functions.
|
@ -22,7 +22,7 @@ type BlendMode* = enum
|
||||||
bmLuminosity
|
bmLuminosity
|
||||||
|
|
||||||
bmMask ## Special blend mode that is used for masking
|
bmMask ## Special blend mode that is used for masking
|
||||||
bmCopy ## Special that does not blend but copies the pixels from target.
|
bmOverwrite ## Special that does not blend but copies the pixels from target.
|
||||||
bmSubtractMask ## Inverse mask
|
bmSubtractMask ## Inverse mask
|
||||||
|
|
||||||
proc parseBlendMode*(s: string): BlendMode =
|
proc parseBlendMode*(s: string): BlendMode =
|
||||||
|
@ -45,8 +45,6 @@ proc parseBlendMode*(s: string): BlendMode =
|
||||||
of "SATURATION": bmSaturation
|
of "SATURATION": bmSaturation
|
||||||
of "COLOR": bmColor
|
of "COLOR": bmColor
|
||||||
of "LUMINOSITY": bmLuminosity
|
of "LUMINOSITY": bmLuminosity
|
||||||
of "MASK": bmMask
|
|
||||||
of "COPY": bmCopy
|
|
||||||
else: bmNormal
|
else: bmNormal
|
||||||
|
|
||||||
proc `+`*(a, b: Color): Color {.inline.} =
|
proc `+`*(a, b: Color): Color {.inline.} =
|
||||||
|
@ -99,7 +97,7 @@ proc mix*(blendMode: BlendMode, target, blend: Color): Color =
|
||||||
result.b = target.b
|
result.b = target.b
|
||||||
result.a = target.a * (1 - blend.a)
|
result.a = target.a * (1 - blend.a)
|
||||||
return
|
return
|
||||||
elif blendMode == bmCopy:
|
elif blendMode == bmOverwrite:
|
||||||
result = blend
|
result = blend
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ proc `$`*(image: Image): string =
|
||||||
## Display the image size and channels.
|
## Display the image size and channels.
|
||||||
"<Image " & $image.width & "x" & $image.height & ">"
|
"<Image " & $image.width & "x" & $image.height & ">"
|
||||||
|
|
||||||
proc fraction(v: float32): float32 =
|
proc fractional(v: float32): float32 =
|
||||||
## Returns unsigned fraction part of the float.
|
## Returns unsigned fraction part of the float.
|
||||||
## -13.7868723 -> 0.7868723
|
## -13.7868723 -> 0.7868723
|
||||||
result = abs(v)
|
result = abs(v)
|
||||||
|
@ -181,24 +181,26 @@ proc hasEffect*(blendMode: BlendMode, rgba: ColorRGBA): bool =
|
||||||
case blendMode
|
case blendMode
|
||||||
of bmMask:
|
of bmMask:
|
||||||
rgba.a != 255
|
rgba.a != 255
|
||||||
of bmCopy:
|
of bmOverwrite:
|
||||||
true
|
true
|
||||||
else:
|
else:
|
||||||
rgba.a > 0
|
rgba.a > 0
|
||||||
|
|
||||||
proc drawFast1*(a: Image, b: Image, mat: Mat3): Image =
|
proc drawOverwrite*(a: Image, b: Image, mat: Mat3): Image =
|
||||||
## Draws one image onto another using integer x,y offset with COPY.
|
## Draws one image onto another using integer x,y offset with COPY.
|
||||||
result = newImageNoInit(a.width, a.height)
|
result = newImageNoInit(a.width, a.height)
|
||||||
var matInv = mat.inverse()
|
var matInv = mat.inverse()
|
||||||
|
# TODO: Alternative mem-copies from a and b as scan down.
|
||||||
for y in 0 ..< a.height:
|
for y in 0 ..< a.height:
|
||||||
for x in 0 ..< a.width:
|
for x in 0 ..< a.width:
|
||||||
var rgba = a.getRgbaUnsafe(x, y)
|
var rgba = a.getRgbaUnsafe(x, y)
|
||||||
let srcPos = matInv * vec2(x.float32, y.float32)
|
let srcPos = matInv * vec2(x.float32, y.float32)
|
||||||
|
|
||||||
if b.inside(srcPos.x.floor.int, srcPos.y.floor.int):
|
if b.inside(srcPos.x.floor.int, srcPos.y.floor.int):
|
||||||
rgba = b.getRgbaUnsafe(srcPos.x.floor.int, srcPos.y.floor.int)
|
rgba = b.getRgbaUnsafe(srcPos.x.floor.int, srcPos.y.floor.int)
|
||||||
result.setRgbaUnsafe(x, y, rgba)
|
result.setRgbaUnsafe(x, y, rgba)
|
||||||
|
|
||||||
proc drawFast2*(a: Image, b: Image, mat: Mat3, blendMode: BlendMode): Image =
|
proc drawBlend*(a: Image, b: Image, mat: Mat3, blendMode: BlendMode): Image =
|
||||||
## Draws one image onto another using matrix with color blending.
|
## Draws one image onto another using matrix with color blending.
|
||||||
result = newImageNoInit(a.width, a.height)
|
result = newImageNoInit(a.width, a.height)
|
||||||
var matInv = mat.inverse()
|
var matInv = mat.inverse()
|
||||||
|
@ -206,20 +208,25 @@ proc drawFast2*(a: Image, b: Image, mat: Mat3, blendMode: BlendMode): Image =
|
||||||
for x in 0 ..< a.width:
|
for x in 0 ..< a.width:
|
||||||
var rgba = a.getRgbaUnsafe(x, y)
|
var rgba = a.getRgbaUnsafe(x, y)
|
||||||
let srcPos = matInv * vec2(x.float32, y.float32)
|
let srcPos = matInv * vec2(x.float32, y.float32)
|
||||||
|
|
||||||
if b.inside(srcPos.x.floor.int, srcPos.y.floor.int):
|
if b.inside(srcPos.x.floor.int, srcPos.y.floor.int):
|
||||||
let rgba2 = b.getRgbaUnsafe(srcPos.x.floor.int, srcPos.y.floor.int)
|
let rgba2 = b.getRgbaUnsafe(srcPos.x.floor.int, srcPos.y.floor.int)
|
||||||
if blendMode.hasEffect(rgba2):
|
if blendMode.hasEffect(rgba2):
|
||||||
rgba = blendMode.mix(rgba, rgba2)
|
rgba = blendMode.mix(rgba, rgba2)
|
||||||
result.setRgbaUnsafe(x, y, rgba)
|
result.setRgbaUnsafe(x, y, rgba)
|
||||||
|
|
||||||
proc drawFast3*(a: Image, b: Image, mat: Mat3, blendMode: BlendMode): Image =
|
proc drawBlendSmooth*(a: Image, b: Image, mat: Mat3, blendMode: BlendMode): Image =
|
||||||
## Draws one image onto another using matrix with color blending.
|
## Draws one image onto another using matrix with color blending.
|
||||||
result = newImageNoInit(a.width, a.height)
|
result = newImageNoInit(a.width, a.height)
|
||||||
|
|
||||||
|
# TODO: Implement mip maps.
|
||||||
|
|
||||||
var matInv = mat.inverse()
|
var matInv = mat.inverse()
|
||||||
for y in 0 ..< a.height:
|
for y in 0 ..< a.height:
|
||||||
for x in 0 ..< a.width:
|
for x in 0 ..< a.width:
|
||||||
var rgba = a.getRgbaUnsafe(x, y)
|
var rgba = a.getRgbaUnsafe(x, y)
|
||||||
let srcPos = matInv * vec2(x.float32, y.float32)
|
let srcPos = matInv * vec2(x.float32, y.float32)
|
||||||
|
|
||||||
if b.inside1px(srcPos.x, srcPos.y):
|
if b.inside1px(srcPos.x, srcPos.y):
|
||||||
let rgba2 = b.getRgbaSmooth(srcPos.x, srcPos.y)
|
let rgba2 = b.getRgbaSmooth(srcPos.x, srcPos.y)
|
||||||
if blendMode.hasEffect(rgba2):
|
if blendMode.hasEffect(rgba2):
|
||||||
|
@ -228,19 +235,17 @@ proc drawFast3*(a: Image, b: Image, mat: Mat3, blendMode: BlendMode): Image =
|
||||||
|
|
||||||
proc draw*(a: Image, b: Image, mat: Mat3, blendMode = bmNormal): Image =
|
proc draw*(a: Image, b: Image, mat: Mat3, blendMode = bmNormal): Image =
|
||||||
## Draws one image onto another using matrix with color blending.
|
## Draws one image onto another using matrix with color blending.
|
||||||
|
|
||||||
|
# Decide which ones of the draws best fit current parameters.
|
||||||
let ns = [-1.float32, 0, 1]
|
let ns = [-1.float32, 0, 1]
|
||||||
if mat[0, 0] in ns and mat[0, 1] in ns and
|
if mat[0, 0] in ns and mat[0, 1] in ns and
|
||||||
mat[1, 0] in ns and mat[1, 1] in ns and
|
mat[1, 0] in ns and mat[1, 1] in ns and
|
||||||
mat[2, 0].fraction == 0.0 and mat[2, 1].fraction == 0.0:
|
mat[2, 0].fractional == 0.0 and mat[2, 1].fractional == 0.0:
|
||||||
if blendMode == bmCopy:
|
if blendMode == bmOverwrite:
|
||||||
return drawFast1(
|
return drawOverwrite(a, b, mat)
|
||||||
a, b, mat
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
return drawFast2(
|
return drawBlend(a, b, mat, blendMode)
|
||||||
a, b, mat, blendMode
|
return drawBlendSmooth(a, b, mat, blendMode)
|
||||||
)
|
|
||||||
return drawFast3(a, b, mat, blendMode)
|
|
||||||
|
|
||||||
proc draw*(a: Image, b: Image, pos = vec2(0, 0), blendMode = bmNormal): Image =
|
proc draw*(a: Image, b: Image, pos = vec2(0, 0), blendMode = bmNormal): Image =
|
||||||
a.draw(b, translate(pos), blendMode)
|
a.draw(b, translate(pos), blendMode)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import pixie, chroma, vmath, fidget/opengl/perf, pixie/fileformats/bmp
|
import pixie, chroma, vmath, fidget/opengl/perf, pixie/fileformats/bmp
|
||||||
|
|
||||||
timeIt "benchDrawFast1 COPY":
|
timeIt "drawOverwrite bmOverwrite":
|
||||||
var tmp = 0
|
var tmp = 0
|
||||||
var c: Image
|
var c: Image
|
||||||
for i in 0 ..< 1000:
|
for i in 0 ..< 1000:
|
||||||
|
@ -8,12 +8,12 @@ timeIt "benchDrawFast1 COPY":
|
||||||
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))
|
||||||
c = a.drawFast1(b, translate(vec2(25, 25))) # Copy
|
c = a.drawOverwrite(b, translate(vec2(25, 25))) # Copy
|
||||||
tmp += c.width * c.height
|
tmp += c.width * c.height
|
||||||
c.writeFile("tests/images/benchDrawFast1Copy.png")
|
c.writeFile("tests/images/bench.drawOverwrite.bmOverwrite.png")
|
||||||
echo tmp
|
echo tmp
|
||||||
|
|
||||||
timeIt "benchDrawFast2 COPY":
|
timeIt "drawBlend bmOverwrite":
|
||||||
var tmp = 0
|
var tmp = 0
|
||||||
var c: Image
|
var c: Image
|
||||||
for i in 0 ..< 1000:
|
for i in 0 ..< 1000:
|
||||||
|
@ -21,12 +21,12 @@ timeIt "benchDrawFast2 COPY":
|
||||||
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))
|
||||||
c = a.drawFast2(b, translate(vec2(25, 25)), bmCopy)
|
c = a.drawBlend(b, translate(vec2(25, 25)), bmOverwrite)
|
||||||
tmp += c.width * c.height
|
tmp += c.width * c.height
|
||||||
c.writeFile("tests/images/benchDrawFast2Copy.png")
|
c.writeFile("tests/images/bench.drawBlend.bmOverwrite.png")
|
||||||
echo tmp
|
echo tmp
|
||||||
|
|
||||||
timeIt "benchDrawFast3 COPY":
|
timeIt "drawBlendSmooth bmOverwrite":
|
||||||
var tmp = 0
|
var tmp = 0
|
||||||
var c: Image
|
var c: Image
|
||||||
for i in 0 ..< 1000:
|
for i in 0 ..< 1000:
|
||||||
|
@ -34,12 +34,12 @@ timeIt "benchDrawFast3 COPY":
|
||||||
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))
|
||||||
c = a.drawFast3(b, translate(vec2(25, 25)), bmCopy)
|
c = a.drawBlendSmooth(b, translate(vec2(25, 25)), bmOverwrite)
|
||||||
tmp += c.width * c.height
|
tmp += c.width * c.height
|
||||||
c.writeFile("tests/images/benchDrawFast3Copy.png")
|
c.writeFile("tests/images/bench.drawBlendSmooth.bmOverwrite.png")
|
||||||
echo tmp
|
echo tmp
|
||||||
|
|
||||||
timeIt "benchDrawFast2 Normal":
|
timeIt "drawBlend bmNormal":
|
||||||
var tmp = 0
|
var tmp = 0
|
||||||
var c: Image
|
var c: Image
|
||||||
for i in 0 ..< 1000:
|
for i in 0 ..< 1000:
|
||||||
|
@ -47,12 +47,12 @@ timeIt "benchDrawFast2 Normal":
|
||||||
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))
|
||||||
c = a.drawFast2(b, translate(vec2(25, 25)), bmNormal)
|
c = a.drawBlend(b, translate(vec2(25, 25)), bmNormal)
|
||||||
tmp += c.width * c.height
|
tmp += c.width * c.height
|
||||||
c.writeFile("tests/images/benchDrawFast2Normal.png")
|
c.writeFile("tests/images/bench.drawBlend.bmNormal.png")
|
||||||
echo tmp
|
echo tmp
|
||||||
|
|
||||||
timeIt "benchDrawFast3 Normal":
|
timeIt "drawBlendSmooth bmNormal":
|
||||||
var tmp = 0
|
var tmp = 0
|
||||||
var c: Image
|
var c: Image
|
||||||
for i in 0 ..< 1000:
|
for i in 0 ..< 1000:
|
||||||
|
@ -60,12 +60,12 @@ timeIt "benchDrawFast3 Normal":
|
||||||
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))
|
||||||
c = a.drawFast3(b, translate(vec2(25, 25)), bmNormal)
|
c = a.drawBlendSmooth(b, translate(vec2(25, 25)), bmNormal)
|
||||||
tmp += c.width * c.height
|
tmp += c.width * c.height
|
||||||
c.writeFile("tests/images/benchDrawFast3Normal.png")
|
c.writeFile("tests/images/bench.drawBlendSmooth.bmNormal.png")
|
||||||
echo tmp
|
echo tmp
|
||||||
|
|
||||||
timeIt "benchDrawFast2 Saturation":
|
timeIt "drawBlend bmSaturation":
|
||||||
var tmp = 0
|
var tmp = 0
|
||||||
var c: Image
|
var c: Image
|
||||||
for i in 0 ..< 1000:
|
for i in 0 ..< 1000:
|
||||||
|
@ -73,12 +73,12 @@ timeIt "benchDrawFast2 Saturation":
|
||||||
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, 0, 0, 255))
|
b.fill(rgba(0, 0, 0, 255))
|
||||||
c = a.drawFast2(b, translate(vec2(25, 25)), bmSaturation)
|
c = a.drawBlend(b, translate(vec2(25, 25)), bmSaturation)
|
||||||
tmp += c.width * c.height
|
tmp += c.width * c.height
|
||||||
c.writeFile("tests/images/benchDrawFast2Saturation.png")
|
c.writeFile("tests/images/bench.drawBlend.bmSaturation.png")
|
||||||
echo tmp
|
echo tmp
|
||||||
|
|
||||||
timeIt "benchDrawFast3 Saturation":
|
timeIt "drawBlendSmooth bmSaturation":
|
||||||
var tmp = 0
|
var tmp = 0
|
||||||
var c: Image
|
var c: Image
|
||||||
for i in 0 ..< 1000:
|
for i in 0 ..< 1000:
|
||||||
|
@ -86,20 +86,20 @@ timeIt "benchDrawFast3 Saturation":
|
||||||
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, 0, 0, 255))
|
b.fill(rgba(0, 0, 0, 255))
|
||||||
c = a.drawFast3(b, translate(vec2(25, 25)), bmSaturation)
|
c = a.drawBlendSmooth(b, translate(vec2(25, 25)), bmSaturation)
|
||||||
tmp += c.width * c.height
|
tmp += c.width * c.height
|
||||||
c.writeFile("tests/images/benchDrawFast3Saturation.png")
|
c.writeFile("tests/images/bench.drawBlendSmooth.bmSaturation.png")
|
||||||
echo tmp
|
echo tmp
|
||||||
|
|
||||||
timeIt "benchDrawFast3 Rotation":
|
# timeIt "benchDrawFast3 Rotation":
|
||||||
var tmp = 0
|
# var tmp = 0
|
||||||
var c: Image
|
# var c: Image
|
||||||
for i in 0 ..< 1000:
|
# for i in 0 ..< 1000:
|
||||||
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, 0, 0, 255))
|
# b.fill(rgba(0, 0, 0, 255))
|
||||||
c = a.drawFast3(b, translate(vec2(25, 25)) * rotationMat3(PI/2), bmNormal)
|
# c = a.drawFast3(b, translate(vec2(25, 25)) * rotationMat3(PI/2), bmNormal)
|
||||||
tmp += c.width * c.height
|
# tmp += c.width * c.height
|
||||||
c.writeFile("tests/images/benchDrawFast3Rotation.png")
|
# c.writeFile("tests/images/benchDrawFast3Rotation.png")
|
||||||
echo tmp
|
# echo tmp
|
||||||
|
|
Before Width: | Height: | Size: 328 B After Width: | Height: | Size: 328 B |
Before Width: | Height: | Size: 328 B After Width: | Height: | Size: 328 B |
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 338 B |
Before Width: | Height: | Size: 328 B After Width: | Height: | Size: 328 B |
Before Width: | Height: | Size: 339 B After Width: | Height: | Size: 339 B |
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 338 B |
Before Width: | Height: | Size: 328 B After Width: | Height: | Size: 328 B |
Before Width: | Height: | Size: 339 B |
Before Width: | Height: | Size: 337 B |