PageRenderTime 56ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llrender/llrender.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2297 lines | 1888 code | 327 blank | 82 comment | 367 complexity | 73ffb20d02bfba812f86640f5dd72536 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llrender.cpp
  3. * @brief LLRender implementation
  4. *
  5. * $LicenseInfo:firstyear=2001&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 "llrender.h"
  28. #include "llvertexbuffer.h"
  29. #include "llcubemap.h"
  30. #include "llglslshader.h"
  31. #include "llimagegl.h"
  32. #include "llrendertarget.h"
  33. #include "lltexture.h"
  34. #include "llshadermgr.h"
  35. LLRender gGL;
  36. // Handy copies of last good GL matrices
  37. F32 gGLModelView[16];
  38. F32 gGLLastModelView[16];
  39. F32 gGLLastProjection[16];
  40. F32 gGLProjection[16];
  41. S32 gGLViewport[4];
  42. U32 LLRender::sUICalls = 0;
  43. U32 LLRender::sUIVerts = 0;
  44. U32 LLTexUnit::sWhiteTexture = 0;
  45. bool LLRender::sGLCoreProfile = false;
  46. static const U32 LL_NUM_TEXTURE_LAYERS = 32;
  47. static const U32 LL_NUM_LIGHT_UNITS = 8;
  48. static GLenum sGLTextureType[] =
  49. {
  50. GL_TEXTURE_2D,
  51. GL_TEXTURE_RECTANGLE_ARB,
  52. GL_TEXTURE_CUBE_MAP_ARB,
  53. GL_TEXTURE_2D_MULTISAMPLE
  54. };
  55. static GLint sGLAddressMode[] =
  56. {
  57. GL_REPEAT,
  58. GL_MIRRORED_REPEAT,
  59. GL_CLAMP_TO_EDGE
  60. };
  61. static GLenum sGLCompareFunc[] =
  62. {
  63. GL_NEVER,
  64. GL_ALWAYS,
  65. GL_LESS,
  66. GL_LEQUAL,
  67. GL_EQUAL,
  68. GL_NOTEQUAL,
  69. GL_GEQUAL,
  70. GL_GREATER
  71. };
  72. const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0;
  73. static GLenum sGLBlendFactor[] =
  74. {
  75. GL_ONE,
  76. GL_ZERO,
  77. GL_DST_COLOR,
  78. GL_SRC_COLOR,
  79. GL_ONE_MINUS_DST_COLOR,
  80. GL_ONE_MINUS_SRC_COLOR,
  81. GL_DST_ALPHA,
  82. GL_SRC_ALPHA,
  83. GL_ONE_MINUS_DST_ALPHA,
  84. GL_ONE_MINUS_SRC_ALPHA,
  85. GL_ZERO // 'BF_UNDEF'
  86. };
  87. LLTexUnit::LLTexUnit(S32 index)
  88. : mCurrTexType(TT_NONE), mCurrBlendType(TB_MULT),
  89. mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
  90. mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
  91. mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
  92. mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0),
  93. mHasMipMaps(false)
  94. {
  95. llassert_always(index < (S32)LL_NUM_TEXTURE_LAYERS);
  96. mIndex = index;
  97. }
  98. //static
  99. U32 LLTexUnit::getInternalType(eTextureType type)
  100. {
  101. return sGLTextureType[type];
  102. }
  103. void LLTexUnit::refreshState(void)
  104. {
  105. // We set dirty to true so that the tex unit knows to ignore caching
  106. // and we reset the cached tex unit state
  107. gGL.flush();
  108. glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
  109. //
  110. // Per apple spec, don't call glEnable/glDisable when index exceeds max texture units
  111. // http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html
  112. //
  113. bool enableDisable = !LLGLSLShader::sNoFixedFunction &&
  114. (mIndex < gGLManager.mNumTextureUnits) && mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE;
  115. if (mCurrTexType != TT_NONE)
  116. {
  117. if (enableDisable)
  118. {
  119. glEnable(sGLTextureType[mCurrTexType]);
  120. }
  121. glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture);
  122. }
  123. else
  124. {
  125. if (enableDisable)
  126. {
  127. glDisable(GL_TEXTURE_2D);
  128. }
  129. glBindTexture(GL_TEXTURE_2D, 0);
  130. }
  131. if (mCurrBlendType != TB_COMBINE)
  132. {
  133. setTextureBlendType(mCurrBlendType);
  134. }
  135. else
  136. {
  137. setTextureCombiner(mCurrColorOp, mCurrColorSrc1, mCurrColorSrc2, false);
  138. setTextureCombiner(mCurrAlphaOp, mCurrAlphaSrc1, mCurrAlphaSrc2, true);
  139. }
  140. }
  141. void LLTexUnit::activate(void)
  142. {
  143. if (mIndex < 0) return;
  144. if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty)
  145. {
  146. gGL.flush();
  147. glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
  148. gGL.mCurrTextureUnitIndex = mIndex;
  149. }
  150. }
  151. void LLTexUnit::enable(eTextureType type)
  152. {
  153. if (mIndex < 0) return;
  154. if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) )
  155. {
  156. stop_glerror();
  157. activate();
  158. stop_glerror();
  159. if (mCurrTexType != TT_NONE && !gGL.mDirty)
  160. {
  161. disable(); // Force a disable of a previous texture type if it's enabled.
  162. stop_glerror();
  163. }
  164. mCurrTexType = type;
  165. gGL.flush();
  166. if (!LLGLSLShader::sNoFixedFunction &&
  167. type != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&
  168. mIndex < gGLManager.mNumTextureUnits)
  169. {
  170. stop_glerror();
  171. glEnable(sGLTextureType[type]);
  172. stop_glerror();
  173. }
  174. }
  175. }
  176. void LLTexUnit::disable(void)
  177. {
  178. if (mIndex < 0) return;
  179. if (mCurrTexType != TT_NONE)
  180. {
  181. activate();
  182. unbind(mCurrTexType);
  183. gGL.flush();
  184. if (!LLGLSLShader::sNoFixedFunction &&
  185. mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&
  186. mIndex < gGLManager.mNumTextureUnits)
  187. {
  188. glDisable(sGLTextureType[mCurrTexType]);
  189. }
  190. mCurrTexType = TT_NONE;
  191. }
  192. }
  193. bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
  194. {
  195. stop_glerror();
  196. if (mIndex < 0) return false;
  197. gGL.flush();
  198. LLImageGL* gl_tex = NULL ;
  199. if (texture == NULL || !(gl_tex = texture->getGLTexture()))
  200. {
  201. llwarns << "NULL LLTexUnit::bind texture" << llendl;
  202. return false;
  203. }
  204. if (!gl_tex->getTexName()) //if texture does not exist
  205. {
  206. //if deleted, will re-generate it immediately
  207. texture->forceImmediateUpdate() ;
  208. gl_tex->forceUpdateBindStats() ;
  209. return texture->bindDefaultImage(mIndex);
  210. }
  211. //in audit, replace the selected texture by the default one.
  212. if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0)
  213. {
  214. if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize)
  215. {
  216. gl_tex->updateBindStats(gl_tex->mTextureMemory);
  217. return bind(LLImageGL::sHighlightTexturep.get());
  218. }
  219. }
  220. if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
  221. {
  222. activate();
  223. enable(gl_tex->getTarget());
  224. mCurrTexture = gl_tex->getTexName();
  225. glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
  226. if(gl_tex->updateBindStats(gl_tex->mTextureMemory))
  227. {
  228. texture->setActive() ;
  229. texture->updateBindStatsForTester() ;
  230. }
  231. mHasMipMaps = gl_tex->mHasMipMaps;
  232. if (gl_tex->mTexOptionsDirty)
  233. {
  234. gl_tex->mTexOptionsDirty = false;
  235. setTextureAddressMode(gl_tex->mAddressMode);
  236. setTextureFilteringOption(gl_tex->mFilterOption);
  237. }
  238. }
  239. return true;
  240. }
  241. bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
  242. {
  243. stop_glerror();
  244. if (mIndex < 0) return false;
  245. if(!texture)
  246. {
  247. llwarns << "NULL LLTexUnit::bind texture" << llendl;
  248. return false;
  249. }
  250. if(!texture->getTexName())
  251. {
  252. if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName())
  253. {
  254. return bind(LLImageGL::sDefaultGLTexture) ;
  255. }
  256. stop_glerror();
  257. return false ;
  258. }
  259. if ((mCurrTexture != texture->getTexName()) || forceBind)
  260. {
  261. gGL.flush();
  262. stop_glerror();
  263. activate();
  264. stop_glerror();
  265. enable(texture->getTarget());
  266. stop_glerror();
  267. mCurrTexture = texture->getTexName();
  268. glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
  269. stop_glerror();
  270. texture->updateBindStats(texture->mTextureMemory);
  271. mHasMipMaps = texture->mHasMipMaps;
  272. if (texture->mTexOptionsDirty)
  273. {
  274. stop_glerror();
  275. texture->mTexOptionsDirty = false;
  276. setTextureAddressMode(texture->mAddressMode);
  277. setTextureFilteringOption(texture->mFilterOption);
  278. stop_glerror();
  279. }
  280. }
  281. stop_glerror();
  282. return true;
  283. }
  284. bool LLTexUnit::bind(LLCubeMap* cubeMap)
  285. {
  286. if (mIndex < 0) return false;
  287. gGL.flush();
  288. if (cubeMap == NULL)
  289. {
  290. llwarns << "NULL LLTexUnit::bind cubemap" << llendl;
  291. return false;
  292. }
  293. if (mCurrTexture != cubeMap->mImages[0]->getTexName())
  294. {
  295. if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
  296. {
  297. activate();
  298. enable(LLTexUnit::TT_CUBE_MAP);
  299. mCurrTexture = cubeMap->mImages[0]->getTexName();
  300. glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture);
  301. mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps;
  302. cubeMap->mImages[0]->updateBindStats(cubeMap->mImages[0]->mTextureMemory);
  303. if (cubeMap->mImages[0]->mTexOptionsDirty)
  304. {
  305. cubeMap->mImages[0]->mTexOptionsDirty = false;
  306. setTextureAddressMode(cubeMap->mImages[0]->mAddressMode);
  307. setTextureFilteringOption(cubeMap->mImages[0]->mFilterOption);
  308. }
  309. return true;
  310. }
  311. else
  312. {
  313. llwarns << "Using cube map without extension!" << llendl;
  314. return false;
  315. }
  316. }
  317. return true;
  318. }
  319. // LLRenderTarget is unavailible on the mapserver since it uses FBOs.
  320. #if !LL_MESA_HEADLESS
  321. bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
  322. {
  323. if (mIndex < 0) return false;
  324. gGL.flush();
  325. if (bindDepth)
  326. {
  327. if (renderTarget->hasStencil())
  328. {
  329. llerrs << "Cannot bind a render buffer for sampling. Allocate render target without a stencil buffer if sampling of depth buffer is required." << llendl;
  330. }
  331. bindManual(renderTarget->getUsage(), renderTarget->getDepth());
  332. }
  333. else
  334. {
  335. bindManual(renderTarget->getUsage(), renderTarget->getTexture());
  336. }
  337. return true;
  338. }
  339. #endif // LL_MESA_HEADLESS
  340. bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
  341. {
  342. if (mIndex < 0)
  343. {
  344. return false;
  345. }
  346. if(mCurrTexture != texture)
  347. {
  348. gGL.flush();
  349. activate();
  350. enable(type);
  351. mCurrTexture = texture;
  352. glBindTexture(sGLTextureType[type], texture);
  353. mHasMipMaps = hasMips;
  354. }
  355. return true;
  356. }
  357. void LLTexUnit::unbind(eTextureType type)
  358. {
  359. stop_glerror();
  360. if (mIndex < 0) return;
  361. // Disabled caching of binding state.
  362. if (mCurrTexType == type)
  363. {
  364. gGL.flush();
  365. activate();
  366. mCurrTexture = 0;
  367. if (LLGLSLShader::sNoFixedFunction && type == LLTexUnit::TT_TEXTURE)
  368. {
  369. glBindTexture(sGLTextureType[type], sWhiteTexture);
  370. }
  371. else
  372. {
  373. glBindTexture(sGLTextureType[type], 0);
  374. }
  375. stop_glerror();
  376. }
  377. }
  378. void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
  379. {
  380. if (mIndex < 0 || mCurrTexture == 0) return;
  381. gGL.flush();
  382. activate();
  383. glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]);
  384. glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]);
  385. if (mCurrTexType == TT_CUBE_MAP)
  386. {
  387. glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]);
  388. }
  389. }
  390. void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option)
  391. {
  392. if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return;
  393. gGL.flush();
  394. if (option == TFO_POINT)
  395. {
  396. glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  397. }
  398. else
  399. {
  400. glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  401. }
  402. if (option >= TFO_TRILINEAR && mHasMipMaps)
  403. {
  404. glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  405. }
  406. else if (option >= TFO_BILINEAR)
  407. {
  408. glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  409. }
  410. else
  411. {
  412. glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  413. }
  414. if (gGLManager.mHasAnisotropic)
  415. {
  416. if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC)
  417. {
  418. if (gGL.mMaxAnisotropy < 1.f)
  419. {
  420. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGL.mMaxAnisotropy);
  421. llinfos << "gGL.mMaxAnisotropy: " << gGL.mMaxAnisotropy << llendl ;
  422. gGL.mMaxAnisotropy = llmax(1.f, gGL.mMaxAnisotropy) ;
  423. }
  424. glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGL.mMaxAnisotropy);
  425. }
  426. else
  427. {
  428. glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
  429. }
  430. }
  431. }
  432. void LLTexUnit::setTextureBlendType(eTextureBlendType type)
  433. {
  434. if (LLGLSLShader::sNoFixedFunction)
  435. { //texture blend type means nothing when using shaders
  436. return;
  437. }
  438. if (mIndex < 0) return;
  439. // Do nothing if it's already correctly set.
  440. if (mCurrBlendType == type && !gGL.mDirty)
  441. {
  442. return;
  443. }
  444. gGL.flush();
  445. activate();
  446. mCurrBlendType = type;
  447. S32 scale_amount = 1;
  448. switch (type)
  449. {
  450. case TB_REPLACE:
  451. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  452. break;
  453. case TB_ADD:
  454. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
  455. break;
  456. case TB_MULT:
  457. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  458. break;
  459. case TB_MULT_X2:
  460. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  461. scale_amount = 2;
  462. break;
  463. case TB_ALPHA_BLEND:
  464. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  465. break;
  466. case TB_COMBINE:
  467. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
  468. break;
  469. default:
  470. llerrs << "Unknown Texture Blend Type: " << type << llendl;
  471. break;
  472. }
  473. setColorScale(scale_amount);
  474. setAlphaScale(1);
  475. }
  476. GLint LLTexUnit::getTextureSource(eTextureBlendSrc src)
  477. {
  478. switch(src)
  479. {
  480. // All four cases should return the same value.
  481. case TBS_PREV_COLOR:
  482. case TBS_PREV_ALPHA:
  483. case TBS_ONE_MINUS_PREV_COLOR:
  484. case TBS_ONE_MINUS_PREV_ALPHA:
  485. return GL_PREVIOUS_ARB;
  486. // All four cases should return the same value.
  487. case TBS_TEX_COLOR:
  488. case TBS_TEX_ALPHA:
  489. case TBS_ONE_MINUS_TEX_COLOR:
  490. case TBS_ONE_MINUS_TEX_ALPHA:
  491. return GL_TEXTURE;
  492. // All four cases should return the same value.
  493. case TBS_VERT_COLOR:
  494. case TBS_VERT_ALPHA:
  495. case TBS_ONE_MINUS_VERT_COLOR:
  496. case TBS_ONE_MINUS_VERT_ALPHA:
  497. return GL_PRIMARY_COLOR_ARB;
  498. // All four cases should return the same value.
  499. case TBS_CONST_COLOR:
  500. case TBS_CONST_ALPHA:
  501. case TBS_ONE_MINUS_CONST_COLOR:
  502. case TBS_ONE_MINUS_CONST_ALPHA:
  503. return GL_CONSTANT_ARB;
  504. default:
  505. llwarns << "Unknown eTextureBlendSrc: " << src << ". Using Vertex Color instead." << llendl;
  506. return GL_PRIMARY_COLOR_ARB;
  507. }
  508. }
  509. GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)
  510. {
  511. switch(src)
  512. {
  513. // All four cases should return the same value.
  514. case TBS_PREV_COLOR:
  515. case TBS_TEX_COLOR:
  516. case TBS_VERT_COLOR:
  517. case TBS_CONST_COLOR:
  518. return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR;
  519. // All four cases should return the same value.
  520. case TBS_PREV_ALPHA:
  521. case TBS_TEX_ALPHA:
  522. case TBS_VERT_ALPHA:
  523. case TBS_CONST_ALPHA:
  524. return GL_SRC_ALPHA;
  525. // All four cases should return the same value.
  526. case TBS_ONE_MINUS_PREV_COLOR:
  527. case TBS_ONE_MINUS_TEX_COLOR:
  528. case TBS_ONE_MINUS_VERT_COLOR:
  529. case TBS_ONE_MINUS_CONST_COLOR:
  530. return (isAlpha) ? GL_ONE_MINUS_SRC_ALPHA : GL_ONE_MINUS_SRC_COLOR;
  531. // All four cases should return the same value.
  532. case TBS_ONE_MINUS_PREV_ALPHA:
  533. case TBS_ONE_MINUS_TEX_ALPHA:
  534. case TBS_ONE_MINUS_VERT_ALPHA:
  535. case TBS_ONE_MINUS_CONST_ALPHA:
  536. return GL_ONE_MINUS_SRC_ALPHA;
  537. default:
  538. llwarns << "Unknown eTextureBlendSrc: " << src << ". Using Source Color or Alpha instead." << llendl;
  539. return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR;
  540. }
  541. }
  542. void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha)
  543. {
  544. if (LLGLSLShader::sNoFixedFunction)
  545. { //register combiners do nothing when not using fixed function
  546. return;
  547. }
  548. if (mIndex < 0) return;
  549. activate();
  550. if (mCurrBlendType != TB_COMBINE || gGL.mDirty)
  551. {
  552. mCurrBlendType = TB_COMBINE;
  553. gGL.flush();
  554. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
  555. }
  556. // We want an early out, because this function does a LOT of stuff.
  557. if ( ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2))
  558. || (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2)) ) && !gGL.mDirty)
  559. {
  560. return;
  561. }
  562. gGL.flush();
  563. // Get the gl source enums according to the eTextureBlendSrc sources passed in
  564. GLint source1 = getTextureSource(src1);
  565. GLint source2 = getTextureSource(src2);
  566. // Get the gl operand enums according to the eTextureBlendSrc sources passed in
  567. GLint operand1 = getTextureSourceType(src1, isAlpha);
  568. GLint operand2 = getTextureSourceType(src2, isAlpha);
  569. // Default the scale amount to 1
  570. S32 scale_amount = 1;
  571. GLenum comb_enum, src0_enum, src1_enum, src2_enum, operand0_enum, operand1_enum, operand2_enum;
  572. if (isAlpha)
  573. {
  574. // Set enums to ALPHA ones
  575. comb_enum = GL_COMBINE_ALPHA_ARB;
  576. src0_enum = GL_SOURCE0_ALPHA_ARB;
  577. src1_enum = GL_SOURCE1_ALPHA_ARB;
  578. src2_enum = GL_SOURCE2_ALPHA_ARB;
  579. operand0_enum = GL_OPERAND0_ALPHA_ARB;
  580. operand1_enum = GL_OPERAND1_ALPHA_ARB;
  581. operand2_enum = GL_OPERAND2_ALPHA_ARB;
  582. // cache current combiner
  583. mCurrAlphaOp = op;
  584. mCurrAlphaSrc1 = src1;
  585. mCurrAlphaSrc2 = src2;
  586. }
  587. else
  588. {
  589. // Set enums to RGB ones
  590. comb_enum = GL_COMBINE_RGB_ARB;
  591. src0_enum = GL_SOURCE0_RGB_ARB;
  592. src1_enum = GL_SOURCE1_RGB_ARB;
  593. src2_enum = GL_SOURCE2_RGB_ARB;
  594. operand0_enum = GL_OPERAND0_RGB_ARB;
  595. operand1_enum = GL_OPERAND1_RGB_ARB;
  596. operand2_enum = GL_OPERAND2_RGB_ARB;
  597. // cache current combiner
  598. mCurrColorOp = op;
  599. mCurrColorSrc1 = src1;
  600. mCurrColorSrc2 = src2;
  601. }
  602. switch(op)
  603. {
  604. case TBO_REPLACE:
  605. // Slightly special syntax (no second sources), just set all and return.
  606. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE);
  607. glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1);
  608. glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1);
  609. (isAlpha) ? setAlphaScale(1) : setColorScale(1);
  610. return;
  611. case TBO_MULT:
  612. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE);
  613. break;
  614. case TBO_MULT_X2:
  615. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE);
  616. scale_amount = 2;
  617. break;
  618. case TBO_MULT_X4:
  619. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE);
  620. scale_amount = 4;
  621. break;
  622. case TBO_ADD:
  623. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD);
  624. break;
  625. case TBO_ADD_SIGNED:
  626. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD_SIGNED_ARB);
  627. break;
  628. case TBO_SUBTRACT:
  629. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_SUBTRACT_ARB);
  630. break;
  631. case TBO_LERP_VERT_ALPHA:
  632. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
  633. glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR_ARB);
  634. glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA);
  635. break;
  636. case TBO_LERP_TEX_ALPHA:
  637. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
  638. glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_TEXTURE);
  639. glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA);
  640. break;
  641. case TBO_LERP_PREV_ALPHA:
  642. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
  643. glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PREVIOUS_ARB);
  644. glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA);
  645. break;
  646. case TBO_LERP_CONST_ALPHA:
  647. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
  648. glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_CONSTANT_ARB);
  649. glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA);
  650. break;
  651. case TBO_LERP_VERT_COLOR:
  652. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
  653. glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR_ARB);
  654. glTexEnvi(GL_TEXTURE_ENV, operand2_enum, (isAlpha) ? GL_SRC_ALPHA : GL_SRC_COLOR);
  655. break;
  656. default:
  657. llwarns << "Unknown eTextureBlendOp: " << op << ". Setting op to replace." << llendl;
  658. // Slightly special syntax (no second sources), just set all and return.
  659. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE);
  660. glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1);
  661. glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1);
  662. (isAlpha) ? setAlphaScale(1) : setColorScale(1);
  663. return;
  664. }
  665. // Set sources, operands, and scale accordingly
  666. glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1);
  667. glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1);
  668. glTexEnvi(GL_TEXTURE_ENV, src1_enum, source2);
  669. glTexEnvi(GL_TEXTURE_ENV, operand1_enum, operand2);
  670. (isAlpha) ? setAlphaScale(scale_amount) : setColorScale(scale_amount);
  671. }
  672. void LLTexUnit::setColorScale(S32 scale)
  673. {
  674. if (mCurrColorScale != scale || gGL.mDirty)
  675. {
  676. mCurrColorScale = scale;
  677. gGL.flush();
  678. glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale );
  679. }
  680. }
  681. void LLTexUnit::setAlphaScale(S32 scale)
  682. {
  683. if (mCurrAlphaScale != scale || gGL.mDirty)
  684. {
  685. mCurrAlphaScale = scale;
  686. gGL.flush();
  687. glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale );
  688. }
  689. }
  690. // Useful for debugging that you've manually assigned a texture operation to the correct
  691. // texture unit based on the currently set active texture in opengl.
  692. void LLTexUnit::debugTextureUnit(void)
  693. {
  694. if (mIndex < 0) return;
  695. GLint activeTexture;
  696. glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
  697. if ((GL_TEXTURE0_ARB + mIndex) != activeTexture)
  698. {
  699. U32 set_unit = (activeTexture - GL_TEXTURE0_ARB);
  700. llwarns << "Incorrect Texture Unit! Expected: " << set_unit << " Actual: " << mIndex << llendl;
  701. }
  702. }
  703. LLLightState::LLLightState(S32 index)
  704. : mIndex(index),
  705. mEnabled(false),
  706. mConstantAtten(1.f),
  707. mLinearAtten(0.f),
  708. mQuadraticAtten(0.f),
  709. mSpotExponent(0.f),
  710. mSpotCutoff(180.f)
  711. {
  712. if (mIndex == 0)
  713. {
  714. mDiffuse.set(1,1,1,1);
  715. mSpecular.set(1,1,1,1);
  716. }
  717. mAmbient.set(0,0,0,1);
  718. mPosition.set(0,0,1,0);
  719. mSpotDirection.set(0,0,-1);
  720. }
  721. void LLLightState::enable()
  722. {
  723. if (!mEnabled)
  724. {
  725. if (!LLGLSLShader::sNoFixedFunction)
  726. {
  727. glEnable(GL_LIGHT0+mIndex);
  728. }
  729. mEnabled = true;
  730. }
  731. }
  732. void LLLightState::disable()
  733. {
  734. if (mEnabled)
  735. {
  736. if (!LLGLSLShader::sNoFixedFunction)
  737. {
  738. glDisable(GL_LIGHT0+mIndex);
  739. }
  740. mEnabled = false;
  741. }
  742. }
  743. void LLLightState::setDiffuse(const LLColor4& diffuse)
  744. {
  745. if (mDiffuse != diffuse)
  746. {
  747. ++gGL.mLightHash;
  748. mDiffuse = diffuse;
  749. if (!LLGLSLShader::sNoFixedFunction)
  750. {
  751. glLightfv(GL_LIGHT0+mIndex, GL_DIFFUSE, mDiffuse.mV);
  752. }
  753. }
  754. }
  755. void LLLightState::setAmbient(const LLColor4& ambient)
  756. {
  757. if (mAmbient != ambient)
  758. {
  759. ++gGL.mLightHash;
  760. mAmbient = ambient;
  761. if (!LLGLSLShader::sNoFixedFunction)
  762. {
  763. glLightfv(GL_LIGHT0+mIndex, GL_AMBIENT, mAmbient.mV);
  764. }
  765. }
  766. }
  767. void LLLightState::setSpecular(const LLColor4& specular)
  768. {
  769. if (mSpecular != specular)
  770. {
  771. ++gGL.mLightHash;
  772. mSpecular = specular;
  773. if (!LLGLSLShader::sNoFixedFunction)
  774. {
  775. glLightfv(GL_LIGHT0+mIndex, GL_SPECULAR, mSpecular.mV);
  776. }
  777. }
  778. }
  779. void LLLightState::setPosition(const LLVector4& position)
  780. {
  781. //always set position because modelview matrix may have changed
  782. ++gGL.mLightHash;
  783. mPosition = position;
  784. if (!LLGLSLShader::sNoFixedFunction)
  785. {
  786. glLightfv(GL_LIGHT0+mIndex, GL_POSITION, mPosition.mV);
  787. }
  788. else
  789. { //transform position by current modelview matrix
  790. glh::vec4f pos(position.mV);
  791. const glh::matrix4f& mat = gGL.getModelviewMatrix();
  792. mat.mult_matrix_vec(pos);
  793. mPosition.set(pos.v);
  794. }
  795. }
  796. void LLLightState::setConstantAttenuation(const F32& atten)
  797. {
  798. if (mConstantAtten != atten)
  799. {
  800. mConstantAtten = atten;
  801. ++gGL.mLightHash;
  802. if (!LLGLSLShader::sNoFixedFunction)
  803. {
  804. glLightf(GL_LIGHT0+mIndex, GL_CONSTANT_ATTENUATION, atten);
  805. }
  806. }
  807. }
  808. void LLLightState::setLinearAttenuation(const F32& atten)
  809. {
  810. if (mLinearAtten != atten)
  811. {
  812. ++gGL.mLightHash;
  813. mLinearAtten = atten;
  814. if (!LLGLSLShader::sNoFixedFunction)
  815. {
  816. glLightf(GL_LIGHT0+mIndex, GL_LINEAR_ATTENUATION, atten);
  817. }
  818. }
  819. }
  820. void LLLightState::setQuadraticAttenuation(const F32& atten)
  821. {
  822. if (mQuadraticAtten != atten)
  823. {
  824. ++gGL.mLightHash;
  825. mQuadraticAtten = atten;
  826. if (!LLGLSLShader::sNoFixedFunction)
  827. {
  828. glLightf(GL_LIGHT0+mIndex, GL_QUADRATIC_ATTENUATION, atten);
  829. }
  830. }
  831. }
  832. void LLLightState::setSpotExponent(const F32& exponent)
  833. {
  834. if (mSpotExponent != exponent)
  835. {
  836. ++gGL.mLightHash;
  837. mSpotExponent = exponent;
  838. if (!LLGLSLShader::sNoFixedFunction)
  839. {
  840. glLightf(GL_LIGHT0+mIndex, GL_SPOT_EXPONENT, exponent);
  841. }
  842. }
  843. }
  844. void LLLightState::setSpotCutoff(const F32& cutoff)
  845. {
  846. if (mSpotCutoff != cutoff)
  847. {
  848. ++gGL.mLightHash;
  849. mSpotCutoff = cutoff;
  850. if (!LLGLSLShader::sNoFixedFunction)
  851. {
  852. glLightf(GL_LIGHT0+mIndex, GL_SPOT_CUTOFF, cutoff);
  853. }
  854. }
  855. }
  856. void LLLightState::setSpotDirection(const LLVector3& direction)
  857. {
  858. //always set direction because modelview matrix may have changed
  859. ++gGL.mLightHash;
  860. mSpotDirection = direction;
  861. if (!LLGLSLShader::sNoFixedFunction)
  862. {
  863. glLightfv(GL_LIGHT0+mIndex, GL_SPOT_DIRECTION, direction.mV);
  864. }
  865. else
  866. { //transform direction by current modelview matrix
  867. glh::vec3f dir(direction.mV);
  868. const glh::matrix4f& mat = gGL.getModelviewMatrix();
  869. mat.mult_matrix_dir(dir);
  870. mSpotDirection.set(direction);
  871. }
  872. }
  873. LLRender::LLRender()
  874. : mDirty(false),
  875. mCount(0),
  876. mQuadCycle(0),
  877. mMode(LLRender::TRIANGLES),
  878. mCurrTextureUnitIndex(0),
  879. mMaxAnisotropy(0.f)
  880. {
  881. mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS);
  882. for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++)
  883. {
  884. mTexUnits.push_back(new LLTexUnit(i));
  885. }
  886. mDummyTexUnit = new LLTexUnit(-1);
  887. for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; ++i)
  888. {
  889. mLightState.push_back(new LLLightState(i));
  890. }
  891. for (U32 i = 0; i < 4; i++)
  892. {
  893. mCurrColorMask[i] = true;
  894. }
  895. mCurrAlphaFunc = CF_DEFAULT;
  896. mCurrAlphaFuncVal = 0.01f;
  897. mCurrBlendColorSFactor = BF_UNDEF;
  898. mCurrBlendAlphaSFactor = BF_UNDEF;
  899. mCurrBlendColorDFactor = BF_UNDEF;
  900. mCurrBlendAlphaDFactor = BF_UNDEF;
  901. mMatrixMode = LLRender::MM_MODELVIEW;
  902. for (U32 i = 0; i < NUM_MATRIX_MODES; ++i)
  903. {
  904. mMatIdx[i] = 0;
  905. mMatHash[i] = 0;
  906. mCurMatHash[i] = 0xFFFFFFFF;
  907. }
  908. mLightHash = 0;
  909. }
  910. LLRender::~LLRender()
  911. {
  912. shutdown();
  913. }
  914. void LLRender::init()
  915. {
  916. llassert_always(mBuffer.isNull()) ;
  917. stop_glerror();
  918. mBuffer = new LLVertexBuffer(immediate_mask, 0);
  919. mBuffer->allocateBuffer(4096, 0, TRUE);
  920. mBuffer->getVertexStrider(mVerticesp);
  921. mBuffer->getTexCoord0Strider(mTexcoordsp);
  922. mBuffer->getColorStrider(mColorsp);
  923. stop_glerror();
  924. }
  925. void LLRender::shutdown()
  926. {
  927. for (U32 i = 0; i < mTexUnits.size(); i++)
  928. {
  929. delete mTexUnits[i];
  930. }
  931. mTexUnits.clear();
  932. delete mDummyTexUnit;
  933. mDummyTexUnit = NULL;
  934. for (U32 i = 0; i < mLightState.size(); ++i)
  935. {
  936. delete mLightState[i];
  937. }
  938. mLightState.clear();
  939. mBuffer = NULL ;
  940. }
  941. void LLRender::refreshState(void)
  942. {
  943. mDirty = true;
  944. U32 active_unit = mCurrTextureUnitIndex;
  945. for (U32 i = 0; i < mTexUnits.size(); i++)
  946. {
  947. mTexUnits[i]->refreshState();
  948. }
  949. mTexUnits[active_unit]->activate();
  950. setColorMask(mCurrColorMask[0], mCurrColorMask[1], mCurrColorMask[2], mCurrColorMask[3]);
  951. setAlphaRejectSettings(mCurrAlphaFunc, mCurrAlphaFuncVal);
  952. mDirty = false;
  953. }
  954. void LLRender::syncLightState()
  955. {
  956. LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
  957. if (!shader)
  958. {
  959. return;
  960. }
  961. if (shader->mLightHash != mLightHash)
  962. {
  963. shader->mLightHash = mLightHash;
  964. LLVector4 position[8];
  965. LLVector3 direction[8];
  966. LLVector3 attenuation[8];
  967. LLVector3 diffuse[8];
  968. for (U32 i = 0; i < 8; i++)
  969. {
  970. LLLightState* light = mLightState[i];
  971. position[i] = light->mPosition;
  972. direction[i] = light->mSpotDirection;
  973. attenuation[i].set(light->mLinearAtten, light->mQuadraticAtten, light->mSpecular.mV[3]);
  974. diffuse[i].set(light->mDiffuse.mV);
  975. }
  976. shader->uniform4fv(LLShaderMgr::LIGHT_POSITION, 8, position[0].mV);
  977. shader->uniform3fv(LLShaderMgr::LIGHT_DIRECTION, 8, direction[0].mV);
  978. shader->uniform3fv(LLShaderMgr::LIGHT_ATTENUATION, 8, attenuation[0].mV);
  979. shader->uniform3fv(LLShaderMgr::LIGHT_DIFFUSE, 8, diffuse[0].mV);
  980. shader->uniform4fv(LLShaderMgr::LIGHT_AMBIENT, 1, mAmbientLightColor.mV);
  981. //HACK -- duplicate sunlight color for compatibility with drivers that can't deal with multiple shader objects referencing the same uniform
  982. shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, diffuse[0].mV);
  983. }
  984. }
  985. void LLRender::syncMatrices()
  986. {
  987. stop_glerror();
  988. U32 name[] =
  989. {
  990. LLShaderMgr::MODELVIEW_MATRIX,
  991. LLShaderMgr::PROJECTION_MATRIX,
  992. LLShaderMgr::TEXTURE_MATRIX0,
  993. LLShaderMgr::TEXTURE_MATRIX1,
  994. LLShaderMgr::TEXTURE_MATRIX2,
  995. LLShaderMgr::TEXTURE_MATRIX3,
  996. };
  997. LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
  998. static glh::matrix4f cached_mvp;
  999. static U32 cached_mvp_mdv_hash = 0xFFFFFFFF;
  1000. static U32 cached_mvp_proj_hash = 0xFFFFFFFF;
  1001. static glh::matrix4f cached_normal;
  1002. static U32 cached_normal_hash = 0xFFFFFFFF;
  1003. if (shader)
  1004. {
  1005. llassert(shader);
  1006. bool mvp_done = false;
  1007. U32 i = MM_MODELVIEW;
  1008. if (mMatHash[i] != shader->mMatHash[i])
  1009. { //update modelview, normal, and MVP
  1010. glh::matrix4f& mat = mMatrix[i][mMatIdx[i]];
  1011. shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.m);
  1012. shader->mMatHash[i] = mMatHash[i];
  1013. //update normal matrix
  1014. S32 loc = shader->getUniformLocation(LLShaderMgr::NORMAL_MATRIX);
  1015. if (loc > -1)
  1016. {
  1017. if (cached_normal_hash != mMatHash[i])
  1018. {
  1019. cached_normal = mat.inverse().transpose();
  1020. cached_normal_hash = mMatHash[i];
  1021. }
  1022. glh::matrix4f& norm = cached_normal;
  1023. F32 norm_mat[] =
  1024. {
  1025. norm.m[0], norm.m[1], norm.m[2],
  1026. norm.m[4], norm.m[5], norm.m[6],
  1027. norm.m[8], norm.m[9], norm.m[10]
  1028. };
  1029. shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norm_mat);
  1030. }
  1031. //update MVP matrix
  1032. mvp_done = true;
  1033. loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX);
  1034. if (loc > -1)
  1035. {
  1036. U32 proj = MM_PROJECTION;
  1037. if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
  1038. {
  1039. cached_mvp = mat;
  1040. cached_mvp.mult_left(mMatrix[proj][mMatIdx[proj]]);
  1041. cached_mvp_mdv_hash = mMatHash[i];
  1042. cached_mvp_proj_hash = mMatHash[MM_PROJECTION];
  1043. }
  1044. shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m);
  1045. }
  1046. }
  1047. i = MM_PROJECTION;
  1048. if (mMatHash[i] != shader->mMatHash[i])
  1049. { //update projection matrix, normal, and MVP
  1050. glh::matrix4f& mat = mMatrix[i][mMatIdx[i]];
  1051. shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mat.m);
  1052. shader->mMatHash[i] = mMatHash[i];
  1053. if (!mvp_done)
  1054. {
  1055. //update MVP matrix
  1056. S32 loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX);
  1057. if (loc > -1)
  1058. {
  1059. if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
  1060. {
  1061. U32 mdv = MM_MODELVIEW;
  1062. cached_mvp = mat;
  1063. cached_mvp.mult_right(mMatrix[mdv][mMatIdx[mdv]]);
  1064. cached_mvp_mdv_hash = mMatHash[MM_MODELVIEW];
  1065. cached_mvp_proj_hash = mMatHash[MM_PROJECTION];
  1066. }
  1067. shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m);
  1068. }
  1069. }
  1070. }
  1071. for (i = MM_TEXTURE0; i < NUM_MATRIX_MODES; ++i)
  1072. {
  1073. if (mMatHash[i] != shader->mMatHash[i])
  1074. {
  1075. shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mMatrix[i][mMatIdx[i]].m);
  1076. shader->mMatHash[i] = mMatHash[i];
  1077. }
  1078. }
  1079. if (shader->mFeatures.hasLighting || shader->mFeatures.calculatesLighting)
  1080. { //also sync light state
  1081. syncLightState();
  1082. }
  1083. }
  1084. else if (!LLGLSLShader::sNoFixedFunction)
  1085. {
  1086. GLenum mode[] =
  1087. {
  1088. GL_MODELVIEW,
  1089. GL_PROJECTION,
  1090. GL_TEXTURE,
  1091. GL_TEXTURE,
  1092. GL_TEXTURE,
  1093. GL_TEXTURE,
  1094. };
  1095. for (U32 i = 0; i < 2; ++i)
  1096. {
  1097. if (mMatHash[i] != mCurMatHash[i])
  1098. {
  1099. glMatrixMode(mode[i]);
  1100. glLoadMatrixf(mMatrix[i][mMatIdx[i]].m);
  1101. mCurMatHash[i] = mMatHash[i];
  1102. }
  1103. }
  1104. for (U32 i = 2; i < NUM_MATRIX_MODES; ++i)
  1105. {
  1106. if (mMatHash[i] != mCurMatHash[i])
  1107. {
  1108. gGL.getTexUnit(i-2)->activate();
  1109. glMatrixMode(mode[i]);
  1110. glLoadMatrixf(mMatrix[i][mMatIdx[i]].m);
  1111. mCurMatHash[i] = mMatHash[i];
  1112. }
  1113. }
  1114. }
  1115. stop_glerror();
  1116. }
  1117. void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
  1118. {
  1119. flush();
  1120. {
  1121. glh::matrix4f trans_mat(1,0,0,x,
  1122. 0,1,0,y,
  1123. 0,0,1,z,
  1124. 0,0,0,1);
  1125. mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(trans_mat);
  1126. mMatHash[mMatrixMode]++;
  1127. }
  1128. }
  1129. void LLRender::scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
  1130. {
  1131. flush();
  1132. {
  1133. glh::matrix4f scale_mat(x,0,0,0,
  1134. 0,y,0,0,
  1135. 0,0,z,0,
  1136. 0,0,0,1);
  1137. mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(scale_mat);
  1138. mMatHash[mMatrixMode]++;
  1139. }
  1140. }
  1141. void LLRender::ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar)
  1142. {
  1143. flush();
  1144. {
  1145. glh::matrix4f ortho_mat(2.f/(right-left),0,0, -(right+left)/(right-left),
  1146. 0,2.f/(top-bottom),0, -(top+bottom)/(top-bottom),
  1147. 0,0,-2.f/(zFar-zNear), -(zFar+zNear)/(zFar-zNear),
  1148. 0,0,0,1);
  1149. mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(ortho_mat);
  1150. mMatHash[mMatrixMode]++;
  1151. }
  1152. }
  1153. void LLRender::rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z)
  1154. {
  1155. flush();
  1156. {
  1157. F32 r = a * DEG_TO_RAD;
  1158. F32 c = cosf(r);
  1159. F32 s = sinf(r);
  1160. F32 ic = 1.f-c;
  1161. glh::matrix4f rot_mat(x*x*ic+c, x*y*ic-z*s, x*z*ic+y*s, 0,
  1162. x*y*ic+z*s, y*y*ic+c, y*z*ic-x*s, 0,
  1163. x*z*ic-y*s, y*z*ic+x*s, z*z*ic+c, 0,
  1164. 0,0,0,1);
  1165. mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(rot_mat);
  1166. mMatHash[mMatrixMode]++;
  1167. }
  1168. }
  1169. void LLRender::pushMatrix()
  1170. {
  1171. flush();
  1172. {
  1173. if (mMatIdx[mMatrixMode] < LL_MATRIX_STACK_DEPTH-1)
  1174. {
  1175. mMatrix[mMatrixMode][mMatIdx[mMatrixMode]+1] = mMatrix[mMatrixMode][mMatIdx[mMatrixMode]];
  1176. ++mMatIdx[mMatrixMode];
  1177. }
  1178. else
  1179. {
  1180. llwarns << "Matrix stack overflow." << llendl;
  1181. }
  1182. }
  1183. }
  1184. void LLRender::popMatrix()
  1185. {
  1186. flush();
  1187. {
  1188. if (mMatIdx[mMatrixMode] > 0)
  1189. {
  1190. --mMatIdx[mMatrixMode];
  1191. mMatHash[mMatrixMode]++;
  1192. }
  1193. else
  1194. {
  1195. llwarns << "Matrix stack underflow." << llendl;
  1196. }
  1197. }
  1198. }
  1199. void LLRender::loadMatrix(const GLfloat* m)
  1200. {
  1201. flush();
  1202. {
  1203. mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].set_value((GLfloat*) m);
  1204. mMatHash[mMatrixMode]++;
  1205. }
  1206. }
  1207. void LLRender::multMatrix(const GLfloat* m)
  1208. {
  1209. flush();
  1210. {
  1211. glh::matrix4f mat((GLfloat*) m);
  1212. mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(mat);
  1213. mMatHash[mMatrixMode]++;
  1214. }
  1215. }
  1216. void LLRender::matrixMode(U32 mode)
  1217. {
  1218. if (mode == MM_TEXTURE)
  1219. {
  1220. mode = MM_TEXTURE0 + gGL.getCurrentTexUnitIndex();
  1221. }
  1222. llassert(mode < NUM_MATRIX_MODES);
  1223. mMatrixMode = mode;
  1224. }
  1225. void LLRender::loadIdentity()
  1226. {
  1227. flush();
  1228. {
  1229. llassert_always(mMatrixMode < NUM_MATRIX_MODES) ;
  1230. mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity();
  1231. mMatHash[mMatrixMode]++;
  1232. }
  1233. }
  1234. const glh::matrix4f& LLRender::getModelviewMatrix()
  1235. {
  1236. return mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]];
  1237. }
  1238. const glh::matrix4f& LLRender::getProjectionMatrix()
  1239. {
  1240. return mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]];
  1241. }
  1242. void LLRender::translateUI(F32 x, F32 y, F32 z)
  1243. {
  1244. if (mUIOffset.empty())
  1245. {
  1246. llerrs << "Need to push a UI translation frame before offsetting" << llendl;
  1247. }
  1248. mUIOffset.back().mV[0] += x;
  1249. mUIOffset.back().mV[1] += y;
  1250. mUIOffset.back().mV[2] += z;
  1251. }
  1252. void LLRender::scaleUI(F32 x, F32 y, F32 z)
  1253. {
  1254. if (mUIScale.empty())
  1255. {
  1256. llerrs << "Need to push a UI transformation frame before scaling." << llendl;
  1257. }
  1258. mUIScale.back().scaleVec(LLVector3(x,y,z));
  1259. }
  1260. void LLRender::pushUIMatrix()
  1261. {
  1262. if (mUIOffset.empty())
  1263. {
  1264. mUIOffset.push_back(LLVector3(0,0,0));
  1265. }
  1266. else
  1267. {
  1268. mUIOffset.push_back(mUIOffset.back());
  1269. }
  1270. if (mUIScale.empty())
  1271. {
  1272. mUIScale.push_back(LLVector3(1,1,1));
  1273. }
  1274. else
  1275. {
  1276. mUIScale.push_back(mUIScale.back());
  1277. }
  1278. }
  1279. void LLRender::popUIMatrix()
  1280. {
  1281. if (mUIOffset.empty())
  1282. {
  1283. llerrs << "UI offset stack blown." << llendl;
  1284. }
  1285. mUIOffset.pop_back();
  1286. mUIScale.pop_back();
  1287. }
  1288. LLVector3 LLRender::getUITranslation()
  1289. {
  1290. if (mUIOffset.empty())
  1291. {
  1292. return LLVector3(0,0,0);
  1293. }
  1294. return mUIOffset.back();
  1295. }
  1296. LLVector3 LLRender::getUIScale()
  1297. {
  1298. if (mUIScale.empty())
  1299. {
  1300. return LLVector3(1,1,1);
  1301. }
  1302. return mUIScale.back();
  1303. }
  1304. void LLRender::loadUIIdentity()
  1305. {
  1306. if (mUIOffset.empty())
  1307. {
  1308. llerrs << "Need to push UI translation frame before clearing offset." << llendl;
  1309. }
  1310. mUIOffset.back().setVec(0,0,0);
  1311. mUIScale.back().setVec(1,1,1);
  1312. }
  1313. void LLRender::setColorMask(bool writeColor, bool writeAlpha)
  1314. {
  1315. setColorMask(writeColor, writeColor, writeColor, writeAlpha);
  1316. }
  1317. void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha)
  1318. {
  1319. flush();
  1320. if (mCurrColorMask[0] != writeColorR ||
  1321. mCurrColorMask[1] != writeColorG ||
  1322. mCurrColorMask[2] != writeColorB ||
  1323. mCurrColorMask[3] != writeAlpha)
  1324. {
  1325. mCurrColorMask[0] = writeColorR;
  1326. mCurrColorMask[1] = writeColorG;
  1327. mCurrColorMask[2] = writeColorB;
  1328. mCurrColorMask[3] = writeAlpha;
  1329. glColorMask(writeColorR ? GL_TRUE : GL_FALSE,
  1330. writeColorG ? GL_TRUE : GL_FALSE,
  1331. writeColorB ? GL_TRUE : GL_FALSE,
  1332. writeAlpha ? GL_TRUE : GL_FALSE);
  1333. }
  1334. }
  1335. void LLRender::setSceneBlendType(eBlendType type)
  1336. {
  1337. switch (type)
  1338. {
  1339. case BT_ALPHA:
  1340. blendFunc(BF_SOURCE_ALPHA, BF_ONE_MINUS_SOURCE_ALPHA);
  1341. break;
  1342. case BT_ADD:
  1343. blendFunc(BF_ONE, BF_ONE);
  1344. break;
  1345. case BT_ADD_WITH_ALPHA:
  1346. blendFunc(BF_SOURCE_ALPHA, BF_ONE);
  1347. break;
  1348. case BT_MULT:
  1349. blendFunc(BF_DEST_COLOR, BF_ZERO);
  1350. break;
  1351. case BT_MULT_ALPHA:
  1352. blendFunc(BF_DEST_ALPHA, BF_ZERO);
  1353. break;
  1354. case BT_MULT_X2:
  1355. blendFunc(BF_DEST_COLOR, BF_SOURCE_COLOR);
  1356. break;
  1357. case BT_REPLACE:
  1358. blendFunc(BF_ONE, BF_ZERO);
  1359. break;
  1360. default:
  1361. llerrs << "Unknown Scene Blend Type: " << type << llendl;
  1362. break;
  1363. }
  1364. }
  1365. void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value)
  1366. {
  1367. flush();
  1368. if (LLGLSLShader::sNoFixedFunction)
  1369. { //glAlphaFunc is deprecated in OpenGL 3.3
  1370. return;
  1371. }
  1372. if (mCurrAlphaFunc != func ||
  1373. mCurrAlphaFuncVal != value)
  1374. {
  1375. mCurrAlphaFunc = func;
  1376. mCurrAlphaFuncVal = value;
  1377. if (func == CF_DEFAULT)
  1378. {
  1379. glAlphaFunc(GL_GREATER, 0.01f);
  1380. }
  1381. else
  1382. {
  1383. glAlphaFunc(sGLCompareFunc[func], value);
  1384. }
  1385. }
  1386. if (gDebugGL)
  1387. { //make sure cached state is correct
  1388. GLint cur_func = 0;
  1389. glGetIntegerv(GL_ALPHA_TEST_FUNC, &cur_func);
  1390. if (func == CF_DEFAULT)
  1391. {
  1392. func = CF_GREATER;
  1393. }
  1394. if (cur_func != sGLCompareFunc[func])
  1395. {
  1396. llerrs << "Alpha test function corrupted!" << llendl;
  1397. }
  1398. F32 ref = 0.f;
  1399. glGetFloatv(GL_ALPHA_TEST_REF, &ref);
  1400. if (ref != value)
  1401. {
  1402. llerrs << "Alpha test value corrupted!" << llendl;
  1403. }
  1404. }
  1405. }
  1406. void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
  1407. {
  1408. llassert(sfactor < BF_UNDEF);
  1409. llassert(dfactor < BF_UNDEF);
  1410. if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor ||
  1411. mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor)
  1412. {
  1413. mCurrBlendColorSFactor = sfactor;
  1414. mCurrBlendAlphaSFactor = sfactor;
  1415. mCurrBlendColorDFactor = dfactor;
  1416. mCurrBlendAlphaDFactor = dfactor;
  1417. flush();
  1418. glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]);
  1419. }
  1420. }
  1421. void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
  1422. eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor)
  1423. {
  1424. llassert(color_sfactor < BF_UNDEF);
  1425. llassert(color_dfactor < BF_UNDEF);
  1426. llassert(alpha_sfactor < BF_UNDEF);
  1427. llassert(alpha_dfactor < BF_UNDEF);
  1428. if (!gGLManager.mHasBlendFuncSeparate)
  1429. {
  1430. LL_WARNS_ONCE("render") << "no glBlendFuncSeparateEXT(), using color-only blend func" << llendl;
  1431. blendFunc(color_sfactor, color_dfactor);
  1432. return;
  1433. }
  1434. if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor ||
  1435. mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor)
  1436. {
  1437. mCurrBlendColorSFactor = color_sfactor;
  1438. mCurrBlendAlphaSFactor = alpha_sfactor;
  1439. mCurrBlendColorDFactor = color_dfactor;
  1440. mCurrBlendAlphaDFactor = alpha_dfactor;
  1441. flush();
  1442. glBlendFuncSeparateEXT(sGLBlendFactor[color_sfactor], sGLBlendFactor[color_dfactor],
  1443. sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]);
  1444. }
  1445. }
  1446. LLTexUnit* LLRender::getTexUnit(U32 index)
  1447. {
  1448. if (index < mTexUnits.size())
  1449. {
  1450. return mTexUnits[index];
  1451. }
  1452. else
  1453. {
  1454. lldebugs << "Non-existing texture unit layer requested: " << index << llendl;
  1455. return mDummyTexUnit;
  1456. }
  1457. }
  1458. LLLightState* LLRender::getLight(U32 index)
  1459. {
  1460. if (index < mLightState.size())
  1461. {
  1462. return mLightState[index];
  1463. }
  1464. return NULL;
  1465. }
  1466. void LLRender::setAmbientLightColor(const LLColor4& color)
  1467. {
  1468. if (color != mAmbientLightColor)
  1469. {
  1470. ++mLightHash;
  1471. mAmbientLightColor = color;
  1472. if (!LLGLSLShader::sNoFixedFunction)
  1473. {
  1474. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, color.mV);
  1475. }
  1476. }
  1477. }
  1478. bool LLRender::verifyTexUnitActive(U32 unitToVerify)
  1479. {
  1480. if (mCurrTextureUnitIndex == unitToVerify)
  1481. {
  1482. return true;
  1483. }
  1484. else
  1485. {
  1486. llwarns << "TexUnit currently active: " << mCurrTextureUnitIndex << " (expecting " << unitToVerify << ")" << llendl;
  1487. return false;
  1488. }
  1489. }
  1490. void LLRender::clearErrors()
  1491. {
  1492. while (glGetError())
  1493. {
  1494. //loop until no more error flags left
  1495. }
  1496. }
  1497. void LLRender::begin(const GLuint& mode)
  1498. {
  1499. if (mode != mMode)
  1500. {
  1501. if (mode == LLRender::QUADS)
  1502. {
  1503. mQuadCycle = 1;
  1504. }
  1505. if (mMode == LLRender::QUADS ||
  1506. mMode == LLRender::LINES ||
  1507. mMode == LLRender::TRIANGLES ||
  1508. mMode == LLRender::POINTS)
  1509. {
  1510. flush();
  1511. }
  1512. else if (mCount != 0)
  1513. {
  1514. llerrs << "gGL.begin() called redundantly." << llendl;
  1515. }
  1516. mMode = mode;
  1517. }
  1518. }
  1519. void LLRender::end()
  1520. {
  1521. if (mCount == 0)
  1522. {
  1523. return;
  1524. //IMM_ERRS << "GL begin and end called with no vertices specified." << llendl;
  1525. }
  1526. if ((mMode != LLRender::QUADS &&
  1527. mMode != LLRender::LINES &&
  1528. mMode != LLRender::TRIANGLES &&
  1529. mMode != LLRender::POINTS) ||
  1530. mCount > 2048)
  1531. {
  1532. flush();
  1533. }
  1534. }
  1535. void LLRender::flush()
  1536. {
  1537. if (mCount > 0)
  1538. {
  1539. #if 0
  1540. if (!glIsEnabled(GL_VERTEX_ARRAY))
  1541. {
  1542. llerrs << "foo 1" << llendl;
  1543. }
  1544. if (!glIsEnabled(GL_COLOR_ARRAY))
  1545. {
  1546. llerrs << "foo 2" << llendl;
  1547. }
  1548. if (!glIsEnabled(GL_TEXTURE_COORD_ARRAY))
  1549. {
  1550. llerrs << "foo 3" << llendl;
  1551. }
  1552. if (glIsEnabled(GL_NORMAL_ARRAY))
  1553. {
  1554. llerrs << "foo 7" << llendl;
  1555. }
  1556. GLvoid* pointer;
  1557. glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer);
  1558. if (pointer != &(mBuffer[0].v))
  1559. {
  1560. llerrs << "foo 4" << llendl;
  1561. }
  1562. glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer);
  1563. if (pointer != &(mBuffer[0].c))
  1564. {
  1565. llerrs << "foo 5" << llendl;
  1566. }
  1567. glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer);
  1568. if (pointer != &(mBuffer[0].uv))
  1569. {
  1570. llerrs << "foo 6" << llendl;
  1571. }
  1572. #endif
  1573. if (!mUIOffset.empty())
  1574. {
  1575. sUICalls++;
  1576. sUIVerts += mCount;
  1577. }
  1578. if (gDebugGL)
  1579. {
  1580. if (mMode == LLRender::QUADS && !sGLCoreProfile)
  1581. {
  1582. if (mCount%4 != 0)
  1583. {
  1584. llerrs << "Incomplete quad rendered." << llendl;
  1585. }
  1586. }
  1587. if (mMode == LLRender::TRIANGLES)
  1588. {
  1589. if (mCount%3 != 0)
  1590. {
  1591. llerrs << "Incomplete triangle rendered." << llendl;
  1592. }
  1593. }
  1594. if (mMode == LLRender::LINES)
  1595. {
  1596. if (mCount%2 != 0)
  1597. {
  1598. llerrs << "Incomplete line rendered." << llendl;
  1599. }
  1600. }
  1601. }
  1602. //store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
  1603. U32 count = mCount;
  1604. mCount = 0;
  1605. if (mBuffer->useVBOs() && !mBuffer->isLocked())
  1606. { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata)
  1607. mBuffer->getVertexStrider(mVerticesp, 0, count);
  1608. mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count);
  1609. mBuffer->getColorStrider(mColorsp, 0, count);
  1610. }
  1611. mBuffer->flush();
  1612. mBuffer->setBuffer(immediate_mask);
  1613. if (mMode == LLRender::QUADS && sGLCoreProfile)
  1614. {
  1615. mBuffer->drawArrays(LLRender::TRIANGLES, 0, count);
  1616. mQuadCycle = 1;
  1617. }
  1618. else
  1619. {
  1620. mBuffer->drawArrays(mMode, 0, count);
  1621. }
  1622. mVerticesp[0] = mVerticesp[count];
  1623. mTexcoordsp[0] = mTexcoordsp[count];
  1624. mColorsp[0] = mColorsp[count];
  1625. mCount = 0;
  1626. }
  1627. }
  1628. void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
  1629. {
  1630. //the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095]
  1631. if (mCount > 2048)
  1632. { //break when buffer gets reasonably full to keep GL command buffers happy and avoid overflow below
  1633. switch (mMode)
  1634. {
  1635. case LLRender::POINTS: flush(); break;
  1636. case LLRender::TRIANGLES: if (mCount%3==0) flush(); break;
  1637. case LLRender::QUADS: if(mCount%4 == 0) flush(); break;
  1638. case LLRender::LINES: if (mCount%2 == 0) flush(); break;
  1639. }
  1640. }
  1641. if (mCount > 4094)
  1642. {
  1643. // llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl;
  1644. return;
  1645. }
  1646. if (mUIOffset.empty())
  1647. {
  1648. mVerticesp[mCount] = LLVector3(x,y,z);
  1649. }
  1650. else
  1651. {
  1652. LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back());
  1653. mVerticesp[mCount] = vert;
  1654. }
  1655. if (mMode == LLRender::QUADS && LLRender::sGLCoreProfile)
  1656. {
  1657. mQuadCycle++;
  1658. if (mQuadCycle == 4)
  1659. { //copy two vertices so fourth quad element will add a triangle
  1660. mQuadCycle = 0;
  1661. mCount++;
  1662. mVerticesp[mCount] = mVerticesp[mCount-3];
  1663. mColorsp[mCount] = mColorsp[mCount-3];
  1664. mTexcoordsp[mCount] = mTexcoordsp[mCount-3];
  1665. mCount++;
  1666. mVerticesp[mCount] = mVerticesp[mCount-2];
  1667. mColorsp[mCount] = mColorsp[mCount-2];
  1668. mTexcoordsp[mCount] = mTexcoordsp[mCount-2];
  1669. }
  1670. }
  1671. mCount++;
  1672. mVerticesp[mCount] = mVerticesp[mCount-1];
  1673. mColorsp[mCount] = mColorsp[mCount-1];
  1674. mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
  1675. }
  1676. void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count)
  1677. {
  1678. if (mCount + vert_count > 4094)
  1679. {
  1680. // llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl;
  1681. return;
  1682. }
  1683. if (sGLCoreProfile && mMode == LLRender::QUADS)
  1684. { //quads are deprecated, convert to triangle list
  1685. S32 i = 0;
  1686. while (i < vert_count)
  1687. {
  1688. //read first three
  1689. mVerticesp[mCount++] = verts[i++];
  1690. mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
  1691. mColorsp[mCount] = mColorsp[mCount-1];
  1692. mVerticesp[mCount++] = verts[i++];
  1693. mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
  1694. mColorsp[mCount] = mColorsp[mCount-1];
  1695. mVerticesp[mCount++] = verts[i++];
  1696. mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
  1697. mColorsp[mCount] = mColorsp[mCount-1];
  1698. //copy two
  1699. mVerticesp[mCount++] = verts[i-3];
  1700. mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
  1701. mColorsp[mCount] = mColorsp[mCount-1];
  1702. mVerticesp[mCount++] = verts[i-1];
  1703. mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
  1704. mColorsp[mCount] = mColorsp[mCount-1];
  1705. //copy last one
  1706. mVerticesp[mCount++] = verts[i++];
  1707. mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
  1708. mColorsp[mCount] = mColorsp[mCount-1];
  1709. }
  1710. }
  1711. else
  1712. {
  1713. for (S32 i = 0; i < vert_count; i++)
  1714. {
  1715. mVerticesp[mCount] = verts[i];
  1716. mCount++;
  1717. mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
  1718. mColorsp[mCount] = mColorsp[mCount-1];
  1719. }
  1720. }
  1721. mVerticesp[mCount] = mVerticesp[mCount-1];
  1722. }
  1723. void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count)
  1724. {
  1725. if (mCount + vert_count > 4094)
  1726. {
  1727. // llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl;
  1728. return;
  1729. }
  1730. if (sGLCoreProfile && mMode == LLRender::QUADS)
  1731. { //quads are deprecated, convert to triangle list
  1732. S32 i = 0;
  1733. while (i < vert_count)
  1734. {
  1735. //read first three
  1736. mVerticesp[mCount] = verts[i];
  1737. mTexcoordsp[mCount++] = uvs[i++];
  1738. mColorsp[mCount] = mColorsp[mCount-1];
  1739. mVerticesp[mCount] = verts[i];
  1740. mTexcoordsp[mCount++] = uvs[i++];
  1741. mColorsp[mCount] = mColorsp[mCount-1];
  1742. mVerticesp[mCount] = verts[i];
  1743. mTexcoordsp[mCount++] = uvs[i++];
  1744. mColorsp[mCount] = mColorsp[mCount-1];
  1745. //copy last two
  1746. mVerticesp[mCount] = verts[i-3];
  1747. mTexcoordsp[mCount++] = uvs[i-3];
  1748. mColorsp[mCount] = mColorsp[mCount-1];
  1749. mVerticesp[mCount] = verts[i-1];
  1750. mTexcoordsp[mCount++] = uvs[i-1];
  1751. mColorsp[mCount] = mColorsp[mCount-1];
  1752. //copy last one
  1753. mVerticesp[mCount] = verts[i];
  1754. mTexcoordsp[mCount++] = uvs[i++];
  1755. mColorsp[mCount] = mColorsp[mCount-1];
  1756. }
  1757. }
  1758. else
  1759. {
  1760. for (S32 i = 0; i < vert_count; i++)
  1761. {
  1762. mVerticesp[mCount] = verts[i];
  1763. mTexcoordsp[mCount] = uvs[i];
  1764. mCount++;
  1765. mColorsp[mCount] = mColorsp[mCount-1];
  1766. }
  1767. }
  1768. mVerticesp[mCount] = mVerticesp[mCount-1];
  1769. mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
  1770. }
  1771. void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count)
  1772. {
  1773. if (mCount + vert_count > 4094)
  1774. {
  1775. // llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl;
  1776. return;
  1777. }
  1778. if (sGLCoreProfile && mMode == LLRender::QUADS)
  1779. { //quads are deprecated, convert to triangle list
  1780. S32 i = 0;
  1781. while (i < vert_count)
  1782. {
  1783. //read first three
  1784. mVerticesp[mCount] = verts[i];
  1785. mTexcoordsp[mCount] = uvs[i];
  1786. mColorsp[mCount++] = colors[i++];
  1787. mVerticesp[mCount] = verts[i];
  1788. mTexcoordsp[mCount] = uvs[i];
  1789. mColorsp[mCount++] = colors[i++];
  1790. mVerticesp[mCount] = verts[i];
  1791. mTexcoordsp[mCount] = uvs[i];
  1792. mColorsp[mCount++] = colors[i++];
  1793. //copy last two
  1794. mVerticesp[mCount] = verts[i-3];
  1795. mTexcoordsp[mCount] = uvs[i-3];
  1796. mColorsp[mCount++] = colors[i-3];
  1797. mVerticesp[mCount] = verts[i-1];
  1798. mTexcoordsp[mCount] = uvs[i-1];
  1799. mColorsp[mCount++] = colors[i-1];
  1800. //copy last one
  1801. mVerticesp[mCount] = verts[i];
  1802. mTexcoordsp[mCount] = uvs[i];
  1803. mColorsp[mCount++] = colors[i++];
  1804. }
  1805. }
  1806. else
  1807. {
  1808. for (S32 i = 0; i < vert_count; i++)
  1809. {
  1810. mVerticesp[mCount] = verts[i];
  1811. mTexcoordsp[mCount] = uvs[i];
  1812. mColorsp[mCount] = colors[i];
  1813. mCount++;
  1814. }
  1815. }
  1816. mVerticesp[mCount] = mVerticesp[mCount-1];
  1817. mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
  1818. mColorsp[mCount] = mColorsp[mCount-1];
  1819. }
  1820. void LLRender::vertex2i(const GLint& x, const GLint& y)
  1821. {
  1822. vertex3f((GLfloat) x, (GLfloat) y, 0);
  1823. }
  1824. void LLRender::vertex2f(const GLfloat& x, const GLfloat& y)
  1825. {
  1826. vertex3f(x,y,0);
  1827. }
  1828. void LLRender::vertex2fv(const GLfloat* v)
  1829. {
  1830. vertex3f(v[0], v[1], 0);
  1831. }
  1832. void LLRender::vertex3fv(const GLfloat* v)
  1833. {
  1834. vertex3f(v[0], v[1], v[2]);
  1835. }
  1836. void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y)
  1837. {
  1838. mTexcoordsp[mCount] = LLVector2(x,y);
  1839. }
  1840. void LLRender::texCoord2i(const GLint& x, const GLint& y)
  1841. {
  1842. texCoord2f((GLfloat) x, (GLfloat) y);
  1843. }
  1844. void LLRender::texCoord2fv(const GLfloat* tc)
  1845. {
  1846. texCoord2f(tc[0], tc[1]);
  1847. }
  1848. void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a)
  1849. {
  1850. mColorsp[mCount] = LLColor4U(r,g,b,a);
  1851. }
  1852. void LLRender::color4ubv(const GLubyte* c)
  1853. {
  1854. color4ub(c[0], c[1], c[2], c[3]);
  1855. }
  1856. void LLRender::color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a)
  1857. {
  1858. color4ub((GLubyte) (llclamp(r, 0.f, 1.f)*255),
  1859. (GLubyte) (llclamp(g, 0.f, 1.f)*255),
  1860. (GLubyte) (llclamp(b, 0.f, 1.f)*255),
  1861. (GLubyte) (llclamp(a, 0.f, 1.f)*255));
  1862. }
  1863. void LLRender::color4fv(const GLfloat* c)
  1864. {
  1865. color4f(c[0],c[1],c[2],c[3]);
  1866. }
  1867. void LLRender::color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b)
  1868. {
  1869. color4f(r,g,b,1);
  1870. }
  1871. void LLRender::color3fv(const GLfloat* c)
  1872. {
  1873. color4f(c[0],c[1],c[2],1);
  1874. }
  1875. void LLRender::diffuseColor3f(F32 r, F32 g, F32 b)
  1876. {
  1877. LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
  1878. llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
  1879. if (shader)
  1880. {
  1881. shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,1.f);
  1882. }
  1883. else
  1884. {
  1885. glColor3f(r,g,b);
  1886. }
  1887. }
  1888. void LLRender::diffuseColor3fv(const F32* c)
  1889. {
  1890. LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
  1891. llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
  1892. if (shader)
  1893. {
  1894. shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0], c[1], c[2], 1.f);
  1895. }
  1896. else
  1897. {
  1898. glColor3fv(c);
  1899. }
  1900. }
  1901. void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a)
  1902. {
  1903. LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
  1904. llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
  1905. if (shader)
  1906. {
  1907. shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,a);
  1908. }
  1909. else
  1910. {
  1911. glColor4f(r,g,b,a);
  1912. }
  1913. }
  1914. void LLRender::diffuseColor4fv(const F32* c)
  1915. {
  1916. LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
  1917. llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
  1918. if (shader)
  1919. {
  1920. shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, c);
  1921. }
  1922. else
  1923. {
  1924. glColor4fv(c);
  1925. }
  1926. }
  1927. void LLRender::diffuseColor4ubv(const U8* c)
  1928. {
  1929. LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
  1930. llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL);
  1931. if (shader)
  1932. {
  1933. shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0]/255.f, c[1]/255.f, c[2]/255.f, c[3]/255.f);
  1934. }
  1935. else
  1936. {
  1937. glColor4ubv(c);
  1938. }
  1939. }
  1940. void LLRender::debugTexUnits(void)
  1941. {
  1942. LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL;
  1943. std::string active_enabled = "false";
  1944. for (U32 i = 0; i < mTexUnits.size(); i++)
  1945. {
  1946. if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE)
  1947. {
  1948. if (i == mCurrTextureUnitIndex) active_enabled = "true";
  1949. LL_INFOS("TextureUnit") << "TexUnit: " << i << " Enabled" << LL_ENDL;
  1950. LL_INFOS("TextureUnit") << "Enabled As: " ;
  1951. switch (getTexUnit(i)->mCurrTexType)
  1952. {
  1953. case LLTexUnit::TT_TEXTURE:
  1954. LL_CONT << "Texture 2D";
  1955. break;
  1956. case LLTexUnit::TT_RECT_TEXTURE:
  1957. LL_CONT << "Texture Rectangle";
  1958. break;
  1959. case LLTexUnit::TT_CUBE_MAP:
  1960. LL_CONT << "Cube Map";
  1961. break;
  1962. default:
  1963. LL_CONT << "ARGH!!! NONE!";
  1964. break;
  1965. }
  1966. LL_CONT << ", Texture Bound: " << getTexUnit(i)->mCurrTexture << LL_ENDL;
  1967. }
  1968. }
  1969. LL_INFOS("TextureUnit") << "Active TexUnit Enabled : " << active_enabled << LL_ENDL;
  1970. }