From 010ff58d304a71ba67215252b6d35100416742e9 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Wed, 28 Jul 2010 21:46:43 +0000
Subject: [PATCH] New Entity:getDisplayString() method that returns a string
 that makes drawColorString* display the entity image inside the text (only
 works on cards that can do framebuffer objects) Inventory, stores, tooltips,
 ... now display the image Fixed Sunburst description

git-svn-id: http://svn.net-core.org/repos/t-engine4@942 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engine/Entity.lua                        |  31 +++-
 game/engine/Tooltip.lua                       |   6 +-
 game/engine/class.lua                         |   1 +
 game/engine/dialogs/ShowEquipInven.lua        |   4 +-
 game/engine/dialogs/ShowEquipment.lua         |   2 +-
 game/engine/dialogs/ShowInventory.lua         |   2 +-
 game/engine/dialogs/ShowPickupFloor.lua       |   2 +-
 game/engine/dialogs/ShowStore.lua             |   4 +-
 game/engine/utils.lua                         |  31 ++--
 game/modules/tome/class/Actor.lua             |   4 +-
 game/modules/tome/class/Grid.lua              |   6 +-
 game/modules/tome/class/Object.lua            |  10 +-
 game/modules/tome/class/Trap.lua              |   2 +-
 game/modules/tome/data/talents/divine/sun.lua |   2 +-
 src/core_lua.c                                |  32 +++-
 src/map.c                                     | 145 ++++++++++++++----
 16 files changed, 221 insertions(+), 63 deletions(-)

diff --git a/game/engine/Entity.lua b/game/engine/Entity.lua
index 7d5df66baa..10c36c574c 100644
--- a/game/engine/Entity.lua
+++ b/game/engine/Entity.lua
@@ -29,10 +29,12 @@ local next_uid = 1
 local entities_load_functions = {}
 
 _M.__mo_repo = {}
+_M.__mo_final_repo = {}
 
 -- Setup the uids & MO repository as a weak value table, when the entities are no more used anywhere else they disappear from there too
 setmetatable(__uids, {__mode="v"})
 setmetatable(_M.__mo_repo, {__mode="v"})
+setmetatable(_M.__mo_final_repo, {__mode="k"})
 
 --- Invalidates the whole MO repository
 function _M:invalidateAllMO()
@@ -41,6 +43,7 @@ function _M:invalidateAllMO()
 	end
 	_M.__mo_repo = {}
 	setmetatable(_M.__mo_repo, {__mode="v"})
+	setmetatable(_M.__mo_final_repo, {__mode="k"})
 end
 
 local function copy_recurs(dst, src, deep)
@@ -218,9 +221,33 @@ function _M:getMapObjects(tiles, mos, z)
 	until not mo
 end
 
-function _M:getDisplayString(mo)
+--- Get the entity image as an sdl surface and texture for the given tiles and size
+-- @param tiles a Tiles instance that will handle the tiles (usualy pass it the current Map.tiles)
+-- @param w the width
+-- @param h the height
+-- @return the sdl surface and the texture
+function _M:getEntityFinalSurface(tiles, w, h)
+	local id = w.."x"..h
+	if _M.__mo_final_repo[self] and _M.__mo_final_repo[self][id] then return _M.__mo_final_repo[self][id].surface, _M.__mo_final_repo[self][id].tex end
+
+	local Map = require "engine.Map"
+
+	local mos = {}
+	local list = {}
+	self:getMapObjects(tiles, mos, 1)
+	for i = 1, Map.zdepth do
+		if mos[i] then list[#list+1] = mos[i] end
+	end
+	local tex = core.map.mapObjectsToTexture(w, h, unpack(list))
+	_M.__mo_final_repo[self] = _M.__mo_final_repo[self] or {}
+	_M.__mo_final_repo[self][id] = {surface=tex:toSurface(), tex=tex}
+	return _M.__mo_final_repo[self][id].surface, _M.__mo_final_repo[self][id].tex
+end
+
+--- Get a string that will display in text the texture of this entity
+function _M:getDisplayString()
 	if core.display.FBOActive() then
-		return "#UID:"..self.uid..":"..(mo or 0).."#"
+		return "#UID:"..self.uid..":0#"
 	else
 		return ""
 	end
diff --git a/game/engine/Tooltip.lua b/game/engine/Tooltip.lua
index c279832bd0..a8cb476691 100644
--- a/game/engine/Tooltip.lua
+++ b/game/engine/Tooltip.lua
@@ -84,16 +84,16 @@ function _M:display()
 
 	local i = 1
 	local y = 0
-	local r, g, b, max_h = self.color[1], self.color[2], self.color[3], nil
+	local r, g, b = self.color[1], self.color[2], self.color[3], nil
 	for ii, l in ipairs(self.text) do
 		if self.text[i] == "---" then
 			self:drawWBorder(self.surface, 4, 4 + y + 0.5 * self.font_h, self.w - 8)
 			i = i + 1
 			y = y + self.font_h
 		else
-			r, g, b, max_h = self.surface:drawColorStringBlended(self.font, self.text[i], 4, 4 + y, self.color[1], self.color[2], self.color[3])
+			r, g, b = self.surface:drawColorStringBlended(self.font, self.text[i], 4, 4 + y, self.color[1], self.color[2], self.color[3])
 			i = i + 1
-			y = y + max_h
+			y = y + self.font_h
 		end
 	end
 	self.texture = self.surface:glTexture()
diff --git a/game/engine/class.lua b/game/engine/class.lua
index 8559ece0b2..7220f6a313 100644
--- a/game/engine/class.lua
+++ b/game/engine/class.lua
@@ -188,6 +188,7 @@ function _M:save(filter, allow, savefile)
 	if not allow then
 		filter.new = true
 		filter._mo = true
+		filter._mo_final = true
 	else
 		filter.__CLASSNAME = true
 	end
diff --git a/game/engine/dialogs/ShowEquipInven.lua b/game/engine/dialogs/ShowEquipInven.lua
index 125e15945b..e47a74e8e1 100644
--- a/game/engine/dialogs/ShowEquipInven.lua
+++ b/game/engine/dialogs/ShowEquipInven.lua
@@ -133,7 +133,7 @@ function _M:generateList()
 			for item, o in ipairs(self.actor.inven[inven_id]) do
 				if not self.filter or self.filter(o) then
 					local char = string.char(string.byte('a') + i)
-					list[#list+1] = { name=char..") "..o:getName(), color=o:getDisplayColor(), object=o, inven=inven_id, item=item }
+					list[#list+1] = { name=char..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=inven_id, item=item }
 					chars[char] = #list
 					i = i + 1
 				end
@@ -150,7 +150,7 @@ function _M:generateList()
 	for item, o in ipairs(self.actor:getInven("INVEN")) do
 		if not self.filter or self.filter(o) then
 			local char = string.char(string.byte('a') + i)
-			list[#list+1] = { name=char..") "..o:getName(), color=o:getDisplayColor(), object=o, inven=self.actor.INVEN_INVEN, item=item }
+			list[#list+1] = { name=char..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=self.actor.INVEN_INVEN, item=item }
 			chars[char] = #list
 			i = i + 1
 		end
diff --git a/game/engine/dialogs/ShowEquipment.lua b/game/engine/dialogs/ShowEquipment.lua
index f589b2fc1b..cedfdf1081 100644
--- a/game/engine/dialogs/ShowEquipment.lua
+++ b/game/engine/dialogs/ShowEquipment.lua
@@ -77,7 +77,7 @@ function _M:generateList()
 			for item, o in ipairs(self.actor.inven[inven_id]) do
 				if not self.filter or self.filter(o) then
 					local char = string.char(string.byte('a') + i)
-					list[#list+1] = { name=char..") "..o:getName(), color=o:getDisplayColor(), object=o, inven=inven_id, item=item }
+					list[#list+1] = { name=char..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, inven=inven_id, item=item }
 					chars[char] = #list
 					i = i + 1
 				end
diff --git a/game/engine/dialogs/ShowInventory.lua b/game/engine/dialogs/ShowInventory.lua
index 6d99f16271..ee698ea73d 100644
--- a/game/engine/dialogs/ShowInventory.lua
+++ b/game/engine/dialogs/ShowInventory.lua
@@ -117,7 +117,7 @@ function _M:generateList()
 	local i = 0
 	for item, o in ipairs(self.inven) do
 		if not self.filter or self.filter(o) then
-			list[#list+1] = { name=string.char(string.byte('a') + i)..") "..o:getName(), color=o:getDisplayColor(), object=o, item=item }
+			list[#list+1] = { name=string.char(string.byte('a') + i)..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, item=item }
 			i = i + 1
 		end
 	end
diff --git a/game/engine/dialogs/ShowPickupFloor.lua b/game/engine/dialogs/ShowPickupFloor.lua
index 90aa98ed56..86d5ad1fc2 100644
--- a/game/engine/dialogs/ShowPickupFloor.lua
+++ b/game/engine/dialogs/ShowPickupFloor.lua
@@ -84,7 +84,7 @@ function _M:generateList()
 		local o = game.level.map:getObject(self.x, self.y, idx)
 		if not o then break end
 		if not self.filter or self.filter(o) then
-			list[#list+1] = { name=string.char(string.byte('a') + i - 1)..") "..o:getName(), color=o:getDisplayColor(), object=o, item=idx }
+			list[#list+1] = { name=string.char(string.byte('a') + i - 1)..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, item=idx }
 			i = i + 1
 		end
 		idx = idx + 1
diff --git a/game/engine/dialogs/ShowStore.lua b/game/engine/dialogs/ShowStore.lua
index f6f271ae88..747e16c18d 100644
--- a/game/engine/dialogs/ShowStore.lua
+++ b/game/engine/dialogs/ShowStore.lua
@@ -95,7 +95,7 @@ function _M:generateList()
 	local i = 0
 	for item, o in ipairs(self.store_inven) do
 		if not self.store_filter or self.store_filter(o) then
-			list[#list+1] = { name=string.char(string.byte('a') + i)..") "..o:getName(), color=o:getDisplayColor(), object=o, item=item }
+			list[#list+1] = { name=string.char(string.byte('a') + i)..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, item=item }
 			i = i + 1
 		end
 	end
@@ -106,7 +106,7 @@ function _M:generateList()
 	local i = 0
 	for item, o in ipairs(self.actor_inven) do
 		if not self.actor_filter or self.actor_filter(o) then
-			list[#list+1] = { name=string.char(string.byte('a') + i)..") "..o:getName(), color=o:getDisplayColor(), object=o, item=item }
+			list[#list+1] = { name=string.char(string.byte('a') + i)..") "..o:getDisplayString()..o:getName(), color=o:getDisplayColor(), object=o, item=item }
 			i = i + 1
 		end
 	end
diff --git a/game/engine/utils.lua b/game/engine/utils.lua
index 62fccb618e..e748516cc0 100644
--- a/game/engine/utils.lua
+++ b/game/engine/utils.lua
@@ -243,18 +243,22 @@ end
 
 local tmps = core.display.newSurface(1, 1)
 getmetatable(tmps).__index.drawColorString = function(s, font, str, x, y, r, g, b)
+	local Puid = "UID:" * lpeg.R"09"^1 * ":" * lpeg.R"09"
+	local Puid_cap = "UID:" * lpeg.C(lpeg.R"09"^1) * ":" * lpeg.C(lpeg.R"09")
 	local Pcolorname = (lpeg.R"AZ" + "_")^3
 	local Pcode = (lpeg.R"af" + lpeg.R"09" + lpeg.R"AF")
 	local Pcolorcode = Pcode * Pcode
 
-	local list = str:split("#" * ((Pcolorcode * Pcolorcode * Pcolorcode) + Pcolorname) * "#", true)
+	local list = str:split("#" * (Puid + (Pcolorcode * Pcolorcode * Pcolorcode) + Pcolorname) * "#", true)
 	r = r or 255
 	g = g or 255
 	b = b or 255
 	local oldr, oldg, oldb = r, g, b
+	local max_h = 0
 	for i, v in ipairs(list) do
 		local nr, ng, nb = lpeg.match("#" * lpeg.C(Pcolorcode) * lpeg.C(Pcolorcode) * lpeg.C(Pcolorcode) * "#", v)
 		local col = lpeg.match("#" * lpeg.C(Pcolorname) * "#", v)
+		local uid, mo = lpeg.match("#" * Puid_cap * "#", v)
 		if nr and ng and nb then
 			oldr, oldg, oldb = r, g, b
 			r, g, b = nr:parseHex(), ng:parseHex(), nb:parseHex()
@@ -265,13 +269,25 @@ getmetatable(tmps).__index.drawColorString = function(s, font, str, x, y, r, g,
 				oldr, oldg, oldb = r, g, b
 				r, g, b = colors[col].r, colors[col].g, colors[col].b
 			end
+		elseif uid and mo then
+			uid = tonumber(uid)
+			mo = tonumber(mo)
+			local e = __uids[uid]
+			if e then
+				local surf = e:getEntityFinalSurface(game.level.map.tiles, font:lineSkip(), font:lineSkip())
+				local w, h = surf:getSize()
+				s:merge(surf, x, y)
+				if h > max_h then max_h = h end
+				x = x + (w or 0)
+			end
 		else
 			local w, h = font:size(v)
+			if h > max_h then max_h = h end
 			s:drawString(font, v, x, y, r, g, b)
 			x = x + w
 		end
 	end
-	return r, g, b
+	return r, g, b, max_h
 end
 
 getmetatable(tmps).__index.drawColorStringCentered = function(s, font, str, dx, dy, dw, dh, r, g, b)
@@ -280,6 +296,7 @@ getmetatable(tmps).__index.drawColorStringCentered = function(s, font, str, dx,
 	s:drawColorString(font, str, x, y, r, g, b)
 end
 
+
 getmetatable(tmps).__index.drawColorStringBlended = function(s, font, str, x, y, r, g, b)
 	local Puid = "UID:" * lpeg.R"09"^1 * ":" * lpeg.R"09"
 	local Puid_cap = "UID:" * lpeg.C(lpeg.R"09"^1) * ":" * lpeg.C(lpeg.R"09")
@@ -308,17 +325,13 @@ getmetatable(tmps).__index.drawColorStringBlended = function(s, font, str, x, y,
 				r, g, b = colors[col].r, colors[col].g, colors[col].b
 			end
 		elseif uid and mo then
-			os.exit("FINISH UID DISPLAY IN STRING")
 			uid = tonumber(uid)
 			mo = tonumber(mo)
 			local e = __uids[uid]
 			if e then
-				local surfs = e:getEntitySurfaces(game.level.map.tilesSDL)
-				local w, h = nil, nil
-				for i = 1, #surfs do
-					if not w then w, h = surfs[i]:getSize() end
-					s:merge(surfs[i], x, y)
-				end
+				local surf = e:getEntityFinalSurface(game.level.map.tiles, font:lineSkip(), font:lineSkip())
+				local w, h = surf:getSize()
+				s:merge(surf, x, y)
 				if h > max_h then max_h = h end
 				x = x + (w or 0)
 			end
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 2a9945fdf5..28105476b0 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -401,7 +401,7 @@ function _M:tooltip()
 		resists[#resists+1] = string.format("%d%% %s", v, t == "all" and "all" or DamageType:get(t).name)
 	end
 
-	return ([[%s%s
+	return ([[%s%s%s
 Rank: %s%s
 #00ffff#Level: %d
 Exp: %d/%d
@@ -412,7 +412,7 @@ Size: #ANTIQUE_WHITE#%s
 %s
 Faction: %s%s (%s)
 %s]]):format(
-	rank_color, self.name,
+	self:getDisplayString(), rank_color, self.name,
 	rank_color, rank,
 	self.level,
 	self.exp,
diff --git a/game/modules/tome/class/Grid.lua b/game/modules/tome/class/Grid.lua
index aa886a71d8..a9a2091e5c 100644
--- a/game/modules/tome/class/Grid.lua
+++ b/game/modules/tome/class/Grid.lua
@@ -67,12 +67,12 @@ function _M:tooltip()
 	if self.show_tooltip then
 		local name = ((self.show_tooltip == true) and self.name or self.show_tooltip)
 		if self.desc then
-			return name.."\n"..self.desc
+			return self:getDisplayString()..name.."\n"..self.desc
 		else
-			return name
+			return self:getDisplayString()..name
 		end
 	else
-		return self.name
+		return self:getDisplayString()..self.name
 	end
 end
 
diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua
index 27ef74cb59..29e32c8901 100644
--- a/game/modules/tome/class/Object.lua
+++ b/game/modules/tome/class/Object.lua
@@ -74,7 +74,7 @@ end
 
 --- Returns a tooltip for the object
 function _M:tooltip()
-	return self:getDesc()
+	return self:getDesc{do_color=true}
 end
 
 --- Describes an attribute, to expand object name
@@ -152,7 +152,7 @@ function _M:getName(t)
 	else
 		local _, c = self:getDisplayColor()
 		local ds = self:getDisplayString()
-		if qty == 1 or t.no_count then return c..name.."#LAST#"
+		if qty == 1 or t.no_count then return c..ds..name.."#LAST#"
 		else return c..qty.." "..ds..name.."#LAST#"
 		end
 	end
@@ -326,13 +326,13 @@ function _M:getTextualDesc()
 end
 
 --- Gets the full desc of the object
-function _M:getDesc()
+function _M:getDesc(name_param)
 	local _, c = self:getDisplayColor()
 	local desc
 	if not self:isIdentified() then
-		desc = { c..self:getName().."#FFFFFF#" }
+		desc = { c..self:getName(name_param).."#FFFFFF#" }
 	else
-		desc = { c..self:getName().."#FFFFFF#", self.desc }
+		desc = { c..self:getName(name_param).."#FFFFFF#", self.desc }
 	end
 
 	local reqs = self:getRequirementDesc(game.player)
diff --git a/game/modules/tome/class/Trap.lua b/game/modules/tome/class/Trap.lua
index e7599257e9..f137d2644a 100644
--- a/game/modules/tome/class/Trap.lua
+++ b/game/modules/tome/class/Trap.lua
@@ -44,7 +44,7 @@ end
 --- Returns a tooltip for the trap
 function _M:tooltip()
 	if self:knownBy(game.player) then
-		return self:getName()
+		return self:getDisplayString()..self:getName()
 	end
 end
 
diff --git a/game/modules/tome/data/talents/divine/sun.lua b/game/modules/tome/data/talents/divine/sun.lua
index 9a4dd20b56..4a7f9f442d 100644
--- a/game/modules/tome/data/talents/divine/sun.lua
+++ b/game/modules/tome/data/talents/divine/sun.lua
@@ -143,6 +143,6 @@ newTalent{
 	end,
 	info = function(self, t)
 		return ([[Conjures a furious burst of sunlight, dealing %0.2f light damage to all those around you in a radius of 4.
-		The damage will increase with the Magic stat]]):format(self:getTalentLevel(t), self:combatTalentSpellDamage(t, 10, 160))
+		The damage will increase with the Magic stat]]):format(self:combatTalentSpellDamage(t, 10, 160))
 	end,
 }
diff --git a/src/core_lua.c b/src/core_lua.c
index b8e7491651..156961249a 100644
--- a/src/core_lua.c
+++ b/src/core_lua.c
@@ -669,8 +669,34 @@ static int sdl_new_surface(lua_State *L)
 		rmask, gmask, bmask, amask
 		);
 
-        if (s == NULL)
-          printf("ERROR : SDL_CreateRGBSurface : %s\n",SDL_GetError());
+	if (s == NULL)
+		printf("ERROR : SDL_CreateRGBSurface : %s\n",SDL_GetError());
+
+	return 1;
+}
+
+static int gl_texture_to_sdl(lua_State *L)
+{
+	GLuint *t = (GLuint*)auxiliar_checkclass(L, "gl{texture}", 1);
+
+	SDL_Surface **s = (SDL_Surface**)lua_newuserdata(L, sizeof(SDL_Surface*));
+	auxiliar_setclass(L, "sdl{surface}", -1);
+
+	// Bind the texture to read
+	glBindTexture(GL_TEXTURE_2D, *t);
+
+	// Get texture size
+	GLint w, h;
+	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
+	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
+//	printf("Making surface from texture %dx%d\n", w, h);
+	// Get texture data
+	GLubyte *tmp = calloc(w*h*4, sizeof(GLubyte));
+	glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, tmp);
+
+	// Make sdl surface from it
+	*s = SDL_CreateRGBSurfaceFrom(tmp, w, h, 32, w*4, 0,0,0,0);
+//	SDL_SaveBMP(*s, "/tmp/foo.bmp");
 
 	return 1;
 }
@@ -1092,7 +1118,6 @@ static int sdl_redraw_screen(lua_State *L)
 	return 0;
 }
 
-
 /**************************************************************
  * Framebuffer Objects
  **************************************************************/
@@ -1277,6 +1302,7 @@ static const struct luaL_reg sdl_texture_reg[] =
 	{"close", sdl_free_texture},
 	{"toScreen", sdl_texture_toscreen},
 	{"makeOutline", sdl_texture_outline},
+	{"toSurface", gl_texture_to_sdl},
 	{NULL, NULL},
 };
 
diff --git a/src/map.c b/src/map.c
index 2db407e5bb..5865dfbf23 100644
--- a/src/map.c
+++ b/src/map.c
@@ -128,39 +128,130 @@ static int map_object_is_valid(lua_State *L)
 	return 1;
 }
 
-static int map_object_display(lua_State *L)
+static bool _CheckGL_Error(const char* GLcall, const char* file, const int line)
 {
-	map_object *m = (map_object*)auxiliar_checkclass(L, "core{mapobj}", 1);
-	SDL_Surface **s = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 2);
-	int dx = luaL_checknumber(L, 3);
-	int dy = luaL_checknumber(L, 4);
-	int w = luaL_checknumber(L, 5);
-	int h = luaL_checknumber(L, 6);
-	float r = luaL_checknumber(L, 7);
-	float g = luaL_checknumber(L, 8);
-	float b = luaL_checknumber(L, 9);
-	float a = luaL_checknumber(L, 10);
+    GLenum errCode;
+    if((errCode = glGetError())!=GL_NO_ERROR)
+    {
+		printf("OPENGL ERROR #%i: (%s) in file %s on line %i\n",errCode,gluErrorString(errCode), file, line);
+        printf("OPENGL Call: %s\n",GLcall);
+        return FALSE;
+    }
+    return TRUE;
+}
 
-	glColor4f(r, g, b, (a > 1) ? 1 : ((a < 0) ? 0 : a));
+//#define _DEBUG
+#ifdef _DEBUG
+#define CHECKGL( GLcall )                               		\
+    GLcall;                                             		\
+    if(!_CheckGL_Error( #GLcall, __FILE__, __LINE__))     		\
+    exit(-1);
+#else
+#define CHECKGL( GLcall)        \
+    GLcall;
+#endif
+static int map_objects_display(lua_State *L)
+{
+	if (!fbo_active) return 0;
 
-	int z;
-	if (m->shader) useShader(m->shader, 1, 1, 1,1, r, g, b, a);
-	for (z = (!shaders_active) ? 0 : (m->nb_textures - 1); z >= 0; z--)
+	int w = luaL_checknumber(L, 1);
+	int h = luaL_checknumber(L, 2);
+
+	// Setup our FBO
+	// WARNING: this is a static, only one FBO is ever made, and never deleted, for some reasons
+	// deleting it makes the game crash when doing a chain lightning spell under luajit1 ... (yeah I know .. weird)
+	static GLuint fbo = 0;
+	if (!fbo) CHECKGL(glGenFramebuffersEXT(1, &fbo));
+	CHECKGL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo));
+
+	// Now setup a texture to render to
+	GLuint img;
+	CHECKGL(glGenTextures(1, &img));
+	CHECKGL(glBindTexture(GL_TEXTURE_2D, img));
+	CHECKGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
+	CHECKGL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
+	CHECKGL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
+	CHECKGL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+	CHECKGL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, img, 0));
+
+	GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+	if(status != GL_FRAMEBUFFER_COMPLETE_EXT) return 0;
+
+	// Set the viewport and save the old one
+	CHECKGL(glPushAttrib(GL_VIEWPORT_BIT));
+
+	CHECKGL(glViewport(0, 0, w, h));
+	glMatrixMode(GL_PROJECTION);
+	CHECKGL(glPushMatrix());
+	glLoadIdentity();
+	glOrtho(0, w, 0, h, -101, 101);
+	glMatrixMode( GL_MODELVIEW );
+
+	/* Reset The View */
+	glLoadIdentity( );
+
+	glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
+	CHECKGL(glClear(GL_COLOR_BUFFER_BIT));
+	CHECKGL(glLoadIdentity());
+
+	/***************************************************
+	 * Render to buffer
+	 ***************************************************/
+	int moid = 3;
+	while (lua_isuserdata(L, moid))
 	{
-		if (multitexture_active && shaders_active) glActiveTexture(GL_TEXTURE0+z);
-		glBindTexture(m->textures_is3d[z] ? GL_TEXTURE_3D : GL_TEXTURE_2D, m->textures[z]);
+		map_object *m = (map_object*)auxiliar_checkclass(L, "core{mapobj}", moid);
+
+		glColor4f(1, 1, 1, 1);
+
+		int z;
+		if (m->shader) useShader(m->shader, 1, 1, 1, 1, 1, 1, 1, 1);
+		for (z = (!shaders_active) ? 0 : (m->nb_textures - 1); z >= 0; z--)
+		{
+			if (multitexture_active && shaders_active) glActiveTexture(GL_TEXTURE0+z);
+			glBindTexture(m->textures_is3d[z] ? GL_TEXTURE_3D : GL_TEXTURE_2D, m->textures[z]);
+		}
+
+		int dx = 0, dy = 0;
+		int dz = moid;
+		glBegin(GL_QUADS);
+		glTexCoord2f(0,0); glVertex3f((dx), (dy),				(dz));
+		glTexCoord2f(1,0); glVertex3f(w + (dx), (dy),			(dz));
+		glTexCoord2f(1,1); glVertex3f(w + (dx), h + (dy),	(dz));
+		glTexCoord2f(0,1); glVertex3f((dx), h + (dy),			(dz));
+		glEnd();
+
+		if (m->shader) glUseProgramObjectARB(0);
+
+		moid++;
 	}
+	/***************************************************
+	 ***************************************************/
 
-	int dz = 99;
-	glBegin(GL_QUADS);
-	glTexCoord2f(0,0); glVertex3f((dx), (dy),				(dz));
-	glTexCoord2f(1,0); glVertex3f(w + (dx), (dy),			(dz));
-	glTexCoord2f(1,1); glVertex3f(w + (dx), h + (dy),	(dz));
-	glTexCoord2f(0,1); glVertex3f((dx), h + (dy),			(dz));
-	glEnd();
 
-	if (m->shader) glUseProgramObjectARB(0);
-	return 0;
+	// Unbind texture from FBO and then unbind FBO
+	CHECKGL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0));
+	CHECKGL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
+	// Restore viewport
+	CHECKGL(glPopAttrib());
+
+	// Cleanup
+	// No, dot not it's a static, see upwards
+//	CHECKGL(glDeleteFramebuffersEXT(1, &fbo));
+
+	glMatrixMode(GL_PROJECTION);
+	CHECKGL(glPopMatrix());
+	glMatrixMode( GL_MODELVIEW );
+
+	glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+
+
+	// Now register the texture to lua
+	GLuint *t = (GLuint*)lua_newuserdata(L, sizeof(GLuint));
+	auxiliar_setclass(L, "gl{texture}", -1);
+	*t = img;
+
+	return 1;
 }
 
 
@@ -667,6 +758,7 @@ static const struct luaL_reg maplib[] =
 {
 	{"newMap", map_new},
 	{"newObject", map_object_new},
+	{"mapObjectsToTexture", map_objects_display},
 	{NULL, NULL},
 };
 
@@ -700,7 +792,6 @@ static const struct luaL_reg map_object_reg[] =
 	{"shader", map_object_shader},
 	{"invalidate", map_object_invalid},
 	{"isValid", map_object_is_valid},
-	{"display", map_object_display},
 	{NULL, NULL},
 };
 
-- 
GitLab