lldynamictexture.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /**
  2. * @file lldynamictexture.cpp
  3. * @brief Implementation of LLDynamicTexture class
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-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 "lldynamictexture.h"
  34. #include "llgl.h"
  35. #include "llglslshader.h"
  36. #include "llrender.h"
  37. #include "llvertexbuffer.h"
  38. #include "llpipeline.h"
  39. #include "llviewercamera.h"
  40. #include "llviewercontrol.h"
  41. #include "llviewertexture.h"
  42. #include "llviewerwindow.h"
  43. // static
  44. LLViewerDynamicTexture::instance_list_t
  45. LLViewerDynamicTexture::sInstances[LLViewerDynamicTexture::ORDER_COUNT];
  46. S32 LLViewerDynamicTexture::sNumRenders = 0;
  47. LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height,
  48. S32 components, EOrder order,
  49. bool clamp)
  50. : LLViewerTexture(width, height, components, false),
  51. mClamp(clamp)
  52. {
  53. llassert(components >= 1 && components <= 4 && order >= 0 &&
  54. order < ORDER_COUNT);
  55. generateGLTexture();
  56. sInstances[order].insert(this);
  57. }
  58. LLViewerDynamicTexture::~LLViewerDynamicTexture()
  59. {
  60. for (S32 order = 0; order < ORDER_COUNT; ++order)
  61. {
  62. // Will fail in all but one case.
  63. sInstances[order].erase(this);
  64. }
  65. }
  66. //virtual
  67. S8 LLViewerDynamicTexture::getType() const
  68. {
  69. return LLViewerTexture::DYNAMIC_TEXTURE;
  70. }
  71. void LLViewerDynamicTexture::generateGLTexture()
  72. {
  73. LLViewerTexture::generateGLTexture();
  74. generateGLTexture(-1, 0, 0, false);
  75. }
  76. void LLViewerDynamicTexture::generateGLTexture(S32 internal_fmt,
  77. U32 primary_fmt,
  78. U32 type_format,
  79. bool swap_bytes)
  80. {
  81. if (mComponents < 1 || mComponents > 4)
  82. {
  83. llerrs << "Bad number of components in dynamic texture: "
  84. << mComponents << llendl;
  85. }
  86. LLPointer<LLImageRaw> raw_imagep = new LLImageRaw(mFullWidth, mFullHeight,
  87. mComponents);
  88. if (internal_fmt >= 0)
  89. {
  90. setExplicitFormat(internal_fmt, primary_fmt, type_format, swap_bytes);
  91. }
  92. createGLTexture(0, raw_imagep, 0, true);
  93. setAddressMode(mClamp ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);
  94. mImageGLp->setGLTextureCreated(false);
  95. }
  96. void LLViewerDynamicTexture::preRender(bool clear_depth)
  97. {
  98. // Using offscreen render target, just use the bottom left corner
  99. mOrigin.set(0, 0);
  100. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  101. // Set up camera
  102. mCamera.setOrigin(gViewerCamera);
  103. mCamera.setAxes(gViewerCamera);
  104. mCamera.setAspect(gViewerCamera.getAspect());
  105. mCamera.setView(gViewerCamera.getView());
  106. mCamera.setNear(gViewerCamera.getNear());
  107. glViewport(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight);
  108. if (clear_depth)
  109. {
  110. glClear(GL_DEPTH_BUFFER_BIT);
  111. }
  112. }
  113. void LLViewerDynamicTexture::postRender(bool success)
  114. {
  115. if (success)
  116. {
  117. if (mImageGLp.isNull() || !mImageGLp->getHasGLTexture() ||
  118. mImageGLp->getDiscardLevel() != 0)
  119. {
  120. generateGLTexture();
  121. }
  122. mImageGLp->setSubImageFromFrameBuffer(0, 0, mOrigin.mX, mOrigin.mY,
  123. mFullWidth, mFullHeight);
  124. }
  125. // Restore viewport
  126. gViewerWindowp->setupViewport();
  127. // Restore camera
  128. gViewerCamera.setOrigin(mCamera);
  129. gViewerCamera.setAxes(mCamera);
  130. gViewerCamera.setAspect(mCamera.getAspect());
  131. gViewerCamera.setViewNoBroadcast(mCamera.getView());
  132. gViewerCamera.setNear(mCamera.getNear());
  133. }
  134. // Calls update on each dynamic texture. Calls each group in order: "first,"
  135. // then "middle," then "last."
  136. //static
  137. bool LLViewerDynamicTexture::updateAllInstances()
  138. {
  139. sNumRenders = 0;
  140. if (gGLManager.mIsDisabled)
  141. {
  142. return true;
  143. }
  144. // Note: we only *do* need a bound target for rendering PBR material
  145. // previews, meaning only in PBR mode. HB
  146. LLRenderTarget* bake_targetp =
  147. gUsePBRShaders ? &gPipeline.mAuxillaryRT.mDeferredScreen : NULL;
  148. if (bake_targetp)
  149. {
  150. bake_targetp->bindTarget();
  151. bake_targetp->clear();
  152. }
  153. LLGLSLShader::unbind(); // Also unbinds the vertex buffer. HB
  154. bool result = false;
  155. bool ret = false;
  156. for (S32 order = 0; order < ORDER_COUNT; ++order)
  157. {
  158. for (instance_list_t::iterator iter = sInstances[order].begin(),
  159. end = sInstances[order].end();
  160. iter != end; ++iter)
  161. {
  162. LLViewerDynamicTexture* texp = *iter;
  163. if (texp->needsRender())
  164. {
  165. glClear(GL_DEPTH_BUFFER_BIT);
  166. // Note: LL's code got 'gDepthDirty = true;' at this point, but
  167. // this is totally bogus and causes weird, random occlusion
  168. // issues. HB
  169. gGL.color4f(1.f, 1.f, 1.f, 1.f);
  170. texp->preRender(); // Must be called outside of startRender()
  171. result = texp->render();
  172. if (result)
  173. {
  174. ret = true;
  175. ++sNumRenders;
  176. }
  177. gGL.flush();
  178. LLVertexBuffer::unbind();
  179. texp->postRender(result);
  180. }
  181. }
  182. }
  183. if (bake_targetp)
  184. {
  185. bake_targetp->flush();
  186. }
  187. gGL.flush();
  188. return ret;
  189. }