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

游戏引擎

开发平台:

C++ Builder

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