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
00059 using std::vector;
00060 using std::pair;
00061 using std::make_pair;
00062 using std::string;
00063
00064 LLVector4 gShinyOrigin;
00065
00066
00067 LLGLSLShader gObjectSimpleProgram;
00068 LLGLSLShader gObjectSimpleWaterProgram;
00069 LLGLSLShader gObjectFullbrightProgram;
00070 LLGLSLShader gObjectFullbrightWaterProgram;
00071
00072 LLGLSLShader gObjectFullbrightShinyProgram;
00073 LLGLSLShader gObjectShinyProgram;
00074 LLGLSLShader gObjectShinyWaterProgram;
00075
00076
00077 LLGLSLShader gTerrainProgram;
00078 LLGLSLShader gTerrainWaterProgram;
00079 LLGLSLShader gWaterProgram;
00080 LLGLSLShader gUnderWaterProgram;
00081
00082
00083 LLGLSLShader gHighlightProgram;
00084
00085
00086 GLhandleARB gAvatarSkinVertex;
00087
00088
00089 LLGLSLShader gAvatarProgram;
00090 LLGLSLShader gAvatarWaterProgram;
00091 LLGLSLShader gAvatarEyeballProgram;
00092 LLGLSLShader gAvatarPickProgram;
00093
00094
00095 LLGLSLShader gWLSkyProgram;
00096 LLGLSLShader gWLCloudProgram;
00097
00098
00099 LLGLSLShader gGlowProgram;
00100 LLGLSLShader gGlowExtractProgram;
00101 LLGLSLShader gPostColorFilterProgram;
00102 LLGLSLShader gPostNightVisionProgram;
00103
00104
00105 LLGLSLShader gDeferredDiffuseProgram;
00106
00107
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
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
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
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
00270
00271
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
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
00343
00344 if(features->calculatesAtmospherics)
00345 {
00346 if (!shader->attachObject("windlight/atmosphericsVarsF.glsl"))
00347 {
00348 return FALSE;
00349 }
00350 }
00351
00352
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
00377
00378 }
00379
00380
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
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
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
00463
00464 S32 LLShaderMgr::getVertexShaderLevel(S32 type)
00465 {
00466 return LLPipeline::sDisableShaders ? 0 : sVertexShaderLevel[type];
00467 }
00468
00469
00470
00471
00472
00473 static LLString get_object_log(GLhandleARB ret)
00474 {
00475 LLString res;
00476
00477
00478 GLint length;
00479 glGetObjectParameterivARB(ret, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
00480 if (length > 0)
00481 {
00482
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
00522 LLFILE* file = NULL;
00523
00524 S32 try_gpu_class = shader_level;
00525 S32 gpu_class;
00526
00527
00528 for (gpu_class = try_gpu_class; gpu_class > 0; gpu_class--)
00529 {
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");
00536 if (file)
00537 {
00538 LL_INFOS("ShaderLoading") << "Loading file: shaders/class" << gpu_class << "/" << filename << " (Want class " << gpu_class << ")" << LL_ENDL;
00539 break;
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
00550
00551 GLcharARB buff[1024];
00552 GLcharARB* text[1024];
00553 GLuint count = 0;
00554
00555
00556
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
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
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
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
00591 for (GLuint i = 0; i < count; i++)
00592 {
00593 free(text[i]);
00594 }
00595 if (error == GL_NO_ERROR)
00596 {
00597
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
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
00616 if (ret)
00617 {
00618
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
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
00643 LL_WARNS("ShaderLoading") << "GLSL Linker Error:" << LL_ENDL;
00644 }
00645
00646
00647
00648 #if 0
00649
00650
00651 glBegin(gGL.mMode);
00652 glEnd();
00653
00654
00655
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
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
00707
00708 void LLShaderMgr::setShaders()
00709 {
00710 if (!gPipeline.mInitialized)
00711 {
00712 return;
00713 }
00714
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
00734 gPipeline.resetVertexBuffers();
00735
00736 if (gViewerWindow)
00737 {
00738 gViewerWindow->setCursor(UI_CURSOR_WAIT);
00739 }
00740
00741
00742 gPipeline.setLightingDetail(-1);
00743
00744
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
00765
00766 wl_class = 1;
00767
00768
00769
00770
00771
00772
00773
00774 if(LLFeatureManager::getInstance()->getGPUClass() < GPU_CLASS_2)
00775 {
00776
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
00801 if (sVertexShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull())
00802 {
00803 gSky.mVOSkyp->forceSkyUpdate();
00804 }
00805
00806
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
00824 loadShadersEnvironment();
00825 loadShadersWater();
00826 loadShadersObject();
00827 loadShadersWindLight();
00828 loadShadersEffects();
00829 loadShadersInterface();
00830 loadShadersDeferred();
00831
00832
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
00847 if(avatar_cloth)
00848 {
00849 avatar_class = 3;
00850 }
00851
00852
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();
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
00956
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
00964
00965
00966
00967 if(LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_1)
00968 {
00969 sum_lights_class = 2;
00970 }
00971 #endif
00972
00973
00974 if (gPipeline.getLightingDetail() == 0)
00975 {
00976 sum_lights_class = 1;
00977 }
00978
00979
00980
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
00996 for (U32 i = 0; i < shaders.size(); i++)
00997 {
00998
00999 if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB) == 0)
01000 {
01001 return FALSE;
01002 }
01003 }
01004
01005
01006
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
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
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
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
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
01141
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
01196
01197
01198
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
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
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
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
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
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
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
01601 mProgramObject = glCreateProgramObjectARB();
01602
01603
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
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
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
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 {
01697
01698
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];
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
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
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
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 {
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
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
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 }