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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lldrawpoolalpha.cpp
  3.  * @brief LLDrawPoolAlpha class implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-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 "llviewerprecompiledheaders.h"
  33. #include "lldrawpoolalpha.h"
  34. #include "llglheaders.h"
  35. #include "llviewercontrol.h"
  36. #include "llcriticaldamp.h"
  37. #include "llfasttimer.h"
  38. #include "llrender.h"
  39. #include "llcubemap.h"
  40. #include "llsky.h"
  41. #include "lldrawable.h"
  42. #include "llface.h"
  43. #include "llviewercamera.h"
  44. #include "llviewertexturelist.h" // For debugging
  45. #include "llviewerobjectlist.h" // For debugging
  46. #include "llviewerwindow.h"
  47. #include "pipeline.h"
  48. #include "llviewershadermgr.h"
  49. #include "llviewerregion.h"
  50. #include "lldrawpoolwater.h"
  51. #include "llspatialpartition.h"
  52. BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
  53. static BOOL deferred_render = FALSE;
  54. LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
  55. LLRenderPass(type), current_shader(NULL), target_shader(NULL),
  56. simple_shader(NULL), fullbright_shader(NULL)
  57. {
  58. }
  59. LLDrawPoolAlpha::~LLDrawPoolAlpha()
  60. {
  61. }
  62. void LLDrawPoolAlpha::prerender()
  63. {
  64. mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
  65. }
  66. S32 LLDrawPoolAlpha::getNumDeferredPasses()
  67. {
  68. return 1;
  69. }
  70. void LLDrawPoolAlpha::beginDeferredPass(S32 pass)
  71. {
  72. }
  73. void LLDrawPoolAlpha::endDeferredPass(S32 pass)
  74. {
  75. }
  76. void LLDrawPoolAlpha::renderDeferred(S32 pass)
  77. {
  78. gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
  79. {
  80. LLFastTimer t(FTM_RENDER_GRASS);
  81. gDeferredTreeProgram.bind();
  82. LLGLEnable test(GL_ALPHA_TEST);
  83. //render alpha masked objects
  84. LLRenderPass::renderTexture(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
  85. gDeferredTreeProgram.unbind();
  86. }
  87. gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
  88. }
  89. S32 LLDrawPoolAlpha::getNumPostDeferredPasses() 
  90. return 1; 
  91. }
  92. void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) 
  93. LLFastTimer t(FTM_RENDER_ALPHA);
  94. simple_shader = &gDeferredAlphaProgram;
  95. fullbright_shader = &gDeferredFullbrightProgram;
  96. deferred_render = TRUE;
  97. if (mVertexShaderLevel > 0)
  98. {
  99. // Start out with no shaders.
  100. current_shader = target_shader = NULL;
  101. }
  102. gPipeline.enableLightsDynamic();
  103. }
  104. void LLDrawPoolAlpha::endPostDeferredPass(S32 pass) 
  105. deferred_render = FALSE;
  106. endRenderPass(pass);
  107. }
  108. void LLDrawPoolAlpha::renderPostDeferred(S32 pass) 
  109. render(pass); 
  110. }
  111. void LLDrawPoolAlpha::beginRenderPass(S32 pass)
  112. {
  113. LLFastTimer t(FTM_RENDER_ALPHA);
  114. if (LLPipeline::sUnderWaterRender)
  115. {
  116. simple_shader = &gObjectSimpleWaterProgram;
  117. fullbright_shader = &gObjectFullbrightWaterProgram;
  118. }
  119. else
  120. {
  121. simple_shader = &gObjectSimpleProgram;
  122. fullbright_shader = &gObjectFullbrightProgram;
  123. }
  124. if (mVertexShaderLevel > 0)
  125. {
  126. // Start out with no shaders.
  127. current_shader = target_shader = NULL;
  128. LLGLSLShader::bindNoShader();
  129. }
  130. gPipeline.enableLightsDynamic();
  131. }
  132. void LLDrawPoolAlpha::endRenderPass( S32 pass )
  133. {
  134. LLFastTimer t(FTM_RENDER_ALPHA);
  135. LLRenderPass::endRenderPass(pass);
  136. if(gPipeline.canUseWindLightShaders()) 
  137. {
  138. LLGLSLShader::bindNoShader();
  139. }
  140. }
  141. void LLDrawPoolAlpha::render(S32 pass)
  142. {
  143. LLFastTimer t(FTM_RENDER_ALPHA);
  144. LLGLSPipelineAlpha gls_pipeline_alpha;
  145. if (LLPipeline::sFastAlpha && !deferred_render)
  146. {
  147. LLGLDisable blend_disable(GL_BLEND);
  148. gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f);
  149. if (mVertexShaderLevel > 0)
  150. {
  151. if (!LLPipeline::sRenderDeferred)
  152. {
  153. simple_shader->bind();
  154. pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
  155. }
  156. fullbright_shader->bind();
  157. pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask());
  158. LLGLSLShader::bindNoShader();
  159. }
  160. else
  161. {
  162. gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
  163. pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask());
  164. gPipeline.enableLightsDynamic();
  165. pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
  166. }
  167. gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
  168. }
  169. LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE);
  170. renderAlpha(getVertexDataMask());
  171. if (deferred_render && current_shader != NULL)
  172. {
  173. gPipeline.unbindDeferredShader(*current_shader);
  174. }
  175. if (sShowDebugAlpha)
  176. {
  177. if(gPipeline.canUseWindLightShaders()) 
  178. {
  179. LLGLSLShader::bindNoShader();
  180. }
  181. gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
  182. glColor4f(1,0,0,1);
  183. LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f*1024.f);
  184. gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE) ;
  185. renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
  186. LLVertexBuffer::MAP_TEXCOORD0);
  187. }
  188. }
  189. void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
  190. {
  191. for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
  192. {
  193. LLSpatialGroup* group = *i;
  194. if (group->mSpatialPartition->mRenderByGroup &&
  195. !group->isDead())
  196. {
  197. LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
  198. for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
  199. {
  200. LLDrawInfo& params = **k;
  201. if (params.mParticle)
  202. {
  203. continue;
  204. }
  205. LLRenderPass::applyModelMatrix(params);
  206. if (params.mGroup)
  207. {
  208. params.mGroup->rebuildMesh();
  209. }
  210. params.mVertexBuffer->setBuffer(mask);
  211. params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
  212. gPipeline.addTrianglesDrawn(params.mCount/3);
  213. }
  214. }
  215. }
  216. }
  217. void LLDrawPoolAlpha::renderAlpha(U32 mask)
  218. {
  219. BOOL initialized_lighting = FALSE;
  220. BOOL light_enabled = TRUE;
  221. S32 diffuse_channel = 0;
  222. //BOOL is_particle = FALSE;
  223. BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders())
  224. || gPipeline.canUseWindLightShadersOnObjects();
  225. // check to see if it's a particle and if it's "close"
  226. {
  227. if (LLPipeline::sImpostorRender)
  228. {
  229. gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
  230. }
  231. else
  232. {
  233. gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
  234. }
  235. }
  236. for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
  237. {
  238. LLSpatialGroup* group = *i;
  239. if (group->mSpatialPartition->mRenderByGroup &&
  240. !group->isDead())
  241. {
  242. LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
  243. for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
  244. {
  245. LLDrawInfo& params = **k;
  246. LLRenderPass::applyModelMatrix(params);
  247. if (params.mFullbright)
  248. {
  249. // Turn off lighting if it hasn't already been so.
  250. if (light_enabled || !initialized_lighting)
  251. {
  252. initialized_lighting = TRUE;
  253. if (use_shaders) 
  254. {
  255. target_shader = fullbright_shader;
  256. }
  257. else
  258. {
  259. gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
  260. }
  261. light_enabled = FALSE;
  262. }
  263. }
  264. // Turn on lighting if it isn't already.
  265. else if (!light_enabled || !initialized_lighting)
  266. {
  267. initialized_lighting = TRUE;
  268. if (use_shaders) 
  269. {
  270. target_shader = simple_shader;
  271. }
  272. else
  273. {
  274. gPipeline.enableLightsDynamic();
  275. }
  276. light_enabled = TRUE;
  277. }
  278. // If we need shaders, and we're not ALREADY using the proper shader, then bind it
  279. // (this way we won't rebind shaders unnecessarily).
  280. if(use_shaders && (current_shader != target_shader))
  281. {
  282. llassert(target_shader != NULL);
  283. if (deferred_render && current_shader != NULL)
  284. {
  285. gPipeline.unbindDeferredShader(*current_shader);
  286. diffuse_channel = 0;
  287. }
  288. current_shader = target_shader;
  289. if (deferred_render)
  290. {
  291. gPipeline.bindDeferredShader(*current_shader);
  292. diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
  293. }
  294. else
  295. {
  296. current_shader->bind();
  297. }
  298. }
  299. else if (!use_shaders && current_shader != NULL)
  300. {
  301. if (deferred_render)
  302. {
  303. gPipeline.unbindDeferredShader(*current_shader);
  304. diffuse_channel = 0;
  305. }
  306. LLGLSLShader::bindNoShader();
  307. current_shader = NULL;
  308. }
  309. if (params.mGroup)
  310. {
  311. params.mGroup->rebuildMesh();
  312. }
  313. if (params.mTexture.notNull())
  314. {
  315. gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get());
  316. if(params.mTexture.notNull())
  317. {
  318. params.mTexture->addTextureStats(params.mVSize);
  319. }
  320. if (params.mTextureMatrix)
  321. {
  322. gGL.getTexUnit(0)->activate();
  323. glMatrixMode(GL_TEXTURE);
  324. glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
  325. gPipeline.mTextureMatrixOps++;
  326. }
  327. }
  328. params.mVertexBuffer->setBuffer(mask);
  329. params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
  330. gPipeline.addTrianglesDrawn(params.mCount/3);
  331. if (params.mTextureMatrix && params.mTexture.notNull())
  332. {
  333. gGL.getTexUnit(0)->activate();
  334. glLoadIdentity();
  335. glMatrixMode(GL_MODELVIEW);
  336. }
  337. }
  338. }
  339. }
  340. if (deferred_render && current_shader != NULL)
  341. {
  342. gPipeline.unbindDeferredShader(*current_shader);
  343. LLVertexBuffer::unbind();
  344. LLGLState::checkStates();
  345. LLGLState::checkTextureChannels();
  346. LLGLState::checkClientArrays();
  347. }
  348. if (!light_enabled)
  349. {
  350. gPipeline.enableLightsDynamic();
  351. }
  352. }