From 99b82d944937ce321f64aa91fb18ab2aedd3992a Mon Sep 17 00:00:00 2001 From: "Graham Linden graham@lindenlab.com" Date: Sun, 18 Feb 2018 15:52:23 +0000 Subject: Atmospherics WIP libatmosphere integrated in indra/llrender/llatmosphere.cpp Still working on runtime shaders to use libatmosphere precomputed atmospherics textures --- indra/cmake/LLRender.cmake | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/cmake') diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake index 868922451f..0940d1de63 100644 --- a/indra/cmake/LLRender.cmake +++ b/indra/cmake/LLRender.cmake @@ -3,6 +3,7 @@ include(Variables) include(FreeType) include(GLH) +include(Atmosphere) set(LLRENDER_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llrender -- cgit v1.3 From 6cc4a091b3ba4dd4842cc06e3b34af3d04dc5796 Mon Sep 17 00:00:00 2001 From: "Graham Linden graham@lindenlab.com" Date: Thu, 22 Feb 2018 00:35:24 +0000 Subject: Add settings/validations for new advanced atmo settings. --- autobuild.xml | 30 ++-- indra/cmake/Atmosphere.cmake | 5 + indra/llinventory/llsettingsbase.cpp | 2 +- indra/llinventory/llsettingsbase.h | 1 + indra/llinventory/llsettingssky.cpp | 287 +++++++++++++++++++++++++++++++- indra/llinventory/llsettingssky.h | 30 +++- indra/llrender/CMakeLists.txt | 7 +- indra/llrender/llatmosphere.cpp | 218 ++++++++++++++++++++++++ indra/llrender/llatmosphere.h | 72 ++++++++ indra/llrender/llgltexture.h | 2 +- indra/newview/app_settings/settings.xml | 2 +- indra/newview/lldrawpoolwlsky.cpp | 2 +- indra/newview/llsettingsvo.cpp | 1 + indra/newview/llviewershadermgr.cpp | 6 +- indra/newview/llviewertexture.cpp | 4 +- indra/newview/pipeline.cpp | 2 +- 16 files changed, 636 insertions(+), 35 deletions(-) create mode 100644 indra/cmake/Atmosphere.cmake create mode 100644 indra/llrender/llatmosphere.cpp create mode 100644 indra/llrender/llatmosphere.h (limited to 'indra/cmake') diff --git a/autobuild.xml b/autobuild.xml index 7652b95d96..d387dfba72 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -64,16 +64,16 @@ archive hash - 1df4dcf1581c3a7eae267d100ddd4b3b + b6fa628aafcdd006d17e799825fbeb91 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/100/1371370/libatmosphere-1.0.0-100-windows64-133713370.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/13879/86217/libatmosphere-1.0.0.100-windows64-512753.tar.bz2 name windows64 version - 1.4.5.504800 + 1.0.0.512753 apr_suite @@ -1724,9 +1724,9 @@ archive hash - 1463e6a7c6aa65bc65292bd7e48c107e + 7b769c4284bdbd5fce536395d1eab695 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/13675/84961/kdu-7.A.3.512635-darwin-512635.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4054/11304/kdu-7.9.1.504041-darwin-504041.tar.bz2 name darwin @@ -1736,9 +1736,9 @@ archive hash - d3ef7a02b7b765355096ba66085433be + a48db5cf79a4631090bfc968572d9953 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/13674/84957/kdu-7.A.3.512635-darwin64-512635.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4052/11292/kdu-7.9.1.504041-darwin64-504041.tar.bz2 name darwin64 @@ -1748,9 +1748,9 @@ archive hash - 78c94809fe2c4ce9323cb2d4a0d1b105 + ed952c0cb86329e63a8db190953962d8 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/13672/84968/kdu-7.A.3.512635-linux-512635.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/kdu_3p-update-kdu/rev/296932/arch/Linux/installer/kdu-7.2.296932-linux-296932.tar.bz2 name linux @@ -1760,9 +1760,9 @@ archive hash - 87f9381c1da1148985a9f5ef3e09aeba + 99b0b22f87cebdd02c4cc954a7b3b465 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/13673/84974/kdu-7.A.3.512635-linux64-512635.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4053/11298/kdu-7.9.1.504041-linux64-504041.tar.bz2 name linux64 @@ -1772,9 +1772,9 @@ archive hash - e570aaf7e77dec7538f68d1bcfbc5abe + f3ff5982b3b5f02738044432dd77a2c1 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/13677/84986/kdu-7.A.3.512635-windows-512635.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4055/11310/kdu-7.9.1.504041-windows-504041.tar.bz2 name windows @@ -1784,9 +1784,9 @@ archive hash - f8ed3aaf6b3f840a5bf2819e5e931cac + 3010fa35f412b36296342b07de06f1ca url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/13676/84980/kdu-7.A.3.512635-windows64-512635.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4056/11316/kdu-7.9.1.504041-windows64-504041.tar.bz2 name windows64 diff --git a/indra/cmake/Atmosphere.cmake b/indra/cmake/Atmosphere.cmake new file mode 100644 index 0000000000..0975e3df02 --- /dev/null +++ b/indra/cmake/Atmosphere.cmake @@ -0,0 +1,5 @@ +# -*- cmake -*- +include(Prebuilt) +use_prebuilt_binary(libatmosphere) +set(LIBATMOSPHERE_LIBRARIES libatmosphere) +set(LIBATMOSPHERE_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/atmosphere) diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index 7ade345168..0918252fa0 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -333,7 +333,7 @@ LLSD LLSettingsBase::settingValidation(LLSD &settings, validation_list_t &valida { std::stringstream errtext; - errtext << "Settings LLSD fails validation and could not be corrected for '" << test.getName() << "'!"; + errtext << "Settings LLSD fails validation and could not be corrected for '" << test.getName() << "'!\n"; errors.append( errtext.str() ); isValid = false; } diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h index 420bcb9943..4273e1d3a0 100644 --- a/indra/llinventory/llsettingsbase.h +++ b/indra/llinventory/llsettingsbase.h @@ -191,6 +191,7 @@ public: typedef std::vector validation_list_t; static LLSD settingValidation(LLSD &settings, validation_list_t &validations); + protected: LLSettingsBase(); diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 572b5703b3..ff3f5224dd 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -79,12 +79,28 @@ const std::string LLSettingsSky::SETTING_MOON_TEXTUREID("moon_id"); const std::string LLSettingsSky::SETTING_STAR_BRIGHTNESS("star_brightness"); const std::string LLSettingsSky::SETTING_SUNLIGHT_COLOR("sunlight_color"); const std::string LLSettingsSky::SETTING_SUN_ROTATION("sun_rotation"); -const std::string LLSettingsSky::SETTING_SUN_TEXUTUREID("sun_id"); +const std::string LLSettingsSky::SETTING_SUN_TEXTUREID("sun_id"); const std::string LLSettingsSky::SETTING_LEGACY_EAST_ANGLE("east_angle"); const std::string LLSettingsSky::SETTING_LEGACY_ENABLE_CLOUD_SCROLL("enable_cloud_scroll"); const std::string LLSettingsSky::SETTING_LEGACY_SUN_ANGLE("sun_angle"); +// these are new settings for the advanced atmospherics model +const std::string LLSettingsSky::SETTING_PLANET_RADIUS("planet_radius"); +const std::string LLSettingsSky::SETTING_SKY_BOTTOM_RADIUS("sky_bottom_radius"); +const std::string LLSettingsSky::SETTING_SKY_TOP_RADIUS("sky_top_radius"); +const std::string LLSettingsSky::SETTING_RAYLEIGH_CONFIG("rayleigh"); +const std::string LLSettingsSky::SETTING_MIE_CONFIG("mie"); +const std::string LLSettingsSky::SETTING_ABSORPTION_CONFIG("absorption"); +const std::string LLSettingsSky::KEY_DENSITY_PROFILE("density"); +const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH("width"); +const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM("exp_term"); +const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR("exp_scale"); +const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM("linear_term"); +const std::string LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM("constant_term"); +const std::string LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR("anisotropy"); +const std::string LLSettingsSky::SETTING_SUN_ARC_RADIANS("sun_arc_radians"); + //========================================================================= LLSettingsSky::LLSettingsSky(const LLSD &data) : LLSettingsBase(data) @@ -144,6 +160,78 @@ LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const return slepSet; } +LLSettingsSky::validation_list_t LLSettingsSky::rayleighValidationList() +{ + static validation_list_t rayleighValidation; + if (rayleighValidation.empty()) + { + rayleighValidation.push_back(Validator(SETTING_DENSITY_PROFILE_WIDTH, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(32768.0f))))); + + rayleighValidation.push_back(Validator(SETTING_DENSITY_PROFILE_EXP_TERM, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + + rayleighValidation.push_back(Validator(SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-1.0f)(1.0f))))); + + rayleighValidation.push_back(Validator(SETTING_DENSITY_PROFILE_LINEAR_TERM, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + + rayleighValidation.push_back(Validator(SETTING_DENSITY_PROFILE_CONSTANT_TERM, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + } + return rayleighValidation; +} + +LLSettingsSky::validation_list_t LLSettingsSky::absorptionValidationList() +{ + static validation_list_t absorptionValidation; + if (absorptionValidation.empty()) + { + absorptionValidation.push_back(Validator(SETTING_DENSITY_PROFILE_WIDTH, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(32768.0f))))); + + absorptionValidation.push_back(Validator(SETTING_DENSITY_PROFILE_EXP_TERM, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + + absorptionValidation.push_back(Validator(SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-1.0f)(1.0f))))); + + absorptionValidation.push_back(Validator(SETTING_DENSITY_PROFILE_LINEAR_TERM, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + + absorptionValidation.push_back(Validator(SETTING_DENSITY_PROFILE_CONSTANT_TERM, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + } + return absorptionValidation; +} + +LLSettingsSky::validation_list_t LLSettingsSky::mieValidationList() +{ + static validation_list_t mieValidation; + if (mieValidation.empty()) + { + mieValidation.push_back(Validator(SETTING_DENSITY_PROFILE_WIDTH, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(32768.0f))))); + + mieValidation.push_back(Validator(SETTING_DENSITY_PROFILE_EXP_TERM, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + + mieValidation.push_back(Validator(SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-1.0f)(1.0f))))); + + mieValidation.push_back(Validator(SETTING_DENSITY_PROFILE_LINEAR_TERM, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(2.0f))))); + + mieValidation.push_back(Validator(SETTING_DENSITY_PROFILE_CONSTANT_TERM, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + + mieValidation.push_back(Validator(SETTING_MIE_ANISOTROPY_FACTOR, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f))))); + } + return mieValidation; +} + LLSettingsSky::validation_list_t LLSettingsSky::getValidationList() const { return LLSettingsSky::validationList(); @@ -224,7 +312,19 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList() LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")), LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*"))))); validation.push_back(Validator(SETTING_SUN_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal)); - validation.push_back(Validator(SETTING_SUN_TEXUTUREID, false, LLSD::TypeUUID)); + validation.push_back(Validator(SETTING_SUN_TEXTUREID, false, LLSD::TypeUUID)); + + validation.push_back(Validator(SETTING_PLANET_RADIUS, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(32768.0f))))); + + validation.push_back(Validator(SETTING_SKY_BOTTOM_RADIUS, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(32768.0f))))); + + validation.push_back(Validator(SETTING_SKY_TOP_RADIUS, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(1000.0f)(32768.0f))))); + + validation.push_back(Validator(SETTING_SUN_ARC_RADIANS, true, LLSD::TypeReal, + boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(0.1f))))); } return validation; @@ -268,13 +368,194 @@ LLSD LLSettingsSky::defaults() dfltsetting[SETTING_BLOOM_TEXTUREID] = IMG_BLOOM1; dfltsetting[SETTING_CLOUD_TEXTUREID] = LLUUID::null; dfltsetting[SETTING_MOON_TEXTUREID] = IMG_MOON; // gMoonTextureID; // These two are returned by the login... wow! - dfltsetting[SETTING_SUN_TEXUTUREID] = IMG_SUN; // gSunTextureID; + dfltsetting[SETTING_SUN_TEXTUREID] = IMG_SUN; // gSunTextureID; dfltsetting[SETTING_TYPE] = "sky"; + // defaults are for earth... + dfltsetting[SETTING_PLANET_RADIUS] = 6360.0f; + dfltsetting[SETTING_SKY_BOTTOM_RADIUS] = 6360.0f; + dfltsetting[SETTING_SKY_TOP_RADIUS] = 6420.0f; + dfltsetting[SETTING_SUN_ARC_RADIANS] = 0.00935f / 2.0f; + + LLSD dflt_rayleigh; + dflt_rayleigh[SETTING_DENSITY_PROFILE_WIDTH] = 0.0f; // 0 -> the entire atmosphere + dflt_rayleigh[SETTING_DENSITY_PROFILE_EXP_TERM] = 1.0f; + dflt_rayleigh[SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR] = -1.0f / 8000.0f; + dflt_rayleigh[SETTING_DENSITY_PROFILE_LINEAR_TERM] = 0.0f; + dflt_rayleigh[SETTING_DENSITY_PROFILE_CONSTANT_TERM] = 0.0f; + + dfltsetting[SETTING_RAYLEIGH_CONFIG] = dflt_rayleigh; + + LLSD dflt_mie; + dflt_mie[SETTING_DENSITY_PROFILE_WIDTH] = 0.0f; // 0 -> the entire atmosphere + dflt_mie[SETTING_DENSITY_PROFILE_EXP_TERM] = 1.0f; + dflt_mie[SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR] = -1.0f / 1200.0f; + dflt_mie[SETTING_DENSITY_PROFILE_LINEAR_TERM] = 0.0f; + dflt_mie[SETTING_DENSITY_PROFILE_CONSTANT_TERM] = 0.0f; + dflt_mie[SETTING_MIE_ANISOTROPY_FACTOR] = 0.9f; + + dfltsetting[SETTING_MIE_CONFIG] = dflt_mie; + + // absorption (ozone) has two linear ramping zones + LLSD dflt_absorption_a; + dflt_absorption_a[SETTING_DENSITY_PROFILE_WIDTH] = 25000.0f; // 0 -> the entire atmosphere + dflt_absorption_a[SETTING_DENSITY_PROFILE_EXP_TERM] = 0.0f; + dflt_absorption_a[SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR] = 0.0f; + dflt_absorption_a[SETTING_DENSITY_PROFILE_LINEAR_TERM] = -1.0f / 25000.0f; + dflt_absorption_a[SETTING_DENSITY_PROFILE_CONSTANT_TERM] = -2.0f / 3.0f; + + LLSD dflt_absorption_b; + dflt_absorption_b[SETTING_DENSITY_PROFILE_WIDTH] = 0.0f; // 0 -> remainder of the atmosphere + dflt_absorption_b[SETTING_DENSITY_PROFILE_EXP_TERM] = 0.0f; + dflt_absorption_b[SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR] = 0.0f; + dflt_absorption_b[SETTING_DENSITY_PROFILE_LINEAR_TERM] = -1.0f / 15000.0f; + dflt_absorption_b[SETTING_DENSITY_PROFILE_CONSTANT_TERM] = 8.0f / 3.0f; + + LLSD wtf; + wtf.append(dflt_absorption_a); + wtf.append(dflt_absorption_b); + + dfltsetting[SETTING_ABSORPTION_CONFIG] = wtf; + return dfltsetting; } +#pragma optimize("", off) + +LLSD LLSettingsSky::settingValidation(LLSD &settingsIn, validation_list_t &validations) +{ + // Make a copy we can safely modify + LLSD settings = settingsIn; + + validation_list_t& rayleighValidations = rayleighValidationList(); + validation_list_t& absorptionValidations = absorptionValidationList(); + validation_list_t& mieValidations = mieValidationList(); + + bool isValid = true; + + LLSD& rayleighConfigs = settings[SETTING_RAYLEIGH_CONFIG]; + LLSD& mieConfigs = settings[SETTING_MIE_CONFIG]; + LLSD& absorptionConfigs = settings[SETTING_ABSORPTION_CONFIG]; + +// this is an attempt to handle a single defined layer (w/o array elem) +// but also handle an array of density profiles if they are specified thus. + if (rayleighConfigs.isArray()) + { + for (LLSD::array_iterator it = rayleighConfigs.beginArray(); it != rayleighConfigs.endArray(); ++it) + { + LLSD rayleighResults = LLSettingsBase::settingValidation(*it, rayleighValidations); + if (!rayleighResults["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky Rayleigh Density Profile setting validation failed!\n" << rayleighResults << LL_ENDL; + LLSettingsSky::ptr_t(); + isValid = false; + } + } + } + else + { + LLSD rayleighResults = LLSettingsBase::settingValidation(rayleighConfigs, rayleighValidations); + if (!rayleighResults["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky Rayleigh Density Profile setting validation failed!\n" << rayleighResults << LL_ENDL; + LLSettingsSky::ptr_t(); + isValid = false; + } + } + + if (mieConfigs.isArray()) + { + for (LLSD::array_iterator it = mieConfigs.beginArray(); it != mieConfigs.endArray(); ++it) + { + LLSD mieResults = LLSettingsBase::settingValidation(*it, mieValidations); + if (!mieResults["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky Mie Density Profile setting validation failed!\n" << mieResults << LL_ENDL; + LLSettingsSky::ptr_t(); + isValid = false; + } + } + } + else + { + LLSD mieResults = LLSettingsBase::settingValidation(mieConfigs, mieValidations); + if (!mieResults["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky Mie Density Profile setting validation failed!\n" << mieResults << LL_ENDL; + LLSettingsSky::ptr_t(); + isValid = false; + } + } + + if (absorptionConfigs.isArray()) + { + for (LLSD::array_iterator it = absorptionConfigs.beginArray(); it != absorptionConfigs.endArray(); ++it) + { + LLSD absorptionResults = LLSettingsBase::settingValidation(*it, absorptionValidations); + if (!absorptionResults["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky Absorption Density Profile setting validation failed!\n" << absorptionResults << LL_ENDL; + LLSettingsSky::ptr_t(); + isValid = false; + } + } + } + else + { + LLSD absorptionResults = LLSettingsBase::settingValidation(absorptionConfigs, absorptionValidations); + if (!absorptionResults["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky Absorption Density Profile setting validation failed!\n" << absorptionResults << LL_ENDL; + LLSettingsSky::ptr_t(); + isValid = false; + } + } + +#if 0 + LLSD& rayleigh = settings[SETTING_RAYLEIGH_CONFIG]; + LLSD& absorption = settings[SETTING_ABSORPTION_CONFIG]; + LLSD& mie = settings[SETTING_MIE_CONFIG]; + LLSD rayleighResults = LLSettingsBase::settingValidation(rayleigh, rayleighValidations); + LLSD absorptionResults = LLSettingsBase::settingValidation(absorption, absorptionValidations); + LLSD mieResults = LLSettingsBase::settingValidation(mie, mieValidations); + + if (!rayleighResults["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky Rayleigh Density Profile setting validation failed!\n" << rayleighResults << LL_ENDL; + LLSettingsSky::ptr_t(); + isValid = false; + } + + if (!absorptionResults["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky Absorption Density Profile setting validation failed!\n" << absorptionResults << LL_ENDL; + LLSettingsSky::ptr_t(); + isValid = false; + } + + if (!mieResults["success"].asBoolean()) + { + LL_WARNS("SETTINGS") << "Sky Mie Density Profile setting validation failed!\n" << mieResults << LL_ENDL; + LLSettingsSky::ptr_t(); + isValid = false; + } +#endif + + settings.erase(SETTING_RAYLEIGH_CONFIG); + settings.erase(SETTING_ABSORPTION_CONFIG); + settings.erase(SETTING_MIE_CONFIG); + + if (isValid) + { + return LLSettingsBase::settingValidation(settings, validations); + } + + return LLSDMap("success", LLSD::Boolean(false)); +} + +#pragma optimize("", on) + LLSD LLSettingsSky::translateLegacySettings(LLSD legacy) { LLSD newsettings(defaults()); diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index e9ffbdb32c..1d860016fb 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -60,7 +60,24 @@ public: static const std::string SETTING_STAR_BRIGHTNESS; static const std::string SETTING_SUNLIGHT_COLOR; static const std::string SETTING_SUN_ROTATION; - static const std::string SETTING_SUN_TEXUTUREID; + static const std::string SETTING_SUN_TEXTUREID; + + static const std::string SETTING_PLANET_RADIUS; + static const std::string SETTING_SKY_BOTTOM_RADIUS; + static const std::string SETTING_SKY_TOP_RADIUS; + static const std::string SETTING_SUN_ARC_RADIANS; + + static const std::string SETTING_RAYLEIGH_CONFIG; + static const std::string SETTING_MIE_CONFIG; + static const std::string SETTING_ABSORPTION_CONFIG; + + static const std::string KEY_DENSITY_PROFILE; + static const std::string SETTING_DENSITY_PROFILE_WIDTH; + static const std::string SETTING_DENSITY_PROFILE_EXP_TERM; + static const std::string SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR; + static const std::string SETTING_DENSITY_PROFILE_LINEAR_TERM; + static const std::string SETTING_DENSITY_PROFILE_CONSTANT_TERM; + static const std::string SETTING_MIE_ANISOTROPY_FACTOR; typedef std::shared_ptr ptr_t; typedef std::pair azimalt_t; @@ -345,7 +362,7 @@ public: LLUUID getSunTextureId() const { - return mSettings[SETTING_SUN_TEXUTUREID].asUUID(); + return mSettings[SETTING_SUN_TEXTUREID].asUUID(); } // Internal/calculated settings @@ -414,6 +431,8 @@ public: static LLSD translateLegacySettings(LLSD legacy); + static LLSD settingValidation(LLSD &settings, validation_list_t &validations); + protected: static const std::string SETTING_LEGACY_EAST_ANGLE; static const std::string SETTING_LEGACY_ENABLE_CLOUD_SCROLL; @@ -423,9 +442,14 @@ protected: virtual stringset_t getSlerpKeys() const; - virtual void updateSettings(); + virtual void updateSettings(); private: + // validations for structured sections of sky settings data + static validation_list_t rayleighValidationList(); + static validation_list_t absorptionValidationList(); + static validation_list_t mieValidationList(); + static const F32 NIGHTTIME_ELEVATION; static const F32 NIGHTTIME_ELEVATION_COS; diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 89451a072c..dcfbd71dec 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -107,7 +107,9 @@ if (BUILD_HEADLESS) ${LLXML_LIBRARIES} ${LLVFS_LIBRARIES} ${LLWINDOW_HEADLESS_LIBRARIES} - ${OPENGL_HEADLESS_LIBRARIES}) + ${LIBATMOSPHERE_LIBRARIES} + ${OPENGL_HEADLESS_LIBRARIES} + ) endif (BUILD_HEADLESS) @@ -130,6 +132,7 @@ target_link_libraries(llrender ${LLVFS_LIBRARIES} ${LLWINDOW_LIBRARIES} ${FREETYPE_LIBRARIES} + ${LIBATMOSPHERE_LIBRARIES} ${OPENGL_LIBRARIES} - ${ATMOSPHERE_LIBRARIES}) + ) diff --git a/indra/llrender/llatmosphere.cpp b/indra/llrender/llatmosphere.cpp new file mode 100644 index 0000000000..fb159a3e47 --- /dev/null +++ b/indra/llrender/llatmosphere.cpp @@ -0,0 +1,218 @@ +/** + * @file llatmosphere.cpp + * @brief LLAtmosphere integration impl + * + * $LicenseInfo:firstyear=2018&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2018, 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 "linden_common.h" + +#include "llatmosphere.h" +#include "llfasttimer.h" +#include "llsys.h" +#include "llglheaders.h" +#include "llrender.h" +#include "llshadermgr.h" +#include "llglslshader.h" + +LLAtmosphere* gAtmosphere = nullptr; + +void LLAtmosphere::initClass() +{ + if (!gAtmosphere) + { + gAtmosphere = new LLAtmosphere; + } +} + +void LLAtmosphere::cleanupClass() +{ + if(gAtmosphere) + { + delete gAtmosphere; + } + gAtmosphere = NULL; +} + +LLAtmosphere::LLAtmosphere() +{ + // Init libatmosphere model + m_config.num_scattering_orders = 4; + + // Values from "Reference Solar Spectral Irradiance: ASTM G-173", ETR column + // (see http://rredc.nrel.gov/solar/spectra/am1.5/ASTMG173/ASTMG173.html), + // summed and averaged in each bin (e.g. the value for 360nm is the average + // of the ASTM G-173 values for all wavelengths between 360 and 370nm). + // Values in W.m^-2. + const int kLambdaMin = 360; + const int kLambdaMax = 830; + const double kSolarIrradiance[48] = { + 1.11776, 1.14259, 1.01249, 1.14716, 1.72765, 1.73054, 1.6887, 1.61253, + 1.91198, 2.03474, 2.02042, 2.02212, 1.93377, 1.95809, 1.91686, 1.8298, + 1.8685, 1.8931, 1.85149, 1.8504, 1.8341, 1.8345, 1.8147, 1.78158, 1.7533, + 1.6965, 1.68194, 1.64654, 1.6048, 1.52143, 1.55622, 1.5113, 1.474, 1.4482, + 1.41018, 1.36775, 1.34188, 1.31429, 1.28303, 1.26758, 1.2367, 1.2082, + 1.18737, 1.14683, 1.12362, 1.1058, 1.07124, 1.04992 + }; + + // Values from http://www.iup.uni-bremen.de/gruppen/molspec/databases/ + // referencespectra/o3spectra2011/index.html for 233K, summed and averaged in + // each bin (e.g. the value for 360nm is the average of the original values + // for all wavelengths between 360 and 370nm). Values in m^2. + const double kOzoneCrossSection[48] = { + 1.18e-27, 2.182e-28, 2.818e-28, 6.636e-28, 1.527e-27, 2.763e-27, 5.52e-27, + 8.451e-27, 1.582e-26, 2.316e-26, 3.669e-26, 4.924e-26, 7.752e-26, 9.016e-26, + 1.48e-25, 1.602e-25, 2.139e-25, 2.755e-25, 3.091e-25, 3.5e-25, 4.266e-25, + 4.672e-25, 4.398e-25, 4.701e-25, 5.019e-25, 4.305e-25, 3.74e-25, 3.215e-25, + 2.662e-25, 2.238e-25, 1.852e-25, 1.473e-25, 1.209e-25, 9.423e-26, 7.455e-26, + 6.566e-26, 5.105e-26, 4.15e-26, 4.228e-26, 3.237e-26, 2.451e-26, 2.801e-26, + 2.534e-26, 1.624e-26, 1.465e-26, 2.078e-26, 1.383e-26, 7.105e-27 + }; + + // From https://en.wikipedia.org/wiki/Dobson_unit, in molecules.m^-2. + const double kDobsonUnit = 2.687e20; + + // Maximum number density of ozone molecules, in m^-3 (computed so at to get + // 300 Dobson units of ozone - for this we divide 300 DU by the integral of + // the ozone density profile defined below, which is equal to 15km). + const double kMaxOzoneNumberDensity = 300.0 * kDobsonUnit / 15000.0; + + const double kSunAngularRadius = 0.00935 / 2.0; + const double kBottomRadius = 6360000.0; + const double kTopRadius = 6420000.0; + const double kRayleigh = 1.24062e-6; + const double kRayleighScaleHeight = 8000.0; + const double kMieScaleHeight = 1200.0; + const double kMieAngstromAlpha = 0.0; + const double kMieAngstromBeta = 5.328e-3; + const double kMieSingleScatteringAlbedo = 0.9; + const double kMiePhaseFunctionG = 0.8; + const double max_sun_zenith_angle = F_PI * 2.0 / 3.0; + + atmosphere::DensityProfileLayer rayleigh_density(0.0, 1.0, -1.0 / kRayleighScaleHeight, 0.0, 0.0); + atmosphere::DensityProfileLayer mie_density(0.0, 1.0, -1.0 / kMieScaleHeight, 0.0, 0.0); + + // Density profile increasing linearly from 0 to 1 between 10 and 25km, and + // decreasing linearly from 1 to 0 between 25 and 40km. This is an approximate + // profile from http://www.kln.ac.lk/science/Chemistry/Teaching_Resources/ + // Documents/Introduction%20to%20atmospheric%20chemistry.pdf (page 10). + std::vector ozone_density; + ozone_density.push_back(atmosphere::DensityProfileLayer(25000.0, 0.0, 0.0, 1.0 / 15000.0, -2.0 / 3.0)); + ozone_density.push_back(atmosphere::DensityProfileLayer(0.0, 0.0, 0.0, -1.0 / 15000.0, 8.0 / 3.0)); + + std::vector wavelengths; + std::vector solar_irradiance; + std::vector rayleigh_scattering; + std::vector mie_scattering; + std::vector mie_extinction; + std::vector absorption_extinction; + std::vector ground_albedo; + + for (int l = kLambdaMin; l <= kLambdaMax; l += 10) + { + double lambda = static_cast(l) * 1e-3; // micro-meters + double mie = kMieAngstromBeta / kMieScaleHeight * pow(lambda, -kMieAngstromAlpha); + wavelengths.push_back(l); + solar_irradiance.push_back(kSolarIrradiance[(l - kLambdaMin) / 10]); + rayleigh_scattering.push_back(kRayleigh * pow(lambda, -4)); + mie_scattering.push_back(mie * kMieSingleScatteringAlbedo); + mie_extinction.push_back(mie); + absorption_extinction.push_back(kMaxOzoneNumberDensity * kOzoneCrossSection[(l - kLambdaMin) / 10]); + ground_albedo.push_back(0.1f); + } + + m_model = new atmosphere::Model( + wavelengths, + solar_irradiance, + kSunAngularRadius, + kBottomRadius, + kTopRadius, + {rayleigh_density}, + rayleigh_scattering, + {mie_density}, + mie_scattering, + mie_extinction, + kMiePhaseFunctionG, + ozone_density, + absorption_extinction, + ground_albedo, + max_sun_zenith_angle, + 1000.0, + 15, + false, + true); + + m_model->Init(m_config, m_textures); + + m_transmittance = new LLGLTexture; + m_scattering = new LLGLTexture; + m_mie_scattering = new LLGLTexture; + + m_transmittance->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); + m_transmittance->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); + m_transmittance->setExplicitFormat(GL_RGB16F, GL_RGB, GL_FLOAT); + m_transmittance->setTexName(m_textures.transmittance_texture); + m_transmittance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE); + + m_scattering->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); + m_scattering->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); + m_scattering->setExplicitFormat(GL_RGB16F, GL_RGB, GL_FLOAT); + m_scattering->setTexName(m_textures.transmittance_texture); + m_scattering->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D); + + m_mie_scattering->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); + m_mie_scattering->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); + m_mie_scattering->setExplicitFormat(GL_RGB16F, GL_RGB, GL_FLOAT); + m_mie_scattering->setTexName(m_textures.transmittance_texture); + m_mie_scattering->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D); +}; + +LLAtmosphere::~LLAtmosphere() +{ + // Cease referencing textures from atmosphere::model from our LLGLTextures wrappers for same. + m_transmittance->setTexName(0); + m_scattering->setTexName(0); + m_mie_scattering->setTexName(0); + + delete m_model; + m_model = nullptr; +} + +LLGLTexture* LLAtmosphere::getTransmittance() const +{ + return m_transmittance; +} + +LLGLTexture* LLAtmosphere::getScattering() const +{ + return m_scattering; +} + +LLGLTexture* LLAtmosphere::getMieScattering() const +{ + return m_mie_scattering; +} + +GLuint LLAtmosphere::getAtmosphericShaderForLink() const +{ + return m_model ? m_model->GetShader() : 0; +} diff --git a/indra/llrender/llatmosphere.h b/indra/llrender/llatmosphere.h new file mode 100644 index 0000000000..4aa36be27f --- /dev/null +++ b/indra/llrender/llatmosphere.h @@ -0,0 +1,72 @@ +/** + * @file llatmosphere.h + * @brief LLAtmosphere class for integration with libatmosphere + * + * $LicenseInfo:firstyear=2018&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2018, 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$ + */ + +#ifndef LL_ATMOSPHERE_H +#define LL_ATMOSPHERE_H + +#include "llglheaders.h" +#include "llgltexture.h" +#include "libatmosphere/model.h" + +class LLAtmosphere +{ +public: + LLAtmosphere(); + ~LLAtmosphere(); + + static void initClass(); + static void cleanupClass(); + + const LLAtmosphere& operator=(const LLAtmosphere& rhs) + { + LL_ERRS() << "Illegal operation!" << LL_ENDL; + return *this; + } + + LLGLTexture* getTransmittance() const; + LLGLTexture* getScattering() const; + LLGLTexture* getMieScattering() const; + + GLuint getAtmosphericShaderForLink() const; + +protected: + LLAtmosphere(const LLAtmosphere& rhs) + { + *this = rhs; + } + + atmosphere::ModelConfig m_config; + atmosphere::PrecomputedTextures m_textures; + atmosphere::Model* m_model = nullptr; + + LLPointer m_transmittance; + LLPointer m_scattering; + LLPointer m_mie_scattering; +}; + +extern LLAtmosphere* gAtmosphere; + +#endif // LL_ATMOSPHERE_H diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index a57e48ffad..b8d646ed15 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -133,7 +133,7 @@ public: void setGLTextureCreated (bool initialized); void setCategory(S32 category) ; void setTexName(LLGLuint); // for forcing w/ externally created textures only - void setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target); + void setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target); LLTexUnit::eTextureAddressMode getAddressMode(void) const ; S32 getMaxDiscardLevel() const; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index d277a1158c..9f1b9fb373 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10131,7 +10131,7 @@ Type Boolean Value - 1 + 0 RenderUseTriStrips diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 042d7d971a..a28041034b 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -186,7 +186,7 @@ void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const // bind precomputed textures necessary for calculating sun and sky luminance sky_shader->bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance()); sky_shader->bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering()); - sky_shader->bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getSingleMieScattering()); + sky_shader->bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering()); static float sunSize = (float)cos(0.0005); diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 6b1c663357..db68b39f75 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -117,6 +117,7 @@ LLSettingsSky::ptr_t LLSettingsVOSky::buildDefaultSky() settings[SETTING_NAME] = std::string("_default_"); LLSettingsSky::validation_list_t validations = LLSettingsSky::validationList(); + LLSD results = LLSettingsSky::settingValidation(settings, validations); if (!results["success"].asBoolean()) { diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index bec05fa263..6d174442fb 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -3308,7 +3308,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() } // this shader uses gather so it can't live with the other basic shaders safely - if (success) + if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] >= 3)) { gDownsampleMinMaxDepthRectProgram.mName = "DownsampleMinMaxDepthRect Shader"; gDownsampleMinMaxDepthRectProgram.mShaderFiles.clear(); @@ -3331,8 +3331,6 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() success = gInscatterRectProgram.createShader(NULL, NULL); } - llassert(success); - if (success) { gWLSkyProgram.mName = "Windlight Sky Shader"; @@ -3349,8 +3347,6 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() success = gWLSkyProgram.createShader(NULL, NULL); } - llassert(success); - if (success && (mVertexShaderLevel[SHADER_WINDLIGHT] < 3)) { gWLCloudProgram.mName = "Windlight Cloud Program"; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index cbde0af9b3..e59e86529a 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -98,8 +98,8 @@ const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64; const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez; const S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128; const S32 DEFAULT_ICON_DIMENTIONS = 32; -S32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256. -S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA; +U32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256. +U32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA; BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE; F32 LLViewerTexture::sCurrentTime = 0.0f; F32 LLViewerTexture::sTexelPixelRatio = 1.0f; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 849273df15..8f691a0453 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -381,7 +381,7 @@ bool LLPipeline::sRenderBump = true; bool LLPipeline::sBakeSunlight = false; bool LLPipeline::sNoAlpha = false; bool LLPipeline::sUseTriStrips = true; -bool LLPipeline::sUseAdvancedAtmospherics = true; +bool LLPipeline::sUseAdvancedAtmospherics = false; bool LLPipeline::sUseFarClip = true; bool LLPipeline::sShadowRender = false; bool LLPipeline::sWaterReflections = false; -- cgit v1.3 From 1d522aca8a5d5205f6d6150699ce5b9b8425c007 Mon Sep 17 00:00:00 2001 From: "Graham Linden graham@lindenlab.com" Date: Tue, 6 Mar 2018 19:20:52 +0000 Subject: Reference updated libatmosphere package. --- autobuild.xml | 16 ++++++++-------- indra/cmake/Atmosphere.cmake | 2 +- indra/llrender/CMakeLists.txt | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'indra/cmake') diff --git a/autobuild.xml b/autobuild.xml index 6a463b7654..207c6d7e1a 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -64,9 +64,9 @@ archive hash - 3950f04d10efd9596093e45f2a265ce1 + 053b2324eed0a023f7fdb6b206b62795 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/14058/88070/libatmosphere-1.0.0.100-darwin-512856.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/14502/92362/libatmosphere-1.0.0.100-darwin-513070.tar.bz2 name darwin @@ -76,9 +76,9 @@ archive hash - c679a42268c3b22bb94366a7dff2e885 + 729cb87547380bdf6860222b46298ff6 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/14482/92320/libatmosphere-1.0.0.100-darwin64-513060.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/14501/92356/libatmosphere-1.0.0.100-darwin64-513070.tar.bz2 name darwin64 @@ -88,9 +88,9 @@ archive hash - 724fcf872b40b2fcf717e4569517725a + d79c2b71cd3609274aa9f73a80de3472 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/14481/92314/libatmosphere-1.0.0.100-windows-513059.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/14507/92471/libatmosphere-1.0.0.100-windows-513070.tar.bz2 name windows @@ -100,9 +100,9 @@ archive hash - 3edae1ac94886c4611489202d1a8eaa1 + bbf84ebf5c8f34c6c08a43daeb22b580 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/14480/92308/libatmosphere-1.0.0.100-windows64-513059.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/14506/92465/libatmosphere-1.0.0.100-windows64-513070.tar.bz2 name windows64 diff --git a/indra/cmake/Atmosphere.cmake b/indra/cmake/Atmosphere.cmake index 0975e3df02..9c14df2a11 100644 --- a/indra/cmake/Atmosphere.cmake +++ b/indra/cmake/Atmosphere.cmake @@ -1,5 +1,5 @@ # -*- cmake -*- include(Prebuilt) use_prebuilt_binary(libatmosphere) -set(LIBATMOSPHERE_LIBRARIES libatmosphere) +set(LIBATMOSPHERE_LIBRARIES atmosphere) set(LIBATMOSPHERE_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/atmosphere) diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index dcfbd71dec..26aaf10d07 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -132,7 +132,7 @@ target_link_libraries(llrender ${LLVFS_LIBRARIES} ${LLWINDOW_LIBRARIES} ${FREETYPE_LIBRARIES} - ${LIBATMOSPHERE_LIBRARIES} + ${LIBATMOSPHERE_LIBRARIES} ${OPENGL_LIBRARIES} ) -- cgit v1.3 From d8eff424a5fb340b828802351e2b7f6b63bfa30f Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Sat, 2 Mar 2019 07:17:46 -0800 Subject: SL-10664 --- autobuild.xml | 68 +---- indra/cmake/LLRender.cmake | 1 - indra/llrender/CMakeLists.txt | 2 - indra/llrender/llatmosphere.cpp | 69 +----- indra/llrender/llatmosphere.h | 73 +++++- indra/llrender/llshadermgr.h | 2 +- indra/newview/app_settings/settings.xml | 11 - .../app_settings/shaders/class1/deferred/cofF.glsl | 10 +- indra/newview/lldrawpoolwlsky.cpp | 148 +---------- indra/newview/lldrawpoolwlsky.h | 3 - indra/newview/llenvironment.cpp | 32 ++- indra/newview/llfloatereditextdaycycle.cpp | 45 ---- indra/newview/llfloaterfixedenvironment.cpp | 8 - indra/newview/llviewercontrol.cpp | 12 - indra/newview/llviewerdisplay.cpp | 5 - indra/newview/llviewerobject.cpp | 1 + indra/newview/llviewershadermgr.cpp | 70 +----- indra/newview/llviewershadermgr.h | 3 - indra/newview/llvoavatar.cpp | 2 +- indra/newview/pipeline.cpp | 273 +-------------------- indra/newview/pipeline.h | 7 - 21 files changed, 104 insertions(+), 741 deletions(-) (limited to 'indra/cmake') diff --git a/autobuild.xml b/autobuild.xml index 6d7c161117..3db07622a9 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -44,73 +44,7 @@ version 1.2.15 - - libatmosphere - - copyright - Copyright © 2017 Eric Bruneton. - description - Precomputed multiple atmospheric scattering library. - license - BSD - license_file - LICENSES/libatmosphere.txt - name - libatmosphere - platforms - - darwin - - archive - - hash - bca20bcdf1a2c26b16e71fb2c1316cbe - url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24187/188163/libatmosphere-1.0.0.100-darwin-519422.tar.bz2 - - name - darwin - - darwin64 - - archive - - hash - 9ce4c97f1eda8caa556573abd6e1ebd0 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24188/188166/libatmosphere-1.0.0.100-darwin64-519422.tar.bz2 - - name - darwin64 - - windows - - archive - - hash - 6a61502ab1cca316f85310ded8bf9b9a - url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24190/188181/libatmosphere-1.0.0.100-windows-519422.tar.bz2 - - name - windows - - windows64 - - archive - - hash - 496410cb43e03ddf1777cd295c2d5dba - url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/24189/188175/libatmosphere-1.0.0.100-windows64-519422.tar.bz2 - - name - windows64 - - - version - 1.0.0.513060 - + apr_suite copyright diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake index 0940d1de63..868922451f 100644 --- a/indra/cmake/LLRender.cmake +++ b/indra/cmake/LLRender.cmake @@ -3,7 +3,6 @@ include(Variables) include(FreeType) include(GLH) -include(Atmosphere) set(LLRENDER_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llrender diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index bcb5a847f6..0a23b6c041 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -13,7 +13,6 @@ include(LLVFS) include(LLWindow) include(LLXML) include(LLVFS) -include(Atmosphere) include_directories( ${FREETYPE_INCLUDE_DIRS} @@ -25,7 +24,6 @@ include_directories( ${LLWINDOW_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} ${LLVFS_INCLUDE_DIRS} - ${ATMOSPHERE_INCLUDE_DIR} ) include_directories(SYSTEM ${LLCOMMON_SYSTEM_INCLUDE_DIRS} diff --git a/indra/llrender/llatmosphere.cpp b/indra/llrender/llatmosphere.cpp index 12c6685354..a0b92564c3 100644 --- a/indra/llrender/llatmosphere.cpp +++ b/indra/llrender/llatmosphere.cpp @@ -88,8 +88,8 @@ AtmosphericModelSettings::AtmosphericModelSettings() , m_sunArcRadians(0.00045f) , m_mieAnisotropy(0.8f) { - atmosphere::DensityProfileLayer rayleigh_density(0.0, 1.0, -1.0 / kRayleighScaleHeight, 0.0, 0.0); - atmosphere::DensityProfileLayer mie_density(0.0, 1.0, -1.0 / kMieScaleHeight, 0.0, 0.0); + DensityLayer rayleigh_density(0.0, 1.0, -1.0 / kRayleighScaleHeight, 0.0, 0.0); + DensityLayer mie_density(0.0, 1.0, -1.0 / kMieScaleHeight, 0.0, 0.0); m_rayleighProfile.push_back(rayleigh_density); m_mieProfile.push_back(mie_density); @@ -98,8 +98,8 @@ AtmosphericModelSettings::AtmosphericModelSettings() // decreasing linearly from 1 to 0 between 25 and 40km. This is an approximate // profile from http://www.kln.ac.lk/science/Chemistry/Teaching_Resources/ // Documents/Introduction%20to%20atmospheric%20chemistry.pdf (page 10). - m_absorptionProfile.push_back(atmosphere::DensityProfileLayer(25000.0, 0.0, 0.0, 1.0 / 15000.0, -2.0 / 3.0)); - m_absorptionProfile.push_back(atmosphere::DensityProfileLayer(0.0, 0.0, 0.0, -1.0 / 15000.0, 8.0 / 3.0)); + m_absorptionProfile.push_back(DensityLayer(25000.0, 0.0, 0.0, 1.0 / 15000.0, -2.0 / 3.0)); + m_absorptionProfile.push_back(DensityLayer(0.0, 0.0, 0.0, -1.0 / 15000.0, 8.0 / 3.0)); } AtmosphericModelSettings::AtmosphericModelSettings( @@ -227,64 +227,12 @@ LLAtmosphere::~LLAtmosphere() { m_mie_scatter_texture->setTexName(0); } - - delete m_model; - m_model = nullptr; } bool LLAtmosphere::configureAtmosphericModel(AtmosphericModelSettings& settings) { - if ((m_model != nullptr) && (settings == m_settings)) - { - return true; - } - - if (m_model) - { - delete m_model; - } - m_model = nullptr; - - getTransmittance()->setTexName(0); - getScattering()->setTexName(0); - getMieScattering()->setTexName(0); - getIlluminance()->setTexName(0); - - // Init libatmosphere model - m_model = new atmosphere::Model( - m_config, - m_wavelengths, - m_solar_irradiance, - settings.m_sunArcRadians, - settings.m_skyBottomRadius * 1000.0f, - settings.m_skyTopRadius * 1000.0f, - settings.m_rayleighProfile, - m_rayleigh_scattering, - settings.m_mieProfile, - m_mie_scattering, - m_mie_extinction, - settings.m_mieAnisotropy, - settings.m_absorptionProfile, - m_absorption_extinction, - m_ground_albedo, - max_sun_zenith_angle, - 1000.0, - 3, - false, // do not combine_scattering...we want indep textures - false, // use 32F for 2d textures to avoid artifacts - true); // use 16F for 3d textures to reduce footprint - - if (m_model) - { - m_model->Init(m_config, m_textures); - getTransmittance()->setTexName(m_textures.transmittance_texture); - getScattering()->setTexName(m_textures.scattering_texture); - getMieScattering()->setTexName(m_textures.single_mie_scattering_texture); - getIlluminance()->setTexName(m_textures.illuminance_texture); - m_settings = settings; - } - - return m_model != nullptr; + // TBD + return true; } LLGLTexture* LLAtmosphere::getTransmittance() @@ -342,8 +290,3 @@ LLGLTexture* LLAtmosphere::getIlluminance() } return m_illuminance; } - -GLhandleARB LLAtmosphere::getAtmosphericShaderForLink() const -{ - return m_model ? m_model->GetShader() : 0; -} diff --git a/indra/llrender/llatmosphere.h b/indra/llrender/llatmosphere.h index a010803595..572365d864 100644 --- a/indra/llrender/llatmosphere.h +++ b/indra/llrender/llatmosphere.h @@ -1,6 +1,6 @@ /** * @file llatmosphere.h - * @brief LLAtmosphere class for integration with libatmosphere + * @brief LLAtmosphere class * * $LicenseInfo:firstyear=2018&license=viewerlgpl$ * Second Life Viewer Source Code @@ -29,9 +29,70 @@ #include "llglheaders.h" #include "llgltexture.h" -#include "libatmosphere/model.h" -typedef std::vector DensityProfile; +// An atmosphere layer of width 'width' (in m), and whose density is defined as +// 'exp_term' * exp('exp_scale' * h) + 'linear_term' * h + 'constant_term', +// clamped to [0,1], and where h is the altitude (in m). 'exp_term' and +// 'constant_term' are unitless, while 'exp_scale' and 'linear_term' are in +// m^-1. +class DensityLayer { + public: + DensityLayer() + : width(0.0f) + , exp_term(0.0f) + , exp_scale(0.0f) + , linear_term(0.0f) + , constant_term(0.0f) + { + } + + DensityLayer(float width, float exp_term, float exp_scale, float linear_term, float constant_term) + : width(width) + , exp_term(exp_term) + , exp_scale(exp_scale) + , linear_term(linear_term) + , constant_term(constant_term) + { + } + + bool operator==(const DensityLayer& rhs) const + { + if (width != rhs.width) + { + return false; + } + + if (exp_term != rhs.exp_term) + { + return false; + } + + if (exp_scale != rhs.exp_scale) + { + return false; + } + + if (linear_term != rhs.linear_term) + { + return false; + } + + if (constant_term != rhs.constant_term) + { + return false; + } + + return true; + } + + float width = 1024.0f; + float exp_term = 1.0f; + float exp_scale = 1.0f; + float linear_term = 1.0f; + float constant_term = 0.0f; +}; + +typedef std::vector DensityProfile; class AtmosphericModelSettings { @@ -83,8 +144,6 @@ public: LLGLTexture* getMieScattering(); LLGLTexture* getIlluminance(); - GLhandleARB getAtmosphericShaderForLink() const; - bool configureAtmosphericModel(AtmosphericModelSettings& settings); protected: @@ -93,10 +152,6 @@ protected: *this = rhs; } - atmosphere::ModelConfig m_config; - atmosphere::PrecomputedTextures m_textures; - atmosphere::Model* m_model = nullptr; - LLPointer m_transmittance; LLPointer m_scattering; LLPointer m_mie_scatter_texture; diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 497c3eb231..e0a67e6198 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -226,7 +226,7 @@ public: SUN_SIZE, FOG_COLOR, - // precomputed textures from libatmosphere + // precomputed textures TRANSMITTANCE_TEX, SCATTER_TEX, SINGLE_MIE_SCATTER_TEX, diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 3e8a854df3..67f311bb4f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10277,17 +10277,6 @@ Value 0 - RenderUseAdvancedAtmospherics - - Comment - Use fancy precomputed atmospherics and stuff. - Persist - 1 - Type - Boolean - Value - 0 - RenderUseTriStrips Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl index 380d382020..079d8458c9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl @@ -50,8 +50,6 @@ uniform vec2 screen_res; VARYING vec2 vary_fragcoord; -float getDepth(vec2 pos_screen); - float calc_cof(float depth) { float sc = (depth-focal_distance)/-depth*blur_constant; @@ -70,8 +68,12 @@ float calc_cof(float depth) void main() { vec2 tc = vary_fragcoord.xy; - - float depth = getDepth(tc); + + float z = texture2DRect(depthMap, tc).r; + z = z*2.0-1.0; + vec4 ndc = vec4(0.0, 0.0, z, 1.0); + vec4 p = inv_proj*ndc; + float depth = p.z/p.w; vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 7e297a05a5..07d72e3d9b 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -187,63 +187,6 @@ void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLoca gGL.popMatrix(); } -void LLDrawPoolWLSky::renderSkyHazeAdvanced(const LLVector3& camPosLocal, F32 camHeightLocal) const -{ - if (gPipeline.useAdvancedAtmospherics() && gPipeline.canUseWindLightShaders() && gAtmosphere) - { - LLGLSPipelineDepthTestSkyBox sky(true, false); - - sky_shader->bind(); - - // bind precomputed textures necessary for calculating sun and sky luminance - sky_shader->bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance()); - sky_shader->bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering()); - sky_shader->bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering()); - sky_shader->bindTexture(LLShaderMgr::ILLUMINANCE_TEX, gAtmosphere->getIlluminance()); - - LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - - LLViewerTexture* rainbow_tex = gSky.mVOSkyp->getRainbowTex(); - LLViewerTexture* halo_tex = gSky.mVOSkyp->getHaloTex(); - - sky_shader->bindTexture(LLShaderMgr::RAINBOW_MAP, rainbow_tex); - sky_shader->bindTexture(LLShaderMgr::HALO_MAP, halo_tex); - - LLVector3 sun_dir = LLEnvironment::instance().getSunDirection(); - LLVector3 moon_dir = LLEnvironment::instance().getMoonDirection(); - - F32 sunSize = (float)cosf(psky->getSunArcRadians()); - sky_shader->uniform1f(LLShaderMgr::SUN_SIZE, sunSize); - sky_shader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, sun_dir.mV); - sky_shader->uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, moon_dir.mV); - - - F32 moisture_level = (float)psky->getSkyMoistureLevel(); - F32 droplet_radius = (float)psky->getSkyDropletRadius(); - F32 ice_level = (float)psky->getSkyIceLevel(); - - sky_shader->uniform1f(LLShaderMgr::MOISTURE_LEVEL, moisture_level); - sky_shader->uniform1f(LLShaderMgr::DROPLET_RADIUS, droplet_radius); - sky_shader->uniform1f(LLShaderMgr::ICE_LEVEL, ice_level); - - llassert(sky_shader->getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX)); - - glh::matrix4f proj_mat = get_current_projection(); - glh::matrix4f inv_proj = proj_mat.inverse(); - - sky_shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m); - - sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor()); - sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, psky->getIsSunUp() ? 1 : 0); - - sky_shader->uniform3f(sCamPosLocal, camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]); - - renderFsSky(camPosLocal, camHeightLocal, sky_shader); - - sky_shader->unbind(); - } -} - void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const { LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); @@ -427,78 +370,6 @@ void LLDrawPoolWLSky::renderStarsDeferred(void) const gDeferredStarProgram.unbind(); } -void LLDrawPoolWLSky::renderSkyCloudsAdvanced(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const -{ - if (gPipeline.canUseWindLightShaders() - && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) - && gSky.mVOSkyp->getCloudNoiseTex() - && gAtmosphere) - { - LLGLSPipelineBlendSkyBox pipeline(true, true); - - LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - - cloudshader->bind(); - - LLPointer cloud_noise = gSky.mVOSkyp->getCloudNoiseTex(); - LLPointer cloud_noise_next = gSky.mVOSkyp->getCloudNoiseTexNext(); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); - - F32 cloud_variance = psky ? psky->getCloudVariance() : 0.0f; - F32 blend_factor = psky ? psky->getBlendFactor() : 0.0f; - - // if we even have sun disc textures to work with... - if (cloud_noise || cloud_noise_next) - { - if (cloud_noise && (!cloud_noise_next || (cloud_noise == cloud_noise_next))) - { - // Bind current and next sun textures - cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE); - blend_factor = 0; - } - else if (cloud_noise_next && !cloud_noise) - { - cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise_next, LLTexUnit::TT_TEXTURE); - blend_factor = 0; - } - else if (cloud_noise_next != cloud_noise) - { - cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE); - cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, cloud_noise_next, LLTexUnit::TT_TEXTURE); - } - } - - cloudshader->bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance()); - cloudshader->bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering()); - cloudshader->bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering()); - cloudshader->bindTexture(LLShaderMgr::ILLUMINANCE_TEX, gAtmosphere->getIlluminance()); - - LLVector3 sun_dir = LLEnvironment::instance().getSunDirection(); - LLVector3 moon_dir = LLEnvironment::instance().getMoonDirection(); - - F32 sunSize = (float)cosf(psky->getSunArcRadians()); - cloudshader->uniform1f(LLShaderMgr::SUN_SIZE, sunSize); - cloudshader->uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, sun_dir.mV); - cloudshader->uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, moon_dir.mV); - - cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); - cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance); - cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor()); - - cloudshader->uniform3f(sCamPosLocal, camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]); - - /// Render the skydome - renderDome(camPosLocal, camHeightLocal, cloudshader); - - cloudshader->unbind(); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); - } -} - void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const { if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex()) @@ -741,22 +612,11 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) if (gPipeline.canUseWindLightShaders()) { - if (gPipeline.useAdvancedAtmospherics()) - { - renderSkyHazeAdvanced(origin, camHeightLocal); - renderStarsDeferred(); - renderHeavenlyBodies(); - renderSkyCloudsAdvanced(origin, camHeightLocal, cloud_shader); - } - else - { - renderSkyHazeDeferred(origin, camHeightLocal); - renderStarsDeferred(); - renderHeavenlyBodies(); - renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader); - } + renderSkyHazeDeferred(origin, camHeightLocal); + renderStarsDeferred(); + renderHeavenlyBodies(); + renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader); } - gGL.setColorMask(true, true); } diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h index ea11060eb5..b05f0f8605 100644 --- a/indra/newview/lldrawpoolwlsky.h +++ b/indra/newview/lldrawpoolwlsky.h @@ -94,9 +94,6 @@ private: void renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const; void renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const; - void renderSkyHazeAdvanced(const LLVector3& camPosLocal, F32 camHeightLocal) const; - void renderSkyCloudsAdvanced(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const; - void renderStarsDeferred(void) const; void renderStars(void) const; void renderHeavenlyBodies(); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index f021c4a8c3..18777e53d1 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -882,6 +882,14 @@ LLSettingsWater::ptr_t LLEnvironment::getCurrentWater() const return pwater; } +void LayerConfigToDensityLayer(const LLSD& layerConfig, DensityLayer& layerOut) +{ + layerOut.constant_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal(); + layerOut.exp_scale = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal(); + layerOut.exp_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal(); + layerOut.linear_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal(); + layerOut.width = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal(); +} void LLEnvironment::getAtmosphericModelSettings(AtmosphericModelSettings& settingsOut, const LLSettingsSky::ptr_t &psky) { @@ -894,13 +902,9 @@ void LLEnvironment::getAtmosphericModelSettings(AtmosphericModelSettings& settin settingsOut.m_rayleighProfile.clear(); for (LLSD::array_iterator itf = rayleigh.beginArray(); itf != rayleigh.endArray(); ++itf) { - atmosphere::DensityProfileLayer layer; + DensityLayer layer; LLSD& layerConfig = (*itf); - layer.constant_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal(); - layer.exp_scale = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal(); - layer.exp_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal(); - layer.linear_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal(); - layer.width = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal(); + LayerConfigToDensityLayer(layerConfig, layer); settingsOut.m_rayleighProfile.push_back(layer); } @@ -908,13 +912,9 @@ void LLEnvironment::getAtmosphericModelSettings(AtmosphericModelSettings& settin settingsOut.m_mieProfile.clear(); for (LLSD::array_iterator itf = mie.beginArray(); itf != mie.endArray(); ++itf) { - atmosphere::DensityProfileLayer layer; + DensityLayer layer; LLSD& layerConfig = (*itf); - layer.constant_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal(); - layer.exp_scale = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal(); - layer.exp_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal(); - layer.linear_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal(); - layer.width = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal(); + LayerConfigToDensityLayer(layerConfig, layer); settingsOut.m_mieProfile.push_back(layer); } settingsOut.m_mieAnisotropy = psky->getMieAnisotropy(); @@ -923,13 +923,9 @@ void LLEnvironment::getAtmosphericModelSettings(AtmosphericModelSettings& settin settingsOut.m_absorptionProfile.clear(); for (LLSD::array_iterator itf = absorption.beginArray(); itf != absorption.endArray(); ++itf) { - atmosphere::DensityProfileLayer layer; + DensityLayer layer; LLSD& layerConfig = (*itf); - layer.constant_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM].asReal(); - layer.exp_scale = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR].asReal(); - layer.exp_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM].asReal(); - layer.linear_term = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM].asReal(); - layer.width = layerConfig[LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH].asReal(); + LayerConfigToDensityLayer(layerConfig, layer); settingsOut.m_absorptionProfile.push_back(layer); } } diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index 3f2a89be88..f05f0fb021 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -248,28 +248,6 @@ BOOL LLFloaterEditExtDayCycle::postBuild() S32 tab_count = tab_container->getTabCount(); LLSettingsEditPanel *panel = nullptr; - - // Add or remove density tab as necessary - // Must be before operation on all tabs below - if (gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics")) - { - panel = dynamic_cast(tab_container->findChildView("panel_settings_sky_density")); - if (!panel) - { - panel = new LLPanelSettingsSkyDensityTab; - panel->buildFromFile("panel_settings_sky_density.xml"); - tab_container->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(false)); - } - } - else - { - panel = dynamic_cast(tab_container->findChildView("panel_settings_sky_density")); - if (panel) - { - tab_container->removeTabPanel(panel); - } - delete panel; - } for (S32 idx = 0; idx < tab_count; ++idx) { @@ -1261,29 +1239,6 @@ void LLFloaterEditExtDayCycle::updateSkyTabs(const LLSettingsSkyPtr_t &p_sky) { panel->setSky(p_sky); } - - if (gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics")) - { - panel = dynamic_cast(tab_container->findChildView("panel_settings_sky_density")); - if (!panel) - { - panel = new LLPanelSettingsSkyDensityTab; - panel->buildFromFile("panel_settings_sky_density.xml"); - panel->setOnDirtyFlagChanged([this](LLPanel *, bool value) { onPanelDirtyFlagChanged(value); }); - tab_container->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(false)); - } - panel->setSky(std::static_pointer_cast(p_sky)); - } - else - { - panel = dynamic_cast(tab_container->findChildView("panel_settings_sky_density")); - if (panel) - { - tab_container->removeTabPanel(panel); - delete panel; - } - } - } void LLFloaterEditExtDayCycle::updateLabels() diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index b7e92e7e56..f08c36a7e7 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -795,14 +795,6 @@ BOOL LLFloaterFixedEnvironmentSky::postBuild() panel->setOnDirtyFlagChanged([this](LLPanel *, bool value) { onPanelDirtyFlagChanged(value); }); mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(false)); - if (gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics")) - { - panel = new LLPanelSettingsSkyDensityTab; - panel->buildFromFile("panel_settings_sky_density.xml"); - panel->setSky(std::static_pointer_cast(mSettings)); - panel->setOnDirtyFlagChanged([this](LLPanel *, bool value) { onPanelDirtyFlagChanged(value); }); - mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(false)); - } return TRUE; } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index ebc55fa0dd..88984d518a 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -410,17 +410,6 @@ static bool handleRenderDeferredChanged(const LLSD& newvalue) return true; } -static bool handleRenderUseAdvancedAtmosphericsChanged(const LLSD& newvalue) -{ - if (gPipeline.isInit()) - { - LLPipeline::refreshCachedSettings(); - // Need to reload shaders when changing atmospherics implementations... - LLViewerShaderMgr::instance()->setShaders(); - } - return true; -} - // This looks a great deal like handleRenderDeferredChanged because // Advanced Lighting (Materials) implies bumps and shiny so disabling // bumps should further disable that feature. @@ -655,7 +644,6 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2)); gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2)); gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2)); - gSavedSettings.getControl("RenderUseAdvancedAtmospherics")->getSignal()->connect(boost::bind(&handleRenderUseAdvancedAtmosphericsChanged, _2)); gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 2d4478bfdb..5d01e7e584 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1021,11 +1021,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) } } - if (LLPipeline::sRenderDeferred && gAtmosphere && gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics")) - { - gPipeline.generateSkyIndirect(); - } - if (LLPipeline::sRenderDeferred) { gPipeline.renderDeferredLighting(&gPipeline.mScreen); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 1e46a1cf9e..a7151c4d1b 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3072,6 +3072,7 @@ void LLViewerObject::unlinkControlAvatar() if (mControlAvatar) { mControlAvatar->markForDeath(); + mControlAvatar->mRootVolp = NULL; mControlAvatar = NULL; } } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 319ae3b9a7..1f5778db61 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -242,10 +242,6 @@ LLGLSLShader gDeferredSkinnedFullbrightShinyProgram; LLGLSLShader gDeferredSkinnedFullbrightProgram; LLGLSLShader gNormalMapGenProgram; -LLGLSLShader gDeferredGenSkyShProgram; -LLGLSLShader gDeferredGatherSkyShProgram; -LLGLSLShader gDeferredShVisProgram; - // Deferred materials shaders LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; @@ -341,10 +337,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredWLCloudProgram); mShaderList.push_back(&gDeferredWLCloudShadowProgram); mShaderList.push_back(&gDeferredWLMoonProgram); - mShaderList.push_back(&gDeferredWLSunProgram); - mShaderList.push_back(&gDeferredGenSkyShProgram); - mShaderList.push_back(&gDeferredGatherSkyShProgram); - mShaderList.push_back(&gDeferredShVisProgram); + mShaderList.push_back(&gDeferredWLSunProgram); } LLViewerShaderMgr::~LLViewerShaderMgr() @@ -1294,10 +1287,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredMaterialProgram[i].unload(); gDeferredMaterialWaterProgram[i].unload(); } - - gDeferredGenSkyShProgram.unload(); - gDeferredGatherSkyShProgram.unload(); - gDeferredShVisProgram.unload(); return TRUE; } @@ -2042,14 +2031,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { //if using SSAO, take screen space light map into account as if shadows are enabled gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2); } - - // insure we use class3/deferred version of softenLight for advanced atmo.. - gDeferredSoftenProgram.mShaderLevel = gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics") ? 3 : gDeferredSoftenProgram.mShaderLevel; - - if (gAtmosphere && gDeferredSoftenProgram.mShaderLevel > 2) - { - gDeferredSoftenProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); - } success = gDeferredSoftenProgram.createShader(NULL, NULL); llassert(success); @@ -2075,11 +2056,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSoftenWaterProgram.mFeatures.isDeferred = true; gDeferredSoftenWaterProgram.mFeatures.hasShadows = true; - if (gAtmosphere && gDeferredSoftenWaterProgram.mShaderLevel > 2) - { - gDeferredSoftenWaterProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); - } - if (gSavedSettings.getBOOL("RenderDeferredSSAO")) { //if using SSAO, take screen space light map into account as if shadows are enabled gDeferredSoftenWaterProgram.mShaderLevel = llmax(gDeferredSoftenWaterProgram.mShaderLevel, 2); @@ -2355,10 +2331,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT]; gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; - if (gAtmosphere && gDeferredWLSkyProgram.mShaderLevel > 2) - { - gDeferredWLSkyProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); - } + success = gDeferredWLSkyProgram.createShader(NULL, NULL); llassert(success); } @@ -2376,10 +2349,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT]; gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; - if (gAtmosphere && gDeferredWLCloudProgram.mShaderLevel > 2) - { - gDeferredWLCloudProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); - } + success = gDeferredWLCloudProgram.createShader(NULL, NULL); llassert(success); } @@ -2402,40 +2372,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success && gAtmosphere && (mShaderLevel[SHADER_WINDLIGHT] > 2)) - { - gDeferredGenSkyShProgram.mName = "Deferred Generate Sky Indirect SH Program"; - gDeferredGenSkyShProgram.mShaderFiles.clear(); - gDeferredGenSkyShProgram.mShaderFiles.push_back(make_pair("deferred/genSkyShV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredGenSkyShProgram.mShaderFiles.push_back(make_pair("deferred/genSkyShF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredGenSkyShProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT]; - gDeferredGenSkyShProgram.mExtraLinkObject = gAtmosphere->getAtmosphericShaderForLink(); - success = gDeferredGenSkyShProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success && gAtmosphere && (mShaderLevel[SHADER_WINDLIGHT] > 2)) - { - gDeferredGatherSkyShProgram.mName = "Deferred Gather Sky Indirect SH Program"; - gDeferredGatherSkyShProgram.mShaderFiles.clear(); - gDeferredGatherSkyShProgram.mShaderFiles.push_back(make_pair("deferred/gatherSkyShV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredGatherSkyShProgram.mShaderFiles.push_back(make_pair("deferred/gatherSkyShF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredGatherSkyShProgram.mShaderLevel = 3; - success = gDeferredGatherSkyShProgram.createShader(NULL, NULL); - llassert(success); - } - - if (success) - { - gDeferredShVisProgram.mName = "Deferred SH Vis Program"; - gDeferredShVisProgram.mShaderFiles.clear(); - gDeferredShVisProgram.mShaderFiles.push_back(make_pair("deferred/shVisV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredShVisProgram.mShaderFiles.push_back(make_pair("deferred/shVisF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredShVisProgram.mShaderLevel = 3; - success = gDeferredShVisProgram.createShader(NULL, NULL); - llassert(success); - } - if (success) { gDeferredWLSunProgram.mName = "Deferred Windlight Sun Program"; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index e55b59d4e2..8e1801612e 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -329,9 +329,6 @@ extern LLGLSLShader gDeferredSkinnedFullbrightShinyProgram; extern LLGLSLShader gDeferredSkinnedFullbrightProgram; extern LLGLSLShader gNormalMapGenProgram; -extern LLGLSLShader gDeferredGenSkyShProgram; -extern LLGLSLShader gDeferredGatherSkyShProgram; -extern LLGLSLShader gDeferredShVisProgram; // Deferred materials shaders extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index cc030dfb60..d13b926930 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -9745,7 +9745,7 @@ void LLVOAvatar::updateImpostors() iter != instances_copy.end(); ++iter) { LLVOAvatar* avatar = (LLVOAvatar*) *iter; - if (!avatar->isDead() && avatar->isVisible() + if (avatar && !avatar->isDead() && avatar->isVisible() && ( (avatar->isImpostor() || LLVOAvatar::AV_DO_NOT_RENDER == avatar->getVisualMuteSettings()) && avatar->needsImpostorUpdate()) ) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 73e78aadd0..7e8e401470 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -326,7 +326,6 @@ bool LLPipeline::sRenderBump = true; bool LLPipeline::sBakeSunlight = false; bool LLPipeline::sNoAlpha = false; bool LLPipeline::sUseTriStrips = true; -bool LLPipeline::sUseAdvancedAtmospherics = false; bool LLPipeline::sUseFarClip = true; bool LLPipeline::sShadowRender = false; bool LLPipeline::sWaterReflections = false; @@ -972,18 +971,6 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) } } - // for EEP atmospherics - bool allocated_sh0 = mSkySH.allocate(64, 64, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_TEXTURE); - if (!allocated_sh0) - { - return false; - } - else - { - mSkySH.addColorAttachment(GL_RGBA16F_ARB); - mSkySH.addColorAttachment(GL_RGBA16F_ARB); - } - U32 width = (U32) (resX*scale); U32 height = width; @@ -1098,7 +1085,6 @@ void LLPipeline::refreshCachedSettings() RenderAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP"); WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); RenderDeferred = gSavedSettings.getBOOL("RenderDeferred"); - sUseAdvancedAtmospherics = WindLightUseAtmosShaders && gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics"); RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash"); RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples"); RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor"); @@ -5382,55 +5368,6 @@ void LLPipeline::renderDebug() visible_selected_groups.clear(); - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SH) && gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics") && LLPipeline::sRenderDeferred) - { - bindDeferredShader(gDeferredShVisProgram); - - S32 l1r_channel = gDeferredShVisProgram.enableTexture(LLShaderMgr::SH_INPUT_L1R, gPipeline.mSkySH.getUsage()); - if (l1r_channel > -1) - { - gPipeline.mSkySH.bindTexture(0,l1r_channel); - gGL.getTexUnit(l1r_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - S32 l1b_channel = gDeferredShVisProgram.enableTexture(LLShaderMgr::SH_INPUT_L1G, gPipeline.mSkySH.getUsage()); - if (l1b_channel > -1) - { - gPipeline.mSkySH.bindTexture(1,l1b_channel); - gGL.getTexUnit(l1b_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - S32 l1g_channel = gDeferredShVisProgram.enableTexture(LLShaderMgr::SH_INPUT_L1B, gPipeline.mSkySH.getUsage()); - if (l1g_channel > -1) - { - gPipeline.mSkySH.bindTexture(2,l1g_channel); - gGL.getTexUnit(l1g_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE, GL_FALSE, GL_ALWAYS); - - LLVector3 pos = LLViewerCamera::instance().getOrigin(); - pos += LLViewerCamera::instance().getAtAxis() * 10.0f; - - gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - - gGL.begin(LLRender::TRIANGLES); - gGL.texCoord2f(0.0f, 0.0f); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(0.0f, 1.0f); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(1.0f, 0.0f); - gGL.vertex2f(3,-1); - - gGL.end(); - gGL.flush(); - - unbindDeferredShader(gDeferredShVisProgram); - } - if (LLGLSLShader::sNoFixedFunction) { gUIProgram.bind(); @@ -8748,27 +8685,6 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target) LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); - - S32 l1r_channel = soften_shader.enableTexture(LLShaderMgr::SH_INPUT_L1R, mSkySH.getUsage()); - if (l1r_channel > -1) - { - mSkySH.bindTexture(0,l1r_channel); - gGL.getTexUnit(l1r_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - S32 l1b_channel = soften_shader.enableTexture(LLShaderMgr::SH_INPUT_L1G, mSkySH.getUsage()); - if (l1b_channel > -1) - { - mSkySH.bindTexture(1,l1b_channel); - gGL.getTexUnit(l1b_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - S32 l1g_channel = soften_shader.enableTexture(LLShaderMgr::SH_INPUT_L1B, mSkySH.getUsage()); - if (l1g_channel > -1) - { - mSkySH.bindTexture(2,l1g_channel); - gGL.getTexUnit(l1g_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } //full screen blit gGL.pushMatrix(); @@ -9420,11 +9336,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glh::matrix4f projection = get_current_projection(); glh::matrix4f mat; - stop_glerror(); - LLPlane plane; - S32 detail = RenderReflectionDetail; - bool materials_in_water = LLPipeline::sRenderDeferred && gSavedSettings.getS32("RenderWaterMaterials"); F32 water_height = gAgent.getRegion()->getWaterHeight(); @@ -9440,6 +9352,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) camera.setOriginAndLookAt(reflect_origin, LLVector3::z_axis, reflect_interest_point); //plane params + LLPlane plane; LLVector3 pnorm; S32 water_clip = 0; if (!LLViewerCamera::getInstance()->cameraUnderWater()) @@ -9605,8 +9518,10 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLPipeline::sUseOcclusion = occlusion; camera.setOrigin(camera_in.getOrigin()); + //render distortion map static bool last_update = true; + if (last_update) { camera.setFar(camera_in.getFar()); @@ -10232,183 +10147,6 @@ LLRenderTarget* LLPipeline::getShadowTarget(U32 i) return &mShadow[i]; } -static LLTrace::BlockTimerStatHandle FTM_GEN_SKY_INDIRECT("Gen Sky Indirect"); - -void LLPipeline::generateSkyIndirect() -{ - if (!sRenderDeferred || !gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics")) - { - return; - } - - LL_RECORD_BLOCK_TIME(FTM_GEN_SKY_INDIRECT); - - gGL.setColorMask(true, true); - - LLVertexBuffer::unbind(); - - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - - mSkySH.bindTarget(); - - bindDeferredShader(gDeferredGenSkyShProgram, &mSkySH); - - gDeferredGenSkyShProgram.bind(); - - llassert(gAtmosphere); - - int channel = -1; - - if (gAtmosphere) - { - // bind precomputed textures necessary for calculating sun and sky luminance - channel = gDeferredGenSkyShProgram.enableTexture(LLShaderMgr::TRANSMITTANCE_TEX, LLTexUnit::TT_TEXTURE); - if (channel > -1) - { - gDeferredGenSkyShProgram.bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance()); - } - - channel = gDeferredGenSkyShProgram.enableTexture(LLShaderMgr::SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D); - if (channel > -1) - { - gDeferredGenSkyShProgram.bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering()); - } - - channel = gDeferredGenSkyShProgram.enableTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D); - if (channel > -1) - { - gDeferredGenSkyShProgram.bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering()); - } - - channel = gDeferredGenSkyShProgram.enableTexture(LLShaderMgr::ILLUMINANCE_TEX, LLTexUnit::TT_TEXTURE); - if (channel > -1) - { - gDeferredGenSkyShProgram.bindTexture(LLShaderMgr::ILLUMINANCE_TEX, gAtmosphere->getIlluminance()); - } - } - - gDeferredGenSkyShProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mSkySH.getWidth(), mSkySH.getHeight()); - - LLStrider vertices; - LLStrider texCoords; - LLStrider indices; - - if (!mDeferredVB->allocateBuffer(4, 6, TRUE)) - { - LL_WARNS() << "Failed to allocate Vertex Buffer on full screen sky update" << LL_ENDL; - } - - BOOL success = mDeferredVB->getVertexStrider(vertices) - && mDeferredVB->getTexCoord0Strider(texCoords) - && mDeferredVB->getIndexStrider(indices); - - if(!success) - { - LL_ERRS() << "Failed updating WindLight fullscreen sky geometry." << LL_ENDL; - } - - *vertices++ = LLVector3(-1.0f, -1.0f, 0.0f); - *vertices++ = LLVector3( 1.0f, -1.0f, 0.0f); - *vertices++ = LLVector3(-1.0f, 1.0f, 0.0f); - *vertices++ = LLVector3( 1.0f, 1.0f, 0.0f); - - *texCoords++ = LLVector2(0.0f, 0.0f); - *texCoords++ = LLVector2(1.0f, 0.0f); - *texCoords++ = LLVector2(0.0f, 1.0f); - *texCoords++ = LLVector2(1.0f, 1.0f); - - *indices++ = 0; - *indices++ = 1; - *indices++ = 2; - *indices++ = 1; - *indices++ = 3; - *indices++ = 2; - - mDeferredVB->flush(); - - glClearColor(0,0,0,0); - mSkySH.clear(GL_COLOR_BUFFER_BIT); - - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE, GL_FALSE, GL_ALWAYS); - - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); - mDeferredVB->drawRange(LLRender::TRIANGLES, 0, mDeferredVB->getNumVerts() - 1, mDeferredVB->getNumIndices(), 0); - stop_glerror(); - - gDeferredGenSkyShProgram.disableTexture(LLShaderMgr::TRANSMITTANCE_TEX); - gDeferredGenSkyShProgram.disableTexture(LLShaderMgr::SCATTER_TEX); - gDeferredGenSkyShProgram.disableTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX); - gDeferredGenSkyShProgram.disableTexture(LLShaderMgr::ILLUMINANCE_TEX); - gDeferredGenSkyShProgram.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->activate(); - gDeferredGenSkyShProgram.unbind(); - - mSkySH.flush(); - -#if GATHER_SKY_SH - gDeferredGatherSkyShProgram.bind(); - - S32 res = mSkySH[0].getWidth(); - S32 ping = 0; - - while (res > 1) - { - S32 pong = 1 - ping; - S32 l1r_channel = gDeferredGatherSkyShProgram.enableTexture(LLShaderMgr::SH_INPUT_L1R, mSkySH[ping].getUsage()); - if (l1r_channel > -1) - { - mSkySH[ping].bindTexture(0,l1r_channel); - gGL.getTexUnit(l1r_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - S32 l1b_channel = gDeferredGatherSkyShProgram.enableTexture(LLShaderMgr::SH_INPUT_L1G, mSkySH[ping].getUsage()); - if (l1b_channel > -1) - { - mSkySH[ping].bindTexture(1,l1b_channel); - gGL.getTexUnit(l1b_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - S32 l1g_channel = gDeferredGatherSkyShProgram.enableTexture(LLShaderMgr::SH_INPUT_L1B, mSkySH[ping].getUsage()); - if (l1g_channel > -1) - { - mSkySH[ping].bindTexture(2,l1g_channel); - gGL.getTexUnit(l1g_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - gDeferredGatherSkyShProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, res >> 1, res >> 1); - - glViewport(0, 0, res >> 1, res >> 1); - - mSkySH[pong].bindTarget(); - - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); - mDeferredVB->drawRange(LLRender::TRIANGLES, 0, mDeferredVB->getNumVerts() - 1, mDeferredVB->getNumIndices(), 0); - stop_glerror(); - - mSkySH[pong].flush(); - - gGL.getTexUnit(l1r_channel)->unbind(mSkySH[ping].getUsage()); - gGL.getTexUnit(l1b_channel)->unbind(mSkySH[ping].getUsage()); - gGL.getTexUnit(l1g_channel)->unbind(mSkySH[ping].getUsage()); - - ping ^= 1; - res >>= 1; - } -#endif - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); -} - static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow"); void LLPipeline::generateSunShadow(LLCamera& camera) @@ -11877,8 +11615,3 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id ) } } -bool LLPipeline::useAdvancedAtmospherics() const -{ - return sUseAdvancedAtmospherics; -} - diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c94a69eaf0..c41fd0189c 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -287,7 +287,6 @@ public: void generateSunShadow(LLCamera& camera); LLRenderTarget* getShadowTarget(U32 i); - void generateSkyIndirect(); void generateHighlight(LLCamera& camera); void renderHighlight(const LLViewerObject* obj, F32 fade); void setHighlightObject(LLDrawable* obj) { mHighlightObject = obj; } @@ -545,8 +544,6 @@ public: void updateCamera(bool reset = false); - bool useAdvancedAtmospherics() const; - LLVector3 mFlyCamPosition; LLQuaternion mFlyCamRotation; @@ -574,7 +571,6 @@ public: static bool sBakeSunlight; static bool sNoAlpha; static bool sUseTriStrips; - static bool sUseAdvancedAtmospherics; static bool sUseFarClip; static bool sShadowRender; static bool sWaterReflections; @@ -659,9 +655,6 @@ public: //texture for making the glow LLRenderTarget mGlow[3]; - // texture for SH indirect sky contribution - LLRenderTarget mSkySH; - //noise map U32 mNoiseMap; U32 mTrueNoiseMap; -- cgit v1.3 From 192aee0f191e6070b91be066b599b8dc3302a5e1 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 31 Jan 2020 15:05:51 +0000 Subject: Merged in SL-11445 Upgrade Fmodex to Fmod Studio --- autobuild.xml | 78 +++ indra/cmake/CMakeLists.txt | 1 + indra/cmake/Copy3rdPartyLibs.cmake | 16 +- indra/cmake/FMODEX.cmake | 10 +- indra/cmake/FMODSTUDIO.cmake | 38 ++ indra/llaudio/CMakeLists.txt | 18 + indra/llaudio/llaudioengine_fmodstudio.cpp | 659 ++++++++++++++++++++++++++ indra/llaudio/llaudioengine_fmodstudio.h | 130 +++++ indra/llaudio/lllistener_fmodstudio.cpp | 138 ++++++ indra/llaudio/lllistener_fmodstudio.h | 65 +++ indra/llaudio/llstreamingaudio_fmodstudio.cpp | 392 +++++++++++++++ indra/llaudio/llstreamingaudio_fmodstudio.h | 73 +++ indra/newview/CMakeLists.txt | 33 +- indra/newview/llstartup.cpp | 15 +- indra/newview/viewer_manifest.py | 77 ++- 15 files changed, 1711 insertions(+), 32 deletions(-) create mode 100644 indra/cmake/FMODSTUDIO.cmake create mode 100644 indra/llaudio/llaudioengine_fmodstudio.cpp create mode 100644 indra/llaudio/llaudioengine_fmodstudio.h create mode 100644 indra/llaudio/lllistener_fmodstudio.cpp create mode 100644 indra/llaudio/lllistener_fmodstudio.h create mode 100644 indra/llaudio/llstreamingaudio_fmodstudio.cpp create mode 100644 indra/llaudio/llstreamingaudio_fmodstudio.h (limited to 'indra/cmake') diff --git a/autobuild.xml b/autobuild.xml index 1f1db48bdc..d119746780 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -817,6 +817,84 @@ version 4.44.64.501533 + fmodstudio + + copyright + FMOD Studio by Firelight Technologies Pty Ltd. + description + FMOD Studio API + license + fmod + license_file + LICENSES/fmodstudio.txt + name + fmodstudio + platforms + + darwin64 + + archive + + hash + 5b65500b8992f96d409c79bc9a694ec6 + url + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/50234/453770/fmodstudio-2.00.07.535399-darwin64-535399.tar.bz2 + + name + darwin64 + + linux + + archive + + hash + 3dec74f5af59ee8ad44bc6da77582167 + url + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/50231/453756/fmodstudio-2.00.07.535399-linux-535399.tar.bz2 + + name + linux + + linux64 + + archive + + hash + 3dec74f5af59ee8ad44bc6da77582167 + url + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/50231/453756/fmodstudio-2.00.07.535399-linux-535399.tar.bz2 + + name + linux64 + + windows + + archive + + hash + 6e5855d0703f496ad8d61f9d9c6ae6a9 + url + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/50236/453775/fmodstudio-2.00.07.535399-windows-535399.tar.bz2 + + name + windows + + windows64 + + archive + + hash + a1677997916de45b860c20b83103ff3d + url + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/50233/453772/fmodstudio-2.00.07.535399-windows64-535399.tar.bz2 + + name + windows64 + + + version + 2.00.07.535399 + fontconfig copyright diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 84e1c5d6fd..6dbf26c4a9 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -40,6 +40,7 @@ set(cmake_SOURCE_FILES FindXmlRpcEpi.cmake FindZLIB.cmake FMODEX.cmake + FMODSTUDIO.cmake FreeType.cmake GLEXT.cmake GLH.cmake diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index c73a1fdb47..f7904cc5d7 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -63,7 +63,6 @@ if(WINDOWS) endif (BUGSPLAT_DB) if (FMODEX) - if(ADDRESS_SIZE EQUAL 32) set(release_files ${release_files} fmodex.dll) else(ADDRESS_SIZE EQUAL 32) @@ -71,6 +70,11 @@ if(WINDOWS) endif(ADDRESS_SIZE EQUAL 32) endif (FMODEX) + if (FMODSTUDIO) + set(debug_files ${debug_files} fmodL.dll) + set(release_files ${release_files} fmod.dll) + endif (FMODSTUDIO) + #******************************* # Copy MS C runtime dlls, required for packaging. # *TODO - Adapt this to support VC9 @@ -197,6 +201,11 @@ elseif(DARWIN) set(release_files ${release_files} libfmodex.dylib) endif (FMODEX) + if (FMODSTUDIO) + set(debug_files ${debug_files} libfmodL.dylib) + set(release_files ${release_files} libfmod.dylib) + endif (FMODSTUDIO) + elseif(LINUX) # linux is weird, multiple side by side configurations aren't supported # and we don't seem to have any debug shared libs built yet anyways... @@ -247,6 +256,11 @@ elseif(LINUX) set(release_files ${release_files} "libfmodex.so") endif (FMODEX) + if (FMODSTUDIO) + set(debug_files ${debug_files} "libfmodL.so") + set(release_files ${release_files} "libfmod.so") + endif (FMODSTUDIO) + else(WINDOWS) message(STATUS "WARNING: unrecognized platform for staging 3rd party libs, skipping...") set(vivox_lib_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/i686-linux") diff --git a/indra/cmake/FMODEX.cmake b/indra/cmake/FMODEX.cmake index 720933d1b7..25add0c8f2 100644 --- a/indra/cmake/FMODEX.cmake +++ b/indra/cmake/FMODEX.cmake @@ -1,13 +1,9 @@ # -*- cmake -*- -# FMOD can be set when launching the make using the argument -DFMOD:BOOL=ON -# When building using proprietary binaries though (i.e. having access to LL private servers), -# we always build with FMODEX. -# Open source devs should use the -DFMODEX:BOOL=ON then if they want to build with FMOD, whether +# FMODEX can be set when launching the make using the argument -DFMOD:BOOL=ON +# No longer used by default, see FMODSTRUDIO. +# Open source devs should use the -DFMODEX:BOOL=ON then if they want to build with FMODEX, whether # they are using USESYSTEMLIBS or not. -if (INSTALL_PROPRIETARY) - set(FMODEX ON CACHE BOOL "Using FMOD Ex sound library.") -endif (INSTALL_PROPRIETARY) if (FMODEX) if (USESYSTEMLIBS) diff --git a/indra/cmake/FMODSTUDIO.cmake b/indra/cmake/FMODSTUDIO.cmake new file mode 100644 index 0000000000..1539270d6c --- /dev/null +++ b/indra/cmake/FMODSTUDIO.cmake @@ -0,0 +1,38 @@ +# -*- cmake -*- + +# FMODSTUDIO can be set when launching the make using the argument -DFMODSTUDIO:BOOL=ON +# When building using proprietary binaries though (i.e. having access to LL private servers), +# we always build with FMODSTUDIO. +if (INSTALL_PROPRIETARY) + set(FMODSTUDIO ON CACHE BOOL "Using FMODSTUDIO sound library.") +endif (INSTALL_PROPRIETARY) + +if (FMODSTUDIO) + if (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR) + # If the path have been specified in the arguments, use that + set(FMODSTUDIO_LIBRARIES ${FMODSTUDIO_LIBRARY}) + else (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR) + # If not, we're going to try to get the package listed in autobuild.xml + # Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL) + # as accessing the private LL location will fail if you don't have the credential + include(Prebuilt) + use_prebuilt_binary(fmodstudio) + if (WINDOWS) + set(FMODSTUDIO_LIBRARY + debug fmodL_vc + optimized fmod_vc) + elseif (DARWIN) + #despite files being called libfmod.dylib, we are searching for fmod + set(FMODSTUDIO_LIBRARY + debug fmodL + optimized fmod) + elseif (LINUX) + set(FMODEX_LIBRARY + debug fmodL + optimized fmod) + endif (WINDOWS) + set(FMODSTUDIO_LIBRARIES ${FMODSTUDIO_LIBRARY}) + set(FMODSTUDIO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodstudio) + endif (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR) +endif (FMODSTUDIO) + diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index e943dd5d5c..6d7030f548 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -5,6 +5,7 @@ project(llaudio) include(00-Common) include(LLAudio) include(FMODEX) +include(FMODSTUDIO) include(OPENAL) include(LLCommon) include(LLMath) @@ -59,6 +60,23 @@ if (FMODEX) ) endif (FMODEX) +if (FMODSTUDIO) + include_directories( + ${FMODSTUDIO_INCLUDE_DIR} + ) + list(APPEND llaudio_SOURCE_FILES + llaudioengine_fmodstudio.cpp + lllistener_fmodstudio.cpp + llstreamingaudio_fmodstudio.cpp + ) + + list(APPEND llaudio_HEADER_FILES + llaudioengine_fmodstudio.h + lllistener_fmodstudio.h + llstreamingaudio_fmodstudio.h + ) +endif (FMODSTUDIO) + if (OPENAL) list(APPEND llaudio_SOURCE_FILES llaudioengine_openal.cpp diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp new file mode 100644 index 0000000000..ec66d590b7 --- /dev/null +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -0,0 +1,659 @@ +/** + * @file audioengine_fmodstudio.cpp + * @brief Implementation of LLAudioEngine class abstracting the audio + * support as a FMODSTUDIO implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, 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 "linden_common.h" + +#include "llstreamingaudio.h" +#include "llstreamingaudio_fmodstudio.h" + +#include "llaudioengine_fmodstudio.h" +#include "lllistener_fmodstudio.h" + +#include "llerror.h" +#include "llmath.h" +#include "llrand.h" + +#include "fmodstudio/fmod.hpp" +#include "fmodstudio/fmod_errors.h" +#include "lldir.h" +#include "llapr.h" + +#include "sound_ids.h" + +FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels); + +FMOD::ChannelGroup *LLAudioEngine_FMODSTUDIO::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0}; + +LLAudioEngine_FMODSTUDIO::LLAudioEngine_FMODSTUDIO(bool enable_profiler) +{ + mInited = false; + mWindGen = NULL; + mWindDSP = NULL; + mSystem = NULL; + mEnableProfiler = enable_profiler; + mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); +} + + +LLAudioEngine_FMODSTUDIO::~LLAudioEngine_FMODSTUDIO() +{ + delete mWindDSPDesc; +} + + +static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) +{ + if (result == FMOD_OK) + return false; + LL_DEBUGS() << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; + return true; +} + +bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata) +{ + U32 version; + FMOD_RESULT result; + + LL_DEBUGS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() initializing FMOD" << LL_ENDL; + + result = FMOD::System_Create(&mSystem); + if (Check_FMOD_Error(result, "FMOD::System_Create")) + return false; + + //will call LLAudioEngine_FMODSTUDIO::allocateListener, which needs a valid mSystem pointer. + LLAudioEngine::init(num_channels, userdata); + + result = mSystem->getVersion(&version); + Check_FMOD_Error(result, "FMOD::System::getVersion"); + + if (version < FMOD_VERSION) + { + LL_WARNS("AppInit") << "FMOD Studio version mismatch, actual: " << version + << " expected:" << FMOD_VERSION << LL_ENDL; + } + + // In this case, all sounds, PLUS wind and stream will be software. + result = mSystem->setSoftwareChannels(num_channels + 2); + Check_FMOD_Error(result, "FMOD::System::setSoftwareChannels"); + + FMOD_ADVANCEDSETTINGS settings; + memset(&settings, 0, sizeof(settings)); + settings.cbSize = sizeof(FMOD_ADVANCEDSETTINGS); + settings.resamplerMethod = FMOD_DSP_RESAMPLER_LINEAR; + + result = mSystem->setAdvancedSettings(&settings); + Check_FMOD_Error(result, "FMOD::System::setAdvancedSettings"); + + U32 fmod_flags = FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED | FMOD_INIT_THREAD_UNSAFE; + if (mEnableProfiler) + { + fmod_flags |= FMOD_INIT_PROFILE_ENABLE; + } + + // initialize the FMOD engine + // number of channel in this case looks to be identiacal to number of max simultaneously + // playing objects and we can set practically any number + result = mSystem->init(num_channels + 2, fmod_flags, 0); + if (Check_FMOD_Error(result, "Error initializing FMOD Studio")) + { + // If it fails here and (result == FMOD_ERR_OUTPUT_CREATEBUFFER), + // we can retry with other settings + return false; + } + + // set up our favourite FMOD-native streaming audio implementation if none has already been added + if (!getStreamingAudioImpl()) // no existing implementation added + setStreamingAudioImpl(new LLStreamingAudio_FMODSTUDIO(mSystem)); + + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() FMOD Studio initialized correctly" << LL_ENDL; + + int r_numbuffers, r_samplerate, r_channels; + unsigned int r_bufferlength; + char r_name[512]; + int latency = 100; + mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers); + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL; + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_numbuffers=" << r_numbuffers << LL_ENDL; + + mSystem->getDriverInfo(0, r_name, 511, NULL, &r_samplerate, NULL, &r_channels); + r_name[511] = '\0'; + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_name=\"" << r_name << "\"" << LL_ENDL; + + if (r_samplerate != 0) + latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate); + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): latency=" << latency << "ms" << LL_ENDL; + + mInited = true; + + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): initialization complete." << LL_ENDL; + + return true; +} + + +std::string LLAudioEngine_FMODSTUDIO::getDriverName(bool verbose) +{ + llassert_always(mSystem); + if (verbose) + { + U32 version; + if (!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion")) + { + return llformat("FMOD Studio %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF); + } + } + return "FMODSTUDIO"; +} + + +void LLAudioEngine_FMODSTUDIO::allocateListener(void) +{ + mListenerp = (LLListener *) new LLListener_FMODSTUDIO(mSystem); + if (!mListenerp) + { + LL_WARNS() << "Listener creation failed" << LL_ENDL; + } +} + + +void LLAudioEngine_FMODSTUDIO::shutdown() +{ + stopInternetStream(); + + LL_INFOS() << "About to LLAudioEngine::shutdown()" << LL_ENDL; + LLAudioEngine::shutdown(); + + LL_INFOS() << "LLAudioEngine_FMODSTUDIO::shutdown() closing FMOD Studio" << LL_ENDL; + if (mSystem) + { + mSystem->close(); + mSystem->release(); + } + LL_INFOS() << "LLAudioEngine_FMODSTUDIO::shutdown() done closing FMOD Studio" << LL_ENDL; + + delete mListenerp; + mListenerp = NULL; +} + + +LLAudioBuffer * LLAudioEngine_FMODSTUDIO::createBuffer() +{ + return new LLAudioBufferFMODSTUDIO(mSystem); +} + + +LLAudioChannel * LLAudioEngine_FMODSTUDIO::createChannel() +{ + return new LLAudioChannelFMODSTUDIO(mSystem); +} + +bool LLAudioEngine_FMODSTUDIO::initWind() +{ + mNextWindUpdate = 0.0; + + if (!mWindDSP) + { + memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero + strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name)); + mWindDSPDesc->pluginsdkversion = FMOD_PLUGIN_SDK_VERSION; + mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads + if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) + return false; + + if (mWindGen) + delete mWindGen; + + int frequency = 44100; + + FMOD_SPEAKERMODE mode; + if (Check_FMOD_Error(mSystem->getSoftwareFormat(&frequency, &mode, nullptr), "FMOD::System::getSoftwareFormat")) + { + cleanupWind(); + return false; + } + + mWindGen = new LLWindGen((U32)frequency); + + if (Check_FMOD_Error(mWindDSP->setUserData((void*)mWindGen), "FMOD::DSP::setUserData")) + { + cleanupWind(); + return false; + } + if (Check_FMOD_Error(mWindDSP->setChannelFormat(FMOD_CHANNELMASK_STEREO, 2, mode), "FMOD::DSP::setChannelFormat")) + { + cleanupWind(); + return false; + } + } + + // *TODO: Should this guard against multiple plays? + if (Check_FMOD_Error(mSystem->playDSP(mWindDSP, nullptr, false, nullptr), "FMOD::System::playDSP")) + { + cleanupWind(); + return false; + } + return true; +} + + +void LLAudioEngine_FMODSTUDIO::cleanupWind() +{ + if (mWindDSP) + { + FMOD::ChannelGroup* master_group = NULL; + if (!Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup") + && master_group) + { + master_group->removeDSP(mWindDSP); + } + mWindDSP->release(); + mWindDSP = NULL; + } + + delete mWindDSPDesc; + mWindDSPDesc = NULL; + + delete mWindGen; + mWindGen = NULL; +} + + +//----------------------------------------------------------------------- +void LLAudioEngine_FMODSTUDIO::updateWind(LLVector3 wind_vec, F32 camera_height_above_water) +{ + LLVector3 wind_pos; + F64 pitch; + F64 center_freq; + + if (!mEnableWind) + { + return; + } + + if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) + { + + // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up) + // need to convert this to the conventional orientation DS3D and OpenAL use + // where +X = right, +Y = up, +Z = backwards + + wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]); + + // cerr << "Wind update" << endl; + + pitch = 1.0 + mapWindVecToPitch(wind_vec); + center_freq = 80.0 * pow(pitch, 2.5*(mapWindVecToGain(wind_vec) + 1.0)); + + mWindGen->mTargetFreq = (F32)center_freq; + mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; + mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); + } +} + +//----------------------------------------------------------------------- +void LLAudioEngine_FMODSTUDIO::setInternalGain(F32 gain) +{ + if (!mInited) + { + return; + } + + gain = llclamp(gain, 0.0f, 1.0f); + + FMOD::ChannelGroup *master_group; + mSystem->getMasterChannelGroup(&master_group); + + master_group->setVolume(gain); + + LLStreamingAudioInterface *saimpl = getStreamingAudioImpl(); + if (saimpl) + { + // fmod likes its streaming audio channel gain re-asserted after + // master volume change. + saimpl->setGain(saimpl->getGain()); + } +} + +// +// LLAudioChannelFMODSTUDIO implementation +// + +LLAudioChannelFMODSTUDIO::LLAudioChannelFMODSTUDIO(FMOD::System *system) : LLAudioChannel(), mSystemp(system), mChannelp(NULL), mLastSamplePos(0) +{ +} + + +LLAudioChannelFMODSTUDIO::~LLAudioChannelFMODSTUDIO() +{ + cleanup(); +} + +bool LLAudioChannelFMODSTUDIO::updateBuffer() +{ + if (LLAudioChannel::updateBuffer()) + { + // Base class update returned true, which means that we need to actually + // set up the channel for a different buffer. + + LLAudioBufferFMODSTUDIO *bufferp = (LLAudioBufferFMODSTUDIO *)mCurrentSourcep->getCurrentBuffer(); + + // Grab the FMOD sample associated with the buffer + FMOD::Sound *soundp = bufferp->getSound(); + if (!soundp) + { + // This is bad, there should ALWAYS be a sound associated with a legit + // buffer. + LL_ERRS() << "No FMOD sound!" << LL_ENDL; + return false; + } + + + // Actually play the sound. Start it off paused so we can do all the necessary + // setup. + if (!mChannelp) + { + FMOD_RESULT result = getSystem()->playSound(soundp, NULL /*free channel?*/, true, &mChannelp); + Check_FMOD_Error(result, "FMOD::System::playSound"); + } + + // Setting up channel mChannelID + } + + // If we have a source for the channel, we need to update its gain. + if (mCurrentSourcep) + { + // SJB: warnings can spam and hurt framerate, disabling + //FMOD_RESULT result; + + mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain()); + //Check_FMOD_Error(result, "FMOD::Channel::setVolume"); + + mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); + /*if(Check_FMOD_Error(result, "FMOD::Channel::setMode")) + { + S32 index; + mChannelp->getIndex(&index); + LL_WARNS() << "Channel " << index << "Source ID: " << mCurrentSourcep->getID() + << " at " << mCurrentSourcep->getPositionGlobal() << LL_ENDL; + }*/ + } + + return true; +} + + +void LLAudioChannelFMODSTUDIO::update3DPosition() +{ + if (!mChannelp) + { + // We're not actually a live channel (i.e., we're not playing back anything) + return; + } + + LLAudioBufferFMODSTUDIO *bufferp = (LLAudioBufferFMODSTUDIO *)mCurrentBufferp; + if (!bufferp) + { + // We don't have a buffer associated with us (should really have been picked up + // by the above if. + return; + } + + if (mCurrentSourcep->isAmbient()) + { + // Ambient sound, don't need to do any positional updates. + set3DMode(false); + } + else + { + // Localized sound. Update the position and velocity of the sound. + set3DMode(true); + + LLVector3 float_pos; + float_pos.setVec(mCurrentSourcep->getPositionGlobal()); + FMOD_RESULT result = mChannelp->set3DAttributes((FMOD_VECTOR*)float_pos.mV, (FMOD_VECTOR*)mCurrentSourcep->getVelocity().mV); + Check_FMOD_Error(result, "FMOD::Channel::set3DAttributes"); + } +} + + +void LLAudioChannelFMODSTUDIO::updateLoop() +{ + if (!mChannelp) + { + // May want to clear up the loop/sample counters. + return; + } + + // + // Hack: We keep track of whether we looped or not by seeing when the + // sample position looks like it's going backwards. Not reliable; may + // yield false negatives. + // + U32 cur_pos; + mChannelp->getPosition(&cur_pos, FMOD_TIMEUNIT_PCMBYTES); + + if (cur_pos < (U32)mLastSamplePos) + { + mLoopedThisFrame = true; + } + mLastSamplePos = cur_pos; +} + + +void LLAudioChannelFMODSTUDIO::cleanup() +{ + if (!mChannelp) + { + // Aborting cleanup with no channel handle. + return; + } + + //Cleaning up channel mChannelID + Check_FMOD_Error(mChannelp->stop(), "FMOD::Channel::stop"); + + mCurrentBufferp = NULL; + mChannelp = NULL; +} + + +void LLAudioChannelFMODSTUDIO::play() +{ + if (!mChannelp) + { + LL_WARNS() << "Playing without a channel handle, aborting" << LL_ENDL; + return; + } + + Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::pause"); + + getSource()->setPlayedOnce(true); + + if (LLAudioEngine_FMODSTUDIO::mChannelGroups[getSource()->getType()]) + mChannelp->setChannelGroup(LLAudioEngine_FMODSTUDIO::mChannelGroups[getSource()->getType()]); +} + + +void LLAudioChannelFMODSTUDIO::playSynced(LLAudioChannel *channelp) +{ + LLAudioChannelFMODSTUDIO *fmod_channelp = (LLAudioChannelFMODSTUDIO*)channelp; + if (!(fmod_channelp->mChannelp && mChannelp)) + { + // Don't have channels allocated to both the master and the slave + return; + } + + U32 cur_pos; + if (Check_FMOD_Error(mChannelp->getPosition(&cur_pos, FMOD_TIMEUNIT_PCMBYTES), "Unable to retrieve current position")) + return; + + cur_pos %= mCurrentBufferp->getLength(); + + // Try to match the position of our sync master + Check_FMOD_Error(mChannelp->setPosition(cur_pos, FMOD_TIMEUNIT_PCMBYTES), "Unable to set current position"); + + // Start us playing + play(); +} + + +bool LLAudioChannelFMODSTUDIO::isPlaying() +{ + if (!mChannelp) + { + return false; + } + + bool paused, playing; + mChannelp->getPaused(&paused); + mChannelp->isPlaying(&playing); + return !paused && playing; +} + + +// +// LLAudioChannelFMODSTUDIO implementation +// + + +LLAudioBufferFMODSTUDIO::LLAudioBufferFMODSTUDIO(FMOD::System *system) : mSystemp(system), mSoundp(NULL) +{ +} + + +LLAudioBufferFMODSTUDIO::~LLAudioBufferFMODSTUDIO() +{ + if (mSoundp) + { + mSoundp->release(); + mSoundp = NULL; + } +} + + +bool LLAudioBufferFMODSTUDIO::loadWAV(const std::string& filename) +{ + // Try to open a wav file from disk. This will eventually go away, as we don't + // really want to block doing this. + if (filename.empty()) + { + // invalid filename, abort. + return false; + } + + if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB)) + { + // File not found, abort. + return false; + } + + if (mSoundp) + { + // If there's already something loaded in this buffer, clean it up. + mSoundp->release(); + mSoundp = NULL; + } + + FMOD_MODE base_mode = FMOD_LOOP_NORMAL; + FMOD_CREATESOUNDEXINFO exinfo; + memset(&exinfo, 0, sizeof(exinfo)); + exinfo.cbsize = sizeof(exinfo); + exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_WAV; //Hint to speed up loading. + // Load up the wav file into an fmod sample +#if LL_WINDOWS + FMOD_RESULT result = getSystem()->createSound((const char*)utf8str_to_utf16str(filename).c_str(), base_mode, &exinfo, &mSoundp); +#else + FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp); +#endif + + if (result != FMOD_OK) + { + // We failed to load the file for some reason. + LL_WARNS() << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << LL_ENDL; + + // + // If we EVER want to load wav files provided by end users, we need + // to rethink this! + // + // file is probably corrupt - remove it. + LLFile::remove(filename); + return false; + } + + // Everything went well, return true + return true; +} + + +U32 LLAudioBufferFMODSTUDIO::getLength() +{ + if (!mSoundp) + { + return 0; + } + + U32 length; + mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES); + return length; +} + + +void LLAudioChannelFMODSTUDIO::set3DMode(bool use3d) +{ + FMOD_MODE current_mode; + if (mChannelp->getMode(¤t_mode) != FMOD_OK) + return; + FMOD_MODE new_mode = current_mode; + new_mode &= ~(use3d ? FMOD_2D : FMOD_3D); + new_mode |= use3d ? FMOD_3D : FMOD_2D; + + if (current_mode != new_mode) + { + mChannelp->setMode(new_mode); + } +} + +// *NOTE: This is almost certainly being called on the mixer thread, +// not the main thread. May have implications for callees or audio +// engine shutdown. + +FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels) +{ + // inbuffer = fmod's original mixbuffer. + // outbuffer = the buffer passed from the previous DSP unit. + // length = length in samples at this mix time. + + LLWindGen *windgen; + FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance; + + thisdsp->getUserData((void **)&windgen); + S32 channels, configwidth, configheight; + thisdsp->getInfo(0, 0, &channels, &configwidth, &configheight); + + windgen->windGenerate((LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT *)outbuffer, length); + + return FMOD_OK; +} diff --git a/indra/llaudio/llaudioengine_fmodstudio.h b/indra/llaudio/llaudioengine_fmodstudio.h new file mode 100644 index 0000000000..69276244da --- /dev/null +++ b/indra/llaudio/llaudioengine_fmodstudio.h @@ -0,0 +1,130 @@ +/** + * @file audioengine_fmodstudio.h + * @brief Definition of LLAudioEngine class abstracting the audio + * support as a FMODSTUDIO implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, 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$ + */ + +#ifndef LL_AUDIOENGINE_FMODSTUDIO_H +#define LL_AUDIOENGINE_FMODSTUDIO_H + +#include "llaudioengine.h" +#include "llwindgen.h" + +//Stubs +class LLAudioStreamManagerFMODSTUDIO; +namespace FMOD +{ + class System; + class Channel; + class ChannelGroup; + class Sound; + class DSP; +} +typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION; + +//Interfaces +class LLAudioEngine_FMODSTUDIO : public LLAudioEngine +{ +public: + LLAudioEngine_FMODSTUDIO(bool enable_profiler); + virtual ~LLAudioEngine_FMODSTUDIO(); + + // initialization/startup/shutdown + virtual bool init(const S32 num_channels, void *user_data); + virtual std::string getDriverName(bool verbose); + virtual void allocateListener(); + + virtual void shutdown(); + + /*virtual*/ bool initWind(); + /*virtual*/ void cleanupWind(); + + /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water); + + typedef F32 MIXBUFFERFORMAT; + + FMOD::System *getSystem() const {return mSystem;} +protected: + /*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to. + /*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel. + + /*virtual*/ void setInternalGain(F32 gain); + + bool mInited; + + LLWindGen *mWindGen; + + FMOD_DSP_DESCRIPTION *mWindDSPDesc; + FMOD::DSP *mWindDSP; + FMOD::System *mSystem; + bool mEnableProfiler; + +public: + static FMOD::ChannelGroup *mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT]; +}; + + +class LLAudioChannelFMODSTUDIO : public LLAudioChannel +{ +public: + LLAudioChannelFMODSTUDIO(FMOD::System *audioengine); + virtual ~LLAudioChannelFMODSTUDIO(); + +protected: + /*virtual*/ void play(); + /*virtual*/ void playSynced(LLAudioChannel *channelp); + /*virtual*/ void cleanup(); + /*virtual*/ bool isPlaying(); + + /*virtual*/ bool updateBuffer(); + /*virtual*/ void update3DPosition(); + /*virtual*/ void updateLoop(); + + void set3DMode(bool use3d); +protected: + FMOD::System *getSystem() const {return mSystemp;} + FMOD::System *mSystemp; + FMOD::Channel *mChannelp; + S32 mLastSamplePos; +}; + + +class LLAudioBufferFMODSTUDIO : public LLAudioBuffer +{ +public: + LLAudioBufferFMODSTUDIO(FMOD::System *audioengine); + virtual ~LLAudioBufferFMODSTUDIO(); + + /*virtual*/ bool loadWAV(const std::string& filename); + /*virtual*/ U32 getLength(); + friend class LLAudioChannelFMODSTUDIO; +protected: + FMOD::System *getSystem() const {return mSystemp;} + FMOD::System *mSystemp; + FMOD::Sound *getSound() const{ return mSoundp; } + FMOD::Sound *mSoundp; +}; + + +#endif // LL_AUDIOENGINE_FMODSTUDIO_H diff --git a/indra/llaudio/lllistener_fmodstudio.cpp b/indra/llaudio/lllistener_fmodstudio.cpp new file mode 100644 index 0000000000..fd88b981c4 --- /dev/null +++ b/indra/llaudio/lllistener_fmodstudio.cpp @@ -0,0 +1,138 @@ +/** + * @file listener_fmodstudio.cpp + * @brief Implementation of LISTENER class abstracting the audio + * support as a FMODSTUDIO implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, 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 "linden_common.h" +#include "llaudioengine.h" +#include "lllistener_fmodstudio.h" +#include "fmodstudio/fmod.hpp" + +//----------------------------------------------------------------------- +// constructor +//----------------------------------------------------------------------- +LLListener_FMODSTUDIO::LLListener_FMODSTUDIO(FMOD::System *system) +{ + mSystem = system; + init(); +} + +//----------------------------------------------------------------------- +LLListener_FMODSTUDIO::~LLListener_FMODSTUDIO() +{ +} + +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::init(void) +{ + // do inherited + LLListener::init(); + mDopplerFactor = 1.0f; + mRolloffFactor = 1.0f; +} + +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::translate(LLVector3 offset) +{ + LLListener::translate(offset); + + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); +} + +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::setPosition(LLVector3 pos) +{ + LLListener::setPosition(pos); + + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); +} + +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::setVelocity(LLVector3 vel) +{ + LLListener::setVelocity(vel); + + mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); +} + +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::orient(LLVector3 up, LLVector3 at) +{ + LLListener::orient(up, at); + + // Welcome to the transition between right and left + // (coordinate systems, that is) + // Leaving the at vector alone results in a L/R reversal + // since DX is left-handed and we (LL, OpenGL, OpenAL) are right-handed + at = -at; + + mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV); +} + +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::commitDeferredChanges() +{ + if (!mSystem) + { + return; + } + + mSystem->update(); +} + + +void LLListener_FMODSTUDIO::setRolloffFactor(F32 factor) +{ + //An internal FMODEx optimization skips 3D updates if there have not been changes to the 3D sound environment. + //Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well. + //In short: Changing the position ticks a dirtyflag inside fmodex, which makes it not skip 3D processing next update call. + if (mRolloffFactor != factor) + { + LLVector3 pos = mVelocity - LLVector3(0.f, 0.f, .1f); + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL); + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mVelocity.mV, NULL, NULL, NULL); + } + mRolloffFactor = factor; + mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); +} + + +F32 LLListener_FMODSTUDIO::getRolloffFactor() +{ + return mRolloffFactor; +} + + +void LLListener_FMODSTUDIO::setDopplerFactor(F32 factor) +{ + mDopplerFactor = factor; + mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); +} + + +F32 LLListener_FMODSTUDIO::getDopplerFactor() +{ + return mDopplerFactor; +} diff --git a/indra/llaudio/lllistener_fmodstudio.h b/indra/llaudio/lllistener_fmodstudio.h new file mode 100644 index 0000000000..6ad85d9700 --- /dev/null +++ b/indra/llaudio/lllistener_fmodstudio.h @@ -0,0 +1,65 @@ +/** + * @file listener_fmodstudio.h + * @brief Description of LISTENER class abstracting the audio support + * as an FMOD 3D implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, 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$ + */ + +#ifndef LL_LISTENER_FMODSTUDIO_H +#define LL_LISTENER_FMODSTUDIO_H + +#include "lllistener.h" + +//Stubs +namespace FMOD +{ + class System; +} + +//Interfaces +class LLListener_FMODSTUDIO : public LLListener +{ +public: + LLListener_FMODSTUDIO(FMOD::System *system); + virtual ~LLListener_FMODSTUDIO(); + virtual void init(); + + virtual void translate(LLVector3 offset); + virtual void setPosition(LLVector3 pos); + virtual void setVelocity(LLVector3 vel); + virtual void orient(LLVector3 up, LLVector3 at); + virtual void commitDeferredChanges(); + + virtual void setDopplerFactor(F32 factor); + virtual F32 getDopplerFactor(); + virtual void setRolloffFactor(F32 factor); + virtual F32 getRolloffFactor(); +protected: + FMOD::System *mSystem; + F32 mDopplerFactor; + F32 mRolloffFactor; +}; + +#endif + + diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp new file mode 100644 index 0000000000..08d19209aa --- /dev/null +++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp @@ -0,0 +1,392 @@ +/** + * @file streamingaudio_fmodstudio.cpp + * @brief LLStreamingAudio_FMODSTUDIO implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, 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 "linden_common.h" + +#include "llmath.h" + +#include "fmodstudio/fmod.hpp" +#include "fmodstudio/fmod_errors.h" + +#include "llstreamingaudio_fmodstudio.h" + + +class LLAudioStreamManagerFMODSTUDIO +{ +public: + LLAudioStreamManagerFMODSTUDIO(FMOD::System *system, const std::string& url); + FMOD::Channel* startStream(); + bool stopStream(); // Returns true if the stream was successfully stopped. + bool ready(); + + const std::string& getURL() { return mInternetStreamURL; } + + FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered = NULL, bool* starving = NULL, bool* diskbusy = NULL); +protected: + FMOD::System* mSystem; + FMOD::Channel* mStreamChannel; + FMOD::Sound* mInternetStream; + bool mReady; + + std::string mInternetStreamURL; +}; + + + +//--------------------------------------------------------------------------- +// Internet Streaming +//--------------------------------------------------------------------------- +LLStreamingAudio_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) : +mSystem(system), +mCurrentInternetStreamp(NULL), +mFMODInternetStreamChannelp(NULL), +mGain(1.0f) +{ + // Number of milliseconds of audio to buffer for the audio card. + // Must be larger than the usual Second Life frame stutter time. + const U32 buffer_seconds = 10; //sec + const U32 estimated_bitrate = 128; //kbit/sec + mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES); + + // Here's where we set the size of the network buffer and some buffering + // parameters. In this case we want a network buffer of 16k, we want it + // to prebuffer 40% of that when we first connect, and we want it + // to rebuffer 80% of that whenever we encounter a buffer underrun. + + // Leave the net buffer properties at the default. + //FSOUND_Stream_Net_SetBufferProperties(20000, 40, 80); +} + + +LLStreamingAudio_FMODSTUDIO::~LLStreamingAudio_FMODSTUDIO() +{ + // nothing interesting/safe to do. +} + + +void LLStreamingAudio_FMODSTUDIO::start(const std::string& url) +{ + //if (!mInited) + //{ + // LL_WARNS() << "startInternetStream before audio initialized" << LL_ENDL; + // return; + //} + + // "stop" stream but don't clear url, etc. in case url == mInternetStreamURL + stop(); + + if (!url.empty()) + { + LL_INFOS() << "Starting internet stream: " << url << LL_ENDL; + mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, url); + mURL = url; + } + else + { + LL_INFOS() << "Set internet stream to null" << LL_ENDL; + mURL.clear(); + } +} + + +void LLStreamingAudio_FMODSTUDIO::update() +{ + // Kill dead internet streams, if possible + std::list::iterator iter; + for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();) + { + LLAudioStreamManagerFMODSTUDIO *streamp = *iter; + if (streamp->stopStream()) + { + LL_INFOS() << "Closed dead stream" << LL_ENDL; + delete streamp; + mDeadStreams.erase(iter++); + } + else + { + iter++; + } + } + + // Don't do anything if there are no streams playing + if (!mCurrentInternetStreamp) + { + return; + } + + unsigned int progress; + bool starving; + bool diskbusy; + FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy); + + if (open_state == FMOD_OPENSTATE_READY) + { + // Stream is live + + // start the stream if it's ready + if (!mFMODInternetStreamChannelp && + (mFMODInternetStreamChannelp = mCurrentInternetStreamp->startStream())) + { + // Reset volume to previously set volume + setGain(getGain()); + mFMODInternetStreamChannelp->setPaused(false); + } + } + else if (open_state == FMOD_OPENSTATE_ERROR) + { + stop(); + return; + } + + if (mFMODInternetStreamChannelp) + { + FMOD::Sound *sound = NULL; + + if (mFMODInternetStreamChannelp->getCurrentSound(&sound) == FMOD_OK && sound) + { + FMOD_TAG tag; + S32 tagcount, dirtytagcount; + + if (sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount) + { + for (S32 i = 0; i < tagcount; ++i) + { + if (sound->getTag(NULL, i, &tag) != FMOD_OK) + continue; + + if (tag.type == FMOD_TAGTYPE_FMOD) + { + if (!strcmp(tag.name, "Sample Rate Change")) + { + LL_INFOS() << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL; + mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)); + } + continue; + } + } + } + + if (starving) + { + bool paused = false; + mFMODInternetStreamChannelp->getPaused(&paused); + if (!paused) + { + LL_INFOS() << "Stream starvation detected! Pausing stream until buffer nearly full." << LL_ENDL; + LL_INFOS() << " (diskbusy=" << diskbusy << ")" << LL_ENDL; + LL_INFOS() << " (progress=" << progress << ")" << LL_ENDL; + mFMODInternetStreamChannelp->setPaused(true); + } + } + else if (progress > 80) + { + mFMODInternetStreamChannelp->setPaused(false); + } + } + } +} + +void LLStreamingAudio_FMODSTUDIO::stop() +{ + if (mFMODInternetStreamChannelp) + { + mFMODInternetStreamChannelp->setPaused(true); + mFMODInternetStreamChannelp->setPriority(0); + mFMODInternetStreamChannelp = NULL; + } + + if (mCurrentInternetStreamp) + { + LL_INFOS() << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << LL_ENDL; + if (mCurrentInternetStreamp->stopStream()) + { + delete mCurrentInternetStreamp; + } + else + { + LL_WARNS() << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << LL_ENDL; + mDeadStreams.push_back(mCurrentInternetStreamp); + } + mCurrentInternetStreamp = NULL; + //mURL.clear(); + } +} + +void LLStreamingAudio_FMODSTUDIO::pause(int pauseopt) +{ + if (pauseopt < 0) + { + pauseopt = mCurrentInternetStreamp ? 1 : 0; + } + + if (pauseopt) + { + if (mCurrentInternetStreamp) + { + stop(); + } + } + else + { + start(getURL()); + } +} + + +// A stream is "playing" if it has been requested to start. That +// doesn't necessarily mean audio is coming out of the speakers. +int LLStreamingAudio_FMODSTUDIO::isPlaying() +{ + if (mCurrentInternetStreamp) + { + return 1; // Active and playing + } + else if (!mURL.empty()) + { + return 2; // "Paused" + } + else + { + return 0; + } +} + + +F32 LLStreamingAudio_FMODSTUDIO::getGain() +{ + return mGain; +} + + +std::string LLStreamingAudio_FMODSTUDIO::getURL() +{ + return mURL; +} + + +void LLStreamingAudio_FMODSTUDIO::setGain(F32 vol) +{ + mGain = vol; + + if (mFMODInternetStreamChannelp) + { + vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here? + + mFMODInternetStreamChannelp->setVolume(vol); + } +} + +/////////////////////////////////////////////////////// +// manager of possibly-multiple internet audio streams + +LLAudioStreamManagerFMODSTUDIO::LLAudioStreamManagerFMODSTUDIO(FMOD::System *system, const std::string& url) : +mSystem(system), +mStreamChannel(NULL), +mInternetStream(NULL), +mReady(false) +{ + mInternetStreamURL = url; + + FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream); + + if (result != FMOD_OK) + { + LL_WARNS() << "Couldn't open fmod stream, error " + << FMOD_ErrorString(result) + << LL_ENDL; + mReady = false; + return; + } + + mReady = true; +} + +FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream() +{ + // We need a live and opened stream before we try and play it. + if (!mInternetStream || getOpenState() != FMOD_OPENSTATE_READY) + { + LL_WARNS() << "No internet stream to start playing!" << LL_ENDL; + return NULL; + } + + if (mStreamChannel) + return mStreamChannel; //Already have a channel for this stream. + + mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel); + return mStreamChannel; +} + +bool LLAudioStreamManagerFMODSTUDIO::stopStream() +{ + if (mInternetStream) + { + + + bool close = true; + switch (getOpenState()) + { + case FMOD_OPENSTATE_CONNECTING: + close = false; + break; + default: + close = true; + } + + if (close) + { + mInternetStream->release(); + mStreamChannel = NULL; + mInternetStream = NULL; + return true; + } + else + { + return false; + } + } + else + { + return true; + } +} + +FMOD_OPENSTATE LLAudioStreamManagerFMODSTUDIO::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy) +{ + FMOD_OPENSTATE state; + mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy); + return state; +} + +void LLStreamingAudio_FMODSTUDIO::setBufferSizes(U32 streambuffertime, U32 decodebuffertime) +{ + mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES); + FMOD_ADVANCEDSETTINGS settings; + memset(&settings, 0, sizeof(settings)); + settings.cbSize = sizeof(settings); + settings.defaultDecodeBufferSize = decodebuffertime;//ms + mSystem->setAdvancedSettings(&settings); +} diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.h b/indra/llaudio/llstreamingaudio_fmodstudio.h new file mode 100644 index 0000000000..6637b2d155 --- /dev/null +++ b/indra/llaudio/llstreamingaudio_fmodstudio.h @@ -0,0 +1,73 @@ +/** + * @file streamingaudio_fmodstudio.h + * @brief Definition of LLStreamingAudio_FMODSTUDIO implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, 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$ + */ + +#ifndef LL_STREAMINGAUDIO_FMODSTUDIO_H +#define LL_STREAMINGAUDIO_FMODSTUDIO_H + +#include "stdtypes.h" // from llcommon + +#include "llstreamingaudio.h" +#include "lltimer.h" + +//Stubs +class LLAudioStreamManagerFMODSTUDIO; +namespace FMOD +{ + class System; + class Channel; +} + +//Interfaces +class LLStreamingAudio_FMODSTUDIO : public LLStreamingAudioInterface +{ +public: + LLStreamingAudio_FMODSTUDIO(FMOD::System *system); + /*virtual*/ ~LLStreamingAudio_FMODSTUDIO(); + + /*virtual*/ void start(const std::string& url); + /*virtual*/ void stop(); + /*virtual*/ void pause(S32 pause); + /*virtual*/ void update(); + /*virtual*/ S32 isPlaying(); + /*virtual*/ void setGain(F32 vol); + /*virtual*/ F32 getGain(); + /*virtual*/ std::string getURL(); + + /*virtual*/ bool supportsAdjustableBufferSizes(){return true;} + /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime); +private: + FMOD::System *mSystem; + + LLAudioStreamManagerFMODSTUDIO *mCurrentInternetStreamp; + FMOD::Channel *mFMODInternetStreamChannelp; + std::list mDeadStreams; + + std::string mURL; + F32 mGain; +}; + + +#endif // LL_STREAMINGAUDIO_FMODEX_H diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index cf8f99ed25..22871a9d94 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -19,6 +19,7 @@ include(DirectX) include(DragDrop) include(EXPAT) include(FMODEX) +include(FMODSTUDIO) include(GLOD) include(Hunspell) include(JsonCpp) @@ -67,6 +68,10 @@ if(FMODEX) include_directories(${FMODEX_INCLUDE_DIR}) endif(FMODEX) +if(FMODSTUDIO) + include_directories(${FMODSTUDIO_INCLUDE_DIR}) +endif(FMODSTUDIO) + include_directories( ${DBUSGLIB_INCLUDE_DIRS} ${JSONCPP_INCLUDE_DIR} @@ -1711,9 +1716,14 @@ endif (OPENAL) if (FMODEX) set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX") - set(FMODWRAPPER_LIBRARY ${FMODEX_LIBRARY}) + set(FMODEXWRAPPER_LIBRARY ${FMODEX_LIBRARY}) endif (FMODEX) +if (FMODSTUDIO) + set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODSTUDIO") + set(FMODWRAPPER_LIBRARY ${FMODSTUDIO_LIBRARY}) +endif (FMODSTUDIO) + set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES}) @@ -1837,6 +1847,14 @@ if (WINDOWS) ) endif (FMODEX) + if (FMODSTUDIO) + list(APPEND COPY_INPUT_DEPENDENCIES + ${SHARED_LIB_STAGING_DIR}/Release/fmod.dll + ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmod.dll + ${SHARED_LIB_STAGING_DIR}/Debug/fmodL.dll + ) + endif (FMODSTUDIO) + add_custom_command( OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat COMMAND ${PYTHON_EXECUTABLE} @@ -1846,6 +1864,8 @@ if (WINDOWS) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--fmodex=${FMODEX}" + "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -1907,6 +1927,8 @@ if (WINDOWS) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--fmodex=${FMODEX}" + "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2004,6 +2026,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${BOOST_CONTEXT_LIBRARY} ${DBUSGLIB_LIBRARIES} ${OPENGL_LIBRARIES} + ${FMODEXWRAPPER_LIBRARY} # must come after LLAudio ${FMODWRAPPER_LIBRARY} # must come after LLAudio ${GLOD_LIBRARIES} ${OPENGL_LIBRARIES} @@ -2052,6 +2075,8 @@ if (LINUX) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--fmodex=${FMODEX}" + "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2078,6 +2103,8 @@ if (LINUX) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--fmodex=${FMODEX}" + "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2154,6 +2181,8 @@ if (DARWIN) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--fmodex=${FMODEX}" + "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER} @@ -2188,6 +2217,8 @@ if (DARWIN) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--fmodex=${FMODEX}" + "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 684d3bd421..137d73fead 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -43,6 +43,10 @@ # include "llaudioengine_fmodex.h" #endif +#ifdef LL_FMODSTUDIO +# include "llaudioengine_fmodstudio.h" +#endif + #ifdef LL_OPENAL #include "llaudioengine_openal.h" #endif @@ -623,7 +627,7 @@ bool idle_startup() delete gAudiop; gAudiop = NULL; -#ifdef LL_FMODEX +#ifdef LL_FMODEX #if !LL_WINDOWS if (NULL == getenv("LL_BAD_FMODEX_DRIVER")) #endif // !LL_WINDOWS @@ -632,6 +636,15 @@ bool idle_startup() } #endif +#ifdef LL_FMODSTUDIO +#if !LL_WINDOWS + if (NULL == getenv("LL_BAD_FMODEX_DRIVER")) +#endif // !LL_WINDOWS + { + gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODSTUDIO(gSavedSettings.getBOOL("FMODExProfilerEnable")); + } +#endif + #ifdef LL_OPENAL #if !LL_WINDOWS if (NULL == getenv("LL_BAD_OPENAL_DRIVER")) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index a403760670..0140a4b928 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -513,14 +513,20 @@ class WindowsManifest(ViewerManifest): print err.message print "Skipping GLOD library (assumming linked statically)" - # Get fmodex dll, continue if missing - try: + # Get fmodex dll if needed + # Normally only fmodex or fmodstudio are needed, but just in case checkking both. + if self.args['fmodex'] == 'ON': if(self.address_size == 64): self.path("fmodex64.dll") else: self.path("fmodex.dll") - except: - print "Skipping fmodex audio library(assuming other audio engine)" + + # Get fmodstudio dll if needed + if self.args['fmodstudio'] == 'ON': + if(self.args['configuration'].lower() == 'debug'): + self.path("fmodL.dll") + else: + self.path("fmod.dll") # For textures self.path("openjpeg.dll") @@ -1046,17 +1052,31 @@ class DarwinManifest(ViewerManifest): ): self.path2basename(relpkgdir, libfile) - # dylibs that vary based on configuration - if self.args['configuration'].lower() == 'debug': - for libfile in ( - "libfmodexL.dylib", - ): - dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile) - else: - for libfile in ( - "libfmodex.dylib", - ): - dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) + # Fmodex dylibs that vary based on configuration + if self.args['fmodex'] == 'ON': + if self.args['configuration'].lower() == 'debug': + for libfile in ( + "libfmodexL.dylib", + ): + dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile) + else: + for libfile in ( + "libfmodex.dylib", + ): + dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) + + # Fmod studio dylibs (vary based on configuration) + if self.args['fmodstudio'] == 'ON': + if self.args['configuration'].lower() == 'debug': + for libfile in ( + "libfmodL.dylib", + ): + dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile) + else: + for libfile in ( + "libfmod.dylib", + ): + dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) # our apps executable_path = {} @@ -1519,13 +1539,24 @@ class Linux_i686_Manifest(LinuxManifest): print "tcmalloc files not found, skipping" pass - try: - self.path("libfmodex-*.so") - self.path("libfmodex.so") - pass - except: - print "Skipping libfmodex.so - not found" - pass + if self.args['fmodex'] == 'ON': + try: + self.path("libfmodex-*.so") + self.path("libfmodex.so") + pass + except: + print "Skipping libfmodex.so - not found" + pass + + if self.args['fmodstudio'] == 'ON': + try: + self.path("libfmod.so.11.7") + self.path("libfmod.so.11") + self.path("libfmod.so") + pass + except: + print "Skipping libfmod.so - not found" + pass # Vivox runtimes @@ -1555,6 +1586,8 @@ if __name__ == "__main__": extra_arguments = [ dict(name='bugsplat', description="""BugSplat database to which to post crashes, if BugSplat crash reporting is desired""", default=''), + dict(name='fmodex', description="""Indication if fmodex libraries are needed""", default='OFF'), + dict(name='fmodstudio', description="""Indication if fmod studio libraries are needed""", default='OFF'), ] try: main(extra=extra_arguments) -- cgit v1.3 From e76f25d25fb96965fcf37a477bbf8c14ef1eccb2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 4 Feb 2020 16:19:20 +0200 Subject: SL-11445 Couple small fixes --- .gitignore | 1 + indra/cmake/FMODSTUDIO.cmake | 2 +- indra/llaudio/lllistener_fmodstudio.cpp | 5 +++-- indra/llaudio/llstreamingaudio_fmodstudio.h | 2 +- indra/newview/app_settings/settings.xml | 6 +++--- 5 files changed, 9 insertions(+), 7 deletions(-) (limited to 'indra/cmake') diff --git a/.gitignore b/.gitignore index 27b629a578..2d32e94c78 100755 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.bak *.diff *.orig +*.patch *.pyc *.rej *.swp diff --git a/indra/cmake/FMODSTUDIO.cmake b/indra/cmake/FMODSTUDIO.cmake index 1539270d6c..8840354ac6 100644 --- a/indra/cmake/FMODSTUDIO.cmake +++ b/indra/cmake/FMODSTUDIO.cmake @@ -27,7 +27,7 @@ if (FMODSTUDIO) debug fmodL optimized fmod) elseif (LINUX) - set(FMODEX_LIBRARY + set(FMODSTUDIO_LIBRARY debug fmodL optimized fmod) endif (WINDOWS) diff --git a/indra/llaudio/lllistener_fmodstudio.cpp b/indra/llaudio/lllistener_fmodstudio.cpp index fd88b981c4..34f3d00eae 100644 --- a/indra/llaudio/lllistener_fmodstudio.cpp +++ b/indra/llaudio/lllistener_fmodstudio.cpp @@ -105,9 +105,10 @@ void LLListener_FMODSTUDIO::commitDeferredChanges() void LLListener_FMODSTUDIO::setRolloffFactor(F32 factor) { - //An internal FMODEx optimization skips 3D updates if there have not been changes to the 3D sound environment. + //An internal FMOD optimization skips 3D updates if there have not been changes to the 3D sound environment. + // (this was true for FMODex, looks to be still true for FMOD STUDIO) //Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well. - //In short: Changing the position ticks a dirtyflag inside fmodex, which makes it not skip 3D processing next update call. + //In short: Changing the position ticks a dirtyflag inside fmod, which makes it not skip 3D processing next update call. if (mRolloffFactor != factor) { LLVector3 pos = mVelocity - LLVector3(0.f, 0.f, .1f); diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.h b/indra/llaudio/llstreamingaudio_fmodstudio.h index 6637b2d155..1fc3c54d79 100644 --- a/indra/llaudio/llstreamingaudio_fmodstudio.h +++ b/indra/llaudio/llstreamingaudio_fmodstudio.h @@ -70,4 +70,4 @@ private: }; -#endif // LL_STREAMINGAUDIO_FMODEX_H +#endif // LL_STREAMINGAUDIO_FMODSTUDIO_H diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index da1e87fda4..2907d9f5b3 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -16167,7 +16167,7 @@ FMODExProfilerEnable Comment - Enable profiler tool if using FMOD Ex + Enable profiler tool if using FMOD Ex or FMOD Studio Persist 1 Type @@ -16178,7 +16178,7 @@ FMODExDecodeBufferSize Comment - Sets the streaming decode buffer size (in milliseconds) + Sets the streaming decode buffer size (in milliseconds) for FMOD Ex or FMOD Studio Persist 1 Type @@ -16189,7 +16189,7 @@ FMODExStreamBufferSize Comment - Sets the streaming buffer size (in milliseconds) + Sets the streaming buffer size (in milliseconds) for FMOD Ex or FMOD Studio Persist 1 Type -- cgit v1.3 From 6627d684a20dbc420de7814066c31a930c0e0e10 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 4 Feb 2020 17:12:19 +0200 Subject: SL-12654 Remove support for building with fmod ex --- autobuild.xml | 88 ---- indra/cmake/CMakeLists.txt | 2 - indra/cmake/Copy3rdPartyLibs.cmake | 18 - indra/cmake/FMODEX.cmake | 42 -- indra/cmake/FindFMODEX.cmake | 65 --- indra/llaudio/CMakeLists.txt | 18 - indra/llaudio/llaudioengine_fmodex.cpp | 767 ---------------------------- indra/llaudio/llaudioengine_fmodex.h | 130 ----- indra/llaudio/lllistener_fmodex.cpp | 140 ----- indra/llaudio/lllistener_fmodex.h | 65 --- indra/llaudio/llstreamingaudio_fmodex.cpp | 392 -------------- indra/llaudio/llstreamingaudio_fmodex.h | 73 --- indra/newview/CMakeLists.txt | 25 - indra/newview/linux_tools/client-readme.txt | 4 +- indra/newview/linux_tools/wrapper.sh | 2 + indra/newview/llstartup.cpp | 15 +- indra/newview/viewer_manifest.py | 31 -- 17 files changed, 5 insertions(+), 1872 deletions(-) delete mode 100644 indra/cmake/FMODEX.cmake delete mode 100644 indra/cmake/FindFMODEX.cmake delete mode 100644 indra/llaudio/llaudioengine_fmodex.cpp delete mode 100644 indra/llaudio/llaudioengine_fmodex.h delete mode 100644 indra/llaudio/lllistener_fmodex.cpp delete mode 100644 indra/llaudio/lllistener_fmodex.h delete mode 100644 indra/llaudio/llstreamingaudio_fmodex.cpp delete mode 100644 indra/llaudio/llstreamingaudio_fmodex.h (limited to 'indra/cmake') diff --git a/autobuild.xml b/autobuild.xml index d119746780..a4f39be595 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -729,94 +729,6 @@ version 2.1.1.500375 - fmodex - - copyright - COPYRIGHT 2014 FIRELIGHT TECHNOLOGIES PTY LTD. ALL RIGHTS RESERVED - license - fmodex - license_file - LICENSES/fmodex.txt - name - fmodex - platforms - - darwin - - archive - - hash - ed0d8767652aecd65a7fef3e28645bad - url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/fmodex_3p-update-fmodex/rev/297261/arch/Darwin/installer/fmodex-4.44.31.297261-darwin-297261.tar.bz2 - - name - darwin - - darwin64 - - archive - - hash - 93257fce19120c01751362775a01b925 - url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1545/3481/fmodex-4.44.64.501533-darwin64-501533.tar.bz2 - - name - darwin64 - - linux - - archive - - hash - b847ec838da1ad1dd646df9d74e9b395 - url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/p64_3p-fmodex/rev/314207/arch/Linux/installer/fmodex-4.44.61.314207-linux-314207.tar.bz2 - - name - linux - - linux64 - - archive - - hash - 89a75d8719f7b2cbe1e54cd8407bb992 - url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1544/3476/fmodex-4.44.64.501533-linux64-501533.tar.bz2 - - name - linux64 - - windows - - archive - - hash - 601c2fc41a18812a45678ef9a87ef772 - url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1546/3486/fmodex-4.44.64.501533-windows-501533.tar.bz2 - - name - windows - - windows64 - - archive - - hash - e5cde35ae26ebfa256cfe670986e152e - url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1547/3487/fmodex-4.44.64.501533-windows64-501533.tar.bz2 - - name - windows64 - - - version - 4.44.64.501533 - fmodstudio copyright diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 6dbf26c4a9..3a14bf522f 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -28,7 +28,6 @@ set(cmake_SOURCE_FILES FindAPR.cmake FindAutobuild.cmake FindBerkeleyDB.cmake - FindFMODEX.cmake FindGLH.cmake FindGoogleBreakpad.cmake FindHUNSPELL.cmake @@ -39,7 +38,6 @@ set(cmake_SOURCE_FILES FindURIPARSER.cmake FindXmlRpcEpi.cmake FindZLIB.cmake - FMODEX.cmake FMODSTUDIO.cmake FreeType.cmake GLEXT.cmake diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index f7904cc5d7..82cd5d62e8 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -62,14 +62,6 @@ if(WINDOWS) endif(ADDRESS_SIZE EQUAL 32) endif (BUGSPLAT_DB) - if (FMODEX) - if(ADDRESS_SIZE EQUAL 32) - set(release_files ${release_files} fmodex.dll) - else(ADDRESS_SIZE EQUAL 32) - set(release_files ${release_files} fmodex64.dll) - endif(ADDRESS_SIZE EQUAL 32) - endif (FMODEX) - if (FMODSTUDIO) set(debug_files ${debug_files} fmodL.dll) set(release_files ${release_files} fmod.dll) @@ -196,11 +188,6 @@ elseif(DARWIN) libnghttp2.14.14.0.dylib ) - if (FMODEX) - set(debug_files ${debug_files} libfmodexL.dylib) - set(release_files ${release_files} libfmodex.dylib) - endif (FMODEX) - if (FMODSTUDIO) set(debug_files ${debug_files} libfmodL.dylib) set(release_files ${release_files} libfmod.dylib) @@ -251,11 +238,6 @@ elseif(LINUX) libfontconfig.so.1 ) - if (FMODEX) - set(debug_files ${debug_files} "libfmodexL.so") - set(release_files ${release_files} "libfmodex.so") - endif (FMODEX) - if (FMODSTUDIO) set(debug_files ${debug_files} "libfmodL.so") set(release_files ${release_files} "libfmod.so") diff --git a/indra/cmake/FMODEX.cmake b/indra/cmake/FMODEX.cmake deleted file mode 100644 index 25add0c8f2..0000000000 --- a/indra/cmake/FMODEX.cmake +++ /dev/null @@ -1,42 +0,0 @@ -# -*- cmake -*- - -# FMODEX can be set when launching the make using the argument -DFMOD:BOOL=ON -# No longer used by default, see FMODSTRUDIO. -# Open source devs should use the -DFMODEX:BOOL=ON then if they want to build with FMODEX, whether -# they are using USESYSTEMLIBS or not. - -if (FMODEX) - if (USESYSTEMLIBS) - # In that case, we use the version of the library installed on the system - set(FMODEX_FIND_REQUIRED ON) - include(FindFMODEX) - else (USESYSTEMLIBS) - if (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR) - # If the path have been specified in the arguments, use that - set(FMODEX_LIBRARIES ${FMODEX_LIBRARY}) - MESSAGE(STATUS "Using FMODEX path: ${FMODEX_LIBRARIES}, ${FMODEX_INCLUDE_DIR}") - else (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR) - # If not, we're going to try to get the package listed in autobuild.xml - # Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL) - # as accessing the private LL location will fail if you don't have the credential - include(Prebuilt) - use_prebuilt_binary(fmodex) - if (WINDOWS) - set(FMODEX_LIBRARY - debug fmodexL_vc - optimized fmodex_vc) - elseif (DARWIN) - set(FMODEX_LIBRARY - debug fmodexL - optimized fmodex) - elseif (LINUX) - set(FMODEX_LIBRARY - debug fmodexL - optimized fmodex) - endif (WINDOWS) - set(FMODEX_LIBRARIES ${FMODEX_LIBRARY}) - set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodex) - endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR) - endif (USESYSTEMLIBS) -endif (FMODEX) - diff --git a/indra/cmake/FindFMODEX.cmake b/indra/cmake/FindFMODEX.cmake deleted file mode 100644 index b621727c0e..0000000000 --- a/indra/cmake/FindFMODEX.cmake +++ /dev/null @@ -1,65 +0,0 @@ -# -*- cmake -*- - -# - Find FMODEX -# Find the FMODEX includes and library -# This module defines -# FMODEX_INCLUDE_DIR, where to find fmod.h and fmod_errors.h -# FMODEX_LIBRARIES, the libraries needed to use FMODEX. -# FMODEX, If false, do not try to use FMODEX. -# also defined, but not for general use are -# FMODEX_LIBRARY, where to find the FMODEX library. - -FIND_PATH(FMODEX_INCLUDE_DIR fmod.h PATH_SUFFIXES fmod) - -SET(FMODEX_NAMES ${FMODEX_NAMES} fmodex fmodvc fmodexL_vc) -FIND_LIBRARY(FMODEX_LIBRARY - NAMES ${FMODEX_NAMES} - PATH_SUFFIXES fmodex - ) - -IF (FMODEX_SDK_DIR OR WINDOWS) - if(WINDOWS) - set(FMODEX_SDK_DIR "$ENV{PROGRAMFILES}/FMOD SoundSystem/FMOD Programmers API Windows" CACHE PATH "Path to FMODEX") - STRING(REGEX REPLACE "\\\\" "/" FMODEX_SDK_DIR ${FMODEX_SDK_DIR}) - endif(WINDOWS) - find_library(FMODEX_LIBRARY - fmodex_vc fmodexL_vc - PATHS - ${FMODEX_SDK_DIR}/api/lib - ${FMODEX_SDK_DIR}/api - ${FMODEX_SDK_DIR} - ) - find_path(FMODEX_INCLUDE_DIR fmod.h - ${FMODEX_SDK_DIR}/api/inc - ${FMODEX_SDK_DIR}/api - ${FMODEX_SDK_DIR} - ) - find_path(FMODEX_INCLUDE_DIR fmod.h - ${FMODEX_SDK_DIR}/api/inc - ${FMODEX_SDK_DIR}/api - ${FMODEX_SDK_DIR} - ) - IF (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR) - SET(FMODEX_LIBRARIES ${FMODEX_LIBRARY}) - SET(FMODEX_FOUND "YES") - endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR) -ENDIF (FMODEX_SDK_DIR OR WINDOWS) - -IF (FMODEX_FOUND) - IF (NOT FMODEX_FIND_QUIETLY) - MESSAGE(STATUS "Found FMODEX: ${FMODEX_LIBRARIES}") - ENDIF (NOT FMODEX_FIND_QUIETLY) -ELSE (FMODEX_FOUND) - IF (FMODEX_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find FMODEX library") - ENDIF (FMODEX_FIND_REQUIRED) -ENDIF (FMODEX_FOUND) - -# Deprecated declarations. -SET (NATIVE_FMODEX_INCLUDE_PATH ${FMODEX_INCLUDE_DIR} ) -GET_FILENAME_COMPONENT (NATIVE_FMODEX_LIB_PATH ${FMODEX_LIBRARY} PATH) - -MARK_AS_ADVANCED( - FMODEX_LIBRARY - FMODEX_INCLUDE_DIR - ) diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index 6d7030f548..8b628a058e 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -4,7 +4,6 @@ project(llaudio) include(00-Common) include(LLAudio) -include(FMODEX) include(FMODSTUDIO) include(OPENAL) include(LLCommon) @@ -43,23 +42,6 @@ set(llaudio_HEADER_FILES llwindgen.h ) -if (FMODEX) - include_directories( - ${FMODEX_INCLUDE_DIR} - ) - list(APPEND llaudio_SOURCE_FILES - llaudioengine_fmodex.cpp - lllistener_fmodex.cpp - llstreamingaudio_fmodex.cpp - ) - - list(APPEND llaudio_HEADER_FILES - llaudioengine_fmodex.h - lllistener_fmodex.h - llstreamingaudio_fmodex.h - ) -endif (FMODEX) - if (FMODSTUDIO) include_directories( ${FMODSTUDIO_INCLUDE_DIR} diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp deleted file mode 100644 index 7e65a05e48..0000000000 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ /dev/null @@ -1,767 +0,0 @@ -/** - * @file audioengine_fmodex.cpp - * @brief Implementation of LLAudioEngine class abstracting the audio - * support as a FMODEX implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2014, 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 "linden_common.h" - -#include "llstreamingaudio.h" -#include "llstreamingaudio_fmodex.h" - -#include "llaudioengine_fmodex.h" -#include "lllistener_fmodex.h" - -#include "llerror.h" -#include "llmath.h" -#include "llrand.h" - -#include "fmod.hpp" -#include "fmod_errors.h" -#include "lldir.h" -#include "llapr.h" - -#include "sound_ids.h" - -FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels); - -FMOD::ChannelGroup *LLAudioEngine_FMODEX::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0}; - -LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler) -{ - mInited = false; - mWindGen = NULL; - mWindDSP = NULL; - mSystem = NULL; - mEnableProfiler = enable_profiler; - mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); -} - - -LLAudioEngine_FMODEX::~LLAudioEngine_FMODEX() -{ - delete mWindDSPDesc; -} - - -inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) -{ - if(result == FMOD_OK) - return false; - LL_DEBUGS() << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; - return true; -} - -void* F_STDCALL decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) -{ - if(type & FMOD_MEMORY_STREAM_DECODE) - { - LL_INFOS() << "Decode buffer size: " << size << LL_ENDL; - } - else if(type & FMOD_MEMORY_STREAM_FILE) - { - LL_INFOS() << "Strean buffer size: " << size << LL_ENDL; - } - return new char[size]; -} -void* F_STDCALL decode_realloc(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) -{ - memset(ptr,0,size); - return ptr; -} -void F_STDCALL decode_dealloc(void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr) -{ - delete[] (char*)ptr; -} - -bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata) -{ - U32 version; - FMOD_RESULT result; - - LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL; - - //result = FMOD::Memory_Initialize(NULL, 0, &decode_alloc, &decode_realloc, &decode_dealloc, FMOD_MEMORY_STREAM_DECODE | FMOD_MEMORY_STREAM_FILE); - //if(Check_FMOD_Error(result, "FMOD::Memory_Initialize")) - // return false; - - // turn off non-error log spam to fmod.log (TODO: why do we even have an fmod.log if we don't link against log lib?) - FMOD::Debug_SetLevel(FMOD_DEBUG_LEVEL_ERROR); - - result = FMOD::System_Create(&mSystem); - if(Check_FMOD_Error(result, "FMOD::System_Create")) - return false; - - //will call LLAudioEngine_FMODEX::allocateListener, which needs a valid mSystem pointer. - LLAudioEngine::init(num_channels, userdata); - - result = mSystem->getVersion(&version); - Check_FMOD_Error(result, "FMOD::System::getVersion"); - - if (version < FMOD_VERSION) - { - LL_WARNS("AppInit") << "Error : You are using the wrong FMOD Ex version (" << version - << ")! You should be using FMOD Ex" << FMOD_VERSION << LL_ENDL; - } - - result = mSystem->setSoftwareFormat(44100, FMOD_SOUND_FORMAT_PCM16, 0, 0, FMOD_DSP_RESAMPLER_LINEAR); - Check_FMOD_Error(result,"FMOD::System::setSoftwareFormat"); - - // In this case, all sounds, PLUS wind and stream will be software. - result = mSystem->setSoftwareChannels(num_channels + 2); - Check_FMOD_Error(result,"FMOD::System::setSoftwareChannels"); - - U32 fmod_flags = FMOD_INIT_NORMAL; - if(mEnableProfiler) - { - fmod_flags |= FMOD_INIT_ENABLE_PROFILE; - mSystem->createChannelGroup("None", &mChannelGroups[AUDIO_TYPE_NONE]); - mSystem->createChannelGroup("SFX", &mChannelGroups[AUDIO_TYPE_SFX]); - mSystem->createChannelGroup("UI", &mChannelGroups[AUDIO_TYPE_UI]); - mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]); - } - -#if LL_LINUX - bool audio_ok = false; - - if (!audio_ok) - { - if (NULL == getenv("LL_BAD_FMOD_PULSEAUDIO")) /*Flawfinder: ignore*/ - { - LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL; - if(mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK && - (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK) - { - LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL; - audio_ok = true; - } - else - { - Check_FMOD_Error(result, "PulseAudio audio output FAILED to initialize"); - } - } - else - { - LL_DEBUGS("AppInit") << "PulseAudio audio output SKIPPED" << LL_ENDL; - } - } - if (!audio_ok) - { - if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/ - { - LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; - if(mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK && - (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK) - { - LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; - audio_ok = true; - } - else - { - Check_FMOD_Error(result, "ALSA audio output FAILED to initialize"); - } - } - else - { - LL_DEBUGS("AppInit") << "ALSA audio output SKIPPED" << LL_ENDL; - } - } - if (!audio_ok) - { - if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/ - { - LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL; - if(mSystem->setOutput(FMOD_OUTPUTTYPE_OSS) == FMOD_OK && - (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK) - { - LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL; - audio_ok = true; - } - else - { - Check_FMOD_Error(result, "OSS audio output FAILED to initialize"); - } - } - else - { - LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL; - } - } - if (!audio_ok) - { - LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL; - return false; - } - - // We're interested in logging which output method we - // ended up with, for QA purposes. - FMOD_OUTPUTTYPE output_type; - mSystem->getOutput(&output_type); - switch (output_type) - { - case FMOD_OUTPUTTYPE_NOSOUND: - LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break; - case FMOD_OUTPUTTYPE_PULSEAUDIO: - LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break; - case FMOD_OUTPUTTYPE_ALSA: - LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break; - case FMOD_OUTPUTTYPE_OSS: - LL_INFOS("AppInit") << "Audio output: OSS" << LL_ENDL; break; - default: - LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break; - }; -#else // LL_LINUX - - // initialize the FMOD engine - result = mSystem->init( num_channels + 2, fmod_flags, 0); - if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) - { - /* - Ok, the speaker mode selected isn't supported by this soundcard. Switch it - back to stereo... - */ - result = mSystem->setSpeakerMode(FMOD_SPEAKERMODE_STEREO); - Check_FMOD_Error(result,"Error falling back to stereo mode"); - /* - ... and re-init. - */ - result = mSystem->init( num_channels + 2, fmod_flags, 0); - } - if(Check_FMOD_Error(result, "Error initializing FMOD Ex")) - return false; -#endif - - // set up our favourite FMOD-native streaming audio implementation if none has already been added - if (!getStreamingAudioImpl()) // no existing implementation added - setStreamingAudioImpl(new LLStreamingAudio_FMODEX(mSystem)); - - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init() FMOD Ex initialized correctly" << LL_ENDL; - - int r_numbuffers, r_samplerate, r_channels, r_bits; - unsigned int r_bufferlength; - mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers); - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL; - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_numbuffers=" << r_numbuffers << LL_ENDL; - - mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits); - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_samplerate=" << r_samplerate << "Hz" << LL_ENDL; - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_channels=" << r_channels << LL_ENDL; - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bits =" << r_bits << LL_ENDL; - - char r_name[512]; - mSystem->getDriverInfo(0, r_name, 511, 0); - r_name[511] = '\0'; - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_name=\"" << r_name << "\"" << LL_ENDL; - - int latency = 100; // optimistic default - i suspect if sample rate is 0, everything breaks. - if ( r_samplerate != 0 ) - latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate); - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): latency=" << latency << "ms" << LL_ENDL; - - mInited = true; - - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): initialization complete." << LL_ENDL; - - return true; -} - - -std::string LLAudioEngine_FMODEX::getDriverName(bool verbose) -{ - llassert_always(mSystem); - if (verbose) - { - U32 version; - if(!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion")) - { - return llformat("FMOD Ex %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF); - } - } - return "FMODEx"; -} - - -void LLAudioEngine_FMODEX::allocateListener(void) -{ - mListenerp = (LLListener *) new LLListener_FMODEX(mSystem); - if (!mListenerp) - { - LL_WARNS() << "Listener creation failed" << LL_ENDL; - } -} - - -void LLAudioEngine_FMODEX::shutdown() -{ - stopInternetStream(); - - LL_INFOS() << "About to LLAudioEngine::shutdown()" << LL_ENDL; - LLAudioEngine::shutdown(); - - LL_INFOS() << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << LL_ENDL; - if ( mSystem ) // speculative fix for MAINT-2657 - { - mSystem->close(); - mSystem->release(); - } - LL_INFOS() << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << LL_ENDL; - - delete mListenerp; - mListenerp = NULL; -} - - -LLAudioBuffer * LLAudioEngine_FMODEX::createBuffer() -{ - return new LLAudioBufferFMODEX(mSystem); -} - - -LLAudioChannel * LLAudioEngine_FMODEX::createChannel() -{ - return new LLAudioChannelFMODEX(mSystem); -} - -bool LLAudioEngine_FMODEX::initWind() -{ - mNextWindUpdate = 0.0; - - if (!mWindDSP) - { - memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero - strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name)); - mWindDSPDesc->channels = 2; - mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads - if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) - return false; - - if (mWindGen) - delete mWindGen; - - float frequency = 44100; - mWindDSP->getDefaults(&frequency,0,0,0); - mWindGen = new LLWindGen((U32)frequency); - mWindDSP->setUserData((void*)mWindGen); - } - - // *TODO: Should this guard against multiple plays? - if (mWindDSP) - { - mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0); - return true; - } - return false; -} - - -void LLAudioEngine_FMODEX::cleanupWind() -{ - if (mWindDSP) - { - mWindDSP->remove(); - mWindDSP->release(); - mWindDSP = NULL; - } - - delete mWindGen; - mWindGen = NULL; -} - - -//----------------------------------------------------------------------- -void LLAudioEngine_FMODEX::updateWind(LLVector3 wind_vec, F32 camera_height_above_water) -{ - LLVector3 wind_pos; - F64 pitch; - F64 center_freq; - - if (!mEnableWind) - { - return; - } - - if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) - { - - // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up) - // need to convert this to the conventional orientation DS3D and OpenAL use - // where +X = right, +Y = up, +Z = backwards - - wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]); - - // cerr << "Wind update" << endl; - - pitch = 1.0 + mapWindVecToPitch(wind_vec); - center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0)); - - mWindGen->mTargetFreq = (F32)center_freq; - mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; - mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); - } -} - -//----------------------------------------------------------------------- -void LLAudioEngine_FMODEX::setInternalGain(F32 gain) -{ - if (!mInited) - { - return; - } - - gain = llclamp( gain, 0.0f, 1.0f ); - - FMOD::ChannelGroup *master_group; - mSystem->getMasterChannelGroup(&master_group); - - master_group->setVolume(gain); - - LLStreamingAudioInterface *saimpl = getStreamingAudioImpl(); - if ( saimpl ) - { - // fmod likes its streaming audio channel gain re-asserted after - // master volume change. - saimpl->setGain(saimpl->getGain()); - } -} - -// -// LLAudioChannelFMODEX implementation -// - -LLAudioChannelFMODEX::LLAudioChannelFMODEX(FMOD::System *system) : LLAudioChannel(), mSystemp(system), mChannelp(NULL), mLastSamplePos(0) -{ -} - - -LLAudioChannelFMODEX::~LLAudioChannelFMODEX() -{ - cleanup(); -} - -bool LLAudioChannelFMODEX::updateBuffer() -{ - if (LLAudioChannel::updateBuffer()) - { - // Base class update returned true, which means that we need to actually - // set up the channel for a different buffer. - - LLAudioBufferFMODEX *bufferp = (LLAudioBufferFMODEX *)mCurrentSourcep->getCurrentBuffer(); - - // Grab the FMOD sample associated with the buffer - FMOD::Sound *soundp = bufferp->getSound(); - if (!soundp) - { - // This is bad, there should ALWAYS be a sound associated with a legit - // buffer. - LL_ERRS() << "No FMOD sound!" << LL_ENDL; - return false; - } - - - // Actually play the sound. Start it off paused so we can do all the necessary - // setup. - if(!mChannelp) - { - FMOD_RESULT result = getSystem()->playSound(FMOD_CHANNEL_FREE, soundp, true, &mChannelp); - Check_FMOD_Error(result, "FMOD::System::playSound"); - } - - //LL_INFOS() << "Setting up channel " << std::hex << mChannelID << std::dec << LL_ENDL; - } - - // If we have a source for the channel, we need to update its gain. - if (mCurrentSourcep) - { - // SJB: warnings can spam and hurt framerate, disabling - //FMOD_RESULT result; - - mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain()); - //Check_FMOD_Error(result, "FMOD::Channel::setVolume"); - - mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); - /*if(Check_FMOD_Error(result, "FMOD::Channel::setMode")) - { - S32 index; - mChannelp->getIndex(&index); - LL_WARNS() << "Channel " << index << "Source ID: " << mCurrentSourcep->getID() - << " at " << mCurrentSourcep->getPositionGlobal() << LL_ENDL; - }*/ - } - - return true; -} - - -void LLAudioChannelFMODEX::update3DPosition() -{ - if (!mChannelp) - { - // We're not actually a live channel (i.e., we're not playing back anything) - return; - } - - LLAudioBufferFMODEX *bufferp = (LLAudioBufferFMODEX *)mCurrentBufferp; - if (!bufferp) - { - // We don't have a buffer associated with us (should really have been picked up - // by the above if. - return; - } - - if (mCurrentSourcep->isAmbient()) - { - // Ambient sound, don't need to do any positional updates. - set3DMode(false); - } - else - { - // Localized sound. Update the position and velocity of the sound. - set3DMode(true); - - LLVector3 float_pos; - float_pos.setVec(mCurrentSourcep->getPositionGlobal()); - FMOD_RESULT result = mChannelp->set3DAttributes((FMOD_VECTOR*)float_pos.mV, (FMOD_VECTOR*)mCurrentSourcep->getVelocity().mV); - Check_FMOD_Error(result, "FMOD::Channel::set3DAttributes"); - } -} - - -void LLAudioChannelFMODEX::updateLoop() -{ - if (!mChannelp) - { - // May want to clear up the loop/sample counters. - return; - } - - // - // Hack: We keep track of whether we looped or not by seeing when the - // sample position looks like it's going backwards. Not reliable; may - // yield false negatives. - // - U32 cur_pos; - mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES); - - if (cur_pos < (U32)mLastSamplePos) - { - mLoopedThisFrame = true; - } - mLastSamplePos = cur_pos; -} - - -void LLAudioChannelFMODEX::cleanup() -{ - if (!mChannelp) - { - //LL_INFOS() << "Aborting cleanup with no channel handle." << LL_ENDL; - return; - } - - //LL_INFOS() << "Cleaning up channel: " << mChannelID << LL_ENDL; - Check_FMOD_Error(mChannelp->stop(),"FMOD::Channel::stop"); - - mCurrentBufferp = NULL; - mChannelp = NULL; -} - - -void LLAudioChannelFMODEX::play() -{ - if (!mChannelp) - { - LL_WARNS() << "Playing without a channel handle, aborting" << LL_ENDL; - return; - } - - Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::pause"); - - getSource()->setPlayedOnce(true); - - if(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()]) - mChannelp->setChannelGroup(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()]); -} - - -void LLAudioChannelFMODEX::playSynced(LLAudioChannel *channelp) -{ - LLAudioChannelFMODEX *fmod_channelp = (LLAudioChannelFMODEX*)channelp; - if (!(fmod_channelp->mChannelp && mChannelp)) - { - // Don't have channels allocated to both the master and the slave - return; - } - - U32 cur_pos; - if(Check_FMOD_Error(mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES), "Unable to retrieve current position")) - return; - - cur_pos %= mCurrentBufferp->getLength(); - - // Try to match the position of our sync master - Check_FMOD_Error(mChannelp->setPosition(cur_pos,FMOD_TIMEUNIT_PCMBYTES),"Unable to set current position"); - - // Start us playing - play(); -} - - -bool LLAudioChannelFMODEX::isPlaying() -{ - if (!mChannelp) - { - return false; - } - - bool paused, playing; - mChannelp->getPaused(&paused); - mChannelp->isPlaying(&playing); - return !paused && playing; -} - - -// -// LLAudioChannelFMODEX implementation -// - - -LLAudioBufferFMODEX::LLAudioBufferFMODEX(FMOD::System *system) : mSystemp(system), mSoundp(NULL) -{ -} - - -LLAudioBufferFMODEX::~LLAudioBufferFMODEX() -{ - if(mSoundp) - { - mSoundp->release(); - mSoundp = NULL; - } -} - - -bool LLAudioBufferFMODEX::loadWAV(const std::string& filename) -{ - // Try to open a wav file from disk. This will eventually go away, as we don't - // really want to block doing this. - if (filename.empty()) - { - // invalid filename, abort. - return false; - } - - if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB)) - { - // File not found, abort. - return false; - } - - if (mSoundp) - { - // If there's already something loaded in this buffer, clean it up. - mSoundp->release(); - mSoundp = NULL; - } - - FMOD_MODE base_mode = FMOD_LOOP_NORMAL | FMOD_SOFTWARE; - FMOD_CREATESOUNDEXINFO exinfo; - memset(&exinfo,0,sizeof(exinfo)); - exinfo.cbsize = sizeof(exinfo); - exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_WAV; //Hint to speed up loading. - // Load up the wav file into an fmod sample -#if LL_WINDOWS - FMOD_RESULT result = getSystem()->createSound((const char*)utf8str_to_utf16str(filename).c_str(), base_mode | FMOD_UNICODE, &exinfo, &mSoundp); -#else - FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp); -#endif - - if (result != FMOD_OK) - { - // We failed to load the file for some reason. - LL_WARNS() << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << LL_ENDL; - - // - // If we EVER want to load wav files provided by end users, we need - // to rethink this! - // - // file is probably corrupt - remove it. - LLFile::remove(filename); - return false; - } - - // Everything went well, return true - return true; -} - - -U32 LLAudioBufferFMODEX::getLength() -{ - if (!mSoundp) - { - return 0; - } - - U32 length; - mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES); - return length; -} - - -void LLAudioChannelFMODEX::set3DMode(bool use3d) -{ - FMOD_MODE current_mode; - if(mChannelp->getMode(¤t_mode) != FMOD_OK) - return; - FMOD_MODE new_mode = current_mode; - new_mode &= ~(use3d ? FMOD_2D : FMOD_3D); - new_mode |= use3d ? FMOD_3D : FMOD_2D; - - if(current_mode != new_mode) - { - mChannelp->setMode(new_mode); - } -} - -// *NOTE: This is almost certainly being called on the mixer thread, -// not the main thread. May have implications for callees or audio -// engine shutdown. - -FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbuffer, float *newbuffer, unsigned int length, int inchannels, int outchannels) -{ - // originalbuffer = fmod's original mixbuffer. - // newbuffer = the buffer passed from the previous DSP unit. - // length = length in samples at this mix time. - // userdata = user parameter passed through in FSOUND_DSP_Create. - - LLWindGen *windgen; - FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance; - - thisdsp->getUserData((void **)&windgen); - S32 channels, configwidth, configheight; - thisdsp->getInfo(0, 0, &channels, &configwidth, &configheight); - - windgen->windGenerate((LLAudioEngine_FMODEX::MIXBUFFERFORMAT *)newbuffer, length); - - return FMOD_OK; -} diff --git a/indra/llaudio/llaudioengine_fmodex.h b/indra/llaudio/llaudioengine_fmodex.h deleted file mode 100644 index ca389d489f..0000000000 --- a/indra/llaudio/llaudioengine_fmodex.h +++ /dev/null @@ -1,130 +0,0 @@ -/** - * @file audioengine_fmodex.h - * @brief Definition of LLAudioEngine class abstracting the audio - * support as a FMODEX implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2014, 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$ - */ - -#ifndef LL_AUDIOENGINE_FMODEX_H -#define LL_AUDIOENGINE_FMODEX_H - -#include "llaudioengine.h" -#include "llwindgen.h" - -//Stubs -class LLAudioStreamManagerFMODEX; -namespace FMOD -{ - class System; - class Channel; - class ChannelGroup; - class Sound; - class DSP; -} -typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION; - -//Interfaces -class LLAudioEngine_FMODEX : public LLAudioEngine -{ -public: - LLAudioEngine_FMODEX(bool enable_profiler); - virtual ~LLAudioEngine_FMODEX(); - - // initialization/startup/shutdown - virtual bool init(const S32 num_channels, void *user_data); - virtual std::string getDriverName(bool verbose); - virtual void allocateListener(); - - virtual void shutdown(); - - /*virtual*/ bool initWind(); - /*virtual*/ void cleanupWind(); - - /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water); - - typedef F32 MIXBUFFERFORMAT; - - FMOD::System *getSystem() const {return mSystem;} -protected: - /*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to. - /*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel. - - /*virtual*/ void setInternalGain(F32 gain); - - bool mInited; - - LLWindGen *mWindGen; - - FMOD_DSP_DESCRIPTION *mWindDSPDesc; - FMOD::DSP *mWindDSP; - FMOD::System *mSystem; - bool mEnableProfiler; - -public: - static FMOD::ChannelGroup *mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT]; -}; - - -class LLAudioChannelFMODEX : public LLAudioChannel -{ -public: - LLAudioChannelFMODEX(FMOD::System *audioengine); - virtual ~LLAudioChannelFMODEX(); - -protected: - /*virtual*/ void play(); - /*virtual*/ void playSynced(LLAudioChannel *channelp); - /*virtual*/ void cleanup(); - /*virtual*/ bool isPlaying(); - - /*virtual*/ bool updateBuffer(); - /*virtual*/ void update3DPosition(); - /*virtual*/ void updateLoop(); - - void set3DMode(bool use3d); -protected: - FMOD::System *getSystem() const {return mSystemp;} - FMOD::System *mSystemp; - FMOD::Channel *mChannelp; - S32 mLastSamplePos; -}; - - -class LLAudioBufferFMODEX : public LLAudioBuffer -{ -public: - LLAudioBufferFMODEX(FMOD::System *audioengine); - virtual ~LLAudioBufferFMODEX(); - - /*virtual*/ bool loadWAV(const std::string& filename); - /*virtual*/ U32 getLength(); - friend class LLAudioChannelFMODEX; -protected: - FMOD::System *getSystem() const {return mSystemp;} - FMOD::System *mSystemp; - FMOD::Sound *getSound() const{ return mSoundp; } - FMOD::Sound *mSoundp; -}; - - -#endif // LL_AUDIOENGINE_FMODEX_H diff --git a/indra/llaudio/lllistener_fmodex.cpp b/indra/llaudio/lllistener_fmodex.cpp deleted file mode 100644 index 31ab47a635..0000000000 --- a/indra/llaudio/lllistener_fmodex.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file listener_fmodex.cpp - * @brief Implementation of LISTENER class abstracting the audio - * support as a FMODEX implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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 "linden_common.h" -#include "llaudioengine.h" -#include "lllistener_fmodex.h" -#include "fmod.hpp" - -//----------------------------------------------------------------------- -// constructor -//----------------------------------------------------------------------- -LLListener_FMODEX::LLListener_FMODEX(FMOD::System *system) -{ - mSystem = system; - init(); -} - -//----------------------------------------------------------------------- -LLListener_FMODEX::~LLListener_FMODEX() -{ -} - -//----------------------------------------------------------------------- -void LLListener_FMODEX::init(void) -{ - // do inherited - LLListener::init(); - mDopplerFactor = 1.0f; - mRolloffFactor = 1.0f; -} - -//----------------------------------------------------------------------- -void LLListener_FMODEX::translate(LLVector3 offset) -{ - LLListener::translate(offset); - - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); -} - -//----------------------------------------------------------------------- -void LLListener_FMODEX::setPosition(LLVector3 pos) -{ - LLListener::setPosition(pos); - - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); -} - -//----------------------------------------------------------------------- -void LLListener_FMODEX::setVelocity(LLVector3 vel) -{ - LLListener::setVelocity(vel); - - mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); -} - -//----------------------------------------------------------------------- -void LLListener_FMODEX::orient(LLVector3 up, LLVector3 at) -{ - LLListener::orient(up, at); - - // Welcome to the transition between right and left - // (coordinate systems, that is) - // Leaving the at vector alone results in a L/R reversal - // since DX is left-handed and we (LL, OpenGL, OpenAL) are right-handed - at = -at; - - mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV); -} - -//----------------------------------------------------------------------- -void LLListener_FMODEX::commitDeferredChanges() -{ - if(!mSystem) - { - return; - } - - mSystem->update(); -} - - -void LLListener_FMODEX::setRolloffFactor(F32 factor) -{ - //An internal FMODEx optimization skips 3D updates if there have not been changes to the 3D sound environment. - //Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well. - //In short: Changing the position ticks a dirtyflag inside fmodex, which makes it not skip 3D processing next update call. - if(mRolloffFactor != factor) - { - LLVector3 pos = mVelocity - LLVector3(0.f,0.f,.1f); - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL); - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mVelocity.mV, NULL, NULL, NULL); - } - mRolloffFactor = factor; - mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); -} - - -F32 LLListener_FMODEX::getRolloffFactor() -{ - return mRolloffFactor; -} - - -void LLListener_FMODEX::setDopplerFactor(F32 factor) -{ - mDopplerFactor = factor; - mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); -} - - -F32 LLListener_FMODEX::getDopplerFactor() -{ - return mDopplerFactor; -} - - diff --git a/indra/llaudio/lllistener_fmodex.h b/indra/llaudio/lllistener_fmodex.h deleted file mode 100644 index 073b65d53a..0000000000 --- a/indra/llaudio/lllistener_fmodex.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @file listener_fmodex.h - * @brief Description of LISTENER class abstracting the audio support - * as an FMOD 3D implementation (windows and Linux) - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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$ - */ - -#ifndef LL_LISTENER_FMODEX_H -#define LL_LISTENER_FMODEX_H - -#include "lllistener.h" - -//Stubs -namespace FMOD -{ - class System; -} - -//Interfaces -class LLListener_FMODEX : public LLListener -{ - public: - LLListener_FMODEX(FMOD::System *system); - virtual ~LLListener_FMODEX(); - virtual void init(); - - virtual void translate(LLVector3 offset); - virtual void setPosition(LLVector3 pos); - virtual void setVelocity(LLVector3 vel); - virtual void orient(LLVector3 up, LLVector3 at); - virtual void commitDeferredChanges(); - - virtual void setDopplerFactor(F32 factor); - virtual F32 getDopplerFactor(); - virtual void setRolloffFactor(F32 factor); - virtual F32 getRolloffFactor(); - protected: - FMOD::System *mSystem; - F32 mDopplerFactor; - F32 mRolloffFactor; -}; - -#endif - - diff --git a/indra/llaudio/llstreamingaudio_fmodex.cpp b/indra/llaudio/llstreamingaudio_fmodex.cpp deleted file mode 100644 index 9c9e85c00c..0000000000 --- a/indra/llaudio/llstreamingaudio_fmodex.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/** - * @file streamingaudio_fmodex.cpp - * @brief LLStreamingAudio_FMODEX implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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 "linden_common.h" - -#include "llmath.h" - -#include "fmod.hpp" -#include "fmod_errors.h" - -#include "llstreamingaudio_fmodex.h" - - -class LLAudioStreamManagerFMODEX -{ -public: - LLAudioStreamManagerFMODEX(FMOD::System *system, const std::string& url); - FMOD::Channel* startStream(); - bool stopStream(); // Returns true if the stream was successfully stopped. - bool ready(); - - const std::string& getURL() { return mInternetStreamURL; } - - FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered=NULL, bool* starving=NULL, bool* diskbusy=NULL); -protected: - FMOD::System* mSystem; - FMOD::Channel* mStreamChannel; - FMOD::Sound* mInternetStream; - bool mReady; - - std::string mInternetStreamURL; -}; - - - -//--------------------------------------------------------------------------- -// Internet Streaming -//--------------------------------------------------------------------------- -LLStreamingAudio_FMODEX::LLStreamingAudio_FMODEX(FMOD::System *system) : - mSystem(system), - mCurrentInternetStreamp(NULL), - mFMODInternetStreamChannelp(NULL), - mGain(1.0f) -{ - // Number of milliseconds of audio to buffer for the audio card. - // Must be larger than the usual Second Life frame stutter time. - const U32 buffer_seconds = 10; //sec - const U32 estimated_bitrate = 128; //kbit/sec - mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES); - - // Here's where we set the size of the network buffer and some buffering - // parameters. In this case we want a network buffer of 16k, we want it - // to prebuffer 40% of that when we first connect, and we want it - // to rebuffer 80% of that whenever we encounter a buffer underrun. - - // Leave the net buffer properties at the default. - //FSOUND_Stream_Net_SetBufferProperties(20000, 40, 80); -} - - -LLStreamingAudio_FMODEX::~LLStreamingAudio_FMODEX() -{ - // nothing interesting/safe to do. -} - - -void LLStreamingAudio_FMODEX::start(const std::string& url) -{ - //if (!mInited) - //{ - // LL_WARNS() << "startInternetStream before audio initialized" << LL_ENDL; - // return; - //} - - // "stop" stream but don't clear url, etc. in case url == mInternetStreamURL - stop(); - - if (!url.empty()) - { - LL_INFOS() << "Starting internet stream: " << url << LL_ENDL; - mCurrentInternetStreamp = new LLAudioStreamManagerFMODEX(mSystem,url); - mURL = url; - } - else - { - LL_INFOS() << "Set internet stream to null" << LL_ENDL; - mURL.clear(); - } -} - - -void LLStreamingAudio_FMODEX::update() -{ - // Kill dead internet streams, if possible - std::list::iterator iter; - for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();) - { - LLAudioStreamManagerFMODEX *streamp = *iter; - if (streamp->stopStream()) - { - LL_INFOS() << "Closed dead stream" << LL_ENDL; - delete streamp; - mDeadStreams.erase(iter++); - } - else - { - iter++; - } - } - - // Don't do anything if there are no streams playing - if (!mCurrentInternetStreamp) - { - return; - } - - unsigned int progress; - bool starving; - bool diskbusy; - FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy); - - if (open_state == FMOD_OPENSTATE_READY) - { - // Stream is live - - // start the stream if it's ready - if (!mFMODInternetStreamChannelp && - (mFMODInternetStreamChannelp = mCurrentInternetStreamp->startStream())) - { - // Reset volume to previously set volume - setGain(getGain()); - mFMODInternetStreamChannelp->setPaused(false); - } - } - else if(open_state == FMOD_OPENSTATE_ERROR) - { - stop(); - return; - } - - if(mFMODInternetStreamChannelp) - { - FMOD::Sound *sound = NULL; - - if(mFMODInternetStreamChannelp->getCurrentSound(&sound) == FMOD_OK && sound) - { - FMOD_TAG tag; - S32 tagcount, dirtytagcount; - - if(sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount) - { - for(S32 i = 0; i < tagcount; ++i) - { - if(sound->getTag(NULL, i, &tag)!=FMOD_OK) - continue; - - if (tag.type == FMOD_TAGTYPE_FMOD) - { - if (!strcmp(tag.name, "Sample Rate Change")) - { - LL_INFOS() << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL; - mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)); - } - continue; - } - } - } - - if(starving) - { - bool paused = false; - mFMODInternetStreamChannelp->getPaused(&paused); - if(!paused) - { - LL_INFOS() << "Stream starvation detected! Pausing stream until buffer nearly full." << LL_ENDL; - LL_INFOS() << " (diskbusy="<setPaused(true); - } - } - else if(progress > 80) - { - mFMODInternetStreamChannelp->setPaused(false); - } - } - } -} - -void LLStreamingAudio_FMODEX::stop() -{ - if (mFMODInternetStreamChannelp) - { - mFMODInternetStreamChannelp->setPaused(true); - mFMODInternetStreamChannelp->setPriority(0); - mFMODInternetStreamChannelp = NULL; - } - - if (mCurrentInternetStreamp) - { - LL_INFOS() << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << LL_ENDL; - if (mCurrentInternetStreamp->stopStream()) - { - delete mCurrentInternetStreamp; - } - else - { - LL_WARNS() << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << LL_ENDL; - mDeadStreams.push_back(mCurrentInternetStreamp); - } - mCurrentInternetStreamp = NULL; - //mURL.clear(); - } -} - -void LLStreamingAudio_FMODEX::pause(int pauseopt) -{ - if (pauseopt < 0) - { - pauseopt = mCurrentInternetStreamp ? 1 : 0; - } - - if (pauseopt) - { - if (mCurrentInternetStreamp) - { - stop(); - } - } - else - { - start(getURL()); - } -} - - -// A stream is "playing" if it has been requested to start. That -// doesn't necessarily mean audio is coming out of the speakers. -int LLStreamingAudio_FMODEX::isPlaying() -{ - if (mCurrentInternetStreamp) - { - return 1; // Active and playing - } - else if (!mURL.empty()) - { - return 2; // "Paused" - } - else - { - return 0; - } -} - - -F32 LLStreamingAudio_FMODEX::getGain() -{ - return mGain; -} - - -std::string LLStreamingAudio_FMODEX::getURL() -{ - return mURL; -} - - -void LLStreamingAudio_FMODEX::setGain(F32 vol) -{ - mGain = vol; - - if (mFMODInternetStreamChannelp) - { - vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here? - - mFMODInternetStreamChannelp->setVolume(vol); - } -} - -/////////////////////////////////////////////////////// -// manager of possibly-multiple internet audio streams - -LLAudioStreamManagerFMODEX::LLAudioStreamManagerFMODEX(FMOD::System *system, const std::string& url) : - mSystem(system), - mStreamChannel(NULL), - mInternetStream(NULL), - mReady(false) -{ - mInternetStreamURL = url; - - FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream); - - if (result!= FMOD_OK) - { - LL_WARNS() << "Couldn't open fmod stream, error " - << FMOD_ErrorString(result) - << LL_ENDL; - mReady = false; - return; - } - - mReady = true; -} - -FMOD::Channel *LLAudioStreamManagerFMODEX::startStream() -{ - // We need a live and opened stream before we try and play it. - if (!mInternetStream || getOpenState() != FMOD_OPENSTATE_READY) - { - LL_WARNS() << "No internet stream to start playing!" << LL_ENDL; - return NULL; - } - - if(mStreamChannel) - return mStreamChannel; //Already have a channel for this stream. - - mSystem->playSound(FMOD_CHANNEL_FREE, mInternetStream, true, &mStreamChannel); - return mStreamChannel; -} - -bool LLAudioStreamManagerFMODEX::stopStream() -{ - if (mInternetStream) - { - - - bool close = true; - switch (getOpenState()) - { - case FMOD_OPENSTATE_CONNECTING: - close = false; - break; - default: - close = true; - } - - if (close) - { - mInternetStream->release(); - mStreamChannel = NULL; - mInternetStream = NULL; - return true; - } - else - { - return false; - } - } - else - { - return true; - } -} - -FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy) -{ - FMOD_OPENSTATE state; - mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy); - return state; -} - -void LLStreamingAudio_FMODEX::setBufferSizes(U32 streambuffertime, U32 decodebuffertime) -{ - mSystem->setStreamBufferSize(streambuffertime/1000*128*128, FMOD_TIMEUNIT_RAWBYTES); - FMOD_ADVANCEDSETTINGS settings; - memset(&settings,0,sizeof(settings)); - settings.cbsize=sizeof(settings); - settings.defaultDecodeBufferSize = decodebuffertime;//ms - mSystem->setAdvancedSettings(&settings); -} diff --git a/indra/llaudio/llstreamingaudio_fmodex.h b/indra/llaudio/llstreamingaudio_fmodex.h deleted file mode 100644 index 2787840ba1..0000000000 --- a/indra/llaudio/llstreamingaudio_fmodex.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file streamingaudio_fmodex.h - * @brief Definition of LLStreamingAudio_FMODEX implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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$ - */ - -#ifndef LL_STREAMINGAUDIO_FMODEX_H -#define LL_STREAMINGAUDIO_FMODEX_H - -#include "stdtypes.h" // from llcommon - -#include "llstreamingaudio.h" -#include "lltimer.h" - -//Stubs -class LLAudioStreamManagerFMODEX; -namespace FMOD -{ - class System; - class Channel; -} - -//Interfaces -class LLStreamingAudio_FMODEX : public LLStreamingAudioInterface -{ - public: - LLStreamingAudio_FMODEX(FMOD::System *system); - /*virtual*/ ~LLStreamingAudio_FMODEX(); - - /*virtual*/ void start(const std::string& url); - /*virtual*/ void stop(); - /*virtual*/ void pause(S32 pause); - /*virtual*/ void update(); - /*virtual*/ S32 isPlaying(); - /*virtual*/ void setGain(F32 vol); - /*virtual*/ F32 getGain(); - /*virtual*/ std::string getURL(); - - /*virtual*/ bool supportsAdjustableBufferSizes(){return true;} - /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime); -private: - FMOD::System *mSystem; - - LLAudioStreamManagerFMODEX *mCurrentInternetStreamp; - FMOD::Channel *mFMODInternetStreamChannelp; - std::list mDeadStreams; - - std::string mURL; - F32 mGain; -}; - - -#endif // LL_STREAMINGAUDIO_FMODEX_H diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 22871a9d94..f8ed19f884 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -18,7 +18,6 @@ include(DBusGlib) include(DirectX) include(DragDrop) include(EXPAT) -include(FMODEX) include(FMODSTUDIO) include(GLOD) include(Hunspell) @@ -64,10 +63,6 @@ if (NOT HAVOK_TPV) add_subdirectory(${LLPHYSICSEXTENSIONS_SRC_DIR} llphysicsextensions) endif (NOT HAVOK_TPV) -if(FMODEX) - include_directories(${FMODEX_INCLUDE_DIR}) -endif(FMODEX) - if(FMODSTUDIO) include_directories(${FMODSTUDIO_INCLUDE_DIR}) endif(FMODSTUDIO) @@ -1714,11 +1709,6 @@ if (OPENAL) set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL") endif (OPENAL) -if (FMODEX) - set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX") - set(FMODEXWRAPPER_LIBRARY ${FMODEX_LIBRARY}) -endif (FMODEX) - if (FMODSTUDIO) set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODSTUDIO") set(FMODWRAPPER_LIBRARY ${FMODSTUDIO_LIBRARY}) @@ -1839,14 +1829,6 @@ if (WINDOWS) ) endif (ADDRESS_SIZE EQUAL 64) - if (FMODEX) - list(APPEND COPY_INPUT_DEPENDENCIES - ${SHARED_LIB_STAGING_DIR}/Release/fmodex.dll - ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmodex.dll - ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll - ) - endif (FMODEX) - if (FMODSTUDIO) list(APPEND COPY_INPUT_DEPENDENCIES ${SHARED_LIB_STAGING_DIR}/Release/fmod.dll @@ -1864,7 +1846,6 @@ if (WINDOWS) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" - "--fmodex=${FMODEX}" "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} @@ -1927,7 +1908,6 @@ if (WINDOWS) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" - "--fmodex=${FMODEX}" "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} @@ -2026,7 +2006,6 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${BOOST_CONTEXT_LIBRARY} ${DBUSGLIB_LIBRARIES} ${OPENGL_LIBRARIES} - ${FMODEXWRAPPER_LIBRARY} # must come after LLAudio ${FMODWRAPPER_LIBRARY} # must come after LLAudio ${GLOD_LIBRARIES} ${OPENGL_LIBRARIES} @@ -2075,7 +2054,6 @@ if (LINUX) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" - "--fmodex=${FMODEX}" "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} @@ -2103,7 +2081,6 @@ if (LINUX) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" - "--fmodex=${FMODEX}" "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} @@ -2181,7 +2158,6 @@ if (DARWIN) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" - "--fmodex=${FMODEX}" "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} @@ -2217,7 +2193,6 @@ if (DARWIN) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" - "--fmodex=${FMODEX}" "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} diff --git a/indra/newview/linux_tools/client-readme.txt b/indra/newview/linux_tools/client-readme.txt index e01b9e4bc6..aaa8a6b6d7 100644 --- a/indra/newview/linux_tools/client-readme.txt +++ b/indra/newview/linux_tools/client-readme.txt @@ -187,8 +187,8 @@ The 'secondlife' script which launches Second Life contains some configuration options for advanced troubleshooters. * AUDIO - Edit the 'secondlife' script and you will see these audio - options: LL_BAD_OPENAL_DRIVER, LL_BAD_FMOD_ESD, LL_BAD_FMOD_OSS, and - LL_BAD_FMOD_ALSA. Second Life tries to use OpenAL, ESD, OSS, then ALSA + options: LL_BAD_OPENAL_DRIVER, LL_BAD_FMODSTUDIO_DRIVER. + Second Life tries to use OpenAL, FMODSTUDIO audio drivers in this order; you may uncomment the corresponding LL_BAD_* option to skip an audio driver which you believe may be causing you trouble. diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index c23401d5a6..e04090297c 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -4,6 +4,8 @@ ## These options are for self-assisted troubleshooting during this beta ## testing phase; you should not usually need to touch them. +## - Avoids using any FMOD STUDIO audio driver. +#export LL_BAD_FMODSTUDIO_DRIVER=x ## - Avoids using any FMOD Ex audio driver. #export LL_BAD_FMODEX_DRIVER=x ## - Avoids using any OpenAL audio driver. diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 137d73fead..f5276b47ea 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -39,10 +39,6 @@ #include "llviewermedia_streamingaudio.h" #include "llaudioengine.h" -#ifdef LL_FMODEX -# include "llaudioengine_fmodex.h" -#endif - #ifdef LL_FMODSTUDIO # include "llaudioengine_fmodstudio.h" #endif @@ -627,18 +623,9 @@ bool idle_startup() delete gAudiop; gAudiop = NULL; -#ifdef LL_FMODEX -#if !LL_WINDOWS - if (NULL == getenv("LL_BAD_FMODEX_DRIVER")) -#endif // !LL_WINDOWS - { - gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODEX(gSavedSettings.getBOOL("FMODExProfilerEnable")); - } -#endif - #ifdef LL_FMODSTUDIO #if !LL_WINDOWS - if (NULL == getenv("LL_BAD_FMODEX_DRIVER")) + if (NULL == getenv("LL_BAD_FMODSTUDIO_DRIVER")) #endif // !LL_WINDOWS { gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODSTUDIO(gSavedSettings.getBOOL("FMODExProfilerEnable")); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 0140a4b928..572c84c396 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -513,14 +513,6 @@ class WindowsManifest(ViewerManifest): print err.message print "Skipping GLOD library (assumming linked statically)" - # Get fmodex dll if needed - # Normally only fmodex or fmodstudio are needed, but just in case checkking both. - if self.args['fmodex'] == 'ON': - if(self.address_size == 64): - self.path("fmodex64.dll") - else: - self.path("fmodex.dll") - # Get fmodstudio dll if needed if self.args['fmodstudio'] == 'ON': if(self.args['configuration'].lower() == 'debug'): @@ -1052,19 +1044,6 @@ class DarwinManifest(ViewerManifest): ): self.path2basename(relpkgdir, libfile) - # Fmodex dylibs that vary based on configuration - if self.args['fmodex'] == 'ON': - if self.args['configuration'].lower() == 'debug': - for libfile in ( - "libfmodexL.dylib", - ): - dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile) - else: - for libfile in ( - "libfmodex.dylib", - ): - dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) - # Fmod studio dylibs (vary based on configuration) if self.args['fmodstudio'] == 'ON': if self.args['configuration'].lower() == 'debug': @@ -1539,15 +1518,6 @@ class Linux_i686_Manifest(LinuxManifest): print "tcmalloc files not found, skipping" pass - if self.args['fmodex'] == 'ON': - try: - self.path("libfmodex-*.so") - self.path("libfmodex.so") - pass - except: - print "Skipping libfmodex.so - not found" - pass - if self.args['fmodstudio'] == 'ON': try: self.path("libfmod.so.11.7") @@ -1586,7 +1556,6 @@ if __name__ == "__main__": extra_arguments = [ dict(name='bugsplat', description="""BugSplat database to which to post crashes, if BugSplat crash reporting is desired""", default=''), - dict(name='fmodex', description="""Indication if fmodex libraries are needed""", default='OFF'), dict(name='fmodstudio', description="""Indication if fmod studio libraries are needed""", default='OFF'), ] try: -- cgit v1.3