transparency support

This commit is contained in:
BuckarooBanzay 2024-05-22 10:32:27 +02:00
parent f339dc1c47
commit c300004da8
4 changed files with 44 additions and 33 deletions

View File

@ -8,6 +8,22 @@ function Canvas:get_index(x, y)
return (self.width * y) + x + 1 return (self.width * y) + x + 1
end end
function Canvas:add_pixel(x, y, fg)
fg.a = fg.a or 255
local i = self:get_index(x, y)
local bg = self.png_data[i]
local a = fg.a / 255
local ai = 1 - a
self.png_data[i] = {
r = ((fg.r * a) + (bg.r * ai)),
g = ((fg.g * a) + (bg.g * ai)),
b = ((fg.b * a) + (bg.b * ai)),
a = math.max(bg.a, fg.a)
}
end
function Canvas:set_pixel(x, y, colorspec) function Canvas:set_pixel(x, y, colorspec)
local i = self:get_index(x, y) local i = self:get_index(x, y)
self.png_data[i] = colorspec self.png_data[i] = colorspec

View File

@ -40,14 +40,29 @@ function isogen.get_cube_position(center_x, center_y, cube_len, _, pos)
return x, y return x, y
end end
function isogen.probe_position(min, max, pos, ipos) function isogen.probe_position(min, max, pos, ipos, list)
list = list or {}
while vector.in_area(pos, min, max) do while vector.in_area(pos, min, max) do
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if node.name ~= "air" and node.name ~= "ignore" then local color = isogen.get_color(node)
return node, pos if color then
local rel_pos = vector.subtract(pos, min)
local rel_max = vector.subtract(max, min)
local order =
(rel_pos.y * (rel_max.x * rel_max.z)) +
(rel_max.x - rel_pos.x) +
(rel_max.z - rel_pos.z)
table.insert(list, {
pos = pos,
color = color,
order = order,
node = node
})
end end
pos = vector.add(pos, ipos) pos = vector.add(pos, ipos)
end end
return list
end end
local function flip_pos(pos, max, axis) local function flip_pos(pos, max, axis)

View File

@ -1,22 +1,4 @@
local function probe_and_add(list, min, max, pos, ipos)
local node, npos = isogen.probe_position(min, max, pos, ipos)
if node then
local rel_pos = vector.subtract(npos, min)
local rel_max = vector.subtract(max, min)
local order =
(rel_pos.y * (rel_max.x * rel_max.z)) +
(rel_max.x - rel_pos.x) +
(rel_max.z - rel_pos.z)
table.insert(list, {
node = node,
pos = npos,
order = order
})
end
end
local function clamp(v, min, max) local function clamp(v, min, max)
if v > max then if v > max then
return max return max
@ -53,21 +35,21 @@ function isogen.draw(pos1, pos2, cube_len)
-- top layer -- top layer
for x=min.x, max.x do for x=min.x, max.x do
for z=min.z, max.z do for z=min.z, max.z do
probe_and_add(list, min, max, vector.new(x, max.y, z), ipos) isogen.probe_position(min, max, vector.new(x, max.y, z), ipos, list)
end end
end end
-- left layer (without top stride) -- left layer (without top stride)
for x=min.x, max.x do for x=min.x, max.x do
for y=min.y, max.y-1 do for y=min.y, max.y-1 do
probe_and_add(list, min, max, vector.new(x, y, min.z), ipos) isogen.probe_position(min, max, vector.new(x, y, min.z), ipos, list)
end end
end end
-- right layer (without top and left stride) -- right layer (without top and left stride)
for z=min.z+1, max.z do for z=min.z+1, max.z do
for y=min.y, max.y-1 do for y=min.y, max.y-1 do
probe_and_add(list, min, max, vector.new(min.x, y, z), ipos) isogen.probe_position(min, max, vector.new(min.x, y, z), ipos, list)
end end
end end
@ -77,12 +59,10 @@ function isogen.draw(pos1, pos2, cube_len)
for _, entry in ipairs(list) do for _, entry in ipairs(list) do
local rel_pos = vector.subtract(entry.pos, min) local rel_pos = vector.subtract(entry.pos, min)
local color = isogen.get_color(entry.node) local color = entry.color
if color then
local x, y = isogen.get_cube_position(center_x, center_y, cube_len, 0, rel_pos) local x, y = isogen.get_cube_position(center_x, center_y, cube_len, 0, rel_pos)
isogen.draw_cube(canvas, cube_len, x, y, color, color_adjust(color, -10), color_adjust(color, 10)) isogen.draw_cube(canvas, cube_len, x, y, color, color_adjust(color, -10), color_adjust(color, 10))
end end
end
return canvas:png() return canvas:png()
end end

View File

@ -11,9 +11,9 @@ function isogen.draw_cube(canvas, cube_len, x_offset, y_offset, color1, color2,
for x=0,half_len_zero_indexed do for x=0,half_len_zero_indexed do
for y=0,half_len_zero_indexed do for y=0,half_len_zero_indexed do
-- left -- left
canvas:set_pixel(x_offset+x, y_offset+y+quarter_len+yo, color1) canvas:add_pixel(x_offset+x, y_offset+y+quarter_len+yo, color1)
-- right -- right
canvas:set_pixel(x_offset+cube_len-1-x, y_offset+y+quarter_len+yo, color2) canvas:add_pixel(x_offset+cube_len-1-x, y_offset+y+quarter_len+yo, color2)
end end
if x % 2 == 0 then if x % 2 == 0 then
yo = yo + 1 yo = yo + 1
@ -26,9 +26,9 @@ function isogen.draw_cube(canvas, cube_len, x_offset, y_offset, color1, color2,
for x=0,half_len_zero_indexed-1 do for x=0,half_len_zero_indexed-1 do
for y=0,yl do for y=0,yl do
-- left -- left
canvas:set_pixel(x_offset+1+x, y_offset+quarter_len-1-yo+y, color3) canvas:add_pixel(x_offset+1+x, y_offset+quarter_len-1-yo+y, color3)
-- right -- right
canvas:set_pixel(x_offset+cube_len-2-x, y_offset+quarter_len-1-yo+y, color3) canvas:add_pixel(x_offset+cube_len-2-x, y_offset+quarter_len-1-yo+y, color3)
end end
if x % 2 ~= 0 then if x % 2 ~= 0 then
yo = yo + 1 yo = yo + 1