llwlparammanager.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:15k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /**
  2.  * @file llwlparammanager.cpp
  3.  * @brief Implementation for the LLWLParamManager class.
  4.  *
  5.  * $LicenseInfo:firstyear=2007&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2007-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llwlparammanager.h"
  34. #include "pipeline.h"
  35. #include "llsky.h"
  36. #include "llfloaterreg.h"
  37. #include "llsliderctrl.h"
  38. #include "llspinctrl.h"
  39. #include "llcheckboxctrl.h"
  40. #include "lluictrlfactory.h"
  41. #include "llcombobox.h"
  42. #include "lllineeditor.h"
  43. #include "llsdserialize.h"
  44. #include "v4math.h"
  45. #include "llviewercontrol.h"
  46. #include "llwlparamset.h"
  47. #include "llpostprocess.h"
  48. #include "llfloaterwindlight.h"
  49. #include "llfloaterdaycycle.h"
  50. #include "llfloaterenvsettings.h"
  51. #include "curl/curl.h"
  52. LLWLParamManager * LLWLParamManager::sInstance = NULL;
  53. static LLFastTimer::DeclareTimer FTM_UPDATE_WLPARAM("Update Windlight Params");
  54. LLWLParamManager::LLWLParamManager() :
  55. //set the defaults for the controls
  56. // index is from sWLUniforms in pipeline.cpp line 979
  57. /// Sun Delta Terrain tweak variables.
  58. mSunDeltaYaw(180.0f),
  59. mSceneLightStrength(2.0f),
  60. mWLGamma(1.0f, "gamma"),
  61. mBlueHorizon(0.25f, 0.25f, 1.0f, 1.0f, "blue_horizon", "WLBlueHorizon"),
  62. mHazeDensity(1.0f, 1.0f, 1.0f, 0.5f, "haze_density"),
  63. mBlueDensity(0.25f, 0.25f, 0.25f, 1.0f, "blue_density", "WLBlueDensity"),
  64. mDensityMult(1.0f, "density_multiplier", 1000),
  65. mHazeHorizon(1.0f, 1.0f, 1.0f, 0.5f, "haze_horizon"),
  66. mMaxAlt(4000.0f, "max_y"),
  67. // Lighting
  68. mLightnorm(0.f, 0.707f, -0.707f, 1.f, "lightnorm"),
  69. mSunlight(0.5f, 0.5f, 0.5f, 1.0f, "sunlight_color", "WLSunlight"),
  70. mAmbient(0.5f, 0.75f, 1.0f, 1.19f, "ambient", "WLAmbient"),
  71. mGlow(18.0f, 0.0f, -0.01f, 1.0f, "glow"),
  72. // Clouds
  73. mCloudColor(0.5f, 0.5f, 0.5f, 1.0f, "cloud_color", "WLCloudColor"),
  74. mCloudMain(0.5f, 0.5f, 0.125f, 1.0f, "cloud_pos_density1"),
  75. mCloudCoverage(0.0f, "cloud_shadow"),
  76. mCloudDetail(0.0f, 0.0f, 0.0f, 1.0f, "cloud_pos_density2"),
  77. mDistanceMult(1.0f, "distance_multiplier"),
  78. mCloudScale(0.42f, "cloud_scale"),
  79. // sky dome
  80. mDomeOffset(0.96f),
  81. mDomeRadius(15000.f)
  82. {
  83. }
  84. LLWLParamManager::~LLWLParamManager()
  85. {
  86. }
  87. void LLWLParamManager::loadPresets(const std::string& file_name)
  88. {
  89. std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""));
  90. LL_DEBUGS2("AppInit", "Shaders") << "Loading Default WindLight settings from " << path_name << LL_ENDL;
  91. bool found = true;
  92. while(found) 
  93. {
  94. std::string name;
  95. found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name, false);
  96. if(found)
  97. {
  98. name=name.erase(name.length()-4);
  99. // bugfix for SL-46920: preventing filenames that break stuff.
  100. char * curl_str = curl_unescape(name.c_str(), name.size());
  101. std::string unescaped_name(curl_str);
  102. curl_free(curl_str);
  103. curl_str = NULL;
  104. LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL;
  105. loadPreset(unescaped_name,FALSE);
  106. }
  107. }
  108. // And repeat for user presets, note the user presets will modify any system presets already loaded
  109. std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", ""));
  110. LL_DEBUGS2("AppInit", "Shaders") << "Loading User WindLight settings from " << path_name2 << LL_ENDL;
  111. found = true;
  112. while(found) 
  113. {
  114. std::string name;
  115. found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name, false);
  116. if(found)
  117. {
  118. name=name.erase(name.length()-4);
  119. // bugfix for SL-46920: preventing filenames that break stuff.
  120. char * curl_str = curl_unescape(name.c_str(), name.size());
  121. std::string unescaped_name(curl_str);
  122. curl_free(curl_str);
  123. curl_str = NULL;
  124. LL_DEBUGS2("AppInit", "Shaders") << "name: " << name << LL_ENDL;
  125. loadPreset(unescaped_name,FALSE);
  126. }
  127. }
  128. }
  129. void LLWLParamManager::savePresets(const std::string & fileName)
  130. {
  131. //Nobody currently calls me, but if they did, then its reasonable to write the data out to the user's folder
  132. //and not over the RO system wide version.
  133. LLSD paramsData(LLSD::emptyMap());
  134. std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", fileName));
  135. for(std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.begin();
  136. mIt != mParamList.end();
  137. ++mIt) 
  138. {
  139. paramsData[mIt->first] = mIt->second.getAll();
  140. }
  141. llofstream presetsXML(pathName);
  142. LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
  143. formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
  144. presetsXML.close();
  145. }
  146. void LLWLParamManager::loadPreset(const std::string & name,bool propagate)
  147. {
  148. // bugfix for SL-46920: preventing filenames that break stuff.
  149. char * curl_str = curl_escape(name.c_str(), name.size());
  150. std::string escaped_filename(curl_str);
  151. curl_free(curl_str);
  152. curl_str = NULL;
  153. escaped_filename += ".xml";
  154. std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", escaped_filename));
  155. LL_DEBUGS2("AppInit", "Shaders") << "Loading WindLight sky setting from " << pathName << LL_ENDL;
  156. llifstream presetsXML;
  157. presetsXML.open(pathName.c_str());
  158. // That failed, try loading from the users area instead.
  159. if(!presetsXML)
  160. {
  161. pathName=gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", escaped_filename);
  162. LL_DEBUGS2("AppInit", "Shaders") << "Loading User WindLight sky setting from " << pathName << LL_ENDL;
  163. presetsXML.clear();
  164.         presetsXML.open(pathName.c_str());
  165. }
  166. if (presetsXML)
  167. {
  168. LLSD paramsData(LLSD::emptyMap());
  169. LLPointer<LLSDParser> parser = new LLSDXMLParser();
  170. parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED);
  171. std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name);
  172. if(mIt == mParamList.end())
  173. {
  174. addParamSet(name, paramsData);
  175. }
  176. else 
  177. {
  178. setParamSet(name, paramsData);
  179. }
  180. presetsXML.close();
  181. else 
  182. {
  183. llwarns << "Can't find " << name << llendl;
  184. return;
  185. }
  186. if(propagate)
  187. {
  188. getParamSet(name, mCurParams);
  189. propagateParameters();
  190. }
  191. }
  192. void LLWLParamManager::savePreset(const std::string & name)
  193. {
  194. // bugfix for SL-46920: preventing filenames that break stuff.
  195. char * curl_str = curl_escape(name.c_str(), name.size());
  196. std::string escaped_filename(curl_str);
  197. curl_free(curl_str);
  198. curl_str = NULL;
  199. escaped_filename += ".xml";
  200. // make an empty llsd
  201. LLSD paramsData(LLSD::emptyMap());
  202. std::string pathName(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", escaped_filename));
  203. // fill it with LLSD windlight params
  204. paramsData = mParamList[name].getAll();
  205. // write to file
  206. llofstream presetsXML(pathName);
  207. LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
  208. formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
  209. presetsXML.close();
  210. propagateParameters();
  211. }
  212. void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)
  213. {
  214. if (gPipeline.canUseWindLightShaders())
  215. {
  216. mCurParams.update(shader);
  217. }
  218. if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT)
  219. {
  220. shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mRotatedLightDir.mV);
  221. shader->uniform3fv("camPosLocal", 1, LLViewerCamera::getInstance()->getOrigin().mV);
  222. else if (shader->mShaderGroup == LLGLSLShader::SG_SKY)
  223. {
  224. shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mClampedLightDir.mV);
  225. }
  226. shader->uniform1f("scene_light_strength", mSceneLightStrength);
  227. }
  228. void LLWLParamManager::propagateParameters(void)
  229. {
  230. LLFastTimer ftm(FTM_UPDATE_WLPARAM);
  231. LLVector4 sunDir;
  232. LLVector4 moonDir;
  233. // set the sun direction from SunAngle and EastAngle
  234. F32 sinTheta = sin(mCurParams.getEastAngle());
  235. F32 cosTheta = cos(mCurParams.getEastAngle());
  236. F32 sinPhi = sin(mCurParams.getSunAngle());
  237. F32 cosPhi = cos(mCurParams.getSunAngle());
  238. sunDir.mV[0] = -sinTheta * cosPhi;
  239. sunDir.mV[1] = sinPhi;
  240. sunDir.mV[2] = cosTheta * cosPhi;
  241. sunDir.mV[3] = 0;
  242. moonDir = -sunDir;
  243. // is the normal from the sun or the moon
  244. if(sunDir.mV[1] >= 0)
  245. {
  246. mLightDir = sunDir;
  247. }
  248. else if(sunDir.mV[1] < 0 && sunDir.mV[1] > LLSky::NIGHTTIME_ELEVATION_COS)
  249. {
  250. // clamp v1 to 0 so sun never points up and causes weirdness on some machines
  251. LLVector3 vec(sunDir.mV[0], sunDir.mV[1], sunDir.mV[2]);
  252. vec.mV[1] = 0;
  253. vec.normVec();
  254. mLightDir = LLVector4(vec, 0.f);
  255. }
  256. else
  257. {
  258. mLightDir = moonDir;
  259. }
  260. // calculate the clamp lightnorm for sky (to prevent ugly banding in sky
  261. // when haze goes below the horizon
  262. mClampedLightDir = sunDir;
  263. if (mClampedLightDir.mV[1] < -0.1f)
  264. {
  265. mClampedLightDir.mV[1] = -0.1f;
  266. }
  267. mCurParams.set("lightnorm", mLightDir);
  268. // bind the variables for all shaders only if we're using WindLight
  269. LLViewerShaderMgr::shader_iter shaders_iter, end_shaders;
  270. end_shaders = LLViewerShaderMgr::instance()->endShaders();
  271. for(shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter) 
  272. {
  273. if (shaders_iter->mProgramObject != 0
  274. && (gPipeline.canUseWindLightShaders()
  275. || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
  276. {
  277. shaders_iter->mUniformsDirty = TRUE;
  278. }
  279. }
  280. // get the cfr version of the sun's direction
  281. LLVector3 cfrSunDir(sunDir.mV[2], sunDir.mV[0], sunDir.mV[1]);
  282. // set direction and don't allow overriding
  283. gSky.setSunDirection(cfrSunDir, LLVector3(0,0,0));
  284. gSky.setOverrideSun(TRUE);
  285. }
  286. void LLWLParamManager::update(LLViewerCamera * cam)
  287. {
  288. LLFastTimer ftm(FTM_UPDATE_WLPARAM);
  289. // update clouds, sun, and general
  290. mCurParams.updateCloudScrolling();
  291. // update only if running
  292. if(mAnimator.mIsRunning) 
  293. {
  294. mAnimator.update(mCurParams);
  295. }
  296. // update the shaders and the menu
  297. propagateParameters();
  298. // sync menus if they exist
  299. LLFloaterWindLight* wlfloater = LLFloaterReg::findTypedInstance<LLFloaterWindLight>("env_windlight");
  300. if (wlfloater)
  301. {
  302. wlfloater->syncMenu();
  303. }
  304. LLFloaterDayCycle* dlfloater = LLFloaterReg::findTypedInstance<LLFloaterDayCycle>("env_day_cycle");
  305. if (dlfloater)
  306. {
  307. dlfloater->syncMenu();
  308. }
  309. LLFloaterEnvSettings* envfloater = LLFloaterReg::findTypedInstance<LLFloaterEnvSettings>("env_settings");
  310. if (envfloater)
  311. {
  312. envfloater->syncMenu();
  313. }
  314. F32 camYaw = cam->getYaw();
  315. // *TODO: potential optimization - this block may only need to be
  316. // executed some of the time.  For example for water shaders only.
  317. {
  318. F32 camYawDelta = mSunDeltaYaw * DEG_TO_RAD;
  319. LLVector3 lightNorm3(mLightDir);
  320. lightNorm3 *= LLQuaternion(-(camYaw + camYawDelta), LLVector3(0.f, 1.f, 0.f));
  321. mRotatedLightDir = LLVector4(lightNorm3, 0.f);
  322. LLViewerShaderMgr::shader_iter shaders_iter, end_shaders;
  323. end_shaders = LLViewerShaderMgr::instance()->endShaders();
  324. for(shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
  325. {
  326. if (shaders_iter->mProgramObject != 0
  327. && (gPipeline.canUseWindLightShaders()
  328. || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
  329. {
  330. shaders_iter->mUniformsDirty = TRUE;
  331. }
  332. }
  333. }
  334. }
  335. // static
  336. void LLWLParamManager::initClass(void)
  337. {
  338. instance();
  339. }
  340. // static
  341. void LLWLParamManager::cleanupClass()
  342. {
  343. delete sInstance;
  344. sInstance = NULL;
  345. }
  346. void LLWLParamManager::resetAnimator(F32 curTime, bool run)
  347. {
  348. mAnimator.setTrack(mDay.mTimeMap, mDay.mDayRate, 
  349. curTime, run);
  350. return;
  351. }
  352. bool LLWLParamManager::addParamSet(const std::string& name, LLWLParamSet& param)
  353. {
  354. // add a new one if not one there already
  355. std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name);
  356. if(mIt == mParamList.end()) 
  357. {
  358. mParamList[name] = param;
  359. return true;
  360. }
  361. return false;
  362. }
  363. BOOL LLWLParamManager::addParamSet(const std::string& name, LLSD const & param)
  364. {
  365. // add a new one if not one there already
  366. std::map<std::string, LLWLParamSet>::const_iterator finder = mParamList.find(name);
  367. if(finder == mParamList.end())
  368. {
  369. mParamList[name].setAll(param);
  370. return TRUE;
  371. }
  372. else
  373. {
  374. return FALSE;
  375. }
  376. }
  377. bool LLWLParamManager::getParamSet(const std::string& name, LLWLParamSet& param)
  378. {
  379. // find it and set it
  380. std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name);
  381. if(mIt != mParamList.end()) 
  382. {
  383. param = mParamList[name];
  384. param.mName = name;
  385. return true;
  386. }
  387. return false;
  388. }
  389. bool LLWLParamManager::setParamSet(const std::string& name, LLWLParamSet& param)
  390. {
  391. mParamList[name] = param;
  392. return true;
  393. }
  394. bool LLWLParamManager::setParamSet(const std::string& name, const LLSD & param)
  395. {
  396. // quick, non robust (we won't be working with files, but assets) check
  397. if(!param.isMap()) 
  398. {
  399. return false;
  400. }
  401. mParamList[name].setAll(param);
  402. return true;
  403. }
  404. bool LLWLParamManager::removeParamSet(const std::string& name, bool delete_from_disk)
  405. {
  406. // remove from param list
  407. std::map<std::string, LLWLParamSet>::iterator mIt = mParamList.find(name);
  408. if(mIt != mParamList.end()) 
  409. {
  410. mParamList.erase(mIt);
  411. }
  412. F32 key;
  413. // remove all references
  414. bool stat = true;
  415. do 
  416. {
  417. // get it
  418. stat = mDay.getKey(name, key);
  419. if(stat == false) 
  420. {
  421. break;
  422. }
  423. // and remove
  424. stat = mDay.removeKey(key);
  425. } while(stat == true);
  426. if(delete_from_disk)
  427. {
  428. std::string path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", ""));
  429. // use full curl escaped name
  430. char * curl_str = curl_escape(name.c_str(), name.size());
  431. std::string escaped_name(curl_str);
  432. curl_free(curl_str);
  433. curl_str = NULL;
  434. gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml");
  435. }
  436. return true;
  437. }
  438. // static
  439. LLWLParamManager * LLWLParamManager::instance()
  440. {
  441. if(NULL == sInstance)
  442. {
  443. sInstance = new LLWLParamManager();
  444. sInstance->loadPresets(LLStringUtil::null);
  445. // load the day
  446. sInstance->mDay.loadDayCycle(std::string("Default.xml"));
  447. // *HACK - sets cloud scrolling to what we want... fix this better in the future
  448. sInstance->getParamSet("Default", sInstance->mCurParams);
  449. // set it to noon
  450. sInstance->resetAnimator(0.5, true);
  451. // but use linden time sets it to what the estate is
  452. sInstance->mAnimator.mUseLindenTime = true;
  453. }
  454. return sInstance;
  455. }