Hello lovers!
I'm trying to improve my rendering method. It's really simple, 320x200 canvas with 16 colors, but I need to draw it pixel by pixel, taking a value from a 2d array.
What I do now is have a spritebatch and 16 1x1 quads (for each color), and when I need to render the canvas, I clean the batch, go through the array and add each pixel to the batch, and then draw. It works fine for now (without much logic) if I skip 2 or 3 frames.
Is there a better way? Shaders maybe?
Thanks!
Faster pixel by pixel render?
Re: Faster pixel by pixel render?
From what you write, I don't think it's clear how you can solve this problem. Here are however some things to think about:
1. Have you considered not storing it as a 2D array in the first place? A 2D array is sort of an image already, why not use an image-like format directly? It could be ImageData (if you want to use threads) or a Canvas or SpriteBatch. That way, you skip the conversion step.
2. Shaders could be used, but I don't think you can send a large-ish 2D array to the GPU, to be accesed from the shader, without converting it to some kind of image first. The largest supported matrix size is 4x4. I guess you could divide your 2D array into a whole bunch of 4x4-matrices and send all of those... Not sure if that's going to be slow or not.
1. Have you considered not storing it as a 2D array in the first place? A 2D array is sort of an image already, why not use an image-like format directly? It could be ImageData (if you want to use threads) or a Canvas or SpriteBatch. That way, you skip the conversion step.
2. Shaders could be used, but I don't think you can send a large-ish 2D array to the GPU, to be accesed from the shader, without converting it to some kind of image first. The largest supported matrix size is 4x4. I guess you could divide your 2D array into a whole bunch of 4x4-matrices and send all of those... Not sure if that's going to be slow or not.
My game called Hat Cat and the Obvious Crimes Against the Fundamental Laws of Physics is out now!
Re: Faster pixel by pixel render?
The thing is I want to update it often, once per two frames preferably.
What I'm trying to do is something like http://en.wikipedia.org/wiki/Memory-mapped_I/O. Basically, there is a programmable computer inside a love game, and to draw to the screen you'd need to set a value to some address in memory (which, in the end, is a lua array). The main bottleneck I see with lua is drawing to the screen.
Please, don't crash my hopes by telling me that the only solution to this is to redo everything in C...
What I'm trying to do is something like http://en.wikipedia.org/wiki/Memory-mapped_I/O. Basically, there is a programmable computer inside a love game, and to draw to the screen you'd need to set a value to some address in memory (which, in the end, is a lua array). The main bottleneck I see with lua is drawing to the screen.
Please, don't crash my hopes by telling me that the only solution to this is to redo everything in C...
- Positive07
- Party member
- Posts: 1014
- Joined: Sun Aug 12, 2012 4:34 pm
- Location: Argentina
Re: Faster pixel by pixel render?
ImageData:T-Bone wrote: 1. Have you considered not storing it as a 2D array in the first place? A 2D array is sort of an image already, why not use an image-like format directly? It could be ImageData (if you want to use threads) or a Canvas or SpriteBatch. That way, you skip the conversion step.
- Can be passed to other threads as T-Bone said, this means you could render it in other thread then pass it to the main thread
- You can set and get data from each pixel with [wiki]ImageData:setPixel[/wiki] and [wiki]ImageData:getPixel[/wiki]
- You can render it really fast with the map function [wiki]ImageData:mapPixel[/wiki]
Code: Select all
ImageData:mapPixel(function (x,y, oldr, oldg, oldb, olda)
return unpack(Your2DArray[x][y])
end)
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
Re: Faster pixel by pixel render?
Just tried both mapPixel and setPixel. Using setPixel was twice faster than mapPixel for some reason, but still twice slower than useing spriteBatch with 64000 sprites...
I guess optimizing spriteBatch method is the only optimal way. So far I found these ways for optimization: use set instead of clearing and adding sprites each time, use bind and unbind, use 256 2x1 quads instead of 16 1x1 (and cutting sprite number in half). Is there something else you can think of?
I guess optimizing spriteBatch method is the only optimal way. So far I found these ways for optimization: use set instead of clearing and adding sprites each time, use bind and unbind, use 256 2x1 quads instead of 16 1x1 (and cutting sprite number in half). Is there something else you can think of?
Re: Faster pixel by pixel render?
When you tried working with ImageData, did you use another thread? I don't think there's much point to it unless you use more than one thread. Optimally you should use as many threads as there are CPU cores.
My game called Hat Cat and the Obvious Crimes Against the Fundamental Laws of Physics is out now!
-
- Prole
- Posts: 11
- Joined: Sun Apr 06, 2014 4:43 pm
- Location: Novokuznetsk, Russia
Re: Faster pixel by pixel render?
Maybe you could use the FFI replacements for ImageData functions: https://github.com/slime73/love-snippet ... ta-ffi.luamapimopi wrote:Is there something else you can think of?
Probably not a best solution though since these functions are not thread-safe (you'll have to only use them in the main thread).
Also there won't be any performance increase on iOS because LuaJIT can't compile bytecode to a native code on that platform thanks to Apple.
↑↑↓↓↑↑↑↑
- Positive07
- Party member
- Posts: 1014
- Joined: Sun Aug 12, 2012 4:34 pm
- Location: Argentina
Re: Faster pixel by pixel render?
Or in another thread, since they exist in the thread /threads that require the functionsDaniel_Cortez wrote: Probably not a best solution though since these functions are not thread-safe (you'll have to only use them in the main thread).
THIS! ENTIRELY!T-Bone wrote:When you tried working with ImageData, did you use another thread? I don't think there's much point to it unless you use more than one thread. Optimally you should use as many threads as there are CPU cores.
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
-
- Prole
- Posts: 11
- Joined: Sun Apr 06, 2014 4:43 pm
- Location: Novokuznetsk, Russia
Re: Faster pixel by pixel render?
Do you mean manipulating an image data in multiple threads or just moving all the manipulation code to another thread?T-Bone wrote:When you tried working with ImageData, did you use another thread? I don't think there's much point to it unless you use more than one thread. Optimally you should use as many threads as there are CPU cores.
Because using multiple threads will only make sense if you're going to manipulate 2 or more images in separate threads since setPixel and mapPixel methods are using mutexes.
↑↑↓↓↑↑↑↑
Re: Faster pixel by pixel render?
One idea I've mulled over is that if you have a lot of calls to love.graphics.setColor, maybe you can figure a way to batch process the pixels. If you figure that each pixel can be described by a number between 0 and 64000 (320*200), then you could have preallocated arrays set up, one for each color, each table using a key like N to mark the end of the array, and then when time comes to paint, iterate over your pixel grid, and for each color you find, add that location at color[id][color[id].N+1] = location. Then, you render by setting the color once, and then drawing your single pixel rectangle to the locations indicated in each list.
I'm... not certain this would get too much faster. It may be a better idea for simulating ASCII text rendering and not the actual pixels, but I could see it being worth a shot, just for laughs.
I'm... not certain this would get too much faster. It may be a better idea for simulating ASCII text rendering and not the actual pixels, but I could see it being worth a shot, just for laughs.
Who is online
Users browsing this forum: Google [Bot] and 1 guest