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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lldrawpooltree.cpp
  3.  * @brief LLDrawPoolTree 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 "lldrawpooltree.h"
  34. #include "lldrawable.h"
  35. #include "llface.h"
  36. #include "llsky.h"
  37. #include "llvotree.h"
  38. #include "pipeline.h"
  39. #include "llviewercamera.h"
  40. #include "llviewershadermgr.h"
  41. #include "llrender.h"
  42. #include "llviewercontrol.h"
  43. S32 LLDrawPoolTree::sDiffTex = 0;
  44. static LLGLSLShader* shader = NULL;
  45. static LLFastTimer::DeclareTimer FTM_SHADOW_TREE("Tree Shadow");
  46. LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) :
  47. LLFacePool(POOL_TREE),
  48. mTexturep(texturep)
  49. {
  50. mTexturep->setAddressMode(LLTexUnit::TAM_WRAP);
  51. }
  52. LLDrawPool *LLDrawPoolTree::instancePool()
  53. {
  54. return new LLDrawPoolTree(mTexturep);
  55. }
  56. void LLDrawPoolTree::prerender()
  57. {
  58. mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
  59. }
  60. void LLDrawPoolTree::beginRenderPass(S32 pass)
  61. {
  62. LLFastTimer t(FTM_RENDER_TREES);
  63. gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
  64. if (LLPipeline::sUnderWaterRender)
  65. {
  66. shader = &gObjectSimpleWaterProgram;
  67. }
  68. else
  69. {
  70. shader = &gObjectSimpleProgram;
  71. }
  72. if (gPipeline.canUseWindLightShadersOnObjects())
  73. {
  74. shader->bind();
  75. }
  76. else
  77. {
  78. gPipeline.enableLightsDynamic();
  79. }
  80. }
  81. void LLDrawPoolTree::render(S32 pass)
  82. {
  83. LLFastTimer t(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES);
  84. if (mDrawFace.empty())
  85. {
  86. return;
  87. }
  88. LLGLEnable test(GL_ALPHA_TEST);
  89. LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);
  90. if (gSavedSettings.getBOOL("RenderAnimateTrees"))
  91. {
  92. renderTree();
  93. }
  94. else
  95. {
  96. gGL.getTexUnit(sDiffTex)->bind(mTexturep);
  97. for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
  98.  iter != mDrawFace.end(); iter++)
  99. {
  100. LLFace *face = *iter;
  101. face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
  102. face->mVertexBuffer->drawRange(LLRender::TRIANGLES, 0, face->mVertexBuffer->getRequestedVerts()-1, face->mVertexBuffer->getRequestedIndices(), 0); 
  103. gPipeline.addTrianglesDrawn(face->mVertexBuffer->getRequestedIndices()/3);
  104. }
  105. }
  106. }
  107. void LLDrawPoolTree::endRenderPass(S32 pass)
  108. {
  109. LLFastTimer t(FTM_RENDER_TREES);
  110. gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
  111. if (gPipeline.canUseWindLightShadersOnObjects())
  112. {
  113. shader->unbind();
  114. }
  115. }
  116. //============================================
  117. // deferred implementation
  118. //============================================
  119. void LLDrawPoolTree::beginDeferredPass(S32 pass)
  120. {
  121. LLFastTimer t(FTM_RENDER_TREES);
  122. gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
  123. shader = &gDeferredTreeProgram;
  124. shader->bind();
  125. }
  126. void LLDrawPoolTree::renderDeferred(S32 pass)
  127. {
  128. render(pass);
  129. }
  130. void LLDrawPoolTree::endDeferredPass(S32 pass)
  131. {
  132. LLFastTimer t(FTM_RENDER_TREES);
  133. gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
  134. shader->unbind();
  135. }
  136. //============================================
  137. // shadow implementation
  138. //============================================
  139. void LLDrawPoolTree::beginShadowPass(S32 pass)
  140. {
  141. LLFastTimer t(FTM_SHADOW_TREE);
  142. gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
  143. glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"),
  144. gSavedSettings.getF32("RenderDeferredTreeShadowBias"));
  145. gDeferredShadowProgram.bind();
  146. }
  147. void LLDrawPoolTree::renderShadow(S32 pass)
  148. {
  149. render(pass);
  150. }
  151. void LLDrawPoolTree::endShadowPass(S32 pass)
  152. {
  153. LLFastTimer t(FTM_SHADOW_TREE);
  154. gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
  155. glPolygonOffset(gSavedSettings.getF32("RenderDeferredSpotShadowOffset"),
  156. gSavedSettings.getF32("RenderDeferredSpotShadowBias"));
  157. //gDeferredShadowProgram.unbind();
  158. }
  159. void LLDrawPoolTree::renderForSelect()
  160. {
  161. if (mDrawFace.empty())
  162. {
  163. return;
  164. }
  165. LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f);
  166. LLGLSObjectSelectAlpha gls_alpha;
  167. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  168. gGL.setSceneBlendType(LLRender::BT_REPLACE);
  169. gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
  170. gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
  171. gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);
  172. if (gSavedSettings.getBOOL("RenderAnimateTrees"))
  173. {
  174. renderTree(TRUE);
  175. }
  176. else
  177. {
  178. gGL.getTexUnit(sDiffTex)->bind(mTexturep);
  179. for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
  180.  iter != mDrawFace.end(); iter++)
  181. {
  182. LLFace *face = *iter;
  183. LLDrawable *drawablep = face->getDrawable();
  184. if (drawablep->isDead() || face->mVertexBuffer.isNull())
  185. {
  186. continue;
  187. }
  188. // Render each of the trees
  189. LLVOTree *treep = (LLVOTree *)drawablep->getVObj().get();
  190. LLColor4U color(255,255,255,255);
  191. if (treep->mGLName != 0)
  192. {
  193. S32 name = treep->mGLName;
  194. color = LLColor4U((U8)(name >> 16), (U8)(name >> 8), (U8)name, 255);
  195. LLFacePool::LLOverrideFaceColor col(this, color);
  196. face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
  197. face->mVertexBuffer->drawRange(LLRender::TRIANGLES, 0, face->mVertexBuffer->getRequestedVerts()-1, face->mVertexBuffer->getRequestedIndices(), 0); 
  198. gPipeline.addTrianglesDrawn(face->mVertexBuffer->getRequestedIndices()/3);
  199. }
  200. }
  201. }
  202. gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
  203. gGL.setSceneBlendType(LLRender::BT_ALPHA);
  204. gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
  205. }
  206. void LLDrawPoolTree::renderTree(BOOL selecting)
  207. {
  208. LLGLState normalize(GL_NORMALIZE, TRUE);
  209. // Bind the texture for this tree.
  210. gGL.getTexUnit(sDiffTex)->bind(mTexturep.get(), TRUE);
  211. U32 indices_drawn = 0;
  212. glMatrixMode(GL_MODELVIEW);
  213. for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
  214.  iter != mDrawFace.end(); iter++)
  215. {
  216. LLFace *face = *iter;
  217. LLDrawable *drawablep = face->getDrawable();
  218. if (drawablep->isDead() || face->mVertexBuffer.isNull())
  219. {
  220. continue;
  221. }
  222. face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
  223. U16* indicesp = (U16*) face->mVertexBuffer->getIndicesPointer();
  224. // Render each of the trees
  225. LLVOTree *treep = (LLVOTree *)drawablep->getVObj().get();
  226. LLColor4U color(255,255,255,255);
  227. if (!selecting || treep->mGLName != 0)
  228. {
  229. if (selecting)
  230. {
  231. S32 name = treep->mGLName;
  232. color = LLColor4U((U8)(name >> 16), (U8)(name >> 8), (U8)name, 255);
  233. }
  234. gGLLastMatrix = NULL;
  235. glLoadMatrixd(gGLModelView);
  236. //glPushMatrix();
  237. F32 mat[16];
  238. for (U32 i = 0; i < 16; i++)
  239. mat[i] = (F32) gGLModelView[i];
  240. LLMatrix4 matrix(mat);
  241. // Translate to tree base  HACK - adjustment in Z plants tree underground
  242. const LLVector3 &pos_agent = treep->getPositionAgent();
  243. //glTranslatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
  244. LLMatrix4 trans_mat;
  245. trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
  246. trans_mat *= matrix;
  247. // Rotate to tree position and bend for current trunk/wind
  248. // Note that trunk stiffness controls the amount of bend at the trunk as 
  249. // opposed to the crown of the tree
  250. // 
  251. const F32 TRUNK_STIFF = 22.f;
  252. LLQuaternion rot = 
  253. LLQuaternion(treep->mTrunkBend.magVec()*TRUNK_STIFF*DEG_TO_RAD, LLVector4(treep->mTrunkBend.mV[VX], treep->mTrunkBend.mV[VY], 0)) *
  254. LLQuaternion(90.f*DEG_TO_RAD, LLVector4(0,0,1)) *
  255. treep->getRotation();
  256. LLMatrix4 rot_mat(rot);
  257. rot_mat *= trans_mat;
  258. F32 radius = treep->getScale().magVec()*0.05f;
  259. LLMatrix4 scale_mat;
  260. scale_mat.mMatrix[0][0] = 
  261. scale_mat.mMatrix[1][1] =
  262. scale_mat.mMatrix[2][2] = radius;
  263. scale_mat *= rot_mat;
  264. const F32 THRESH_ANGLE_FOR_BILLBOARD = 15.f;
  265. const F32 BLEND_RANGE_FOR_BILLBOARD = 3.f;
  266. F32 droop = treep->mDroop + 25.f*(1.f - treep->mTrunkBend.magVec());
  267. S32 stop_depth = 0;
  268. F32 app_angle = treep->getAppAngle()*LLVOTree::sTreeFactor;
  269. F32 alpha = 1.0;
  270. S32 trunk_LOD = 0;
  271. for (S32 j = 0; j < 4; j++)
  272. {
  273. if (app_angle > LLVOTree::sLODAngles[j])
  274. {
  275. trunk_LOD = j;
  276. break;
  277. }
  278. if (app_angle < (THRESH_ANGLE_FOR_BILLBOARD - BLEND_RANGE_FOR_BILLBOARD))
  279. {
  280. //
  281. //  Draw only the billboard 
  282. //
  283. //  Only the billboard, can use closer to normal alpha func.
  284. stop_depth = -1;
  285. LLFacePool::LLOverrideFaceColor clr(this, color); 
  286. indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha);
  287. }
  288. else // if (app_angle > (THRESH_ANGLE_FOR_BILLBOARD + BLEND_RANGE_FOR_BILLBOARD))
  289. {
  290. //
  291. //  Draw only the full geometry tree
  292. //
  293. //stop_depth = (app_angle < THRESH_ANGLE_FOR_RECURSION_REDUCTION);
  294. LLFacePool::LLOverrideFaceColor clr(this, color); 
  295. indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha);
  296. }
  297. //glPopMatrix();
  298. }
  299. }
  300. }
  301. BOOL LLDrawPoolTree::verify() const
  302. {
  303. /* BOOL ok = TRUE;
  304. if (!ok)
  305. {
  306. printDebugInfo();
  307. }
  308. return ok;*/
  309. return TRUE;
  310. }
  311. LLViewerTexture *LLDrawPoolTree::getTexture()
  312. {
  313. return mTexturep;
  314. }
  315. LLViewerTexture *LLDrawPoolTree::getDebugTexture()
  316. {
  317. return mTexturep;
  318. }
  319. LLColor3 LLDrawPoolTree::getDebugColor() const
  320. {
  321. return LLColor3(1.f, 0.f, 1.f);
  322. }