diff options
author | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
commit | cd17687f01420952712a500107e0f93e7ab8d5f8 (patch) | |
tree | ce48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/newview/llwaterparammanager.cpp | |
parent | Second Life viewer sources 1.19.0.5 (diff) | |
download | meta-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.cpp | 433 |
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 | |||
64 | LLWaterParamManager * LLWaterParamManager::sInstance = NULL; | ||
65 | |||
66 | LLWaterParamManager::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 | |||
82 | LLWaterParamManager::~LLWaterParamManager() | ||
83 | { | ||
84 | } | ||
85 | |||
86 | void 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 | |||
129 | void 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 | |||
173 | void 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 | |||
200 | void 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 | |||
225 | void 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 | |||
239 | void 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 | ||
303 | void LLWaterParamManager::initClass(void) | ||
304 | { | ||
305 | instance(); | ||
306 | } | ||
307 | |||
308 | // static | ||
309 | void LLWaterParamManager::cleanupClass(void) | ||
310 | { | ||
311 | delete sInstance; | ||
312 | sInstance = NULL; | ||
313 | } | ||
314 | |||
315 | bool 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 | |||
328 | BOOL 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 | |||
343 | bool 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 | |||
357 | bool LLWaterParamManager::setParamSet(const std::string& name, LLWaterParamSet& param) | ||
358 | { | ||
359 | mParamList[name] = param; | ||
360 | |||
361 | return true; | ||
362 | } | ||
363 | |||
364 | bool 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 | |||
377 | bool 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 | |||
402 | F32 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 | ||
421 | LLWaterParamManager * 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 | } | ||