283 lines
8.9 KiB
C++
283 lines
8.9 KiB
C++
/**
|
|
* @file llenvmanager.cpp
|
|
* @brief Implementation of classes managing WindLight and water settings.
|
|
*
|
|
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
|
* Second Life Viewer Source Code
|
|
* Copyright (C) 2011, Linden Research, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation;
|
|
* version 2.1 of the License only.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include "llviewerprecompiledheaders.h"
|
|
|
|
#include "llenvironment.h"
|
|
|
|
#include "llagent.h"
|
|
#include "lldaycyclemanager.h"
|
|
#include "llviewercontrol.h" // for gSavedSettings
|
|
#include "llviewerregion.h"
|
|
#include "llwaterparammanager.h"
|
|
#include "llwlhandlers.h"
|
|
#include "llwlparammanager.h"
|
|
#include "lltrans.h"
|
|
#include "lltrace.h"
|
|
#include "llfasttimer.h"
|
|
#include "llviewercamera.h"
|
|
#include "pipeline.h"
|
|
|
|
//=========================================================================
|
|
const F32 LLEnvironment::SUN_DELTA_YAW(F_PI); // 180deg
|
|
|
|
namespace
|
|
{
|
|
LLTrace::BlockTimerStatHandle FTM_ENVIRONMENT_UPDATE("Update Environment Tick");
|
|
LLTrace::BlockTimerStatHandle FTM_SHADER_PARAM_UPDATE("Update Shader Parameters");
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
LLEnvironment::LLEnvironment():
|
|
mCurrentSky(),
|
|
mSkysById(),
|
|
mSkysByName()
|
|
{
|
|
LLSettingsSky::ptr_t p_default_sky = LLSettingsSky::buildDefaultSky();
|
|
addSky(p_default_sky);
|
|
mCurrentSky = p_default_sky;
|
|
}
|
|
|
|
LLEnvironment::~LLEnvironment()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
void LLEnvironment::update(const LLViewerCamera * cam)
|
|
{
|
|
LL_RECORD_BLOCK_TIME(FTM_ENVIRONMENT_UPDATE);
|
|
|
|
// update clouds, sun, and general
|
|
updateCloudScroll();
|
|
mCurrentSky->update();
|
|
|
|
// // update only if running
|
|
// if (mAnimator.getIsRunning())
|
|
// {
|
|
// mAnimator.update(mCurParams);
|
|
// }
|
|
|
|
LLVector3 lightdir = mCurrentSky->getLightDirection();
|
|
// update the shaders and the menu
|
|
|
|
F32 camYaw = cam->getYaw();
|
|
|
|
stop_glerror();
|
|
|
|
// *TODO: potential optimization - this block may only need to be
|
|
// executed some of the time. For example for water shaders only.
|
|
{
|
|
LLVector3 lightNorm3(mCurrentSky->getLightDirection());
|
|
|
|
lightNorm3 *= LLQuaternion(-(camYaw + SUN_DELTA_YAW), LLVector3(0.f, 1.f, 0.f));
|
|
mRotatedLight = LLVector4(lightNorm3, 0.f);
|
|
|
|
LLViewerShaderMgr::shader_iter shaders_iter, end_shaders;
|
|
end_shaders = LLViewerShaderMgr::instance()->endShaders();
|
|
for (shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter)
|
|
{
|
|
if ((shaders_iter->mProgramObject != 0)
|
|
&& (gPipeline.canUseWindLightShaders()
|
|
|| shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER))
|
|
{
|
|
shaders_iter->mUniformsDirty = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLEnvironment::updateCloudScroll()
|
|
{
|
|
// This is a function of the environment rather than the sky, since it should
|
|
// persist through sky transitions.
|
|
static LLTimer s_cloud_timer;
|
|
|
|
F64 delta_t = s_cloud_timer.getElapsedTimeAndResetF64();
|
|
|
|
LLVector2 cloud_delta = static_cast<F32>(delta_t)* (mCurrentSky->getCloudScrollRate() - LLVector2(10.0, 10.0)) / 100.0;
|
|
mCloudScrollDelta += cloud_delta;
|
|
|
|
// {
|
|
// LLVector2 v2(mCurrentSky->getCloudScrollRate());
|
|
// static F32 xoffset(0.f);
|
|
// static F32 yoffset(0.f);
|
|
//
|
|
// xoffset += F32(delta_t * (v2[0] - 10.f) / 100.f);
|
|
// yoffset += F32(delta_t * (v2[1] - 10.f) / 100.f);
|
|
//
|
|
// LL_WARNS("RIDER") << "offset " << mCloudScrollDelta << " vs (" << xoffset << ", " << yoffset << ")" << LL_ENDL;
|
|
// }
|
|
|
|
|
|
}
|
|
|
|
void LLEnvironment::updateGLVariablesForSettings(LLGLSLShader *shader, const LLSettingsBase::ptr_t &psetting)
|
|
{
|
|
LL_RECORD_BLOCK_TIME(FTM_SHADER_PARAM_UPDATE);
|
|
|
|
//_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL;
|
|
LLSettingsBase::parammapping_t params = psetting->getParameterMap();
|
|
for (LLSettingsBase::parammapping_t::iterator it = params.begin(); it != params.end(); ++it)
|
|
{
|
|
if (!psetting->mSettings.has((*it).first))
|
|
continue;
|
|
|
|
LLSD value = psetting->mSettings[(*it).first];
|
|
LLSD::Type setting_type = value.type();
|
|
|
|
stop_glerror();
|
|
switch (setting_type)
|
|
{
|
|
case LLSD::TypeInteger:
|
|
shader->uniform1i((*it).second, value.asInteger());
|
|
//_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
|
|
break;
|
|
case LLSD::TypeReal:
|
|
shader->uniform1f((*it).second, value.asReal());
|
|
//_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
|
|
break;
|
|
|
|
case LLSD::TypeBoolean:
|
|
shader->uniform1i((*it).second, value.asBoolean() ? 1 : 0);
|
|
//_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL;
|
|
break;
|
|
|
|
case LLSD::TypeArray:
|
|
{
|
|
LLVector4 vect4(value);
|
|
//_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL;
|
|
shader->uniform4fv((*it).second, 1, vect4.mV);
|
|
|
|
break;
|
|
}
|
|
|
|
// case LLSD::TypeMap:
|
|
// case LLSD::TypeString:
|
|
// case LLSD::TypeUUID:
|
|
// case LLSD::TypeURI:
|
|
// case LLSD::TypeBinary:
|
|
// case LLSD::TypeDate:
|
|
default:
|
|
break;
|
|
}
|
|
stop_glerror();
|
|
}
|
|
//_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL;
|
|
|
|
psetting->applySpecial(shader);
|
|
|
|
if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && !LLPipeline::sUnderWaterRender)
|
|
{
|
|
shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
|
|
}
|
|
else
|
|
{
|
|
shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
|
|
}
|
|
|
|
}
|
|
|
|
void LLEnvironment::updateShaderUniforms(LLGLSLShader *shader)
|
|
{
|
|
|
|
if (gPipeline.canUseWindLightShaders())
|
|
{
|
|
updateGLVariablesForSettings(shader, mCurrentSky);
|
|
}
|
|
|
|
if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT)
|
|
{
|
|
stop_glerror();
|
|
shader->uniform4fv(LLShaderMgr::LIGHTNORM, 1, mRotatedLight.mV);
|
|
shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
|
|
stop_glerror();
|
|
}
|
|
else if (shader->mShaderGroup == LLGLSLShader::SG_SKY)
|
|
{
|
|
stop_glerror();
|
|
shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mCurrentSky->getLightDirectionClamped().mV);
|
|
stop_glerror();
|
|
}
|
|
|
|
shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mCurrentSky->getSceneLightStrength());
|
|
|
|
// {
|
|
// LLVector4 cloud_scroll(mCloudScroll[0], mCloudScroll[1], 0.0, 0.0);
|
|
// // val.mV[0] = F32(i->second[0].asReal()) + mCloudScrollXOffset;
|
|
// // val.mV[1] = F32(i->second[1].asReal()) + mCloudScrollYOffset;
|
|
// // val.mV[2] = (F32)i->second[2].asReal();
|
|
// // val.mV[3] = (F32)i->second[3].asReal();
|
|
//
|
|
// stop_glerror();
|
|
// shader->uniform4fv(LLSettingsSky::SETTING_CLOUD_POS_DENSITY1, 1, cloud_scroll.mV);
|
|
// stop_glerror();
|
|
// }
|
|
|
|
|
|
}
|
|
//--------------------------------------------------------------------------
|
|
|
|
void LLEnvironment::addSky(const LLSettingsSky::ptr_t &sky)
|
|
{
|
|
std::string name = sky->getValue(LLSettingsSky::SETTING_NAME).asString();
|
|
|
|
std::pair<NamedSkyMap_t::iterator, bool> result;
|
|
result = mSkysByName.insert(NamedSkyMap_t::value_type(name, sky));
|
|
|
|
if (!result.second)
|
|
(*(result.first)).second = sky;
|
|
}
|
|
|
|
void LLEnvironment::addSky(const LLUUID &id, const LLSettingsSky::ptr_t &sky)
|
|
{
|
|
// std::string name = sky->getValue(LLSettingsSky::SETTING_NAME).asString();
|
|
//
|
|
// std::pair<NamedSkyMap_t::iterator, bool> result;
|
|
// result = mSkysByName.insert(NamedSkyMap_t::value_type(name, sky));
|
|
//
|
|
// if (!result.second)
|
|
// (*(result.first)).second = sky;
|
|
}
|
|
|
|
void LLEnvironment::removeSky(const std::string &name)
|
|
{
|
|
NamedSkyMap_t::iterator it = mSkysByName.find(name);
|
|
if (it != mSkysByName.end())
|
|
mSkysByName.erase(it);
|
|
}
|
|
|
|
void LLEnvironment::removeSky(const LLUUID &id)
|
|
{
|
|
|
|
}
|
|
|
|
void LLEnvironment::clearAllSkys()
|
|
{
|
|
mSkysByName.clear();
|
|
mSkysById.clear();
|
|
}
|
|
|