llglslshader.cpp

Go to the documentation of this file.
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 //utility shader objects (not shader programs)
00042 GLhandleARB                     gLightVertex;
00043 GLhandleARB                     gLightFragment;
00044 GLhandleARB                     gScatterVertex;
00045 GLhandleARB                     gScatterFragment;
00046 
00047 LLVector4                       gShinyOrigin;
00048 
00049 //object shaders
00050 LLGLSLShader            gObjectSimpleProgram;
00051 LLGLSLShader            gObjectAlphaProgram;
00052 LLGLSLShader            gObjectBumpProgram;
00053 LLGLSLShader            gObjectShinyProgram;
00054 
00055 //environment shaders
00056 LLGLSLShader            gTerrainProgram;
00057 LLGLSLShader            gGlowProgram;
00058 LLGLSLShader            gGroundProgram;
00059 LLGLSLShader            gWaterProgram;
00060 
00061 //interface shaders
00062 LLGLSLShader            gHighlightProgram;
00063 
00064 //avatar skinning utility shader object
00065 GLhandleARB                     gAvatarSkinVertex;
00066 
00067 //avatar shader handles
00068 LLGLSLShader            gAvatarProgram;
00069 LLGLSLShader            gAvatarEyeballProgram;
00070 LLGLSLShader            gAvatarPickProgram;
00071 
00072 //current avatar shader parameter pointer
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 //glsl parameter tables
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 // Set Levels
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 // Load Shader
00174 
00175 static LLString get_object_log(GLhandleARB ret)
00176 {
00177         LLString res;
00178         
00179         //get log length
00180         GLint length;
00181         glGetObjectParameterivARB(ret, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
00182         if (length > 0)
00183         {
00184                 //the log could be any size, so allocate appropriately
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         //read in from file
00224         FILE* file = NULL;
00225 
00226         S32 try_gpu_class = sVertexShaderLevel[cls];
00227         S32 gpu_class;
00228 
00229         //find the most relevant file
00230         for (gpu_class = try_gpu_class; gpu_class > 0; gpu_class--)
00231         {       //search from the current gpu class down to class 1 to find the most relevant shader
00232                 std::stringstream fname;
00233                 fname << gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
00234                 fname << gpu_class << "/" << filename;
00235                 
00236 //              llinfos << "Looking in " << fname.str().c_str() << llendl;
00237                 file = fopen(fname.str().c_str(), "r");         /* Flawfinder: ignore */
00238                 if (file)
00239                 {
00240                         break; // done
00241                 }
00242         }
00243         
00244         if (file == NULL)
00245         {
00246                 llinfos << "GLSL Shader file not found: " << filename << llendl;
00247                 return 0;
00248         }
00249 
00250         //we can't have any lines longer than 1024 characters 
00251         //or any shaders longer than 1024 lines... deal - DaveP
00252         GLcharARB buff[1024];
00253         GLcharARB* text[1024];
00254         GLuint count = 0;
00255 
00256 
00257         //copy file into memory
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         //create shader object
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                 //load source
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                         //compile source
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         //free memory
00292         for (GLuint i = 0; i < count; i++)
00293         {
00294                 free(text[i]);
00295         }
00296         if (error == GL_NO_ERROR)
00297         {
00298                 //check for errors
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                         //an error occured, print log
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         //successfully loaded, save results
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                 /*if (try_gpu_class == sMaxVertexShaderLevel[cls])
00339                 {
00340                         max = gpu_class;
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         //check for errors
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                 //an error occured, print log
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         //check program validity against current GL
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 // Shader Management
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         //hack to reset buffers that change behavior with shaders
00428         gPipeline.resetVertexBuffers();
00429 
00430         if (gViewerWindow)
00431         {
00432                 gViewerWindow->setCursor(UI_CURSOR_WAIT);
00433         }
00434 
00435         // Lighting
00436         gPipeline.setLightingDetail(-1);
00437 
00438         // Shaders
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                 // Load lighting shaders
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                         // Load all shaders to set max levels
00470                         loadShadersEnvironment();
00471                         loadShadersObject();
00472                         // Load max avatar shaders to set the max level
00473                         sVertexShaderLevel[SHADER_AVATAR] = 3;
00474                         sMaxVertexShaderLevel[SHADER_AVATAR] = 3;
00475                         loadShadersAvatar();
00476 
00477                         // Load shaders to correct levels
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(); // unloads
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                                 // Set the actual level
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(); // unloads
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         // Load light dependency shaders first
00560         // All of these have to load for any shaders to function
00561         
00562     std::string lightvertex = "lighting/lightV.glsl";
00563         //get default light function implementation
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         // NOTE: Scatter shaders use the ENVIRONMENT detail level
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                 //load water vertex shader
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                 //load ground vertex shader
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                 //load terrain vertex shader
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                 //load glow shader
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                 //load object (volume/tree) vertex shader
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                 //load object bumpy vertex shader
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                 //load object alpha vertex shader
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                 //load shiny vertex shader
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         /*if (success)
00856         {
00857                 //load specular (eyeball) vertex program
00858                 std::string eyeballvertex = "avatar/eyeballV.glsl";
00859                 std::string eyeballfragment = "avatar/eyeballF.glsl";
00860                 gAvatarEyeballProgram.mProgramObject = glCreateProgramObjectARB();
00861                 gAvatarEyeballProgram.attachObjects(baseObjects, baseCount);
00862                 gAvatarEyeballProgram.attachObject(loadShader(eyeballvertex, SHADER_AVATAR, GL_VERTEX_SHADER_ARB));
00863                 gAvatarEyeballProgram.attachObject(loadShader(eyeballfragment, SHADER_AVATAR, GL_FRAGMENT_SHADER_ARB));
00864                 success = gAvatarEyeballProgram.mapAttributes();
00865                 if (success)
00866                 {
00867                         success = gAvatarEyeballProgram.mapUniforms();
00868                 }
00869                 if( !success )
00870                 {
00871                         llwarns << "Failed to load " << eyeballvertex << llendl;
00872                 }
00873         }*/
00874 
00875         if (success)
00876         {
00877                 gAvatarSkinVertex = loadShader("avatar/avatarSkinV.glsl", SHADER_AVATAR, GL_VERTEX_SHADER_ARB);
00878                 //load avatar vertex shader
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                 //load avatar picking shader
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                 //load highlighting shader
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 // LLGLSL Shader implementation
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         //hack to make apple not complain
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         //link the program
01032         BOOL res = link();
01033 
01034         mAttribute.clear();
01035         mAttribute.resize(LLShaderMgr::sReservedAttribCount + count, -1);
01036         
01037         if (res)
01038         { //read back channel locations
01039 
01040                 //read back reserved channels first
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];                /* Flawfinder: ignore */
01080         name[0] = 0;
01081 
01082         glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
01083         
01084         //find the index of this uniform
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])))           /* Flawfinder: ignore */
01088                 {
01089                         //found it
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])))              /* Flawfinder: ignore */
01102                 {
01103                         //found it
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         //llinfos << "Unknown uniform: " << name << llendl;
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         {       //this here is a texture
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         //initialize arrays
01136         mUniform.resize(count + LLShaderMgr::sReservedUniformCount, -1);
01137         mTexture.resize(count + LLShaderMgr::sReservedUniformCount, -1);
01138         
01139         bind();
01140 
01141         //get the number of active uniforms
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 

Generated on Thu Jul 1 06:08:40 2010 for Second Life Viewer by  doxygen 1.4.7