Skip to content

Commit

Permalink
IT'S ALIVE!
Browse files Browse the repository at this point in the history
  • Loading branch information
warmist committed Jul 30, 2018
1 parent b4b2430 commit 8161487
Show file tree
Hide file tree
Showing 8 changed files with 425 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ set(SRCS
src/imgui-SFML.cpp
src/filesys.cpp
src/limgui.cpp
src/lua_buffers.cpp
${IMGUI}/imgui.cpp
${IMGUI}/imgui_draw.cpp
${IMGUI}/imgui_demo.cpp
Expand All @@ -48,6 +49,7 @@ set(HDRS
src/limgui.h
src/stb_image.h
src/stb_image_write.h
src/lua_buffers.h
${LUA}/lua.hpp
${LUA}/lualib.h
)
Expand Down
11 changes: 0 additions & 11 deletions projects/circle.lua
Original file line number Diff line number Diff line change
@@ -1,11 +0,0 @@
for i=1,10 do
print(i)
end
color={0,0,0,0}

function update( )
imgui.Begin("Hello")
local changed
changed,color=imgui.ColorEdit3("thing",color)
imgui.End()
end
102 changes: 102 additions & 0 deletions projects/spirograph.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
--[[ Example:
imgui_config=make_config{
{"debug_display",false},
{"complexity",0.5,type="float"}, --implied min=0,max=1
{"shapes","3"},
{"w",3,type="int",min=1,max=5},
}
Begin
End
Bullet
BulletText
RadioButton
CollapsingHeader
SliderFloat
SliderAngle
SliderInt
InputText
]]
function make_config(tbl,defaults)
local ret={}
defaults=defaults or {}
for i,v in ipairs(tbl) do
ret[v[1]]=defaults[v[1]] or v[2]
ret[i]=v
end
return ret
end

img_buf=img_buf or buffers.Make("color")
tick=tick or 0
config=make_config({
{"color",{0.5,0,0,1},type="color"},
{"k",0.2,type="float"},
{"l",0.4,type="float"},
{"R",400,type="int",min=0,max=512},
{"ticking",100,type="float",min=1,max=10000},
},config)

function draw_config( tbl )
for _,entry in ipairs(tbl) do
local name=entry[1]
local v=tbl[name]
local k=name
if type(v)=="boolean" then
if imgui.Button(k) then
tbl[k]=not tbl[k]
end
elseif type(v)=="string" then
local changing
changing,tbl[k]=imgui.InputText(k,tbl[k])
entry.changing=changing
else --if type(v)~="table" then

if entry.type=="int" then
local changing
changing,tbl[k]=imgui.SliderInt(k,tbl[k],entry.min or 0,entry.max or 100)
entry.changing=changing
elseif entry.type=="float" then
local changing
changing,tbl[k]=imgui.SliderFloat(k,tbl[k],entry.min or 0,entry.max or 1)
entry.changing=changing
elseif entry.type=="angle" then
local changing
changing,tbl[k]=imgui.SliderAngle(k,tbl[k],entry.min or 0,entry.max or 360)
entry.changing=changing
elseif entry.type=="color" then
local changing
changing,tbl[k]=imgui.ColorEdit4(k,tbl[k],true)
entry.changing=changing
end

end
end
end
function pos( t )
local k=config.k
local l=config.l
return config.R*((1-k)*math.cos(t)+l*k*math.cos(((1-k)/k)*t)),
config.R*((1-k)*math.sin(t)-l*k*math.sin(((1-k)/k)*t))
end
function update( )
imgui.Begin("Hello")

draw_config(config)
local c_u8={config.color[1]*255,config.color[2]*255,config.color[3]*255,config.color[4]*255}
if imgui.Button("Clear image") then
local s=STATE.size
for x=0,s[1]-1 do
for y=0,s[2]-1 do
img_buf:set(x,y,{0,0,0,0})
end
end
end
imgui.End()
for i=1,config.ticking do
local x,y=pos(tick/config.ticking);
img_buf:set(x+512,y+512,c_u8)
tick=tick+1
end
buffers.Present(img_buf)
end
4 changes: 4 additions & 0 deletions src/limgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

#include <imgui.h>
#include <vector>

#include "lua.hpp"
#include "lualib.h"
#include "lauxlib.h"
int lua_absindex(lua_State *L, int i) {
if (i < 0 && i > LUA_REGISTRYINDEX)
i += lua_gettop(L) + 1;
Expand Down
7 changes: 2 additions & 5 deletions src/limgui.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#pragma once

#include "lua.hpp"
#include "lualib.h"
#include "lauxlib.h"

struct lua_State;
int lua_open_imgui(lua_State* L);

//NOTE: call this because on error, there might be unmatched imgui::begin/end(s)
void fixup_imgui_state();
229 changes: 229 additions & 0 deletions src/lua_buffers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
#include "lua_buffers.h"

#include "SFML\Graphics.hpp"

#include "lua.hpp"
#include "lualib.h"
#include "lauxlib.h"

#include <unordered_map>
enum class buffer_type {
vector_u8x4,
vector_float,
};
struct u8x4 {
uint8_t r, g, b, a;
};
struct buffer_entry
{
int w;
buffer_type t;
};
std::unordered_map<void*, buffer_entry> buffer_registry;

void get_current_size(lua_State* L, int& x, int& y)
{
lua_getglobal(L, "STATE");
lua_getfield(L, -1, "size");

lua_rawgeti(L, -1, 1);
x=lua_tointeger(L, -1);
lua_pop(L, 1);

lua_rawgeti(L, -1, 2);
y = lua_tointeger(L, -1);
lua_pop(L, 1);

lua_pop(L, 2);
}



template <typename T>
struct buffer_value_access{
static constexpr char* name();
static int push(lua_State* L, const T& v);
static T to_element(lua_State* L, int id);
static std::vector<T>* check(lua_State* L, int id) { return *reinterpret_cast<std::vector<T>**>(luaL_checkudata(L, id, name())); }
static int get_buffer(lua_State* L)
{
auto ptr = buffer_value_access<T>::check(L, 1);
int x = luaL_checkinteger(L, 2);
int y = luaL_checkinteger(L, 3);
auto e = buffer_registry[ptr];
auto& v = ptr->at(x*e.w + y); \
return buffer_value_access<T>::push(L, v);
}
static int set_buffer(lua_State* L) {
auto ptr = buffer_value_access<T>::check(L, 1);
int x = luaL_checkinteger(L, 2);
int y = luaL_checkinteger(L, 3);
auto new_value = buffer_value_access<T>::to_element(L, 4);
auto e = buffer_registry[ptr];
ptr->at(x*e.w + y) = new_value;
return 0;
}
static int del_buffer(lua_State* L) {
auto ptr= check(L, 1);
buffer_registry.erase(ptr); delete ptr;
return 0;
}
static int len_buffer(lua_State* L) {
auto ptr = check(L, 1);
lua_pushnumber(L, ptr->size());
return 1;
}
static int index_buffer(lua_State* L) {
auto ptr = check(L, 1);
int id = luaL_checkinteger(L, 2);
auto& v = ptr->at(id);
return push(L, v);
}
static int newindex_buffer(lua_State* L){
auto ptr = check(L, 1);
int id = luaL_checkinteger(L, 2);
auto new_value = to_element(L, 3);
ptr->at(id) = new_value;
return 0;
}
static void resize_buffer(void* d, int w, int h){
auto p = reinterpret_cast<std::vector<T>*>(d);
p->resize(w*h);
buffer_registry[d].w = w;
}
static int make_buffer(lua_State* L, int w, int h){
auto ret = new std::vector<T>(w*h);
buffer_registry[ret].w = w;
auto np=lua_newuserdata(L,sizeof(ret));
*reinterpret_cast<std::vector<T>**>(np)=ret;
if (luaL_newmetatable(L, name()))
{
lua_pushcfunction(L, del_buffer);
lua_setfield(L, -2, "__gc");
lua_pushcfunction(L, len_buffer);
lua_setfield(L, -2, "__len");

lua_pushcfunction(L, get_buffer);
lua_setfield(L, -2, "get");
lua_pushcfunction(L, set_buffer);
lua_setfield(L, -2, "set");
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
}
lua_setmetatable(L, -2);
return 1;
}
};

static int make_lua_auto_buffer(lua_State* L)
{
const char* buf_type = luaL_checkstring(L, 1);
int x, y;
get_current_size(L, x, y);

if (strcmp(buf_type, "color")==0)
{
return buffer_value_access<u8x4>::make_buffer(L,x,y);
} else if (strcmp(buf_type, "float") == 0)
{
return buffer_value_access<float>::make_buffer(L, x, y);
}
}
static int present_buffer(lua_State* L)
{
auto ptr= buffer_value_access<u8x4>::check(L, 1);
lua_getglobal(L, "STATE");
lua_getfield(L, -1, "texture");

auto tex=reinterpret_cast<sf::Texture*>(lua_touserdata(L, -1));
lua_pop(L, 2);
tex->update(reinterpret_cast<const sf::Uint8*>(ptr->data()));
return 0;
}
static const luaL_Reg lua_buffers_lib[] = {
{ "Make",make_lua_auto_buffer },
{ "Present",present_buffer},
{ NULL, NULL }
};

int lua_open_buffers(lua_State * L)
{
luaL_newlib(L, lua_buffers_lib);

lua_setglobal(L, "buffers");

return 1;
}

void resize_lua_buffers(int w, int h)
{
for (auto& v : buffer_registry)
{
switch (v.second.t)
{
#define DO_BUFFER_RESIZE(tname,name) case buffer_type::vector_##tname: buffer_value_access<tname>::resize_buffer(v.first,w,h);break
DO_BUFFER_RESIZE(u8x4, color);
DO_BUFFER_RESIZE(float, float);
default:
break;
}
}
}
#undef DO_BUFFER_RESIZE

template<>
static constexpr char * buffer_value_access<u8x4>::name()
{
return "color_buffer";
}

template<>
static int buffer_value_access<u8x4>::push(lua_State * L, const u8x4& v)
{
lua_newtable(L);

lua_pushinteger(L, v.r);
lua_rawseti(L, -2, 1);

lua_pushinteger(L, v.g);
lua_rawseti(L, -2, 2);

lua_pushinteger(L, v.b);
lua_rawseti(L, -2, 3);

lua_pushinteger(L, v.a);
lua_rawseti(L, -2, 4);

return 1;
}

template<>
static u8x4 buffer_value_access<u8x4>::to_element(lua_State * L, int id)
{
u8x4 ret;
luaL_checktype(L, id, LUA_TTABLE);
lua_rawgeti(L, id, 1); ret.r = lua_tointeger(L, -1); lua_pop(L, 1);
lua_rawgeti(L, id, 2); ret.g = lua_tointeger(L, -1); lua_pop(L, 1);
lua_rawgeti(L, id, 3); ret.b = lua_tointeger(L, -1); lua_pop(L, 1);
lua_rawgeti(L, id, 4); ret.a = lua_tointeger(L, -1); lua_pop(L, 1);
return ret;
}

template<>
static constexpr char * buffer_value_access<float>::name()
{
return "float_buffer";
}

template<>
static int buffer_value_access<float>::push(lua_State * L, const float& v)
{
lua_pushnumber(L, v);
return 1;
}

template<>
static float buffer_value_access<float>::to_element(lua_State * L, int id)
{
return luaL_checknumber(L, id);
}
6 changes: 6 additions & 0 deletions src/lua_buffers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

struct lua_State;
int lua_open_buffers(lua_State* L);

void resize_lua_buffers(int w,int h);
Loading

0 comments on commit 8161487

Please sign in to comment.