diff options
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/CMakeLists.txt | 12 | ||||
-rw-r--r-- | indra/llrender/llatmosphere.cpp | 349 | ||||
-rw-r--r-- | indra/llrender/llatmosphere.h | 118 | ||||
-rw-r--r-- | indra/llrender/llgl.cpp | 85 | ||||
-rw-r--r-- | indra/llrender/llgl.h | 10 | ||||
-rw-r--r-- | indra/llrender/llglslshader.cpp | 96 | ||||
-rw-r--r-- | indra/llrender/llglslshader.h | 9 | ||||
-rw-r--r-- | indra/llrender/llglstates.h | 24 | ||||
-rw-r--r-- | indra/llrender/llgltexture.cpp | 198 | ||||
-rw-r--r-- | indra/llrender/llgltexture.h | 10 | ||||
-rw-r--r-- | indra/llrender/llimagegl.cpp | 39 | ||||
-rw-r--r-- | indra/llrender/llimagegl.h | 9 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 160 | ||||
-rw-r--r-- | indra/llrender/llrender.h | 53 | ||||
-rw-r--r-- | indra/llrender/llshadermgr.cpp | 224 | ||||
-rw-r--r-- | indra/llrender/llshadermgr.h | 39 | ||||
-rw-r--r-- | indra/llrender/lltexture.cpp | 12 | ||||
-rw-r--r-- | indra/llrender/lltexture.h | 22 |
18 files changed, 1184 insertions, 285 deletions
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 07a0d8c402..bcb5a847f6 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -13,6 +13,7 @@ include(LLVFS) include(LLWindow) include(LLXML) include(LLVFS) +include(Atmosphere) include_directories( ${FREETYPE_INCLUDE_DIRS} @@ -24,6 +25,7 @@ include_directories( ${LLWINDOW_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} ${LLVFS_INCLUDE_DIRS} + ${ATMOSPHERE_INCLUDE_DIR} ) include_directories(SYSTEM ${LLCOMMON_SYSTEM_INCLUDE_DIRS} @@ -31,6 +33,7 @@ include_directories(SYSTEM ) set(llrender_SOURCE_FILES + llatmosphere.cpp llcubemap.cpp llfontbitmapcache.cpp llfontfreetype.cpp @@ -57,6 +60,7 @@ set(llrender_SOURCE_FILES set(llrender_HEADER_FILES CMakeLists.txt + llatmosphere.h llcubemap.h llfontgl.h llfontfreetype.h @@ -105,7 +109,9 @@ if (BUILD_HEADLESS) ${LLXML_LIBRARIES} ${LLVFS_LIBRARIES} ${LLWINDOW_HEADLESS_LIBRARIES} - ${OPENGL_HEADLESS_LIBRARIES}) + ${LIBATMOSPHERE_LIBRARIES} + ${OPENGL_HEADLESS_LIBRARIES} + ) endif (BUILD_HEADLESS) @@ -128,5 +134,7 @@ target_link_libraries(llrender ${LLVFS_LIBRARIES} ${LLWINDOW_LIBRARIES} ${FREETYPE_LIBRARIES} - ${OPENGL_LIBRARIES}) + ${LIBATMOSPHERE_LIBRARIES} + ${OPENGL_LIBRARIES} + ) diff --git a/indra/llrender/llatmosphere.cpp b/indra/llrender/llatmosphere.cpp new file mode 100644 index 0000000000..12c6685354 --- /dev/null +++ b/indra/llrender/llatmosphere.cpp @@ -0,0 +1,349 @@ +/** + * @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; + +const double max_sun_zenith_angle = F_PI * 2.0 / 3.0; + +AtmosphericModelSettings::AtmosphericModelSettings() + : m_skyBottomRadius(6360.0f) + , m_skyTopRadius(6420.0f) + , m_sunArcRadians(0.00045f) + , m_mieAnisotropy(0.8f) +{ + atmosphere::DensityProfileLayer rayleigh_density(0.0, 1.0, -1.0 / kRayleighScaleHeight, 0.0, 0.0); + atmosphere::DensityProfileLayer mie_density(0.0, 1.0, -1.0 / kMieScaleHeight, 0.0, 0.0); + + m_rayleighProfile.push_back(rayleigh_density); + m_mieProfile.push_back(mie_density); + + // Density profile increasing linearly from 0 to 1 between 10 and 25km, and + // decreasing linearly from 1 to 0 between 25 and 40km. This is an approximate + // profile from http://www.kln.ac.lk/science/Chemistry/Teaching_Resources/ + // Documents/Introduction%20to%20atmospheric%20chemistry.pdf (page 10). + m_absorptionProfile.push_back(atmosphere::DensityProfileLayer(25000.0, 0.0, 0.0, 1.0 / 15000.0, -2.0 / 3.0)); + m_absorptionProfile.push_back(atmosphere::DensityProfileLayer(0.0, 0.0, 0.0, -1.0 / 15000.0, 8.0 / 3.0)); +} + +AtmosphericModelSettings::AtmosphericModelSettings( + DensityProfile& rayleighProfile, + DensityProfile& mieProfile, + DensityProfile& absorptionProfile) +: m_skyBottomRadius(6360.0f) +, m_skyTopRadius(6420.0f) +, m_rayleighProfile(rayleighProfile) +, m_mieProfile(mieProfile) +, m_absorptionProfile(absorptionProfile) +, m_sunArcRadians(0.00045f) +, m_mieAnisotropy(0.8f) +{ +} + +AtmosphericModelSettings::AtmosphericModelSettings( + F32 skyBottomRadius, + F32 skyTopRadius, + DensityProfile& rayleighProfile, + DensityProfile& mieProfile, + DensityProfile& absorptionProfile, + F32 sunArcRadians, + F32 mieAniso) +: m_skyBottomRadius(skyBottomRadius) +, m_skyTopRadius(skyTopRadius) +, m_rayleighProfile(rayleighProfile) +, m_mieProfile(mieProfile) +, m_absorptionProfile(absorptionProfile) +, m_sunArcRadians(sunArcRadians) +, m_mieAnisotropy(mieAniso) +{ +} + +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); + } + + delete m_model; + m_model = nullptr; +} + +bool LLAtmosphere::configureAtmosphericModel(AtmosphericModelSettings& settings) +{ + if ((m_model != nullptr) && (settings == m_settings)) + { + return true; + } + + if (m_model) + { + delete m_model; + } + m_model = nullptr; + + getTransmittance()->setTexName(0); + getScattering()->setTexName(0); + getMieScattering()->setTexName(0); + getIlluminance()->setTexName(0); + + // Init libatmosphere model + m_model = new atmosphere::Model( + m_config, + m_wavelengths, + m_solar_irradiance, + settings.m_sunArcRadians, + settings.m_skyBottomRadius * 1000.0f, + settings.m_skyTopRadius * 1000.0f, + settings.m_rayleighProfile, + m_rayleigh_scattering, + settings.m_mieProfile, + m_mie_scattering, + m_mie_extinction, + settings.m_mieAnisotropy, + settings.m_absorptionProfile, + m_absorption_extinction, + m_ground_albedo, + max_sun_zenith_angle, + 1000.0, + 3, + false, // do not combine_scattering...we want indep textures + false, // use 32F for 2d textures to avoid artifacts + true); // use 16F for 3d textures to reduce footprint + + if (m_model) + { + m_model->Init(m_config, m_textures); + getTransmittance()->setTexName(m_textures.transmittance_texture); + getScattering()->setTexName(m_textures.scattering_texture); + getMieScattering()->setTexName(m_textures.single_mie_scattering_texture); + getIlluminance()->setTexName(m_textures.illuminance_texture); + m_settings = settings; + } + + return m_model != nullptr; +} + +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; +} + +GLhandleARB LLAtmosphere::getAtmosphericShaderForLink() const +{ + return m_model ? m_model->GetShader() : 0; +} diff --git a/indra/llrender/llatmosphere.h b/indra/llrender/llatmosphere.h new file mode 100644 index 0000000000..a010803595 --- /dev/null +++ b/indra/llrender/llatmosphere.h @@ -0,0 +1,118 @@ +/** + * @file llatmosphere.h + * @brief LLAtmosphere class for integration with libatmosphere + * + * $LicenseInfo:firstyear=2018&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2018, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_ATMOSPHERE_H +#define LL_ATMOSPHERE_H + +#include "llglheaders.h" +#include "llgltexture.h" +#include "libatmosphere/model.h" + +typedef std::vector<atmosphere::DensityProfileLayer> DensityProfile; + +class AtmosphericModelSettings +{ +public: + AtmosphericModelSettings(); + + AtmosphericModelSettings( + DensityProfile& rayleighProfile, + DensityProfile& mieProfile, + DensityProfile& absorptionProfile); + + AtmosphericModelSettings( + F32 skyBottomRadius, + F32 skyTopRadius, + DensityProfile& rayleighProfile, + DensityProfile& mieProfile, + DensityProfile& absorptionProfile, + F32 sunArcRadians, + F32 mieAniso); + + 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(); + + GLhandleARB getAtmosphericShaderForLink() const; + + bool configureAtmosphericModel(AtmosphericModelSettings& settings); + +protected: + LLAtmosphere(const LLAtmosphere& rhs) + { + *this = rhs; + } + + atmosphere::ModelConfig m_config; + atmosphere::PrecomputedTextures m_textures; + atmosphere::Model* m_model = nullptr; + + 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/llgl.cpp b/indra/llrender/llgl.cpp index 35b6951779..b6300578e6 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" @@ -1352,8 +1353,8 @@ void LLGLManager::initExtensions() // nSight doesn't support use of ARB funcs that have been normalized in the API if (!LLRender::sNsightDebugSupport) { - glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB"); - glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB"); + glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetAttribLocationARB"); + glBindAttribLocationARB = (PFNGLBINDATTRIBLOCATIONARBPROC) GLH_EXT_GET_PROC_ADDRESS("glBindAttribLocationARB"); } else { @@ -2267,6 +2268,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 +2307,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() @@ -2478,27 +2485,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,5 +2586,39 @@ 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); +} diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 4c4302d05b..362fda5fb1 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -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/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 4702042ab9..528f23b3ee 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -37,12 +37,6 @@ #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; @@ -84,6 +78,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) @@ -402,6 +402,11 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes, mDefines["OLD_SELECT"] = "1"; #endif + if (mExtraLinkObject) + { + attachObject(mExtraLinkObject); + } + //compile new source vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin(); for ( ; fileIter != mShaderFiles.end(); fileIter++ ) @@ -448,12 +453,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 +490,18 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes, return success; } -BOOL LLGLSLShader::attachObject(std::string object) +BOOL LLGLSLShader::attachObject(std::string object_path) { - if (LLShaderMgr::instance()->mShaderObjects.count(object) > 0) + if (LLShaderMgr::instance()->mShaderObjects.count(object_path) > 0) { stop_glerror(); - glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mShaderObjects[object]); + glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mShaderObjects[object_path]); 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; } } @@ -511,7 +516,7 @@ void LLGLSLShader::attachObject(GLhandleARB object) } 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; } } @@ -561,7 +566,7 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri mAttribute[i] = index; #endif mAttributeMask |= 1 << i; - LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL; + LL_DEBUGS("ShaderUniform") << "Attribute " << name << " assigned to channel " << index << LL_ENDL; } } if (attributes != NULL) @@ -573,7 +578,7 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri if (index != -1) { mAttribute[LLShaderMgr::instance()->mReservedAttribs.size() + i] = index; - LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL; + LL_DEBUGS("ShaderUniform") << "Attribute " << name << " assigned to channel " << index << LL_ENDL; } } } @@ -658,7 +663,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * mUniformNameMap[location] = name; mUniformMap[hashedName] = location; - LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL; + LL_DEBUGS("ShaderUniform") << "Uniform " << name << " is at location " << location << LL_ENDL; //find the index of this uniform for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++) @@ -706,7 +711,7 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) type == GL_SAMPLER_2D_MULTISAMPLE) { //this here is a texture glUniform1iARB(location, mActiveTextureChannels); - LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL; + LL_DEBUGS("ShaderUniform") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL; return mActiveTextureChannels++; } return -1; @@ -759,18 +764,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 +796,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 +807,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; @@ -849,7 +855,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms) unbind(); - LL_DEBUGS("ShaderLoading") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL; + LL_DEBUGS("ShaderUniform") << "Total Uniform Size: " << mTotalUniformSize << LL_ENDL; return res; } @@ -858,7 +864,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); } @@ -928,7 +934,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu { 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; } @@ -954,7 +960,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; } @@ -972,7 +978,7 @@ S32 LLGLSLShader::enableTexture(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; } S32 index = mTexture[uniform]; @@ -988,7 +994,7 @@ S32 LLGLSLShader::disableTexture(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; } S32 index = mTexture[uniform]; @@ -1017,7 +1023,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 +1045,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 +1067,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 +1090,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 +1113,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 +1136,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 +1159,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 +1182,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 +1205,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 +1228,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 +1251,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 +1268,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 +1285,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 +1302,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..c06668eb43 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; @@ -211,6 +217,8 @@ public: std::vector<U32> mTextureMagFilter; std::vector<U32> mTextureMinFilter; + GLhandleARB mExtraLinkObject = 0; + private: void unloadInternal(); }; @@ -222,5 +230,4 @@ extern LLGLSLShader gSolidColorProgram; //Alpha mask shader (declared here so llappearance can access properly) extern LLGLSLShader gAlphaMaskProgram; - #endif 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..e9a39d8acb 100644 --- a/indra/llrender/llgltexture.cpp +++ b/indra/llrender/llgltexture.cpp @@ -30,20 +30,20 @@ // static S32 LLGLTexture::getTotalNumOfCategories() { - return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ; + return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2; } // static //index starts from zero. S32 LLGLTexture::getIndexFromCategory(S32 category) { - return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ; + return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1; } //static S32 LLGLTexture::getCategoryFromIndex(S32 index) { - return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ; + return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1; } LLGLTexture::LLGLTexture(BOOL usemipmaps) @@ -55,19 +55,19 @@ LLGLTexture::LLGLTexture(BOOL usemipmaps) LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) { init(); - mFullWidth = width ; - mFullHeight = height ; + mFullWidth = width; + mFullHeight = height; mUseMipMaps = usemipmaps; - mComponents = components ; + mComponents = components; setTexelsPerImage(); } LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) { init(); - mUseMipMaps = usemipmaps ; + mUseMipMaps = usemipmaps; // Create an empty image of the specified size and width - mGLTexturep = new LLImageGL(raw, usemipmaps) ; + mGLTexturep = new LLImageGL(raw, usemipmaps); } LLGLTexture::~LLGLTexture() @@ -81,13 +81,13 @@ void LLGLTexture::init() mFullWidth = 0; mFullHeight = 0; - mTexelsPerImage = 0 ; - mUseMipMaps = FALSE ; - mComponents = 0 ; + mTexelsPerImage = 0; + mUseMipMaps = FALSE; + mComponents = 0; - mTextureState = NO_DELETE ; + mTextureState = NO_DELETE; mDontDiscard = FALSE; - mNeedsGLTexture = FALSE ; + mNeedsGLTexture = FALSE; } void LLGLTexture::cleanup() @@ -111,287 +111,301 @@ void LLGLTexture::setBoostLevel(S32 level) { if(mBoostLevel != level) { - mBoostLevel = level ; + mBoostLevel = level; if(mBoostLevel != LLGLTexture::BOOST_NONE && mBoostLevel != LLGLTexture::BOOST_ICON) { - setNoDelete() ; + setNoDelete(); } } } void LLGLTexture::forceActive() { - mTextureState = ACTIVE ; + mTextureState = ACTIVE; } void LLGLTexture::setActive() { if(mTextureState != NO_DELETE) { - mTextureState = ACTIVE ; + mTextureState = ACTIVE; } } //set the texture to stay in memory void LLGLTexture::setNoDelete() { - mTextureState = NO_DELETE ; + mTextureState = NO_DELETE; } void LLGLTexture::generateGLTexture() { if(mGLTexturep.isNull()) { - mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ; + mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps); } } LLImageGL* LLGLTexture::getGLTexture() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep ; + return mGLTexturep; } BOOL LLGLTexture::createGLTexture() { if(mGLTexturep.isNull()) { - generateGLTexture() ; + generateGLTexture(); } - return mGLTexturep->createGLTexture() ; + return mGLTexturep->createGLTexture(); } BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ; + BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category); if(ret) { - mFullWidth = mGLTexturep->getCurrentWidth() ; - mFullHeight = mGLTexturep->getCurrentHeight() ; - mComponents = mGLTexturep->getComponents() ; + mFullWidth = mGLTexturep->getCurrentWidth(); + mFullHeight = mGLTexturep->getCurrentHeight(); + mComponents = mGLTexturep->getComponents(); setTexelsPerImage(); } - return ret ; + return ret; } void LLGLTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ; + mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes); } void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode) { - llassert(mGLTexturep.notNull()) ; - mGLTexturep->setAddressMode(mode) ; + llassert(mGLTexturep.notNull()); + mGLTexturep->setAddressMode(mode); } void LLGLTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option) { - llassert(mGLTexturep.notNull()) ; - mGLTexturep->setFilteringOption(option) ; + llassert(mGLTexturep.notNull()); + mGLTexturep->setFilteringOption(option); } //virtual S32 LLGLTexture::getWidth(S32 discard_level) const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getWidth(discard_level) ; + llassert(mGLTexturep.notNull()); + return mGLTexturep->getWidth(discard_level); } //virtual S32 LLGLTexture::getHeight(S32 discard_level) const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getHeight(discard_level) ; + llassert(mGLTexturep.notNull()); + return mGLTexturep->getHeight(discard_level); } S32 LLGLTexture::getMaxDiscardLevel() const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getMaxDiscardLevel() ; + llassert(mGLTexturep.notNull()); + return mGLTexturep->getMaxDiscardLevel(); } S32 LLGLTexture::getDiscardLevel() const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getDiscardLevel() ; + llassert(mGLTexturep.notNull()); + return mGLTexturep->getDiscardLevel(); } S8 LLGLTexture::getComponents() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getComponents() ; + return mGLTexturep->getComponents(); } LLGLuint LLGLTexture::getTexName() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getTexName() ; + return mGLTexturep->getTexName(); } BOOL LLGLTexture::hasGLTexture() const { if(mGLTexturep.notNull()) { - return mGLTexturep->getHasGLTexture() ; + return mGLTexturep->getHasGLTexture(); } - return FALSE ; + return FALSE; } BOOL LLGLTexture::getBoundRecently() const { if(mGLTexturep.notNull()) { - return mGLTexturep->getBoundRecently() ; + return mGLTexturep->getBoundRecently(); } - return FALSE ; + return FALSE; } LLTexUnit::eTextureType LLGLTexture::getTarget(void) const { - llassert(mGLTexturep.notNull()) ; - return mGLTexturep->getTarget() ; + llassert(mGLTexturep.notNull()); + return mGLTexturep->getTarget(); } BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ; + return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height); } BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ; + return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height); } void LLGLTexture::setGLTextureCreated (bool initialized) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - mGLTexturep->setGLTextureCreated (initialized) ; + mGLTexturep->setGLTextureCreated (initialized); } void LLGLTexture::setCategory(S32 category) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); + + mGLTexturep->setCategory(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()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getAddressMode() ; + return mGLTexturep->getAddressMode(); } S32Bytes LLGLTexture::getTextureMemory() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->mTextureMemory ; + return mGLTexturep->mTextureMemory; } LLGLenum LLGLTexture::getPrimaryFormat() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getPrimaryFormat() ; + return mGLTexturep->getPrimaryFormat(); } BOOL LLGLTexture::getIsAlphaMask() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getIsAlphaMask() ; + return mGLTexturep->getIsAlphaMask(); } BOOL LLGLTexture::getMask(const LLVector2 &tc) { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getMask(tc) ; + return mGLTexturep->getMask(tc); } F32 LLGLTexture::getTimePassedSinceLastBound() { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getTimePassedSinceLastBound() ; + return mGLTexturep->getTimePassedSinceLastBound(); } BOOL LLGLTexture::getMissed() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getMissed() ; + return mGLTexturep->getMissed(); } BOOL LLGLTexture::isJustBound() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->isJustBound() ; + return mGLTexturep->isJustBound(); } void LLGLTexture::forceUpdateBindStats(void) const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->forceUpdateBindStats() ; + return mGLTexturep->forceUpdateBindStats(); } U32 LLGLTexture::getTexelsInAtlas() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getTexelsInAtlas() ; + return mGLTexturep->getTexelsInAtlas(); } U32 LLGLTexture::getTexelsInGLTexture() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getTexelsInGLTexture() ; + return mGLTexturep->getTexelsInGLTexture(); } BOOL LLGLTexture::isGLTextureCreated() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->isGLTextureCreated() ; + return mGLTexturep->isGLTextureCreated(); } S32 LLGLTexture::getDiscardLevelInAtlas() const { - llassert(mGLTexturep.notNull()) ; + llassert(mGLTexturep.notNull()); - return mGLTexturep->getDiscardLevelInAtlas() ; + return mGLTexturep->getDiscardLevelInAtlas(); } void LLGLTexture::destroyGLTexture() { if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture()) { - mGLTexturep->destroyGLTexture() ; - mTextureState = DELETED ; + mGLTexturep->destroyGLTexture(); + mTextureState = DELETED; } } 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..bdaed05591 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -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..25ec493fa2 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -352,10 +352,9 @@ 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 +364,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 +375,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 +385,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) diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 2be54be062..4f3d7eed0a 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(); @@ -234,6 +237,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 +284,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..e3bb9298cb 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -59,7 +59,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[] = @@ -894,6 +895,15 @@ void LLLightState::setDiffuse(const LLColor4& diffuse) } } +void LLLightState::setDiffuseB(const LLColor4& diffuse) +{ + if (mDiffuseB != diffuse) + { + ++gGL.mLightHash; + mDiffuseB = diffuse; + } +} + void LLLightState::setAmbient(const LLColor4& ambient) { if (mAmbient != ambient) @@ -1150,8 +1160,9 @@ void LLRender::syncLightState() LLVector4 position[8]; LLVector3 direction[8]; - LLVector3 attenuation[8]; + LLVector4 attenuation[8]; LLVector3 diffuse[8]; + LLVector3 diffuseB[8]; for (U32 i = 0; i < 8; i++) { @@ -1159,17 +1170,18 @@ void LLRender::syncLightState() position[i] = light->mPosition; direction[i] = light->mSpotDirection; - attenuation[i].set(light->mLinearAtten, light->mQuadraticAtten, light->mSpecular.mV[3]); + attenuation[i].set(light->mLinearAtten, light->mQuadraticAtten, light->mSpecular.mV[2], light->mSpecular.mV[3]); diffuse[i].set(light->mDiffuse.mV); + diffuseB[i].set(light->mDiffuseB.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->uniform4fv(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); + shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, diffuseB[0].mV); } } @@ -1190,6 +1202,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 +1216,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]]; + + // 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[i], 1, GL_FALSE, mat.m); - shader->mMatHash[i] = mMatHash[i]; + 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 +1235,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 +1251,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 +1275,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 +1297,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; @@ -1307,7 +1338,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 +1348,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 +1484,21 @@ 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_always(tex_index <= 3); + mode = eMatrixMode(MM_TEXTURE0 + gGL.getCurrentTexUnitIndex()); } 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 +2365,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..3f2d5eb35d 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 @@ -228,6 +229,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); @@ -244,6 +246,7 @@ protected: S32 mIndex; bool mEnabled; LLColor4 mDiffuse; + LLColor4 mDiffuseB; LLColor4 mAmbient; LLColor4 mSpecular; LLVector4 mPosition; @@ -264,10 +267,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 +364,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(); @@ -450,7 +454,7 @@ public: 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 +499,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/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index e721ad93fa..11e84d8785 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; @@ -98,7 +90,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) } } - if (features->calculatesLighting || features->atmosphericHelpers) + if (features->calculatesLighting || features->calculatesAtmospherics) { if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl")) { @@ -179,6 +171,8 @@ 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) @@ -194,7 +188,47 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) } } - // NOTE order of shader object attaching is VERY IMPORTANT!!! + if (features->calculatesLighting || features->calculatesAtmospherics) + { + if (!shader->attachObject("windlight/atmosphericsHelpersF.glsl")) + { + return FALSE; + } + } + + // we want this BEFORE shadows and AO because those facilities use pos/norm access + if (features->isDeferred) + { + if (!shader->attachObject("deferred/deferredUtil.glsl")) + { + return FALSE; + } + } + + if (features->hasShadows) + { + if (!shader->attachObject("deferred/shadowUtil.glsl")) + { + return FALSE; + } + } + + if (features->hasAmbientOcclusion) + { + if (!shader->attachObject("deferred/aoUtil.glsl")) + { + return FALSE; + } + } + + if (features->hasIndirect) + { + if (!shader->attachObject("deferred/indirect.glsl")) + { + return FALSE; + } + } + if (features->hasGamma) { if (!shader->attachObject("windlight/gammaF.glsl")) @@ -202,7 +236,23 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } - + + if (features->hasSrgb) + { + if (!shader->attachObject("environment/srgbF.glsl")) + { + return FALSE; + } + } + + if (features->encodesNormal) + { + if (!shader->attachObject("environment/encodeNormF.glsl")) + { + return FALSE; + } + } + if (features->hasAtmospherics) { if (!shader->attachObject("windlight/atmosphericsF.glsl")) @@ -509,35 +559,54 @@ 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) +{ + for (GLuint i = 0; i < shader_code_count; i++) + { + LL_SHADER_LOADING_WARNS() << i << ": " << shader_code_text[i] << LL_ENDL; + } + LL_SHADER_LOADING_WARNS() << 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 << ":\n" << LL_ENDL; + LL_SHADER_LOADING_WARNS() << 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) { - LL_WARNS("ShaderLoading") << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL; + LL_SHADER_LOADING_WARNS() << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL; } } - LL_DEBUGS("ShaderLoading") << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL; + //LL_SHADER_LOADING_WARNS() << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL; if (filename.empty()) { @@ -551,6 +620,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 @@ -558,18 +628,33 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade fname << getShaderDirPrefix(); fname << gpu_class << "/" << filename; - LL_DEBUGS("ShaderLoading") << "Looking in " << fname.str() << LL_ENDL; - 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; } @@ -648,7 +733,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 @@ -899,38 +984,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade { //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 - + dumpObjectLog(ret, TRUE, open_file_name); + dumpShaderSource(shader_code_count, shader_code_text); ret = 0; } } @@ -959,7 +1014,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; } @@ -975,7 +1030,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 @@ -1008,7 +1063,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; } @@ -1019,7 +1074,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; } @@ -1035,7 +1090,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 @@ -1069,6 +1124,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"); @@ -1111,13 +1167,16 @@ 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("sunlight_color"); mReservedUniforms.push_back("ambient"); mReservedUniforms.push_back("blue_horizon"); mReservedUniforms.push_back("blue_density"); @@ -1177,6 +1236,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"); @@ -1234,8 +1294,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"); @@ -1267,6 +1327,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..497c3eb231 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -42,6 +42,7 @@ public: PROJECTION_MATRIX, INVERSE_PROJECTION_MATRIX, MODELVIEW_PROJECTION_MATRIX, + INVERSE_MODELVIEW_MATRIX, NORMAL_MATRIX, TEXTURE_MATRIX0, TEXTURE_MATRIX1, @@ -73,10 +74,13 @@ public: PROJECTOR_AMBIENT_LOD, DIFFUSE_COLOR, DIFFUSE_MAP, + ALTERNATE_DIFFUSE_MAP, SPECULAR_MAP, BUMP_MAP, + BUMP_MAP2, ENVIRONMENT_MAP, CLOUD_NOISE_MAP, + CLOUD_NOISE_MAP_NEXT, FULLBRIGHT, LIGHTNORM, SUNLIGHT_COLOR, @@ -131,6 +135,7 @@ public: DEFERRED_SPOT_SHADOW_BIAS, DEFERRED_SPOT_SHADOW_OFFSET, DEFERRED_SUN_DIR, + DEFERRED_MOON_DIR, DEFERRED_SHADOW_RES, DEFERRED_PROJ_SHADOW_RES, DEFERRED_DEPTH_CUTOFF, @@ -215,7 +220,38 @@ public: TERRAIN_ALPHARAMP, SHINY_ORIGIN, -DISPLAY_GAMMA, + DISPLAY_GAMMA, + + INSCATTER_RT, + SUN_SIZE, + FOG_COLOR, + + // precomputed textures from libatmosphere + TRANSMITTANCE_TEX, + SCATTER_TEX, + SINGLE_MIE_SCATTER_TEX, + ILLUMINANCE_TEX, + BLEND_FACTOR, + + NO_ATMO, + MOISTURE_LEVEL, + DROPLET_RADIUS, + ICE_LEVEL, + RAINBOW_MAP, + HALO_MAP, + + MOON_BRIGHTNESS, + + CLOUD_VARIANCE, + + SH_INPUT_L1R, + SH_INPUT_L1G, + SH_INPUT_L1B, + + SUN_MOON_GLOW_FACTOR, + WATER_EDGE_FACTOR, + SUN_UP_FACTOR, + MOONLIGHT_COLOR, END_RESERVED_UNIFORMS } eGLSLReservedUniforms; @@ -226,6 +262,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); 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 |