summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llatmosphere.cpp348
-rw-r--r--indra/llrender/llatmosphere.h50
-rw-r--r--indra/llrender/llglslshader.cpp324
-rw-r--r--indra/llrender/llglslshader.h36
-rw-r--r--indra/llrender/llrender.cpp127
-rw-r--r--indra/llrender/llrender.h22
-rw-r--r--indra/llrender/llshadermgr.cpp47
-rw-r--r--indra/llrender/llshadermgr.h8
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;