From 90a7a2d915e4de64ee7213c9be6fdc5937c524d9 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Mon, 14 Feb 2011 00:52:38 +0000
Subject: [PATCH] refactor stuff

git-svn-id: http://svn.net-core.org/repos/t-engine4@2718 51575b47-30f0-44d4-a5cc-537603b46e54
---
 .../default/engine/interface/PlayerRun.lua    |  4 +-
 game/engines/default/engine/ui/Dialog.lua     |  3 +-
 game/modules/tome/class/Game.lua              | 66 +++++++++++--------
 .../tome/data/gfx/shaders/main_fbo.frag       | 36 ++--------
 .../tome/data/gfx/shaders/main_fbo.lua        |  1 -
 .../tome/data/gfx/shaders/map_fbo.frag        | 21 ++++++
 .../modules/tome/data/gfx/shaders/map_fbo.lua | 28 ++++++++
 src/map.c                                     | 18 +++--
 8 files changed, 111 insertions(+), 66 deletions(-)
 create mode 100644 game/modules/tome/data/gfx/shaders/map_fbo.frag
 create mode 100644 game/modules/tome/data/gfx/shaders/map_fbo.lua

diff --git a/game/engines/default/engine/interface/PlayerRun.lua b/game/engines/default/engine/interface/PlayerRun.lua
index bd51cebde8..1f9e7febce 100644
--- a/game/engines/default/engine/interface/PlayerRun.lua
+++ b/game/engines/default/engine/interface/PlayerRun.lua
@@ -77,7 +77,7 @@ function _M:runInit(dir)
 		cnt = 1,
 		dialog = Dialog:simplePopup("Running...", "You are running, press Enter to stop.", function()
 			self:runStop()
-		end),
+		end, false, true),
 	}
 	self.running.dialog.__showup = nil
 	self.running.dialog.__hidden = true
@@ -107,7 +107,7 @@ function _M:runFollow(path)
 		cnt = 1,
 		dialog = Dialog:simplePopup("Running...", "You are running, press any key to stop.", function()
 			self:runStop()
-		end),
+		end, false, true),
 	}
 	self.running.dialog.__showup = nil
 	self.running.dialog.__hidden = true
diff --git a/game/engines/default/engine/ui/Dialog.lua b/game/engines/default/engine/ui/Dialog.lua
index 55ebb1643f..b9ad7a30a4 100644
--- a/game/engines/default/engine/ui/Dialog.lua
+++ b/game/engines/default/engine/ui/Dialog.lua
@@ -43,12 +43,13 @@ function _M:listPopup(title, text, list, w, h, fct)
 end
 
 --- Requests a simple, press any key, dialog
-function _M:simplePopup(title, text, fct, no_leave)
+function _M:simplePopup(title, text, fct, no_leave, any_leave)
 	local w, h = self.font:size(text)
 	local d = new(title, 1, 1)
 	d:loadUI{{left = 3, top = 3, ui=require("engine.ui.Textzone").new{width=w+10, height=h+5, text=text}}}
 	if not no_leave then
 		d.key:addBind("EXIT", function() game:unregisterDialog(d) if fct then fct() end end)
+		if any_leave then d.key:addCommand("__DEFAULT", function() game:unregisterDialog(d) if fct then fct() end end) end
 		local close = require("engine.ui.Button").new{text="Close", fct=function() d.key:triggerVirtual("EXIT") end}
 		d:loadUI{no_reset=true, {hcenter = 0, bottom = 3, ui=close}}
 		d:setFocus(close)
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 2625f73bfa..ff9e7ff4e1 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -341,10 +341,9 @@ function _M:setupDisplayMode(reboot, mode)
 
 		-- Create the framebuffer
 		self.fbo = core.display.newFBO(Map.viewport.width, Map.viewport.height)
-		if self.fbo then
-			self.fbo_shader = Shader.new("main_fbo")
-			if not self.fbo_shader.shad then self.fbo = nil self.fbo_shader = nil end
-		end
+		if self.fbo then self.fbo_shader = Shader.new("main_fbo") if not self.fbo_shader.shad then self.fbo = nil self.fbo_shader = nil end end
+		self.mapfbo = core.display.newFBO(Map.viewport.width + 3 * Map.tile_w, Map.viewport.height + 3 * Map.tile_h)
+		if self.mapfbo then self.mapfbo_shader = Shader.new("map_fbo") if not self.mapfbo_shader.shad then self.mapfbo = nil self.mapfbo_shader = nil end end
 		if self.player then self.player:updateMainShader() end
 	end
 
@@ -728,53 +727,68 @@ function _M:display(nb_keyframes)
 
 	-- Now the map, if any
 	if self.level and self.level.map and self.level.map.finished then
+		local map = self.level.map
+
 		-- Display the map and compute FOV for the player if needed
-		local changed = self.level.map.changed
+		local changed = map.changed
 		if changed then
 			self.player:playerFOV()
 		end
 
-		-- Display using Framebuffer, so that we can use shaders and all
-		if self.fbo then
+		-- Display using Framebuffer, so that we can use shaders and all; also uses a second FBO for map smooth FOV shading
+		if self.fbo and self.mapfbo then
+			self.mapfbo:use(true)
+				if self.level.data.background then self.level.data.background(self.level, 0, 0, nb_keyframes) end
+				map:display(0, 0, nb_keyframes, true) -- Display at the base of the FBO and make sure to display everything as the shader will do smooth FOV over it
+				map._map:updateSeensTexture()
+				if self.level.data.foreground then self.level.data.foreground(self.level, 0, 0, nb_keyframes) end
+				if self.level.data.weather_particle then self.state:displayWeather(self.level, self.level.data.weather_particle, nb_keyframes) end
+			self.mapfbo:use(false)
+
 			self.fbo:use(true)
+				map._map:bindSeensTexture(1)
+				self.mapfbo_shader:setUniform("seensinfo", {map._map:getSeensInfo()})
+				local sx, sy = map._map:getScroll()
+				self.mapfbo:toScreen(sx-Map.tile_w, sy-Map.tile_h, map.viewport.width + 3 * Map.tile_w, map.viewport.height + 3 * Map.tile_h, self.mapfbo_shader.shad)
+			self.fbo:use(false)
 
-			if self.level.data.background then self.level.data.background(self.level, 0, 0, nb_keyframes) end
-			self.level.map:display(0, 0, nb_keyframes, true) -- Display at the base of the FBO and make sure to display everything as the shader will do smooth FOV over it
-			if self.level.data.foreground then self.level.data.foreground(self.level, 0, 0, nb_keyframes) end
-			if self.level.data.weather_particle then self.state:displayWeather(self.level, self.level.data.weather_particle, nb_keyframes) end
+			_2DNoise:bind(1, false)
+			self.fbo:toScreen(map.display_x, map.display_y, map.viewport.width, map.viewport.height, self.fbo_shader.shad)
+			self.target:display()
 
+		-- Display using Framebuffer, so that we can use shaders and all
+		elseif self.fbo then
+			self.fbo:use(true)
+				if self.level.data.background then self.level.data.background(self.level, 0, 0, nb_keyframes) end
+				map:display(0, 0, nb_keyframes)
+				if self.level.data.foreground then self.level.data.foreground(self.level, 0, 0, nb_keyframes) end
+				if self.level.data.weather_particle then self.state:displayWeather(self.level, self.level.data.weather_particle, nb_keyframes) end
 			self.fbo:use(false)
+
 			_2DNoise:bind(1, false)
-			if changed then self.level.map._map:updateSeensTexture() end
-			self.level.map._map:bindSeensTexture(2)
-			self.fbo_shader:setUniform("seensinfo", {self.level.map._map:getSeensInfo()})
-			self.fbo:toScreen(
-				self.level.map.display_x, self.level.map.display_y,
-				self.level.map.viewport.width, self.level.map.viewport.height,
-				self.fbo_shader.shad
-			)
+			self.fbo:toScreen(map.display_x, map.display_y, map.viewport.width, map.viewport.height, self.fbo_shader.shad)
 			self.target:display()
 
-		-- Basic display
+		-- Basic display; no FBOs
 		else
-			if self.level.data.background then self.level.data.background(self.level, self.level.map.display_x, self.level.map.display_y, nb_keyframes) end
-			self.level.map:display(nil, nil, nb_keyframes)
+			if self.level.data.background then self.level.data.background(self.level, map.display_x, map.display_y, nb_keyframes) end
+			map:display(nil, nil, nb_keyframes)
 			self.target:display()
-			if self.level.data.foreground then self.level.data.foreground(self.level, self.level.map.display_x, self.level.map.display_y, nb_keyframes) end
+			if self.level.data.foreground then self.level.data.foreground(self.level, map.display_x, map.display_y, nb_keyframes) end
 			if self.level.data.weather_particle then self.state:displayWeather(self.level, self.level.data.weather_particle, nb_keyframes) end
 		end
 
 		if not self.zone_name_s then self:updateZoneName() end
 		self.zone_name_s:toScreenFull(
-			self.level.map.display_x + self.level.map.viewport.width - self.zone_name_w - 15,
-			self.level.map.display_y + self.level.map.viewport.height - self.zone_name_h - 5,
+			map.display_x + map.viewport.width - self.zone_name_w - 15,
+			map.display_y + map.viewport.height - self.zone_name_h - 5,
 			self.zone_name_w, self.zone_name_h,
 			self.zone_name_tw, self.zone_name_th
 		)
 
 		-- Minimap display
 		self.minimap_bg:toScreen(0, 35, 200, 200)
-		self.level.map:minimapDisplay(0, 35, util.bound(self.player.x - 25, 0, self.level.map.w - 50), util.bound(self.player.y - 25, 0, self.level.map.h - 50), 50, 50, 1)
+		map:minimapDisplay(0, 35, util.bound(self.player.x - 25, 0, map.w - 50), util.bound(self.player.y - 25, 0, map.h - 50), 50, 50, 1)
 	end
 
 	-- We display the player's interface
diff --git a/game/modules/tome/data/gfx/shaders/main_fbo.frag b/game/modules/tome/data/gfx/shaders/main_fbo.frag
index 5e68631fc9..013d4d9cba 100644
--- a/game/modules/tome/data/gfx/shaders/main_fbo.frag
+++ b/game/modules/tome/data/gfx/shaders/main_fbo.frag
@@ -5,35 +5,11 @@ uniform float tick;
 uniform sampler2D noisevol;
 uniform vec2 texSize;
 uniform sampler2D tex;
-uniform sampler2D seens;
-uniform vec4 seensinfo;
 uniform vec3 colorize;
 
-// Return the given pixel, this allows things like blur to work even with smooth fov shading
-vec4 get_pixel(vec2 coord)
-{
-	/*
-	 * Few lines to do some tricky things
-	 * The game provides use with a "seens" texture that is the computed FOV
-	 * We use this to lookup the current tile and shadow it as needed
-	 * seenscoords is arranged as this: (tile_w, tile_h, view_scene_w, view_scene_h)
-	 * We offset by 1x1.25 tiles .. dont ask why, it just works :/
-	 */
-	vec2 seenscoord = vec2((((coord.x + 64 / texSize.x) / seensinfo.r)) * texSize.x / seensinfo.b, (((coord.y + 80 / texSize.y) / seensinfo.g)) * texSize.y / seensinfo.a);
-	vec3 seen = texture2D(seens, seenscoord);
-	vec4 res = texture2D(tex, coord.xy);
-	res.r *= seen.r;
-	res.g *= seen.g;
-	res.b *= seen.b;
-
-	// Now we got our shaded pixel, we can do otehr stuff with it
-//	res = texture2D(tex, coord.xy); // this is a non shading version
-	return res;
-}
-
 void main(void)
 {
-	gl_FragColor = get_pixel(gl_TexCoord[0]);
+	gl_FragColor = texture2D(tex, gl_TexCoord[0].xy);
 
 	if (motionblur > 0.0)
 	{
@@ -58,7 +34,7 @@ void main(void)
 			{
 				for(int j = -blursize; j <= 0; j++)
 				{
-					sample += get_pixel(vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y)));
+					sample += texture2D(tex, vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y)));
 				}
 			}
 		}
@@ -68,7 +44,7 @@ void main(void)
 			{
 				for(int j = 0; j <= blursize; j++)
 				{
-					sample += get_pixel(vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y)));
+					sample += texture2D(tex, vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y)));
 				}
 			}
 		}
@@ -78,7 +54,7 @@ void main(void)
 			{
 				for(int j = -blursize; j <= 0; j++)
 				{
-					sample += get_pixel(vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y)));
+					sample += texture2D(tex, vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y)));
 				}
 			}
 		}
@@ -88,7 +64,7 @@ void main(void)
 			{
 				for(int j = 0; j <= blursize; j++)
 				{
-					sample += get_pixel(vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y)));
+					sample += texture2D(tex, vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y)));
 				}
 			}
 		}
@@ -110,7 +86,7 @@ void main(void)
 		{
 			for(int j = -blursize; j <= blursize; j++)
 			{
-				sample += get_pixel(vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y)));
+				sample += texture2D(tex, vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y)));
 			}
 		}
 		sample /= (blur*2.0) * (blur*2.0);
diff --git a/game/modules/tome/data/gfx/shaders/main_fbo.lua b/game/modules/tome/data/gfx/shaders/main_fbo.lua
index 423e85468f..9eadd16867 100644
--- a/game/modules/tome/data/gfx/shaders/main_fbo.lua
+++ b/game/modules/tome/data/gfx/shaders/main_fbo.lua
@@ -23,7 +23,6 @@ return {
 	args = {
 		tex = { texture = 0 },
 		noisevol = { texture = 1 },
-		seens = { texture = 2 },
 	},
 	clone = false,
 }
diff --git a/game/modules/tome/data/gfx/shaders/map_fbo.frag b/game/modules/tome/data/gfx/shaders/map_fbo.frag
new file mode 100644
index 0000000000..1496858d78
--- /dev/null
+++ b/game/modules/tome/data/gfx/shaders/map_fbo.frag
@@ -0,0 +1,21 @@
+uniform vec2 texSize;
+uniform sampler2D tex;
+uniform sampler2D seens;
+uniform vec4 seensinfo;
+
+void main(void)
+{
+	/*
+	 * Few lines to do some tricky things
+	 * The game provides use with a "seens" texture that is the computed FOV
+	 * We use this to lookup the current tile and shadow it as needed
+	 * seenscoords is arranged as this: (tile_w, tile_h, view_scene_w, view_scene_h)
+	 * We offset by 1x1.25 tiles .. dont ask why, it just works :/
+	 */
+	vec2 seenscoord = vec2((((gl_TexCoord[0].x + seensinfo.r / texSize.x) / seensinfo.r)) * texSize.x / seensinfo.b, (((gl_TexCoord[0].y + (seensinfo.g * -1.5) / texSize.y) / seensinfo.g)) * texSize.y / seensinfo.a);
+	vec4 seen = texture2D(seens, seenscoord);
+	gl_FragColor = texture2D(tex, gl_TexCoord[0].xy);
+	gl_FragColor.r *= seen.r;
+	gl_FragColor.g *= seen.g;
+	gl_FragColor.b *= seen.b;
+}
diff --git a/game/modules/tome/data/gfx/shaders/map_fbo.lua b/game/modules/tome/data/gfx/shaders/map_fbo.lua
new file mode 100644
index 0000000000..8c8592da2e
--- /dev/null
+++ b/game/modules/tome/data/gfx/shaders/map_fbo.lua
@@ -0,0 +1,28 @@
+-- ToME - Tales of Maj'Eyal
+-- 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
+
+return {
+	frag = "map_fbo",
+	vert = nil,
+	args = {
+		tex = { texture = 0 },
+		seens = { texture = 1 },
+	},
+	clone = false,
+}
diff --git a/src/map.c b/src/map.c
index b9e7fae71d..4d3d0f57f7 100644
--- a/src/map.c
+++ b/src/map.c
@@ -792,7 +792,7 @@ static int map_bind_seen_texture(lua_State *L)
 	if (unit > 0 && !multitexture_active) return 0;
 
 	if (unit > 0) tglActiveTexture(GL_TEXTURE0+unit);
-	tglBindTexture(GL_TEXTURE_2D, map->seens_texture);
+	glBindTexture(GL_TEXTURE_2D, map->seens_texture);
 	if (unit > 0) tglActiveTexture(GL_TEXTURE0);
 
 	return 0;
@@ -832,8 +832,6 @@ static int map_set_scroll(lua_State *L)
 
 #define SMOOTH_SCROLL()  \
 	float animdx = 0, animdy = 0; \
-	int mx = map->mx; \
-	int my = map->my; \
 	if (map->move_max) \
 	{ \
 		map->move_step += nb_keyframes; \
@@ -860,6 +858,8 @@ static int map_get_scroll(lua_State *L)
 {
 	map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1);
 	int nb_keyframes = 1;
+	int mx = map->mx;
+	int my = map->my;
 	SMOOTH_SCROLL();
 	lua_pushnumber(L, -animdx);
 	lua_pushnumber(L, -animdy);
@@ -1040,6 +1040,8 @@ static int map_to_screen(lua_State *L)
 	int vert_idx = 0;
 	int col_idx = 0;
 	GLuint cur_tex = 0;
+	int mx = map->mx;
+	int my = map->my;
 
 	/* Enables Depth Testing */
 	glEnable(GL_DEPTH_TEST);
@@ -1052,9 +1054,13 @@ static int map_to_screen(lua_State *L)
 	glColorPointer(4, GL_FLOAT, 0, colors);
 
 	// Smooth scrolling
-	SMOOTH_SCROLL();
-	x -= animdx;
-	y -= animdy;
+	// If we use shaders for FOV display it means we must uses fbos for smooth scroll too
+	if (!always_show)
+	{
+		SMOOTH_SCROLL();
+		x -= animdx;
+		y -= animdy;
+	}
 
 	map->used_mx = mx;
 	map->used_my = my;
-- 
GitLab