aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llglslshader.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:54 -0500
committerJacek Antonelli2008-08-15 23:44:54 -0500
commitb2afb8800bb033a04bb3ecdf0363068d56648ef1 (patch)
tree3568129b5bbddb47cd39d622b4137a8fbff4abaf /linden/indra/newview/llglslshader.cpp
parentSecond Life viewer sources 1.14.0.1 (diff)
downloadmeta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.zip
meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.gz
meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.bz2
meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.xz
Second Life viewer sources 1.15.0.2
Diffstat (limited to 'linden/indra/newview/llglslshader.cpp')
-rw-r--r--linden/indra/newview/llglslshader.cpp1221
1 files changed, 1221 insertions, 0 deletions
diff --git a/linden/indra/newview/llglslshader.cpp b/linden/indra/newview/llglslshader.cpp
new file mode 100644
index 0000000..3f23a66
--- /dev/null
+++ b/linden/indra/newview/llglslshader.cpp
@@ -0,0 +1,1221 @@
1/**
2 * @file llglslshader.cpp
3 * @brief GLSL helper functions and state.
4 *
5 * Copyright (c) 2005-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include "llviewerprecompiledheaders.h"
30
31#include "llviewerwindow.h"
32#include "llglslshader.h"
33#include "llviewercontrol.h"
34#include "pipeline.h"
35#include "llworld.h"
36
37//utility shader objects (not shader programs)
38GLhandleARB gLightVertex;
39GLhandleARB gLightFragment;
40GLhandleARB gScatterVertex;
41GLhandleARB gScatterFragment;
42
43LLVector4 gShinyOrigin;
44
45//object shaders
46LLGLSLShader gObjectSimpleProgram;
47LLGLSLShader gObjectAlphaProgram;
48LLGLSLShader gObjectBumpProgram;
49LLGLSLShader gObjectShinyProgram;
50
51//environment shaders
52LLGLSLShader gTerrainProgram;
53LLGLSLShader gGlowProgram;
54LLGLSLShader gGroundProgram;
55LLGLSLShader gWaterProgram;
56
57//interface shaders
58LLGLSLShader gHighlightProgram;
59
60//avatar skinning utility shader object
61GLhandleARB gAvatarSkinVertex;
62
63//avatar shader handles
64LLGLSLShader gAvatarProgram;
65LLGLSLShader gAvatarEyeballProgram;
66LLGLSLShader gAvatarPickProgram;
67
68//current avatar shader parameter pointer
69GLint gAvatarMatrixParam;
70GLint gMaterialIndex;
71GLint gSpecularIndex;
72
73S32 LLShaderMgr::sVertexShaderLevel[SHADER_COUNT] = { 0 };
74S32 LLShaderMgr::sMaxVertexShaderLevel[SHADER_COUNT] = { 0 };
75
76//glsl parameter tables
77const char* LLShaderMgr::sReservedAttribs[] =
78{
79 "materialColor",
80 "specularColor",
81 "binormal"
82};
83
84U32 LLShaderMgr::sReservedAttribCount = LLShaderMgr::END_RESERVED_ATTRIBS;
85
86const char* LLShaderMgr::sAvatarAttribs[] =
87{
88 "weight",
89 "clothing",
90 "gWindDir",
91 "gSinWaveParams",
92 "gGravity"
93};
94
95U32 LLShaderMgr::sAvatarAttribCount = sizeof(LLShaderMgr::sAvatarAttribs)/sizeof(char*);
96
97const char* LLShaderMgr::sAvatarUniforms[] =
98{
99 "matrixPalette"
100};
101
102U32 LLShaderMgr::sAvatarUniformCount = 1;
103
104const char* LLShaderMgr::sReservedUniforms[] =
105{
106 "diffuseMap",
107 "specularMap",
108 "bumpMap",
109 "environmentMap",
110 "scatterMap"
111};
112
113U32 LLShaderMgr::sReservedUniformCount = LLShaderMgr::END_RESERVED_UNIFORMS;
114
115const char* LLShaderMgr::sTerrainUniforms[] =
116{
117 "detail0",
118 "detail1",
119 "alphaRamp"
120};
121
122U32 LLShaderMgr::sTerrainUniformCount = sizeof(LLShaderMgr::sTerrainUniforms)/sizeof(char*);
123
124const char* LLShaderMgr::sGlowUniforms[] =
125{
126 "delta"
127};
128
129U32 LLShaderMgr::sGlowUniformCount = sizeof(LLShaderMgr::sGlowUniforms)/sizeof(char*);
130
131const char* LLShaderMgr::sShinyUniforms[] =
132{
133 "origin"
134};
135
136U32 LLShaderMgr::sShinyUniformCount = sizeof(LLShaderMgr::sShinyUniforms)/sizeof(char*);
137
138const char* LLShaderMgr::sWaterUniforms[] =
139{
140 "screenTex",
141 "eyeVec",
142 "time",
143 "d1",
144 "d2",
145 "lightDir",
146 "specular",
147 "lightExp",
148 "fbScale",
149 "refScale"
150};
151
152U32 LLShaderMgr::sWaterUniformCount = sizeof(LLShaderMgr::sWaterUniforms)/sizeof(char*);
153
154
155//============================================================================
156// Set Levels
157
158S32 LLShaderMgr::getVertexShaderLevel(S32 type)
159{
160 return sVertexShaderLevel[type];
161}
162
163S32 LLShaderMgr::getMaxVertexShaderLevel(S32 type)
164{
165 return sMaxVertexShaderLevel[type];
166}
167
168//============================================================================
169// Load Shader
170
171static LLString get_object_log(GLhandleARB ret)
172{
173 LLString res;
174
175 //get log length
176 GLint length;
177 glGetObjectParameterivARB(ret, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
178 if (length > 0)
179 {
180 //the log could be any size, so allocate appropriately
181 GLcharARB* log = new GLcharARB[length];
182 glGetInfoLogARB(ret, length, &length, log);
183 res = LLString(log);
184 delete[] log;
185 }
186 return res;
187}
188
189void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
190{
191 LLString log = get_object_log(ret);
192 if (warns)
193 {
194 llwarns << log << llendl;
195 }
196 else
197 {
198 llinfos << log << llendl;
199 }
200}
201
202GLhandleARB LLShaderMgr::loadShader(const LLString& filename, S32 cls, GLenum type)
203{
204 GLenum error;
205 error = glGetError();
206 if (error != GL_NO_ERROR)
207 {
208 llwarns << "GL ERROR entering loadShader(): " << error << llendl;
209 }
210
211 llinfos << "Loading shader file: " << filename << llendl;
212
213 if (filename.empty())
214 {
215 return 0;
216 }
217
218
219 //read in from file
220 FILE* file = NULL;
221
222 S32 try_gpu_class = sVertexShaderLevel[cls];
223 S32 gpu_class;
224
225 //find the most relevant file
226 for (gpu_class = try_gpu_class; gpu_class > 0; gpu_class--)
227 { //search from the current gpu class down to class 1 to find the most relevant shader
228 std::stringstream fname;
229 fname << gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
230 fname << gpu_class << "/" << filename;
231
232// llinfos << "Looking in " << fname.str().c_str() << llendl;
233 file = fopen(fname.str().c_str(), "r"); /* Flawfinder: ignore */
234 if (file)
235 {
236 break; // done
237 }
238 }
239
240 if (file == NULL)
241 {
242 llinfos << "GLSL Shader file not found: " << filename << llendl;
243 return 0;
244 }
245
246 //we can't have any lines longer than 1024 characters
247 //or any shaders longer than 1024 lines... deal - DaveP
248 GLcharARB buff[1024];
249 GLcharARB* text[1024];
250 GLuint count = 0;
251
252 //copy file into memory
253 while(fgets(buff, 1024, file) != NULL)
254 {
255 text[count++] = strdup(buff);
256 }
257 fclose(file);
258
259 //create shader object
260 GLhandleARB ret = glCreateShaderObjectARB(type);
261 error = glGetError();
262 if (error != GL_NO_ERROR)
263 {
264 llwarns << "GL ERROR in glCreateShaderObjectARB: " << error << llendl;
265 }
266 else
267 {
268 //load source
269 glShaderSourceARB(ret, count, (const GLcharARB**) text, NULL);
270 error = glGetError();
271 if (error != GL_NO_ERROR)
272 {
273 llwarns << "GL ERROR in glShaderSourceARB: " << error << llendl;
274 }
275 else
276 {
277 //compile source
278 glCompileShaderARB(ret);
279 error = glGetError();
280 if (error != GL_NO_ERROR)
281 {
282 llwarns << "GL ERROR in glCompileShaderARB: " << error << llendl;
283 }
284 }
285 }
286 //free memory
287 for (GLuint i = 0; i < count; i++)
288 {
289 free(text[i]);
290 }
291 if (error == GL_NO_ERROR)
292 {
293 //check for errors
294 GLint success = GL_TRUE;
295 glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success);
296 error = glGetError();
297 if (error != GL_NO_ERROR || success == GL_FALSE)
298 {
299 //an error occured, print log
300 llwarns << "GLSL Compilation Error: (" << error << ") in " << filename << llendl;
301 dumpObjectLog(ret);
302 ret = 0;
303 }
304 }
305 else
306 {
307 ret = 0;
308 }
309 stop_glerror();
310
311 //successfully loaded, save results
312#if 1 // 1.9.1
313 if (ret)
314 {
315 sVertexShaderLevel[cls] = try_gpu_class;
316 }
317 else
318 {
319 if (sVertexShaderLevel[cls] > 1)
320 {
321 sVertexShaderLevel[cls] = sVertexShaderLevel[cls] - 1;
322 ret = loadShader(filename,cls,type);
323 if (ret && sMaxVertexShaderLevel[cls] > sVertexShaderLevel[cls])
324 {
325 sMaxVertexShaderLevel[cls] = sVertexShaderLevel[cls];
326 }
327 }
328 }
329#else
330 if (ret)
331 {
332 S32 max = -1;
333 /*if (try_gpu_class == sMaxVertexShaderLevel[cls])
334 {
335 max = gpu_class;
336 }*/
337 saveVertexShaderLevel(cls,try_gpu_class,max);
338 }
339 else
340 {
341 if (sVertexShaderLevel[cls] > 1)
342 {
343 sVertexShaderLevel[cls] = sVertexShaderLevel[cls] - 1;
344 ret = loadShader(f,cls,type);
345 if (ret && sMaxVertexShaderLevel[cls] > sVertexShaderLevel[cls])
346 {
347 saveVertexShaderLevel(cls, sVertexShaderLevel[cls], sVertexShaderLevel[cls]);
348 }
349 }
350 }
351#endif
352 return ret;
353}
354
355BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
356{
357 //check for errors
358 glLinkProgramARB(obj);
359 GLint success = GL_TRUE;
360 glGetObjectParameterivARB(obj, GL_OBJECT_LINK_STATUS_ARB, &success);
361 if (!suppress_errors && success == GL_FALSE)
362 {
363 //an error occured, print log
364 llwarns << "GLSL Linker Error:" << llendl;
365 }
366
367 LLString log = get_object_log(obj);
368 LLString::toLower(log);
369 if (log.find("software") != LLString::npos)
370 {
371 llwarns << "GLSL Linker: Running in Software:" << llendl;
372 success = GL_FALSE;
373 suppress_errors = FALSE;
374 }
375 if (!suppress_errors)
376 {
377 dumpObjectLog(obj, !success);
378 }
379
380 return success;
381}
382
383BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj)
384{
385 //check program validity against current GL
386 glValidateProgramARB(obj);
387 GLint success = GL_TRUE;
388 glGetObjectParameterivARB(obj, GL_OBJECT_VALIDATE_STATUS_ARB, &success);
389 if (success == GL_FALSE)
390 {
391 llwarns << "GLSL program not valid: " << llendl;
392 dumpObjectLog(obj);
393 }
394 else
395 {
396 dumpObjectLog(obj, FALSE);
397 }
398
399 return success;
400}
401
402//============================================================================
403// Shader Management
404
405void LLShaderMgr::setShaders()
406{
407 if (!gPipeline.mInitialized)
408 {
409 return;
410 }
411
412 if (gGLManager.mHasFramebufferObject)
413 {
414 LLPipeline::sDynamicReflections = gSavedSettings.getBOOL("RenderDynamicReflections");
415 LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
416 }
417 else
418 {
419 LLPipeline::sDynamicReflections = LLPipeline::sRenderGlow = FALSE;
420 }
421
422 //hack to reset buffers that change behavior with shaders
423 gPipeline.resetVertexBuffers();
424
425 if (gViewerWindow)
426 {
427 gViewerWindow->setCursor(UI_CURSOR_WAIT);
428 }
429
430 // Lighting
431 gPipeline.setLightingDetail(-1);
432
433 // Shaders
434 for (S32 i=0; i<SHADER_COUNT; i++)
435 {
436 sVertexShaderLevel[i] = 0;
437 sMaxVertexShaderLevel[i] = 0;
438 }
439 if (gPipeline.canUseVertexShaders() && gSavedSettings.getBOOL("VertexShaderEnable"))
440 {
441 S32 light_class = 2;
442 S32 env_class = 2;
443 S32 obj_class = 0;
444
445 if (gPipeline.getLightingDetail() == 0)
446 {
447 light_class = 1;
448 }
449 // Load lighting shaders
450 sVertexShaderLevel[SHADER_LIGHTING] = light_class;
451 sMaxVertexShaderLevel[SHADER_LIGHTING] = light_class;
452 sVertexShaderLevel[SHADER_ENVIRONMENT] = env_class;
453 sMaxVertexShaderLevel[SHADER_ENVIRONMENT] = env_class;
454 sVertexShaderLevel[SHADER_OBJECT] = obj_class;
455 sMaxVertexShaderLevel[SHADER_OBJECT] = obj_class;
456
457 BOOL loaded = loadShadersLighting();
458
459 if (loaded)
460 {
461 gPipeline.mVertexShadersEnabled = TRUE;
462 gPipeline.mVertexShadersLoaded = 1;
463
464 // Load all shaders to set max levels
465 loadShadersEnvironment();
466 loadShadersObject();
467 // Load max avatar shaders to set the max level
468 sVertexShaderLevel[SHADER_AVATAR] = 3;
469 sMaxVertexShaderLevel[SHADER_AVATAR] = 3;
470 loadShadersAvatar();
471
472 // Load shaders to correct levels
473 if (!gSavedSettings.getBOOL("RenderRippleWater"))
474 {
475 if (gSavedSettings.getBOOL("RenderGlow"))
476 {
477 sVertexShaderLevel[SHADER_ENVIRONMENT] = 1;
478 }
479 else
480 {
481 sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
482 loadShadersEnvironment(); // unloads
483 }
484 }
485
486#if LL_DARWIN // force avatar shaders off for mac
487 sVertexShaderLevel[SHADER_AVATAR] = 0;
488 sMaxVertexShaderLevel[SHADER_AVATAR] = 0;
489#else
490 if (gSavedSettings.getBOOL("RenderAvatarVP"))
491 {
492 S32 avatar = gSavedSettings.getS32("RenderAvatarMode");
493 S32 avatar_class = 1 + avatar;
494 // Set the actual level
495 sVertexShaderLevel[SHADER_AVATAR] = avatar_class;
496 loadShadersAvatar();
497 if (sVertexShaderLevel[SHADER_AVATAR] != avatar_class)
498 {
499 if (sVertexShaderLevel[SHADER_AVATAR] == 0)
500 {
501 gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
502 }
503 avatar = llmax(sVertexShaderLevel[SHADER_AVATAR]-1,0);
504 gSavedSettings.setS32("RenderAvatarMode", avatar);
505 }
506 }
507 else
508 {
509 sVertexShaderLevel[SHADER_AVATAR] = 0;
510 gSavedSettings.setS32("RenderAvatarMode", 0);
511 loadShadersAvatar(); // unloads
512 }
513#endif
514 }
515 else
516 {
517 gPipeline.mVertexShadersEnabled = FALSE;
518 gPipeline.mVertexShadersLoaded = 0;
519 }
520 }
521 if (gViewerWindow)
522 {
523 gViewerWindow->setCursor(UI_CURSOR_ARROW);
524 }
525}
526
527void LLShaderMgr::unloadShaders()
528{
529 gObjectSimpleProgram.unload();
530 gObjectShinyProgram.unload();
531 gObjectBumpProgram.unload();
532 gObjectAlphaProgram.unload();
533 gWaterProgram.unload();
534 gTerrainProgram.unload();
535 gGlowProgram.unload();
536 gGroundProgram.unload();
537 gAvatarProgram.unload();
538 gAvatarEyeballProgram.unload();
539 gAvatarPickProgram.unload();
540 gHighlightProgram.unload();
541
542 sVertexShaderLevel[SHADER_LIGHTING] = 0;
543 sVertexShaderLevel[SHADER_OBJECT] = 0;
544 sVertexShaderLevel[SHADER_AVATAR] = 0;
545 sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
546 sVertexShaderLevel[SHADER_INTERFACE] = 0;
547
548 gLightVertex = gLightFragment = gScatterVertex = gScatterFragment = 0;
549 gPipeline.mVertexShadersLoaded = 0;
550}
551
552BOOL LLShaderMgr::loadShadersLighting()
553{
554 // Load light dependency shaders first
555 // All of these have to load for any shaders to function
556
557 std::string lightvertex = "lighting/lightV.glsl";
558 //get default light function implementation
559 gLightVertex = loadShader(lightvertex, SHADER_LIGHTING, GL_VERTEX_SHADER_ARB);
560 if( !gLightVertex )
561 {
562 llwarns << "Failed to load " << lightvertex << llendl;
563 return FALSE;
564 }
565
566 std::string lightfragment = "lighting/lightF.glsl";
567 gLightFragment = loadShader(lightfragment, SHADER_LIGHTING, GL_FRAGMENT_SHADER_ARB);
568 if ( !gLightFragment )
569 {
570 llwarns << "Failed to load " << lightfragment << llendl;
571 return FALSE;
572 }
573
574 // NOTE: Scatter shaders use the ENVIRONMENT detail level
575
576 std::string scattervertex = "environment/scatterV.glsl";
577 gScatterVertex = loadShader(scattervertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB);
578 if ( !gScatterVertex )
579 {
580 llwarns << "Failed to load " << scattervertex << llendl;
581 return FALSE;
582 }
583
584 std::string scatterfragment = "environment/scatterF.glsl";
585 gScatterFragment = loadShader(scatterfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB);
586 if ( !gScatterFragment )
587 {
588 llwarns << "Failed to load " << scatterfragment << llendl;
589 return FALSE;
590 }
591
592 return TRUE;
593}
594
595BOOL LLShaderMgr::loadShadersEnvironment()
596{
597 GLhandleARB baseObjects[] =
598 {
599 gLightFragment,
600 gLightVertex,
601 gScatterFragment,
602 gScatterVertex
603 };
604 S32 baseCount = 4;
605
606 BOOL success = TRUE;
607
608 if (sVertexShaderLevel[SHADER_ENVIRONMENT] == 0)
609 {
610 gWaterProgram.unload();
611 gGroundProgram.unload();
612 gTerrainProgram.unload();
613 gGlowProgram.unload();
614 return FALSE;
615 }
616
617 if (success)
618 {
619 //load water vertex shader
620 std::string waterfragment = "environment/waterF.glsl";
621 std::string watervertex = "environment/waterV.glsl";
622 gWaterProgram.mProgramObject = glCreateProgramObjectARB();
623 gWaterProgram.attachObjects(baseObjects, baseCount);
624 gWaterProgram.attachObject(loadShader(watervertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB));
625 gWaterProgram.attachObject(loadShader(waterfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB));
626
627 success = gWaterProgram.mapAttributes();
628 if (success)
629 {
630 success = gWaterProgram.mapUniforms(sWaterUniforms, sWaterUniformCount);
631 }
632 if (!success)
633 {
634 llwarns << "Failed to load " << watervertex << llendl;
635 }
636 }
637 if (success)
638 {
639 //load ground vertex shader
640 std::string groundvertex = "environment/groundV.glsl";
641 std::string groundfragment = "environment/groundF.glsl";
642 gGroundProgram.mProgramObject = glCreateProgramObjectARB();
643 gGroundProgram.attachObjects(baseObjects, baseCount);
644 gGroundProgram.attachObject(loadShader(groundvertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB));
645 gGroundProgram.attachObject(loadShader(groundfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB));
646
647 success = gGroundProgram.mapAttributes();
648 if (success)
649 {
650 success = gGroundProgram.mapUniforms();
651 }
652 if (!success)
653 {
654 llwarns << "Failed to load " << groundvertex << llendl;
655 }
656 }
657
658 if (success)
659 {
660 //load terrain vertex shader
661 std::string terrainvertex = "environment/terrainV.glsl";
662 std::string terrainfragment = "environment/terrainF.glsl";
663 gTerrainProgram.mProgramObject = glCreateProgramObjectARB();
664 gTerrainProgram.attachObjects(baseObjects, baseCount);
665 gTerrainProgram.attachObject(loadShader(terrainvertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB));
666 gTerrainProgram.attachObject(loadShader(terrainfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB));
667 success = gTerrainProgram.mapAttributes();
668 if (success)
669 {
670 success = gTerrainProgram.mapUniforms(sTerrainUniforms, sTerrainUniformCount);
671 }
672 if (!success)
673 {
674 llwarns << "Failed to load " << terrainvertex << llendl;
675 }
676 }
677
678 if (success)
679 {
680 //load glow shader
681 std::string glowvertex = "environment/glowV.glsl";
682 std::string glowfragment = "environment/glowF.glsl";
683 gGlowProgram.mProgramObject = glCreateProgramObjectARB();
684 gGlowProgram.attachObjects(baseObjects, baseCount);
685 gGlowProgram.attachObject(loadShader(glowvertex, SHADER_ENVIRONMENT, GL_VERTEX_SHADER_ARB));
686 gGlowProgram.attachObject(loadShader(glowfragment, SHADER_ENVIRONMENT, GL_FRAGMENT_SHADER_ARB));
687 success = gGlowProgram.mapAttributes();
688 if (success)
689 {
690 success = gGlowProgram.mapUniforms(sGlowUniforms, sGlowUniformCount);
691 }
692 if (!success)
693 {
694 llwarns << "Failed to load " << glowvertex << llendl;
695 }
696 }
697
698 if( !success )
699 {
700 sVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
701 sMaxVertexShaderLevel[SHADER_ENVIRONMENT] = 0;
702 return FALSE;
703 }
704
705 if (gWorldPointer)
706 {
707 gWorldPointer->updateWaterObjects();
708 }
709
710 return TRUE;
711}
712
713BOOL LLShaderMgr::loadShadersObject()
714{
715 GLhandleARB baseObjects[] =
716 {
717 gLightFragment,
718 gLightVertex,
719 gScatterFragment,
720 gScatterVertex
721 };
722 S32 baseCount = 4;
723
724 BOOL success = TRUE;
725
726 if (sVertexShaderLevel[SHADER_OBJECT] == 0)
727 {
728 gObjectShinyProgram.unload();
729 gObjectSimpleProgram.unload();
730 gObjectBumpProgram.unload();
731 gObjectAlphaProgram.unload();
732 return FALSE;
733 }
734
735#if 0
736 if (success)
737 {
738 //load object (volume/tree) vertex shader
739 std::string simplevertex = "objects/simpleV.glsl";
740 std::string simplefragment = "objects/simpleF.glsl";
741 gObjectSimpleProgram.mProgramObject = glCreateProgramObjectARB();
742 gObjectSimpleProgram.attachObjects(baseObjects, baseCount);
743 gObjectSimpleProgram.attachObject(loadShader(simplevertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB));
744 gObjectSimpleProgram.attachObject(loadShader(simplefragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB));
745 success = gObjectSimpleProgram.mapAttributes();
746 if (success)
747 {
748 success = gObjectSimpleProgram.mapUniforms();
749 }
750 if( !success )
751 {
752 llwarns << "Failed to load " << simplevertex << llendl;
753 }
754 }
755
756 if (success)
757 {
758 //load object bumpy vertex shader
759 std::string bumpshinyvertex = "objects/bumpshinyV.glsl";
760 std::string bumpshinyfragment = "objects/bumpshinyF.glsl";
761 gObjectBumpProgram.mProgramObject = glCreateProgramObjectARB();
762 gObjectBumpProgram.attachObjects(baseObjects, baseCount);
763 gObjectBumpProgram.attachObject(loadShader(bumpshinyvertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB));
764 gObjectBumpProgram.attachObject(loadShader(bumpshinyfragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB));
765 success = gObjectBumpProgram.mapAttributes();
766 if (success)
767 {
768 success = gObjectBumpProgram.mapUniforms();
769 }
770 if( !success )
771 {
772 llwarns << "Failed to load " << bumpshinyvertex << llendl;
773 }
774 }
775
776 if (success)
777 {
778 //load object alpha vertex shader
779 std::string alphavertex = "objects/alphaV.glsl";
780 std::string alphafragment = "objects/alphaF.glsl";
781 gObjectAlphaProgram.mProgramObject = glCreateProgramObjectARB();
782 gObjectAlphaProgram.attachObjects(baseObjects, baseCount);
783 gObjectAlphaProgram.attachObject(loadShader(alphavertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB));
784 gObjectAlphaProgram.attachObject(loadShader(alphafragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB));
785
786 success = gObjectAlphaProgram.mapAttributes();
787 if (success)
788 {
789 success = gObjectAlphaProgram.mapUniforms();
790 }
791 if( !success )
792 {
793 llwarns << "Failed to load " << alphavertex << llendl;
794 }
795 }
796#endif
797
798 if (success)
799 {
800 //load shiny vertex shader
801 std::string shinyvertex = "objects/shinyV.glsl";
802 std::string shinyfragment = "objects/shinyF.glsl";
803 gObjectShinyProgram.mProgramObject = glCreateProgramObjectARB();
804 gObjectShinyProgram.attachObjects(baseObjects, baseCount);
805 gObjectShinyProgram.attachObject(loadShader(shinyvertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB));
806 gObjectShinyProgram.attachObject(loadShader(shinyfragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB));
807
808 success = gObjectShinyProgram.mapAttributes();
809 if (success)
810 {
811 success = gObjectShinyProgram.mapUniforms(sShinyUniforms, sShinyUniformCount);
812 }
813 if( !success )
814 {
815 llwarns << "Failed to load " << shinyvertex << llendl;
816 }
817 }
818
819 if( !success )
820 {
821 sVertexShaderLevel[SHADER_OBJECT] = 0;
822 sMaxVertexShaderLevel[SHADER_OBJECT] = 0;
823 return FALSE;
824 }
825
826 return TRUE;
827}
828
829BOOL LLShaderMgr::loadShadersAvatar()
830{
831 GLhandleARB baseObjects[] =
832 {
833 gLightFragment,
834 gLightVertex,
835 gScatterFragment,
836 gScatterVertex
837 };
838 S32 baseCount = 4;
839
840 BOOL success = TRUE;
841
842 if (sVertexShaderLevel[SHADER_AVATAR] == 0)
843 {
844 gAvatarProgram.unload();
845 gAvatarEyeballProgram.unload();
846 gAvatarPickProgram.unload();
847 return FALSE;
848 }
849
850 if (success)
851 {
852 //load specular (eyeball) vertex program
853 std::string eyeballvertex = "avatar/eyeballV.glsl";
854 std::string eyeballfragment = "avatar/eyeballF.glsl";
855 gAvatarEyeballProgram.mProgramObject = glCreateProgramObjectARB();
856 gAvatarEyeballProgram.attachObjects(baseObjects, baseCount);
857 gAvatarEyeballProgram.attachObject(loadShader(eyeballvertex, SHADER_AVATAR, GL_VERTEX_SHADER_ARB));
858 gAvatarEyeballProgram.attachObject(loadShader(eyeballfragment, SHADER_AVATAR, GL_FRAGMENT_SHADER_ARB));
859 success = gAvatarEyeballProgram.mapAttributes();
860 if (success)
861 {
862 success = gAvatarEyeballProgram.mapUniforms();
863 }
864 if( !success )
865 {
866 llwarns << "Failed to load " << eyeballvertex << llendl;
867 }
868 }
869
870 if (success)
871 {
872 gAvatarSkinVertex = loadShader("avatar/avatarSkinV.glsl", SHADER_AVATAR, GL_VERTEX_SHADER_ARB);
873 //load avatar vertex shader
874 std::string avatarvertex = "avatar/avatarV.glsl";
875 std::string avatarfragment = "avatar/avatarF.glsl";
876
877 gAvatarProgram.mProgramObject = glCreateProgramObjectARB();
878 gAvatarProgram.attachObjects(baseObjects, baseCount);
879 gAvatarProgram.attachObject(gAvatarSkinVertex);
880 gAvatarProgram.attachObject(loadShader(avatarvertex, SHADER_AVATAR, GL_VERTEX_SHADER_ARB));
881 gAvatarProgram.attachObject(loadShader(avatarfragment, SHADER_AVATAR, GL_FRAGMENT_SHADER_ARB));
882
883 success = gAvatarProgram.mapAttributes(sAvatarAttribs, sAvatarAttribCount);
884 if (success)
885 {
886 success = gAvatarProgram.mapUniforms(sAvatarUniforms, sAvatarUniformCount);
887 }
888 if( !success )
889 {
890 llwarns << "Failed to load " << avatarvertex << llendl;
891 }
892 }
893
894 if (success)
895 {
896 //load avatar picking shader
897 std::string pickvertex = "avatar/pickAvatarV.glsl";
898 std::string pickfragment = "avatar/pickAvatarF.glsl";
899 gAvatarPickProgram.mProgramObject = glCreateProgramObjectARB();
900 gAvatarPickProgram.attachObject(loadShader(pickvertex, SHADER_AVATAR, GL_VERTEX_SHADER_ARB));
901 gAvatarPickProgram.attachObject(loadShader(pickfragment, SHADER_AVATAR, GL_FRAGMENT_SHADER_ARB));
902 gAvatarPickProgram.attachObject(gAvatarSkinVertex);
903
904 success = gAvatarPickProgram.mapAttributes(sAvatarAttribs, sAvatarAttribCount);
905 if (success)
906 {
907 success = gAvatarPickProgram.mapUniforms(sAvatarUniforms, sAvatarUniformCount);
908 }
909 if( !success )
910 {
911 llwarns << "Failed to load " << pickvertex << llendl;
912 }
913 }
914
915 if( !success )
916 {
917 sVertexShaderLevel[SHADER_AVATAR] = 0;
918 sMaxVertexShaderLevel[SHADER_AVATAR] = 0;
919 return FALSE;
920 }
921
922 return TRUE;
923}
924
925BOOL LLShaderMgr::loadShadersInterface()
926{
927 BOOL success = TRUE;
928
929 if (sVertexShaderLevel[SHADER_INTERFACE] == 0)
930 {
931 gHighlightProgram.unload();
932 return FALSE;
933 }
934
935 if (success)
936 {
937 //load highlighting shader
938 std::string highlightvertex = "interface/highlightV.glsl";
939 std::string highlightfragment = "interface/highlightF.glsl";
940 gHighlightProgram.mProgramObject = glCreateProgramObjectARB();
941 gHighlightProgram.attachObject(loadShader(highlightvertex, SHADER_INTERFACE, GL_VERTEX_SHADER_ARB));
942 gHighlightProgram.attachObject(loadShader(highlightfragment, SHADER_INTERFACE, GL_FRAGMENT_SHADER_ARB));
943
944 success = gHighlightProgram.mapAttributes();
945 if (success)
946 {
947 success = gHighlightProgram.mapUniforms();
948 }
949 if( !success )
950 {
951 llwarns << "Failed to load " << highlightvertex << llendl;
952 }
953 }
954
955 if( !success )
956 {
957 sVertexShaderLevel[SHADER_INTERFACE] = 0;
958 sMaxVertexShaderLevel[SHADER_INTERFACE] = 0;
959 return FALSE;
960 }
961
962 return TRUE;
963}
964
965
966//===============================
967// LLGLSL Shader implementation
968//===============================
969LLGLSLShader::LLGLSLShader()
970: mProgramObject(0)
971{ }
972
973void LLGLSLShader::unload()
974{
975 stop_glerror();
976 mAttribute.clear();
977 mTexture.clear();
978 mUniform.clear();
979
980 if (mProgramObject)
981 {
982 GLhandleARB obj[1024];
983 GLsizei count;
984
985 glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
986 for (GLsizei i = 0; i < count; i++)
987 {
988 glDeleteObjectARB(obj[i]);
989 }
990
991 glDeleteObjectARB(mProgramObject);
992
993 mProgramObject = 0;
994 }
995
996 //hack to make apple not complain
997 glGetError();
998
999 stop_glerror();
1000}
1001
1002void LLGLSLShader::attachObject(GLhandleARB object)
1003{
1004 if (object != 0)
1005 {
1006 stop_glerror();
1007 glAttachObjectARB(mProgramObject, object);
1008 stop_glerror();
1009 }
1010 else
1011 {
1012 llwarns << "Attempting to attach non existing shader object. " << llendl;
1013 }
1014}
1015
1016void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
1017{
1018 for (S32 i = 0; i < count; i++)
1019 {
1020 attachObject(objects[i]);
1021 }
1022}
1023
1024BOOL LLGLSLShader::mapAttributes(const char** attrib_names, S32 count)
1025{
1026 //link the program
1027 BOOL res = link();
1028
1029 mAttribute.clear();
1030 mAttribute.resize(LLShaderMgr::sReservedAttribCount + count, -1);
1031
1032 if (res)
1033 { //read back channel locations
1034
1035 //read back reserved channels first
1036 for (S32 i = 0; i < (S32) LLShaderMgr::sReservedAttribCount; i++)
1037 {
1038 const char* name = LLShaderMgr::sReservedAttribs[i];
1039 S32 index = glGetAttribLocationARB(mProgramObject, name);
1040 if (index != -1)
1041 {
1042 mAttribute[i] = index;
1043 llinfos << "Attribute " << name << " assigned to channel " << index << llendl;
1044 }
1045 }
1046
1047 for (S32 i = 0; i < count; i++)
1048 {
1049 const char* name = attrib_names[i];
1050 S32 index = glGetAttribLocationARB(mProgramObject, name);
1051 if (index != -1)
1052 {
1053 mAttribute[LLShaderMgr::sReservedAttribCount + i] = index;
1054 llinfos << "Attribute " << name << " assigned to channel " << index << llendl;
1055 }
1056 }
1057
1058 return TRUE;
1059 }
1060
1061 return FALSE;
1062}
1063
1064void LLGLSLShader::mapUniform(GLint index, const char** uniform_names, S32 count)
1065{
1066 if (index == -1)
1067 {
1068 return;
1069 }
1070
1071 GLenum type;
1072 GLsizei length;
1073 GLint size;
1074 char name[1024]; /* Flawfinder: ignore */
1075 name[0] = 0;
1076
1077 glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, name);
1078
1079 //find the index of this uniform
1080 for (S32 i = 0; i < (S32) LLShaderMgr::sReservedUniformCount; i++)
1081 {
1082 if (mUniform[i] == -1 && !strncmp(LLShaderMgr::sReservedUniforms[i],name, strlen(LLShaderMgr::sReservedUniforms[i]))) /* Flawfinder: ignore */
1083 {
1084 //found it
1085 S32 location = glGetUniformLocationARB(mProgramObject, name);
1086 mUniform[i] = location;
1087 llinfos << "Uniform " << name << " is at location " << location << llendl;
1088 mTexture[i] = mapUniformTextureChannel(location, type);
1089 return;
1090 }
1091 }
1092
1093 for (S32 i = 0; i < count; i++)
1094 {
1095 if (mUniform[i+LLShaderMgr::sReservedUniformCount] == -1 &&
1096 !strncmp(uniform_names[i],name, strlen(uniform_names[i]))) /* Flawfinder: ignore */
1097 {
1098 //found it
1099 S32 location = glGetUniformLocationARB(mProgramObject, name);
1100 mUniform[i+LLShaderMgr::sReservedUniformCount] = location;
1101 llinfos << "Uniform " << name << " is at location " << location << " stored in index " <<
1102 (i+LLShaderMgr::sReservedUniformCount) << llendl;
1103 mTexture[i+LLShaderMgr::sReservedUniformCount] = mapUniformTextureChannel(location, type);
1104 return;
1105 }
1106 }
1107
1108 //llinfos << "Unknown uniform: " << name << llendl;
1109 }
1110
1111GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
1112{
1113 if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB)
1114 { //this here is a texture
1115 glUniform1iARB(location, mActiveTextureChannels);
1116 llinfos << "Assigned to texture channel " << mActiveTextureChannels << llendl;
1117 return mActiveTextureChannels++;
1118 }
1119 return -1;
1120}
1121
1122BOOL LLGLSLShader::mapUniforms(const char** uniform_names, S32 count)
1123{
1124 BOOL res = TRUE;
1125
1126 mActiveTextureChannels = 0;
1127 mUniform.clear();
1128 mTexture.clear();
1129
1130 //initialize arrays
1131 mUniform.resize(count + LLShaderMgr::sReservedUniformCount, -1);
1132 mTexture.resize(count + LLShaderMgr::sReservedUniformCount, -1);
1133
1134 bind();
1135
1136 //get the number of active uniforms
1137 GLint activeCount;
1138 glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
1139
1140 for (S32 i = 0; i < activeCount; i++)
1141 {
1142 mapUniform(i, uniform_names, count);
1143 }
1144
1145 unbind();
1146
1147 return res;
1148}
1149
1150BOOL LLGLSLShader::link(BOOL suppress_errors)
1151{
1152 return LLShaderMgr::linkProgramObject(mProgramObject, suppress_errors);
1153}
1154
1155void LLGLSLShader::bind()
1156{
1157 glUseProgramObjectARB(mProgramObject);
1158 if (mAttribute.size() > 0)
1159 {
1160 gMaterialIndex = mAttribute[0];
1161 }
1162}
1163
1164void LLGLSLShader::unbind()
1165{
1166 for (U32 i = 0; i < mAttribute.size(); ++i)
1167 {
1168 vertexAttrib4f(i, 0,0,0,1);
1169 }
1170 glUseProgramObjectARB(0);
1171}
1172
1173S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode)
1174{
1175 if (uniform < 0 || uniform >= (S32)mTexture.size())
1176 {
1177 llerrs << "LLGLSLShader::enableTexture: uniform out of range: " << uniform << llendl;
1178 }
1179 S32 index = mTexture[uniform];
1180 if (index != -1)
1181 {
1182 glActiveTextureARB(GL_TEXTURE0_ARB+index);
1183 glEnable(mode);
1184 }
1185 return index;
1186}
1187
1188S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode)
1189{
1190 S32 index = mTexture[uniform];
1191 if (index != -1)
1192 {
1193 glActiveTextureARB(GL_TEXTURE0_ARB+index);
1194 glDisable(mode);
1195 }
1196 return index;
1197}
1198
1199void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1200{
1201 if (mAttribute[index] > 0)
1202 {
1203 glVertexAttrib4fARB(mAttribute[index], x, y, z, w);
1204 }
1205}
1206
1207void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
1208{
1209 if (mAttribute[index] > 0)
1210 {
1211 glVertexAttrib4fvARB(mAttribute[index], v);
1212 }
1213}
1214
1215void LLScatterShader::init(GLhandleARB shader, int map_stage)
1216{
1217 glUseProgramObjectARB(shader);
1218 glUniform1iARB(glGetUniformLocationARB(shader, "scatterMap"), map_stage);
1219 glUseProgramObjectARB(0);
1220}
1221