Draw Pixels (Native Extension)


Draw Pixels.apk.zip (2.3 MB) - apk for performance testing

Defold engine native extension for drawing pixels and simple geometry into texture buffer.
Thanks @britzl and @Mathias_Westerdahl for help.

(Like a result of this polling)

Feel free to contribute!

If you want to contribute and don’t know what you can do, look into next list:

  • Draw rectangle by two corner dots
  • Draw line with thickness parameter
  • Anti aliasing
  • (Done!!! thanks @thekrasnikoff) Bézier curves
  • (Done!!! thanks @britzl )Draw line




How to make a drawing game?
Drawing dynamic custom shapes from edge coordinates
Strange behavior of a sprite loaded from resource.set_texture (SOLVED)

Great! Is this to be used for debugging, or fast enough to be used in games?



It depend of your game, but I have plans to use it in one of my game, yes.
I added into main post apk for performance testing.



NE was updated with new parameter “angle” for filled rectangle



Draw pixels NE has a lot of changes after my last post here. Small status update for people who don’t follow repository on github.

First of all huge THANKS to all contributors: @britzl, @d954mas, @thekrasnikoff ! Thank you guys!

New methods:
drawpixels.pixel(buffer, x, y, r, g, b, a) to draw a pixel to the buffer
drawpixels.color(buffer, x, y) to read color from buffer
drawpixels.line(buffer_info, x0, y0, x1, y1, red, green, blue, alpha) to draw a line to the buffer
drawpixels.bezier(buffer_info, x0, y0, xc, yc, x1, y1, red, green, blue, alpha) draw a bezier line between two points and one control point

Refactoring and code clearing
Performance optimisation!!!
Bug fixing

Release notes for every release avaliable on this page: https://github.com/AGulev/drawpixels/releases



Correct link: https://defold.com/assets/drawpixels/



Is there a way to draw on top of a predefined texture/png? Rather than starting with a “blank canvas”?



It is possible

I did this right now in the example, so I will give the function code init

function init(self)
  msg.post("@render:", "clear_color", {color = vmath.vector4(1, 1, 1, 1)})
  -- size of texture when scaled to nearest power of two
  local width = 1024
  local height = 2048
  local channels = 4
  local file = io.open("image.png", "rb")
  local bytes = file:read("*a")
  local png = image.load(bytes,true)
  local my_buffer = png.buffer
  -- we have to create table with next fields: buffer, width, height, channels
  self.buffer_info = {
    buffer = buffer.create(#my_buffer, { {name=hash("rgba"), type=buffer.VALUE_TYPE_UINT8, count=4} } ),
    width = width,
    height = height,
    channels = channels -- 3 for rgb, 4 for rgba
  local stream = buffer.get_stream(self.buffer_info.buffer, hash("rgba"))
  for i = 1, #my_buffer do
    stream[i] = string.byte(my_buffer, i)
  self.dirty = true
  self.current_color = vmath.vector4(0, 0, 0, 1)
  self.current_tool = "pencil"
  -- drawing params
  self.prev_pos = vmath.vector3()
  self.resource_path = go.get("#sprite", "texture0")
  self.header = {
    width = width,
    height = height,
    type = resource.TEXTURE_TYPE_2D,
    format = resource.TEXTURE_FORMAT_RGBA,
    num_mip_maps = 1
  self.rotation = 0


That is BEAUTIFUL. Thanks! This is a powerful extension.



I’ve been playing with this a while and it’s so much fun! I’m stuck trying to create “canvas” instances dynamically. This doesn’t work because the pixels are tied to this bitmap:

self.resource_path = go.get("#sprite", "texture0")

What’s drawn on one canvas is therefore also drawn to the other. One solution is to use two separate sprites. In my case that won’t work, because my (ambitious) plan is to create (literally) millions canvases dynamically, each different from the others.

Is it possible to create a texture on the fly somehow? I noticed this is possible in GUI, but I haven’t been able to find a similar way to do it with a go.

Here is a minimal example of the issue: PixelDrawInstances.zip (5.4 MB)

Edit: If textures cannot be created at runtime, I suppose one workaround would be to re-use a pool of 10 sprites or so, and make sure none of the visible canvases are using the same sprite.



Well you’re going to have to limit yourself. Each canvas takes up texture memory and there’s only a certain amount of it available. Think of a max amount that you can support (think about target platform and min GPU memory you want to support) and design around that.

1 Like


Yes, wise words. This is exciting though, a lot of possibilities for a nice side project!



New DrawPixels 2.0.0

  • New API methods: drawpixels.gradient_line() , drawpixels.arc() , drawpixels.filled_arc() , drawpixels.gradient_arc() , drawpixels.start_fill() , drawpixels.end_fill() , drawpixels.fill_area() .
  • Antialiasing option for the following functions: drawpixels.filled_circle() , drawpixels.line() , drawpixels.circle() .
  • Line width option for the following functions: drawpixels.circle() , drawpixels.line() .
  • premultiply_alpha option.

Thanks @sergeysinyavsky for these improvements!



Great work. This is turning into a Legendary Extension ™!



Really great, thanks.

I think I have a really simple request:

How exactly would I add stickers (sprites) to the example? (As in draw with smilies or something)