diff options
| author | Graham Linden <graham@lindenlab.com> | 2019-01-03 08:46:45 -0800 | 
|---|---|---|
| committer | Graham Linden <graham@lindenlab.com> | 2019-01-03 08:46:45 -0800 | 
| commit | 744e22e3645e205fa3f37ff3532bca607057887f (patch) | |
| tree | a093805396e34b3c9ff723b538001bf28499d96b /indra/newview | |
| parent | 07bff3129adaabb90f09b71fa65c8be0c3ecef5d (diff) | |
| parent | a0a1d93fb6a74149bbef57f1d1489510247110ca (diff) | |
Merge VR
Diffstat (limited to 'indra/newview')
| -rw-r--r-- | indra/newview/lldrawpoolwater.cpp | 314 | ||||
| -rw-r--r-- | indra/newview/llvosky.cpp | 2248 | 
2 files changed, 1581 insertions, 981 deletions
| diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index ee37f36cbd..9316890156 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -46,9 +46,14 @@  #include "llworld.h"  #include "pipeline.h"  #include "llviewershadermgr.h" -#include "llenvironment.h" -#include "llsettingssky.h" -#include "llsettingswater.h" +#include "llwaterparammanager.h" + +#if LL_WINDOWS +#pragma optimize("", off) +#endif + +const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004"); +const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");  static float sTime; @@ -57,51 +62,42 @@ BOOL deferred_render = FALSE;  BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;  BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;  BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE; +LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f);  F32 LLDrawPoolWater::sWaterFogEnd = 0.f; -LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER) -{ -} +LLVector3 LLDrawPoolWater::sLightDir; -LLDrawPoolWater::~LLDrawPoolWater() +LLDrawPoolWater::LLDrawPoolWater() : +	LLFacePool(POOL_WATER)  { -} +	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	gGL.getTexUnit(0)->bind(mHBTex[0]) ; +	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP); -void LLDrawPoolWater::setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId) -{ -    LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); -    mWaterImagep[0] = LLViewerTextureManager::getFetchedTexture(!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId()); -    mWaterImagep[1] = LLViewerTextureManager::getFetchedTexture(!nextTransparentTextureId.isNull() ? nextTransparentTextureId : (!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId())); -    mWaterImagep[0]->addTextureStats(1024.f*1024.f); -    mWaterImagep[1]->addTextureStats(1024.f*1024.f); -} +	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	gGL.getTexUnit(0)->bind(mHBTex[1]); +	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP); -void LLDrawPoolWater::setOpaqueTexture(const LLUUID& opaqueTextureId) -{ -    LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); -    mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(opaqueTextureId); -    mOpaqueWaterImagep->addTextureStats(1024.f*1024.f); + +	mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE); +	llassert(mWaterImagep); +	mWaterImagep->setNoDelete(); +	mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE); +	llassert(mOpaqueWaterImagep); +	mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL); +	mWaterNormp->setNoDelete(); + +	restoreGL();  } -void LLDrawPoolWater::setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId) +LLDrawPoolWater::~LLDrawPoolWater()  { -    LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); -    mWaterNormp[0] = LLViewerTextureManager::getFetchedTexture(!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId()); -    mWaterNormp[1] = LLViewerTextureManager::getFetchedTexture(!nextNormalMapId.isNull() ? nextNormalMapId : (!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId())); -    mWaterNormp[0]->addTextureStats(1024.f*1024.f); -    mWaterNormp[1]->addTextureStats(1024.f*1024.f);  }  //static  void LLDrawPoolWater::restoreGL()  { -	/*LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); -    if (pwater) -    { -        setTransparentTextures(pwater->getTransparentTextureID(), pwater->getNextTransparentTextureID()); -        setOpaqueTexture(pwater->GetDefaultOpaqueTextureAssetId()); -        setNormalMaps(pwater->getNormalMapID(), pwater->getNextNormalMapID()); -    }*/ +	  }  LLDrawPool *LLDrawPoolWater::instancePool() @@ -113,7 +109,14 @@ LLDrawPool *LLDrawPoolWater::instancePool()  void LLDrawPoolWater::prerender()  { -	mShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; +	mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? +		LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; + +	// got rid of modulation by light color since it got a little too +	// green at sunset and sl-57047 (underwater turns black at 8:00) +	sWaterFogColor = LLWaterParamManager::instance().getFogColor(); +	sWaterFogColor.mV[3] = 0; +  }  S32 LLDrawPoolWater::getNumPasses() @@ -179,7 +182,7 @@ void LLDrawPoolWater::render(S32 pass)  	LLGLEnable blend(GL_BLEND); -	if ((mShaderLevel > 0) && !sSkipScreenCopy) +	if ((mVertexShaderLevel > 0) && !sSkipScreenCopy)  	{  		shade();  		return; @@ -204,13 +207,10 @@ void LLDrawPoolWater::render(S32 pass)  	LLGLDisable cullFace(GL_CULL_FACE);  	// Set up second pass first +	mWaterImagep->addTextureStats(1024.f*1024.f);  	gGL.getTexUnit(1)->activate();  	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); -	gGL.getTexUnit(1)->bind(mWaterImagep[0]) ; - -    gGL.getTexUnit(2)->activate(); -	gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); -	gGL.getTexUnit(2)->bind(mWaterImagep[1]) ; +	gGL.getTexUnit(1)->bind(mWaterImagep) ;  	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();  	F32 up_dot = camera_up * LLVector3::z_axis; @@ -267,14 +267,6 @@ void LLDrawPoolWater::render(S32 pass)  	gGL.getTexUnit(1)->activate();  	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);  	gGL.getTexUnit(1)->disable(); - -    glDisable(GL_TEXTURE_GEN_S); //texture unit 1 -	glDisable(GL_TEXTURE_GEN_T); //texture unit 1 - -    gGL.getTexUnit(1)->activate(); -	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); -	gGL.getTexUnit(1)->disable(); -  	glDisable(GL_TEXTURE_GEN_S); //texture unit 1  	glDisable(GL_TEXTURE_GEN_T); //texture unit 1 @@ -374,6 +366,8 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()  	gPipeline.disableLights(); +	mOpaqueWaterImagep->addTextureStats(1024.f*1024.f); +  	// Activate the texture binding and bind one  	// texture since all images will have the same texture  	gGL.getTexUnit(0)->activate(); @@ -471,7 +465,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face)  	LLGLSNoFog noFog; -	gGL.getTexUnit(0)->bind((dr == 0) ? voskyp->getSunTex() : voskyp->getMoonTex()); +	gGL.getTexUnit(0)->bind(mHBTex[dr]);  	LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV));  	face->renderIndexed(); @@ -496,33 +490,31 @@ void LLDrawPoolWater::shade()  	LLColor3 light_diffuse(0,0,0);  	F32 light_exp = 0.0f;  	LLVector3 light_dir; - -    LLEnvironment& environment = LLEnvironment::instance(); -    LLSettingsWater::ptr_t pwater = environment.getCurrentWater(); -    LLSettingsSky::ptr_t   psky   = environment.getCurrentSky(); - -    light_dir = environment.getLightDirection(); -    light_dir.normalize(); - -    bool sun_up  = environment.getIsSunUp(); -    bool moon_up = environment.getIsMoonUp(); - -    if (sun_up) -    { -        light_diffuse += voskyp->getSun().getColorCached(); -    } -    // moonlight is several orders of magnitude less bright than sunlight, -    // so only use this color when the moon alone is showing -    else if (moon_up) -    {         -        light_diffuse += psky->getMoonDiffuse();  +	LLColor3 light_color; + +	if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) 	  +    { 	  +        light_dir  = gSky.getSunDirection(); 	  +        light_dir.normVec(); 	 +		light_color = gSky.getSunDiffuseColor(); +		if(gSky.mVOSkyp) { +	        light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); 	  +			light_diffuse.normVec(); 	  +		} +        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	  +        light_diffuse *= light_exp + 0.25f; 	  +    } 	  +    else  	  +    { 	  +        light_dir       = gSky.getMoonDirection(); 	  +        light_dir.normVec(); 	  +		light_color = gSky.getMoonDiffuseColor(); +        light_diffuse   = gSky.mVOSkyp->getMoon().getColorCached(); 	  +        light_diffuse.normVec(); 	  +        light_diffuse *= 0.5f; 	  +        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	       } -    light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f); - -    light_diffuse.normalize(); -    light_diffuse *= (light_exp + 0.25f); -  	light_exp *= light_exp;  	light_exp *= light_exp;  	light_exp *= light_exp; @@ -530,22 +522,20 @@ void LLDrawPoolWater::shade()  	light_exp *= 256.f;  	light_exp = light_exp > 32.f ? light_exp : 32.f; -    light_diffuse *= 6.f; -  	LLGLSLShader* shader; -	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - LLEnvironment::instance().getWaterHeight(); +	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();  	if (eyedepth < 0.f && LLPipeline::sWaterReflections)  	{ -	    if (deferred_render) -	    { -            shader = &gDeferredUnderWaterProgram; -	    } +	if (deferred_render) +	{ +			shader = &gDeferredUnderWaterProgram; +	}  		else -        { -	        shader = &gUnderWaterProgram; -        } +	{ +		shader = &gUnderWaterProgram; +	}  	}  	else if (deferred_render)  	{ @@ -556,18 +546,16 @@ void LLDrawPoolWater::shade()  		shader = &gWaterProgram;  	} -    shader->bind(); -  	if (deferred_render)  	{ -        if (shader->getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0) -	    { -		    glh::matrix4f norm_mat = get_current_modelview().inverse().transpose(); -		    shader->uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m); -	    } +		gPipeline.bindDeferredShader(*shader); +	} +	else +	{ +		shader->bind();  	} -	sTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f; +	sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;  	S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX); @@ -581,48 +569,43 @@ void LLDrawPoolWater::shade()  	//bind normal map  	S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); -    if (mWaterNormp[0]) -    { -	    gGL.getTexUnit(bumpTex)->bind(mWaterNormp[0]) ; +	LLWaterParamManager * param_mgr = &LLWaterParamManager::instance(); -	    if (gSavedSettings.getBOOL("RenderWaterMipNormal")) -	    { -		    mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); -	    } -	    else  -	    { -		    mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_POINT); -	    } +	// change mWaterNormp if needed +	if (mWaterNormp->getID() != param_mgr->getNormalMapID()) +	{ +		mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID());  	} -    if (mWaterNormp[1]) -    { -        bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2); - -        gGL.getTexUnit(bumpTex)->bind(mWaterNormp[1]) ; - -	    if (gSavedSettings.getBOOL("RenderWaterMipNormal")) -	    { -            mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); -	    } -	    else  -	    { -            mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_POINT); -	    } +	mWaterNormp->addTextureStats(1024.f*1024.f); +	gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ; +	if (gSavedSettings.getBOOL("RenderWaterMipNormal")) +	{ +		mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);  	} - -    shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR, 1, pwater->getWaterFogColor().mV); -    shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, pwater->getWaterFogDensity()); +	else  +	{ +		mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT); +	} +	 +	S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);	 +		 +	if (screentex > -1) +	{ +		shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); +		shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY,  +			param_mgr->getFogDensity()); +		gPipeline.mWaterDis.bindTexture(0, screentex); +	} +	 +	stop_glerror(); -    // bind reflection texture from RenderTarget -	S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);  	gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);	 -	if (mShaderLevel == 1) +	if (mVertexShaderLevel == 1)  	{ -        LLColor4 fog_color(pwater->getWaterFogColor(), 0.f); -        fog_color[3] = pwater->getWaterFogDensity(); -        shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV); +		sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue; +		shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);  	}  	F32 screenRes[] =  @@ -636,30 +619,25 @@ void LLDrawPoolWater::shade()  	S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);  	stop_glerror(); +	light_dir.normVec(); +	sLightDir = light_dir; +	 +	light_diffuse *= 6.f; +  	//shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);  	shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth);  	shader->uniform1f(LLShaderMgr::WATER_TIME, sTime);  	shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);  	shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);  	shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); -    if (LLEnvironment::instance().isCloudScrollPaused()) -    { -        static const std::array<F32, 2> zerowave{ {0.0f, 0.0f} }; -         -        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, zerowave.data()); -        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, zerowave.data()); -    } -    else -    { -        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV); -        shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV); -    } +	shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV); +	shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV);  	shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); -	shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV); -	shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale()); -	shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset()); -    shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier()); +	shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, param_mgr->getNormalScale().mV); +	shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, param_mgr->getFresnelScale()); +	shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, param_mgr->getFresnelOffset()); +	shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, param_mgr->getBlurMultiplier());  	F32 sunAngle = llmax(0.f, light_dir.mV[2]);  	F32 scaledAngle = 1.f - sunAngle; @@ -674,12 +652,12 @@ void LLDrawPoolWater::shade()  	if (LLViewerCamera::getInstance()->cameraUnderWater())  	{  		water_color.setVec(1.f, 1.f, 1.f, 0.4f); -		shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow()); +		shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow());  	}  	else  	{  		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); -		shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove()); +		shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove());  	}  	if (water_color.mV[3] > 0.9f) @@ -687,19 +665,40 @@ void LLDrawPoolWater::shade()  		water_color.mV[3] = 0.9f;  	} -	{		 +	{ +		LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);  		LLGLDisable cullface(GL_CULL_FACE); - -        sNeedsReflectionUpdate = TRUE;			 -        sNeedsDistortionUpdate = TRUE; - -        for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) +		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); +			iter != mDrawFace.end(); iter++)  		{  			LLFace *face = *iter; + +			if (voskyp->isReflFace(face)) +			{ +				continue; +			} + +			LLVOWater* water = (LLVOWater*) face->getViewerObject();  			gGL.getTexUnit(diffTex)->bind(face->getTexture()); -            face->renderIndexed(); + +			sNeedsReflectionUpdate = TRUE; +			 +			if (water->getUseTexture() || !water->getIsEdgePatch()) +			{ +				sNeedsDistortionUpdate = TRUE; +				face->renderIndexed(); +			} +			else if (gGLManager.mHasDepthClamp || deferred_render) +			{ +				face->renderIndexed(); +			} +			else +			{ +				LLGLSquashToFarClip far_clip(glh_get_current_projection()); +				face->renderIndexed(); +			}  		} -    } +	}  	shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);  	shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);	 @@ -708,7 +707,14 @@ void LLDrawPoolWater::shade()  	shader->disableTexture(LLShaderMgr::WATER_REFTEX);  	shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH); -	shader->unbind(); +	if (deferred_render) +	{ +		gPipeline.unbindDeferredShader(*shader); +	} +	else +	{ +		shader->unbind(); +	}  	gGL.getTexUnit(0)->activate();  	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index af078251b3..54ec238fde 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -48,42 +48,156 @@  #include "llworld.h"  #include "pipeline.h"  #include "lldrawpoolwlsky.h" -#include "v3colorutil.h" - -#include "llsettingssky.h" -#include "llenvironment.h" - -#include "lltrace.h" -#include "llfasttimer.h" +#include "llwlparammanager.h" +#include "llwaterparammanager.h"  #undef min  #undef max -namespace +#if LL_WINDOWS +#pragma optimize("", off) +#endif + +static const S32 NUM_TILES_X = 8; +static const S32 NUM_TILES_Y = 4; +static const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y; + +// Heavenly body constants +static const F32 SUN_DISK_RADIUS	= 0.5f; +static const F32 MOON_DISK_RADIUS	= SUN_DISK_RADIUS * 0.9f; +static const F32 SUN_INTENSITY = 1e5; + +// Texture coordinates: +static const LLVector2 TEX00 = LLVector2(0.f, 0.f); +static const LLVector2 TEX01 = LLVector2(0.f, 1.f); +static const LLVector2 TEX10 = LLVector2(1.f, 0.f); +static const LLVector2 TEX11 = LLVector2(1.f, 1.f); + +// Exported globals +LLUUID gSunTextureID = IMG_SUN; +LLUUID gMoonTextureID = IMG_MOON; + +class LLFastLn  { -    const S32 NUM_TILES_X = 8; -    const S32 NUM_TILES_Y = 4; -    const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y; +public: +	LLFastLn()  +	{ +		mTable[0] = 0; +		for( S32 i = 1; i < 257; i++ ) +		{ +			mTable[i] = log((F32)i); +		} +	} + +	F32 ln( F32 x ) +	{ +		const F32 OO_255 = 0.003921568627450980392156862745098f; +		const F32 LN_255 = 5.5412635451584261462455391880218f; + +		if( x < OO_255 ) +		{ +			return log(x); +		} +		else +		if( x < 1 ) +		{ +			x *= 255.f; +			S32 index = llfloor(x); +			F32 t = x - index; +			F32 low = mTable[index]; +			F32 high = mTable[index + 1]; +			return low + t * (high - low) - LN_255; +		} +		else +		if( x <= 255 ) +		{ +			S32 index = llfloor(x); +			F32 t = x - index; +			F32 low = mTable[index]; +			F32 high = mTable[index + 1]; +			return low + t * (high - low); +		} +		else +		{ +			return log( x ); +		} +	} + +	F32 pow( F32 x, F32 y ) +	{ +		return (F32)LL_FAST_EXP(y * ln(x)); +	} + + +private: +	F32 mTable[257]; // index 0 is unused +}; + +static LLFastLn gFastLn; -    // Heavenly body constants -    const F32 SUN_DISK_RADIUS	= 0.5f; -    const F32 MOON_DISK_RADIUS	= SUN_DISK_RADIUS * 0.9f; -    const F32 SUN_INTENSITY = 1e5; -    // Texture coordinates: -    const LLVector2 TEX00 = LLVector2(0.f, 0.f); -    const LLVector2 TEX01 = LLVector2(0.f, 1.f); -    const LLVector2 TEX10 = LLVector2(1.f, 0.f); -    const LLVector2 TEX11 = LLVector2(1.f, 1.f); +// Functions used a lot. -    const F32 LIGHT_DIRECTION_THRESHOLD = (F32) cosf(DEG_TO_RAD * 1.f); -    const F32 COLOR_CHANGE_THRESHOLD = 0.01f; +inline F32 LLHaze::calcPhase(const F32 cos_theta) const +{ +	const F32 g2 = mG * mG; +	const F32 den = 1 + g2 - 2 * mG * cos_theta; +	return (1 - g2) * gFastLn.pow(den, -1.5); +} + +inline void color_pow(LLColor3 &col, const F32 e) +{ +	col.mV[0] = gFastLn.pow(col.mV[0], e); +	col.mV[1] = gFastLn.pow(col.mV[1], e); +	col.mV[2] = gFastLn.pow(col.mV[2], e); +} -    LLTrace::BlockTimerStatHandle FTM_VOSKY_UPDATETIMER("VOSky Update Timer Tick"); -    LLTrace::BlockTimerStatHandle FTM_VOSKY_UPDATEFORCED("VOSky Update Forced"); +inline LLColor3 color_norm(const LLColor3 &col) +{ +	const F32 m = color_max(col); +	if (m > 1.f) +	{ +		return 1.f/m * col; +	} +	else return col; +} + +inline void color_gamma_correct(LLColor3 &col) +{ +	const F32 gamma_inv = 1.f/1.2f; +	if (col.mV[0] != 0.f) +	{ +		col.mV[0] = gFastLn.pow(col.mV[0], gamma_inv); +	} +	if (col.mV[1] != 0.f) +	{ +		col.mV[1] = gFastLn.pow(col.mV[1], gamma_inv); +	} +	if (col.mV[2] != 0.f) +	{ +		col.mV[2] = gFastLn.pow(col.mV[2], gamma_inv); +	} +} -    F32Seconds UPDATE_EXPRY(2.0f); +static LLColor3 calc_air_sca_sea_level() +{ +	static LLColor3 WAVE_LEN(675, 520, 445); +	static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN); +	static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1); +	static LLColor3 n4 = n21 * n21; +	static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f; +	static LLColor3 wl4 = wl2 * wl2; +	static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4; +	static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2); +	return dens_div_N * color_div ( mult_const, wl4 );  } + +// static constants. +LLColor3 const LLHaze::sAirScaSeaLevel = calc_air_sca_sea_level(); +F32 const LLHaze::sAirScaIntense = color_intens(LLHaze::sAirScaSeaLevel);	 +F32 const LLHaze::sAirScaAvg = LLHaze::sAirScaIntense / 3.f; + +  /***************************************  		SkyTex  ***************************************/ @@ -139,32 +253,6 @@ LLSkyTex::~LLSkyTex()  	mSkyDirs = NULL;  } -S32 LLSkyTex::getResolution() -{ -    return sResolution; -} - -S32 LLSkyTex::getCurrent() -{ -    return sCurrent; -} - -S32 LLSkyTex::stepCurrent() { -    sCurrent++; -    sCurrent &= 1; -    return sCurrent; -} - -S32 LLSkyTex::getNext() -{ -    return ((sCurrent+1) & 1); -} - -S32 LLSkyTex::getWhich(const BOOL curr) -{ -    int tex = curr ? sCurrent : getNext(); -    return tex; -}  void LLSkyTex::initEmpty(const S32 tex)  { @@ -205,6 +293,9 @@ void LLSkyTex::create(const F32 brightness)  	createGLImage(sCurrent);  } + + +  void LLSkyTex::createGLImage(S32 which)  {	  	mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL); @@ -213,175 +304,14 @@ void LLSkyTex::createGLImage(S32 which)  void LLSkyTex::bindTexture(BOOL curr)  { -    int tex = getWhich(curr); -	gGL.getTexUnit(0)->bind(mTexture[tex], true); -} - -LLImageRaw* LLSkyTex::getImageRaw(BOOL curr) -{ -    int tex = getWhich(curr); -    return mImageRaw[tex]; -} - -/*************************************** -    LLHeavenBody -***************************************/ - -F32	LLHeavenBody::sInterpVal = 0; - -LLHeavenBody::LLHeavenBody(const F32 rad) -: mDirectionCached(LLVector3(0,0,0)), -  mDirection(LLVector3(0,0,0)), -  mIntensity(0.f), -  mDiskRadius(rad), -  mDraw(FALSE), -  mHorizonVisibility(1.f), -  mVisibility(1.f), -  mVisible(FALSE) -{ -	mColor.setToBlack(); -	mColorCached.setToBlack(); -} - -const LLVector3& LLHeavenBody::getDirection() const -{ -    return mDirection; -} - -void LLHeavenBody::setDirection(const LLVector3 &direction) -{ -    mDirection = direction; -} - -void LLHeavenBody::setAngularVelocity(const LLVector3 &ang_vel) -{ -    mAngularVelocity = ang_vel; -} - -const LLVector3& LLHeavenBody::getAngularVelocity() const -{ -    return mAngularVelocity; -} - -const LLVector3& LLHeavenBody::getDirectionCached() const -{ -    return mDirectionCached; -} - -void LLHeavenBody::renewDirection() -{ -    mDirectionCached = mDirection; -} - -const LLColor3& LLHeavenBody::getColorCached() const -{ -    return mColorCached; -} - -void LLHeavenBody::setColorCached(const LLColor3& c) -{ -    mColorCached = c; -} - -const LLColor3& LLHeavenBody::getColor() const -{ -    return mColor; -} - -void LLHeavenBody::setColor(const LLColor3& c) -{ -    mColor = c; -} - -void LLHeavenBody::renewColor() -{ -    mColorCached = mColor; -} - -F32 LLHeavenBody::interpVal() -{ -    return sInterpVal; -} - -void LLHeavenBody::setInterpVal(const F32 v) -{ -    sInterpVal = v; -} - -LLColor3 LLHeavenBody::getInterpColor() const -{ -	return sInterpVal * mColor + (1 - sInterpVal) * mColorCached; -} - -const F32& LLHeavenBody::getVisibility() const -{ -    return mVisibility; -} - -void LLHeavenBody::setVisibility(const F32 c) -{ -    mVisibility = c; -} - -bool LLHeavenBody::isVisible() const -{ -    return mVisible; -} - -void LLHeavenBody::setVisible(const bool v) -{ -    mVisible = v; -} - -const F32& LLHeavenBody::getIntensity() const -{ -    return mIntensity; -} - -void LLHeavenBody::setIntensity(const F32 c) -{ -    mIntensity = c; -} - -void LLHeavenBody::setDiskRadius(const F32 radius) -{ -    mDiskRadius = radius; -} - -F32	LLHeavenBody::getDiskRadius() const -{ -    return mDiskRadius; -} - -void LLHeavenBody::setDraw(const bool draw) -{ -    mDraw = draw; -} - -bool LLHeavenBody::getDraw() const -{ -    return mDraw; -} - -const LLVector3& LLHeavenBody::corner(const S32 n) const -{ -    return mQuadCorner[n]; -} - -LLVector3& LLHeavenBody::corner(const S32 n) -{ -    return mQuadCorner[n]; -} - -const LLVector3* LLHeavenBody::corners() const -{ -    return mQuadCorner; +	gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)], true);  }  /***************************************  		Sky  ***************************************/ +F32	LLHeavenBody::sInterpVal = 0;  S32 LLVOSky::sResolution = LLSkyTex::getResolution();  S32 LLVOSky::sTileResX = sResolution/NUM_TILES_X; @@ -400,15 +330,32 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)  	mWorldScale(1.f),  	mBumpSunDir(0.f, 0.f, 1.f)  { +	bool error = false; +	  	/// WL PARAMS +	dome_radius = 1.f; +	dome_offset_ratio = 0.f; +	sunlight_color = LLColor3(); +	ambient = LLColor3(); +	gamma = 1.f; +	lightnorm = LLVector4(); +	blue_density = LLColor3(); +	blue_horizon = LLColor3(); +	haze_density = 0.f; +	haze_horizon = 1.f; +	density_multiplier = 0.f; +	max_y = 0.f; +	glow = LLColor3(); +	cloud_shadow = 0.f; +	cloud_color = LLColor3(); +	cloud_scale = 0.f; +	cloud_pos_density1 = LLColor3(); +	cloud_pos_density2 = LLColor3();  	mInitialized = FALSE;  	mbCanSelect = FALSE;  	mUpdateTimer.reset(); -    mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPRY); -    mForceUpdateThrottle.reset(); -  	for (S32 i = 0; i < 6; i++)  	{  		mSkyTex[i].init(); @@ -423,13 +370,33 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)  	mAtmHeight = ATM_HEIGHT;  	mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS); +	mSunDefaultPosition = LLVector3(LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error)); +	if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition")) +	{ +		initSunDirection(mSunDefaultPosition, LLVector3(0, 0, 0)); +	} +	mAmbientScale = gSavedSettings.getF32("SkyAmbientScale"); +	mNightColorShift = gSavedSettings.getColor3("SkyNightColorShift"); +	mFogColor.mV[VRED] = mFogColor.mV[VGREEN] = mFogColor.mV[VBLUE] = 0.5f; +	mFogColor.mV[VALPHA] = 0.0f; +	mFogRatio = 1.2f; +  	mSun.setIntensity(SUN_INTENSITY);  	mMoon.setIntensity(0.1f * SUN_INTENSITY); +	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +	mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1); +	mBloomTexturep->setNoDelete() ; +	mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +  	mHeavenlyBodyUpdated = FALSE ;  	mDrawRefl = 0; -	mInterpVal = 0.f;     +	mHazeConcentration = 0.f; +	mInterpVal = 0.f;  } @@ -443,32 +410,11 @@ LLVOSky::~LLVOSky()  void LLVOSky::init()  { -    llassert(!mInitialized); - -    // Update sky at least once to get correct initial sun/moon directions and lighting calcs performed -    LLEnvironment::instance().getCurrentSky()->update(); - -	updateDirections(); - -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - -    // invariants across whole sky tex process... -    m_atmosphericsVars.blue_density = psky->getBlueDensity();     -    m_atmosphericsVars.blue_horizon = psky->getBlueHorizon(); -    m_atmosphericsVars.haze_density = psky->getHazeDensity(); -    m_atmosphericsVars.haze_horizon = psky->getHazeHorizon(); -    m_atmosphericsVars.density_multiplier = psky->getDensityMultiplier(); -    m_atmosphericsVars.max_y = psky->getMaxY(); -    m_atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm(); -    m_atmosphericsVars.sunlight = psky->getSunlightColor(); -    m_atmosphericsVars.ambient = psky->getAmbientColor();     -    m_atmosphericsVars.glow = psky->getGlow(); -    m_atmosphericsVars.cloud_shadow = psky->getCloudShadow(); -    m_atmosphericsVars.dome_radius = psky->getDomeRadius(); -    m_atmosphericsVars.dome_offset = psky->getDomeOffset(); -    m_atmosphericsVars.light_atten = psky->getLightAttenuation(m_atmosphericsVars.max_y); -    m_atmosphericsVars.light_transmittance = psky->getLightTransmittance(); -    m_atmosphericsVars.gamma = psky->getGamma(); +   	const F32 haze_int = color_intens(mHaze.calcSigSca(0)); +	mHazeConcentration = haze_int / +		(color_intens(LLHaze::calcAirSca(0)) + haze_int); + +	calcAtmospherics();  	// Initialize the cached normalized direction vectors  	for (S32 side = 0; side < 6; ++side) @@ -476,7 +422,7 @@ void LLVOSky::init()  		for (S32 tile = 0; tile < NUM_TILES; ++tile)  		{  			initSkyTextureDirs(side, tile); -			createSkyTexture(m_atmosphericsVars, side, tile, false); +			createSkyTexture(side, tile);  		}  	} @@ -487,107 +433,9 @@ void LLVOSky::init()  	}  	initCubeMap(); -  	mInitialized = true;  	mHeavenlyBodyUpdated = FALSE ; - -    mRainbowMap = LLViewerTextureManager::getFetchedTexture(psky->getRainbowTextureId(), FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -    mHaloMap    = LLViewerTextureManager::getFetchedTexture(psky->getHaloTextureId(),  FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -} - - -void LLVOSky::calc() -{ -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - -    // invariants across whole sky tex process... -    m_atmosphericsVars.blue_density = psky->getBlueDensity();     -    m_atmosphericsVars.blue_horizon = psky->getBlueHorizon(); -    m_atmosphericsVars.haze_density = psky->getHazeDensity(); -    m_atmosphericsVars.haze_horizon = psky->getHazeHorizon(); -    m_atmosphericsVars.density_multiplier = psky->getDensityMultiplier(); -    m_atmosphericsVars.max_y = psky->getMaxY(); -    m_atmosphericsVars.sun_norm = LLEnvironment::instance().getClampedSunNorm(); -    m_atmosphericsVars.sunlight = psky->getSunlightColor(); -    m_atmosphericsVars.ambient = psky->getAmbientColor();     -    m_atmosphericsVars.glow = psky->getGlow(); -    m_atmosphericsVars.cloud_shadow = psky->getCloudShadow(); -    m_atmosphericsVars.dome_radius = psky->getDomeRadius(); -    m_atmosphericsVars.dome_offset = psky->getDomeOffset(); -    m_atmosphericsVars.light_atten = psky->getLightAttenuation(m_atmosphericsVars.max_y); -    m_atmosphericsVars.light_transmittance = psky->getLightTransmittance(); -    m_atmosphericsVars.gamma = psky->getGamma(); - -	LLColor3 vary_HazeColor; -	LLColor3 vary_SunlightColor; -	LLColor3 vary_AmbientColor; -	{ -		// Initialize temp variables -		LLColor3 sunlight = m_atmosphericsVars.sunlight; - -		// Sunlight attenuation effect (hue and brightness) due to atmosphere -		// this is used later for sunlight modulation at various altitudes -		LLColor3 light_atten = -			(m_atmosphericsVars.blue_density * 1.0 + smear(m_atmosphericsVars.haze_density * 0.25f)) * (m_atmosphericsVars.density_multiplier * m_atmosphericsVars.max_y); - -		// Calculate relative weights -		LLColor3 temp2(0.f, 0.f, 0.f); -		LLColor3 temp1 = m_atmosphericsVars.blue_density + smear(m_atmosphericsVars.haze_density); -		LLColor3 blue_weight = componentDiv(m_atmosphericsVars.blue_density, temp1); -		LLColor3 haze_weight = componentDiv(smear(m_atmosphericsVars.haze_density), temp1); - -		// Compute sunlight from P & lightnorm (for long rays like sky) -		/// USE only lightnorm. -		// temp2[1] = llmax(0.f, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] ); -		F32 lighty = getSun().getDirection().mV[2]; -		temp2.mV[1] = llmax(0.f, lighty); -		if(temp2.mV[1] > 0.f) -		{ -			temp2.mV[1] = 1.f / temp2.mV[1]; -		} -		componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); - -		// Distance -		temp2.mV[2] = m_atmosphericsVars.density_multiplier; - -		// Transparency (-> temp1) -		temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); - -		// vary_AtmosAttenuation = temp1;  - -		//increase ambient when there are more clouds -		LLColor3 tmpAmbient = m_atmosphericsVars.ambient + (smear(1.f) - m_atmosphericsVars.ambient) * m_atmosphericsVars.cloud_shadow * 0.5f; - -		//haze color -		vary_HazeColor = -			(m_atmosphericsVars.blue_horizon * blue_weight * (sunlight * (1.f - m_atmosphericsVars.cloud_shadow) + tmpAmbient)	 -			+ componentMult(m_atmosphericsVars.haze_horizon * haze_weight, sunlight * (1.f - m_atmosphericsVars.cloud_shadow) * temp2.mV[0] + tmpAmbient) -				 );	 - -		//brightness of surface both sunlight and ambient -		vary_SunlightColor = componentMult(sunlight, temp1) * 1.f; -		vary_SunlightColor.clamp(); -		vary_SunlightColor = smear(1.0f) - vary_SunlightColor; -		vary_SunlightColor = componentPow(vary_SunlightColor, m_atmosphericsVars.gamma); -		vary_SunlightColor = smear(1.0f) - vary_SunlightColor; -		vary_AmbientColor = componentMult(tmpAmbient, temp1) * 0.5; -		vary_AmbientColor.clamp(); -		vary_AmbientColor = smear(1.0f) - vary_AmbientColor; -		vary_AmbientColor = componentPow(vary_AmbientColor, m_atmosphericsVars.gamma); -		vary_AmbientColor = smear(1.0f) - vary_AmbientColor; - -		componentMultBy(vary_HazeColor, LLColor3(1.f, 1.f, 1.f) - temp1); - -	} - -	mSun.setColor(vary_SunlightColor); -	mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f)); - -	mSun.renewDirection(); -	mSun.renewColor(); -	mMoon.renewDirection(); -	mMoon.renewColor();  }  void LLVOSky::initCubeMap()  @@ -630,16 +478,15 @@ void LLVOSky::restoreGL()  	{  		mSkyTex[i].restoreGL();  	} +	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +	mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1); +	mBloomTexturep->setNoDelete() ; +	mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - -    if (psky) -    { -        setSunTextures(psky->getSunTextureId(), psky->getNextSunTextureId()); -        setMoonTextures(psky->getMoonTextureId(), psky->getNextMoonTextureId()); -    } - -	updateDirections(); +	calcAtmospherics();	  	if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap  	    && LLCubeMap::sUseCubeMaps) @@ -655,11 +502,10 @@ void LLVOSky::restoreGL()  		if(cube_map)  		{  			cube_map->init(images); +			mForceUpdate = TRUE;  		}  	} -    mForceUpdate = TRUE; -  	if (mDrawable)  	{  		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); @@ -699,7 +545,7 @@ void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile)  	}  } -void LLVOSky::createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32 tile, bool skip_sky_tex) +void LLVOSky::createSkyTexture(const S32 side, const S32 tile)  {  	S32 tile_x = tile % NUM_TILES_X;  	S32 tile_y = tile / NUM_TILES_X; @@ -708,55 +554,495 @@ void LLVOSky::createSkyTexture(AtmosphericsVars& vars, const S32 side, const S32  	S32 tile_y_pos = tile_y * sTileResY;  	S32 x, y; -    if (!skip_sky_tex) -    { -        for (y = tile_y_pos; y < (tile_y_pos + sTileResY); ++y) -	    { -		    for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x) -		    { -                mSkyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(vars, mSkyTex[side].getDir(x, y)), x, y); -		    } -	    } -    } -  	for (y = tile_y_pos; y < (tile_y_pos + sTileResY); ++y)  	{  		for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x)  		{ -			mShinyTex[side].setPixel(m_legacyAtmospherics.calcSkyColorInDir(vars, mSkyTex[side].getDir(x, y), true), x, y); +			mSkyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y)), x, y); +			mShinyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y), true), x, y);  		}  	}  } -void LLVOSky::updateDirections(void) +static inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right) +{ +	return LLColor3(left.mV[0]/right.mV[0], +					 left.mV[1]/right.mV[1], +					 left.mV[2]/right.mV[2]); +} + + +static inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right) +{ +	return LLColor3(left.mV[0]*right.mV[0], +					 left.mV[1]*right.mV[1], +					 left.mV[2]*right.mV[2]); +} + + +static inline LLColor3 componentExp(LLColor3 const &v) +{ +	return LLColor3(exp(v.mV[0]), +					 exp(v.mV[1]), +					 exp(v.mV[2])); +} + +static inline LLColor3 componentPow(LLColor3 const &v, F32 exponent) +{ +	return LLColor3(pow(v.mV[0], exponent), +					pow(v.mV[1], exponent), +					pow(v.mV[2], exponent)); +} + +static inline LLColor3 componentSaturate(LLColor3 const &v) +{ +	return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f), +					 std::max(std::min(v.mV[1], 1.f), 0.f), +					 std::max(std::min(v.mV[2], 1.f), 0.f)); +} + + +static inline LLColor3 componentSqrt(LLColor3 const &v) +{ +	return LLColor3(sqrt(v.mV[0]), +					 sqrt(v.mV[1]), +					 sqrt(v.mV[2])); +} + +static inline void componentMultBy(LLColor3 & left, LLColor3 const & right)  { -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); +	left.mV[0] *= right.mV[0]; +	left.mV[1] *= right.mV[1]; +	left.mV[2] *= right.mV[2]; +} -    mLastSunLightingDirection  = mSun.getDirection(); -    mLastMoonLightingDirection = mMoon.getDirection(); +static inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount) +{ +	return (left + ((right - left) * amount)); +} -    mSun.setDirection(psky->getSunDirection()); -	mMoon.setDirection(psky->getMoonDirection()); +static inline LLColor3 smear(F32 val) +{ +	return LLColor3(val, val, val); +} -    mSun.setColor(psky->getSunlightColor()); -	mMoon.setColor(psky->getMoonDiffuse()); +void LLVOSky::initAtmospherics(void) +{	 +	bool error; +	 +	// uniform parameters for convenience +	dome_radius = LLWLParamManager::getInstance()->getDomeRadius(); +	dome_offset_ratio = LLWLParamManager::getInstance()->getDomeOffset(); +	sunlight_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("sunlight_color", error)); +	ambient = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("ambient", error)); +	//lightnorm = LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error); +	gamma = LLWLParamManager::getInstance()->mCurParams.getFloat("gamma", error); +	blue_density = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_density", error)); +	blue_horizon = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_horizon", error)); +	haze_density = LLWLParamManager::getInstance()->mCurParams.getFloat("haze_density", error); +	haze_horizon = LLWLParamManager::getInstance()->mCurParams.getFloat("haze_horizon", error); +	density_multiplier = LLWLParamManager::getInstance()->mCurParams.getFloat("density_multiplier", error); +	max_y = LLWLParamManager::getInstance()->mCurParams.getFloat("max_y", error); +	glow = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("glow", error)); +	cloud_shadow = LLWLParamManager::getInstance()->mCurParams.getFloat("cloud_shadow", error); +	cloud_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_color", error)); +	cloud_scale = LLWLParamManager::getInstance()->mCurParams.getFloat("cloud_scale", error); +	cloud_pos_density1 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density1", error)); +	cloud_pos_density2 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density2", error)); + +	// light norm is different.  We need the sun's direction, not the light direction +	// which could be from the moon.  And we need to clamp it +	// just like for the gpu +	LLVector3 sunDir = gSky.getSunDirection(); + +	// CFR_TO_OGL +	lightnorm = LLVector4(sunDir.mV[1], sunDir.mV[2], sunDir.mV[0], 0); +	unclamped_lightnorm = lightnorm; +	if(lightnorm.mV[1] < -0.1f) +	{ +		lightnorm.mV[1] = -0.1f; +	} +	 +} + +LLColor4 LLVOSky::calcSkyColorInDir(const LLVector3 &dir, bool isShiny) +{ +	F32 saturation = 0.3f; +	if (dir.mV[VZ] < -0.02f) +	{ +		LLColor4 col = LLColor4(llmax(mFogColor[0],0.2f), llmax(mFogColor[1],0.2f), llmax(mFogColor[2],0.22f),0.f); +		if (isShiny) +		{ +			LLColor3 desat_fog = LLColor3(mFogColor); +			F32 brightness = desat_fog.brightness(); +			// So that shiny somewhat shows up at night. +			if (brightness < 0.15f) +			{ +				brightness = 0.15f; +				desat_fog = smear(0.15f); +			} +			LLColor3 greyscale = smear(brightness); +			desat_fog = desat_fog * saturation + greyscale * (1.0f - saturation); +			if (!gPipeline.canUseWindLightShaders()) +			{ +				col = LLColor4(desat_fog, 0.f); +			} +			else  +			{ +				col = LLColor4(desat_fog * 0.5f, 0.f); +			} +		} +		float x = 1.0f-fabsf(-0.1f-dir.mV[VZ]); +		x *= x; +		col.mV[0] *= x*x; +		col.mV[1] *= powf(x, 2.5f); +		col.mV[2] *= x*x*x; +		return col; +	} + +	// undo OGL_TO_CFR_ROTATION and negate vertical direction. +	LLVector3 Pn = LLVector3(-dir[1] , -dir[2], -dir[0]); + +	LLColor3 vary_HazeColor(0,0,0); +	LLColor3 vary_CloudColorSun(0,0,0); +	LLColor3 vary_CloudColorAmbient(0,0,0); +	F32 vary_CloudDensity(0); +	LLVector2 vary_HorizontalProjection[2]; +	vary_HorizontalProjection[0] = LLVector2(0,0); +	vary_HorizontalProjection[1] = LLVector2(0,0); + +	calcSkyColorWLVert(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient, +						vary_CloudDensity, vary_HorizontalProjection); +	 +	LLColor3 sky_color =  calcSkyColorWLFrag(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient,  +								vary_CloudDensity, vary_HorizontalProjection); +	if (isShiny) +	{ +		F32 brightness = sky_color.brightness(); +		LLColor3 greyscale = smear(brightness); +		sky_color = sky_color * saturation + greyscale * (1.0f - saturation); +		sky_color *= (0.5f + 0.5f * brightness); +	} +	return LLColor4(sky_color, 0.0f); +} + +// turn on floating point precision +// in vs2003 for this function.  Otherwise +// sky is aliased looking 7:10 - 8:50 +#if LL_MSVC && __MSVC_VER__ < 8 +#pragma optimize("p", on) +#endif + +void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,  +							LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,  +							LLVector2 vary_HorizontalProjection[2]) +{ +	// project the direction ray onto the sky dome. +	F32 phi = acos(Pn[1]); +	F32 sinA = sin(F_PI - phi); +	if (fabsf(sinA) < 0.01f) +	{ //avoid division by zero +		sinA = 0.01f; +	} + +	F32 Plen = dome_radius * sin(F_PI + phi + asin(dome_offset_ratio * sinA)) / sinA; + +	Pn *= Plen; + +	vary_HorizontalProjection[0] = LLVector2(Pn[0], Pn[2]); +	vary_HorizontalProjection[0] /= - 2.f * Plen; + +	// Set altitude +	if (Pn[1] > 0.f) +	{ +		Pn *= (max_y / Pn[1]); +	} +	else +	{ +		Pn *= (-32000.f / Pn[1]); +	} + +	Plen = Pn.length(); +	Pn /= Plen; + +	// Initialize temp variables +	LLColor3 sunlight = sunlight_color; + +	// Sunlight attenuation effect (hue and brightness) due to atmosphere +	// this is used later for sunlight modulation at various altitudes +	LLColor3 light_atten = +		(blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y); + +	// Calculate relative weights +	LLColor3 temp2(0.f, 0.f, 0.f); +	LLColor3 temp1 = blue_density + smear(haze_density); +	LLColor3 blue_weight = componentDiv(blue_density, temp1); +	LLColor3 haze_weight = componentDiv(smear(haze_density), temp1); + +	// Compute sunlight from P & lightnorm (for long rays like sky) +	temp2.mV[1] = llmax(F_APPROXIMATELY_ZERO, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] ); + +	temp2.mV[1] = 1.f / temp2.mV[1]; +	componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); + +	// Distance +	temp2.mV[2] = Plen * density_multiplier; + +	// Transparency (-> temp1) +	temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); + + +	// Compute haze glow +	temp2.mV[0] = Pn * LLVector3(lightnorm); + +	temp2.mV[0] = 1.f - temp2.mV[0]; +		// temp2.x is 0 at the sun and increases away from sun +	temp2.mV[0] = llmax(temp2.mV[0], .001f);	 +		// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) +	temp2.mV[0] *= glow.mV[0]; +		// Higher glow.x gives dimmer glow (because next step is 1 / "angle") +	temp2.mV[0] = pow(temp2.mV[0], glow.mV[2]); +		// glow.z should be negative, so we're doing a sort of (1 / "angle") function + +	// Add "minimum anti-solar illumination" +	temp2.mV[0] += .25f; + + +	// Haze color above cloud +	vary_HazeColor = (blue_horizon * blue_weight * (sunlight + ambient) +				+ componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + ambient) +			 );	 + +	// Increase ambient when there are more clouds +	LLColor3 tmpAmbient = ambient + (LLColor3::white - ambient) * cloud_shadow * 0.5f; + +	// Dim sunlight by cloud shadow percentage +	sunlight *= (1.f - cloud_shadow); + +	// Haze color below cloud +	LLColor3 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient) +				+ componentMult(haze_horizon * haze_weight, sunlight * temp2.mV[0] + tmpAmbient) +			 );	 + +	// Final atmosphere additive +	componentMultBy(vary_HazeColor, LLColor3::white - temp1); + +	sunlight = sunlight_color; +	temp2.mV[1] = llmax(0.f, lightnorm[1] * 2.f); +	temp2.mV[1] = 1.f / temp2.mV[1]; +	componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); + +	// Attenuate cloud color by atmosphere +	temp1 = componentSqrt(temp1);	//less atmos opacity (more transparency) below clouds + +	// At horizon, blend high altitude sky color towards the darker color below the clouds +	vary_HazeColor += +		componentMult(additiveColorBelowCloud - vary_HazeColor, LLColor3::white - componentSqrt(temp1)); +		 +	if (Pn[1] < 0.f) +	{ +		// Eric's original:  +		// LLColor3 dark_brown(0.143f, 0.129f, 0.114f); +		LLColor3 dark_brown(0.082f, 0.076f, 0.066f); +		LLColor3 brown(0.430f, 0.386f, 0.322f); +		LLColor3 sky_lighting = sunlight + ambient; +		F32 haze_brightness = vary_HazeColor.brightness(); + +		if (Pn[1] < -0.05f) +		{ +			vary_HazeColor = colorMix(dark_brown, brown, -Pn[1] * 0.9f) * sky_lighting * haze_brightness; +		} +		 +		if (Pn[1] > -0.1f) +		{ +			vary_HazeColor = colorMix(LLColor3::white * haze_brightness, vary_HazeColor, fabs((Pn[1] + 0.05f) * -20.f)); +		} +	} +} + +#if LL_MSVC && __MSVC_VER__ < 8 +#pragma optimize("p", off) +#endif + +LLColor3 LLVOSky::calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,  +							LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,  +							LLVector2 vary_HorizontalProjection[2]) +{ +	LLColor3 res; + +	LLColor3 color0 = vary_HazeColor; +	 +	if (!gPipeline.canUseWindLightShaders()) +	{ +		LLColor3 color1 = color0 * 2.0f; +		color1 = smear(1.f) - componentSaturate(color1); +		componentPow(color1, gamma); +		res = smear(1.f) - color1; +	}  +	else  +	{ +		res = color0; +	} + +#	ifndef LL_RELEASE_FOR_DOWNLOAD + +	LLColor3 color2 = 2.f * color0; + +	LLColor3 color3 = LLColor3(1.f, 1.f, 1.f) - componentSaturate(color2); +	componentPow(color3, gamma); +	color3 = LLColor3(1.f, 1.f, 1.f) - color3; + +	static enum { +		OUT_DEFAULT		= 0, +		OUT_SKY_BLUE	= 1, +		OUT_RED			= 2, +		OUT_PN			= 3, +		OUT_HAZE		= 4, +	} debugOut = OUT_DEFAULT; + +	switch(debugOut)  +	{ +		case OUT_DEFAULT: +			break; +		case OUT_SKY_BLUE: +			res = LLColor3(0.4f, 0.4f, 0.9f); +			break; +		case OUT_RED: +			res = LLColor3(1.f, 0.f, 0.f); +			break; +		case OUT_PN: +			res = LLColor3(Pn[0], Pn[1], Pn[2]); +			break; +		case OUT_HAZE: +			res = vary_HazeColor; +			break; +	} +#	endif // LL_RELEASE_FOR_DOWNLOAD +	return res; +} + +LLColor3 LLVOSky::createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient) +{ +	return componentMult(diffuse, sundiffuse) * 4.0f + +			componentMult(ambient, sundiffuse) * 2.0f + sunambient; +} + +LLColor3 LLVOSky::createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient) +{ +	return (componentMult(ambient, sundiffuse) + sunambient) * 0.8f; +} + + +void LLVOSky::calcAtmospherics(void) +{ +	initAtmospherics(); + +	LLColor3 vary_HazeColor; +	LLColor3 vary_SunlightColor; +	LLColor3 vary_AmbientColor; +	{ +		// Initialize temp variables +		LLColor3 sunlight = sunlight_color; + +		// Sunlight attenuation effect (hue and brightness) due to atmosphere +		// this is used later for sunlight modulation at various altitudes +		LLColor3 light_atten = +			(blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y); + +		// Calculate relative weights +		LLColor3 temp2(0.f, 0.f, 0.f); +		LLColor3 temp1 = blue_density + smear(haze_density); +		LLColor3 blue_weight = componentDiv(blue_density, temp1); +		LLColor3 haze_weight = componentDiv(smear(haze_density), temp1); + +		// Compute sunlight from P & lightnorm (for long rays like sky) +		/// USE only lightnorm. +		// temp2[1] = llmax(0.f, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] ); +		 +		// and vary_sunlight will work properly with moon light +		F32 lighty = unclamped_lightnorm[1]; +		if(lighty < LLSky::NIGHTTIME_ELEVATION_COS) +		{ +			lighty = -lighty; +		} + +		temp2.mV[1] = llmax(0.f, lighty); +		if(temp2.mV[1] > 0.f) +		{ +			temp2.mV[1] = 1.f / temp2.mV[1]; +		} +		componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1])); + +		// Distance +		temp2.mV[2] = density_multiplier; + +		// Transparency (-> temp1) +		temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]); + +		// vary_AtmosAttenuation = temp1;  + +		//increase ambient when there are more clouds +		LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5f; + +		//haze color +		vary_HazeColor = +			(blue_horizon * blue_weight * (sunlight*(1.f - cloud_shadow) + tmpAmbient)	 +			+ componentMult(haze_horizon * haze_weight, sunlight*(1.f - cloud_shadow) * temp2.mV[0] + tmpAmbient) +				 );	 + +		//brightness of surface both sunlight and ambient +		vary_SunlightColor = componentMult(sunlight, temp1) * 1.f; +		vary_SunlightColor.clamp(); +		vary_SunlightColor = smear(1.0f) - vary_SunlightColor; +		vary_SunlightColor = componentPow(vary_SunlightColor, gamma); +		vary_SunlightColor = smear(1.0f) - vary_SunlightColor; +		vary_AmbientColor = componentMult(tmpAmbient, temp1) * 0.5; +		vary_AmbientColor.clamp(); +		vary_AmbientColor = smear(1.0f) - vary_AmbientColor; +		vary_AmbientColor = componentPow(vary_AmbientColor, gamma); +		vary_AmbientColor = smear(1.0f) - vary_AmbientColor; + +		componentMultBy(vary_HazeColor, LLColor3(1.f, 1.f, 1.f) - temp1); + +	} + +	mSun.setColor(vary_SunlightColor); +	mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f));  	mSun.renewDirection();  	mSun.renewColor();  	mMoon.renewDirection();  	mMoon.renewColor(); + +	float dp = getToSunLast() * LLVector3(0,0,1.f); +	if (dp < 0) +	{ +		dp = 0; +	} + +	// Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio +	// between sunlight and point lights in windlight to normalize point lights. +	F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f); +	LLWLParamManager::getInstance()->mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp); + +	mSunDiffuse = vary_SunlightColor; +	mSunAmbient = vary_AmbientColor; +	mMoonDiffuse = vary_SunlightColor; +	mMoonAmbient = vary_AmbientColor; + +	mTotalAmbient = vary_AmbientColor; +	mTotalAmbient.setAlpha(1); +	 +	mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f; +	mFadeColor.setAlpha(0);  }  void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time)  {  } -bool LLVOSky::updateSky() -{     -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - -    LLColor4 total_ambient = psky->getTotalAmbient(); - +BOOL LLVOSky::updateSky() +{  	if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)))  	{  		return TRUE; @@ -776,13 +1062,11 @@ bool LLVOSky::updateSky()  	const S32 total_no_tiles = 6 * NUM_TILES;  	const S32 cycle_frame_no = total_no_tiles + 1; -	if (mUpdateTimer.getElapsedTimeF32() > 0.025f) +	if (mUpdateTimer.getElapsedTimeF32() > 0.001f)  	{ -        mUpdateTimer.reset(); +		mUpdateTimer.reset();  		const S32 frame = next_frame; -        mForceUpdate = mForceUpdate || (total_no_tiles == frame); -  		++next_frame;  		next_frame = next_frame % cycle_frame_no; @@ -790,150 +1074,117 @@ bool LLVOSky::updateSky()  		// sInterpVal = (F32)next_frame / cycle_frame_no;  		LLSkyTex::setInterpVal( mInterpVal );  		LLHeavenBody::setInterpVal( mInterpVal ); -		updateDirections(); - -        LLVector3 direction = mSun.getDirection(); -		direction.normalize(); -		const F32 dot_sun  = direction * mLastSunLightingDirection; -        const F32 dot_moon = direction * mLastMoonLightingDirection; +		calcAtmospherics(); -		LLColor3 delta_color; -		delta_color.setVec(mLastTotalAmbient.mV[0] - total_ambient.mV[0], -							mLastTotalAmbient.mV[1] - total_ambient.mV[1], -                            mLastTotalAmbient.mV[2] - total_ambient.mV[2]); - -        bool sun_direction_changed  = (dot_sun < LIGHT_DIRECTION_THRESHOLD); -        bool moon_direction_changed = (dot_moon < LIGHT_DIRECTION_THRESHOLD); -        bool color_changed          = (delta_color.length() >= COLOR_CHANGE_THRESHOLD); - -        mForceUpdate = mForceUpdate || sun_direction_changed; -        mForceUpdate = mForceUpdate || moon_direction_changed; -        mForceUpdate = mForceUpdate || color_changed; -        mForceUpdate = mForceUpdate || !mInitialized; - -        bool is_alm_wl_sky = gPipeline.canUseWindLightShaders(); - -        calc(); - -        if (mForceUpdate && mForceUpdateThrottle.hasExpired()) +		if (mForceUpdate || total_no_tiles == frame)  		{ -            LL_RECORD_BLOCK_TIME(FTM_VOSKY_UPDATEFORCED); - -            mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPRY); -  			LLSkyTex::stepCurrent(); -		 -			if (!direction.isExactlyZero()) +			 +			const static F32 LIGHT_DIRECTION_THRESHOLD = (F32) cos(DEG_TO_RAD * 1.f); +			const static F32 COLOR_CHANGE_THRESHOLD = 0.01f; + +			LLVector3 direction = mSun.getDirection(); +			direction.normalize(); +			const F32 dot_lighting = direction * mLastLightingDirection; + +			LLColor3 delta_color; +			delta_color.setVec(mLastTotalAmbient.mV[0] - mTotalAmbient.mV[0], +							   mLastTotalAmbient.mV[1] - mTotalAmbient.mV[1], +							   mLastTotalAmbient.mV[2] - mTotalAmbient.mV[2]); + +			if ( mForceUpdate  +				 || (((dot_lighting < LIGHT_DIRECTION_THRESHOLD) +				 || (delta_color.length() > COLOR_CHANGE_THRESHOLD) +				 || !mInitialized) +				&& !direction.isExactlyZero()))  			{ -                mLastTotalAmbient = total_ambient; +				mLastLightingDirection = direction; +				mLastTotalAmbient = mTotalAmbient;  				mInitialized = TRUE;  				if (mCubeMap)  				{ -					updateFog(LLViewerCamera::getInstance()->getFar()); - -					for (int side = 0; side < 6; side++)  +                    if (mForceUpdate)  					{ -						for (int tile = 0; tile < NUM_TILES; tile++)  +						updateFog(LLViewerCamera::getInstance()->getFar()); +						for (int side = 0; side < 6; side++)   						{ -							createSkyTexture(m_atmosphericsVars, side, tile, is_alm_wl_sky); +							for (int tile = 0; tile < NUM_TILES; tile++)  +							{ +								createSkyTexture(side, tile); +							}  						} -					} -                    int tex = mSkyTex[0].getWhich(TRUE); +						calcAtmospherics(); -					for (int side = 0; side < 6; side++)  -					{ -                        LLImageRaw* raw1 = nullptr; -                        LLImageRaw* raw2 = nullptr; - -                        if (!is_alm_wl_sky) -                        { -						    raw1 = mSkyTex[side].getImageRaw(TRUE); -						    raw2 = mSkyTex[side].getImageRaw(FALSE); -						    raw2->copy(raw1); -						    mSkyTex[side].createGLImage(tex); -                        } - -						raw1 = mShinyTex[side].getImageRaw(TRUE); -						raw2 = mShinyTex[side].getImageRaw(FALSE); -						raw2->copy(raw1); -						mShinyTex[side].createGLImage(tex); +						for (int side = 0; side < 6; side++)  +						{ +							LLImageRaw* raw1 = mSkyTex[side].getImageRaw(TRUE); +							LLImageRaw* raw2 = mSkyTex[side].getImageRaw(FALSE); +							raw2->copy(raw1); +							mSkyTex[side].createGLImage(mSkyTex[side].getWhich(FALSE)); + +							raw1 = mShinyTex[side].getImageRaw(TRUE); +							raw2 = mShinyTex[side].getImageRaw(FALSE); +							raw2->copy(raw1); +							mShinyTex[side].createGLImage(mShinyTex[side].getWhich(FALSE)); +						} +						next_frame = 0;	  					} -					next_frame = 0;	 - -			        // update the sky texture -                    if (!is_alm_wl_sky) -                    { -			            for (S32 i = 0; i < 6; ++i) -			            { -                            mSkyTex[i].create(1.0f); -			            } -                    } - -                    for (S32 i = 0; i < 6; ++i) -			        { -				        mShinyTex[i].create(1.0f); -			        } - -			        // update the environment map -			        if (mCubeMap) -			        { -				        std::vector<LLPointer<LLImageRaw> > images; -				        images.reserve(6); -				        for (S32 side = 0; side < 6; side++) -				        { -					        images.push_back(mShinyTex[side].getImageRaw(TRUE)); -				        } -				        mCubeMap->init(images); -				        gGL.getTexUnit(0)->disable(); -			        }                      				} -            } +			} + +			/// *TODO really, sky texture and env map should be shared on a single texture +			/// I'll let Brad take this at some point + +			// update the sky texture +			for (S32 i = 0; i < 6; ++i) +			{ +				mSkyTex[i].create(1.0f); +				mShinyTex[i].create(1.0f); +			} +			 +			// update the environment map +			if (mCubeMap) +			{ +				std::vector<LLPointer<LLImageRaw> > images; +				images.reserve(6); +				for (S32 side = 0; side < 6; side++) +				{ +					images.push_back(mShinyTex[side].getImageRaw(TRUE)); +				} +				mCubeMap->init(images); +				gGL.getTexUnit(0)->disable(); +			}  			gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); +			// *TODO: decide whether we need to update the stars vertex buffer in LLVOWLSky -Brad. +			//gPipeline.markRebuild(gSky.mVOWLSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); +  			mForceUpdate = FALSE;  		} +		else +		{ +			const S32 side = frame / NUM_TILES; +			const S32 tile = frame % NUM_TILES; +			createSkyTexture(side, tile); +		}  	}  	if (mDrawable.notNull() && mDrawable->getFace(0) && !mDrawable->getFace(0)->getVertexBuffer())  	{  		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);  	} -  	return TRUE;  }  void LLVOSky::updateTextures()  { -	if (mSunTexturep[0]) +	if (mSunTexturep)  	{ -		mSunTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA ); -    } - -    if (mSunTexturep[1]) -	{ -		mSunTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA ); -    } - -    if (mMoonTexturep[0]) -	{ -		mMoonTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA ); -    } - -    if (mMoonTexturep[1]) -	{ -		mMoonTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA ); -    }    - -    if (mBloomTexturep[0]) -    { -		mBloomTexturep[0]->addTextureStats( (F32)MAX_IMAGE_AREA ); -	} - -    if (mBloomTexturep[1]) -    { -		mBloomTexturep[1]->addTextureStats( (F32)MAX_IMAGE_AREA ); +		mSunTexturep->addTextureStats( (F32)MAX_IMAGE_AREA ); +		mMoonTexturep->addTextureStats( (F32)MAX_IMAGE_AREA ); +		mBloomTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );  	}  } @@ -951,121 +1202,60 @@ LLDrawable *LLVOSky::createDrawable(LLPipeline *pipeline)  		mFace[FACE_SIDE0 + i] = mDrawable->addFace(poolp, NULL);  	} -	mFace[FACE_SUN]   = mDrawable->addFace(poolp, nullptr); -	mFace[FACE_MOON]  = mDrawable->addFace(poolp, nullptr); -	mFace[FACE_BLOOM] = mDrawable->addFace(poolp, nullptr); +	mFace[FACE_SUN] = mDrawable->addFace(poolp, mSunTexturep); +	mFace[FACE_MOON] = mDrawable->addFace(poolp, mMoonTexturep); +	mFace[FACE_BLOOM] = mDrawable->addFace(poolp, mBloomTexturep);  	return mDrawable;  } -void LLVOSky::setSunScale(F32 sun_scale) -{ -    mSunScale  = sun_scale; -} - -void LLVOSky::setMoonScale(F32 moon_scale) +//by bao +//fake vertex buffer updating +//to guarantee at least updating one VBO buffer every frame +//to walk around the bug caused by ATI card --> DEV-3855 +// +void LLVOSky::createDummyVertexBuffer()  { -    mMoonScale = moon_scale; -} - -void LLVOSky::setSunTextures(const LLUUID& sun_texture, const LLUUID& sun_texture_next) -{ -    // We test the UUIDs here because we explicitly do not want the default image returned by getFetchedTexture in that case... -    mSunTexturep[0] = sun_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(sun_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -    mSunTexturep[1] = sun_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(sun_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); - -    if (mFace[FACE_SUN]) -    { -        if (mSunTexturep[0]) -        { -	        mSunTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP); -        } - -        LLViewerTexture* current_tex0 = mFace[FACE_SUN]->getTexture(LLRender::DIFFUSE_MAP); -        LLViewerTexture* current_tex1 = mFace[FACE_SUN]->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP); - -        if (current_tex0 && (mSunTexturep[0] != current_tex0) && current_tex0->isViewerMediaTexture()) -        { -            static_cast<LLViewerMediaTexture*>(current_tex0)->removeMediaFromFace(mFace[FACE_SUN]); -        } - -        if (current_tex1 && (mSunTexturep[1] != current_tex1) && current_tex1->isViewerMediaTexture()) -        { -            static_cast<LLViewerMediaTexture*>(current_tex1)->removeMediaFromFace(mFace[FACE_SUN]); -        } - -        mFace[FACE_SUN]->setTexture(LLRender::DIFFUSE_MAP, mSunTexturep[0]); - -        if (mSunTexturep[1]) -        { -	        mSunTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);             -        } -        mFace[FACE_SUN]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mSunTexturep[1]); -    } -} +	if(!mFace[FACE_DUMMY]) +	{ +		LLDrawPoolSky *poolp = (LLDrawPoolSky*) gPipeline.getPool(LLDrawPool::POOL_SKY); +		mFace[FACE_DUMMY] = mDrawable->addFace(poolp, NULL); +	} -void LLVOSky::setMoonTextures(const LLUUID& moon_texture, const LLUUID& moon_texture_next) -{ -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - -    mMoonTexturep[0] = moon_texture.isNull()      ? nullptr : LLViewerTextureManager::getFetchedTexture(moon_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -    mMoonTexturep[1] = moon_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(moon_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); - -    if (mFace[FACE_MOON]) -    { -        if (mMoonTexturep[0]) -        { -	        mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP); -        } -        mFace[FACE_MOON]->setTexture(LLRender::DIFFUSE_MAP, mMoonTexturep[0]); -     -        if (mMoonTexturep[1]) -        { -	        mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP); -            mFace[FACE_MOON]->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mMoonTexturep[1]); -        } -    } +	if(!mFace[FACE_DUMMY]->getVertexBuffer()) +	{ +		LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); +		buff->allocateBuffer(1, 1, TRUE); +		mFace[FACE_DUMMY]->setVertexBuffer(buff); +	}  } -void LLVOSky::setCloudNoiseTextures(const LLUUID& cloud_noise_texture, const LLUUID& cloud_noise_texture_next) -{ -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - -    mCloudNoiseTexturep[0] = cloud_noise_texture.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(cloud_noise_texture, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -    mCloudNoiseTexturep[1] = cloud_noise_texture_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(cloud_noise_texture_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); - -    if (mCloudNoiseTexturep[0]) -    { -	    mCloudNoiseTexturep[0]->setAddressMode(LLTexUnit::TAM_WRAP); -    } +static LLTrace::BlockTimerStatHandle FTM_RENDER_FAKE_VBO_UPDATE("Fake VBO Update"); -    if (mCloudNoiseTexturep[1]) -    { -	    mCloudNoiseTexturep[1]->setAddressMode(LLTexUnit::TAM_WRAP); -    } -} - -void LLVOSky::setBloomTextures(const LLUUID& bloom_texture, const LLUUID& bloom_texture_next) -{ -    LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); +void LLVOSky::updateDummyVertexBuffer() +{	 +	if(!LLVertexBuffer::sEnableVBOs) +		return ; -    LLUUID bloom_tex = bloom_texture.isNull() ? psky->GetDefaultBloomTextureId() : bloom_texture; -    LLUUID bloom_tex_next = bloom_texture_next.isNull() ? (bloom_texture.isNull() ? psky->GetDefaultBloomTextureId() : bloom_texture) : bloom_texture_next; +	if(mHeavenlyBodyUpdated) +	{ +		mHeavenlyBodyUpdated = FALSE ; +		return ; +	} -    mBloomTexturep[0] = bloom_tex.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(bloom_tex, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); -    mBloomTexturep[1] = bloom_tex_next.isNull() ? nullptr : LLViewerTextureManager::getFetchedTexture(bloom_tex_next, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); +	LL_RECORD_BLOCK_TIME(FTM_RENDER_FAKE_VBO_UPDATE) ; -    if (mBloomTexturep[0]) -    { -	    mBloomTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP); -    } +	if(!mFace[FACE_DUMMY] || !mFace[FACE_DUMMY]->getVertexBuffer()) +		createDummyVertexBuffer() ; -    if (mBloomTexturep[1]) -    { -	    mBloomTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP); -    } +	LLStrider<LLVector3> vertices ; +	mFace[FACE_DUMMY]->getVertexBuffer()->getVertexStrider(vertices,  0); +	*vertices = mCameraPosAgent ; +	mFace[FACE_DUMMY]->getVertexBuffer()->flush();  } - +//---------------------------------- +//end of fake vertex buffer updating +//----------------------------------  static LLTrace::BlockTimerStatHandle FTM_GEO_SKY("Sky Geometry");  BOOL LLVOSky::updateGeometry(LLDrawable *drawable) @@ -1074,14 +1264,13 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)  	if (mFace[FACE_REFLECTION] == NULL)  	{  		LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER); -		if (gPipeline.getPool(LLDrawPool::POOL_WATER)->getShaderLevel() != 0) +		if (gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() != 0)  		{  			mFace[FACE_REFLECTION] = drawable->addFace(poolp, NULL);  		}  	}  	mCameraPosAgent = drawable->getPositionAgent(); -  	mEarthCenter.mV[0] = mCameraPosAgent.mV[0];  	mEarthCenter.mV[1] = mCameraPosAgent.mV[1]; @@ -1155,40 +1344,64 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)  	LLVector3 up = right % look_at;  	right.normalize();  	up.normalize(); -     -    bool draw_sun  = updateHeavenlyBodyGeometry(drawable, mSunScale, FACE_SUN, mSun, up, right); -    bool draw_moon = updateHeavenlyBodyGeometry(drawable, mMoonScale, FACE_MOON, mMoon, up, right); - -    draw_sun  &= LLEnvironment::getInstance()->getIsSunUp(); -    draw_moon &= LLEnvironment::getInstance()->getIsMoonUp(); -	mSun.setDraw(draw_sun); -	mMoon.setDraw(draw_moon); +	const static F32 elevation_factor = 0.0f/sResolution; +	const F32 cos_max_angle = cosHorizon(elevation_factor); +	mSun.setDraw(updateHeavenlyBodyGeometry(drawable, FACE_SUN, TRUE, mSun, cos_max_angle, up, right)); +	mMoon.setDraw(updateHeavenlyBodyGeometry(drawable, FACE_MOON, FALSE, mMoon, cos_max_angle, up, right));  	const F32 water_height = gAgent.getRegion()->getWaterHeight() + 0.01f;  		// LLWorld::getInstance()->getWaterHeight() + 0.01f;  	const F32 camera_height = mCameraPosAgent.mV[2];  	const F32 height_above_water = camera_height - water_height; -	bool sun_flag = FALSE; +	BOOL sun_flag = FALSE; +  	if (mSun.isVisible()) -	{         -        sun_flag = !mMoon.isVisible() || ((look_at * mSun.getDirection()) > 0); +	{ +		if (mMoon.isVisible()) +		{ +			sun_flag = look_at * mSun.getDirection() > 0; +		} +		else +		{ +			sun_flag = TRUE; +		}  	} -    bool above_water = (height_above_water > 0); -    bool render_ref  = above_water && gPipeline.getPool(LLDrawPool::POOL_WATER)->getShaderLevel() == 0; -    setDrawRefl(above_water ? (sun_flag ? 0 : 1) : -1); -    if (render_ref) -	{         -        updateReflectionGeometry(drawable, height_above_water, mSun); -    } +	if (height_above_water > 0) +	{ +		BOOL render_ref = gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0; + +		if (sun_flag) +		{ +			setDrawRefl(0); +			if (render_ref) +			{ +				updateReflectionGeometry(drawable, height_above_water, mSun); +			} +		} +		else +		{ +			setDrawRefl(1); +			if (render_ref) +			{ +				updateReflectionGeometry(drawable, height_above_water, mMoon); +			} +		} +	} +	else +	{ +		setDrawRefl(-1); +	}  	LLPipeline::sCompiles++;  	return TRUE;  } -bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const S32 f, LLHeavenBody& hb, const LLVector3 &up, const LLVector3 &right) +BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, const BOOL is_sun, +										 LLHeavenBody& hb, const F32 cos_max_angle, +										 const LLVector3 &up, const LLVector3 &right)  {  	mHeavenlyBodyUpdated = TRUE ; @@ -1199,28 +1412,52 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const  	S32 index_offset;  	LLFace *facep; -	LLVector3 to_dir   = hb.getDirection(); +	LLVector3 to_dir = hb.getDirection(); + +	if (!is_sun) +	{ +		to_dir.mV[2] = llmax(to_dir.mV[2]+0.1f, 0.1f); +	}  	LLVector3 draw_pos = to_dir * HEAVENLY_BODY_DIST; +  	LLVector3 hb_right = to_dir % LLVector3::z_axis;  	LLVector3 hb_up = hb_right % to_dir;  	hb_right.normalize();  	hb_up.normalize(); -    const F32 enlargm_factor = ( 1 - to_dir.mV[2] ); +	//const static F32 cos_max_turn = sqrt(3.f) / 2; // 30 degrees +	//const F32 cos_turn_right = 1. / (llmax(cos_max_turn, hb_right * right)); +	//const F32 cos_turn_up = 1. / llmax(cos_max_turn, hb_up * up); + +	const F32 enlargm_factor = ( 1 - to_dir.mV[2] );  	F32 horiz_enlargement = 1 + enlargm_factor * 0.3f;  	F32 vert_enlargement = 1 + enlargm_factor * 0.2f; -	const LLVector3 scaled_right = horiz_enlargement * scale * HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR * hb.getDiskRadius() * hb_right; -	const LLVector3 scaled_up    = vert_enlargement  * scale * HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR * hb.getDiskRadius() * hb_up; +	// Parameters for the water reflection +	hb.setU(HEAVENLY_BODY_FACTOR * horiz_enlargement * hb.getDiskRadius() * hb_right); +	hb.setV(HEAVENLY_BODY_FACTOR * vert_enlargement * hb.getDiskRadius() * hb_up); +	// End of parameters for the water reflection + +	const LLVector3 scaled_right = HEAVENLY_BODY_DIST * hb.getU(); +	const LLVector3 scaled_up = HEAVENLY_BODY_DIST * hb.getV(); +	//const LLVector3 scaled_right = horiz_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius() * hb_right;//right; +	//const LLVector3 scaled_up = vert_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius() * hb_up;//up;  	LLVector3 v_clipped[4]; -	v_clipped[0] = draw_pos - scaled_right + scaled_up; -	v_clipped[1] = draw_pos - scaled_right - scaled_up; -	v_clipped[2] = draw_pos + scaled_right + scaled_up; -	v_clipped[3] = draw_pos + scaled_right - scaled_up; +	hb.corner(0) = draw_pos - scaled_right + scaled_up; +	hb.corner(1) = draw_pos - scaled_right - scaled_up; +	hb.corner(2) = draw_pos + scaled_right + scaled_up; +	hb.corner(3) = draw_pos + scaled_right - scaled_up; + +	F32 t_left, t_right; +	if (!clip_quad_to_horizon(t_left, t_right, v_clipped, hb.corners(), cos_max_angle)) +	{ +		hb.setVisible(FALSE); +		return FALSE; +	}  	hb.setVisible(TRUE);  	facep = mFace[f];  @@ -1270,9 +1507,164 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const  	facep->getVertexBuffer()->flush(); +	if (is_sun) +	{ +		if ((t_left > 0) && (t_right > 0)) +		{ +			F32 t = (t_left + t_right) * 0.5f; +			mSun.setHorizonVisibility(0.5f * (1 + cos(t * F_PI))); +		} +		else +		{ +			mSun.setHorizonVisibility(); +		} +		updateSunHaloGeometry(drawable); +	} +  	return TRUE;  } + + + +// Clips quads with top and bottom sides parallel to horizon. + +BOOL clip_quad_to_horizon(F32& t_left, F32& t_right, LLVector3 v_clipped[4], +						  const LLVector3 v_corner[4], const F32 cos_max_angle) +{ +	t_left = clip_side_to_horizon(v_corner[1], v_corner[0], cos_max_angle); +	t_right = clip_side_to_horizon(v_corner[3], v_corner[2], cos_max_angle); + +	if ((t_left >= 1) || (t_right >= 1)) +	{ +		return FALSE; +	} + +	//const BOOL left_clip = (t_left > 0); +	//const BOOL right_clip = (t_right > 0); + +	//if (!left_clip && !right_clip) +	{ +		for (S32 vtx = 0; vtx < 4; ++vtx) +		{ +			v_clipped[vtx]  = v_corner[vtx]; +		} +	} +/*	else +	{ +		v_clipped[0] = v_corner[0]; +		v_clipped[1] = left_clip ? ((1 - t_left) * v_corner[1] + t_left * v_corner[0]) +									: v_corner[1]; +		v_clipped[2] = v_corner[2]; +		v_clipped[3] = right_clip ? ((1 - t_right) * v_corner[3] + t_right * v_corner[2]) +									: v_corner[3]; +	}*/ + +	return TRUE; +} + + +F32 clip_side_to_horizon(const LLVector3& V0, const LLVector3& V1, const F32 cos_max_angle) +{ +	const LLVector3 V = V1 - V0; +	const F32 k2 = 1.f/(cos_max_angle * cos_max_angle) - 1; +	const F32 A = V.mV[0] * V.mV[0] + V.mV[1] * V.mV[1] - k2 * V.mV[2] * V.mV[2]; +	const F32 B = V0.mV[0] * V.mV[0] + V0.mV[1] * V.mV[1] - k2 * V0.mV[2] * V.mV[2]; +	const F32 C = V0.mV[0] * V0.mV[0] + V0.mV[1] * V0.mV[1] - k2 * V0.mV[2] * V0.mV[2]; + +	if (fabs(A) < 1e-7) +	{ +		return -0.1f;	// v0 is cone origin and v1 is on the surface of the cone. +	} + +	const F32 det = sqrt(B*B - A*C); +	const F32 t1 = (-B - det) / A; +	const F32 t2 = (-B + det) / A; +	const F32 z1 = V0.mV[2] + t1 * V.mV[2]; +	const F32 z2 = V0.mV[2] + t2 * V.mV[2]; +	if (z1 * cos_max_angle < 0) +	{ +		return t2; +	} +	else if (z2 * cos_max_angle < 0) +	{ +		return t1; +	} +	else if ((t1 < 0) || (t1 > 1)) +	{ +		return t2; +	} +	else +	{ +		return t1; +	} +} + + +void LLVOSky::updateSunHaloGeometry(LLDrawable *drawable ) +{ +#if 0 +	const LLVector3* v_corner = mSun.corners(); + +	LLStrider<LLVector3> verticesp; +	LLStrider<LLVector3> normalsp; +	LLStrider<LLVector2> texCoordsp; +	LLStrider<U16> indicesp; +	S32 index_offset; +	LLFace *face; + +	const LLVector3 right = 2 * (v_corner[2] - v_corner[0]); +	LLVector3 up = 2 * (v_corner[2] - v_corner[3]); +	up.normalize(); +	F32 size = right.length(); +	up = size * up; +	const LLVector3 draw_pos = 0.25 * (v_corner[0] + v_corner[1] + v_corner[2] + v_corner[3]); +	 +	LLVector3 v_glow_corner[4]; + +	v_glow_corner[0] = draw_pos - right + up; +	v_glow_corner[1] = draw_pos - right - up; +	v_glow_corner[2] = draw_pos + right + up; +	v_glow_corner[3] = draw_pos + right - up; + +	face = mFace[FACE_BLOOM];  + +	if (face->mVertexBuffer.isNull()) +	{ +		face->setSize(4, 6); +		face->setGeomIndex(0); +		face->setIndicesIndex(0); +		face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); +		face->mVertexBuffer->allocateBuffer(4, 6, TRUE); +	} + +	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); +	if (-1 == index_offset) +	{ +		return; +	} + +	for (S32 vtx = 0; vtx < 4; ++vtx) +	{ +		*(verticesp++)  = v_glow_corner[vtx] + mCameraPosAgent; +	} + +	*(texCoordsp++) = TEX01; +	*(texCoordsp++) = TEX00; +	*(texCoordsp++) = TEX11; +	*(texCoordsp++) = TEX10; + +	*indicesp++ = index_offset + 0; +	*indicesp++ = index_offset + 2; +	*indicesp++ = index_offset + 1; + +	*indicesp++ = index_offset + 1; +	*indicesp++ = index_offset + 2; +	*indicesp++ = index_offset + 3; +#endif +} + +  F32 dtReflection(const LLVector3& p, F32 cos_dir_from_top, F32 sin_dir_from_top, F32 diff_angl_dir)  {  	LLVector3 P = p; @@ -1334,6 +1726,9 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,  	LLVector3 look_at_right = look_at % LLVector3::z_axis;  	look_at_right.normalize(); +	const static F32 cos_horizon_angle = cosHorizon(0.0f/sResolution); +	//const static F32 horizon_angle = acos(cos_horizon_angle); +  	const F32 enlargm_factor = ( 1 - to_dir.mV[2] );  	F32 horiz_enlargement = 1 + enlargm_factor * 0.3f;  	F32 vert_enlargement = 1 + enlargm_factor * 0.2f; @@ -1348,10 +1743,22 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,  	LLVector3 top_hb = v_corner[0] = stretch_corner[0] = hb_pos - Right + Up;  	v_corner[1] = stretch_corner[1] = hb_pos - Right - Up; +	F32 dt_hor, dt; +	dt_hor = clip_side_to_horizon(v_corner[1], v_corner[0], cos_horizon_angle); +  	LLVector2 TEX0t = TEX00;  	LLVector2 TEX1t = TEX10;  	LLVector3 lower_corner = v_corner[1]; +	if ((dt_hor > 0) && (dt_hor < 1)) +	{ +		TEX0t = LLVector2(0, dt_hor); +		TEX1t = LLVector2(1, dt_hor); +		lower_corner = (1 - dt_hor) * v_corner[1] + dt_hor * v_corner[0]; +	} +	else +		dt_hor = llmax(0.0f, llmin(1.0f, dt_hor)); +  	top_hb.normalize();  	const F32 cos_angle_of_view = fabs(top_hb.mV[VZ]);  	const F32 extension = llmin (5.0f, 1.0f / cos_angle_of_view); @@ -1363,6 +1770,9 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,  	stretch_corner[0] = lower_corner + extension * (stretch_corner[0] - lower_corner);  	stretch_corner[1] = lower_corner + extension * (stretch_corner[1] - lower_corner); +	dt = dt_hor; + +  	F32 cos_dir_from_top[2];  	LLVector3 dir = stretch_corner[0]; @@ -1451,8 +1861,9 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,  		F32 dt_tex = dtReflection(P, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir); -		TEX0tt = LLVector2(0, dt_tex); -		TEX1tt = LLVector2(1, dt_tex); +		dt = dt_tex; +		TEX0tt = LLVector2(0, dt); +		TEX1tt = LLVector2(1, dt);  		quads++;  	}  	else @@ -1463,225 +1874,408 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,  	LLFace *face = mFace[FACE_REFLECTION];  -    if (face) -    { -        if (!face->getVertexBuffer() || quads * 4 != face->getGeomCount()) -        { -            face->setSize(quads * 4, quads * 6); -            LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); -			if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) +	if (!face->getVertexBuffer() || quads*4 != face->getGeomCount()) +	{ +		face->setSize(quads * 4, quads * 6); +		LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); +		if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) +		{ +			LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to " +				<< face->getGeomCount() << " vertices and " +				<< face->getIndicesCount() << " indices" << LL_ENDL; +		} +		face->setIndicesIndex(0); +		face->setGeomIndex(0); +		face->setVertexBuffer(buff); +	} +	 +	LLStrider<LLVector3> verticesp; +	LLStrider<LLVector3> normalsp; +	LLStrider<LLVector2> texCoordsp; +	LLStrider<U16> indicesp; +	S32 index_offset; +	 +	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); +	if (-1 == index_offset) +	{ +		return; +	} + +	LLColor3 hb_col3 = HB.getInterpColor(); +	hb_col3.clamp(); +	const LLColor4 hb_col = LLColor4(hb_col3); + +	const F32 min_attenuation = 0.4f; +	const F32 max_attenuation = 0.7f; +	const F32 attenuation = min_attenuation +		+ cos_angle_of_view * (max_attenuation - min_attenuation); + +	LLColor4 hb_refl_col = (1-attenuation) * hb_col + attenuation * mFogColor; +	face->setFaceColor(hb_refl_col); +	 +	LLVector3 v_far[2]; +	v_far[0] = v_refl_corner[1]; +	v_far[1] = v_refl_corner[3]; + +	if(dt_clip > 0) +	{ +		if (dt_clip >= 1) +		{ +			for (S32 vtx = 0; vtx < 4; ++vtx) +			{ +				F32 ratio = far_clip / v_refl_corner[vtx].length(); +				*(verticesp++) = v_refl_corner[vtx] = ratio * v_refl_corner[vtx] + mCameraPosAgent; +			} +			const LLVector3 draw_pos = 0.25 * +				(v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]); +			face->mCenterAgent = draw_pos; +		} +		else +		{ +			F32 ratio = far_clip / v_refl_corner[1].length(); +			v_sprite_corner[1] = v_refl_corner[1] * ratio; + +			ratio = far_clip / v_refl_corner[3].length(); +			v_sprite_corner[3] = v_refl_corner[3] * ratio; + +			v_refl_corner[1] = (1 - dt_clip) * v_refl_corner[1] + dt_clip * v_refl_corner[0]; +			v_refl_corner[3] = (1 - dt_clip) * v_refl_corner[3] + dt_clip * v_refl_corner[2]; +			v_sprite_corner[0] = v_refl_corner[1]; +			v_sprite_corner[2] = v_refl_corner[3]; + +			for (S32 vtx = 0; vtx < 4; ++vtx)  			{ -				LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to " -					<< face->getGeomCount() << " vertices and " -					<< face->getIndicesCount() << " indices" << LL_ENDL; +				*(verticesp++) = v_sprite_corner[vtx] + mCameraPosAgent;  			} -            face->setIndicesIndex(0); -            face->setGeomIndex(0); -            face->setVertexBuffer(buff); -        } - -        LLStrider<LLVector3> verticesp; -        LLStrider<LLVector3> normalsp; -        LLStrider<LLVector2> texCoordsp; -        LLStrider<U16> indicesp; -        S32 index_offset; - -        index_offset = face->getGeometry(verticesp, normalsp, texCoordsp, indicesp); -        if (-1 == index_offset) -        { -            return; -        } - -        LLColor3 hb_col3 = HB.getInterpColor(); -        hb_col3.clamp(); -        const LLColor4 hb_col = LLColor4(hb_col3); - -        const F32 min_attenuation = 0.4f; -        const F32 max_attenuation = 0.7f; -        const F32 attenuation = min_attenuation -            + cos_angle_of_view * (max_attenuation - min_attenuation); - -        LLColor4 hb_refl_col = (1 - attenuation) * hb_col + attenuation * getSkyFogColor(); -        face->setFaceColor(hb_refl_col); - -        LLVector3 v_far[2]; -        v_far[0] = v_refl_corner[1]; -        v_far[1] = v_refl_corner[3]; - -        if (dt_clip > 0) -        { -            if (dt_clip >= 1) -            { -                for (S32 vtx = 0; vtx < 4; ++vtx) -                { -                    F32 ratio = far_clip / v_refl_corner[vtx].length(); -                    *(verticesp++) = v_refl_corner[vtx] = ratio * v_refl_corner[vtx] + mCameraPosAgent; -                } -                const LLVector3 draw_pos = 0.25 * -                    (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]); -                face->mCenterAgent = draw_pos; -            } -            else -            { -                F32 ratio = far_clip / v_refl_corner[1].length(); -                v_sprite_corner[1] = v_refl_corner[1] * ratio; - -                ratio = far_clip / v_refl_corner[3].length(); -                v_sprite_corner[3] = v_refl_corner[3] * ratio; - -                v_refl_corner[1] = (1 - dt_clip) * v_refl_corner[1] + dt_clip * v_refl_corner[0]; -                v_refl_corner[3] = (1 - dt_clip) * v_refl_corner[3] + dt_clip * v_refl_corner[2]; -                v_sprite_corner[0] = v_refl_corner[1]; -                v_sprite_corner[2] = v_refl_corner[3]; - -                for (S32 vtx = 0; vtx < 4; ++vtx) -                { -                    *(verticesp++) = v_sprite_corner[vtx] + mCameraPosAgent; -                } - -                const LLVector3 draw_pos = 0.25 * -                    (v_refl_corner[0] + v_sprite_corner[1] + v_refl_corner[2] + v_sprite_corner[3]); -                face->mCenterAgent = draw_pos; -            } - -            *(texCoordsp++) = TEX0tt; -            *(texCoordsp++) = TEX0t; -            *(texCoordsp++) = TEX1tt; -            *(texCoordsp++) = TEX1t; - -            *indicesp++ = index_offset + 0; -            *indicesp++ = index_offset + 2; -            *indicesp++ = index_offset + 1; - -            *indicesp++ = index_offset + 1; -            *indicesp++ = index_offset + 2; -            *indicesp++ = index_offset + 3; - -            index_offset += 4; -        } - -        if (dt_clip < 1) -        { -            if (dt_clip <= 0) -            { -                const LLVector3 draw_pos = 0.25 * -                    (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]); -                face->mCenterAgent = draw_pos; -            } - -            const F32 raws_inv = 1.f / raws; -            const F32 cols_inv = 1.f / cols; -            LLVector3 left = v_refl_corner[0] - v_refl_corner[1]; -            LLVector3 right = v_refl_corner[2] - v_refl_corner[3]; -            left *= raws_inv; -            right *= raws_inv; - -            for (S32 raw = 0; raw < raws; ++raw) -            { -                F32 dt_v0 = raw * raws_inv; -                F32 dt_v1 = (raw + 1) * raws_inv; -                const LLVector3 BL = v_refl_corner[1] + (F32)raw * left; -                const LLVector3 BR = v_refl_corner[3] + (F32)raw * right; -                const LLVector3 EL = BL + left; -                const LLVector3 ER = BR + right; -                dt_v0 = dt_v1 = dtReflection(EL, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir); -                for (S32 col = 0; col < cols; ++col) -                { -                    F32 dt_h0 = col * cols_inv; -                    *(verticesp++) = (1 - dt_h0) * EL + dt_h0 * ER + mCameraPosAgent; -                    *(verticesp++) = (1 - dt_h0) * BL + dt_h0 * BR + mCameraPosAgent; -                    F32 dt_h1 = (col + 1) * cols_inv; -                    *(verticesp++) = (1 - dt_h1) * EL + dt_h1 * ER + mCameraPosAgent; -                    *(verticesp++) = (1 - dt_h1) * BL + dt_h1 * BR + mCameraPosAgent; - -                    *(texCoordsp++) = LLVector2(dt_h0, dt_v1); -                    *(texCoordsp++) = LLVector2(dt_h0, dt_v0); -                    *(texCoordsp++) = LLVector2(dt_h1, dt_v1); -                    *(texCoordsp++) = LLVector2(dt_h1, dt_v0); - -                    *indicesp++ = index_offset + 0; -                    *indicesp++ = index_offset + 2; -                    *indicesp++ = index_offset + 1; - -                    *indicesp++ = index_offset + 1; -                    *indicesp++ = index_offset + 2; -                    *indicesp++ = index_offset + 3; - -                    index_offset += 4; -                } -            } -        } - -        face->getVertexBuffer()->flush(); -    } + +			const LLVector3 draw_pos = 0.25 * +				(v_refl_corner[0] + v_sprite_corner[1] + v_refl_corner[2] + v_sprite_corner[3]); +			face->mCenterAgent = draw_pos; +		} + +		*(texCoordsp++) = TEX0tt; +		*(texCoordsp++) = TEX0t; +		*(texCoordsp++) = TEX1tt; +		*(texCoordsp++) = TEX1t; + +		*indicesp++ = index_offset + 0; +		*indicesp++ = index_offset + 2; +		*indicesp++ = index_offset + 1; + +		*indicesp++ = index_offset + 1; +		*indicesp++ = index_offset + 2; +		*indicesp++ = index_offset + 3; + +		index_offset += 4; +	} + +	if (dt_clip < 1) +	{ +		if (dt_clip <= 0) +		{ +			const LLVector3 draw_pos = 0.25 * +				(v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]); +			face->mCenterAgent = draw_pos; +		} + +		const F32 raws_inv = 1.f/raws; +		const F32 cols_inv = 1.f/cols; +		LLVector3 left	= v_refl_corner[0] - v_refl_corner[1]; +		LLVector3 right = v_refl_corner[2] - v_refl_corner[3]; +		left *= raws_inv; +		right *= raws_inv; + +		F32 dt_raw = dt; + +		for (S32 raw = 0; raw < raws; ++raw) +		{ +			F32 dt_v0 = raw * raws_inv; +			F32 dt_v1 = (raw + 1) * raws_inv; +			const LLVector3 BL = v_refl_corner[1] + (F32)raw * left; +			const LLVector3 BR = v_refl_corner[3] + (F32)raw * right; +			const LLVector3 EL = BL + left; +			const LLVector3 ER = BR + right; +			dt_v0 = dt_raw; +			dt_raw = dt_v1 = dtReflection(EL, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir); +			for (S32 col = 0; col < cols; ++col) +			{ +				F32 dt_h0 = col * cols_inv; +				*(verticesp++) = (1 - dt_h0) * EL + dt_h0 * ER + mCameraPosAgent; +				*(verticesp++) = (1 - dt_h0) * BL + dt_h0 * BR + mCameraPosAgent; +				F32 dt_h1 = (col + 1) * cols_inv; +				*(verticesp++) = (1 - dt_h1) * EL + dt_h1 * ER + mCameraPosAgent; +				*(verticesp++) = (1 - dt_h1) * BL + dt_h1 * BR + mCameraPosAgent; + +				*(texCoordsp++) = LLVector2(dt_h0, dt_v1); +				*(texCoordsp++) = LLVector2(dt_h0, dt_v0); +				*(texCoordsp++) = LLVector2(dt_h1, dt_v1); +				*(texCoordsp++) = LLVector2(dt_h1, dt_v0); + +				*indicesp++ = index_offset + 0; +				*indicesp++ = index_offset + 2; +				*indicesp++ = index_offset + 1; + +				*indicesp++ = index_offset + 1; +				*indicesp++ = index_offset + 2; +				*indicesp++ = index_offset + 3; + +				index_offset += 4; +			} +		} +	} + +	face->getVertexBuffer()->flush();  } + + +  void LLVOSky::updateFog(const F32 distance)  { -    LLEnvironment& environment = LLEnvironment::instance(); -    if (environment.getCurrentSky() != nullptr) -    { -        LLVector3 light_dir = LLVector3(environment.getClampedLightNorm()); -        m_legacyAtmospherics.updateFog(distance, light_dir); -    } -} +	if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG)) +	{ +		if (!LLGLSLShader::sNoFixedFunction) +		{ +			glFogf(GL_FOG_DENSITY, 0); +			glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV); +			glFogf(GL_FOG_END, 1000000.f); +		} +		return; +	} -void LLVOSky::setSunAndMoonDirectionsCFR(const LLVector3 &sun_dir_cfr, const LLVector3 &moon_dir_cfr) -{ -    mSun.setDirection(sun_dir_cfr);	 -	mMoon.setDirection(moon_dir_cfr); +	const BOOL hide_clip_plane = TRUE; +	LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f); -	// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping -	// on the upward facing faces of cubes. -    { -	    // Same as dot product with the up direction + clamp. -	    F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]); -	    sunDot *= sunDot;	 +	const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f; +	// LLWorld::getInstance()->getWaterHeight(); +	F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2]; + +	F32 near_clip_height = LLViewerCamera::getInstance()->getAtAxis().mV[VZ] * LLViewerCamera::getInstance()->getNear(); +	camera_height += near_clip_height; + +	F32 fog_distance = 0.f; +	LLColor3 res_color[3]; + +	LLColor3 sky_fog_color = LLColor3::white; +	LLColor3 render_fog_color = LLColor3::white; -	    // Create normalized vector that has the sunDir pushed south about an hour and change. -	    LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; +	LLVector3 tosun = getToSunLast(); +	const F32 tosun_z = tosun.mV[VZ]; +	tosun.mV[VZ] = 0.f; +	tosun.normalize(); +	LLVector3 perp_tosun; +	perp_tosun.mV[VX] = -tosun.mV[VY]; +	perp_tosun.mV[VY] = tosun.mV[VX]; +	LLVector3 tosun_45 = tosun + perp_tosun; +	tosun_45.normalize(); -	    // Blend between normal sun dir and adjusted sun dir based on how close we are -	    // to having the sun overhead. -	    mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot); -	    mBumpSunDir.normalize(); -    } +	F32 delta = 0.06f; +	tosun.mV[VZ] = delta; +	perp_tosun.mV[VZ] = delta; +	tosun_45.mV[VZ] = delta; +	tosun.normalize(); +	perp_tosun.normalize(); +	tosun_45.normalize(); -	updateDirections(); +	// Sky colors, just slightly above the horizon in the direction of the sun, perpendicular to the sun, and at a 45 degree angle to the sun. +	initAtmospherics(); +	res_color[0] = calcSkyColorInDir(tosun); +	res_color[1] = calcSkyColorInDir(perp_tosun); +	res_color[2] = calcSkyColorInDir(tosun_45); -    mForceUpdate = true; +	sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]); + +	F32 full_off = -0.25f; +	F32 full_on = 0.00f; +	F32 on = (tosun_z - full_off) / (full_on - full_off); +	on = llclamp(on, 0.01f, 1.f); +	sky_fog_color *= 0.5f * on; + + +	// We need to clamp these to non-zero, in order for the gamma correction to work. 0^y = ??? +	S32 i; +	for (i = 0; i < 3; i++) +	{ +		sky_fog_color.mV[i] = llmax(0.0001f, sky_fog_color.mV[i]); +	} + +	color_gamma_correct(sky_fog_color); + +	render_fog_color = sky_fog_color; + +	F32 fog_density = 0.f; +	fog_distance = mFogRatio * distance; +	 +	if (camera_height > water_height) +	{ +		LLColor4 fog(render_fog_color); +		if (!LLGLSLShader::sNoFixedFunction) +		{ +			glFogfv(GL_FOG_COLOR, fog.mV); +		} +		mGLFogCol = fog; + +		if (hide_clip_plane) +		{ +			// For now, set the density to extend to the cull distance. +			const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f))) +			fog_density = f_log/fog_distance; +			if (!LLGLSLShader::sNoFixedFunction) +			{ +				glFogi(GL_FOG_MODE, GL_EXP2); +			} +		} +		else +		{ +			const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f)) +			fog_density = (f_log)/fog_distance; +			if (!LLGLSLShader::sNoFixedFunction) +			{ +				glFogi(GL_FOG_MODE, GL_EXP); +			} +		} +	} +	else +	{ +		F32 depth = water_height - camera_height; +		 +		// get the water param manager variables +		float water_fog_density = LLWaterParamManager::getInstance()->getFogDensity(); +		LLColor4 water_fog_color(LLDrawPoolWater::sWaterFogColor.mV); +		 +		// adjust the color based on depth.  We're doing linear approximations +		float depth_scale = gSavedSettings.getF32("WaterGLFogDepthScale"); +		float depth_modifier = 1.0f - llmin(llmax(depth / depth_scale, 0.01f),  +			gSavedSettings.getF32("WaterGLFogDepthFloor")); + +		LLColor4 fogCol = water_fog_color * depth_modifier; +		fogCol.setAlpha(1); + +		// set the gl fog color +		mGLFogCol = fogCol; + +		// set the density based on what the shaders use +		fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale"); + +		if (!LLGLSLShader::sNoFixedFunction) +		{ +			glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV); +			glFogi(GL_FOG_MODE, GL_EXP2); +		} +	} + +	mFogColor = sky_fog_color; +	mFogColor.setAlpha(1); +	LLDrawPoolWater::sWaterFogEnd = fog_distance*2.2f; + +	if (!LLGLSLShader::sNoFixedFunction) +	{ +		LLGLSFog gls_fog; +		glFogf(GL_FOG_END, fog_distance*2.2f); +		glFogf(GL_FOG_DENSITY, fog_density); +		glHint(GL_FOG_HINT, GL_NICEST); +	} +	stop_glerror();  } -void LLVOSky::setSunDirectionCFR(const LLVector3 &sun_dir_cfr) + +// Functions used a lot. +F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply)  { -    mSun.setDirection(sun_dir_cfr);	 +	F32 mv = color_max(col); +	if (0 == mv) +	{ +		return 0; +	} -	// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping -	// on the upward facing faces of cubes. -    { -	    // Same as dot product with the up direction + clamp. -	    F32 sunDot = llmax(0.f, sun_dir_cfr.mV[2]); -	    sunDot *= sunDot;	 +	col *= 1.f / mv; +	color_pow(col, e); +	if (postmultiply) +	{ +		col *= mv; +	} +	return mv; +} -	    // Create normalized vector that has the sunDir pushed south about an hour and change. -	    LLVector3 adjustedDir = (sun_dir_cfr + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; +// Returns angle (RADIANs) between the horizontal projection of "v" and the x_axis. +// Range of output is 0.0f to 2pi //359.99999...f +// Returns 0.0f when "v" = +/- z_axis. +F32 azimuth(const LLVector3 &v) +{ +	F32 azimuth = 0.0f; +	if (v.mV[VX] == 0.0f) +	{ +		if (v.mV[VY] > 0.0f) +		{ +			azimuth = F_PI * 0.5f; +		} +		else if (v.mV[VY] < 0.0f) +		{ +			azimuth = F_PI * 1.5f;// 270.f; +		} +	} +	else +	{ +		azimuth = (F32) atan(v.mV[VY] / v.mV[VX]); +		if (v.mV[VX] < 0.0f) +		{ +			azimuth += F_PI; +		} +		else if (v.mV[VY] < 0.0f) +		{ +			azimuth += F_PI * 2; +		} +	}	 +	return azimuth; +} -	    // Blend between normal sun dir and adjusted sun dir based on how close we are -	    // to having the sun overhead. -	    mBumpSunDir = adjustedDir * sunDot + sun_dir_cfr * (1.0f - sunDot); -	    mBumpSunDir.normalize(); -    } +void LLVOSky::initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity) +{ +	LLVector3 sun_direction = (sun_dir.length() == 0) ? LLVector3::x_axis : sun_dir; +	sun_direction.normalize(); +	mSun.setDirection(sun_direction); +	mSun.renewDirection(); +	mSun.setAngularVelocity(sun_ang_velocity); +	mMoon.setDirection(-mSun.getDirection()); +	mMoon.renewDirection(); +	mLastLightingDirection = mSun.getDirection(); -	updateDirections(); +	calcAtmospherics(); -    mForceUpdate = true; +	if ( !mInitialized ) +	{ +		init(); +		LLSkyTex::stepCurrent(); +	}		  } -void LLVOSky::setMoonDirectionCFR(const LLVector3 &moon_dir_cfr) +void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity)  { -	mMoon.setDirection(moon_dir_cfr); - -	updateDirections(); +	LLVector3 sun_direction = (sun_dir.length() == 0) ? LLVector3::x_axis : sun_dir; +	sun_direction.normalize(); -    mForceUpdate = true; +	// Push the sun "South" as it approaches directly overhead so that we can always see bump mapping +	// on the upward facing faces of cubes. +	LLVector3 newDir = sun_direction; + +	// Same as dot product with the up direction + clamp. +	F32 sunDot = llmax(0.f, newDir.mV[2]); +	sunDot *= sunDot;	 + +	// Create normalized vector that has the sunDir pushed south about an hour and change. +	LLVector3 adjustedDir = (newDir + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f; + +	// Blend between normal sun dir and adjusted sun dir based on how close we are +	// to having the sun overhead. +	mBumpSunDir = adjustedDir * sunDot + newDir * (1.0f - sunDot); +	mBumpSunDir.normalize(); + +	F32 dp = mLastLightingDirection * sun_direction; +	mSun.setDirection(sun_direction); +	mSun.setAngularVelocity(sun_ang_velocity); +	mMoon.setDirection(-sun_direction); +	calcAtmospherics(); +	if (dp < 0.995f) { //the sun jumped a great deal, update immediately +		mForceUpdate = TRUE; +	}  } | 
