aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llwaterparammanager.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:34 -0500
committerJacek Antonelli2008-08-15 23:45:34 -0500
commitcd17687f01420952712a500107e0f93e7ab8d5f8 (patch)
treece48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/newview/llwaterparammanager.cpp
parentSecond Life viewer sources 1.19.0.5 (diff)
downloadmeta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.zip
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.gz
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.bz2
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.xz
Second Life viewer sources 1.19.1.0
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llwaterparammanager.cpp433
1 files changed, 433 insertions, 0 deletions
diff --git a/linden/indra/newview/llwaterparammanager.cpp b/linden/indra/newview/llwaterparammanager.cpp
new file mode 100644
index 0000000..ae913af
--- /dev/null
+++ b/linden/indra/newview/llwaterparammanager.cpp
@@ -0,0 +1,433 @@
1/**
2 * @file llwaterparammanager.cpp
3 * @brief Implementation for the LLWaterParamManager class.
4 *
5 * $LicenseInfo:firstyear=2007&license=viewergpl$
6 *
7 * Copyright (c) 2007-2008, 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 http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 * $/LicenseInfo$
30 */
31
32#include "llviewerprecompiledheaders.h"
33
34#include "llwaterparammanager.h"
35
36#include "pipeline.h"
37#include "llsky.h"
38
39#include "llsliderctrl.h"
40#include "llspinctrl.h"
41#include "llcheckboxctrl.h"
42#include "llvieweruictrlfactory.h"
43#include "llviewercontrol.h"
44#include "llviewercamera.h"
45#include "llcombobox.h"
46#include "lllineeditor.h"
47#include "llsdserialize.h"
48
49#include "v4math.h"
50#include "llviewerdisplay.h"
51#include "llviewercontrol.h"
52#include "llviewerwindow.h"
53#include "lldrawpoolwater.h"
54#include "llagent.h"
55#include "llviewerregion.h"
56
57#include "llwlparammanager.h"
58#include "llwaterparamset.h"
59#include "llpostprocess.h"
60#include "llfloaterwater.h"
61
62#include "curl/curl.h"
63
64LLWaterParamManager * LLWaterParamManager::sInstance = NULL;
65
66LLWaterParamManager::LLWaterParamManager() :
67 mFogColor(22.f/255.f, 43.f/255.f, 54.f/255.f, 0.0f, 0.0f, "waterFogColor", "WaterFogColor"),
68 mFogDensity(4, "waterFogDensity", 2),
69 mUnderWaterFogMod(0.25, "underWaterFogMod"),
70 mNormalScale(2.f, 2.f, 2.f, "normScale"),
71 mFresnelScale(0.5f, "fresnelScale"),
72 mFresnelOffset(0.4f, "fresnelOffset"),
73 mScaleAbove(0.025f, "scaleAbove"),
74 mScaleBelow(0.2f, "scaleBelow"),
75 mBlurMultiplier(0.1f, "blurMultiplier"),
76 mWave1Dir(.5f, .5f, "wave1Dir"),
77 mWave2Dir(.5f, .5f, "wave2Dir"),
78 mDensitySliderValue(1.0f)
79{
80}
81
82LLWaterParamManager::~LLWaterParamManager()
83{
84}
85
86void LLWaterParamManager::loadAllPresets(const LLString& file_name)
87{
88 LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", ""));
89 llinfos << "Loading water settings from " << path_name << llendl;
90
91 //mParamList.clear();
92
93 bool found = true;
94 while(found)
95 {
96 std::string name;
97 found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name, false);
98
99 llinfos << "name: " << name << llendl;
100
101 // if we have one
102 if(found)
103 {
104 // bugfix for SL-46920: preventing filenames that break stuff.
105 char * curl_str = curl_unescape(name.c_str(), name.size());
106 std::string unescaped_name(curl_str);
107 curl_free(curl_str);
108 curl_str = NULL;
109
110 // not much error checking here since we're getting rid of this
111 std::string water_name = unescaped_name.substr(0, unescaped_name.size() - 4);
112
113 LLString cur_path(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", name));
114 llinfos << "Loading water from " << cur_path << llendl;
115
116 std::ifstream water_xml(cur_path.c_str());
117 if (water_xml)
118 {
119 LLSD water_data(LLSD::emptyMap());
120 LLPointer<LLSDParser> parser = new LLSDXMLParser();
121 parser->parse(water_xml, water_data, LLSDSerialize::SIZE_UNLIMITED);
122
123 addParamSet(water_name, water_data);
124 }
125 }
126 }
127}
128
129void LLWaterParamManager::loadPreset(const LLString & name)
130{
131 // bugfix for SL-46920: preventing filenames that break stuff.
132 char * curl_str = curl_escape(name.c_str(), name.size());
133 std::string escaped_filename(curl_str);
134 curl_free(curl_str);
135 curl_str = NULL;
136
137 escaped_filename += ".xml";
138
139 std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", escaped_filename));
140 llinfos << "Loading water settings from " << pathName << llendl;
141
142 std::ifstream presetsXML(pathName.c_str());
143
144 if (presetsXML)
145 {
146 LLSD paramsData(LLSD::emptyMap());
147
148 LLPointer<LLSDParser> parser = new LLSDXMLParser();
149
150 parser->parse(presetsXML, paramsData, LLSDSerialize::SIZE_UNLIMITED);
151
152 std::map<std::string, LLWaterParamSet>::iterator mIt = mParamList.find(name);
153 if(mIt == mParamList.end())
154 {
155 addParamSet(name, paramsData);
156 }
157 else
158 {
159 setParamSet(name, paramsData);
160 }
161 }
162 else
163 {
164 llwarns << "Can't find " << name << llendl;
165 return;
166 }
167
168 getParamSet(name, mCurParams);
169
170 propagateParameters();
171}
172
173void LLWaterParamManager::savePreset(const LLString & name)
174{
175 // bugfix for SL-46920: preventing filenames that break stuff.
176 char * curl_str = curl_escape(name.c_str(), name.size());
177 std::string escaped_filename(curl_str);
178 curl_free(curl_str);
179 curl_str = NULL;
180
181 escaped_filename += ".xml";
182
183 // make an empty llsd
184 LLSD paramsData(LLSD::emptyMap());
185 std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", escaped_filename));
186
187 // fill it with LLSD windlight params
188 paramsData = mParamList[name].getAll();
189
190 // write to file
191 std::ofstream presetsXML(pathName.c_str());
192 LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
193 formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
194 presetsXML.close();
195
196 propagateParameters();
197}
198
199
200void LLWaterParamManager::propagateParameters(void)
201{
202 // bind the variables only if we're using shaders
203 if(gPipeline.canUseVertexShaders())
204 {
205 LLShaderMgr::shader_iter shaders_iter, end_shaders;
206 end_shaders = LLShaderMgr::endShaders();
207 for(shaders_iter = LLShaderMgr::beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
208 {
209 if (shaders_iter->mProgramObject != 0
210 && shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)
211 {
212 shaders_iter->mUniformsDirty = TRUE;
213 }
214 }
215 }
216
217 bool err;
218 F32 fog_density_slider =
219 log(mCurParams.getFloat(mFogDensity.mName, err)) /
220 log(mFogDensity.mBase);
221
222 setDensitySliderValue(fog_density_slider);
223}
224
225void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader)
226{
227 if (shader->mShaderGroup == LLGLSLShader::SG_WATER)
228 {
229 shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, LLWLParamManager::instance()->getRotatedLightDir().mV);
230 shader->uniform3fv("camPosLocal", 1, gCamera->getOrigin().mV);
231 shader->uniform4fv("waterFogColor", 1, LLDrawPoolWater::sWaterFogColor.mV);
232 shader->uniform4fv("waterPlane", 1, mWaterPlane.mV);
233 shader->uniform1f("waterFogDensity", getFogDensity());
234 shader->uniform1f("waterFogKS", mWaterFogKS);
235 shader->uniform4f("distance_multiplier", 0, 0, 0, 0);
236 }
237}
238
239void LLWaterParamManager::update(LLViewerCamera * cam)
240{
241 LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM);
242
243 // update the shaders and the menu
244 propagateParameters();
245
246 // sync menus if they exist
247 if(LLFloaterWater::isOpen())
248 {
249 LLFloaterWater::instance()->syncMenu();
250 }
251
252 stop_glerror();
253
254 // only do this if we're dealing with shaders
255 if(gPipeline.canUseVertexShaders())
256 {
257 //transform water plane to eye space
258 glh::vec3f norm(0, 0, 1);
259 glh::vec3f p(0, 0, gAgent.getRegion()->getWaterHeight()+0.1f);
260
261 F32 modelView[16];
262 for (U32 i = 0; i < 16; i++)
263 {
264 modelView[i] = (F32) gGLModelView[i];
265 }
266
267 glh::matrix4f mat(modelView);
268 glh::matrix4f invtrans = mat.inverse().transpose();
269 glh::vec3f enorm;
270 glh::vec3f ep;
271 invtrans.mult_matrix_vec(norm, enorm);
272 enorm.normalize();
273 mat.mult_matrix_vec(p, ep);
274
275 mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
276
277 LLVector3 sunMoonDir;
278 if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS)
279 {
280 sunMoonDir = gSky.getSunDirection();
281 }
282 else
283 {
284 sunMoonDir = gSky.getMoonDirection();
285 }
286 sunMoonDir.normVec();
287 mWaterFogKS = 1.f/llmax(sunMoonDir.mV[2], WATER_FOG_LIGHT_CLAMP);
288
289 LLShaderMgr::shader_iter shaders_iter, end_shaders;
290 end_shaders = LLShaderMgr::endShaders();
291 for(shaders_iter = LLShaderMgr::beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
292 {
293 if (shaders_iter->mProgramObject != 0
294 && shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)
295 {
296 shaders_iter->mUniformsDirty = TRUE;
297 }
298 }
299 }
300}
301
302// static
303void LLWaterParamManager::initClass(void)
304{
305 instance();
306}
307
308// static
309void LLWaterParamManager::cleanupClass(void)
310{
311 delete sInstance;
312 sInstance = NULL;
313}
314
315bool LLWaterParamManager::addParamSet(const std::string& name, LLWaterParamSet& param)
316{
317 // add a new one if not one there already
318 std::map<std::string, LLWaterParamSet>::iterator mIt = mParamList.find(name);
319 if(mIt == mParamList.end())
320 {
321 mParamList[name] = param;
322 return true;
323 }
324
325 return false;
326}
327
328BOOL LLWaterParamManager::addParamSet(const std::string& name, LLSD const & param)
329{
330 // add a new one if not one there already
331 std::map<std::string, LLWaterParamSet>::const_iterator finder = mParamList.find(name);
332 if(finder == mParamList.end())
333 {
334 mParamList[name].setAll(param);
335 return TRUE;
336 }
337 else
338 {
339 return FALSE;
340 }
341}
342
343bool LLWaterParamManager::getParamSet(const std::string& name, LLWaterParamSet& param)
344{
345 // find it and set it
346 std::map<std::string, LLWaterParamSet>::iterator mIt = mParamList.find(name);
347 if(mIt != mParamList.end())
348 {
349 param = mParamList[name];
350 param.mName = name;
351 return true;
352 }
353
354 return false;
355}
356
357bool LLWaterParamManager::setParamSet(const std::string& name, LLWaterParamSet& param)
358{
359 mParamList[name] = param;
360
361 return true;
362}
363
364bool LLWaterParamManager::setParamSet(const std::string& name, const LLSD & param)
365{
366 // quick, non robust (we won't be working with files, but assets) check
367 if(!param.isMap())
368 {
369 return false;
370 }
371
372 mParamList[name].setAll(param);
373
374 return true;
375}
376
377bool LLWaterParamManager::removeParamSet(const std::string& name, bool delete_from_disk)
378{
379 // remove from param list
380 std::map<std::string, LLWaterParamSet>::iterator mIt = mParamList.find(name);
381 if(mIt != mParamList.end())
382 {
383 mParamList.erase(mIt);
384 }
385
386 if(delete_from_disk)
387 {
388 LLString path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", ""));
389
390 // use full curl escaped name
391 char * curl_str = curl_escape(name.c_str(), name.size());
392 std::string escaped_name(curl_str);
393 curl_free(curl_str);
394 curl_str = NULL;
395
396 gDirUtilp->deleteFilesInDir(path_name, escaped_name + ".xml");
397 }
398
399 return true;
400}
401
402F32 LLWaterParamManager::getFogDensity(void)
403{
404 bool err;
405
406 F32 fogDensity = mCurParams.getFloat("waterFogDensity", err);
407
408 // modify if we're underwater
409 const F32 water_height = gAgent.getRegion()->getWaterHeight();
410 F32 camera_height = gAgent.getCameraPositionAgent().mV[2];
411 if(camera_height <= water_height)
412 {
413 // raise it to the underwater fog density modifier
414 fogDensity = pow(fogDensity, mCurParams.getFloat("underWaterFogMod", err));
415 }
416
417 return fogDensity;
418}
419
420// static
421LLWaterParamManager * LLWaterParamManager::instance()
422{
423 if(NULL == sInstance)
424 {
425 sInstance = new LLWaterParamManager();
426
427 sInstance->loadAllPresets("");
428
429 sInstance->getParamSet("Default", sInstance->mCurParams);
430 }
431
432 return sInstance;
433}