summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/CMakeLists.txt3
-rw-r--r--indra/llrender/llatmosphere.cpp290
-rw-r--r--indra/llrender/llatmosphere.h173
-rw-r--r--indra/llrender/llcubemap.cpp28
-rw-r--r--indra/llrender/llcubemap.h3
-rw-r--r--indra/llrender/llfontregistry.cpp3
-rw-r--r--indra/llrender/llgl.cpp312
-rw-r--r--indra/llrender/llgl.h18
-rw-r--r--indra/llrender/llglcommonfunc.h2
-rw-r--r--indra/llrender/llglheaders.h239
-rw-r--r--indra/llrender/llglslshader.cpp169
-rw-r--r--indra/llrender/llglslshader.h18
-rw-r--r--indra/llrender/llglstates.h24
-rw-r--r--indra/llrender/llgltexture.cpp20
-rw-r--r--indra/llrender/llgltexture.h12
-rw-r--r--indra/llrender/llimagegl.cpp350
-rw-r--r--indra/llrender/llimagegl.h12
-rw-r--r--indra/llrender/llrender.cpp296
-rw-r--r--indra/llrender/llrender.h69
-rw-r--r--indra/llrender/llrender2dutils.cpp100
-rw-r--r--indra/llrender/llrender2dutils.h35
-rw-r--r--indra/llrender/llrendertarget.cpp23
-rw-r--r--indra/llrender/llrendertarget.h2
-rw-r--r--indra/llrender/llshadermgr.cpp432
-rw-r--r--indra/llrender/llshadermgr.h403
-rw-r--r--indra/llrender/lltexture.cpp12
-rw-r--r--indra/llrender/lltexture.h22
-rw-r--r--indra/llrender/lluiimage.cpp101
-rw-r--r--indra/llrender/lluiimage.h50
-rw-r--r--indra/llrender/lluiimage.inl77
-rw-r--r--indra/llrender/llvertexbuffer.cpp127
-rw-r--r--indra/llrender/llvertexbuffer.h43
32 files changed, 2309 insertions, 1159 deletions
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 07a0d8c402..47e7ad915b 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -31,6 +31,7 @@ include_directories(SYSTEM
)
set(llrender_SOURCE_FILES
+ llatmosphere.cpp
llcubemap.cpp
llfontbitmapcache.cpp
llfontfreetype.cpp
@@ -57,6 +58,7 @@ set(llrender_SOURCE_FILES
set(llrender_HEADER_FILES
CMakeLists.txt
+ llatmosphere.h
llcubemap.h
llfontgl.h
llfontfreetype.h
@@ -78,6 +80,7 @@ set(llrender_HEADER_FILES
llshadermgr.h
lltexture.h
lluiimage.h
+ lluiimage.inl
llvertexbuffer.h
llglcommonfunc.h
)
diff --git a/indra/llrender/llatmosphere.cpp b/indra/llrender/llatmosphere.cpp
new file mode 100644
index 0000000000..ffc17c89f8
--- /dev/null
+++ b/indra/llrender/llatmosphere.cpp
@@ -0,0 +1,290 @@
+/**
+ * @file llatmosphere.cpp
+ * @brief LLAtmosphere integration impl
+ *
+ * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2018, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llatmosphere.h"
+#include "llfasttimer.h"
+#include "llsys.h"
+#include "llglheaders.h"
+#include "llrender.h"
+#include "llshadermgr.h"
+#include "llglslshader.h"
+
+LLAtmosphere* gAtmosphere = nullptr;
+
+// 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 kGroundAlbedo = 0.1;
+
+AtmosphericModelSettings::AtmosphericModelSettings()
+ : m_skyBottomRadius(6360.0f)
+ , m_skyTopRadius(6420.0f)
+ , m_sunArcRadians(0.00045f)
+ , m_mieAnisotropy(0.8f)
+{
+ DensityLayer rayleigh_density(0.0, 1.0, -1.0 / kRayleighScaleHeight, 0.0, 0.0);
+ DensityLayer mie_density(0.0, 1.0, -1.0 / kMieScaleHeight, 0.0, 0.0);
+
+ m_rayleighProfile.push_back(rayleigh_density);
+ m_mieProfile.push_back(mie_density);
+
+ // 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(DensityLayer(25000.0, 0.0, 0.0, 1.0 / 15000.0, -2.0 / 3.0));
+ m_absorptionProfile.push_back(DensityLayer(0.0, 0.0, 0.0, -1.0 / 15000.0, 8.0 / 3.0));
+}
+
+AtmosphericModelSettings::AtmosphericModelSettings(
+ 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)
+{
+}
+
+bool AtmosphericModelSettings::operator==(const AtmosphericModelSettings& rhs) const
+{
+ if (m_skyBottomRadius != rhs.m_skyBottomRadius)
+ {
+ return false;
+ }
+
+ if (m_skyTopRadius != rhs.m_skyTopRadius)
+ {
+ return false;
+ }
+
+ if (m_sunArcRadians != rhs.m_sunArcRadians)
+ {
+ return false;
+ }
+
+ if (m_mieAnisotropy != rhs.m_mieAnisotropy)
+ {
+ return false;
+ }
+
+ if (m_rayleighProfile != rhs.m_rayleighProfile)
+ {
+ return false;
+ }
+
+ if (m_mieProfile != rhs.m_mieProfile)
+ {
+ return false;
+ }
+
+ if (m_absorptionProfile != rhs.m_absorptionProfile)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void LLAtmosphere::initClass()
+{
+ if (!gAtmosphere)
+ {
+ gAtmosphere = new LLAtmosphere;
+ }
+}
+
+void LLAtmosphere::cleanupClass()
+{
+ if(gAtmosphere)
+ {
+ delete gAtmosphere;
+ }
+ gAtmosphere = NULL;
+}
+
+LLAtmosphere::LLAtmosphere()
+{
+ 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(kGroundAlbedo);
+ }
+
+ AtmosphericModelSettings defaults;
+ configureAtmosphericModel(defaults);
+}
+
+LLAtmosphere::~LLAtmosphere()
+{
+ // Cease referencing textures from atmosphere::model from our LLGLTextures wrappers for same.
+ if (m_transmittance)
+ {
+ m_transmittance->setTexName(0);
+ }
+
+ if (m_scattering)
+ {
+ m_scattering->setTexName(0);
+ }
+
+ if (m_mie_scatter_texture)
+ {
+ m_mie_scatter_texture->setTexName(0);
+ }
+}
+
+bool LLAtmosphere::configureAtmosphericModel(AtmosphericModelSettings& settings)
+{
+ // TBD
+ return true;
+}
+
+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_RGB32F_ARB, GL_RGB, GL_FLOAT);
+ m_transmittance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE);
+ }
+ return m_transmittance;
+}
+
+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()
+{
+ 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()
+{
+ 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_RGB32F_ARB, GL_RGB, GL_FLOAT);
+ m_illuminance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE);
+ }
+ return m_illuminance;
+}
diff --git a/indra/llrender/llatmosphere.h b/indra/llrender/llatmosphere.h
new file mode 100644
index 0000000000..572365d864
--- /dev/null
+++ b/indra/llrender/llatmosphere.h
@@ -0,0 +1,173 @@
+/**
+ * @file llatmosphere.h
+ * @brief LLAtmosphere class
+ *
+ * $LicenseInfo:firstyear=2018&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2018, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_ATMOSPHERE_H
+#define LL_ATMOSPHERE_H
+
+#include "llglheaders.h"
+#include "llgltexture.h"
+
+// An atmosphere layer of width 'width' (in m), and whose density is defined as
+// 'exp_term' * exp('exp_scale' * h) + 'linear_term' * h + 'constant_term',
+// clamped to [0,1], and where h is the altitude (in m). 'exp_term' and
+// 'constant_term' are unitless, while 'exp_scale' and 'linear_term' are in
+// m^-1.
+class DensityLayer {
+ public:
+ DensityLayer()
+ : width(0.0f)
+ , exp_term(0.0f)
+ , exp_scale(0.0f)
+ , linear_term(0.0f)
+ , constant_term(0.0f)
+ {
+ }
+
+ DensityLayer(float width, float exp_term, float exp_scale, float linear_term, float constant_term)
+ : width(width)
+ , exp_term(exp_term)
+ , exp_scale(exp_scale)
+ , linear_term(linear_term)
+ , constant_term(constant_term)
+ {
+ }
+
+ bool operator==(const DensityLayer& rhs) const
+ {
+ if (width != rhs.width)
+ {
+ return false;
+ }
+
+ if (exp_term != rhs.exp_term)
+ {
+ return false;
+ }
+
+ if (exp_scale != rhs.exp_scale)
+ {
+ return false;
+ }
+
+ if (linear_term != rhs.linear_term)
+ {
+ return false;
+ }
+
+ if (constant_term != rhs.constant_term)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ float width = 1024.0f;
+ float exp_term = 1.0f;
+ float exp_scale = 1.0f;
+ float linear_term = 1.0f;
+ float constant_term = 0.0f;
+};
+
+typedef std::vector<DensityLayer> 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);
+
+ bool operator==(const AtmosphericModelSettings& rhs) const;
+
+ F32 m_skyBottomRadius;
+ F32 m_skyTopRadius;
+ DensityProfile m_rayleighProfile;
+ DensityProfile m_mieProfile;
+ DensityProfile m_absorptionProfile;
+ F32 m_sunArcRadians;
+ F32 m_mieAnisotropy;
+};
+
+class LLAtmosphere
+{
+public:
+ LLAtmosphere();
+ ~LLAtmosphere();
+
+ static void initClass();
+ static void cleanupClass();
+
+ const LLAtmosphere& operator=(const LLAtmosphere& rhs)
+ {
+ LL_ERRS() << "Illegal operation!" << LL_ENDL;
+ return *this;
+ }
+
+ LLGLTexture* getTransmittance();
+ LLGLTexture* getScattering();
+ LLGLTexture* getMieScattering();
+ LLGLTexture* getIlluminance();
+
+ bool configureAtmosphericModel(AtmosphericModelSettings& settings);
+
+protected:
+ LLAtmosphere(const LLAtmosphere& rhs)
+ {
+ *this = rhs;
+ }
+
+ LLPointer<LLGLTexture> m_transmittance;
+ LLPointer<LLGLTexture> m_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;
+
+ AtmosphericModelSettings m_settings;
+};
+
+extern LLAtmosphere* gAtmosphere;
+
+#endif // LL_ATMOSPHERE_H
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index af4e3fdda0..5947bca670 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -43,20 +43,13 @@
const F32 epsilon = 1e-7f;
const U16 RESOLUTION = 64;
-#if LL_DARWIN
-// mipmap generation on cubemap textures seems to be broken on the Mac for at least some cards.
-// Since the cubemap is small (64x64 per face) and doesn't have any fine detail, turning off mipmaps is a usable workaround.
-const BOOL use_cube_mipmaps = FALSE;
-#else
-const BOOL use_cube_mipmaps = FALSE; //current build works best without cube mipmaps
-#endif
-
bool LLCubeMap::sUseCubeMaps = true;
-LLCubeMap::LLCubeMap()
+LLCubeMap::LLCubeMap(bool init_as_srgb)
: mTextureStage(0),
mTextureCoordStage(0),
- mMatrixStage(0)
+ mMatrixStage(0),
+ mIssRGB(init_as_srgb)
{
mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
@@ -82,12 +75,17 @@ void LLCubeMap::initGL()
U32 texname = 0;
LLImageGL::generateTextures(1, &texname);
-
+
for (int i = 0; i < 6; i++)
{
- mImages[i] = new LLImageGL(64, 64, 4, (use_cube_mipmaps? TRUE : FALSE));
+ mImages[i] = new LLImageGL(RESOLUTION, RESOLUTION, 4, FALSE);
+ #if USE_SRGB_DECODE
+ if (mIssRGB) {
+ mImages[i]->setExplicitFormat(GL_SRGB8_ALPHA8, GL_RGBA);
+ }
+ #endif
mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
- mRawImages[i] = new LLImageRaw(64, 64, 4);
+ mRawImages[i] = new LLImageRaw(RESOLUTION, RESOLUTION, 4);
mImages[i]->createGLTexture(0, mRawImages[i], texname);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
@@ -154,7 +152,7 @@ void LLCubeMap::initGLData()
{
for (int i = 0; i < 6; i++)
{
- mImages[i]->setSubImage(mRawImages[i], 0, 0, 64, 64);
+ mImages[i]->setSubImage(mRawImages[i], 0, 0, RESOLUTION, RESOLUTION);
}
}
@@ -484,7 +482,7 @@ void LLCubeMap::paintIn(LLVector3 dir[4], const LLColor4U& col)
td[offset + cc] = U8((td[offset + cc] + col.mV[cc]) * 0.5);
}
}
- mImages[side]->setSubImage(mRawImages[side], 0, 0, 64, 64);
+ mImages[side]->setSubImage(mRawImages[side], 0, 0, RESOLUTION, RESOLUTION);
}
}
diff --git a/indra/llrender/llcubemap.h b/indra/llrender/llcubemap.h
index ee2c41e026..95b6d12099 100644
--- a/indra/llrender/llcubemap.h
+++ b/indra/llrender/llcubemap.h
@@ -36,8 +36,9 @@ class LLVector3;
// Environment map hack!
class LLCubeMap : public LLRefCount
{
+ bool mIssRGB;
public:
- LLCubeMap();
+ LLCubeMap(bool init_as_srgb);
void init(const std::vector<LLPointer<LLImageRaw> >& rawimages);
void initGL();
void initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages);
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index ac2b695a3e..f2dc5771e9 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -45,6 +45,7 @@ bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc);
bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node);
const std::string MACOSX_FONT_PATH_LIBRARY = "/Library/Fonts/";
+const std::string MACOSX_FONT_SUPPLEMENTAL = "Supplemental/";
LLFontDescriptor::char_functor_map_t LLFontDescriptor::mCharFunctors({
{ "is_emoji", LLStringOps::isEmoji }
@@ -490,6 +491,8 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
++font_file_it)
{
LLFontGL *fontp = NULL;
+ font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + MACOSX_FONT_SUPPLEMENTAL + *file_name_it);
+ font_paths.push_back(sys_path + MACOSX_FONT_SUPPLEMENTAL + *file_name_it);
bool is_ft_collection = (std::find_if(font_collection_files.begin(), font_collection_files.end(),
[&font_file_it](const LLFontFileInfo& ffi) { return font_file_it->FileName == ffi.FileName; }) != font_collection_files.end());
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index c0f0cec80b..43fedeca64 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -36,6 +36,7 @@
#include "llsys.h"
#include "llgl.h"
+#include "llglstates.h"
#include "llrender.h"
#include "llerror.h"
@@ -49,6 +50,10 @@
#include "llglheaders.h"
#include "llglslshader.h"
+#if LL_WINDOWS
+#include "lldxhardware.h"
+#endif
+
#ifdef _DEBUG
//#define GL_STATE_VERIFY
#endif
@@ -146,7 +151,7 @@ LLMatrix4 gGLObliqueProjectionInverse;
std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
-#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
+#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
// ATI prototypes
#if LL_WINDOWS
@@ -323,7 +328,7 @@ PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
#endif
// vertex shader prototypes
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB = NULL;
PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB = NULL;
PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB = NULL;
@@ -342,7 +347,7 @@ PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB = NULL;
PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB = NULL;
PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB = NULL;
PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB = NULL;
-#endif // LL_LINUX || LL_SOLARIS
+#endif // LL_LINUX
PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4nbvARB = NULL;
PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4nivARB = NULL;
PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4nsvARB = NULL;
@@ -350,7 +355,7 @@ PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4nubARB = NULL;
PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4nubvARB = NULL;
PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4nuivARB = NULL;
PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4nusvARB = NULL;
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB = NULL;
PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB = NULL;
PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB = NULL;
@@ -388,12 +393,14 @@ PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB = NULL;
PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB = NULL;
PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB = NULL;
PFNGLISPROGRAMARBPROC glIsProgramARB = NULL;
-#endif // LL_LINUX || LL_SOLARIS
+#endif // LL_LINUX
PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB = NULL;
PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB = NULL;
PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL;
#if LL_WINDOWS
+PFNWGLGETGPUIDSAMDPROC wglGetGPUIDsAMD = NULL;
+PFNWGLGETGPUINFOAMDPROC wglGetGPUInfoAMD = NULL;
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
#endif
@@ -413,6 +420,7 @@ LLGLManager::LLGLManager() :
mHasMultitexture(FALSE),
mHasATIMemInfo(FALSE),
+ mHasAMDAssociations(FALSE),
mHasNVXMemInfo(FALSE),
mNumTextureUnits(1),
mHasMipMapGeneration(FALSE),
@@ -463,8 +471,6 @@ LLGLManager::LLGLManager() :
mHasSeparateSpecularColor(FALSE),
- mDebugGPU(FALSE),
-
mDriverVersionMajor(1),
mDriverVersionMinor(0),
mDriverVersionRelease(0),
@@ -497,7 +503,16 @@ void LLGLManager::initWGL()
{
LL_WARNS("RenderInit") << "No ARB create context extensions" << LL_ENDL;
}
-
+
+ // For retreiving information per AMD adapter,
+ // because we can't trust curently selected/default one when there are multiple
+ mHasAMDAssociations = ExtensionExists("WGL_AMD_gpu_association", gGLHExts.mSysExts);
+ if (mHasAMDAssociations)
+ {
+ GLH_EXT_NAME(wglGetGPUIDsAMD) = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD");
+ GLH_EXT_NAME(wglGetGPUInfoAMD) = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD");
+ }
+
if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
{
GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
@@ -568,10 +583,10 @@ bool LLGLManager::initGL()
// Extract video card strings and convert to upper case to
// work around driver-to-driver variation in capitalization.
- mGLVendor = std::string((const char *)glGetString(GL_VENDOR));
+ mGLVendor = ll_safe_string((const char *)glGetString(GL_VENDOR));
LLStringUtil::toUpper(mGLVendor);
- mGLRenderer = std::string((const char *)glGetString(GL_RENDERER));
+ mGLRenderer = ll_safe_string((const char *)glGetString(GL_RENDERER));
LLStringUtil::toUpper(mGLRenderer);
parse_gl_version( &mDriverVersionMajor,
@@ -683,23 +698,78 @@ bool LLGLManager::initGL()
stop_glerror();
S32 old_vram = mVRAM;
+ mVRAM = 0;
- if (mHasATIMemInfo)
+#if LL_WINDOWS
+ if (mHasAMDAssociations)
+ {
+ GLuint gl_gpus_count = wglGetGPUIDsAMD(0, 0);
+ if (gl_gpus_count > 0)
+ {
+ GLuint* ids = new GLuint[gl_gpus_count];
+ wglGetGPUIDsAMD(gl_gpus_count, ids);
+
+ GLuint mem_mb = 0;
+ for (U32 i = 0; i < gl_gpus_count; i++)
+ {
+ wglGetGPUInfoAMD(ids[i],
+ WGL_GPU_RAM_AMD,
+ GL_UNSIGNED_INT,
+ sizeof(GLuint),
+ &mem_mb);
+ if (mVRAM < mem_mb)
+ {
+ // basically pick the best AMD and trust driver/OS to know to switch
+ mVRAM = mem_mb;
+ }
+ }
+ }
+ if (mVRAM != 0)
+ {
+ LL_WARNS("RenderInit") << "VRAM Detected (AMDAssociations):" << mVRAM << LL_ENDL;
+ }
+ }
+#endif
+
+ if (mHasATIMemInfo && mVRAM == 0)
{ //ask the gl how much vram is free at startup and attempt to use no more than half of that
S32 meminfo[4];
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
- mVRAM = meminfo[0]/1024;
+ mVRAM = meminfo[0] / 1024;
+ LL_WARNS("RenderInit") << "VRAM Detected (ATIMemInfo):" << mVRAM << LL_ENDL;
}
- else if (mHasNVXMemInfo)
+
+ if (mHasNVXMemInfo && mVRAM == 0)
{
S32 dedicated_memory;
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory);
mVRAM = dedicated_memory/1024;
+ LL_WARNS("RenderInit") << "VRAM Detected (NVXMemInfo):" << mVRAM << LL_ENDL;
}
+#if LL_WINDOWS
if (mVRAM < 256)
- { //something likely went wrong using the above extensions, fall back to old method
+ {
+ // Something likely went wrong using the above extensions
+ // try WMI first and fall back to old method (from dxdiag) if all else fails
+ // Function will check all GPUs WMI knows of and will pick up the one with most
+ // memory. We need to check all GPUs because system can switch active GPU to
+ // weaker one, to preserve power when not under load.
+ S32 mem = LLDXHardware::getMBVideoMemoryViaWMI();
+ if (mem != 0)
+ {
+ mVRAM = mem;
+ LL_WARNS("RenderInit") << "VRAM Detected (WMI):" << mVRAM<< LL_ENDL;
+ }
+ }
+#endif
+
+ if (mVRAM < 256 && old_vram > 0)
+ {
+ // fall back to old method
+ // Note: on Windows value will be from LLDXHardware.
+ // Either received via dxdiag or via WMI by id from dxdiag.
mVRAM = old_vram;
}
@@ -782,10 +852,6 @@ bool LLGLManager::initGL()
stop_glerror();
- setToDebugGPU();
-
- stop_glerror();
-
initGLStates();
stop_glerror();
@@ -793,17 +859,6 @@ bool LLGLManager::initGL()
return true;
}
-void LLGLManager::setToDebugGPU()
-{
- //"MOBILE INTEL(R) 965 EXPRESS CHIP",
- if (mGLRenderer.find("INTEL") != std::string::npos && mGLRenderer.find("965") != std::string::npos)
- {
- mDebugGPU = TRUE ;
- }
-
- return ;
-}
-
void LLGLManager::getGLInfo(LLSD& info)
{
if (gHeadlessClient)
@@ -815,9 +870,9 @@ void LLGLManager::getGLInfo(LLSD& info)
}
else
{
- info["GLInfo"]["GLVendor"] = std::string((const char *)glGetString(GL_VENDOR));
- info["GLInfo"]["GLRenderer"] = std::string((const char *)glGetString(GL_RENDERER));
- info["GLInfo"]["GLVersion"] = std::string((const char *)glGetString(GL_VERSION));
+ info["GLInfo"]["GLVendor"] = ll_safe_string((const char *)glGetString(GL_VENDOR));
+ info["GLInfo"]["GLRenderer"] = ll_safe_string((const char *)glGetString(GL_RENDERER));
+ info["GLInfo"]["GLVersion"] = ll_safe_string((const char *)glGetString(GL_VERSION));
}
#if !LL_MESA_HEADLESS
@@ -867,9 +922,9 @@ void LLGLManager::printGLInfoString()
}
else
{
- LL_INFOS("RenderInit") << "GL_VENDOR: " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
- LL_INFOS("RenderInit") << "GL_RENDERER: " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
- LL_INFOS("RenderInit") << "GL_VERSION: " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
+ LL_INFOS("RenderInit") << "GL_VENDOR: " << ll_safe_string((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
+ LL_INFOS("RenderInit") << "GL_RENDERER: " << ll_safe_string((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
+ LL_INFOS("RenderInit") << "GL_VERSION: " << ll_safe_string((const char *)glGetString(GL_VERSION)) << LL_ENDL;
}
#if !LL_MESA_HEADLESS
@@ -893,6 +948,79 @@ std::string LLGLManager::getRawGLString()
return gl_string;
}
+void LLGLManager::asLLSD(LLSD& info)
+{
+ // Currently these are duplicates of fields in "system".
+ info["gpu_vendor"] = mGLVendorShort;
+ info["gpu_version"] = mDriverVersionVendorString;
+ info["opengl_version"] = mGLVersionString;
+
+ info["vram"] = mVRAM;
+
+ // Extensions used by everyone
+ info["has_multitexture"] = mHasMultitexture;
+ info["has_ati_mem_info"] = mHasATIMemInfo;
+ info["has_nvx_mem_info"] = mHasNVXMemInfo;
+ info["num_texture_units"] = mNumTextureUnits;
+ info["has_mip_map_generation"] = mHasMipMapGeneration;
+ info["has_compressed_textures"] = mHasCompressedTextures;
+ info["has_framebuffer_object"] = mHasFramebufferObject;
+ info["max_samples"] = mMaxSamples;
+ info["has_blend_func_separate"] = mHasBlendFuncSeparate;
+
+ // ARB Extensions
+ info["has_vertex_buffer_object"] = mHasVertexBufferObject;
+ info["has_vertex_array_object"] = mHasVertexArrayObject;
+ info["has_sync"] = mHasSync;
+ info["has_map_buffer_range"] = mHasMapBufferRange;
+ info["has_flush_buffer_range"] = mHasFlushBufferRange;
+ info["has_pbuffer"] = mHasPBuffer;
+ info["has_shader_objects"] = mHasShaderObjects;
+ info["has_vertex_shader"] = mHasVertexShader;
+ info["has_fragment_shader"] = mHasFragmentShader;
+ info["num_texture_image_units"] = mNumTextureImageUnits;
+ info["has_occlusion_query"] = mHasOcclusionQuery;
+ info["has_timer_query"] = mHasTimerQuery;
+ info["has_occlusion_query2"] = mHasOcclusionQuery2;
+ info["has_point_parameters"] = mHasPointParameters;
+ info["has_draw_buffers"] = mHasDrawBuffers;
+ info["has_depth_clamp"] = mHasDepthClamp;
+ info["has_texture_rectangle"] = mHasTextureRectangle;
+ info["has_texture_multisample"] = mHasTextureMultisample;
+ info["has_transform_feedback"] = mHasTransformFeedback;
+ info["max_sample_mask_words"] = mMaxSampleMaskWords;
+ info["max_color_texture_samples"] = mMaxColorTextureSamples;
+ info["max_depth_texture_samples"] = mMaxDepthTextureSamples;
+ info["max_integer_samples"] = mMaxIntegerSamples;
+
+ // Other extensions.
+ info["has_anisotropic"] = mHasAnisotropic;
+ info["has_arb_env_combine"] = mHasARBEnvCombine;
+ info["has_cube_map"] = mHasCubeMap;
+ info["has_debug_output"] = mHasDebugOutput;
+ info["has_srgb_texture"] = mHassRGBTexture;
+ info["has_srgb_framebuffer"] = mHassRGBFramebuffer;
+ info["has_texture_srgb_decode"] = mHasTexturesRGBDecode;
+
+ // Vendor-specific extensions
+ info["is_ati"] = mIsATI;
+ info["is_nvidia"] = mIsNVIDIA;
+ info["is_intel"] = mIsIntel;
+ info["is_gf2or4mx"] = mIsGF2or4MX;
+ info["is_gf3"] = mIsGF3;
+ info["is_gf_gfx"] = mIsGFFX;
+ info["ati_offset_vertical_lines"] = mATIOffsetVerticalLines;
+ info["ati_old_driver"] = mATIOldDriver;
+
+ // Other fields
+ info["has_requirements"] = mHasRequirements;
+ info["has_separate_specular_color"] = mHasSeparateSpecularColor;
+ info["max_vertex_range"] = mGLMaxVertexRange;
+ info["max_index_range"] = mGLMaxIndexRange;
+ info["max_texture_size"] = mGLMaxTextureSize;
+ info["gl_renderer"] = mGLRenderer;
+}
+
void LLGLManager::shutdownGL()
{
if (mInited)
@@ -961,7 +1089,7 @@ void LLGLManager::initExtensions()
mHasTextureRectangle = FALSE;
#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
- mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
+ mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts); //Basic AMD method, also see mHasAMDAssociations
mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
@@ -998,6 +1126,12 @@ void LLGLManager::initExtensions()
mHassRGBFramebuffer = ExtensionExists("GL_EXT_framebuffer_sRGB", gGLHExts.mSysExts);
#endif
+#ifdef GL_EXT_texture_sRGB_decode
+ mHasTexturesRGBDecode = ExtensionExists("GL_EXT_texture_sRGB_decode", gGLHExts.mSysExts);
+#else
+ mHasTexturesRGBDecode = ExtensionExists("GL_ARB_texture_sRGB_decode", gGLHExts.mSysExts);
+#endif
+
mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f;
mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
@@ -1015,7 +1149,7 @@ void LLGLManager::initExtensions()
mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
#endif
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
LL_INFOS() << "initExtensions() checking shell variables to adjust features..." << LL_ENDL;
// Our extension support for the Linux Client is very young with some
// potential driver gotchas, so offer a semi-secret way to turn it off.
@@ -1085,7 +1219,7 @@ void LLGLManager::initExtensions()
if (strchr(blacklist,'u')) mHasDepthClamp = FALSE;
}
-#endif // LL_LINUX || LL_SOLARIS
+#endif // LL_LINUX
if (!mHasMultitexture)
{
@@ -1163,7 +1297,7 @@ void LLGLManager::initExtensions()
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
-#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
+#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
if (mHasVertexBufferObject)
{
@@ -1262,7 +1396,7 @@ void LLGLManager::initExtensions()
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageCallbackARB");
glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetDebugMessageLogARB");
}
-#if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS
+#if (!LL_LINUX) || LL_LINUX_NV_GL_HEADERS
// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah
glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
if (!glDrawRangeElements)
@@ -2044,7 +2178,8 @@ LLGLState::LLGLState(LLGLenum state, S32 enabled) :
if (mState)
{
mWasEnabled = sStateMap[state];
- llassert(mWasEnabled == glIsEnabled(state));
+ // we can't actually assert on this as queued changes to state are not reflected by glIsEnabled
+ //llassert(mWasEnabled == glIsEnabled(state));
setEnabled(enabled);
stop_glerror();
}
@@ -2267,6 +2402,17 @@ LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& mode
}
}
+void LLGLUserClipPlane::disable()
+{
+ if (mApply)
+ {
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+ mApply = false;
+}
+
void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
{
glh::matrix4f& P = mProjection;
@@ -2295,12 +2441,7 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
LLGLUserClipPlane::~LLGLUserClipPlane()
{
- if (mApply)
- {
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- }
+ disable();
}
LLGLNamePool::LLGLNamePool()
@@ -2376,9 +2517,8 @@ void LLGLNamePool::release(GLuint name)
//static
void LLGLNamePool::upkeepPools()
{
- for (tracker_t::instance_iter iter = beginInstances(); iter != endInstances(); ++iter)
+ for (auto& pool : instance_snapshot())
{
- LLGLNamePool & pool = *iter;
pool.upkeep();
}
}
@@ -2386,9 +2526,8 @@ void LLGLNamePool::upkeepPools()
//static
void LLGLNamePool::cleanupPools()
{
- for (tracker_t::instance_iter iter = beginInstances(); iter != endInstances(); ++iter)
+ for (auto& pool : instance_snapshot())
{
- LLGLNamePool & pool = *iter;
pool.cleanup();
}
}
@@ -2478,27 +2617,45 @@ void LLGLDepthTest::checkState()
}
}
-LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P, U32 layer)
+LLGLSquashToFarClip::LLGLSquashToFarClip()
+{
+ glh::matrix4f proj = get_current_projection();
+ setProjectionMatrix(proj, 0);
+}
+
+LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f& P, U32 layer)
+{
+ setProjectionMatrix(P, layer);
+}
+
+
+void LLGLSquashToFarClip::setProjectionMatrix(glh::matrix4f& projection, U32 layer)
{
F32 depth = 0.99999f - 0.0001f * layer;
for (U32 i = 0; i < 4; i++)
{
- P.element(2, i) = P.element(3, i) * depth;
+ projection.element(2, i) = projection.element(3, i) * depth;
}
+ LLRender::eMatrixMode last_matrix_mode = gGL.getMatrixMode();
+
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
- gGL.loadMatrix(P.m);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.loadMatrix(projection.m);
+
+ gGL.matrixMode(last_matrix_mode);
}
LLGLSquashToFarClip::~LLGLSquashToFarClip()
{
+ LLRender::eMatrixMode last_matrix_mode = gGL.getMatrixMode();
+
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ gGL.matrixMode(last_matrix_mode);
}
@@ -2561,11 +2718,50 @@ void LLGLSyncFence::wait()
#endif
}
+LLGLSPipelineSkyBox::LLGLSPipelineSkyBox()
+: mAlphaTest(GL_ALPHA_TEST)
+, mCullFace(GL_CULL_FACE)
+, mSquashClip()
+{
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glDisable(GL_LIGHTING);
+ glDisable(GL_FOG);
+ glDisable(GL_CLIP_PLANE0);
+ }
+}
+
+LLGLSPipelineSkyBox::~LLGLSPipelineSkyBox()
+{
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glEnable(GL_LIGHTING);
+ glEnable(GL_FOG);
+ glEnable(GL_CLIP_PLANE0);
+ }
+}
+
+LLGLSPipelineDepthTestSkyBox::LLGLSPipelineDepthTestSkyBox(bool depth_test, bool depth_write)
+: LLGLSPipelineSkyBox()
+, mDepth(depth_test ? GL_TRUE : GL_FALSE, depth_write ? GL_TRUE : GL_FALSE, GL_LEQUAL)
+{
+
+}
+
+LLGLSPipelineBlendSkyBox::LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_write)
+: LLGLSPipelineDepthTestSkyBox(depth_test, depth_write)
+, mBlend(GL_BLEND)
+{
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+}
+
#if LL_WINDOWS
-// Expose desired use of high-performance graphics processor to Optimus driver
+// Expose desired use of high-performance graphics processor to Optimus driver and to AMD driver
+// https://docs.nvidia.com/gameworks/content/technologies/desktop/optimus.htm
extern "C"
{
- _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
+ __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
+ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
#endif
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 4c4302d05b..a07e2d9bb0 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -78,6 +78,7 @@ public:
// Extensions used by everyone
BOOL mHasMultitexture;
BOOL mHasATIMemInfo;
+ BOOL mHasAMDAssociations;
BOOL mHasNVXMemInfo;
S32 mNumTextureUnits;
BOOL mHasMipMapGeneration;
@@ -118,6 +119,7 @@ public:
BOOL mHasDebugOutput;
BOOL mHassRGBTexture;
BOOL mHassRGBFramebuffer;
+ BOOL mHasTexturesRGBDecode;
// Vendor-specific extensions
BOOL mIsATI;
@@ -140,9 +142,6 @@ public:
// Misc extensions
BOOL mHasSeparateSpecularColor;
- //whether this GPU is in the debug list.
- BOOL mDebugGPU;
-
S32 mDriverVersionMajor;
S32 mDriverVersionMinor;
S32 mDriverVersionRelease;
@@ -163,6 +162,8 @@ public:
void printGLInfoString();
void getGLInfo(LLSD& info);
+ void asLLSD(LLSD& info);
+
// In ALL CAPS
std::string mGLVendor;
std::string mGLVendorShort;
@@ -174,7 +175,6 @@ private:
void initExtensions();
void initGLStates();
void initGLImages();
- void setToDebugGPU();
};
extern LLGLManager gGLManager;
@@ -348,6 +348,7 @@ public:
~LLGLUserClipPlane();
void setPlane(F32 a, F32 b, F32 c, F32 d);
+ void disable();
private:
bool mApply;
@@ -360,14 +361,17 @@ private:
Modify and load projection matrix to push depth values to far clip plane.
Restores projection matrix on destruction.
- GL_MODELVIEW_MATRIX is active whenever program execution
- leaves this class.
+ Saves/restores matrix mode around projection manipulation.
Does not stack.
*/
class LLGLSquashToFarClip
{
public:
- LLGLSquashToFarClip(glh::matrix4f projection, U32 layer = 0);
+ LLGLSquashToFarClip();
+ LLGLSquashToFarClip(glh::matrix4f& projection, U32 layer = 0);
+
+ void setProjectionMatrix(glh::matrix4f& projection, U32 layer);
+
~LLGLSquashToFarClip();
};
diff --git a/indra/llrender/llglcommonfunc.h b/indra/llrender/llglcommonfunc.h
index f1f8ff7bc4..e6d3755755 100644
--- a/indra/llrender/llglcommonfunc.h
+++ b/indra/llrender/llglcommonfunc.h
@@ -1,5 +1,5 @@
/**
-* @file llphoenixfunc.h
+* @file llglcommonfunc.h
* @brief File include common opengl code snippets
*
* $LicenseInfo:firstyear=2003&license=viewerlgpl$
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index 722dd9050b..6bca3623e0 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -27,242 +27,7 @@
#ifndef LL_LLGLHEADERS_H
#define LL_LLGLHEADERS_H
-#if LL_SOLARIS
-# if defined(__sparc)
-# define I_NEED_OS2_H // avoiding BOOL conflicts
-# endif
-# include "GL/gl.h"
-# if defined(__sparc)
-# undef I_NEED_OS2_H
-# ifdef BOOL
-# undef BOOL // now get rid of Xmd.h crap
-# endif
-# endif
-# include "GL/glx.h"
-# define GL_GLEXT_PROTOTYPES 1
-# include "GL/glext.h"
-# include "GL/glu.h"
-# include "GL/glx.h"
-# define GLX_GLXEXT_PROTOTYPES 1
-# include "GL/glxext.h"
-//# define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddressARB((const GLubyte*)(p))
-# define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddress((const GLubyte*)(p))
-
-// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly
-// This header is distributed with SL. You'll find it in linden/libraries/include/GL/
-# define __APPLE__
-# include "GL/glh_extensions.h"
-# undef __APPLE__
-
-
-// GL_ARB_vertex_buffer_object
-extern PFNGLBINDBUFFERARBPROC glBindBufferARB;
-extern PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB;
-extern PFNGLGENBUFFERSARBPROC glGenBuffersARB;
-extern PFNGLISBUFFERARBPROC glIsBufferARB;
-extern PFNGLBUFFERDATAARBPROC glBufferDataARB;
-extern PFNGLBUFFERSUBDATAARBPROC glBufferSubDataARB;
-extern PFNGLGETBUFFERSUBDATAARBPROC glGetBufferSubDataARB;
-extern PFNGLMAPBUFFERARBPROC glMapBufferARB;
-extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
-extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
-extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
-
-// GL_ARB_vertex_array_object
-extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
-extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
-extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
-extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
-
-// GL_ARB_sync
-extern PFNGLFENCESYNCPROC glFenceSync;
-extern PFNGLISSYNCPROC glIsSync;
-extern PFNGLDELETESYNCPROC glDeleteSync;
-extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync;
-extern PFNGLWAITSYNCPROC glWaitSync;
-extern PFNGLGETINTEGER64VPROC glGetInteger64v;
-extern PFNGLGETSYNCIVPROC glGetSynciv;
-
-// GL_APPLE_flush_buffer_range
-extern PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE;
-extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE;
-
-// GL_ARB_map_buffer_range
-extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
-extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange;
-
-// GL_ATI_vertex_array_object
-extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI;
-extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI;
-extern PFNGLUPDATEOBJECTBUFFERATIPROC glUpdateObjectBufferATI;
-extern PFNGLGETOBJECTBUFFERFVATIPROC glGetObjectBufferfvATI;
-extern PFNGLGETOBJECTBUFFERIVATIPROC glGetObjectBufferivATI;
-extern PFNGLFREEOBJECTBUFFERATIPROC glFreeObjectBufferATI;
-extern PFNGLARRAYOBJECTATIPROC glArrayObjectATI;
-extern PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glVertexAttribArrayObjectATI;
-extern PFNGLGETARRAYOBJECTFVATIPROC glGetArrayObjectfvATI;
-extern PFNGLGETARRAYOBJECTIVATIPROC glGetArrayObjectivATI;
-extern PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI;
-extern PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI;
-extern PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI;
-
-// GL_ARB_occlusion_query
-extern PFNGLGENQUERIESARBPROC glGenQueriesARB;
-extern PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB;
-extern PFNGLISQUERYARBPROC glIsQueryARB;
-extern PFNGLBEGINQUERYARBPROC glBeginQueryARB;
-extern PFNGLENDQUERYARBPROC glEndQueryARB;
-extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;
-extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
-extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
-
-// GL_ARB_timer_query
-extern PFNGLQUERYCOUNTERPROC glQueryCounter;
-extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
-extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
-
-// GL_ARB_point_parameters
-extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
-extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
-
-// GL_ARB_shader_objects
-extern PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
-extern PFNGLGETHANDLEARBPROC glGetHandleARB;
-extern PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
-extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
-extern PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
-extern PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
-extern PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
-extern PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
-extern PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
-extern PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
-extern PFNGLVALIDATEPROGRAMARBPROC glValidateProgramARB;
-extern PFNGLUNIFORM1FARBPROC glUniform1fARB;
-extern PFNGLUNIFORM2FARBPROC glUniform2fARB;
-extern PFNGLUNIFORM3FARBPROC glUniform3fARB;
-extern PFNGLUNIFORM4FARBPROC glUniform4fARB;
-extern PFNGLUNIFORM1IARBPROC glUniform1iARB;
-extern PFNGLUNIFORM2IARBPROC glUniform2iARB;
-extern PFNGLUNIFORM3IARBPROC glUniform3iARB;
-extern PFNGLUNIFORM4IARBPROC glUniform4iARB;
-extern PFNGLUNIFORM1FVARBPROC glUniform1fvARB;
-extern PFNGLUNIFORM2FVARBPROC glUniform2fvARB;
-extern PFNGLUNIFORM3FVARBPROC glUniform3fvARB;
-extern PFNGLUNIFORM4FVARBPROC glUniform4fvARB;
-extern PFNGLUNIFORM1IVARBPROC glUniform1ivARB;
-extern PFNGLUNIFORM2IVARBPROC glUniform2ivARB;
-extern PFNGLUNIFORM3IVARBPROC glUniform3ivARB;
-extern PFNGLUNIFORM4IVARBPROC glUniform4ivARB;
-extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB;
-extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB;
-extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv;
-extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB;
-extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB;
-extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
-extern PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
-extern PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB;
-extern PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
-extern PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB;
-extern PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB;
-extern PFNGLGETUNIFORMIVARBPROC glGetUniformivARB;
-extern PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB;
-
-// GL_ARB_vertex_shader
-extern PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB;
-extern PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB;
-extern PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB;
-extern PFNGLVERTEXATTRIB1FVARBPROC glVertexAttrib1fvARB;
-extern PFNGLVERTEXATTRIB1SARBPROC glVertexAttrib1sARB;
-extern PFNGLVERTEXATTRIB1SVARBPROC glVertexAttrib1svARB;
-extern PFNGLVERTEXATTRIB2DARBPROC glVertexAttrib2dARB;
-extern PFNGLVERTEXATTRIB2DVARBPROC glVertexAttrib2dvARB;
-extern PFNGLVERTEXATTRIB2FARBPROC glVertexAttrib2fARB;
-extern PFNGLVERTEXATTRIB2FVARBPROC glVertexAttrib2fvARB;
-extern PFNGLVERTEXATTRIB2SARBPROC glVertexAttrib2sARB;
-extern PFNGLVERTEXATTRIB2SVARBPROC glVertexAttrib2svARB;
-extern PFNGLVERTEXATTRIB3DARBPROC glVertexAttrib3dARB;
-extern PFNGLVERTEXATTRIB3DVARBPROC glVertexAttrib3dvARB;
-extern PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB;
-extern PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB;
-extern PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB;
-extern PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB;
-extern PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4nbvARB;
-extern PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4nivARB;
-extern PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4nsvARB;
-extern PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4nubARB;
-extern PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4nubvARB;
-extern PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4nuivARB;
-extern PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4nusvARB;
-extern PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB;
-extern PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB;
-extern PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB;
-extern PFNGLVERTEXATTRIB4FARBPROC glVertexAttrib4fARB;
-extern PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB;
-extern PFNGLVERTEXATTRIB4IVARBPROC glVertexAttrib4ivARB;
-extern PFNGLVERTEXATTRIB4SARBPROC glVertexAttrib4sARB;
-extern PFNGLVERTEXATTRIB4SVARBPROC glVertexAttrib4svARB;
-extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
-extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
-extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
-extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
-extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
-extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
-extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
-extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
-extern PFNGLBINDPROGRAMARBPROC glBindProgramARB;
-extern PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB;
-extern PFNGLGENPROGRAMSARBPROC glGenProgramsARB;
-extern PFNGLPROGRAMENVPARAMETER4DARBPROC glProgramEnvParameter4dARB;
-extern PFNGLPROGRAMENVPARAMETER4DVARBPROC glProgramEnvParameter4dvARB;
-extern PFNGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB;
-extern PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB;
-extern PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB;
-extern PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glProgramLocalParameter4dvARB;
-extern PFNGLPROGRAMLOCALPARAMETER4FARBPROC glProgramLocalParameter4fARB;
-extern PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB;
-extern PFNGLGETPROGRAMENVPARAMETERDVARBPROC glGetProgramEnvParameterdvARB;
-extern PFNGLGETPROGRAMENVPARAMETERFVARBPROC glGetProgramEnvParameterfvARB;
-extern PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB;
-extern PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glGetProgramLocalParameterfvARB;
-extern PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
-extern PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB;
-extern PFNGLGETVERTEXATTRIBDVARBPROC glGetVertexAttribdvARB;
-extern PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB;
-extern PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB;
-extern PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB;
-extern PFNGLISPROGRAMARBPROC glIsProgramARB;
-extern PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB;
-extern PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB;
-extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;
-
-extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
-extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB;
-
-extern PFNGLCOLORTABLEEXTPROC glColorTableEXT;
-
-//GL_EXT_blend_func_separate
-extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
-
-//GL_EXT_framebuffer_object
-extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
-extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
-extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
-extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT;
-extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
-extern PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT;
-extern PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT;
-extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
-extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
-extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
-extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
-extern PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT;
-extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
-extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT;
-extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
-extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
-extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
-
-#elif LL_MESA
+#if LL_MESA
//----------------------------------------------------------------------------
// MESA headers
// quotes so we get libraries/.../GL/ version
@@ -618,6 +383,8 @@ extern PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI;
extern PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI;
extern PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI;
+extern PFNWGLGETGPUIDSAMDPROC wglGetGPUIDsAMD;
+extern PFNWGLGETGPUINFOAMDPROC wglGetGPUInfoAMD;
extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
// GL_ARB_occlusion_query
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 141ed51260..4351f6e2c8 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -37,11 +37,9 @@
#include "OpenGL/OpenGL.h"
#endif
-#ifdef LL_RELEASE_FOR_DOWNLOAD
-#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
-#else
-#define UNIFORM_ERRS LL_ERRS("Shader")
-#endif
+// Print-print list of shader included source files that are linked together via glAttachObjectARB()
+// i.e. On macOS / OSX the AMD GLSL linker will display an error if a varying is left in an undefined state.
+#define DEBUG_SHADER_INCLUDES 0
// Lots of STL stuff in here, using namespace std to keep things more readable
using std::vector;
@@ -84,6 +82,12 @@ LLShaderFeatures::LLShaderFeatures()
, hasObjectSkinning(false)
, hasAtmospherics(false)
, hasGamma(false)
+ , hasSrgb(false)
+ , encodesNormal(false)
+ , isDeferred(false)
+ , hasIndirect(false)
+ , hasShadows(false)
+ , hasAmbientOcclusion(false)
, mIndexedTextureChannels(0)
, disableTextureIndex(false)
, hasAlphaMask(false)
@@ -344,13 +348,13 @@ void LLGLSLShader::unloadInternal()
{
GLhandleARB obj[1024];
GLsizei count;
+ glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
- glGetAttachedObjectsARB(mProgramObject, sizeof(obj)/sizeof(obj[0]), &count, obj);
for (GLsizei i = 0; i < count; i++)
{
glDetachObjectARB(mProgramObject, obj[i]);
- glDeleteObjectARB(obj[i]);
- }
+ glDeleteObjectARB(obj[i]);
+ }
glDeleteObjectARB(mProgramObject);
@@ -392,16 +396,28 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
mLightHash = 0xFFFFFFFF;
llassert_always(!mShaderFiles.empty());
- BOOL success = TRUE;
// Create program
mProgramObject = glCreateProgramObjectARB();
+ if (mProgramObject == 0)
+ {
+ // Shouldn't happen if shader related extensions, like ARB_vertex_shader, exist.
+ LL_SHADER_LOADING_WARNS() << "Failed to create handle for shader: " << mName << LL_ENDL;
+ unloadInternal();
+ return FALSE;
+ }
+
+ BOOL success = TRUE;
#if LL_DARWIN
// work-around missing mix(vec3,vec3,bvec3)
mDefines["OLD_SELECT"] = "1";
#endif
+#if DEBUG_SHADER_INCLUDES
+ fprintf(stderr, "--- %s ---\n", mName.c_str());
+#endif // DEBUG_SHADER_INCLUDES
+
//compile new source
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
@@ -448,12 +464,12 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
}
if( !success )
{
- LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL;
+ LL_SHADER_LOADING_WARNS() << "Failed to link shader: " << mName << LL_ENDL;
// Try again using a lower shader level;
if (mShaderLevel > 0)
{
- LL_WARNS("ShaderLoading") << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
+ LL_SHADER_LOADING_WARNS() << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
mShaderLevel--;
return createShader(attributes,uniforms);
}
@@ -485,18 +501,61 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
return success;
}
-BOOL LLGLSLShader::attachObject(std::string object)
+#if DEBUG_SHADER_INCLUDES
+void dumpAttachObject( const char *func_name, GLhandleARB program_object, const std::string &object_path )
+{
+ GLcharARB* info_log;
+ GLint info_len_expect = 0;
+ GLint info_len_actual = 0;
+
+ glGetObjectParameterivARB(program_object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_len_expect);
+ fprintf(stderr, " * %-20s(), log size: %d, %s\n", func_name, info_len_expect, object_path.c_str());
+
+ if (info_len_expect > 0)
+ {
+ fprintf(stderr, " ========== %s() ========== \n", func_name);
+ info_log = new GLcharARB [ info_len_expect ];
+ glGetInfoLogARB(program_object, info_len_expect, &info_len_actual, info_log);
+ fprintf(stderr, "%s\n", info_log);
+ delete [] info_log;
+ }
+}
+#endif // DEBUG_SHADER_INCLUDES
+
+BOOL LLGLSLShader::attachVertexObject(std::string object_path)
+{
+ if (LLShaderMgr::instance()->mVertexShaderObjects.count(object_path) > 0)
+ {
+ stop_glerror();
+ glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mVertexShaderObjects[object_path]);
+#if DEBUG_SHADER_INCLUDES
+ dumpAttachObject("attachVertexObject", mProgramObject, object_path);
+#endif // DEBUG_SHADER_INCLUDES
+ stop_glerror();
+ return TRUE;
+ }
+ else
+ {
+ LL_SHADER_LOADING_WARNS() << "Attempting to attach shader object: '" << object_path << "' that hasn't been compiled." << LL_ENDL;
+ return FALSE;
+ }
+}
+
+BOOL LLGLSLShader::attachFragmentObject(std::string object_path)
{
- if (LLShaderMgr::instance()->mShaderObjects.count(object) > 0)
+ if (LLShaderMgr::instance()->mFragmentShaderObjects.count(object_path) > 0)
{
stop_glerror();
- glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mShaderObjects[object]);
+ glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mFragmentShaderObjects[object_path]);
+#if DEBUG_SHADER_INCLUDES
+ dumpAttachObject("attachFragmentObject", mProgramObject, object_path);
+#endif // DEBUG_SHADER_INCLUDES
stop_glerror();
return TRUE;
}
else
{
- LL_WARNS("ShaderLoading") << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL;
+ LL_SHADER_LOADING_WARNS() << "Attempting to attach shader object: '" << object_path << "' that hasn't been compiled." << LL_ENDL;
return FALSE;
}
}
@@ -507,11 +566,15 @@ void LLGLSLShader::attachObject(GLhandleARB object)
{
stop_glerror();
glAttachObjectARB(mProgramObject, object);
+#if DEBUG_SHADER_INCLUDES
+ std::string object_path("???");
+ dumpAttachObject("attachObject", mProgramObject, object_path);
+#endif // DEBUG_SHADER_INCLUDES
stop_glerror();
}
else
{
- LL_WARNS("ShaderLoading") << "Attempting to attach non existing shader object. " << LL_ENDL;
+ LL_SHADER_LOADING_WARNS() << "Attempting to attach non existing shader object. " << LL_ENDL;
}
}
@@ -690,6 +753,11 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
}
}
+void LLGLSLShader::clearPermutations()
+{
+ mDefines.clear();
+}
+
void LLGLSLShader::addPermutation(std::string name, std::string value)
{
mDefines[name] = value;
@@ -759,18 +827,19 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
S32 diffuseMap = glGetUniformLocationARB(mProgramObject, "diffuseMap");
S32 specularMap = glGetUniformLocationARB(mProgramObject, "specularMap");
S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap");
+ S32 altDiffuseMap = glGetUniformLocationARB(mProgramObject, "altDiffuseMap");
S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap");
std::set<S32> skip_index;
- if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap))
+ if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap || -1 != altDiffuseMap))
{
GLenum type;
GLsizei length;
GLint size = -1;
char name[1024];
- diffuseMap = specularMap = bumpMap = environmentMap = -1;
+ diffuseMap = altDiffuseMap = specularMap = bumpMap = environmentMap = -1;
for (S32 i = 0; i < activeCount; i++)
{
@@ -790,12 +859,6 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
continue;
}
- if (-1 == specularMap && std::string(name) == "specularMap")
- {
- specularMap = i;
- continue;
- }
-
if (-1 == bumpMap && std::string(name) == "bumpMap")
{
bumpMap = i;
@@ -807,6 +870,12 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
environmentMap = i;
continue;
}
+
+ if (-1 == altDiffuseMap && std::string(name) == "altDiffuseMap")
+ {
+ altDiffuseMap = i;
+ continue;
+ }
}
bool specularDiff = specularMap < diffuseMap && -1 != specularMap;
@@ -858,7 +927,7 @@ BOOL LLGLSLShader::link(BOOL suppress_errors)
{
BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
- if (!suppress_errors)
+ if (!success && !suppress_errors)
{
LLShaderMgr::instance()->dumpObjectLog(mProgramObject, !success, mName);
}
@@ -916,19 +985,19 @@ void LLGLSLShader::bindNoShader(void)
}
}
-S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
+S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace)
{
S32 channel = 0;
channel = getUniformLocation(uniform);
- return bindTexture(channel, texture, mode);
+ return bindTexture(channel, texture, mode, colorspace);
}
-S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
+S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace)
{
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
- UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
return -1;
}
@@ -937,6 +1006,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu
if (uniform > -1)
{
gGL.getTexUnit(uniform)->bind(texture, mode);
+ gGL.getTexUnit(uniform)->setTextureColorSpace(colorspace);
}
return uniform;
@@ -954,7 +1024,7 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
- UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
return -1;
}
@@ -968,11 +1038,11 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
return uniform;
}
-S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
+S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space)
{
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
- UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
return -1;
}
S32 index = mTexture[uniform];
@@ -980,21 +1050,22 @@ S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
gGL.getTexUnit(index)->activate();
gGL.getTexUnit(index)->enable(mode);
+ gGL.getTexUnit(index)->setTextureColorSpace(space);
}
return index;
}
-S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
+S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space)
{
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
- UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
+ LL_SHADER_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(index)->getCurrType() != mode)
+ if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode && gGL.getTexUnit(index)->getCurrColorSpace() != space)
{
if (gDebugSession)
{
@@ -1017,7 +1088,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1039,7 +1110,7 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x)
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1061,7 +1132,7 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1084,7 +1155,7 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1107,7 +1178,7 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1130,7 +1201,7 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1153,7 +1224,7 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1176,7 +1247,7 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1199,7 +1270,7 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1222,7 +1293,7 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1245,7 +1316,7 @@ void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, c
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1262,7 +1333,7 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1279,7 +1350,7 @@ void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose,
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@@ -1296,7 +1367,7 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
{
if (mUniform.size() <= index)
{
- UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
+ LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index b56b914013..7cf6d3c941 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -48,6 +48,12 @@ public:
bool hasObjectSkinning;
bool hasAtmospherics;
bool hasGamma;
+ bool hasShadows;
+ bool hasAmbientOcclusion;
+ bool hasSrgb;
+ bool encodesNormal;
+ bool isDeferred;
+ bool hasIndirect;
S32 mIndexedTextureChannels;
bool disableTextureIndex;
bool hasAlphaMask;
@@ -96,7 +102,8 @@ public:
std::vector<LLStaticHashedString> * uniforms,
U32 varying_count = 0,
const char** varyings = NULL);
- BOOL attachObject(std::string object);
+ BOOL attachFragmentObject(std::string object);
+ BOOL attachVertexObject(std::string object);
void attachObject(GLhandleARB object);
void attachObjects(GLhandleARB* objects = NULL, S32 count = 0);
BOOL mapAttributes(const std::vector<LLStaticHashedString> * attributes);
@@ -139,6 +146,7 @@ public:
GLint getAttribLocation(U32 attrib);
GLint mapUniformTextureChannel(GLint location, GLenum type);
+ void clearPermutations();
void addPermutation(std::string name, std::string value);
void removePermutation(std::string name);
@@ -146,13 +154,13 @@ public:
//if given texture uniform is active in the shader,
//the corresponding channel will be active upon return
//returns channel texture is enabled in from [0-MAX)
- S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
- S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
+ S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
// bindTexture returns the texture unit we've bound the texture to.
// You can reuse the return value to unbind a texture when required.
- S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
- S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
+ S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
+ S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h
index 0e2c3bcb44..a4924eba14 100644
--- a/indra/llrender/llglstates.h
+++ b/indra/llrender/llglstates.h
@@ -208,11 +208,27 @@ public:
class LLGLSPipelineSkyBox
{
protected:
- LLGLDisable mAlphaTest, mCullFace, mFog;
+ LLGLDisable mAlphaTest;
+ LLGLDisable mCullFace;
+ LLGLSquashToFarClip mSquashClip;
public:
- LLGLSPipelineSkyBox()
- : mAlphaTest(GL_ALPHA_TEST), mCullFace(GL_CULL_FACE), mFog(GL_FOG)
- { }
+ LLGLSPipelineSkyBox();
+ ~LLGLSPipelineSkyBox();
+};
+
+class LLGLSPipelineDepthTestSkyBox : public LLGLSPipelineSkyBox
+{
+public:
+ LLGLSPipelineDepthTestSkyBox(bool depth_test, bool depth_write);
+
+ LLGLDepthTest mDepth;
+};
+
+class LLGLSPipelineBlendSkyBox : public LLGLSPipelineDepthTestSkyBox
+{
+public:
+ LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_write);
+ LLGLEnable mBlend;
};
class LLGLSTracker
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
index 3a6eebebba..ad501687ed 100644
--- a/indra/llrender/llgltexture.cpp
+++ b/indra/llrender/llgltexture.cpp
@@ -288,6 +288,18 @@ void LLGLTexture::setCategory(S32 category)
mGLTexturep->setCategory(category) ;
}
+void LLGLTexture::setTexName(LLGLuint texName)
+{
+ llassert(mGLTexturep.notNull());
+ return mGLTexturep->setTexName(texName);
+}
+
+void LLGLTexture::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target)
+{
+ llassert(mGLTexturep.notNull());
+ return mGLTexturep->setTarget(target, bind_target);
+}
+
LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode(void) const
{
llassert(mGLTexturep.notNull()) ;
@@ -389,9 +401,11 @@ void LLGLTexture::destroyGLTexture()
void LLGLTexture::setTexelsPerImage()
{
- S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
- S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
- mTexelsPerImage = (F32)fullwidth * fullheight;
+ U32 fullwidth = llmin(mFullWidth,U32(MAX_IMAGE_SIZE_DEFAULT));
+ U32 fullheight = llmin(mFullHeight,U32(MAX_IMAGE_SIZE_DEFAULT));
+ mTexelsPerImage = (U32)fullwidth * fullheight;
}
+static LLUUID sStubUUID;
+const LLUUID& LLGLTexture::getID() const { return sStubUUID; }
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
index 70610d9626..071912c2c2 100644
--- a/indra/llrender/llgltexture.h
+++ b/indra/llrender/llgltexture.h
@@ -1,5 +1,5 @@
/**
- * @file llglviewertexture.h
+ * @file llgltexture.h
* @brief Object for managing opengl textures
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
@@ -104,7 +104,7 @@ public:
virtual void dump(); // debug info to LL_INFOS()
- virtual const LLUUID& getID() const = 0;
+ virtual const LLUUID& getID() const;
void setBoostLevel(S32 level);
S32 getBoostLevel() { return mBoostLevel; }
@@ -133,6 +133,8 @@ public:
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
void setGLTextureCreated (bool initialized);
void setCategory(S32 category) ;
+ void setTexName(LLGLuint); // for forcing w/ externally created textures only
+ void setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target);
LLTexUnit::eTextureAddressMode getAddressMode(void) const ;
S32 getMaxDiscardLevel() const;
@@ -179,11 +181,11 @@ protected:
protected:
S32 mBoostLevel; // enum describing priority level
- S32 mFullWidth;
- S32 mFullHeight;
+ U32 mFullWidth;
+ U32 mFullHeight;
BOOL mUseMipMaps;
S8 mComponents;
- F32 mTexelsPerImage; // Texels per image.
+ U32 mTexelsPerImage; // Texels per image.
mutable S8 mNeedsGLTexture;
//GL texture
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 40217b2e80..0151d20128 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -184,34 +184,47 @@ void LLImageGL::cleanupClass()
//static
S32 LLImageGL::dataFormatBits(S32 dataformat)
{
- switch (dataformat)
- {
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 4;
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 8;
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 8;
- case GL_LUMINANCE: return 8;
- case GL_ALPHA: return 8;
- case GL_COLOR_INDEX: return 8;
- case GL_LUMINANCE_ALPHA: return 16;
- case GL_RGB: return 24;
- case GL_RGB8: return 24;
- case GL_RGBA: return 32;
- case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac
- default:
- LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;
- return 0;
- }
+ switch (dataformat)
+ {
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 4;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 4;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 8;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 8;
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 8;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 8;
+ case GL_LUMINANCE: return 8;
+ case GL_ALPHA: return 8;
+ case GL_COLOR_INDEX: return 8;
+ case GL_LUMINANCE_ALPHA: return 16;
+ case GL_RGB: return 24;
+ case GL_SRGB: return 24;
+ case GL_RGB8: return 24;
+ case GL_RGBA: return 32;
+ case GL_SRGB_ALPHA: return 32;
+ case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac
+ default:
+ LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;
+ return 0;
+ }
}
//static
S32 LLImageGL::dataFormatBytes(S32 dataformat, S32 width, S32 height)
{
- if (dataformat >= GL_COMPRESSED_RGB_S3TC_DXT1_EXT &&
- dataformat <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
- {
- if (width < 4) width = 4;
- if (height < 4) height = 4;
- }
+ switch (dataformat)
+ {
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ if (width < 4) width = 4;
+ if (height < 4) height = 4;
+ break;
+ default:
+ break;
+ }
S32 bytes ((width*height*dataFormatBits(dataformat)+7)>>3);
S32 aligned = (bytes+3)&~3;
return aligned;
@@ -223,14 +236,19 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)
switch (dataformat)
{
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 3;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 3;
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 4;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 4;
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 4;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 4;
case GL_LUMINANCE: return 1;
case GL_ALPHA: return 1;
case GL_COLOR_INDEX: return 1;
case GL_LUMINANCE_ALPHA: return 2;
case GL_RGB: return 3;
+ case GL_SRGB: return 3;
case GL_RGBA: return 4;
+ case GL_SRGB_ALPHA: return 4;
case GL_BGRA: return 4; // Used for QuickTime media textures on the Mac
default:
LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;
@@ -355,7 +373,7 @@ BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, B
LLImageGL::LLImageGL(BOOL usemipmaps)
: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
- mSaveData(0)
+ mSaveData(0), mExternalTexture(FALSE)
{
init(usemipmaps);
setSize(0, 0, 0);
@@ -365,7 +383,7 @@ LLImageGL::LLImageGL(BOOL usemipmaps)
LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
- mSaveData(0)
+ mSaveData(0), mExternalTexture(FALSE)
{
llassert( components <= 4 );
init(usemipmaps);
@@ -376,7 +394,7 @@ LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps)
: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
- mSaveData(0)
+ mSaveData(0), mExternalTexture(FALSE)
{
init(usemipmaps);
setSize(0, 0, 0);
@@ -386,12 +404,36 @@ LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps)
createGLTexture(0, imageraw);
}
+LLImageGL::LLImageGL(
+ LLGLuint texName,
+ U32 components,
+ LLGLenum target,
+ LLGLint formatInternal,
+ LLGLenum formatPrimary,
+ LLGLenum formatType,
+ LLTexUnit::eTextureAddressMode addressMode)
+ : LLTrace::MemTrackable<LLImageGL>("LLImageGL"), mSaveData(0), mExternalTexture(TRUE)
+{
+ init(false);
+ mTexName = texName;
+ mTarget = target;
+ mComponents = components;
+ mAddressMode = addressMode;
+ mFormatType = formatType;
+ mFormatInternal = formatInternal;
+ mFormatPrimary = formatPrimary;
+}
+
+
LLImageGL::~LLImageGL()
{
- LLImageGL::cleanup();
- sImageList.erase(this);
- freePickMask();
- sCount--;
+ if (!mExternalTexture)
+ {
+ LLImageGL::cleanup();
+ sImageList.erase(this);
+ freePickMask();
+ sCount--;
+ }
}
void LLImageGL::init(BOOL usemipmaps)
@@ -626,10 +668,20 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
LL_RECORD_BLOCK_TIME(FTM_SET_IMAGE);
bool is_compressed = false;
- if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
- {
- is_compressed = true;
- }
+
+ switch (mFormatPrimary)
+ {
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ is_compressed = true;
+ break;
+ default:
+ break;
+ }
@@ -933,38 +985,56 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
return FALSE;
}
- if( !mHasExplicitFormat )
- {
- switch (mComponents)
- {
- case 1:
- // Use luminance alpha (for fonts)
- mFormatInternal = GL_LUMINANCE8;
- mFormatPrimary = GL_LUMINANCE;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- case 2:
- // Use luminance alpha (for fonts)
- mFormatInternal = GL_LUMINANCE8_ALPHA8;
- mFormatPrimary = GL_LUMINANCE_ALPHA;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- case 3:
- mFormatInternal = GL_RGB8;
- mFormatPrimary = GL_RGB;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- case 4:
- mFormatInternal = GL_RGBA8;
- mFormatPrimary = GL_RGBA;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- default:
- LL_ERRS() << "Bad number of components for texture: " << (U32)getComponents() << LL_ENDL;
- }
- }
-
- mCurrentDiscardLevel = discard_level;
+ if (!mHasExplicitFormat)
+ {
+ switch (mComponents)
+ {
+ case 1:
+ // Use luminance alpha (for fonts)
+ mFormatInternal = GL_LUMINANCE8;
+ mFormatPrimary = GL_LUMINANCE;
+ mFormatType = GL_UNSIGNED_BYTE;
+ break;
+ case 2:
+ // Use luminance alpha (for fonts)
+ mFormatInternal = GL_LUMINANCE8_ALPHA8;
+ mFormatPrimary = GL_LUMINANCE_ALPHA;
+ mFormatType = GL_UNSIGNED_BYTE;
+ break;
+ case 3:
+#if USE_SRGB_DECODE
+ if (gGLManager.mHasTexturesRGBDecode)
+ {
+ mFormatInternal = GL_SRGB8;
+ }
+ else
+#endif
+ {
+ mFormatInternal = GL_RGB8;
+ }
+ mFormatPrimary = GL_RGB;
+ mFormatType = GL_UNSIGNED_BYTE;
+ break;
+ case 4:
+#if USE_SRGB_DECODE
+ if (gGLManager.mHasTexturesRGBDecode)
+ {
+ mFormatInternal = GL_SRGB8_ALPHA8;
+ }
+ else
+#endif
+ {
+ mFormatInternal = GL_RGBA8;
+ }
+ mFormatPrimary = GL_RGBA;
+ mFormatType = GL_UNSIGNED_BYTE;
+ break;
+ default:
+ LL_ERRS() << "Bad number of components for texture: " << (U32) getComponents() << LL_ENDL;
+ }
+ }
+
+ mCurrentDiscardLevel = discard_level;
mDiscardLevelInAtlas = discard_level;
mTexelsInAtlas = raw_image->getWidth() * raw_image->getHeight() ;
mLastBindTime = sLastFrameTime;
@@ -1203,10 +1273,18 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
case GL_RGB8:
intformat = GL_COMPRESSED_RGB;
break;
+ case GL_SRGB:
+ case GL_SRGB8:
+ intformat = GL_COMPRESSED_SRGB;
+ break;
case GL_RGBA:
case GL_RGBA8:
intformat = GL_COMPRESSED_RGBA;
break;
+ case GL_SRGB_ALPHA:
+ case GL_SRGB8_ALPHA8:
+ intformat = GL_COMPRESSED_SRGB_ALPHA;
+ break;
case GL_LUMINANCE:
case GL_LUMINANCE8:
intformat = GL_COMPRESSED_LUMINANCE;
@@ -1308,35 +1386,62 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
return FALSE;
}
+ if (mHasExplicitFormat &&
+ ((mFormatPrimary == GL_RGBA && mComponents < 4) ||
+ (mFormatPrimary == GL_RGB && mComponents < 3)))
+
+ {
+ LL_WARNS() << "Incorrect format: " << std::hex << mFormatPrimary << " components: " << (U32)mComponents << LL_ENDL;
+ mHasExplicitFormat = FALSE;
+ }
+
if( !mHasExplicitFormat )
{
- switch (mComponents)
- {
- case 1:
- // Use luminance alpha (for fonts)
- mFormatInternal = GL_LUMINANCE8;
- mFormatPrimary = GL_LUMINANCE;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- case 2:
- // Use luminance alpha (for fonts)
- mFormatInternal = GL_LUMINANCE8_ALPHA8;
- mFormatPrimary = GL_LUMINANCE_ALPHA;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- case 3:
- mFormatInternal = GL_RGB8;
- mFormatPrimary = GL_RGB;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- case 4:
- mFormatInternal = GL_RGBA8;
- mFormatPrimary = GL_RGBA;
- mFormatType = GL_UNSIGNED_BYTE;
- break;
- default:
- LL_ERRS() << "Bad number of components for texture: " << (U32)getComponents() << LL_ENDL;
- }
+ switch (mComponents)
+ {
+ case 1:
+ // Use luminance alpha (for fonts)
+ mFormatInternal = GL_LUMINANCE8;
+ mFormatPrimary = GL_LUMINANCE;
+ mFormatType = GL_UNSIGNED_BYTE;
+ break;
+ case 2:
+ // Use luminance alpha (for fonts)
+ mFormatInternal = GL_LUMINANCE8_ALPHA8;
+ mFormatPrimary = GL_LUMINANCE_ALPHA;
+ mFormatType = GL_UNSIGNED_BYTE;
+ break;
+ case 3:
+ #if USE_SRGB_DECODE
+ if (gGLManager.mHasTexturesRGBDecode)
+ {
+ mFormatInternal = GL_SRGB8;
+ }
+ else
+ #endif
+ {
+ mFormatInternal = GL_RGB8;
+ }
+ mFormatPrimary = GL_RGB;
+ mFormatType = GL_UNSIGNED_BYTE;
+ break;
+ case 4:
+ #if USE_SRGB_DECODE
+ if (gGLManager.mHasTexturesRGBDecode)
+ {
+ mFormatInternal = GL_SRGB8_ALPHA8;
+ }
+ else
+ #endif
+ {
+ mFormatInternal = GL_RGBA8;
+ }
+ mFormatPrimary = GL_RGBA;
+ mFormatType = GL_UNSIGNED_BYTE;
+ break;
+ default:
+ LL_ERRS() << "Bad number of components for texture: " << (U32)getComponents() << LL_ENDL;
+ }
calcAlphaChannelOffsetAndStride() ;
}
@@ -1764,28 +1869,30 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
}
mAlphaStride = -1 ;
- switch (mFormatPrimary)
- {
- case GL_LUMINANCE:
- case GL_ALPHA:
- mAlphaStride = 1;
- break;
- case GL_LUMINANCE_ALPHA:
- mAlphaStride = 2;
- break;
- case GL_RGB:
- mNeedsAlphaAndPickMask = FALSE ;
- mIsMask = FALSE;
- return ; //no alpha channel.
- case GL_RGBA:
- mAlphaStride = 4;
- break;
- case GL_BGRA_EXT:
- mAlphaStride = 4;
- break;
- default:
- break;
- }
+ switch (mFormatPrimary)
+ {
+ case GL_LUMINANCE:
+ case GL_ALPHA:
+ mAlphaStride = 1;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ mAlphaStride = 2;
+ break;
+ case GL_RGB:
+ case GL_SRGB:
+ mNeedsAlphaAndPickMask = FALSE;
+ mIsMask = FALSE;
+ return; //no alpha channel.
+ case GL_RGBA:
+ case GL_SRGB_ALPHA:
+ mAlphaStride = 4;
+ break;
+ case GL_BGRA_EXT:
+ mAlphaStride = 4;
+ break;
+ default:
+ break;
+ }
mAlphaOffset = -1 ;
if (mFormatType == GL_UNSIGNED_BYTE)
@@ -1968,12 +2075,13 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
freePickMask();
- if (mFormatType != GL_UNSIGNED_BYTE ||
- mFormatPrimary != GL_RGBA)
- {
- //cannot generate a pick mask for this texture
- return;
- }
+ if (mFormatType != GL_UNSIGNED_BYTE ||
+ ((mFormatPrimary != GL_RGBA)
+ && (mFormatPrimary != GL_SRGB_ALPHA)))
+ {
+ //cannot generate a pick mask for this texture
+ return;
+ }
#ifdef SHOW_ASSERT
const U32 pickSize = createPickMask(width, height);
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 2be54be062..61ddc8d59b 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -84,7 +84,10 @@ public:
LLImageGL(BOOL usemipmaps = TRUE);
LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE);
LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps = TRUE);
-
+
+ // For wrapping textures created via GL elsewhere with our API only. Use with caution.
+ LLImageGL(LLGLuint mTexName, U32 components, LLGLenum target, LLGLint formatInternal, LLGLenum formatPrimary, LLGLenum formatType, LLTexUnit::eTextureAddressMode addressMode);
+
protected:
virtual ~LLImageGL();
@@ -130,6 +133,7 @@ public:
S32 getMipBytes(S32 discard_level = -1) const;
BOOL getBoundRecently() const;
BOOL isJustBound() const;
+ BOOL getHasExplicitFormat() const { return mHasExplicitFormat; }
LLGLenum getPrimaryFormat() const { return mFormatPrimary; }
LLGLenum getFormatType() const { return mFormatType; }
@@ -194,7 +198,7 @@ private:
U16 mPickMaskWidth;
U16 mPickMaskHeight;
S8 mUseMipMaps;
- S8 mHasExplicitFormat; // If false (default), GL format is f(mComponents)
+ BOOL mHasExplicitFormat; // If false (default), GL format is f(mComponents)
S8 mAutoGenMips;
BOOL mIsMask;
@@ -234,6 +238,8 @@ protected:
LLGLenum mFormatType;
BOOL mFormatSwapBytes;// if true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1)
+ BOOL mExternalTexture;
+
// STATICS
public:
static std::set<LLImageGL*> sImageList;
@@ -279,6 +285,8 @@ public:
void setCategory(S32 category) {mCategory = category;}
S32 getCategory()const {return mCategory;}
+ void setTexName(GLuint texName) { mTexName = texName; }
+
//for debug use: show texture size distribution
//----------------------------------------
static S32 sCurTexSizeBar ;
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 65d6181920..03b6aac20c 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -50,6 +50,7 @@ U32 LLRender::sUIVerts = 0;
U32 LLTexUnit::sWhiteTexture = 0;
bool LLRender::sGLCoreProfile = false;
bool LLRender::sNsightDebugSupport = false;
+LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f);
static const U32 LL_NUM_TEXTURE_LAYERS = 32;
static const U32 LL_NUM_LIGHT_UNITS = 8;
@@ -59,7 +60,8 @@ static const GLenum sGLTextureType[] =
GL_TEXTURE_2D,
GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_CUBE_MAP_ARB,
- GL_TEXTURE_2D_MULTISAMPLE
+ GL_TEXTURE_2D_MULTISAMPLE,
+ GL_TEXTURE_3D
};
static const GLint sGLAddressMode[] =
@@ -104,7 +106,7 @@ LLTexUnit::LLTexUnit(S32 index)
mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
- mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0),
+ mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0), mTexColorSpace(TCS_LINEAR),
mHasMipMaps(false),
mIndex(index)
{
@@ -161,6 +163,8 @@ void LLTexUnit::refreshState(void)
setTextureCombiner(mCurrColorOp, mCurrColorSrc1, mCurrColorSrc2, false);
setTextureCombiner(mCurrAlphaOp, mCurrAlphaSrc1, mCurrAlphaSrc2, true);
}
+
+ setTextureColorSpace(mTexColorSpace);
}
void LLTexUnit::activate(void)
@@ -218,6 +222,8 @@ void LLTexUnit::disable(void)
{
glDisable(sGLTextureType[mCurrTexType]);
}
+
+ setTextureColorSpace(TCS_LINEAR);
mCurrTexType = TT_NONE;
}
@@ -254,7 +260,8 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
gl_tex->mTexOptionsDirty = false;
setTextureAddressMode(gl_tex->mAddressMode);
setTextureFilteringOption(gl_tex->mFilterOption);
- }
+ }
+ setTextureColorSpace(mTexColorSpace);
}
}
else
@@ -329,6 +336,7 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
setTextureFilteringOption(texture->mFilterOption);
stop_glerror();
}
+ setTextureColorSpace(mTexColorSpace);
}
stop_glerror();
@@ -354,7 +362,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
{
activate();
enable(LLTexUnit::TT_CUBE_MAP);
- mCurrTexture = cubeMap->mImages[0]->getTexName();
+ mCurrTexture = cubeMap->mImages[0]->getTexName();
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture);
mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps;
cubeMap->mImages[0]->updateBindStats(cubeMap->mImages[0]->mTextureMemory);
@@ -363,7 +371,8 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
cubeMap->mImages[0]->mTexOptionsDirty = false;
setTextureAddressMode(cubeMap->mImages[0]->mAddressMode);
setTextureFilteringOption(cubeMap->mImages[0]->mFilterOption);
- }
+ }
+ setTextureColorSpace(mTexColorSpace);
return true;
}
else
@@ -414,7 +423,8 @@ bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
enable(type);
mCurrTexture = texture;
glBindTexture(sGLTextureType[type], texture);
- mHasMipMaps = hasMips;
+ mHasMipMaps = hasMips;
+ setTextureColorSpace(mTexColorSpace);
}
return true;
}
@@ -434,6 +444,9 @@ void LLTexUnit::unbind(eTextureType type)
if (mCurrTexType == type)
{
mCurrTexture = 0;
+
+ // Always make sure our texture color space is reset to linear. SRGB sampling should be opt-in in the vast majority of cases. Also prevents color space "popping".
+ mTexColorSpace = TCS_LINEAR;
if (LLGLSLShader::sNoFixedFunction && type == LLTexUnit::TT_TEXTURE)
{
glBindTexture(sGLTextureType[type], sWhiteTexture);
@@ -837,6 +850,34 @@ void LLTexUnit::debugTextureUnit(void)
}
}
+void LLTexUnit::setTextureColorSpace(eTextureColorSpace space)
+{
+ mTexColorSpace = space;
+
+#if USE_SRGB_DECODE
+ if (gGLManager.mHasTexturesRGBDecode)
+ {
+ if (space == TCS_SRGB)
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
+ }
+ else
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
+ }
+
+ if (gDebugGL)
+ {
+ assert_glerror();
+ }
+ }
+ else
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
+ }
+#endif
+}
+
LLLightState::LLLightState(S32 index)
: mIndex(index),
mEnabled(false),
@@ -849,9 +890,12 @@ LLLightState::LLLightState(S32 index)
if (mIndex == 0)
{
mDiffuse.set(1,1,1,1);
+ mDiffuseB.set(0,0,0,0);
mSpecular.set(1,1,1,1);
}
+ mSunIsPrimary = true;
+
mAmbient.set(0,0,0,1);
mPosition.set(0,0,1,0);
mSpotDirection.set(0,0,-1);
@@ -894,6 +938,24 @@ void LLLightState::setDiffuse(const LLColor4& diffuse)
}
}
+void LLLightState::setDiffuseB(const LLColor4& diffuse)
+{
+ if (mDiffuseB != diffuse)
+ {
+ ++gGL.mLightHash;
+ mDiffuseB = diffuse;
+ }
+}
+
+void LLLightState::setSunPrimary(bool v)
+{
+ if (mSunIsPrimary != v)
+ {
+ ++gGL.mLightHash;
+ mSunIsPrimary = v;
+ }
+}
+
void LLLightState::setAmbient(const LLColor4& ambient)
{
if (mAmbient != ambient)
@@ -1137,40 +1199,46 @@ void LLRender::refreshState(void)
void LLRender::syncLightState()
{
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
-
- if (!shader)
- {
- return;
- }
-
- if (shader->mLightHash != mLightHash)
- {
- shader->mLightHash = mLightHash;
-
- LLVector4 position[8];
- LLVector3 direction[8];
- LLVector3 attenuation[8];
- LLVector3 diffuse[8];
-
- for (U32 i = 0; i < 8; i++)
- {
- LLLightState* light = mLightState[i];
-
- position[i] = light->mPosition;
- direction[i] = light->mSpotDirection;
- attenuation[i].set(light->mLinearAtten, light->mQuadraticAtten, light->mSpecular.mV[3]);
- diffuse[i].set(light->mDiffuse.mV);
- }
-
- shader->uniform4fv(LLShaderMgr::LIGHT_POSITION, 8, position[0].mV);
- shader->uniform3fv(LLShaderMgr::LIGHT_DIRECTION, 8, direction[0].mV);
- shader->uniform3fv(LLShaderMgr::LIGHT_ATTENUATION, 8, attenuation[0].mV);
- shader->uniform3fv(LLShaderMgr::LIGHT_DIFFUSE, 8, diffuse[0].mV);
- shader->uniform4fv(LLShaderMgr::LIGHT_AMBIENT, 1, mAmbientLightColor.mV);
- //HACK -- duplicate sunlight color for compatibility with drivers that can't deal with multiple shader objects referencing the same uniform
- shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, diffuse[0].mV);
- }
+ LLGLSLShader *shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ if (!shader)
+ {
+ return;
+ }
+
+ if (shader->mLightHash != mLightHash)
+ {
+ shader->mLightHash = mLightHash;
+
+ LLVector4 position[LL_NUM_LIGHT_UNITS];
+ LLVector3 direction[LL_NUM_LIGHT_UNITS];
+ LLVector4 attenuation[LL_NUM_LIGHT_UNITS];
+ LLVector3 diffuse[LL_NUM_LIGHT_UNITS];
+ LLVector3 diffuse_b[LL_NUM_LIGHT_UNITS];
+ bool sun_primary[LL_NUM_LIGHT_UNITS];
+
+ for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; i++)
+ {
+ LLLightState *light = mLightState[i];
+
+ position[i] = light->mPosition;
+ direction[i] = light->mSpotDirection;
+ attenuation[i].set(light->mLinearAtten, light->mQuadraticAtten, light->mSpecular.mV[2], light->mSpecular.mV[3]);
+ diffuse[i].set(light->mDiffuse.mV);
+ diffuse_b[i].set(light->mDiffuseB.mV);
+ sun_primary[i] = light->mSunIsPrimary;
+ }
+
+ shader->uniform4fv(LLShaderMgr::LIGHT_POSITION, LL_NUM_LIGHT_UNITS, position[0].mV);
+ shader->uniform3fv(LLShaderMgr::LIGHT_DIRECTION, LL_NUM_LIGHT_UNITS, direction[0].mV);
+ shader->uniform4fv(LLShaderMgr::LIGHT_ATTENUATION, LL_NUM_LIGHT_UNITS, attenuation[0].mV);
+ shader->uniform3fv(LLShaderMgr::LIGHT_DIFFUSE, LL_NUM_LIGHT_UNITS, diffuse[0].mV);
+ shader->uniform4fv(LLShaderMgr::LIGHT_AMBIENT, 1, mAmbientLightColor.mV);
+ shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_primary[0] ? 1 : 0);
+ shader->uniform4fv(LLShaderMgr::AMBIENT, 1, mAmbientLightColor.mV);
+ shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, diffuse[0].mV);
+ shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, diffuse_b[0].mV);
+ }
}
void LLRender::syncMatrices()
@@ -1190,6 +1258,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;
@@ -1203,12 +1272,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);
@@ -1216,7 +1291,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];
}
@@ -1232,6 +1307,11 @@ void LLRender::syncMatrices()
shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norm_mat);
}
+ if (shader->getUniformLocation(LLShaderMgr::INVERSE_MODELVIEW_MATRIX))
+ {
+ 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);
@@ -1251,14 +1331,21 @@ 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]];
+
+ // it would be nice to have this automatically track the state of the proj matrix
+ // but certain render paths (deferred lighting) require it to be mismatched *sigh*
+ //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)
{
@@ -1266,7 +1353,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;
@@ -1290,7 +1377,7 @@ void LLRender::syncMatrices()
}
- if (shader->mFeatures.hasLighting || shader->mFeatures.calculatesLighting)
+ if (shader->mFeatures.hasLighting || shader->mFeatures.calculatesLighting || shader->mFeatures.calculatesAtmospherics)
{ //also sync light state
syncLightState();
}
@@ -1307,7 +1394,7 @@ void LLRender::syncMatrices()
GL_TEXTURE,
};
- for (U32 i = 0; i < 2; ++i)
+ for (U32 i = 0; i < MM_TEXTURE0; ++i)
{
if (mMatHash[i] != mCurMatHash[i])
{
@@ -1317,11 +1404,11 @@ void LLRender::syncMatrices()
}
}
- for (U32 i = 2; i < NUM_MATRIX_MODES; ++i)
+ for (U32 i = MM_TEXTURE0; i < NUM_MATRIX_MODES; ++i)
{
if (mMatHash[i] != mCurMatHash[i])
{
- gGL.getTexUnit(i-2)->activate();
+ gGL.getTexUnit(i-MM_TEXTURE0)->activate();
glMatrixMode(mode[i]);
glLoadMatrixf(mMatrix[i][mMatIdx[i]].m);
mCurMatHash[i] = mMatHash[i];
@@ -1453,18 +1540,27 @@ void LLRender::multMatrix(const GLfloat* m)
}
}
-void LLRender::matrixMode(U32 mode)
+void LLRender::matrixMode(eMatrixMode mode)
{
if (mode == MM_TEXTURE)
{
- mode = MM_TEXTURE0 + gGL.getCurrentTexUnitIndex();
+ U32 tex_index = gGL.getCurrentTexUnitIndex();
+ // the shaders don't actually reference anything beyond texture_matrix0/1 outside of terrain rendering
+ llassert(tex_index <= 3);
+ mode = eMatrixMode(MM_TEXTURE0 + tex_index);
+ if (mode > MM_TEXTURE3)
+ {
+ // getCurrentTexUnitIndex() can go as high as 32 (LL_NUM_TEXTURE_LAYERS)
+ // Large value will result in a crash at mMatrix
+ LL_WARNS_ONCE() << "Attempted to assign matrix mode out of bounds: " << mode << LL_ENDL;
+ mode = MM_TEXTURE0;
+ }
}
- llassert(mode < NUM_MATRIX_MODES);
mMatrixMode = mode;
}
-U32 LLRender::getMatrixMode()
+LLRender::eMatrixMode LLRender::getMatrixMode()
{
if (mMatrixMode >= MM_TEXTURE0 && mMatrixMode <= MM_TEXTURE3)
{ //always return MM_TEXTURE if current matrix mode points at any texture matrix
@@ -2331,3 +2427,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);
+
+}
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 32bb728d8a..af8568f8a3 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -61,10 +61,11 @@ public:
typedef enum
{
TT_TEXTURE = 0, // Standard 2D Texture
- TT_RECT_TEXTURE, // Non power of 2 texture
- TT_CUBE_MAP, // 6-sided cube map texture
+ TT_RECT_TEXTURE, // Non power of 2 texture
+ TT_CUBE_MAP, // 6-sided cube map texture
TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample
- TT_NONE // No texture type is currently enabled
+ TT_TEXTURE_3D, // standard 3D Texture
+ TT_NONE, // No texture type is currently enabled
} eTextureType;
typedef enum
@@ -130,6 +131,12 @@ public:
TBS_ONE_MINUS_CONST_ALPHA
} eTextureBlendSrc;
+ typedef enum
+ {
+ TCS_LINEAR = 0,
+ TCS_SRGB
+ } eTextureColorSpace;
+
LLTexUnit(S32 index);
// Refreshes renderer state of the texture unit to the cached values
@@ -152,7 +159,7 @@ public:
// Binds the LLImageGL to this texture unit
// (automatically enables the unit for the LLImageGL's texture type)
bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false);
- bool bind(LLTexture* texture, bool for_rendering = false, bool forceBind = false);
+ bool bind(LLTexture* texture, bool for_rendering = false, bool forceBind = false);
// Binds a cubemap to this texture unit
// (automatically enables the texture unit for cubemaps)
@@ -197,6 +204,10 @@ public:
void setHasMipMaps(bool hasMips) { mHasMipMaps = hasMips; }
+ void setTextureColorSpace(eTextureColorSpace space);
+
+ eTextureColorSpace getCurrColorSpace() { return mTexColorSpace; }
+
protected:
const S32 mIndex;
U32 mCurrTexture;
@@ -208,6 +219,7 @@ protected:
eTextureBlendOp mCurrAlphaOp;
eTextureBlendSrc mCurrAlphaSrc1;
eTextureBlendSrc mCurrAlphaSrc2;
+ eTextureColorSpace mTexColorSpace;
S32 mCurrColorScale;
S32 mCurrAlphaScale;
bool mHasMipMaps;
@@ -228,6 +240,7 @@ public:
void enable();
void disable();
void setDiffuse(const LLColor4& diffuse);
+ void setDiffuseB(const LLColor4& diffuse);
void setAmbient(const LLColor4& ambient);
void setSpecular(const LLColor4& specular);
void setPosition(const LLVector4& position);
@@ -237,6 +250,7 @@ public:
void setSpotExponent(const F32& exponent);
void setSpotCutoff(const F32& cutoff);
void setSpotDirection(const LLVector3& direction);
+ void setSunPrimary(bool v);
protected:
friend class LLRender;
@@ -244,6 +258,8 @@ protected:
S32 mIndex;
bool mEnabled;
LLColor4 mDiffuse;
+ LLColor4 mDiffuseB;
+ bool mSunIsPrimary;
LLColor4 mAmbient;
LLColor4 mSpecular;
LLVector4 mPosition;
@@ -264,10 +280,11 @@ public:
enum eTexIndex
{
- DIFFUSE_MAP = 0,
- NORMAL_MAP,
- SPECULAR_MAP,
- NUM_TEXTURE_CHANNELS,
+ DIFFUSE_MAP = 0,
+ ALTERNATE_DIFFUSE_MAP = 1,
+ NORMAL_MAP = 1,
+ SPECULAR_MAP = 2,
+ NUM_TEXTURE_CHANNELS = 3,
};
enum eVolumeTexIndex
@@ -360,8 +377,8 @@ public:
void loadMatrix(const GLfloat* m);
void loadIdentity();
void multMatrix(const GLfloat* m);
- void matrixMode(U32 mode);
- U32 getMatrixMode();
+ void matrixMode(eMatrixMode mode);
+ eMatrixMode getMatrixMode();
const glh::matrix4f& getModelviewMatrix();
const glh::matrix4f& getProjectionMatrix();
@@ -446,11 +463,12 @@ public:
static U32 sUIVerts;
static bool sGLCoreProfile;
static bool sNsightDebugSupport;
+ static LLVector2 sUIGLScaleFactor;
private:
friend class LLLightState;
- U32 mMatrixMode;
+ eMatrixMode mMatrixMode;
U32 mMatIdx[NUM_MATRIX_MODES];
U32 mMatHash[NUM_MATRIX_MODES];
glh::matrix4f mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH];
@@ -495,4 +513,33 @@ 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);
+
+#if LL_RELEASE_FOR_DOWNLOAD
+ #define LL_SHADER_LOADING_WARNS(...) LL_WARNS_ONCE("ShaderLoading")
+ #define LL_SHADER_UNIFORM_ERRS(...) LL_WARNS_ONCE("Shader")
+#else
+ #define LL_SHADER_LOADING_WARNS(...) LL_WARNS()
+ #define LL_SHADER_UNIFORM_ERRS(...) LL_ERRS("Shader")
+#endif
+
#endif
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index 4e2ebfd51e..dd34f3e383 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -46,8 +46,6 @@
// Globals
//
const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
-/*static*/ LLVector2 LLRender2D::sGLScaleFactor(1.f, 1.f);
-/*static*/ LLImageProviderInterface* LLRender2D::sImageProvider = NULL;
//
// Functions
@@ -108,10 +106,10 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixe
top += LLFontGL::sCurOrigin.mY;
gGL.loadUIIdentity();
- gl_rect_2d(llfloor((F32)left * LLRender2D::sGLScaleFactor.mV[VX]) - pixel_offset,
- llfloor((F32)top * LLRender2D::sGLScaleFactor.mV[VY]) + pixel_offset,
- llfloor((F32)right * LLRender2D::sGLScaleFactor.mV[VX]) + pixel_offset,
- llfloor((F32)bottom * LLRender2D::sGLScaleFactor.mV[VY]) - pixel_offset,
+ gl_rect_2d(llfloor((F32)left * LLRender::sUIGLScaleFactor.mV[VX]) - pixel_offset,
+ llfloor((F32)top * LLRender::sUIGLScaleFactor.mV[VY]) + pixel_offset,
+ llfloor((F32)right * LLRender::sUIGLScaleFactor.mV[VX]) + pixel_offset,
+ llfloor((F32)bottom * LLRender::sUIGLScaleFactor.mV[VY]) - pixel_offset,
filled);
gGL.popUIMatrix();
}
@@ -800,7 +798,7 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL
}
gGL.end();
- LLRender2D::setLineWidth(1.f);
+ LLRender2D::getInstance()->setLineWidth(1.f);
}
void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
@@ -967,7 +965,7 @@ void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
}
else
{ //polygon stipple is deprecated, use "Checker" texture
- LLPointer<LLUIImage> img = LLRender2D::getUIImage("Checker");
+ LLPointer<LLUIImage> img = LLRender2D::getInstance()->getUIImage("Checker");
gGL.getTexUnit(0)->bind(img->getImage());
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
@@ -1567,25 +1565,25 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
}
-// static
-void LLRender2D::initClass(LLImageProviderInterface* image_provider,
- const LLVector2* scale_factor)
+LLRender2D::LLRender2D(LLImageProviderInterface* image_provider)
{
- sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
- sImageProvider = image_provider;
+ mImageProvider = image_provider;
+ if(mImageProvider)
+ {
+ mImageProvider->addOnRemovalCallback(resetProvider);
+ }
}
-// static
-void LLRender2D::cleanupClass()
+LLRender2D::~LLRender2D()
{
- if(sImageProvider)
+ if(mImageProvider)
{
- sImageProvider->cleanUp();
+ mImageProvider->cleanUp();
+ mImageProvider->deleteOnRemovalCallback(resetProvider);
}
}
-
-//static
+// static
void LLRender2D::translate(F32 x, F32 y, F32 z)
{
gGL.translateUI(x,y,z);
@@ -1594,14 +1592,14 @@ void LLRender2D::translate(F32 x, F32 y, F32 z)
LLFontGL::sCurDepth += z;
}
-//static
+// static
void LLRender2D::pushMatrix()
{
gGL.pushUIMatrix();
LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
}
-//static
+// static
void LLRender2D::popMatrix()
{
gGL.popUIMatrix();
@@ -1610,7 +1608,7 @@ void LLRender2D::popMatrix()
LLFontGL::sOriginStack.pop_back();
}
-//static
+// static
void LLRender2D::loadIdentity()
{
gGL.loadUIIdentity();
@@ -1619,25 +1617,18 @@ void LLRender2D::loadIdentity()
LLFontGL::sCurDepth = 0.f;
}
-//static
-void LLRender2D::setScaleFactor(const LLVector2 &scale_factor)
-{
- sGLScaleFactor = scale_factor;
-}
-
-//static
+// static
void LLRender2D::setLineWidth(F32 width)
{
gGL.flush();
- glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f));
+ glLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f));
}
-//static
LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority)
{
- if (sImageProvider)
+ if (mImageProvider)
{
- return sImageProvider->getUIImageByID(image_id, priority);
+ return mImageProvider->getUIImageByID(image_id, priority);
}
else
{
@@ -1645,12 +1636,49 @@ LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 prio
}
}
-//static
LLPointer<LLUIImage> LLRender2D::getUIImage(const std::string& name, S32 priority)
{
- if (!name.empty() && sImageProvider)
- return sImageProvider->getUIImage(name, priority);
+ if (!name.empty() && mImageProvider)
+ return mImageProvider->getUIImage(name, priority);
else
return NULL;
}
+// static
+void LLRender2D::resetProvider()
+{
+ if (LLRender2D::instanceExists())
+ {
+ LLRender2D::getInstance()->mImageProvider = NULL;
+ }
+}
+
+// class LLImageProviderInterface
+
+LLImageProviderInterface::~LLImageProviderInterface()
+{
+ for (callback_list_t::iterator iter = mCallbackList.begin(); iter != mCallbackList.end();)
+ {
+ callback_list_t::iterator curiter = iter++;
+ (*curiter)();
+ }
+}
+
+void LLImageProviderInterface::addOnRemovalCallback(callback_t func)
+{
+ if (!func)
+ {
+ return;
+ }
+ mCallbackList.push_back(func);
+}
+
+void LLImageProviderInterface::deleteOnRemovalCallback(callback_t func)
+{
+ callback_list_t::iterator iter = std::find(mCallbackList.begin(), mCallbackList.end(), func);
+ if (iter != mCallbackList.end())
+ {
+ mCallbackList.erase(iter);
+ }
+}
+
diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h
index cce3b4ed51..206e68f084 100644
--- a/indra/llrender/llrender2dutils.h
+++ b/indra/llrender/llrender2dutils.h
@@ -32,6 +32,7 @@
#include "llpointer.h" // LLPointer<>
#include "llrect.h"
+#include "llsingleton.h"
#include "llglslshader.h"
class LLColor4;
@@ -121,39 +122,51 @@ inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL
class LLImageProviderInterface;
-class LLRender2D
+class LLRender2D : public LLParamSingleton<LLRender2D>
{
+ LLSINGLETON(LLRender2D, LLImageProviderInterface* image_provider);
LOG_CLASS(LLRender2D);
+ ~LLRender2D();
public:
- static void initClass(LLImageProviderInterface* image_provider,
- const LLVector2* scale_factor);
- static void cleanupClass();
-
static void pushMatrix();
static void popMatrix();
static void loadIdentity();
static void translate(F32 x, F32 y, F32 z = 0.0f);
static void setLineWidth(F32 width);
- static void setScaleFactor(const LLVector2& scale_factor);
- static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
- static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
+ LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
+ LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
+
+protected:
+ // since LLRender2D has no control of image provider's lifecycle
+ // we need a way to tell LLRender2D that provider died and
+ // LLRender2D needs to be updated.
+ static void resetProvider();
- static LLVector2 sGLScaleFactor;
private:
- static LLImageProviderInterface* sImageProvider;
+ LLImageProviderInterface* mImageProvider;
};
class LLImageProviderInterface
{
protected:
LLImageProviderInterface() {};
- virtual ~LLImageProviderInterface() {};
+ virtual ~LLImageProviderInterface();
public:
virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
virtual void cleanUp() = 0;
+
+ // to notify holders when pointer gets deleted
+ typedef void(*callback_t)();
+ void addOnRemovalCallback(callback_t func);
+ void deleteOnRemovalCallback(callback_t func);
+
+private:
+
+ typedef std::list< callback_t > callback_list_t;
+ callback_list_t mCallbackList;
};
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index cd484b4fe9..e3c0255290 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -501,10 +501,27 @@ U32 LLRenderTarget::getNumTextures() const
return mTex.size();
}
-
-void LLRenderTarget::bindTexture(U32 index, S32 channel)
+void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options)
{
- gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index));
+ gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index));
+
+ bool isSRGB = false;
+ llassert(mInternalFormat.size() > index);
+ switch (mInternalFormat[index])
+ {
+ case GL_SRGB:
+ case GL_SRGB8:
+ case GL_SRGB_ALPHA:
+ case GL_SRGB8_ALPHA8:
+ isSRGB = true;
+ break;
+
+ default:
+ break;
+ }
+
+ gGL.getTexUnit(channel)->setTextureFilteringOption(filter_options);
+ gGL.getTexUnit(channel)->setTextureColorSpace(isSRGB ? LLTexUnit::TCS_SRGB : LLTexUnit::TCS_LINEAR);
}
void LLRenderTarget::flush(bool fetch_depth)
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 6dc84d978d..6c07ac5b1c 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -120,7 +120,7 @@ public:
U32 getDepth(void) const { return mDepth; }
bool hasStencil() const { return mStencil; }
- void bindTexture(U32 index, S32 channel);
+ void bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options = LLTexUnit::TFO_BILINEAR);
//flush rendering operations
//must be called when rendering is complete
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 643c368870..e8c6295930 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -25,22 +25,14 @@
*/
#include "linden_common.h"
-
#include "llshadermgr.h"
-
-#include "llfile.h"
#include "llrender.h"
+#include "llfile.h"
#if LL_DARWIN
#include "OpenGL/OpenGL.h"
#endif
-#ifdef LL_RELEASE_FOR_DOWNLOAD
-#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
-#else
-#define UNIFORM_ERRS LL_ERRS("Shader")
-#endif
-
// Lots of STL stuff in here, using namespace std to keep things more readable
using std::vector;
using std::pair;
@@ -87,20 +79,20 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->hasWaterFog)
{
- if (!shader->attachObject("windlight/atmosphericsVarsWaterV.glsl"))
+ if (!shader->attachVertexObject("windlight/atmosphericsVarsWaterV.glsl"))
{
return FALSE;
}
}
- else if (!shader->attachObject("windlight/atmosphericsVarsV.glsl"))
+ else if (!shader->attachVertexObject("windlight/atmosphericsVarsV.glsl"))
{
return FALSE;
}
}
- if (features->calculatesLighting || features->atmosphericHelpers)
+ if (features->calculatesLighting || features->calculatesAtmospherics)
{
- if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl"))
+ if (!shader->attachVertexObject("windlight/atmosphericsHelpersV.glsl"))
{
return FALSE;
}
@@ -110,40 +102,40 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->isSpecular)
{
- if (!shader->attachObject("lighting/lightFuncSpecularV.glsl"))
+ if (!shader->attachVertexObject("lighting/lightFuncSpecularV.glsl"))
{
return FALSE;
}
if (!features->isAlphaLighting)
{
- if (!shader->attachObject("lighting/sumLightsSpecularV.glsl"))
+ if (!shader->attachVertexObject("lighting/sumLightsSpecularV.glsl"))
{
return FALSE;
}
}
- if (!shader->attachObject("lighting/lightSpecularV.glsl"))
+ if (!shader->attachVertexObject("lighting/lightSpecularV.glsl"))
{
return FALSE;
}
}
else
{
- if (!shader->attachObject("lighting/lightFuncV.glsl"))
+ if (!shader->attachVertexObject("lighting/lightFuncV.glsl"))
{
return FALSE;
}
if (!features->isAlphaLighting)
{
- if (!shader->attachObject("lighting/sumLightsV.glsl"))
+ if (!shader->attachVertexObject("lighting/sumLightsV.glsl"))
{
return FALSE;
}
}
- if (!shader->attachObject("lighting/lightV.glsl"))
+ if (!shader->attachVertexObject("lighting/lightV.glsl"))
{
return FALSE;
}
@@ -152,8 +144,12 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
// NOTE order of shader object attaching is VERY IMPORTANT!!!
if (features->calculatesAtmospherics)
- {
- if (!shader->attachObject("windlight/atmosphericsV.glsl"))
+ {
+ if (!shader->attachVertexObject("windlight/atmosphericsFuncs.glsl")) {
+ return FALSE;
+ }
+
+ if (!shader->attachVertexObject("windlight/atmosphericsV.glsl"))
{
return FALSE;
}
@@ -161,7 +157,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
if (features->hasSkinning)
{
- if (!shader->attachObject("avatar/avatarSkinV.glsl"))
+ if (!shader->attachVertexObject("avatar/avatarSkinV.glsl"))
{
return FALSE;
}
@@ -169,7 +165,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
if (features->hasObjectSkinning)
{
- if (!shader->attachObject("avatar/objectSkinV.glsl"))
+ if (!shader->attachVertexObject("avatar/objectSkinV.glsl"))
{
return FALSE;
}
@@ -179,33 +175,95 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
// Attach Fragment Shader Features Next
///////////////////////////////////////
+// NOTE order of shader object attaching is VERY IMPORTANT!!!
+
if(features->calculatesAtmospherics)
{
if (features->hasWaterFog)
{
- if (!shader->attachObject("windlight/atmosphericsVarsWaterF.glsl"))
+ if (!shader->attachFragmentObject("windlight/atmosphericsVarsWaterF.glsl"))
{
return FALSE;
}
}
- else if (!shader->attachObject("windlight/atmosphericsVarsF.glsl"))
+ else if (!shader->attachFragmentObject("windlight/atmosphericsVarsF.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
+ if (features->calculatesLighting || features->calculatesAtmospherics)
+ {
+ if (!shader->attachFragmentObject("windlight/atmosphericsHelpersF.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
+ // we want this BEFORE shadows and AO because those facilities use pos/norm access
+ if (features->isDeferred)
+ {
+ if (!shader->attachFragmentObject("deferred/deferredUtil.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
+ if (features->hasShadows)
+ {
+ if (!shader->attachFragmentObject("deferred/shadowUtil.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
+ if (features->hasAmbientOcclusion)
+ {
+ if (!shader->attachFragmentObject("deferred/aoUtil.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
+ if (features->hasIndirect)
+ {
+ if (!shader->attachFragmentObject("deferred/indirect.glsl"))
{
return FALSE;
}
}
- // NOTE order of shader object attaching is VERY IMPORTANT!!!
if (features->hasGamma)
{
- if (!shader->attachObject("windlight/gammaF.glsl"))
+ if (!shader->attachFragmentObject("windlight/gammaF.glsl"))
{
return FALSE;
}
}
-
- if (features->hasAtmospherics)
+
+ if (features->hasSrgb)
{
- if (!shader->attachObject("windlight/atmosphericsF.glsl"))
+ if (!shader->attachFragmentObject("environment/srgbF.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
+ if (features->encodesNormal)
+ {
+ if (!shader->attachFragmentObject("environment/encodeNormF.glsl"))
+ {
+ return FALSE;
+ }
+ }
+
+ if (features->hasAtmospherics)
+ {
+ if (!shader->attachFragmentObject("windlight/atmosphericsFuncs.glsl")) {
+ return FALSE;
+ }
+
+ if (!shader->attachFragmentObject("windlight/atmosphericsF.glsl"))
{
return FALSE;
}
@@ -213,7 +271,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
if (features->hasTransport)
{
- if (!shader->attachObject("windlight/transportF.glsl"))
+ if (!shader->attachFragmentObject("windlight/transportF.glsl"))
{
return FALSE;
}
@@ -225,7 +283,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
// NOTE order of shader object attaching is VERY IMPORTANT!!!
if (features->hasWaterFog)
{
- if (!shader->attachObject("environment/waterFogF.glsl"))
+ if (!shader->attachFragmentObject("environment/waterFogF.glsl"))
{
return FALSE;
}
@@ -239,14 +297,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->hasAlphaMask)
{
- if (!shader->attachObject("lighting/lightWaterAlphaMaskNonIndexedF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightWaterAlphaMaskNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
- if (!shader->attachObject("lighting/lightWaterNonIndexedF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightWaterNonIndexedF.glsl"))
{
return FALSE;
}
@@ -256,14 +314,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->hasAlphaMask)
{
- if (!shader->attachObject("lighting/lightWaterAlphaMaskF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightWaterAlphaMaskF.glsl"))
{
return FALSE;
}
}
else
{
- if (!shader->attachObject("lighting/lightWaterF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightWaterF.glsl"))
{
return FALSE;
}
@@ -278,14 +336,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->hasAlphaMask)
{
- if (!shader->attachObject("lighting/lightAlphaMaskNonIndexedF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightAlphaMaskNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
- if (!shader->attachObject("lighting/lightNonIndexedF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightNonIndexedF.glsl"))
{
return FALSE;
}
@@ -295,14 +353,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->hasAlphaMask)
{
- if (!shader->attachObject("lighting/lightAlphaMaskF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightAlphaMaskF.glsl"))
{
return FALSE;
}
}
else
{
- if (!shader->attachObject("lighting/lightF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightF.glsl"))
{
return FALSE;
}
@@ -320,14 +378,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->disableTextureIndex)
{
- if (!shader->attachObject("lighting/lightFullbrightShinyWaterNonIndexedF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightFullbrightShinyWaterNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
- if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightFullbrightShinyWaterF.glsl"))
{
return FALSE;
}
@@ -340,12 +398,12 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->hasAlphaMask)
{
- if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl"))
{
return FALSE;
}
}
- else if (!shader->attachObject("lighting/lightFullbrightWaterNonIndexedF.glsl"))
+ else if (!shader->attachFragmentObject("lighting/lightFullbrightWaterNonIndexedF.glsl"))
{
return FALSE;
}
@@ -354,12 +412,12 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->hasAlphaMask)
{
- if (!shader->attachObject("lighting/lightFullbrightWaterAlphaMaskF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightFullbrightWaterAlphaMaskF.glsl"))
{
return FALSE;
}
}
- else if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
+ else if (!shader->attachFragmentObject("lighting/lightFullbrightWaterF.glsl"))
{
return FALSE;
}
@@ -371,14 +429,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->disableTextureIndex)
{
- if (!shader->attachObject("lighting/lightFullbrightShinyNonIndexedF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightFullbrightShinyNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
- if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightFullbrightShinyF.glsl"))
{
return FALSE;
}
@@ -393,14 +451,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
if (features->hasAlphaMask)
{
- if (!shader->attachObject("lighting/lightFullbrightNonIndexedAlphaMaskF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightFullbrightNonIndexedAlphaMaskF.glsl"))
{
return FALSE;
}
}
else
{
- if (!shader->attachObject("lighting/lightFullbrightNonIndexedF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightFullbrightNonIndexedF.glsl"))
{
return FALSE;
}
@@ -410,14 +468,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->hasAlphaMask)
{
- if (!shader->attachObject("lighting/lightFullbrightAlphaMaskF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightFullbrightAlphaMaskF.glsl"))
{
return FALSE;
}
}
else
{
- if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightFullbrightF.glsl"))
{
return FALSE;
}
@@ -435,14 +493,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->disableTextureIndex)
{
- if (!shader->attachObject("lighting/lightShinyWaterNonIndexedF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightShinyWaterNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
- if (!shader->attachObject("lighting/lightShinyWaterF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightShinyWaterF.glsl"))
{
return FALSE;
}
@@ -454,14 +512,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
if (features->disableTextureIndex)
{
- if (!shader->attachObject("lighting/lightShinyNonIndexedF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightShinyNonIndexedF.glsl"))
{
return FALSE;
}
}
else
{
- if (!shader->attachObject("lighting/lightShinyF.glsl"))
+ if (!shader->attachFragmentObject("lighting/lightShinyF.glsl"))
{
return FALSE;
}
@@ -472,14 +530,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
if (features->mIndexedTextureChannels <= 1)
{
- if (!shader->attachObject("objects/nonindexedTextureV.glsl"))
+ if (!shader->attachVertexObject("objects/nonindexedTextureV.glsl"))
{
return FALSE;
}
}
else
{
- if (!shader->attachObject("objects/indexedTextureV.glsl"))
+ if (!shader->attachVertexObject("objects/indexedTextureV.glsl"))
{
return FALSE;
}
@@ -509,32 +567,55 @@ static std::string get_object_log(GLhandleARB ret)
return res;
}
+//dump shader source for debugging
+void LLShaderMgr::dumpShaderSource(U32 shader_code_count, GLcharARB** shader_code_text)
+{
+ char num_str[16]; // U32 = max 10 digits
+
+ LL_SHADER_LOADING_WARNS() << "\n";
+
+ for (U32 i = 0; i < shader_code_count; i++)
+ {
+ snprintf(num_str, sizeof(num_str), "%4d: ", i+1);
+ std::string line_number(num_str);
+ LL_CONT << line_number << shader_code_text[i];
+ }
+ LL_CONT << LL_ENDL;
+}
+
void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string& filename)
{
std::string log = get_object_log(ret);
+ std::string fname = filename;
+ if (filename.empty())
+ {
+ fname = "unknown shader file";
+ }
- if (log.length() > 0 || warns)
+ if (log.length() > 0)
{
- LL_DEBUGS("ShaderLoading") << "Shader loading ";
-
- if (!filename.empty())
- {
- LL_CONT << "From " << filename << ":\n";
- }
- LL_CONT << log << LL_ENDL;
+ LL_SHADER_LOADING_WARNS() << "Shader loading from " << fname << LL_ENDL;
+ LL_SHADER_LOADING_WARNS() << "\n" << log << LL_ENDL;
}
}
GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines, S32 texture_index_channels)
{
+
+// endsure work-around for missing GLSL funcs gets propogated to feature shader files (e.g. srgbF.glsl)
+#if LL_DARWIN
+ if (defines)
+ {
+ (*defines)["OLD_SELECT"] = "1";
+ }
+#endif
+
GLenum error = GL_NO_ERROR;
- if (gDebugGL)
+
+ error = glGetError();
+ if (error != GL_NO_ERROR)
{
- error = glGetError();
- if (error != GL_NO_ERROR)
- {
- LL_WARNS("ShaderLoading") << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL;
- }
+ LL_SHADER_LOADING_WARNS() << "GL ERROR entering loadShaderFile(): " << error << " for file: " << filename << LL_ENDL;
}
if (filename.empty())
@@ -549,6 +630,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
S32 try_gpu_class = shader_level;
S32 gpu_class;
+ std::string open_file_name;
//find the most relevant file
for (gpu_class = try_gpu_class; gpu_class > 0; gpu_class--)
{ //search from the current gpu class down to class 1 to find the most relevant shader
@@ -556,18 +638,33 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
fname << getShaderDirPrefix();
fname << gpu_class << "/" << filename;
-
- file = LLFile::fopen(fname.str(), "r"); /* Flawfinder: ignore */
+ open_file_name = fname.str();
+
+ /*
+ Would be awesome, if we didn't have shaders that re-use files
+ with different environments to say, add skinning, etc
+ can't depend on cached version to have evaluate ifdefs identically...
+ if we can define a deterministic hash for the shader based on
+ all the inputs, maybe we can save some time here.
+ if (mShaderObjects.count(filename) > 0)
+ {
+ return mShaderObjects[filename];
+ }
+
+ */
+
+ LL_DEBUGS("ShaderLoading") << "Looking in " << open_file_name << LL_ENDL;
+ file = LLFile::fopen(open_file_name, "r"); /* Flawfinder: ignore */
if (file)
{
- LL_DEBUGS("ShaderLoading") << "Loading file: shaders/class" << gpu_class << "/" << filename << " (Want class " << gpu_class << ")" << LL_ENDL;
+ LL_DEBUGS("ShaderLoading") << "Loading file: " << open_file_name << " (Want class " << gpu_class << ")" << LL_ENDL;
break; // done
}
}
if (file == NULL)
{
- LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << filename << LL_ENDL;
+ LL_SHADER_LOADING_WARNS() << "GLSL Shader file not found: " << open_file_name << LL_ENDL;
return 0;
}
@@ -612,7 +709,31 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
else
{
- if (major_version < 4)
+ if (major_version >= 4)
+ {
+ //set version to 400
+ shader_code_text[shader_code_count++] = strdup("#version 400\n");
+ }
+ else if (major_version == 3)
+ {
+ if (minor_version < 10)
+ {
+ shader_code_text[shader_code_count++] = strdup("#version 300\n");
+ }
+ else if (minor_version <= 19)
+ {
+ shader_code_text[shader_code_count++] = strdup("#version 310\n");
+ }
+ else if (minor_version <= 29)
+ {
+ shader_code_text[shader_code_count++] = strdup("#version 320\n");
+ }
+ else
+ {
+ shader_code_text[shader_code_count++] = strdup("#version 330\n");
+ }
+ }
+ else
{
//set version to 1.30
shader_code_text[shader_code_count++] = strdup("#version 130\n");
@@ -620,10 +741,6 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
extra_code_text[extra_code_count++] = strdup("precision mediump int;\n");
extra_code_text[extra_code_count++] = strdup("precision highp float;\n");
}
- else
- { //set version to 400
- shader_code_text[shader_code_count++] = strdup("#version 400\n");
- }
extra_code_text[extra_code_count++] = strdup("#define DEFINE_GL_FRAGCOLOR 1\n");
extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n");
@@ -646,7 +763,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
extra_code_text[extra_code_count++] = strdup("#define texture2D texture\n");
extra_code_text[extra_code_count++] = strdup("#define textureCube texture\n");
extra_code_text[extra_code_count++] = strdup("#define texture2DLod textureLod\n");
- extra_code_text[extra_code_count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
+ extra_code_text[extra_code_count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
if (major_version > 1 || minor_version >= 40)
{ //GLSL 1.40 replaces texture2DRect et al with texture
@@ -704,7 +821,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
*/
- extra_code_text[extra_code_count++] = strdup("#define HAS_DIFFUSE_LOOKUP 1\n");
+ extra_code_text[extra_code_count++] = strdup("#define HAS_DIFFUSE_LOOKUP\n");
//uniform declartion
for (S32 i = 0; i < texture_index_channels; ++i)
@@ -763,11 +880,6 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
LL_ERRS() << "Indexed texture rendering requires GLSL 1.30 or later." << LL_ENDL;
}
}
- else
- {
- extra_code_text[extra_code_count++] = strdup("#define HAS_DIFFUSE_LOOKUP 0\n");
- }
-
//copy file into memory
enum {
@@ -852,85 +964,45 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
//create shader object
GLhandleARB ret = glCreateShaderObjectARB(type);
- if (gDebugGL)
+
+ error = glGetError();
+ if (error != GL_NO_ERROR)
{
- error = glGetError();
- if (error != GL_NO_ERROR)
- {
- LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << LL_ENDL;
- }
+ LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << " for file: " << open_file_name << LL_ENDL;
}
-
+
//load source
glShaderSourceARB(ret, shader_code_count, (const GLcharARB**) shader_code_text, NULL);
- if (gDebugGL)
+ error = glGetError();
+ if (error != GL_NO_ERROR)
{
- error = glGetError();
- if (error != GL_NO_ERROR)
- {
- LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << LL_ENDL;
- }
+ LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << " for file: " << open_file_name << LL_ENDL;
}
//compile source
glCompileShaderARB(ret);
- if (gDebugGL)
+ error = glGetError();
+ if (error != GL_NO_ERROR)
{
- error = glGetError();
- if (error != GL_NO_ERROR)
- {
- LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << LL_ENDL;
- }
+ LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << " for file: " << open_file_name << LL_ENDL;
}
-
+
if (error == GL_NO_ERROR)
{
//check for errors
GLint success = GL_TRUE;
glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success);
- if (gDebugGL || success == GL_FALSE)
- {
- error = glGetError();
- if (error != GL_NO_ERROR || success == GL_FALSE)
- {
- //an error occured, print log
- LL_WARNS("ShaderLoading") << "GLSL Compilation Error:" << LL_ENDL;
- dumpObjectLog(ret, TRUE, filename);
-#if LL_WINDOWS
- std::stringstream ostr;
- //dump shader source for debugging
- for (GLuint i = 0; i < shader_code_count; i++)
- {
- ostr << i << ": " << shader_code_text[i];
- if (i % 128 == 0)
- { //dump every 128 lines
-
- LL_WARNS("ShaderLoading") << "\n" << ostr.str() << LL_ENDL;
- ostr = std::stringstream();
- }
-
- }
-
- LL_WARNS("ShaderLoading") << "\n" << ostr.str() << LL_ENDL;
-#else
- std::string str;
-
- for (GLuint i = 0; i < shader_code_count; i++) {
- str.append(shader_code_text[i]);
-
- if (i % 128 == 0)
- {
- LL_WARNS("ShaderLoading") << str << LL_ENDL;
- str = "";
- }
- }
-#endif
-
- ret = 0;
- }
+ error = glGetError();
+ if (error != GL_NO_ERROR || success == GL_FALSE)
+ {
+ //an error occured, print log
+ LL_WARNS("ShaderLoading") << "GLSL Compilation Error:" << LL_ENDL;
+ dumpObjectLog(ret, TRUE, open_file_name);
+ dumpShaderSource(shader_code_count, shader_code_text);
+ ret = 0;
}
}
else
@@ -949,7 +1021,12 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (ret)
{
// Add shader file to map
- mShaderObjects[filename] = ret;
+ if (type == GL_VERTEX_SHADER_ARB) {
+ mVertexShaderObjects[filename] = ret;
+ }
+ else if (type == GL_FRAGMENT_SHADER_ARB) {
+ mFragmentShaderObjects[filename] = ret;
+ }
shader_level = try_gpu_class;
}
else
@@ -957,7 +1034,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (shader_level > 1)
{
shader_level--;
- return loadShaderFile(filename,shader_level,type, defines, texture_index_channels);
+ return loadShaderFile(filename, shader_level, type, defines, texture_index_channels);
}
LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;
}
@@ -973,7 +1050,7 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
if (!suppress_errors && success == GL_FALSE)
{
//an error occured, print log
- LL_WARNS("ShaderLoading") << "GLSL Linker Error:" << LL_ENDL;
+ LL_SHADER_LOADING_WARNS() << "GLSL Linker Error:" << LL_ENDL;
}
#if LL_DARWIN
@@ -1006,7 +1083,7 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
CGLGetParameter(ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing);
if (!fragmentGPUProcessing || !vertexGPUProcessing)
{
- LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
+ LL_SHADER_LOADING_WARNS() << "GLSL Linker: Running in Software:" << LL_ENDL;
success = GL_FALSE;
suppress_errors = FALSE;
}
@@ -1017,7 +1094,7 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
LLStringUtil::toLower(log);
if (log.find("software") != std::string::npos)
{
- LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
+ LL_SHADER_LOADING_WARNS() << "GLSL Linker: Running in Software:" << LL_ENDL;
success = GL_FALSE;
suppress_errors = FALSE;
}
@@ -1033,7 +1110,7 @@ BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj)
glGetObjectParameterivARB(obj, GL_OBJECT_VALIDATE_STATUS_ARB, &success);
if (success == GL_FALSE)
{
- LL_WARNS("ShaderLoading") << "GLSL program not valid: " << LL_ENDL;
+ LL_SHADER_LOADING_WARNS() << "GLSL program not valid: " << LL_ENDL;
dumpObjectLog(obj);
}
else
@@ -1067,6 +1144,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");
@@ -1090,7 +1168,7 @@ void LLShaderMgr::initAttribsAndUniforms()
llassert(mReservedUniforms.size() == LLShaderMgr::MULTI_LIGHT_FAR_Z+1);
-
+ //NOTE: MUST match order in eGLSLReservedUniforms
mReservedUniforms.push_back("proj_mat");
mReservedUniforms.push_back("proj_near");
mReservedUniforms.push_back("proj_p");
@@ -1109,14 +1187,17 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("color");
mReservedUniforms.push_back("diffuseMap");
+ mReservedUniforms.push_back("altDiffuseMap");
mReservedUniforms.push_back("specularMap");
mReservedUniforms.push_back("bumpMap");
+ mReservedUniforms.push_back("bumpMap2");
mReservedUniforms.push_back("environmentMap");
- mReservedUniforms.push_back("cloude_noise_texture");
+ mReservedUniforms.push_back("cloud_noise_texture");
+ mReservedUniforms.push_back("cloud_noise_texture_next");
mReservedUniforms.push_back("fullbright");
mReservedUniforms.push_back("lightnorm");
- mReservedUniforms.push_back("sunlight_color_copy");
- mReservedUniforms.push_back("ambient");
+ mReservedUniforms.push_back("sunlight_color");
+ mReservedUniforms.push_back("ambient_color");
mReservedUniforms.push_back("blue_horizon");
mReservedUniforms.push_back("blue_density");
mReservedUniforms.push_back("haze_horizon");
@@ -1175,6 +1256,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("spot_shadow_bias");
mReservedUniforms.push_back("spot_shadow_offset");
mReservedUniforms.push_back("sun_dir");
+ mReservedUniforms.push_back("moon_dir");
mReservedUniforms.push_back("shadow_res");
mReservedUniforms.push_back("proj_shadow_res");
mReservedUniforms.push_back("depth_cutoff");
@@ -1217,8 +1299,6 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("bloomMap");
mReservedUniforms.push_back("projectionMap");
mReservedUniforms.push_back("norm_mat");
-
- mReservedUniforms.push_back("global_gamma");
mReservedUniforms.push_back("texture_gamma");
mReservedUniforms.push_back("specular_color");
@@ -1232,8 +1312,8 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("refTex");
mReservedUniforms.push_back("eyeVec");
mReservedUniforms.push_back("time");
- mReservedUniforms.push_back("d1");
- mReservedUniforms.push_back("d2");
+ mReservedUniforms.push_back("waveDir1");
+ mReservedUniforms.push_back("waveDir2");
mReservedUniforms.push_back("lightDir");
mReservedUniforms.push_back("specular");
mReservedUniforms.push_back("lightExp");
@@ -1265,6 +1345,34 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("origin");
mReservedUniforms.push_back("display_gamma");
+
+ mReservedUniforms.push_back("inscatter");
+ mReservedUniforms.push_back("sun_size");
+ mReservedUniforms.push_back("fog_color");
+
+ mReservedUniforms.push_back("transmittance_texture");
+ mReservedUniforms.push_back("scattering_texture");
+ mReservedUniforms.push_back("single_mie_scattering_texture");
+ mReservedUniforms.push_back("irradiance_texture");
+ mReservedUniforms.push_back("blend_factor");
+ mReservedUniforms.push_back("no_atmo");
+ mReservedUniforms.push_back("moisture_level");
+ mReservedUniforms.push_back("droplet_radius");
+ mReservedUniforms.push_back("ice_level");
+ mReservedUniforms.push_back("rainbow_map");
+ mReservedUniforms.push_back("halo_map");
+ mReservedUniforms.push_back("moon_brightness");
+ mReservedUniforms.push_back("cloud_variance");
+
+ mReservedUniforms.push_back("sh_input_r");
+ mReservedUniforms.push_back("sh_input_g");
+ mReservedUniforms.push_back("sh_input_b");
+
+ mReservedUniforms.push_back("sun_moon_glow_factor");
+ mReservedUniforms.push_back("water_edge");
+ mReservedUniforms.push_back("sun_up_factor");
+ mReservedUniforms.push_back("moonlight_color");
+
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
std::set<std::string> dupe_check;
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 394b38f832..3908efd4ec 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -36,188 +36,223 @@ public:
LLShaderMgr();
virtual ~LLShaderMgr();
- typedef enum
- {
- MODELVIEW_MATRIX = 0,
- PROJECTION_MATRIX,
- INVERSE_PROJECTION_MATRIX,
- MODELVIEW_PROJECTION_MATRIX,
- NORMAL_MATRIX,
- TEXTURE_MATRIX0,
- TEXTURE_MATRIX1,
- TEXTURE_MATRIX2,
- TEXTURE_MATRIX3,
- OBJECT_PLANE_S,
- OBJECT_PLANE_T,
- VIEWPORT,
- LIGHT_POSITION,
- LIGHT_DIRECTION,
- LIGHT_ATTENUATION,
- LIGHT_DIFFUSE,
- LIGHT_AMBIENT,
- MULTI_LIGHT_COUNT,
- MULTI_LIGHT,
- MULTI_LIGHT_COL,
- MULTI_LIGHT_FAR_Z,
- PROJECTOR_MATRIX,
- PROJECTOR_NEAR,
- PROJECTOR_P,
- PROJECTOR_N,
- PROJECTOR_ORIGIN,
- PROJECTOR_RANGE,
- PROJECTOR_AMBIANCE,
- PROJECTOR_SHADOW_INDEX,
- PROJECTOR_SHADOW_FADE,
- PROJECTOR_FOCUS,
- PROJECTOR_LOD,
- PROJECTOR_AMBIENT_LOD,
- DIFFUSE_COLOR,
- DIFFUSE_MAP,
- SPECULAR_MAP,
- BUMP_MAP,
- ENVIRONMENT_MAP,
- CLOUD_NOISE_MAP,
- FULLBRIGHT,
- LIGHTNORM,
- SUNLIGHT_COLOR,
- AMBIENT,
- BLUE_HORIZON,
- BLUE_DENSITY,
- HAZE_HORIZON,
- HAZE_DENSITY,
- CLOUD_SHADOW,
- DENSITY_MULTIPLIER,
- DISTANCE_MULTIPLIER,
- MAX_Y,
- GLOW,
- CLOUD_COLOR,
- CLOUD_POS_DENSITY1,
- CLOUD_POS_DENSITY2,
- CLOUD_SCALE,
- GAMMA,
- SCENE_LIGHT_STRENGTH,
- LIGHT_CENTER,
- LIGHT_SIZE,
- LIGHT_FALLOFF,
- BOX_CENTER,
- BOX_SIZE,
-
- GLOW_MIN_LUMINANCE,
- GLOW_MAX_EXTRACT_ALPHA,
- GLOW_LUM_WEIGHTS,
- GLOW_WARMTH_WEIGHTS,
- GLOW_WARMTH_AMOUNT,
- GLOW_STRENGTH,
- GLOW_DELTA,
-
- MINIMUM_ALPHA,
- EMISSIVE_BRIGHTNESS,
-
- DEFERRED_SHADOW_MATRIX,
- DEFERRED_ENV_MAT,
- DEFERRED_SHADOW_CLIP,
- DEFERRED_SUN_WASH,
- DEFERRED_SHADOW_NOISE,
- DEFERRED_BLUR_SIZE,
- DEFERRED_SSAO_RADIUS,
- DEFERRED_SSAO_MAX_RADIUS,
- DEFERRED_SSAO_FACTOR,
- DEFERRED_SSAO_FACTOR_INV,
- DEFERRED_SSAO_EFFECT_MAT,
- DEFERRED_SCREEN_RES,
- DEFERRED_NEAR_CLIP,
- DEFERRED_SHADOW_OFFSET,
- DEFERRED_SHADOW_BIAS,
- DEFERRED_SPOT_SHADOW_BIAS,
- DEFERRED_SPOT_SHADOW_OFFSET,
- DEFERRED_SUN_DIR,
- DEFERRED_SHADOW_RES,
- DEFERRED_PROJ_SHADOW_RES,
- DEFERRED_DEPTH_CUTOFF,
- DEFERRED_NORM_CUTOFF,
- DEFERRED_SHADOW_TARGET_WIDTH,
-
- FXAA_TC_SCALE,
- FXAA_RCP_SCREEN_RES,
- FXAA_RCP_FRAME_OPT,
- FXAA_RCP_FRAME_OPT2,
-
- DOF_FOCAL_DISTANCE,
- DOF_BLUR_CONSTANT,
- DOF_TAN_PIXEL_ANGLE,
- DOF_MAGNIFICATION,
- DOF_MAX_COF,
- DOF_RES_SCALE,
- DOF_WIDTH,
- DOF_HEIGHT,
-
- DEFERRED_DEPTH,
- DEFERRED_SHADOW0,
- DEFERRED_SHADOW1,
- DEFERRED_SHADOW2,
- DEFERRED_SHADOW3,
- DEFERRED_SHADOW4,
- DEFERRED_SHADOW5,
- DEFERRED_NORMAL,
- DEFERRED_POSITION,
- DEFERRED_DIFFUSE,
- DEFERRED_SPECULAR,
- DEFERRED_NOISE,
- DEFERRED_LIGHTFUNC,
- DEFERRED_LIGHT,
- DEFERRED_BLOOM,
- DEFERRED_PROJECTION,
- DEFERRED_NORM_MATRIX,
-
- GLOBAL_GAMMA,
- TEXTURE_GAMMA,
-
- SPECULAR_COLOR,
- ENVIRONMENT_INTENSITY,
-
- AVATAR_MATRIX,
- AVATAR_TRANSLATION,
-
- WATER_SCREENTEX,
- WATER_SCREENDEPTH,
- WATER_REFTEX,
- WATER_EYEVEC,
- WATER_TIME,
- WATER_WAVE_DIR1,
- WATER_WAVE_DIR2,
- WATER_LIGHT_DIR,
- WATER_SPECULAR,
- WATER_SPECULAR_EXP,
- WATER_FOGCOLOR,
- WATER_FOGDENSITY,
- WATER_FOGKS,
- WATER_REFSCALE,
- WATER_WATERHEIGHT,
- WATER_WATERPLANE,
- WATER_NORM_SCALE,
- WATER_FRESNEL_SCALE,
- WATER_FRESNEL_OFFSET,
- WATER_BLUR_MULTIPLIER,
- WATER_SUN_ANGLE,
- WATER_SCALED_ANGLE,
- WATER_SUN_ANGLE2,
-
- WL_CAMPOSLOCAL,
-
- AVATAR_WIND,
- AVATAR_SINWAVE,
- AVATAR_GRAVITY,
-
- TERRAIN_DETAIL0,
- TERRAIN_DETAIL1,
- TERRAIN_DETAIL2,
- TERRAIN_DETAIL3,
- TERRAIN_ALPHARAMP,
-
- SHINY_ORIGIN,
-DISPLAY_GAMMA,
- END_RESERVED_UNIFORMS
- } eGLSLReservedUniforms;
+ // clang-format off
+ typedef enum
+ { // Shader uniform name, set in LLShaderMgr::initAttribsAndUniforms()
+ MODELVIEW_MATRIX = 0, // "modelview_matrix"
+ PROJECTION_MATRIX, // "projection_matrix"
+ INVERSE_PROJECTION_MATRIX, // "inv_proj"
+ MODELVIEW_PROJECTION_MATRIX, // "modelview_projection_matrix"
+ INVERSE_MODELVIEW_MATRIX, // "inv_modelview"
+ NORMAL_MATRIX, // "normal_matrix"
+ TEXTURE_MATRIX0, // "texture_matrix0"
+ TEXTURE_MATRIX1, // "texture_matrix1"
+ TEXTURE_MATRIX2, // "texture_matrix2"
+ TEXTURE_MATRIX3, // "texture_matrix3"
+ OBJECT_PLANE_S, // "object_plane_s"
+ OBJECT_PLANE_T, // "object_plane_t"
+ VIEWPORT, // "viewport"
+ LIGHT_POSITION, // "light_position"
+ LIGHT_DIRECTION, // "light_direction"
+ LIGHT_ATTENUATION, // "light_attenuation"
+ LIGHT_DIFFUSE, // "light_diffuse"
+ LIGHT_AMBIENT, // "light_ambient"
+ MULTI_LIGHT_COUNT, // "light_count"
+ MULTI_LIGHT, // "light"
+ MULTI_LIGHT_COL, // "light_col"
+ MULTI_LIGHT_FAR_Z, // "far_z"
+ PROJECTOR_MATRIX, // "proj_mat"
+ PROJECTOR_NEAR, // "proj_near"
+ PROJECTOR_P, // "proj_p"
+ PROJECTOR_N, // "proj_n"
+ PROJECTOR_ORIGIN, // "proj_origin"
+ PROJECTOR_RANGE, // "proj_range"
+ PROJECTOR_AMBIANCE, // "proj_ambiance"
+ PROJECTOR_SHADOW_INDEX, // "proj_shadow_idx"
+ PROJECTOR_SHADOW_FADE, // "shadow_fade"
+ PROJECTOR_FOCUS, // "proj_focus"
+ PROJECTOR_LOD, // "proj_lod"
+ PROJECTOR_AMBIENT_LOD, // "proj_ambient_lod"
+ DIFFUSE_COLOR, // "color"
+ DIFFUSE_MAP, // "diffuseMap"
+ ALTERNATE_DIFFUSE_MAP, // "altDiffuseMap"
+ SPECULAR_MAP, // "specularMap"
+ BUMP_MAP, // "bumpMap"
+ BUMP_MAP2, // "bumpMap2"
+ ENVIRONMENT_MAP, // "environmentMap"
+ CLOUD_NOISE_MAP, // "cloud_noise_texture"
+ CLOUD_NOISE_MAP_NEXT, // "cloud_noise_texture_next"
+ FULLBRIGHT, // "fullbright"
+ LIGHTNORM, // "lightnorm"
+ SUNLIGHT_COLOR, // "sunlight_color"
+ AMBIENT, // "ambient_color"
+ BLUE_HORIZON, // "blue_horizon"
+ BLUE_DENSITY, // "blue_density"
+ HAZE_HORIZON, // "haze_horizon"
+ HAZE_DENSITY, // "haze_density"
+ CLOUD_SHADOW, // "cloud_shadow"
+ DENSITY_MULTIPLIER, // "density_multiplier"
+ DISTANCE_MULTIPLIER, // "distance_multiplier"
+ MAX_Y, // "max_y"
+ GLOW, // "glow"
+ CLOUD_COLOR, // "cloud_color"
+ CLOUD_POS_DENSITY1, // "cloud_pos_density1"
+ CLOUD_POS_DENSITY2, // "cloud_pos_density2"
+ CLOUD_SCALE, // "cloud_scale"
+ GAMMA, // "gamma"
+ SCENE_LIGHT_STRENGTH, // "scene_light_strength"
+ LIGHT_CENTER, // "center"
+ LIGHT_SIZE, // "size"
+ LIGHT_FALLOFF, // "falloff"
+ BOX_CENTER, // "box_center"
+ BOX_SIZE, // "box_size"
+
+ GLOW_MIN_LUMINANCE, // "minLuminance"
+ GLOW_MAX_EXTRACT_ALPHA, // "maxExtractAlpha"
+ GLOW_LUM_WEIGHTS, // "lumWeights"
+ GLOW_WARMTH_WEIGHTS, // "warmthWeights"
+ GLOW_WARMTH_AMOUNT, // "warmthAmount"
+ GLOW_STRENGTH, // "glowStrength"
+ GLOW_DELTA, // "glowDelta"
+
+ MINIMUM_ALPHA, // "minimum_alpha"
+ EMISSIVE_BRIGHTNESS, // "emissive_brightness"
+
+ DEFERRED_SHADOW_MATRIX, // "shadow_matrix"
+ DEFERRED_ENV_MAT, // "env_mat"
+ DEFERRED_SHADOW_CLIP, // "shadow_clip"
+ DEFERRED_SUN_WASH, // "sun_wash"
+ DEFERRED_SHADOW_NOISE, // "shadow_noise"
+ DEFERRED_BLUR_SIZE, // "blur_size"
+ DEFERRED_SSAO_RADIUS, // "ssao_radius"
+ DEFERRED_SSAO_MAX_RADIUS, // "ssao_max_radius"
+ DEFERRED_SSAO_FACTOR, // "ssao_factor"
+ DEFERRED_SSAO_FACTOR_INV, // "ssao_factor_inv"
+ DEFERRED_SSAO_EFFECT_MAT, // "ssao_effect_mat"
+ DEFERRED_SCREEN_RES, // "screen_res"
+ DEFERRED_NEAR_CLIP, // "near_clip"
+ DEFERRED_SHADOW_OFFSET, // "shadow_offset"
+ DEFERRED_SHADOW_BIAS, // "shadow_bias"
+ DEFERRED_SPOT_SHADOW_BIAS, // "spot_shadow_bias"
+ DEFERRED_SPOT_SHADOW_OFFSET, // "spot_shadow_offset"
+ DEFERRED_SUN_DIR, // "sun_dir"
+ DEFERRED_MOON_DIR, // "moon_dir"
+ DEFERRED_SHADOW_RES, // "shadow_res"
+ DEFERRED_PROJ_SHADOW_RES, // "proj_shadow_res"
+ DEFERRED_DEPTH_CUTOFF, // "depth_cutoff"
+ DEFERRED_NORM_CUTOFF, // "norm_cutoff"
+ DEFERRED_SHADOW_TARGET_WIDTH, // "shadow_target_width"
+
+ FXAA_TC_SCALE, // "tc_scale"
+ FXAA_RCP_SCREEN_RES, // "rcp_screen_res"
+ FXAA_RCP_FRAME_OPT, // "rcp_frame_opt"
+ FXAA_RCP_FRAME_OPT2, // "rcp_frame_opt2"
+
+ DOF_FOCAL_DISTANCE, // "focal_distance"
+ DOF_BLUR_CONSTANT, // "blur_constant"
+ DOF_TAN_PIXEL_ANGLE, // "tan_pixel_angle"
+ DOF_MAGNIFICATION, // "magnification"
+ DOF_MAX_COF, // "max_cof"
+ DOF_RES_SCALE, // "res_scale"
+ DOF_WIDTH, // "dof_width"
+ DOF_HEIGHT, // "dof_height"
+
+ DEFERRED_DEPTH, // "depthMap"
+ DEFERRED_SHADOW0, // "shadowMap0"
+ DEFERRED_SHADOW1, // "shadowMap1"
+ DEFERRED_SHADOW2, // "shadowMap2"
+ DEFERRED_SHADOW3, // "shadowMap3"
+ DEFERRED_SHADOW4, // "shadowMap4"
+ DEFERRED_SHADOW5, // "shadowMap5"
+ DEFERRED_NORMAL, // "normalMap"
+ DEFERRED_POSITION, // "positionMap"
+ DEFERRED_DIFFUSE, // "diffuseRect"
+ DEFERRED_SPECULAR, // "specularRect"
+ DEFERRED_NOISE, // "noiseMap"
+ DEFERRED_LIGHTFUNC, // "lightFunc"
+ DEFERRED_LIGHT, // "lightMap"
+ DEFERRED_BLOOM, // "bloomMap"
+ DEFERRED_PROJECTION, // "projectionMap"
+ DEFERRED_NORM_MATRIX, // "norm_mat"
+ TEXTURE_GAMMA, // "texture_gamma"
+ SPECULAR_COLOR, // "specular_color"
+ ENVIRONMENT_INTENSITY, // "env_intensity"
+
+ AVATAR_MATRIX, // "matrixPalette"
+ AVATAR_TRANSLATION, // "translationPalette"
+
+ WATER_SCREENTEX, // "screenTex"
+ WATER_SCREENDEPTH, // "screenDepth"
+ WATER_REFTEX, // "refTex"
+ WATER_EYEVEC, // "eyeVec"
+ WATER_TIME, // "time"
+ WATER_WAVE_DIR1, // "waveDir1"
+ WATER_WAVE_DIR2, // "waveDir2"
+ WATER_LIGHT_DIR, // "lightDir"
+ WATER_SPECULAR, // "specular"
+ WATER_SPECULAR_EXP, // "lightExp"
+ WATER_FOGCOLOR, // "waterFogColor"
+ WATER_FOGDENSITY, // "waterFogDensity"
+ WATER_FOGKS, // "waterFogKS"
+ WATER_REFSCALE, // "refScale"
+ WATER_WATERHEIGHT, // "waterHeight"
+ WATER_WATERPLANE, // "waterPlane"
+ WATER_NORM_SCALE, // "normScale"
+ WATER_FRESNEL_SCALE, // "fresnelScale"
+ WATER_FRESNEL_OFFSET, // "fresnelOffset"
+ WATER_BLUR_MULTIPLIER, // "blurMultiplier"
+ WATER_SUN_ANGLE, // "sunAngle"
+ WATER_SCALED_ANGLE, // "scaledAngle"
+ WATER_SUN_ANGLE2, // "sunAngle2"
+
+ WL_CAMPOSLOCAL, // "camPosLocal"
+
+ AVATAR_WIND, // "gWindDir"
+ AVATAR_SINWAVE, // "gSinWaveParams"
+ AVATAR_GRAVITY, // "gGravity"
+
+ TERRAIN_DETAIL0, // "detail_0"
+ TERRAIN_DETAIL1, // "detail_1"
+ TERRAIN_DETAIL2, // "detail_2"
+ TERRAIN_DETAIL3, // "detail_3"
+ TERRAIN_ALPHARAMP, // "alpha_ramp"
+
+ SHINY_ORIGIN, // "origin"
+ DISPLAY_GAMMA, // "display_gamma"
+
+ INSCATTER_RT, // "inscatter"
+ SUN_SIZE, // "sun_size"
+ FOG_COLOR, // "fog_color"
+
+ // precomputed textures
+ TRANSMITTANCE_TEX, // "transmittance_texture"
+ SCATTER_TEX, // "scattering_texture"
+ SINGLE_MIE_SCATTER_TEX, // "single_mie_scattering_texture"
+ ILLUMINANCE_TEX, // "irradiance_texture"
+ BLEND_FACTOR, // "blend_factor"
+
+ NO_ATMO, // "no_atmo"
+ MOISTURE_LEVEL, // "moisture_level"
+ DROPLET_RADIUS, // "droplet_radius"
+ ICE_LEVEL, // "ice_level"
+ RAINBOW_MAP, // "rainbow_map"
+ HALO_MAP, // "halo_map"
+
+ MOON_BRIGHTNESS, // "moon_brightness"
+
+ CLOUD_VARIANCE, // "cloud_variance"
+
+ SH_INPUT_L1R, // "sh_input_r"
+ SH_INPUT_L1G, // "sh_input_g"
+ SH_INPUT_L1B, // "sh_input_b"
+
+ SUN_MOON_GLOW_FACTOR, // "sun_moon_glow_factor"
+ WATER_EDGE_FACTOR, // "water_edge"
+ SUN_UP_FACTOR, // "sun_up_factor"
+ MOONLIGHT_COLOR, // "moonlight_color"
+ END_RESERVED_UNIFORMS
+ } eGLSLReservedUniforms;
+ // clang-format on
// singleton pattern implementation
static LLShaderMgr * instance();
@@ -226,6 +261,7 @@ DISPLAY_GAMMA,
BOOL attachShaderFeatures(LLGLSLShader * shader);
void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE, const std::string& filename = "");
+ void dumpShaderSource(U32 shader_code_count, GLcharARB** shader_code_text);
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
BOOL validateProgramObject(GLhandleARB obj);
GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1);
@@ -238,7 +274,8 @@ DISPLAY_GAMMA,
public:
// Map of shader names to compiled
- std::map<std::string, GLhandleARB> mShaderObjects;
+ std::map<std::string, GLhandleARB> mVertexShaderObjects;
+ std::map<std::string, GLhandleARB> mFragmentShaderObjects;
//global (reserved slot) shader parameters
std::vector<std::string> mReservedAttribs;
diff --git a/indra/llrender/lltexture.cpp b/indra/llrender/lltexture.cpp
index 90fbcec2be..6eef36216c 100644
--- a/indra/llrender/lltexture.cpp
+++ b/indra/llrender/lltexture.cpp
@@ -29,3 +29,15 @@
LLTexture::~LLTexture()
{
}
+
+S8 LLTexture::getType() const { llassert(false); return 0; }
+void LLTexture::setKnownDrawSize(S32 width, S32 height) { llassert(false); }
+bool LLTexture::bindDefaultImage(const S32 stage) { llassert(false); return false; }
+bool LLTexture::bindDebugImage(const S32 stage) { llassert(false); return false; }
+void LLTexture::forceImmediateUpdate() { llassert(false); }
+void LLTexture::setActive() { llassert(false); }
+S32 LLTexture::getWidth(S32 discard_level) const { llassert(false); return 0; }
+S32 LLTexture::getHeight(S32 discard_level) const { llassert(false); return 0; }
+bool LLTexture::isActiveFetching() { llassert(false); return false; }
+LLImageGL* LLTexture::getGLTexture() const { llassert(false); return nullptr; }
+void LLTexture::updateBindStatsForTester() { }
diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h
index 9fca8b8cd3..41481fb8a7 100644
--- a/indra/llrender/lltexture.h
+++ b/indra/llrender/lltexture.h
@@ -58,21 +58,21 @@ public:
//
//interfaces to access LLGLTexture
//
- virtual S8 getType() const = 0 ;
- virtual void setKnownDrawSize(S32 width, S32 height) = 0 ;
- virtual bool bindDefaultImage(const S32 stage = 0) = 0 ;
- virtual bool bindDebugImage(const S32 stage = 0) = 0;
- virtual void forceImmediateUpdate() = 0 ;
- virtual void setActive() = 0 ;
- virtual S32 getWidth(S32 discard_level = -1) const = 0 ;
- virtual S32 getHeight(S32 discard_level = -1) const = 0 ;
- virtual bool isActiveFetching() = 0;
+ virtual S8 getType() const;
+ virtual void setKnownDrawSize(S32 width, S32 height);
+ virtual bool bindDefaultImage(const S32 stage = 0);
+ virtual bool bindDebugImage(const S32 stage = 0);
+ virtual void forceImmediateUpdate();
+ virtual void setActive();
+ virtual S32 getWidth(S32 discard_level = -1) const;
+ virtual S32 getHeight(S32 discard_level = -1) const;
+ virtual bool isActiveFetching();
private:
//note: do not make this function public.
- virtual LLImageGL* getGLTexture() const = 0 ;
+ virtual LLImageGL* getGLTexture() const;
- virtual void updateBindStatsForTester() = 0 ;
+ virtual void updateBindStatsForTester();
};
#endif
diff --git a/indra/llrender/lluiimage.cpp b/indra/llrender/lluiimage.cpp
index 5d8f92b2e6..424672fe8e 100644
--- a/indra/llrender/lluiimage.cpp
+++ b/indra/llrender/lluiimage.cpp
@@ -31,7 +31,6 @@
// Project includes
#include "lluiimage.h"
-#include "llrender2dutils.h"
LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
: mName(name),
@@ -39,67 +38,29 @@ LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
mScaleRegion(0.f, 1.f, 1.f, 0.f),
mClipRegion(0.f, 1.f, 1.f, 0.f),
mImageLoaded(NULL),
- mScaleStyle(SCALE_INNER)
-{}
+ mScaleStyle(SCALE_INNER),
+ mCachedW(-1),
+ mCachedH(-1)
+{
+ getTextureWidth();
+ getTextureHeight();
+}
LLUIImage::~LLUIImage()
{
delete mImageLoaded;
}
-void LLUIImage::setClipRegion(const LLRectf& region)
+S32 LLUIImage::getWidth() const
{
- mClipRegion = region;
+ // return clipped dimensions of actual image area
+ return ll_round((F32)mImage->getWidth(0) * mClipRegion.getWidth());
}
-void LLUIImage::setScaleRegion(const LLRectf& region)
+S32 LLUIImage::getHeight() const
{
- mScaleRegion = region;
-}
-
-void LLUIImage::setScaleStyle(LLUIImage::EScaleStyle style)
-{
- mScaleStyle = style;
-}
-
-//TODO: move drawing implementation inside class
-void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const
-{
- draw(x, y, getWidth(), getHeight(), color);
-}
-
-void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
-{
- gl_draw_scaled_image_with_border(
- x, y,
- width, height,
- mImage,
- color,
- FALSE,
- mClipRegion,
- mScaleRegion,
- mScaleStyle == SCALE_INNER);
-}
-
-void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
-{
- gl_draw_scaled_image_with_border(
- x, y,
- width, height,
- mImage,
- color,
- TRUE,
- mClipRegion,
- mScaleRegion,
- mScaleStyle == SCALE_INNER);
-}
-
-void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const
-{
- LLRect border_rect;
- border_rect.setOriginAndSize(x, y, width, height);
- border_rect.stretch(border_width, border_width);
- drawSolid(border_rect, color);
+ // return clipped dimensions of actual image area
+ return ll_round((F32)mImage->getHeight(0) * mClipRegion.getHeight());
}
void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis,
@@ -120,12 +81,12 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c
}
}
- LLRender2D::pushMatrix();
+ LLRender2D::getInstance()->pushMatrix();
{
LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis);
- LLRender2D::translate(rect_origin.mV[VX],
- rect_origin.mV[VY],
- rect_origin.mV[VZ]);
+ LLRender2D::getInstance()->translate(rect_origin.mV[VX],
+ rect_origin.mV[VY],
+ rect_origin.mV[VZ]);
gGL.getTexUnit(0)->bind(getImage());
gGL.color4fv(color.mV);
@@ -142,31 +103,10 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c
rect.getWidth() * x_axis,
rect.getHeight() * y_axis);
- } LLRender2D::popMatrix();
+ } LLRender2D::getInstance()->popMatrix();
}
-
-S32 LLUIImage::getWidth() const
-{
- // return clipped dimensions of actual image area
- return ll_round((F32)mImage->getWidth(0) * mClipRegion.getWidth());
-}
-
-S32 LLUIImage::getHeight() const
-{
- // return clipped dimensions of actual image area
- return ll_round((F32)mImage->getHeight(0) * mClipRegion.getHeight());
-}
-
-S32 LLUIImage::getTextureWidth() const
-{
- return mImage->getWidth(0);
-}
-
-S32 LLUIImage::getTextureHeight() const
-{
- return mImage->getHeight(0);
-}
+//#include "lluiimage.inl"
boost::signals2::connection LLUIImage::addLoadedCallback( const image_loaded_signal_t::slot_type& cb )
{
@@ -186,7 +126,6 @@ void LLUIImage::onImageLoaded()
}
}
-
namespace LLInitParam
{
void ParamValue<LLUIImage*>::updateValueFromBlock()
@@ -199,7 +138,7 @@ namespace LLInitParam
return;
}
- LLUIImage* imagep = LLRender2D::getUIImage(name());
+ LLUIImage* imagep = LLRender2D::getInstance()->getUIImage(name());
if (imagep)
{
updateValue(imagep);
diff --git a/indra/llrender/lluiimage.h b/indra/llrender/lluiimage.h
index 6f47385eb0..e462e19004 100644
--- a/indra/llrender/lluiimage.h
+++ b/indra/llrender/lluiimage.h
@@ -36,6 +36,7 @@
#include <boost/signals2.hpp>
#include "llinitparam.h"
#include "lltexture.h"
+#include "llrender2dutils.h"
extern const LLColor4 UI_VERTEX_COLOR;
@@ -53,35 +54,46 @@ public:
LLUIImage(const std::string& name, LLPointer<LLTexture> image);
virtual ~LLUIImage();
- void setClipRegion(const LLRectf& region);
- void setScaleRegion(const LLRectf& region);
- void setScaleStyle(EScaleStyle style);
+ LL_FORCE_INLINE void setClipRegion(const LLRectf& region)
+ {
+ mClipRegion = region;
+ }
- LLPointer<LLTexture> getImage() { return mImage; }
- const LLPointer<LLTexture>& getImage() const { return mImage; }
+ LL_FORCE_INLINE void setScaleRegion(const LLRectf& region)
+ {
+ mScaleRegion = region;
+ }
- void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const;
- void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const;
- void draw(const LLRect& rect, const LLColor4& color = UI_VERTEX_COLOR) const { draw(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
+ LL_FORCE_INLINE void setScaleStyle(EScaleStyle style)
+ {
+ mScaleStyle = style;
+ }
+
+ LL_FORCE_INLINE LLPointer<LLTexture> getImage() { return mImage; }
+ LL_FORCE_INLINE const LLPointer<LLTexture>& getImage() const { return mImage; }
+
+ LL_FORCE_INLINE void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const;
+ LL_FORCE_INLINE void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const;
+ LL_FORCE_INLINE void draw(const LLRect& rect, const LLColor4& color = UI_VERTEX_COLOR) const { draw(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
- void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const;
- void drawSolid(const LLRect& rect, const LLColor4& color) const { drawSolid(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
- void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, getWidth(), getHeight(), color); }
+ LL_FORCE_INLINE void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const;
+ LL_FORCE_INLINE void drawSolid(const LLRect& rect, const LLColor4& color) const { drawSolid(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
+ LL_FORCE_INLINE void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, getWidth(), getHeight(), color); }
- void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
- void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
- void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); }
+ LL_FORCE_INLINE void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
+ LL_FORCE_INLINE void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
+ LL_FORCE_INLINE void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); }
void draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis, const LLRect& rect, const LLColor4& color);
- const std::string& getName() const { return mName; }
+ LL_FORCE_INLINE const std::string& getName() const { return mName; }
virtual S32 getWidth() const;
virtual S32 getHeight() const;
// returns dimensions of underlying textures, which might not be equal to ui image portion
- S32 getTextureWidth() const;
- S32 getTextureHeight() const;
+ LL_FORCE_INLINE S32 getTextureWidth() const;
+ LL_FORCE_INLINE S32 getTextureHeight() const;
boost::signals2::connection addLoadedCallback( const image_loaded_signal_t::slot_type& cb );
@@ -95,8 +107,12 @@ protected:
LLRectf mClipRegion;
LLPointer<LLTexture> mImage;
EScaleStyle mScaleStyle;
+ mutable S32 mCachedW;
+ mutable S32 mCachedH;
};
+#include "lluiimage.inl"
+
namespace LLInitParam
{
template<>
diff --git a/indra/llrender/lluiimage.inl b/indra/llrender/lluiimage.inl
new file mode 100644
index 0000000000..f5227556f0
--- /dev/null
+++ b/indra/llrender/lluiimage.inl
@@ -0,0 +1,77 @@
+/**
+ * @file lluiimage.inl
+ * @brief UI inline func implementation
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const
+{
+ draw(x, y, getWidth(), getHeight(), color);
+}
+
+void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
+{
+ gl_draw_scaled_image_with_border(
+ x, y,
+ width, height,
+ mImage,
+ color,
+ FALSE,
+ mClipRegion,
+ mScaleRegion,
+ mScaleStyle == SCALE_INNER);
+}
+
+void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
+{
+ gl_draw_scaled_image_with_border(
+ x, y,
+ width, height,
+ mImage,
+ color,
+ TRUE,
+ mClipRegion,
+ mScaleRegion,
+ mScaleStyle == SCALE_INNER);
+}
+
+void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const
+{
+ LLRect border_rect;
+ border_rect.setOriginAndSize(x, y, width, height);
+ border_rect.stretch(border_width, border_width);
+ drawSolid(border_rect, color);
+}
+
+// returns dimensions of underlying textures, which might not be equal to ui image portion
+S32 LLUIImage::getTextureWidth() const
+{
+ mCachedW = (mCachedW == -1) ? getWidth() : mCachedW;
+ return mCachedW;
+}
+
+S32 LLUIImage::getTextureHeight() const
+{
+ mCachedH = (mCachedH == -1) ? getHeight() : mCachedH;
+ return mCachedH;
+}
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 1312f6afda..7d2b09ca4a 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -660,6 +660,9 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto
void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
{
+ llassert(start < (U32)mNumVerts);
+ llassert(end < (U32)mNumVerts);
+
if (start >= (U32) mNumVerts ||
end >= (U32) mNumVerts)
{
@@ -679,6 +682,9 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
U16* idx = ((U16*) getIndicesPointer())+indices_offset;
for (U32 i = 0; i < count; ++i)
{
+ llassert(idx[i] >= start);
+ llassert(idx[i] <= end);
+
if (idx[i] < start || idx[i] > end)
{
LL_ERRS() << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << LL_ENDL;
@@ -697,6 +703,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
for (U32 i = start; i < end; i++)
{
S32 idx = (S32) (v[i][3]+0.25f);
+ llassert(idx >= 0);
if (idx < 0 || idx >= shader->mFeatures.mIndexedTextureChannels)
{
LL_ERRS() << "Bad texture index found in vertex data stream." << LL_ENDL;
@@ -942,15 +949,15 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
if (ret_usage != GL_DYNAMIC_COPY_ARB)
{
- if (sDisableVBOMapping)
- { //always use stream draw if VBO mapping is disabled
- ret_usage = GL_STREAM_DRAW_ARB;
- }
- else
- {
- ret_usage = GL_DYNAMIC_DRAW_ARB;
- }
- }
+ if (sDisableVBOMapping)
+ { //always use stream draw if VBO mapping is disabled
+ ret_usage = GL_STREAM_DRAW_ARB;
+ }
+ else
+ {
+ ret_usage = GL_DYNAMIC_DRAW_ARB;
+ }
+ }
}
return ret_usage;
@@ -1186,7 +1193,7 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
return true;
}
- bool sucsess = true;
+ bool success = true;
mEmpty = true;
@@ -1208,9 +1215,9 @@ bool LLVertexBuffer::createGLBuffer(U32 size)
if (!mMappedData)
{
- sucsess = false;
+ success = false;
}
- return sucsess;
+ return success;
}
bool LLVertexBuffer::createGLIndices(U32 size)
@@ -1225,7 +1232,7 @@ bool LLVertexBuffer::createGLIndices(U32 size)
return true;
}
- bool sucsess = true;
+ bool success = true;
mEmpty = true;
@@ -1250,9 +1257,9 @@ bool LLVertexBuffer::createGLIndices(U32 size)
if (!mMappedIndexData)
{
- sucsess = false;
+ success = false;
}
- return sucsess;
+ return success;
}
void LLVertexBuffer::destroyGLBuffer()
@@ -1299,7 +1306,7 @@ bool LLVertexBuffer::updateNumVerts(S32 nverts)
{
llassert(nverts >= 0);
- bool sucsess = true;
+ bool success = true;
if (nverts > 65536)
{
@@ -1311,34 +1318,34 @@ bool LLVertexBuffer::updateNumVerts(S32 nverts)
if (needed_size > mSize || needed_size <= mSize/2)
{
- sucsess &= createGLBuffer(needed_size);
+ success &= createGLBuffer(needed_size);
}
sVertexCount -= mNumVerts;
mNumVerts = nverts;
sVertexCount += mNumVerts;
- return sucsess;
+ return success;
}
bool LLVertexBuffer::updateNumIndices(S32 nindices)
{
llassert(nindices >= 0);
- bool sucsess = true;
+ bool success = true;
U32 needed_size = sizeof(U16) * nindices;
if (needed_size > mIndicesSize || needed_size <= mIndicesSize/2)
{
- sucsess &= createGLIndices(needed_size);
+ success &= createGLIndices(needed_size);
}
sIndexCount -= mNumIndices;
mNumIndices = nindices;
sIndexCount += mNumIndices;
- return sucsess;
+ return success;
}
bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
@@ -1351,10 +1358,10 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
LL_ERRS() << "Bad vertex buffer allocation: " << nverts << " : " << nindices << LL_ENDL;
}
- bool sucsess = true;
+ bool success = true;
- sucsess &= updateNumVerts(nverts);
- sucsess &= updateNumIndices(nindices);
+ success &= updateNumVerts(nverts);
+ success &= updateNumIndices(nindices);
if (create && (nverts || nindices))
{
@@ -1370,7 +1377,7 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
}
}
- return sucsess;
+ return success;
}
static LLTrace::BlockTimerStatHandle FTM_SETUP_VERTEX_ARRAY("Setup VAO");
@@ -1471,7 +1478,12 @@ void LLVertexBuffer::setupVertexArray()
//glVertexattribIPointer requires GLSL 1.30 or later
if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
{
- glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], (const GLvoid*) mOffsets[i]);
+ // nat 2018-10-24: VS 2017 also notices the issue
+ // described below, and warns even with reinterpret_cast.
+ // Cast via intptr_t to make it painfully obvious to the
+ // compiler that we're doing this intentionally.
+ glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i],
+ reinterpret_cast<const GLvoid*>(intptr_t(mOffsets[i])));
}
#endif
}
@@ -1486,7 +1498,7 @@ void LLVertexBuffer::setupVertexArray()
// rather than as an actual pointer, so it's okay.
glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i],
attrib_normalized[i], sTypeSize[i],
- reinterpret_cast<GLvoid*>(mOffsets[i]));
+ reinterpret_cast<GLvoid*>(intptr_t(mOffsets[i])));
}
}
else
@@ -1506,10 +1518,10 @@ bool LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
llassert(newnverts >= 0);
llassert(newnindices >= 0);
- bool sucsess = true;
+ bool success = true;
- sucsess &= updateNumVerts(newnverts);
- sucsess &= updateNumIndices(newnindices);
+ success &= updateNumVerts(newnverts);
+ success &= updateNumIndices(newnindices);
if (useVBOs())
{
@@ -1521,7 +1533,7 @@ bool LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
}
}
- return sucsess;
+ return success;
}
bool LLVertexBuffer::useVBOs() const
@@ -2319,34 +2331,35 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{
U32 unsatisfied_mask = (required_mask & ~data_mask);
- U32 i = 0;
- while (i < TYPE_MAX)
- {
+ for (U32 i = 0; i < TYPE_MAX; i++)
+ {
U32 unsatisfied_flag = unsatisfied_mask & (1 << i);
- switch (unsatisfied_flag)
- {
- case MAP_VERTEX: LL_INFOS() << "Missing vert pos" << LL_ENDL; break;
- case MAP_NORMAL: LL_INFOS() << "Missing normals" << LL_ENDL; break;
- case MAP_TEXCOORD0: LL_INFOS() << "Missing TC 0" << LL_ENDL; break;
- case MAP_TEXCOORD1: LL_INFOS() << "Missing TC 1" << LL_ENDL; break;
- case MAP_TEXCOORD2: LL_INFOS() << "Missing TC 2" << LL_ENDL; break;
- case MAP_TEXCOORD3: LL_INFOS() << "Missing TC 3" << LL_ENDL; break;
- case MAP_COLOR: LL_INFOS() << "Missing vert color" << LL_ENDL; break;
- case MAP_EMISSIVE: LL_INFOS() << "Missing emissive" << LL_ENDL; break;
- case MAP_TANGENT: LL_INFOS() << "Missing tangent" << LL_ENDL; break;
- case MAP_WEIGHT: LL_INFOS() << "Missing weight" << LL_ENDL; break;
- case MAP_WEIGHT4: LL_INFOS() << "Missing weightx4" << LL_ENDL; break;
- case MAP_CLOTHWEIGHT: LL_INFOS() << "Missing clothweight" << LL_ENDL; break;
- case MAP_TEXTURE_INDEX: LL_INFOS() << "Missing tex index" << LL_ENDL; break;
- default: LL_INFOS() << "Missing who effin knows: " << unsatisfied_flag << LL_ENDL;
- }
- }
-
- if (unsatisfied_mask & (1 << TYPE_INDEX))
- {
- LL_INFOS() << "Missing indices" << LL_ENDL;
- }
+ switch (unsatisfied_flag)
+ {
+ case 0: break;
+ case MAP_VERTEX: LL_INFOS() << "Missing vert pos" << LL_ENDL; break;
+ case MAP_NORMAL: LL_INFOS() << "Missing normals" << LL_ENDL; break;
+ case MAP_TEXCOORD0: LL_INFOS() << "Missing TC 0" << LL_ENDL; break;
+ case MAP_TEXCOORD1: LL_INFOS() << "Missing TC 1" << LL_ENDL; break;
+ case MAP_TEXCOORD2: LL_INFOS() << "Missing TC 2" << LL_ENDL; break;
+ case MAP_TEXCOORD3: LL_INFOS() << "Missing TC 3" << LL_ENDL; break;
+ case MAP_COLOR: LL_INFOS() << "Missing vert color" << LL_ENDL; break;
+ case MAP_EMISSIVE: LL_INFOS() << "Missing emissive" << LL_ENDL; break;
+ case MAP_TANGENT: LL_INFOS() << "Missing tangent" << LL_ENDL; break;
+ case MAP_WEIGHT: LL_INFOS() << "Missing weight" << LL_ENDL; break;
+ case MAP_WEIGHT4: LL_INFOS() << "Missing weightx4" << LL_ENDL; break;
+ case MAP_CLOTHWEIGHT: LL_INFOS() << "Missing clothweight" << LL_ENDL; break;
+ case MAP_TEXTURE_INDEX: LL_INFOS() << "Missing tex index" << LL_ENDL; break;
+ default: LL_INFOS() << "Missing who effin knows: " << unsatisfied_flag << LL_ENDL;
+ }
+ }
+
+ // TYPE_INDEX is beyond TYPE_MAX, so check for it individually
+ if (unsatisfied_mask & (1 << TYPE_INDEX))
+ {
+ LL_INFOS() << "Missing indices" << LL_ENDL;
+ }
LL_ERRS() << "Shader consumption mismatches data provision." << LL_ENDL;
}
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index c89d7e3958..dbe1a3687f 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -155,9 +155,8 @@ public:
//get the size of a buffer with the given typemask and vertex count
//fill offsets with the offset of each vertex component array into the buffer
// indexed by the following enum
- static S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);
+ static S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);
-
//WARNING -- when updating these enums you MUST
// 1 - update LLVertexBuffer::sTypeSize
// 2 - add a strider accessor
@@ -165,24 +164,28 @@ public:
// 4 - modify LLVertexBuffer::setupClientArray
// 5 - modify LLViewerShaderMgr::mReservedAttribs
// 6 - update LLVertexBuffer::setupVertexArray
- enum {
- TYPE_VERTEX = 0,
- TYPE_NORMAL,
- TYPE_TEXCOORD0,
- TYPE_TEXCOORD1,
- TYPE_TEXCOORD2,
- TYPE_TEXCOORD3,
- TYPE_COLOR,
- TYPE_EMISSIVE,
- TYPE_TANGENT,
- TYPE_WEIGHT,
- TYPE_WEIGHT4,
- TYPE_CLOTHWEIGHT,
- TYPE_TEXTURE_INDEX,
- TYPE_MAX,
- TYPE_INDEX,
- };
- enum {
+
+ // clang-format off
+ enum { // Shader attribute name, set in LLShaderMgr::initAttribsAndUniforms()
+ TYPE_VERTEX = 0, // "position"
+ TYPE_NORMAL, // "normal"
+ TYPE_TEXCOORD0, // "texcoord0"
+ TYPE_TEXCOORD1, // "texcoord1"
+ TYPE_TEXCOORD2, // "texcoord2"
+ TYPE_TEXCOORD3, // "texcoord3"
+ TYPE_COLOR, // "diffuse_color"
+ TYPE_EMISSIVE, // "emissive"
+ TYPE_TANGENT, // "tangent"
+ TYPE_WEIGHT, // "weight"
+ TYPE_WEIGHT4, // "weight4"
+ TYPE_CLOTHWEIGHT, // "clothing"
+ TYPE_TEXTURE_INDEX, // "texture_index"
+ TYPE_MAX, // TYPE_MAX is the size/boundary marker for attributes that go in the vertex buffer
+ TYPE_INDEX, // TYPE_INDEX is beyond _MAX because it lives in a separate (index) buffer
+ };
+ // clang-format on
+
+ enum {
MAP_VERTEX = (1<<TYPE_VERTEX),
MAP_NORMAL = (1<<TYPE_NORMAL),
MAP_TEXCOORD0 = (1<<TYPE_TEXCOORD0),