I actually initially followed your “draw_pixels” example, which took a while to study and understand. I’ve made some modifications to it, along with other algorithms like flood_fill(), etc. Here’s the bulk of it. Thanks for making those examples, by the way. Some of them have come in handy!
----------------------------------------------------------------
-- CONSTANTS
----------------------------------------------------------------
-- Size of canvas (pixels)
local WIDTH = 1024
local HEIGHT = 512
-- Buffer constructor info for convenience
local BUFFER_SIZE = WIDTH * HEIGHT
local BUFFER_INFO = { {
name = hash("rgba"),
type = buffer.VALUE_TYPE_UINT8,
count = 4
} }
-- Texture header for convenience
local HEADER = {
width = WIDTH,
height = HEIGHT,
type = resource.TEXTURE_TYPE_2D,
format = resource.TEXTURE_FORMAT_RGBA,
num_mip_maps = 1
}
----------------------------------------------------------------
-- HELPER FUNCTIONS
----------------------------------------------------------------
-- Paints a single pixel on the canvas
local function paint(self, x, y, r, g, b, a)
assert(0 <= x and x < WIDTH and 0 <= y and y < HEIGHT)
local index = y * WIDTH * 4 + x * 4 + 1
self.stream[index + 0] = r
self.stream[index + 1] = g
self.stream[index + 2] = b
self.stream[index + 3] = a
self.dirty = true
end
-- Replicates a grid of pixels by copying it to the canvas
local function replicate(self, grid, grid_width, grid_height)
assert(grid_width <= WIDTH and grid_height <= HEIGHT)
for y = 0, grid_height - 1 do
for x = 0, grid_width - 1 do
local index = y * grid_width + x + 1
paint(self, x, y, grid[index].x, grid[index].y, grid[index].z, grid[index].w)
end
end
end
----------------------------------------------------------------
-- ENGINE FUNCTIONS
----------------------------------------------------------------
-- Init canvas with a buffer and a stream with which to edit the buffer
function init(self)
self.buffer = buffer.create(BUFFER_SIZE, BUFFER_INFO)
self.stream = buffer.get_stream(self.buffer, hash("rgba"))
end
-- Update canvas with new pixels when dirty
function update(self, dt)
if self.dirty then
local path = go.get("#sprite", "texture0")
resource.set_texture(path, HEADER, self.buffer)
self.dirty = true
end
end
-- Process paint request messages
function on_message(self, message_id, message, sender)
if message_id == REPLICATE then
replicate(self, message.grid, message.grid_width, message.grid_height)
end
end