Skip to content
Snippets Groups Projects
Commit d0e746c5 authored by DarkGod's avatar DarkGod
Browse files

Improve shaders performance in some cases

parent d6e2f9b7
No related branches found
No related tags found
No related merge requests found
......@@ -41,6 +41,7 @@ function _M:save()
return class.save(self, {
ps = true,
gl_texture = true,
_shader = true,
})
end
......
......@@ -41,7 +41,11 @@ function _M:cleanup()
for name, s in pairs(self.progs) do
if s.dieat < time then todel[name] = true end
end
for name, _ in pairs(todel) do self.progs[name] = nil end
for name, _ in pairs(todel) do
self.progs[name] = nil
self.progsreset[name] = nil
print("Deleting temp shader", name)
end
end
--- Make a shader
......@@ -152,10 +156,13 @@ function _M:loaded()
if _M.progsperm[self.totalname] then
-- print("[SHADER] using permcached shader "..self.totalname)
self.shad = _M.progsperm[self.totalname]
elseif _M.progs[self.totalname] and not _M.progsreset[self.totalname] then
elseif _M.progs[self.totalname] then
-- print("[SHADER] using cached shader "..self.totalname)
self.shad = _M.progs[self.totalname].shad
_M.progs[self.totalname].dieat = os.time() + 60
_M.progs[self.totalname].dieat = os.time() + 60*4
if _M.progsreset[self.totalname] then
self.shad = self.shad:clone()
end
else
print("[SHADER] Loading from /data/gfx/shaders/"..self.name..".lua")
local f, err = loadfile("/data/gfx/shaders/"..self.name..".lua")
......@@ -170,18 +177,17 @@ function _M:loaded()
if not core.shader.allow(def.require_kind) then return end
end
if def.resetargs then
self.totalname = self:makeTotalName(def.resetargs)
end
print("[SHADER] Loaded shader with totalname", self.totalname)
if not _M.progs[self.totalname] then
_M.progs[self.totalname] = {shad=self:createProgram(def), dieat=def.resetargs and (os.time() + 3) or (os.time() + 60)}
_M.progsreset[self.totalname] = def.resetargs
_M.progs[self.totalname] = {shad=self:createProgram(def), dieat=(os.time() + 60*4)}
else
_M.progs[self.totalname].dieat = def.resetargs and (os.time() + 3) or (os.time() + 60)
_M.progs[self.totalname].dieat = (os.time() + 60*4)
end
if def.resetargs then
_M.progsreset[self.totalname] = def.resetargs
end
self.shad = _M.progs[self.totalname].shad
if self.shad then
......@@ -194,8 +200,9 @@ function _M:loaded()
end
if self.shad and _M.progsreset[self.totalname] then
self.shad:resetClean()
for k, v in pairs(_M.progsreset[self.totalname]) do
self:setUniform(k, v(self))
self:setResetUniform(k, v(self))
end
end
end
......@@ -221,6 +228,27 @@ function _M:setUniform(k, v)
end
end
function _M:setResetUniform(k, v)
if type(v) == "number" then
print("[SHADER] setting reset param", k, v)
self.shad:resetParamNumber(k, v)
elseif type(v) == "table" then
if v.texture then
-- print("[SHADER] setting texture param", k, v.texture)
self.shad:resetParamTexture(k, v.texture, v.is3d)
elseif #v == 2 then
-- print("[SHADER] setting vec2 param", k, v[1], v[2])
self.shad:resetParamNumber2(k, v[1], v[2])
elseif #v == 3 then
-- print("[SHADER] setting vec3 param", k, v[1], v[2], v[3])
self.shad:resetParamNumber3(k, v[1], v[2], v[3])
elseif #v == 4 then
-- print("[SHADER] setting vec4 param", k, v[1], v[2], v[3], v[4])
self.shad:resetParamNumber4(k, v[1], v[2], v[3], v[4])
end
end
end
----------------------------------------------------------------------------
-- Default shaders
----------------------------------------------------------------------------
......
......@@ -26,10 +26,9 @@ return {
side = noup or 0,
verticalIntensityAdjust = 0,
scrollingSpeed = scrollingSpeed or 0.004,
chargesCount = chargesCount or 6,
},
resetargs = {
unused = function() return rng.range(1, 99999) end,
chargesCount = function(self) return self.args.chargesCount or 0 end,
},
clone = true,
}
......@@ -144,7 +144,8 @@ newTalent{
p.nb = p.nb + 1
if p.adv_gfx then
if p.particles[1] and p.particles[1]._shader and p.particles[1]._shader.shad then
p.particles[1]._shader:setUniform("chargesCount", util.bound(p.nb, 0, 10))
p.particles[1]._shader.shad:resetClean()
p.particles[1]._shader:setResetUniform("chargesCount", util.bound(p.nb, 0, 10))
p.particles[1].shader.chargesCount = util.bound(p.nb, 0, 10)
end
else
......@@ -160,7 +161,8 @@ newTalent{
p.nb = p.nb - 1
if p.adv_gfx then
if p.particles[1] and p.particles[1]._shader and p.particles[1]._shader.shad then
p.particles[1]._shader:setUniform("chargesCount", util.bound(p.nb, 0, 10))
p.particles[1]._shader.shad:resetClean()
p.particles[1]._shader:setResetUniform("chargesCount", util.bound(p.nb, 0, 10))
p.particles[1].shader.chargesCount = util.bound(p.nb, 0, 10)
end
else
......@@ -177,7 +179,10 @@ newTalent{
local adv_gfx = core.shader.allow("adv") and true or false
local ps = {}
if adv_gfx then
ps[1] = self:addParticles(Particles.new("shader_ring_rotating", 1, {toback=true, a=0.5, rotation=0, radius=1.5, img="bone_shield"}, {type="boneshield", chargesCount=util.bound(nb, 0, 10)}))
ps[1] = self:addParticles(Particles.new("shader_ring_rotating", 1, {toback=true, a=0.5, rotation=0, radius=1.5, img="bone_shield"}, {type="boneshield"}))
ps[1]._shader.shad:resetClean()
ps[1]._shader:setResetUniform("chargesCount", util.bound(nb, 0, 10))
ps[1].shader.chargesCount = util.bound(nb, 0, 10)
else
for i = 1, nb do ps[#ps+1] = self:addParticles(Particles.new("bone_shield", 1)) end
end
......
......@@ -52,6 +52,25 @@ void useShader(shader_type *p, int x, int y, int w, int h, float r, float g, flo
c[0] = w;
c[1] = h;
glUniform2fvARB(p->p_texsize, 1, c);
shader_reset_uniform *ru = p->reset_uniforms;
while (ru) {
switch (ru->kind) {
case UNIFORM_NUMBER:
glUniform1fvARB(ru->p, 1, &ru->data.number);
break;
case UNIFORM_VEC2:
glUniform2fvARB(ru->p, 1, ru->data.vec2);
break;
case UNIFORM_VEC3:
glUniform3fvARB(ru->p, 1, ru->data.vec3);
break;
case UNIFORM_VEC4:
glUniform4fvARB(ru->p, 1, ru->data.vec4);
break;
}
ru = ru->next;
}
}
static GLuint loadShader(const char* code, GLuint type)
......@@ -96,6 +115,8 @@ static int program_new(lua_State *L)
auxiliar_setclass(L, "gl{program}", -1);
p->shader = glCreateProgramObjectARB();
p->reset_uniforms = NULL;
p->clone = FALSE;
printf("New GL Shader program %d\n", p->shader);
......@@ -106,12 +127,32 @@ static int program_free(lua_State *L)
{
shader_type *p = (shader_type*)lua_touserdata(L, 1);
glDeleteObjectARB(p->shader);
printf("Deleting shader %d (is clone %d)\n", p->shader, p->clone);
if (!p->clone) glDeleteObjectARB(p->shader);
while (p->reset_uniforms) {
shader_reset_uniform *ru = p->reset_uniforms;
free(ru);
p->reset_uniforms = p->reset_uniforms->next;
}
lua_pushnumber(L, 1);
return 1;
}
static int program_remove_resets(lua_State *L)
{
shader_type *p = (shader_type*)lua_touserdata(L, 1);
while (p->reset_uniforms) {
shader_reset_uniform *ru = p->reset_uniforms;
free(ru);
p->reset_uniforms = p->reset_uniforms->next;
}
return 0;
}
static int program_attach(lua_State *L)
{
shader_type *p = (shader_type*)lua_touserdata(L, 1);
......@@ -132,6 +173,46 @@ static int program_detach(lua_State *L)
return 0;
}
static int program_clone(lua_State *L)
{
shader_type *p = (shader_type*)lua_touserdata(L, 1);
shader_type *np = (shader_type*)lua_newuserdata(L, sizeof(shader_type)); // 2
auxiliar_setclass(L, "gl{program}", -1);
np->clone = TRUE;
np->shader = p->shader;
np->p_tick = p->p_tick;
np->p_color = p->p_color;
np->p_mapcoord = p->p_mapcoord;
np->p_texsize = p->p_texsize;
np->reset_uniforms = NULL;
lua_getmetatable(L, 1); // 3
lua_newtable(L); // 4
// Iterate old table and copy to new table
lua_pushnil(L);
while (lua_next(L, 3) != 0) {
lua_pushvalue(L, -2);
lua_pushvalue(L, -2);
lua_rawset(L, 4);
lua_pop(L, 1);
}
// Capture a reference to the parent so it is not GC'ed before us
lua_pushstring(L, "_parent_clone");
lua_pushvalue(L, 1);
lua_rawset(L, 4);
lua_setmetatable(L, 2);
lua_pop(L, 1);
printf("Cloned shader %d\n", p->shader);
return 1;
}
static int program_set_uniform_number(lua_State *L)
{
shader_type *p = (shader_type*)lua_touserdata(L, 1);
......@@ -196,6 +277,68 @@ static int program_set_uniform_number4(lua_State *L)
return 0;
}
static int program_reset_uniform_number(lua_State *L)
{
shader_type *p = (shader_type*)lua_touserdata(L, 1);
const char *var = luaL_checkstring(L, 2);
shader_reset_uniform *ru = malloc(sizeof(shader_reset_uniform));
ru->next = p->reset_uniforms;
p->reset_uniforms = ru;
ru->p = glGetUniformLocationARB(p->shader, var);
ru->kind = UNIFORM_NUMBER;
ru->data.number = luaL_checknumber(L, 3);
return 0;
}
static int program_reset_uniform_number2(lua_State *L)
{
shader_type *p = (shader_type*)lua_touserdata(L, 1);
const char *var = luaL_checkstring(L, 2);
shader_reset_uniform *ru = malloc(sizeof(shader_reset_uniform));
ru->next = p->reset_uniforms;
p->reset_uniforms = ru;
ru->p = glGetUniformLocationARB(p->shader, var);
ru->kind = UNIFORM_VEC2;
ru->data.vec2[0] = luaL_checknumber(L, 3);
ru->data.vec2[1] = luaL_checknumber(L, 4);
return 0;
}
static int program_reset_uniform_number3(lua_State *L)
{
shader_type *p = (shader_type*)lua_touserdata(L, 1);
const char *var = luaL_checkstring(L, 2);
shader_reset_uniform *ru = malloc(sizeof(shader_reset_uniform));
ru->next = p->reset_uniforms;
p->reset_uniforms = ru;
ru->p = glGetUniformLocationARB(p->shader, var);
ru->kind = UNIFORM_VEC3;
ru->data.vec3[0] = luaL_checknumber(L, 3);
ru->data.vec3[1] = luaL_checknumber(L, 4);
ru->data.vec3[2] = luaL_checknumber(L, 5);
return 0;
}
static int program_reset_uniform_number4(lua_State *L)
{
shader_type *p = (shader_type*)lua_touserdata(L, 1);
const char *var = luaL_checkstring(L, 2);
shader_reset_uniform *ru = malloc(sizeof(shader_reset_uniform));
ru->next = p->reset_uniforms;
p->reset_uniforms = ru;
ru->p = glGetUniformLocationARB(p->shader, var);
ru->kind = UNIFORM_VEC4;
ru->data.vec4[0] = luaL_checknumber(L, 3);
ru->data.vec4[1] = luaL_checknumber(L, 4);
ru->data.vec4[2] = luaL_checknumber(L, 5);
ru->data.vec4[3] = luaL_checknumber(L, 6);
return 0;
}
static int program_set_uniform_texture(lua_State *L)
{
shader_type *p = (shader_type*)lua_touserdata(L, 1);
......@@ -471,6 +614,7 @@ static const struct luaL_Reg shaderlib[] =
static const struct luaL_Reg program_reg[] =
{
{"__gc", program_free},
{"clone", program_clone},
{"compile", program_compile},
{"attach", program_attach},
{"detach", program_detach},
......@@ -479,6 +623,11 @@ static const struct luaL_Reg program_reg[] =
{"paramNumber3", program_set_uniform_number3},
{"paramNumber4", program_set_uniform_number4},
{"paramTexture", program_set_uniform_texture},
{"resetClean", program_remove_resets},
{"resetParamNumber", program_reset_uniform_number},
{"resetParamNumber2", program_reset_uniform_number2},
{"resetParamNumber3", program_reset_uniform_number3},
{"resetParamNumber4", program_reset_uniform_number4},
{"use", program_use},
{NULL, NULL},
};
......
#ifndef __USESHADER_H__
#define __USESHADER_H__
struct s_shader_reset_uniform {
enum{UNIFORM_NUMBER, UNIFORM_VEC2, UNIFORM_VEC3, UNIFORM_VEC4} kind;
GLint p;
union {
GLfloat number;
GLfloat vec2[2];
GLfloat vec3[3];
GLfloat vec4[4];
} data;
struct s_shader_reset_uniform *next;
};
typedef struct s_shader_reset_uniform shader_reset_uniform;
typedef struct {
bool clone;
GLuint shader;
GLint p_tick, p_color, p_mapcoord, p_texsize;
int params_ref;
struct s_shader_reset_uniform *reset_uniforms;
} shader_type;
extern bool shaders_active;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment