llcubemap.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /**
  2. * @file llcubemap.cpp
  3. * @brief LLCubeMap 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 "linden_common.h"
  33. #include "llcubemap.h"
  34. #include "llglslshader.h"
  35. #include "llmatrix4a.h"
  36. #include "llrender.h"
  37. #include "llvector3.h"
  38. constexpr U16 RESOLUTION = 64;
  39. LLCubeMap::LLCubeMap(bool init_as_srgb)
  40. : mTextureStage(0),
  41. mMatrixStage(0),
  42. mIsSRGB(init_as_srgb)
  43. {
  44. mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
  45. mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  46. mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
  47. mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
  48. mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
  49. mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
  50. }
  51. void LLCubeMap::initGL()
  52. {
  53. llassert(gGLManager.mInited);
  54. if (mImages[0].isNull())
  55. {
  56. U32 texname = 0;
  57. LLImageGL::generateTextures(1, &texname);
  58. LLTexUnit* unit0 = gGL.getTexUnit(0);
  59. for (S32 i = 0; i < 6; ++i)
  60. {
  61. mImages[i] = new LLImageGL(RESOLUTION, RESOLUTION, 4, false);
  62. mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
  63. mRawImages[i] = new LLImageRaw(RESOLUTION, RESOLUTION, 4);
  64. mImages[i]->createGLTexture(0, mRawImages[i], texname);
  65. unit0->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
  66. mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
  67. stop_glerror();
  68. }
  69. unit0->disable();
  70. }
  71. disableTexture();
  72. }
  73. void LLCubeMap::destroyGL()
  74. {
  75. for (S32 i = 0; i < 6; ++i)
  76. {
  77. mImages[i] = NULL;
  78. }
  79. }
  80. void LLCubeMap::initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages)
  81. {
  82. bool flip_x[6] = { false, true, false, false, true, false };
  83. bool flip_y[6] = { true, true, true, false, true, true };
  84. bool transpose[6] = { false, false, false, false, true, true };
  85. // Yes, I know that this is inefficient! - djs 08/08/02
  86. for (S32 i = 0; i < 6; ++i)
  87. {
  88. const U8* sd = rawimages[i]->getData();
  89. U8* td = mRawImages[i]->getData();
  90. if (!sd || !td)
  91. {
  92. continue;
  93. }
  94. S32 offset = 0;
  95. S32 sx, sy, so;
  96. for (S32 y = 0; y < RESOLUTION; ++y)
  97. {
  98. for (S32 x = 0; x < RESOLUTION; ++x)
  99. {
  100. sx = x;
  101. sy = y;
  102. if (flip_y[i])
  103. {
  104. sy = 63 - y;
  105. }
  106. if (flip_x[i])
  107. {
  108. sx = 63 - x;
  109. }
  110. if (transpose[i])
  111. {
  112. S32 temp = sx;
  113. sx = sy;
  114. sy = temp;
  115. }
  116. so = RESOLUTION * sy + sx;
  117. so *= 4;
  118. *(td + offset++) = *(sd + so++);
  119. *(td + offset++) = *(sd + so++);
  120. *(td + offset++) = *(sd + so++);
  121. *(td + offset++) = *(sd + so++);
  122. }
  123. }
  124. }
  125. }
  126. void LLCubeMap::initGLData()
  127. {
  128. for (S32 i = 0; i < 6; ++i)
  129. {
  130. mImages[i]->setSubImage(mRawImages[i], 0, 0, RESOLUTION, RESOLUTION);
  131. }
  132. }
  133. void LLCubeMap::init(const std::vector<LLPointer<LLImageRaw> >& rawimages)
  134. {
  135. if (!gGLManager.mIsDisabled)
  136. {
  137. initGL();
  138. initRawData(rawimages);
  139. initGLData();
  140. }
  141. }
  142. void LLCubeMap::bind()
  143. {
  144. gGL.getTexUnit(mTextureStage)->bind(this);
  145. }
  146. void LLCubeMap::enableTexture(S32 stage)
  147. {
  148. mTextureStage = stage;
  149. if (stage >= 0)
  150. {
  151. gGL.getTexUnit(stage)->enable(LLTexUnit::TT_CUBE_MAP);
  152. }
  153. }
  154. void LLCubeMap::disableTexture()
  155. {
  156. if (mTextureStage >= 0)
  157. {
  158. LLTexUnit* unit = gGL.getTexUnit(mTextureStage);
  159. unit->disable();
  160. if (mTextureStage == 0)
  161. {
  162. unit->enable(LLTexUnit::TT_TEXTURE);
  163. }
  164. }
  165. }
  166. void LLCubeMap::setMatrix(S32 stage)
  167. {
  168. mMatrixStage = stage;
  169. if (mMatrixStage < 0) return;
  170. #if 0
  171. if (stage > 0)
  172. #endif
  173. {
  174. gGL.getTexUnit(stage)->activate();
  175. }
  176. LLMatrix4a trans(gGLModelView);
  177. trans.setRow<3>(LLVector4a::getZero());
  178. trans.transpose();
  179. gGL.matrixMode(LLRender::MM_TEXTURE);
  180. gGL.pushMatrix();
  181. gGL.loadMatrix(trans);
  182. gGL.matrixMode(LLRender::MM_MODELVIEW);
  183. #if 0
  184. if (stage > 0)
  185. {
  186. gGL.getTexUnit(0)->activate();
  187. }
  188. #endif
  189. }
  190. void LLCubeMap::restoreMatrix()
  191. {
  192. if (mMatrixStage < 0) return;
  193. #if 0
  194. if (mMatrixStage > 0)
  195. #endif
  196. {
  197. gGL.getTexUnit(mMatrixStage)->activate();
  198. }
  199. gGL.matrixMode(LLRender::MM_TEXTURE);
  200. gGL.popMatrix();
  201. gGL.matrixMode(LLRender::MM_MODELVIEW);
  202. #if 0
  203. if (mMatrixStage > 0)
  204. {
  205. gGL.getTexUnit(0)->activate();
  206. }
  207. #endif
  208. }
  209. void LLCubeMap::initReflectionMap(U32 resolution, U32 components)
  210. {
  211. U32 texname = 0;
  212. LLImageGL::generateTextures(1, &texname);
  213. mImages[0] = new LLImageGL(resolution, resolution, components, true);
  214. mImages[0]->setTexName(texname);
  215. mImages[0]->setTarget(mTargets[0], LLTexUnit::TT_CUBE_MAP);
  216. gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
  217. mImages[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
  218. }
  219. void LLCubeMap::initEnvironmentMap(const std::vector<LLPointer<LLImageRaw> >& rawimages)
  220. {
  221. llassert(rawimages.size() == 6);
  222. U32 texname = 0;
  223. LLImageGL::generateTextures(1, &texname);
  224. U32 resolution = rawimages[0]->getWidth();
  225. U32 components = rawimages[0]->getComponents();
  226. LLTexUnit* unit0 = gGL.getTexUnit(0);
  227. for (U32 i = 0; i < 6; ++i)
  228. {
  229. llassert(rawimages[i]->getWidth() == resolution &&
  230. rawimages[i]->getHeight() == resolution &&
  231. (U32)rawimages[i]->getComponents() == components);
  232. mImages[i] = new LLImageGL(resolution, resolution, components, true);
  233. mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
  234. mRawImages[i] = rawimages[i];
  235. mImages[i]->createGLTexture(0, mRawImages[i], texname);
  236. unit0->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
  237. mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
  238. stop_glerror();
  239. mImages[i]->setSubImage(mRawImages[i], 0, 0, resolution, resolution);
  240. }
  241. enableTexture(0);
  242. bind();
  243. mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
  244. glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
  245. glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
  246. unit0->disable();
  247. disableTexture();
  248. }
  249. void LLCubeMap::generateMipMaps()
  250. {
  251. mImages[0]->setUseMipMaps(true);
  252. mImages[0]->setHasMipMaps(true);
  253. enableTexture(0);
  254. bind();
  255. mImages[0]->setFilteringOption(LLTexUnit::TFO_BILINEAR);
  256. glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
  257. gGL.getTexUnit(0)->disable();
  258. disableTexture();
  259. }