Led Shooter

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.

4 Likes

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);
}

1 Like

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.

1 Like

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))
1 Like

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.

1 Like

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.

3 Likes

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

1 Like

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).:open_mouth:
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/

1 Like

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

4 Likes

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.

1 Like

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?

1 Like

no error message =(
2017-12-26_23-25-43

Sometimes there is something useful in that textbox you know.

1 Like

My mistake. It fall on line.

printf("%i",size_ignored);

Thanks for @sergey.lerg. It work realy fast. :+1:

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
10 Likes