llglslshader.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llfeaturemanager.h"
00035 #include "llglslshader.h"
00036 
00037 #include "llfile.h"
00038 #include "llviewerwindow.h"
00039 #include "llviewercontrol.h"
00040 #include "pipeline.h"
00041 #include "llworld.h"
00042 #include "llwlparammanager.h"
00043 #include "llwaterparammanager.h"
00044 #include "llsky.h"
00045 #include "llvosky.h"
00046 #include "llglimmediate.h"
00047 
00048 #if LL_DARWIN
00049 #include "OpenGL/OpenGL.h"
00050 #endif
00051 
00052 #ifdef LL_RELEASE_FOR_DOWNLOAD
00053 #define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
00054 #else
00055 #define UNIFORM_ERRS LL_ERRS("Shader")
00056 #endif
00057 
00058 // Lots of STL stuff in here, using namespace std to keep things more readable
00059 using std::vector;
00060 using std::pair;
00061 using std::make_pair;
00062 using std::string;
00063 
00064 LLVector4                       gShinyOrigin;
00065 
00066 //object shaders
00067 LLGLSLShader            gObjectSimpleProgram;
00068 LLGLSLShader            gObjectSimpleWaterProgram;
00069 LLGLSLShader            gObjectFullbrightProgram;
00070 LLGLSLShader            gObjectFullbrightWaterProgram;
00071 
00072 LLGLSLShader            gObjectFullbrightShinyProgram;
00073 LLGLSLShader            gObjectShinyProgram;
00074 LLGLSLShader            gObjectShinyWaterProgram;
00075 
00076 //environment shaders
00077 LLGLSLShader            gTerrainProgram;
00078 LLGLSLShader            gTerrainWaterProgram;
00079 LLGLSLShader            gWaterProgram;
00080 LLGLSLShader            gUnderWaterProgram;
00081 
00082 //interface shaders
00083 LLGLSLShader            gHighlightProgram;
00084 
00085 //avatar skinning utility shader object
00086 GLhandleARB                     gAvatarSkinVertex;
00087 
00088 //avatar shader handles
00089 LLGLSLShader            gAvatarProgram;
00090 LLGLSLShader            gAvatarWaterProgram;
00091 LLGLSLShader            gAvatarEyeballProgram;
00092 LLGLSLShader            gAvatarPickProgram;
00093 
00094 // WindLight shader handles
00095 LLGLSLShader                    gWLSkyProgram;
00096 LLGLSLShader                    gWLCloudProgram;
00097 
00098 // Effects Shaders
00099 LLGLSLShader                    gGlowProgram;
00100 LLGLSLShader                    gGlowExtractProgram;
00101 LLGLSLShader                    gPostColorFilterProgram;
00102 LLGLSLShader                    gPostNightVisionProgram;
00103 
00104 // Deferred rendering shaders
00105 LLGLSLShader                    gDeferredDiffuseProgram;
00106 
00107 //current avatar shader parameter pointer
00108 GLint                           gAvatarMatrixParam;
00109 
00110 S32     LLShaderMgr::sVertexShaderLevel[SHADER_COUNT] = { 0 };
00111 
00112 S32     LLShaderMgr::sMaxAvatarShaderLevel = 0;
00113 
00114 std::map<string, GLhandleARB> LLShaderMgr::sShaderObjects;
00115 vector<string> LLShaderMgr::sReservedAttribs;
00116 vector<string> LLShaderMgr::sWLUniforms;
00117 vector<string> LLShaderMgr::sTerrainUniforms;
00118 vector<string> LLShaderMgr::sReservedUniforms;
00119 vector<string> LLShaderMgr::sShinyUniforms;
00120 vector<string> LLShaderMgr::sWaterUniforms;
00121 vector<string> LLShaderMgr::sGlowUniforms;
00122 vector<string> LLShaderMgr::sGlowExtractUniforms;
00123 vector<string> LLShaderMgr::sAvatarAttribs;
00124 vector<string> LLShaderMgr::sAvatarUniforms;
00125 //vector< GLhandleARB > LLShaderMgr::sBaseObjects;
00126 
00128 LLGLSLShader * const LLShaderMgr::sShaderList[] = 
00129 {
00130         &gWLSkyProgram,
00131         &gWLCloudProgram,
00132         &gAvatarProgram,
00133         &gObjectShinyProgram,
00134         &gWaterProgram,
00135         &gAvatarEyeballProgram, 
00136         &gObjectSimpleProgram,
00137         &gObjectFullbrightProgram,
00138         &gObjectFullbrightShinyProgram,
00139         &gTerrainProgram,
00140         &gTerrainWaterProgram,
00141         &gObjectSimpleWaterProgram,
00142         &gObjectFullbrightWaterProgram,
00143         &gAvatarWaterProgram,
00144         &gObjectShinyWaterProgram,
00145         &gUnderWaterProgram,
00146 };
00147 const size_t LLShaderMgr::sNumShaders = sizeof(sShaderList) / sizeof(sShaderList[0]);
00148 
00149 
00150 BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
00151 {
00152         /*F32 dot = v1.mV[0] * v2.mV[0] +
00153                                 v1.mV[1] * v2.mV[1] +
00154                                 v1.mV[2] * v2.mV[2] +
00155                                 v1.mV[3] * v2.mV[3];
00156 
00157         F32 mag = v1.mV[0] * v1.mV[0] +
00158                                 v1.mV[1] * v1.mV[1] +
00159                                 v1.mV[2] * v1.mV[2] +
00160                                 v1.mV[3] * v1.mV[3];
00161 
00162         F32 val = (dot/mag);
00163 
00164         if (val > 2.0f || val < 0.1f)
00165         {
00166                 return TRUE;
00167         }
00168 
00169         return FALSE;*/
00170 
00171         return v1 != v2;
00172 }
00173 
00174 LLShaderFeatures::LLShaderFeatures()
00175 : calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
00176 hasTransport(false), hasSkinning(false), hasAtmospherics(false), isSpecular(false),
00177 hasGamma(false), hasLighting(false), calculatesAtmospherics(false)
00178 {
00179 }
00180 
00181 void LLShaderMgr::initAttribsAndUniforms(void)
00182 {
00183         if (sReservedAttribs.empty())
00184         {
00185                 sReservedAttribs.push_back("materialColor");
00186                 sReservedAttribs.push_back("specularColor");
00187                 sReservedAttribs.push_back("binormal");
00188 
00189                 sAvatarAttribs.reserve(5);
00190                 sAvatarAttribs.push_back("weight");
00191                 sAvatarAttribs.push_back("clothing");
00192                 sAvatarAttribs.push_back("gWindDir");
00193                 sAvatarAttribs.push_back("gSinWaveParams");
00194                 sAvatarAttribs.push_back("gGravity");
00195 
00196                 sAvatarUniforms.push_back("matrixPalette");
00197 
00198                 sReservedUniforms.reserve(24);
00199                 sReservedUniforms.push_back("diffuseMap");
00200                 sReservedUniforms.push_back("specularMap");
00201                 sReservedUniforms.push_back("bumpMap");
00202                 sReservedUniforms.push_back("environmentMap");
00203                 sReservedUniforms.push_back("cloude_noise_texture");
00204                 sReservedUniforms.push_back("fullbright");
00205                 sReservedUniforms.push_back("lightnorm");
00206                 sReservedUniforms.push_back("sunlight_color");
00207                 sReservedUniforms.push_back("ambient");
00208                 sReservedUniforms.push_back("blue_horizon");
00209                 sReservedUniforms.push_back("blue_density");
00210                 sReservedUniforms.push_back("haze_horizon");
00211                 sReservedUniforms.push_back("haze_density");
00212                 sReservedUniforms.push_back("cloud_shadow");
00213                 sReservedUniforms.push_back("density_multiplier");
00214                 sReservedUniforms.push_back("distance_multiplier");
00215                 sReservedUniforms.push_back("max_y");
00216                 sReservedUniforms.push_back("glow");
00217                 sReservedUniforms.push_back("cloud_color");
00218                 sReservedUniforms.push_back("cloud_pos_density1");
00219                 sReservedUniforms.push_back("cloud_pos_density2");
00220                 sReservedUniforms.push_back("cloud_scale");
00221                 sReservedUniforms.push_back("gamma");
00222                 sReservedUniforms.push_back("scene_light_strength");
00223 
00224                 sWLUniforms.push_back("camPosLocal");
00225 
00226                 sTerrainUniforms.reserve(5);
00227                 sTerrainUniforms.push_back("detail_0");
00228                 sTerrainUniforms.push_back("detail_1");
00229                 sTerrainUniforms.push_back("detail_2");
00230                 sTerrainUniforms.push_back("detail_3");
00231                 sTerrainUniforms.push_back("alpha_ramp");
00232 
00233                 sGlowUniforms.push_back("glowDelta");
00234                 sGlowUniforms.push_back("glowStrength");
00235 
00236                 sGlowExtractUniforms.push_back("minLuminance");
00237                 sGlowExtractUniforms.push_back("maxExtractAlpha");
00238                 sGlowExtractUniforms.push_back("lumWeights");
00239                 sGlowExtractUniforms.push_back("warmthWeights");
00240                 sGlowExtractUniforms.push_back("warmthAmount");
00241 
00242                 sShinyUniforms.push_back("origin");
00243 
00244                 sWaterUniforms.reserve(12);
00245                 sWaterUniforms.push_back("screenTex");
00246                 sWaterUniforms.push_back("screenDepth");
00247                 sWaterUniforms.push_back("refTex");
00248                 sWaterUniforms.push_back("eyeVec");
00249                 sWaterUniforms.push_back("time");
00250                 sWaterUniforms.push_back("d1");
00251                 sWaterUniforms.push_back("d2");
00252                 sWaterUniforms.push_back("lightDir");
00253                 sWaterUniforms.push_back("specular");
00254                 sWaterUniforms.push_back("lightExp");
00255                 sWaterUniforms.push_back("fogCol");
00256                 sWaterUniforms.push_back("kd");
00257                 sWaterUniforms.push_back("refScale");
00258                 sWaterUniforms.push_back("waterHeight");
00259         }       
00260 }
00261 
00262 BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
00263 {
00264         llassert_always(shader != NULL);
00265         LLShaderFeatures *features = & shader->mFeatures;
00266         
00268         // Attach Vertex Shader Features First
00270         
00271         // NOTE order of shader object attaching is VERY IMPORTANT!!!
00272         if (features->calculatesAtmospherics)
00273         {
00274                 if (!shader->attachObject("windlight/atmosphericsVarsV.glsl"))
00275                 {
00276                         return FALSE;
00277                 }
00278         }
00279 
00280         if (features->calculatesLighting)
00281         {
00282                 if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl"))
00283                 {
00284                         return FALSE;
00285                 }
00286                 
00287                 if (features->isSpecular)
00288                 {
00289                         if (!shader->attachObject("lighting/lightFuncSpecularV.glsl"))
00290                         {
00291                                 return FALSE;
00292                         }
00293                         
00294                         if (!shader->attachObject("lighting/sumLightsSpecularV.glsl"))
00295                         {
00296                                 return FALSE;
00297                         }
00298                         
00299                         if (!shader->attachObject("lighting/lightSpecularV.glsl"))
00300                         {
00301                                 return FALSE;
00302                         }
00303                 }
00304                 else 
00305                 {
00306                         if (!shader->attachObject("lighting/lightFuncV.glsl"))
00307                         {
00308                                 return FALSE;
00309                         }
00310                         
00311                         if (!shader->attachObject("lighting/sumLightsV.glsl"))
00312                         {
00313                                 return FALSE;
00314                         }
00315                         
00316                         if (!shader->attachObject("lighting/lightV.glsl"))
00317                         {
00318                                 return FALSE;
00319                         }
00320                 }
00321         }
00322         
00323         // NOTE order of shader object attaching is VERY IMPORTANT!!!
00324         if (features->calculatesAtmospherics)
00325         {
00326                 if (!shader->attachObject("windlight/atmosphericsV.glsl"))
00327                 {
00328                         return FALSE;
00329                 }
00330         }
00331 
00332         if (features->hasSkinning)
00333         {
00334                 if (!shader->attachObject("avatar/avatarSkinV.glsl"))
00335                 {
00336                         return FALSE;
00337                 }
00338         }
00339         
00341         // Attach Fragment Shader Features Next
00343 
00344         if(features->calculatesAtmospherics)
00345         {
00346                 if (!shader->attachObject("windlight/atmosphericsVarsF.glsl"))
00347                 {
00348                         return FALSE;
00349                 }
00350         }
00351 
00352         // NOTE order of shader object attaching is VERY IMPORTANT!!!
00353         if (features->hasGamma)
00354         {
00355                 if (!shader->attachObject("windlight/gammaF.glsl"))
00356                 {
00357                         return FALSE;
00358                 }
00359         }
00360         
00361         if (features->hasAtmospherics)
00362         {
00363                 if (!shader->attachObject("windlight/atmosphericsF.glsl"))
00364                 {
00365                         return FALSE;
00366                 }
00367         }
00368         
00369         if (features->hasTransport)
00370         {
00371                 if (!shader->attachObject("windlight/transportF.glsl"))
00372                 {
00373                         return FALSE;
00374                 }
00375 
00376                 // Test hasFullbright and hasShiny and attach fullbright and 
00377                 // fullbright shiny atmos transport if we split them out.
00378         }
00379 
00380         // NOTE order of shader object attaching is VERY IMPORTANT!!!
00381         if (features->hasWaterFog)
00382         {
00383                 if (!shader->attachObject("environment/waterFogF.glsl"))
00384                 {
00385                         return FALSE;
00386                 }
00387         }
00388         
00389         if (features->hasLighting)
00390         {
00391         
00392                 if (features->hasWaterFog)
00393                 {
00394                         if (!shader->attachObject("lighting/lightWaterF.glsl"))
00395                         {
00396                                 return FALSE;
00397                         }
00398                 }
00399                 
00400                 else
00401                 {
00402                         if (!shader->attachObject("lighting/lightF.glsl"))
00403                         {
00404                                 return FALSE;
00405                         }
00406                 }               
00407         }
00408         
00409         // NOTE order of shader object attaching is VERY IMPORTANT!!!
00410         else if (features->isFullbright)
00411         {
00412         
00413                 if (features->hasWaterFog)
00414                 {
00415                         if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
00416                         {
00417                                 return FALSE;
00418                         }
00419                 }
00420                 
00421                 else if (features->isShiny)
00422                 {
00423                         if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl"))
00424                         {
00425                                 return FALSE;
00426                         }
00427                 }
00428                 
00429                 else
00430                 {
00431                         if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
00432                         {
00433                                 return FALSE;
00434                         }
00435                 }
00436         }
00437 
00438         // NOTE order of shader object attaching is VERY IMPORTANT!!!
00439         else if (features->isShiny)
00440         {
00441         
00442                 if (features->hasWaterFog)
00443                 {
00444                         if (!shader->attachObject("lighting/lightShinyWaterF.glsl"))
00445                         {
00446                                 return FALSE;
00447                         }
00448                 }
00449                 
00450                 else 
00451                 {
00452                         if (!shader->attachObject("lighting/lightShinyF.glsl"))
00453                         {
00454                                 return FALSE;
00455                         }
00456                 }
00457         }
00458         return TRUE;
00459 }
00460 
00461 //============================================================================
00462 // Set Levels
00463 
00464 S32 LLShaderMgr::getVertexShaderLevel(S32 type)
00465 {
00466         return LLPipeline::sDisableShaders ? 0 : sVertexShaderLevel[type];
00467 }
00468 
00469 
00470 //============================================================================
00471 // Load Shader
00472 
00473 static LLString get_object_log(GLhandleARB ret)
00474 {
00475         LLString res;
00476         
00477         //get log length 
00478         GLint length;
00479         glGetObjectParameterivARB(ret, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
00480         if (length > 0)
00481         {
00482                 //the log could be any size, so allocate appropriately
00483                 GLcharARB* log = new GLcharARB[length];
00484                 glGetInfoLogARB(ret, length, &length, log);
00485                 res = LLString((char *)log);
00486                 delete[] log;
00487         }
00488         return res;
00489 }
00490 
00491 void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns) 
00492 {
00493         LLString log = get_object_log(ret);
00494         if (warns)
00495         {
00496                 LL_WARNS("ShaderLoading") << log << LL_ENDL;
00497         }
00498         else
00499         {
00500                 LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
00501         }
00502 }
00503 
00504 GLhandleARB LLShaderMgr::loadShaderFile(const LLString& filename, S32 & shader_level, GLenum type)
00505 {
00506         GLenum error;
00507         error = glGetError();
00508         if (error != GL_NO_ERROR)
00509         {
00510                 LL_WARNS("ShaderLoading") << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL;
00511         }
00512         
00513         LL_DEBUGS("ShaderLoading") << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL;
00514 
00515         if (filename.empty()) 
00516         {
00517                 return 0;
00518         }
00519 
00520 
00521         //read in from file
00522         LLFILE* file = NULL;
00523 
00524         S32 try_gpu_class = shader_level;
00525         S32 gpu_class;
00526 
00527         //find the most relevant file
00528         for (gpu_class = try_gpu_class; gpu_class > 0; gpu_class--)
00529         {       //search from the current gpu class down to class 1 to find the most relevant shader
00530                 std::stringstream fname;
00531                 fname << gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
00532                 fname << gpu_class << "/" << filename;
00533                 
00534                 LL_DEBUGS("ShaderLoading") << "Looking in " << fname.str().c_str() << LL_ENDL;
00535                 file = LLFile::fopen(fname.str().c_str(), "r");         /* Flawfinder: ignore */
00536                 if (file)
00537                 {
00538                         LL_INFOS("ShaderLoading") << "Loading file: shaders/class" << gpu_class << "/" << filename << " (Want class " << gpu_class << ")" << LL_ENDL;
00539                         break; // done
00540                 }
00541         }
00542         
00543         if (file == NULL)
00544         {
00545                 LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << filename << LL_ENDL;
00546                 return 0;
00547         }
00548 
00549         //we can't have any lines longer than 1024 characters 
00550         //or any shaders longer than 1024 lines... deal - DaveP
00551         GLcharARB buff[1024];
00552         GLcharARB* text[1024];
00553         GLuint count = 0;
00554 
00555 
00556         //copy file into memory
00557         while(fgets((char *)buff, 1024, file) != NULL && count < (sizeof(buff)/sizeof(buff[0]))) 
00558         {
00559                 text[count++] = (GLcharARB *)strdup((char *)buff); 
00560         }
00561         fclose(file);
00562 
00563         //create shader object
00564         GLhandleARB ret = glCreateShaderObjectARB(type);
00565         error = glGetError();
00566         if (error != GL_NO_ERROR)
00567         {
00568                 LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << LL_ENDL;
00569         }
00570         else
00571         {
00572                 //load source
00573                 glShaderSourceARB(ret, count, (const GLcharARB**) text, NULL);
00574                 error = glGetError();
00575                 if (error != GL_NO_ERROR)
00576                 {
00577                         LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << LL_ENDL;
00578                 }
00579                 else
00580                 {
00581                         //compile source
00582                         glCompileShaderARB(ret);
00583                         error = glGetError();
00584                         if (error != GL_NO_ERROR)
00585                         {
00586                                 LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << LL_ENDL;
00587                         }
00588                 }
00589         }
00590         //free memory
00591         for (GLuint i = 0; i < count; i++)
00592         {
00593                 free(text[i]);
00594         }
00595         if (error == GL_NO_ERROR)
00596         {
00597                 //check for errors
00598                 GLint success = GL_TRUE;
00599                 glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success);
00600                 error = glGetError();
00601                 if (error != GL_NO_ERROR || success == GL_FALSE) 
00602                 {
00603                         //an error occured, print log
00604                         LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
00605                         dumpObjectLog(ret);
00606                         ret = 0;
00607                 }
00608         }
00609         else
00610         {
00611                 ret = 0;
00612         }
00613         stop_glerror();
00614 
00615         //successfully loaded, save results
00616         if (ret)
00617         {
00618                 // Add shader file to map
00619                 sShaderObjects[filename] = ret;
00620                 shader_level = try_gpu_class;
00621         }
00622         else
00623         {
00624                 if (shader_level > 1)
00625                 {
00626                         shader_level--;
00627                         return loadShaderFile(filename,shader_level,type);
00628                 }
00629                 LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;  
00630         }
00631         return ret;
00632 }
00633 
00634 BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors) 
00635 {
00636         //check for errors
00637         glLinkProgramARB(obj);
00638         GLint success = GL_TRUE;
00639         glGetObjectParameterivARB(obj, GL_OBJECT_LINK_STATUS_ARB, &success);
00640         if (!suppress_errors && success == GL_FALSE) 
00641         {
00642                 //an error occured, print log
00643                 LL_WARNS("ShaderLoading") << "GLSL Linker Error:" << LL_ENDL;
00644         }
00645 
00646 // NOTE: Removing LL_DARWIN block as it doesn't seem to actually give the correct answer, 
00647 // but want it for reference once I move it.
00648 #if 0
00649         // Force an evaluation of the gl state so the driver can tell if the shader will run in hardware or software
00650         // per Apple's suggestion   
00651         glBegin(gGL.mMode);
00652         glEnd();
00653 
00654         // Query whether the shader can or cannot run in hardware
00655         // http://developer.apple.com/qa/qa2007/qa1502.html
00656         long vertexGPUProcessing;
00657         CGLContextObj ctx = CGLGetCurrentContext();
00658         CGLGetParameter (ctx, kCGLCPGPUVertexProcessing, &vertexGPUProcessing); 
00659         long fragmentGPUProcessing;
00660         CGLGetParameter (ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing);
00661         if (!fragmentGPUProcessing || !vertexGPUProcessing)
00662         {
00663                 LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
00664                 success = GL_FALSE;
00665                 suppress_errors = FALSE;                
00666         }
00667         
00668 #else
00669         LLString log = get_object_log(obj);
00670         LLString::toLower(log);
00671         if (log.find("software") != LLString::npos)
00672         {
00673                 LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
00674                 success = GL_FALSE;
00675                 suppress_errors = FALSE;
00676         }
00677 #endif
00678         if (!suppress_errors)
00679         {
00680         dumpObjectLog(obj, !success);
00681         }
00682 
00683         return success;
00684 }
00685 
00686 BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj)
00687 {
00688         //check program validity against current GL
00689         glValidateProgramARB(obj);
00690         GLint success = GL_TRUE;
00691         glGetObjectParameterivARB(obj, GL_OBJECT_VALIDATE_STATUS_ARB, &success);
00692         if (success == GL_FALSE)
00693         {
00694                 LL_WARNS("ShaderLoading") << "GLSL program not valid: " << LL_ENDL;
00695                 dumpObjectLog(obj);
00696         }
00697         else
00698         {
00699                 dumpObjectLog(obj, FALSE);
00700         }
00701 
00702         return success;
00703 }
00704 
00705 //============================================================================
00706 // Shader Management
00707 
00708 void LLShaderMgr::setShaders()
00709 {
00710         if (!gPipeline.mInitialized)
00711         {
00712                 return;
00713         }
00714         // Make sure the compiled shader map is cleared before we recompile shaders.
00715         sShaderObjects.clear();
00716         
00717         initAttribsAndUniforms();
00718         gPipeline.releaseGLBuffers();
00719 
00720         if (gSavedSettings.getBOOL("VertexShaderEnable"))
00721         {
00722                 LLPipeline::sDynamicReflections = gSavedSettings.getBOOL("RenderDynamicReflections") && gGLManager.mHasCubeMap && LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap");
00723                 LLPipeline::sWaterReflections = gGLManager.mHasCubeMap;
00724                 LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); 
00725         }
00726         else
00727         {
00728                 LLPipeline::sDynamicReflections = 
00729                         LLPipeline::sRenderGlow = 
00730                         LLPipeline::sWaterReflections = FALSE;
00731         }
00732         
00733         //hack to reset buffers that change behavior with shaders
00734         gPipeline.resetVertexBuffers();
00735 
00736         if (gViewerWindow)
00737         {
00738                 gViewerWindow->setCursor(UI_CURSOR_WAIT);
00739         }
00740 
00741         // Lighting
00742         gPipeline.setLightingDetail(-1);
00743 
00744         // Shaders
00745         LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL;
00746         for (S32 i = 0; i < SHADER_COUNT; i++)
00747         {
00748                 sVertexShaderLevel[i] = 0;
00749         }
00750         sMaxAvatarShaderLevel = 0;
00751 
00752         if (LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") 
00753                 && gSavedSettings.getBOOL("VertexShaderEnable"))
00754         {
00755                 S32 light_class = 2;
00756                 S32 env_class = 2;
00757                 S32 obj_class = 2;
00758                 S32 effect_class = 2;
00759                 S32 wl_class = 2;
00760                 S32 water_class = 2;
00761                 S32 deferred_class = 0;
00762                 if (!gSavedSettings.getBOOL("WindLightUseAtmosShaders"))
00763                 {
00764                         // user has disabled WindLight in their settings, downgrade
00765                         // windlight shaders to stub versions.
00766                         wl_class = 1;
00767 
00768                         // if class one or less, turn off more shaders
00769                         // since higher end cards won't see any real gain
00770                         // from turning off most of the shaders,
00771                         // but class one would
00772                         // TODO: Make water on class one cards color things
00773                         // beneath it properly
00774                         if(LLFeatureManager::getInstance()->getGPUClass() < GPU_CLASS_2)
00775                         {
00776                                 // use lesser water and other stuff
00777                                 light_class = 2;
00778                                 env_class = 0;
00779                                 obj_class = 0;
00780                                 effect_class = 1;
00781                                 water_class = 1;
00782                         }
00783                 }
00784 
00785                 if (gSavedSettings.getBOOL("RenderDeferred"))
00786                 {
00787                         light_class = 1;
00788                         env_class = 0;
00789                         obj_class = 0;
00790                         water_class = 1;
00791                         effect_class = 1;
00792                         deferred_class = 1;
00793                 }
00794 
00795                 if(!gSavedSettings.getBOOL("EnableRippleWater"))
00796                 {
00797                         water_class = 0;
00798                 }
00799 
00800                 // Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders
00801                 if (sVertexShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull())
00802                 {
00803                         gSky.mVOSkyp->forceSkyUpdate();
00804                 }
00805 
00806                 // Load lighting shaders
00807                 sVertexShaderLevel[SHADER_LIGHTING] = light_class;
00808                 sVertexShaderLevel[SHADER_INTERFACE] = light_class;
00809                 sVertexShaderLevel[SHADER_ENVIRONMENT] = env_class;
00810                 sVertexShaderLevel[SHADER_WATER] = water_class;
00811                 sVertexShaderLevel[SHADER_OBJECT] = obj_class;
00812                 sVertexShaderLevel[SHADER_EFFECT] = effect_class;
00813                 sVertexShaderLevel[SHADER_WINDLIGHT] = wl_class;
00814                 sVertexShaderLevel[SHADER_DEFERRED] = deferred_class;
00815 
00816                 BOOL loaded = loadBasicShaders();
00817 
00818                 if (loaded)
00819                 {
00820                         gPipeline.mVertexShadersEnabled = TRUE;
00821                         gPipeline.mVertexShadersLoaded = 1;
00822 
00823                         // Load all shaders to set max levels
00824                         loadShadersEnvironment();
00825                         loadShadersWater();
00826                         loadShadersObject();
00827                         loadShadersWindLight();
00828                         loadShadersEffects();
00829                         loadShadersInterface();
00830                         loadShadersDeferred();
00831 
00832                         // Load max avatar shaders to set the max level
00833                         sVertexShaderLevel[SHADER_AVATAR] = 3;
00834                         sMaxAvatarShaderLevel = 3;
00835                         loadShadersAvatar();
00836                         
00837 #if 0 && LL_DARWIN // force avatar shaders off for mac
00838                         sVertexShaderLevel[SHADER_AVATAR] = 0;
00839                         sMaxAvatarShaderLevel = 0;
00840 #else
00841                         if (gSavedSettings.getBOOL("RenderAvatarVP"))
00842                         {
00843                                 BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
00844                                 S32 avatar_class = 1;
00845                                 
00846                                 // cloth is a class3 shader
00847                                 if(avatar_cloth)
00848                                 {
00849                                         avatar_class = 3;
00850                                 }
00851 
00852                                 // Set the actual level
00853                                 sVertexShaderLevel[SHADER_AVATAR] = avatar_class;
00854                                 loadShadersAvatar();
00855                                 if (sVertexShaderLevel[SHADER_AVATAR] != avatar_class)
00856                                 {
00857                                         if (sVertexShaderLevel[SHADER_AVATAR] == 0)
00858                                         {
00859                                                 gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
00860                                         }
00861                                         if(llmax(sVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3)
00862                                         {
00863                                                 avatar_cloth = true;
00864                                         }
00865                                         else
00866                                         {
00867                                                 avatar_cloth = false;
00868                                         }
00869                                         gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
00870                                 }
00871                         }
00872                         else
00873                         {
00874                                 sVertexShaderLevel[SHADER_AVATAR] = 0;
00875                                 gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
00876                                 loadShadersAvatar(); // unloads
00877                         }
00878 #endif
00879                 }
00880                 else
00881                 {
00882                         gPipeline.mVertexShadersEnabled = FALSE;
00883                         gPipeline.mVertexShadersLoaded = 0;
00884                         sVertexShaderLevel[SHADER_LIGHTING] = 0;
00885                         sVertexShaderLevel[SHADER_INTERFACE] = 0;
00886                         sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
00887                         sVertexShaderLevel[SHADER_WATER] = 0;
00888                         sVertexShaderLevel[SHADER_OBJECT] = 0;
00889                         sVertexShaderLevel[SHADER_EFFECT] = 0;
00890                         sVertexShaderLevel[SHADER_WINDLIGHT] = 0;
00891                 }
00892         }
00893         else
00894         {
00895                 gPipeline.mVertexShadersEnabled = FALSE;
00896                 gPipeline.mVertexShadersLoaded = 0;
00897                 sVertexShaderLevel[SHADER_LIGHTING] = 0;
00898                 sVertexShaderLevel[SHADER_INTERFACE] = 0;
00899                 sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
00900                 sVertexShaderLevel[SHADER_WATER] = 0;
00901                 sVertexShaderLevel[SHADER_OBJECT] = 0;
00902                 sVertexShaderLevel[SHADER_EFFECT] = 0;
00903                 sVertexShaderLevel[SHADER_WINDLIGHT] = 0;
00904         }
00905         
00906         if (gViewerWindow)
00907         {
00908                 gViewerWindow->setCursor(UI_CURSOR_ARROW);
00909         }
00910         gPipeline.createGLBuffers();
00911 }
00912 
00913 void LLShaderMgr::unloadShaders()
00914 {
00915         gObjectSimpleProgram.unload();
00916         gObjectSimpleWaterProgram.unload();
00917         gObjectFullbrightProgram.unload();
00918         gObjectFullbrightWaterProgram.unload();
00919 
00920         gObjectShinyProgram.unload();
00921         gObjectFullbrightShinyProgram.unload();
00922         gObjectShinyWaterProgram.unload();
00923         gWaterProgram.unload();
00924         gUnderWaterProgram.unload();
00925         gTerrainProgram.unload();
00926         gTerrainWaterProgram.unload();
00927         gGlowProgram.unload();
00928         gGlowExtractProgram.unload();
00929         gAvatarProgram.unload();
00930         gAvatarWaterProgram.unload();
00931         gAvatarEyeballProgram.unload();
00932         gAvatarPickProgram.unload();
00933         gHighlightProgram.unload();
00934 
00935         gWLSkyProgram.unload();
00936         gWLCloudProgram.unload();
00937 
00938         gPostColorFilterProgram.unload();
00939         gPostNightVisionProgram.unload();
00940 
00941         gDeferredDiffuseProgram.unload();
00942 
00943         sVertexShaderLevel[SHADER_LIGHTING] = 0;
00944         sVertexShaderLevel[SHADER_OBJECT] = 0;
00945         sVertexShaderLevel[SHADER_AVATAR] = 0;
00946         sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
00947         sVertexShaderLevel[SHADER_WATER] = 0;
00948         sVertexShaderLevel[SHADER_INTERFACE] = 0;
00949 
00950         gPipeline.mVertexShadersLoaded = 0;
00951 }
00952 
00953 BOOL LLShaderMgr::loadBasicShaders()
00954 {
00955         // Load basic dependency shaders first
00956         // All of these have to load for any shaders to function
00957         
00958 #if LL_DARWIN // Mac can't currently handle all 8 lights, 
00959         S32 sum_lights_class = 2;
00960 #else 
00961         S32 sum_lights_class = 3;
00962 
00963         // class one cards will get the lower sum lights
00964         // class zero we're not going to think about
00965         // since a class zero card COULD be a ridiculous new card
00966         // and old cards should have the features masked
00967         if(LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_1)
00968         {
00969                 sum_lights_class = 2;
00970         }
00971 #endif
00972 
00973         // If we have sun and moon only checked, then only sum those lights.
00974         if (gPipeline.getLightingDetail() == 0)
00975         {
00976                 sum_lights_class = 1;
00977         }
00978 
00979         // Load the Basic Vertex Shaders at the appropriate level. 
00980         // (in order of shader function call depth for reference purposes, deepest level first)
00981 
00982         vector< pair<string, S32> > shaders;
00983         shaders.reserve(10);
00984         shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl",               sVertexShaderLevel[SHADER_WINDLIGHT] ) );
00985         shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl",    sVertexShaderLevel[SHADER_WINDLIGHT] ) );
00986         shaders.push_back( make_pair( "lighting/lightFuncV.glsl",                               sVertexShaderLevel[SHADER_LIGHTING] ) );
00987         shaders.push_back( make_pair( "lighting/sumLightsV.glsl",                               sum_lights_class ) );
00988         shaders.push_back( make_pair( "lighting/lightV.glsl",                                   sVertexShaderLevel[SHADER_LIGHTING] ) );
00989         shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl",               sVertexShaderLevel[SHADER_LIGHTING] ) );
00990         shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl",               sum_lights_class ) );
00991         shaders.push_back( make_pair( "lighting/lightSpecularV.glsl",                   sVertexShaderLevel[SHADER_LIGHTING] ) );
00992         shaders.push_back( make_pair( "windlight/atmosphericsV.glsl",                   sVertexShaderLevel[SHADER_WINDLIGHT] ) );
00993         shaders.push_back( make_pair( "avatar/avatarSkinV.glsl",                                1 ) );
00994 
00995         // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
00996         for (U32 i = 0; i < shaders.size(); i++)
00997         {
00998                 // Note usage of GL_VERTEX_SHADER_ARB
00999                 if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB) == 0)
01000                 {
01001                         return FALSE;
01002                 }
01003         }
01004 
01005         // Load the Basic Fragment Shaders at the appropriate level. 
01006         // (in order of shader function call depth for reference purposes, deepest level first)
01007 
01008         shaders.clear();
01009         shaders.reserve(12);
01010         shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl",               sVertexShaderLevel[SHADER_WINDLIGHT] ) );
01011         shaders.push_back( make_pair( "windlight/gammaF.glsl",                                  sVertexShaderLevel[SHADER_WINDLIGHT]) );
01012         shaders.push_back( make_pair( "windlight/atmosphericsF.glsl",                   sVertexShaderLevel[SHADER_WINDLIGHT] ) );
01013         shaders.push_back( make_pair( "windlight/transportF.glsl",                              sVertexShaderLevel[SHADER_WINDLIGHT] ) );       
01014         shaders.push_back( make_pair( "environment/waterFogF.glsl",                             sVertexShaderLevel[SHADER_WATER] ) );
01015         shaders.push_back( make_pair( "lighting/lightF.glsl",                                   sVertexShaderLevel[SHADER_LIGHTING] ) );
01016         shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl",                 sVertexShaderLevel[SHADER_LIGHTING] ) );
01017         shaders.push_back( make_pair( "lighting/lightWaterF.glsl",                              sVertexShaderLevel[SHADER_LIGHTING] ) );
01018         shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl",    sVertexShaderLevel[SHADER_LIGHTING] ) );
01019         shaders.push_back( make_pair( "lighting/lightShinyF.glsl",                              sVertexShaderLevel[SHADER_LIGHTING] ) );
01020         shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl",    sVertexShaderLevel[SHADER_LIGHTING] ) );
01021         shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl",                 sVertexShaderLevel[SHADER_LIGHTING] ) );
01022         
01023         for (U32 i = 0; i < shaders.size(); i++)
01024         {
01025                 // Note usage of GL_FRAGMENT_SHADER_ARB
01026                 if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB) == 0)
01027                 {
01028                         return FALSE;
01029                 }
01030         }
01031 
01032         return TRUE;
01033 }
01034 
01035 BOOL LLShaderMgr::loadShadersEnvironment()
01036 {
01037         BOOL success = TRUE;
01038 
01039         if (sVertexShaderLevel[SHADER_ENVIRONMENT] == 0)
01040         {
01041                 gTerrainProgram.unload();
01042                 return FALSE;
01043         }
01044 
01045         if (success)
01046         {
01047                 gTerrainProgram.mName = "Terrain Shader";
01048                 gTerrainProgram.mFeatures.calculatesLighting = true;
01049                 gTerrainProgram.mFeatures.calculatesAtmospherics = true;
01050                 gTerrainProgram.mFeatures.hasAtmospherics = true;
01051                 gTerrainProgram.mFeatures.hasGamma = true;
01052                 gTerrainProgram.mShaderFiles.clear();
01053                 gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));
01054                 gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
01055                 gTerrainProgram.mShaderLevel = sVertexShaderLevel[SHADER_ENVIRONMENT];
01056                 success = gTerrainProgram.createShader(NULL, &sTerrainUniforms);
01057         }
01058 
01059         if (!success)
01060         {
01061                 sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
01062                 return FALSE;
01063         }
01064         
01065         LLWorld::getInstance()->updateWaterObjects();
01066         
01067         return TRUE;
01068 }
01069 
01070 BOOL LLShaderMgr::loadShadersWater()
01071 {
01072         BOOL success = TRUE;
01073         BOOL terrainWaterSuccess = TRUE;
01074 
01075         if (sVertexShaderLevel[SHADER_WATER] == 0)
01076         {
01077                 gWaterProgram.unload();
01078                 gUnderWaterProgram.unload();
01079                 gTerrainWaterProgram.unload();
01080                 return FALSE;
01081         }
01082 
01083         if (success)
01084         {
01085                 // load water shader
01086                 gWaterProgram.mName = "Water Shader";
01087                 gWaterProgram.mFeatures.calculatesAtmospherics = true;
01088                 gWaterProgram.mFeatures.hasGamma = true;
01089                 gWaterProgram.mFeatures.hasTransport = true;
01090                 gWaterProgram.mShaderFiles.clear();
01091                 gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
01092                 gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
01093                 gWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_WATER];
01094                 success = gWaterProgram.createShader(NULL, &sWaterUniforms);
01095         }
01096 
01097         if (success)
01098         {
01099                 //load under water vertex shader
01100                 gUnderWaterProgram.mName = "Underwater Shader";
01101                 gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
01102                 gUnderWaterProgram.mShaderFiles.clear();
01103                 gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
01104                 gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
01105                 gUnderWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_WATER];
01106                 gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
01107                 
01108                 success = gUnderWaterProgram.createShader(NULL, &sWaterUniforms);
01109         }
01110 
01111         if (success)
01112         {
01113                 //load terrain water shader
01114                 gTerrainWaterProgram.mName = "Terrain Water Shader";
01115                 gTerrainWaterProgram.mFeatures.calculatesLighting = true;
01116                 gTerrainWaterProgram.mFeatures.calculatesAtmospherics = true;
01117                 gTerrainWaterProgram.mFeatures.hasAtmospherics = true;
01118                 gTerrainWaterProgram.mFeatures.hasWaterFog = true;
01119                 gTerrainWaterProgram.mShaderFiles.clear();
01120                 gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));
01121                 gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
01122                 gTerrainWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_ENVIRONMENT];
01123                 gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
01124                 terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, &sTerrainUniforms);
01125         }       
01126 
01128         if (gWaterProgram.mShaderLevel != sVertexShaderLevel[SHADER_WATER]
01129                 || gUnderWaterProgram.mShaderLevel != sVertexShaderLevel[SHADER_WATER])
01130         {
01131                 sVertexShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel);
01132         }
01133 
01134         if (!success)
01135         {
01136                 sVertexShaderLevel[SHADER_WATER] = 0;
01137                 return FALSE;
01138         }
01139 
01140         // if we failed to load the terrain water shaders and we need them (using class2 water),
01141         // then drop down to class1 water.
01142         if (sVertexShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess)
01143         {
01144                 sVertexShaderLevel[SHADER_WATER]--;
01145                 return loadShadersWater();
01146         }
01147         
01148         LLWorld::getInstance()->updateWaterObjects();
01149 
01150         return TRUE;
01151 }
01152 
01153 BOOL LLShaderMgr::loadShadersEffects()
01154 {
01155         BOOL success = TRUE;
01156 
01157         if (sVertexShaderLevel[SHADER_EFFECT] == 0)
01158         {
01159                 gGlowProgram.unload();
01160                 gGlowExtractProgram.unload();
01161                 gPostColorFilterProgram.unload();       
01162                 gPostNightVisionProgram.unload();
01163                 return FALSE;
01164         }
01165 
01166         if (success)
01167         {
01168                 gGlowProgram.mName = "Glow Shader (Post)";
01169                 gGlowProgram.mShaderFiles.clear();
01170                 gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB));
01171                 gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB));
01172                 gGlowProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT];
01173                 success = gGlowProgram.createShader(NULL, &sGlowUniforms);
01174                 if (!success)
01175                 {
01176                         LLPipeline::sRenderGlow = FALSE;
01177                 }
01178         }
01179         
01180         if (success)
01181         {
01182                 gGlowExtractProgram.mName = "Glow Extract Shader (Post)";
01183                 gGlowExtractProgram.mShaderFiles.clear();
01184                 gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB));
01185                 gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB));
01186                 gGlowExtractProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT];
01187                 success = gGlowExtractProgram.createShader(NULL, &sGlowExtractUniforms);
01188                 if (!success)
01189                 {
01190                         LLPipeline::sRenderGlow = FALSE;
01191                 }
01192         }
01193         
01194 #if 0
01195         // disabling loading of postprocess shaders until we fix
01196         // ATI sampler2DRect compatibility.
01197         
01198         //load Color Filter Shader
01199         if (success)
01200         {
01201                 vector<string> shaderUniforms;
01202                 shaderUniforms.reserve(7);
01203                 shaderUniforms.push_back("RenderTexture");
01204                 shaderUniforms.push_back("gamma");
01205                 shaderUniforms.push_back("brightness");
01206                 shaderUniforms.push_back("contrast");
01207                 shaderUniforms.push_back("contrastBase");
01208                 shaderUniforms.push_back("saturation");
01209                 shaderUniforms.push_back("lumWeights");
01210 
01211                 gPostColorFilterProgram.mName = "Color Filter Shader (Post)";
01212                 gPostColorFilterProgram.mShaderFiles.clear();
01213                 gPostColorFilterProgram.mShaderFiles.push_back(make_pair("effects/colorFilterF.glsl", GL_FRAGMENT_SHADER_ARB));
01214                 gPostColorFilterProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB));
01215                 gPostColorFilterProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT];
01216                 success = gPostColorFilterProgram.createShader(NULL, &shaderUniforms);
01217         }
01218 
01219         //load Night Vision Shader
01220         if (success)
01221         {
01222                 vector<string> shaderUniforms;
01223                 shaderUniforms.reserve(5);
01224                 shaderUniforms.push_back("RenderTexture");
01225                 shaderUniforms.push_back("NoiseTexture");
01226                 shaderUniforms.push_back("brightMult");
01227                 shaderUniforms.push_back("noiseStrength");
01228                 shaderUniforms.push_back("lumWeights");
01229 
01230                 gPostNightVisionProgram.mName = "Night Vision Shader (Post)";
01231                 gPostNightVisionProgram.mShaderFiles.clear();
01232                 gPostNightVisionProgram.mShaderFiles.push_back(make_pair("effects/nightVisionF.glsl", GL_FRAGMENT_SHADER_ARB));
01233                 gPostNightVisionProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB));
01234                 gPostNightVisionProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT];
01235                 success = gPostNightVisionProgram.createShader(NULL, &shaderUniforms);
01236         }
01237         #endif
01238 
01239         return success;
01240 
01241 }
01242 
01243 BOOL LLShaderMgr::loadShadersDeferred()
01244 {
01245         if (sVertexShaderLevel[SHADER_DEFERRED] == 0)
01246         {
01247                 gDeferredDiffuseProgram.unload();
01248                 return FALSE;
01249         }
01250 
01251         BOOL success = TRUE;
01252 
01253         if (success)
01254         {
01255                 gDeferredDiffuseProgram.mName = "Deffered Diffuse Shader";
01256                 gDeferredDiffuseProgram.mShaderFiles.clear();
01257                 gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
01258                 gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB));
01259                 gDeferredDiffuseProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED];
01260                 success = gDeferredDiffuseProgram.createShader(NULL, NULL);
01261         }
01262 
01263         return success;
01264 }
01265 
01266 BOOL LLShaderMgr::loadShadersObject()
01267 {
01268         BOOL success = TRUE;
01269 
01270         if (sVertexShaderLevel[SHADER_OBJECT] == 0)
01271         {
01272                 gObjectShinyProgram.unload();
01273                 gObjectFullbrightShinyProgram.unload();
01274                 gObjectShinyWaterProgram.unload();
01275                 gObjectSimpleProgram.unload();
01276                 gObjectSimpleWaterProgram.unload();
01277                 gObjectFullbrightProgram.unload();
01278                 gObjectFullbrightWaterProgram.unload();
01279                 return FALSE;
01280         }
01281 
01282         if (success)
01283         {
01284                 gObjectSimpleProgram.mName = "Simple Shader";
01285                 gObjectSimpleProgram.mFeatures.calculatesLighting = true;
01286                 gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true;
01287                 gObjectSimpleProgram.mFeatures.hasGamma = true;
01288                 gObjectSimpleProgram.mFeatures.hasAtmospherics = true;
01289                 gObjectSimpleProgram.mFeatures.hasLighting = true;
01290                 gObjectSimpleProgram.mShaderFiles.clear();
01291                 gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
01292                 gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
01293                 gObjectSimpleProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
01294                 success = gObjectSimpleProgram.createShader(NULL, NULL);
01295         }
01296         
01297         if (success)
01298         {
01299                 gObjectSimpleWaterProgram.mName = "Simple Water Shader";
01300                 gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true;
01301                 gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true;
01302                 gObjectSimpleWaterProgram.mFeatures.hasWaterFog = true;
01303                 gObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true;
01304                 gObjectSimpleWaterProgram.mFeatures.hasLighting = true;
01305                 gObjectSimpleWaterProgram.mShaderFiles.clear();
01306                 gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
01307                 gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
01308                 gObjectSimpleWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
01309                 gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
01310                 success = gObjectSimpleWaterProgram.createShader(NULL, NULL);
01311         }
01312         
01313         if (success)
01314         {
01315                 gObjectFullbrightProgram.mName = "Fullbright Shader";
01316                 gObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true;
01317                 gObjectFullbrightProgram.mFeatures.hasGamma = true;
01318                 gObjectFullbrightProgram.mFeatures.hasTransport = true;
01319                 gObjectFullbrightProgram.mFeatures.isFullbright = true;
01320                 gObjectFullbrightProgram.mShaderFiles.clear();
01321                 gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
01322                 gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
01323                 gObjectFullbrightProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
01324                 success = gObjectFullbrightProgram.createShader(NULL, NULL);
01325         }
01326 
01327         if (success)
01328         {
01329                 gObjectFullbrightWaterProgram.mName = "Fullbright Water Shader";
01330                 gObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
01331                 gObjectFullbrightWaterProgram.mFeatures.isFullbright = true;
01332                 gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;             
01333                 gObjectFullbrightWaterProgram.mFeatures.hasTransport = true;
01334                 gObjectFullbrightWaterProgram.mShaderFiles.clear();
01335                 gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
01336                 gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
01337                 gObjectFullbrightWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
01338                 gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
01339                 success = gObjectFullbrightWaterProgram.createShader(NULL, NULL);
01340         }
01341 
01342         if (success)
01343         {
01344                 gObjectShinyProgram.mName = "Shiny Shader";
01345                 gObjectShinyProgram.mFeatures.calculatesAtmospherics = true;
01346                 gObjectShinyProgram.mFeatures.calculatesLighting = true;
01347                 gObjectShinyProgram.mFeatures.hasGamma = true;
01348                 gObjectShinyProgram.mFeatures.hasAtmospherics = true;
01349                 gObjectShinyProgram.mFeatures.isShiny = true;
01350                 gObjectShinyProgram.mShaderFiles.clear();
01351                 gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
01352                 gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));           
01353                 gObjectShinyProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
01354                 success = gObjectShinyProgram.createShader(NULL, &sShinyUniforms);
01355         }
01356 
01357         if (success)
01358         {
01359                 gObjectShinyWaterProgram.mName = "Shiny Water Shader";
01360                 gObjectShinyWaterProgram.mFeatures.calculatesAtmospherics = true;
01361                 gObjectShinyWaterProgram.mFeatures.calculatesLighting = true;
01362                 gObjectShinyWaterProgram.mFeatures.isShiny = true;
01363                 gObjectShinyWaterProgram.mFeatures.hasWaterFog = true;
01364                 gObjectShinyWaterProgram.mFeatures.hasAtmospherics = true;
01365                 gObjectShinyWaterProgram.mShaderFiles.clear();
01366                 gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
01367                 gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
01368                 gObjectShinyWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
01369                 gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
01370                 success = gObjectShinyWaterProgram.createShader(NULL, &sShinyUniforms);
01371         }
01372         
01373         if (success)
01374         {
01375                 gObjectFullbrightShinyProgram.mName = "Fullbright Shiny Shader";
01376                 gObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
01377                 gObjectFullbrightShinyProgram.mFeatures.isFullbright = true;
01378                 gObjectFullbrightShinyProgram.mFeatures.isShiny = true;
01379                 gObjectFullbrightShinyProgram.mFeatures.hasGamma = true;
01380                 gObjectFullbrightShinyProgram.mFeatures.hasTransport = true;
01381                 gObjectFullbrightShinyProgram.mShaderFiles.clear();
01382                 gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
01383                 gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
01384                 gObjectFullbrightShinyProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
01385                 success = gObjectFullbrightShinyProgram.createShader(NULL, &sShinyUniforms);
01386         }
01387 
01388 
01389         if( !success )
01390         {
01391                 sVertexShaderLevel[SHADER_OBJECT] = 0;
01392                 return FALSE;
01393         }
01394         
01395         return TRUE;
01396 }
01397 
01398 BOOL LLShaderMgr::loadShadersAvatar()
01399 {
01400         BOOL success = TRUE;
01401 
01402         if (sVertexShaderLevel[SHADER_AVATAR] == 0)
01403         {
01404                 gAvatarProgram.unload();
01405                 gAvatarWaterProgram.unload();
01406                 gAvatarEyeballProgram.unload();
01407                 gAvatarPickProgram.unload();
01408                 return FALSE;
01409         }
01410 
01411         if (success)
01412         {
01413                 gAvatarProgram.mName = "Avatar Shader";
01414                 gAvatarProgram.mFeatures.hasSkinning = true;
01415                 gAvatarProgram.mFeatures.calculatesAtmospherics = true;
01416                 gAvatarProgram.mFeatures.calculatesLighting = true;
01417                 gAvatarProgram.mFeatures.hasGamma = true;
01418                 gAvatarProgram.mFeatures.hasAtmospherics = true;
01419                 gAvatarProgram.mFeatures.hasLighting = true;
01420                 gAvatarProgram.mShaderFiles.clear();
01421                 gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
01422                 gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));
01423                 gAvatarProgram.mShaderLevel = sVertexShaderLevel[SHADER_AVATAR];
01424                 success = gAvatarProgram.createShader(&sAvatarAttribs, &sAvatarUniforms);
01425                         
01426                 if (success)
01427                 {
01428                         gAvatarWaterProgram.mName = "Avatar Water Shader";
01429                         gAvatarWaterProgram.mFeatures.hasSkinning = true;
01430                         gAvatarWaterProgram.mFeatures.calculatesAtmospherics = true;
01431                         gAvatarWaterProgram.mFeatures.calculatesLighting = true;
01432                         gAvatarWaterProgram.mFeatures.hasWaterFog = true;
01433                         gAvatarWaterProgram.mFeatures.hasAtmospherics = true;
01434                         gAvatarWaterProgram.mFeatures.hasLighting = true;
01435                         gAvatarWaterProgram.mShaderFiles.clear();
01436                         gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
01437                         gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
01438                         // Note: no cloth under water:
01439                         gAvatarWaterProgram.mShaderLevel = llmin(sVertexShaderLevel[SHADER_AVATAR], 1); 
01440                         gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;                              
01441                         success = gAvatarWaterProgram.createShader(&sAvatarAttribs, &sAvatarUniforms);
01442                 }
01443 
01445                 if (gAvatarProgram.mShaderLevel != sVertexShaderLevel[SHADER_AVATAR])
01446                 {
01447                         sMaxAvatarShaderLevel = sVertexShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel;
01448                 }
01449         }
01450 
01451         if (success)
01452         {
01453                 gAvatarPickProgram.mName = "Avatar Pick Shader";
01454                 gAvatarPickProgram.mFeatures.hasSkinning = true;
01455                 gAvatarPickProgram.mShaderFiles.clear();
01456                 gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB));
01457                 gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB));
01458                 gAvatarPickProgram.mShaderLevel = sVertexShaderLevel[SHADER_AVATAR];
01459                 success = gAvatarPickProgram.createShader(&sAvatarAttribs, &sAvatarUniforms);
01460         }
01461 
01462         if (success)
01463         {
01464                 gAvatarEyeballProgram.mName = "Avatar Eyeball Program";
01465                 gAvatarEyeballProgram.mFeatures.calculatesLighting = true;
01466                 gAvatarEyeballProgram.mFeatures.isSpecular = true;
01467                 gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true;
01468                 gAvatarEyeballProgram.mFeatures.hasGamma = true;
01469                 gAvatarEyeballProgram.mFeatures.hasAtmospherics = true;
01470                 gAvatarEyeballProgram.mFeatures.hasLighting = true;
01471                 gAvatarEyeballProgram.mShaderFiles.clear();
01472                 gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB));
01473                 gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB));
01474                 gAvatarEyeballProgram.mShaderLevel = sVertexShaderLevel[SHADER_AVATAR];
01475                 success = gAvatarEyeballProgram.createShader(NULL, NULL);
01476         }
01477 
01478         if( !success )
01479         {
01480                 sVertexShaderLevel[SHADER_AVATAR] = 0;
01481                 sMaxAvatarShaderLevel = 0;
01482                 return FALSE;
01483         }
01484         
01485         return TRUE;
01486 }
01487 
01488 BOOL LLShaderMgr::loadShadersInterface()
01489 {
01490         BOOL success = TRUE;
01491 
01492         if (sVertexShaderLevel[SHADER_INTERFACE] == 0)
01493         {
01494                 gHighlightProgram.unload();
01495                 return FALSE;
01496         }
01497         
01498         if (success)
01499         {
01500                 gHighlightProgram.mName = "Highlight Shader";
01501                 gHighlightProgram.mShaderFiles.clear();
01502                 gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB));
01503                 gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
01504                 gHighlightProgram.mShaderLevel = sVertexShaderLevel[SHADER_INTERFACE];          
01505                 success = gHighlightProgram.createShader(NULL, NULL);
01506         }
01507 
01508         if( !success )
01509         {
01510                 sVertexShaderLevel[SHADER_INTERFACE] = 0;
01511                 return FALSE;
01512         }
01513         
01514         return TRUE;
01515 }
01516 
01517 BOOL LLShaderMgr::loadShadersWindLight()
01518 {       
01519         BOOL success = TRUE;
01520 
01521         if (sVertexShaderLevel[SHADER_WINDLIGHT] < 2)
01522         {
01523                 gWLSkyProgram.unload();
01524                 gWLCloudProgram.unload();
01525                 return FALSE;
01526         }
01527 
01528         if (success)
01529         {
01530                 gWLSkyProgram.mName = "Windlight Sky Shader";
01531                 //gWLSkyProgram.mFeatures.hasGamma = true;
01532                 gWLSkyProgram.mShaderFiles.clear();
01533                 gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyV.glsl", GL_VERTEX_SHADER_ARB));
01534                 gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER_ARB));
01535                 gWLSkyProgram.mShaderLevel = sVertexShaderLevel[SHADER_WINDLIGHT];
01536                 gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
01537                 success = gWLSkyProgram.createShader(NULL, &sWLUniforms);
01538         }
01539 
01540         if (success)
01541         {
01542                 gWLCloudProgram.mName = "Windlight Cloud Program";
01543                 //gWLCloudProgram.mFeatures.hasGamma = true;
01544                 gWLCloudProgram.mShaderFiles.clear();
01545                 gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsV.glsl", GL_VERTEX_SHADER_ARB));
01546                 gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));
01547                 gWLCloudProgram.mShaderLevel = sVertexShaderLevel[SHADER_WINDLIGHT];
01548                 gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
01549                 success = gWLCloudProgram.createShader(NULL, &sWLUniforms);
01550         }
01551 
01552         return success;
01553 }
01554 
01555 
01556 //===============================
01557 // LLGLSL Shader implementation
01558 //===============================
01559 LLGLSLShader::LLGLSLShader()
01560 : mProgramObject(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT)
01561 {
01562 }
01563 
01564 void LLGLSLShader::unload()
01565 {
01566         stop_glerror();
01567         mAttribute.clear();
01568         mTexture.clear();
01569         mUniform.clear();
01570         mShaderFiles.clear();
01571 
01572         if (mProgramObject)
01573         {
01574                 GLhandleARB obj[1024];
01575                 GLsizei count;
01576 
01577                 glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
01578                 for (GLsizei i = 0; i < count; i++)
01579                 {
01580                         glDeleteObjectARB(obj[i]);
01581                 }
01582 
01583                 glDeleteObjectARB(mProgramObject);
01584 
01585                 mProgramObject = 0;
01586         }
01587         
01588         //hack to make apple not complain
01589         glGetError();
01590         
01591         stop_glerror();
01592 }
01593 
01594 BOOL LLGLSLShader::createShader(vector<string> * attributes,
01595                                                                 vector<string> * uniforms)
01596 {
01597         llassert_always(!mShaderFiles.empty());
01598         BOOL success = TRUE;
01599 
01600         // Create program
01601         mProgramObject = glCreateProgramObjectARB();
01602         
01603         // Attach existing objects
01604         if (!LLShaderMgr::attachShaderFeatures(this))
01605         {
01606                 return FALSE;
01607         }
01608 
01609         vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
01610         for ( ; fileIter != mShaderFiles.end(); fileIter++ )
01611         {
01612                 GLhandleARB shaderhandle = LLShaderMgr::loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second);
01613                 LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
01614                 if (mShaderLevel > 0)
01615                 {
01616                         attachObject(shaderhandle);
01617                 }
01618                 else
01619                 {
01620                         success = FALSE;
01621                 }
01622         }
01623 
01624         // Map attributes and uniforms
01625         if (success)
01626         {
01627                 success = mapAttributes(attributes);
01628         }
01629         if (success)
01630         {
01631                 success = mapUniforms(uniforms);
01632         }
01633         if( !success )
01634         {
01635                 LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL;
01636 
01637                 // Try again using a lower shader level;
01638                 if (mShaderLevel > 0)
01639                 {
01640                         LL_WARNS("ShaderLoading") << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
01641                         mShaderLevel--;
01642                         return createShader(attributes,uniforms);
01643                 }
01644         }
01645         return success;
01646 }
01647 
01648 BOOL LLGLSLShader::attachObject(std::string object)
01649 {
01650         if (LLShaderMgr::sShaderObjects.count(object) > 0)
01651         {
01652                 stop_glerror();
01653                 glAttachObjectARB(mProgramObject, LLShaderMgr::sShaderObjects[object]);
01654                 stop_glerror();
01655                 return TRUE;
01656         }
01657         else
01658         {
01659                 LL_WARNS("ShaderLoading") << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL;
01660                 return FALSE;
01661         }
01662 }
01663 
01664 void LLGLSLShader::attachObject(GLhandleARB object)
01665 {
01666         if (object != 0)
01667         {
01668                 stop_glerror();
01669                 glAttachObjectARB(mProgramObject, object);
01670                 stop_glerror();
01671         }
01672         else
01673         {
01674                 LL_WARNS("ShaderLoading") << "Attempting to attach non existing shader object. " << LL_ENDL;
01675         }
01676 }
01677 
01678 void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
01679 {
01680         for (S32 i = 0; i < count; i++)
01681         {
01682                 attachObject(objects[i]);
01683         }
01684 }
01685 
01686 BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
01687 {
01688         //link the program
01689         BOOL res = link();
01690 
01691         mAttribute.clear();
01692         U32 numAttributes = (attributes == NULL) ? 0 : attributes->size();
01693         mAttribute.resize(LLShaderMgr::sReservedAttribs.size() + numAttributes, -1);
01694         
01695         if (res)
01696         { //read back channel locations
01697 
01698                 //read back reserved channels first
01699                 for (U32 i = 0; i < (S32) LLShaderMgr::sReservedAttribs.size(); i++)
01700                 {
01701                         const char* name = LLShaderMgr::sReservedAttribs[i].c_str();
01702                         S32 index = glGetAttribLocationARB(mProgramObject, (GLcharARB *)name);
01703                         if (index != -1)
01704                         {
01705                                 mAttribute[i] = index;
01706                                 LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
01707                         }
01708                 }
01709                 if (attributes != NULL)
01710                 {
01711                         for (U32 i = 0; i < numAttributes; i++)
01712                         {
01713                                 const char* name = (*attributes)[i].c_str();
01714                                 S32 index = glGetAttribLocationARB(mProgramObject, name);
01715                                 if (index != -1)
01716                                 {
01717                                         mAttribute[LLShaderMgr::sReservedAttribs.size() + i] = index;
01718                                         LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
01719                                 }
01720                         }
01721                 }
01722 
01723                 return TRUE;
01724         }
01725         
01726         return FALSE;
01727 }
01728 
01729 void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
01730 {
01731         if (index == -1)
01732         {
01733                 return;
01734         }
01735 
01736         GLenum type;
01737         GLsizei length;
01738         GLint size;
01739         char name[1024];                /* Flawfinder: ignore */
01740         name[0] = 0;
01741 
01742         glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
01743         S32 location = glGetUniformLocationARB(mProgramObject, name);
01744         if (location != -1)
01745         {
01746                 mUniformMap[name] = location;
01747                 LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
01748         
01749                 //find the index of this uniform
01750                 for (S32 i = 0; i < (S32) LLShaderMgr::sReservedUniforms.size(); i++)
01751                 {
01752                         if ( (mUniform[i] == -1)
01753                                 && (LLShaderMgr::sReservedUniforms[i].compare(0, length, name, LLShaderMgr::sReservedUniforms[i].length()) == 0))
01754                         {
01755                                 //found it
01756                                 mUniform[i] = location;
01757                                 mTexture[i] = mapUniformTextureChannel(location, type);
01758                                 return;
01759                         }
01760                 }
01761 
01762                 if (uniforms != NULL)
01763                 {
01764                         for (U32 i = 0; i < uniforms->size(); i++)
01765                         {
01766                                 if ( (mUniform[i+LLShaderMgr::sReservedUniforms.size()] == -1)
01767                                         && ((*uniforms)[i].compare(0, length, name, (*uniforms)[i].length()) == 0))
01768                                 {
01769                                         //found it
01770                                         mUniform[i+LLShaderMgr::sReservedUniforms.size()] = location;
01771                                         mTexture[i+LLShaderMgr::sReservedUniforms.size()] = mapUniformTextureChannel(location, type);
01772                                         return;
01773                                 }
01774                         }
01775                 }
01776         }
01777  }
01778 
01779 GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
01780 {
01781         if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB)
01782         {       //this here is a texture
01783                 glUniform1iARB(location, mActiveTextureChannels);
01784                 LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
01785                 return mActiveTextureChannels++;
01786         }
01787         return -1;
01788 }
01789 
01790 BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
01791 {
01792         BOOL res = TRUE;
01793         
01794         mActiveTextureChannels = 0;
01795         mUniform.clear();
01796         mUniformMap.clear();
01797         mTexture.clear();
01798         mValue.clear();
01799         //initialize arrays
01800         U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size();
01801         mUniform.resize(numUniforms + LLShaderMgr::sReservedUniforms.size(), -1);
01802         mTexture.resize(numUniforms + LLShaderMgr::sReservedUniforms.size(), -1);
01803         
01804         bind();
01805 
01806         //get the number of active uniforms
01807         GLint activeCount;
01808         glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
01809 
01810         for (S32 i = 0; i < activeCount; i++)
01811         {
01812                 mapUniform(i, uniforms);
01813         }
01814 
01815         unbind();
01816 
01817         return res;
01818 }
01819 
01820 BOOL LLGLSLShader::link(BOOL suppress_errors)
01821 {
01822         return LLShaderMgr::linkProgramObject(mProgramObject, suppress_errors);
01823 }
01824 
01825 void LLGLSLShader::bind()
01826 {
01827         if (gGLManager.mHasShaderObjects)
01828         {
01829                 glUseProgramObjectARB(mProgramObject);
01830 
01831                 if (mUniformsDirty)
01832                 {
01833                         LLWLParamManager::instance()->updateShaderUniforms(this);
01834                         LLWaterParamManager::instance()->updateShaderUniforms(this);
01835                         mUniformsDirty = FALSE;
01836                 }
01837         }
01838 }
01839 
01840 void LLGLSLShader::unbind()
01841 {
01842         if (gGLManager.mHasShaderObjects)
01843         {
01844                 for (U32 i = 0; i < mAttribute.size(); ++i)
01845                 {
01846                         vertexAttrib4f(i, 0,0,0,1);
01847                 }
01848                 glUseProgramObjectARB(0);
01849         }
01850 }
01851 
01852 S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode)
01853 {
01854         if (uniform < 0 || uniform >= (S32)mTexture.size())
01855         {
01856                 UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
01857                 return -1;
01858         }
01859         S32 index = mTexture[uniform];
01860         if (index != -1)
01861         {
01862                 glActiveTextureARB(GL_TEXTURE0_ARB+index);
01863                 glEnable(mode);
01864         }
01865         return index;
01866 }
01867 
01868 S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode)
01869 {
01870         if (uniform < 0 || uniform >= (S32)mTexture.size())
01871         {
01872                 UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
01873                 return -1;
01874         }
01875         S32 index = mTexture[uniform];
01876         if (index != -1)
01877         {
01878                 glActiveTextureARB(GL_TEXTURE0_ARB+index);
01879                 glDisable(mode);
01880         }
01881         return index;
01882 }
01883 
01884 void LLGLSLShader::uniform1f(U32 index, GLfloat x)
01885 {
01886         if (mProgramObject > 0)
01887         {       
01888                 if (mUniform.size() <= index)
01889                 {
01890                         UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
01891                         return;
01892                 }
01893 
01894                 if (mUniform[index] >= 0)
01895                 {
01896                         std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
01897                         if (iter == mValue.end() || iter->second.mV[0] != x)
01898                         {
01899                                 glUniform1fARB(mUniform[index], x);
01900                                 mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
01901                         }
01902                 }
01903         }
01904 }
01905 
01906 void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
01907 {
01908         if (mProgramObject > 0)
01909         {       
01910                 if (mUniform.size() <= index)
01911                 {
01912                         UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
01913                         return;
01914                 }
01915 
01916                 if (mUniform[index] >= 0)
01917                 {
01918                         std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
01919                         LLVector4 vec(x,y,0.f,0.f);
01920                         if (iter == mValue.end() || shouldChange(iter->second,vec))
01921                         {
01922                                 glUniform2fARB(mUniform[index], x, y);
01923                                 mValue[mUniform[index]] = vec;
01924                         }
01925                 }
01926         }
01927 }
01928 
01929 void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
01930 {
01931         if (mProgramObject > 0)
01932         {       
01933                 if (mUniform.size() <= index)
01934                 {
01935                         UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
01936                         return;
01937                 }
01938 
01939                 if (mUniform[index] >= 0)
01940                 {
01941                         std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
01942                         LLVector4 vec(x,y,z,0.f);
01943                         if (iter == mValue.end() || shouldChange(iter->second,vec))
01944                         {
01945                                 glUniform3fARB(mUniform[index], x, y, z);
01946                                 mValue[mUniform[index]] = vec;
01947                         }
01948                 }
01949         }
01950 }
01951 
01952 void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
01953 {
01954         if (mProgramObject > 0)
01955         {       
01956                 if (mUniform.size() <= index)
01957                 {
01958                         UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
01959                         return;
01960                 }
01961 
01962                 if (mUniform[index] >= 0)
01963                 {
01964                         std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
01965                         LLVector4 vec(x,y,z,w);
01966                         if (iter == mValue.end() || shouldChange(iter->second,vec))
01967                         {
01968                                 glUniform4fARB(mUniform[index], x, y, z, w);
01969                                 mValue[mUniform[index]] = vec;
01970                         }
01971                 }
01972         }
01973 }
01974 
01975 void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
01976 {
01977         if (mProgramObject > 0)
01978         {       
01979                 if (mUniform.size() <= index)
01980                 {
01981                         UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
01982                         return;
01983                 }
01984 
01985                 if (mUniform[index] >= 0)
01986                 {
01987                         std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
01988                         LLVector4 vec(v[0],0.f,0.f,0.f);
01989                         if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
01990                         {
01991                                 glUniform1fvARB(mUniform[index], count, v);
01992                                 mValue[mUniform[index]] = vec;
01993                         }
01994                 }
01995         }
01996 }
01997 
01998 void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
01999 {
02000         if (mProgramObject > 0)
02001         {       
02002                 if (mUniform.size() <= index)
02003                 {
02004                         UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
02005                         return;
02006                 }
02007 
02008                 if (mUniform[index] >= 0)
02009                 {
02010                         std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
02011                         LLVector4 vec(v[0],v[1],0.f,0.f);
02012                         if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
02013                         {
02014                                 glUniform2fvARB(mUniform[index], count, v);
02015                                 mValue[mUniform[index]] = vec;
02016                         }
02017                 }
02018         }
02019 }
02020 
02021 void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
02022 {
02023         if (mProgramObject > 0)
02024         {       
02025                 if (mUniform.size() <= index)
02026                 {
02027                         UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
02028                         return;
02029                 }
02030 
02031                 if (mUniform[index] >= 0)
02032                 {
02033                         std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
02034                         LLVector4 vec(v[0],v[1],v[2],0.f);
02035                         if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
02036                         {
02037                                 glUniform3fvARB(mUniform[index], count, v);
02038                                 mValue[mUniform[index]] = vec;
02039                         }
02040                 }
02041         }
02042 }
02043 
02044 void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
02045 {
02046         if (mProgramObject > 0)
02047         {       
02048                 if (mUniform.size() <= index)
02049                 {
02050                         UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
02051                         return;
02052                 }
02053 
02054                 if (mUniform[index] >= 0)
02055                 {
02056                         std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
02057                         LLVector4 vec(v[0],v[1],v[2],v[3]);
02058                         if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
02059                         {
02060                                 glUniform4fvARB(mUniform[index], count, v);
02061                                 mValue[mUniform[index]] = vec;
02062                         }
02063                 }
02064         }
02065 }
02066 
02067 void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
02068 {
02069         if (mProgramObject > 0)
02070         {       
02071                 if (mUniform.size() <= index)
02072                 {
02073                         UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
02074                         return;
02075                 }
02076 
02077                 if (mUniform[index] >= 0)
02078                 {
02079                         glUniformMatrix2fvARB(mUniform[index], count, transpose, v);
02080                 }
02081         }
02082 }
02083 
02084 void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
02085 {
02086         if (mProgramObject > 0)
02087         {       
02088                 if (mUniform.size() <= index)
02089                 {
02090                         UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
02091                         return;
02092                 }
02093 
02094                 if (mUniform[index] >= 0)
02095                 {
02096                         glUniformMatrix3fvARB(mUniform[index], count, transpose, v);
02097                 }
02098         }
02099 }
02100 
02101 void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
02102 {
02103         if (mProgramObject > 0)
02104         {       
02105                 if (mUniform.size() <= index)
02106                 {
02107                         UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
02108                         return;
02109                 }
02110 
02111                 if (mUniform[index] >= 0)
02112                 {
02113                         glUniformMatrix4fvARB(mUniform[index], count, transpose, v);
02114                 }
02115         }
02116 }
02117 
02118 GLint LLGLSLShader::getUniformLocation(const string& uniform)
02119 {
02120         if (mProgramObject > 0)
02121         {
02122                 std::map<string, GLint>::iterator iter = mUniformMap.find(uniform);
02123                 if (iter != mUniformMap.end())
02124                 {
02125                         llassert(iter->second == glGetUniformLocationARB(mProgramObject, uniform.c_str()));
02126                         return iter->second;
02127                 }
02128         }
02129 
02130         return -1;
02131 }
02132 
02133 void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
02134 {
02135         GLint location = getUniformLocation(uniform);
02136                                 
02137         if (location >= 0)
02138         {
02139                 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
02140                 LLVector4 vec(v,0.f,0.f,0.f);
02141                 if (iter == mValue.end() || shouldChange(iter->second,vec))
02142                 {
02143                         glUniform1fARB(location, v);
02144                         mValue[location] = vec;
02145                 }
02146         }
02147 }
02148 
02149 void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y)
02150 {
02151         GLint location = getUniformLocation(uniform);
02152                                 
02153         if (location >= 0)
02154         {
02155                 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
02156                 LLVector4 vec(x,y,0.f,0.f);
02157                 if (iter == mValue.end() || shouldChange(iter->second,vec))
02158                 {
02159                         glUniform2fARB(location, x,y);
02160                         mValue[location] = vec;
02161                 }
02162         }
02163 
02164 }
02165 
02166 void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloat z)
02167 {
02168         GLint location = getUniformLocation(uniform);
02169                                 
02170         if (location >= 0)
02171         {
02172                 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
02173                 LLVector4 vec(x,y,z,0.f);
02174                 if (iter == mValue.end() || shouldChange(iter->second,vec))
02175                 {
02176                         glUniform3fARB(location, x,y,z);
02177                         mValue[location] = vec;
02178                 }
02179         }
02180 }
02181 
02182 void LLGLSLShader::uniform4f(const string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
02183 {
02184         GLint location = getUniformLocation(uniform);
02185 
02186         if (location >= 0)
02187         {
02188                 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
02189                 LLVector4 vec(x,y,z,w);
02190                 if (iter == mValue.end() || shouldChange(iter->second,vec))
02191                 {
02192                         glUniform4fARB(location, x,y,z,w);
02193                         mValue[location] = vec;
02194                 }
02195         }
02196 }
02197 
02198 void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v)
02199 {
02200         GLint location = getUniformLocation(uniform);
02201 
02202         if (location >= 0)
02203         {
02204                 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
02205                 LLVector4 vec(v[0],0.f,0.f,0.f);
02206                 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
02207                 {
02208                         glUniform1fvARB(location, count, v);
02209                         mValue[location] = vec;
02210                 }
02211         }
02212 }
02213 
02214 void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v)
02215 {
02216         GLint location = getUniformLocation(uniform);
02217                                 
02218         if (location >= 0)
02219         {
02220                 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
02221                 LLVector4 vec(v[0],v[1],0.f,0.f);
02222                 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
02223                 {
02224                         glUniform2fvARB(location, count, v);
02225                         mValue[location] = vec;
02226                 }
02227         }
02228 }
02229 
02230 void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v)
02231 {
02232         GLint location = getUniformLocation(uniform);
02233                                 
02234         if (location >= 0)
02235         {
02236                 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
02237                 LLVector4 vec(v[0],v[1],v[2],0.f);
02238                 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
02239                 {
02240                         glUniform3fvARB(location, count, v);
02241                         mValue[location] = vec;
02242                 }
02243         }
02244 }
02245 
02246 void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v)
02247 {
02248         GLint location = getUniformLocation(uniform);
02249 
02250         if (location >= 0)
02251         {
02252                 LLVector4 vec(v);
02253                 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
02254                 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
02255                 {
02256                         glUniform4fvARB(location, count, v);
02257                         mValue[location] = vec;
02258                 }
02259         }
02260 }
02261 
02262 void LLGLSLShader::uniformMatrix2fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
02263 {
02264         GLint location = getUniformLocation(uniform);
02265                                 
02266         if (location >= 0)
02267         {
02268                 glUniformMatrix2fvARB(location, count, transpose, v);
02269         }
02270 }
02271 
02272 void LLGLSLShader::uniformMatrix3fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
02273 {
02274         GLint location = getUniformLocation(uniform);
02275                                 
02276         if (location >= 0)
02277         {
02278                 glUniformMatrix3fvARB(location, count, transpose, v);
02279         }
02280 }
02281 
02282 void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
02283 {
02284         GLint location = getUniformLocation(uniform);
02285                                 
02286         if (location >= 0)
02287         {
02288                 glUniformMatrix4fvARB(location, count, transpose, v);
02289         }
02290 }
02291 
02292 
02293 void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
02294 {
02295         if (mAttribute[index] > 0)
02296         {
02297                 glVertexAttrib4fARB(mAttribute[index], x, y, z, w);
02298         }
02299 }
02300 
02301 void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
02302 {
02303         if (mAttribute[index] > 0)
02304         {
02305                 glVertexAttrib4fvARB(mAttribute[index], v);
02306         }
02307 }

Generated on Fri May 16 08:33:37 2008 for SecondLife by  doxygen 1.5.5