Page 1 of 1

The less consuming way to draw an image out of lists of 0 and 1 ?

Posted: Fri Apr 17, 2020 7:24 pm
by Harrylechienfou
Hi there ! Hope everybody is fine during those weird times.
So, I created a simple algorithm that creates a list of 0 and 1 with that kind of outputs (it's a silly example supposed to be a cross) :

listCreated = {
{0,0,1,1,0,0}
{0,0,1,1,0,0}
{1,1,1,1,1,1}
{0,0,1,1,0,0}
{0,0,1,1,0,0}
}

So, in that example, I have a function that reads the list and if there's a 0 it draws nothing, and if there's a 1 it draws a rectangle using love.graphics.rectangle(). But the thing is, if I want to draw a hell lot of those kind of lists, it is a lot of work for my poor computer. Since I'm planning to create a game where all the graphics are made of those kinds of lists (with sometimes more than just 0 and 1, for example with informations about the color, etc), and since I'm planning to create those "lists/graphics" procedurally on the go (I don't want to make real images out of them for that project anyway), I need to know the best/less-consuming technique out there.

Here is where I need your help : what is the best way to use those kind of lists and draw them ? I guess it is not love.graphics.rectangle(). For example, is using an image like a PNG (a simple pixel for example) instead of a rectangle() more or less consuming for the computer ? Maybe there is another way to do those kinds of things (bitmaps ? maybe a module ?) ?
Even though I don't need it for my current project, I would also love to know if you have tips or good links about actually creating an image file out of those lists of 0 and 1 (but it's a side question), like a bitmap or a PNG even, I don't know.
Sorry if my question is silly, I'm obviously not an expert in Lua programming ;)

PS : excuse my (bad) English, I'm French.

Re: The less consuming way to draw an image out of lists of 0 and 1 ?

Posted: Fri Apr 17, 2020 9:07 pm
by MrFariator
Depending on how often and how many of those lists you create at run time (or how many of them are unique, for that matter), I think you could use love.image.newImageData and ImageData:setPixel to effectively create and store those lists in memory as image data objects. That way you could draw one "list" with a single call to love.graphics.draw, and so you don't have to go through each and every 0 and 1 from all lists you'd like to draw. Of course, this approach assumes that the lists do not change their contents too often or rapidly, and that you can share the resulting image data to represent multiple list objects that look the same. Might also get some performance penalties due to switching the texture every so often, so grouping draw calls that use the same image data would be preferable.

Another approach might be using sprite batches: use a common texture to represent the colors, split that into quads, and add those quads into a sprite batch in whatever shape or formation the list lays out. Then update that sprite batch as need arises. Canvases might also be helpful in this regard; just don't update the canvas contents if nothing changes on the screen or the layer/area a canvas might cover.

There may be other (and better) approaches as well, but those are the ones that immediately come to mind.

Re: The less consuming way to draw an image out of lists of 0 and 1 ?

Posted: Fri Apr 17, 2020 10:17 pm
by pgimeno
MrFariator wrote: Fri Apr 17, 2020 9:07 pm Depending on how often and how many of those lists you create at run time (or how many of them are unique, for that matter), I think you could use love.image.newImageData and ImageData:setPixel to effectively create and store those lists in memory as image data objects. That way you could draw one "list" with a single call to love.graphics.draw,
Note that you can't draw ImageData objects. You can however use (Image):replacePixels to replace part of an Image object with ImageData.

Re: The less consuming way to draw an image out of lists of 0 and 1 ?

Posted: Fri Apr 17, 2020 10:21 pm
by MrFariator
Right, I meant to mention turning the image data into an actual image with love.graphics.newImage, but I guess I lost my train of thought somewhere along the line.

Re: The less consuming way to draw an image out of lists of 0 and 1 ?

Posted: Sun Apr 19, 2020 1:25 pm
by Harrylechienfou
Thanks for the great answers ! I tried love.image.newImageData, ImageData:setPixel and love.graphics.newImage and it seems to work just fine . I think I'll do it this way unless I encounter some performance issues with it, but I think that'll be fine.

I have another question though : Is there a way to do the exact opposite of that ? By that I mean take an actual image (like a PNG), "read it", and turn it into a Lua list, with 0 and 1 representing the actual pixels (or I guess 4 numbers per pixels if that's a color image with alpha) ?
I think maybe imageData:getPixel() is there for that purpose but I'm not sure that's really optimized...
Edit : seems to work fine too. Cool !

Re: The less consuming way to draw an image out of lists of 0 and 1 ?

Posted: Sun Apr 19, 2020 10:20 pm
by zorg
It probably would be more performant with ImageData:mapPixel

Re: The less consuming way to draw an image out of lists of 0 and 1 ?

Posted: Mon Apr 20, 2020 1:41 pm
by Ulydev
I'm wondering how efficient it would be to draw it with a fragment shader?
for example (pseudocode)

Code: Select all

return vec4(vec3(1.0, 1.0, 1.0) * array[pixel.y][pixel.x], 1.0);
I guess the bottleneck would be sending the data to the shader, but then would it be faster?