Forked from
tome / Tales of MajEyal
13802 commits behind the upstream repository.
-
dg authored
typos git-svn-id: http://svn.net-core.org/repos/t-engine4@1168 51575b47-30f0-44d4-a5cc-537603b46e54
dg authoredtypos git-svn-id: http://svn.net-core.org/repos/t-engine4@1168 51575b47-30f0-44d4-a5cc-537603b46e54
Shader.lua 4.33 KiB
-- TE4 - T-Engine 4
-- Copyright (C) 2009, 2010 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org
require "engine.class"
--- Handles a particles system
-- Used by engine.Map
module(..., package.seeall, class.make)
_M.verts = {}
_M.frags = {}
_M.progs = {}
--- Make a shader
function _M:init(name, args)
self.args = args or {}
self.name = name
self.totalname = self:makeTotalName()
-- print("[SHADER] making shader from", name, " into ", self.totalname)
if core.shader.active() then self:loaded() end
end
function _M:makeTotalName()
local str = {}
for k, v in pairs(self.args) do
if type(v) == "number" then
str[#str+1] = v
elseif type(v) == "table" then
if v.texture then
if v.is3d then str[#str+1] = k.."=tex3d("..v.texture..")"
else str[#str+1] = k.."=tex3d("..v.texture..")" end
elseif #v == 2 then
str[#str+1] = k.."=vec2("..v[1]..","..v[2]..")"
elseif #v == 3 then
str[#str+1] = k.."=vec3("..v[1]..","..v[2]..","..v[3]..")"
elseif #v == 4 then
str[#str+1] = k.."=vec4("..v[1]..","..v[2]..","..v[3]..","..v[4]..")"
end
end
end
return self.name.."["..table.concat(str,",").."]"
end
--- Serialization
function _M:save()
return class.save(self, {
shad = true,
})
end
function _M:getFragment(name)
if not name then return nil end
if self.frags[name] then return self.frags[name] end
local f = fs.open("/data/gfx/shaders/"..name..".frag", "r")
local code = {}
while true do
local l = f:read(1)
if not l then break end
code[#code+1] = l
end
f:close()
self.frags[name] = core.shader.newShader(table.concat(code))
print("[SHADER] created fragment shader from /data/gfx/shaders/"..name..".frag")
return self.frags[name]
end
function _M:getVertex(name)
if not name then return nil end
if self.verts[name] then return self.verts[name] end
local f = fs.open("/data/gfx/shaders/"..name..".vert", "r")
local code = {}
while true do
local l = f:read(1)
if not l then break end
code[#code+1] = l
end
f:close()
self.verts[name] = core.shader.newShader(table.concat(code), true)
print("[SHADER] created vertex shader from /data/gfx/shaders/"..name..".vert")
return self.verts[name]
end
function _M:createProgram(def)
local shad = core.shader.newProgram()
if def.vert then shad:attach(self:getVertex(def.vert)) end
if def.frag then shad:attach(self:getFragment(def.frag)) end
if not shad:compile() then return nil end
return shad
end
function _M:loaded()
if _M.progs[self.totalname] then
self.shad = _M.progs[self.totalname]
-- print("[SHADER] using cached shader "..self.totalname)
self.shad = _M.progs[self.totalname]
else
print("[SHADER] Loading from /data/gfx/shaders/"..self.name..".lua")
local f, err = loadfile("/data/gfx/shaders/"..self.name..".lua")
if not f and err then error(err) end
setfenv(f, setmetatable(self.args or {}, {__index=_G}))
local def = f()
_M.progs[self.totalname] = self:createProgram(def)
self.shad = _M.progs[self.totalname]
if self.shad then
for k, v in pairs(def.args) do
self:setUniform(k, v)
end
end
end
end
function _M:setUniform(k, v)
if type(v) == "number" then
-- print("[SHADER] setting param", k, v)
self.shad:paramNumber(k, v)
elseif type(v) == "table" then
if v.texture then
-- print("[SHADER] setting texture param", k, v.texture)
self.shad:paramTexture(k, v.texture, v.is3d)
elseif #v == 2 then
-- print("[SHADER] setting vec2 param", k, v[1], v[2])
self.shad:paramNumber2(k, v[1], v[2])
elseif #v == 3 then
-- print("[SHADER] setting vec3 param", k, v[1], v[2], v[3])
self.shad:paramNumber3(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:paramNumber4(k, v[1], v[2], v[3], v[4])
end
end
end