local gl = honey.gl local module = {} setmetatable(module, {__index=_G}) setfenv(1, module) Shader = {} Shader.__index = Shader local function compileShader(source, type) local shader = gl.CreateShader(type) gl.ShaderSource(shader, source) gl.CompileShader(shader) return shader end function Shader.new(_, sources) local self = {} self.locations = {} self.links = {} local shaders = {} if sources.vertex then table.insert(shaders, compileShader(sources.vertex, gl.VERTEX_SHADER)) end if sources.fragment then table.insert(shaders, compileShader(sources.fragment, gl.FRAGMENT_SHADER)) end self.program = gl.CreateProgram() for _, shader in ipairs(shaders) do gl.AttachShader(self.program, shader) end gl.LinkProgram(self.program) for _, shader in ipairs(shaders) do gl.DeleteShader(shader) end setmetatable(self, Shader) return self end setmetatable(Shader, {__call=Shader.new}) function Shader.getLocation(self, name) if self.locations[name] then return self.locations[name] end local location = gl.GetUniformLocation(self.program, name) self.locations[name] = location return location end function Shader.use(self) gl.UseProgram(self.program) end function Shader.setInt(self, name, value) local location = self:getLocation(name) gl.Uniform1i(location, value) end function Shader.setFloat(self, name, value) local location = self:getLocation(name) gl.Uniform1f(location, value) end function Shader.setVec3(self, name, value) local location = self:getLocation(name) gl.Uniform3f(location, value[1], value[2], value[3]) end function Shader.setVec4(self, name, value) local location = self:getLocation(name) gl.Uniform3f(location, value[1], value[2], value[3], value[4]) end function Shader.setMatrix(self, name, matrix) local location = self:getLocation(name) gl.UniformMatrix4fv(location, false, matrix.data) end function Shader.configure(self, tbl) local processKey = function(key, set) local subtbl = tbl[key] if subtbl then for name, value in pairs(subtbl) do self[set](self, name, value) end end end processKey("int", "setInt") processKey("float", "setFloat") processKey("vec3", "setVec3") processKey("vec4", "setVec4") processKey("matrix", "setMatrix") end return module.Shader