diff options
13 files changed, 715 insertions, 773 deletions
diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index 7d7547ecb1..7f2b5d4597 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -389,7 +389,7 @@ bool LLSettingsBase::validate() LLSD LLSettingsBase::settingValidation(LLSD &settings, validation_list_t &validations, bool partial) { - static Validator validateName(SETTING_NAME, false, LLSD::TypeString, boost::bind(&Validator::verifyStringLength, _1, 32)); + static Validator validateName(SETTING_NAME, false, LLSD::TypeString, boost::bind(&Validator::verifyStringLength, _1, 63)); static Validator validateId(SETTING_ID, false, LLSD::TypeUUID); static Validator validateHash(SETTING_HASH, false, LLSD::TypeInteger); static Validator validateType(SETTING_TYPE, false, LLSD::TypeString); diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl index bea016300d..4134220306 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl @@ -50,7 +50,7 @@ float pcfShadow(sampler2DShadow shadowMap, vec3 norm, vec4 stc, float bias_mul, { float offset = shadow_bias * bias_mul; stc.xyz /= stc.w; - stc.z += offset * 3.0; + stc.z += offset * 2.0; stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*shadow_res.y))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here float cs = shadow2D(shadowMap, stc.xyz).x; float shadow = cs * 4.0; diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 8fea4e5d27..180f38b1e1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -157,6 +157,6 @@ void main() vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz); frag_data[0] = vec4(color.rgb, 0); // diffuse - frag_data[1] = vec4(specular * 0.15, 0.5); // speccolor, spec + frag_data[1] = vec4(specular * 0.5, 0.5); // speccolor, spec frag_data[2] = vec4(encode_normal(screenspacewavef.xyz), 0.05, 0);// normalxy, 0, 0 } diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 03e5143fca..e41b4b99a3 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -190,11 +190,10 @@ vec3 post_atmo = color.rgb; bloom = fogged.a; #endif +// srgb colorspace debuggables //color.rgb = amblit; -//color.rgb = vec3(ambient); //color.rgb = sunlit; //color.rgb = post_ambient; -//color.rgb = vec3(final_da); //color.rgb = sun_contrib; //color.rgb = post_sunlight; //color.rgb = diffuse_srgb.rgb; @@ -208,6 +207,11 @@ vec3 post_atmo = color.rgb; color.rgb = srgb_to_linear(color.rgb); } +// linear debuggables +//color.rgb = vec3(final_da); +//color.rgb = vec3(ambient); +//color.rgb = vec3(scol); + frag_color.rgb = color.rgb; frag_color.a = bloom; } diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl index 4ac44feee5..d66983a951 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl @@ -22,8 +22,6 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - - // VARYING param funcs void setSunlitColor(vec3 v); diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl index 2683b06e1b..2de708d94b 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl @@ -51,11 +51,11 @@ vec3 atmosTransport(vec3 light) vec3 fullbrightAtmosTransport(vec3 light) { float brightness = dot(light.rgb, vec3(0.33333)); - return atmosTransportFrag(light, getAdditiveColor() * (brightness * 0.5 + 0.5), getAtmosAttenuation()); + return atmosTransportFrag(light * 0.5, getAdditiveColor() * (brightness * 0.5 + 0.5), getAtmosAttenuation()); } vec3 fullbrightShinyAtmosTransport(vec3 light) { float brightness = dot(light.rgb, vec3(0.33333)); - return atmosTransportFrag(light, getAdditiveColor() * (brightness * 0.5 + 0.5), getAtmosAttenuation()); + return atmosTransportFrag(light * 0.5, getAdditiveColor() * (brightness * brightness), getAtmosAttenuation()); } diff --git a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl index c0a0d4782d..88dfa8a907 100644 --- a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl @@ -37,22 +37,29 @@ uniform vec4 blue_density; uniform float haze_horizon; uniform float haze_density; uniform float cloud_shadow; +uniform float density_multiplier; +uniform float distance_multiplier; uniform float max_y; uniform vec4 glow; uniform float scene_light_strength; uniform mat3 ssao_effect_mat; +uniform int no_atmo; +uniform float sun_moon_glow_factor; vec3 scaleSoftClipFrag(vec3 light); vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten) { - light *= atten.r; - light += additive; - return (2.0 * light); + if (no_atmo == 1) + { + return light; + } + light *= atten.r; + light += additive; + return light * 2.0; } vec3 atmosLighting(vec3 light) { return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation()); } - diff --git a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl index e7e56087ab..08eb119510 100644 --- a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl @@ -35,10 +35,12 @@ uniform int no_atmo; vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten) { if (no_atmo == 1) - { + { return light; } - return (light + additive) * atten * 2.0; + light *= atten.r; + light += additive; + return light * 2.0; } vec3 atmosTransport(vec3 light) @@ -48,10 +50,12 @@ vec3 atmosTransport(vec3 light) vec3 fullbrightAtmosTransport(vec3 light) { - return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation()); + float brightness = dot(light.rgb, vec3(0.33333)); + return atmosTransportFrag(light * 0.5, getAdditiveColor() * (brightness * 0.5 + 0.5), getAtmosAttenuation()); } vec3 fullbrightShinyAtmosTransport(vec3 light) { - return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation()); + float brightness = dot(light.rgb, vec3(0.33333)); + return atmosTransportFrag(light * 0.5, getAdditiveColor() * (brightness * brightness), getAtmosAttenuation()); } diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index f08c36a7e7..a94b7c219f 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -388,12 +388,14 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data) std::string ctrl_action = ctrl->getName(); std::string local_desc; + LLSettingsBase::ptr_t setting_clone; bool is_local = false; // because getString can be empty if (mSettings->getSettingsType() == "water") { LLSettingsWater::ptr_t water = std::static_pointer_cast<LLSettingsWater>(mSettings); if (water) { + setting_clone = water->buildClone(); // LLViewerFetchedTexture and check for FTT_LOCAL_FILE or check LLLocalBitmapMgr if (LLLocalBitmapMgr::isLocal(water->getNormalMapID())) { @@ -412,6 +414,7 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data) LLSettingsSky::ptr_t sky = std::static_pointer_cast<LLSettingsSky>(mSettings); if (sky) { + setting_clone = sky->buildClone(); if (LLLocalBitmapMgr::isLocal(sky->getSunTextureId())) { local_desc = LLTrans::getString("EnvironmentSun"); @@ -445,19 +448,19 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data) if (ctrl_action == ACTION_SAVE) { - doApplyUpdateInventory(); + doApplyUpdateInventory(setting_clone); } else if (ctrl_action == ACTION_SAVEAS) { LLSD args; args["DESC"] = mSettings->getName(); - LLNotificationsUtil::add("SaveSettingAs", args, LLSD(), boost::bind(&LLFloaterFixedEnvironment::onSaveAsCommit, this, _1, _2)); + LLNotificationsUtil::add("SaveSettingAs", args, LLSD(), boost::bind(&LLFloaterFixedEnvironment::onSaveAsCommit, this, _1, _2, setting_clone)); } else if ((ctrl_action == ACTION_APPLY_LOCAL) || (ctrl_action == ACTION_APPLY_PARCEL) || (ctrl_action == ACTION_APPLY_REGION)) { - doApplyEnvironment(ctrl_action); + doApplyEnvironment(ctrl_action, setting_clone); } else { @@ -465,7 +468,7 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data) } } -void LLFloaterFixedEnvironment::onSaveAsCommit(const LLSD& notification, const LLSD& response) +void LLFloaterFixedEnvironment::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (0 == option) @@ -474,7 +477,7 @@ void LLFloaterFixedEnvironment::onSaveAsCommit(const LLSD& notification, const L LLStringUtil::trim(settings_name); if (mCanMod) { - doApplyCreateNewInventory(settings_name); + doApplyCreateNewInventory(settings_name, settings); } else if (mInventoryItem) { @@ -514,44 +517,44 @@ void LLFloaterFixedEnvironment::onButtonLoad() checkAndConfirmSettingsLoss([this](){ doSelectFromInventory(); }); } -void LLFloaterFixedEnvironment::doApplyCreateNewInventory(std::string settings_name) +void LLFloaterFixedEnvironment::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings) { if (mInventoryItem) { LLUUID parent_id = mInventoryItem->getParentUUID(); U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); - LLSettingsVOBase::createInventoryItem(mSettings, next_owner_perm, parent_id, settings_name, + LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name, [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); } else { LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); // This method knows what sort of settings object to create. - LLSettingsVOBase::createInventoryItem(mSettings, parent_id, settings_name, + LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name, [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); } } -void LLFloaterFixedEnvironment::doApplyUpdateInventory() +void LLFloaterFixedEnvironment::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings) { LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL; if (mInventoryId.isNull()) { - LLSettingsVOBase::createInventoryItem(mSettings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(), + LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(), [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); } else { - LLSettingsVOBase::updateInventoryItem(mSettings, mInventoryId, + LLSettingsVOBase::updateInventoryItem(settings, mInventoryId, [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); } } -void LLFloaterFixedEnvironment::doApplyEnvironment(const std::string &where) +void LLFloaterFixedEnvironment::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings) { if (where == ACTION_APPLY_LOCAL) { - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, mSettings); + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings); } else if (where == ACTION_APPLY_PARCEL) { @@ -568,13 +571,13 @@ void LLFloaterFixedEnvironment::doApplyEnvironment(const std::string &where) { LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1); } - else if (mSettings->getSettingsType() == "sky") + else if (settings->getSettingsType() == "sky") { - LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsSky>(mSettings), -1, -1); + LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsSky>(settings), -1, -1); } - else if (mSettings->getSettingsType() == "water") + else if (settings->getSettingsType() == "water") { - LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsWater>(mSettings), -1, -1); + LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsWater>(settings), -1, -1); } } else if (where == ACTION_APPLY_REGION) @@ -583,13 +586,13 @@ void LLFloaterFixedEnvironment::doApplyEnvironment(const std::string &where) { LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1); } - else if (mSettings->getSettingsType() == "sky") + else if (settings->getSettingsType() == "sky") { - LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsSky>(mSettings), -1, -1); + LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsSky>(settings), -1, -1); } - else if (mSettings->getSettingsType() == "water") + else if (settings->getSettingsType() == "water") { - LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsWater>(mSettings), -1, -1); + LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsWater>(settings), -1, -1); } } else diff --git a/indra/newview/llfloaterfixedenvironment.h b/indra/newview/llfloaterfixedenvironment.h index f694e59281..138f26cfd7 100644 --- a/indra/newview/llfloaterfixedenvironment.h +++ b/indra/newview/llfloaterfixedenvironment.h @@ -86,9 +86,9 @@ protected: LLSettingsBase::ptr_t mSettings; virtual void doImportFromDisk() = 0; - virtual void doApplyCreateNewInventory(std::string settings_name); - virtual void doApplyUpdateInventory(); - virtual void doApplyEnvironment(const std::string &where); + virtual void doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings); + virtual void doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings); + virtual void doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings); void doCloseInventoryFloater(bool quitting = false); bool canUseInventory() const; @@ -116,7 +116,7 @@ protected: void onPanelDirtyFlagChanged(bool); virtual void onClickCloseBtn(bool app_quitting = false) override; - void onSaveAsCommit(const LLSD& notification, const LLSD& response); + void onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings); private: void onNameChanged(const std::string &name); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index a181fdaf50..7e0f377953 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -207,10 +207,14 @@ void LLSkyTex::create(const F32 brightness) void LLSkyTex::createGLImage(S32 which) { - if (LLPipeline::RenderDeferred) { +#if USE_SRGB_DECODE + if (LLPipeline::RenderDeferred) + { mTexture[which]->setExplicitFormat(GL_SRGB8_ALPHA8, GL_RGBA); } - else { + else +#endif + { mTexture[which]->setExplicitFormat(GL_RGBA8, GL_RGBA); } mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 211993fb46..628e7ae2d7 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6215,7 +6215,16 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) mMoonDir.setVec(moon_dir); // calculates diffuse sunlight per-pixel downstream, just provide setting sunlight_color - mSunDiffuse.setVec(psky->getSunlightColor()); + if (canUseWindLightShaders()) + { + mSunDiffuse.setVec(psky->getSunlightColor()); + } + else + { + // not using atmo shaders, use CPU-generated attenuated sunlight diffuse... + mSunDiffuse.setVec(psky->getSunDiffuse()); + } + mMoonDiffuse.setVec(psky->getMoonDiffuse()); F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]); @@ -7551,7 +7560,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - mScreen.bindTexture(0, 0, LLTexUnit::TFO_BILINEAR); + mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT); gGL.color4f(1,1,1,1); gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); @@ -7784,7 +7793,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); if (channel > -1) { - mScreen.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + mScreen.bindTexture(0, channel); } shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f); @@ -7823,7 +7832,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); if (channel > -1) { - mDeferredLight.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + mDeferredLight.bindTexture(0, channel); } shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); @@ -7867,7 +7876,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); if (channel > -1) { - mScreen.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + mScreen.bindTexture(0, channel); } if (!LLViewerCamera::getInstance()->cameraUnderWater()) @@ -7915,7 +7924,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); if (channel > -1) { - mScreen.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + mScreen.bindTexture(0, channel); } if (!LLViewerCamera::getInstance()->cameraUnderWater()) @@ -7962,7 +7971,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); if (channel > -1) { - mDeferredLight.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + mDeferredLight.bindTexture(0, channel); } gGL.begin(LLRender::TRIANGLE_STRIP); @@ -8217,7 +8226,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ channel = shader.enableTexture(LLShaderMgr::DEFERRED_BLOOM); if (channel > -1) { - mGlow[1].bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + mGlow[1].bindTexture(0, channel); } stop_glerror(); @@ -10019,862 +10028,775 @@ static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_RENDER("Spot Shadow void LLPipeline::generateSunShadow(LLCamera& camera) { - if (!sRenderDeferred || RenderShadowDetail <= 0) - { - if (mNeedsShadowTargetClear) - { - LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); - - for (S32 j = 0; j < 6; j++) - { - LLRenderTarget* shadow_target = getShadowTarget(j); - if (shadow_target) - { - shadow_target->bindTarget(); - shadow_target->clear(); - shadow_target->flush(); - } - } - mNeedsShadowTargetClear = false; - } - - return; - } - - mNeedsShadowTargetClear = true; - - LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW); - - LLEnvironment& environment = LLEnvironment::instance(); - LLSettingsSky::ptr_t psky = environment.getCurrentSky(); - - bool skip_avatar_update = false; - if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) - { - skip_avatar_update = true; - } - - F64 last_modelview[16]; - F64 last_projection[16]; - for (U32 i = 0; i < 16; i++) - { //store last_modelview of world camera - last_modelview[i] = gGLLastModelView[i]; - last_projection[i] = gGLLastProjection[i]; - } - - pushRenderTypeMask(); - andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, - LLPipeline::RENDER_TYPE_ALPHA, - LLPipeline::RENDER_TYPE_GRASS, - LLPipeline::RENDER_TYPE_FULLBRIGHT, - LLPipeline::RENDER_TYPE_BUMP, - LLPipeline::RENDER_TYPE_VOLUME, - LLPipeline::RENDER_TYPE_AVATAR, - LLPipeline::RENDER_TYPE_TREE, - LLPipeline::RENDER_TYPE_TERRAIN, - LLPipeline::RENDER_TYPE_WATER, - LLPipeline::RENDER_TYPE_VOIDWATER, - LLPipeline::RENDER_TYPE_PASS_ALPHA, - LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_GRASS, - LLPipeline::RENDER_TYPE_PASS_SIMPLE, - LLPipeline::RENDER_TYPE_PASS_BUMP, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, - LLPipeline::RENDER_TYPE_PASS_SHINY, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, - LLPipeline::RENDER_TYPE_PASS_MATERIAL, - LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA, - LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE, - LLPipeline::RENDER_TYPE_PASS_SPECMAP, - LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND, - LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK, - LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE, - LLPipeline::RENDER_TYPE_PASS_NORMMAP, - LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND, - LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK, - LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE, - LLPipeline::RENDER_TYPE_PASS_NORMSPEC, - LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND, - LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK, - LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE, - END_RENDER_TYPES); - - S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); - - // if not using VSM, disable color writes - if (shadow_detail <= 2) - { - gGL.setColorMask(false, false); - } + if (!sRenderDeferred || RenderShadowDetail <= 0) + { + return; + } - bool sun_up = environment.getIsSunUp(); - bool moon_up = environment.getIsMoonUp(); + LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW); - bool ignore_shadows = (shadow_detail == 0); // explicitly disabled shadows + bool skip_avatar_update = false; + if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) + { - // no sun or moon, no shadows - if (!sun_up && !moon_up) - { - ignore_shadows |= true; - } - // only moon and moon is black - else if (!sun_up && moon_up & (mMoonDiffuse == LLColor4::black)) - { - ignore_shadows |= true; - } - // only sun and sun is black - else if (!moon_up && sun_up && (mSunDiffuse == LLColor4::black)) - { - ignore_shadows |= true; - } - // both up, but both black - else if ((mSunDiffuse == LLColor4::black) && (mMoonDiffuse == LLColor4::black)) - { - ignore_shadows |= true; - } + skip_avatar_update = true; + } - if (ignore_shadows) - { //sun diffuse is totally black, shadows don't matter - LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + if (!skip_avatar_update) + { + gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON); + } - for (S32 j = 0; j < 4; j++) - { - LLRenderTarget* shadow_target = getShadowTarget(j); - if (shadow_target) - { - shadow_target->bindTarget(); - shadow_target->clear(); - shadow_target->flush(); - } - } + F64 last_modelview[16]; + F64 last_projection[16]; + for (U32 i = 0; i < 16; i++) + { //store last_modelview of world camera + last_modelview[i] = gGLLastModelView[i]; + last_projection[i] = gGLLastProjection[i]; + } - if (shadow_detail == 0) - { - for (S32 j = 4; j < 6; j++) - { - LLRenderTarget* shadow_target = getShadowTarget(j); - if (shadow_target) - { - shadow_target->bindTarget(); - shadow_target->clear(); - shadow_target->flush(); - } - } - } - } + pushRenderTypeMask(); + andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, + LLPipeline::RENDER_TYPE_ALPHA, + LLPipeline::RENDER_TYPE_GRASS, + LLPipeline::RENDER_TYPE_FULLBRIGHT, + LLPipeline::RENDER_TYPE_BUMP, + LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_VOIDWATER, + LLPipeline::RENDER_TYPE_PASS_ALPHA, + LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_GRASS, + LLPipeline::RENDER_TYPE_PASS_SIMPLE, + LLPipeline::RENDER_TYPE_PASS_BUMP, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, + LLPipeline::RENDER_TYPE_PASS_SHINY, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, + LLPipeline::RENDER_TYPE_PASS_MATERIAL, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE, + LLPipeline::RENDER_TYPE_PASS_SPECMAP, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK, + LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE, + LLPipeline::RENDER_TYPE_PASS_NORMMAP, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK, + LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK, + LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE, + END_RENDER_TYPES); + + gGL.setColorMask(false, false); - //get sun view matrix - - //store current projection/modelview matrix - glh::matrix4f saved_proj = get_current_projection(); - glh::matrix4f saved_view = get_current_modelview(); - glh::matrix4f inv_view = saved_view.inverse(); + LLEnvironment& environment = LLEnvironment::instance(); - glh::matrix4f view[6]; - glh::matrix4f proj[6]; - - //clip contains parallel split distances for 3 splits - LLVector3 clip = RenderShadowClipPlanes; + //get sun view matrix + + //store current projection/modelview matrix + glh::matrix4f saved_proj = get_current_projection(); + glh::matrix4f saved_view = get_current_modelview(); + glh::matrix4f inv_view = saved_view.inverse(); - //F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold"); + glh::matrix4f view[6]; + glh::matrix4f proj[6]; + + //clip contains parallel split distances for 3 splits + LLVector3 clip = RenderShadowClipPlanes; - //far clip on last split is minimum of camera view distance and 128 - mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]); + LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir); - clip = RenderShadowOrthoClipPlanes; - mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]); + //F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold"); - //currently used for amount to extrude frusta corners for constructing shadow frusta - //LLVector3 n = RenderShadowNearDist; - //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; + //far clip on last split is minimum of camera view distance and 128 + mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]); - LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir); + clip = RenderShadowOrthoClipPlanes; + mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]); - //put together a universal "near clip" plane for shadow frusta - LLPlane shadow_near_clip; - { - LLVector3 p = gAgent.getPositionAgent(); - p += caster_dir * RenderFarClip*2.f; - shadow_near_clip.setVec(p, caster_dir); - } + //currently used for amount to extrude frusta corners for constructing shadow frusta + //LLVector3 n = RenderShadowNearDist; + //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; - LLVector3 lightDir = -caster_dir; - lightDir.normVec(); + //put together a universal "near clip" plane for shadow frusta + LLPlane shadow_near_clip; + { + LLVector3 p = gAgent.getPositionAgent(); + p += caster_dir * RenderFarClip*2.f; + shadow_near_clip.setVec(p, caster_dir); + } - glh::vec3f light_dir(lightDir.mV); + LLVector3 lightDir = -caster_dir; + lightDir.normVec(); - //create light space camera matrix - - LLVector3 at = lightDir; + glh::vec3f light_dir(lightDir.mV); - LLVector3 up = camera.getAtAxis(); + //create light space camera matrix + + LLVector3 at = lightDir; - if (fabsf(up*lightDir) > 0.75f) - { - up = camera.getUpAxis(); - } + LLVector3 up = camera.getAtAxis(); - /*LLVector3 left = up%at; - up = at%left;*/ + if (fabsf(up*lightDir) > 0.75f) + { + up = camera.getUpAxis(); + } - up.normVec(); - at.normVec(); - - LLCamera main_camera = camera; - - F32 near_clip = 0.f; - { - //get visible point cloud - std::vector<LLVector3> fp; + /*LLVector3 left = up%at; + up = at%left;*/ - main_camera.calcAgentFrustumPlanes(main_camera.mAgentFrustum); - - LLVector3 min,max; - getVisiblePointCloud(main_camera,min,max,fp); + up.normVec(); + at.normVec(); + + + LLCamera main_camera = camera; + + F32 near_clip = 0.f; + { + //get visible point cloud + std::vector<LLVector3> fp; - if (fp.empty()) - { - if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) - { - mShadowCamera[0] = main_camera; - mShadowExtents[0][0] = min; - mShadowExtents[0][1] = max; - - mShadowFrustPoints[0].clear(); - mShadowFrustPoints[1].clear(); - mShadowFrustPoints[2].clear(); - mShadowFrustPoints[3].clear(); - } - popRenderTypeMask(); + main_camera.calcAgentFrustumPlanes(main_camera.mAgentFrustum); + + LLVector3 min,max; + getVisiblePointCloud(main_camera,min,max,fp); - if (!skip_avatar_update) - { - gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); - } + if (fp.empty()) + { + if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowCamera[0] = main_camera; + mShadowExtents[0][0] = min; + mShadowExtents[0][1] = max; - return; - } + mShadowFrustPoints[0].clear(); + mShadowFrustPoints[1].clear(); + mShadowFrustPoints[2].clear(); + mShadowFrustPoints[3].clear(); + } + popRenderTypeMask(); - //get good split distances for frustum - for (U32 i = 0; i < fp.size(); ++i) - { - glh::vec3f v(fp[i].mV); - saved_view.mult_matrix_vec(v); - fp[i].setVec(v.v); - } + if (!skip_avatar_update) + { + gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); + } - min = fp[0]; - max = fp[0]; + return; + } - //get camera space bounding box - for (U32 i = 1; i < fp.size(); ++i) - { - update_min_max(min, max, fp[i]); - } + //get good split distances for frustum + for (U32 i = 0; i < fp.size(); ++i) + { + glh::vec3f v(fp[i].mV); + saved_view.mult_matrix_vec(v); + fp[i].setVec(v.v); + } - near_clip = -max.mV[2]; - F32 far_clip = -min.mV[2]*2.f; + min = fp[0]; + max = fp[0]; - //far_clip = llmin(far_clip, 128.f); - far_clip = llmin(far_clip, camera.getFar()); + //get camera space bounding box + for (U32 i = 1; i < fp.size(); ++i) + { + update_min_max(min, max, fp[i]); + } - F32 range = far_clip-near_clip; + near_clip = llclamp(-max.mV[2], 0.01f, 4.0f); + F32 far_clip = llclamp(-min.mV[2]*2.f, 16.0f, 512.0f); - LLVector3 split_exp = RenderShadowSplitExponent; + //far_clip = llmin(far_clip, 128.f); + far_clip = llmin(far_clip, camera.getFar()); - F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) ); - - da = powf(da, split_exp.mV[2]); + F32 range = far_clip-near_clip; - F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da; - - for (U32 i = 0; i < 4; ++i) - { - F32 x = (F32)(i+1)/4.f; - x = powf(x, sxp); - mSunClipPlanes.mV[i] = near_clip+range*x; - } + LLVector3 split_exp = RenderShadowSplitExponent; - mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding - } + F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) ); + + da = powf(da, split_exp.mV[2]); - // convenience array of 4 near clip plane distances - F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; + F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da; + + for (U32 i = 0; i < 4; ++i) + { + F32 x = (F32)(i+1)/4.f; + x = powf(x, sxp); + mSunClipPlanes.mV[i] = near_clip+range*x; + } - if (!ignore_shadows) - { - for (S32 j = 0; j < 4; j++) - { - LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW_SETUP); + mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding + } - if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) - { - mShadowFrustPoints[j].clear(); - } + // convenience array of 4 near clip plane distances + F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; + - LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j); + if (mSunDiffuse == LLColor4::black) + { //sun diffuse is totally black, shadows don't matter + LLGLDepthTest depth(GL_TRUE); - //restore render matrices - set_current_modelview(saved_view); - set_current_projection(saved_proj); + for (S32 j = 0; j < 4; j++) + { + mShadow[j].bindTarget(); + mShadow[j].clear(); + mShadow[j].flush(); + } + } + else + { + for (S32 j = 0; j < 4; j++) + { + if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowFrustPoints[j].clear(); + } - LLVector3 eye = camera.getOrigin(); + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j); - //camera used for shadow cull/render - LLCamera shadow_cam; - - //create world space camera frustum for this split - shadow_cam = camera; - shadow_cam.setFar(16.f); - - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + //restore render matrices + set_current_modelview(saved_view); + set_current_projection(saved_proj); - LLVector3* frust = shadow_cam.mAgentFrustum; + LLVector3 eye = camera.getOrigin(); - LLVector3 pn = shadow_cam.getAtAxis(); - - LLVector3 min, max; + //camera used for shadow cull/render + LLCamera shadow_cam; + + //create world space camera frustum for this split + shadow_cam = camera; + shadow_cam.setFar(16.f); + + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - //construct 8 corners of split frustum section - for (U32 i = 0; i < 4; i++) - { - LLVector3 delta = frust[i+4]-eye; - delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f; - delta.normVec(); - F32 dp = delta*pn; - frust[i] = eye + (delta*dist[j]*0.75f)/dp; - frust[i+4] = eye + (delta*dist[j+1]*1.25f)/dp; - } - - shadow_cam.calcAgentFrustumPlanes(frust); - shadow_cam.mFrustumCornerDist = 0.f; - - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - mShadowCamera[j] = shadow_cam; - } + LLVector3* frust = shadow_cam.mAgentFrustum; - std::vector<LLVector3> fp; + LLVector3 pn = shadow_cam.getAtAxis(); + + LLVector3 min, max; - if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)) - { - //no possible shadow receivers - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - mShadowExtents[j][0] = LLVector3(); - mShadowExtents[j][1] = LLVector3(); - mShadowCamera[j+4] = shadow_cam; - } + //construct 8 corners of split frustum section + for (U32 i = 0; i < 4; i++) + { + LLVector3 delta = frust[i+4]-eye; + delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f; + delta.normVec(); + F32 dp = delta*pn; + frust[i] = eye + (delta*dist[j]*0.75f)/dp; + frust[i+4] = eye + (delta*dist[j+1]*1.25f)/dp; + } + + shadow_cam.calcAgentFrustumPlanes(frust); + shadow_cam.mFrustumCornerDist = 0.f; + + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowCamera[j] = shadow_cam; + } - LLRenderTarget* shadow_target = getShadowTarget(j); - if (shadow_target) - { - shadow_target->bindTarget(); - { - LLGLDepthTest depth(GL_TRUE); - shadow_target->clear(); - } - shadow_target->flush(); - } + std::vector<LLVector3> fp; - mShadowError.mV[j] = 0.f; - mShadowFOV.mV[j] = 0.f; + if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)) + { + //no possible shadow receivers + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowExtents[j][0] = LLVector3(); + mShadowExtents[j][1] = LLVector3(); + mShadowCamera[j+4] = shadow_cam; + } - continue; - } + mShadow[j].bindTarget(); + { + LLGLDepthTest depth(GL_TRUE); + mShadow[j].clear(); + } + mShadow[j].flush(); - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - mShadowExtents[j][0] = min; - mShadowExtents[j][1] = max; - mShadowFrustPoints[j] = fp; - } - + mShadowError.mV[j] = 0.f; + mShadowFOV.mV[j] = 0.f; - //find a good origin for shadow projection - LLVector3 origin; + continue; + } - //get a temporary view projection - view[j] = look(camera.getOrigin(), lightDir, -up); + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowExtents[j][0] = min; + mShadowExtents[j][1] = max; + mShadowFrustPoints[j] = fp; + } + - std::vector<LLVector3> wpf; + //find a good origin for shadow projection + LLVector3 origin; - for (U32 i = 0; i < fp.size(); i++) - { - glh::vec3f p = glh::vec3f(fp[i].mV); - view[j].mult_matrix_vec(p); - wpf.push_back(LLVector3(p.v)); - } + //get a temporary view projection + view[j] = look(camera.getOrigin(), lightDir, -up); - min = wpf[0]; - max = wpf[0]; + std::vector<LLVector3> wpf; - for (U32 i = 0; i < fp.size(); ++i) - { //get AABB in camera space - update_min_max(min, max, wpf[i]); - } + for (U32 i = 0; i < fp.size(); i++) + { + glh::vec3f p = glh::vec3f(fp[i].mV); + view[j].mult_matrix_vec(p); + wpf.push_back(LLVector3(p.v)); + } - // Construct a perspective transform with perspective along y-axis that contains - // points in wpf - //Known: - // - far clip plane - // - near clip plane - // - points in frustum - //Find: - // - origin - - //get some "interesting" points of reference - LLVector3 center = (min+max)*0.5f; - LLVector3 size = (max-min)*0.5f; - LLVector3 near_center = center; - near_center.mV[1] += size.mV[1]*2.f; - - - //put all points in wpf in quadrant 0, reletive to center of min/max - //get the best fit line using least squares - F32 bfm = 0.f; - F32 bfb = 0.f; + min = wpf[0]; + max = wpf[0]; - for (U32 i = 0; i < wpf.size(); ++i) - { - wpf[i] -= center; - wpf[i].mV[0] = fabsf(wpf[i].mV[0]); - wpf[i].mV[2] = fabsf(wpf[i].mV[2]); - } + for (U32 i = 0; i < fp.size(); ++i) + { //get AABB in camera space + update_min_max(min, max, wpf[i]); + } - if (!wpf.empty()) - { - F32 sx = 0.f; - F32 sx2 = 0.f; - F32 sy = 0.f; - F32 sxy = 0.f; - - for (U32 i = 0; i < wpf.size(); ++i) - { - sx += wpf[i].mV[0]; - sx2 += wpf[i].mV[0]*wpf[i].mV[0]; - sy += wpf[i].mV[1]; - sxy += wpf[i].mV[0]*wpf[i].mV[1]; - } + // Construct a perspective transform with perspective along y-axis that contains + // points in wpf + //Known: + // - far clip plane + // - near clip plane + // - points in frustum + //Find: + // - origin - bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2); - bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2); - } - - { - // best fit line is y=bfm*x+bfb - - //find point that is furthest to the right of line - F32 off_x = -1.f; - LLVector3 lp; + //get some "interesting" points of reference + LLVector3 center = (min+max)*0.5f; + LLVector3 size = (max-min)*0.5f; + LLVector3 near_center = center; + near_center.mV[1] += size.mV[1]*2.f; + + + //put all points in wpf in quadrant 0, reletive to center of min/max + //get the best fit line using least squares + F32 bfm = 0.f; + F32 bfb = 0.f; - for (U32 i = 0; i < wpf.size(); ++i) - { - //y = bfm*x+bfb - //x = (y-bfb)/bfm - F32 lx = (wpf[i].mV[1]-bfb)/bfm; + for (U32 i = 0; i < wpf.size(); ++i) + { + wpf[i] -= center; + wpf[i].mV[0] = fabsf(wpf[i].mV[0]); + wpf[i].mV[2] = fabsf(wpf[i].mV[2]); + } - lx = wpf[i].mV[0]-lx; - - if (off_x < lx) - { - off_x = lx; - lp = wpf[i]; - } - } + if (!wpf.empty()) + { + F32 sx = 0.f; + F32 sx2 = 0.f; + F32 sy = 0.f; + F32 sxy = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + sx += wpf[i].mV[0]; + sx2 += wpf[i].mV[0]*wpf[i].mV[0]; + sy += wpf[i].mV[1]; + sxy += wpf[i].mV[0]*wpf[i].mV[1]; + } - //get line with slope bfm through lp - // bfb = y-bfm*x - bfb = lp.mV[1]-bfm*lp.mV[0]; + bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2); + bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2); + } + + { + // best fit line is y=bfm*x+bfb + + //find point that is furthest to the right of line + F32 off_x = -1.f; + LLVector3 lp; - //calculate error - mShadowError.mV[j] = 0.f; + for (U32 i = 0; i < wpf.size(); ++i) + { + //y = bfm*x+bfb + //x = (y-bfb)/bfm + F32 lx = (wpf[i].mV[1]-bfb)/bfm; - for (U32 i = 0; i < wpf.size(); ++i) - { - F32 lx = (wpf[i].mV[1]-bfb)/bfm; - mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx); - } + lx = wpf[i].mV[0]-lx; + + if (off_x < lx) + { + off_x = lx; + lp = wpf[i]; + } + } - mShadowError.mV[j] /= wpf.size(); - mShadowError.mV[j] /= size.mV[0]; + //get line with slope bfm through lp + // bfb = y-bfm*x + bfb = lp.mV[1]-bfm*lp.mV[0]; - if (mShadowError.mV[j] > RenderShadowErrorCutoff) - { //just use ortho projection - mShadowFOV.mV[j] = -1.f; - origin.clearVec(); - proj[j] = gl_ortho(min.mV[0], max.mV[0], - min.mV[1], max.mV[1], - -max.mV[2], -min.mV[2]); - } - else - { - //origin is where line x = 0; - origin.setVec(0,bfb,0); + //calculate error + mShadowError.mV[j] = 0.f; - F32 fovz = 1.f; - F32 fovx = 1.f; - - LLVector3 zp; - LLVector3 xp; + for (U32 i = 0; i < wpf.size(); ++i) + { + F32 lx = (wpf[i].mV[1]-bfb)/bfm; + mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx); + } - for (U32 i = 0; i < wpf.size(); ++i) - { - LLVector3 atz = wpf[i]-origin; - atz.mV[0] = 0.f; - atz.normVec(); - if (fovz > -atz.mV[1]) - { - zp = wpf[i]; - fovz = -atz.mV[1]; - } - - LLVector3 atx = wpf[i]-origin; - atx.mV[2] = 0.f; - atx.normVec(); - if (fovx > -atx.mV[1]) - { - fovx = -atx.mV[1]; - xp = wpf[i]; - } - } + mShadowError.mV[j] /= wpf.size(); + mShadowError.mV[j] /= size.mV[0]; - fovx = acos(fovx); - fovz = acos(fovz); + if (mShadowError.mV[j] > RenderShadowErrorCutoff) + { //just use ortho projection + mShadowFOV.mV[j] = -1.f; + origin.clearVec(); + proj[j] = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + } + else + { + //origin is where line x = 0; + origin.setVec(0,bfb,0); - F32 cutoff = llmin((F32) RenderShadowFOVCutoff, 1.4f); - - mShadowFOV.mV[j] = fovx; - - if (fovx < cutoff && fovz > cutoff) - { - //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff - F32 d = zp.mV[2]/tan(cutoff); - F32 ny = zp.mV[1] + fabsf(d); + F32 fovz = 1.f; + F32 fovx = 1.f; + + LLVector3 zp; + LLVector3 xp; - origin.mV[1] = ny; + for (U32 i = 0; i < wpf.size(); ++i) + { + LLVector3 atz = wpf[i]-origin; + atz.mV[0] = 0.f; + atz.normVec(); + if (fovz > -atz.mV[1]) + { + zp = wpf[i]; + fovz = -atz.mV[1]; + } + + LLVector3 atx = wpf[i]-origin; + atx.mV[2] = 0.f; + atx.normVec(); + if (fovx > -atx.mV[1]) + { + fovx = -atx.mV[1]; + xp = wpf[i]; + } + } - fovz = 1.f; - fovx = 1.f; + fovx = acos(fovx); + fovz = acos(fovz); - for (U32 i = 0; i < wpf.size(); ++i) - { - LLVector3 atz = wpf[i]-origin; - atz.mV[0] = 0.f; - atz.normVec(); - fovz = llmin(fovz, -atz.mV[1]); - - LLVector3 atx = wpf[i]-origin; - atx.mV[2] = 0.f; - atx.normVec(); - fovx = llmin(fovx, -atx.mV[1]); - } + F32 cutoff = llmin((F32) RenderShadowFOVCutoff, 1.4f); + + mShadowFOV.mV[j] = fovx; + + if (fovx < cutoff && fovz > cutoff) + { + //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff + F32 d = zp.mV[2]/tan(cutoff); + F32 ny = zp.mV[1] + fabsf(d); - fovx = acos(fovx); - fovz = acos(fovz); + origin.mV[1] = ny; - mShadowFOV.mV[j] = cutoff; - } + fovz = 1.f; + fovx = 1.f; - - origin += center; - - F32 ynear = -(max.mV[1]-origin.mV[1]); - F32 yfar = -(min.mV[1]-origin.mV[1]); - - if (ynear < 0.1f) //keep a sensible near clip plane - { - F32 diff = 0.1f-ynear; - origin.mV[1] += diff; - ynear += diff; - yfar += diff; - } - - if (fovx > cutoff) - { //just use ortho projection - origin.clearVec(); - mShadowError.mV[j] = -1.f; - proj[j] = gl_ortho(min.mV[0], max.mV[0], - min.mV[1], max.mV[1], - -max.mV[2], -min.mV[2]); - } - else - { - //get perspective projection - view[j] = view[j].inverse(); + for (U32 i = 0; i < wpf.size(); ++i) + { + LLVector3 atz = wpf[i]-origin; + atz.mV[0] = 0.f; + atz.normVec(); + fovz = llmin(fovz, -atz.mV[1]); + + LLVector3 atx = wpf[i]-origin; + atx.mV[2] = 0.f; + atx.normVec(); + fovx = llmin(fovx, -atx.mV[1]); + } - glh::vec3f origin_agent(origin.mV); - - //translate view to origin - view[j].mult_matrix_vec(origin_agent); + fovx = acos(fovx); + fovz = acos(fovz); - eye = LLVector3(origin_agent.v); + mShadowFOV.mV[j] = cutoff; + } - if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - mShadowFrustOrigin[j] = eye; - } - - view[j] = look(LLVector3(origin_agent.v), lightDir, -up); + + origin += center; + + F32 ynear = -(max.mV[1]-origin.mV[1]); + F32 yfar = -(min.mV[1]-origin.mV[1]); + + if (ynear < 0.1f) //keep a sensible near clip plane + { + F32 diff = 0.1f-ynear; + origin.mV[1] += diff; + ynear += diff; + yfar += diff; + } + + if (fovx > cutoff) + { //just use ortho projection + origin.clearVec(); + mShadowError.mV[j] = -1.f; + proj[j] = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + } + else + { + //get perspective projection + view[j] = view[j].inverse(); - F32 fx = 1.f/tanf(fovx); - F32 fz = 1.f/tanf(fovz); + glh::vec3f origin_agent(origin.mV); + + //translate view to origin + view[j].mult_matrix_vec(origin_agent); - proj[j] = glh::matrix4f(-fx, 0, 0, 0, - 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar), - 0, 0, -fz, 0, - 0, -1.f, 0, 0); - } - } - } + eye = LLVector3(origin_agent.v); - //shadow_cam.setFar(128.f); - shadow_cam.setOriginAndLookAt(eye, up, center); + if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowFrustOrigin[j] = eye; + } + + view[j] = look(LLVector3(origin_agent.v), lightDir, -up); - shadow_cam.setOrigin(0,0,0); + F32 fx = 1.f/tanf(fovx); + F32 fz = 1.f/tanf(fovz); - set_current_modelview(view[j]); - set_current_projection(proj[j]); + proj[j] = glh::matrix4f(-fx, 0, 0, 0, + 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar), + 0, 0, -fz, 0, + 0, -1.f, 0, 0); + } + } + } - shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); - shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip); + //shadow_cam.setFar(128.f); + shadow_cam.setOriginAndLookAt(eye, up, center); - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + shadow_cam.setOrigin(0,0,0); - //translate and scale to from [-1, 1] to [0, 1] - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); + set_current_modelview(view[j]); + set_current_projection(proj[j]); - set_current_modelview(view[j]); - set_current_projection(proj[j]); + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - for (U32 i = 0; i < 16; i++) - { - gGLLastModelView[i] = mShadowModelview[j].m[i]; - gGLLastProjection[i] = mShadowProjection[j].m[i]; - } + //shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); + shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip); - mShadowModelview[j] = view[j]; - mShadowProjection[j] = proj[j]; + //translate and scale to from [-1, 1] to [0, 1] + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); - - mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; - - stop_glerror(); + set_current_modelview(view[j]); + set_current_projection(proj[j]); - LLRenderTarget* shadow_target = getShadowTarget(j); + for (U32 i = 0; i < 16; i++) + { + gGLLastModelView[i] = mShadowModelview[j].m[i]; + gGLLastProjection[i] = mShadowProjection[j].m[i]; + } - if (shadow_target) - { - shadow_target->bindTarget(); - shadow_target->getViewport(gGLViewport); - shadow_target->clear(); + mShadowModelview[j] = view[j]; + mShadowProjection[j] = proj[j]; + mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; + + stop_glerror(); - U32 target_width = shadow_target->getWidth(); + mShadow[j].bindTarget(); + mShadow[j].getViewport(gGLViewport); + mShadow[j].clear(); + + U32 target_width = mShadow[j].getWidth(); - { - LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW_RENDER_DIRECTIONAL); + { + static LLCullResult result[4]; + renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, FALSE, target_width); + } - static LLCullResult result[4]; - renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width); - } + mShadow[j].flush(); + + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowCamera[j+4] = shadow_cam; + } + } + } - shadow_target->flush(); - } + + //hack to disable projector shadows + bool gen_shadow = RenderShadowDetail > 1; - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - mShadowCamera[j+4] = shadow_cam; - } - } - } + if (gen_shadow) + { + LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); + F32 fade_amt = gFrameIntervalSeconds.value() + * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0); - - //hack to disable projector shadows - bool gen_shadow = RenderShadowDetail > 1; + //update shadow targets + for (U32 i = 0; i < 2; i++) + { //for each current shadow + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i); - if (gen_shadow) - { - LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW_SPOT_SETUP); - - LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); - F32 fade_amt = gFrameIntervalSeconds.value() - * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0); - - //update shadow targets - for (U32 i = 0; i < 2; i++) - { //for each current shadow - LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i); - - if (mShadowSpotLight[i].notNull() && - (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || - mShadowSpotLight[i] == mTargetShadowSpotLight[1])) - { //keep this spotlight - mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); - } - else - { //fade out this light - mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); - - if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) - { //faded out, grab one of the pending spots (whichever one isn't already taken) - if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) - { - mShadowSpotLight[i] = mTargetShadowSpotLight[0]; - } - else - { - mShadowSpotLight[i] = mTargetShadowSpotLight[1]; - } - } - } - } + if (mShadowSpotLight[i].notNull() && + (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || + mShadowSpotLight[i] == mTargetShadowSpotLight[1])) + { //keep this spotlight + mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); + } + else + { //fade out this light + mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); + + if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) + { //faded out, grab one of the pending spots (whichever one isn't already taken) + if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) + { + mShadowSpotLight[i] = mTargetShadowSpotLight[0]; + } + else + { + mShadowSpotLight[i] = mTargetShadowSpotLight[1]; + } + } + } + } - for (S32 i = 0; i < 2; i++) - { - set_current_modelview(saved_view); - set_current_projection(saved_proj); + for (S32 i = 0; i < 2; i++) + { + set_current_modelview(saved_view); + set_current_projection(saved_proj); - if (mShadowSpotLight[i].isNull()) - { - continue; - } + if (mShadowSpotLight[i].isNull()) + { + continue; + } - LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); + LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); - if (!volume) - { - mShadowSpotLight[i] = NULL; - continue; - } + if (!volume) + { + mShadowSpotLight[i] = NULL; + continue; + } - LLDrawable* drawable = mShadowSpotLight[i]; + LLDrawable* drawable = mShadowSpotLight[i]; - LLVector3 params = volume->getSpotLightParams(); - F32 fov = params.mV[0]; + LLVector3 params = volume->getSpotLightParams(); + F32 fov = params.mV[0]; - //get agent->light space matrix (modelview) - LLVector3 center = drawable->getPositionAgent(); - LLQuaternion quat = volume->getRenderRotation(); + //get agent->light space matrix (modelview) + LLVector3 center = drawable->getPositionAgent(); + LLQuaternion quat = volume->getRenderRotation(); - //get near clip plane - LLVector3 scale = volume->getScale(); - LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); - at_axis *= quat; + //get near clip plane + LLVector3 scale = volume->getScale(); + LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); + at_axis *= quat; - LLVector3 np = center+at_axis; - at_axis.normVec(); + LLVector3 np = center+at_axis; + at_axis.normVec(); - //get origin that has given fov for plane np, at_axis, and given scale - F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); + //get origin that has given fov for plane np, at_axis, and given scale + F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); - LLVector3 origin = np - at_axis*dist; + LLVector3 origin = np - at_axis*dist; - LLMatrix4 mat(quat, LLVector4(origin, 1.f)); + LLMatrix4 mat(quat, LLVector4(origin, 1.f)); - view[i+4] = glh::matrix4f((F32*) mat.mMatrix); + view[i+4] = glh::matrix4f((F32*) mat.mMatrix); - view[i+4] = view[i+4].inverse(); + view[i+4] = view[i+4].inverse(); - //get perspective matrix - F32 near_clip = dist+0.01f; - F32 width = scale.mV[VX]; - F32 height = scale.mV[VY]; - F32 far_clip = dist+volume->getLightRadius()*1.5f; + //get perspective matrix + F32 near_clip = dist+0.01f; + F32 width = scale.mV[VX]; + F32 height = scale.mV[VY]; + F32 far_clip = dist+volume->getLightRadius()*1.5f; - F32 fovy = fov * RAD_TO_DEG; - F32 aspect = width/height; - - proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width/height; + + proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); - //translate and scale to from [-1, 1] to [0, 1] - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); + //translate and scale to from [-1, 1] to [0, 1] + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); - set_current_modelview(view[i+4]); - set_current_projection(proj[i+4]); + set_current_modelview(view[i+4]); + set_current_projection(proj[i+4]); - mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; - - for (U32 j = 0; j < 16; j++) - { - gGLLastModelView[j] = mShadowModelview[i+4].m[j]; - gGLLastProjection[j] = mShadowProjection[i+4].m[j]; - } + mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; + + for (U32 j = 0; j < 16; j++) + { + gGLLastModelView[j] = mShadowModelview[i+4].m[j]; + gGLLastProjection[j] = mShadowProjection[i+4].m[j]; + } - mShadowModelview[i+4] = view[i+4]; - mShadowProjection[i+4] = proj[i+4]; + mShadowModelview[i+4] = view[i+4]; + mShadowProjection[i+4] = proj[i+4]; - LLCamera shadow_cam = camera; - shadow_cam.setFar(far_clip); - shadow_cam.setOrigin(origin); + LLCamera shadow_cam = camera; + shadow_cam.setFar(far_clip); + shadow_cam.setOrigin(origin); - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - stop_glerror(); + stop_glerror(); - LLRenderTarget* shadow_target = getShadowTarget(i + 4); + mShadow[i+4].bindTarget(); + mShadow[i+4].getViewport(gGLViewport); + mShadow[i+4].clear(); - if (shadow_target) - { - LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW_SPOT_RENDER); + U32 target_width = mShadow[i+4].getWidth(); - shadow_target->bindTarget(); - shadow_target->getViewport(gGLViewport); - shadow_target->clear(); - - U32 target_width = shadow_target->getWidth(); + static LLCullResult result[2]; - static LLCullResult result[2]; - LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4); + LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4); - renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width); + renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width); - shadow_target->flush(); - } - } - } - else - { //no spotlight shadows - mShadowSpotLight[0] = mShadowSpotLight[1] = NULL; - } + mShadow[i+4].flush(); + } + } + else + { //no spotlight shadows + mShadowSpotLight[0] = mShadowSpotLight[1] = NULL; + } - if (!CameraOffset) - { - set_current_modelview(saved_view); - set_current_projection(saved_proj); - } - else - { - set_current_modelview(view[1]); - set_current_projection(proj[1]); - gGL.loadMatrix(view[1].m); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.loadMatrix(proj[1].m); - gGL.matrixMode(LLRender::MM_MODELVIEW); - } - gGL.setColorMask(true, false); + if (!CameraOffset) + { + set_current_modelview(saved_view); + set_current_projection(saved_proj); + } + else + { + set_current_modelview(view[1]); + set_current_projection(proj[1]); + gGL.loadMatrix(view[1].m); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.loadMatrix(proj[1].m); + gGL.matrixMode(LLRender::MM_MODELVIEW); + } + gGL.setColorMask(true, false); - for (U32 i = 0; i < 16; i++) - { - gGLLastModelView[i] = last_modelview[i]; - gGLLastProjection[i] = last_projection[i]; - } + for (U32 i = 0; i < 16; i++) + { + gGLLastModelView[i] = last_modelview[i]; + gGLLastProjection[i] = last_projection[i]; + } - popRenderTypeMask(); + popRenderTypeMask(); - if (!skip_avatar_update) - { - gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); - } + if (!skip_avatar_update) + { + gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); + } } void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture) diff --git a/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml index 348c0ce195..dbf91b0834 100644 --- a/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml +++ b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml @@ -44,7 +44,7 @@ width="250" name="settings_name" prevalidate_callback="ascii" - max_length_chars="32" + max_length_chars="63" height="20"/> <button height="23" |