aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llglslshader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llglslshader.cpp')
-rw-r--r--linden/indra/newview/llglslshader.cpp2310
1 files changed, 0 insertions, 2310 deletions
diff --git a/linden/indra/newview/llglslshader.cpp b/linden/indra/newview/llglslshader.cpp
deleted file mode 100644
index a9274b5..0000000
--- a/linden/indra/newview/llglslshader.cpp
+++ /dev/null
@@ -1,2310 +0,0 @@
1/**
2 * @file llglslshader.cpp
3 * @brief GLSL helper functions and state.
4 *
5 * $LicenseInfo:firstyear=2005&license=viewergpl$
6 *
7 * Copyright (c) 2005-2008, Linden Research, Inc.
8 *
9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"), unless you have obtained a separate licensing agreement
13 * ("Other License"), formally executed by you and Linden Lab. Terms of
14 * the GPL can be found in doc/GPL-license.txt in this distribution, or
15 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
16 *
17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 * $/LicenseInfo$
30 */
31
32#include "llviewerprecompiledheaders.h"
33
34#include "llfeaturemanager.h"
35#include "llglslshader.h"
36
37#include "llfile.h"
38#include "llviewerwindow.h"
39#include "llviewercontrol.h"
40#include "pipeline.h"
41#include "llworld.h"
42#include "llwlparammanager.h"
43#include "llwaterparammanager.h"
44#include "llsky.h"
45#include "llvosky.h"
46#include "llrender.h"
47
48#if LL_DARWIN
49#include "OpenGL/OpenGL.h"
50#endif
51
52#ifdef LL_RELEASE_FOR_DOWNLOAD
53#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
54#else
55#define UNIFORM_ERRS LL_ERRS("Shader")
56#endif
57
58// Lots of STL stuff in here, using namespace std to keep things more readable
59using std::vector;
60using std::pair;
61using std::make_pair;
62using std::string;
63
64LLVector4 gShinyOrigin;
65
66//object shaders
67LLGLSLShader gObjectSimpleProgram;
68LLGLSLShader gObjectSimpleWaterProgram;
69LLGLSLShader gObjectFullbrightProgram;
70LLGLSLShader gObjectFullbrightWaterProgram;
71
72LLGLSLShader gObjectFullbrightShinyProgram;
73LLGLSLShader gObjectShinyProgram;
74LLGLSLShader gObjectShinyWaterProgram;
75
76//environment shaders
77LLGLSLShader gTerrainProgram;
78LLGLSLShader gTerrainWaterProgram;
79LLGLSLShader gWaterProgram;
80LLGLSLShader gUnderWaterProgram;
81
82//interface shaders
83LLGLSLShader gHighlightProgram;
84
85//avatar skinning utility shader object
86GLhandleARB gAvatarSkinVertex;
87
88//avatar shader handles
89LLGLSLShader gAvatarProgram;
90LLGLSLShader gAvatarWaterProgram;
91LLGLSLShader gAvatarEyeballProgram;
92LLGLSLShader gAvatarPickProgram;
93
94// WindLight shader handles
95LLGLSLShader gWLSkyProgram;
96LLGLSLShader gWLCloudProgram;
97
98// Effects Shaders
99LLGLSLShader gGlowProgram;
100LLGLSLShader gGlowExtractProgram;
101LLGLSLShader gPostColorFilterProgram;
102LLGLSLShader gPostNightVisionProgram;
103
104// Deferred rendering shaders
105LLGLSLShader gDeferredDiffuseProgram;
106
107//current avatar shader parameter pointer
108GLint gAvatarMatrixParam;
109
110S32 LLShaderMgr::sVertexShaderLevel[SHADER_COUNT] = { 0 };
111
112S32 LLShaderMgr::sMaxAvatarShaderLevel = 0;
113
114std::map<string, GLhandleARB> LLShaderMgr::sShaderObjects;
115vector<string> LLShaderMgr::sReservedAttribs;
116vector<string> LLShaderMgr::sWLUniforms;
117vector<string> LLShaderMgr::sTerrainUniforms;
118vector<string> LLShaderMgr::sReservedUniforms;
119vector<string> LLShaderMgr::sShinyUniforms;
120vector<string> LLShaderMgr::sWaterUniforms;
121vector<string> LLShaderMgr::sGlowUniforms;
122vector<string> LLShaderMgr::sGlowExtractUniforms;
123vector<string> LLShaderMgr::sAvatarAttribs;
124vector<string> LLShaderMgr::sAvatarUniforms;
125//vector< GLhandleARB > LLShaderMgr::sBaseObjects;
126
127/// Make sure WL Sky is the first program
128LLGLSLShader * const LLShaderMgr::sShaderList[] =
129{
130 &gWLSkyProgram,
131 &gWLCloudProgram,
132 &gAvatarProgram,
133 &gObjectShinyProgram,
134 &gWaterProgram,
135 &gAvatarEyeballProgram,
136 &gObjectSimpleProgram,
137 &gObjectFullbrightProgram,
138 &gObjectFullbrightShinyProgram,
139 &gTerrainProgram,
140 &gTerrainWaterProgram,
141 &gObjectSimpleWaterProgram,
142 &gObjectFullbrightWaterProgram,
143 &gAvatarWaterProgram,
144 &gObjectShinyWaterProgram,
145 &gUnderWaterProgram,
146};
147const size_t LLShaderMgr::sNumShaders = sizeof(sShaderList) / sizeof(sShaderList[0]);
148
149
150BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
151{
152 /*F32 dot = v1.mV[0] * v2.mV[0] +
153 v1.mV[1] * v2.mV[1] +
154 v1.mV[2] * v2.mV[2] +
155 v1.mV[3] * v2.mV[3];
156
157 F32 mag = v1.mV[0] * v1.mV[0] +
158 v1.mV[1] * v1.mV[1] +
159 v1.mV[2] * v1.mV[2] +
160 v1.mV[3] * v1.mV[3];
161
162 F32 val = (dot/mag);
163
164 if (val > 2.0f || val < 0.1f)
165 {
166 return TRUE;
167 }
168
169 return FALSE;*/
170
171 return v1 != v2;
172}
173
174LLShaderFeatures::LLShaderFeatures()
175: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
176hasTransport(false), hasSkinning(false), hasAtmospherics(false), isSpecular(false),
177hasGamma(false), hasLighting(false), calculatesAtmospherics(false)
178{
179}
180
181void LLShaderMgr::initAttribsAndUniforms(void)
182{
183 if (sReservedAttribs.empty())
184 {
185 sReservedAttribs.push_back("materialColor");
186 sReservedAttribs.push_back("specularColor");
187 sReservedAttribs.push_back("binormal");
188
189 sAvatarAttribs.reserve(5);
190 sAvatarAttribs.push_back("weight");
191 sAvatarAttribs.push_back("clothing");
192 sAvatarAttribs.push_back("gWindDir");
193 sAvatarAttribs.push_back("gSinWaveParams");
194 sAvatarAttribs.push_back("gGravity");
195
196 sAvatarUniforms.push_back("matrixPalette");
197
198 sReservedUniforms.reserve(24);
199 sReservedUniforms.push_back("diffuseMap");
200 sReservedUniforms.push_back("specularMap");
201 sReservedUniforms.push_back("bumpMap");
202 sReservedUniforms.push_back("environmentMap");
203 sReservedUniforms.push_back("cloude_noise_texture");
204 sReservedUniforms.push_back("fullbright");
205 sReservedUniforms.push_back("lightnorm");
206 sReservedUniforms.push_back("sunlight_color");
207 sReservedUniforms.push_back("ambient");
208 sReservedUniforms.push_back("blue_horizon");
209 sReservedUniforms.push_back("blue_density");
210 sReservedUniforms.push_back("haze_horizon");
211 sReservedUniforms.push_back("haze_density");
212 sReservedUniforms.push_back("cloud_shadow");
213 sReservedUniforms.push_back("density_multiplier");
214 sReservedUniforms.push_back("distance_multiplier");
215 sReservedUniforms.push_back("max_y");
216 sReservedUniforms.push_back("glow");
217 sReservedUniforms.push_back("cloud_color");
218 sReservedUniforms.push_back("cloud_pos_density1");
219 sReservedUniforms.push_back("cloud_pos_density2");
220 sReservedUniforms.push_back("cloud_scale");
221 sReservedUniforms.push_back("gamma");
222 sReservedUniforms.push_back("scene_light_strength");
223
224 sWLUniforms.push_back("camPosLocal");
225
226 sTerrainUniforms.reserve(5);
227 sTerrainUniforms.push_back("detail_0");
228 sTerrainUniforms.push_back("detail_1");
229 sTerrainUniforms.push_back("detail_2");
230 sTerrainUniforms.push_back("detail_3");
231 sTerrainUniforms.push_back("alpha_ramp");
232
233 sGlowUniforms.push_back("glowDelta");
234 sGlowUniforms.push_back("glowStrength");
235
236 sGlowExtractUniforms.push_back("minLuminance");
237 sGlowExtractUniforms.push_back("maxExtractAlpha");
238 sGlowExtractUniforms.push_back("lumWeights");
239 sGlowExtractUniforms.push_back("warmthWeights");
240 sGlowExtractUniforms.push_back("warmthAmount");
241
242 sShinyUniforms.push_back("origin");
243
244 sWaterUniforms.reserve(12);
245 sWaterUniforms.push_back("screenTex");
246 sWaterUniforms.push_back("screenDepth");
247 sWaterUniforms.push_back("refTex");
248 sWaterUniforms.push_back("eyeVec");
249 sWaterUniforms.push_back("time");
250 sWaterUniforms.push_back("d1");
251 sWaterUniforms.push_back("d2");
252 sWaterUniforms.push_back("lightDir");
253 sWaterUniforms.push_back("specular");
254 sWaterUniforms.push_back("lightExp");
255 sWaterUniforms.push_back("fogCol");
256 sWaterUniforms.push_back("kd");
257 sWaterUniforms.push_back("refScale");
258 sWaterUniforms.push_back("waterHeight");
259 }
260}
261
262BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
263{
264 llassert_always(shader != NULL);
265 LLShaderFeatures *features = & shader->mFeatures;
266
267 //////////////////////////////////////
268 // Attach Vertex Shader Features First
269 //////////////////////////////////////
270
271 // NOTE order of shader object attaching is VERY IMPORTANT!!!
272 if (features->calculatesAtmospherics)
273 {
274 if (!shader->attachObject("windlight/atmosphericsVarsV.glsl"))
275 {
276 return FALSE;
277 }
278 }
279
280 if (features->calculatesLighting)
281 {
282 if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl"))
283 {
284 return FALSE;
285 }
286
287 if (features->isSpecular)
288 {
289 if (!shader->attachObject("lighting/lightFuncSpecularV.glsl"))
290 {
291 return FALSE;
292 }
293
294 if (!shader->attachObject("lighting/sumLightsSpecularV.glsl"))
295 {
296 return FALSE;
297 }
298
299 if (!shader->attachObject("lighting/lightSpecularV.glsl"))
300 {
301 return FALSE;
302 }
303 }
304 else
305 {
306 if (!shader->attachObject("lighting/lightFuncV.glsl"))
307 {
308 return FALSE;
309 }
310
311 if (!shader->attachObject("lighting/sumLightsV.glsl"))
312 {
313 return FALSE;
314 }
315
316 if (!shader->attachObject("lighting/lightV.glsl"))
317 {
318 return FALSE;
319 }
320 }
321 }
322
323 // NOTE order of shader object attaching is VERY IMPORTANT!!!
324 if (features->calculatesAtmospherics)
325 {
326 if (!shader->attachObject("windlight/atmosphericsV.glsl"))
327 {
328 return FALSE;
329 }
330 }
331
332 if (features->hasSkinning)
333 {
334 if (!shader->attachObject("avatar/avatarSkinV.glsl"))
335 {
336 return FALSE;
337 }
338 }
339
340 ///////////////////////////////////////
341 // Attach Fragment Shader Features Next
342 ///////////////////////////////////////
343
344 if(features->calculatesAtmospherics)
345 {
346 if (!shader->attachObject("windlight/atmosphericsVarsF.glsl"))
347 {
348 return FALSE;
349 }
350 }
351
352 // NOTE order of shader object attaching is VERY IMPORTANT!!!
353 if (features->hasGamma)
354 {
355 if (!shader->attachObject("windlight/gammaF.glsl"))
356 {
357 return FALSE;
358 }
359 }
360
361 if (features->hasAtmospherics)
362 {
363 if (!shader->attachObject("windlight/atmosphericsF.glsl"))
364 {
365 return FALSE;
366 }
367 }
368
369 if (features->hasTransport)
370 {
371 if (!shader->attachObject("windlight/transportF.glsl"))
372 {
373 return FALSE;
374 }
375
376 // Test hasFullbright and hasShiny and attach fullbright and
377 // fullbright shiny atmos transport if we split them out.
378 }
379
380 // NOTE order of shader object attaching is VERY IMPORTANT!!!
381 if (features->hasWaterFog)
382 {
383 if (!shader->attachObject("environment/waterFogF.glsl"))
384 {
385 return FALSE;
386 }
387 }
388
389 if (features->hasLighting)
390 {
391
392 if (features->hasWaterFog)
393 {
394 if (!shader->attachObject("lighting/lightWaterF.glsl"))
395 {
396 return FALSE;
397 }
398 }
399
400 else
401 {
402 if (!shader->attachObject("lighting/lightF.glsl"))
403 {
404 return FALSE;
405 }
406 }
407 }
408
409 // NOTE order of shader object attaching is VERY IMPORTANT!!!
410 else if (features->isFullbright)
411 {
412
413 if (features->hasWaterFog)
414 {
415 if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
416 {
417 return FALSE;
418 }
419 }
420
421 else if (features->isShiny)
422 {
423 if (!shader->attachObject("lighting/lightFullbrightShinyF.glsl"))
424 {
425 return FALSE;
426 }
427 }
428
429 else
430 {
431 if (!shader->attachObject("lighting/lightFullbrightF.glsl"))
432 {
433 return FALSE;
434 }
435 }
436 }
437
438 // NOTE order of shader object attaching is VERY IMPORTANT!!!
439 else if (features->isShiny)
440 {
441
442 if (features->hasWaterFog)
443 {
444 if (!shader->attachObject("lighting/lightShinyWaterF.glsl"))
445 {
446 return FALSE;
447 }
448 }
449
450 else
451 {
452 if (!shader->attachObject("lighting/lightShinyF.glsl"))
453 {
454 return FALSE;
455 }
456 }
457 }
458 return TRUE;
459}
460
461//============================================================================
462// Set Levels
463
464S32 LLShaderMgr::getVertexShaderLevel(S32 type)
465{
466 return LLPipeline::sDisableShaders ? 0 : sVertexShaderLevel[type];
467}
468
469
470//============================================================================
471// Load Shader
472
473static LLString get_object_log(GLhandleARB ret)
474{
475 LLString res;
476
477 //get log length
478 GLint length;
479 glGetObjectParameterivARB(ret, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
480 if (length > 0)
481 {
482 //the log could be any size, so allocate appropriately
483 GLcharARB* log = new GLcharARB[length];
484 glGetInfoLogARB(ret, length, &length, log);
485 res = LLString((char *)log);
486 delete[] log;
487 }
488 return res;
489}
490
491void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
492{
493 LLString log = get_object_log(ret);
494 if (warns)
495 {
496 LL_WARNS("ShaderLoading") << log << LL_ENDL;
497 }
498 else
499 {
500 LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
501 }
502}
503
504GLhandleARB LLShaderMgr::loadShaderFile(const LLString& filename, S32 & shader_level, GLenum type)
505{
506 GLenum error;
507 error = glGetError();
508 if (error != GL_NO_ERROR)
509 {
510 LL_WARNS("ShaderLoading") << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL;
511 }
512
513 LL_DEBUGS("ShaderLoading") << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL;
514
515 if (filename.empty())
516 {
517 return 0;
518 }
519
520
521 //read in from file
522 LLFILE* file = NULL;
523
524 S32 try_gpu_class = shader_level;
525 S32 gpu_class;
526
527 //find the most relevant file
528 for (gpu_class = try_gpu_class; gpu_class > 0; gpu_class--)
529 { //search from the current gpu class down to class 1 to find the most relevant shader
530 std::stringstream fname;
531 fname << gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
532 fname << gpu_class << "/" << filename;
533
534 LL_DEBUGS("ShaderLoading") << "Looking in " << fname.str().c_str() << LL_ENDL;
535 file = LLFile::fopen(fname.str().c_str(), "r"); /* Flawfinder: ignore */
536 if (file)
537 {
538 LL_INFOS("ShaderLoading") << "Loading file: shaders/class" << gpu_class << "/" << filename << " (Want class " << gpu_class << ")" << LL_ENDL;
539 break; // done
540 }
541 }
542
543 if (file == NULL)
544 {
545 LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << filename << LL_ENDL;
546 return 0;
547 }
548
549 //we can't have any lines longer than 1024 characters
550 //or any shaders longer than 1024 lines... deal - DaveP
551 GLcharARB buff[1024];
552 GLcharARB* text[1024];
553 GLuint count = 0;
554
555
556 //copy file into memory
557 while(fgets((char *)buff, 1024, file) != NULL && count < (sizeof(buff)/sizeof(buff[0])))
558 {
559 text[count++] = (GLcharARB *)strdup((char *)buff);
560 }
561 fclose(file);
562
563 //create shader object
564 GLhandleARB ret = glCreateShaderObjectARB(type);
565 error = glGetError();
566 if (error != GL_NO_ERROR)
567 {
568 LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << LL_ENDL;
569 }
570 else
571 {
572 //load source
573 glShaderSourceARB(ret, count, (const GLcharARB**) text, NULL);
574 error = glGetError();
575 if (error != GL_NO_ERROR)
576 {
577 LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << LL_ENDL;
578 }
579 else
580 {
581 //compile source
582 glCompileShaderARB(ret);
583 error = glGetError();
584 if (error != GL_NO_ERROR)
585 {
586 LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << LL_ENDL;
587 }
588 }
589 }
590 //free memory
591 for (GLuint i = 0; i < count; i++)
592 {
593 free(text[i]);
594 }
595 if (error == GL_NO_ERROR)
596 {
597 //check for errors
598 GLint success = GL_TRUE;
599 glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success);
600 error = glGetError();
601 if (error != GL_NO_ERROR || success == GL_FALSE)
602 {
603 //an error occured, print log
604 LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
605 dumpObjectLog(ret);
606 ret = 0;
607 }
608 }
609 else
610 {
611 ret = 0;
612 }
613 stop_glerror();
614
615 //successfully loaded, save results
616 if (ret)
617 {
618 // Add shader file to map
619 sShaderObjects[filename] = ret;
620 shader_level = try_gpu_class;
621 }
622 else
623 {
624 if (shader_level > 1)
625 {
626 shader_level--;
627 return loadShaderFile(filename,shader_level,type);
628 }
629 LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;
630 }
631 return ret;
632}
633
634BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
635{
636 //check for errors
637 glLinkProgramARB(obj);
638 GLint success = GL_TRUE;
639 glGetObjectParameterivARB(obj, GL_OBJECT_LINK_STATUS_ARB, &success);
640 if (!suppress_errors && success == GL_FALSE)
641 {
642 //an error occured, print log
643 LL_WARNS("ShaderLoading") << "GLSL Linker Error:" << LL_ENDL;
644 }
645
646// NOTE: Removing LL_DARWIN block as it doesn't seem to actually give the correct answer,
647// but want it for reference once I move it.
648#if 0
649 // Force an evaluation of the gl state so the driver can tell if the shader will run in hardware or software
650 // per Apple's suggestion
651 glBegin(gGL.mMode);
652 glEnd();
653
654 // Query whether the shader can or cannot run in hardware
655 // http://developer.apple.com/qa/qa2007/qa1502.html
656 long vertexGPUProcessing;
657 CGLContextObj ctx = CGLGetCurrentContext();
658 CGLGetParameter (ctx, kCGLCPGPUVertexProcessing, &vertexGPUProcessing);
659 long fragmentGPUProcessing;
660 CGLGetParameter (ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing);
661 if (!fragmentGPUProcessing || !vertexGPUProcessing)
662 {
663 LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
664 success = GL_FALSE;
665 suppress_errors = FALSE;
666 }
667
668#else
669 LLString log = get_object_log(obj);
670 LLString::toLower(log);
671 if (log.find("software") != LLString::npos)
672 {
673 LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
674 success = GL_FALSE;
675 suppress_errors = FALSE;
676 }
677#endif
678 if (!suppress_errors)
679 {
680 dumpObjectLog(obj, !success);
681 }
682
683 return success;
684}
685
686BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj)
687{
688 //check program validity against current GL
689 glValidateProgramARB(obj);
690 GLint success = GL_TRUE;
691 glGetObjectParameterivARB(obj, GL_OBJECT_VALIDATE_STATUS_ARB, &success);
692 if (success == GL_FALSE)
693 {
694 LL_WARNS("ShaderLoading") << "GLSL program not valid: " << LL_ENDL;
695 dumpObjectLog(obj);
696 }
697 else
698 {
699 dumpObjectLog(obj, FALSE);
700 }
701
702 return success;
703}
704
705//============================================================================
706// Shader Management
707
708void LLShaderMgr::setShaders()
709{
710 if (!gPipeline.mInitialized)
711 {
712 return;
713 }
714 // Make sure the compiled shader map is cleared before we recompile shaders.
715 sShaderObjects.clear();
716
717 initAttribsAndUniforms();
718 gPipeline.releaseGLBuffers();
719
720 if (gSavedSettings.getBOOL("VertexShaderEnable"))
721 {
722 LLPipeline::sWaterReflections = gGLManager.mHasCubeMap;
723 LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
724 }
725 else
726 {
727 LLPipeline::sRenderGlow =
728 LLPipeline::sWaterReflections = FALSE;
729 }
730
731 //hack to reset buffers that change behavior with shaders
732 gPipeline.resetVertexBuffers();
733
734 if (gViewerWindow)
735 {
736 gViewerWindow->setCursor(UI_CURSOR_WAIT);
737 }
738
739 // Lighting
740 gPipeline.setLightingDetail(-1);
741
742 // Shaders
743 LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL;
744 for (S32 i = 0; i < SHADER_COUNT; i++)
745 {
746 sVertexShaderLevel[i] = 0;
747 }
748 sMaxAvatarShaderLevel = 0;
749
750 if (LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")
751 && gSavedSettings.getBOOL("VertexShaderEnable"))
752 {
753 S32 light_class = 2;
754 S32 env_class = 2;
755 S32 obj_class = 2;
756 S32 effect_class = 2;
757 S32 wl_class = 2;
758 S32 water_class = 2;
759 S32 deferred_class = 0;
760 if (!gSavedSettings.getBOOL("WindLightUseAtmosShaders"))
761 {
762 // user has disabled WindLight in their settings, downgrade
763 // windlight shaders to stub versions.
764 wl_class = 1;
765
766 // if class one or less, turn off more shaders
767 // since higher end cards won't see any real gain
768 // from turning off most of the shaders,
769 // but class one would
770 // TODO: Make water on class one cards color things
771 // beneath it properly
772 if(LLFeatureManager::getInstance()->getGPUClass() < GPU_CLASS_2)
773 {
774 // use lesser water and other stuff
775 light_class = 2;
776 env_class = 0;
777 obj_class = 0;
778 effect_class = 1;
779 water_class = 1;
780 }
781 }
782
783 if (gSavedSettings.getBOOL("RenderDeferred"))
784 {
785 light_class = 1;
786 env_class = 0;
787 obj_class = 0;
788 water_class = 1;
789 effect_class = 1;
790 deferred_class = 1;
791 }
792
793 if(!gSavedSettings.getBOOL("EnableRippleWater"))
794 {
795 water_class = 0;
796 }
797
798 // Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders
799 if (sVertexShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull())
800 {
801 gSky.mVOSkyp->forceSkyUpdate();
802 }
803
804 // Load lighting shaders
805 sVertexShaderLevel[SHADER_LIGHTING] = light_class;
806 sVertexShaderLevel[SHADER_INTERFACE] = light_class;
807 sVertexShaderLevel[SHADER_ENVIRONMENT] = env_class;
808 sVertexShaderLevel[SHADER_WATER] = water_class;
809 sVertexShaderLevel[SHADER_OBJECT] = obj_class;
810 sVertexShaderLevel[SHADER_EFFECT] = effect_class;
811 sVertexShaderLevel[SHADER_WINDLIGHT] = wl_class;
812 sVertexShaderLevel[SHADER_DEFERRED] = deferred_class;
813
814 BOOL loaded = loadBasicShaders();
815
816 if (loaded)
817 {
818 gPipeline.mVertexShadersEnabled = TRUE;
819 gPipeline.mVertexShadersLoaded = 1;
820
821 // Load all shaders to set max levels
822 loadShadersEnvironment();
823 loadShadersWater();
824 loadShadersObject();
825 loadShadersWindLight();
826 loadShadersEffects();
827 loadShadersInterface();
828 loadShadersDeferred();
829
830 // Load max avatar shaders to set the max level
831 sVertexShaderLevel[SHADER_AVATAR] = 3;
832 sMaxAvatarShaderLevel = 3;
833 loadShadersAvatar();
834
835#if 0 && LL_DARWIN // force avatar shaders off for mac
836 sVertexShaderLevel[SHADER_AVATAR] = 0;
837 sMaxAvatarShaderLevel = 0;
838#else
839 if (gSavedSettings.getBOOL("RenderAvatarVP"))
840 {
841 BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
842 S32 avatar_class = 1;
843
844 // cloth is a class3 shader
845 if(avatar_cloth)
846 {
847 avatar_class = 3;
848 }
849
850 // Set the actual level
851 sVertexShaderLevel[SHADER_AVATAR] = avatar_class;
852 loadShadersAvatar();
853 if (sVertexShaderLevel[SHADER_AVATAR] != avatar_class)
854 {
855 if (sVertexShaderLevel[SHADER_AVATAR] == 0)
856 {
857 gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
858 }
859 if(llmax(sVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3)
860 {
861 avatar_cloth = true;
862 }
863 else
864 {
865 avatar_cloth = false;
866 }
867 gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
868 }
869 }
870 else
871 {
872 sVertexShaderLevel[SHADER_AVATAR] = 0;
873 gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
874 loadShadersAvatar(); // unloads
875 }
876#endif
877 }
878 else
879 {
880 gPipeline.mVertexShadersEnabled = FALSE;
881 gPipeline.mVertexShadersLoaded = 0;
882 sVertexShaderLevel[SHADER_LIGHTING] = 0;
883 sVertexShaderLevel[SHADER_INTERFACE] = 0;
884 sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
885 sVertexShaderLevel[SHADER_WATER] = 0;
886 sVertexShaderLevel[SHADER_OBJECT] = 0;
887 sVertexShaderLevel[SHADER_EFFECT] = 0;
888 sVertexShaderLevel[SHADER_WINDLIGHT] = 0;
889 }
890 }
891 else
892 {
893 gPipeline.mVertexShadersEnabled = FALSE;
894 gPipeline.mVertexShadersLoaded = 0;
895 sVertexShaderLevel[SHADER_LIGHTING] = 0;
896 sVertexShaderLevel[SHADER_INTERFACE] = 0;
897 sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
898 sVertexShaderLevel[SHADER_WATER] = 0;
899 sVertexShaderLevel[SHADER_OBJECT] = 0;
900 sVertexShaderLevel[SHADER_EFFECT] = 0;
901 sVertexShaderLevel[SHADER_WINDLIGHT] = 0;
902 }
903
904 if (gViewerWindow)
905 {
906 gViewerWindow->setCursor(UI_CURSOR_ARROW);
907 }
908 gPipeline.createGLBuffers();
909}
910
911void LLShaderMgr::unloadShaders()
912{
913 gObjectSimpleProgram.unload();
914 gObjectSimpleWaterProgram.unload();
915 gObjectFullbrightProgram.unload();
916 gObjectFullbrightWaterProgram.unload();
917
918 gObjectShinyProgram.unload();
919 gObjectFullbrightShinyProgram.unload();
920 gObjectShinyWaterProgram.unload();
921 gWaterProgram.unload();
922 gUnderWaterProgram.unload();
923 gTerrainProgram.unload();
924 gTerrainWaterProgram.unload();
925 gGlowProgram.unload();
926 gGlowExtractProgram.unload();
927 gAvatarProgram.unload();
928 gAvatarWaterProgram.unload();
929 gAvatarEyeballProgram.unload();
930 gAvatarPickProgram.unload();
931 gHighlightProgram.unload();
932
933 gWLSkyProgram.unload();
934 gWLCloudProgram.unload();
935
936 gPostColorFilterProgram.unload();
937 gPostNightVisionProgram.unload();
938
939 gDeferredDiffuseProgram.unload();
940
941 sVertexShaderLevel[SHADER_LIGHTING] = 0;
942 sVertexShaderLevel[SHADER_OBJECT] = 0;
943 sVertexShaderLevel[SHADER_AVATAR] = 0;
944 sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
945 sVertexShaderLevel[SHADER_WATER] = 0;
946 sVertexShaderLevel[SHADER_INTERFACE] = 0;
947
948 gPipeline.mVertexShadersLoaded = 0;
949}
950
951BOOL LLShaderMgr::loadBasicShaders()
952{
953 // Load basic dependency shaders first
954 // All of these have to load for any shaders to function
955
956#if LL_DARWIN // Mac can't currently handle all 8 lights,
957 S32 sum_lights_class = 2;
958#else
959 S32 sum_lights_class = 3;
960
961 // class one cards will get the lower sum lights
962 // class zero we're not going to think about
963 // since a class zero card COULD be a ridiculous new card
964 // and old cards should have the features masked
965 if(LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_1)
966 {
967 sum_lights_class = 2;
968 }
969#endif
970
971 // If we have sun and moon only checked, then only sum those lights.
972 if (gPipeline.getLightingDetail() == 0)
973 {
974 sum_lights_class = 1;
975 }
976
977 // Load the Basic Vertex Shaders at the appropriate level.
978 // (in order of shader function call depth for reference purposes, deepest level first)
979
980 vector< pair<string, S32> > shaders;
981 shaders.reserve(10);
982 shaders.push_back( make_pair( "windlight/atmosphericsVarsV.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) );
983 shaders.push_back( make_pair( "windlight/atmosphericsHelpersV.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) );
984 shaders.push_back( make_pair( "lighting/lightFuncV.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) );
985 shaders.push_back( make_pair( "lighting/sumLightsV.glsl", sum_lights_class ) );
986 shaders.push_back( make_pair( "lighting/lightV.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) );
987 shaders.push_back( make_pair( "lighting/lightFuncSpecularV.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) );
988 shaders.push_back( make_pair( "lighting/sumLightsSpecularV.glsl", sum_lights_class ) );
989 shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) );
990 shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) );
991 shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) );
992
993 // We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
994 for (U32 i = 0; i < shaders.size(); i++)
995 {
996 // Note usage of GL_VERTEX_SHADER_ARB
997 if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB) == 0)
998 {
999 return FALSE;
1000 }
1001 }
1002
1003 // Load the Basic Fragment Shaders at the appropriate level.
1004 // (in order of shader function call depth for reference purposes, deepest level first)
1005
1006 shaders.clear();
1007 shaders.reserve(12);
1008 shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) );
1009 shaders.push_back( make_pair( "windlight/gammaF.glsl", sVertexShaderLevel[SHADER_WINDLIGHT]) );
1010 shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) );
1011 shaders.push_back( make_pair( "windlight/transportF.glsl", sVertexShaderLevel[SHADER_WINDLIGHT] ) );
1012 shaders.push_back( make_pair( "environment/waterFogF.glsl", sVertexShaderLevel[SHADER_WATER] ) );
1013 shaders.push_back( make_pair( "lighting/lightF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) );
1014 shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) );
1015 shaders.push_back( make_pair( "lighting/lightWaterF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) );
1016 shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) );
1017 shaders.push_back( make_pair( "lighting/lightShinyF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) );
1018 shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) );
1019 shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", sVertexShaderLevel[SHADER_LIGHTING] ) );
1020
1021 for (U32 i = 0; i < shaders.size(); i++)
1022 {
1023 // Note usage of GL_FRAGMENT_SHADER_ARB
1024 if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB) == 0)
1025 {
1026 return FALSE;
1027 }
1028 }
1029
1030 return TRUE;
1031}
1032
1033BOOL LLShaderMgr::loadShadersEnvironment()
1034{
1035 BOOL success = TRUE;
1036
1037 if (sVertexShaderLevel[SHADER_ENVIRONMENT] == 0)
1038 {
1039 gTerrainProgram.unload();
1040 return FALSE;
1041 }
1042
1043 if (success)
1044 {
1045 gTerrainProgram.mName = "Terrain Shader";
1046 gTerrainProgram.mFeatures.calculatesLighting = true;
1047 gTerrainProgram.mFeatures.calculatesAtmospherics = true;
1048 gTerrainProgram.mFeatures.hasAtmospherics = true;
1049 gTerrainProgram.mFeatures.hasGamma = true;
1050 gTerrainProgram.mShaderFiles.clear();
1051 gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));
1052 gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
1053 gTerrainProgram.mShaderLevel = sVertexShaderLevel[SHADER_ENVIRONMENT];
1054 success = gTerrainProgram.createShader(NULL, &sTerrainUniforms);
1055 }
1056
1057 if (!success)
1058 {
1059 sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
1060 return FALSE;
1061 }
1062
1063 LLWorld::getInstance()->updateWaterObjects();
1064
1065 return TRUE;
1066}
1067
1068BOOL LLShaderMgr::loadShadersWater()
1069{
1070 BOOL success = TRUE;
1071 BOOL terrainWaterSuccess = TRUE;
1072
1073 if (sVertexShaderLevel[SHADER_WATER] == 0)
1074 {
1075 gWaterProgram.unload();
1076 gUnderWaterProgram.unload();
1077 gTerrainWaterProgram.unload();
1078 return FALSE;
1079 }
1080
1081 if (success)
1082 {
1083 // load water shader
1084 gWaterProgram.mName = "Water Shader";
1085 gWaterProgram.mFeatures.calculatesAtmospherics = true;
1086 gWaterProgram.mFeatures.hasGamma = true;
1087 gWaterProgram.mFeatures.hasTransport = true;
1088 gWaterProgram.mShaderFiles.clear();
1089 gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
1090 gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
1091 gWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_WATER];
1092 success = gWaterProgram.createShader(NULL, &sWaterUniforms);
1093 }
1094
1095 if (success)
1096 {
1097 //load under water vertex shader
1098 gUnderWaterProgram.mName = "Underwater Shader";
1099 gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
1100 gUnderWaterProgram.mShaderFiles.clear();
1101 gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
1102 gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
1103 gUnderWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_WATER];
1104 gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
1105
1106 success = gUnderWaterProgram.createShader(NULL, &sWaterUniforms);
1107 }
1108
1109 if (success)
1110 {
1111 //load terrain water shader
1112 gTerrainWaterProgram.mName = "Terrain Water Shader";
1113 gTerrainWaterProgram.mFeatures.calculatesLighting = true;
1114 gTerrainWaterProgram.mFeatures.calculatesAtmospherics = true;
1115 gTerrainWaterProgram.mFeatures.hasAtmospherics = true;
1116 gTerrainWaterProgram.mFeatures.hasWaterFog = true;
1117 gTerrainWaterProgram.mShaderFiles.clear();
1118 gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));
1119 gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
1120 gTerrainWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_ENVIRONMENT];
1121 gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
1122 terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, &sTerrainUniforms);
1123 }
1124
1125 /// Keep track of water shader levels
1126 if (gWaterProgram.mShaderLevel != sVertexShaderLevel[SHADER_WATER]
1127 || gUnderWaterProgram.mShaderLevel != sVertexShaderLevel[SHADER_WATER])
1128 {
1129 sVertexShaderLevel[SHADER_WATER] = llmin(gWaterProgram.mShaderLevel, gUnderWaterProgram.mShaderLevel);
1130 }
1131
1132 if (!success)
1133 {
1134 sVertexShaderLevel[SHADER_WATER] = 0;
1135 return FALSE;
1136 }
1137
1138 // if we failed to load the terrain water shaders and we need them (using class2 water),
1139 // then drop down to class1 water.
1140 if (sVertexShaderLevel[SHADER_WATER] > 1 && !terrainWaterSuccess)
1141 {
1142 sVertexShaderLevel[SHADER_WATER]--;
1143 return loadShadersWater();
1144 }
1145
1146 LLWorld::getInstance()->updateWaterObjects();
1147
1148 return TRUE;
1149}
1150
1151BOOL LLShaderMgr::loadShadersEffects()
1152{
1153 BOOL success = TRUE;
1154
1155 if (sVertexShaderLevel[SHADER_EFFECT] == 0)
1156 {
1157 gGlowProgram.unload();
1158 gGlowExtractProgram.unload();
1159 gPostColorFilterProgram.unload();
1160 gPostNightVisionProgram.unload();
1161 return FALSE;
1162 }
1163
1164 if (success)
1165 {
1166 gGlowProgram.mName = "Glow Shader (Post)";
1167 gGlowProgram.mShaderFiles.clear();
1168 gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB));
1169 gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB));
1170 gGlowProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT];
1171 success = gGlowProgram.createShader(NULL, &sGlowUniforms);
1172 if (!success)
1173 {
1174 LLPipeline::sRenderGlow = FALSE;
1175 }
1176 }
1177
1178 if (success)
1179 {
1180 gGlowExtractProgram.mName = "Glow Extract Shader (Post)";
1181 gGlowExtractProgram.mShaderFiles.clear();
1182 gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB));
1183 gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB));
1184 gGlowExtractProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT];
1185 success = gGlowExtractProgram.createShader(NULL, &sGlowExtractUniforms);
1186 if (!success)
1187 {
1188 LLPipeline::sRenderGlow = FALSE;
1189 }
1190 }
1191
1192#if 0
1193 // disabling loading of postprocess shaders until we fix
1194 // ATI sampler2DRect compatibility.
1195
1196 //load Color Filter Shader
1197 if (success)
1198 {
1199 vector<string> shaderUniforms;
1200 shaderUniforms.reserve(7);
1201 shaderUniforms.push_back("RenderTexture");
1202 shaderUniforms.push_back("gamma");
1203 shaderUniforms.push_back("brightness");
1204 shaderUniforms.push_back("contrast");
1205 shaderUniforms.push_back("contrastBase");
1206 shaderUniforms.push_back("saturation");
1207 shaderUniforms.push_back("lumWeights");
1208
1209 gPostColorFilterProgram.mName = "Color Filter Shader (Post)";
1210 gPostColorFilterProgram.mShaderFiles.clear();
1211 gPostColorFilterProgram.mShaderFiles.push_back(make_pair("effects/colorFilterF.glsl", GL_FRAGMENT_SHADER_ARB));
1212 gPostColorFilterProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB));
1213 gPostColorFilterProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT];
1214 success = gPostColorFilterProgram.createShader(NULL, &shaderUniforms);
1215 }
1216
1217 //load Night Vision Shader
1218 if (success)
1219 {
1220 vector<string> shaderUniforms;
1221 shaderUniforms.reserve(5);
1222 shaderUniforms.push_back("RenderTexture");
1223 shaderUniforms.push_back("NoiseTexture");
1224 shaderUniforms.push_back("brightMult");
1225 shaderUniforms.push_back("noiseStrength");
1226 shaderUniforms.push_back("lumWeights");
1227
1228 gPostNightVisionProgram.mName = "Night Vision Shader (Post)";
1229 gPostNightVisionProgram.mShaderFiles.clear();
1230 gPostNightVisionProgram.mShaderFiles.push_back(make_pair("effects/nightVisionF.glsl", GL_FRAGMENT_SHADER_ARB));
1231 gPostNightVisionProgram.mShaderFiles.push_back(make_pair("effects/drawQuadV.glsl", GL_VERTEX_SHADER_ARB));
1232 gPostNightVisionProgram.mShaderLevel = sVertexShaderLevel[SHADER_EFFECT];
1233 success = gPostNightVisionProgram.createShader(NULL, &shaderUniforms);
1234 }
1235 #endif
1236
1237 return success;
1238
1239}
1240
1241BOOL LLShaderMgr::loadShadersDeferred()
1242{
1243 if (sVertexShaderLevel[SHADER_DEFERRED] == 0)
1244 {
1245 gDeferredDiffuseProgram.unload();
1246 return FALSE;
1247 }
1248
1249 BOOL success = TRUE;
1250
1251 if (success)
1252 {
1253 gDeferredDiffuseProgram.mName = "Deffered Diffuse Shader";
1254 gDeferredDiffuseProgram.mShaderFiles.clear();
1255 gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
1256 gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB));
1257 gDeferredDiffuseProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED];
1258 success = gDeferredDiffuseProgram.createShader(NULL, NULL);
1259 }
1260
1261 return success;
1262}
1263
1264BOOL LLShaderMgr::loadShadersObject()
1265{
1266 BOOL success = TRUE;
1267
1268 if (sVertexShaderLevel[SHADER_OBJECT] == 0)
1269 {
1270 gObjectShinyProgram.unload();
1271 gObjectFullbrightShinyProgram.unload();
1272 gObjectShinyWaterProgram.unload();
1273 gObjectSimpleProgram.unload();
1274 gObjectSimpleWaterProgram.unload();
1275 gObjectFullbrightProgram.unload();
1276 gObjectFullbrightWaterProgram.unload();
1277 return FALSE;
1278 }
1279
1280 if (success)
1281 {
1282 gObjectSimpleProgram.mName = "Simple Shader";
1283 gObjectSimpleProgram.mFeatures.calculatesLighting = true;
1284 gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true;
1285 gObjectSimpleProgram.mFeatures.hasGamma = true;
1286 gObjectSimpleProgram.mFeatures.hasAtmospherics = true;
1287 gObjectSimpleProgram.mFeatures.hasLighting = true;
1288 gObjectSimpleProgram.mShaderFiles.clear();
1289 gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
1290 gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
1291 gObjectSimpleProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
1292 success = gObjectSimpleProgram.createShader(NULL, NULL);
1293 }
1294
1295 if (success)
1296 {
1297 gObjectSimpleWaterProgram.mName = "Simple Water Shader";
1298 gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true;
1299 gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true;
1300 gObjectSimpleWaterProgram.mFeatures.hasWaterFog = true;
1301 gObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true;
1302 gObjectSimpleWaterProgram.mFeatures.hasLighting = true;
1303 gObjectSimpleWaterProgram.mShaderFiles.clear();
1304 gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
1305 gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
1306 gObjectSimpleWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
1307 gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
1308 success = gObjectSimpleWaterProgram.createShader(NULL, NULL);
1309 }
1310
1311 if (success)
1312 {
1313 gObjectFullbrightProgram.mName = "Fullbright Shader";
1314 gObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true;
1315 gObjectFullbrightProgram.mFeatures.hasGamma = true;
1316 gObjectFullbrightProgram.mFeatures.hasTransport = true;
1317 gObjectFullbrightProgram.mFeatures.isFullbright = true;
1318 gObjectFullbrightProgram.mShaderFiles.clear();
1319 gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
1320 gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
1321 gObjectFullbrightProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
1322 success = gObjectFullbrightProgram.createShader(NULL, NULL);
1323 }
1324
1325 if (success)
1326 {
1327 gObjectFullbrightWaterProgram.mName = "Fullbright Water Shader";
1328 gObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
1329 gObjectFullbrightWaterProgram.mFeatures.isFullbright = true;
1330 gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;
1331 gObjectFullbrightWaterProgram.mFeatures.hasTransport = true;
1332 gObjectFullbrightWaterProgram.mShaderFiles.clear();
1333 gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
1334 gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
1335 gObjectFullbrightWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
1336 gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
1337 success = gObjectFullbrightWaterProgram.createShader(NULL, NULL);
1338 }
1339
1340 if (success)
1341 {
1342 gObjectShinyProgram.mName = "Shiny Shader";
1343 gObjectShinyProgram.mFeatures.calculatesAtmospherics = true;
1344 gObjectShinyProgram.mFeatures.calculatesLighting = true;
1345 gObjectShinyProgram.mFeatures.hasGamma = true;
1346 gObjectShinyProgram.mFeatures.hasAtmospherics = true;
1347 gObjectShinyProgram.mFeatures.isShiny = true;
1348 gObjectShinyProgram.mShaderFiles.clear();
1349 gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
1350 gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
1351 gObjectShinyProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
1352 success = gObjectShinyProgram.createShader(NULL, &sShinyUniforms);
1353 }
1354
1355 if (success)
1356 {
1357 gObjectShinyWaterProgram.mName = "Shiny Water Shader";
1358 gObjectShinyWaterProgram.mFeatures.calculatesAtmospherics = true;
1359 gObjectShinyWaterProgram.mFeatures.calculatesLighting = true;
1360 gObjectShinyWaterProgram.mFeatures.isShiny = true;
1361 gObjectShinyWaterProgram.mFeatures.hasWaterFog = true;
1362 gObjectShinyWaterProgram.mFeatures.hasAtmospherics = true;
1363 gObjectShinyWaterProgram.mShaderFiles.clear();
1364 gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
1365 gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
1366 gObjectShinyWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
1367 gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
1368 success = gObjectShinyWaterProgram.createShader(NULL, &sShinyUniforms);
1369 }
1370
1371 if (success)
1372 {
1373 gObjectFullbrightShinyProgram.mName = "Fullbright Shiny Shader";
1374 gObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
1375 gObjectFullbrightShinyProgram.mFeatures.isFullbright = true;
1376 gObjectFullbrightShinyProgram.mFeatures.isShiny = true;
1377 gObjectFullbrightShinyProgram.mFeatures.hasGamma = true;
1378 gObjectFullbrightShinyProgram.mFeatures.hasTransport = true;
1379 gObjectFullbrightShinyProgram.mShaderFiles.clear();
1380 gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
1381 gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
1382 gObjectFullbrightShinyProgram.mShaderLevel = sVertexShaderLevel[SHADER_OBJECT];
1383 success = gObjectFullbrightShinyProgram.createShader(NULL, &sShinyUniforms);
1384 }
1385
1386
1387 if( !success )
1388 {
1389 sVertexShaderLevel[SHADER_OBJECT] = 0;
1390 return FALSE;
1391 }
1392
1393 return TRUE;
1394}
1395
1396BOOL LLShaderMgr::loadShadersAvatar()
1397{
1398 BOOL success = TRUE;
1399
1400 if (sVertexShaderLevel[SHADER_AVATAR] == 0)
1401 {
1402 gAvatarProgram.unload();
1403 gAvatarWaterProgram.unload();
1404 gAvatarEyeballProgram.unload();
1405 gAvatarPickProgram.unload();
1406 return FALSE;
1407 }
1408
1409 if (success)
1410 {
1411 gAvatarProgram.mName = "Avatar Shader";
1412 gAvatarProgram.mFeatures.hasSkinning = true;
1413 gAvatarProgram.mFeatures.calculatesAtmospherics = true;
1414 gAvatarProgram.mFeatures.calculatesLighting = true;
1415 gAvatarProgram.mFeatures.hasGamma = true;
1416 gAvatarProgram.mFeatures.hasAtmospherics = true;
1417 gAvatarProgram.mFeatures.hasLighting = true;
1418 gAvatarProgram.mShaderFiles.clear();
1419 gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
1420 gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));
1421 gAvatarProgram.mShaderLevel = sVertexShaderLevel[SHADER_AVATAR];
1422 success = gAvatarProgram.createShader(&sAvatarAttribs, &sAvatarUniforms);
1423
1424 if (success)
1425 {
1426 gAvatarWaterProgram.mName = "Avatar Water Shader";
1427 gAvatarWaterProgram.mFeatures.hasSkinning = true;
1428 gAvatarWaterProgram.mFeatures.calculatesAtmospherics = true;
1429 gAvatarWaterProgram.mFeatures.calculatesLighting = true;
1430 gAvatarWaterProgram.mFeatures.hasWaterFog = true;
1431 gAvatarWaterProgram.mFeatures.hasAtmospherics = true;
1432 gAvatarWaterProgram.mFeatures.hasLighting = true;
1433 gAvatarWaterProgram.mShaderFiles.clear();
1434 gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
1435 gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
1436 // Note: no cloth under water:
1437 gAvatarWaterProgram.mShaderLevel = llmin(sVertexShaderLevel[SHADER_AVATAR], 1);
1438 gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
1439 success = gAvatarWaterProgram.createShader(&sAvatarAttribs, &sAvatarUniforms);
1440 }
1441
1442 /// Keep track of avatar levels
1443 if (gAvatarProgram.mShaderLevel != sVertexShaderLevel[SHADER_AVATAR])
1444 {
1445 sMaxAvatarShaderLevel = sVertexShaderLevel[SHADER_AVATAR] = gAvatarProgram.mShaderLevel;
1446 }
1447 }
1448
1449 if (success)
1450 {
1451 gAvatarPickProgram.mName = "Avatar Pick Shader";
1452 gAvatarPickProgram.mFeatures.hasSkinning = true;
1453 gAvatarPickProgram.mShaderFiles.clear();
1454 gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB));
1455 gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB));
1456 gAvatarPickProgram.mShaderLevel = sVertexShaderLevel[SHADER_AVATAR];
1457 success = gAvatarPickProgram.createShader(&sAvatarAttribs, &sAvatarUniforms);
1458 }
1459
1460 if (success)
1461 {
1462 gAvatarEyeballProgram.mName = "Avatar Eyeball Program";
1463 gAvatarEyeballProgram.mFeatures.calculatesLighting = true;
1464 gAvatarEyeballProgram.mFeatures.isSpecular = true;
1465 gAvatarEyeballProgram.mFeatures.calculatesAtmospherics = true;
1466 gAvatarEyeballProgram.mFeatures.hasGamma = true;
1467 gAvatarEyeballProgram.mFeatures.hasAtmospherics = true;
1468 gAvatarEyeballProgram.mFeatures.hasLighting = true;
1469 gAvatarEyeballProgram.mShaderFiles.clear();
1470 gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB));
1471 gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB));
1472 gAvatarEyeballProgram.mShaderLevel = sVertexShaderLevel[SHADER_AVATAR];
1473 success = gAvatarEyeballProgram.createShader(NULL, NULL);
1474 }
1475
1476 if( !success )
1477 {
1478 sVertexShaderLevel[SHADER_AVATAR] = 0;
1479 sMaxAvatarShaderLevel = 0;
1480 return FALSE;
1481 }
1482
1483 return TRUE;
1484}
1485
1486BOOL LLShaderMgr::loadShadersInterface()
1487{
1488 BOOL success = TRUE;
1489
1490 if (sVertexShaderLevel[SHADER_INTERFACE] == 0)
1491 {
1492 gHighlightProgram.unload();
1493 return FALSE;
1494 }
1495
1496 if (success)
1497 {
1498 gHighlightProgram.mName = "Highlight Shader";
1499 gHighlightProgram.mShaderFiles.clear();
1500 gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB));
1501 gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
1502 gHighlightProgram.mShaderLevel = sVertexShaderLevel[SHADER_INTERFACE];
1503 success = gHighlightProgram.createShader(NULL, NULL);
1504 }
1505
1506 if( !success )
1507 {
1508 sVertexShaderLevel[SHADER_INTERFACE] = 0;
1509 return FALSE;
1510 }
1511
1512 return TRUE;
1513}
1514
1515BOOL LLShaderMgr::loadShadersWindLight()
1516{
1517 BOOL success = TRUE;
1518
1519 if (sVertexShaderLevel[SHADER_WINDLIGHT] < 2)
1520 {
1521 gWLSkyProgram.unload();
1522 gWLCloudProgram.unload();
1523 return FALSE;
1524 }
1525
1526 if (success)
1527 {
1528 gWLSkyProgram.mName = "Windlight Sky Shader";
1529 //gWLSkyProgram.mFeatures.hasGamma = true;
1530 gWLSkyProgram.mShaderFiles.clear();
1531 gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyV.glsl", GL_VERTEX_SHADER_ARB));
1532 gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER_ARB));
1533 gWLSkyProgram.mShaderLevel = sVertexShaderLevel[SHADER_WINDLIGHT];
1534 gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
1535 success = gWLSkyProgram.createShader(NULL, &sWLUniforms);
1536 }
1537
1538 if (success)
1539 {
1540 gWLCloudProgram.mName = "Windlight Cloud Program";
1541 //gWLCloudProgram.mFeatures.hasGamma = true;
1542 gWLCloudProgram.mShaderFiles.clear();
1543 gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsV.glsl", GL_VERTEX_SHADER_ARB));
1544 gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));
1545 gWLCloudProgram.mShaderLevel = sVertexShaderLevel[SHADER_WINDLIGHT];
1546 gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
1547 success = gWLCloudProgram.createShader(NULL, &sWLUniforms);
1548 }
1549
1550 return success;
1551}
1552
1553
1554//===============================
1555// LLGLSL Shader implementation
1556//===============================
1557LLGLSLShader::LLGLSLShader()
1558: mProgramObject(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT)
1559{
1560}
1561
1562void LLGLSLShader::unload()
1563{
1564 stop_glerror();
1565 mAttribute.clear();
1566 mTexture.clear();
1567 mUniform.clear();
1568 mShaderFiles.clear();
1569
1570 if (mProgramObject)
1571 {
1572 GLhandleARB obj[1024];
1573 GLsizei count;
1574
1575 glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
1576 for (GLsizei i = 0; i < count; i++)
1577 {
1578 glDeleteObjectARB(obj[i]);
1579 }
1580
1581 glDeleteObjectARB(mProgramObject);
1582
1583 mProgramObject = 0;
1584 }
1585
1586 //hack to make apple not complain
1587 glGetError();
1588
1589 stop_glerror();
1590}
1591
1592BOOL LLGLSLShader::createShader(vector<string> * attributes,
1593 vector<string> * uniforms)
1594{
1595 llassert_always(!mShaderFiles.empty());
1596 BOOL success = TRUE;
1597
1598 // Create program
1599 mProgramObject = glCreateProgramObjectARB();
1600
1601 // Attach existing objects
1602 if (!LLShaderMgr::attachShaderFeatures(this))
1603 {
1604 return FALSE;
1605 }
1606
1607 vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
1608 for ( ; fileIter != mShaderFiles.end(); fileIter++ )
1609 {
1610 GLhandleARB shaderhandle = LLShaderMgr::loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second);
1611 LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
1612 if (mShaderLevel > 0)
1613 {
1614 attachObject(shaderhandle);
1615 }
1616 else
1617 {
1618 success = FALSE;
1619 }
1620 }
1621
1622 // Map attributes and uniforms
1623 if (success)
1624 {
1625 success = mapAttributes(attributes);
1626 }
1627 if (success)
1628 {
1629 success = mapUniforms(uniforms);
1630 }
1631 if( !success )
1632 {
1633 LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL;
1634
1635 // Try again using a lower shader level;
1636 if (mShaderLevel > 0)
1637 {
1638 LL_WARNS("ShaderLoading") << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
1639 mShaderLevel--;
1640 return createShader(attributes,uniforms);
1641 }
1642 }
1643 return success;
1644}
1645
1646BOOL LLGLSLShader::attachObject(std::string object)
1647{
1648 if (LLShaderMgr::sShaderObjects.count(object) > 0)
1649 {
1650 stop_glerror();
1651 glAttachObjectARB(mProgramObject, LLShaderMgr::sShaderObjects[object]);
1652 stop_glerror();
1653 return TRUE;
1654 }
1655 else
1656 {
1657 LL_WARNS("ShaderLoading") << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL;
1658 return FALSE;
1659 }
1660}
1661
1662void LLGLSLShader::attachObject(GLhandleARB object)
1663{
1664 if (object != 0)
1665 {
1666 stop_glerror();
1667 glAttachObjectARB(mProgramObject, object);
1668 stop_glerror();
1669 }
1670 else
1671 {
1672 LL_WARNS("ShaderLoading") << "Attempting to attach non existing shader object. " << LL_ENDL;
1673 }
1674}
1675
1676void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
1677{
1678 for (S32 i = 0; i < count; i++)
1679 {
1680 attachObject(objects[i]);
1681 }
1682}
1683
1684BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
1685{
1686 //link the program
1687 BOOL res = link();
1688
1689 mAttribute.clear();
1690 U32 numAttributes = (attributes == NULL) ? 0 : attributes->size();
1691 mAttribute.resize(LLShaderMgr::sReservedAttribs.size() + numAttributes, -1);
1692
1693 if (res)
1694 { //read back channel locations
1695
1696 //read back reserved channels first
1697 for (U32 i = 0; i < (S32) LLShaderMgr::sReservedAttribs.size(); i++)
1698 {
1699 const char* name = LLShaderMgr::sReservedAttribs[i].c_str();
1700 S32 index = glGetAttribLocationARB(mProgramObject, (GLcharARB *)name);
1701 if (index != -1)
1702 {
1703 mAttribute[i] = index;
1704 LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
1705 }
1706 }
1707 if (attributes != NULL)
1708 {
1709 for (U32 i = 0; i < numAttributes; i++)
1710 {
1711 const char* name = (*attributes)[i].c_str();
1712 S32 index = glGetAttribLocationARB(mProgramObject, name);
1713 if (index != -1)
1714 {
1715 mAttribute[LLShaderMgr::sReservedAttribs.size() + i] = index;
1716 LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
1717 }
1718 }
1719 }
1720
1721 return TRUE;
1722 }
1723
1724 return FALSE;
1725}
1726
1727void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
1728{
1729 if (index == -1)
1730 {
1731 return;
1732 }
1733
1734 GLenum type;
1735 GLsizei length;
1736 GLint size;
1737 char name[1024]; /* Flawfinder: ignore */
1738 name[0] = 0;
1739
1740 glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
1741 S32 location = glGetUniformLocationARB(mProgramObject, name);
1742 if (location != -1)
1743 {
1744 mUniformMap[name] = location;
1745 LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
1746
1747 //find the index of this uniform
1748 for (S32 i = 0; i < (S32) LLShaderMgr::sReservedUniforms.size(); i++)
1749 {
1750 if ( (mUniform[i] == -1)
1751 && (LLShaderMgr::sReservedUniforms[i].compare(0, length, name, LLShaderMgr::sReservedUniforms[i].length()) == 0))
1752 {
1753 //found it
1754 mUniform[i] = location;
1755 mTexture[i] = mapUniformTextureChannel(location, type);
1756 return;
1757 }
1758 }
1759
1760 if (uniforms != NULL)
1761 {
1762 for (U32 i = 0; i < uniforms->size(); i++)
1763 {
1764 if ( (mUniform[i+LLShaderMgr::sReservedUniforms.size()] == -1)
1765 && ((*uniforms)[i].compare(0, length, name, (*uniforms)[i].length()) == 0))
1766 {
1767 //found it
1768 mUniform[i+LLShaderMgr::sReservedUniforms.size()] = location;
1769 mTexture[i+LLShaderMgr::sReservedUniforms.size()] = mapUniformTextureChannel(location, type);
1770 return;
1771 }
1772 }
1773 }
1774 }
1775 }
1776
1777GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
1778{
1779 if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB)
1780 { //this here is a texture
1781 glUniform1iARB(location, mActiveTextureChannels);
1782 LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
1783 return mActiveTextureChannels++;
1784 }
1785 return -1;
1786}
1787
1788BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
1789{
1790 BOOL res = TRUE;
1791
1792 mActiveTextureChannels = 0;
1793 mUniform.clear();
1794 mUniformMap.clear();
1795 mTexture.clear();
1796 mValue.clear();
1797 //initialize arrays
1798 U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size();
1799 mUniform.resize(numUniforms + LLShaderMgr::sReservedUniforms.size(), -1);
1800 mTexture.resize(numUniforms + LLShaderMgr::sReservedUniforms.size(), -1);
1801
1802 bind();
1803
1804 //get the number of active uniforms
1805 GLint activeCount;
1806 glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
1807
1808 for (S32 i = 0; i < activeCount; i++)
1809 {
1810 mapUniform(i, uniforms);
1811 }
1812
1813 unbind();
1814
1815 return res;
1816}
1817
1818BOOL LLGLSLShader::link(BOOL suppress_errors)
1819{
1820 return LLShaderMgr::linkProgramObject(mProgramObject, suppress_errors);
1821}
1822
1823void LLGLSLShader::bind()
1824{
1825 if (gGLManager.mHasShaderObjects)
1826 {
1827 glUseProgramObjectARB(mProgramObject);
1828
1829 if (mUniformsDirty)
1830 {
1831 LLWLParamManager::instance()->updateShaderUniforms(this);
1832 LLWaterParamManager::instance()->updateShaderUniforms(this);
1833 mUniformsDirty = FALSE;
1834 }
1835 }
1836}
1837
1838void LLGLSLShader::unbind()
1839{
1840 if (gGLManager.mHasShaderObjects)
1841 {
1842 for (U32 i = 0; i < mAttribute.size(); ++i)
1843 {
1844 vertexAttrib4f(i, 0,0,0,1);
1845 }
1846 glUseProgramObjectARB(0);
1847 }
1848}
1849
1850void LLGLSLShader::bindNoShader(void)
1851{
1852 glUseProgramObjectARB(0);
1853}
1854
1855S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode)
1856{
1857 if (uniform < 0 || uniform >= (S32)mTexture.size())
1858 {
1859 UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
1860 return -1;
1861 }
1862 S32 index = mTexture[uniform];
1863 if (index != -1)
1864 {
1865 gGL.getTexUnit(index)->activate();
1866 glEnable(mode);
1867 }
1868 return index;
1869}
1870
1871S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode)
1872{
1873 if (uniform < 0 || uniform >= (S32)mTexture.size())
1874 {
1875 UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
1876 return -1;
1877 }
1878 S32 index = mTexture[uniform];
1879 if (index != -1)
1880 {
1881 gGL.getTexUnit(index)->activate();
1882 glDisable(mode);
1883 }
1884 return index;
1885}
1886
1887void LLGLSLShader::uniform1f(U32 index, GLfloat x)
1888{
1889 if (mProgramObject > 0)
1890 {
1891 if (mUniform.size() <= index)
1892 {
1893 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
1894 return;
1895 }
1896
1897 if (mUniform[index] >= 0)
1898 {
1899 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
1900 if (iter == mValue.end() || iter->second.mV[0] != x)
1901 {
1902 glUniform1fARB(mUniform[index], x);
1903 mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
1904 }
1905 }
1906 }
1907}
1908
1909void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
1910{
1911 if (mProgramObject > 0)
1912 {
1913 if (mUniform.size() <= index)
1914 {
1915 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
1916 return;
1917 }
1918
1919 if (mUniform[index] >= 0)
1920 {
1921 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
1922 LLVector4 vec(x,y,0.f,0.f);
1923 if (iter == mValue.end() || shouldChange(iter->second,vec))
1924 {
1925 glUniform2fARB(mUniform[index], x, y);
1926 mValue[mUniform[index]] = vec;
1927 }
1928 }
1929 }
1930}
1931
1932void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
1933{
1934 if (mProgramObject > 0)
1935 {
1936 if (mUniform.size() <= index)
1937 {
1938 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
1939 return;
1940 }
1941
1942 if (mUniform[index] >= 0)
1943 {
1944 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
1945 LLVector4 vec(x,y,z,0.f);
1946 if (iter == mValue.end() || shouldChange(iter->second,vec))
1947 {
1948 glUniform3fARB(mUniform[index], x, y, z);
1949 mValue[mUniform[index]] = vec;
1950 }
1951 }
1952 }
1953}
1954
1955void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1956{
1957 if (mProgramObject > 0)
1958 {
1959 if (mUniform.size() <= index)
1960 {
1961 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
1962 return;
1963 }
1964
1965 if (mUniform[index] >= 0)
1966 {
1967 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
1968 LLVector4 vec(x,y,z,w);
1969 if (iter == mValue.end() || shouldChange(iter->second,vec))
1970 {
1971 glUniform4fARB(mUniform[index], x, y, z, w);
1972 mValue[mUniform[index]] = vec;
1973 }
1974 }
1975 }
1976}
1977
1978void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
1979{
1980 if (mProgramObject > 0)
1981 {
1982 if (mUniform.size() <= index)
1983 {
1984 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
1985 return;
1986 }
1987
1988 if (mUniform[index] >= 0)
1989 {
1990 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
1991 LLVector4 vec(v[0],0.f,0.f,0.f);
1992 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
1993 {
1994 glUniform1fvARB(mUniform[index], count, v);
1995 mValue[mUniform[index]] = vec;
1996 }
1997 }
1998 }
1999}
2000
2001void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
2002{
2003 if (mProgramObject > 0)
2004 {
2005 if (mUniform.size() <= index)
2006 {
2007 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
2008 return;
2009 }
2010
2011 if (mUniform[index] >= 0)
2012 {
2013 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
2014 LLVector4 vec(v[0],v[1],0.f,0.f);
2015 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
2016 {
2017 glUniform2fvARB(mUniform[index], count, v);
2018 mValue[mUniform[index]] = vec;
2019 }
2020 }
2021 }
2022}
2023
2024void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
2025{
2026 if (mProgramObject > 0)
2027 {
2028 if (mUniform.size() <= index)
2029 {
2030 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
2031 return;
2032 }
2033
2034 if (mUniform[index] >= 0)
2035 {
2036 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
2037 LLVector4 vec(v[0],v[1],v[2],0.f);
2038 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
2039 {
2040 glUniform3fvARB(mUniform[index], count, v);
2041 mValue[mUniform[index]] = vec;
2042 }
2043 }
2044 }
2045}
2046
2047void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
2048{
2049 if (mProgramObject > 0)
2050 {
2051 if (mUniform.size() <= index)
2052 {
2053 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
2054 return;
2055 }
2056
2057 if (mUniform[index] >= 0)
2058 {
2059 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
2060 LLVector4 vec(v[0],v[1],v[2],v[3]);
2061 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
2062 {
2063 glUniform4fvARB(mUniform[index], count, v);
2064 mValue[mUniform[index]] = vec;
2065 }
2066 }
2067 }
2068}
2069
2070void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
2071{
2072 if (mProgramObject > 0)
2073 {
2074 if (mUniform.size() <= index)
2075 {
2076 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
2077 return;
2078 }
2079
2080 if (mUniform[index] >= 0)
2081 {
2082 glUniformMatrix2fvARB(mUniform[index], count, transpose, v);
2083 }
2084 }
2085}
2086
2087void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
2088{
2089 if (mProgramObject > 0)
2090 {
2091 if (mUniform.size() <= index)
2092 {
2093 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
2094 return;
2095 }
2096
2097 if (mUniform[index] >= 0)
2098 {
2099 glUniformMatrix3fvARB(mUniform[index], count, transpose, v);
2100 }
2101 }
2102}
2103
2104void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
2105{
2106 if (mProgramObject > 0)
2107 {
2108 if (mUniform.size() <= index)
2109 {
2110 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
2111 return;
2112 }
2113
2114 if (mUniform[index] >= 0)
2115 {
2116 glUniformMatrix4fvARB(mUniform[index], count, transpose, v);
2117 }
2118 }
2119}
2120
2121GLint LLGLSLShader::getUniformLocation(const string& uniform)
2122{
2123 if (mProgramObject > 0)
2124 {
2125 std::map<string, GLint>::iterator iter = mUniformMap.find(uniform);
2126 if (iter != mUniformMap.end())
2127 {
2128 llassert(iter->second == glGetUniformLocationARB(mProgramObject, uniform.c_str()));
2129 return iter->second;
2130 }
2131 }
2132
2133 return -1;
2134}
2135
2136void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
2137{
2138 GLint location = getUniformLocation(uniform);
2139
2140 if (location >= 0)
2141 {
2142 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
2143 LLVector4 vec(v,0.f,0.f,0.f);
2144 if (iter == mValue.end() || shouldChange(iter->second,vec))
2145 {
2146 glUniform1fARB(location, v);
2147 mValue[location] = vec;
2148 }
2149 }
2150}
2151
2152void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y)
2153{
2154 GLint location = getUniformLocation(uniform);
2155
2156 if (location >= 0)
2157 {
2158 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
2159 LLVector4 vec(x,y,0.f,0.f);
2160 if (iter == mValue.end() || shouldChange(iter->second,vec))
2161 {
2162 glUniform2fARB(location, x,y);
2163 mValue[location] = vec;
2164 }
2165 }
2166
2167}
2168
2169void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloat z)
2170{
2171 GLint location = getUniformLocation(uniform);
2172
2173 if (location >= 0)
2174 {
2175 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
2176 LLVector4 vec(x,y,z,0.f);
2177 if (iter == mValue.end() || shouldChange(iter->second,vec))
2178 {
2179 glUniform3fARB(location, x,y,z);
2180 mValue[location] = vec;
2181 }
2182 }
2183}
2184
2185void LLGLSLShader::uniform4f(const string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2186{
2187 GLint location = getUniformLocation(uniform);
2188
2189 if (location >= 0)
2190 {
2191 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
2192 LLVector4 vec(x,y,z,w);
2193 if (iter == mValue.end() || shouldChange(iter->second,vec))
2194 {
2195 glUniform4fARB(location, x,y,z,w);
2196 mValue[location] = vec;
2197 }
2198 }
2199}
2200
2201void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v)
2202{
2203 GLint location = getUniformLocation(uniform);
2204
2205 if (location >= 0)
2206 {
2207 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
2208 LLVector4 vec(v[0],0.f,0.f,0.f);
2209 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
2210 {
2211 glUniform1fvARB(location, count, v);
2212 mValue[location] = vec;
2213 }
2214 }
2215}
2216
2217void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v)
2218{
2219 GLint location = getUniformLocation(uniform);
2220
2221 if (location >= 0)
2222 {
2223 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
2224 LLVector4 vec(v[0],v[1],0.f,0.f);
2225 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
2226 {
2227 glUniform2fvARB(location, count, v);
2228 mValue[location] = vec;
2229 }
2230 }
2231}
2232
2233void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v)
2234{
2235 GLint location = getUniformLocation(uniform);
2236
2237 if (location >= 0)
2238 {
2239 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
2240 LLVector4 vec(v[0],v[1],v[2],0.f);
2241 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
2242 {
2243 glUniform3fvARB(location, count, v);
2244 mValue[location] = vec;
2245 }
2246 }
2247}
2248
2249void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v)
2250{
2251 GLint location = getUniformLocation(uniform);
2252
2253 if (location >= 0)
2254 {
2255 LLVector4 vec(v);
2256 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
2257 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
2258 {
2259 glUniform4fvARB(location, count, v);
2260 mValue[location] = vec;
2261 }
2262 }
2263}
2264
2265void LLGLSLShader::uniformMatrix2fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
2266{
2267 GLint location = getUniformLocation(uniform);
2268
2269 if (location >= 0)
2270 {
2271 glUniformMatrix2fvARB(location, count, transpose, v);
2272 }
2273}
2274
2275void LLGLSLShader::uniformMatrix3fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
2276{
2277 GLint location = getUniformLocation(uniform);
2278
2279 if (location >= 0)
2280 {
2281 glUniformMatrix3fvARB(location, count, transpose, v);
2282 }
2283}
2284
2285void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
2286{
2287 GLint location = getUniformLocation(uniform);
2288
2289 if (location >= 0)
2290 {
2291 glUniformMatrix4fvARB(location, count, transpose, v);
2292 }
2293}
2294
2295
2296void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2297{
2298 if (mAttribute[index] > 0)
2299 {
2300 glVertexAttrib4fARB(mAttribute[index], x, y, z, w);
2301 }
2302}
2303
2304void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
2305{
2306 if (mAttribute[index] > 0)
2307 {
2308 glVertexAttrib4fvARB(mAttribute[index], v);
2309 }
2310}