PageRenderTime 394ms CodeModel.GetById 13ms RepoModel.GetById 4ms app.codeStats 1ms

/indra/newview/lldrawpool.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 530 lines | 391 code | 76 blank | 63 comment | 41 complexity | 238561d6ca9f8eecc50af2435db09247 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lldrawpool.cpp
  3. * @brief LLDrawPool class implementation
  4. *
  5. * $LicenseInfo:firstyear=2002&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 "llviewerprecompiledheaders.h"
  27. #include "lldrawpool.h"
  28. #include "llrender.h"
  29. #include "llfasttimer.h"
  30. #include "llviewercontrol.h"
  31. #include "lldrawable.h"
  32. #include "lldrawpoolalpha.h"
  33. #include "lldrawpoolavatar.h"
  34. #include "lldrawpoolbump.h"
  35. #include "lldrawpoolground.h"
  36. #include "lldrawpoolsimple.h"
  37. #include "lldrawpoolsky.h"
  38. #include "lldrawpooltree.h"
  39. #include "lldrawpoolterrain.h"
  40. #include "lldrawpoolwater.h"
  41. #include "llface.h"
  42. #include "llviewerobjectlist.h" // For debug listing.
  43. #include "pipeline.h"
  44. #include "llspatialpartition.h"
  45. #include "llviewercamera.h"
  46. #include "lldrawpoolwlsky.h"
  47. S32 LLDrawPool::sNumDrawPools = 0;
  48. //=============================
  49. // Draw Pool Implementation
  50. //=============================
  51. LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
  52. {
  53. LLDrawPool *poolp = NULL;
  54. switch (type)
  55. {
  56. case POOL_SIMPLE:
  57. poolp = new LLDrawPoolSimple();
  58. break;
  59. case POOL_GRASS:
  60. poolp = new LLDrawPoolGrass();
  61. break;
  62. case POOL_FULLBRIGHT:
  63. poolp = new LLDrawPoolFullbright();
  64. break;
  65. case POOL_INVISIBLE:
  66. poolp = new LLDrawPoolInvisible();
  67. break;
  68. case POOL_GLOW:
  69. poolp = new LLDrawPoolGlow();
  70. break;
  71. case POOL_ALPHA:
  72. poolp = new LLDrawPoolAlpha();
  73. break;
  74. case POOL_AVATAR:
  75. poolp = new LLDrawPoolAvatar();
  76. break;
  77. case POOL_TREE:
  78. poolp = new LLDrawPoolTree(tex0);
  79. break;
  80. case POOL_TERRAIN:
  81. poolp = new LLDrawPoolTerrain(tex0);
  82. break;
  83. case POOL_SKY:
  84. poolp = new LLDrawPoolSky();
  85. break;
  86. case POOL_VOIDWATER:
  87. case POOL_WATER:
  88. poolp = new LLDrawPoolWater();
  89. break;
  90. case POOL_GROUND:
  91. poolp = new LLDrawPoolGround();
  92. break;
  93. case POOL_BUMP:
  94. poolp = new LLDrawPoolBump();
  95. break;
  96. case POOL_WL_SKY:
  97. poolp = new LLDrawPoolWLSky();
  98. break;
  99. default:
  100. llerrs << "Unknown draw pool type!" << llendl;
  101. return NULL;
  102. }
  103. llassert(poolp->mType == type);
  104. return poolp;
  105. }
  106. LLDrawPool::LLDrawPool(const U32 type)
  107. {
  108. mType = type;
  109. sNumDrawPools++;
  110. mId = sNumDrawPools;
  111. mVertexShaderLevel = 0;
  112. }
  113. LLDrawPool::~LLDrawPool()
  114. {
  115. }
  116. LLViewerTexture *LLDrawPool::getDebugTexture()
  117. {
  118. return NULL;
  119. }
  120. //virtual
  121. void LLDrawPool::beginRenderPass( S32 pass )
  122. {
  123. }
  124. //virtual
  125. S32 LLDrawPool::getNumPasses()
  126. {
  127. return 1;
  128. }
  129. //virtual
  130. void LLDrawPool::beginDeferredPass(S32 pass)
  131. {
  132. }
  133. //virtual
  134. void LLDrawPool::endDeferredPass(S32 pass)
  135. {
  136. }
  137. //virtual
  138. S32 LLDrawPool::getNumDeferredPasses()
  139. {
  140. return 0;
  141. }
  142. //virtual
  143. void LLDrawPool::renderDeferred(S32 pass)
  144. {
  145. }
  146. //virtual
  147. void LLDrawPool::beginPostDeferredPass(S32 pass)
  148. {
  149. }
  150. //virtual
  151. void LLDrawPool::endPostDeferredPass(S32 pass)
  152. {
  153. }
  154. //virtual
  155. S32 LLDrawPool::getNumPostDeferredPasses()
  156. {
  157. return 0;
  158. }
  159. //virtual
  160. void LLDrawPool::renderPostDeferred(S32 pass)
  161. {
  162. }
  163. //virtual
  164. void LLDrawPool::endRenderPass( S32 pass )
  165. {
  166. /*for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
  167. { //dummy cleanup of any currently bound textures
  168. if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
  169. {
  170. gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
  171. gGL.getTexUnit(i)->disable();
  172. }
  173. }*/
  174. //make sure channel 0 is active channel
  175. gGL.getTexUnit(0)->activate();
  176. }
  177. //virtual
  178. void LLDrawPool::beginShadowPass(S32 pass)
  179. {
  180. }
  181. //virtual
  182. void LLDrawPool::endShadowPass(S32 pass)
  183. {
  184. }
  185. //virtual
  186. S32 LLDrawPool::getNumShadowPasses()
  187. {
  188. return 0;
  189. }
  190. //virtual
  191. void LLDrawPool::renderShadow(S32 pass)
  192. {
  193. }
  194. //=============================
  195. // Face Pool Implementation
  196. //=============================
  197. LLFacePool::LLFacePool(const U32 type)
  198. : LLDrawPool(type)
  199. {
  200. resetDrawOrders();
  201. }
  202. LLFacePool::~LLFacePool()
  203. {
  204. destroy();
  205. }
  206. void LLFacePool::destroy()
  207. {
  208. if (!mReferences.empty())
  209. {
  210. llinfos << mReferences.size() << " references left on deletion of draw pool!" << llendl;
  211. }
  212. }
  213. void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures)
  214. {
  215. }
  216. // static
  217. S32 LLFacePool::drawLoop(face_array_t& face_list)
  218. {
  219. S32 res = 0;
  220. if (!face_list.empty())
  221. {
  222. for (std::vector<LLFace*>::iterator iter = face_list.begin();
  223. iter != face_list.end(); iter++)
  224. {
  225. LLFace *facep = *iter;
  226. res += facep->renderIndexed();
  227. }
  228. }
  229. return res;
  230. }
  231. // static
  232. S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage)
  233. {
  234. S32 res = 0;
  235. if (!face_list.empty())
  236. {
  237. for (std::vector<LLFace*>::iterator iter = face_list.begin();
  238. iter != face_list.end(); iter++)
  239. {
  240. LLFace *facep = *iter;
  241. gGL.getTexUnit(stage)->bind(facep->getTexture(), TRUE) ;
  242. gGL.getTexUnit(0)->activate();
  243. res += facep->renderIndexed();
  244. }
  245. }
  246. return res;
  247. }
  248. void LLFacePool::drawLoop()
  249. {
  250. if (!mDrawFace.empty())
  251. {
  252. drawLoop(mDrawFace);
  253. }
  254. }
  255. void LLFacePool::enqueue(LLFace* facep)
  256. {
  257. mDrawFace.push_back(facep);
  258. }
  259. // virtual
  260. BOOL LLFacePool::addFace(LLFace *facep)
  261. {
  262. addFaceReference(facep);
  263. return TRUE;
  264. }
  265. // virtual
  266. BOOL LLFacePool::removeFace(LLFace *facep)
  267. {
  268. removeFaceReference(facep);
  269. vector_replace_with_last(mDrawFace, facep);
  270. return TRUE;
  271. }
  272. // Not absolutely sure if we should be resetting all of the chained pools as well - djs
  273. void LLFacePool::resetDrawOrders()
  274. {
  275. mDrawFace.resize(0);
  276. }
  277. LLViewerTexture *LLFacePool::getTexture()
  278. {
  279. return NULL;
  280. }
  281. void LLFacePool::removeFaceReference(LLFace *facep)
  282. {
  283. if (facep->getReferenceIndex() != -1)
  284. {
  285. if (facep->getReferenceIndex() != (S32)mReferences.size())
  286. {
  287. LLFace *back = mReferences.back();
  288. mReferences[facep->getReferenceIndex()] = back;
  289. back->setReferenceIndex(facep->getReferenceIndex());
  290. }
  291. mReferences.pop_back();
  292. }
  293. facep->setReferenceIndex(-1);
  294. }
  295. void LLFacePool::addFaceReference(LLFace *facep)
  296. {
  297. if (-1 == facep->getReferenceIndex())
  298. {
  299. facep->setReferenceIndex(mReferences.size());
  300. mReferences.push_back(facep);
  301. }
  302. }
  303. BOOL LLFacePool::verify() const
  304. {
  305. BOOL ok = TRUE;
  306. for (std::vector<LLFace*>::const_iterator iter = mDrawFace.begin();
  307. iter != mDrawFace.end(); iter++)
  308. {
  309. const LLFace* facep = *iter;
  310. if (facep->getPool() != this)
  311. {
  312. llinfos << "Face in wrong pool!" << llendl;
  313. facep->printDebugInfo();
  314. ok = FALSE;
  315. }
  316. else if (!facep->verify())
  317. {
  318. ok = FALSE;
  319. }
  320. }
  321. return ok;
  322. }
  323. void LLFacePool::printDebugInfo() const
  324. {
  325. llinfos << "Pool " << this << " Type: " << getType() << llendl;
  326. }
  327. BOOL LLFacePool::LLOverrideFaceColor::sOverrideFaceColor = FALSE;
  328. void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color)
  329. {
  330. gGL.diffuseColor4fv(color.mV);
  331. }
  332. void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color)
  333. {
  334. glColor4ubv(color.mV);
  335. }
  336. void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a)
  337. {
  338. gGL.diffuseColor4f(r,g,b,a);
  339. }
  340. //=============================
  341. // Render Pass Implementation
  342. //=============================
  343. LLRenderPass::LLRenderPass(const U32 type)
  344. : LLDrawPool(type)
  345. {
  346. }
  347. LLRenderPass::~LLRenderPass()
  348. {
  349. }
  350. LLDrawPool* LLRenderPass::instancePool()
  351. {
  352. #if LL_RELEASE_FOR_DOWNLOAD
  353. llwarns << "Attempting to instance a render pass. Invalid operation." << llendl;
  354. #else
  355. llerrs << "Attempting to instance a render pass. Invalid operation." << llendl;
  356. #endif
  357. return NULL;
  358. }
  359. void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
  360. {
  361. LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
  362. for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
  363. {
  364. LLDrawInfo *pparams = *k;
  365. if (pparams) {
  366. pushBatch(*pparams, mask, texture);
  367. }
  368. }
  369. }
  370. void LLRenderPass::renderTexture(U32 type, U32 mask)
  371. {
  372. pushBatches(type, mask, TRUE);
  373. }
  374. void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
  375. {
  376. for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
  377. {
  378. LLDrawInfo* pparams = *i;
  379. if (pparams)
  380. {
  381. pushBatch(*pparams, mask, texture, batch_textures);
  382. }
  383. }
  384. }
  385. void LLRenderPass::applyModelMatrix(LLDrawInfo& params)
  386. {
  387. if (params.mModelMatrix != gGLLastMatrix)
  388. {
  389. gGLLastMatrix = params.mModelMatrix;
  390. gGL.loadMatrix(gGLModelView);
  391. if (params.mModelMatrix)
  392. {
  393. gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix);
  394. }
  395. gPipeline.mMatrixOpCount++;
  396. }
  397. }
  398. void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
  399. {
  400. applyModelMatrix(params);
  401. bool tex_setup = false;
  402. if (texture)
  403. {
  404. if (batch_textures && params.mTextureList.size() > 1)
  405. {
  406. for (U32 i = 0; i < params.mTextureList.size(); ++i)
  407. {
  408. if (params.mTextureList[i].notNull())
  409. {
  410. gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
  411. }
  412. }
  413. }
  414. else
  415. { //not batching textures or batch has only 1 texture -- might need a texture matrix
  416. if (params.mTexture.notNull())
  417. {
  418. params.mTexture->addTextureStats(params.mVSize);
  419. gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
  420. if (params.mTextureMatrix)
  421. {
  422. tex_setup = true;
  423. gGL.getTexUnit(0)->activate();
  424. gGL.matrixMode(LLRender::MM_TEXTURE);
  425. gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
  426. gPipeline.mTextureMatrixOps++;
  427. }
  428. }
  429. else
  430. {
  431. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  432. }
  433. }
  434. }
  435. if (params.mVertexBuffer.notNull())
  436. {
  437. if (params.mGroup)
  438. {
  439. params.mGroup->rebuildMesh();
  440. }
  441. params.mVertexBuffer->setBuffer(mask);
  442. params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
  443. gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
  444. }
  445. if (tex_setup)
  446. {
  447. gGL.loadIdentity();
  448. gGL.matrixMode(LLRender::MM_MODELVIEW);
  449. }
  450. }
  451. void LLRenderPass::renderGroups(U32 type, U32 mask, BOOL texture)
  452. {
  453. gPipeline.renderGroups(this, type, mask, texture);
  454. }