I would try what Andreas recommended. Basically just render a tiny pixel art game then draw a texture with holes in it over that at full resolution. You don’t need anything fancy at all, and you will have good performance.
Thanks, for your try. I already done shader for that, and don’t have problem with render. You can try shader, it should work fast too. led.x = width, led.y = height, led.z = width/height. I use model and runtime pixel texture. But for your example shader can be used for postprocessing.
varying mediump vec2 var_texcoord0;
uniform mediump sampler2D tex0;
uniform mediump vec4 led;
const float ledRad = 0.4;
vec3 getColor(vec2 uv){
float center = 0.5/led.y;
float rad = center * ledRad * 2.0;
vec2 newRes = vec2(led.x, led.y);
//get color for one led
//vec2 pixelUV = uv;
vec2 pixelUV = floor(uv * newRes) / newRes;
vec2 coords = pixelUV - uv + center;
//fixed circle aspect
coords.x *= led.z;
//WTF NEED FIX IT NORMAL
coords.x += center * 0.08;
//coords.x -= center;
float d = length(coords);
vec3 color = texture2D(tex0, uv).rgb;
return mix(color, vec3(0), smoothstep(rad *0.9 , rad, d));
}
void main(){
gl_FragColor = vec4(getColor(var_texcoord0.xy).rgb, 1.0);
//gl_FragColor = vec4(color.rgb, 1.0);
}
My problem, is that i need change texture in lua, which is very slow.
I can’t use pixel sprites. Because i need a ability to change color for every pixel in runtime. For example a brightness of pixel can describe it health. Also i need a ability to destroy every pixel of enemy.
For screen 30x40 i spend 4-6 ms for loop in lua in android on galaxy s7. On cheap devices it will be much bigger. I am trying to move for loop in native. It should help.
local update_time = os.clock();
local stream = self.stream
local nodes = LED.NODES
local width = self.width
local index = 1
local arshift = bit.arshift
local band = bit.band
for id = 1, self.width * self.height do
local color = nodes[id]
local index = id * 3 - 2
stream[index] = arshift(band(color, 0xff0000),16)
stream[index + 1] = arshift(band(color, 0x00FF00),8)
stream[index + 2] = band(color, 0x0000ff)
end
local header = { width=self.width, height=self.height, type=resource.TEXTURE_TYPE_2D, format=resource.TEXTURE_FORMAT_RGB, num_mip_maps=0 }
resource.set_texture(self.resource_path, header, self.buffer )
print("update time:" .. (os.clock() - update_time))
You can also try to sample from that pixel texture in a fragment shader and render the LEDs. That may be even cheaper depending on the shader code.
You can try rendering to an 8-bit luminance texture and do palette conversion in a shader. That way you don’t have to write as much data to the buffer. This works only if you have max 255 colors, of course.
Interesting, I need more colors, but I’ll keep it on mind. Also i am thinking about, setting only changed colors. But sometimes i will need changed all pixel, so i should do it as fast as possible
Make native for changing texture.
Looks like native is 20-30% faster.
Anybody have ideas how can i increase speed more?
Test for screen 300x400.
PC
DEBUG:SCRIPT: native: 0.029
DEBUG:SCRIPT: lua:0.04
DEBUG:SCRIPT: native: 0.029
DEBUG:SCRIPT: lua:0.039
DEBUG:SCRIPT: native: 0.029
DEBUG:SCRIPT: lua:0.039
DEBUG:SCRIPT: native: 0.03
DEBUG:SCRIPT: lua:0.04
DEBUG:SCRIPT: native: 0.03
DEBUG:SCRIPT: lua:0.039
DEBUG:SCRIPT: native: 0.031
DEBUG:SCRIPT: lua:0.04
DEBUG:SCRIPT: native: 0.031
DEBUG:SCRIPT: lua:0.039
Android
native: 0.059728999999999
lua:0.077413999999999
native: 0.059455
lua:0.082948999999999
native: 0.058417
lua:0.078471
native: 0.059436
lua:0.080285
native: 0.059778999999999
lua:0.077199
native: 0.060198999999999
lua:0.081021
native: 0.059331
lua:0.082233
native: 0.0600940000000011
lua:0.079887999999999
native: 0.058405
lua:0.079704000000001
native: 0.058944
lua:0.07696
native: 0.058088
lua:0.079167999999997
native: 0.056916999999999
lua:0.079489000000002
native: 0.060658
lua:0.082440000000002
native: 0.059473000000001
lua:0.081376000000002
static int drawPixels(lua_State* L)
{
lua_getfield(L, 1, "width");
lua_getfield(L, 1, "height");
int width = luaL_checknumber(L, -2);
int height = luaL_checknumber(L, -1);
lua_pop(L, 1);
lua_pop(L, 1);
int size = width * height;
printf("width=%d height=%d \n",width,height);
lua_pushstring(L,"stream");
lua_gettable(L, -2 );
lua_pushstring(L,"leds");
lua_gettable(L, -3 );
for(int i=1; i<= size;i++){
lua_rawgeti(L,-1,i);
int color = luaL_checknumber(L, -1);
//printf("i=%d color=%d \n",i,color);
lua_pop(L, 1);
int r = color >> 16;
int g = (color & 0x00FF00) >> 8;
int b= color & 0x0000ff;
int id = i * 3;
lua_pushnumber(L, id - 2);
lua_pushnumber(L, r);
lua_settable(L, -4);
lua_pushnumber(L, id - 1);
lua_pushnumber(L, g);
lua_settable(L, -4);
lua_pushnumber(L, id);
lua_pushnumber(L, b);
lua_settable(L, -4);
//lua_pop(L,1);
}
lua_pop(L,1);
return 1;
}
Looks like setting data to stream is very expensive.
If i comment setting data to stream, i get 1 ms instead of 30. (x30 FASTER).
Why buffer is so slow?
You moved from Lua to C, but you still use Lua calls extensively. You should try working with native representation of buffers directly. https://www.defold.com/ref/dmBuffer/
That’s what I need. But how to get stream, that I create in lua, in C?
Something like this. https://github.com/Lerg/extension-openal/blob/master/openal/src/extension.cpp#L53
I don’t understand. How it should work? How to convert dmScript::LuaHBuffer* to dmBuffer::HBuffer
size for dmBuffer::GetStream is(null)
dmScript::LuaHBuffer* buffer = dmScript::CheckBuffer(L, 2);
uint8_t* stream = 0x0;
uint32_t size_ignored = 0;
dmBuffer::Result r = dmBuffer::GetStream((dmBuffer::HBuffer)buffer, dmHashString64("rgb"), (void**)&stream, &size_ignored);
It has property buffer->m_Buffer
, which is of type HBuffer.
Something like that? It is fall on line dmBuffer::GetStream.
dmScript::LuaHBuffer* buffer = dmScript::CheckBuffer(L, 2);
uint8_t* stream = 0x0;
uint32_t size_ignored = 0;
dmBuffer::HBuffer hBuffer = buffer->m_Buffer;
dmBuffer::Result r = dmBuffer::GetStream(hBuffer, dmHashString64("rgb"), (void**)&stream, &size_ignored);
What error message?
no error message =(
Sometimes there is something useful in that textbox you know.
My mistake. It fall on line.
printf("%i",size_ignored);
Thanks for @sergey.lerg. It work realy fast.
DEBUG:SCRIPT: native: 0.001
DEBUG:SCRIPT: native old: 0.025
DEBUG:SCRIPT: lua:0.038
DEBUG:SCRIPT: native: 0.001
DEBUG:SCRIPT: native old: 0.025
DEBUG:SCRIPT: lua:0.039
DEBUG:SCRIPT: native: 0.002
DEBUG:SCRIPT: native old: 0.025
DEBUG:SCRIPT: lua:0.037