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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llrender.cpp
  3.  * @brief LLRender implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-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 "llrender.h"
  34. #include "llvertexbuffer.h"
  35. #include "llcubemap.h"
  36. #include "llimagegl.h"
  37. #include "llrendertarget.h"
  38. #include "lltexture.h"
  39. LLRender gGL;
  40. // Handy copies of last good GL matrices
  41. F64 gGLModelView[16];
  42. F64 gGLLastModelView[16];
  43. F64 gGLLastProjection[16];
  44. F64 gGLProjection[16];
  45. S32 gGLViewport[4];
  46. static const U32 LL_NUM_TEXTURE_LAYERS = 16; 
  47. static GLenum sGLTextureType[] =
  48. {
  49. GL_TEXTURE_2D,
  50. GL_TEXTURE_RECTANGLE_ARB,
  51. GL_TEXTURE_CUBE_MAP_ARB
  52. };
  53. static GLint sGLAddressMode[] =
  54. {
  55. GL_REPEAT,
  56. GL_MIRRORED_REPEAT,
  57. GL_CLAMP_TO_EDGE
  58. };
  59. static GLenum sGLCompareFunc[] =
  60. {
  61. GL_NEVER,
  62. GL_ALWAYS,
  63. GL_LESS,
  64. GL_LEQUAL,
  65. GL_EQUAL,
  66. GL_NOTEQUAL,
  67. GL_GEQUAL,
  68. GL_GREATER
  69. };
  70. const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0;
  71. static GLenum sGLBlendFactor[] =
  72. {
  73. GL_ONE,
  74. GL_ZERO,
  75. GL_DST_COLOR,
  76. GL_SRC_COLOR,
  77. GL_ONE_MINUS_DST_COLOR,
  78. GL_ONE_MINUS_SRC_COLOR,
  79. GL_DST_ALPHA,
  80. GL_SRC_ALPHA,
  81. GL_ONE_MINUS_DST_ALPHA,
  82. GL_ONE_MINUS_SRC_ALPHA
  83. };
  84. LLTexUnit::LLTexUnit(S32 index)
  85. : mCurrTexType(TT_NONE), mCurrBlendType(TB_MULT), 
  86. mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT),
  87. mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR),
  88. mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA),
  89. mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0),
  90. mHasMipMaps(false)
  91. {
  92. llassert_always(index < (S32)LL_NUM_TEXTURE_LAYERS);
  93. mIndex = index;
  94. }
  95. //static
  96. U32 LLTexUnit::getInternalType(eTextureType type)
  97. {
  98. return sGLTextureType[type];
  99. }
  100. void LLTexUnit::refreshState(void)
  101. {
  102. // We set dirty to true so that the tex unit knows to ignore caching
  103. // and we reset the cached tex unit state
  104. glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
  105. if (mCurrTexType != TT_NONE)
  106. {
  107. glEnable(sGLTextureType[mCurrTexType]);
  108. glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture);
  109. }
  110. else
  111. {
  112. glDisable(GL_TEXTURE_2D);
  113. glBindTexture(GL_TEXTURE_2D, 0);
  114. }
  115. if (mCurrBlendType != TB_COMBINE)
  116. {
  117. setTextureBlendType(mCurrBlendType);
  118. }
  119. else
  120. {
  121. setTextureCombiner(mCurrColorOp, mCurrColorSrc1, mCurrColorSrc2, false);
  122. setTextureCombiner(mCurrAlphaOp, mCurrAlphaSrc1, mCurrAlphaSrc2, true);
  123. }
  124. }
  125. void LLTexUnit::activate(void)
  126. {
  127. if (mIndex < 0) return;
  128. if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty)
  129. {
  130. glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
  131. gGL.mCurrTextureUnitIndex = mIndex;
  132. }
  133. }
  134. void LLTexUnit::enable(eTextureType type)
  135. {
  136. if (mIndex < 0) return;
  137. if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) )
  138. {
  139. activate();
  140. if (mCurrTexType != TT_NONE && !gGL.mDirty)
  141. {
  142. disable(); // Force a disable of a previous texture type if it's enabled.
  143. }
  144. mCurrTexType = type;
  145. gGL.flush();
  146. glEnable(sGLTextureType[type]);
  147. }
  148. }
  149. void LLTexUnit::disable(void)
  150. {
  151. if (mIndex < 0) return;
  152. if (mCurrTexType != TT_NONE)
  153. {
  154. activate();
  155. unbind(mCurrTexType);
  156. glDisable(sGLTextureType[mCurrTexType]);
  157. mCurrTexType = TT_NONE;
  158. }
  159. }
  160. bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
  161. {
  162. stop_glerror();
  163. if (mIndex < 0) return false;
  164. gGL.flush();
  165. LLImageGL* gl_tex = NULL ;
  166. if (texture == NULL || !(gl_tex = texture->getGLTexture()))
  167. {
  168. llwarns << "NULL LLTexUnit::bind texture" << llendl;
  169. return false;
  170. }
  171. if (!gl_tex->getTexName()) //if texture does not exist
  172. {
  173. //if deleted, will re-generate it immediately
  174. texture->forceImmediateUpdate() ;
  175. gl_tex->forceUpdateBindStats() ;
  176. return texture->bindDefaultImage(mIndex);
  177. }
  178. //in audit, replace the selected texture by the default one.
  179. if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0)
  180. {
  181. if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize)
  182. {
  183. gl_tex->updateBindStats(gl_tex->mTextureMemory);
  184. return bind(LLImageGL::sHighlightTexturep.get());
  185. }
  186. }
  187. if ((mCurrTexture != gl_tex->getTexName()) || forceBind)
  188. {
  189. activate();
  190. enable(gl_tex->getTarget());
  191. mCurrTexture = gl_tex->getTexName();
  192. glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
  193. if(gl_tex->updateBindStats(gl_tex->mTextureMemory))
  194. {
  195. texture->setActive() ;
  196. texture->updateBindStatsForTester() ;
  197. }
  198. mHasMipMaps = gl_tex->mHasMipMaps;
  199. if (gl_tex->mTexOptionsDirty)
  200. {
  201. gl_tex->mTexOptionsDirty = false;
  202. setTextureAddressMode(gl_tex->mAddressMode);
  203. setTextureFilteringOption(gl_tex->mFilterOption);
  204. }
  205. }
  206. return true;
  207. }
  208. bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
  209. {
  210. stop_glerror();
  211. if (mIndex < 0) return false;
  212. if(!texture)
  213. {
  214. llwarns << "NULL LLTexUnit::bind texture" << llendl;
  215. return false;
  216. }
  217. if(!texture->getTexName())
  218. {
  219. if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName())
  220. {
  221. return bind(LLImageGL::sDefaultGLTexture) ;
  222. }
  223. return false ;
  224. }
  225. gGL.flush();
  226. if ((mCurrTexture != texture->getTexName()) || forceBind)
  227. {
  228. activate();
  229. enable(texture->getTarget());
  230. mCurrTexture = texture->getTexName();
  231. glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
  232. texture->updateBindStats(texture->mTextureMemory);
  233. mHasMipMaps = texture->mHasMipMaps;
  234. if (texture->mTexOptionsDirty)
  235. {
  236. texture->mTexOptionsDirty = false;
  237. setTextureAddressMode(texture->mAddressMode);
  238. setTextureFilteringOption(texture->mFilterOption);
  239. }
  240. }
  241. return true;
  242. }
  243. bool LLTexUnit::bind(LLCubeMap* cubeMap)
  244. {
  245. if (mIndex < 0) return false;
  246. gGL.flush();
  247. if (cubeMap == NULL)
  248. {
  249. llwarns << "NULL LLTexUnit::bind cubemap" << llendl;
  250. return false;
  251. }
  252. if (mCurrTexture != cubeMap->mImages[0]->getTexName())
  253. {
  254. if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
  255. {
  256. activate();
  257. enable(LLTexUnit::TT_CUBE_MAP);
  258. mCurrTexture = cubeMap->mImages[0]->getTexName();
  259. glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture);
  260. mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps;
  261. cubeMap->mImages[0]->updateBindStats(cubeMap->mImages[0]->mTextureMemory);
  262. if (cubeMap->mImages[0]->mTexOptionsDirty)
  263. {
  264. cubeMap->mImages[0]->mTexOptionsDirty = false;
  265. setTextureAddressMode(cubeMap->mImages[0]->mAddressMode);
  266. setTextureFilteringOption(cubeMap->mImages[0]->mFilterOption);
  267. }
  268. return true;
  269. }
  270. else
  271. {
  272. llwarns << "Using cube map without extension!" << llendl;
  273. return false;
  274. }
  275. }
  276. return true;
  277. }
  278. // LLRenderTarget is unavailible on the mapserver since it uses FBOs.
  279. #if !LL_MESA_HEADLESS
  280. bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
  281. {
  282. if (mIndex < 0) return false;
  283. gGL.flush();
  284. if (bindDepth)
  285. {
  286. if (renderTarget->hasStencil())
  287. {
  288. llerrs << "Cannot bind a render buffer for sampling.  Allocate render target without a stencil buffer if sampling of depth buffer is required." << llendl;
  289. }
  290. bindManual(renderTarget->getUsage(), renderTarget->getDepth());
  291. }
  292. else
  293. {
  294. bindManual(renderTarget->getUsage(), renderTarget->getTexture());
  295. }
  296. return true;
  297. }
  298. #endif // LL_MESA_HEADLESS
  299. bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
  300. {
  301. if (mIndex < 0)  
  302. {
  303. return false;
  304. }
  305. if(mCurrTexture != texture)
  306. {
  307. gGL.flush();
  308. activate();
  309. enable(type);
  310. mCurrTexture = texture;
  311. glBindTexture(sGLTextureType[type], texture);
  312. mHasMipMaps = hasMips;
  313. }
  314. return true;
  315. }
  316. void LLTexUnit::unbind(eTextureType type)
  317. {
  318. stop_glerror();
  319. if (mIndex < 0) return;
  320. // Disabled caching of binding state.
  321. if (mCurrTexType == type)
  322. {
  323. gGL.flush();
  324. activate();
  325. mCurrTexture = 0;
  326. glBindTexture(sGLTextureType[type], 0);
  327. }
  328. }
  329. void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
  330. {
  331. if (mIndex < 0 || mCurrTexture == 0) return;
  332. activate();
  333. glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]);
  334. glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]);
  335. if (mCurrTexType == TT_CUBE_MAP)
  336. {
  337. glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]);
  338. }
  339. }
  340. void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option)
  341. {
  342. if (mIndex < 0 || mCurrTexture == 0) return;
  343. if (option == TFO_POINT)
  344. {
  345. glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  346. }
  347. else
  348. {
  349. glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  350. }
  351. if (option >= TFO_TRILINEAR && mHasMipMaps)
  352. {
  353. glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  354. else if (option >= TFO_BILINEAR)
  355. {
  356. glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  357. }
  358. else
  359. {
  360. glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  361. }
  362. if (gGLManager.mHasAnisotropic)
  363. {
  364. if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC)
  365. {
  366. if (gGL.mMaxAnisotropy < 1.f)
  367. {
  368. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGL.mMaxAnisotropy);
  369. }
  370. glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGL.mMaxAnisotropy);
  371. }
  372. else
  373. {
  374. glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
  375. }
  376. }
  377. }
  378. void LLTexUnit::setTextureBlendType(eTextureBlendType type)
  379. {
  380. if (mIndex < 0) return;
  381. // Do nothing if it's already correctly set.
  382. if (mCurrBlendType == type && !gGL.mDirty)
  383. {
  384. return;
  385. }
  386. activate();
  387. mCurrBlendType = type;
  388. S32 scale_amount = 1;
  389. switch (type) 
  390. {
  391. case TB_REPLACE:
  392. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  393. break;
  394. case TB_ADD:
  395. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
  396. break;
  397. case TB_MULT:
  398. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  399. break;
  400. case TB_MULT_X2:
  401. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  402. scale_amount = 2;
  403. break;
  404. case TB_ALPHA_BLEND:
  405. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  406. break;
  407. case TB_COMBINE:
  408. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
  409. break;
  410. default:
  411. llerrs << "Unknown Texture Blend Type: " << type << llendl;
  412. break;
  413. }
  414. setColorScale(scale_amount);
  415. setAlphaScale(1);
  416. }
  417. GLint LLTexUnit::getTextureSource(eTextureBlendSrc src)
  418. {
  419. switch(src)
  420. {
  421. // All four cases should return the same value.
  422. case TBS_PREV_COLOR:
  423. case TBS_PREV_ALPHA:
  424. case TBS_ONE_MINUS_PREV_COLOR:
  425. case TBS_ONE_MINUS_PREV_ALPHA:
  426. return GL_PREVIOUS_ARB;
  427. // All four cases should return the same value.
  428. case TBS_TEX_COLOR:
  429. case TBS_TEX_ALPHA:
  430. case TBS_ONE_MINUS_TEX_COLOR:
  431. case TBS_ONE_MINUS_TEX_ALPHA:
  432. return GL_TEXTURE;
  433. // All four cases should return the same value.
  434. case TBS_VERT_COLOR:
  435. case TBS_VERT_ALPHA:
  436. case TBS_ONE_MINUS_VERT_COLOR:
  437. case TBS_ONE_MINUS_VERT_ALPHA:
  438. return GL_PRIMARY_COLOR_ARB;
  439. // All four cases should return the same value.
  440. case TBS_CONST_COLOR:
  441. case TBS_CONST_ALPHA:
  442. case TBS_ONE_MINUS_CONST_COLOR:
  443. case TBS_ONE_MINUS_CONST_ALPHA:
  444. return GL_CONSTANT_ARB;
  445. default:
  446. llwarns << "Unknown eTextureBlendSrc: " << src << ".  Using Vertex Color instead." << llendl;
  447. return GL_PRIMARY_COLOR_ARB;
  448. }
  449. }
  450. GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)
  451. {
  452. switch(src)
  453. {
  454. // All four cases should return the same value.
  455. case TBS_PREV_COLOR:
  456. case TBS_TEX_COLOR:
  457. case TBS_VERT_COLOR:
  458. case TBS_CONST_COLOR:
  459. return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR;
  460. // All four cases should return the same value.
  461. case TBS_PREV_ALPHA:
  462. case TBS_TEX_ALPHA:
  463. case TBS_VERT_ALPHA:
  464. case TBS_CONST_ALPHA:
  465. return GL_SRC_ALPHA;
  466. // All four cases should return the same value.
  467. case TBS_ONE_MINUS_PREV_COLOR:
  468. case TBS_ONE_MINUS_TEX_COLOR:
  469. case TBS_ONE_MINUS_VERT_COLOR:
  470. case TBS_ONE_MINUS_CONST_COLOR:
  471. return (isAlpha) ? GL_ONE_MINUS_SRC_ALPHA : GL_ONE_MINUS_SRC_COLOR;
  472. // All four cases should return the same value.
  473. case TBS_ONE_MINUS_PREV_ALPHA:
  474. case TBS_ONE_MINUS_TEX_ALPHA:
  475. case TBS_ONE_MINUS_VERT_ALPHA:
  476. case TBS_ONE_MINUS_CONST_ALPHA:
  477. return GL_ONE_MINUS_SRC_ALPHA;
  478. default:
  479. llwarns << "Unknown eTextureBlendSrc: " << src << ".  Using Source Color or Alpha instead." << llendl;
  480. return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR;
  481. }
  482. }
  483. void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha)
  484. {
  485. if (mIndex < 0) return;
  486. activate();
  487. if (mCurrBlendType != TB_COMBINE || gGL.mDirty)
  488. {
  489. mCurrBlendType = TB_COMBINE;
  490. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
  491. }
  492. // We want an early out, because this function does a LOT of stuff.
  493. if ( ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2))
  494. || (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2)) ) && !gGL.mDirty)
  495. {
  496. return;
  497. }
  498. // Get the gl source enums according to the eTextureBlendSrc sources passed in
  499. GLint source1 = getTextureSource(src1);
  500. GLint source2 = getTextureSource(src2);
  501. // Get the gl operand enums according to the eTextureBlendSrc sources passed in
  502. GLint operand1 = getTextureSourceType(src1, isAlpha);
  503. GLint operand2 = getTextureSourceType(src2, isAlpha);
  504. // Default the scale amount to 1
  505. S32 scale_amount = 1;
  506. GLenum comb_enum, src0_enum, src1_enum, src2_enum, operand0_enum, operand1_enum, operand2_enum;
  507. if (isAlpha)
  508. {
  509. // Set enums to ALPHA ones
  510. comb_enum = GL_COMBINE_ALPHA_ARB;
  511. src0_enum = GL_SOURCE0_ALPHA_ARB;
  512. src1_enum = GL_SOURCE1_ALPHA_ARB;
  513. src2_enum = GL_SOURCE2_ALPHA_ARB;
  514. operand0_enum = GL_OPERAND0_ALPHA_ARB;
  515. operand1_enum = GL_OPERAND1_ALPHA_ARB;
  516. operand2_enum = GL_OPERAND2_ALPHA_ARB;
  517. // cache current combiner
  518. mCurrAlphaOp = op;
  519. mCurrAlphaSrc1 = src1;
  520. mCurrAlphaSrc2 = src2;
  521. }
  522. else 
  523. {
  524. // Set enums to RGB ones
  525. comb_enum = GL_COMBINE_RGB_ARB;
  526. src0_enum = GL_SOURCE0_RGB_ARB;
  527. src1_enum = GL_SOURCE1_RGB_ARB;
  528. src2_enum = GL_SOURCE2_RGB_ARB;
  529. operand0_enum = GL_OPERAND0_RGB_ARB;
  530. operand1_enum = GL_OPERAND1_RGB_ARB;
  531. operand2_enum = GL_OPERAND2_RGB_ARB;
  532. // cache current combiner
  533. mCurrColorOp = op;
  534. mCurrColorSrc1 = src1;
  535. mCurrColorSrc2 = src2;
  536. }
  537. switch(op)
  538. {
  539. case TBO_REPLACE:
  540. // Slightly special syntax (no second sources), just set all and return.
  541. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE);
  542. glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1);
  543. glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1);
  544. (isAlpha) ? setAlphaScale(1) : setColorScale(1);
  545. return;
  546. case TBO_MULT:
  547. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE);
  548. break;
  549. case TBO_MULT_X2:
  550. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE);
  551. scale_amount = 2;
  552. break;
  553. case TBO_MULT_X4:
  554. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE);
  555. scale_amount = 4;
  556. break;
  557. case TBO_ADD:
  558. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD);
  559. break;
  560. case TBO_ADD_SIGNED:
  561. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD_SIGNED_ARB);
  562. break;
  563. case TBO_SUBTRACT:
  564. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_SUBTRACT_ARB);
  565. break;
  566. case TBO_LERP_VERT_ALPHA:
  567. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
  568. glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR_ARB);
  569. glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA);
  570. break;
  571. case TBO_LERP_TEX_ALPHA:
  572. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
  573. glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_TEXTURE);
  574. glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA);
  575. break;
  576. case TBO_LERP_PREV_ALPHA:
  577. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
  578. glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PREVIOUS_ARB);
  579. glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA);
  580. break;
  581. case TBO_LERP_CONST_ALPHA:
  582. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
  583. glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_CONSTANT_ARB);
  584. glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA);
  585. break;
  586. case TBO_LERP_VERT_COLOR:
  587. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE);
  588. glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR_ARB);
  589. glTexEnvi(GL_TEXTURE_ENV, operand2_enum, (isAlpha) ? GL_SRC_ALPHA : GL_SRC_COLOR);
  590. break;
  591. default:
  592. llwarns << "Unknown eTextureBlendOp: " << op << ".  Setting op to replace." << llendl;
  593. // Slightly special syntax (no second sources), just set all and return.
  594. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE);
  595. glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1);
  596. glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1);
  597. (isAlpha) ? setAlphaScale(1) : setColorScale(1);
  598. return;
  599. }
  600. // Set sources, operands, and scale accordingly
  601. glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1);
  602. glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1);
  603. glTexEnvi(GL_TEXTURE_ENV, src1_enum, source2);
  604. glTexEnvi(GL_TEXTURE_ENV, operand1_enum, operand2);
  605. (isAlpha) ? setAlphaScale(scale_amount) : setColorScale(scale_amount);
  606. }
  607. void LLTexUnit::setColorScale(S32 scale)
  608. {
  609. if (mCurrColorScale != scale || gGL.mDirty)
  610. {
  611. mCurrColorScale = scale;
  612. glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale );
  613. }
  614. }
  615. void LLTexUnit::setAlphaScale(S32 scale)
  616. {
  617. if (mCurrAlphaScale != scale || gGL.mDirty)
  618. {
  619. mCurrAlphaScale = scale;
  620. glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale );
  621. }
  622. }
  623. // Useful for debugging that you've manually assigned a texture operation to the correct 
  624. // texture unit based on the currently set active texture in opengl.
  625. void LLTexUnit::debugTextureUnit(void)
  626. {
  627. if (mIndex < 0) return;
  628. GLint activeTexture;
  629. glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
  630. if ((GL_TEXTURE0_ARB + mIndex) != activeTexture)
  631. {
  632. U32 set_unit = (activeTexture - GL_TEXTURE0_ARB);
  633. llwarns << "Incorrect Texture Unit!  Expected: " << set_unit << " Actual: " << mIndex << llendl;
  634. }
  635. }
  636. LLRender::LLRender()
  637.   : mDirty(false),
  638.     mCount(0),
  639.     mMode(LLRender::TRIANGLES),
  640.     mCurrTextureUnitIndex(0),
  641.     mMaxAnisotropy(0.f) 
  642. {
  643. mBuffer = new LLVertexBuffer(immediate_mask, 0);
  644. mBuffer->allocateBuffer(4096, 0, TRUE);
  645. mBuffer->getVertexStrider(mVerticesp);
  646. mBuffer->getTexCoord0Strider(mTexcoordsp);
  647. mBuffer->getColorStrider(mColorsp);
  648. mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS);
  649. for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++)
  650. {
  651. mTexUnits.push_back(new LLTexUnit(i));
  652. }
  653. mDummyTexUnit = new LLTexUnit(-1);
  654. for (U32 i = 0; i < 4; i++)
  655. {
  656. mCurrColorMask[i] = true;
  657. }
  658. mCurrAlphaFunc = CF_DEFAULT;
  659. mCurrAlphaFuncVal = 0.01f;
  660. }
  661. LLRender::~LLRender()
  662. {
  663. shutdown();
  664. }
  665. void LLRender::shutdown()
  666. {
  667. for (U32 i = 0; i < mTexUnits.size(); i++)
  668. {
  669. delete mTexUnits[i];
  670. }
  671. mTexUnits.clear();
  672. delete mDummyTexUnit;
  673. mDummyTexUnit = NULL;
  674. }
  675. void LLRender::refreshState(void)
  676. {
  677. mDirty = true;
  678. U32 active_unit = mCurrTextureUnitIndex;
  679. for (U32 i = 0; i < mTexUnits.size(); i++)
  680. {
  681. mTexUnits[i]->refreshState();
  682. }
  683. mTexUnits[active_unit]->activate();
  684. setColorMask(mCurrColorMask[0], mCurrColorMask[1], mCurrColorMask[2], mCurrColorMask[3]);
  685. setAlphaRejectSettings(mCurrAlphaFunc, mCurrAlphaFuncVal);
  686. mDirty = false;
  687. }
  688. void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
  689. {
  690. flush();
  691. glTranslatef(x,y,z);
  692. }
  693. void LLRender::scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
  694. {
  695. flush();
  696. glScalef(x,y,z);
  697. }
  698. void LLRender::pushMatrix()
  699. {
  700. flush();
  701. glPushMatrix();
  702. }
  703. void LLRender::popMatrix()
  704. {
  705. flush();
  706. glPopMatrix();
  707. }
  708. void LLRender::setColorMask(bool writeColor, bool writeAlpha)
  709. {
  710. setColorMask(writeColor, writeColor, writeColor, writeAlpha);
  711. }
  712. void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha)
  713. {
  714. flush();
  715. mCurrColorMask[0] = writeColorR;
  716. mCurrColorMask[1] = writeColorG;
  717. mCurrColorMask[2] = writeColorB;
  718. mCurrColorMask[3] = writeAlpha;
  719. glColorMask(writeColorR ? GL_TRUE : GL_FALSE, 
  720. writeColorG ? GL_TRUE : GL_FALSE,
  721. writeColorB ? GL_TRUE : GL_FALSE,
  722. writeAlpha ? GL_TRUE : GL_FALSE);
  723. }
  724. void LLRender::setSceneBlendType(eBlendType type)
  725. {
  726. flush();
  727. switch (type) 
  728. {
  729. case BT_ALPHA:
  730. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  731. break;
  732. case BT_ADD:
  733. glBlendFunc(GL_ONE, GL_ONE);
  734. break;
  735. case BT_ADD_WITH_ALPHA:
  736. glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  737. break;
  738. case BT_MULT:
  739. glBlendFunc(GL_DST_COLOR, GL_ZERO);
  740. break;
  741. case BT_MULT_ALPHA:
  742. glBlendFunc(GL_DST_ALPHA, GL_ZERO);
  743. break;
  744. case BT_MULT_X2:
  745. glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
  746. break;
  747. case BT_REPLACE:
  748. glBlendFunc(GL_ONE, GL_ZERO);
  749. break;
  750. default:
  751. llerrs << "Unknown Scene Blend Type: " << type << llendl;
  752. break;
  753. }
  754. }
  755. void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value)
  756. {
  757. flush();
  758. mCurrAlphaFunc = func;
  759. mCurrAlphaFuncVal = value;
  760. if (func == CF_DEFAULT)
  761. {
  762. glAlphaFunc(GL_GREATER, 0.01f);
  763. else
  764. {
  765. glAlphaFunc(sGLCompareFunc[func], value);
  766. }
  767. }
  768. void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
  769. {
  770. flush();
  771. glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]);
  772. }
  773. LLTexUnit* LLRender::getTexUnit(U32 index)
  774. {
  775. if (index < mTexUnits.size())
  776. {
  777. return mTexUnits[index];
  778. }
  779. else 
  780. {
  781. lldebugs << "Non-existing texture unit layer requested: " << index << llendl;
  782. return mDummyTexUnit;
  783. }
  784. }
  785. bool LLRender::verifyTexUnitActive(U32 unitToVerify)
  786. {
  787. if (mCurrTextureUnitIndex == unitToVerify)
  788. {
  789. return true;
  790. }
  791. else 
  792. {
  793. llwarns << "TexUnit currently active: " << mCurrTextureUnitIndex << " (expecting " << unitToVerify << ")" << llendl;
  794. return false;
  795. }
  796. }
  797. void LLRender::clearErrors()
  798. {
  799. while (glGetError())
  800. {
  801. //loop until no more error flags left
  802. }
  803. }
  804. void LLRender::begin(const GLuint& mode)
  805. {
  806. if (mode != mMode)
  807. {
  808. if (mMode == LLRender::QUADS ||
  809. mMode == LLRender::LINES ||
  810. mMode == LLRender::TRIANGLES ||
  811. mMode == LLRender::POINTS)
  812. {
  813. flush();
  814. }
  815. else if (mCount != 0)
  816. {
  817. llerrs << "gGL.begin() called redundantly." << llendl;
  818. }
  819. mMode = mode;
  820. }
  821. }
  822. void LLRender::end()
  823. if (mCount == 0)
  824. {
  825. return;
  826. //IMM_ERRS << "GL begin and end called with no vertices specified." << llendl;
  827. }
  828. if ((mMode != LLRender::QUADS && 
  829. mMode != LLRender::LINES &&
  830. mMode != LLRender::TRIANGLES &&
  831. mMode != LLRender::POINTS) ||
  832. mCount > 2048)
  833. {
  834. flush();
  835. }
  836. }
  837. void LLRender::flush()
  838. {
  839. if (mCount > 0)
  840. {
  841. #if 0
  842. if (!glIsEnabled(GL_VERTEX_ARRAY))
  843. {
  844. llerrs << "foo 1" << llendl;
  845. }
  846. if (!glIsEnabled(GL_COLOR_ARRAY))
  847. {
  848. llerrs << "foo 2" << llendl;
  849. }
  850. if (!glIsEnabled(GL_TEXTURE_COORD_ARRAY))
  851. {
  852. llerrs << "foo 3" << llendl;
  853. }
  854. if (glIsEnabled(GL_NORMAL_ARRAY))
  855. {
  856. llerrs << "foo 7" << llendl;
  857. }
  858. GLvoid* pointer;
  859. glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer);
  860. if (pointer != &(mBuffer[0].v))
  861. {
  862. llerrs << "foo 4" << llendl;
  863. }
  864. glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer);
  865. if (pointer != &(mBuffer[0].c))
  866. {
  867. llerrs << "foo 5" << llendl;
  868. }
  869. glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer);
  870. if (pointer != &(mBuffer[0].uv))
  871. {
  872. llerrs << "foo 6" << llendl;
  873. }
  874. #endif
  875. mBuffer->setBuffer(immediate_mask);
  876. mBuffer->drawArrays(mMode, 0, mCount);
  877. mVerticesp[0] = mVerticesp[mCount];
  878. mTexcoordsp[0] = mTexcoordsp[mCount];
  879. mColorsp[0] = mColorsp[mCount];
  880. mCount = 0;
  881. }
  882. }
  883. void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
  884. //the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095]
  885. if (mCount > 4094)
  886. {
  887. // llwarns << "GL immediate mode overflow.  Some geometry not drawn." << llendl;
  888. return;
  889. }
  890. mVerticesp[mCount] = LLVector3(x,y,z);
  891. mCount++;
  892. if (mCount < 4096)
  893. {
  894. mVerticesp[mCount] = mVerticesp[mCount-1];
  895. mColorsp[mCount] = mColorsp[mCount-1];
  896. mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
  897. }
  898. }
  899. void LLRender::vertex2i(const GLint& x, const GLint& y)
  900. {
  901. vertex3f((GLfloat) x, (GLfloat) y, 0);
  902. }
  903. void LLRender::vertex2f(const GLfloat& x, const GLfloat& y)
  904. vertex3f(x,y,0);
  905. }
  906. void LLRender::vertex2fv(const GLfloat* v)
  907. vertex3f(v[0], v[1], 0);
  908. }
  909. void LLRender::vertex3fv(const GLfloat* v)
  910. {
  911. vertex3f(v[0], v[1], v[2]);
  912. }
  913. void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y)
  914. mTexcoordsp[mCount] = LLVector2(x,y);
  915. }
  916. void LLRender::texCoord2i(const GLint& x, const GLint& y)
  917. texCoord2f((GLfloat) x, (GLfloat) y);
  918. }
  919. void LLRender::texCoord2fv(const GLfloat* tc)
  920. texCoord2f(tc[0], tc[1]);
  921. }
  922. void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a)
  923. {
  924. mColorsp[mCount] = LLColor4U(r,g,b,a);
  925. }
  926. void LLRender::color4ubv(const GLubyte* c)
  927. {
  928. color4ub(c[0], c[1], c[2], c[3]);
  929. }
  930. void LLRender::color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a)
  931. {
  932. color4ub((GLubyte) (llclamp(r, 0.f, 1.f)*255),
  933. (GLubyte) (llclamp(g, 0.f, 1.f)*255),
  934. (GLubyte) (llclamp(b, 0.f, 1.f)*255),
  935. (GLubyte) (llclamp(a, 0.f, 1.f)*255));
  936. }
  937. void LLRender::color4fv(const GLfloat* c)
  938. color4f(c[0],c[1],c[2],c[3]);
  939. }
  940. void LLRender::color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b)
  941. color4f(r,g,b,1);
  942. }
  943. void LLRender::color3fv(const GLfloat* c)
  944. color4f(c[0],c[1],c[2],1);
  945. }
  946. void LLRender::debugTexUnits(void)
  947. {
  948. LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL;
  949. std::string active_enabled = "false";
  950. for (U32 i = 0; i < mTexUnits.size(); i++)
  951. {
  952. if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE)
  953. {
  954. if (i == mCurrTextureUnitIndex) active_enabled = "true";
  955. LL_INFOS("TextureUnit") << "TexUnit: " << i << " Enabled" << LL_ENDL;
  956. LL_INFOS("TextureUnit") << "Enabled As: " ;
  957. switch (getTexUnit(i)->mCurrTexType)
  958. {
  959. case LLTexUnit::TT_TEXTURE:
  960. LL_CONT << "Texture 2D";
  961. break;
  962. case LLTexUnit::TT_RECT_TEXTURE:
  963. LL_CONT << "Texture Rectangle";
  964. break;
  965. case LLTexUnit::TT_CUBE_MAP:
  966. LL_CONT << "Cube Map";
  967. break;
  968. default:
  969. LL_CONT << "ARGH!!! NONE!";
  970. break;
  971. }
  972. LL_CONT << ", Texture Bound: " << getTexUnit(i)->mCurrTexture << LL_ENDL;
  973. }
  974. }
  975. LL_INFOS("TextureUnit") << "Active TexUnit Enabled : " << active_enabled << LL_ENDL;
  976. }