llglslshader.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:22k
源码类别:

游戏引擎

开发平台:

C++ Builder

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