PageRenderTime 256ms CodeModel.GetById 51ms app.highlight 182ms RepoModel.GetById 13ms app.codeStats 1ms

/indra/newview/lldrawpoolwater.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 725 lines | 526 code | 140 blank | 59 comment | 64 complexity | 50fd524b975c10ebeddec212b8ce8c6c MD5 | raw file
  1/** 
  2 * @file lldrawpoolwater.cpp
  3 * @brief LLDrawPoolWater class implementation
  4 *
  5 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28#include "llfeaturemanager.h"
 29#include "lldrawpoolwater.h"
 30
 31#include "llviewercontrol.h"
 32#include "lldir.h"
 33#include "llerror.h"
 34#include "m3math.h"
 35#include "llrender.h"
 36
 37#include "llagent.h"		// for gAgent for getRegion for getWaterHeight
 38#include "llcubemap.h"
 39#include "lldrawable.h"
 40#include "llface.h"
 41#include "llsky.h"
 42#include "llviewertexturelist.h"
 43#include "llviewerregion.h"
 44#include "llvosky.h"
 45#include "llvowater.h"
 46#include "llworld.h"
 47#include "pipeline.h"
 48#include "llviewershadermgr.h"
 49#include "llwaterparammanager.h"
 50
 51const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004");
 52const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");
 53
 54static float sTime;
 55
 56BOOL deferred_render = FALSE;
 57
 58BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
 59BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
 60BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
 61LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f);
 62F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
 63
 64LLVector3 LLDrawPoolWater::sLightDir;
 65
 66LLDrawPoolWater::LLDrawPoolWater() :
 67	LLFacePool(POOL_WATER)
 68{
 69	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
 70	gGL.getTexUnit(0)->bind(mHBTex[0]) ;
 71	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
 72
 73	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
 74	gGL.getTexUnit(0)->bind(mHBTex[1]);
 75	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
 76
 77
 78	mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE);
 79	llassert(mWaterImagep);
 80	mWaterImagep->setNoDelete();
 81	mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE);
 82	llassert(mOpaqueWaterImagep);
 83	mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL);
 84	mWaterNormp->setNoDelete();
 85
 86	restoreGL();
 87}
 88
 89LLDrawPoolWater::~LLDrawPoolWater()
 90{
 91}
 92
 93//static
 94void LLDrawPoolWater::restoreGL()
 95{
 96	
 97}
 98
 99LLDrawPool *LLDrawPoolWater::instancePool()
100{
101	llerrs << "Should never be calling instancePool on a water pool!" << llendl;
102	return NULL;
103}
104
105
106void LLDrawPoolWater::prerender()
107{
108	mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ?
109		LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
110
111	// got rid of modulation by light color since it got a little too
112	// green at sunset and sl-57047 (underwater turns black at 8:00)
113	sWaterFogColor = LLWaterParamManager::instance().getFogColor();
114	sWaterFogColor.mV[3] = 0;
115
116}
117
118S32 LLDrawPoolWater::getNumPasses()
119{
120	if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f)
121	{
122		return 1;
123	}
124
125	return 0;
126}
127
128void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
129{
130	beginRenderPass(pass);
131	deferred_render = TRUE;
132}
133
134void LLDrawPoolWater::endPostDeferredPass(S32 pass)
135{
136	endRenderPass(pass);
137	deferred_render = FALSE;
138}
139
140//===============================
141//DEFERRED IMPLEMENTATION
142//===============================
143void LLDrawPoolWater::renderDeferred(S32 pass)
144{
145	LLFastTimer t(FTM_RENDER_WATER);
146	deferred_render = TRUE;
147	shade();
148	deferred_render = FALSE;
149}
150
151//=========================================
152
153void LLDrawPoolWater::render(S32 pass)
154{
155	LLFastTimer ftm(FTM_RENDER_WATER);
156	if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
157	{
158		return;
159	}
160
161	//do a quick 'n dirty depth sort
162	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
163			 iter != mDrawFace.end(); iter++)
164	{
165		LLFace* facep = *iter;
166		facep->mDistance = -facep->mCenterLocal.mV[2];
167	}
168
169	std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());
170
171	// See if we are rendering water as opaque or not
172	if (!gSavedSettings.getBOOL("RenderTransparentWater"))
173	{
174		// render water for low end hardware
175		renderOpaqueLegacyWater();
176		return;
177	}
178
179	LLGLEnable blend(GL_BLEND);
180
181	if ((mVertexShaderLevel > 0) && !sSkipScreenCopy)
182	{
183		shade();
184		return;
185	}
186
187	LLVOSky *voskyp = gSky.mVOSkyp;
188
189	stop_glerror();
190
191	if (!gGLManager.mHasMultitexture)
192	{
193		// Ack!  No multitexture!  Bail!
194		return;
195	}
196
197	LLFace* refl_face = voskyp->getReflFace();
198
199	gPipeline.disableLights();
200	
201	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
202
203	LLGLDisable cullFace(GL_CULL_FACE);
204	
205	// Set up second pass first
206	mWaterImagep->addTextureStats(1024.f*1024.f);
207	gGL.getTexUnit(1)->activate();
208	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
209	gGL.getTexUnit(1)->bind(mWaterImagep) ;
210
211	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
212	F32 up_dot = camera_up * LLVector3::z_axis;
213
214	LLColor4 water_color;
215	if (LLViewerCamera::getInstance()->cameraUnderWater())
216	{
217		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
218	}
219	else
220	{
221		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
222	}
223
224	gGL.diffuseColor4fv(water_color.mV);
225
226	// Automatically generate texture coords for detail map
227	glEnable(GL_TEXTURE_GEN_S); //texture unit 1
228	glEnable(GL_TEXTURE_GEN_T); //texture unit 1
229	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
230	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
231
232	// Slowly move over time.
233	F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f);
234	F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f};
235	F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f};
236	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
237	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
238
239	gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
240	gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
241
242	gGL.getTexUnit(0)->activate();
243	
244	glClearStencil(1);
245	glClear(GL_STENCIL_BUFFER_BIT);
246	LLGLEnable gls_stencil(GL_STENCIL_TEST);
247	glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
248	glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
249
250	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
251		 iter != mDrawFace.end(); iter++)
252	{
253		LLFace *face = *iter;
254		if (voskyp->isReflFace(face))
255		{
256			continue;
257		}
258		gGL.getTexUnit(0)->bind(face->getTexture());
259		face->renderIndexed();
260	}
261
262	// Now, disable texture coord generation on texture state 1
263	gGL.getTexUnit(1)->activate();
264	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
265	gGL.getTexUnit(1)->disable();
266	glDisable(GL_TEXTURE_GEN_S); //texture unit 1
267	glDisable(GL_TEXTURE_GEN_T); //texture unit 1
268
269	// Disable texture coordinate and color arrays
270	gGL.getTexUnit(0)->activate();
271	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
272
273	stop_glerror();
274	
275	if (gSky.mVOSkyp->getCubeMap())
276	{
277		gSky.mVOSkyp->getCubeMap()->enable(0);
278		gSky.mVOSkyp->getCubeMap()->bind();
279
280		gGL.matrixMode(LLRender::MM_TEXTURE);
281		gGL.loadIdentity();
282		LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
283		LLMatrix4 camera_rot(camera_mat.getMat3());
284		camera_rot.invert();
285
286		gGL.loadMatrix((F32 *)camera_rot.mMatrix);
287
288		gGL.matrixMode(LLRender::MM_MODELVIEW);
289		LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f,  0.5f*up_dot);
290
291		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
292
293		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
294			 iter != mDrawFace.end(); iter++)
295		{
296			LLFace *face = *iter;
297			if (voskyp->isReflFace(face))
298			{
299				//refl_face = face;
300				continue;
301			}
302
303			if (face->getGeomCount() > 0)
304			{					
305				face->renderIndexed();
306			}
307		}
308
309		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
310
311		gSky.mVOSkyp->getCubeMap()->disable();
312		
313		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
314		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
315		gGL.matrixMode(LLRender::MM_TEXTURE);
316		gGL.loadIdentity();
317		gGL.matrixMode(LLRender::MM_MODELVIEW);
318		
319	}
320
321	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
322
323    if (refl_face)
324	{
325		glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
326		renderReflection(refl_face);
327	}
328
329	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
330}
331
332// for low end hardware
333void LLDrawPoolWater::renderOpaqueLegacyWater()
334{
335	LLVOSky *voskyp = gSky.mVOSkyp;
336
337	LLGLSLShader* shader = NULL;
338	if (LLGLSLShader::sNoFixedFunction)
339	{
340		if (LLPipeline::sUnderWaterRender)
341		{
342			shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
343		}
344		else
345		{
346			shader = &gObjectSimpleNonIndexedTexGenProgram;
347		}
348
349		shader->bind();
350	}
351
352	stop_glerror();
353
354	// Depth sorting and write to depth buffer
355	// since this is opaque, we should see nothing
356	// behind the water.  No blending because
357	// of no transparency.  And no face culling so
358	// that the underside of the water is also opaque.
359	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
360	LLGLDisable no_cull(GL_CULL_FACE);
361	LLGLDisable no_blend(GL_BLEND);
362
363	gPipeline.disableLights();
364
365	mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
366
367	// Activate the texture binding and bind one
368	// texture since all images will have the same texture
369	gGL.getTexUnit(0)->activate();
370	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
371	gGL.getTexUnit(0)->bind(mOpaqueWaterImagep);
372
373	// Automatically generate texture coords for water texture
374	if (!shader)
375	{
376		glEnable(GL_TEXTURE_GEN_S); //texture unit 0
377		glEnable(GL_TEXTURE_GEN_T); //texture unit 0
378		glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
379		glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
380	}
381
382	// Use the fact that we know all water faces are the same size
383	// to save some computation
384
385	// Slowly move texture coordinates over time so the watter appears
386	// to be moving.
387	F32 movement_period_secs = 50.f;
388
389	F32 offset = fmod(gFrameTimeSeconds, movement_period_secs);
390
391	if (movement_period_secs != 0)
392	{
393	 	offset /= movement_period_secs;
394	}
395	else
396	{
397		offset = 0;
398	}
399
400	F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset };
401	F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset };
402
403	if (!shader)
404	{
405		glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
406		glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
407	}
408	else
409	{
410		shader->uniform4fv("object_plane_s", 1, tp0);
411		shader->uniform4fv("object_plane_t", 1, tp1);
412	}
413
414	gGL.diffuseColor3f(1.f, 1.f, 1.f);
415
416	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
417		 iter != mDrawFace.end(); iter++)
418	{
419		LLFace *face = *iter;
420		if (voskyp->isReflFace(face))
421		{
422			continue;
423		}
424
425		face->renderIndexed();
426	}
427
428	stop_glerror();
429
430	if (!shader)
431	{
432		// Reset the settings back to expected values
433		glDisable(GL_TEXTURE_GEN_S); //texture unit 0
434		glDisable(GL_TEXTURE_GEN_T); //texture unit 0
435	}
436
437	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
438	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
439}
440
441
442void LLDrawPoolWater::renderReflection(LLFace* face)
443{
444	LLVOSky *voskyp = gSky.mVOSkyp;
445
446	if (!voskyp)
447	{
448		return;
449	}
450
451	if (!face->getGeomCount())
452	{
453		return;
454	}
455	
456	S8 dr = voskyp->getDrawRefl();
457	if (dr < 0)
458	{
459		return;
460	}
461
462	LLGLSNoFog noFog;
463
464	gGL.getTexUnit(0)->bind(mHBTex[dr]);
465
466	LLOverrideFaceColor override(this, face->getFaceColor().mV);
467	face->renderIndexed();
468}
469
470void LLDrawPoolWater::shade()
471{
472	if (!deferred_render)
473	{
474		gGL.setColorMask(true, true);
475	}
476
477	LLVOSky *voskyp = gSky.mVOSkyp;
478
479	if(voskyp == NULL) 
480	{
481		return;
482	}
483
484	LLGLDisable blend(GL_BLEND);
485
486	LLColor3 light_diffuse(0,0,0);
487	F32 light_exp = 0.0f;
488	LLVector3 light_dir;
489	LLColor3 light_color;
490
491	if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) 	 
492    { 	 
493        light_dir  = gSky.getSunDirection(); 	 
494        light_dir.normVec(); 	
495		light_color = gSky.getSunDiffuseColor();
496		if(gSky.mVOSkyp) {
497	        light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); 	 
498			light_diffuse.normVec(); 	 
499		}
500        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	 
501        light_diffuse *= light_exp + 0.25f; 	 
502    } 	 
503    else  	 
504    { 	 
505        light_dir       = gSky.getMoonDirection(); 	 
506        light_dir.normVec(); 	 
507		light_color = gSky.getMoonDiffuseColor();
508        light_diffuse   = gSky.mVOSkyp->getMoon().getColorCached(); 	 
509        light_diffuse.normVec(); 	 
510        light_diffuse *= 0.5f; 	 
511        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	 
512    }
513
514	light_exp *= light_exp;
515	light_exp *= light_exp;
516	light_exp *= light_exp;
517	light_exp *= light_exp;
518	light_exp *= 256.f;
519	light_exp = light_exp > 32.f ? light_exp : 32.f;
520
521	LLGLSLShader* shader;
522
523	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
524	
525	if (deferred_render)
526	{
527		shader = &gDeferredWaterProgram;
528	}
529	else if (eyedepth < 0.f && LLPipeline::sWaterReflections)
530	{
531		shader = &gUnderWaterProgram;
532	}
533	else
534	{
535		shader = &gWaterProgram;
536	}
537
538	if (deferred_render)
539	{
540		gPipeline.bindDeferredShader(*shader);
541	}
542	else
543	{
544		shader->bind();
545	}
546
547	sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
548	
549	S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX);
550		
551	if (reftex > -1)
552	{
553		gGL.getTexUnit(reftex)->activate();
554		gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
555		gGL.getTexUnit(0)->activate();
556	}	
557
558	//bind normal map
559	S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
560
561	LLWaterParamManager * param_mgr = &LLWaterParamManager::instance();
562
563	// change mWaterNormp if needed
564	if (mWaterNormp->getID() != param_mgr->getNormalMapID())
565	{
566		mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID());
567	}
568
569	mWaterNormp->addTextureStats(1024.f*1024.f);
570	gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ;
571	if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
572	{
573		mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
574	}
575	else 
576	{
577		mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT);
578	}
579	
580	S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX);	
581		
582	if (screentex > -1)
583	{
584		shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
585		shader->uniform1f(LLViewerShaderMgr::WATER_FOGDENSITY, 
586			param_mgr->getFogDensity());
587		gPipeline.mWaterDis.bindTexture(0, screentex);
588	}
589	
590	stop_glerror();
591	
592	gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);	
593
594	if (mVertexShaderLevel == 1)
595	{
596		sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue;
597		shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
598	}
599
600	F32 screenRes[] = 
601	{
602		1.f/gGLViewport[2],
603		1.f/gGLViewport[3]
604	};
605	shader->uniform2fv("screenRes", 1, screenRes);
606	stop_glerror();
607	
608	S32 diffTex = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
609	stop_glerror();
610	
611	light_dir.normVec();
612	sLightDir = light_dir;
613	
614	light_diffuse *= 6.f;
615
616	//shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);
617	shader->uniform1f(LLViewerShaderMgr::WATER_WATERHEIGHT, eyedepth);
618	shader->uniform1f(LLViewerShaderMgr::WATER_TIME, sTime);
619	shader->uniform3fv(LLViewerShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
620	shader->uniform3fv(LLViewerShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
621	shader->uniform1f(LLViewerShaderMgr::WATER_SPECULAR_EXP, light_exp);
622	shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV);
623	shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV);
624	shader->uniform3fv(LLViewerShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
625
626	shader->uniform3fv("normScale", 1, param_mgr->getNormalScale().mV);
627	shader->uniform1f("fresnelScale", param_mgr->getFresnelScale());
628	shader->uniform1f("fresnelOffset", param_mgr->getFresnelOffset());
629	shader->uniform1f("blurMultiplier", param_mgr->getBlurMultiplier());
630
631	F32 sunAngle = llmax(0.f, light_dir.mV[2]);
632	F32 scaledAngle = 1.f - sunAngle;
633
634	shader->uniform1f("sunAngle", sunAngle);
635	shader->uniform1f("scaledAngle", scaledAngle);
636	shader->uniform1f("sunAngle2", 0.1f + 0.2f*sunAngle);
637
638	LLColor4 water_color;
639	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
640	F32 up_dot = camera_up * LLVector3::z_axis;
641	if (LLViewerCamera::getInstance()->cameraUnderWater())
642	{
643		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
644		shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow());
645	}
646	else
647	{
648		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
649		shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove());
650	}
651
652	if (water_color.mV[3] > 0.9f)
653	{
654		water_color.mV[3] = 0.9f;
655	}
656
657	{
658		LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
659		LLGLDisable cullface(GL_CULL_FACE);
660		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
661			iter != mDrawFace.end(); iter++)
662		{
663			LLFace *face = *iter;
664
665			if (voskyp->isReflFace(face))
666			{
667				continue;
668			}
669
670			LLVOWater* water = (LLVOWater*) face->getViewerObject();
671			gGL.getTexUnit(diffTex)->bind(face->getTexture());
672
673			sNeedsReflectionUpdate = TRUE;
674			
675			if (water->getUseTexture() || !water->getIsEdgePatch())
676			{
677				sNeedsDistortionUpdate = TRUE;
678				face->renderIndexed();
679			}
680			else if (gGLManager.mHasDepthClamp || deferred_render)
681			{
682				face->renderIndexed();
683			}
684			else
685			{
686				LLGLSquashToFarClip far_clip(glh_get_current_projection());
687				face->renderIndexed();
688			}
689		}
690	}
691	
692	shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
693	shader->disableTexture(LLViewerShaderMgr::WATER_SCREENTEX);	
694	shader->disableTexture(LLViewerShaderMgr::BUMP_MAP);
695	shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
696	shader->disableTexture(LLViewerShaderMgr::WATER_REFTEX);
697	shader->disableTexture(LLViewerShaderMgr::WATER_SCREENDEPTH);
698
699	if (deferred_render)
700	{
701		gPipeline.unbindDeferredShader(*shader);
702	}
703	else
704	{
705		shader->unbind();
706	}
707
708	gGL.getTexUnit(0)->activate();
709	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
710	if (!deferred_render)
711	{
712		gGL.setColorMask(true, false);
713	}
714
715}
716
717LLViewerTexture *LLDrawPoolWater::getDebugTexture()
718{
719	return LLViewerFetchedTexture::sSmokeImagep;
720}
721
722LLColor3 LLDrawPoolWater::getDebugColor() const
723{
724	return LLColor3(0.f, 1.f, 1.f);
725}