00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llviewerwindow.h"
00035 #include "llfeaturemanager.h"
00036 #include "llglslshader.h"
00037 #include "llviewercontrol.h"
00038 #include "pipeline.h"
00039 #include "llworld.h"
00040
00041
00042 GLhandleARB gLightVertex;
00043 GLhandleARB gLightFragment;
00044 GLhandleARB gScatterVertex;
00045 GLhandleARB gScatterFragment;
00046
00047 LLVector4 gShinyOrigin;
00048
00049
00050 LLGLSLShader gObjectSimpleProgram;
00051 LLGLSLShader gObjectAlphaProgram;
00052 LLGLSLShader gObjectBumpProgram;
00053 LLGLSLShader gObjectShinyProgram;
00054
00055
00056 LLGLSLShader gTerrainProgram;
00057 LLGLSLShader gGlowProgram;
00058 LLGLSLShader gGroundProgram;
00059 LLGLSLShader gWaterProgram;
00060
00061
00062 LLGLSLShader gHighlightProgram;
00063
00064
00065 GLhandleARB gAvatarSkinVertex;
00066
00067
00068 LLGLSLShader gAvatarProgram;
00069 LLGLSLShader gAvatarEyeballProgram;
00070 LLGLSLShader gAvatarPickProgram;
00071
00072
00073 GLint gAvatarMatrixParam;
00074 GLint gMaterialIndex;
00075 GLint gSpecularIndex;
00076
00077 S32 LLShaderMgr::sVertexShaderLevel[SHADER_COUNT] = { 0 };
00078 S32 LLShaderMgr::sMaxVertexShaderLevel[SHADER_COUNT] = { 0 };
00079
00080
00081 const char* LLShaderMgr::sReservedAttribs[] =
00082 {
00083 "materialColor",
00084 "specularColor",
00085 "binormal"
00086 };
00087
00088 U32 LLShaderMgr::sReservedAttribCount = LLShaderMgr::END_RESERVED_ATTRIBS;
00089
00090 const char* LLShaderMgr::sAvatarAttribs[] =
00091 {
00092 "weight",
00093 "clothing",
00094 "gWindDir",
00095 "gSinWaveParams",
00096 "gGravity"
00097 };
00098
00099 U32 LLShaderMgr::sAvatarAttribCount = sizeof(LLShaderMgr::sAvatarAttribs)/sizeof(char*);
00100
00101 const char* LLShaderMgr::sAvatarUniforms[] =
00102 {
00103 "matrixPalette"
00104 };
00105
00106 U32 LLShaderMgr::sAvatarUniformCount = 1;
00107
00108 const char* LLShaderMgr::sReservedUniforms[] =
00109 {
00110 "diffuseMap",
00111 "specularMap",
00112 "bumpMap",
00113 "environmentMap",
00114 "scatterMap"
00115 };
00116
00117 U32 LLShaderMgr::sReservedUniformCount = LLShaderMgr::END_RESERVED_UNIFORMS;
00118
00119 const char* LLShaderMgr::sTerrainUniforms[] =
00120 {
00121 "detail0",
00122 "detail1",
00123 "alphaRamp"
00124 };
00125
00126 U32 LLShaderMgr::sTerrainUniformCount = sizeof(LLShaderMgr::sTerrainUniforms)/sizeof(char*);
00127
00128 const char* LLShaderMgr::sGlowUniforms[] =
00129 {
00130 "delta"
00131 };
00132
00133 U32 LLShaderMgr::sGlowUniformCount = sizeof(LLShaderMgr::sGlowUniforms)/sizeof(char*);
00134
00135 const char* LLShaderMgr::sShinyUniforms[] =
00136 {
00137 "origin"
00138 };
00139
00140 U32 LLShaderMgr::sShinyUniformCount = sizeof(LLShaderMgr::sShinyUniforms)/sizeof(char*);
00141
00142 const char* LLShaderMgr::sWaterUniforms[] =
00143 {
00144 "screenTex",
00145 "eyeVec",
00146 "time",
00147 "d1",
00148 "d2",
00149 "lightDir",
00150 "specular",
00151 "lightExp",
00152 "fbScale",
00153 "refScale"
00154 };
00155
00156 U32 LLShaderMgr::sWaterUniformCount = sizeof(LLShaderMgr::sWaterUniforms)/sizeof(char*);
00157
00158
00159
00160
00161
00162 S32 LLShaderMgr::getVertexShaderLevel(S32 type)
00163 {
00164 return sVertexShaderLevel[type];
00165 }
00166
00167 S32 LLShaderMgr::getMaxVertexShaderLevel(S32 type)
00168 {
00169 return sMaxVertexShaderLevel[type];
00170 }
00171
00172
00173
00174
00175 static LLString get_object_log(GLhandleARB ret)
00176 {
00177 LLString res;
00178
00179
00180 GLint length;
00181 glGetObjectParameterivARB(ret, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
00182 if (length > 0)
00183 {
00184
00185 GLcharARB* log = new GLcharARB[length];
00186 glGetInfoLogARB(ret, length, &length, log);
00187 res = LLString((char *)log);
00188 delete[] log;
00189 }
00190 return res;
00191 }
00192
00193 void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
00194 {
00195 LLString log = get_object_log(ret);
00196 if (warns)
00197 {
00198 llwarns << log << llendl;
00199 }
00200 else
00201 {
00202 llinfos << log << llendl;
00203 }
00204 }
00205
00206 GLhandleARB LLShaderMgr::loadShader(const LLString& filename, S32 cls, GLenum type)
00207 {
00208 GLenum error;
00209 error = glGetError();
00210 if (error != GL_NO_ERROR)
00211 {
00212 llwarns << "GL ERROR entering loadShader(): " << error << llendl;
00213 }
00214
00215 llinfos << "Loading shader file: " << filename << llendl;
00216
00217 if (filename.empty())
00218 {
00219 return 0;
00220 }
00221
00222
00223
00224 FILE* file = NULL;
00225
00226 S32 try_gpu_class = sVertexShaderLevel[cls];
00227 S32 gpu_class;
00228
00229
00230 for (gpu_class = try_gpu_class; gpu_class > 0; gpu_class--)
00231 {
00232 std::stringstream fname;
00233 fname << gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
00234 fname << gpu_class << "/" << filename;
00235
00236
00237 file = fopen(fname.str().c_str(), "r");
00238 if (file)
00239 {
00240 break;
00241 }
00242 }
00243
00244 if (file == NULL)
00245 {
00246 llinfos << "GLSL Shader file not found: " << filename << llendl;
00247 return 0;
00248 }
00249
00250
00251
00252 GLcharARB buff[1024];
00253 GLcharARB* text[1024];
00254 GLuint count = 0;
00255
00256
00257
00258 while(fgets((char *)buff, 1024, file) != NULL && count < (sizeof(buff)/sizeof(buff[0])))
00259 {
00260 text[count++] = (GLcharARB *)strdup((char *)buff);
00261 }
00262 fclose(file);
00263
00264
00265 GLhandleARB ret = glCreateShaderObjectARB(type);
00266 error = glGetError();
00267 if (error != GL_NO_ERROR)
00268 {
00269 llwarns << "GL ERROR in glCreateShaderObjectARB: " << error << llendl;
00270 }
00271 else
00272 {
00273
00274 glShaderSourceARB(ret, count, (const GLcharARB**) text, NULL);
00275 error = glGetError();
00276 if (error != GL_NO_ERROR)
00277 {
00278 llwarns << "GL ERROR in glShaderSourceARB: " << error << llendl;
00279 }
00280 else
00281 {
00282
00283 glCompileShaderARB(ret);
00284 error = glGetError();
00285 if (error != GL_NO_ERROR)
00286 {
00287 llwarns << "GL ERROR in glCompileShaderARB: " << error << llendl;
00288 }
00289 }
00290 }
00291
00292 for (GLuint i = 0; i < count; i++)
00293 {
00294 free(text[i]);
00295 }
00296 if (error == GL_NO_ERROR)
00297 {
00298
00299 GLint success = GL_TRUE;
00300 glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success);
00301 error = glGetError();
00302 if (error != GL_NO_ERROR || success == GL_FALSE)
00303 {
00304
00305 llwarns << "GLSL Compilation Error: (" << error << ") in " << filename << llendl;
00306 dumpObjectLog(ret);
00307 ret = 0;
00308 }
00309 }
00310 else
00311 {
00312 ret = 0;
00313 }
00314 stop_glerror();
00315
00316
00317 #if 1 // 1.9.1
00318 if (ret)
00319 {
00320 sVertexShaderLevel[cls] = try_gpu_class;
00321 }
00322 else
00323 {
00324 if (sVertexShaderLevel[cls] > 1)
00325 {
00326 sVertexShaderLevel[cls] = sVertexShaderLevel[cls] - 1;
00327 ret = loadShader(filename,cls,type);
00328 if (ret && sMaxVertexShaderLevel[cls] > sVertexShaderLevel[cls])
00329 {
00330 sMaxVertexShaderLevel[cls] = sVertexShaderLevel[cls];
00331 }
00332 }
00333 }
00334 #else
00335 if (ret)
00336 {
00337 S32 max = -1;
00338
00339
00340
00341
00342 saveVertexShaderLevel(cls,try_gpu_class,max);
00343 }
00344 else
00345 {
00346 if (sVertexShaderLevel[cls] > 1)
00347 {
00348 sVertexShaderLevel[cls] = sVertexShaderLevel[cls] - 1;
00349 ret = loadShader(f,cls,type);
00350 if (ret && sMaxVertexShaderLevel[cls] > sVertexShaderLevel[cls])
00351 {
00352 saveVertexShaderLevel(cls, sVertexShaderLevel[cls], sVertexShaderLevel[cls]);
00353 }
00354 }
00355 }
00356 #endif
00357 return ret;
00358 }
00359
00360 BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
00361 {
00362
00363 glLinkProgramARB(obj);
00364 GLint success = GL_TRUE;
00365 glGetObjectParameterivARB(obj, GL_OBJECT_LINK_STATUS_ARB, &success);
00366 if (!suppress_errors && success == GL_FALSE)
00367 {
00368
00369 llwarns << "GLSL Linker Error:" << llendl;
00370 }
00371
00372 LLString log = get_object_log(obj);
00373 LLString::toLower(log);
00374 if (log.find("software") != LLString::npos)
00375 {
00376 llwarns << "GLSL Linker: Running in Software:" << llendl;
00377 success = GL_FALSE;
00378 suppress_errors = FALSE;
00379 }
00380 if (!suppress_errors)
00381 {
00382 dumpObjectLog(obj, !success);
00383 }
00384
00385 return success;
00386 }
00387
00388 BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj)
00389 {
00390
00391 glValidateProgramARB(obj);
00392 GLint success = GL_TRUE;
00393 glGetObjectParameterivARB(obj, GL_OBJECT_VALIDATE_STATUS_ARB, &success);
00394 if (success == GL_FALSE)
00395 {
00396 llwarns << "GLSL program not valid: " << llendl;
00397 dumpObjectLog(obj);
00398 }
00399 else
00400 {
00401 dumpObjectLog(obj, FALSE);
00402 }
00403
00404 return success;
00405 }
00406
00407
00408
00409
00410 void LLShaderMgr::setShaders()
00411 {
00412 if (!gPipeline.mInitialized)
00413 {
00414 return;
00415 }
00416
00417 if (gGLManager.mHasFramebufferObject)
00418 {
00419 LLPipeline::sDynamicReflections = gSavedSettings.getBOOL("RenderDynamicReflections") && gGLManager.mHasCubeMap && gFeatureManagerp->isFeatureAvailable("RenderCubeMap");
00420 LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
00421 }
00422 else
00423 {
00424 LLPipeline::sDynamicReflections = LLPipeline::sRenderGlow = FALSE;
00425 }
00426
00427
00428 gPipeline.resetVertexBuffers();
00429
00430 if (gViewerWindow)
00431 {
00432 gViewerWindow->setCursor(UI_CURSOR_WAIT);
00433 }
00434
00435
00436 gPipeline.setLightingDetail(-1);
00437
00438
00439 for (S32 i=0; i<SHADER_COUNT; i++)
00440 {
00441 sVertexShaderLevel[i] = 0;
00442 sMaxVertexShaderLevel[i] = 0;
00443 }
00444 if (gPipeline.canUseVertexShaders() && gSavedSettings.getBOOL("VertexShaderEnable"))
00445 {
00446 S32 light_class = 2;
00447 S32 env_class = 2;
00448 S32 obj_class = 0;
00449
00450 if (gPipeline.getLightingDetail() == 0)
00451 {
00452 light_class = 1;
00453 }
00454
00455 sVertexShaderLevel[SHADER_LIGHTING] = light_class;
00456 sMaxVertexShaderLevel[SHADER_LIGHTING] = light_class;
00457 sVertexShaderLevel[SHADER_ENVIRONMENT] = env_class;
00458 sMaxVertexShaderLevel[SHADER_ENVIRONMENT] = env_class;
00459 sVertexShaderLevel[SHADER_OBJECT] = obj_class;
00460 sMaxVertexShaderLevel[SHADER_OBJECT] = obj_class;
00461
00462 BOOL loaded = loadShadersLighting();
00463
00464 if (loaded)
00465 {
00466 gPipeline.mVertexShadersEnabled = TRUE;
00467 gPipeline.mVertexShadersLoaded = 1;
00468
00469
00470 loadShadersEnvironment();
00471 loadShadersObject();
00472
00473 sVertexShaderLevel[SHADER_AVATAR] = 3;
00474 sMaxVertexShaderLevel[SHADER_AVATAR] = 3;
00475 loadShadersAvatar();
00476
00477
00478 if (!(gSavedSettings.getBOOL("RenderRippleWater") && gGLManager.mHasCubeMap && gFeatureManagerp->isFeatureAvailable("RenderCubeMap")))
00479 {
00480 if (gSavedSettings.getBOOL("RenderGlow"))
00481 {
00482 sVertexShaderLevel[SHADER_ENVIRONMENT] = 1;
00483 }
00484 else
00485 {
00486 sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
00487 loadShadersEnvironment();
00488 }
00489 }
00490
00491 #if LL_DARWIN // force avatar shaders off for mac
00492 sVertexShaderLevel[SHADER_AVATAR] = 0;
00493 sMaxVertexShaderLevel[SHADER_AVATAR] = 0;
00494 #else
00495 if (gSavedSettings.getBOOL("RenderAvatarVP"))
00496 {
00497 S32 avatar = gSavedSettings.getS32("RenderAvatarMode");
00498 S32 avatar_class = 1 + avatar;
00499
00500 sVertexShaderLevel[SHADER_AVATAR] = avatar_class;
00501 loadShadersAvatar();
00502 if (sVertexShaderLevel[SHADER_AVATAR] != avatar_class)
00503 {
00504 if (sVertexShaderLevel[SHADER_AVATAR] == 0)
00505 {
00506 gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
00507 }
00508 avatar = llmax(sVertexShaderLevel[SHADER_AVATAR]-1,0);
00509 gSavedSettings.setS32("RenderAvatarMode", avatar);
00510 }
00511 }
00512 else
00513 {
00514 sVertexShaderLevel[SHADER_AVATAR] = 0;
00515 gSavedSettings.setS32("RenderAvatarMode", 0);
00516 loadShadersAvatar();
00517 }
00518 #endif
00519 }
00520 else
00521 {
00522 gPipeline.mVertexShadersEnabled = FALSE;
00523 gPipeline.mVertexShadersLoaded = 0;
00524 }
00525 }
00526 if (gViewerWindow)
00527 {
00528 gViewerWindow->setCursor(UI_CURSOR_ARROW);
00529 }
00530 }
00531
00532 void LLShaderMgr::unloadShaders()
00533 {
00534 gObjectSimpleProgram.unload();
00535 gObjectShinyProgram.unload();
00536 gObjectBumpProgram.unload();
00537 gObjectAlphaProgram.unload();
00538 gWaterProgram.unload();
00539 gTerrainProgram.unload();
00540 gGlowProgram.unload();
00541 gGroundProgram.unload();
00542 gAvatarProgram.unload();
00543 gAvatarEyeballProgram.unload();
00544 gAvatarPickProgram.unload();
00545 gHighlightProgram.unload();
00546
00547 sVertexShaderLevel[SHADER_LIGHTING] = 0;
00548 sVertexShaderLevel[SHADER_OBJECT] = 0;
00549 sVertexShaderLevel[SHADER_AVATAR] = 0;
00550 sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
00551 sVertexShaderLevel[SHADER_INTERFACE] = 0;
00552
00553 gLightVertex = gLightFragment = gScatterVertex = gScatterFragment = 0;
00554 gPipeline.mVertexShadersLoaded = 0;
00555 }
00556
00557 BOOL LLShaderMgr::loadShadersLighting()
00558 {
00559
00560
00561
00562 std::string lightvertex = "lighting/lightV.glsl";
00563
00564 gLightVertex = loadShader(lightvertex, SHADER_LIGHTING, GL_VERTEX_SHADER_ARB);
00565 if( !gLightVertex )
00566 {
00567 llwarns << "Failed to load " << lightvertex << llendl;
00568 return FALSE;
00569 }
00570
00571 std::string lightfragment = "lighting/lightF.glsl";
00572 gLightFragment = loadShader(lightfragment, SHADER_LIGHTING, GL_FRAGMENT_SHADER_ARB);
00573 if ( !gLightFragment )
00574 {
00575 llwarns << "Failed to load " << lightfragment << llendl;
00576 return FALSE;
00577 }
00578
00579
00580
00581 std::string scattervertex = "environment/scatterV.glsl";
00582 gScatterVertex = loadShader(scattervertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB);
00583 if ( !gScatterVertex )
00584 {
00585 llwarns << "Failed to load " << scattervertex << llendl;
00586 return FALSE;
00587 }
00588
00589 std::string scatterfragment = "environment/scatterF.glsl";
00590 gScatterFragment = loadShader(scatterfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB);
00591 if ( !gScatterFragment )
00592 {
00593 llwarns << "Failed to load " << scatterfragment << llendl;
00594 return FALSE;
00595 }
00596
00597 return TRUE;
00598 }
00599
00600 BOOL LLShaderMgr::loadShadersEnvironment()
00601 {
00602 GLhandleARB baseObjects[] =
00603 {
00604 gLightFragment,
00605 gLightVertex,
00606 gScatterFragment,
00607 gScatterVertex
00608 };
00609 S32 baseCount = 4;
00610
00611 BOOL success = TRUE;
00612
00613 if (sVertexShaderLevel[SHADER_ENVIRONMENT] == 0)
00614 {
00615 gWaterProgram.unload();
00616 gGroundProgram.unload();
00617 gTerrainProgram.unload();
00618 gGlowProgram.unload();
00619 return FALSE;
00620 }
00621
00622 if (success)
00623 {
00624
00625 std::string waterfragment = "environment/waterF.glsl";
00626 std::string watervertex = "environment/waterV.glsl";
00627 gWaterProgram.mProgramObject = glCreateProgramObjectARB();
00628 gWaterProgram.attachObjects(baseObjects, baseCount);
00629 gWaterProgram.attachObject(loadShader(watervertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB));
00630 gWaterProgram.attachObject(loadShader(waterfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB));
00631
00632 success = gWaterProgram.mapAttributes();
00633 if (success)
00634 {
00635 success = gWaterProgram.mapUniforms(sWaterUniforms, sWaterUniformCount);
00636 }
00637 if (!success)
00638 {
00639 llwarns << "Failed to load " << watervertex << llendl;
00640 }
00641 }
00642 if (success)
00643 {
00644
00645 std::string groundvertex = "environment/groundV.glsl";
00646 std::string groundfragment = "environment/groundF.glsl";
00647 gGroundProgram.mProgramObject = glCreateProgramObjectARB();
00648 gGroundProgram.attachObjects(baseObjects, baseCount);
00649 gGroundProgram.attachObject(loadShader(groundvertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB));
00650 gGroundProgram.attachObject(loadShader(groundfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB));
00651
00652 success = gGroundProgram.mapAttributes();
00653 if (success)
00654 {
00655 success = gGroundProgram.mapUniforms();
00656 }
00657 if (!success)
00658 {
00659 llwarns << "Failed to load " << groundvertex << llendl;
00660 }
00661 }
00662
00663 if (success)
00664 {
00665
00666 std::string terrainvertex = "environment/terrainV.glsl";
00667 std::string terrainfragment = "environment/terrainF.glsl";
00668 gTerrainProgram.mProgramObject = glCreateProgramObjectARB();
00669 gTerrainProgram.attachObjects(baseObjects, baseCount);
00670 gTerrainProgram.attachObject(loadShader(terrainvertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB));
00671 gTerrainProgram.attachObject(loadShader(terrainfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB));
00672 success = gTerrainProgram.mapAttributes();
00673 if (success)
00674 {
00675 success = gTerrainProgram.mapUniforms(sTerrainUniforms, sTerrainUniformCount);
00676 }
00677 if (!success)
00678 {
00679 llwarns << "Failed to load " << terrainvertex << llendl;
00680 }
00681 }
00682
00683 if (success)
00684 {
00685
00686 std::string glowvertex = "environment/glowV.glsl";
00687 std::string glowfragment = "environment/glowF.glsl";
00688 gGlowProgram.mProgramObject = glCreateProgramObjectARB();
00689 gGlowProgram.attachObjects(baseObjects, baseCount);
00690 gGlowProgram.attachObject(loadShader(glowvertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB));
00691 gGlowProgram.attachObject(loadShader(glowfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB));
00692 success = gGlowProgram.mapAttributes();
00693 if (success)
00694 {
00695 success = gGlowProgram.mapUniforms(sGlowUniforms, sGlowUniformCount);
00696 }
00697 if (!success)
00698 {
00699 llwarns << "Failed to load " << glowvertex << llendl;
00700 }
00701 }
00702
00703 if( !success )
00704 {
00705 sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
00706 sMaxVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
00707 return FALSE;
00708 }
00709
00710 if (gWorldPointer)
00711 {
00712 gWorldPointer->updateWaterObjects();
00713 }
00714
00715 return TRUE;
00716 }
00717
00718 BOOL LLShaderMgr::loadShadersObject()
00719 {
00720 GLhandleARB baseObjects[] =
00721 {
00722 gLightFragment,
00723 gLightVertex,
00724 gScatterFragment,
00725 gScatterVertex
00726 };
00727 S32 baseCount = 4;
00728
00729 BOOL success = TRUE;
00730
00731 if (sVertexShaderLevel[SHADER_OBJECT] == 0)
00732 {
00733 gObjectShinyProgram.unload();
00734 gObjectSimpleProgram.unload();
00735 gObjectBumpProgram.unload();
00736 gObjectAlphaProgram.unload();
00737 return FALSE;
00738 }
00739
00740 #if 0
00741 if (success)
00742 {
00743
00744 std::string simplevertex = "objects/simpleV.glsl";
00745 std::string simplefragment = "objects/simpleF.glsl";
00746 gObjectSimpleProgram.mProgramObject = glCreateProgramObjectARB();
00747 gObjectSimpleProgram.attachObjects(baseObjects, baseCount);
00748 gObjectSimpleProgram.attachObject(loadShader(simplevertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB));
00749 gObjectSimpleProgram.attachObject(loadShader(simplefragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB));
00750 success = gObjectSimpleProgram.mapAttributes();
00751 if (success)
00752 {
00753 success = gObjectSimpleProgram.mapUniforms();
00754 }
00755 if( !success )
00756 {
00757 llwarns << "Failed to load " << simplevertex << llendl;
00758 }
00759 }
00760
00761 if (success)
00762 {
00763
00764 std::string bumpshinyvertex = "objects/bumpshinyV.glsl";
00765 std::string bumpshinyfragment = "objects/bumpshinyF.glsl";
00766 gObjectBumpProgram.mProgramObject = glCreateProgramObjectARB();
00767 gObjectBumpProgram.attachObjects(baseObjects, baseCount);
00768 gObjectBumpProgram.attachObject(loadShader(bumpshinyvertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB));
00769 gObjectBumpProgram.attachObject(loadShader(bumpshinyfragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB));
00770 success = gObjectBumpProgram.mapAttributes();
00771 if (success)
00772 {
00773 success = gObjectBumpProgram.mapUniforms();
00774 }
00775 if( !success )
00776 {
00777 llwarns << "Failed to load " << bumpshinyvertex << llendl;
00778 }
00779 }
00780
00781 if (success)
00782 {
00783
00784 std::string alphavertex = "objects/alphaV.glsl";
00785 std::string alphafragment = "objects/alphaF.glsl";
00786 gObjectAlphaProgram.mProgramObject = glCreateProgramObjectARB();
00787 gObjectAlphaProgram.attachObjects(baseObjects, baseCount);
00788 gObjectAlphaProgram.attachObject(loadShader(alphavertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB));
00789 gObjectAlphaProgram.attachObject(loadShader(alphafragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB));
00790
00791 success = gObjectAlphaProgram.mapAttributes();
00792 if (success)
00793 {
00794 success = gObjectAlphaProgram.mapUniforms();
00795 }
00796 if( !success )
00797 {
00798 llwarns << "Failed to load " << alphavertex << llendl;
00799 }
00800 }
00801 #endif
00802
00803 if (success)
00804 {
00805
00806 std::string shinyvertex = "objects/shinyV.glsl";
00807 std::string shinyfragment = "objects/shinyF.glsl";
00808 gObjectShinyProgram.mProgramObject = glCreateProgramObjectARB();
00809 gObjectShinyProgram.attachObjects(baseObjects, baseCount);
00810 gObjectShinyProgram.attachObject(loadShader(shinyvertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB));
00811 gObjectShinyProgram.attachObject(loadShader(shinyfragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB));
00812
00813 success = gObjectShinyProgram.mapAttributes();
00814 if (success)
00815 {
00816 success = gObjectShinyProgram.mapUniforms(sShinyUniforms, sShinyUniformCount);
00817 }
00818 if( !success )
00819 {
00820 llwarns << "Failed to load " << shinyvertex << llendl;
00821 }
00822 }
00823
00824 if( !success )
00825 {
00826 sVertexShaderLevel[SHADER_OBJECT] = 0;
00827 sMaxVertexShaderLevel[SHADER_OBJECT] = 0;
00828 return FALSE;
00829 }
00830
00831 return TRUE;
00832 }
00833
00834 BOOL LLShaderMgr::loadShadersAvatar()
00835 {
00836 GLhandleARB baseObjects[] =
00837 {
00838 gLightFragment,
00839 gLightVertex,
00840 gScatterFragment,
00841 gScatterVertex
00842 };
00843 S32 baseCount = 4;
00844
00845 BOOL success = TRUE;
00846
00847 if (sVertexShaderLevel[SHADER_AVATAR] == 0)
00848 {
00849 gAvatarProgram.unload();
00850 gAvatarEyeballProgram.unload();
00851 gAvatarPickProgram.unload();
00852 return FALSE;
00853 }
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 if (success)
00876 {
00877 gAvatarSkinVertex = loadShader("avatar/avatarSkinV.glsl", SHADER_AVATAR, GL_VERTEX_SHADER_ARB);
00878
00879 std::string avatarvertex = "avatar/avatarV.glsl";
00880 std::string avatarfragment = "avatar/avatarF.glsl";
00881
00882 gAvatarProgram.mProgramObject = glCreateProgramObjectARB();
00883 gAvatarProgram.attachObjects(baseObjects, baseCount);
00884 gAvatarProgram.attachObject(gAvatarSkinVertex);
00885 gAvatarProgram.attachObject(loadShader(avatarvertex, SHADER_AVATAR, GL_VERTEX_SHADER_ARB));
00886 gAvatarProgram.attachObject(loadShader(avatarfragment, SHADER_AVATAR, GL_FRAGMENT_SHADER_ARB));
00887
00888 success = gAvatarProgram.mapAttributes(sAvatarAttribs, sAvatarAttribCount);
00889 if (success)
00890 {
00891 success = gAvatarProgram.mapUniforms(sAvatarUniforms, sAvatarUniformCount);
00892 }
00893 if( !success )
00894 {
00895 llwarns << "Failed to load " << avatarvertex << llendl;
00896 }
00897 }
00898
00899 if (success)
00900 {
00901
00902 std::string pickvertex = "avatar/pickAvatarV.glsl";
00903 std::string pickfragment = "avatar/pickAvatarF.glsl";
00904 gAvatarPickProgram.mProgramObject = glCreateProgramObjectARB();
00905 gAvatarPickProgram.attachObject(loadShader(pickvertex, SHADER_AVATAR, GL_VERTEX_SHADER_ARB));
00906 gAvatarPickProgram.attachObject(loadShader(pickfragment, SHADER_AVATAR, GL_FRAGMENT_SHADER_ARB));
00907 gAvatarPickProgram.attachObject(gAvatarSkinVertex);
00908
00909 success = gAvatarPickProgram.mapAttributes(sAvatarAttribs, sAvatarAttribCount);
00910 if (success)
00911 {
00912 success = gAvatarPickProgram.mapUniforms(sAvatarUniforms, sAvatarUniformCount);
00913 }
00914 if( !success )
00915 {
00916 llwarns << "Failed to load " << pickvertex << llendl;
00917 }
00918 }
00919
00920 if( !success )
00921 {
00922 sVertexShaderLevel[SHADER_AVATAR] = 0;
00923 sMaxVertexShaderLevel[SHADER_AVATAR] = 0;
00924 return FALSE;
00925 }
00926
00927 return TRUE;
00928 }
00929
00930 BOOL LLShaderMgr::loadShadersInterface()
00931 {
00932 BOOL success = TRUE;
00933
00934 if (sVertexShaderLevel[SHADER_INTERFACE] == 0)
00935 {
00936 gHighlightProgram.unload();
00937 return FALSE;
00938 }
00939
00940 if (success)
00941 {
00942
00943 std::string highlightvertex = "interface/highlightV.glsl";
00944 std::string highlightfragment = "interface/highlightF.glsl";
00945 gHighlightProgram.mProgramObject = glCreateProgramObjectARB();
00946 gHighlightProgram.attachObject(loadShader(highlightvertex, SHADER_INTERFACE, GL_VERTEX_SHADER_ARB));
00947 gHighlightProgram.attachObject(loadShader(highlightfragment, SHADER_INTERFACE, GL_FRAGMENT_SHADER_ARB));
00948
00949 success = gHighlightProgram.mapAttributes();
00950 if (success)
00951 {
00952 success = gHighlightProgram.mapUniforms();
00953 }
00954 if( !success )
00955 {
00956 llwarns << "Failed to load " << highlightvertex << llendl;
00957 }
00958 }
00959
00960 if( !success )
00961 {
00962 sVertexShaderLevel[SHADER_INTERFACE] = 0;
00963 sMaxVertexShaderLevel[SHADER_INTERFACE] = 0;
00964 return FALSE;
00965 }
00966
00967 return TRUE;
00968 }
00969
00970
00971
00972
00973
00974 LLGLSLShader::LLGLSLShader()
00975 : mProgramObject(0)
00976 { }
00977
00978 void LLGLSLShader::unload()
00979 {
00980 stop_glerror();
00981 mAttribute.clear();
00982 mTexture.clear();
00983 mUniform.clear();
00984
00985 if (mProgramObject)
00986 {
00987 GLhandleARB obj[1024];
00988 GLsizei count;
00989
00990 glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
00991 for (GLsizei i = 0; i < count; i++)
00992 {
00993 glDeleteObjectARB(obj[i]);
00994 }
00995
00996 glDeleteObjectARB(mProgramObject);
00997
00998 mProgramObject = 0;
00999 }
01000
01001
01002 glGetError();
01003
01004 stop_glerror();
01005 }
01006
01007 void LLGLSLShader::attachObject(GLhandleARB object)
01008 {
01009 if (object != 0)
01010 {
01011 stop_glerror();
01012 glAttachObjectARB(mProgramObject, object);
01013 stop_glerror();
01014 }
01015 else
01016 {
01017 llwarns << "Attempting to attach non existing shader object. " << llendl;
01018 }
01019 }
01020
01021 void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
01022 {
01023 for (S32 i = 0; i < count; i++)
01024 {
01025 attachObject(objects[i]);
01026 }
01027 }
01028
01029 BOOL LLGLSLShader::mapAttributes(const char** attrib_names, S32 count)
01030 {
01031
01032 BOOL res = link();
01033
01034 mAttribute.clear();
01035 mAttribute.resize(LLShaderMgr::sReservedAttribCount + count, -1);
01036
01037 if (res)
01038 {
01039
01040
01041 for (S32 i = 0; i < (S32) LLShaderMgr::sReservedAttribCount; i++)
01042 {
01043 const char* name = LLShaderMgr::sReservedAttribs[i];
01044 S32 index = glGetAttribLocationARB(mProgramObject, (GLcharARB *)name);
01045 if (index != -1)
01046 {
01047 mAttribute[i] = index;
01048 llinfos << "Attribute " << name << " assigned to channel " << index << llendl;
01049 }
01050 }
01051
01052 for (S32 i = 0; i < count; i++)
01053 {
01054 const char* name = attrib_names[i];
01055 S32 index = glGetAttribLocationARB(mProgramObject, (GLcharARB *)name);
01056 if (index != -1)
01057 {
01058 mAttribute[LLShaderMgr::sReservedAttribCount + i] = index;
01059 llinfos << "Attribute " << name << " assigned to channel " << index << llendl;
01060 }
01061 }
01062
01063 return TRUE;
01064 }
01065
01066 return FALSE;
01067 }
01068
01069 void LLGLSLShader::mapUniform(GLint index, const char** uniform_names, S32 count)
01070 {
01071 if (index == -1)
01072 {
01073 return;
01074 }
01075
01076 GLenum type;
01077 GLsizei length;
01078 GLint size;
01079 char name[1024];
01080 name[0] = 0;
01081
01082 glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
01083
01084
01085 for (S32 i = 0; i < (S32) LLShaderMgr::sReservedUniformCount; i++)
01086 {
01087 if (mUniform[i] == -1 && !strncmp(LLShaderMgr::sReservedUniforms[i],name, strlen(LLShaderMgr::sReservedUniforms[i])))
01088 {
01089
01090 S32 location = glGetUniformLocationARB(mProgramObject, (GLcharARB *)name);
01091 mUniform[i] = location;
01092 llinfos << "Uniform " << name << " is at location " << location << llendl;
01093 mTexture[i] = mapUniformTextureChannel(location, type);
01094 return;
01095 }
01096 }
01097
01098 for (S32 i = 0; i < count; i++)
01099 {
01100 if (mUniform[i+LLShaderMgr::sReservedUniformCount] == -1 &&
01101 !strncmp(uniform_names[i],name, strlen(uniform_names[i])))
01102 {
01103
01104 S32 location = glGetUniformLocationARB(mProgramObject, (GLcharARB *)name);
01105 mUniform[i+LLShaderMgr::sReservedUniformCount] = location;
01106 llinfos << "Uniform " << name << " is at location " << location << " stored in index " <<
01107 (i+LLShaderMgr::sReservedUniformCount) << llendl;
01108 mTexture[i+LLShaderMgr::sReservedUniformCount] = mapUniformTextureChannel(location, type);
01109 return;
01110 }
01111 }
01112
01113
01114 }
01115
01116 GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
01117 {
01118 if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB)
01119 {
01120 glUniform1iARB(location, mActiveTextureChannels);
01121 llinfos << "Assigned to texture channel " << mActiveTextureChannels << llendl;
01122 return mActiveTextureChannels++;
01123 }
01124 return -1;
01125 }
01126
01127 BOOL LLGLSLShader::mapUniforms(const char** uniform_names, S32 count)
01128 {
01129 BOOL res = TRUE;
01130
01131 mActiveTextureChannels = 0;
01132 mUniform.clear();
01133 mTexture.clear();
01134
01135
01136 mUniform.resize(count + LLShaderMgr::sReservedUniformCount, -1);
01137 mTexture.resize(count + LLShaderMgr::sReservedUniformCount, -1);
01138
01139 bind();
01140
01141
01142 GLint activeCount;
01143 glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
01144
01145 for (S32 i = 0; i < activeCount; i++)
01146 {
01147 mapUniform(i, uniform_names, count);
01148 }
01149
01150 unbind();
01151
01152 return res;
01153 }
01154
01155 BOOL LLGLSLShader::link(BOOL suppress_errors)
01156 {
01157 return LLShaderMgr::linkProgramObject(mProgramObject, suppress_errors);
01158 }
01159
01160 void LLGLSLShader::bind()
01161 {
01162 glUseProgramObjectARB(mProgramObject);
01163 if (mAttribute.size() > 0)
01164 {
01165 gMaterialIndex = mAttribute[0];
01166 }
01167 }
01168
01169 void LLGLSLShader::unbind()
01170 {
01171 for (U32 i = 0; i < mAttribute.size(); ++i)
01172 {
01173 vertexAttrib4f(i, 0,0,0,1);
01174 }
01175 glUseProgramObjectARB(0);
01176 }
01177
01178 S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode)
01179 {
01180 if (uniform < 0 || uniform >= (S32)mTexture.size())
01181 {
01182 llerrs << "LLGLSLShader::enableTexture: uniform out of range: " << uniform << llendl;
01183 }
01184 S32 index = mTexture[uniform];
01185 if (index != -1)
01186 {
01187 glActiveTextureARB(GL_TEXTURE0_ARB+index);
01188 glEnable(mode);
01189 }
01190 return index;
01191 }
01192
01193 S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode)
01194 {
01195 S32 index = mTexture[uniform];
01196 if (index != -1)
01197 {
01198 glActiveTextureARB(GL_TEXTURE0_ARB+index);
01199 glDisable(mode);
01200 }
01201 return index;
01202 }
01203
01204 void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
01205 {
01206 if (mAttribute[index] > 0)
01207 {
01208 glVertexAttrib4fARB(mAttribute[index], x, y, z, w);
01209 }
01210 }
01211
01212 void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
01213 {
01214 if (mAttribute[index] > 0)
01215 {
01216 glVertexAttrib4fvARB(mAttribute[index], v);
01217 }
01218 }
01219
01220 void LLScatterShader::init(GLhandleARB shader, int map_stage)
01221 {
01222 glUseProgramObjectARB(shader);
01223 glUniform1iARB(glGetUniformLocationARB(shader, (GLcharARB *)"scatterMap"), map_stage);
01224 glUseProgramObjectARB(0);
01225 }
01226