Conflicts:
	plugins/rendermax/renderer_light.cpp
develop
Japa 2013-06-25 23:23:52 +05:30
commit 539abff49a
6 changed files with 101 additions and 36 deletions

@ -36,4 +36,4 @@ ENDIF(UNIX)
# this makes sure all the stuff is put in proper places and linked to dfhack # this makes sure all the stuff is put in proper places and linked to dfhack
DFHACK_PLUGIN(rendermax ${PROJECT_SRCS} LINK_LIBRARIES ${PROJECT_LIBS}) DFHACK_PLUGIN(rendermax ${PROJECT_SRCS} LINK_LIBRARIES ${PROJECT_LIBS})
install(FILES rendermax.lua install(FILES rendermax.lua
DESTINATION ${DFHACK_DATA_DESTINATION}) DESTINATION ${DFHACK_BINARY_DESTINATION})

@ -27,7 +27,7 @@ using df::global::gps;
using namespace DFHack; using namespace DFHack;
using df::coord2d; using df::coord2d;
const float levelDim=0.2f;
const float RootTwo = 1.4142135623730950488016887242097f; const float RootTwo = 1.4142135623730950488016887242097f;
lightSource::lightSource(lightCell power,int radius):power(power),flicker(false) lightSource::lightSource(lightCell power,int radius):power(power),flicker(false)
@ -36,6 +36,7 @@ lightSource::lightSource(lightCell power,int radius):power(power),flicker(false)
this->radius = radius; this->radius = radius;
else else
{ {
float levelDim = 0.2f;
float totalPower = power.r; float totalPower = power.r;
if(totalPower < power.g)totalPower = power.g; if(totalPower < power.g)totalPower = power.g;
if(totalPower < power.b)totalPower = power.b; if(totalPower < power.b)totalPower = power.b;
@ -239,6 +240,16 @@ void lightingEngineViewscreen::doFovs()
} }
} }
} }
void lightingEngineViewscreen::clear()
{
lightMap.assign(lightMap.size(),lightCell(1,1,1));
tthread::lock_guard<tthread::fast_mutex> guard(myRenderer->dataMutex);
if(lightMap.size()==myRenderer->lightGrid.size())
{
std::swap(myRenderer->lightGrid,lightMap);
myRenderer->invalidate();
}
}
void lightingEngineViewscreen::calculate() void lightingEngineViewscreen::calculate()
{ {
rect2d vp=getMapViewport(); rect2d vp=getMapViewport();
@ -270,8 +281,8 @@ void lightingEngineViewscreen::updateWindow()
std::swap(lightMap,myRenderer->lightGrid); std::swap(lightMap,myRenderer->lightGrid);
rect2d vp=getMapViewport(); rect2d vp=getMapViewport();
//myRenderer->invalidateRect(vp.first.x,vp.first.y,vp.second.x-vp.first.x,vp.second.y-vp.first.y); myRenderer->invalidateRect(vp.first.x,vp.first.y,vp.second.x-vp.first.x,vp.second.y-vp.first.y);
myRenderer->invalidate(); //myRenderer->invalidate();
//std::copy(lightMap.begin(),lightMap.end(),myRenderer->lightGrid.begin()); //std::copy(lightMap.begin(),lightMap.end(),myRenderer->lightGrid.begin());
} }
void lightSource::combine(const lightSource& other) void lightSource::combine(const lightSource& other)
@ -462,7 +473,7 @@ void lightingEngineViewscreen::doSun(const lightSource& sky,MapExtras::MapCache&
void lightingEngineViewscreen::doOcupancyAndLights() void lightingEngineViewscreen::doOcupancyAndLights()
{ {
// TODO better curve (+red dawn ?) // TODO better curve (+red dawn ?)
float daycol = 0;//abs((*df::global::cur_year_tick % 1200) - 600.0) / 400.0; float daycol = 1;//abs((*df::global::cur_year_tick % 1200) - 600.0) / 400.0;
lightCell sky_col(daycol, daycol, daycol); lightCell sky_col(daycol, daycol, daycol);
lightSource sky(sky_col, 15); lightSource sky(sky_col, 15);
@ -602,21 +613,20 @@ void lightingEngineViewscreen::doOcupancyAndLights()
} }
if(df::global::cursor->x>-30000) if(df::global::cursor->x>-30000)
{ {
//lightSource cursor(lightCell(9.6f,8.4f,0.3f),-1);
//cursor.flicker=false;
int wx=df::global::cursor->x-window_x+vp.first.x; int wx=df::global::cursor->x-window_x+vp.first.x;
int wy=df::global::cursor->y-window_y+vp.first.y; int wy=df::global::cursor->y-window_y+vp.first.y;
int tile=getIndex(wx,wy); int tile=getIndex(wx,wy);
applyMaterial(tile,matCursor); applyMaterial(tile,matCursor);
} }
lightSource citizen(lightCell(0.80f,0.80f,0.90f),6); //citizen only emit light, if defined
if(matCitizen.isEmiting)
for (int i=0;i<df::global::world->units.active.size();++i) for (int i=0;i<df::global::world->units.active.size();++i)
{ {
df::unit *u = df::global::world->units.active[i]; df::unit *u = df::global::world->units.active[i];
coord2d pos=worldToViewportCoord(coord2d(u->pos.x,u->pos.y),vp,window2d); coord2d pos=worldToViewportCoord(coord2d(u->pos.x,u->pos.y),vp,window2d);
if(u->pos.z==window_z && isInViewport(pos,vp)) if(u->pos.z==window_z && isInViewport(pos,vp))
if (DFHack::Units::isCitizen(u) && !u->counters.unconscious) if (DFHack::Units::isCitizen(u) && !u->counters.unconscious)
addLight(getIndex(pos.x,pos.y),citizen); addLight(getIndex(pos.x,pos.y),matCitizen.makeSource());
} }
//buildings //buildings
for(size_t i = 0; i < df::global::world->buildings.all.size(); i++) for(size_t i = 0; i < df::global::world->buildings.all.size(); i++)
@ -754,6 +764,10 @@ int lightingEngineViewscreen::parseSpecial(lua_State* L)
LOAD_SPECIAL(FROZEN_LIQUID,matIce); LOAD_SPECIAL(FROZEN_LIQUID,matIce);
LOAD_SPECIAL(AMBIENT,matAmbience); LOAD_SPECIAL(AMBIENT,matAmbience);
LOAD_SPECIAL(CURSOR,matCursor); LOAD_SPECIAL(CURSOR,matCursor);
LOAD_SPECIAL(CITIZEN,matCitizen);
lua_getfield(L,-1,"LevelDim");
if(!lua_isnil(L,-1) && lua_isnumber(L,-1))engine->levelDim=lua_tonumber(L,-1);
lua_pop(L,1);
return 0; return 0;
} }
#undef LOAD_SPECIAL #undef LOAD_SPECIAL
@ -766,6 +780,8 @@ void lightingEngineViewscreen::defaultSettings()
matCursor=matLightDef(lightCell(0.96f,0.84f,0.03f),11); matCursor=matLightDef(lightCell(0.96f,0.84f,0.03f),11);
matCursor.flicker=true; matCursor.flicker=true;
matWall=matLightDef(lightCell(0,0,0)); matWall=matLightDef(lightCell(0,0,0));
matCitizen=matLightDef(lightCell(0.8f,0.8f,0.9f),6);
levelDim=0.2f;
} }
void lightingEngineViewscreen::loadSettings() void lightingEngineViewscreen::loadSettings()
{ {
@ -782,6 +798,7 @@ void lightingEngineViewscreen::loadSettings()
if(ret==LUA_ERRFILE) if(ret==LUA_ERRFILE)
{ {
out.printerr("File not found:%s\n",settingsfile.c_str()); out.printerr("File not found:%s\n",settingsfile.c_str());
lua_pop(s,1);
} }
else if(ret==LUA_ERRSYNTAX) else if(ret==LUA_ERRSYNTAX)
{ {
@ -805,6 +822,7 @@ void lightingEngineViewscreen::loadSettings()
Lua::SafeCall(out,s,2,0); Lua::SafeCall(out,s,2,0);
} }
} }
} }
catch(std::exception& e) catch(std::exception& e)

@ -75,6 +75,7 @@ public:
virtual void updateWindow()=0; virtual void updateWindow()=0;
virtual void loadSettings()=0; virtual void loadSettings()=0;
virtual void clear()=0;
protected: protected:
renderer_light* myRenderer; renderer_light* myRenderer;
@ -108,7 +109,7 @@ struct matLightDef
bool flicker; bool flicker;
lightCell emitColor; lightCell emitColor;
int radius; int radius;
matLightDef(){} matLightDef():isTransparent(false),isEmiting(false),transparency(0,0,0),emitColor(0,0,0),radius(0){}
matLightDef(lightCell transparency,lightCell emit,int rad):isTransparent(true),isEmiting(true), matLightDef(lightCell transparency,lightCell emit,int rad):isTransparent(true),isEmiting(true),
transparency(transparency),emitColor(emit),radius(rad){} transparency(transparency),emitColor(emit),radius(rad){}
matLightDef(lightCell emit,int rad):isTransparent(false),isEmiting(true),emitColor(emit),radius(rad),transparency(0,0,0){} matLightDef(lightCell emit,int rad):isTransparent(false),isEmiting(true),emitColor(emit),radius(rad),transparency(0,0,0){}
@ -130,6 +131,7 @@ public:
void updateWindow(); void updateWindow();
void loadSettings(); void loadSettings();
void clear();
private: private:
df::coord2d worldToViewportCoord(const df::coord2d& in,const DFHack::rect2d& r,const df::coord2d& window2d) ; df::coord2d worldToViewportCoord(const df::coord2d& in,const DFHack::rect2d& r,const df::coord2d& window2d) ;
@ -170,6 +172,8 @@ private:
matLightDef matCursor; matLightDef matCursor;
matLightDef matWall; matLightDef matWall;
matLightDef matWater; matLightDef matWater;
matLightDef matCitizen;
float levelDim;
//materials //materials
std::map<std::pair<int,int>,matLightDef> matDefs; std::map<std::pair<int,int>,matLightDef> matDefs;

@ -124,13 +124,13 @@ public:
for(int j=y;j<y+h;j++) for(int j=y;j<y+h;j++)
{ {
int index=i*df::global::gps->dimy + j; int index=i*df::global::gps->dimy + j;
screen_old[index*4]=0; screen_old[index*4]=screen[index*4]+1;//ensure tile is different
} }
}; };
void invalidate() void invalidate()
{ {
//invalidateRect(0,0,df::global::gps->dimx,df::global::gps->dimy); invalidateRect(0,0,df::global::gps->dimx,df::global::gps->dimy);
df::global::gps->force_full_display_count++; //df::global::gps->force_full_display_count++;
}; };
protected: protected:
renderer* parent; renderer* parent;

@ -3,6 +3,8 @@
#include <LuaTools.h> #include <LuaTools.h>
#include <VTableInterpose.h>
#include "Core.h" #include "Core.h"
#include "Console.h" #include "Console.h"
#include "Export.h" #include "Export.h"
@ -15,12 +17,18 @@
#include "renderer_opengl.hpp" #include "renderer_opengl.hpp"
#include "renderer_light.hpp" #include "renderer_light.hpp"
#include "df/viewscreen_dwarfmodest.h"
#include "df/viewscreen_dungeonmodest.h"
using df::viewscreen_dungeonmodest;
using df::viewscreen_dwarfmodest;
using namespace DFHack; using namespace DFHack;
using std::vector; using std::vector;
using std::string; using std::string;
enum RENDERER_MODE enum RENDERER_MODE
{ {
MODE_DEFAULT,MODE_TRIPPY,MODE_TRUECOLOR,MODE_LUA,MODE_LIGHT,MODE_LIGHT_OFF MODE_DEFAULT,MODE_TRIPPY,MODE_TRUECOLOR,MODE_LUA,MODE_LIGHT
}; };
RENDERER_MODE current_mode=MODE_DEFAULT; RENDERER_MODE current_mode=MODE_DEFAULT;
lightingEngine *engine=NULL; lightingEngine *engine=NULL;
@ -42,10 +50,44 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
)); ));
return CR_OK; return CR_OK;
} }
struct dwarmode_render_hook : viewscreen_dwarfmodest{
typedef df::viewscreen_dwarfmodest interpose_base;
DEFINE_VMETHOD_INTERPOSE(void,render,())
{
CoreSuspendClaimer suspend;
INTERPOSE_NEXT(render)();
engine->calculate();
engine->updateWindow();
}
};
IMPLEMENT_VMETHOD_INTERPOSE(dwarmode_render_hook, render);
struct dungeon_render_hook : viewscreen_dungeonmodest{
typedef df::viewscreen_dungeonmodest interpose_base;
DEFINE_VMETHOD_INTERPOSE(void,render,())
{
CoreSuspendClaimer suspend;
INTERPOSE_NEXT(render)();
engine->calculate();
engine->updateWindow();
}
};
IMPLEMENT_VMETHOD_INTERPOSE(dungeon_render_hook, render);
void removeOld() void removeOld()
{ {
if(engine)
{
CoreSuspender lock;
INTERPOSE_HOOK(dwarmode_render_hook,render).apply(false);
INTERPOSE_HOOK(dungeon_render_hook,render).apply(false);
delete engine;
}
if(current_mode!=MODE_DEFAULT) if(current_mode!=MODE_DEFAULT)
delete df::global::enabler->renderer; delete df::global::enabler->renderer;
current_mode=MODE_DEFAULT; current_mode=MODE_DEFAULT;
} }
void installNew(df::renderer* r,RENDERER_MODE newMode) void installNew(df::renderer* r,RENDERER_MODE newMode)
@ -231,6 +273,10 @@ DFHACK_PLUGIN_LUA_COMMANDS {
DFHACK_LUA_COMMAND(invalidate), DFHACK_LUA_COMMAND(invalidate),
DFHACK_LUA_END DFHACK_LUA_END
}; };
static command_result rendermax(color_ostream &out, vector <string> & parameters) static command_result rendermax(color_ostream &out, vector <string> & parameters)
{ {
if(parameters.size()==0) if(parameters.size()==0)
@ -304,20 +350,23 @@ static command_result rendermax(color_ostream &out, vector <string> & parameters
} }
else if(cmd=="light") else if(cmd=="light")
{ {
if(current_mode!=MODE_LIGHT || current_mode!=MODE_LIGHT_OFF) if(current_mode!=MODE_LIGHT)
{ {
removeOld(); removeOld();
renderer_light *myRender=new renderer_light(df::global::enabler->renderer); renderer_light *myRender=new renderer_light(df::global::enabler->renderer);
installNew(myRender,MODE_LIGHT); installNew(myRender,MODE_LIGHT);
engine=new lightingEngineViewscreen(myRender); engine=new lightingEngineViewscreen(myRender);
engine->calculate(); INTERPOSE_HOOK(dwarmode_render_hook,render).apply(true);
engine->updateWindow(); INTERPOSE_HOOK(dungeon_render_hook,render).apply(true);
} }
else if(current_mode==MODE_LIGHT && parameters.size()>1) else if(current_mode==MODE_LIGHT && parameters.size()>1)
{ {
if(parameters[1]=="reload") if(parameters[1]=="reload")
{
CoreSuspender suspend;
engine->loadSettings(); engine->loadSettings();
} }
}
else else
out.printerr("Light mode already enabled"); out.printerr("Light mode already enabled");
@ -327,8 +376,6 @@ static command_result rendermax(color_ostream &out, vector <string> & parameters
{ {
if(current_mode==MODE_DEFAULT) if(current_mode==MODE_DEFAULT)
out.print("%s\n","Not installed, doing nothing."); out.print("%s\n","Not installed, doing nothing.");
else if(current_mode==MODE_LIGHT)
current_mode=MODE_LIGHT_OFF;
else else
removeOld(); removeOld();
@ -336,27 +383,21 @@ static command_result rendermax(color_ostream &out, vector <string> & parameters
} }
return CR_WRONG_USAGE; return CR_WRONG_USAGE;
} }
DFhackCExport command_result plugin_onupdate (color_ostream &out)
DFhackCExport command_result plugin_shutdown(color_ostream &)
{ {
if(engine)
{
if(current_mode==MODE_LIGHT_OFF)
{
delete engine;
engine=0;
removeOld(); removeOld();
}
else
{
engine->calculate();
engine->updateWindow();
}
}
return CR_OK; return CR_OK;
} }
DFhackCExport command_result plugin_shutdown(color_ostream &) DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
{ {
removeOld(); if(event==SC_VIEWSCREEN_CHANGED)
{
CoreSuspendClaimer suspender;
if(current_mode==MODE_LIGHT)
{
engine->clear();
}
}
return CR_OK; return CR_OK;
} }

@ -49,6 +49,8 @@ special.WATER=makeMaterialDef({0.5,0.5,0.8})
special.FROZEN_LIQUID=makeMaterialDef({0.2,0.7,0.9}) -- ice special.FROZEN_LIQUID=makeMaterialDef({0.2,0.7,0.9}) -- ice
special.AMBIENT=makeMaterialDef({0.85,0.85,0.85}) --ambient fog special.AMBIENT=makeMaterialDef({0.85,0.85,0.85}) --ambient fog
special.CURSOR=makeMaterialDef({1,1,1},{0.96,0.84,0.03},11, {"flicker"}) special.CURSOR=makeMaterialDef({1,1,1},{0.96,0.84,0.03},11, {"flicker"})
special.CITIZEN=makeMaterialDef(nil,{0.80,0.80,0.90},6)
special.LevelDim=0.2 -- darkness. Do not set to 0
--TODO dragonfire --TODO dragonfire
--TODO daylight --TODO daylight
--materials --materials