aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llrender/llglslshader.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-09-06 18:24:57 -0500
committerJacek Antonelli2008-09-06 18:25:07 -0500
commit798d367d54a6c6379ad355bd8345fa40e31e7fe9 (patch)
tree1921f1708cd0240648c97bc02df2c2ab5f2fc41e /linden/indra/llrender/llglslshader.cpp
parentSecond Life viewer sources 1.20.15 (diff)
downloadmeta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.zip
meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.gz
meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.bz2
meta-impy-798d367d54a6c6379ad355bd8345fa40e31e7fe9.tar.xz
Second Life viewer sources 1.21.0-RC
Diffstat (limited to '')
-rw-r--r--linden/indra/llrender/llglslshader.cpp823
1 files changed, 823 insertions, 0 deletions
diff --git a/linden/indra/llrender/llglslshader.cpp b/linden/indra/llrender/llglslshader.cpp
new file mode 100644
index 0000000..26984e1
--- /dev/null
+++ b/linden/indra/llrender/llglslshader.cpp
@@ -0,0 +1,823 @@
1/**
2 * @file llglslshader.cpp
3 * @brief GLSL helper functions and state.
4 *
5 * $LicenseInfo:firstyear=2005&license=viewergpl$
6 *
7 * Copyright (c) 2005-2008, Linden Research, Inc.
8 *
9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"), unless you have obtained a separate licensing agreement
13 * ("Other License"), formally executed by you and Linden Lab. Terms of
14 * the GPL can be found in doc/GPL-license.txt in this distribution, or
15 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
16 *
17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 * $/LicenseInfo$
30 */
31
32#include "linden_common.h"
33
34#include "llglslshader.h"
35
36#include "llshadermgr.h"
37#include "llfile.h"
38#include "llrender.h"
39
40#if LL_DARWIN
41#include "OpenGL/OpenGL.h"
42#endif
43
44#ifdef LL_RELEASE_FOR_DOWNLOAD
45#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
46#else
47#define UNIFORM_ERRS LL_ERRS("Shader")
48#endif
49
50// Lots of STL stuff in here, using namespace std to keep things more readable
51using std::vector;
52using std::pair;
53using std::make_pair;
54using std::string;
55
56BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
57{
58 return v1 != v2;
59}
60
61LLShaderFeatures::LLShaderFeatures()
62: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
63hasTransport(false), hasSkinning(false), hasAtmospherics(false), isSpecular(false),
64hasGamma(false), hasLighting(false), calculatesAtmospherics(false)
65{
66}
67
68//===============================
69// LLGLSL Shader implementation
70//===============================
71LLGLSLShader::LLGLSLShader()
72: mProgramObject(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT)
73{
74}
75
76void LLGLSLShader::unload()
77{
78 stop_glerror();
79 mAttribute.clear();
80 mTexture.clear();
81 mUniform.clear();
82 mShaderFiles.clear();
83
84 if (mProgramObject)
85 {
86 GLhandleARB obj[1024];
87 GLsizei count;
88
89 glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
90 for (GLsizei i = 0; i < count; i++)
91 {
92 glDeleteObjectARB(obj[i]);
93 }
94
95 glDeleteObjectARB(mProgramObject);
96
97 mProgramObject = 0;
98 }
99
100 //hack to make apple not complain
101 glGetError();
102
103 stop_glerror();
104}
105
106BOOL LLGLSLShader::createShader(vector<string> * attributes,
107 vector<string> * uniforms)
108{
109 llassert_always(!mShaderFiles.empty());
110 BOOL success = TRUE;
111
112 // Create program
113 mProgramObject = glCreateProgramObjectARB();
114
115 // Attach existing objects
116 if (!LLShaderMgr::instance()->attachShaderFeatures(this))
117 {
118 return FALSE;
119 }
120
121 vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
122 for ( ; fileIter != mShaderFiles.end(); fileIter++ )
123 {
124 GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second);
125 LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
126 if (mShaderLevel > 0)
127 {
128 attachObject(shaderhandle);
129 }
130 else
131 {
132 success = FALSE;
133 }
134 }
135
136 // Map attributes and uniforms
137 if (success)
138 {
139 success = mapAttributes(attributes);
140 }
141 if (success)
142 {
143 success = mapUniforms(uniforms);
144 }
145 if( !success )
146 {
147 LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL;
148
149 // Try again using a lower shader level;
150 if (mShaderLevel > 0)
151 {
152 LL_WARNS("ShaderLoading") << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
153 mShaderLevel--;
154 return createShader(attributes,uniforms);
155 }
156 }
157 return success;
158}
159
160BOOL LLGLSLShader::attachObject(std::string object)
161{
162 if (LLShaderMgr::instance()->mShaderObjects.count(object) > 0)
163 {
164 stop_glerror();
165 glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mShaderObjects[object]);
166 stop_glerror();
167 return TRUE;
168 }
169 else
170 {
171 LL_WARNS("ShaderLoading") << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL;
172 return FALSE;
173 }
174}
175
176void LLGLSLShader::attachObject(GLhandleARB object)
177{
178 if (object != 0)
179 {
180 stop_glerror();
181 glAttachObjectARB(mProgramObject, object);
182 stop_glerror();
183 }
184 else
185 {
186 LL_WARNS("ShaderLoading") << "Attempting to attach non existing shader object. " << LL_ENDL;
187 }
188}
189
190void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
191{
192 for (S32 i = 0; i < count; i++)
193 {
194 attachObject(objects[i]);
195 }
196}
197
198BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
199{
200 //link the program
201 BOOL res = link();
202
203 mAttribute.clear();
204 U32 numAttributes = (attributes == NULL) ? 0 : attributes->size();
205 mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, -1);
206
207 if (res)
208 { //read back channel locations
209
210 //read back reserved channels first
211 for (U32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedAttribs.size(); i++)
212 {
213 const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
214 S32 index = glGetAttribLocationARB(mProgramObject, (const GLcharARB *)name);
215 if (index != -1)
216 {
217 mAttribute[i] = index;
218 LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
219 }
220 }
221 if (attributes != NULL)
222 {
223 for (U32 i = 0; i < numAttributes; i++)
224 {
225 const char* name = (*attributes)[i].c_str();
226 S32 index = glGetAttribLocationARB(mProgramObject, name);
227 if (index != -1)
228 {
229 mAttribute[LLShaderMgr::instance()->mReservedAttribs.size() + i] = index;
230 LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
231 }
232 }
233 }
234
235 return TRUE;
236 }
237
238 return FALSE;
239}
240
241void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
242{
243 if (index == -1)
244 {
245 return;
246 }
247
248 GLenum type;
249 GLsizei length;
250 GLint size;
251 char name[1024]; /* Flawfinder: ignore */
252 name[0] = 0;
253
254 glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
255 S32 location = glGetUniformLocationARB(mProgramObject, name);
256 if (location != -1)
257 {
258 mUniformMap[name] = location;
259 LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
260
261 //find the index of this uniform
262 for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++)
263 {
264 if ( (mUniform[i] == -1)
265 && (LLShaderMgr::instance()->mReservedUniforms[i].compare(0, length, name, LLShaderMgr::instance()->mReservedUniforms[i].length()) == 0))
266 {
267 //found it
268 mUniform[i] = location;
269 mTexture[i] = mapUniformTextureChannel(location, type);
270 return;
271 }
272 }
273
274 if (uniforms != NULL)
275 {
276 for (U32 i = 0; i < uniforms->size(); i++)
277 {
278 if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
279 && ((*uniforms)[i].compare(0, length, name, (*uniforms)[i].length()) == 0))
280 {
281 //found it
282 mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
283 mTexture[i+LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type);
284 return;
285 }
286 }
287 }
288 }
289 }
290
291GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
292{
293 if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB)
294 { //this here is a texture
295 glUniform1iARB(location, mActiveTextureChannels);
296 LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
297 return mActiveTextureChannels++;
298 }
299 return -1;
300}
301
302BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
303{
304 BOOL res = TRUE;
305
306 mActiveTextureChannels = 0;
307 mUniform.clear();
308 mUniformMap.clear();
309 mTexture.clear();
310 mValue.clear();
311 //initialize arrays
312 U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size();
313 mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
314 mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
315
316 bind();
317
318 //get the number of active uniforms
319 GLint activeCount;
320 glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
321
322 for (S32 i = 0; i < activeCount; i++)
323 {
324 mapUniform(i, uniforms);
325 }
326
327 unbind();
328
329 return res;
330}
331
332BOOL LLGLSLShader::link(BOOL suppress_errors)
333{
334 return LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
335}
336
337void LLGLSLShader::bind()
338{
339 if (gGLManager.mHasShaderObjects)
340 {
341 glUseProgramObjectARB(mProgramObject);
342
343 if (mUniformsDirty)
344 {
345 LLShaderMgr::instance()->updateShaderUniforms(this);
346 mUniformsDirty = FALSE;
347 }
348 }
349}
350
351void LLGLSLShader::unbind()
352{
353 if (gGLManager.mHasShaderObjects)
354 {
355 for (U32 i = 0; i < mAttribute.size(); ++i)
356 {
357 vertexAttrib4f(i, 0,0,0,1);
358 }
359 glUseProgramObjectARB(0);
360 }
361}
362
363void LLGLSLShader::bindNoShader(void)
364{
365 glUseProgramObjectARB(0);
366}
367
368S32 LLGLSLShader::enableTexture(S32 uniform, S32 mode)
369{
370 if (uniform < 0 || uniform >= (S32)mTexture.size())
371 {
372 UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
373 return -1;
374 }
375 S32 index = mTexture[uniform];
376 if (index != -1)
377 {
378 gGL.getTexUnit(index)->activate();
379 glEnable(mode);
380 }
381 return index;
382}
383
384S32 LLGLSLShader::disableTexture(S32 uniform, S32 mode)
385{
386 if (uniform < 0 || uniform >= (S32)mTexture.size())
387 {
388 UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
389 return -1;
390 }
391 S32 index = mTexture[uniform];
392 if (index != -1)
393 {
394 gGL.getTexUnit(index)->activate();
395 glDisable(mode);
396 }
397 return index;
398}
399
400void LLGLSLShader::uniform1f(U32 index, GLfloat x)
401{
402 if (mProgramObject > 0)
403 {
404 if (mUniform.size() <= index)
405 {
406 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
407 return;
408 }
409
410 if (mUniform[index] >= 0)
411 {
412 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
413 if (iter == mValue.end() || iter->second.mV[0] != x)
414 {
415 glUniform1fARB(mUniform[index], x);
416 mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
417 }
418 }
419 }
420}
421
422void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
423{
424 if (mProgramObject > 0)
425 {
426 if (mUniform.size() <= index)
427 {
428 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
429 return;
430 }
431
432 if (mUniform[index] >= 0)
433 {
434 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
435 LLVector4 vec(x,y,0.f,0.f);
436 if (iter == mValue.end() || shouldChange(iter->second,vec))
437 {
438 glUniform2fARB(mUniform[index], x, y);
439 mValue[mUniform[index]] = vec;
440 }
441 }
442 }
443}
444
445void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
446{
447 if (mProgramObject > 0)
448 {
449 if (mUniform.size() <= index)
450 {
451 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
452 return;
453 }
454
455 if (mUniform[index] >= 0)
456 {
457 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
458 LLVector4 vec(x,y,z,0.f);
459 if (iter == mValue.end() || shouldChange(iter->second,vec))
460 {
461 glUniform3fARB(mUniform[index], x, y, z);
462 mValue[mUniform[index]] = vec;
463 }
464 }
465 }
466}
467
468void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
469{
470 if (mProgramObject > 0)
471 {
472 if (mUniform.size() <= index)
473 {
474 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
475 return;
476 }
477
478 if (mUniform[index] >= 0)
479 {
480 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
481 LLVector4 vec(x,y,z,w);
482 if (iter == mValue.end() || shouldChange(iter->second,vec))
483 {
484 glUniform4fARB(mUniform[index], x, y, z, w);
485 mValue[mUniform[index]] = vec;
486 }
487 }
488 }
489}
490
491void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
492{
493 if (mProgramObject > 0)
494 {
495 if (mUniform.size() <= index)
496 {
497 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
498 return;
499 }
500
501 if (mUniform[index] >= 0)
502 {
503 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
504 LLVector4 vec(v[0],0.f,0.f,0.f);
505 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
506 {
507 glUniform1fvARB(mUniform[index], count, v);
508 mValue[mUniform[index]] = vec;
509 }
510 }
511 }
512}
513
514void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
515{
516 if (mProgramObject > 0)
517 {
518 if (mUniform.size() <= index)
519 {
520 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
521 return;
522 }
523
524 if (mUniform[index] >= 0)
525 {
526 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
527 LLVector4 vec(v[0],v[1],0.f,0.f);
528 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
529 {
530 glUniform2fvARB(mUniform[index], count, v);
531 mValue[mUniform[index]] = vec;
532 }
533 }
534 }
535}
536
537void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
538{
539 if (mProgramObject > 0)
540 {
541 if (mUniform.size() <= index)
542 {
543 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
544 return;
545 }
546
547 if (mUniform[index] >= 0)
548 {
549 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
550 LLVector4 vec(v[0],v[1],v[2],0.f);
551 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
552 {
553 glUniform3fvARB(mUniform[index], count, v);
554 mValue[mUniform[index]] = vec;
555 }
556 }
557 }
558}
559
560void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
561{
562 if (mProgramObject > 0)
563 {
564 if (mUniform.size() <= index)
565 {
566 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
567 return;
568 }
569
570 if (mUniform[index] >= 0)
571 {
572 std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
573 LLVector4 vec(v[0],v[1],v[2],v[3]);
574 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
575 {
576 glUniform4fvARB(mUniform[index], count, v);
577 mValue[mUniform[index]] = vec;
578 }
579 }
580 }
581}
582
583void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
584{
585 if (mProgramObject > 0)
586 {
587 if (mUniform.size() <= index)
588 {
589 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
590 return;
591 }
592
593 if (mUniform[index] >= 0)
594 {
595 glUniformMatrix2fvARB(mUniform[index], count, transpose, v);
596 }
597 }
598}
599
600void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
601{
602 if (mProgramObject > 0)
603 {
604 if (mUniform.size() <= index)
605 {
606 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
607 return;
608 }
609
610 if (mUniform[index] >= 0)
611 {
612 glUniformMatrix3fvARB(mUniform[index], count, transpose, v);
613 }
614 }
615}
616
617void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
618{
619 if (mProgramObject > 0)
620 {
621 if (mUniform.size() <= index)
622 {
623 UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
624 return;
625 }
626
627 if (mUniform[index] >= 0)
628 {
629 glUniformMatrix4fvARB(mUniform[index], count, transpose, v);
630 }
631 }
632}
633
634GLint LLGLSLShader::getUniformLocation(const string& uniform)
635{
636 if (mProgramObject > 0)
637 {
638 std::map<string, GLint>::iterator iter = mUniformMap.find(uniform);
639 if (iter != mUniformMap.end())
640 {
641 llassert(iter->second == glGetUniformLocationARB(mProgramObject, uniform.c_str()));
642 return iter->second;
643 }
644 }
645
646 return -1;
647}
648
649void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
650{
651 GLint location = getUniformLocation(uniform);
652
653 if (location >= 0)
654 {
655 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
656 LLVector4 vec(v,0.f,0.f,0.f);
657 if (iter == mValue.end() || shouldChange(iter->second,vec))
658 {
659 glUniform1fARB(location, v);
660 mValue[location] = vec;
661 }
662 }
663}
664
665void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y)
666{
667 GLint location = getUniformLocation(uniform);
668
669 if (location >= 0)
670 {
671 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
672 LLVector4 vec(x,y,0.f,0.f);
673 if (iter == mValue.end() || shouldChange(iter->second,vec))
674 {
675 glUniform2fARB(location, x,y);
676 mValue[location] = vec;
677 }
678 }
679
680}
681
682void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloat z)
683{
684 GLint location = getUniformLocation(uniform);
685
686 if (location >= 0)
687 {
688 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
689 LLVector4 vec(x,y,z,0.f);
690 if (iter == mValue.end() || shouldChange(iter->second,vec))
691 {
692 glUniform3fARB(location, x,y,z);
693 mValue[location] = vec;
694 }
695 }
696}
697
698void LLGLSLShader::uniform4f(const string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
699{
700 GLint location = getUniformLocation(uniform);
701
702 if (location >= 0)
703 {
704 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
705 LLVector4 vec(x,y,z,w);
706 if (iter == mValue.end() || shouldChange(iter->second,vec))
707 {
708 glUniform4fARB(location, x,y,z,w);
709 mValue[location] = vec;
710 }
711 }
712}
713
714void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v)
715{
716 GLint location = getUniformLocation(uniform);
717
718 if (location >= 0)
719 {
720 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
721 LLVector4 vec(v[0],0.f,0.f,0.f);
722 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
723 {
724 glUniform1fvARB(location, count, v);
725 mValue[location] = vec;
726 }
727 }
728}
729
730void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v)
731{
732 GLint location = getUniformLocation(uniform);
733
734 if (location >= 0)
735 {
736 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
737 LLVector4 vec(v[0],v[1],0.f,0.f);
738 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
739 {
740 glUniform2fvARB(location, count, v);
741 mValue[location] = vec;
742 }
743 }
744}
745
746void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v)
747{
748 GLint location = getUniformLocation(uniform);
749
750 if (location >= 0)
751 {
752 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
753 LLVector4 vec(v[0],v[1],v[2],0.f);
754 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
755 {
756 glUniform3fvARB(location, count, v);
757 mValue[location] = vec;
758 }
759 }
760}
761
762void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v)
763{
764 GLint location = getUniformLocation(uniform);
765
766 if (location >= 0)
767 {
768 LLVector4 vec(v);
769 std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
770 if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
771 {
772 glUniform4fvARB(location, count, v);
773 mValue[location] = vec;
774 }
775 }
776}
777
778void LLGLSLShader::uniformMatrix2fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
779{
780 GLint location = getUniformLocation(uniform);
781
782 if (location >= 0)
783 {
784 glUniformMatrix2fvARB(location, count, transpose, v);
785 }
786}
787
788void LLGLSLShader::uniformMatrix3fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
789{
790 GLint location = getUniformLocation(uniform);
791
792 if (location >= 0)
793 {
794 glUniformMatrix3fvARB(location, count, transpose, v);
795 }
796}
797
798void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
799{
800 GLint location = getUniformLocation(uniform);
801
802 if (location >= 0)
803 {
804 glUniformMatrix4fvARB(location, count, transpose, v);
805 }
806}
807
808
809void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
810{
811 if (mAttribute[index] > 0)
812 {
813 glVertexAttrib4fARB(mAttribute[index], x, y, z, w);
814 }
815}
816
817void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
818{
819 if (mAttribute[index] > 0)
820 {
821 glVertexAttrib4fvARB(mAttribute[index], v);
822 }
823}