/indra/llrender/llglslshader.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 1016 lines · 849 code · 120 blank · 47 comment · 214 complexity · 67c34fbe454be8e626f7306073ab8eea MD5 · raw file

  1. /**
  2. * @file llglslshader.cpp
  3. * @brief GLSL helper functions and state.
  4. *
  5. * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "llglslshader.h"
  28. #include "llshadermgr.h"
  29. #include "llfile.h"
  30. #include "llrender.h"
  31. #include "llvertexbuffer.h"
  32. #if LL_DARWIN
  33. #include "OpenGL/OpenGL.h"
  34. #endif
  35. #ifdef LL_RELEASE_FOR_DOWNLOAD
  36. #define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
  37. #else
  38. #define UNIFORM_ERRS LL_ERRS("Shader")
  39. #endif
  40. // Lots of STL stuff in here, using namespace std to keep things more readable
  41. using std::vector;
  42. using std::pair;
  43. using std::make_pair;
  44. using std::string;
  45. GLhandleARB LLGLSLShader::sCurBoundShader = 0;
  46. LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
  47. S32 LLGLSLShader::sIndexedTextureChannels = 0;
  48. bool LLGLSLShader::sNoFixedFunction = false;
  49. //UI shader -- declared here so llui_libtest will link properly
  50. LLGLSLShader gUIProgram;
  51. LLGLSLShader gSolidColorProgram;
  52. BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
  53. {
  54. return v1 != v2;
  55. }
  56. LLShaderFeatures::LLShaderFeatures()
  57. : calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
  58. hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false),
  59. hasGamma(false), hasLighting(false), isAlphaLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false),
  60. hasAlphaMask(false)
  61. {
  62. }
  63. //===============================
  64. // LLGLSL Shader implementation
  65. //===============================
  66. LLGLSLShader::LLGLSLShader()
  67. : mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE)
  68. {
  69. }
  70. void LLGLSLShader::unload()
  71. {
  72. stop_glerror();
  73. mAttribute.clear();
  74. mTexture.clear();
  75. mUniform.clear();
  76. mShaderFiles.clear();
  77. if (mProgramObject)
  78. {
  79. GLhandleARB obj[1024];
  80. GLsizei count;
  81. glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
  82. for (GLsizei i = 0; i < count; i++)
  83. {
  84. glDeleteObjectARB(obj[i]);
  85. }
  86. glDeleteObjectARB(mProgramObject);
  87. mProgramObject = 0;
  88. }
  89. //hack to make apple not complain
  90. glGetError();
  91. stop_glerror();
  92. }
  93. BOOL LLGLSLShader::createShader(vector<string> * attributes,
  94. vector<string> * uniforms)
  95. {
  96. //reloading, reset matrix hash values
  97. for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
  98. {
  99. mMatHash[i] = 0xFFFFFFFF;
  100. }
  101. mLightHash = 0xFFFFFFFF;
  102. llassert_always(!mShaderFiles.empty());
  103. BOOL success = TRUE;
  104. // Create program
  105. mProgramObject = glCreateProgramObjectARB();
  106. //compile new source
  107. vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
  108. for ( ; fileIter != mShaderFiles.end(); fileIter++ )
  109. {
  110. GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second, mFeatures.mIndexedTextureChannels);
  111. LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL;
  112. if (shaderhandle > 0)
  113. {
  114. attachObject(shaderhandle);
  115. }
  116. else
  117. {
  118. success = FALSE;
  119. }
  120. }
  121. // Attach existing objects
  122. if (!LLShaderMgr::instance()->attachShaderFeatures(this))
  123. {
  124. return FALSE;
  125. }
  126. if (gGLManager.mGLVersion < 3.1f)
  127. { //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again
  128. mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
  129. }
  130. // Map attributes and uniforms
  131. if (success)
  132. {
  133. success = mapAttributes(attributes);
  134. }
  135. if (success)
  136. {
  137. success = mapUniforms(uniforms);
  138. }
  139. if( !success )
  140. {
  141. LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL;
  142. // Try again using a lower shader level;
  143. if (mShaderLevel > 0)
  144. {
  145. LL_WARNS("ShaderLoading") << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
  146. mShaderLevel--;
  147. return createShader(attributes,uniforms);
  148. }
  149. }
  150. else if (mFeatures.mIndexedTextureChannels > 0)
  151. { //override texture channels for indexed texture rendering
  152. bind();
  153. S32 channel_count = mFeatures.mIndexedTextureChannels;
  154. for (S32 i = 0; i < channel_count; i++)
  155. {
  156. uniform1i(llformat("tex%d", i), i);
  157. }
  158. S32 cur_tex = channel_count; //adjust any texture channels that might have been overwritten
  159. for (U32 i = 0; i < mTexture.size(); i++)
  160. {
  161. if (mTexture[i] > -1 && mTexture[i] < channel_count)
  162. {
  163. llassert(cur_tex < gGLManager.mNumTextureImageUnits);
  164. uniform1i(i, cur_tex);
  165. mTexture[i] = cur_tex++;
  166. }
  167. }
  168. unbind();
  169. }
  170. return success;
  171. }
  172. BOOL LLGLSLShader::attachObject(std::string object)
  173. {
  174. if (LLShaderMgr::instance()->mShaderObjects.count(object) > 0)
  175. {
  176. stop_glerror();
  177. glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mShaderObjects[object]);
  178. stop_glerror();
  179. return TRUE;
  180. }
  181. else
  182. {
  183. LL_WARNS("ShaderLoading") << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL;
  184. return FALSE;
  185. }
  186. }
  187. void LLGLSLShader::attachObject(GLhandleARB object)
  188. {
  189. if (object != 0)
  190. {
  191. stop_glerror();
  192. glAttachObjectARB(mProgramObject, object);
  193. stop_glerror();
  194. }
  195. else
  196. {
  197. LL_WARNS("ShaderLoading") << "Attempting to attach non existing shader object. " << LL_ENDL;
  198. }
  199. }
  200. void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
  201. {
  202. for (S32 i = 0; i < count; i++)
  203. {
  204. attachObject(objects[i]);
  205. }
  206. }
  207. BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
  208. {
  209. //before linking, make sure reserved attributes always have consistent locations
  210. for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
  211. {
  212. const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
  213. glBindAttribLocationARB(mProgramObject, i, (const GLcharARB *) name);
  214. }
  215. //link the program
  216. BOOL res = link();
  217. mAttribute.clear();
  218. U32 numAttributes = (attributes == NULL) ? 0 : attributes->size();
  219. mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, -1);
  220. if (res)
  221. { //read back channel locations
  222. //read back reserved channels first
  223. for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
  224. {
  225. const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
  226. S32 index = glGetAttribLocationARB(mProgramObject, (const GLcharARB *)name);
  227. if (index != -1)
  228. {
  229. mAttribute[i] = index;
  230. LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
  231. }
  232. }
  233. if (attributes != NULL)
  234. {
  235. for (U32 i = 0; i < numAttributes; i++)
  236. {
  237. const char* name = (*attributes)[i].c_str();
  238. S32 index = glGetAttribLocationARB(mProgramObject, name);
  239. if (index != -1)
  240. {
  241. mAttribute[LLShaderMgr::instance()->mReservedAttribs.size() + i] = index;
  242. LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
  243. }
  244. }
  245. }
  246. return TRUE;
  247. }
  248. return FALSE;
  249. }
  250. void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
  251. {
  252. if (index == -1)
  253. {
  254. return;
  255. }
  256. GLenum type;
  257. GLsizei length;
  258. GLint size;
  259. char name[1024]; /* Flawfinder: ignore */
  260. name[0] = 0;
  261. glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, (GLcharARB *)name);
  262. S32 location = glGetUniformLocationARB(mProgramObject, name);
  263. if (location != -1)
  264. {
  265. //chop off "[0]" so we can always access the first element
  266. //of an array by the array name
  267. char* is_array = strstr(name, "[0]");
  268. if (is_array)
  269. {
  270. is_array[0] = 0;
  271. }
  272. mUniformMap[name] = location;
  273. LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
  274. //find the index of this uniform
  275. for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++)
  276. {
  277. if ( (mUniform[i] == -1)
  278. && (LLShaderMgr::instance()->mReservedUniforms[i] == name))
  279. {
  280. //found it
  281. mUniform[i] = location;
  282. mTexture[i] = mapUniformTextureChannel(location, type);
  283. return;
  284. }
  285. }
  286. if (uniforms != NULL)
  287. {
  288. for (U32 i = 0; i < uniforms->size(); i++)
  289. {
  290. if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
  291. && ((*uniforms)[i] == name))
  292. {
  293. //found it
  294. mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
  295. mTexture[i+LLShaderMgr::instance()->mReservedUniforms.size()] = mapUniformTextureChannel(location, type);
  296. return;
  297. }
  298. }
  299. }
  300. }
  301. }
  302. GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type)
  303. {
  304. if (type >= GL_SAMPLER_1D_ARB && type <= GL_SAMPLER_2D_RECT_SHADOW_ARB ||
  305. type == GL_SAMPLER_2D_MULTISAMPLE)
  306. { //this here is a texture
  307. glUniform1iARB(location, mActiveTextureChannels);
  308. LL_DEBUGS("ShaderLoading") << "Assigned to texture channel " << mActiveTextureChannels << LL_ENDL;
  309. return mActiveTextureChannels++;
  310. }
  311. return -1;
  312. }
  313. BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
  314. {
  315. BOOL res = TRUE;
  316. mActiveTextureChannels = 0;
  317. mUniform.clear();
  318. mUniformMap.clear();
  319. mTexture.clear();
  320. mValue.clear();
  321. //initialize arrays
  322. U32 numUniforms = (uniforms == NULL) ? 0 : uniforms->size();
  323. mUniform.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
  324. mTexture.resize(numUniforms + LLShaderMgr::instance()->mReservedUniforms.size(), -1);
  325. bind();
  326. //get the number of active uniforms
  327. GLint activeCount;
  328. glGetObjectParameterivARB(mProgramObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &activeCount);
  329. for (S32 i = 0; i < activeCount; i++)
  330. {
  331. mapUniform(i, uniforms);
  332. }
  333. unbind();
  334. return res;
  335. }
  336. BOOL LLGLSLShader::link(BOOL suppress_errors)
  337. {
  338. return LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
  339. }
  340. void LLGLSLShader::bind()
  341. {
  342. gGL.flush();
  343. if (gGLManager.mHasShaderObjects)
  344. {
  345. LLVertexBuffer::unbind();
  346. glUseProgramObjectARB(mProgramObject);
  347. sCurBoundShader = mProgramObject;
  348. sCurBoundShaderPtr = this;
  349. if (mUniformsDirty)
  350. {
  351. LLShaderMgr::instance()->updateShaderUniforms(this);
  352. mUniformsDirty = FALSE;
  353. }
  354. }
  355. }
  356. void LLGLSLShader::unbind()
  357. {
  358. gGL.flush();
  359. if (gGLManager.mHasShaderObjects)
  360. {
  361. stop_glerror();
  362. if (gGLManager.mIsNVIDIA)
  363. {
  364. for (U32 i = 0; i < mAttribute.size(); ++i)
  365. {
  366. vertexAttrib4f(i, 0,0,0,1);
  367. stop_glerror();
  368. }
  369. }
  370. LLVertexBuffer::unbind();
  371. glUseProgramObjectARB(0);
  372. sCurBoundShader = 0;
  373. sCurBoundShaderPtr = NULL;
  374. stop_glerror();
  375. }
  376. }
  377. void LLGLSLShader::bindNoShader(void)
  378. {
  379. LLVertexBuffer::unbind();
  380. if (gGLManager.mHasShaderObjects)
  381. {
  382. glUseProgramObjectARB(0);
  383. sCurBoundShader = 0;
  384. sCurBoundShaderPtr = NULL;
  385. }
  386. }
  387. S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
  388. {
  389. if (uniform < 0 || uniform >= (S32)mTexture.size())
  390. {
  391. UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
  392. return -1;
  393. }
  394. S32 index = mTexture[uniform];
  395. if (index != -1)
  396. {
  397. gGL.getTexUnit(index)->activate();
  398. gGL.getTexUnit(index)->enable(mode);
  399. }
  400. return index;
  401. }
  402. S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
  403. {
  404. if (uniform < 0 || uniform >= (S32)mTexture.size())
  405. {
  406. UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
  407. return -1;
  408. }
  409. S32 index = mTexture[uniform];
  410. if (index != -1 && gGL.getTexUnit(index)->getCurrType() != LLTexUnit::TT_NONE)
  411. {
  412. if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode)
  413. {
  414. if (gDebugSession)
  415. {
  416. gFailLog << "Texture channel " << index << " texture type corrupted." << std::endl;
  417. ll_fail("LLGLSLShader::disableTexture failed");
  418. }
  419. else
  420. {
  421. llerrs << "Texture channel " << index << " texture type corrupted." << llendl;
  422. }
  423. }
  424. gGL.getTexUnit(index)->disable();
  425. }
  426. return index;
  427. }
  428. void LLGLSLShader::uniform1i(U32 index, GLint x)
  429. {
  430. if (mProgramObject > 0)
  431. {
  432. if (mUniform.size() <= index)
  433. {
  434. UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
  435. return;
  436. }
  437. if (mUniform[index] >= 0)
  438. {
  439. std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
  440. if (iter == mValue.end() || iter->second.mV[0] != x)
  441. {
  442. glUniform1iARB(mUniform[index], x);
  443. mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
  444. }
  445. }
  446. }
  447. }
  448. void LLGLSLShader::uniform1f(U32 index, GLfloat x)
  449. {
  450. if (mProgramObject > 0)
  451. {
  452. if (mUniform.size() <= index)
  453. {
  454. UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
  455. return;
  456. }
  457. if (mUniform[index] >= 0)
  458. {
  459. std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
  460. if (iter == mValue.end() || iter->second.mV[0] != x)
  461. {
  462. glUniform1fARB(mUniform[index], x);
  463. mValue[mUniform[index]] = LLVector4(x,0.f,0.f,0.f);
  464. }
  465. }
  466. }
  467. }
  468. void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
  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. if (mUniform[index] >= 0)
  478. {
  479. std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
  480. LLVector4 vec(x,y,0.f,0.f);
  481. if (iter == mValue.end() || shouldChange(iter->second,vec))
  482. {
  483. glUniform2fARB(mUniform[index], x, y);
  484. mValue[mUniform[index]] = vec;
  485. }
  486. }
  487. }
  488. }
  489. void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
  490. {
  491. if (mProgramObject > 0)
  492. {
  493. if (mUniform.size() <= index)
  494. {
  495. UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
  496. return;
  497. }
  498. if (mUniform[index] >= 0)
  499. {
  500. std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
  501. LLVector4 vec(x,y,z,0.f);
  502. if (iter == mValue.end() || shouldChange(iter->second,vec))
  503. {
  504. glUniform3fARB(mUniform[index], x, y, z);
  505. mValue[mUniform[index]] = vec;
  506. }
  507. }
  508. }
  509. }
  510. void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  511. {
  512. if (mProgramObject > 0)
  513. {
  514. if (mUniform.size() <= index)
  515. {
  516. UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
  517. return;
  518. }
  519. if (mUniform[index] >= 0)
  520. {
  521. std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
  522. LLVector4 vec(x,y,z,w);
  523. if (iter == mValue.end() || shouldChange(iter->second,vec))
  524. {
  525. glUniform4fARB(mUniform[index], x, y, z, w);
  526. mValue[mUniform[index]] = vec;
  527. }
  528. }
  529. }
  530. }
  531. void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
  532. {
  533. if (mProgramObject > 0)
  534. {
  535. if (mUniform.size() <= index)
  536. {
  537. UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
  538. return;
  539. }
  540. if (mUniform[index] >= 0)
  541. {
  542. std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
  543. LLVector4 vec(v[0],0.f,0.f,0.f);
  544. if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
  545. {
  546. glUniform1ivARB(mUniform[index], count, v);
  547. mValue[mUniform[index]] = vec;
  548. }
  549. }
  550. }
  551. }
  552. void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
  553. {
  554. if (mProgramObject > 0)
  555. {
  556. if (mUniform.size() <= index)
  557. {
  558. UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
  559. return;
  560. }
  561. if (mUniform[index] >= 0)
  562. {
  563. std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
  564. LLVector4 vec(v[0],0.f,0.f,0.f);
  565. if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
  566. {
  567. glUniform1fvARB(mUniform[index], count, v);
  568. mValue[mUniform[index]] = vec;
  569. }
  570. }
  571. }
  572. }
  573. void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
  574. {
  575. if (mProgramObject > 0)
  576. {
  577. if (mUniform.size() <= index)
  578. {
  579. UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
  580. return;
  581. }
  582. if (mUniform[index] >= 0)
  583. {
  584. std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
  585. LLVector4 vec(v[0],v[1],0.f,0.f);
  586. if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
  587. {
  588. glUniform2fvARB(mUniform[index], count, v);
  589. mValue[mUniform[index]] = vec;
  590. }
  591. }
  592. }
  593. }
  594. void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
  595. {
  596. if (mProgramObject > 0)
  597. {
  598. if (mUniform.size() <= index)
  599. {
  600. UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
  601. return;
  602. }
  603. if (mUniform[index] >= 0)
  604. {
  605. std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
  606. LLVector4 vec(v[0],v[1],v[2],0.f);
  607. if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
  608. {
  609. glUniform3fvARB(mUniform[index], count, v);
  610. mValue[mUniform[index]] = vec;
  611. }
  612. }
  613. }
  614. }
  615. void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
  616. {
  617. if (mProgramObject > 0)
  618. {
  619. if (mUniform.size() <= index)
  620. {
  621. UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
  622. return;
  623. }
  624. if (mUniform[index] >= 0)
  625. {
  626. std::map<GLint, LLVector4>::iterator iter = mValue.find(mUniform[index]);
  627. LLVector4 vec(v[0],v[1],v[2],v[3]);
  628. if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
  629. {
  630. glUniform4fvARB(mUniform[index], count, v);
  631. mValue[mUniform[index]] = vec;
  632. }
  633. }
  634. }
  635. }
  636. void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
  637. {
  638. if (mProgramObject > 0)
  639. {
  640. if (mUniform.size() <= index)
  641. {
  642. UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
  643. return;
  644. }
  645. if (mUniform[index] >= 0)
  646. {
  647. glUniformMatrix2fvARB(mUniform[index], count, transpose, v);
  648. }
  649. }
  650. }
  651. void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
  652. {
  653. if (mProgramObject > 0)
  654. {
  655. if (mUniform.size() <= index)
  656. {
  657. UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
  658. return;
  659. }
  660. if (mUniform[index] >= 0)
  661. {
  662. glUniformMatrix3fvARB(mUniform[index], count, transpose, v);
  663. }
  664. }
  665. }
  666. void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v)
  667. {
  668. if (mProgramObject > 0)
  669. {
  670. if (mUniform.size() <= index)
  671. {
  672. UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
  673. return;
  674. }
  675. if (mUniform[index] >= 0)
  676. {
  677. glUniformMatrix4fvARB(mUniform[index], count, transpose, v);
  678. }
  679. }
  680. }
  681. GLint LLGLSLShader::getUniformLocation(const string& uniform)
  682. {
  683. GLint ret = -1;
  684. if (mProgramObject > 0)
  685. {
  686. std::map<string, GLint>::iterator iter = mUniformMap.find(uniform);
  687. if (iter != mUniformMap.end())
  688. {
  689. if (gDebugGL)
  690. {
  691. stop_glerror();
  692. if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.c_str()))
  693. {
  694. llerrs << "Uniform does not match." << llendl;
  695. }
  696. stop_glerror();
  697. }
  698. ret = iter->second;
  699. }
  700. }
  701. return ret;
  702. }
  703. GLint LLGLSLShader::getUniformLocation(U32 index)
  704. {
  705. GLint ret = -1;
  706. if (mProgramObject > 0)
  707. {
  708. llassert(index < mUniform.size());
  709. return mUniform[index];
  710. }
  711. return ret;
  712. }
  713. GLint LLGLSLShader::getAttribLocation(U32 attrib)
  714. {
  715. if (attrib < mAttribute.size())
  716. {
  717. return mAttribute[attrib];
  718. }
  719. else
  720. {
  721. return -1;
  722. }
  723. }
  724. void LLGLSLShader::uniform1i(const string& uniform, GLint v)
  725. {
  726. GLint location = getUniformLocation(uniform);
  727. if (location >= 0)
  728. {
  729. std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
  730. LLVector4 vec(v,0.f,0.f,0.f);
  731. if (iter == mValue.end() || shouldChange(iter->second,vec))
  732. {
  733. glUniform1iARB(location, v);
  734. mValue[location] = vec;
  735. }
  736. }
  737. }
  738. void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
  739. {
  740. GLint location = getUniformLocation(uniform);
  741. if (location >= 0)
  742. {
  743. std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
  744. LLVector4 vec(v,0.f,0.f,0.f);
  745. if (iter == mValue.end() || shouldChange(iter->second,vec))
  746. {
  747. glUniform1fARB(location, v);
  748. mValue[location] = vec;
  749. }
  750. }
  751. }
  752. void LLGLSLShader::uniform2f(const string& uniform, GLfloat x, GLfloat y)
  753. {
  754. GLint location = getUniformLocation(uniform);
  755. if (location >= 0)
  756. {
  757. std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
  758. LLVector4 vec(x,y,0.f,0.f);
  759. if (iter == mValue.end() || shouldChange(iter->second,vec))
  760. {
  761. glUniform2fARB(location, x,y);
  762. mValue[location] = vec;
  763. }
  764. }
  765. }
  766. void LLGLSLShader::uniform3f(const string& uniform, GLfloat x, GLfloat y, GLfloat z)
  767. {
  768. GLint location = getUniformLocation(uniform);
  769. if (location >= 0)
  770. {
  771. std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
  772. LLVector4 vec(x,y,z,0.f);
  773. if (iter == mValue.end() || shouldChange(iter->second,vec))
  774. {
  775. glUniform3fARB(location, x,y,z);
  776. mValue[location] = vec;
  777. }
  778. }
  779. }
  780. void LLGLSLShader::uniform4f(const string& uniform, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  781. {
  782. GLint location = getUniformLocation(uniform);
  783. if (location >= 0)
  784. {
  785. std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
  786. LLVector4 vec(x,y,z,w);
  787. if (iter == mValue.end() || shouldChange(iter->second,vec))
  788. {
  789. glUniform4fARB(location, x,y,z,w);
  790. mValue[location] = vec;
  791. }
  792. }
  793. }
  794. void LLGLSLShader::uniform1fv(const string& uniform, U32 count, const GLfloat* v)
  795. {
  796. GLint location = getUniformLocation(uniform);
  797. if (location >= 0)
  798. {
  799. std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
  800. LLVector4 vec(v[0],0.f,0.f,0.f);
  801. if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
  802. {
  803. glUniform1fvARB(location, count, v);
  804. mValue[location] = vec;
  805. }
  806. }
  807. }
  808. void LLGLSLShader::uniform2fv(const string& uniform, U32 count, const GLfloat* v)
  809. {
  810. GLint location = getUniformLocation(uniform);
  811. if (location >= 0)
  812. {
  813. std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
  814. LLVector4 vec(v[0],v[1],0.f,0.f);
  815. if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
  816. {
  817. glUniform2fvARB(location, count, v);
  818. mValue[location] = vec;
  819. }
  820. }
  821. }
  822. void LLGLSLShader::uniform3fv(const string& uniform, U32 count, const GLfloat* v)
  823. {
  824. GLint location = getUniformLocation(uniform);
  825. if (location >= 0)
  826. {
  827. std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
  828. LLVector4 vec(v[0],v[1],v[2],0.f);
  829. if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
  830. {
  831. glUniform3fvARB(location, count, v);
  832. mValue[location] = vec;
  833. }
  834. }
  835. }
  836. void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v)
  837. {
  838. GLint location = getUniformLocation(uniform);
  839. if (location >= 0)
  840. {
  841. LLVector4 vec(v);
  842. std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
  843. if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
  844. {
  845. stop_glerror();
  846. glUniform4fvARB(location, count, v);
  847. stop_glerror();
  848. mValue[location] = vec;
  849. }
  850. }
  851. }
  852. void LLGLSLShader::uniformMatrix2fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
  853. {
  854. GLint location = getUniformLocation(uniform);
  855. if (location >= 0)
  856. {
  857. glUniformMatrix2fvARB(location, count, transpose, v);
  858. }
  859. }
  860. void LLGLSLShader::uniformMatrix3fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
  861. {
  862. GLint location = getUniformLocation(uniform);
  863. if (location >= 0)
  864. {
  865. glUniformMatrix3fvARB(location, count, transpose, v);
  866. }
  867. }
  868. void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean transpose, const GLfloat* v)
  869. {
  870. GLint location = getUniformLocation(uniform);
  871. if (location >= 0)
  872. {
  873. stop_glerror();
  874. glUniformMatrix4fvARB(location, count, transpose, v);
  875. stop_glerror();
  876. }
  877. }
  878. void LLGLSLShader::vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  879. {
  880. if (mAttribute[index] > 0)
  881. {
  882. glVertexAttrib4fARB(mAttribute[index], x, y, z, w);
  883. }
  884. }
  885. void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
  886. {
  887. if (mAttribute[index] > 0)
  888. {
  889. glVertexAttrib4fvARB(mAttribute[index], v);
  890. }
  891. }
  892. void LLGLSLShader::setMinimumAlpha(F32 minimum)
  893. {
  894. gGL.flush();
  895. uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum);
  896. }