Add drawFast4 integer-matrix.
|
@ -136,9 +136,9 @@ proc getRgbaSmooth*(image: Image, x, y: float64): ColorRGBA {.inline.} =
|
||||||
proc hasEffect*(blendMode: BlendMode, rgba: ColorRGBA): bool =
|
proc hasEffect*(blendMode: BlendMode, rgba: ColorRGBA): bool =
|
||||||
## Returns true if applying rgba with current blend mode has effect.
|
## Returns true if applying rgba with current blend mode has effect.
|
||||||
case blendMode
|
case blendMode
|
||||||
of Mask:
|
of bmMask:
|
||||||
rgba.a != 255
|
rgba.a != 255
|
||||||
of COPY:
|
of bmCopy:
|
||||||
true
|
true
|
||||||
else:
|
else:
|
||||||
rgba.a > 0
|
rgba.a > 0
|
||||||
|
@ -154,63 +154,88 @@ proc fraction(v: float32): float32 =
|
||||||
result = abs(v)
|
result = abs(v)
|
||||||
result = result - floor(result)
|
result = result - floor(result)
|
||||||
|
|
||||||
proc drawFast*(a: Image, b: Image, x, y: int): Image =
|
proc drawFast1*(a: Image, b: Image, x, y: int): 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 = newImage(a.width, a.height)
|
result = newImage(a.width, a.height)
|
||||||
for yd in 0 ..< a.width:
|
for yd in 0 ..< a.width:
|
||||||
for xd in 0 ..< a.height:
|
for xd in 0 ..< a.height:
|
||||||
var rgba = a.getRgbaUnsafe(xd, yd)
|
var rgba = a.getRgbaUnsafe(xd, yd)
|
||||||
if b.inside(xd + x, yd + y):
|
if b.inside(xd - x, yd - y):
|
||||||
rgba = b.getRgbaUnsafe(xd + x, yd + y)
|
rgba = b.getRgbaUnsafe(xd - x, yd - y)
|
||||||
result.setRgbaUnsafe(xd, yd, rgba)
|
result.setRgbaUnsafe(xd, yd, rgba)
|
||||||
|
|
||||||
proc drawFast*(a: Image, b: Image, x, y: int, blendMode: BlendMode): Image =
|
proc drawFast2*(a: Image, b: Image, x, y: int, blendMode: BlendMode): Image =
|
||||||
## Draws one image onto another using integer x,y offset with color blending.
|
## Draws one image onto another using integer x,y offset with color blending.
|
||||||
result = newImage(a.width, a.height)
|
result = newImage(a.width, a.height)
|
||||||
for yd in 0 ..< a.width:
|
for yd in 0 ..< a.width:
|
||||||
for xd in 0 ..< a.height:
|
for xd in 0 ..< a.height:
|
||||||
var rgba = a.getRgbaUnsafe(xd, yd)
|
var rgba = a.getRgbaUnsafe(xd, yd)
|
||||||
if b.inside(xd + x, yd + y):
|
if b.inside(xd - x, yd - y):
|
||||||
var rgba2 = b.getRgbaUnsafe(xd + x, yd + y)
|
var rgba2 = b.getRgbaUnsafe(xd - x, yd - y)
|
||||||
if blendMode.hasEffect(rgba2):
|
if blendMode.hasEffect(rgba2):
|
||||||
rgba = blendMode.mix(rgba, rgba2)
|
rgba = blendMode.mix(rgba, rgba2)
|
||||||
result.setRgbaUnsafe(xd, yd, rgba)
|
result.setRgbaUnsafe(xd, yd, rgba)
|
||||||
|
|
||||||
proc drawFast*(a: Image, b: Image, mat: Mat3, blendMode: BlendMode): Image =
|
proc drawFast3*(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 = newImage(a.width, a.height)
|
result = newImage(a.width, a.height)
|
||||||
|
var matInv = mat.inverse()
|
||||||
for y in 0 ..< a.width:
|
for y in 0 ..< a.width:
|
||||||
for x in 0 ..< a.height:
|
for x in 0 ..< a.height:
|
||||||
var rgba = a.getRgbaUnsafe(x, y)
|
var rgba = a.getRgbaUnsafe(x, y)
|
||||||
let srcPos = mat * 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):
|
||||||
rgba = blendMode.mix(rgba, rgba2)
|
rgba = blendMode.mix(rgba, rgba2)
|
||||||
result.setRgbaUnsafe(x, y, rgba)
|
result.setRgbaUnsafe(x, y, rgba)
|
||||||
|
|
||||||
proc draw*(a: Image, b: Image, mat: Mat3, blendMode = Normal): Image =
|
proc drawFast4*(a: Image, b: Image, mat: Mat3, blendMode: BlendMode): Image =
|
||||||
|
## Draws one image onto another using matrix with color blending.
|
||||||
|
result = newImage(a.width, a.height)
|
||||||
|
var matInv = mat.inverse()
|
||||||
|
for y in 0 ..< a.width:
|
||||||
|
for x in 0 ..< a.height:
|
||||||
|
var rgba = a.getRgbaUnsafe(x, y)
|
||||||
|
let srcPos = matInv * vec2(x.float32, y.float32)
|
||||||
|
if b.inside(srcPos.x.floor.int, srcPos.y.floor.int):
|
||||||
|
let rgba2 = b.getRgbaUnsafe(srcPos.x.floor.int, srcPos.y.floor.int)
|
||||||
|
if blendMode.hasEffect(rgba2):
|
||||||
|
rgba = blendMode.mix(rgba, rgba2)
|
||||||
|
result.setRgbaUnsafe(x, y, rgba)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
if mat[0, 0] == 1 and mat[0, 1] == 0 and
|
if mat[0, 0] == 1 and mat[0, 1] == 0 and
|
||||||
mat[1, 0] == 0 and mat[1, 1] == 1 and
|
mat[1, 0] == 0 and mat[1, 1] == 1 and
|
||||||
mat[2, 0].fraction == 0.0 and mat[2, 1].fraction == 0.0:
|
mat[2, 0].fraction == 0.0 and mat[2, 1].fraction == 0.0:
|
||||||
# Matrix is simple integer translation fast path:
|
# Matrix is simple integer translation fast path:
|
||||||
if blendMode == Copy:
|
if blendMode == bmCopy:
|
||||||
echo "use 1"
|
#echo "use 1"
|
||||||
return drawFast(
|
return drawFast1(
|
||||||
a, b, mat[2, 0].int, mat[2, 1].int
|
a, b, mat[2, 0].int, mat[2, 1].int
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
echo "use 2"
|
#echo "use 2"
|
||||||
return drawFast(
|
return drawFast2(
|
||||||
a, b, mat[2, 0].int, mat[2, 1].int, blendMode
|
a, b, mat[2, 0].int, mat[2, 1].int, blendMode
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let ns = [-1.float32, 0, 1]
|
||||||
|
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[2, 0].fraction == 0.0 and mat[2, 1].fraction == 0.0:
|
||||||
|
echo "use 4"
|
||||||
|
return drawFast4(
|
||||||
|
a, b, mat, blendMode
|
||||||
|
)
|
||||||
|
|
||||||
# Todo: if matrix is a simple flip -> fast path
|
# Todo: if matrix is a simple flip -> fast path
|
||||||
echo "use 3"
|
# 4 rotation x 3 flips = 12 combo
|
||||||
return drawFast(a, b, mat, blendMode)
|
#echo "use 3"
|
||||||
|
return drawFast3(a, b, mat, blendMode)
|
||||||
|
|
||||||
|
|
||||||
proc draw*(a: Image, b: Image, pos = vec2(0, 0), blendMode = Normal): 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)
|
||||||
|
|
119
tests/benchmark_draw.nim
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
import pixie, chroma, vmath, fidget/opengl/perf, pixie/fileformats/bmp
|
||||||
|
|
||||||
|
timeIt "benchDrawFast1 COPY":
|
||||||
|
var tmp = 0
|
||||||
|
var c: Image
|
||||||
|
for i in 0 ..< 1000:
|
||||||
|
var a = newImage(100, 100)
|
||||||
|
a.fill(rgba(255, 0, 0, 255))
|
||||||
|
var b = newImage(100, 100)
|
||||||
|
b.fill(rgba(0, 255, 0, 255))
|
||||||
|
c = a.drawFast1(b, x = 25, y = 25) # Copy
|
||||||
|
tmp += c.width * c.height
|
||||||
|
c.writeFile("tests/images/benchDrawFast1Copy.png")
|
||||||
|
echo tmp
|
||||||
|
|
||||||
|
timeIt "benchDrawFast2 COPY":
|
||||||
|
var tmp = 0
|
||||||
|
var c: Image
|
||||||
|
for i in 0 ..< 1000:
|
||||||
|
var a = newImage(100, 100)
|
||||||
|
a.fill(rgba(255, 0, 0, 255))
|
||||||
|
var b = newImage(100, 100)
|
||||||
|
b.fill(rgba(0, 255, 0, 255))
|
||||||
|
c = a.drawFast2(b, x = 25, y = 25, bmCopy)
|
||||||
|
tmp += c.width * c.height
|
||||||
|
c.writeFile("tests/images/benchDrawFast2Copy.png")
|
||||||
|
echo tmp
|
||||||
|
|
||||||
|
timeIt "benchDrawFast3 COPY":
|
||||||
|
var tmp = 0
|
||||||
|
var c: Image
|
||||||
|
for i in 0 ..< 1000:
|
||||||
|
var a = newImage(100, 100)
|
||||||
|
a.fill(rgba(255, 0, 0, 255))
|
||||||
|
var b = newImage(100, 100)
|
||||||
|
b.fill(rgba(0, 255, 0, 255))
|
||||||
|
c = a.drawFast3(b, translate(vec2(25, 25)), bmCopy)
|
||||||
|
tmp += c.width * c.height
|
||||||
|
c.writeFile("tests/images/benchDrawFast3Copy.png")
|
||||||
|
echo tmp
|
||||||
|
|
||||||
|
timeIt "benchDrawFast2 Normal":
|
||||||
|
var tmp = 0
|
||||||
|
var c: Image
|
||||||
|
for i in 0 ..< 1000:
|
||||||
|
var a = newImage(100, 100)
|
||||||
|
a.fill(rgba(255, 0, 0, 255))
|
||||||
|
var b = newImage(100, 100)
|
||||||
|
b.fill(rgba(0, 255, 0, 255))
|
||||||
|
c = a.drawFast2(b, x = 25, y = 25, bmNormal)
|
||||||
|
tmp += c.width * c.height
|
||||||
|
c.writeFile("tests/images/benchDrawFast2Normal.png")
|
||||||
|
echo tmp
|
||||||
|
|
||||||
|
timeIt "benchDrawFast3 Normal":
|
||||||
|
var tmp = 0
|
||||||
|
var c: Image
|
||||||
|
for i in 0 ..< 1000:
|
||||||
|
var a = newImage(100, 100)
|
||||||
|
a.fill(rgba(255, 0, 0, 255))
|
||||||
|
var b = newImage(100, 100)
|
||||||
|
b.fill(rgba(0, 255, 0, 255))
|
||||||
|
c = a.drawFast3(b, translate(vec2(25, 25)), bmNormal)
|
||||||
|
tmp += c.width * c.height
|
||||||
|
c.writeFile("tests/images/benchDrawFast3Normal.png")
|
||||||
|
echo tmp
|
||||||
|
|
||||||
|
timeIt "benchDrawFast2 Saturation":
|
||||||
|
var tmp = 0
|
||||||
|
var c: Image
|
||||||
|
for i in 0 ..< 1000:
|
||||||
|
var a = newImage(100, 100)
|
||||||
|
a.fill(rgba(255, 0, 0, 255))
|
||||||
|
var b = newImage(100, 100)
|
||||||
|
b.fill(rgba(0, 0, 0, 255))
|
||||||
|
c = a.drawFast2(b, x = 25, y = 25, bmSaturation)
|
||||||
|
tmp += c.width * c.height
|
||||||
|
c.writeFile("tests/images/benchDrawFast2Saturation.png")
|
||||||
|
echo tmp
|
||||||
|
|
||||||
|
timeIt "benchDrawFast3 Saturation":
|
||||||
|
var tmp = 0
|
||||||
|
var c: Image
|
||||||
|
for i in 0 ..< 1000:
|
||||||
|
var a = newImage(100, 100)
|
||||||
|
a.fill(rgba(255, 0, 0, 255))
|
||||||
|
var b = newImage(100, 100)
|
||||||
|
b.fill(rgba(0, 0, 0, 255))
|
||||||
|
c = a.drawFast3(b, translate(vec2(25, 25)), bmSaturation)
|
||||||
|
tmp += c.width * c.height
|
||||||
|
c.writeFile("tests/images/benchDrawFast3Saturation.png")
|
||||||
|
echo tmp
|
||||||
|
|
||||||
|
|
||||||
|
timeIt "benchDrawFast4 Rotation":
|
||||||
|
var tmp = 0
|
||||||
|
var c: Image
|
||||||
|
for i in 0 ..< 1000:
|
||||||
|
var a = newImage(100, 100)
|
||||||
|
a.fill(rgba(255, 0, 0, 255))
|
||||||
|
var b = newImage(100, 100)
|
||||||
|
b.fill(rgba(0, 0, 0, 255))
|
||||||
|
c = a.drawFast4(b, translate(vec2(25, 25)) * rotationMat3(PI/2), bmNormal)
|
||||||
|
tmp += c.width * c.height
|
||||||
|
c.writeFile("tests/images/benchDrawFast2Rotation.png")
|
||||||
|
echo tmp
|
||||||
|
|
||||||
|
timeIt "benchDrawFast3 Rotation":
|
||||||
|
var tmp = 0
|
||||||
|
var c: Image
|
||||||
|
for i in 0 ..< 1000:
|
||||||
|
var a = newImage(100, 100)
|
||||||
|
a.fill(rgba(255, 0, 0, 255))
|
||||||
|
var b = newImage(100, 100)
|
||||||
|
b.fill(rgba(0, 0, 0, 255))
|
||||||
|
c = a.drawFast3(b, translate(vec2(25, 25)) * rotationMat3(PI/2), bmNormal)
|
||||||
|
tmp += c.width * c.height
|
||||||
|
c.writeFile("tests/images/benchDrawFast3Rotation.png")
|
||||||
|
echo tmp
|
|
@ -1,6 +1,6 @@
|
||||||
import pixie, chroma, vmath, fidget/opengl/perf, pixie/fileformats/bmp
|
import pixie, chroma, vmath, fidget/opengl/perf, pixie/fileformats/bmp
|
||||||
|
|
||||||
proc inPlaceDraw*(destImage: Image, srcImage: Image, mat: Mat3, blendMode = Normal) =
|
proc inPlaceDraw*(destImage: Image, srcImage: Image, mat: Mat3, blendMode = bmNormal) =
|
||||||
## Draws one image onto another using matrix with color blending.
|
## Draws one image onto another using matrix with color blending.
|
||||||
for y in 0 ..< destImage.width:
|
for y in 0 ..< destImage.width:
|
||||||
for x in 0 ..< destImage.height:
|
for x in 0 ..< destImage.height:
|
||||||
|
@ -14,7 +14,7 @@ proc inPlaceDraw*(destImage: Image, srcImage: Image, mat: Mat3, blendMode = Norm
|
||||||
rgba = blendMode.mix(destRgba, srcRgba)
|
rgba = blendMode.mix(destRgba, srcRgba)
|
||||||
destImage.setRgbaUnsafe(x, y, rgba)
|
destImage.setRgbaUnsafe(x, y, rgba)
|
||||||
|
|
||||||
proc inPlaceDraw*(destImage: Image, srcImage: Image, pos = vec2(0, 0), blendMode = Normal) =
|
proc inPlaceDraw*(destImage: Image, srcImage: Image, pos = vec2(0, 0), blendMode = bmNormal) =
|
||||||
destImage.inPlaceDraw(srcImage, translate(-pos), blendMode)
|
destImage.inPlaceDraw(srcImage, translate(-pos), blendMode)
|
||||||
|
|
||||||
block:
|
block:
|
||||||
|
@ -30,7 +30,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))
|
||||||
var c = a.draw(b, pos=vec2(25, 25))
|
var c = a.drawFast3(b, translate(vec2(25, 25)), bmNormal)
|
||||||
writeFile("tests/images/copyDraw.bmp", c.encodeBmp())
|
writeFile("tests/images/copyDraw.bmp", c.encodeBmp())
|
||||||
|
|
||||||
timeIt "inPlaceDraw":
|
timeIt "inPlaceDraw":
|
||||||
|
@ -51,6 +51,6 @@ timeIt "copyDraw":
|
||||||
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.draw(b, pos=vec2(25, 25))
|
var c = a.drawFast3(b, translate(vec2(25, 25)), bmNormal)
|
||||||
tmp += c.width * c.height
|
tmp += c.width * c.height
|
||||||
echo tmp
|
echo tmp
|
BIN
tests/images/benchDrawFast1Copy.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
tests/images/benchDrawFast2Copy.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
tests/images/benchDrawFast2Normal.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
tests/images/benchDrawFast2Rotation.png
Normal file
After Width: | Height: | Size: 339 B |
BIN
tests/images/benchDrawFast2Saturation.png
Normal file
After Width: | Height: | Size: 337 B |
BIN
tests/images/benchDrawFast3Copy.png
Normal file
After Width: | Height: | Size: 339 B |
BIN
tests/images/benchDrawFast3Normal.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
tests/images/benchDrawFast3Rotation.png
Normal file
After Width: | Height: | Size: 329 B |
BIN
tests/images/benchDrawFast3Saturation.png
Normal file
After Width: | Height: | Size: 337 B |
BIN
tests/images/drawFast1.master.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
tests/images/drawFast1.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
tests/images/drawFast2.master.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
tests/images/drawFast2.png
Normal file
After Width: | Height: | Size: 328 B |
BIN
tests/images/drawFast3.master.png
Normal file
After Width: | Height: | Size: 358 B |
BIN
tests/images/drawFast3.png
Normal file
After Width: | Height: | Size: 358 B |
BIN
tests/images/drawFast3Rot.master.png
Normal file
After Width: | Height: | Size: 375 B |
BIN
tests/images/drawFast3Rot.png
Normal file
After Width: | Height: | Size: 375 B |
BIN
tests/images/drawFast4.master.png
Normal file
After Width: | Height: | Size: 336 B |
BIN
tests/images/drawFast4.png
Normal file
After Width: | Height: | Size: 336 B |
BIN
tests/images/drawFast4Rot.master.png
Normal file
After Width: | Height: | Size: 336 B |
BIN
tests/images/drawFast4Rot.png
Normal file
After Width: | Height: | Size: 336 B |
Before Width: | Height: | Size: 356 B After Width: | Height: | Size: 358 B |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
@ -4,7 +4,8 @@ proc writeAndCheck(image: Image, fileName: string) =
|
||||||
image.writeFile(fileName)
|
image.writeFile(fileName)
|
||||||
let masterFileName = fileName.changeFileExt(".master.png")
|
let masterFileName = fileName.changeFileExt(".master.png")
|
||||||
if not existsFile(masterFileName):
|
if not existsFile(masterFileName):
|
||||||
quit("Master file: " & masterFileName & " not found!")
|
echo "Master file: " & masterFileName & " not found!"
|
||||||
|
return
|
||||||
var master = readImage(fileName)
|
var master = readImage(fileName)
|
||||||
assert image.width == master.width
|
assert image.width == master.width
|
||||||
assert image.height == master.height
|
assert image.height == master.height
|
||||||
|
@ -25,21 +26,32 @@ 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.draw(b, pos=vec2(25, 25))
|
var c = a.drawFast1(b, x=25, y=25)
|
||||||
c.writeAndCheck("tests/images/draw.png")
|
c.writeAndCheck("tests/images/drawFast1.png")
|
||||||
|
|
||||||
block:
|
block:
|
||||||
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.draw(b, pos=vec2(25, 25), COPY)
|
var c = a.drawFast2(b, x=25, y=25, bmCopy)
|
||||||
c.writeAndCheck("tests/images/drawCopy.png")
|
c.writeAndCheck("tests/images/drawFast2.png")
|
||||||
|
|
||||||
block:
|
block:
|
||||||
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.draw(b, pos=vec2(25.15, 25.15))
|
var c = a.drawFast3(b, translate(vec2(25.15, 25.15)), bmCopy)
|
||||||
c.writeAndCheck("tests/images/drawSmooth.png")
|
c.writeAndCheck("tests/images/drawFast3.png")
|
||||||
|
|
||||||
|
block:
|
||||||
|
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.drawFast4(b, translate(vec2(25.15, 25.15)) * rotationMat3(PI/2), bmCopy)
|
||||||
|
c.writeAndCheck("tests/images/drawFast4Rot.png")
|
||||||
|
|
||||||
|
var d = a.drawFast3(b, translate(vec2(25.15, 25.15)) * rotationMat3(PI/2), bmCopy)
|
||||||
|
d.writeAndCheck("tests/images/drawFast3Rot.png")
|
||||||
|
|