From 50963c73faf5aadc9cca03a1df2968c7f2b85723 Mon Sep 17 00:00:00 2001 From: Warmist Date: Fri, 14 Feb 2014 11:50:12 +0200 Subject: [PATCH] rendermax: added adv mode lights also more proc-expensive diffuse mode. --- plugins/rendermax/renderer_light.cpp | 109 ++++++++++++++++++++++++--- plugins/rendermax/renderer_light.hpp | 14 ++-- plugins/rendermax/rendermax.cpp | 2 + plugins/rendermax/rendermax.lua | 5 +- 4 files changed, 113 insertions(+), 17 deletions(-) diff --git a/plugins/rendermax/renderer_light.cpp b/plugins/rendermax/renderer_light.cpp index 4df4ea9bf..1127c6636 100644 --- a/plugins/rendermax/renderer_light.cpp +++ b/plugins/rendermax/renderer_light.cpp @@ -124,6 +124,7 @@ void lightingEngineViewscreen::reinit() ocupancy.resize(size); lights.resize(size); } + void plotCircle(int xm, int ym, int r,const std::function& setPixel) { int x = -r, y = 0, err = 2-2*r; /* II. Quadrant */ @@ -163,7 +164,7 @@ void plotLine(int x0, int y0, int x1, int y1,rgbf power,const std::function= dy) { err += dy; x0 += sx; rdx=sx;} /* e_xy+e_x > 0 */ if (e2 <= dx) { err += dx; y0 += sy; rdy=sy;} /* e_xy+e_y < 0 */ } + return ; } +void plotLineDiffuse(int x0, int y0, int x1, int y1,rgbf power,int num_diffuse,const std::function& setPixel,bool skip_hack=false) +{ + + int dx = abs(x1-x0), sx = x0= dy) { err += dy; x0 += sx; rdx=sx;} /* e_xy+e_x > 0 */ + if (e2 <= dx) { err += dx; y0 += sy; rdy=sy;} /* e_xy+e_y < 0 */ + if(num_diffuse>0 && dsq/4<(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0))//reached center? + { + const float betta=0.25; + int nx=y1-y0; //right angle + int ny=x1-x0; + if((nx*nx+ny*ny)*betta*betta>2) + { + plotLineDiffuse(x0,y0,x0+nx*betta,y0+ny*betta,power,num_diffuse-1,setPixel,true); + plotLineDiffuse(x0,y0,x0-nx*betta,y0-ny*betta,power,num_diffuse-1,setPixel,true); + } + } + } + return ; +} void plotLineAA(int x0, int y0, int x1, int y1,rgbf power,const std::function& setPixelAA) { int dx = abs(x1-x0), sx = x0invalidate(); return; } - + + bool isAdventure=(*df::global::gametype==df::game_type::ADVENTURE_ARENA)|| + (*df::global::gametype==df::game_type::ADVENTURE_MAIN); + if(isAdventure) + { + fixAdvMode(adv_mode); + } + if(doDebug) std::swap(ocupancy,myRenderer->lightGrid); else @@ -278,9 +322,47 @@ void lightingEngineViewscreen::updateWindow() myRenderer->invalidateRect(vp.first.x,vp.first.y,vp.second.x-vp.first.x,vp.second.y-vp.first.y); } - -static size_t max_list_size = 100000; // Avoid iterating over huge lists - +void lightingEngineViewscreen::preRender() +{ + +} +void lightingEngineViewscreen::fixAdvMode(int mode) +{ + + MapExtras::MapCache mc; + const rgbf dim(levelDim,levelDim,levelDim); + rect2d vp=getMapViewport(); + int window_x=*df::global::window_x; + int window_y=*df::global::window_y; + int window_z=*df::global::window_z; + coord2d vpSize=rect_size(vp); + //mode 0-> make dark non-visible parts + if(mode==0) + { + for(int x=vp.first.x;x make everything visible, let the lighting hide stuff + else if(mode==1) + { + for(int x=vp.first.x;xtiletypeAt(gpos); df::tile_designation d = b->DesignationAt(gpos); - if(d.bits.hidden) + if(d.bits.hidden ) { curCell=rgbf(0,0,0); continue; // do not process hidden stuff, TODO other hidden stuff @@ -947,6 +1029,8 @@ int lightingEngineViewscreen::parseSpecial(lua_State* L) GETLUANUMBER(engine->levelDim,levelDim); GETLUANUMBER(engine->dayHour,dayHour); GETLUANUMBER(engine->daySpeed,daySpeed); + GETLUANUMBER(engine->num_diffuse,diffusionCount); + GETLUANUMBER(engine->adv_mode,advMode); lua_getfield(L,-1,"dayColors"); if(lua_istable(L,-1)) { @@ -1091,6 +1175,8 @@ void lightingEngineViewscreen::defaultSettings() levelDim=0.2f; dayHour=-1; daySpeed=1; + adv_mode=0; + num_diffuse=0; dayColors.push_back(rgbf(0,0,0)); dayColors.push_back(rgbf(1,1,1)); dayColors.push_back(rgbf(0,0,0)); @@ -1281,17 +1367,17 @@ rgbf lightThread::lightUpCell(rgbf power,int dx,int dy,int tx,int ty) else return rgbf(); } -void lightThread::doRay(const rgbf& power,int cx,int cy,int tx,int ty) +void lightThread::doRay(const rgbf& power,int cx,int cy,int tx,int ty,int num_diffuse) { using namespace std::placeholders; - - plotLine(cx,cy,tx,ty,power,std::bind(&lightThread::lightUpCell,this,_1,_2,_3,_4,_5)); + plotLineDiffuse(cx,cy,tx,ty,power,num_diffuse,std::bind(&lightThread::lightUpCell,this,_1,_2,_3,_4,_5)); } void lightThread::doLight( int x,int y ) { using namespace std::placeholders; lightSource& csource=dispatch.lights[x*dispatch.getH()+y]; + int num_diffuse=dispatch.num_diffusion; if(csource.radius>0) { rgbf power=csource.power; @@ -1310,8 +1396,9 @@ void lightThread::doLight( int x,int y ) surrounds += lightUpCell( power, i, j,x+i, y+j); //and this is wall hack (so that walls look nice) if(surrounds.dot(surrounds)>0.00001f) //if we needed to light up the suroundings, then raycast { + plotSquare(x,y,radius, - std::bind(&lightThread::doRay,this,power,x,y,_1,_2)); + std::bind(&lightThread::doRay,this,power,x,y,_1,_2,num_diffuse)); } } } @@ -1343,7 +1430,7 @@ void lightThreadDispatch::signalDoneOcclusion() occlusionDone.notify_all(); } -lightThreadDispatch::lightThreadDispatch( lightingEngineViewscreen* p ):parent(p),lights(parent->lights),occlusion(parent->ocupancy), +lightThreadDispatch::lightThreadDispatch( lightingEngineViewscreen* p ):parent(p),lights(parent->lights),occlusion(parent->ocupancy),num_diffusion(parent->num_diffuse), lightMap(parent->lightMap),writeCount(0),occlusionReady(false) { diff --git a/plugins/rendermax/renderer_light.hpp b/plugins/rendermax/renderer_light.hpp index eadd497e6..83d5da28f 100644 --- a/plugins/rendermax/renderer_light.hpp +++ b/plugins/rendermax/renderer_light.hpp @@ -47,7 +47,7 @@ private: float light_adaptation; rgbf adapt_to_light(const rgbf& light) { - const float influence=0.0001; + const float influence=0.0001f; const float max_adapt=1; const float min_adapt=0; float intensity=(light.r+light.g+light.b)/3.0; @@ -136,6 +136,7 @@ public: virtual void calculate()=0; virtual void updateWindow()=0; + virtual void preRender()=0; virtual void loadSettings()=0; virtual void clear()=0; @@ -225,7 +226,8 @@ public: tthread::mutex unprocessedMutex; std::stack unprocessed; //stack of parts of map where lighting is not finished std::vector& occlusion; - + int& num_diffusion; + tthread::mutex writeLock; //mutex for lightMap std::vector& lightMap; @@ -257,7 +259,7 @@ public: void run(); private: void doLight(int x,int y); - void doRay(const rgbf& power,int cx,int cy,int tx,int ty); + void doRay(const rgbf& power,int cx,int cy,int tx,int ty,int num_diffuse); rgbf lightUpCell(rgbf power,int dx,int dy,int tx,int ty); }; class lightingEngineViewscreen:public lightingEngine @@ -269,13 +271,13 @@ public: void calculate(); void updateWindow(); - + void preRender(); void loadSettings(); void clear(); void debug(bool enable){doDebug=enable;}; private: - + void fixAdvMode(int mode); df::coord2d worldToViewportCoord(const df::coord2d& in,const DFHack::rect2d& r,const df::coord2d& window2d) ; @@ -313,6 +315,7 @@ private: std::vector lights; //Threading stuff + int num_diffuse; //under same lock as ocupancy lightThreadDispatch threading; //misc void setHour(float h){dayHour=h;}; @@ -346,6 +349,7 @@ private: matLightDef matWater; matLightDef matCitizen; float levelDim; + int adv_mode; //materials std::unordered_map,matLightDef> matDefs; //buildings diff --git a/plugins/rendermax/rendermax.cpp b/plugins/rendermax/rendermax.cpp index 0a15807af..dcfee0092 100644 --- a/plugins/rendermax/rendermax.cpp +++ b/plugins/rendermax/rendermax.cpp @@ -61,6 +61,7 @@ struct dwarmode_render_hook : viewscreen_dwarfmodest{ DEFINE_VMETHOD_INTERPOSE(void,render,()) { CoreSuspendClaimer suspend; + engine->preRender(); INTERPOSE_NEXT(render)(); engine->calculate(); engine->updateWindow(); @@ -73,6 +74,7 @@ struct dungeon_render_hook : viewscreen_dungeonmodest{ DEFINE_VMETHOD_INTERPOSE(void,render,()) { CoreSuspendClaimer suspend; + engine->preRender(); INTERPOSE_NEXT(render)(); engine->calculate(); engine->updateWindow(); diff --git a/plugins/rendermax/rendermax.lua b/plugins/rendermax/rendermax.lua index 24b5c7fc8..d26b3d2c1 100644 --- a/plugins/rendermax/rendermax.lua +++ b/plugins/rendermax/rendermax.lua @@ -189,6 +189,9 @@ special.dayColors={ {0,0,0}, --dark at 0 hours {0.5,0.5,0.5}, {0,0,0}} --dark at 24 hours special.daySpeed=1 -- 1->1200 cur_year_ticks per day. 2->600 ticks +special.diffusionCount=1 -- split beam max 1 times to mimic diffuse lights +special.advMode=0 -- 1 or 0 different modes for adv mode. 0-> use df vision system, + -- 1(does not work)->everything visible, let rendermax light do the work --TODO dragonfire --materials @@ -219,4 +222,4 @@ addCreature("ELEMENTMAN_MAGMA",{0.8,0.2,0.2},{0.8,0.2,0.2},5) --items addItem("GEM",nil,nil,{"useMaterial","onGround"}) addItem("ROUGH",nil,nil,{"useMaterial","onGround"}) -addItem("SMALLGEM",nil,nil,{"useMaterial","onGround"}) \ No newline at end of file +addItem("SMALLGEM",nil,nil,{"useMaterial","onGround"})