PageRenderTime 66ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llvosky.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2287 lines | 1726 code | 405 blank | 156 comment | 182 complexity | 21e683142957bd34200da12e121ccd81 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llvosky.cpp
  3. * @brief LLVOSky class implementation
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llvosky.h"
  28. #include "imageids.h"
  29. #include "llfeaturemanager.h"
  30. #include "llviewercontrol.h"
  31. #include "llframetimer.h"
  32. #include "timing.h"
  33. #include "llagent.h"
  34. #include "llagentcamera.h"
  35. #include "lldrawable.h"
  36. #include "llface.h"
  37. #include "llcubemap.h"
  38. #include "lldrawpoolsky.h"
  39. #include "lldrawpoolwater.h"
  40. #include "llglheaders.h"
  41. #include "llsky.h"
  42. #include "llviewercamera.h"
  43. #include "llviewertexturelist.h"
  44. #include "llviewerobjectlist.h"
  45. #include "llviewerregion.h"
  46. #include "llworld.h"
  47. #include "pipeline.h"
  48. #include "lldrawpoolwlsky.h"
  49. #include "llwlparammanager.h"
  50. #include "llwaterparammanager.h"
  51. #undef min
  52. #undef max
  53. static const S32 NUM_TILES_X = 8;
  54. static const S32 NUM_TILES_Y = 4;
  55. static const S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y;
  56. // Heavenly body constants
  57. static const F32 SUN_DISK_RADIUS = 0.5f;
  58. static const F32 MOON_DISK_RADIUS = SUN_DISK_RADIUS * 0.9f;
  59. static const F32 SUN_INTENSITY = 1e5;
  60. static const F32 SUN_DISK_INTENSITY = 24.f;
  61. // Texture coordinates:
  62. static const LLVector2 TEX00 = LLVector2(0.f, 0.f);
  63. static const LLVector2 TEX01 = LLVector2(0.f, 1.f);
  64. static const LLVector2 TEX10 = LLVector2(1.f, 0.f);
  65. static const LLVector2 TEX11 = LLVector2(1.f, 1.f);
  66. // Exported globals
  67. LLUUID gSunTextureID = IMG_SUN;
  68. LLUUID gMoonTextureID = IMG_MOON;
  69. class LLFastLn
  70. {
  71. public:
  72. LLFastLn()
  73. {
  74. mTable[0] = 0;
  75. for( S32 i = 1; i < 257; i++ )
  76. {
  77. mTable[i] = log((F32)i);
  78. }
  79. }
  80. F32 ln( F32 x )
  81. {
  82. const F32 OO_255 = 0.003921568627450980392156862745098f;
  83. const F32 LN_255 = 5.5412635451584261462455391880218f;
  84. if( x < OO_255 )
  85. {
  86. return log(x);
  87. }
  88. else
  89. if( x < 1 )
  90. {
  91. x *= 255.f;
  92. S32 index = llfloor(x);
  93. F32 t = x - index;
  94. F32 low = mTable[index];
  95. F32 high = mTable[index + 1];
  96. return low + t * (high - low) - LN_255;
  97. }
  98. else
  99. if( x <= 255 )
  100. {
  101. S32 index = llfloor(x);
  102. F32 t = x - index;
  103. F32 low = mTable[index];
  104. F32 high = mTable[index + 1];
  105. return low + t * (high - low);
  106. }
  107. else
  108. {
  109. return log( x );
  110. }
  111. }
  112. F32 pow( F32 x, F32 y )
  113. {
  114. return (F32)LL_FAST_EXP(y * ln(x));
  115. }
  116. private:
  117. F32 mTable[257]; // index 0 is unused
  118. };
  119. static LLFastLn gFastLn;
  120. // Functions used a lot.
  121. inline F32 LLHaze::calcPhase(const F32 cos_theta) const
  122. {
  123. const F32 g2 = mG * mG;
  124. const F32 den = 1 + g2 - 2 * mG * cos_theta;
  125. return (1 - g2) * gFastLn.pow(den, -1.5);
  126. }
  127. inline void color_pow(LLColor3 &col, const F32 e)
  128. {
  129. col.mV[0] = gFastLn.pow(col.mV[0], e);
  130. col.mV[1] = gFastLn.pow(col.mV[1], e);
  131. col.mV[2] = gFastLn.pow(col.mV[2], e);
  132. }
  133. inline LLColor3 color_norm(const LLColor3 &col)
  134. {
  135. const F32 m = color_max(col);
  136. if (m > 1.f)
  137. {
  138. return 1.f/m * col;
  139. }
  140. else return col;
  141. }
  142. inline void color_gamma_correct(LLColor3 &col)
  143. {
  144. const F32 gamma_inv = 1.f/1.2f;
  145. if (col.mV[0] != 0.f)
  146. {
  147. col.mV[0] = gFastLn.pow(col.mV[0], gamma_inv);
  148. }
  149. if (col.mV[1] != 0.f)
  150. {
  151. col.mV[1] = gFastLn.pow(col.mV[1], gamma_inv);
  152. }
  153. if (col.mV[2] != 0.f)
  154. {
  155. col.mV[2] = gFastLn.pow(col.mV[2], gamma_inv);
  156. }
  157. }
  158. static LLColor3 calc_air_sca_sea_level()
  159. {
  160. static LLColor3 WAVE_LEN(675, 520, 445);
  161. static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN);
  162. static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1);
  163. static LLColor3 n4 = n21 * n21;
  164. static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f;
  165. static LLColor3 wl4 = wl2 * wl2;
  166. static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4;
  167. static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2);
  168. return dens_div_N * color_div ( mult_const, wl4 );
  169. }
  170. // static constants.
  171. LLColor3 const LLHaze::sAirScaSeaLevel = calc_air_sca_sea_level();
  172. F32 const LLHaze::sAirScaIntense = color_intens(LLHaze::sAirScaSeaLevel);
  173. F32 const LLHaze::sAirScaAvg = LLHaze::sAirScaIntense / 3.f;
  174. /***************************************
  175. SkyTex
  176. ***************************************/
  177. S32 LLSkyTex::sComponents = 4;
  178. S32 LLSkyTex::sResolution = 64;
  179. F32 LLSkyTex::sInterpVal = 0.f;
  180. S32 LLSkyTex::sCurrent = 0;
  181. LLSkyTex::LLSkyTex() :
  182. mSkyData(NULL),
  183. mSkyDirs(NULL)
  184. {
  185. }
  186. void LLSkyTex::init()
  187. {
  188. mSkyData = new LLColor4[sResolution * sResolution];
  189. mSkyDirs = new LLVector3[sResolution * sResolution];
  190. for (S32 i = 0; i < 2; ++i)
  191. {
  192. mTexture[i] = LLViewerTextureManager::getLocalTexture(FALSE);
  193. mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
  194. mImageRaw[i] = new LLImageRaw(sResolution, sResolution, sComponents);
  195. initEmpty(i);
  196. }
  197. }
  198. void LLSkyTex::cleanupGL()
  199. {
  200. mTexture[0] = NULL;
  201. mTexture[1] = NULL;
  202. }
  203. void LLSkyTex::restoreGL()
  204. {
  205. for (S32 i = 0; i < 2; i++)
  206. {
  207. mTexture[i] = LLViewerTextureManager::getLocalTexture(FALSE);
  208. mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
  209. }
  210. }
  211. LLSkyTex::~LLSkyTex()
  212. {
  213. delete[] mSkyData;
  214. mSkyData = NULL;
  215. delete[] mSkyDirs;
  216. mSkyDirs = NULL;
  217. }
  218. void LLSkyTex::initEmpty(const S32 tex)
  219. {
  220. U8* data = mImageRaw[tex]->getData();
  221. for (S32 i = 0; i < sResolution; ++i)
  222. {
  223. for (S32 j = 0; j < sResolution; ++j)
  224. {
  225. const S32 basic_offset = (i * sResolution + j);
  226. S32 offset = basic_offset * sComponents;
  227. data[offset] = 0;
  228. data[offset+1] = 0;
  229. data[offset+2] = 0;
  230. data[offset+3] = 255;
  231. mSkyData[basic_offset].setToBlack();
  232. }
  233. }
  234. createGLImage(tex);
  235. }
  236. void LLSkyTex::create(const F32 brightness)
  237. {
  238. /// Brightness ignored for now.
  239. U8* data = mImageRaw[sCurrent]->getData();
  240. for (S32 i = 0; i < sResolution; ++i)
  241. {
  242. for (S32 j = 0; j < sResolution; ++j)
  243. {
  244. const S32 basic_offset = (i * sResolution + j);
  245. S32 offset = basic_offset * sComponents;
  246. U32* pix = (U32*)(data + offset);
  247. LLColor4U temp = LLColor4U(mSkyData[basic_offset]);
  248. *pix = temp.mAll;
  249. }
  250. }
  251. createGLImage(sCurrent);
  252. }
  253. void LLSkyTex::createGLImage(S32 which)
  254. {
  255. mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLViewerTexture::LOCAL);
  256. mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
  257. }
  258. void LLSkyTex::bindTexture(BOOL curr)
  259. {
  260. gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)], true);
  261. }
  262. /***************************************
  263. Sky
  264. ***************************************/
  265. F32 LLHeavenBody::sInterpVal = 0;
  266. S32 LLVOSky::sResolution = LLSkyTex::getResolution();
  267. S32 LLVOSky::sTileResX = sResolution/NUM_TILES_X;
  268. S32 LLVOSky::sTileResY = sResolution/NUM_TILES_Y;
  269. LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
  270. : LLStaticViewerObject(id, pcode, regionp, TRUE),
  271. mSun(SUN_DISK_RADIUS), mMoon(MOON_DISK_RADIUS),
  272. mBrightnessScale(1.f),
  273. mBrightnessScaleNew(0.f),
  274. mBrightnessScaleGuess(1.f),
  275. mWeatherChange(FALSE),
  276. mCloudDensity(0.2f),
  277. mWind(0.f),
  278. mForceUpdate(FALSE),
  279. mWorldScale(1.f),
  280. mBumpSunDir(0.f, 0.f, 1.f)
  281. {
  282. bool error = false;
  283. /// WL PARAMS
  284. dome_radius = 1.f;
  285. dome_offset_ratio = 0.f;
  286. sunlight_color = LLColor3();
  287. ambient = LLColor3();
  288. gamma = 1.f;
  289. lightnorm = LLVector4();
  290. blue_density = LLColor3();
  291. blue_horizon = LLColor3();
  292. haze_density = 0.f;
  293. haze_horizon = LLColor3();
  294. density_multiplier = 0.f;
  295. max_y = 0.f;
  296. glow = LLColor3();
  297. cloud_shadow = 0.f;
  298. cloud_color = LLColor3();
  299. cloud_scale = 0.f;
  300. cloud_pos_density1 = LLColor3();
  301. cloud_pos_density2 = LLColor3();
  302. mInitialized = FALSE;
  303. mbCanSelect = FALSE;
  304. mUpdateTimer.reset();
  305. for (S32 i = 0; i < 6; i++)
  306. {
  307. mSkyTex[i].init();
  308. mShinyTex[i].init();
  309. }
  310. for (S32 i=0; i<FACE_COUNT; i++)
  311. {
  312. mFace[i] = NULL;
  313. }
  314. mCameraPosAgent = gAgentCamera.getCameraPositionAgent();
  315. mAtmHeight = ATM_HEIGHT;
  316. mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS);
  317. mSunDefaultPosition = LLVector3(LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error));
  318. if (gSavedSettings.getBOOL("SkyOverrideSimSunPosition"))
  319. {
  320. initSunDirection(mSunDefaultPosition, LLVector3(0, 0, 0));
  321. }
  322. mAmbientScale = gSavedSettings.getF32("SkyAmbientScale");
  323. mNightColorShift = gSavedSettings.getColor3("SkyNightColorShift");
  324. mFogColor.mV[VRED] = mFogColor.mV[VGREEN] = mFogColor.mV[VBLUE] = 0.5f;
  325. mFogColor.mV[VALPHA] = 0.0f;
  326. mFogRatio = 1.2f;
  327. mSun.setIntensity(SUN_INTENSITY);
  328. mMoon.setIntensity(0.1f * SUN_INTENSITY);
  329. mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
  330. mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
  331. mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
  332. mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
  333. mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
  334. mBloomTexturep->setNoDelete() ;
  335. mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
  336. mHeavenlyBodyUpdated = FALSE ;
  337. mDrawRefl = 0;
  338. mHazeConcentration = 0.f;
  339. mInterpVal = 0.f;
  340. }
  341. LLVOSky::~LLVOSky()
  342. {
  343. // Don't delete images - it'll get deleted by gTextureList on shutdown
  344. // This needs to be done for each texture
  345. mCubeMap = NULL;
  346. }
  347. void LLVOSky::init()
  348. {
  349. const F32 haze_int = color_intens(mHaze.calcSigSca(0));
  350. mHazeConcentration = haze_int /
  351. (color_intens(LLHaze::calcAirSca(0)) + haze_int);
  352. calcAtmospherics();
  353. // Initialize the cached normalized direction vectors
  354. for (S32 side = 0; side < 6; ++side)
  355. {
  356. for (S32 tile = 0; tile < NUM_TILES; ++tile)
  357. {
  358. initSkyTextureDirs(side, tile);
  359. createSkyTexture(side, tile);
  360. }
  361. }
  362. for (S32 i = 0; i < 6; ++i)
  363. {
  364. mSkyTex[i].create(1.0f);
  365. mShinyTex[i].create(1.0f);
  366. }
  367. initCubeMap();
  368. mInitialized = true;
  369. mHeavenlyBodyUpdated = FALSE ;
  370. }
  371. void LLVOSky::initCubeMap()
  372. {
  373. std::vector<LLPointer<LLImageRaw> > images;
  374. for (S32 side = 0; side < 6; side++)
  375. {
  376. images.push_back(mShinyTex[side].getImageRaw());
  377. }
  378. if (mCubeMap)
  379. {
  380. mCubeMap->init(images);
  381. }
  382. else if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
  383. {
  384. mCubeMap = new LLCubeMap();
  385. mCubeMap->init(images);
  386. }
  387. gGL.getTexUnit(0)->disable();
  388. }
  389. void LLVOSky::cleanupGL()
  390. {
  391. S32 i;
  392. for (i = 0; i < 6; i++)
  393. {
  394. mSkyTex[i].cleanupGL();
  395. }
  396. if (getCubeMap())
  397. {
  398. getCubeMap()->destroyGL();
  399. }
  400. }
  401. void LLVOSky::restoreGL()
  402. {
  403. S32 i;
  404. for (i = 0; i < 6; i++)
  405. {
  406. mSkyTex[i].restoreGL();
  407. }
  408. mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
  409. mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
  410. mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
  411. mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
  412. mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
  413. mBloomTexturep->setNoDelete() ;
  414. mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
  415. calcAtmospherics();
  416. if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap
  417. && LLCubeMap::sUseCubeMaps)
  418. {
  419. LLCubeMap* cube_map = getCubeMap();
  420. std::vector<LLPointer<LLImageRaw> > images;
  421. for (S32 side = 0; side < 6; side++)
  422. {
  423. images.push_back(mShinyTex[side].getImageRaw());
  424. }
  425. if(cube_map)
  426. {
  427. cube_map->init(images);
  428. mForceUpdate = TRUE;
  429. }
  430. }
  431. if (mDrawable)
  432. {
  433. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
  434. }
  435. }
  436. void LLVOSky::initSkyTextureDirs(const S32 side, const S32 tile)
  437. {
  438. S32 tile_x = tile % NUM_TILES_X;
  439. S32 tile_y = tile / NUM_TILES_X;
  440. S32 tile_x_pos = tile_x * sTileResX;
  441. S32 tile_y_pos = tile_y * sTileResY;
  442. F32 coeff[3] = {0, 0, 0};
  443. const S32 curr_coef = side >> 1; // 0/1 = Z axis, 2/3 = Y, 4/5 = X
  444. const S32 side_dir = (((side & 1) << 1) - 1); // even = -1, odd = 1
  445. const S32 x_coef = (curr_coef + 1) % 3;
  446. const S32 y_coef = (x_coef + 1) % 3;
  447. coeff[curr_coef] = (F32)side_dir;
  448. F32 inv_res = 1.f/sResolution;
  449. S32 x, y;
  450. for (y = tile_y_pos; y < (tile_y_pos + sTileResY); ++y)
  451. {
  452. for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x)
  453. {
  454. coeff[x_coef] = F32((x<<1) + 1) * inv_res - 1.f;
  455. coeff[y_coef] = F32((y<<1) + 1) * inv_res - 1.f;
  456. LLVector3 dir(coeff[0], coeff[1], coeff[2]);
  457. dir.normalize();
  458. mSkyTex[side].setDir(dir, x, y);
  459. mShinyTex[side].setDir(dir, x, y);
  460. }
  461. }
  462. }
  463. void LLVOSky::createSkyTexture(const S32 side, const S32 tile)
  464. {
  465. S32 tile_x = tile % NUM_TILES_X;
  466. S32 tile_y = tile / NUM_TILES_X;
  467. S32 tile_x_pos = tile_x * sTileResX;
  468. S32 tile_y_pos = tile_y * sTileResY;
  469. S32 x, y;
  470. for (y = tile_y_pos; y < (tile_y_pos + sTileResY); ++y)
  471. {
  472. for (x = tile_x_pos; x < (tile_x_pos + sTileResX); ++x)
  473. {
  474. mSkyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y)), x, y);
  475. mShinyTex[side].setPixel(calcSkyColorInDir(mSkyTex[side].getDir(x, y), true), x, y);
  476. }
  477. }
  478. }
  479. static inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right)
  480. {
  481. return LLColor3(left.mV[0]/right.mV[0],
  482. left.mV[1]/right.mV[1],
  483. left.mV[2]/right.mV[2]);
  484. }
  485. static inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right)
  486. {
  487. return LLColor3(left.mV[0]*right.mV[0],
  488. left.mV[1]*right.mV[1],
  489. left.mV[2]*right.mV[2]);
  490. }
  491. static inline LLColor3 componentExp(LLColor3 const &v)
  492. {
  493. return LLColor3(exp(v.mV[0]),
  494. exp(v.mV[1]),
  495. exp(v.mV[2]));
  496. }
  497. static inline LLColor3 componentPow(LLColor3 const &v, F32 exponent)
  498. {
  499. return LLColor3(pow(v.mV[0], exponent),
  500. pow(v.mV[1], exponent),
  501. pow(v.mV[2], exponent));
  502. }
  503. static inline LLColor3 componentSaturate(LLColor3 const &v)
  504. {
  505. return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f),
  506. std::max(std::min(v.mV[1], 1.f), 0.f),
  507. std::max(std::min(v.mV[2], 1.f), 0.f));
  508. }
  509. static inline LLColor3 componentSqrt(LLColor3 const &v)
  510. {
  511. return LLColor3(sqrt(v.mV[0]),
  512. sqrt(v.mV[1]),
  513. sqrt(v.mV[2]));
  514. }
  515. static inline void componentMultBy(LLColor3 & left, LLColor3 const & right)
  516. {
  517. left.mV[0] *= right.mV[0];
  518. left.mV[1] *= right.mV[1];
  519. left.mV[2] *= right.mV[2];
  520. }
  521. static inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount)
  522. {
  523. return (left + ((right - left) * amount));
  524. }
  525. static inline F32 texture2D(LLPointer<LLImageRaw> const & tex, LLVector2 const & uv)
  526. {
  527. U16 w = tex->getWidth();
  528. U16 h = tex->getHeight();
  529. U16 r = U16(uv[0] * w) % w;
  530. U16 c = U16(uv[1] * h) % h;
  531. U8 const * imageBuffer = tex->getData();
  532. U8 sample = imageBuffer[r * w + c];
  533. return sample / 255.f;
  534. }
  535. static inline LLColor3 smear(F32 val)
  536. {
  537. return LLColor3(val, val, val);
  538. }
  539. void LLVOSky::initAtmospherics(void)
  540. {
  541. bool error;
  542. // uniform parameters for convenience
  543. dome_radius = LLWLParamManager::getInstance()->getDomeRadius();
  544. dome_offset_ratio = LLWLParamManager::getInstance()->getDomeOffset();
  545. sunlight_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("sunlight_color", error));
  546. ambient = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("ambient", error));
  547. //lightnorm = LLWLParamManager::getInstance()->mCurParams.getVector("lightnorm", error);
  548. gamma = LLWLParamManager::getInstance()->mCurParams.getVector("gamma", error)[0];
  549. blue_density = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_density", error));
  550. blue_horizon = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("blue_horizon", error));
  551. haze_density = LLWLParamManager::getInstance()->mCurParams.getVector("haze_density", error)[0];
  552. haze_horizon = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("haze_horizon", error));
  553. density_multiplier = LLWLParamManager::getInstance()->mCurParams.getVector("density_multiplier", error)[0];
  554. max_y = LLWLParamManager::getInstance()->mCurParams.getVector("max_y", error)[0];
  555. glow = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("glow", error));
  556. cloud_shadow = LLWLParamManager::getInstance()->mCurParams.getVector("cloud_shadow", error)[0];
  557. cloud_color = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_color", error));
  558. cloud_scale = LLWLParamManager::getInstance()->mCurParams.getVector("cloud_scale", error)[0];
  559. cloud_pos_density1 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density1", error));
  560. cloud_pos_density2 = LLColor3(LLWLParamManager::getInstance()->mCurParams.getVector("cloud_pos_density2", error));
  561. // light norm is different. We need the sun's direction, not the light direction
  562. // which could be from the moon. And we need to clamp it
  563. // just like for the gpu
  564. LLVector3 sunDir = gSky.getSunDirection();
  565. // CFR_TO_OGL
  566. lightnorm = LLVector4(sunDir.mV[1], sunDir.mV[2], sunDir.mV[0], 0);
  567. unclamped_lightnorm = lightnorm;
  568. if(lightnorm.mV[1] < -0.1f)
  569. {
  570. lightnorm.mV[1] = -0.1f;
  571. }
  572. }
  573. LLColor4 LLVOSky::calcSkyColorInDir(const LLVector3 &dir, bool isShiny)
  574. {
  575. F32 saturation = 0.3f;
  576. if (dir.mV[VZ] < -0.02f)
  577. {
  578. LLColor4 col = LLColor4(llmax(mFogColor[0],0.2f), llmax(mFogColor[1],0.2f), llmax(mFogColor[2],0.22f),0.f);
  579. if (isShiny)
  580. {
  581. LLColor3 desat_fog = LLColor3(mFogColor);
  582. F32 brightness = desat_fog.brightness();
  583. // So that shiny somewhat shows up at night.
  584. if (brightness < 0.15f)
  585. {
  586. brightness = 0.15f;
  587. desat_fog = smear(0.15f);
  588. }
  589. LLColor3 greyscale = smear(brightness);
  590. desat_fog = desat_fog * saturation + greyscale * (1.0f - saturation);
  591. if (!gPipeline.canUseWindLightShaders())
  592. {
  593. col = LLColor4(desat_fog, 0.f);
  594. }
  595. else
  596. {
  597. col = LLColor4(desat_fog * 0.5f, 0.f);
  598. }
  599. }
  600. float x = 1.0f-fabsf(-0.1f-dir.mV[VZ]);
  601. x *= x;
  602. col.mV[0] *= x*x;
  603. col.mV[1] *= powf(x, 2.5f);
  604. col.mV[2] *= x*x*x;
  605. return col;
  606. }
  607. // undo OGL_TO_CFR_ROTATION and negate vertical direction.
  608. LLVector3 Pn = LLVector3(-dir[1] , -dir[2], -dir[0]);
  609. LLColor3 vary_HazeColor(0,0,0);
  610. LLColor3 vary_CloudColorSun(0,0,0);
  611. LLColor3 vary_CloudColorAmbient(0,0,0);
  612. F32 vary_CloudDensity(0);
  613. LLVector2 vary_HorizontalProjection[2];
  614. vary_HorizontalProjection[0] = LLVector2(0,0);
  615. vary_HorizontalProjection[1] = LLVector2(0,0);
  616. calcSkyColorWLVert(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient,
  617. vary_CloudDensity, vary_HorizontalProjection);
  618. LLColor3 sky_color = calcSkyColorWLFrag(Pn, vary_HazeColor, vary_CloudColorSun, vary_CloudColorAmbient,
  619. vary_CloudDensity, vary_HorizontalProjection);
  620. if (isShiny)
  621. {
  622. F32 brightness = sky_color.brightness();
  623. LLColor3 greyscale = smear(brightness);
  624. sky_color = sky_color * saturation + greyscale * (1.0f - saturation);
  625. sky_color *= (0.5f + 0.5f * brightness);
  626. }
  627. return LLColor4(sky_color, 0.0f);
  628. }
  629. // turn on floating point precision
  630. // in vs2003 for this function. Otherwise
  631. // sky is aliased looking 7:10 - 8:50
  632. #if LL_MSVC && __MSVC_VER__ < 8
  633. #pragma optimize("p", on)
  634. #endif
  635. void LLVOSky::calcSkyColorWLVert(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,
  636. LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,
  637. LLVector2 vary_HorizontalProjection[2])
  638. {
  639. // project the direction ray onto the sky dome.
  640. F32 phi = acos(Pn[1]);
  641. F32 sinA = sin(F_PI - phi);
  642. if (fabsf(sinA) < 0.01f)
  643. { //avoid division by zero
  644. sinA = 0.01f;
  645. }
  646. F32 Plen = dome_radius * sin(F_PI + phi + asin(dome_offset_ratio * sinA)) / sinA;
  647. Pn *= Plen;
  648. vary_HorizontalProjection[0] = LLVector2(Pn[0], Pn[2]);
  649. vary_HorizontalProjection[0] /= - 2.f * Plen;
  650. // Set altitude
  651. if (Pn[1] > 0.f)
  652. {
  653. Pn *= (max_y / Pn[1]);
  654. }
  655. else
  656. {
  657. Pn *= (-32000.f / Pn[1]);
  658. }
  659. Plen = Pn.length();
  660. Pn /= Plen;
  661. // Initialize temp variables
  662. LLColor3 sunlight = sunlight_color;
  663. // Sunlight attenuation effect (hue and brightness) due to atmosphere
  664. // this is used later for sunlight modulation at various altitudes
  665. LLColor3 light_atten =
  666. (blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y);
  667. // Calculate relative weights
  668. LLColor3 temp2(0.f, 0.f, 0.f);
  669. LLColor3 temp1 = blue_density + smear(haze_density);
  670. LLColor3 blue_weight = componentDiv(blue_density, temp1);
  671. LLColor3 haze_weight = componentDiv(smear(haze_density), temp1);
  672. // Compute sunlight from P & lightnorm (for long rays like sky)
  673. temp2.mV[1] = llmax(F_APPROXIMATELY_ZERO, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] );
  674. temp2.mV[1] = 1.f / temp2.mV[1];
  675. componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
  676. // Distance
  677. temp2.mV[2] = Plen * density_multiplier;
  678. // Transparency (-> temp1)
  679. temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]);
  680. // Compute haze glow
  681. temp2.mV[0] = Pn * LLVector3(lightnorm);
  682. temp2.mV[0] = 1.f - temp2.mV[0];
  683. // temp2.x is 0 at the sun and increases away from sun
  684. temp2.mV[0] = llmax(temp2.mV[0], .001f);
  685. // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
  686. temp2.mV[0] *= glow.mV[0];
  687. // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
  688. temp2.mV[0] = pow(temp2.mV[0], glow.mV[2]);
  689. // glow.z should be negative, so we're doing a sort of (1 / "angle") function
  690. // Add "minimum anti-solar illumination"
  691. temp2.mV[0] += .25f;
  692. // Haze color above cloud
  693. vary_HazeColor = (blue_horizon * blue_weight * (sunlight + ambient)
  694. + componentMult(haze_horizon.mV[0] * haze_weight, sunlight * temp2.mV[0] + ambient)
  695. );
  696. // Increase ambient when there are more clouds
  697. LLColor3 tmpAmbient = ambient + (LLColor3::white - ambient) * cloud_shadow * 0.5f;
  698. // Dim sunlight by cloud shadow percentage
  699. sunlight *= (1.f - cloud_shadow);
  700. // Haze color below cloud
  701. LLColor3 additiveColorBelowCloud = (blue_horizon * blue_weight * (sunlight + tmpAmbient)
  702. + componentMult(haze_horizon.mV[0] * haze_weight, sunlight * temp2.mV[0] + tmpAmbient)
  703. );
  704. // Final atmosphere additive
  705. componentMultBy(vary_HazeColor, LLColor3::white - temp1);
  706. sunlight = sunlight_color;
  707. temp2.mV[1] = llmax(0.f, lightnorm[1] * 2.f);
  708. temp2.mV[1] = 1.f / temp2.mV[1];
  709. componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
  710. // Attenuate cloud color by atmosphere
  711. temp1 = componentSqrt(temp1); //less atmos opacity (more transparency) below clouds
  712. // At horizon, blend high altitude sky color towards the darker color below the clouds
  713. vary_HazeColor +=
  714. componentMult(additiveColorBelowCloud - vary_HazeColor, LLColor3::white - componentSqrt(temp1));
  715. if (Pn[1] < 0.f)
  716. {
  717. // Eric's original:
  718. // LLColor3 dark_brown(0.143f, 0.129f, 0.114f);
  719. LLColor3 dark_brown(0.082f, 0.076f, 0.066f);
  720. LLColor3 brown(0.430f, 0.386f, 0.322f);
  721. LLColor3 sky_lighting = sunlight + ambient;
  722. F32 haze_brightness = vary_HazeColor.brightness();
  723. if (Pn[1] < -0.05f)
  724. {
  725. vary_HazeColor = colorMix(dark_brown, brown, -Pn[1] * 0.9f) * sky_lighting * haze_brightness;
  726. }
  727. if (Pn[1] > -0.1f)
  728. {
  729. vary_HazeColor = colorMix(LLColor3::white * haze_brightness, vary_HazeColor, fabs((Pn[1] + 0.05f) * -20.f));
  730. }
  731. }
  732. }
  733. #if LL_MSVC && __MSVC_VER__ < 8
  734. #pragma optimize("p", off)
  735. #endif
  736. LLColor3 LLVOSky::calcSkyColorWLFrag(LLVector3 & Pn, LLColor3 & vary_HazeColor, LLColor3 & vary_CloudColorSun,
  737. LLColor3 & vary_CloudColorAmbient, F32 & vary_CloudDensity,
  738. LLVector2 vary_HorizontalProjection[2])
  739. {
  740. LLColor3 res;
  741. LLColor3 color0 = vary_HazeColor;
  742. if (!gPipeline.canUseWindLightShaders())
  743. {
  744. LLColor3 color1 = color0 * 2.0f;
  745. color1 = smear(1.f) - componentSaturate(color1);
  746. componentPow(color1, gamma);
  747. res = smear(1.f) - color1;
  748. }
  749. else
  750. {
  751. res = color0;
  752. }
  753. # ifndef LL_RELEASE_FOR_DOWNLOAD
  754. LLColor3 color2 = 2.f * color0;
  755. LLColor3 color3 = LLColor3(1.f, 1.f, 1.f) - componentSaturate(color2);
  756. componentPow(color3, gamma);
  757. color3 = LLColor3(1.f, 1.f, 1.f) - color3;
  758. static enum {
  759. OUT_DEFAULT = 0,
  760. OUT_SKY_BLUE = 1,
  761. OUT_RED = 2,
  762. OUT_PN = 3,
  763. OUT_HAZE = 4,
  764. } debugOut = OUT_DEFAULT;
  765. switch(debugOut)
  766. {
  767. case OUT_DEFAULT:
  768. break;
  769. case OUT_SKY_BLUE:
  770. res = LLColor3(0.4f, 0.4f, 0.9f);
  771. break;
  772. case OUT_RED:
  773. res = LLColor3(1.f, 0.f, 0.f);
  774. break;
  775. case OUT_PN:
  776. res = LLColor3(Pn[0], Pn[1], Pn[2]);
  777. break;
  778. case OUT_HAZE:
  779. res = vary_HazeColor;
  780. break;
  781. }
  782. # endif // LL_RELEASE_FOR_DOWNLOAD
  783. return res;
  784. }
  785. LLColor3 LLVOSky::createDiffuseFromWL(LLColor3 diffuse, LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient)
  786. {
  787. return componentMult(diffuse, sundiffuse) * 4.0f +
  788. componentMult(ambient, sundiffuse) * 2.0f + sunambient;
  789. }
  790. LLColor3 LLVOSky::createAmbientFromWL(LLColor3 ambient, LLColor3 sundiffuse, LLColor3 sunambient)
  791. {
  792. return (componentMult(ambient, sundiffuse) + sunambient) * 0.8f;
  793. }
  794. void LLVOSky::calcAtmospherics(void)
  795. {
  796. initAtmospherics();
  797. LLColor3 vary_HazeColor;
  798. LLColor3 vary_SunlightColor;
  799. LLColor3 vary_AmbientColor;
  800. {
  801. // Initialize temp variables
  802. LLColor3 sunlight = sunlight_color;
  803. // Sunlight attenuation effect (hue and brightness) due to atmosphere
  804. // this is used later for sunlight modulation at various altitudes
  805. LLColor3 light_atten =
  806. (blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y);
  807. // Calculate relative weights
  808. LLColor3 temp2(0.f, 0.f, 0.f);
  809. LLColor3 temp1 = blue_density + smear(haze_density);
  810. LLColor3 blue_weight = componentDiv(blue_density, temp1);
  811. LLColor3 haze_weight = componentDiv(smear(haze_density), temp1);
  812. // Compute sunlight from P & lightnorm (for long rays like sky)
  813. /// USE only lightnorm.
  814. // temp2[1] = llmax(0.f, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] );
  815. // and vary_sunlight will work properly with moon light
  816. F32 lighty = unclamped_lightnorm[1];
  817. if(lighty < LLSky::NIGHTTIME_ELEVATION_COS)
  818. {
  819. lighty = -lighty;
  820. }
  821. temp2.mV[1] = llmax(0.f, lighty);
  822. if(temp2.mV[1] > 0.f)
  823. {
  824. temp2.mV[1] = 1.f / temp2.mV[1];
  825. }
  826. componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
  827. // Distance
  828. temp2.mV[2] = density_multiplier;
  829. // Transparency (-> temp1)
  830. temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]);
  831. // vary_AtmosAttenuation = temp1;
  832. //increase ambient when there are more clouds
  833. LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5f;
  834. //haze color
  835. vary_HazeColor =
  836. (blue_horizon * blue_weight * (sunlight*(1.f - cloud_shadow) + tmpAmbient)
  837. + componentMult(haze_horizon.mV[0] * haze_weight, sunlight*(1.f - cloud_shadow) * temp2.mV[0] + tmpAmbient)
  838. );
  839. //brightness of surface both sunlight and ambient
  840. vary_SunlightColor = componentMult(sunlight, temp1) * 1.f;
  841. vary_SunlightColor.clamp();
  842. vary_SunlightColor = smear(1.0f) - vary_SunlightColor;
  843. vary_SunlightColor = componentPow(vary_SunlightColor, gamma);
  844. vary_SunlightColor = smear(1.0f) - vary_SunlightColor;
  845. vary_AmbientColor = componentMult(tmpAmbient, temp1) * 0.5;
  846. vary_AmbientColor.clamp();
  847. vary_AmbientColor = smear(1.0f) - vary_AmbientColor;
  848. vary_AmbientColor = componentPow(vary_AmbientColor, gamma);
  849. vary_AmbientColor = smear(1.0f) - vary_AmbientColor;
  850. componentMultBy(vary_HazeColor, LLColor3(1.f, 1.f, 1.f) - temp1);
  851. }
  852. mSun.setColor(vary_SunlightColor);
  853. mMoon.setColor(LLColor3(1.0f, 1.0f, 1.0f));
  854. mSun.renewDirection();
  855. mSun.renewColor();
  856. mMoon.renewDirection();
  857. mMoon.renewColor();
  858. float dp = getToSunLast() * LLVector3(0,0,1.f);
  859. if (dp < 0)
  860. {
  861. dp = 0;
  862. }
  863. // Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio
  864. // between sunlight and point lights in windlight to normalize point lights.
  865. F32 sun_dynamic_range = llmax(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f);
  866. LLWLParamManager::getInstance()->mSceneLightStrength = 2.0f * (1.0f + sun_dynamic_range * dp);
  867. mSunDiffuse = vary_SunlightColor;
  868. mSunAmbient = vary_AmbientColor;
  869. mMoonDiffuse = vary_SunlightColor;
  870. mMoonAmbient = vary_AmbientColor;
  871. mTotalAmbient = vary_AmbientColor;
  872. mTotalAmbient.setAlpha(1);
  873. mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f;
  874. mFadeColor.setAlpha(0);
  875. }
  876. BOOL LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
  877. {
  878. return TRUE;
  879. }
  880. BOOL LLVOSky::updateSky()
  881. {
  882. if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)))
  883. {
  884. return TRUE;
  885. }
  886. if (mDead)
  887. {
  888. // It's dead. Don't update it.
  889. return TRUE;
  890. }
  891. if (gGLManager.mIsDisabled)
  892. {
  893. return TRUE;
  894. }
  895. static S32 next_frame = 0;
  896. const S32 total_no_tiles = 6 * NUM_TILES;
  897. const S32 cycle_frame_no = total_no_tiles + 1;
  898. if (mUpdateTimer.getElapsedTimeF32() > 0.001f)
  899. {
  900. mUpdateTimer.reset();
  901. const S32 frame = next_frame;
  902. ++next_frame;
  903. next_frame = next_frame % cycle_frame_no;
  904. mInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no;
  905. // sInterpVal = (F32)next_frame / cycle_frame_no;
  906. LLSkyTex::setInterpVal( mInterpVal );
  907. LLHeavenBody::setInterpVal( mInterpVal );
  908. calcAtmospherics();
  909. if (mForceUpdate || total_no_tiles == frame)
  910. {
  911. LLSkyTex::stepCurrent();
  912. const static F32 LIGHT_DIRECTION_THRESHOLD = (F32) cos(DEG_TO_RAD * 1.f);
  913. const static F32 COLOR_CHANGE_THRESHOLD = 0.01f;
  914. LLVector3 direction = mSun.getDirection();
  915. direction.normalize();
  916. const F32 dot_lighting = direction * mLastLightingDirection;
  917. LLColor3 delta_color;
  918. delta_color.setVec(mLastTotalAmbient.mV[0] - mTotalAmbient.mV[0],
  919. mLastTotalAmbient.mV[1] - mTotalAmbient.mV[1],
  920. mLastTotalAmbient.mV[2] - mTotalAmbient.mV[2]);
  921. if ( mForceUpdate
  922. || (((dot_lighting < LIGHT_DIRECTION_THRESHOLD)
  923. || (delta_color.length() > COLOR_CHANGE_THRESHOLD)
  924. || !mInitialized)
  925. && !direction.isExactlyZero()))
  926. {
  927. mLastLightingDirection = direction;
  928. mLastTotalAmbient = mTotalAmbient;
  929. mInitialized = TRUE;
  930. if (mCubeMap)
  931. {
  932. if (mForceUpdate)
  933. {
  934. updateFog(LLViewerCamera::getInstance()->getFar());
  935. for (int side = 0; side < 6; side++)
  936. {
  937. for (int tile = 0; tile < NUM_TILES; tile++)
  938. {
  939. createSkyTexture(side, tile);
  940. }
  941. }
  942. calcAtmospherics();
  943. for (int side = 0; side < 6; side++)
  944. {
  945. LLImageRaw* raw1 = mSkyTex[side].getImageRaw(TRUE);
  946. LLImageRaw* raw2 = mSkyTex[side].getImageRaw(FALSE);
  947. raw2->copy(raw1);
  948. mSkyTex[side].createGLImage(mSkyTex[side].getWhich(FALSE));
  949. raw1 = mShinyTex[side].getImageRaw(TRUE);
  950. raw2 = mShinyTex[side].getImageRaw(FALSE);
  951. raw2->copy(raw1);
  952. mShinyTex[side].createGLImage(mShinyTex[side].getWhich(FALSE));
  953. }
  954. next_frame = 0;
  955. }
  956. }
  957. }
  958. /// *TODO really, sky texture and env map should be shared on a single texture
  959. /// I'll let Brad take this at some point
  960. // update the sky texture
  961. for (S32 i = 0; i < 6; ++i)
  962. {
  963. mSkyTex[i].create(1.0f);
  964. mShinyTex[i].create(1.0f);
  965. }
  966. // update the environment map
  967. if (mCubeMap)
  968. {
  969. std::vector<LLPointer<LLImageRaw> > images;
  970. images.reserve(6);
  971. for (S32 side = 0; side < 6; side++)
  972. {
  973. images.push_back(mShinyTex[side].getImageRaw(TRUE));
  974. }
  975. mCubeMap->init(images);
  976. gGL.getTexUnit(0)->disable();
  977. }
  978. gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
  979. // *TODO: decide whether we need to update the stars vertex buffer in LLVOWLSky -Brad.
  980. //gPipeline.markRebuild(gSky.mVOWLSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
  981. mForceUpdate = FALSE;
  982. }
  983. else
  984. {
  985. const S32 side = frame / NUM_TILES;
  986. const S32 tile = frame % NUM_TILES;
  987. createSkyTexture(side, tile);
  988. }
  989. }
  990. if (mDrawable.notNull() && mDrawable->getFace(0) && !mDrawable->getFace(0)->getVertexBuffer())
  991. {
  992. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
  993. }
  994. return TRUE;
  995. }
  996. void LLVOSky::updateTextures()
  997. {
  998. if (mSunTexturep)
  999. {
  1000. mSunTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );
  1001. mMoonTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );
  1002. mBloomTexturep->addTextureStats( (F32)MAX_IMAGE_AREA );
  1003. }
  1004. }
  1005. LLDrawable *LLVOSky::createDrawable(LLPipeline *pipeline)
  1006. {
  1007. pipeline->allocDrawable(this);
  1008. mDrawable->setLit(FALSE);
  1009. LLDrawPoolSky *poolp = (LLDrawPoolSky*) gPipeline.getPool(LLDrawPool::POOL_SKY);
  1010. poolp->setSkyTex(mSkyTex);
  1011. mDrawable->setRenderType(LLPipeline::RENDER_TYPE_SKY);
  1012. for (S32 i = 0; i < 6; ++i)
  1013. {
  1014. mFace[FACE_SIDE0 + i] = mDrawable->addFace(poolp, NULL);
  1015. }
  1016. mFace[FACE_SUN] = mDrawable->addFace(poolp, mSunTexturep);
  1017. mFace[FACE_MOON] = mDrawable->addFace(poolp, mMoonTexturep);
  1018. mFace[FACE_BLOOM] = mDrawable->addFace(poolp, mBloomTexturep);
  1019. return mDrawable;
  1020. }
  1021. //by bao
  1022. //fake vertex buffer updating
  1023. //to guarantee at least updating one VBO buffer every frame
  1024. //to walk around the bug caused by ATI card --> DEV-3855
  1025. //
  1026. void LLVOSky::createDummyVertexBuffer()
  1027. {
  1028. if(!mFace[FACE_DUMMY])
  1029. {
  1030. LLDrawPoolSky *poolp = (LLDrawPoolSky*) gPipeline.getPool(LLDrawPool::POOL_SKY);
  1031. mFace[FACE_DUMMY] = mDrawable->addFace(poolp, NULL);
  1032. }
  1033. if(!mFace[FACE_DUMMY]->getVertexBuffer())
  1034. {
  1035. LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
  1036. buff->allocateBuffer(1, 1, TRUE);
  1037. mFace[FACE_DUMMY]->setVertexBuffer(buff);
  1038. }
  1039. }
  1040. static LLFastTimer::DeclareTimer FTM_RENDER_FAKE_VBO_UPDATE("Fake VBO Update");
  1041. void LLVOSky::updateDummyVertexBuffer()
  1042. {
  1043. if(!LLVertexBuffer::sEnableVBOs)
  1044. return ;
  1045. if(mHeavenlyBodyUpdated)
  1046. {
  1047. mHeavenlyBodyUpdated = FALSE ;
  1048. return ;
  1049. }
  1050. LLFastTimer t(FTM_RENDER_FAKE_VBO_UPDATE) ;
  1051. if(!mFace[FACE_DUMMY] || !mFace[FACE_DUMMY]->getVertexBuffer())
  1052. createDummyVertexBuffer() ;
  1053. LLStrider<LLVector3> vertices ;
  1054. mFace[FACE_DUMMY]->getVertexBuffer()->getVertexStrider(vertices, 0);
  1055. *vertices = mCameraPosAgent ;
  1056. mFace[FACE_DUMMY]->getVertexBuffer()->flush();
  1057. }
  1058. //----------------------------------
  1059. //end of fake vertex buffer updating
  1060. //----------------------------------
  1061. static LLFastTimer::DeclareTimer FTM_GEO_SKY("Sky Geometry");
  1062. BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
  1063. {
  1064. LLFastTimer ftm(FTM_GEO_SKY);
  1065. if (mFace[FACE_REFLECTION] == NULL)
  1066. {
  1067. LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
  1068. if (gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() != 0)
  1069. {
  1070. mFace[FACE_REFLECTION] = drawable->addFace(poolp, NULL);
  1071. }
  1072. }
  1073. mCameraPosAgent = drawable->getPositionAgent();
  1074. mEarthCenter.mV[0] = mCameraPosAgent.mV[0];
  1075. mEarthCenter.mV[1] = mCameraPosAgent.mV[1];
  1076. LLVector3 v_agent[8];
  1077. for (S32 i = 0; i < 8; ++i)
  1078. {
  1079. F32 x_sgn = (i&1) ? 1.f : -1.f;
  1080. F32 y_sgn = (i&2) ? 1.f : -1.f;
  1081. F32 z_sgn = (i&4) ? 1.f : -1.f;
  1082. v_agent[i] = HORIZON_DIST * SKY_BOX_MULT * LLVector3(x_sgn, y_sgn, z_sgn);
  1083. }
  1084. LLStrider<LLVector3> verticesp;
  1085. LLStrider<LLVector3> normalsp;
  1086. LLStrider<LLVector2> texCoordsp;
  1087. LLStrider<U16> indicesp;
  1088. U16 index_offset;
  1089. LLFace *face;
  1090. for (S32 side = 0; side < 6; ++side)
  1091. {
  1092. face = mFace[FACE_SIDE0 + side];
  1093. if (!face->getVertexBuffer())
  1094. {
  1095. face->setSize(4, 6);
  1096. face->setGeomIndex(0);
  1097. face->setIndicesIndex(0);
  1098. LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
  1099. buff->allocateBuffer(4, 6, TRUE);
  1100. face->setVertexBuffer(buff);
  1101. index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
  1102. S32 vtx = 0;
  1103. S32 curr_bit = side >> 1; // 0/1 = Z axis, 2/3 = Y, 4/5 = X
  1104. S32 side_dir = side & 1; // even - 0, odd - 1
  1105. S32 i_bit = (curr_bit + 2) % 3;
  1106. S32 j_bit = (i_bit + 2) % 3;
  1107. LLVector3 axis;
  1108. axis.mV[curr_bit] = 1;
  1109. face->mCenterAgent = (F32)((side_dir << 1) - 1) * axis * HORIZON_DIST;
  1110. vtx = side_dir << curr_bit;
  1111. *(verticesp++) = v_agent[vtx];
  1112. *(verticesp++) = v_agent[vtx | 1 << j_bit];
  1113. *(verticesp++) = v_agent[vtx | 1 << i_bit];
  1114. *(verticesp++) = v_agent[vtx | 1 << i_bit | 1 << j_bit];
  1115. *(texCoordsp++) = TEX00;
  1116. *(texCoordsp++) = TEX01;
  1117. *(texCoordsp++) = TEX10;
  1118. *(texCoordsp++) = TEX11;
  1119. // Triangles for each side
  1120. *indicesp++ = index_offset + 0;
  1121. *indicesp++ = index_offset + 1;
  1122. *indicesp++ = index_offset + 3;
  1123. *indicesp++ = index_offset + 0;
  1124. *indicesp++ = index_offset + 3;
  1125. *indicesp++ = index_offset + 2;
  1126. buff->flush();
  1127. }
  1128. }
  1129. const LLVector3 &look_at = LLViewerCamera::getInstance()->getAtAxis();
  1130. LLVector3 right = look_at % LLVector3::z_axis;
  1131. LLVector3 up = right % look_at;
  1132. right.normalize();
  1133. up.normalize();
  1134. const static F32 elevation_factor = 0.0f/sResolution;
  1135. const F32 cos_max_angle = cosHorizon(elevation_factor);
  1136. mSun.setDraw(updateHeavenlyBodyGeometry(drawable, FACE_SUN, TRUE, mSun, cos_max_angle, up, right));
  1137. mMoon.setDraw(updateHeavenlyBodyGeometry(drawable, FACE_MOON, FALSE, mMoon, cos_max_angle, up, right));
  1138. const F32 water_height = gAgent.getRegion()->getWaterHeight() + 0.01f;
  1139. // LLWorld::getInstance()->getWaterHeight() + 0.01f;
  1140. const F32 camera_height = mCameraPosAgent.mV[2];
  1141. const F32 height_above_water = camera_height - water_height;
  1142. BOOL sun_flag = FALSE;
  1143. if (mSun.isVisible())
  1144. {
  1145. if (mMoon.isVisible())
  1146. {
  1147. sun_flag = look_at * mSun.getDirection() > 0;
  1148. }
  1149. else
  1150. {
  1151. sun_flag = TRUE;
  1152. }
  1153. }
  1154. if (height_above_water > 0)
  1155. {
  1156. BOOL render_ref = gPipeline.getPool(LLDrawPool::POOL_WATER)->getVertexShaderLevel() == 0;
  1157. if (sun_flag)
  1158. {
  1159. setDrawRefl(0);
  1160. if (render_ref)
  1161. {
  1162. updateReflectionGeometry(drawable, height_above_water, mSun);
  1163. }
  1164. }
  1165. else
  1166. {
  1167. setDrawRefl(1);
  1168. if (render_ref)
  1169. {
  1170. updateReflectionGeometry(drawable, height_above_water, mMoon);
  1171. }
  1172. }
  1173. }
  1174. else
  1175. {
  1176. setDrawRefl(-1);
  1177. }
  1178. LLPipeline::sCompiles++;
  1179. return TRUE;
  1180. }
  1181. BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, const BOOL is_sun,
  1182. LLHeavenBody& hb, const F32 cos_max_angle,
  1183. const LLVector3 &up, const LLVector3 &right)
  1184. {
  1185. mHeavenlyBodyUpdated = TRUE ;
  1186. LLStrider<LLVector3> verticesp;
  1187. LLStrider<LLVector3> normalsp;
  1188. LLStrider<LLVector2> texCoordsp;
  1189. LLStrider<U16> indicesp;
  1190. S32 index_offset;
  1191. LLFace *facep;
  1192. LLVector3 to_dir = hb.getDirection();
  1193. if (!is_sun)
  1194. {
  1195. to_dir.mV[2] = llmax(to_dir.mV[2]+0.1f, 0.1f);
  1196. }
  1197. LLVector3 draw_pos = to_dir * HEAVENLY_BODY_DIST;
  1198. LLVector3 hb_right = to_dir % LLVector3::z_axis;
  1199. LLVector3 hb_up = hb_right % to_dir;
  1200. hb_right.normalize();
  1201. hb_up.normalize();
  1202. //const static F32 cos_max_turn = sqrt(3.f) / 2; // 30 degrees
  1203. //const F32 cos_turn_right = 1. / (llmax(cos_max_turn, hb_right * right));
  1204. //const F32 cos_turn_up = 1. / llmax(cos_max_turn, hb_up * up);
  1205. const F32 enlargm_factor = ( 1 - to_dir.mV[2] );
  1206. F32 horiz_enlargement = 1 + enlargm_factor * 0.3f;
  1207. F32 vert_enlargement = 1 + enlargm_factor * 0.2f;
  1208. // Parameters for the water reflection
  1209. hb.setU(HEAVENLY_BODY_FACTOR * horiz_enlargement * hb.getDiskRadius() * hb_right);
  1210. hb.setV(HEAVENLY_BODY_FACTOR * vert_enlargement * hb.getDiskRadius() * hb_up);
  1211. // End of parameters for the water reflection
  1212. const LLVector3 scaled_right = HEAVENLY_BODY_DIST * hb.getU();
  1213. const LLVector3 scaled_up = HEAVENLY_BODY_DIST * hb.getV();
  1214. //const LLVector3 scaled_right = horiz_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius() * hb_right;//right;
  1215. //const LLVector3 scaled_up = vert_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius() * hb_up;//up;
  1216. LLVector3 v_clipped[4];
  1217. hb.corner(0) = draw_pos - scaled_right + scaled_up;
  1218. hb.corner(1) = draw_pos - scaled_right - scaled_up;
  1219. hb.corner(2) = draw_pos + scaled_right + scaled_up;
  1220. hb.corner(3) = draw_pos + scaled_right - scaled_up;
  1221. F32 t_left, t_right;
  1222. if (!clip_quad_to_horizon(t_left, t_right, v_clipped, hb.corners(), cos_max_angle))
  1223. {
  1224. hb.setVisible(FALSE);
  1225. return FALSE;
  1226. }
  1227. hb.setVisible(TRUE);
  1228. facep = mFace[f];
  1229. if (!facep->getVertexBuffer())
  1230. {
  1231. facep->setSize(4, 6);
  1232. LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
  1233. buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE);
  1234. facep->setGeomIndex(0);
  1235. facep->setIndicesIndex(0);
  1236. facep->setVertexBuffer(buff);
  1237. }
  1238. llassert(facep->getVertexBuffer()->getNumIndices() == 6);
  1239. index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
  1240. if (-1 == index_offset)
  1241. {
  1242. return TRUE;
  1243. }
  1244. for (S32 vtx = 0; vtx < 4; ++vtx)
  1245. {
  1246. hb.corner(vtx) = v_clipped[vtx];
  1247. *(verticesp++) = hb.corner(vtx) + mCameraPosAgent;
  1248. }
  1249. *(texCoordsp++) = TEX01;
  1250. *(texCoordsp++) = TEX00;
  1251. *(texCoordsp++) = TEX11;
  1252. *(texCoordsp++) = TEX10;
  1253. *indicesp++ = index_offset + 0;
  1254. *indicesp++ = index_offset + 2;
  1255. *indicesp++ = index_offset + 1;
  1256. *indicesp++ = index_offset + 1;
  1257. *indicesp++ = index_offset + 2;
  1258. *indicesp++ = index_offset + 3;
  1259. facep->getVertexBuffer()->flush();
  1260. if (is_sun)
  1261. {
  1262. if ((t_left > 0) && (t_right > 0))
  1263. {
  1264. F32 t = (t_left + t_right) * 0.5f;
  1265. mSun.setHorizonVisibility(0.5f * (1 + cos(t * F_PI)));
  1266. }
  1267. else
  1268. {
  1269. mSun.setHorizonVisibility();
  1270. }
  1271. updateSunHaloGeometry(drawable);
  1272. }
  1273. return TRUE;
  1274. }
  1275. // Clips quads with top and bottom sides parallel to horizon.
  1276. BOOL clip_quad_to_horizon(F32& t_left, F32& t_right, LLVector3 v_clipped[4],
  1277. const LLVector3 v_corner[4], const F32 cos_max_angle)
  1278. {
  1279. t_left = clip_side_to_horizon(v_corner[1], v_corner[0], cos_max_angle);
  1280. t_right = clip_side_to_horizon(v_corner[3], v_corner[2], cos_max_angle);
  1281. if ((t_left >= 1) || (t_right >= 1))
  1282. {
  1283. return FALSE;
  1284. }
  1285. //const BOOL left_clip = (t_left > 0);
  1286. //const BOOL right_clip = (t_right > 0);
  1287. //if (!left_clip && !right_clip)
  1288. {
  1289. for (S32 vtx = 0; vtx < 4; ++vtx)
  1290. {
  1291. v_clipped[vtx] = v_corner[vtx];
  1292. }
  1293. }
  1294. /* else
  1295. {
  1296. v_clipped[0] = v_corner[0];
  1297. v_clipped[1] = left_clip ? ((1 - t_left) * v_corner[1] + t_left * v_corner[0])
  1298. : v_corner[1];
  1299. v_clipped[2] = v_corner[2];
  1300. v_clipped[3] = right_clip ? ((1 - t_right) * v_corner[3] + t_right * v_corner[2])
  1301. : v_corner[3];
  1302. }*/
  1303. return TRUE;
  1304. }
  1305. F32 clip_side_to_horizon(const LLVector3& V0, const LLVector3& V1, const F32 cos_max_angle)
  1306. {
  1307. const LLVector3 V = V1 - V0;
  1308. const F32 k2 = 1.f/(cos_max_angle * cos_max_angle) - 1;
  1309. const F32 A = V.mV[0] * V.mV[0] + V.mV[1] * V.mV[1] - k2 * V.mV[2] * V.mV[2];
  1310. const F32 B = V0.mV[0] * V.mV[0] + V0.mV[1] * V.mV[1] - k2 * V0.mV[2] * V.mV[2];
  1311. const F32 C = V0.mV[0] * V0.mV[0] + V0.mV[1] * V0.mV[1] - k2 * V0.mV[2] * V0.mV[2];
  1312. if (fabs(A) < 1e-7)
  1313. {
  1314. return -0.1f; // v0 is cone origin and v1 is on the surface of the cone.
  1315. }
  1316. const F32 det = sqrt(B*B - A*C);
  1317. const F32 t1 = (-B - det) / A;
  1318. const F32 t2 = (-B + det) / A;
  1319. const F32 z1 = V0.mV[2] + t1 * V.mV[2];
  1320. const F32 z2 = V0.mV[2] + t2 * V.mV[2];
  1321. if (z1 * cos_max_angle < 0)
  1322. {
  1323. return t2;
  1324. }
  1325. else if (z2 * cos_max_angle < 0)
  1326. {
  1327. return t1;
  1328. }
  1329. else if ((t1 < 0) || (t1 > 1))
  1330. {
  1331. return t2;
  1332. }
  1333. else
  1334. {
  1335. return t1;
  1336. }
  1337. }
  1338. void LLVOSky::updateSunHaloGeometry(LLDrawable *drawable )
  1339. {
  1340. #if 0
  1341. const LLVector3* v_corner = mSun.corners();
  1342. LLStrider<LLVector3> verticesp;
  1343. LLStrider<LLVector3> normalsp;
  1344. LLStrider<LLVector2> texCoordsp;
  1345. LLStrider<U16> indicesp;
  1346. S32 index_offset;
  1347. LLFace *face;
  1348. const LLVector3 right = 2 * (v_corner[2] - v_corner[0]);
  1349. LLVector3 up = 2 * (v_corner[2] - v_corner[3]);
  1350. up.normalize();
  1351. F32 size = right.length();
  1352. up = size * up;
  1353. const LLVector3 draw_pos = 0.25 * (v_corner[0] + v_corner[1] + v_corner[2] + v_corner[3]);
  1354. LLVector3 v_glow_corner[4];
  1355. v_glow_corner[0] = draw_pos - right + up;
  1356. v_glow_corner[1] = draw_pos - right - up;
  1357. v_glow_corner[2] = draw_pos + right + up;
  1358. v_glow_corner[3] = draw_pos + right - up;
  1359. face = mFace[FACE_BLOOM];
  1360. if (face->mVertexBuffer.isNull())
  1361. {
  1362. face->setSize(4, 6);
  1363. face->setGeomIndex(0);
  1364. face->setIndicesIndex(0);
  1365. face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
  1366. face->mVertexBuffer->allocateBuffer(4, 6, TRUE);
  1367. }
  1368. index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
  1369. if (-1 == index_offset)
  1370. {
  1371. return;
  1372. }
  1373. for (S32 vtx = 0; vtx < 4; ++vtx)
  1374. {
  1375. *(verticesp++) = v_glow_corner[vtx] + mCameraPosAgent;
  1376. }
  1377. *(texCoordsp++) = TEX01;
  1378. *(texCoordsp++) = TEX00;
  1379. *(texCoordsp++) = TEX11;
  1380. *(texCoordsp++) = TEX10;
  1381. *indicesp++ = index_offset + 0;
  1382. *indicesp++ = index_offset + 2;
  1383. *indicesp++ = index_offset + 1;
  1384. *indicesp++ = index_offset + 1;
  1385. *indicesp++ = index_offset + 2;
  1386. *indicesp++ = index_offset + 3;
  1387. #endif
  1388. }
  1389. F32 dtReflection(const LLVector3& p, F32 cos_dir_from_top, F32 sin_dir_from_top, F32 diff_angl_dir)
  1390. {
  1391. LLVector3 P = p;
  1392. P.normalize();
  1393. const F32 cos_dir_angle = -P.mV[VZ];
  1394. const F32 sin_dir_angle = sqrt(1 - cos_dir_angle * cos_dir_angle);
  1395. F32 cos_diff_angles = cos_dir_angle * cos_dir_from_top
  1396. + sin_dir_angle * sin_dir_from_top;
  1397. F32 diff_angles;
  1398. if (cos_diff_angles > (1 - 1e-7))
  1399. diff_angles = 0;
  1400. else
  1401. diff_angles = acos(cos_diff_angles);
  1402. const F32 rel_diff_angles = diff_angles / diff_angl_dir;
  1403. const F32 dt = 1 - rel_diff_angles;
  1404. return (dt < 0) ? 0 : dt;
  1405. }
  1406. F32 dtClip(const LLVector3& v0, const LLVector3& v1, F32 far_clip2)
  1407. {
  1408. F32 dt_clip;
  1409. const LLVector3 otrezok = v1 - v0;
  1410. const F32 A = otrezok.lengthSquared();
  1411. const F32 B = v0 * otrezok;
  1412. const F32 C = v0.lengthSquared() - far_clip2;
  1413. const F32 det = sqrt(B*B - A*C);
  1414. dt_clip = (-B - det) / A;
  1415. if ((dt_clip < 0) || (dt_clip > 1))
  1416. dt_clip = (-B + det) / A;
  1417. return dt_clip;
  1418. }
  1419. void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
  1420. const LLHeavenBody& HB)
  1421. {
  1422. const LLVector3 &look_at = LLViewerCamera::getInstance()->getAtAxis();
  1423. // const F32 water_height = gAgent.getRegion()->getWaterHeight() + 0.001f;
  1424. // LLWorld::getInstance()->getWaterHeight() + 0.001f;
  1425. LLVector3 to_dir = HB.getDirection();
  1426. LLVector3 hb_pos = to_dir * (HORIZON_DIST - 10);
  1427. LLVector3 to_dir_proj = to_dir;
  1428. to_dir_proj.mV[VZ] = 0;
  1429. to_dir_proj.normalize();
  1430. LLVector3 Right = to_dir % LLVector3::z_axis;
  1431. LLVector3 Up = Right % to_dir;
  1432. Right.normalize();
  1433. Up.normalize();
  1434. // finding angle between look direction and sprite.
  1435. LLVector3 look_at_right = look_at % LLVector3::z_axis;
  1436. look_at_right.normalize();
  1437. const static F32 cos_horizon_angle = cosHorizon(0.0f/sResolution);
  1438. //const static F32 horizon_angle = acos(cos_horizon_angle);
  1439. const F32 enlargm_factor = ( 1 - to_dir.mV[2] );
  1440. F32 horiz_enlargement = 1 + enlargm_factor * 0.3f;
  1441. F32 vert_enlargement = 1 + enlargm_factor * 0.2f;
  1442. F32 vert_size = vert_enlargement * HEAVENLY_BODY_SCALE * HB.getDiskRadius();
  1443. Right *= /*cos_lookAt_toDir */ horiz_enlargement * HEAVENLY_BODY_SCALE * HB.getDiskRadius();
  1444. Up *= vert_size;
  1445. LLVector3 v_corner[2];
  1446. LLVector3 stretch_corner[2];
  1447. LLVector3 top_hb = v_corner[0] = stretch_corner[0] = hb_pos - Right + Up;
  1448. v_corner[1] = stretch_corner[1] = hb_pos - Right - Up;
  1449. F32 dt_hor, dt;
  1450. dt_hor = clip_side_to_horizon(v_corner[1], v_corner[0], cos_horizon_angle);
  1451. LLVector2 TEX0t = TEX00;
  1452. LLVector2 TEX1t = TEX10;
  1453. LLVector3 lower_corner = v_corner[1];
  1454. if ((dt_hor > 0) && (dt_hor < 1))
  1455. {
  1456. TEX0t = LLVector2(0, dt_hor);
  1457. TEX1t = LLVector2(1, dt_hor);
  1458. lower_corner = (1 - dt_hor) * v_corner[1] + dt_hor * v_corner[0];
  1459. }
  1460. else
  1461. dt_hor = llmax(0.0f, llmin(1.0f, dt_hor));
  1462. top_hb.normalize();
  1463. const F32 cos_angle_of_view = fabs(top_hb.mV[VZ]);
  1464. const F32 extension = llmin (5.0f, 1.0f / cos_angle_of_view);
  1465. const S32 cols = 1;
  1466. const S32 raws = lltrunc(16 * extension);
  1467. S32 quads = cols * raws;
  1468. stretch_corner[0] = lower_corner + extension * (stretch_corner[0] - lower_corner);
  1469. stretch_corner[1] = lower_corner + extension * (stretch_corner[1] - lower_corner);
  1470. dt = dt_hor;
  1471. F32 cos_dir_from_top[2];
  1472. LLVector3 dir = stretch_corner[0];
  1473. dir.normalize();
  1474. cos_dir_from_top[0] = dir.mV[VZ];
  1475. dir = stretch_corner[1];
  1476. dir.normalize();
  1477. cos_dir_from_top[1] = dir.mV[VZ];
  1478. const F32 sin_dir_from_top = sqrt(1 - cos_dir_from_top[0] * cos_dir_from_top[0]);
  1479. const F32 sin_dir_from_top2 = sqrt(1 - cos_dir_from_top[1] * cos_dir_from_top[1]);
  1480. const F32 cos_diff_dir = cos_dir_from_top[0] * cos_dir_from_top[1]
  1481. + sin_dir_from_top * sin_dir_from_top2;
  1482. const F32 diff_angl_dir = acos(cos_diff_dir);
  1483. v_corner[0] = stretch_corner[0];
  1484. v_corner[1] = lower_corner;
  1485. LLVector2 TEX0tt = TEX01;
  1486. LLVector2 TEX1tt = TEX11;
  1487. LLVector3 v_refl_corner[4];
  1488. LLVector3 v_sprite_corner[4];
  1489. S32 vtx;
  1490. for (vtx = 0; vtx < 2; ++vtx)
  1491. {
  1492. LLVector3 light_proj = v_corner[vtx];
  1493. light_proj.normalize();
  1494. const F32 z = light_proj.mV[VZ];
  1495. const F32 sin_angle = sqrt(1 - z * z);
  1496. light_proj *= 1.f / sin_angle;
  1497. light_proj.mV[VZ] = 0;
  1498. const F32 to_refl_point = H * sin_angle / fabs(z);
  1499. v_refl_corner[vtx] = to_refl_point * light_proj;
  1500. }
  1501. for (vtx = 2; vtx < 4; ++vtx)
  1502. {
  1503. const LLVector3 to_dir_vec = (to_dir_proj * v_refl_corner[vtx-2]) * to_dir_proj;
  1504. v_refl_corner[vtx] = v_refl_corner[vtx-2] + 2 * (to_dir_vec - v_refl_corner[vtx-2]);
  1505. }
  1506. for (vtx = 0; vtx < 4; ++vtx)
  1507. v_refl_corner[vtx].mV[VZ] -= H;
  1508. S32 side = 0;
  1509. LLVector3 refl_corn_norm[2];
  1510. refl_corn_norm[0] = v_refl_corner[1];
  1511. refl_corn_norm[0].normalize();
  1512. refl_corn_norm[1] = v_refl_corner[3];
  1513. refl_corn_norm[1].normalize();
  1514. F32 cos_refl_look_at[2];
  1515. cos_refl_look_at[0] = refl_corn_norm[0] * look_at;
  1516. cos_refl_look_at[1] = refl_corn_norm[1] * look_at;
  1517. if (cos_refl_look_at[1] > cos_refl_look_at[0])
  1518. {
  1519. side = 2;
  1520. }
  1521. //const F32 far_clip = (LLViewerCamera::getInstance()->getFar() - 0.01) / far_clip_factor;
  1522. const F32 far_clip = 512;
  1523. const F32 far_clip2 = far_clip*far_clip;
  1524. F32 dt_clip;
  1525. F32 vtx_near2, vtx_far2;
  1526. if ((vtx_far2 = v_refl_corner[side].lengthSquared()) > far_clip2)
  1527. {
  1528. // whole thing is sprite: reflection is beyond far clip plane.
  1529. dt_clip = 1.1f;
  1530. quads = 1;
  1531. }
  1532. else if ((vtx_near2 = v_refl_corner[side+1].lengthSquared()) > far_clip2)
  1533. {
  1534. // part is reflection, the rest is sprite.
  1535. dt_clip = dtClip(v_refl_corner[side + 1], v_refl_corner[side], far_clip2);
  1536. const LLVector3 P = (1 - dt_clip) * v_refl_corner[side + 1] + dt_clip * v_refl_corner[side];
  1537. F32 dt_tex = dtReflection(P, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir);
  1538. dt = dt_tex;
  1539. TEX0tt = LLVector2(0, dt);
  1540. TEX1tt = LLVector2(1, dt);
  1541. quads++;
  1542. }
  1543. else
  1544. {
  1545. // whole thing is correct reflection.
  1546. dt_clip = -0.1f;
  1547. }
  1548. LLFace *face = mFace[FACE_REFLECTION];
  1549. if (!face->getVertexBuffer() || quads*4 != face->getGeomCount())
  1550. {
  1551. face->setSize(quads * 4, quads * 6);
  1552. LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
  1553. buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE);
  1554. face->setIndicesIndex(0);
  1555. face->setGeomIndex(0);
  1556. face->setVertexBuffer(buff);
  1557. }
  1558. LLStrider<LLVector3> verticesp;
  1559. LLStrider<LLVector3> normalsp;
  1560. LLStrider<LLVector2> texCoordsp;
  1561. LLStrider<U16> indicesp;
  1562. S32 index_offset;
  1563. index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
  1564. if (-1 == index_offset)
  1565. {
  1566. return;
  1567. }
  1568. LLColor3 hb_col3 = HB.getInterpColor();
  1569. hb_col3.clamp();
  1570. const LLColor4 hb_col = LLColor4(hb_col3);
  1571. const F32 min_attenuation = 0.4f;
  1572. const F32 max_attenuation = 0.7f;
  1573. const F32 attenuation = min_attenuation
  1574. + cos_angle_of_view * (max_attenuation - min_attenuation);
  1575. LLColor4 hb_refl_col = (1-attenuation) * hb_col + attenuation * mFogColor;
  1576. face->setFaceColor(hb_refl_col);
  1577. LLVector3 v_far[2];
  1578. v_far[0] = v_refl_corner[1];
  1579. v_far[1] = v_refl_corner[3];
  1580. if(dt_clip > 0)
  1581. {
  1582. if (dt_clip >= 1)
  1583. {
  1584. for (S32 vtx = 0; vtx < 4; ++vtx)
  1585. {
  1586. F32 ratio = far_clip / v_refl_corner[vtx].length();
  1587. *(verticesp++) = v_refl_corner[vtx] = ratio * v_refl_corner[vtx] + mCameraPosAgent;
  1588. }
  1589. const LLVector3 draw_pos = 0.25 *
  1590. (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]);
  1591. face->mCenterAgent = draw_pos;
  1592. }
  1593. else
  1594. {
  1595. F32 ratio = far_clip / v_refl_corner[1].length();
  1596. v_sprite_corner[1] = v_refl_corner[1] * ratio;
  1597. ratio = far_clip / v_refl_corner[3].length();
  1598. v_sprite_corner[3] = v_refl_corner[3] * ratio;
  1599. v_refl_corner[1] = (1 - dt_clip) * v_refl_corner[1] + dt_clip * v_refl_corner[0];
  1600. v_refl_corner[3] = (1 - dt_clip) * v_refl_corner[3] + dt_clip * v_refl_corner[2];
  1601. v_sprite_corner[0] = v_refl_corner[1];
  1602. v_sprite_corner[2] = v_refl_corner[3];
  1603. for (S32 vtx = 0; vtx < 4; ++vtx)
  1604. {
  1605. *(verticesp++) = v_sprite_corner[vtx] + mCameraPosAgent;
  1606. }
  1607. const LLVector3 draw_pos = 0.25 *
  1608. (v_refl_corner[0] + v_sprite_corner[1] + v_refl_corner[2] + v_sprite_corner[3]);
  1609. face->mCenterAgent = draw_pos;
  1610. }
  1611. *(texCoordsp++) = TEX0tt;
  1612. *(texCoordsp++) = TEX0t;
  1613. *(texCoordsp++) = TEX1tt;
  1614. *(texCoordsp++) = TEX1t;
  1615. *indicesp++ = index_offset + 0;
  1616. *indicesp++ = index_offset + 2;
  1617. *indicesp++ = index_offset + 1;
  1618. *indicesp++ = index_offset + 1;
  1619. *indicesp++ = index_offset + 2;
  1620. *indicesp++ = index_offset + 3;
  1621. index_offset += 4;
  1622. }
  1623. if (dt_clip < 1)
  1624. {
  1625. if (dt_clip <= 0)
  1626. {
  1627. const LLVector3 draw_pos = 0.25 *
  1628. (v_refl_corner[0] + v_refl_corner[1] + v_refl_corner[2] + v_refl_corner[3]);
  1629. face->mCenterAgent = draw_pos;
  1630. }
  1631. const F32 raws_inv = 1.f/raws;
  1632. const F32 cols_inv = 1.f/cols;
  1633. LLVector3 left = v_refl_corner[0] - v_refl_corner[1];
  1634. LLVector3 right = v_refl_corner[2] - v_refl_corner[3];
  1635. left *= raws_inv;
  1636. right *= raws_inv;
  1637. F32 dt_raw = dt;
  1638. for (S32 raw = 0; raw < raws; ++raw)
  1639. {
  1640. F32 dt_v0 = raw * raws_inv;
  1641. F32 dt_v1 = (raw + 1) * raws_inv;
  1642. const LLVector3 BL = v_refl_corner[1] + (F32)raw * left;
  1643. const LLVector3 BR = v_refl_corner[3] + (F32)raw * right;
  1644. const LLVector3 EL = BL + left;
  1645. const LLVector3 ER = BR + right;
  1646. dt_v0 = dt_raw;
  1647. dt_raw = dt_v1 = dtReflection(EL, cos_dir_from_top[0], sin_dir_from_top, diff_angl_dir);
  1648. for (S32 col = 0; col < cols; ++col)
  1649. {
  1650. F32 dt_h0 = col * cols_inv;
  1651. *(verticesp++) = (1 - dt_h0) * EL + dt_h0 * ER + mCameraPosAgent;
  1652. *(verticesp++) = (1 - dt_h0) * BL + dt_h0 * BR + mCameraPosAgent;
  1653. F32 dt_h1 = (col + 1) * cols_inv;
  1654. *(verticesp++) = (1 - dt_h1) * EL + dt_h1 * ER + mCameraPosAgent;
  1655. *(verticesp++) = (1 - dt_h1) * BL + dt_h1 * BR + mCameraPosAgent;
  1656. *(texCoordsp++) = LLVector2(dt_h0, dt_v1);
  1657. *(texCoordsp++) = LLVector2(dt_h0, dt_v0);
  1658. *(texCoordsp++) = LLVector2(dt_h1, dt_v1);
  1659. *(texCoordsp++) = LLVector2(dt_h1, dt_v0);
  1660. *indicesp++ = index_offset + 0;
  1661. *indicesp++ = index_offset + 2;
  1662. *indicesp++ = index_offset + 1;
  1663. *indicesp++ = index_offset + 1;
  1664. *indicesp++ = index_offset + 2;
  1665. *indicesp++ = index_offset + 3;
  1666. index_offset += 4;
  1667. }
  1668. }
  1669. }
  1670. face->getVertexBuffer()->flush();
  1671. }
  1672. void LLVOSky::updateFog(const F32 distance)
  1673. {
  1674. if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG))
  1675. {
  1676. if (!LLGLSLShader::sNoFixedFunction)
  1677. {
  1678. glFogf(GL_FOG_DENSITY, 0);
  1679. glFogfv(GL_FOG_COLOR, (F32 *) &LLColor4::white.mV);
  1680. glFogf(GL_FOG_END, 1000000.f);
  1681. }
  1682. return;
  1683. }
  1684. const BOOL hide_clip_plane = TRUE;
  1685. LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f);
  1686. const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f;
  1687. // LLWorld::getInstance()->getWaterHeight();
  1688. F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2];
  1689. F32 near_clip_height = LLViewerCamera::getInstance()->getAtAxis().mV[VZ] * LLViewerCamera::getInstance()->getNear();
  1690. camera_height += near_clip_height;
  1691. F32 fog_distance = 0.f;
  1692. LLColor3 res_color[3];
  1693. LLColor3 sky_fog_color = LLColor3::white;
  1694. LLColor3 render_fog_color = LLColor3::white;
  1695. LLVector3 tosun = getToSunLast();
  1696. const F32 tosun_z = tosun.mV[VZ];
  1697. tosun.mV[VZ] = 0.f;
  1698. tosun.normalize();
  1699. LLVector3 perp_tosun;
  1700. perp_tosun.mV[VX] = -tosun.mV[VY];
  1701. perp_tosun.mV[VY] = tosun.mV[VX];
  1702. LLVector3 tosun_45 = tosun + perp_tosun;
  1703. tosun_45.normalize();
  1704. F32 delta = 0.06f;
  1705. tosun.mV[VZ] = delta;
  1706. perp_tosun.mV[VZ] = delta;
  1707. tosun_45.mV[VZ] = delta;
  1708. tosun.normalize();
  1709. perp_tosun.normalize();
  1710. tosun_45.normalize();
  1711. // Sky colors, just slightly above the horizon in the direction of the sun, perpendicular to the sun, and at a 45 degree angle to the sun.
  1712. initAtmospherics();
  1713. res_color[0] = calcSkyColorInDir(tosun);
  1714. res_color[1] = calcSkyColorInDir(perp_tosun);
  1715. res_color[2] = calcSkyColorInDir(tosun_45);
  1716. sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]);
  1717. F32 full_off = -0.25f;
  1718. F32 full_on = 0.00f;
  1719. F32 on = (tosun_z - full_off) / (full_on - full_off);
  1720. on = llclamp(on, 0.01f, 1.f);
  1721. sky_fog_color *= 0.5f * on;
  1722. // We need to clamp these to non-zero, in order for the gamma correction to work. 0^y = ???
  1723. S32 i;
  1724. for (i = 0; i < 3; i++)
  1725. {
  1726. sky_fog_color.mV[i] = llmax(0.0001f, sky_fog_color.mV[i]);
  1727. }
  1728. color_gamma_correct(sky_fog_color);
  1729. render_fog_color = sky_fog_color;
  1730. F32 fog_density = 0.f;
  1731. fog_distance = mFogRatio * distance;
  1732. if (camera_height > water_height)
  1733. {
  1734. LLColor4 fog(render_fog_color);
  1735. if (!LLGLSLShader::sNoFixedFunction)
  1736. {
  1737. glFogfv(GL_FOG_COLOR, fog.mV);
  1738. }
  1739. mGLFogCol = fog;
  1740. if (hide_clip_plane)
  1741. {
  1742. // For now, set the density to extend to the cull distance.
  1743. const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f)))
  1744. fog_density = f_log/fog_distance;
  1745. if (!LLGLSLShader::sNoFixedFunction)
  1746. {
  1747. glFogi(GL_FOG_MODE, GL_EXP2);
  1748. }
  1749. }
  1750. else
  1751. {
  1752. const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f))
  1753. fog_density = (f_log)/fog_distance;
  1754. if (!LLGLSLShader::sNoFixedFunction)
  1755. {
  1756. glFogi(GL_FOG_MODE, GL_EXP);
  1757. }
  1758. }
  1759. }
  1760. else
  1761. {
  1762. F32 depth = water_height - camera_height;
  1763. // get the water param manager variables
  1764. float water_fog_density = LLWaterParamManager::getInstance()->getFogDensity();
  1765. LLColor4 water_fog_color = LLDrawPoolWater::sWaterFogColor.mV;
  1766. // adjust the color based on depth. We're doing linear approximations
  1767. float depth_scale = gSavedSettings.getF32("WaterGLFogDepthScale");
  1768. float depth_modifier = 1.0f - llmin(llmax(depth / depth_scale, 0.01f),
  1769. gSavedSettings.getF32("WaterGLFogDepthFloor"));
  1770. LLColor4 fogCol = water_fog_color * depth_modifier;
  1771. fogCol.setAlpha(1);
  1772. // set the gl fog color
  1773. mGLFogCol = fogCol;
  1774. // set the density based on what the shaders use
  1775. fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale");
  1776. if (!LLGLSLShader::sNoFixedFunction)
  1777. {
  1778. glFogfv(GL_FOG_COLOR, (F32 *) &fogCol.mV);
  1779. glFogi(GL_FOG_MODE, GL_EXP2);
  1780. }
  1781. }
  1782. mFogColor = sky_fog_color;
  1783. mFogColor.setAlpha(1);
  1784. LLDrawPoolWater::sWaterFogEnd = fog_distance*2.2f;
  1785. if (!LLGLSLShader::sNoFixedFunction)
  1786. {
  1787. LLGLSFog gls_fog;
  1788. glFogf(GL_FOG_END, fog_distance*2.2f);
  1789. glFogf(GL_FOG_DENSITY, fog_density);
  1790. glHint(GL_FOG_HINT, GL_NICEST);
  1791. }
  1792. stop_glerror();
  1793. }
  1794. // Functions used a lot.
  1795. F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply)
  1796. {
  1797. F32 mv = color_max(col);
  1798. if (0 == mv)
  1799. {
  1800. return 0;
  1801. }
  1802. col *= 1.f / mv;
  1803. color_pow(col, e);
  1804. if (postmultiply)
  1805. {
  1806. col *= mv;
  1807. }
  1808. return mv;
  1809. }
  1810. // Returns angle (RADIANs) between the horizontal projection of "v" and the x_axis.
  1811. // Range of output is 0.0f to 2pi //359.99999...f
  1812. // Returns 0.0f when "v" = +/- z_axis.
  1813. F32 azimuth(const LLVector3 &v)
  1814. {
  1815. F32 azimuth = 0.0f;
  1816. if (v.mV[VX] == 0.0f)
  1817. {
  1818. if (v.mV[VY] > 0.0f)
  1819. {
  1820. azimuth = F_PI * 0.5f;
  1821. }
  1822. else if (v.mV[VY] < 0.0f)
  1823. {
  1824. azimuth = F_PI * 1.5f;// 270.f;
  1825. }
  1826. }
  1827. else
  1828. {
  1829. azimuth = (F32) atan(v.mV[VY] / v.mV[VX]);
  1830. if (v.mV[VX] < 0.0f)
  1831. {
  1832. azimuth += F_PI;
  1833. }
  1834. else if (v.mV[VY] < 0.0f)
  1835. {
  1836. azimuth += F_PI * 2;
  1837. }
  1838. }
  1839. return azimuth;
  1840. }
  1841. void LLVOSky::initSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity)
  1842. {
  1843. LLVector3 sun_direction = (sun_dir.length() == 0) ? LLVector3::x_axis : sun_dir;
  1844. sun_direction.normalize();
  1845. mSun.setDirection(sun_direction);
  1846. mSun.renewDirection();
  1847. mSun.setAngularVelocity(sun_ang_velocity);
  1848. mMoon.setDirection(-mSun.getDirection());
  1849. mMoon.renewDirection();
  1850. mLastLightingDirection = mSun.getDirection();
  1851. calcAtmospherics();
  1852. if ( !mInitialized )
  1853. {
  1854. init();
  1855. LLSkyTex::stepCurrent();
  1856. }
  1857. }
  1858. void LLVOSky::setSunDirection(const LLVector3 &sun_dir, const LLVector3 &sun_ang_velocity)
  1859. {
  1860. LLVector3 sun_direction = (sun_dir.length() == 0) ? LLVector3::x_axis : sun_dir;
  1861. sun_direction.normalize();
  1862. // Push the sun "South" as it approaches directly overhead so that we can always see bump mapping
  1863. // on the upward facing faces of cubes.
  1864. LLVector3 newDir = sun_direction;
  1865. // Same as dot product with the up direction + clamp.
  1866. F32 sunDot = llmax(0.f, newDir.mV[2]);
  1867. sunDot *= sunDot;
  1868. // Create normalized vector that has the sunDir pushed south about an hour and change.
  1869. LLVector3 adjustedDir = (newDir + LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
  1870. // Blend between normal sun dir and adjusted sun dir based on how close we are
  1871. // to having the sun overhead.
  1872. mBumpSunDir = adjustedDir * sunDot + newDir * (1.0f - sunDot);
  1873. mBumpSunDir.normalize();
  1874. F32 dp = mLastLightingDirection * sun_direction;
  1875. mSun.setDirection(sun_direction);
  1876. mSun.setAngularVelocity(sun_ang_velocity);
  1877. mMoon.setDirection(-sun_direction);
  1878. calcAtmospherics();
  1879. if (dp < 0.995f) { //the sun jumped a great deal, update immediately
  1880. mForceUpdate = TRUE;
  1881. }
  1882. }