diff options
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llatmosphere.cpp | 348 | ||||
-rw-r--r-- | indra/llrender/llatmosphere.h | 50 | ||||
-rw-r--r-- | indra/llrender/llglslshader.cpp | 324 | ||||
-rw-r--r-- | indra/llrender/llglslshader.h | 36 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 127 | ||||
-rw-r--r-- | indra/llrender/llrender.h | 22 | ||||
-rw-r--r-- | indra/llrender/llshadermgr.cpp | 47 | ||||
-rw-r--r-- | indra/llrender/llshadermgr.h | 8 |
8 files changed, 651 insertions, 311 deletions
diff --git a/indra/llrender/llatmosphere.cpp b/indra/llrender/llatmosphere.cpp index 6ce5292839..644e102a15 100644 --- a/indra/llrender/llatmosphere.cpp +++ b/indra/llrender/llatmosphere.cpp @@ -36,6 +36,102 @@ LLAtmosphere* gAtmosphere = nullptr; +// 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 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 max_sun_zenith_angle = F_PI * 2.0 / 3.0; + +AtmosphericModelSettings::AtmosphericModelSettings() + : m_skyBottomRadius(6360.0f) + , m_skyTopRadius(6420.0f) + , 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); + + m_rayleighProfile.push_back(rayleigh_density); + m_mieProfile.push_back(mie_density); + + // 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). + 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)); +} + +AtmosphericModelSettings::AtmosphericModelSettings( + DensityProfile& rayleighProfile, + DensityProfile& mieProfile, + DensityProfile& absorptionProfile) +: m_skyBottomRadius(6360.0f) +, m_skyTopRadius(6420.0f) +, m_rayleighProfile(rayleighProfile) +, m_mieProfile(mieProfile) +, m_absorptionProfile(absorptionProfile) +, m_sunArcRadians(0.00045f) +, m_mieAnisotropy(0.8f) +{ +} + +AtmosphericModelSettings::AtmosphericModelSettings( + F32 skyBottomRadius, + F32 skyTopRadius, + DensityProfile& rayleighProfile, + DensityProfile& mieProfile, + DensityProfile& absorptionProfile, + F32 sunArcRadians, + F32 mieAniso) +: m_skyBottomRadius(skyBottomRadius) +, m_skyTopRadius(skyTopRadius) +, m_rayleighProfile(rayleighProfile) +, m_mieProfile(mieProfile) +, m_absorptionProfile(absorptionProfile) +, m_sunArcRadians(sunArcRadians) +, m_mieAnisotropy(mieAniso) +{ +} + void LLAtmosphere::initClass() { if (!gAtmosphere) @@ -55,164 +151,152 @@ void LLAtmosphere::cleanupClass() LLAtmosphere::LLAtmosphere() { - // Init libatmosphere model - m_config.num_scattering_orders = 4; + for (int l = kLambdaMin; l <= kLambdaMax; l += 10) + { + double lambda = static_cast<double>(l) * 1e-3; // micro-meters + double mie = kMieAngstromBeta / kMieScaleHeight * pow(lambda, -kMieAngstromAlpha); + m_wavelengths.push_back(l); + m_solar_irradiance.push_back(kSolarIrradiance[(l - kLambdaMin) / 10]); + m_rayleigh_scattering.push_back(kRayleigh * pow(lambda, -4)); + m_mie_scattering.push_back(mie * kMieSingleScatteringAlbedo); + m_mie_extinction.push_back(mie); + m_absorption_extinction.push_back(kMaxOzoneNumberDensity * kOzoneCrossSection[(l - kLambdaMin) / 10]); + m_ground_albedo.push_back(0.6f); + } - // 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; + AtmosphericModelSettings defaults; + configureAtmosphericModel(defaults); +} - 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); +LLAtmosphere::~LLAtmosphere() +{ + // Cease referencing textures from atmosphere::model from our LLGLTextures wrappers for same. + if (m_transmittance) + { + m_transmittance->setTexName(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<atmosphere::DensityProfileLayer> 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<double> wavelengths; - std::vector<double> solar_irradiance; - std::vector<double> rayleigh_scattering; - std::vector<double> mie_scattering; - std::vector<double> mie_extinction; - std::vector<double> absorption_extinction; - std::vector<double> ground_albedo; + if (m_scattering) + { + m_scattering->setTexName(0); + } - for (int l = kLambdaMin; l <= kLambdaMax; l += 10) + if (m_mie_scatter_texture) { - double lambda = static_cast<double>(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_mie_scatter_texture->setTexName(0); + } + + delete m_model; + m_model = nullptr; +} + +bool LLAtmosphere::configureAtmosphericModel(AtmosphericModelSettings& settings) +{ +// Advanced Atmospherics TODO +// Make this store a hash of the precomputed data +// and avoid redundant calcs for identical settings + + 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_config.num_scattering_orders = 4; 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, + 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, 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->generateGLTexture(); - m_transmittance->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); - m_transmittance->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); - m_transmittance->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT); - m_transmittance->setTexName(m_textures.transmittance_texture); - m_transmittance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE); - - m_scattering->generateGLTexture(); - m_scattering->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); - m_scattering->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); - m_scattering->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT); - m_scattering->setTexName(m_textures.transmittance_texture); - m_scattering->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D); - - m_mie_scattering->generateGLTexture(); - m_mie_scattering->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); - m_mie_scattering->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); - m_mie_scattering->setExplicitFormat(GL_RGB16F_ARB, 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); + 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); + } - delete m_model; - m_model = nullptr; + return m_model != nullptr; } -LLGLTexture* LLAtmosphere::getTransmittance() const +LLGLTexture* LLAtmosphere::getTransmittance() { + if (!m_transmittance) + { + m_transmittance = new LLGLTexture; + m_transmittance->generateGLTexture(); + m_transmittance->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); + m_transmittance->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); + m_transmittance->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT); + m_transmittance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE); + } return m_transmittance; } -LLGLTexture* LLAtmosphere::getScattering() const +LLGLTexture* LLAtmosphere::getScattering() { + if (!m_scattering) + { + m_scattering = new LLGLTexture; + m_scattering->generateGLTexture(); + m_scattering->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); + m_scattering->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); + m_scattering->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT); + m_scattering->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D); + } return m_scattering; } -LLGLTexture* LLAtmosphere::getMieScattering() const +LLGLTexture* LLAtmosphere::getMieScattering() +{ + if (!m_mie_scatter_texture) + { + m_mie_scatter_texture = new LLGLTexture; + m_mie_scatter_texture->generateGLTexture(); + m_mie_scatter_texture->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); + m_mie_scatter_texture->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); + m_mie_scatter_texture->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT); + m_mie_scatter_texture->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D); + } + return m_mie_scatter_texture; +} + +LLGLTexture* LLAtmosphere::getIlluminance() { - return m_mie_scattering; + if (!m_illuminance) + { + m_illuminance = new LLGLTexture; + m_illuminance->generateGLTexture(); + m_illuminance->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP); + m_illuminance->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR); + m_illuminance->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT); + m_illuminance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE); + } + return m_illuminance; } GLhandleARB LLAtmosphere::getAtmosphericShaderForLink() const diff --git a/indra/llrender/llatmosphere.h b/indra/llrender/llatmosphere.h index 6a9d1a4438..0d62a069ac 100644 --- a/indra/llrender/llatmosphere.h +++ b/indra/llrender/llatmosphere.h @@ -31,6 +31,36 @@ #include "llgltexture.h" #include "libatmosphere/model.h" +typedef std::vector<atmosphere::DensityProfileLayer> DensityProfile; + +class AtmosphericModelSettings +{ +public: + AtmosphericModelSettings(); + + AtmosphericModelSettings( + DensityProfile& rayleighProfile, + DensityProfile& mieProfile, + DensityProfile& absorptionProfile); + + AtmosphericModelSettings( + F32 skyBottomRadius, + F32 skyTopRadius, + DensityProfile& rayleighProfile, + DensityProfile& mieProfile, + DensityProfile& absorptionProfile, + F32 sunArcRadians, + F32 mieAniso); + + F32 m_skyBottomRadius; + F32 m_skyTopRadius; + DensityProfile m_rayleighProfile; + DensityProfile m_mieProfile; + DensityProfile m_absorptionProfile; + F32 m_sunArcRadians; + F32 m_mieAnisotropy; +}; + class LLAtmosphere { public: @@ -46,12 +76,15 @@ public: return *this; } - LLGLTexture* getTransmittance() const; - LLGLTexture* getScattering() const; - LLGLTexture* getMieScattering() const; + LLGLTexture* getTransmittance(); + LLGLTexture* getScattering(); + LLGLTexture* getMieScattering(); + LLGLTexture* getIlluminance(); GLhandleARB getAtmosphericShaderForLink() const; + bool configureAtmosphericModel(AtmosphericModelSettings& settings); + protected: LLAtmosphere(const LLAtmosphere& rhs) { @@ -64,7 +97,16 @@ protected: LLPointer<LLGLTexture> m_transmittance; LLPointer<LLGLTexture> m_scattering; - LLPointer<LLGLTexture> m_mie_scattering; + LLPointer<LLGLTexture> m_mie_scatter_texture; + LLPointer<LLGLTexture> m_illuminance; + + std::vector<double> m_wavelengths; + std::vector<double> m_solar_irradiance; + std::vector<double> m_rayleigh_scattering; + std::vector<double> m_mie_scattering; + std::vector<double> m_mie_extinction; + std::vector<double> m_absorption_extinction; + std::vector<double> m_ground_albedo; }; extern LLAtmosphere* gAtmosphere; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 37a62da17c..37bcf0c163 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -84,6 +84,9 @@ LLShaderFeatures::LLShaderFeatures() , hasObjectSkinning(false) , hasAtmospherics(false) , hasGamma(false) + , hasSrgb(false) + , encodesNormal(false) + , decodesNormal(false) , mIndexedTextureChannels(0) , disableTextureIndex(false) , hasAlphaMask(false) @@ -154,7 +157,8 @@ void LLGLSLShader::clearStats() mSamplesDrawn = 0; mDrawCalls = 0; mTextureStateFetched = false; - mTextureMagMinFilter.clear(); + mTextureMagFilter.clear(); + mTextureMinFilter.clear(); } void LLGLSLShader::dumpStats() @@ -167,16 +171,14 @@ void LLGLSLShader::dumpStats() { LL_INFOS() << mShaderFiles[i].first << LL_ENDL; } - for (uniforms_index_t::iterator it = mTexture.begin(); it != mTexture.end(); ++it) + for (U32 i = 0; i < mTexture.size(); ++i) { - S32 i = (*it).first; - GLint idx = (*it).second; + GLint idx = mTexture[i]; if (idx >= 0) { GLint uniform_idx = getUniformLocation(i); - magmin_filter_t::iterator it = mTextureMagMinFilter.find(i); - LL_INFOS() << mUniformNameMap[uniform_idx] << " - " << std::hex << (*it).second.second << "/" << (*it).second.first << std::dec << LL_ENDL; + LL_INFOS() << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << LL_ENDL; } } LL_INFOS() << "=============================================" << LL_ENDL; @@ -233,13 +235,14 @@ void LLGLSLShader::placeProfileQuery() if (!mTextureStateFetched) { mTextureStateFetched = true; + mTextureMagFilter.resize(mTexture.size()); + mTextureMinFilter.resize(mTexture.size()); U32 cur_active = gGL.getCurrentTexUnitIndex(); - for (uniforms_index_t::iterator it = mTexture.begin(); it != mTexture.end(); ++it) + for (U32 i = 0; i < mTexture.size(); ++i) { - S32 i = (*it).first; - GLint idx = (*it).second; + GLint idx = mTexture[i]; if (idx >= 0) { @@ -253,7 +256,8 @@ void LLGLSLShader::placeProfileQuery() glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag); glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min); - mTextureMagMinFilter[i] = magmin_values_t(mag, min); + mTextureMagFilter[i] = mag; + mTextureMinFilter[i] = min; } } @@ -411,7 +415,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes, for ( ; fileIter != mShaderFiles.end(); fileIter++ ) { GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, &mDefines, mFeatures.mIndexedTextureChannels); - LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << " shaderhandle=" << shaderhandle << LL_ENDL; + LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL; if (shaderhandle) { attachObject(shaderhandle); @@ -474,14 +478,13 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes, } S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten - for (uniforms_index_t::iterator it = mTexture.begin(); it != mTexture.end(); ++it) + for (U32 i = 0; i < mTexture.size(); i++) { - int i = (*it).first; - if (((*it).second >= 0) && ((*it).second < channel_count)) + if (mTexture[i] > -1 && mTexture[i] < channel_count) { llassert(cur_tex < gGLManager.mNumTextureImageUnits); uniform1i(i, cur_tex); - (*it).second = cur_tex++; + mTexture[i] = cur_tex++; } } unbind(); @@ -668,16 +671,13 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * //find the index of this uniform for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++) { - if (LLShaderMgr::instance()->mReservedUniforms[i] == name) + if ( (mUniform[i] == -1) + && (LLShaderMgr::instance()->mReservedUniforms[i] == name)) { - std::pair<uniforms_index_t::iterator, bool> result; - - result = mUniform.insert(uniforms_index_t::value_type(i, location)); - if (result.second) - { - mTexture[i] = mapUniformTextureChannel(location, type); - return; - } + //found it + mUniform[i] = location; + mTexture[i] = mapUniformTextureChannel(location, type); + return; } } @@ -685,17 +685,13 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * { for (U32 i = 0; i < uniforms->size(); i++) { - std::pair<uniforms_index_t::iterator, bool> result; - S32 index = i + LLShaderMgr::instance()->mReservedUniforms.size(); - - if ((*uniforms)[i].String() == name) + if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1) + && ((*uniforms)[i].String() == name)) { - result = mUniform.insert(uniforms_index_t::value_type(index, location)); - if (result.second) - { - mTexture[index] = mapUniformTextureChannel(location, type); - return; - } + //found it + mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location; + mTexture[i+LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type); + return; } } } @@ -735,6 +731,10 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms) mUniformNameMap.clear(); mTexture.clear(); mValue.clear(); + //initialize arrays + U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size(); + mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1); + mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1); bind(); @@ -934,14 +934,20 @@ S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LL S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode) { - GLint channel = getTexChannelForIndex(uniform); + if (uniform < 0 || uniform >= (S32)mTexture.size()) + { + UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; + return -1; + } + + uniform = mTexture[uniform]; - if (channel > -1) + if (uniform > -1) { - gGL.getTexUnit(channel)->bind(texture, mode); + gGL.getTexUnit(uniform)->bind(texture, mode); } - return channel; + return uniform; } S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureType mode) @@ -954,64 +960,82 @@ S32 LLGLSLShader::unbindTexture(const std::string &uniform, LLTexUnit::eTextureT S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode) { - GLint channel = getTexChannelForIndex(uniform); - - if (channel > -1) + if (uniform < 0 || uniform >= (S32)mTexture.size()) { - gGL.getTexUnit(channel)->unbind(mode); + UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; + return -1; } - return channel; + uniform = mTexture[uniform]; + + if (uniform > -1) + { + gGL.getTexUnit(uniform)->unbind(mode); + } + + return uniform; } S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode) { - GLint channel = getTexChannelForIndex(uniform); - - if (channel != -1) + if (uniform < 0 || uniform >= (S32)mTexture.size()) { - gGL.getTexUnit(channel)->activate(); - gGL.getTexUnit(channel)->enable(mode); + UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; + return -1; } - return channel; + S32 index = mTexture[uniform]; + if (index != -1) + { + gGL.getTexUnit(index)->activate(); + gGL.getTexUnit(index)->enable(mode); + } + return index; } S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode) { - GLint channel = getTexChannelForIndex(uniform); - - if (channel != -1 && gGL.getTexUnit(channel)->getCurrType() != LLTexUnit::TT_NONE) + if (uniform < 0 || uniform >= (S32)mTexture.size()) + { + UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; + return -1; + } + S32 index = mTexture[uniform]; + if (index != -1 && gGL.getTexUnit(index)->getCurrType() != LLTexUnit::TT_NONE) { - if (gDebugGL && gGL.getTexUnit(channel)->getCurrType() != mode) + if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode) { if (gDebugSession) { - gFailLog << "Texture channel " << channel << " texture type corrupted." << std::endl; + gFailLog << "Texture channel " << index << " texture type corrupted." << std::endl; ll_fail("LLGLSLShader::disableTexture failed"); } else { - LL_ERRS() << "Texture channel " << channel << " texture type corrupted." << LL_ENDL; + LL_ERRS() << "Texture channel " << index << " texture type corrupted." << LL_ENDL; } } - gGL.getTexUnit(channel)->disable(); + gGL.getTexUnit(index)->disable(); } - return channel; + return index; } void LLGLSLShader::uniform1i(U32 index, GLint x) { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); if (iter == mValue.end() || iter->second.mV[0] != x) { - glUniform1iARB(location, x); - mValue[location] = LLVector4(x,0.f,0.f,0.f); + glUniform1iARB(mUniform[index], x); + mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f); } } } @@ -1021,15 +1045,19 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x) { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); if (iter == mValue.end() || iter->second.mV[0] != x) { - glUniform1fARB(location, x); - mValue[location] = LLVector4(x,0.f,0.f,0.f); + glUniform1fARB(mUniform[index], x); + mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f); } } } @@ -1039,16 +1067,20 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y) { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); LLVector4 vec(x,y,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { - glUniform2fARB(location, x, y); - mValue[location] = vec; + glUniform2fARB(mUniform[index], x, y); + mValue[mUniform[index]] = vec; } } } @@ -1058,16 +1090,20 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z) { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); LLVector4 vec(x,y,z,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec)) { - glUniform3fARB(location, x, y, z); - mValue[location] = vec; + glUniform3fARB(mUniform[index], x, y, z); + mValue[mUniform[index]] = vec; } } } @@ -1077,16 +1113,20 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); LLVector4 vec(x,y,z,w); if (iter == mValue.end() || shouldChange(iter->second,vec)) { - glUniform4fARB(location, x, y, z, w); - mValue[location] = vec; + glUniform4fARB(mUniform[index], x, y, z, w); + mValue[mUniform[index]] = vec; } } } @@ -1096,16 +1136,20 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v) { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { - glUniform1ivARB(location, count, v); - mValue[location] = vec; + glUniform1ivARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; } } } @@ -1115,16 +1159,20 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v) { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],0.f,0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { - glUniform1fvARB(location, count, v); - mValue[location] = vec; + glUniform1fvARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; } } } @@ -1134,16 +1182,20 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v) { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],v[1],0.f,0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { - glUniform2fvARB(location, count, v); - mValue[location] = vec; + glUniform2fvARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; } } } @@ -1153,16 +1205,20 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v) { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],v[1],v[2],0.f); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { - glUniform3fvARB(location, count, v); - mValue[location] = vec; + glUniform3fvARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; } } } @@ -1172,16 +1228,20 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v) { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - std::map<GLint, LLVector4>::iterator iter = mValue.find(location); + std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]); LLVector4 vec(v[0],v[1],v[2],v[3]); if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) { - glUniform4fvARB(location, count, v); - mValue[location] = vec; + glUniform4fvARB(mUniform[index], count, v); + mValue[mUniform[index]] = vec; } } } @@ -1191,11 +1251,15 @@ void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, c { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - glUniformMatrix2fvARB(location, count, transpose, v); + glUniformMatrix2fvARB(mUniform[index], count, transpose, v); } } } @@ -1204,11 +1268,15 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - glUniformMatrix3fvARB(location, count, transpose, v); + glUniformMatrix3fvARB(mUniform[index], count, transpose, v); } } } @@ -1217,11 +1285,15 @@ void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - glUniformMatrix3x4fv(location, count, transpose, v); + glUniformMatrix3x4fv(mUniform[index], count, transpose, v); } } } @@ -1230,11 +1302,15 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c { if (mProgramObject) { - GLint location = getLocationForIndex(index); + if (mUniform.size() <= index) + { + UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; + return; + } - if (location >= 0) + if (mUniform[index] >= 0) { - glUniformMatrix4fvARB(location, count, transpose, v); + glUniformMatrix4fvARB(mUniform[index], count, transpose, v); } } } @@ -1265,8 +1341,14 @@ GLint LLGLSLShader::getUniformLocation(const LLStaticHashedString& uniform) GLint LLGLSLShader::getUniformLocation(U32 index) { - /*TODO: flatten this... change calls to gUL(U32) */ - return getLocationForIndex(index); + GLint ret = -1; + if (mProgramObject) + { + llassert(index < mUniform.size()); + return mUniform[index]; + } + + return ret; } GLint LLGLSLShader::getAttribLocation(U32 attrib) diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 456fba024a..0934ceba30 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -48,6 +48,9 @@ public: bool hasObjectSkinning; bool hasAtmospherics; bool hasGamma; + bool hasSrgb; + bool encodesNormal; + bool decodesNormal; S32 mIndexedTextureChannels; bool disableTextureIndex; bool hasAlphaMask; @@ -166,11 +169,6 @@ public: U32 mMatHash[LLRender::NUM_MATRIX_MODES]; U32 mLightHash; - typedef std::map<S32, GLint> uniforms_index_t; - typedef std::pair<U32, U32> magmin_values_t; - - typedef std::map < S32, magmin_values_t> magmin_filter_t; - GLhandleARB mProgramObject; #if LL_RELEASE_WITH_DEBUG_INFO struct attr_name @@ -185,12 +183,11 @@ public: std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel #endif U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask()) - uniforms_index_t mUniform; - uniforms_index_t mTexture; - + std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value + std::vector<GLint> mTexture; S32 mTotalUniformSize; S32 mActiveTextureChannels; S32 mShaderLevel; @@ -214,32 +211,13 @@ public: static U32 sTotalDrawCalls; bool mTextureStateFetched; - magmin_filter_t mTextureMagMinFilter; + std::vector<U32> mTextureMagFilter; + std::vector<U32> mTextureMinFilter; GLhandleARB mExtraLinkObject = 0; private: void unloadInternal(); - - inline GLint getLocationForIndex(S32 index) - { - if (!mProgramObject) - return -1; - uniforms_index_t::iterator it = mUniform.find(index); - if (it == mUniform.end()) - return -1; - return (*it).second; - } - - inline GLint getTexChannelForIndex(S32 index) - { - if (!mProgramObject) - return -1; - uniforms_index_t::iterator it = mTexture.find(index); - if (it == mTexture.end()) - return -1; - return (*it).second; - } }; //UI shader (declared here so llui_libtest will link properly) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index a8f622d3ff..5e16aded30 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1191,6 +1191,7 @@ void LLRender::syncMatrices() LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; static glh::matrix4f cached_mvp; + static glh::matrix4f cached_inv_mdv; static U32 cached_mvp_mdv_hash = 0xFFFFFFFF; static U32 cached_mvp_proj_hash = 0xFFFFFFFF; @@ -1204,12 +1205,18 @@ void LLRender::syncMatrices() bool mvp_done = false; U32 i = MM_MODELVIEW; - if (mMatHash[i] != shader->mMatHash[i]) + if (mMatHash[MM_MODELVIEW] != shader->mMatHash[MM_MODELVIEW]) { //update modelview, normal, and MVP - glh::matrix4f& mat = mMatrix[i][mMatIdx[i]]; + glh::matrix4f& mat = mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]]; - shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.m); - shader->mMatHash[i] = mMatHash[i]; + // if MDV has changed, update the cached inverse as well + if (cached_mvp_mdv_hash != mMatHash[MM_MODELVIEW]) + { + cached_inv_mdv = mat.inverse(); + } + + shader->uniformMatrix4fv(name[MM_MODELVIEW], 1, GL_FALSE, mat.m); + shader->mMatHash[MM_MODELVIEW] = mMatHash[MM_MODELVIEW]; //update normal matrix S32 loc = shader->getUniformLocation(LLShaderMgr::NORMAL_MATRIX); @@ -1217,7 +1224,7 @@ void LLRender::syncMatrices() { if (cached_normal_hash != mMatHash[i]) { - cached_normal = mat.inverse().transpose(); + cached_normal = cached_inv_mdv.transpose(); cached_normal_hash = mMatHash[i]; } @@ -1233,6 +1240,17 @@ void LLRender::syncMatrices() shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norm_mat); } + if (shader->getUniformLocation(LLShaderMgr::INVERSE_MODELVIEW_MATRIX)) + { + glh::matrix4f ogl_to_cfr = copy_matrix((F32*)OGL_TO_CFR_ROTATION); + glh::matrix4f modelview = ogl_to_cfr.inverse() * get_current_modelview(); + + glh::matrix4f inv_modelview = modelview.inverse(); + shader->uniformMatrix4fv(LLShaderMgr::INVERSE_MODELVIEW_MATRIX, 1, FALSE, inv_modelview.m); + } + + shader->uniformMatrix4fv(LLShaderMgr::INVERSE_MODELVIEW_MATRIX, 1, GL_FALSE, cached_inv_mdv.m); + //update MVP matrix mvp_done = true; loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX); @@ -1252,14 +1270,19 @@ void LLRender::syncMatrices() } } - i = MM_PROJECTION; - if (mMatHash[i] != shader->mMatHash[i]) + if (mMatHash[MM_PROJECTION] != shader->mMatHash[MM_PROJECTION]) { //update projection matrix, normal, and MVP - glh::matrix4f& mat = mMatrix[i][mMatIdx[i]]; + glh::matrix4f& mat = mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]]; + + if (shader->getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX)) + { + glh::matrix4f inv_proj = mat.inverse(); + shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m); + } - shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.m); - shader->mMatHash[i] = mMatHash[i]; + shader->uniformMatrix4fv(name[MM_PROJECTION], 1, GL_FALSE, mat.m); + shader->mMatHash[MM_PROJECTION] = mMatHash[MM_PROJECTION]; if (!mvp_done) { @@ -1267,7 +1290,7 @@ void LLRender::syncMatrices() S32 loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX); if (loc > -1) { - if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION]) + if (cached_mvp_mdv_hash != mMatHash[MM_PROJECTION] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION]) { U32 mdv = MM_MODELVIEW; cached_mvp = mat; @@ -2332,3 +2355,85 @@ void LLRender::debugTexUnits(void) LL_INFOS("TextureUnit") << "Active TexUnit Enabled : " << active_enabled << LL_ENDL; } + + +glh::matrix4f copy_matrix(F32* src) +{ + glh::matrix4f ret; + ret.set_value(src); + return ret; +} + +glh::matrix4f get_current_modelview() +{ + return copy_matrix(gGLModelView); +} + +glh::matrix4f get_current_projection() +{ + return copy_matrix(gGLProjection); +} + +glh::matrix4f get_last_modelview() +{ + return copy_matrix(gGLLastModelView); +} + +glh::matrix4f get_last_projection() +{ + return copy_matrix(gGLLastProjection); +} + +void copy_matrix(const glh::matrix4f& src, F32* dst) +{ + for (U32 i = 0; i < 16; i++) + { + dst[i] = src.m[i]; + } +} + +void set_current_modelview(const glh::matrix4f& mat) +{ + copy_matrix(mat, gGLModelView); +} + +void set_current_projection(glh::matrix4f& mat) +{ + copy_matrix(mat, gGLProjection); +} + +glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar) +{ + glh::matrix4f ret( + 2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left), + 0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom), + 0.f, 0.f, -2.f/(zfar-znear), -(zfar+znear)/(zfar-znear), + 0.f, 0.f, 0.f, 1.f); + + return ret; +} + +glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) +{ + GLfloat f = 1.f/tanf(DEG_TO_RAD*fovy/2.f); + + return glh::matrix4f(f/aspect, 0, 0, 0, + 0, f, 0, 0, + 0, 0, (zFar+zNear)/(zNear-zFar), (2.f*zFar*zNear)/(zNear-zFar), + 0, 0, -1.f, 0); +} + +glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up) +{ + LLVector3 f = center-eye; + f.normVec(); + up.normVec(); + LLVector3 s = f % up; + LLVector3 u = s % f; + + return glh::matrix4f(s[0], s[1], s[2], 0, + u[0], u[1], u[2], 0, + -f[0], -f[1], -f[2], 0, + 0, 0, 0, 1); + +}
\ No newline at end of file diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 6f22f1d8cb..1bc5e89eac 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -446,7 +446,7 @@ public: static U32 sUICalls; static U32 sUIVerts; static bool sGLCoreProfile; - static bool sNsightDebugSupport; + static bool sNsightDebugSupport; private: friend class LLLightState; @@ -496,4 +496,24 @@ extern S32 gGLViewport[4]; extern LLRender gGL; +// This rotation matrix moves the default OpenGL reference frame +// (-Z at, Y up) to Cory's favorite reference frame (X at, Z up) +const F32 OGL_TO_CFR_ROTATION[16] = { 0.f, 0.f, -1.f, 0.f, // -Z becomes X + -1.f, 0.f, 0.f, 0.f, // -X becomes Y + 0.f, 1.f, 0.f, 0.f, // Y becomes Z + 0.f, 0.f, 0.f, 1.f }; + +glh::matrix4f copy_matrix(F32* src); +glh::matrix4f get_current_modelview(); +glh::matrix4f get_current_projection(); +glh::matrix4f get_last_modelview(); +glh::matrix4f get_last_projection(); + +void copy_matrix(const glh::matrix4f& src, F32* dst); +void set_current_modelview(const glh::matrix4f& mat); +void set_current_projection(glh::matrix4f& mat); + +glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar); +glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); +glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up); #endif diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 287f22783f..1eb1cb56a8 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -98,7 +98,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) } } - if (features->calculatesLighting || features->atmosphericHelpers) + if (features->calculatesLighting || features->calculatesAtmospherics) { if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl")) { @@ -194,6 +194,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) } } + if (features->calculatesLighting || features->calculatesAtmospherics) + { + if (!shader->attachObject("windlight/atmosphericsHelpersF.glsl")) + { + return FALSE; + } + } + // NOTE order of shader object attaching is VERY IMPORTANT!!! if (features->hasGamma) { @@ -202,7 +210,31 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - + + if (features->hasSrgb) + { + if (!shader->attachObject("environment/srgbF.glsl")) + { + return FALSE; + } + } + + if (features->encodesNormal) + { + if (!shader->attachObject("environment/encodeNormF.glsl")) + { + return FALSE; + } + } + + if (features->decodesNormal) + { + if (!shader->attachObject("environment/decodeNormF.glsl")) + { + return FALSE; + } + } + if (features->hasAtmospherics) { if (!shader->attachObject("windlight/atmosphericsF.glsl")) @@ -520,8 +552,8 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string& if (log.length() > 0) { - LL_INFOS() << "Shader loading from " << fname << ":\n" << LL_ENDL; - LL_INFOS() << log << LL_ENDL; + LL_INFOS("ShaderErrors") << "Shader loading from " << fname << ":\n" << LL_ENDL; + LL_INFOS("ShaderErrors") << log << LL_ENDL; } } @@ -953,7 +985,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade // Add shader file to map mShaderObjects[filename] = ret; shader_level = try_gpu_class; - } + } else { if (shader_level > 1) @@ -1069,6 +1101,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("projection_matrix"); mReservedUniforms.push_back("inv_proj"); mReservedUniforms.push_back("modelview_projection_matrix"); + mReservedUniforms.push_back("inv_modelview"); mReservedUniforms.push_back("normal_matrix"); mReservedUniforms.push_back("texture_matrix0"); mReservedUniforms.push_back("texture_matrix1"); @@ -1117,7 +1150,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("cloud_noise_texture"); mReservedUniforms.push_back("fullbright"); mReservedUniforms.push_back("lightnorm"); - mReservedUniforms.push_back("sunlight_color"); + mReservedUniforms.push_back("sunlight_color_copy"); mReservedUniforms.push_back("ambient"); mReservedUniforms.push_back("blue_horizon"); mReservedUniforms.push_back("blue_density"); @@ -1274,8 +1307,8 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("transmittance_texture"); mReservedUniforms.push_back("scattering_texture"); - mReservedUniforms.push_back("irradiance_texture"); mReservedUniforms.push_back("single_mie_scattering_texture"); + mReservedUniforms.push_back("irradiance_texture"); llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index ac3f7d58d5..9919dbe31a 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -30,11 +30,6 @@ #include "llgl.h" #include "llglslshader.h" -/*RIDER: TODO: - * This should use the LL Singleton<> template... but not a quick conversion. - * (llviewershadermgr derives from this) - */ - class LLShaderMgr { public: @@ -47,6 +42,7 @@ public: PROJECTION_MATRIX, INVERSE_PROJECTION_MATRIX, MODELVIEW_PROJECTION_MATRIX, + INVERSE_MODELVIEW_MATRIX, NORMAL_MATRIX, TEXTURE_MATRIX0, TEXTURE_MATRIX1, @@ -229,8 +225,8 @@ public: // precomputed textures from libatmosphere TRANSMITTANCE_TEX, SCATTER_TEX, - ILLUMINANCE_TEX, SINGLE_MIE_SCATTER_TEX, + ILLUMINANCE_TEX, END_RESERVED_UNIFORMS } eGLSLReservedUniforms; |