From 798d367d54a6c6379ad355bd8345fa40e31e7fe9 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Sat, 6 Sep 2008 18:24:57 -0500 Subject: Second Life viewer sources 1.21.0-RC --- linden/indra/newview/llglslshader.cpp | 2310 --------------------------------- 1 file changed, 2310 deletions(-) delete mode 100644 linden/indra/newview/llglslshader.cpp (limited to 'linden/indra/newview/llglslshader.cpp') diff --git a/linden/indra/newview/llglslshader.cpp b/linden/indra/newview/llglslshader.cpp deleted file mode 100644 index a9274b5..0000000 --- a/linden/indra/newview/llglslshader.cpp +++ /dev/null @@ -1,2310 +0,0 @@ -/** - * @file llglslshader.cpp - * @brief GLSL helper functions and state. - * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2008, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfeaturemanager.h" -#include "llglslshader.h" - -#include "llfile.h" -#include "llviewerwindow.h" -#include "llviewercontrol.h" -#include "pipeline.h" -#include "llworld.h" -#include "llwlparammanager.h" -#include "llwaterparammanager.h" -#include "llsky.h" -#include "llvosky.h" -#include "llrender.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; -using std::make_pair; -using std::string; - -LLVector4 gShinyOrigin; - -//object shaders -LLGLSLShader gObjectSimpleProgram; -LLGLSLShader gObjectSimpleWaterProgram; -LLGLSLShader gObjectFullbrightProgram; -LLGLSLShader gObjectFullbrightWaterProgram; - -LLGLSLShader gObjectFullbrightShinyProgram; -LLGLSLShader gObjectShinyProgram; -LLGLSLShader gObjectShinyWaterProgram; - -//environment shaders -LLGLSLShader gTerrainProgram; -LLGLSLShader gTerrainWaterProgram; -LLGLSLShader gWaterProgram; -LLGLSLShader gUnderWaterProgram; - -//interface shaders -LLGLSLShader gHighlightProgram; - -//avatar skinning utility shader object -GLhandleARB gAvatarSkinVertex; - -//avatar shader handles -LLGLSLShader gAvatarProgram; -LLGLSLShader gAvatarWaterProgram; -LLGLSLShader gAvatarEyeballProgram; -LLGLSLShader gAvatarPickProgram; - -// WindLight shader handles -LLGLSLShader gWLSkyProgram; -LLGLSLShader gWLCloudProgram; - -// Effects Shaders -LLGLSLShader gGlowProgram; -LLGLSLShader gGlowExtractProgram; -LLGLSLShader gPostColorFilterProgram; -LLGLSLShader gPostNightVisionProgram; - -// Deferred rendering shaders -LLGLSLShader gDeferredDiffuseProgram; - -//current avatar shader parameter pointer -GLint gAvatarMatrixParam; - -S32 LLShaderMgr::sVertexShaderLevel[SHADER_COUNT] = { 0 }; - -S32 LLShaderMgr::sMaxAvatarShaderLevel = 0; - -std::map LLShaderMgr::sShaderObjects; -vector LLShaderMgr::sReservedAttribs; -vector LLShaderMgr::sWLUniforms; -vector LLShaderMgr::sTerrainUniforms; -vector LLShaderMgr::sReservedUniforms; -vector LLShaderMgr::sShinyUniforms; -vector LLShaderMgr::sWaterUniforms; -vector LLShaderMgr::sGlowUniforms; -vector LLShaderMgr::sGlowExtractUniforms; -vector LLShaderMgr::sAvatarAttribs; -vector LLShaderMgr::sAvatarUniforms; -//vector< GLhandleARB > LLShaderMgr::sBaseObjects; - -/// Make sure WL Sky is the first program -LLGLSLShader * const LLShaderMgr::sShaderList[] = -{ - &gWLSkyProgram, - &gWLCloudProgram, - &gAvatarProgram, - &gObjectShinyProgram, - &gWaterProgram, - &gAvatarEyeballProgram, - &gObjectSimpleProgram, - &gObjectFullbrightProgram, - &gObjectFullbrightShinyProgram, - &gTerrainProgram, - &gTerrainWaterProgram, - &gObjectSimpleWaterProgram, - &gObjectFullbrightWaterProgram, - &gAvatarWaterProgram, - &gObjectShinyWaterProgram, - &gUnderWaterProgram, -}; -const size_t LLShaderMgr::sNumShaders = sizeof(sShaderList) / sizeof(sShaderList[0]); - - -BOOL shouldChange(const LLVector4& v1, const LLVector4& v2) -{ - /*F32 dot = v1.mV[0] * v2.mV[0] + - v1.mV[1] * v2.mV[1] + - v1.mV[2] * v2.mV[2] + - v1.mV[3] * v2.mV[3]; - - F32 mag = v1.mV[0] * v1.mV[0] + - v1.mV[1] * v1.mV[1] + - v1.mV[2] * v1.mV[2] + - v1.mV[3] * v1.mV[3]; - - F32 val = (dot/mag); - - if (val > 2.0f || val < 0.1f) - { - return TRUE; - } - - return FALSE;*/ - - return v1 != v2; -} - -LLShaderFeatures::LLShaderFeatures() -: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false), -hasTransport(false), hasSkinning(false), hasAtmospherics(false), isSpecular(false), -hasGamma(false), hasLighting(false), calculatesAtmospherics(false) -{ -} - -void LLShaderMgr::initAttribsAndUniforms(void) -{ - if (sReservedAttribs.empty()) - { - sReservedAttribs.push_back("materialColor"); - sReservedAttribs.push_back("specularColor"); - sReservedAttribs.push_back("binormal"); - - sAvatarAttribs.reserve(5); - sAvatarAttribs.push_back("weight"); - sAvatarAttribs.push_back("clothing"); - sAvatarAttribs.push_back("gWindDir"); - sAvatarAttribs.push_back("gSinWaveParams"); - sAvatarAttribs.push_back("gGravity"); - - sAvatarUniforms.push_back("matrixPalette"); - - sReservedUniforms.reserve(24); - sReservedUniforms.push_back("diffuseMap"); - sReservedUniforms.push_back("specularMap"); - sReservedUniforms.push_back("bumpMap"); - sReservedUniforms.push_back("environmentMap"); - sReservedUniforms.push_back("cloude_noise_texture"); - sReservedUniforms.push_back("fullbright"); - sReservedUniforms.push_back("lightnorm"); - sReservedUniforms.push_back("sunlight_color"); - sReservedUniforms.push_back("ambient"); - sReservedUniforms.push_back("blue_horizon"); - sReservedUniforms.push_back("blue_density"); - sReservedUniforms.push_back("haze_horizon"); - sReservedUniforms.push_back("haze_density"); - sReservedUniforms.push_back("cloud_shadow"); - sReservedUniforms.push_back("density_multiplier"); - sReservedUniforms.push_back("distance_multiplier"); - sReservedUniforms.push_back("max_y"); - sReservedUniforms.push_back("glow"); - sReservedUniforms.push_back("cloud_color"); - sReservedUniforms.push_back("cloud_pos_density1"); - sReservedUniforms.push_back("cloud_pos_density2"); - sReservedUniforms.push_back("cloud_scale"); - sReservedUniforms.push_back("gamma"); - sReservedUniforms.push_back("scene_light_strength"); - - sWLUniforms.push_back("camPosLocal"); - - sTerrainUniforms.reserve(5); - sTerrainUniforms.push_back("detail_0"); - sTerrainUniforms.push_back("detail_1"); - sTerrainUniforms.push_back("detail_2"); - sTerrainUniforms.push_back("detail_3"); - sTerrainUniforms.push_back("alpha_ramp"); - - sGlowUniforms.push_back("glowDelta"); - sGlowUniforms.push_back("glowStrength"); - - sGlowExtractUniforms.push_back("minLuminance"); - sGlowExtractUniforms.push_back("maxExtractAlpha"); - sGlowExtractUniforms.push_back("lumWeights"); - sGlowExtractUniforms.push_back("warmthWeights"); - sGlowExtractUniforms.push_back("warmthAmount"); - - sShinyUniforms.push_back("origin"); - - sWaterUniforms.reserve(12); - sWaterUniforms.push_back("screenTex"); - sWaterUniforms.push_back("screenDepth"); - sWaterUniforms.push_back("refTex"); - sWaterUniforms.push_back("eyeVec"); - sWaterUniforms.push_back("time"); - sWaterUniforms.push_back("d1"); - sWaterUniforms.push_back("d2"); - sWaterUniforms.push_back("lightDir"); - sWaterUniforms.push_back("specular"); - sWaterUniforms.push_back("lightExp"); - sWaterUniforms.push_back("fogCol"); - sWaterUniforms.push_back("kd"); - sWaterUniforms.push_back("refScale"); - sWaterUniforms.push_back("waterHeight"); - } -} - -BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) -{ - llassert_always(shader != NULL); - LLShaderFeatures *features = & shader->mFeatures; - - ////////////////////////////////////// - // Attach Vertex Shader Features First - ////////////////////////////////////// - - // NOTE order of shader object attaching is VERY IMPORTANT!!! - if (features->calculatesAtmospherics) - { - if (!shader->attachObject("windlight/atmosphericsVarsV.glsl")) - { - return FALSE; - } - } - - if (features->calculatesLighting) - { - if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl")) - { - return FALSE; - } - - if (features->isSpecular) - { - if (!shader->attachObject("lighting/lightFuncSpecularV.glsl")) - { - return FALSE; - } - - if (!shader->attachObject("lighting/sumLightsSpecularV.glsl")) - { - return FALSE; - } - - if (!shader->attachObject("lighting/lightSpecularV.glsl")) - { - return FALSE; - } - } - else - { - if (!shader->attachObject("lighting/lightFuncV.glsl")) - { - return FALSE; - } - - if (!shader->attachObject("lighting/sumLightsV.glsl")) - { - return FALSE; - } - - if (!shader->attachObject("lighting/lightV.glsl")) - { - return FALSE; - } - } - } - - // NOTE order of shader object attaching is VERY IMPORTANT!!! - if (features->calculatesAtmospherics) - { - if (!shader->attachObject("windlight/atmosphericsV.glsl")) - { - return FALSE; - } - } - - if (features->hasSkinning) - { - if (!shader->attachObject("avatar/avatarSkinV.glsl")) - { - return FALSE; - } - } - - /////////////////////////////////////// - // Attach Fragment Shader Features Next - /////////////////////////////////////// - - if(features->calculatesAtmospherics) - { - if (!shader->attachObject("windlight/atmosphericsVarsF.glsl")) - { - return FALSE; - } - } - - // NOTE order of shader object attaching is VERY IMPORTANT!!! - if (features->hasGamma) - { - if (!shader->attachObject("windlight/gammaF.glsl")) - { - return FALSE; - } - } - - if (features->hasAtmospherics) - { - if (!shader->attachObject("windlight/atmosphericsF.glsl")) - { - return FALSE; - } - } - - if (features->hasTransport) - { - if (!shader->attachObject("windlight/transportF.glsl")) - { - return FALSE; - } - - // Test hasFullbright and hasShiny and attach fullbright and - // fullbright shiny atmos transport if we split them out. - } - - // NOTE order of shader object attaching is VERY IMPORTANT!!! - if (features->hasWaterFog) - { - if (!shader->attachObject("environment/waterFogF.glsl")) - { - return FALSE; - } - } - - if (features->hasLighting) - { - - if (features->hasWaterFog) - { - if (!shader->attachObject("lighting/lightWaterF.glsl")) - { - return FALSE; - } - } - - else - { - if (!shader->attachObject("lighting/lightF.glsl")) - { - return FALSE; - } - } - } - - // NOTE order of shader object attaching is VERY IMPORTANT!!! - else if (features->isFullbright) - { - - if (features->hasWaterFog) - { - if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl")) - { - return FALSE; - } - } - - else if (features->isShiny) - { - if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl")) - { - return FALSE; - } - } - - else - { - if (!shader->attachObject("lighting/lightFullbrightF.glsl")) - { - return FALSE; - } - } - } - - // NOTE order of shader object attaching is VERY IMPORTANT!!! - else if (features->isShiny) - { - - if (features->hasWaterFog) - { - if (!shader->attachObject("lighting/lightShinyWaterF.glsl")) - { - return FALSE; - } - } - - else - { - if (!shader->attachObject("lighting/lightShinyF.glsl")) - { - return FALSE; - } - } - } - return TRUE; -} - -//============================================================================ -// Set Levels - -S32 LLShaderMgr::getVertexShaderLevel(S32 type) -{ - return LLPipeline::sDisableShaders ? 0 : sVertexShaderLevel[type]; -} - - -//============================================================================ -// Load Shader - -static LLString get_object_log(GLhandleARB ret) -{ - LLString res; - - //get log length - GLint length; - glGetObjectParameterivARB(ret, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); - if (length > 0) - { - //the log could be any size, so allocate appropriately - GLcharARB* log = new GLcharARB[length]; - glGetInfoLogARB(ret, length, &length, log); - res = LLString((char *)log); - delete[] log; - } - return res; -} - -void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns) -{ - LLString log = get_object_log(ret); - if (warns) - { - LL_WARNS("ShaderLoading") << log << LL_ENDL; - } - else - { - LL_DEBUGS("ShaderLoading") << log << LL_ENDL; - } -} - -GLhandleARB LLShaderMgr::loadShaderFile(const LLString& filename, S32 & shader_level, GLenum type) -{ - GLenum error; - error = glGetError(); - if (error != GL_NO_ERROR) - { - LL_WARNS("ShaderLoading") << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL; - } - - LL_DEBUGS("ShaderLoading") << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL; - - if (filename.empty()) - { - return 0; - } - - - //read in from file - LLFILE* file = NULL; - - S32 try_gpu_class = shader_level; - S32 gpu_class; - - //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 - std::stringstream fname; - fname << gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); - fname << gpu_class << "/" << filename; - - LL_DEBUGS("ShaderLoading") << "Looking in " << fname.str().c_str() << LL_ENDL; - file = LLFile::fopen(fname.str().c_str(), "r"); /* Flawfinder: ignore */ - if (file) - { - LL_INFOS("ShaderLoading") << "Loading file: shaders/class" << gpu_class << "/" << filename << " (Want class " << gpu_class << ")" << LL_ENDL; - break; // done - } - } - - if (file == NULL) - { - LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << filename << LL_ENDL; - return 0; - } - - //we can't have any lines longer than 1024 characters - //or any shaders longer than 1024 lines... deal - DaveP - GLcharARB buff[1024]; - GLcharARB* text[1024]; - GLuint count = 0; - - - //copy file into memory - while(fgets((char *)buff, 1024, file) != NULL && count < (sizeof(buff)/sizeof(buff[0]))) - { - text[count++] = (GLcharARB *)strdup((char *)buff); - } - fclose(file); - - //create shader object - GLhandleARB ret = glCreateShaderObjectARB(type); - error = glGetError(); - if (error != GL_NO_ERROR) - { - LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << LL_ENDL; - } - else - { - //load source - glShaderSourceARB(ret, count, (const GLcharARB**) text, NULL); - error = glGetError(); - if (error != GL_NO_ERROR) - { - LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << LL_ENDL; - } - else - { - //compile source - glCompileShaderARB(ret); - error = glGetError(); - if (error != GL_NO_ERROR) - { - LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << LL_ENDL; - } - } - } - //free memory - for (GLuint i = 0; i < count; i++) - { - free(text[i]); - } - if (error == GL_NO_ERROR) - { - //check for errors - GLint success = GL_TRUE; - glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success); - error = glGetError(); - if (error != GL_NO_ERROR || success == GL_FALSE) - { - //an error occured, print log - LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL; - dumpObjectLog(ret); - ret = 0; - } - } - else - { - ret = 0; - } - stop_glerror(); - - //successfully loaded, save results - if (ret) - { - // Add shader file to map - sShaderObjects[filename] = ret; - shader_level = try_gpu_class; - } - else - { - if (shader_level > 1) - { - shader_level--; - return loadShaderFile(filename,shader_level,type); - } - LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL; - } - return ret; -} - -BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors) -{ - //check for errors - glLinkProgramARB(obj); - GLint success = GL_TRUE; - glGetObjectParameterivARB(obj, GL_OBJECT_LINK_STATUS_ARB, &success); - if (!suppress_errors && success == GL_FALSE) - { - //an error occured, print log - LL_WARNS("ShaderLoading") << "GLSL Linker Error:" << LL_ENDL; - } - -// NOTE: Removing LL_DARWIN block as it doesn't seem to actually give the correct answer, -// but want it for reference once I move it. -#if 0 - // Force an evaluation of the gl state so the driver can tell if the shader will run in hardware or software - // per Apple's suggestion - glBegin(gGL.mMode); - glEnd(); - - // Query whether the shader can or cannot run in hardware - // http://developer.apple.com/qa/qa2007/qa1502.html - long vertexGPUProcessing; - CGLContextObj ctx = CGLGetCurrentContext(); - CGLGetParameter (ctx, kCGLCPGPUVertexProcessing, &vertexGPUProcessing); - long fragmentGPUProcessing; - CGLGetParameter (ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing); - if (!fragmentGPUProcessing || !vertexGPUProcessing) - { - LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL; - success = GL_FALSE; - suppress_errors = FALSE; - } - -#else - LLString log = get_object_log(obj); - LLString::toLower(log); - if (log.find("software") != LLString::npos) - { - LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL; - success = GL_FALSE; - suppress_errors = FALSE; - } -#endif - if (!suppress_errors) - { - dumpObjectLog(obj, !success); - } - - return success; -} - -BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj) -{ - //check program validity against current GL - glValidateProgramARB(obj); - GLint success = GL_TRUE; - glGetObjectParameterivARB(obj, GL_OBJECT_VALIDATE_STATUS_ARB, &success); - if (success == GL_FALSE) - { - LL_WARNS("ShaderLoading") << "GLSL program not valid: " << LL_ENDL; - dumpObjectLog(obj); - } - else - { - dumpObjectLog(obj, FALSE); - } - - return success; -} - -//============================================================================ -// Shader Management - -void LLShaderMgr::setShaders() -{ - if (!gPipeline.mInitialized) - { - return; - } - // Make sure the compiled shader map is cleared before we recompile shaders. - sShaderObjects.clear(); - - initAttribsAndUniforms(); - gPipeline.releaseGLBuffers(); - - if (gSavedSettings.getBOOL("VertexShaderEnable")) - { - LLPipeline::sWaterReflections = gGLManager.mHasCubeMap; - LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); - } - else - { - LLPipeline::sRenderGlow = - LLPipeline::sWaterReflections = FALSE; - } - - //hack to reset buffers that change behavior with shaders - gPipeline.resetVertexBuffers(); - - if (gViewerWindow) - { - gViewerWindow->setCursor(UI_CURSOR_WAIT); - } - - // Lighting - gPipeline.setLightingDetail(-1); - - // Shaders - LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL; - for (S32 i = 0; i < SHADER_COUNT; i++) - { - sVertexShaderLevel[i] = 0; - } - sMaxAvatarShaderLevel = 0; - - if (LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") - && gSavedSettings.getBOOL("VertexShaderEnable")) - { - S32 light_class = 2; - S32 env_class = 2; - S32 obj_class = 2; - S32 effect_class = 2; - S32 wl_class = 2; - S32 water_class = 2; - S32 deferred_class = 0; - if (!gSavedSettings.getBOOL("WindLightUseAtmosShaders")) - { - // user has disabled WindLight in their settings, downgrade - // windlight shaders to stub versions. - wl_class = 1; - - // if class one or less, turn off more shaders - // since higher end cards won't see any real gain - // from turning off most of the shaders, - // but class one would - // TODO: Make water on class one cards color things - // beneath it properly - if(LLFeatureManager::getInstance()->getGPUClass() < GPU_CLASS_2) - { - // use lesser water and other stuff - light_class = 2; - env_class = 0; - obj_class = 0; - effect_class = 1; - water_class = 1; - } - } - - if (gSavedSettings.getBOOL("RenderDeferred")) - { - light_class = 1; - env_class = 0; - obj_class = 0; - water_class = 1; - effect_class = 1; - deferred_class = 1; - } - - if(!gSavedSettings.getBOOL("EnableRippleWater")) - { - water_class = 0; - } - - // Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders - if (sVertexShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull()) - { - gSky.mVOSkyp->forceSkyUpdate(); - } - - // Load lighting shaders - sVertexShaderLevel[SHADER_LIGHTING] = light_class; - sVertexShaderLevel[SHADER_INTERFACE] = light_class; - sVertexShaderLevel[SHADER_ENVIRONMENT] = env_class; - sVertexShaderLevel[SHADER_WATER] = water_class; - sVertexShaderLevel[SHADER_OBJECT] = obj_class; - sVertexShaderLevel[SHADER_EFFECT] = effect_class; - sVertexShaderLevel[SHADER_WINDLIGHT] = wl_class; - sVertexShaderLevel[SHADER_DEFERRED] = deferred_class; - - BOOL loaded = loadBasicShaders(); - - if (loaded) - { - gPipeline.mVertexShadersEnabled = TRUE; - gPipeline.mVertexShadersLoaded = 1; - - // Load all shaders to set max levels - loadShadersEnvironment(); - loadShadersWater(); - loadShadersObject(); - loadShadersWindLight(); - loadShadersEffects(); - loadShadersInterface(); - loadShadersDeferred(); - - // Load max avatar shaders to set the max level - sVertexShaderLevel[SHADER_AVATAR] = 3; - sMaxAvatarShaderLevel = 3; - loadShadersAvatar(); - -#if 0 && LL_DARWIN // force avatar shaders off for mac - sVertexShaderLevel[SHADER_AVATAR] = 0; - sMaxAvatarShaderLevel = 0; -#else - if (gSavedSettings.getBOOL("RenderAvatarVP")) - { - BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth"); - S32 avatar_class = 1; - - // cloth is a class3 shader - if(avatar_cloth) - { - avatar_class = 3; - } - - // Set the actual level - sVertexShaderLevel[SHADER_AVATAR] = avatar_class; - loadShadersAvatar(); - if (sVertexShaderLevel[SHADER_AVATAR] != avatar_class) - { - if (sVertexShaderLevel[SHADER_AVATAR] == 0) - { - gSavedSettings.setBOOL("RenderAvatarVP", FALSE); - } - if(llmax(sVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3) - { - avatar_cloth = true; - } - else - { - avatar_cloth = false; - } - gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth); - } - } - else - { - sVertexShaderLevel[SHADER_AVATAR] = 0; - gSavedSettings.setBOOL("RenderAvatarCloth", FALSE); - loadShadersAvatar(); // unloads - } -#endif - } - else - { - gPipeline.mVertexShadersEnabled = FALSE; - gPipeline.mVertexShadersLoaded = 0; - sVertexShaderLevel[SHADER_LIGHTING] = 0; - sVertexShaderLevel[SHADER_INTERFACE] = 0; - sVertexShaderLevel[SHADER_ENVIRONMENT] = 0; - sVertexShaderLevel[SHADER_WATER] = 0; - sVertexShaderLevel[SHADER_OBJECT] = 0; - sVertexShaderLevel[SHADER_EFFECT] = 0; - sVertexShaderLevel[SHADER_WINDLIGHT] = 0; - } - } - else - { - gPipeline.mVertexShadersEnabled = FALSE; - gPipeline.mVertexShadersLoaded = 0; - sVertexShaderLevel[SHADER_LIGHTING] = 0; - sVertexShaderLevel[SHADER_INTERFACE] = 0; - sVertexShaderLevel[SHADER_ENVIRONMENT] = 0; - sVertexShaderLevel[SHADER_WATER] = 0; - sVertexShaderLevel[SHADER_OBJECT] = 0; - sVertexShaderLevel[SHADER_EFFECT] = 0; - sVertexShaderLevel[SHADER_WINDLIGHT] = 0; - } - - if (gViewerWindow) - { - gViewerWindow->setCursor(UI_CURSOR_ARROW); - } - gPipeline.createGLBuffers(); -} - -void LLShaderMgr::unloadShaders() -{ - gObjectSimpleProgram.unload(); - gObjectSimpleWaterProgram.unload(); - gObjectFullbrightProgram.unload(); - gObjectFullbrightWaterProgram.unload(); - - gObjectShinyProgram.unload(); - gObjectFullbrightShinyProgram.unload(); - gObjectShinyWaterProgram.unload(); - gWaterProgram.unload(); - gUnderWaterProgram.unload(); - gTerrainProgram.unload(); - gTerrainWaterProgram.unload(); - gGlowProgram.unload(); - gGlowExtractProgram.unload(); - gAvatarProgram.unload(); - gAvatarWaterProgram.unload(); - gAvatarEyeballProgram.unload(); - gAvatarPickProgram.unload(); - gHighlightProgram.unload(); - - gWLSkyProgram.unload(); - gWLCloudProgram.unload(); - - gPostColorFilterProgram.unload(); - gPostNightVisionProgram.unload(); - - gDeferredDiffuseProgram.unload(); - - sVertexShaderLevel[SHADER_LIGHTING] = 0; - sVertexShaderLevel[SHADER_OBJECT] = 0; - sVertexShaderLevel[SHADER_AVATAR] = 0; - sVertexShaderLevel[SHADER_ENVIRONMENT] = 0; - sVertexShaderLevel[SHADER_WATER] = 0; - sVertexShaderLevel[SHADER_INTERFACE] = 0; - - gPipeline.mVertexShadersLoaded = 0; -} - -BOOL LLShaderMgr::loadBasicShaders() -{ - // Load basic dependency shaders first - // All of these have to load for any shaders to function - -#if LL_DARWIN // Mac can't currently handle all 8 lights, - S32 sum_lights_class = 2; -#else - S32 sum_lights_class = 3; - - // class one cards will get the lower sum lights - // class zero we're not going to think about - // since a class zero card COULD be a ridiculous new card - // and old cards should have the features masked - if(LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_1) - { - sum_lights_class = 2; - } -#endif - - // If we have sun and moon only checked, then only sum those lights. - if (gPipeline.getLightingDetail() == 0) - { - sum_lights_class = 1; - } - - // Load the Basic Vertex Shaders at the appropriate level. - // (in order of shader function call depth for reference purposes, deepest level first) - - vector< pair > shaders; - shaders.reserve(10); - shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "lighting/lightFuncV.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) ); - shaders.push_back( make_pair( "lighting/lightV.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) ); - shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) ); - - // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now. - for (U32 i = 0; i < shaders.size(); i++) - { - // Note usage of GL_VERTEX_SHADER_ARB - if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB) == 0) - { - return FALSE; - } - } - - // Load the Basic Fragment Shaders at the appropriate level. - // (in order of shader function call depth for reference purposes, deepest level first) - - shaders.clear(); - shaders.reserve(12); - shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "windlight/gammaF.glsl", sVertexShaderLevel[SHADER_WINDLIGHT]) ); - shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "windlight/transportF.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) ); - shaders.push_back( make_pair( "environment/waterFogF.glsl", sVertexShaderLevel[SHADER_WATER] ) ); - shaders.push_back( make_pair( "lighting/lightF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/lightWaterF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/lightShinyF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); - shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) ); - - for (U32 i = 0; i < shaders.size(); i++) - { - // Note usage of GL_FRAGMENT_SHADER_ARB - if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB) == 0) - { - return FALSE; - } - } - - return TRUE; -} - -BOOL LLShaderMgr::loadShadersEnvironment() -{ - BOOL success = TRUE; - - if (sVertexShaderLevel[SHADER_ENVIRONMENT] == 0) - { - gTerrainProgram.unload(); - return FALSE; - } - - if (success) - { - gTerrainProgram.mName = "Terrain Shader"; - gTerrainProgram.mFeatures.calculatesLighting = true; - gTerrainProgram.mFeatures.calculatesAtmospherics = true; - gTerrainProgram.mFeatures.hasAtmospherics = true; - gTerrainProgram.mFeatures.hasGamma = true; - gTerrainProgram.mShaderFiles.clear(); - gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB)); - gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); - gTerrainProgram.mShaderLevel = sVertexShaderLevel[SHADER_ENVIRONMENT]; - success = gTerrainProgram.createShader(NULL, &sTerrainUniforms); - } - - if (!success) - { - sVertexShaderLevel[SHADER_ENVIRONMENT] = 0; - return FALSE; - } - - LLWorld::getInstance()->updateWaterObjects(); - - return TRUE; -} - -BOOL LLShaderMgr::loadShadersWater() -{ - BOOL success = TRUE; - BOOL terrainWaterSuccess = TRUE; - - if (sVertexShaderLevel[SHADER_WATER] == 0) - { - gWaterProgram.unload(); - gUnderWaterProgram.unload(); - gTerrainWaterProgram.unload(); - return FALSE; - } - - if (success) - { - // load water shader - gWaterProgram.mName = "Water Shader"; - gWaterProgram.mFeatures.calculatesAtmospherics = true; - gWaterProgram.mFeatures.hasGamma = true; - gWaterProgram.mFeatures.hasTransport = true; - gWaterProgram.mShaderFiles.clear(); - gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB)); - gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_WATER]; - success = gWaterProgram.createShader(NULL, &sWaterUniforms); - } - - if (success) - { - //load under water vertex shader - gUnderWaterProgram.mName = "Underwater Shader"; - gUnderWaterProgram.mFeatures.calculatesAtmospherics = true; - gUnderWaterProgram.mShaderFiles.clear(); - gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB)); - gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gUnderWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_WATER]; - gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - - success = gUnderWaterProgram.createShader(NULL, &sWaterUniforms); - } - - if (success) - { - //load terrain water shader - gTerrainWaterProgram.mName = "Terrain Water Shader"; - gTerrainWaterProgram.mFeatures.calculatesLighting = true; - gTerrainWaterProgram.mFeatures.calculatesAtmospherics = true; - gTerrainWaterProgram.mFeatures.hasAtmospherics = true; - gTerrainWaterProgram.mFeatures.hasWaterFog = true; - gTerrainWaterProgram.mShaderFiles.clear(); - gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB)); - gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gTerrainWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_ENVIRONMENT]; - gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, &sTerrainUniforms); - } - - /// Keep track of water shader levels - if (gWaterProgram.mShaderLevel != sVertexShaderLevel[SHADER_WATER] - || gUnderWaterProgram.mShaderLevel != sVertexShaderLevel[SHADER_WATER]) - { - sVertexShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel); - } - - if (!success) - { - sVertexShaderLevel[SHADER_WATER] = 0; - return FALSE; - } - - // if we failed to load the terrain water shaders and we need them (using class2 water), - // then drop down to class1 water. - if (sVertexShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess) - { - sVertexShaderLevel[SHADER_WATER]--; - return loadShadersWater(); - } - - LLWorld::getInstance()->updateWaterObjects(); - - return TRUE; -} - -BOOL LLShaderMgr::loadShadersEffects() -{ - BOOL success = TRUE; - - if (sVertexShaderLevel[SHADER_EFFECT] == 0) - { - gGlowProgram.unload(); - gGlowExtractProgram.unload(); - gPostColorFilterProgram.unload(); - gPostNightVisionProgram.unload(); - return FALSE; - } - - if (success) - { - gGlowProgram.mName = "Glow Shader (Post)"; - gGlowProgram.mShaderFiles.clear(); - gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB)); - gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB)); - gGlowProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT]; - success = gGlowProgram.createShader(NULL, &sGlowUniforms); - if (!success) - { - LLPipeline::sRenderGlow = FALSE; - } - } - - if (success) - { - gGlowExtractProgram.mName = "Glow Extract Shader (Post)"; - gGlowExtractProgram.mShaderFiles.clear(); - gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB)); - gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB)); - gGlowExtractProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT]; - success = gGlowExtractProgram.createShader(NULL, &sGlowExtractUniforms); - if (!success) - { - LLPipeline::sRenderGlow = FALSE; - } - } - -#if 0 - // disabling loading of postprocess shaders until we fix - // ATI sampler2DRect compatibility. - - //load Color Filter Shader - if (success) - { - vector shaderUniforms; - shaderUniforms.reserve(7); - shaderUniforms.push_back("RenderTexture"); - shaderUniforms.push_back("gamma"); - shaderUniforms.push_back("brightness"); - shaderUniforms.push_back("contrast"); - shaderUniforms.push_back("contrastBase"); - shaderUniforms.push_back("saturation"); - shaderUniforms.push_back("lumWeights"); - - gPostColorFilterProgram.mName = "Color Filter Shader (Post)"; - gPostColorFilterProgram.mShaderFiles.clear(); - gPostColorFilterProgram.mShaderFiles.push_back(make_pair("effects/colorFilterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gPostColorFilterProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB)); - gPostColorFilterProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT]; - success = gPostColorFilterProgram.createShader(NULL, &shaderUniforms); - } - - //load Night Vision Shader - if (success) - { - vector shaderUniforms; - shaderUniforms.reserve(5); - shaderUniforms.push_back("RenderTexture"); - shaderUniforms.push_back("NoiseTexture"); - shaderUniforms.push_back("brightMult"); - shaderUniforms.push_back("noiseStrength"); - shaderUniforms.push_back("lumWeights"); - - gPostNightVisionProgram.mName = "Night Vision Shader (Post)"; - gPostNightVisionProgram.mShaderFiles.clear(); - gPostNightVisionProgram.mShaderFiles.push_back(make_pair("effects/nightVisionF.glsl", GL_FRAGMENT_SHADER_ARB)); - gPostNightVisionProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB)); - gPostNightVisionProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT]; - success = gPostNightVisionProgram.createShader(NULL, &shaderUniforms); - } - #endif - - return success; - -} - -BOOL LLShaderMgr::loadShadersDeferred() -{ - if (sVertexShaderLevel[SHADER_DEFERRED] == 0) - { - gDeferredDiffuseProgram.unload(); - return FALSE; - } - - BOOL success = TRUE; - - if (success) - { - gDeferredDiffuseProgram.mName = "Deffered Diffuse Shader"; - gDeferredDiffuseProgram.mShaderFiles.clear(); - gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredDiffuseProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredDiffuseProgram.createShader(NULL, NULL); - } - - return success; -} - -BOOL LLShaderMgr::loadShadersObject() -{ - BOOL success = TRUE; - - if (sVertexShaderLevel[SHADER_OBJECT] == 0) - { - gObjectShinyProgram.unload(); - gObjectFullbrightShinyProgram.unload(); - gObjectShinyWaterProgram.unload(); - gObjectSimpleProgram.unload(); - gObjectSimpleWaterProgram.unload(); - gObjectFullbrightProgram.unload(); - gObjectFullbrightWaterProgram.unload(); - return FALSE; - } - - if (success) - { - gObjectSimpleProgram.mName = "Simple Shader"; - gObjectSimpleProgram.mFeatures.calculatesLighting = true; - gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleProgram.mFeatures.hasGamma = true; - gObjectSimpleProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleProgram.mFeatures.hasLighting = true; - gObjectSimpleProgram.mShaderFiles.clear(); - gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectSimpleProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; - success = gObjectSimpleProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectSimpleWaterProgram.mName = "Simple Water Shader"; - gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true; - gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectSimpleWaterProgram.mFeatures.hasWaterFog = true; - gObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true; - gObjectSimpleWaterProgram.mFeatures.hasLighting = true; - gObjectSimpleWaterProgram.mShaderFiles.clear(); - gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectSimpleWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; - gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectSimpleWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightProgram.mName = "Fullbright Shader"; - gObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightProgram.mFeatures.hasGamma = true; - gObjectFullbrightProgram.mFeatures.hasTransport = true; - gObjectFullbrightProgram.mFeatures.isFullbright = true; - gObjectFullbrightProgram.mShaderFiles.clear(); - gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectFullbrightWaterProgram.mName = "Fullbright Water Shader"; - gObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightWaterProgram.mFeatures.isFullbright = true; - gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; - gObjectFullbrightWaterProgram.mFeatures.hasTransport = true; - gObjectFullbrightWaterProgram.mShaderFiles.clear(); - gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; - gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectFullbrightWaterProgram.createShader(NULL, NULL); - } - - if (success) - { - gObjectShinyProgram.mName = "Shiny Shader"; - gObjectShinyProgram.mFeatures.calculatesAtmospherics = true; - gObjectShinyProgram.mFeatures.calculatesLighting = true; - gObjectShinyProgram.mFeatures.hasGamma = true; - gObjectShinyProgram.mFeatures.hasAtmospherics = true; - gObjectShinyProgram.mFeatures.isShiny = true; - gObjectShinyProgram.mShaderFiles.clear(); - gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectShinyProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; - success = gObjectShinyProgram.createShader(NULL, &sShinyUniforms); - } - - if (success) - { - gObjectShinyWaterProgram.mName = "Shiny Water Shader"; - gObjectShinyWaterProgram.mFeatures.calculatesAtmospherics = true; - gObjectShinyWaterProgram.mFeatures.calculatesLighting = true; - gObjectShinyWaterProgram.mFeatures.isShiny = true; - gObjectShinyWaterProgram.mFeatures.hasWaterFog = true; - gObjectShinyWaterProgram.mFeatures.hasAtmospherics = true; - gObjectShinyWaterProgram.mShaderFiles.clear(); - gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectShinyWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; - gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gObjectShinyWaterProgram.createShader(NULL, &sShinyUniforms); - } - - if (success) - { - gObjectFullbrightShinyProgram.mName = "Fullbright Shiny Shader"; - gObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; - gObjectFullbrightShinyProgram.mFeatures.isFullbright = true; - gObjectFullbrightShinyProgram.mFeatures.isShiny = true; - gObjectFullbrightShinyProgram.mFeatures.hasGamma = true; - gObjectFullbrightShinyProgram.mFeatures.hasTransport = true; - gObjectFullbrightShinyProgram.mShaderFiles.clear(); - gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); - gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gObjectFullbrightShinyProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT]; - success = gObjectFullbrightShinyProgram.createShader(NULL, &sShinyUniforms); - } - - - if( !success ) - { - sVertexShaderLevel[SHADER_OBJECT] = 0; - return FALSE; - } - - return TRUE; -} - -BOOL LLShaderMgr::loadShadersAvatar() -{ - BOOL success = TRUE; - - if (sVertexShaderLevel[SHADER_AVATAR] == 0) - { - gAvatarProgram.unload(); - gAvatarWaterProgram.unload(); - gAvatarEyeballProgram.unload(); - gAvatarPickProgram.unload(); - return FALSE; - } - - if (success) - { - gAvatarProgram.mName = "Avatar Shader"; - gAvatarProgram.mFeatures.hasSkinning = true; - gAvatarProgram.mFeatures.calculatesAtmospherics = true; - gAvatarProgram.mFeatures.calculatesLighting = true; - gAvatarProgram.mFeatures.hasGamma = true; - gAvatarProgram.mFeatures.hasAtmospherics = true; - gAvatarProgram.mFeatures.hasLighting = true; - gAvatarProgram.mShaderFiles.clear(); - gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB)); - gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); - gAvatarProgram.mShaderLevel = sVertexShaderLevel[SHADER_AVATAR]; - success = gAvatarProgram.createShader(&sAvatarAttribs, &sAvatarUniforms); - - if (success) - { - gAvatarWaterProgram.mName = "Avatar Water Shader"; - gAvatarWaterProgram.mFeatures.hasSkinning = true; - gAvatarWaterProgram.mFeatures.calculatesAtmospherics = true; - gAvatarWaterProgram.mFeatures.calculatesLighting = true; - gAvatarWaterProgram.mFeatures.hasWaterFog = true; - gAvatarWaterProgram.mFeatures.hasAtmospherics = true; - gAvatarWaterProgram.mFeatures.hasLighting = true; - gAvatarWaterProgram.mShaderFiles.clear(); - gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB)); - gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); - // Note: no cloth under water: - gAvatarWaterProgram.mShaderLevel = llmin(sVertexShaderLevel[SHADER_AVATAR], 1); - gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; - success = gAvatarWaterProgram.createShader(&sAvatarAttribs, &sAvatarUniforms); - } - - /// Keep track of avatar levels - if (gAvatarProgram.mShaderLevel != sVertexShaderLevel[SHADER_AVATAR]) - { - sMaxAvatarShaderLevel = sVertexShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel; - } - } - - if (success) - { - gAvatarPickProgram.mName = "Avatar Pick Shader"; - gAvatarPickProgram.mFeatures.hasSkinning = true; - gAvatarPickProgram.mShaderFiles.clear(); - gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB)); - gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB)); - gAvatarPickProgram.mShaderLevel = sVertexShaderLevel[SHADER_AVATAR]; - success = gAvatarPickProgram.createShader(&sAvatarAttribs, &sAvatarUniforms); - } - - if (success) - { - gAvatarEyeballProgram.mName = "Avatar Eyeball Program"; - gAvatarEyeballProgram.mFeatures.calculatesLighting = true; - gAvatarEyeballProgram.mFeatures.isSpecular = true; - gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true; - gAvatarEyeballProgram.mFeatures.hasGamma = true; - gAvatarEyeballProgram.mFeatures.hasAtmospherics = true; - gAvatarEyeballProgram.mFeatures.hasLighting = true; - gAvatarEyeballProgram.mShaderFiles.clear(); - gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB)); - gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB)); - gAvatarEyeballProgram.mShaderLevel = sVertexShaderLevel[SHADER_AVATAR]; - success = gAvatarEyeballProgram.createShader(NULL, NULL); - } - - if( !success ) - { - sVertexShaderLevel[SHADER_AVATAR] = 0; - sMaxAvatarShaderLevel = 0; - return FALSE; - } - - return TRUE; -} - -BOOL LLShaderMgr::loadShadersInterface() -{ - BOOL success = TRUE; - - if (sVertexShaderLevel[SHADER_INTERFACE] == 0) - { - gHighlightProgram.unload(); - return FALSE; - } - - if (success) - { - gHighlightProgram.mName = "Highlight Shader"; - gHighlightProgram.mShaderFiles.clear(); - gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB)); - gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB)); - gHighlightProgram.mShaderLevel = sVertexShaderLevel[SHADER_INTERFACE]; - success = gHighlightProgram.createShader(NULL, NULL); - } - - if( !success ) - { - sVertexShaderLevel[SHADER_INTERFACE] = 0; - return FALSE; - } - - return TRUE; -} - -BOOL LLShaderMgr::loadShadersWindLight() -{ - BOOL success = TRUE; - - if (sVertexShaderLevel[SHADER_WINDLIGHT] < 2) - { - gWLSkyProgram.unload(); - gWLCloudProgram.unload(); - return FALSE; - } - - if (success) - { - gWLSkyProgram.mName = "Windlight Sky Shader"; - //gWLSkyProgram.mFeatures.hasGamma = true; - gWLSkyProgram.mShaderFiles.clear(); - gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyV.glsl", GL_VERTEX_SHADER_ARB)); - gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER_ARB)); - gWLSkyProgram.mShaderLevel = sVertexShaderLevel[SHADER_WINDLIGHT]; - gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gWLSkyProgram.createShader(NULL, &sWLUniforms); - } - - if (success) - { - gWLCloudProgram.mName = "Windlight Cloud Program"; - //gWLCloudProgram.mFeatures.hasGamma = true; - gWLCloudProgram.mShaderFiles.clear(); - gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsV.glsl", GL_VERTEX_SHADER_ARB)); - gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB)); - gWLCloudProgram.mShaderLevel = sVertexShaderLevel[SHADER_WINDLIGHT]; - gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gWLCloudProgram.createShader(NULL, &sWLUniforms); - } - - return success; -} - - -//=============================== -// LLGLSL Shader implementation -//=============================== -LLGLSLShader::LLGLSLShader() -: mProgramObject(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT) -{ -} - -void LLGLSLShader::unload() -{ - stop_glerror(); - mAttribute.clear(); - mTexture.clear(); - mUniform.clear(); - mShaderFiles.clear(); - - if (mProgramObject) - { - GLhandleARB obj[1024]; - GLsizei count; - - glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj); - for (GLsizei i = 0; i < count; i++) - { - glDeleteObjectARB(obj[i]); - } - - glDeleteObjectARB(mProgramObject); - - mProgramObject = 0; - } - - //hack to make apple not complain - glGetError(); - - stop_glerror(); -} - -BOOL LLGLSLShader::createShader(vector * attributes, - vector * uniforms) -{ - llassert_always(!mShaderFiles.empty()); - BOOL success = TRUE; - - // Create program - mProgramObject = glCreateProgramObjectARB(); - - // Attach existing objects - if (!LLShaderMgr::attachShaderFeatures(this)) - { - return FALSE; - } - - vector< pair >::iterator fileIter = mShaderFiles.begin(); - for ( ; fileIter != mShaderFiles.end(); fileIter++ ) - { - GLhandleARB shaderhandle = LLShaderMgr::loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second); - LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL; - if (mShaderLevel > 0) - { - attachObject(shaderhandle); - } - else - { - success = FALSE; - } - } - - // Map attributes and uniforms - if (success) - { - success = mapAttributes(attributes); - } - if (success) - { - success = mapUniforms(uniforms); - } - if( !success ) - { - LL_WARNS("ShaderLoading") << "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; - mShaderLevel--; - return createShader(attributes,uniforms); - } - } - return success; -} - -BOOL LLGLSLShader::attachObject(std::string object) -{ - if (LLShaderMgr::sShaderObjects.count(object) > 0) - { - stop_glerror(); - glAttachObjectARB(mProgramObject, LLShaderMgr::sShaderObjects[object]); - stop_glerror(); - return TRUE; - } - else - { - LL_WARNS("ShaderLoading") << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL; - return FALSE; - } -} - -void LLGLSLShader::attachObject(GLhandleARB object) -{ - if (object != 0) - { - stop_glerror(); - glAttachObjectARB(mProgramObject, object); - stop_glerror(); - } - else - { - LL_WARNS("ShaderLoading") << "Attempting to attach non existing shader object. " << LL_ENDL; - } -} - -void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count) -{ - for (S32 i = 0; i < count; i++) - { - attachObject(objects[i]); - } -} - -BOOL LLGLSLShader::mapAttributes(const vector * attributes) -{ - //link the program - BOOL res = link(); - - mAttribute.clear(); - U32 numAttributes = (attributes == NULL) ? 0 : attributes->size(); - mAttribute.resize(LLShaderMgr::sReservedAttribs.size() + numAttributes, -1); - - if (res) - { //read back channel locations - - //read back reserved channels first - for (U32 i = 0; i < (S32) LLShaderMgr::sReservedAttribs.size(); i++) - { - const char* name = LLShaderMgr::sReservedAttribs[i].c_str(); - S32 index = glGetAttribLocationARB(mProgramObject, (GLcharARB *)name); - if (index != -1) - { - mAttribute[i] = index; - LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL; - } - } - if (attributes != NULL) - { - for (U32 i = 0; i < numAttributes; i++) - { - const char* name = (*attributes)[i].c_str(); - S32 index = glGetAttribLocationARB(mProgramObject, name); - if (index != -1) - { - mAttribute[LLShaderMgr::sReservedAttribs.size() + i] = index; - LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL; - } - } - } - - return TRUE; - } - - return FALSE; -} - -void LLGLSLShader::mapUniform(GLint index, const vector * uniforms) -{ - if (index == -1) - { - return; - } - - GLenum type; - GLsizei length; - GLint size; - char name[1024]; /* Flawfinder: ignore */ - name[0] = 0; - - glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name); - S32 location = glGetUniformLocationARB(mProgramObject, name); - if (location != -1) - { - mUniformMap[name] = location; - LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL; - - //find the index of this uniform - for (S32 i = 0; i < (S32) LLShaderMgr::sReservedUniforms.size(); i++) - { - if ( (mUniform[i] == -1) - && (LLShaderMgr::sReservedUniforms[i].compare(0, length, name, LLShaderMgr::sReservedUniforms[i].length()) == 0)) - { - //found it - mUniform[i] = location; - mTexture[i] = mapUniformTextureChannel(location, type); - return; - } - } - - if (uniforms != NULL) - { - for (U32 i = 0; i < uniforms->size(); i++) - { - if ( (mUniform[i+LLShaderMgr::sReservedUniforms.size()] == -1) - && ((*uniforms)[i].compare(0, length, name, (*uniforms)[i].length()) == 0)) - { - //found it - mUniform[i+LLShaderMgr::sReservedUniforms.size()] = location; - mTexture[i+LLShaderMgr::sReservedUniforms.size()] = mapUniformTextureChannel(location, type); - return; - } - } - } - } - } - -GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type) -{ - if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB) - { //this here is a texture - glUniform1iARB(location, mActiveTextureChannels); - LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL; - return mActiveTextureChannels++; - } - return -1; -} - -BOOL LLGLSLShader::mapUniforms(const vector * uniforms) -{ - BOOL res = TRUE; - - mActiveTextureChannels = 0; - mUniform.clear(); - mUniformMap.clear(); - mTexture.clear(); - mValue.clear(); - //initialize arrays - U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size(); - mUniform.resize(numUniforms + LLShaderMgr::sReservedUniforms.size(), -1); - mTexture.resize(numUniforms + LLShaderMgr::sReservedUniforms.size(), -1); - - bind(); - - //get the number of active uniforms - GLint activeCount; - glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount); - - for (S32 i = 0; i < activeCount; i++) - { - mapUniform(i, uniforms); - } - - unbind(); - - return res; -} - -BOOL LLGLSLShader::link(BOOL suppress_errors) -{ - return LLShaderMgr::linkProgramObject(mProgramObject, suppress_errors); -} - -void LLGLSLShader::bind() -{ - if (gGLManager.mHasShaderObjects) - { - glUseProgramObjectARB(mProgramObject); - - if (mUniformsDirty) - { - LLWLParamManager::instance()->updateShaderUniforms(this); - LLWaterParamManager::instance()->updateShaderUniforms(this); - mUniformsDirty = FALSE; - } - } -} - -void LLGLSLShader::unbind() -{ - if (gGLManager.mHasShaderObjects) - { - for (U32 i = 0; i < mAttribute.size(); ++i) - { - vertexAttrib4f(i, 0,0,0,1); - } - glUseProgramObjectARB(0); - } -} - -void LLGLSLShader::bindNoShader(void) -{ - glUseProgramObjectARB(0); -} - -S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode) -{ - if (uniform < 0 || uniform >= (S32)mTexture.size()) - { - UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; - return -1; - } - S32 index = mTexture[uniform]; - if (index != -1) - { - gGL.getTexUnit(index)->activate(); - glEnable(mode); - } - return index; -} - -S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode) -{ - if (uniform < 0 || uniform >= (S32)mTexture.size()) - { - UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL; - return -1; - } - S32 index = mTexture[uniform]; - if (index != -1) - { - gGL.getTexUnit(index)->activate(); - glDisable(mode); - } - return index; -} - -void LLGLSLShader::uniform1f(U32 index, GLfloat x) -{ - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map::iterator iter = mValue.find(mUniform[index]); - if (iter == mValue.end() || iter->second.mV[0] != x) - { - glUniform1fARB(mUniform[index], x); - mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f); - } - } - } -} - -void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y) -{ - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(x,y,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform2fARB(mUniform[index], x, y); - mValue[mUniform[index]] = vec; - } - } - } -} - -void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z) -{ - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(x,y,z,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform3fARB(mUniform[index], x, y, z); - mValue[mUniform[index]] = vec; - } - } - } -} - -void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(x,y,z,w); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform4fARB(mUniform[index], x, y, z, w); - mValue[mUniform[index]] = vec; - } - } - } -} - -void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v) -{ - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(v[0],0.f,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform1fvARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; - } - } - } -} - -void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v) -{ - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(v[0],v[1],0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform2fvARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; - } - } - } -} - -void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v) -{ - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(v[0],v[1],v[2],0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform3fvARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; - } - } - } -} - -void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v) -{ - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - std::map::iterator iter = mValue.find(mUniform[index]); - LLVector4 vec(v[0],v[1],v[2],v[3]); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform4fvARB(mUniform[index], count, v); - mValue[mUniform[index]] = vec; - } - } - } -} - -void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) -{ - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - glUniformMatrix2fvARB(mUniform[index], count, transpose, v); - } - } -} - -void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) -{ - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - glUniformMatrix3fvARB(mUniform[index], count, transpose, v); - } - } -} - -void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v) -{ - if (mProgramObject > 0) - { - if (mUniform.size() <= index) - { - UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL; - return; - } - - if (mUniform[index] >= 0) - { - glUniformMatrix4fvARB(mUniform[index], count, transpose, v); - } - } -} - -GLint LLGLSLShader::getUniformLocation(const string& uniform) -{ - if (mProgramObject > 0) - { - std::map::iterator iter = mUniformMap.find(uniform); - if (iter != mUniformMap.end()) - { - llassert(iter->second == glGetUniformLocationARB(mProgramObject, uniform.c_str())); - return iter->second; - } - } - - return -1; -} - -void LLGLSLShader::uniform1f(const string& uniform, GLfloat v) -{ - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map::iterator iter = mValue.find(location); - LLVector4 vec(v,0.f,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform1fARB(location, v); - mValue[location] = vec; - } - } -} - -void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y) -{ - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map::iterator iter = mValue.find(location); - LLVector4 vec(x,y,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform2fARB(location, x,y); - mValue[location] = vec; - } - } - -} - -void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloat z) -{ - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map::iterator iter = mValue.find(location); - LLVector4 vec(x,y,z,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform3fARB(location, x,y,z); - mValue[location] = vec; - } - } -} - -void LLGLSLShader::uniform4f(const string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map::iterator iter = mValue.find(location); - LLVector4 vec(x,y,z,w); - if (iter == mValue.end() || shouldChange(iter->second,vec)) - { - glUniform4fARB(location, x,y,z,w); - mValue[location] = vec; - } - } -} - -void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v) -{ - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map::iterator iter = mValue.find(location); - LLVector4 vec(v[0],0.f,0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform1fvARB(location, count, v); - mValue[location] = vec; - } - } -} - -void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v) -{ - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map::iterator iter = mValue.find(location); - LLVector4 vec(v[0],v[1],0.f,0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform2fvARB(location, count, v); - mValue[location] = vec; - } - } -} - -void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v) -{ - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - std::map::iterator iter = mValue.find(location); - LLVector4 vec(v[0],v[1],v[2],0.f); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform3fvARB(location, count, v); - mValue[location] = vec; - } - } -} - -void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v) -{ - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - LLVector4 vec(v); - std::map::iterator iter = mValue.find(location); - if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1) - { - glUniform4fvARB(location, count, v); - mValue[location] = vec; - } - } -} - -void LLGLSLShader::uniformMatrix2fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v) -{ - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - glUniformMatrix2fvARB(location, count, transpose, v); - } -} - -void LLGLSLShader::uniformMatrix3fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v) -{ - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - glUniformMatrix3fvARB(location, count, transpose, v); - } -} - -void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v) -{ - GLint location = getUniformLocation(uniform); - - if (location >= 0) - { - glUniformMatrix4fvARB(location, count, transpose, v); - } -} - - -void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - if (mAttribute[index] > 0) - { - glVertexAttrib4fARB(mAttribute[index], x, y, z, w); - } -} - -void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v) -{ - if (mAttribute[index] > 0) - { - glVertexAttrib4fvARB(mAttribute[index], v); - } -} -- cgit v1.1