/indra/newview/lldrawpoolalpha.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 538 lines · 420 code · 77 blank · 41 comment · 77 complexity · 4280fa9aa473f7d3263e4a7ebeb3f68d MD5 · raw file

  1. /**
  2. * @file lldrawpoolalpha.cpp
  3. * @brief LLDrawPoolAlpha 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 "lldrawpoolalpha.h"
  28. #include "llglheaders.h"
  29. #include "llviewercontrol.h"
  30. #include "llcriticaldamp.h"
  31. #include "llfasttimer.h"
  32. #include "llrender.h"
  33. #include "llcubemap.h"
  34. #include "llsky.h"
  35. #include "lldrawable.h"
  36. #include "llface.h"
  37. #include "llviewercamera.h"
  38. #include "llviewertexturelist.h" // For debugging
  39. #include "llviewerobjectlist.h" // For debugging
  40. #include "llviewerwindow.h"
  41. #include "pipeline.h"
  42. #include "llviewershadermgr.h"
  43. #include "llviewerregion.h"
  44. #include "lldrawpoolwater.h"
  45. #include "llspatialpartition.h"
  46. BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
  47. static BOOL deferred_render = FALSE;
  48. LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
  49. LLRenderPass(type), current_shader(NULL), target_shader(NULL),
  50. simple_shader(NULL), fullbright_shader(NULL), emissive_shader(NULL),
  51. mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF),
  52. mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF)
  53. {
  54. }
  55. LLDrawPoolAlpha::~LLDrawPoolAlpha()
  56. {
  57. }
  58. void LLDrawPoolAlpha::prerender()
  59. {
  60. mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
  61. }
  62. S32 LLDrawPoolAlpha::getNumDeferredPasses()
  63. {
  64. return 1;
  65. }
  66. void LLDrawPoolAlpha::beginDeferredPass(S32 pass)
  67. {
  68. }
  69. void LLDrawPoolAlpha::endDeferredPass(S32 pass)
  70. {
  71. }
  72. void LLDrawPoolAlpha::renderDeferred(S32 pass)
  73. {
  74. LLFastTimer t(FTM_RENDER_GRASS);
  75. gDeferredDiffuseAlphaMaskProgram.bind();
  76. gDeferredDiffuseAlphaMaskProgram.setMinimumAlpha(0.33f);
  77. //render alpha masked objects
  78. LLRenderPass::pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
  79. gDeferredDiffuseAlphaMaskProgram.unbind();
  80. }
  81. S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
  82. {
  83. if (LLPipeline::sImpostorRender)
  84. { //skip depth buffer filling pass when rendering impostors
  85. return 1;
  86. }
  87. else if (gSavedSettings.getBOOL("RenderDepthOfField"))
  88. {
  89. return 2;
  90. }
  91. else
  92. {
  93. return 1;
  94. }
  95. }
  96. void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
  97. {
  98. LLFastTimer t(FTM_RENDER_ALPHA);
  99. if (pass == 0)
  100. {
  101. simple_shader = &gDeferredAlphaProgram;
  102. fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
  103. //prime simple shader (loads shadow relevant uniforms)
  104. gPipeline.bindDeferredShader(*simple_shader);
  105. }
  106. else
  107. {
  108. //update depth buffer sampler
  109. gPipeline.mScreen.flush();
  110. gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
  111. 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
  112. gPipeline.mDeferredDepth.bindTarget();
  113. simple_shader = NULL;
  114. fullbright_shader = NULL;
  115. gObjectFullbrightAlphaMaskProgram.bind();
  116. gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);
  117. }
  118. deferred_render = TRUE;
  119. if (mVertexShaderLevel > 0)
  120. {
  121. // Start out with no shaders.
  122. current_shader = target_shader = NULL;
  123. }
  124. gPipeline.enableLightsDynamic();
  125. }
  126. void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
  127. {
  128. if (pass == 1)
  129. {
  130. gPipeline.mDeferredDepth.flush();
  131. gPipeline.mScreen.bindTarget();
  132. gObjectFullbrightAlphaMaskProgram.unbind();
  133. }
  134. deferred_render = FALSE;
  135. endRenderPass(pass);
  136. }
  137. void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
  138. {
  139. render(pass);
  140. }
  141. void LLDrawPoolAlpha::beginRenderPass(S32 pass)
  142. {
  143. LLFastTimer t(FTM_RENDER_ALPHA);
  144. if (LLPipeline::sUnderWaterRender)
  145. {
  146. simple_shader = &gObjectSimpleWaterAlphaMaskProgram;
  147. fullbright_shader = &gObjectFullbrightWaterAlphaMaskProgram;
  148. emissive_shader = &gObjectEmissiveWaterProgram;
  149. }
  150. else
  151. {
  152. simple_shader = &gObjectSimpleAlphaMaskProgram;
  153. fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
  154. emissive_shader = &gObjectEmissiveProgram;
  155. }
  156. if (mVertexShaderLevel > 0)
  157. {
  158. // Start out with no shaders.
  159. current_shader = target_shader = NULL;
  160. LLGLSLShader::bindNoShader();
  161. }
  162. gPipeline.enableLightsDynamic();
  163. }
  164. void LLDrawPoolAlpha::endRenderPass( S32 pass )
  165. {
  166. LLFastTimer t(FTM_RENDER_ALPHA);
  167. LLRenderPass::endRenderPass(pass);
  168. if(gPipeline.canUseWindLightShaders())
  169. {
  170. LLGLSLShader::bindNoShader();
  171. }
  172. }
  173. void LLDrawPoolAlpha::render(S32 pass)
  174. {
  175. LLFastTimer t(FTM_RENDER_ALPHA);
  176. LLGLSPipelineAlpha gls_pipeline_alpha;
  177. if (deferred_render && pass == 1)
  178. { //depth only
  179. gGL.setColorMask(false, false);
  180. }
  181. else
  182. {
  183. gGL.setColorMask(true, true);
  184. }
  185. if (LLPipeline::sAutoMaskAlphaNonDeferred)
  186. {
  187. mColorSFactor = LLRender::BF_ONE; // }
  188. mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow
  189. mAlphaSFactor = LLRender::BF_ZERO;
  190. mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds
  191. gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
  192. if (mVertexShaderLevel > 0)
  193. {
  194. if (!LLPipeline::sRenderDeferred || !deferred_render)
  195. {
  196. simple_shader->bind();
  197. simple_shader->setMinimumAlpha(0.33f);
  198. pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
  199. }
  200. if (fullbright_shader)
  201. {
  202. fullbright_shader->bind();
  203. fullbright_shader->setMinimumAlpha(0.33f);
  204. }
  205. pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
  206. //LLGLSLShader::bindNoShader();
  207. }
  208. else
  209. {
  210. gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f); //OK
  211. gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
  212. pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask());
  213. gPipeline.enableLightsDynamic();
  214. pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
  215. gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
  216. }
  217. }
  218. LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ||
  219. (deferred_render && pass == 1) ? GL_TRUE : GL_FALSE);
  220. if (deferred_render && pass == 1)
  221. {
  222. gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
  223. }
  224. else
  225. {
  226. mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend
  227. mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
  228. mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression
  229. mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
  230. gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
  231. if (mVertexShaderLevel > 0)
  232. {
  233. if (LLPipeline::sImpostorRender)
  234. {
  235. fullbright_shader->bind();
  236. fullbright_shader->setMinimumAlpha(0.5f);
  237. simple_shader->bind();
  238. simple_shader->setMinimumAlpha(0.5f);
  239. }
  240. else
  241. {
  242. fullbright_shader->bind();
  243. fullbright_shader->setMinimumAlpha(0.f);
  244. simple_shader->bind();
  245. simple_shader->setMinimumAlpha(0.f);
  246. }
  247. }
  248. else
  249. {
  250. if (LLPipeline::sImpostorRender)
  251. {
  252. gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); //OK
  253. }
  254. else
  255. {
  256. gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); //OK
  257. }
  258. }
  259. }
  260. if (mVertexShaderLevel > 0)
  261. {
  262. renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX);
  263. }
  264. else
  265. {
  266. renderAlpha(getVertexDataMask());
  267. }
  268. gGL.setColorMask(true, false);
  269. if (deferred_render && pass == 1)
  270. {
  271. gGL.setSceneBlendType(LLRender::BT_ALPHA);
  272. }
  273. if (sShowDebugAlpha)
  274. {
  275. BOOL shaders = gPipeline.canUseVertexShaders();
  276. if(shaders)
  277. {
  278. gHighlightProgram.bind();
  279. }
  280. else
  281. {
  282. gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
  283. }
  284. gGL.diffuseColor4f(1,0,0,1);
  285. LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f);
  286. gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ;
  287. renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
  288. LLVertexBuffer::MAP_TEXCOORD0);
  289. pushBatches(LLRenderPass::PASS_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
  290. pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
  291. if(shaders)
  292. {
  293. gHighlightProgram.unbind();
  294. }
  295. }
  296. }
  297. void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
  298. {
  299. for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
  300. {
  301. LLSpatialGroup* group = *i;
  302. if (group->mSpatialPartition->mRenderByGroup &&
  303. !group->isDead())
  304. {
  305. LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
  306. for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
  307. {
  308. LLDrawInfo& params = **k;
  309. if (params.mParticle)
  310. {
  311. continue;
  312. }
  313. LLRenderPass::applyModelMatrix(params);
  314. if (params.mGroup)
  315. {
  316. params.mGroup->rebuildMesh();
  317. }
  318. params.mVertexBuffer->setBuffer(mask);
  319. params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
  320. gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
  321. }
  322. }
  323. }
  324. }
  325. void LLDrawPoolAlpha::renderAlpha(U32 mask)
  326. {
  327. BOOL initialized_lighting = FALSE;
  328. BOOL light_enabled = TRUE;
  329. BOOL use_shaders = gPipeline.canUseVertexShaders();
  330. for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
  331. {
  332. LLSpatialGroup* group = *i;
  333. llassert(group);
  334. llassert(group->mSpatialPartition);
  335. if (group->mSpatialPartition->mRenderByGroup &&
  336. !group->isDead())
  337. {
  338. bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow.
  339. // All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress.
  340. group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE &&
  341. group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE;
  342. LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
  343. for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
  344. {
  345. LLDrawInfo& params = **k;
  346. LLRenderPass::applyModelMatrix(params);
  347. if (params.mFullbright)
  348. {
  349. // Turn off lighting if it hasn't already been so.
  350. if (light_enabled || !initialized_lighting)
  351. {
  352. initialized_lighting = TRUE;
  353. if (use_shaders)
  354. {
  355. target_shader = fullbright_shader;
  356. }
  357. else
  358. {
  359. gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
  360. }
  361. light_enabled = FALSE;
  362. }
  363. }
  364. // Turn on lighting if it isn't already.
  365. else if (!light_enabled || !initialized_lighting)
  366. {
  367. initialized_lighting = TRUE;
  368. if (use_shaders)
  369. {
  370. target_shader = simple_shader;
  371. }
  372. else
  373. {
  374. gPipeline.enableLightsDynamic();
  375. }
  376. light_enabled = TRUE;
  377. }
  378. // If we need shaders, and we're not ALREADY using the proper shader, then bind it
  379. // (this way we won't rebind shaders unnecessarily).
  380. if(use_shaders && (current_shader != target_shader))
  381. {
  382. llassert(target_shader != NULL);
  383. current_shader = target_shader;
  384. current_shader->bind();
  385. }
  386. else if (!use_shaders && current_shader != NULL)
  387. {
  388. LLGLSLShader::bindNoShader();
  389. current_shader = NULL;
  390. }
  391. if (params.mGroup)
  392. {
  393. params.mGroup->rebuildMesh();
  394. }
  395. bool tex_setup = false;
  396. if (use_shaders && params.mTextureList.size() > 1)
  397. {
  398. for (U32 i = 0; i < params.mTextureList.size(); ++i)
  399. {
  400. if (params.mTextureList[i].notNull())
  401. {
  402. gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
  403. }
  404. }
  405. }
  406. else
  407. { //not batching textures or batch has only 1 texture -- might need a texture matrix
  408. if (params.mTexture.notNull())
  409. {
  410. params.mTexture->addTextureStats(params.mVSize);
  411. gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
  412. if (params.mTextureMatrix)
  413. {
  414. tex_setup = true;
  415. gGL.getTexUnit(0)->activate();
  416. gGL.matrixMode(LLRender::MM_TEXTURE);
  417. gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
  418. gPipeline.mTextureMatrixOps++;
  419. }
  420. }
  421. else
  422. {
  423. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  424. }
  425. }
  426. params.mVertexBuffer->setBuffer(mask);
  427. params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
  428. gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
  429. // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
  430. if (current_shader &&
  431. draw_glow_for_this_partition &&
  432. params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
  433. {
  434. // install glow-accumulating blend mode
  435. gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
  436. LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
  437. emissive_shader->bind();
  438. // glow doesn't use vertex colors from the mesh data
  439. params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
  440. // do the actual drawing, again
  441. params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
  442. gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
  443. // restore our alpha blend mode
  444. gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
  445. current_shader->bind();
  446. }
  447. if (tex_setup)
  448. {
  449. gGL.getTexUnit(0)->activate();
  450. gGL.loadIdentity();
  451. gGL.matrixMode(LLRender::MM_MODELVIEW);
  452. }
  453. }
  454. }
  455. }
  456. LLVertexBuffer::unbind();
  457. if (!light_enabled)
  458. {
  459. gPipeline.enableLightsDynamic();
  460. }
  461. }