buldthensnip/pkg/base/lib_shader.lua
2015-02-23 11:37:13 +13:00

125 lines
3.1 KiB
Lua

--[[
This file is part of Ice Lua Components.
Ice Lua Components is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Ice Lua Components is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Ice Lua Components. If not, see <http://www.gnu.org/licenses/>.
]]
do
local shader_stack = {}
function shader_push_nil()
shader_stack[1+#shader_stack] = true
client.glsl_use(nil)
end
function shader_pop_nil()
if shader_stack[#shader_stack] ~= true then
error("mismatched shader pop")
end
shader_stack[#shader_stack] = nil
if #shader_stack == 0 or shader_stack[#shader_stack] == true then
client.glsl_use(nil)
else
local shader = shader_stack[#shader_stack]
shader.activate()
end
end
function shader_new(settings)
local this = {
name = settings.name or "???",
vert = settings.vert or error("must provide vert shader source"),
frag = settings.frag or error("must provide frag shader source"),
attribs = settings.attribs or nil,
unif = {},
}
if this.attribs then
if common.version.num >= 8421376+14 then
this.prog, this.result = client.glsl_create(this.vert, this.frag, this.attribs)
else
this.prog, this.result = nil, "Vertex attributes not supported - upgrade to 0.2.1-14!"
end
else
this.prog, this.result = client.glsl_create(this.vert, this.frag)
end
print("*** Shader", this.name, this.prog, this.result)
if not this.prog then
return nil, this.result
end
function this.push()
shader_stack[1+#shader_stack] = this
this.activate()
end
function this.pop()
if shader_stack[#shader_stack] ~= this then
error("mismatched shader pop")
end
shader_stack[#shader_stack] = nil
if #shader_stack == 0 or shader_stack[#shader_stack] == true then
client.glsl_use(nil)
else
local shader = shader_stack[#shader_stack]
shader.activate()
end
end
function this.activate()
local k, v
client.glsl_use(this.prog)
for k, v in pairs(this.unif) do
local loc = client.glsl_get_uniform_loc(this.prog, k)
if loc then
if #(v[2]) < 1 or #(v[2]) > 4 then
error("too many dimensions for uniform")
end
if v[1] == "f" then
client.glsl_set_uniform_f(loc, unpack(v[2]))
elseif v[1] == "i" then
client.glsl_set_uniform_i(loc, unpack(v[2]))
elseif v[1] == "ui" then
client.glsl_set_uniform_ui(loc, unpack(v[2]))
else
error("invalid uniform type")
end
end
end
end
function this.set_uniform_f(name, ...)
this.unif[name] = {"f", {...}}
end
function this.set_uniform_i(name, ...)
this.unif[name] = {"i", {...}}
end
function this.set_uniform_ui(name, ...)
this.unif[name] = {"ui", {...}}
end
return this, this.result
end
end