Skip to content
Snippets Groups Projects
Commit f58fa99c authored by dg's avatar dg
Browse files

Particles can have shaders attached

New shader-enabled damage shield effect


git-svn-id: http://svn.net-core.org/repos/t-engine4@5387 51575b47-30f0-44d4-a5cc-537603b46e54
parent 1a125415
No related branches found
No related tags found
No related merge requests found
......@@ -26,10 +26,11 @@ module(..., package.seeall, class.make)
local __particles_gl = {}
--- Make a particle emitter
function _M:init(def, radius, args)
function _M:init(def, radius, args, shader)
self.args = args
self.def = def
self.radius = radius or 1
self.shader = shader
self:loaded()
end
......@@ -72,7 +73,18 @@ function _M:loaded()
args = args.."tile_w="..engine.Map.tile_w.."\ntile_h="..engine.Map.tile_h
self.update = fct
self.ps = core.particles.newEmitter("/data/gfx/particles/"..self.def..".lua", args, self.zoom, config.settings.particles_density or 100, gl)
local sha = nil
if self.shader then
if not self._shader then
local Shader = require 'engine.Shader'
self._shader = Shader.new(self.shader.type, self.shader)
end
sha = self._shader.shad
end
self.ps = core.particles.newEmitter("/data/gfx/particles/"..self.def..".lua", args, self.zoom, config.settings.particles_density or 100, gl, sha)
end
function _M:updateZoom()
......
......@@ -27,6 +27,8 @@ _M.verts = {}
_M.frags = {}
_M.progs = {}
loadNoDelay = true
--- Make a shader
function _M:init(name, args)
self.args = args or {}
......
......@@ -1974,6 +1974,13 @@ function _M:onTakeHit(value, src)
end
function _M:takeHit(value, src, death_note)
for eid, p in pairs(self.tmp) do
local e = self.tempeffect_def[eid]
if e.damage_feedback then
e.damage_feedback(self, p, src, value)
end
end
local dead, val = engine.interface.ActorLife.takeHit(self, value, src, death_note)
if dead and src and src.attr and src:attr("overkill") and src.project and not src.turn_procs.overkill then
......
......@@ -1213,8 +1213,15 @@ function _M:setupCommands()
end end
end end,
[{"_g","ctrl"}] = function() if config.settings.cheat then
self:registerDialog(require("mod.dialogs.DownloadCharball").new())
local ps = next(game.player.__particles)
local a = math.rad(rng.float(0, 360))
local r = rng.float(0.2, 0.4)
ps._shader:setUniform("impact", {math.cos(a) * r, math.sin(a) * r})
ps._shader:setUniform("impact_tick", core.game.getTime())
do return end
self:registerDialog(require("mod.dialogs.DownloadCharball").new())
local f, err = loadfile("/data/general/events/snowstorm.lua")
print(f, err)
setfenv(f, setmetatable({level=self.level, zone=self.zone}, {__index=_G}))
......
-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009, 2010, 2011, 2012 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
base_size = 32
local r = 1
local g = 1
local b = 1
local a = 1
return { generator = function()
return {
trail = 0,
life = 10,
size = 38, sizev = 0, sizea = 0,
x = 0, xv = 0, xa = 0,
y = 0, yv = 0, ya = 0,
dir = 0, dirv = dirv, dira = 0,
vel = 0, velv = 0, vela = 0,
r = r, rv = 0, ra = 0,
g = g, gv = 0, ga = 0,
b = b, bv = 0, ba = 0,
a = a, av = -0.02, aa = 0.005,
}
end, },
function(self)
self.ps:emit(1)
end,
1,
"particles_images/shield2"
game/modules/tome/data/gfx/particles_images/shield2.png

16.5 KiB

uniform sampler2D tex;
uniform float tick;
uniform float aadjust;
uniform vec3 color;
uniform float time_factor;
vec3 impact_color = vec3(1.0, 0.3, 1.0);
uniform vec2 impact;
uniform float impact_tick;
void main(void)
{
vec2 uv = vec2(0.5, 0.5) - gl_TexCoord[0].xy;
float l = length(uv) * 2.0;
float ll = l * l;
vec4 c1 = texture2D(tex, (uv * ll / 1.3 + vec2(tick / time_factor, 0.0)));
vec4 c2 = texture2D(tex, (uv * ll / 1.3 + vec2(0.0, tick / time_factor)));
vec4 c = c1 * c2;
float dist = max(min(1.0, 1.0 - l), 0.0) * 3.0;
c.a *= c.a * dist;
float z = l;
c.a *= z;
if (l > 1.0) c.a = 0.0;
if (l < 0.5) {
c.a *= ll * 4.0;
}
// Impact
float it = tick - impact_tick;
if (it < 400.0) {
float v = (400.0 - it) / 400.0;
float il = distance(impact / ll, (vec2(0.5) - gl_TexCoord[0].xy) / ll);
if (il < 0.5 * (1.0 - v)) {
v *= v * v;
float ic = (1.0 - length(uv - impact)) * v * 3.0;
c.rgb = mix(c.rgb, impact_color, ic);
aadjust *= 1.0 + v * 3.0;
}
}
c.a *= aadjust;
c.rgb *= color;
gl_FragColor = c;
}
-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009, 2010, 2011, 2012 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
return {
frag = "shield",
vert = nil,
args = {
tex = { texture = 0 },
color = color or {0.4, 0.7, 1.0},
time_factor = time_factor or 4000,
aadjust = aadjust or 10,
impact = {0, 0},
impact_tick = -1000,
},
clone = false,
}
......@@ -435,6 +435,14 @@ newEffect{
on_aegis = function(self, eff, aegis)
self.damage_shield_absorb = self.damage_shield_absorb + eff.power * aegis / 100
end,
damage_feedback = function(self, eff, src, value)
if eff.particle and eff.particle._shader and eff.particle._shader.shad and src and src.x and src.y then
local r = -rng.float(0.2, 0.4)
local a = math.atan2(src.y - self.y, src.x - self.x)
eff.particle._shader:setUniform("impact", {math.cos(a) * r, math.sin(a) * r})
eff.particle._shader:setUniform("impact_tick", core.game.getTime())
end
end,
activate = function(self, eff)
if self:attr("shield_factor") then eff.power = eff.power * (100 + self:attr("shield_factor")) / 100 end
if self:attr("shield_dur") then eff.dur = eff.dur + self:attr("shield_dur") end
......@@ -443,7 +451,11 @@ newEffect{
--- Warning there can be only one time shield active at once for an actor
self.damage_shield_absorb = eff.power
self.damage_shield_absorb_max = eff.power
eff.particle = self:addParticles(Particles.new("damage_shield", 1))
if core.shader.active() then
eff.particle = self:addParticles(Particles.new("shader_shield", 1, nil, {type="shield", color={0.4, 0.7, 1.0}}))
else
eff.particle = self:addParticles(Particles.new("damage_shield", 1))
end
end,
deactivate = function(self, eff)
self:removeParticles(eff.particle)
......
......@@ -83,6 +83,8 @@ static int particles_new(lua_State *L)
// float zoom = luaL_checknumber(L, 3);
int density = luaL_checknumber(L, 4);
GLuint *texture = (GLuint*)auxiliar_checkclass(L, "gl{texture}", 5);
shader_type *s = NULL;
if (lua_isuserdata(L, 6)) s = (shader_type*)auxiliar_checkclass(L, "gl{program}", 6);
particles_type *ps = (particles_type*)lua_newuserdata(L, sizeof(particles_type));
auxiliar_setclass(L, "core{particles}", -1);
......@@ -100,6 +102,7 @@ static int particles_new(lua_State *L)
ps->particles = NULL;
ps->init = FALSE;
ps->texture = *texture;
ps->shader = s;
thread_add(ps);
return 1;
......@@ -182,6 +185,8 @@ static int particles_to_screen(lua_State *L)
glScalef(ps->zoom * zoom, ps->zoom * zoom, ps->zoom * zoom);
glRotatef(ps->rotate, 0, 0, 1);
if (ps->shader) useShader(ps->shader, 1, 1, 1, 1, 1, 1, 1, 1);
int remaining = ps->batch_nb;
while (remaining >= PARTICLES_PER_ARRAY)
{
......@@ -190,6 +195,8 @@ static int particles_to_screen(lua_State *L)
}
if (remaining) glDrawArrays(GL_QUADS, 0, remaining);
if (ps->shader) glUseProgramObjectARB(0);
glRotatef(-ps->rotate, 0, 0, 1);
glPopMatrix();
glTranslatef(-x, -y, 0);
......
......@@ -22,6 +22,7 @@
#define _PARTICLES_H_
#include "tgl.h"
#include "useshader.h"
typedef struct {
float size, sizev, sizea;
......@@ -40,6 +41,7 @@ typedef struct {
// Read only by main
GLuint texture;
shader_type *shader;
// W by main, R by thread
const char *name_def;
......
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