lldrawpooltree.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /**
  2. * @file lldrawpooltree.cpp
  3. * @brief LLDrawPoolTree class implementation
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewergpl$
  6. *
  7. * Copyright (c) 2002-2009, 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 "llfasttimer.h"
  35. #include "llrender.h"
  36. #include "lldrawable.h"
  37. #include "llenvironment.h"
  38. #include "llface.h"
  39. #include "llpipeline.h"
  40. #include "llviewercontrol.h"
  41. #include "llviewerregion.h"
  42. #include "llviewershadermgr.h"
  43. #include "llvotree.h"
  44. static LLGLSLShader* sShaderp = NULL;
  45. LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture* texturep)
  46. : LLFacePool(POOL_TREE),
  47. mTexturep(texturep)
  48. {
  49. mTexturep->setAddressMode(LLTexUnit::TAM_WRAP);
  50. }
  51. //virtual
  52. void LLDrawPoolTree::prerender()
  53. {
  54. mShaderLevel =
  55. gViewerShaderMgrp->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
  56. }
  57. // For EE rendering only
  58. //virtual
  59. void LLDrawPoolTree::beginRenderPass(S32)
  60. {
  61. LL_FAST_TIMER(FTM_RENDER_TREES);
  62. if (LLPipeline::sUnderWaterRender)
  63. {
  64. sShaderp = &gTreeWaterProgram;
  65. }
  66. else
  67. {
  68. sShaderp = &gTreeProgram;
  69. }
  70. if (gPipeline.shadersLoaded())
  71. {
  72. sShaderp->bind();
  73. sShaderp->setMinimumAlpha(0.5f);
  74. gGL.diffuseColor4f(1.f, 1.f, 1.f, 1.f);
  75. }
  76. else
  77. {
  78. gPipeline.enableLightsDynamic();
  79. gGL.flush();
  80. }
  81. }
  82. // For EE rendering only
  83. //virtual
  84. void LLDrawPoolTree::endRenderPass(S32)
  85. {
  86. LL_FAST_TIMER(FTM_RENDER_TREES);
  87. if (gPipeline.canUseWindLightShaders())
  88. {
  89. sShaderp->unbind();
  90. }
  91. if (mShaderLevel <= 0)
  92. {
  93. gGL.flush();
  94. }
  95. }
  96. //virtual
  97. void LLDrawPoolTree::renderDeferred(S32)
  98. {
  99. LL_FAST_TIMERS(LLPipeline::sShadowRender, FTM_SHADOW_TREE,
  100. FTM_RENDER_TREES);
  101. if (mDrawFace.empty())
  102. {
  103. return;
  104. }
  105. if (LLVOTree::sRenderAnimateTrees)
  106. {
  107. renderTree();
  108. return;
  109. }
  110. gGL.getTexUnit(0)->bindFast(mTexturep);
  111. // Keep Linden tree textures at full res
  112. constexpr F32 MAX_AREA = 1024.f * 1024.f;
  113. gPipeline.touchTexture(mTexturep, MAX_AREA);
  114. for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(),
  115. end = mDrawFace.end();
  116. iter != end; ++iter)
  117. {
  118. LLFace* facep = *iter;
  119. if (!facep) continue; // Paranoia
  120. LLVertexBuffer* buffp = facep->getVertexBuffer();
  121. LLDrawable* drawablep = facep->getDrawable();
  122. if (!buffp || !drawablep) continue;
  123. LLViewerRegion* regionp = drawablep->getRegion();
  124. if (!regionp) continue;
  125. LLRenderPass::applyModelMatrix(&(regionp->mRenderMatrix));
  126. buffp->setBufferFast(LLDrawPoolTree::VERTEX_DATA_MASK);
  127. buffp->drawRangeFast(0, buffp->getNumVerts() - 1,
  128. buffp->getNumIndices(), 0);
  129. }
  130. }
  131. //virtual
  132. void LLDrawPoolTree::beginDeferredPass(S32)
  133. {
  134. LL_FAST_TIMER(FTM_RENDER_TREES);
  135. sShaderp = &gDeferredTreeProgram;
  136. sShaderp->bind();
  137. sShaderp->setMinimumAlpha(0.5f);
  138. }
  139. //virtual
  140. void LLDrawPoolTree::endDeferredPass(S32)
  141. {
  142. LL_FAST_TIMER(FTM_RENDER_TREES);
  143. sShaderp->unbind();
  144. }
  145. //virtual
  146. void LLDrawPoolTree::beginShadowPass(S32)
  147. {
  148. LL_FAST_TIMER(FTM_SHADOW_TREE);
  149. static LLCachedControl<F32> shadow_offset(gSavedSettings,
  150. "RenderDeferredTreeShadowOffset");
  151. static LLCachedControl<F32> shadow_bias(gSavedSettings,
  152. "RenderDeferredTreeShadowBias");
  153. glPolygonOffset(shadow_offset, shadow_bias);
  154. gDeferredTreeShadowProgram.bind();
  155. S32 sun_up = gEnvironment.getIsSunUp() ? 1 : 0;
  156. gDeferredTreeShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
  157. gDeferredTreeShadowProgram.setMinimumAlpha(0.5f);
  158. }
  159. //virtual
  160. void LLDrawPoolTree::endShadowPass(S32)
  161. {
  162. LL_FAST_TIMER(FTM_SHADOW_TREE);
  163. static LLCachedControl<F32> shadow_offset(gSavedSettings,
  164. "RenderDeferredSpotShadowOffset");
  165. static LLCachedControl<F32> shadow_bias(gSavedSettings,
  166. "RenderDeferredSpotShadowBias");
  167. glPolygonOffset(shadow_offset, shadow_bias);
  168. gDeferredTreeShadowProgram.unbind();
  169. }
  170. void LLDrawPoolTree::renderTree()
  171. {
  172. // Bind the texture for this tree.
  173. gGL.getTexUnit(0)->bind(mTexturep.get());
  174. gGL.matrixMode(LLRender::MM_MODELVIEW);
  175. static const LLColor4U color(255, 255, 255, 255);
  176. LLFacePool::LLOverrideFaceColor clr(this, color);
  177. for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(),
  178. end = mDrawFace.end();
  179. iter != end; ++iter)
  180. {
  181. LLFace* face = *iter;
  182. if (!face || !face->getVertexBuffer())
  183. {
  184. continue;
  185. }
  186. LLDrawable* drawablep = face->getDrawable();
  187. if (!drawablep || drawablep->isDead())
  188. {
  189. continue;
  190. }
  191. face->getVertexBuffer()->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
  192. // Render each of the trees
  193. LLVOTree* treep = (LLVOTree*)drawablep->getVObj().get();
  194. if (!treep) continue;
  195. gGLLastMatrix = NULL;
  196. gGL.loadMatrix(gGLModelView.getF32ptr());
  197. LLMatrix4 matrix(gGLModelView.getF32ptr());
  198. // Translate to tree base.
  199. const LLVector3& pos_agent = treep->getPositionAgent();
  200. LLMatrix4 trans_mat;
  201. // *HACK: adjustment in Z plants tree underground
  202. trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY],
  203. pos_agent.mV[VZ] - 0.1f);
  204. trans_mat *= matrix;
  205. // Rotate to tree position and bend for current trunk/wind. Note that
  206. // trunk stiffness controls the amount of bend at the trunk as opposed
  207. // to the crown of the tree
  208. static const LLVector4 z_axis(0.f, 0.f, 1.f, 1.f);
  209. static const LLQuaternion qz(F_PI_BY_TWO, z_axis);
  210. LLQuaternion rot(treep->mTrunkBend.length() * TRUNK_STIFF,
  211. LLVector4(treep->mTrunkBend.mV[VX],
  212. treep->mTrunkBend.mV[VY], 0.f));
  213. LLMatrix4 rot_mat(rot * qz * treep->getRotation());
  214. rot_mat *= trans_mat;
  215. F32 radius = treep->getScale().length() * 0.05f;
  216. LLMatrix4 scale_mat;
  217. scale_mat.mMatrix[0][0] = scale_mat.mMatrix[1][1] =
  218. scale_mat.mMatrix[2][2] = radius;
  219. scale_mat *= rot_mat;
  220. F32 droop = treep->mDroop + 25.f * (1.f - treep->mTrunkBend.length());
  221. F32 app_angle = treep->getAppAngle() * LLVOTree::sTreeFactor;
  222. for (U32 lod = 0; lod < MAX_NUM_TREE_LOD_LEVELS; ++lod)
  223. {
  224. if (app_angle > LLVOTree::sLODAngles[lod])
  225. {
  226. treep->drawBranchPipeline(scale_mat, NULL, lod, 0,
  227. treep->mDepth, treep->mTrunkDepth,
  228. 1.f, treep->mTwist, droop,
  229. treep->mBranches, 1.f);
  230. break;
  231. }
  232. }
  233. }
  234. }