Pixel coloring problem

Yep, that’s what I thought. That should be blazingly fast - unless the afterlying code is extremely poorly programmed.

Quick chime in.  You can absolutely make an app like that with Corona and it will run fine.

Those apps very likely do not render off-screen selectable/paintable blocks.  Your game should not either.  Once you cull off-screen content there will be no issue with performance.

I think the real question here is, “What techniques should be applied to implement this?”  I’m seeing good responses above that all seem on track.

Best of luck on this.  Be sure to share in-progress  updates with us.

Also, if you get stuck, the best way to get help is to make a demo that shows the issue you’re encountering, zip it up, and share it here.  Folks will be more included to run and examine it that dig into partial code posts or just provide their own example.  i.e. It is nicer to look at and help with existing samples as long as they are small and focused.

Memory Bitmap plugin does not solve the problem. Because if you make setPixel 5000 times for example, then performance will drop. Similar loss of FPS with 5000 squares on the screen and using setPixel.

Thank you all for the answers! The best option is to draw one picture in parts, 1500 squares on the screen.

The Memory Bitmap plugin will most likely work in the same way, using the principle of creating squares. Because of this, performance drops. So the setPixel method is not justified.

Hi Buster,

Ah, it’s a shame that the setPixel function is too slow then.

In that case I would go for only drawing the visible on-screen pixels and my wrap-around idea mentioned above. Let me know if you have any problems with that.

We are doing a similar app (still a prototype). We create squares to represent the pixels and so far performance seems to be ok.

Short simple video
https://www.youtube.com/watch?v=3cwvQD6UmhM

The app also has zooming etc. but not visible in the video (recorded on simulator). 

It’s like 20 lines of code to implement the memory bitmap and see it works as expected, also it’s for sure multiple orders of magnitudes more efficient (not only in code executed on average but also wrt to resources used) and it’s also much much simpler code than to try to manually optimize/handle offscreen pixels etc.

And no, memory bitmap does not create rectangles - all it does is, it makes the bitmap used for a texture available for modifications and update/reupload/reswizzle on demand (by the invalidate method) it’s contents as required for the GPU.

Below’s a simple sample with 250.000 pixels, drawing 500 random pixels during touches which runs pretty smooth on my 4 year old 50€ Android tablet.

Now if you want to change 5000 pixels smoothly each frame it’s going to be slow on lowspec devices using Corona as it’s not a natively compiled language - a memory bitmap will still be the only valid/best available choice (besides creating a native c++ extension).

[lua]


– main.lua


local memoryBitmap = require( “plugin.memoryBitmap” )

local tex = memoryBitmap.newTexture(

    {

        width = 500,

        height = 500,

        – format = “rgba”  – (default)

        – format = “rgb”

        – format = “mask”

    })

– Create image using the bitmap texture

local bitmap = display.newImageRect( tex.filename, tex.baseDir, 500, 500 )

bitmap.x = display.contentCenterX

bitmap.y = display.contentCenterY

– place some random pixels

for i = 1, 1000 do

    tex:setPixel( math.random(0, 1000), math.random(0,1000), 1, 0, 0, 1 )  – Set pixel at (10,10) to be red

end

– Submit texture to be updated

tex:invalidate()

local r, g, b = 1, 1, 1

function touchHandler( event )

    if event.phase == “began” then

        r, g, b = math.random(), math.random(), math.random()

    end

    local bmp = event.target

    local x, y = bmp:contentToLocal( event.x, event.y )

    x = (x + bmp.width/2)

    y = (y + bmp.height/2)

    for i = 1, 500 do

        local xx, yy = math.random(x-50, x+50), math.random(y-50, y+50)

        tex:setPixel( xx, yy, r, g, b, 1 )

    end

    tex:invalidate()

end

bitmap:addEventListener( “touch”, touchHandler )

[/lua]

True, it is simpler code than handling ‘offscreen’ pixels, but really even then it’s not really very complex, and something you should easily be able to code in an evening or two (or a full day).

Sure, but if there’s a better solution available that takes 5 minutes …

I’ve spent more time writing the postings in this thread than to implement it using the mechanism that’s made to solve these kinds of problems.

I undertand initially memory bitmap were an unknown and so display objects are a valid workaround but once you know better, there’s no reason to justify or even think about a worse solution.

You wouldn’t drive a 10 mile detour on a track across the fields once you know there’s a 1 mile route on a motorway with no traffic issues if you goal is to reach a target rather than waste time and resources and kill the springs of your car :slight_smile:

Hi Michael,

Sure thing, agreed on all points. I just wanted to let the OP know that even though the MemoryBitmap method is relatively much simpler, in absolute terms we’re not talking about a huge time investment for the ‘difficult’ method either.

This is important to know, because there could be very valid reasons to choose for the ‘difficult’ method. What if you want to use tiny rounded rectangles for your pixels, for example? Or add another style effect like a light glow in the center? Or maybe a cute transition where the pixels slide, rotate or zoom into place? Or overlapping squares, with some blendMode on them? All either impossible or very difficult with the memoryBitmap function, and a piece of cake with the ‘difficult’ method.

So in my book, it’s not about justifying a worse solution. And thinking about the possibilities for all the cool effects I described above definitely justifies thinking about different approaches.

Sure … well … YAGNI.

Also not solving the original stated problem (90k modifiable pixels, not slowing down the machine to a crawl or be forced to zoom in so far you only see a small part of the image).

Wow, you really seem to have a hard time dealing with the fact that people present alternate methods - each with their own benefits and drawbacks.

Personally, I think it’s best if people have informed options, and then decide for themselves wether or not they need certain functionality or not.

Another solution would be to use a canvas texture and draw to that.  You can workout which “pixel” was tapped, redraw that area and invalidate the canvas.

This way only a single texture is actually being drawn by GPU.  So performance should be very fast.