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