mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-31 00:32:48 +00:00
ffc3684b1b
Maintain hierarchical structure of sprite groups instead of flattening. Allows opacity and blend mode to be applied correctly to groups. Sets the foundation for future features like mask layers. Note: Requires full image rendering and impacts performance in some scenarios. Avoids complex code changes for minor performance gains. Co-authored-by: Guilherme Marcondes <guilherme.marcondes@tecnico.ulisboa.pt>
186 lines
5.8 KiB
Lua
186 lines
5.8 KiB
Lua
-- Copyright (C) 2024 Igara Studio S.A.
|
|
--
|
|
-- This file is released under the terms of the MIT license.
|
|
-- Read LICENSE.txt for more information.
|
|
|
|
dofile('./test_utils.lua')
|
|
|
|
-- Enable experimental compose groups feature
|
|
app.preferences.experimental.compose_groups = true
|
|
|
|
function create_group_layer()
|
|
local s = Sprite(2, 2)
|
|
assert(#s.layers == 1)
|
|
|
|
-- create two layers and a group layer
|
|
local a = s.layers[1] a.name = "a"
|
|
assert(#s.layers == 1)
|
|
local b = s:newLayer() b.name = "b"
|
|
assert(#s.layers == 2)
|
|
local g = s:newGroup() g.name = "g"
|
|
assert(#s.layers == 3)
|
|
|
|
-- b is child of g
|
|
b.parent = g
|
|
assert(g.parent == s)
|
|
assert(b.parent == g)
|
|
|
|
assert(#s.layers == 2)
|
|
assert(s.layers[1] == a)
|
|
assert(s.layers[2] == g)
|
|
|
|
return s, a, b, g
|
|
end
|
|
|
|
-- Test groups opacity to impact on children layers
|
|
do
|
|
assert(app.preferences.experimental.compose_groups == true)
|
|
|
|
local s, a, b, g = create_group_layer()
|
|
|
|
-- draw in b layer
|
|
local cel = s:newCel(b, 1, Image(2, 2, ColorMode.RGB))
|
|
local img = cel.image
|
|
|
|
img:drawPixel(0, 0, Color(255, 0, 0, 255))
|
|
img:drawPixel(1, 0, Color(0, 255, 0, 255))
|
|
img:drawPixel(0, 1, Color(0, 0, 255, 255))
|
|
img:drawPixel(1, 1, Color(255, 255, 0, 255))
|
|
|
|
local r = Image(s.spec) -- render
|
|
r:drawSprite(s, 1, 0, 0)
|
|
|
|
expect_clr(r:getPixel(0, 0), app.pixelColor.rgba(255, 0, 0, 255))
|
|
expect_clr(r:getPixel(1, 0), app.pixelColor.rgba(0, 255, 0, 255))
|
|
expect_clr(r:getPixel(0, 1), app.pixelColor.rgba(0, 0, 255, 255))
|
|
expect_clr(r:getPixel(1, 1), app.pixelColor.rgba(255, 255, 0, 255))
|
|
|
|
-- Set opacity to 50%
|
|
g.opacity = 128
|
|
|
|
r = Image(s.spec)
|
|
r:drawSprite(s, 1, 0, 0)
|
|
|
|
print(g.opacity)
|
|
|
|
print(r:getPixel(0, 0), app.pixelColor.rgba(255, 0, 0, 255))
|
|
|
|
-- Assert that the image is drawn with 50% opacity
|
|
expect_clr(r:getPixel(0, 0), app.pixelColor.rgba(255, 0, 0, 128))
|
|
expect_clr(r:getPixel(1, 0), app.pixelColor.rgba(0, 255, 0, 128))
|
|
expect_clr(r:getPixel(0, 1), app.pixelColor.rgba(0, 0, 255, 128))
|
|
expect_clr(r:getPixel(1, 1), app.pixelColor.rgba(255, 255, 0, 128))
|
|
|
|
-- Set opacity to 100%
|
|
g.opacity = 255
|
|
|
|
r = Image(s.spec)
|
|
r:drawSprite(s, 1, 0, 0)
|
|
|
|
expect_eq(g.opacity, 255)
|
|
|
|
-- Assert that the image is drawn with 100% opacity
|
|
expect_clr(r:getPixel(0, 0), app.pixelColor.rgba(255, 0, 0, 255))
|
|
expect_clr(r:getPixel(1, 0), app.pixelColor.rgba(0, 255, 0, 255))
|
|
expect_clr(r:getPixel(0, 1), app.pixelColor.rgba(0, 0, 255, 255))
|
|
expect_clr(r:getPixel(1, 1), app.pixelColor.rgba(255, 255, 0, 255))
|
|
|
|
-- Set group opacity to 50% and layer opacity to 50%
|
|
g.opacity = 128
|
|
b.opacity = 128
|
|
|
|
r = Image(s.spec)
|
|
r:drawSprite(s, 1, 0, 0)
|
|
|
|
assert(g.opacity == 128)
|
|
assert(b.opacity == 128)
|
|
|
|
-- Assert that the image is drawn with 25% opacity
|
|
expect_clr(r:getPixel(0, 0), app.pixelColor.rgba(255, 0, 0, 64))
|
|
expect_clr(r:getPixel(1, 0), app.pixelColor.rgba(0, 255, 0, 64))
|
|
expect_clr(r:getPixel(0, 1), app.pixelColor.rgba(0, 0, 255, 64))
|
|
expect_clr(r:getPixel(1, 1), app.pixelColor.rgba(255, 255, 0, 64))
|
|
|
|
-- Create a new layer in front of the group and check that it's not affected by the group opacity
|
|
local c = s:newLayer()
|
|
c.name = "c"
|
|
|
|
-- draw in c layer
|
|
local cel = s:newCel(c, 1, Image(1, 1, ColorMode.RGB))
|
|
local img = cel.image
|
|
|
|
img:drawPixel(0, 0, Color(255, 0, 255, 255))
|
|
|
|
r = Image(s.spec)
|
|
r:drawSprite(s, 1, 0, 0)
|
|
|
|
-- Assert that the first pixel is drawn with 100% opacity and the remaining ones with 25% opacity
|
|
expect_clr(r:getPixel(0, 0), app.pixelColor.rgba(255, 0, 255, 255))
|
|
expect_clr(r:getPixel(1, 0), app.pixelColor.rgba(0, 255, 0, 64))
|
|
expect_clr(r:getPixel(0, 1), app.pixelColor.rgba(0, 0, 255, 64))
|
|
expect_clr(r:getPixel(1, 1), app.pixelColor.rgba(255, 255, 0, 64))
|
|
|
|
end
|
|
|
|
do -- test group blend to impact children layers
|
|
assert(app.preferences.experimental.compose_groups == true)
|
|
|
|
local s, a, b, g = create_group_layer()
|
|
|
|
-- draw all black in layer a
|
|
local cel = s:newCel(a, 1, Image(2, 2, ColorMode.RGB))
|
|
local img = cel.image
|
|
|
|
img:drawPixel(0, 0, Color(0, 0, 0, 255))
|
|
img:drawPixel(1, 0, Color(0, 0, 0, 255))
|
|
img:drawPixel(0, 1, Color(0, 0, 0, 255))
|
|
img:drawPixel(1, 1, Color(0, 0, 0, 255))
|
|
|
|
-- draw in b layer
|
|
local cel = s:newCel(b, 1, Image(2, 2, ColorMode.RGB))
|
|
local img = cel.image
|
|
|
|
img:drawPixel(0, 0, Color(255, 0, 0, 255))
|
|
img:drawPixel(1, 0, Color(0, 255, 0, 255))
|
|
img:drawPixel(0, 1, Color(0, 0, 255, 255))
|
|
img:drawPixel(1, 1, Color(255, 255, 0, 255))
|
|
|
|
local r = Image(s.spec) -- render
|
|
r:drawSprite(s, 1, 0, 0)
|
|
|
|
expect_clr(r:getPixel(0, 0), app.pixelColor.rgba(255, 0, 0, 255))
|
|
expect_clr(r:getPixel(1, 0), app.pixelColor.rgba(0, 255, 0, 255))
|
|
expect_clr(r:getPixel(0, 1), app.pixelColor.rgba(0, 0, 255, 255))
|
|
expect_clr(r:getPixel(1, 1), app.pixelColor.rgba(255, 255, 0, 255))
|
|
|
|
-- Set blend to MULTIPLY
|
|
g.blendMode = BlendMode.MULTIPLY
|
|
|
|
r = Image(s.spec)
|
|
r:drawSprite(s, 1, 0, 0)
|
|
|
|
-- Assert that the image is drawn with MULTIPLY blend mode
|
|
expect_clr(r:getPixel(0, 0), app.pixelColor.rgba(0, 0, 0, 255))
|
|
expect_clr(r:getPixel(1, 0), app.pixelColor.rgba(0, 0, 0, 255))
|
|
expect_clr(r:getPixel(0, 1), app.pixelColor.rgba(0, 0, 0, 255))
|
|
expect_clr(r:getPixel(1, 1), app.pixelColor.rgba(0, 0, 0, 255))
|
|
|
|
-- Create a new layer in front of the group and check that it's not affected by the group blend mode
|
|
local c = s:newLayer()
|
|
c.name = "c"
|
|
|
|
-- draw in c layer
|
|
local cel = s:newCel(c, 1, Image(1, 1, ColorMode.RGB))
|
|
local img = cel.image
|
|
|
|
img:drawPixel(0, 0, Color(255, 0, 255, 255))
|
|
|
|
r = Image(s.spec)
|
|
r:drawSprite(s, 1, 0, 0)
|
|
|
|
-- Assert that the first pixel is drawn with Normal blend mode and the remaining ones with Multiply blend mode
|
|
expect_clr(r:getPixel(0, 0), app.pixelColor.rgba(255, 0, 255, 255))
|
|
expect_clr(r:getPixel(1, 0), app.pixelColor.rgba(0, 0, 0, 255))
|
|
expect_clr(r:getPixel(0, 1), app.pixelColor.rgba(0, 0, 0, 255))
|
|
expect_clr(r:getPixel(1, 1), app.pixelColor.rgba(0, 0, 0, 255))
|
|
end |