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

游戏引擎

开发平台:

C++ Builder

  1. if (mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS)
  2. {
  3. mNearbyLights.insert(*light);
  4. ((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT);
  5. }
  6. else
  7. {
  8. // crazy cast so that we can overwrite the fade value
  9. // even though gcc enforces sets as const
  10. // (fade value doesn't affect sort so this is safe)
  11. Light* farthest_light = ((Light*) (&(*(mNearbyLights.rbegin()))));
  12. if (light->dist < farthest_light->dist)
  13. {
  14. if (farthest_light->fade >= 0.f)
  15. {
  16. farthest_light->fade = -gFrameIntervalSeconds;
  17. }
  18. }
  19. else
  20. {
  21. break; // none of the other lights are closer
  22. }
  23. }
  24. }
  25. }
  26. }
  27. void LLPipeline::setupHWLights(LLDrawPool* pool)
  28. {
  29. assertInitialized();
  30. // Ambient
  31. LLColor4 ambient = gSky.getTotalAmbientColor();
  32. glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV);
  33. // Light 0 = Sun or Moon (All objects)
  34. {
  35. if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS)
  36. {
  37. mSunDir.setVec(gSky.getSunDirection());
  38. mSunDiffuse.setVec(gSky.getSunDiffuseColor());
  39. }
  40. else
  41. {
  42. mSunDir.setVec(gSky.getMoonDirection());
  43. mSunDiffuse.setVec(gSky.getMoonDiffuseColor());
  44. }
  45. F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]);
  46. if (max_color > 1.f)
  47. {
  48. mSunDiffuse *= 1.f/max_color;
  49. }
  50. mSunDiffuse.clamp();
  51. LLVector4 light_pos(mSunDir, 0.0f);
  52. LLColor4 light_diffuse = mSunDiffuse;
  53. mHWLightColors[0] = light_diffuse;
  54. glLightfv(GL_LIGHT0, GL_POSITION, light_pos.mV); // this is just sun/moon direction
  55. glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse.mV);
  56. glLightfv(GL_LIGHT0, GL_AMBIENT,  LLColor4::black.mV);
  57. glLightfv(GL_LIGHT0, GL_SPECULAR, LLColor4::black.mV);
  58. glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION,  1.0f);
  59. glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION,    0.0f);
  60. glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f);
  61. glLightf (GL_LIGHT0, GL_SPOT_EXPONENT,         0.0f);
  62. glLightf (GL_LIGHT0, GL_SPOT_CUTOFF,           180.0f);
  63. }
  64. // Light 1 = Backlight (for avatars)
  65. // (set by enableLightsAvatar)
  66. S32 cur_light = 2;
  67. // Nearby lights = LIGHT 2-7
  68. mLightMovingMask = 0;
  69. if (mLightingDetail >= 1)
  70. {
  71. for (light_set_t::iterator iter = mNearbyLights.begin();
  72.  iter != mNearbyLights.end(); ++iter)
  73. {
  74. LLDrawable* drawable = iter->drawable;
  75. LLVOVolume* light = drawable->getVOVolume();
  76. if (!light)
  77. {
  78. continue;
  79. }
  80. if (drawable->isState(LLDrawable::ACTIVE))
  81. {
  82. mLightMovingMask |= (1<<cur_light);
  83. }
  84. LLColor4  light_color = light->getLightColor();
  85. light_color.mV[3] = 0.0f;
  86. F32 fade = iter->fade;
  87. if (fade < LIGHT_FADE_TIME)
  88. {
  89. // fade in/out light
  90. if (fade >= 0.f)
  91. {
  92. fade = fade / LIGHT_FADE_TIME;
  93. ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds;
  94. }
  95. else
  96. {
  97. fade = 1.f + fade / LIGHT_FADE_TIME;
  98. ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds;
  99. }
  100. fade = llclamp(fade,0.f,1.f);
  101. light_color *= fade;
  102. }
  103. LLVector3 light_pos(light->getRenderPosition());
  104. LLVector4 light_pos_gl(light_pos, 1.0f);
  105. F32 light_radius = llmax(light->getLightRadius(), 0.001f);
  106. F32 atten, quad;
  107. #if 0 //1.9.1
  108. if (pool->getVertexShaderLevel() > 0)
  109. {
  110. atten = light_radius;
  111. quad = llmax(light->getLightFalloff(), 0.0001f);
  112. }
  113. else
  114. #endif
  115. {
  116. F32 x = (3.f * (1.f + light->getLightFalloff()));
  117. atten = x / (light_radius); // % of brightness at radius
  118. quad = 0.0f;
  119. }
  120. mHWLightColors[cur_light] = light_color;
  121. S32 gllight = GL_LIGHT0+cur_light;
  122. glLightfv(gllight, GL_POSITION, light_pos_gl.mV);
  123. glLightfv(gllight, GL_DIFFUSE,  light_color.mV);
  124. glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV);
  125. glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
  126. glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f);
  127. glLightf (gllight, GL_LINEAR_ATTENUATION,     atten);
  128. glLightf (gllight, GL_QUADRATIC_ATTENUATION,  quad);
  129. glLightf (gllight, GL_SPOT_EXPONENT,          0.0f);
  130. glLightf (gllight, GL_SPOT_CUTOFF,            180.0f);
  131. cur_light++;
  132. if (cur_light >= 8)
  133. {
  134. break; // safety
  135. }
  136. }
  137. }
  138. for ( ; cur_light < 8 ; cur_light++)
  139. {
  140. mHWLightColors[cur_light] = LLColor4::black;
  141. S32 gllight = GL_LIGHT0+cur_light;
  142. glLightfv(gllight, GL_DIFFUSE,  LLColor4::black.mV);
  143. glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV);
  144. glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
  145. }
  146. if (gAgent.getAvatarObject() &&
  147. gAgent.getAvatarObject()->mSpecialRenderMode == 3)
  148. {
  149. LLColor4  light_color = LLColor4::white;
  150. light_color.mV[3] = 0.0f;
  151. LLVector3 light_pos(LLViewerCamera::getInstance()->getOrigin());
  152. LLVector4 light_pos_gl(light_pos, 1.0f);
  153. F32 light_radius = 16.f;
  154. F32 atten, quad;
  155. {
  156. F32 x = 3.f;
  157. atten = x / (light_radius); // % of brightness at radius
  158. quad = 0.0f;
  159. }
  160. mHWLightColors[2] = light_color;
  161. S32 gllight = GL_LIGHT2;
  162. glLightfv(gllight, GL_POSITION, light_pos_gl.mV);
  163. glLightfv(gllight, GL_DIFFUSE,  light_color.mV);
  164. glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV);
  165. glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
  166. glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f);
  167. glLightf (gllight, GL_LINEAR_ATTENUATION,     atten);
  168. glLightf (gllight, GL_QUADRATIC_ATTENUATION,  quad);
  169. glLightf (gllight, GL_SPOT_EXPONENT,          0.0f);
  170. glLightf (gllight, GL_SPOT_CUTOFF,            180.0f);
  171. }
  172. // Init GL state
  173. glDisable(GL_LIGHTING);
  174. for (S32 gllight=GL_LIGHT0; gllight<=GL_LIGHT7; gllight++)
  175. {
  176. glDisable(gllight);
  177. }
  178. mLightMask = 0;
  179. }
  180. void LLPipeline::enableLights(U32 mask)
  181. {
  182. assertInitialized();
  183. if (mLightingDetail == 0)
  184. {
  185. mask &= 0xf003; // sun and backlight only (and fullbright bit)
  186. }
  187. if (mLightMask != mask)
  188. {
  189. stop_glerror();
  190. if (!mLightMask)
  191. {
  192. glEnable(GL_LIGHTING);
  193. }
  194. if (mask)
  195. {
  196. stop_glerror();
  197. for (S32 i=0; i<8; i++)
  198. {
  199. if (mask & (1<<i))
  200. {
  201. glEnable(GL_LIGHT0 + i);
  202. glLightfv(GL_LIGHT0 + i, GL_DIFFUSE,  mHWLightColors[i].mV);
  203. }
  204. else
  205. {
  206. glDisable(GL_LIGHT0 + i);
  207. glLightfv(GL_LIGHT0 + i, GL_DIFFUSE,  LLColor4::black.mV);
  208. }
  209. }
  210. stop_glerror();
  211. }
  212. else
  213. {
  214. glDisable(GL_LIGHTING);
  215. }
  216. stop_glerror();
  217. mLightMask = mask;
  218. LLColor4 ambient = gSky.getTotalAmbientColor();
  219. glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV);
  220. stop_glerror();
  221. }
  222. }
  223. void LLPipeline::enableLightsStatic()
  224. {
  225. assertInitialized();
  226. U32 mask = 0x01; // Sun
  227. if (mLightingDetail >= 2)
  228. {
  229. mask |= mLightMovingMask; // Hardware moving lights
  230. glColor4f(0.f, 0.f, 0.f, 1.0f); // no local lighting by default
  231. }
  232. else
  233. {
  234. mask |= 0xff & (~2); // Hardware local lights
  235. }
  236. enableLights(mask);
  237. }
  238. void LLPipeline::enableLightsDynamic()
  239. {
  240. assertInitialized();
  241. U32 mask = 0xff & (~2); // Local lights
  242. enableLights(mask);
  243. if (mLightingDetail >= 2)
  244. {
  245. glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default
  246. }
  247. LLVOAvatar* avatarp = gAgent.getAvatarObject();
  248. if (avatarp && getLightingDetail() <= 0)
  249. {
  250. if (avatarp->mSpecialRenderMode == 0) // normal
  251. {
  252. gPipeline.enableLightsAvatar();
  253. }
  254. else if (avatarp->mSpecialRenderMode >= 1)  // anim preview
  255. {
  256. gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f));
  257. }
  258. }
  259. }
  260. void LLPipeline::enableLightsAvatar()
  261. {
  262. U32 mask = 0xff; // All lights
  263. setupAvatarLights(FALSE);
  264. enableLights(mask);
  265. }
  266. void LLPipeline::enableLightsAvatarEdit(const LLColor4& color)
  267. {
  268. U32 mask = 0x2002; // Avatar backlight only, set ambient
  269. setupAvatarLights(TRUE);
  270. enableLights(mask);
  271. glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV);
  272. }
  273. void LLPipeline::enableLightsFullbright(const LLColor4& color)
  274. {
  275. assertInitialized();
  276. U32 mask = 0x1000; // Non-0 mask, set ambient
  277. enableLights(mask);
  278. glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV);
  279. if (mLightingDetail >= 2)
  280. {
  281. glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default
  282. }
  283. }
  284. void LLPipeline::disableLights()
  285. {
  286. enableLights(0); // no lighting (full bright)
  287. glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default
  288. }
  289. //============================================================================
  290. class LLMenuItemGL;
  291. class LLInvFVBridge;
  292. struct cat_folder_pair;
  293. class LLVOBranch;
  294. class LLVOLeaf;
  295. void LLPipeline::findReferences(LLDrawable *drawablep)
  296. {
  297. assertInitialized();
  298. if (mLights.find(drawablep) != mLights.end())
  299. {
  300. llinfos << "In mLights" << llendl;
  301. }
  302. if (std::find(mMovedList.begin(), mMovedList.end(), drawablep) != mMovedList.end())
  303. {
  304. llinfos << "In mMovedList" << llendl;
  305. }
  306. if (std::find(mShiftList.begin(), mShiftList.end(), drawablep) != mShiftList.end())
  307. {
  308. llinfos << "In mShiftList" << llendl;
  309. }
  310. if (mRetexturedList.find(drawablep) != mRetexturedList.end())
  311. {
  312. llinfos << "In mRetexturedList" << llendl;
  313. }
  314. if (mActiveQ.find(drawablep) != mActiveQ.end())
  315. {
  316. llinfos << "In mActiveQ" << llendl;
  317. }
  318. if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end())
  319. {
  320. llinfos << "In mBuildQ1" << llendl;
  321. }
  322. if (std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep) != mBuildQ2.end())
  323. {
  324. llinfos << "In mBuildQ2" << llendl;
  325. }
  326. S32 count;
  327. count = gObjectList.findReferences(drawablep);
  328. if (count)
  329. {
  330. llinfos << "In other drawables: " << count << " references" << llendl;
  331. }
  332. }
  333. BOOL LLPipeline::verify()
  334. {
  335. BOOL ok = assertInitialized();
  336. if (ok) 
  337. {
  338. for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
  339. {
  340. LLDrawPool *poolp = *iter;
  341. if (!poolp->verify())
  342. {
  343. ok = FALSE;
  344. }
  345. }
  346. }
  347. if (!ok)
  348. {
  349. llwarns << "Pipeline verify failed!" << llendl;
  350. }
  351. return ok;
  352. }
  353. //////////////////////////////
  354. //
  355. // Collision detection
  356. //
  357. //
  358. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  359. /**
  360.  * A method to compute a ray-AABB intersection.
  361.  * Original code by Andrew Woo, from "Graphics Gems", Academic Press, 1990
  362.  * Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500)
  363.  * Epsilon value added by Klaus Hartmann. (discarding it saves a few cycles only)
  364.  *
  365.  * Hence this version is faster as well as more robust than the original one.
  366.  *
  367.  * Should work provided:
  368.  * 1) the integer representation of 0.0f is 0x00000000
  369.  * 2) the sign bit of the float is the most significant one
  370.  *
  371.  * Report bugs: p.terdiman@codercorner.com
  372.  *
  373.  * param aabb [in] the axis-aligned bounding box
  374.  * param origin [in] ray origin
  375.  * param dir [in] ray direction
  376.  * param coord [out] impact coordinates
  377.  * return true if ray intersects AABB
  378.  */
  379. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  380. //#define RAYAABB_EPSILON 0.00001f
  381. #define IR(x) ((U32&)x)
  382. bool LLRayAABB(const LLVector3 &center, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon)
  383. {
  384. BOOL Inside = TRUE;
  385. LLVector3 MinB = center - size;
  386. LLVector3 MaxB = center + size;
  387. LLVector3 MaxT;
  388. MaxT.mV[VX]=MaxT.mV[VY]=MaxT.mV[VZ]=-1.0f;
  389. // Find candidate planes.
  390. for(U32 i=0;i<3;i++)
  391. {
  392. if(origin.mV[i] < MinB.mV[i])
  393. {
  394. coord.mV[i] = MinB.mV[i];
  395. Inside = FALSE;
  396. // Calculate T distances to candidate planes
  397. if(IR(dir.mV[i])) MaxT.mV[i] = (MinB.mV[i] - origin.mV[i]) / dir.mV[i];
  398. }
  399. else if(origin.mV[i] > MaxB.mV[i])
  400. {
  401. coord.mV[i] = MaxB.mV[i];
  402. Inside = FALSE;
  403. // Calculate T distances to candidate planes
  404. if(IR(dir.mV[i])) MaxT.mV[i] = (MaxB.mV[i] - origin.mV[i]) / dir.mV[i];
  405. }
  406. }
  407. // Ray origin inside bounding box
  408. if(Inside)
  409. {
  410. coord = origin;
  411. return true;
  412. }
  413. // Get largest of the maxT's for final choice of intersection
  414. U32 WhichPlane = 0;
  415. if(MaxT.mV[1] > MaxT.mV[WhichPlane]) WhichPlane = 1;
  416. if(MaxT.mV[2] > MaxT.mV[WhichPlane]) WhichPlane = 2;
  417. // Check final candidate actually inside box
  418. if(IR(MaxT.mV[WhichPlane])&0x80000000) return false;
  419. for(U32 i=0;i<3;i++)
  420. {
  421. if(i!=WhichPlane)
  422. {
  423. coord.mV[i] = origin.mV[i] + MaxT.mV[WhichPlane] * dir.mV[i];
  424. if (epsilon > 0)
  425. {
  426. if(coord.mV[i] < MinB.mV[i] - epsilon || coord.mV[i] > MaxB.mV[i] + epsilon) return false;
  427. }
  428. else
  429. {
  430. if(coord.mV[i] < MinB.mV[i] || coord.mV[i] > MaxB.mV[i]) return false;
  431. }
  432. }
  433. }
  434. return true; // ray hits box
  435. }
  436. //////////////////////////////
  437. //
  438. // Macros, functions, and inline methods from other classes
  439. //
  440. //
  441. void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light)
  442. {
  443. if (drawablep && assertInitialized())
  444. {
  445. if (is_light)
  446. {
  447. mLights.insert(drawablep);
  448. drawablep->setState(LLDrawable::LIGHT);
  449. }
  450. else
  451. {
  452. drawablep->clearState(LLDrawable::LIGHT);
  453. mLights.erase(drawablep);
  454. }
  455. }
  456. }
  457. void LLPipeline::setActive(LLDrawable *drawablep, BOOL active)
  458. {
  459. assertInitialized();
  460. if (active)
  461. {
  462. mActiveQ.insert(drawablep);
  463. }
  464. else
  465. {
  466. mActiveQ.erase(drawablep);
  467. }
  468. }
  469. //static
  470. void LLPipeline::toggleRenderType(U32 type)
  471. {
  472. U32 bit = (1<<type);
  473. gPipeline.mRenderTypeMask ^= bit;
  474. }
  475. //static
  476. void LLPipeline::toggleRenderTypeControl(void* data)
  477. {
  478. U32 type = (U32)(intptr_t)data;
  479. U32 bit = (1<<type);
  480. if (gPipeline.hasRenderType(type))
  481. {
  482. llinfos << "Toggling render type mask " << std::hex << bit << " off" << std::dec << llendl;
  483. }
  484. else
  485. {
  486. llinfos << "Toggling render type mask " << std::hex << bit << " on" << std::dec << llendl;
  487. }
  488. gPipeline.toggleRenderType(type);
  489. }
  490. //static
  491. BOOL LLPipeline::hasRenderTypeControl(void* data)
  492. {
  493. U32 type = (U32)(intptr_t)data;
  494. return gPipeline.hasRenderType(type);
  495. }
  496. // Allows UI items labeled "Hide foo" instead of "Show foo"
  497. //static
  498. BOOL LLPipeline::toggleRenderTypeControlNegated(void* data)
  499. {
  500. S32 type = (S32)(intptr_t)data;
  501. return !gPipeline.hasRenderType(type);
  502. }
  503. //static
  504. void LLPipeline::toggleRenderDebug(void* data)
  505. {
  506. U32 bit = (U32)(intptr_t)data;
  507. if (gPipeline.hasRenderDebugMask(bit))
  508. {
  509. llinfos << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << llendl;
  510. }
  511. else
  512. {
  513. llinfos << "Toggling render debug mask " << std::hex << bit << " on" << std::dec << llendl;
  514. }
  515. gPipeline.mRenderDebugMask ^= bit;
  516. }
  517. //static
  518. BOOL LLPipeline::toggleRenderDebugControl(void* data)
  519. {
  520. U32 bit = (U32)(intptr_t)data;
  521. return gPipeline.hasRenderDebugMask(bit);
  522. }
  523. //static
  524. void LLPipeline::toggleRenderDebugFeature(void* data)
  525. {
  526. U32 bit = (U32)(intptr_t)data;
  527. gPipeline.mRenderDebugFeatureMask ^= bit;
  528. }
  529. //static
  530. BOOL LLPipeline::toggleRenderDebugFeatureControl(void* data)
  531. {
  532. U32 bit = (U32)(intptr_t)data;
  533. return gPipeline.hasRenderDebugFeatureMask(bit);
  534. }
  535. // static
  536. void LLPipeline::setRenderScriptedBeacons(BOOL val)
  537. {
  538. sRenderScriptedBeacons = val;
  539. }
  540. // static
  541. void LLPipeline::toggleRenderScriptedBeacons(void*)
  542. {
  543. sRenderScriptedBeacons = !sRenderScriptedBeacons;
  544. }
  545. // static
  546. BOOL LLPipeline::getRenderScriptedBeacons(void*)
  547. {
  548. return sRenderScriptedBeacons;
  549. }
  550. // static
  551. void LLPipeline::setRenderScriptedTouchBeacons(BOOL val)
  552. {
  553. sRenderScriptedTouchBeacons = val;
  554. }
  555. // static
  556. void LLPipeline::toggleRenderScriptedTouchBeacons(void*)
  557. {
  558. sRenderScriptedTouchBeacons = !sRenderScriptedTouchBeacons;
  559. }
  560. // static
  561. BOOL LLPipeline::getRenderScriptedTouchBeacons(void*)
  562. {
  563. return sRenderScriptedTouchBeacons;
  564. }
  565. // static
  566. void LLPipeline::setRenderPhysicalBeacons(BOOL val)
  567. {
  568. sRenderPhysicalBeacons = val;
  569. }
  570. // static
  571. void LLPipeline::toggleRenderPhysicalBeacons(void*)
  572. {
  573. sRenderPhysicalBeacons = !sRenderPhysicalBeacons;
  574. }
  575. // static
  576. BOOL LLPipeline::getRenderPhysicalBeacons(void*)
  577. {
  578. return sRenderPhysicalBeacons;
  579. }
  580. // static
  581. void LLPipeline::setRenderParticleBeacons(BOOL val)
  582. {
  583. sRenderParticleBeacons = val;
  584. }
  585. // static
  586. void LLPipeline::toggleRenderParticleBeacons(void*)
  587. {
  588. sRenderParticleBeacons = !sRenderParticleBeacons;
  589. }
  590. // static
  591. BOOL LLPipeline::getRenderParticleBeacons(void*)
  592. {
  593. return sRenderParticleBeacons;
  594. }
  595. // static
  596. void LLPipeline::setRenderSoundBeacons(BOOL val)
  597. {
  598. sRenderSoundBeacons = val;
  599. }
  600. // static
  601. void LLPipeline::toggleRenderSoundBeacons(void*)
  602. {
  603. sRenderSoundBeacons = !sRenderSoundBeacons;
  604. }
  605. // static
  606. BOOL LLPipeline::getRenderSoundBeacons(void*)
  607. {
  608. return sRenderSoundBeacons;
  609. }
  610. // static
  611. void LLPipeline::setRenderBeacons(BOOL val)
  612. {
  613. sRenderBeacons = val;
  614. }
  615. // static
  616. void LLPipeline::toggleRenderBeacons(void*)
  617. {
  618. sRenderBeacons = !sRenderBeacons;
  619. }
  620. // static
  621. BOOL LLPipeline::getRenderBeacons(void*)
  622. {
  623. return sRenderBeacons;
  624. }
  625. // static
  626. void LLPipeline::setRenderHighlights(BOOL val)
  627. {
  628. sRenderHighlight = val;
  629. }
  630. // static
  631. void LLPipeline::toggleRenderHighlights(void*)
  632. {
  633. sRenderHighlight = !sRenderHighlight;
  634. }
  635. // static
  636. BOOL LLPipeline::getRenderHighlights(void*)
  637. {
  638. return sRenderHighlight;
  639. }
  640. LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
  641. BOOL pick_transparent,
  642. S32* face_hit,
  643. LLVector3* intersection,         // return the intersection point
  644. LLVector2* tex_coord,            // return the texture coordinates of the intersection point
  645. LLVector3* normal,               // return the surface normal at the intersection point
  646. LLVector3* bi_normal             // return the surface bi-normal at the intersection point
  647. )
  648. {
  649. LLDrawable* drawable = NULL;
  650. LLVector3 local_end = end;
  651. LLVector3 position;
  652. sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE;
  653. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
  654. iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
  655. {
  656. LLViewerRegion* region = *iter;
  657. for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++)
  658. {
  659. if ((j == LLViewerRegion::PARTITION_VOLUME) || 
  660. (j == LLViewerRegion::PARTITION_BRIDGE) || 
  661. (j == LLViewerRegion::PARTITION_TERRAIN) ||
  662. (j == LLViewerRegion::PARTITION_TREE) ||
  663. (j == LLViewerRegion::PARTITION_GRASS))  // only check these partitions for now
  664. {
  665. LLSpatialPartition* part = region->getSpatialPartition(j);
  666. if (part && hasRenderType(part->mDrawableType))
  667. {
  668. LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
  669. if (hit)
  670. {
  671. drawable = hit;
  672. local_end = position;
  673. }
  674. }
  675. }
  676. }
  677. }
  678. if (!sPickAvatar)
  679. {
  680. //save hit info in case we need to restore
  681. //due to attachment override
  682. LLVector3 local_normal;
  683. LLVector3 local_binormal;
  684. LLVector2 local_texcoord;
  685. S32 local_face_hit = -1;
  686. if (face_hit)
  687. local_face_hit = *face_hit;
  688. }
  689. if (tex_coord)
  690. {
  691. local_texcoord = *tex_coord;
  692. }
  693. if (bi_normal)
  694. {
  695. local_binormal = *bi_normal;
  696. }
  697. if (normal)
  698. {
  699. local_normal = *normal;
  700. }
  701. const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f;
  702. //check against avatars
  703. sPickAvatar = TRUE;
  704. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
  705. iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
  706. {
  707. LLViewerRegion* region = *iter;
  708. LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);
  709. if (part && hasRenderType(part->mDrawableType))
  710. {
  711. LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
  712. if (hit)
  713. {
  714. if (!drawable || 
  715. !drawable->getVObj()->isAttachment() ||
  716. (position-local_end).magVec() > ATTACHMENT_OVERRIDE_DIST)
  717. { //avatar overrides if previously hit drawable is not an attachment or 
  718.   //attachment is far enough away from detected intersection
  719. drawable = hit;
  720. local_end = position;
  721. }
  722. else
  723. { //prioritize attachments over avatars
  724. position = local_end;
  725. if (face_hit)
  726. {
  727. *face_hit = local_face_hit;
  728. }
  729. if (tex_coord)
  730. {
  731. *tex_coord = local_texcoord;
  732. }
  733. if (bi_normal)
  734. {
  735. *bi_normal = local_binormal;
  736. }
  737. if (normal)
  738. {
  739. *normal = local_normal;
  740. }
  741. }
  742. }
  743. }
  744. }
  745. }
  746. //check all avatar nametags (silly, isn't it?)
  747. for (std::vector< LLCharacter* >::iterator iter = LLCharacter::sInstances.begin();
  748. iter != LLCharacter::sInstances.end();
  749. ++iter)
  750. {
  751. LLVOAvatar* av = (LLVOAvatar*) *iter;
  752. if (av->mNameText.notNull() && av->mNameText->lineSegmentIntersect(start, local_end, position))
  753. {
  754. drawable = av->mDrawable;
  755. local_end = position;
  756. }
  757. }
  758. if (intersection)
  759. {
  760. *intersection = position;
  761. }
  762. return drawable ? drawable->getVObj().get() : NULL;
  763. }
  764. LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end,
  765.   BOOL pick_transparent,
  766.   S32* face_hit,
  767.   LLVector3* intersection,         // return the intersection point
  768.   LLVector2* tex_coord,            // return the texture coordinates of the intersection point
  769.   LLVector3* normal,               // return the surface normal at the intersection point
  770.   LLVector3* bi_normal             // return the surface bi-normal at the intersection point
  771. )
  772. {
  773. LLDrawable* drawable = NULL;
  774. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
  775. iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
  776. {
  777. LLViewerRegion* region = *iter;
  778. BOOL toggle = FALSE;
  779. if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD))
  780. {
  781. toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
  782. toggle = TRUE;
  783. }
  784. LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
  785. if (part)
  786. {
  787. LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal);
  788. if (hit)
  789. {
  790. drawable = hit;
  791. }
  792. }
  793. if (toggle)
  794. {
  795. toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
  796. }
  797. }
  798. return drawable ? drawable->getVObj().get() : NULL;
  799. }
  800. LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj)
  801. {
  802. if (vobj)
  803. {
  804. LLViewerRegion* region = vobj->getRegion();
  805. if (region)
  806. {
  807. return region->getSpatialPartition(vobj->getPartitionType());
  808. }
  809. }
  810. return NULL;
  811. }
  812. void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
  813. {
  814. if (!drawable || drawable->isDead())
  815. {
  816. return;
  817. }
  818. for (S32 i = 0; i < drawable->getNumFaces(); i++)
  819. {
  820. LLFace* facep = drawable->getFace(i);
  821. facep->mVertexBuffer = NULL;
  822. facep->mLastVertexBuffer = NULL;
  823. }
  824. }
  825. void LLPipeline::resetVertexBuffers()
  826. {
  827. sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
  828. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
  829. iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
  830. {
  831. LLViewerRegion* region = *iter;
  832. for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
  833. {
  834. LLSpatialPartition* part = region->getSpatialPartition(i);
  835. if (part)
  836. {
  837. part->resetVertexBuffers();
  838. }
  839. }
  840. }
  841. resetDrawOrders();
  842. gSky.resetVertexBuffers();
  843. if (LLVertexBuffer::sGLCount > 0)
  844. {
  845. LLVertexBuffer::cleanupClass();
  846. }
  847. //delete all name pool caches
  848. LLGLNamePool::cleanupPools();
  849. if (LLVertexBuffer::sGLCount > 0)
  850. {
  851. llwarns << "VBO wipe failed." << llendl;
  852. }
  853. if (!LLVertexBuffer::sStreamIBOPool.mNameList.empty() ||
  854. !LLVertexBuffer::sStreamVBOPool.mNameList.empty() ||
  855. !LLVertexBuffer::sDynamicIBOPool.mNameList.empty() ||
  856. !LLVertexBuffer::sDynamicVBOPool.mNameList.empty())
  857. {
  858. llwarns << "VBO name pool cleanup failed." << llendl;
  859. }
  860. LLVertexBuffer::unbind();
  861. LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
  862. }
  863. void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture)
  864. {
  865. LLMemType mt_ro(LLMemType::MTYPE_PIPELINE_RENDER_OBJECTS);
  866. assertInitialized();
  867. glLoadMatrixd(gGLModelView);
  868. gGLLastMatrix = NULL;
  869. mSimplePool->pushBatches(type, mask);
  870. glLoadMatrixd(gGLModelView);
  871. gGLLastMatrix = NULL;
  872. }
  873. void LLPipeline::setUseVBO(BOOL use_vbo)
  874. {
  875. if (use_vbo != LLVertexBuffer::sEnableVBOs)
  876. {
  877. if (use_vbo)
  878. {
  879. llinfos << "Enabling VBO." << llendl;
  880. }
  881. else
  882. llinfos << "Disabling VBO." << llendl;
  883. }
  884. resetVertexBuffers();
  885. LLVertexBuffer::initClass(use_vbo);
  886. }
  887. }
  888. void apply_cube_face_rotation(U32 face)
  889. {
  890. switch (face)
  891. {
  892. case 0: 
  893. glRotatef(90.f, 0, 1, 0);
  894. glRotatef(180.f, 1, 0, 0);
  895. break;
  896. case 2: 
  897. glRotatef(-90.f, 1, 0, 0);
  898. break;
  899. case 4:
  900. glRotatef(180.f, 0, 1, 0);
  901. glRotatef(180.f, 0, 0, 1);
  902. break;
  903. case 1: 
  904. glRotatef(-90.f, 0, 1, 0);
  905. glRotatef(180.f, 1, 0, 0);
  906. break;
  907. case 3:
  908. glRotatef(90, 1, 0, 0);
  909. break;
  910. case 5: 
  911. glRotatef(180, 0, 0, 1);
  912. break;
  913. }
  914. }
  915. void validate_framebuffer_object()
  916. {                                                           
  917. GLenum status;                                            
  918. status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 
  919. switch(status) 
  920. {                                          
  921. case GL_FRAMEBUFFER_COMPLETE_EXT:                       
  922. //framebuffer OK, no error.
  923. break;
  924. case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
  925. // frame buffer not OK: probably means unsupported depth buffer format
  926. llerrs << "Framebuffer Incomplete Dimensions." << llendl;
  927. break;
  928. case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
  929. // frame buffer not OK: probably means unsupported depth buffer format
  930. llerrs << "Framebuffer Incomplete Attachment." << llendl;
  931. break; 
  932. case GL_FRAMEBUFFER_UNSUPPORTED_EXT:                    
  933. /* choose different formats */                        
  934. llerrs << "Framebuffer unsupported." << llendl;
  935. break;                                                
  936. default:                                                
  937. llerrs << "Unknown framebuffer status." << llendl;
  938. break;
  939. }
  940. }
  941. void LLPipeline::bindScreenToTexture() 
  942. {
  943. }
  944. static LLFastTimer::DeclareTimer FTM_RENDER_BLOOM("Bloom");
  945. void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
  946. {
  947. LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM);
  948. if (!(gPipeline.canUseVertexShaders() &&
  949. sRenderGlow))
  950. {
  951. return;
  952. }
  953. LLVertexBuffer::unbind();
  954. LLGLState::checkStates();
  955. LLGLState::checkTextureChannels();
  956. assertInitialized();
  957. if (gUseWireframe)
  958. {
  959. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  960. }
  961. U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
  962. LLVector2 tc1(0,0);
  963. LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2,
  964.   (F32) gViewerWindow->getWorldViewHeightRaw()*2);
  965. if (res_mod > 1)
  966. {
  967. tc2 /= (F32) res_mod;
  968. }
  969. gGL.setColorMask(true, true);
  970. LLFastTimer ftm(FTM_RENDER_BLOOM);
  971. gGL.color4f(1,1,1,1);
  972. LLGLDepthTest depth(GL_FALSE);
  973. LLGLDisable blend(GL_BLEND);
  974. LLGLDisable cull(GL_CULL_FACE);
  975. enableLightsFullbright(LLColor4(1,1,1,1));
  976. glMatrixMode(GL_PROJECTION);
  977. glPushMatrix();
  978. glLoadIdentity();
  979. glMatrixMode(GL_MODELVIEW);
  980. glPushMatrix();
  981. glLoadIdentity();
  982. LLGLDisable test(GL_ALPHA_TEST);
  983. gGL.setColorMask(true, true);
  984. glClearColor(0,0,0,0);
  985. if (for_snapshot)
  986. {
  987. gGL.getTexUnit(0)->bind(&mGlow[1]);
  988. {
  989. //LLGLEnable stencil(GL_STENCIL_TEST);
  990. //glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF);
  991. //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  992. //LLGLDisable blend(GL_BLEND);
  993. // If the snapshot is constructed from tiles, calculate which
  994. // tile we're in.
  995. const S32 num_horizontal_tiles = llceil(zoom_factor);
  996. const LLVector2 tile(subfield % num_horizontal_tiles,
  997.  (S32)(subfield / num_horizontal_tiles));
  998. llassert(zoom_factor > 0.0); // Non-zero, non-negative.
  999. const F32 tile_size = 1.0/zoom_factor;
  1000. tc1 = tile*tile_size; // Top left texture coordinates
  1001. tc2 = (tile+LLVector2(1,1))*tile_size; // Bottom right texture coordinates
  1002. LLGLEnable blend(GL_BLEND);
  1003. gGL.setSceneBlendType(LLRender::BT_ADD);
  1004. gGL.begin(LLRender::TRIANGLE_STRIP);
  1005. gGL.color4f(1,1,1,1);
  1006. gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
  1007. gGL.vertex2f(-1,-1);
  1008. gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
  1009. gGL.vertex2f(-1,1);
  1010. gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
  1011. gGL.vertex2f(1,-1);
  1012. gGL.texCoord2f(tc2.mV[0], tc2.mV[1]);
  1013. gGL.vertex2f(1,1);
  1014. gGL.end();
  1015. gGL.flush();
  1016. gGL.setSceneBlendType(LLRender::BT_ALPHA);
  1017. }
  1018. gGL.flush();
  1019. glMatrixMode(GL_PROJECTION);
  1020. glPopMatrix();
  1021. glMatrixMode(GL_MODELVIEW);
  1022. glPopMatrix();
  1023. return;
  1024. }
  1025. {
  1026. {
  1027. LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
  1028. mGlow[2].bindTarget();
  1029. mGlow[2].clear();
  1030. }
  1031. gGlowExtractProgram.bind();
  1032. F32 minLum = llmax(gSavedSettings.getF32("RenderGlowMinLuminance"), 0.0f);
  1033. F32 maxAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha");
  1034. F32 warmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount");
  1035. LLVector3 lumWeights = gSavedSettings.getVector3("RenderGlowLumWeights");
  1036. LLVector3 warmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights");
  1037. gGlowExtractProgram.uniform1f("minLuminance", minLum);
  1038. gGlowExtractProgram.uniform1f("maxExtractAlpha", maxAlpha);
  1039. gGlowExtractProgram.uniform3f("lumWeights", lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]);
  1040. gGlowExtractProgram.uniform3f("warmthWeights", warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]);
  1041. gGlowExtractProgram.uniform1f("warmthAmount", warmthAmount);
  1042. LLGLEnable blend_on(GL_BLEND);
  1043. LLGLEnable test(GL_ALPHA_TEST);
  1044. gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
  1045. gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
  1046. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  1047. gGL.getTexUnit(0)->disable();
  1048. gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE);
  1049. gGL.getTexUnit(0)->bind(&mScreen);
  1050. gGL.color4f(1,1,1,1);
  1051. gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
  1052. gGL.begin(LLRender::TRIANGLE_STRIP);
  1053. gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
  1054. gGL.vertex2f(-1,-1);
  1055. gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
  1056. gGL.vertex2f(-1,3);
  1057. gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
  1058. gGL.vertex2f(3,-1);
  1059. gGL.end();
  1060. gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
  1061. mGlow[2].flush();
  1062. }
  1063. tc1.setVec(0,0);
  1064. tc2.setVec(2,2);
  1065. // power of two between 1 and 1024
  1066. U32 glowResPow = gSavedSettings.getS32("RenderGlowResolutionPow");
  1067. const U32 glow_res = llmax(1, 
  1068. llmin(1024, 1 << glowResPow));
  1069. S32 kernel = gSavedSettings.getS32("RenderGlowIterations")*2;
  1070. F32 delta = gSavedSettings.getF32("RenderGlowWidth") / glow_res;
  1071. // Use half the glow width if we have the res set to less than 9 so that it looks
  1072. // almost the same in either case.
  1073. if (glowResPow < 9)
  1074. {
  1075. delta *= 0.5f;
  1076. }
  1077. F32 strength = gSavedSettings.getF32("RenderGlowStrength");
  1078. gGlowProgram.bind();
  1079. gGlowProgram.uniform1f("glowStrength", strength);
  1080. for (S32 i = 0; i < kernel; i++)
  1081. {
  1082. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  1083. {
  1084. LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
  1085. mGlow[i%2].bindTarget();
  1086. mGlow[i%2].clear();
  1087. }
  1088. if (i == 0)
  1089. {
  1090. gGL.getTexUnit(0)->bind(&mGlow[2]);
  1091. }
  1092. else
  1093. {
  1094. gGL.getTexUnit(0)->bind(&mGlow[(i-1)%2]);
  1095. }
  1096. if (i%2 == 0)
  1097. {
  1098. gGlowProgram.uniform2f("glowDelta", delta, 0);
  1099. }
  1100. else
  1101. {
  1102. gGlowProgram.uniform2f("glowDelta", 0, delta);
  1103. }
  1104. gGL.begin(LLRender::TRIANGLE_STRIP);
  1105. gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
  1106. gGL.vertex2f(-1,-1);
  1107. gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
  1108. gGL.vertex2f(-1,3);
  1109. gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
  1110. gGL.vertex2f(3,-1);
  1111. gGL.end();
  1112. mGlow[i%2].flush();
  1113. }
  1114. gGlowProgram.unbind();
  1115. if (LLRenderTarget::sUseFBO)
  1116. {
  1117. LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
  1118. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  1119. }
  1120. gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
  1121. gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
  1122. gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
  1123. gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
  1124. glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
  1125. tc2.setVec((F32) gViewerWindow->getWorldViewWidthRaw(),
  1126. (F32) gViewerWindow->getWorldViewHeightRaw());
  1127. gGL.flush();
  1128. LLVertexBuffer::unbind();
  1129. if (LLPipeline::sRenderDeferred && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
  1130. {
  1131. LLGLDisable blend(GL_BLEND);
  1132. bindDeferredShader(gDeferredGIFinalProgram);
  1133. S32 channel = gDeferredGIFinalProgram.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
  1134. if (channel > -1)
  1135. {
  1136. mScreen.bindTexture(0, channel);
  1137. }
  1138. gGL.begin(LLRender::TRIANGLE_STRIP);
  1139. gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
  1140. gGL.vertex2f(-1,-1);
  1141. gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
  1142. gGL.vertex2f(-1,3);
  1143. gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
  1144. gGL.vertex2f(3,-1);
  1145. gGL.end();
  1146. unbindDeferredShader(gDeferredGIFinalProgram);
  1147. }
  1148. else
  1149. {
  1150. if (res_mod > 1)
  1151. {
  1152. tc2 /= (F32) res_mod;
  1153. }
  1154. U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
  1155. LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
  1156. buff->allocateBuffer(3,0,TRUE);
  1157. LLStrider<LLVector3> v;
  1158. LLStrider<LLVector2> uv1;
  1159. LLStrider<LLVector2> uv2;
  1160. buff->getVertexStrider(v);
  1161. buff->getTexCoord0Strider(uv1);
  1162. buff->getTexCoord1Strider(uv2);
  1163. uv1[0] = LLVector2(0, 0);
  1164. uv1[1] = LLVector2(0, 2);
  1165. uv1[2] = LLVector2(2, 0);
  1166. uv2[0] = LLVector2(0, 0);
  1167. uv2[1] = LLVector2(0, tc2.mV[1]*2.f);
  1168. uv2[2] = LLVector2(tc2.mV[0]*2.f, 0);
  1169. v[0] = LLVector3(-1,-1,0);
  1170. v[1] = LLVector3(-1,3,0);
  1171. v[2] = LLVector3(3,-1,0);
  1172. buff->setBuffer(0);
  1173. LLGLDisable blend(GL_BLEND);
  1174. //tex unit 0
  1175. gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
  1176. gGL.getTexUnit(0)->bind(&mGlow[1]);
  1177. gGL.getTexUnit(1)->activate();
  1178. gGL.getTexUnit(1)->enable(LLTexUnit::TT_RECT_TEXTURE);
  1179. //tex unit 1
  1180. gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
  1181. gGL.getTexUnit(1)->bind(&mScreen);
  1182. gGL.getTexUnit(1)->activate();
  1183. LLGLEnable multisample(GL_MULTISAMPLE_ARB);
  1184. buff->setBuffer(mask);
  1185. buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
  1186. gGL.getTexUnit(1)->disable();
  1187. gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
  1188. gGL.getTexUnit(0)->activate();
  1189. gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
  1190. }
  1191. gGL.setSceneBlendType(LLRender::BT_ALPHA);
  1192. glMatrixMode(GL_PROJECTION);
  1193. glPopMatrix();
  1194. glMatrixMode(GL_MODELVIEW);
  1195. glPopMatrix();
  1196. LLVertexBuffer::unbind();
  1197. LLGLState::checkStates();
  1198. LLGLState::checkTextureChannels();
  1199. }
  1200. void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRenderTarget* gi_source, LLRenderTarget* last_gi_post, U32 noise_map)
  1201. {
  1202. if (noise_map == 0xFFFFFFFF)
  1203. {
  1204. noise_map = mNoiseMap;
  1205. }
  1206. LLGLState::checkTextureChannels();
  1207. shader.bind();
  1208. S32 channel = 0;
  1209. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
  1210. if (channel > -1)
  1211. {
  1212. mDeferredScreen.bindTexture(0,channel);
  1213. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
  1214. }
  1215. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE);
  1216. if (channel > -1)
  1217. {
  1218. mDeferredScreen.bindTexture(1, channel);
  1219. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
  1220. }
  1221. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE);
  1222. if (channel > -1)
  1223. {
  1224. mDeferredScreen.bindTexture(2, channel);
  1225. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
  1226. }
  1227. if (gi_source)
  1228. {
  1229. BOOL has_gi = FALSE;
  1230. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE);
  1231. if (channel > -1)
  1232. {
  1233. has_gi = TRUE;
  1234. gi_source->bindTexture(0, channel);
  1235. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
  1236. }
  1237. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR);
  1238. if (channel > -1)
  1239. {
  1240. has_gi = TRUE;
  1241. gi_source->bindTexture(1, channel);
  1242. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
  1243. }
  1244. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL);
  1245. if (channel > -1)
  1246. {
  1247. has_gi = TRUE;
  1248. gi_source->bindTexture(2, channel);
  1249. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
  1250. }
  1251. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS);
  1252. if (channel > -1)
  1253. {
  1254. has_gi = TRUE;
  1255. gi_source->bindTexture(1, channel);
  1256. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
  1257. }
  1258. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS);
  1259. if (channel > -1)
  1260. {
  1261. has_gi = TRUE;
  1262. gi_source->bindTexture(3, channel);
  1263. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
  1264. }
  1265. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE);
  1266. if (channel > -1)
  1267. {
  1268. has_gi = TRUE;
  1269. last_gi_post->bindTexture(0, channel);
  1270. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
  1271. }
  1272. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL);
  1273. if (channel > -1)
  1274. {
  1275. has_gi = TRUE;
  1276. last_gi_post->bindTexture(2, channel);
  1277. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
  1278. }
  1279. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS);
  1280. if (channel > -1)
  1281. {
  1282. has_gi = TRUE;
  1283. last_gi_post->bindTexture(1, channel);
  1284. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
  1285. }
  1286. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS);
  1287. if (channel > -1)
  1288. {
  1289. has_gi = TRUE;
  1290. last_gi_post->bindTexture(3, channel);
  1291. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
  1292. }
  1293. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH);
  1294. if (channel > -1)
  1295. {
  1296. has_gi = TRUE;
  1297. gGL.getTexUnit(channel)->bind(gi_source, TRUE);
  1298. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
  1299. stop_glerror();
  1300. glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  1301. glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);
  1302. stop_glerror();
  1303. }
  1304. if (has_gi)
  1305. {
  1306. F32 range_x = llmin(mGIRange.mV[0], 1.f);
  1307. F32 range_y = llmin(mGIRange.mV[1], 1.f);
  1308. LLVector2 scale(range_x,range_y);
  1309. LLVector2 kern[25];
  1310. for (S32 i = 0; i < 5; ++i)
  1311. {
  1312. for (S32 j = 0; j < 5; ++j)
  1313. {
  1314. S32 idx = i*5+j;
  1315. kern[idx].mV[0] = (i-2)*0.5f;
  1316. kern[idx].mV[1] = (j-2)*0.5f;
  1317. kern[idx].scaleVec(scale);
  1318. }
  1319. }
  1320. shader.uniform2fv("gi_kern", 25, (F32*) kern);
  1321. shader.uniformMatrix4fv("gi_mat", 1, FALSE, mGIMatrix.m);
  1322. shader.uniformMatrix4fv("gi_mat_proj", 1, FALSE, mGIMatrixProj.m);
  1323. shader.uniformMatrix4fv("gi_inv_proj", 1, FALSE, mGIInvProj.m);
  1324. shader.uniformMatrix4fv("gi_norm_mat", 1, FALSE, mGINormalMatrix.m);
  1325. }
  1326. }
  1327. /*channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE);
  1328. if (channel > -1)
  1329. {
  1330. mDeferredScreen.bindTexture(3, channel);
  1331. }*/
  1332. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);
  1333. if (channel > -1)
  1334. {
  1335. gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE);
  1336. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
  1337. stop_glerror();
  1338. glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  1339. glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);
  1340. stop_glerror();
  1341. glh::matrix4f projection = glh_get_current_projection();
  1342. glh::matrix4f inv_proj = projection.inverse();
  1343. shader.uniformMatrix4fv("inv_proj", 1, FALSE, inv_proj.m);
  1344. shader.uniform4f("viewport", (F32) gGLViewport[0],
  1345. (F32) gGLViewport[1],
  1346. (F32) gGLViewport[2],
  1347. (F32) gGLViewport[3]);
  1348. }
  1349. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NOISE);
  1350. if (channel > -1)
  1351. {
  1352. gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, noise_map);
  1353. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
  1354. }
  1355. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC);
  1356. if (channel > -1)
  1357. {
  1358. gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
  1359. }
  1360. stop_glerror();
  1361. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
  1362. if (channel > -1)
  1363. {
  1364. mDeferredLight[light_index].bindTexture(0, channel);
  1365. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
  1366. }
  1367. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE);
  1368. if (channel > -1)
  1369. {
  1370. gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true);
  1371. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
  1372. }
  1373. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_BLOOM);
  1374. if (channel > -1)
  1375. {
  1376. mGlow[1].bindTexture(0, channel);
  1377. }
  1378. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
  1379. if (channel > -1)
  1380. {
  1381. gi_source->bindTexture(0, channel);
  1382. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
  1383. }
  1384. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_EDGE, LLTexUnit::TT_RECT_TEXTURE);
  1385. if (channel > -1)
  1386. {
  1387. mEdgeMap.bindTexture(0, channel);
  1388. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
  1389. }
  1390. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
  1391. if (channel > -1)
  1392. {
  1393. mDeferredLight[1].bindTexture(0, channel);
  1394. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
  1395. }
  1396. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
  1397. if (channel > -1)
  1398. {
  1399. mDeferredLight[2].bindTexture(0, channel);
  1400. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
  1401. }
  1402. stop_glerror();
  1403. for (U32 i = 0; i < 4; i++)
  1404. {
  1405. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE);
  1406. stop_glerror();
  1407. if (channel > -1)
  1408. {
  1409. stop_glerror();
  1410. gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE);
  1411. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
  1412. gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
  1413. stop_glerror();
  1414. glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
  1415. glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  1416. stop_glerror();
  1417. }
  1418. }
  1419. for (U32 i = 4; i < 6; i++)
  1420. {
  1421. channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i);
  1422. stop_glerror();
  1423. if (channel > -1)
  1424. {
  1425. stop_glerror();
  1426. gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE);
  1427. gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
  1428. gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
  1429. stop_glerror();
  1430. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
  1431. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  1432. stop_glerror();
  1433. }
  1434. }
  1435. stop_glerror();
  1436. F32 mat[16*6];
  1437. for (U32 i = 0; i < 16; i++)
  1438. {
  1439. mat[i] = mSunShadowMatrix[0].m[i];
  1440. mat[i+16] = mSunShadowMatrix[1].m[i];
  1441. mat[i+32] = mSunShadowMatrix[2].m[i];
  1442. mat[i+48] = mSunShadowMatrix[3].m[i];
  1443. mat[i+64] = mSunShadowMatrix[4].m[i];
  1444. mat[i+80] = mSunShadowMatrix[5].m[i];
  1445. }
  1446. shader.uniformMatrix4fv("shadow_matrix[0]", 6, FALSE, mat);
  1447. shader.uniformMatrix4fv("shadow_matrix", 6, FALSE, mat);
  1448. stop_glerror();
  1449. channel = shader.enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
  1450. if (channel > -1)
  1451. {
  1452. LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
  1453. if (cube_map)
  1454. {
  1455. cube_map->enable(channel);
  1456. cube_map->bind();
  1457. F64* m = gGLModelView;
  1458. F32 mat[] = { m[0], m[1], m[2],
  1459.   m[4], m[5], m[6],
  1460.   m[8], m[9], m[10] };
  1461. shader.uniform3fv("env_mat[0]", 3, mat);
  1462. shader.uniform3fv("env_mat", 3, mat);
  1463. }
  1464. }
  1465. shader.uniform4fv("shadow_clip", 1, mSunClipPlanes.mV);
  1466. shader.uniform1f("sun_wash", gSavedSettings.getF32("RenderDeferredSunWash"));
  1467. shader.uniform1f("shadow_noise", gSavedSettings.getF32("RenderShadowNoise"));
  1468. shader.uniform1f("blur_size", gSavedSettings.getF32("RenderShadowBlurSize"));
  1469. shader.uniform1f("ssao_radius", gSavedSettings.getF32("RenderSSAOScale"));
  1470. shader.uniform1f("ssao_max_radius", gSavedSettings.getU32("RenderSSAOMaxScale"));
  1471. F32 ssao_factor = gSavedSettings.getF32("RenderSSAOFactor");
  1472. shader.uniform1f("ssao_factor", ssao_factor);
  1473. shader.uniform1f("ssao_factor_inv", 1.0/ssao_factor);
  1474. LLVector3 ssao_effect = gSavedSettings.getVector3("RenderSSAOEffect");
  1475. F32 matrix_diag = (ssao_effect[0] + 2.0*ssao_effect[1])/3.0;
  1476. F32 matrix_nondiag = (ssao_effect[0] - ssao_effect[1])/3.0;
  1477. // This matrix scales (proj of color onto <1/rt(3),1/rt(3),1/rt(3)>) by
  1478. // value factor, and scales remainder by saturation factor
  1479. F32 ssao_effect_mat[] = { matrix_diag, matrix_nondiag, matrix_nondiag,
  1480. matrix_nondiag, matrix_diag, matrix_nondiag,
  1481. matrix_nondiag, matrix_nondiag, matrix_diag};
  1482. shader.uniformMatrix3fv("ssao_effect_mat", 1, GL_FALSE, ssao_effect_mat);
  1483. shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
  1484. shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f);
  1485. shader.uniform1f("alpha_soften", gSavedSettings.getF32("RenderDeferredAlphaSoften"));
  1486. shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset"));
  1487. shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias"));
  1488. shader.uniform1f("lum_scale", gSavedSettings.getF32("RenderLuminanceScale"));
  1489. shader.uniform1f("sun_lum_scale", gSavedSettings.getF32("RenderSunLuminanceScale"));
  1490. shader.uniform1f("sun_lum_offset", gSavedSettings.getF32("RenderSunLuminanceOffset"));
  1491. shader.uniform1f("lum_lod", gSavedSettings.getF32("RenderLuminanceDetail"));
  1492. shader.uniform1f("gi_range", gSavedSettings.getF32("RenderGIRange"));
  1493. shader.uniform1f("gi_brightness", gSavedSettings.getF32("RenderGIBrightness"));
  1494. shader.uniform1f("gi_luminance", gSavedSettings.getF32("RenderGILuminance"));
  1495. shader.uniform1f("gi_edge_weight", gSavedSettings.getF32("RenderGIBlurEdgeWeight"));
  1496. shader.uniform1f("gi_blur_brightness", gSavedSettings.getF32("RenderGIBlurBrightness"));
  1497. shader.uniform1f("gi_sample_width", mGILightRadius);
  1498. shader.uniform1f("gi_noise", gSavedSettings.getF32("RenderGINoise"));
  1499. shader.uniform1f("gi_attenuation", gSavedSettings.getF32("RenderGIAttenuation"));
  1500. shader.uniform1f("gi_ambiance", gSavedSettings.getF32("RenderGIAmbiance"));
  1501. shader.uniform2f("shadow_res", mShadow[0].getWidth(), mShadow[0].getHeight());
  1502. shader.uniform2f("proj_shadow_res", mShadow[4].getWidth(), mShadow[4].getHeight());
  1503. shader.uniform1f("depth_cutoff", gSavedSettings.getF32("RenderEdgeDepthCutoff"));
  1504. shader.uniform1f("norm_cutoff", gSavedSettings.getF32("RenderEdgeNormCutoff"));
  1505. if (shader.getUniformLocation("norm_mat") >= 0)
  1506. {
  1507. glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose();
  1508. shader.uniformMatrix4fv("norm_mat", 1, FALSE, norm_mat.m);
  1509. }
  1510. }
  1511. static LLFastTimer::DeclareTimer FTM_GI_TRACE("Trace");
  1512. static LLFastTimer::DeclareTimer FTM_GI_GATHER("Gather");
  1513. static LLFastTimer::DeclareTimer FTM_SUN_SHADOW("Shadow Map");
  1514. static LLFastTimer::DeclareTimer FTM_SOFTEN_SHADOW("Shadow Soften");
  1515. static LLFastTimer::DeclareTimer FTM_EDGE_DETECTION("Find Edges");
  1516. static LLFastTimer::DeclareTimer FTM_LOCAL_LIGHTS("Local Lights");
  1517. static LLFastTimer::DeclareTimer FTM_ATMOSPHERICS("Atmospherics");
  1518. static LLFastTimer::DeclareTimer FTM_FULLSCREEN_LIGHTS("Fullscreen Lights");
  1519. static LLFastTimer::DeclareTimer FTM_PROJECTORS("Projectors");
  1520. static LLFastTimer::DeclareTimer FTM_POST("Post");
  1521. void LLPipeline::renderDeferredLighting()
  1522. {
  1523. if (!sCull)
  1524. {
  1525. return;
  1526. }
  1527. {
  1528. LLFastTimer ftm(FTM_RENDER_DEFERRED);
  1529. LLViewerCamera* camera = LLViewerCamera::getInstance();
  1530. {
  1531. LLGLDepthTest depth(GL_TRUE);
  1532. mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
  1533. 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
  1534. }
  1535. LLGLEnable multisample(GL_MULTISAMPLE_ARB);
  1536. if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
  1537. {
  1538. gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
  1539. }
  1540. //ati doesn't seem to love actually using the stencil buffer on FBO's
  1541. LLGLEnable stencil(GL_STENCIL_TEST);
  1542. glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
  1543. glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  1544. gGL.setColorMask(true, true);
  1545. //draw a cube around every light
  1546. LLVertexBuffer::unbind();
  1547. LLGLEnable cull(GL_CULL_FACE);
  1548. LLGLEnable blend(GL_BLEND);
  1549. glh::matrix4f mat = glh_copy_matrix(gGLModelView);
  1550. F32 vert[] = 
  1551. {
  1552. -1,1,
  1553. -1,-3,
  1554. 3,1,
  1555. };
  1556. glVertexPointer(2, GL_FLOAT, 0, vert);
  1557. glColor3f(1,1,1);
  1558. {
  1559. setupHWLights(NULL); //to set mSunDir;
  1560. LLVector4 dir(mSunDir, 0.f);
  1561. glh::vec4f tc(dir.mV);
  1562. mat.mult_matrix_vec(tc);
  1563. glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);
  1564. }
  1565. if (gSavedSettings.getBOOL("RenderDeferredShadow"))
  1566. {
  1567. glPushMatrix();
  1568. glLoadIdentity();
  1569. glMatrixMode(GL_PROJECTION);
  1570. glPushMatrix();
  1571. glLoadIdentity();
  1572. mDeferredLight[0].bindTarget();
  1573. if (gSavedSettings.getBOOL("RenderDeferredSun"))
  1574. { //paint shadow/SSAO light map (direct lighting lightmap)
  1575. LLFastTimer ftm(FTM_SUN_SHADOW);
  1576. bindDeferredShader(gDeferredSunProgram, 0);
  1577. glClearColor(1,1,1,1);
  1578. mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT);
  1579. glClearColor(0,0,0,0);
  1580. glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
  1581. const U32 slice = 32;
  1582. F32 offset[slice*3];
  1583. for (U32 i = 0; i < 4; i++)
  1584. {
  1585. for (U32 j = 0; j < 8; j++)
  1586. {
  1587. glh::vec3f v;
  1588. v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i);
  1589. v.normalize();
  1590. inv_trans.mult_matrix_vec(v);
  1591. v.normalize();
  1592. offset[(i*8+j)*3+0] = v.v[0];
  1593. offset[(i*8+j)*3+1] = v.v[2];
  1594. offset[(i*8+j)*3+2] = v.v[1];
  1595. }
  1596. }
  1597. gDeferredSunProgram.uniform3fv("offset", slice, offset);
  1598. gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight());
  1599. {
  1600. LLGLDisable blend(GL_BLEND);
  1601. LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
  1602. stop_glerror();
  1603. glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  1604. stop_glerror();
  1605. }
  1606. unbindDeferredShader(gDeferredSunProgram);
  1607. }
  1608. else
  1609. {
  1610. mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT);
  1611. }
  1612. mDeferredLight[0].flush();
  1613. if (gSavedSettings.getBOOL("RenderDeferredBlurLight") &&
  1614.     gSavedSettings.getBOOL("RenderDeferredGI"))
  1615. {
  1616. LLFastTimer ftm(FTM_EDGE_DETECTION);
  1617. //get edge map
  1618. LLGLDisable blend(GL_BLEND);
  1619. LLGLDisable test(GL_ALPHA_TEST);
  1620. LLGLDepthTest depth(GL_FALSE);
  1621. LLGLDisable stencil(GL_STENCIL_TEST);
  1622. {
  1623. gDeferredEdgeProgram.bind();
  1624. mEdgeMap.bindTarget();
  1625. bindDeferredShader(gDeferredEdgeProgram);
  1626. glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  1627. unbindDeferredShader(gDeferredEdgeProgram);
  1628. mEdgeMap.flush();
  1629. }
  1630. }
  1631. if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
  1632. {
  1633. { //get luminance map from previous frame's light map
  1634. LLGLEnable blend(GL_BLEND);
  1635. LLGLDisable test(GL_ALPHA_TEST);
  1636. LLGLDepthTest depth(GL_FALSE);
  1637. LLGLDisable stencil(GL_STENCIL_TEST);
  1638. //static F32 fade = 1.f;
  1639. {
  1640. gGL.setSceneBlendType(LLRender::BT_ALPHA);
  1641. gLuminanceGatherProgram.bind();
  1642. gLuminanceGatherProgram.uniform2f("screen_res", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight());
  1643. mLuminanceMap.bindTarget();
  1644. bindDeferredShader(gLuminanceGatherProgram);
  1645. glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  1646. unbindDeferredShader(gLuminanceGatherProgram);
  1647. mLuminanceMap.flush();
  1648. gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true);
  1649. gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
  1650. glGenerateMipmapEXT(GL_TEXTURE_2D);
  1651. }
  1652. }
  1653. { //paint noisy GI map (bounce lighting lightmap)
  1654. LLFastTimer ftm(FTM_GI_TRACE);
  1655. LLGLDisable blend(GL_BLEND);
  1656. LLGLDepthTest depth(GL_FALSE);
  1657. LLGLDisable test(GL_ALPHA_TEST);
  1658. mGIMapPost[0].bindTarget();
  1659. bindDeferredShader(gDeferredGIProgram, 0, &mGIMap, 0, mTrueNoiseMap);
  1660. glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  1661. unbindDeferredShader(gDeferredGIProgram);
  1662. mGIMapPost[0].flush();
  1663. }
  1664. U32 pass_count = 0;
  1665. if (gSavedSettings.getBOOL("RenderDeferredBlurLight"))
  1666. {
  1667. pass_count = llclamp(gSavedSettings.getU32("RenderGIBlurPasses"), (U32) 1, (U32) 128);
  1668. }
  1669. for (U32 i = 0; i < pass_count; ++i)
  1670. { //gather/soften indirect lighting map
  1671. LLFastTimer ftm(FTM_GI_GATHER);
  1672. bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[0], NULL, mTrueNoiseMap);
  1673. F32 blur_size = gSavedSettings.getF32("RenderGIBlurSize")/((F32) i * gSavedSettings.getF32("RenderGIBlurIncrement")+1.f);
  1674. gDeferredPostGIProgram.uniform2f("delta", 1.f, 0.f);
  1675. gDeferredPostGIProgram.uniform1f("kern_scale", blur_size);
  1676. gDeferredPostGIProgram.uniform1f("gi_blur_brightness", gSavedSettings.getF32("RenderGIBlurBrightness"));
  1677. mGIMapPost[1].bindTarget();
  1678. {
  1679. LLGLDisable blend(GL_BLEND);
  1680. LLGLDepthTest depth(GL_FALSE);
  1681. stop_glerror();
  1682. glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  1683. stop_glerror();
  1684. }
  1685. mGIMapPost[1].flush();
  1686. unbindDeferredShader(gDeferredPostGIProgram);
  1687. bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[1], NULL, mTrueNoiseMap);
  1688. mGIMapPost[0].bindTarget();
  1689. gDeferredPostGIProgram.uniform2f("delta", 0.f, 1.f);
  1690. {
  1691. LLGLDisable blend(GL_BLEND);
  1692. LLGLDepthTest depth(GL_FALSE);
  1693. stop_glerror();
  1694. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  1695. stop_glerror();
  1696. }
  1697. mGIMapPost[0].flush();
  1698. unbindDeferredShader(gDeferredPostGIProgram);
  1699. }
  1700. }
  1701. if (gSavedSettings.getBOOL("RenderDeferredBlurLight"))
  1702. { //soften direct lighting lightmap
  1703. LLFastTimer ftm(FTM_SOFTEN_SHADOW);
  1704. //blur lightmap
  1705. mDeferredLight[1].bindTarget();
  1706. glClearColor(1,1,1,1);
  1707. mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT);
  1708. glClearColor(0,0,0,0);
  1709. bindDeferredShader(gDeferredBlurLightProgram);
  1710. LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian");
  1711. const U32 kern_length = 4;
  1712. F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize");
  1713. F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
  1714. // sample symmetrically with the middle sample falling exactly on 0.0
  1715. F32 x = 0.f;
  1716. LLVector3 gauss[32]; // xweight, yweight, offset
  1717. for (U32 i = 0; i < kern_length; i++)
  1718. {
  1719. gauss[i].mV[0] = llgaussian(x, go.mV[0]);
  1720. gauss[i].mV[1] = llgaussian(x, go.mV[1]);
  1721. gauss[i].mV[2] = x;
  1722. x += 1.f;
  1723. }
  1724. gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f);
  1725. gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor);
  1726. gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV);
  1727. gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
  1728. gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
  1729. {
  1730. LLGLDisable blend(GL_BLEND);
  1731. LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
  1732. stop_glerror();
  1733. glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  1734. stop_glerror();
  1735. }
  1736. mDeferredLight[1].flush();
  1737. unbindDeferredShader(gDeferredBlurLightProgram);
  1738. bindDeferredShader(gDeferredBlurLightProgram, 1);
  1739. mDeferredLight[0].bindTarget();
  1740. gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f);
  1741. {
  1742. LLGLDisable blend(GL_BLEND);
  1743. LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
  1744. stop_glerror();
  1745. glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  1746. stop_glerror();
  1747. }
  1748. mDeferredLight[0].flush();
  1749. unbindDeferredShader(gDeferredBlurLightProgram);
  1750. }
  1751. stop_glerror();
  1752. glPopMatrix();
  1753. stop_glerror();
  1754. glMatrixMode(GL_MODELVIEW);
  1755. stop_glerror();
  1756. glPopMatrix();
  1757. stop_glerror();
  1758. }
  1759. //copy depth and stencil from deferred screen
  1760. //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
  1761. // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
  1762. if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
  1763. {
  1764. mDeferredLight[1].bindTarget();
  1765. mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT);
  1766. }
  1767. else
  1768. {
  1769. mScreen.bindTarget();
  1770. mScreen.clear(GL_COLOR_BUFFER_BIT);
  1771. }
  1772. if (gSavedSettings.getBOOL("RenderDeferredAtmospheric"))
  1773. { //apply sunlight contribution 
  1774. LLFastTimer ftm(FTM_ATMOSPHERICS);
  1775. bindDeferredShader(gDeferredSoftenProgram, 0, &mGIMapPost[0]);
  1776. {
  1777. LLGLDepthTest depth(GL_FALSE);
  1778. LLGLDisable blend(GL_BLEND);
  1779. LLGLDisable test(GL_ALPHA_TEST);
  1780. //full screen blit
  1781. glPushMatrix();
  1782. glLoadIdentity();
  1783. glMatrixMode(GL_PROJECTION);
  1784. glPushMatrix();
  1785. glLoadIdentity();
  1786. glVertexPointer(2, GL_FLOAT, 0, vert);
  1787. glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  1788. glPopMatrix();
  1789. glMatrixMode(GL_MODELVIEW);
  1790. glPopMatrix();
  1791. }
  1792. unbindDeferredShader(gDeferredSoftenProgram);
  1793. }
  1794. { //render sky
  1795. LLGLDisable blend(GL_BLEND);
  1796. LLGLDisable stencil(GL_STENCIL_TEST);
  1797. gGL.setSceneBlendType(LLRender::BT_ALPHA);
  1798. U32 render_mask = mRenderTypeMask;
  1799. mRenderTypeMask = mRenderTypeMask & 
  1800. ((1 << LLPipeline::RENDER_TYPE_SKY) |
  1801. (1 << LLPipeline::RENDER_TYPE_CLOUDS) |
  1802. (1 << LLPipeline::RENDER_TYPE_WL_SKY));
  1803. renderGeomPostDeferred(*LLViewerCamera::getInstance());
  1804. mRenderTypeMask = render_mask;
  1805. }
  1806. BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights");
  1807. BOOL render_fullscreen = gSavedSettings.getBOOL("RenderDeferredFullscreenLights");
  1808. if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
  1809. {
  1810. mDeferredLight[1].flush();
  1811. mDeferredLight[2].bindTarget();
  1812. mDeferredLight[2].clear(GL_COLOR_BUFFER_BIT);
  1813. }
  1814. if (render_local || render_fullscreen)
  1815. {
  1816. gGL.setSceneBlendType(LLRender::BT_ADD);
  1817. std::list<LLVector4> fullscreen_lights;
  1818. LLDrawable::drawable_list_t spot_lights;
  1819. LLDrawable::drawable_list_t fullscreen_spot_lights;
  1820. for (U32 i = 0; i < 2; i++)
  1821. {
  1822. mTargetShadowSpotLight[i] = NULL;
  1823. }
  1824. std::list<LLVector4> light_colors;
  1825. F32 v[24];
  1826. glVertexPointer(3, GL_FLOAT, 0, v);
  1827. BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights");
  1828. {
  1829. bindDeferredShader(gDeferredLightProgram);
  1830. LLGLDepthTest depth(GL_TRUE, GL_FALSE);
  1831. for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
  1832. {
  1833. LLDrawable* drawablep = *iter;
  1834. LLVOVolume* volume = drawablep->getVOVolume();
  1835. if (!volume)
  1836. {
  1837. continue;
  1838. }
  1839. LLVector3 center = drawablep->getPositionAgent();
  1840. F32* c = center.mV;
  1841. F32 s = volume->getLightRadius()*1.5f;
  1842. LLColor3 col = volume->getLightColor();
  1843. col *= volume->getLightIntensity();
  1844. if (col.magVecSquared() < 0.001f)
  1845. {
  1846. continue;
  1847. }
  1848. if (s <= 0.001f)
  1849. {
  1850. continue;
  1851. }
  1852. if (camera->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0)
  1853. {
  1854. continue;
  1855. }
  1856. sVisibleLightCount++;
  1857. glh::vec3f tc(c);
  1858. mat.mult_matrix_vec(tc);
  1859. //vertex positions are encoded so the 3 bits of their vertex index 
  1860. //correspond to their axis facing, with bit position 3,2,1 matching
  1861. //axis facing x,y,z, bit set meaning positive facing, bit clear 
  1862. //meaning negative facing
  1863. v[0] = c[0]-s; v[1]  = c[1]-s; v[2]  = c[2]-s;  // 0 - 0000 
  1864. v[3] = c[0]-s; v[4]  = c[1]-s; v[5]  = c[2]+s;  // 1 - 0001
  1865. v[6] = c[0]-s; v[7]  = c[1]+s; v[8]  = c[2]-s;  // 2 - 0010
  1866. v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s;  // 3 - 0011
  1867.    
  1868. v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100
  1869. v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101
  1870. v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110
  1871. v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111
  1872. if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
  1873. camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
  1874. camera->getOrigin().mV[1] > c[1] + s + 0.2f ||
  1875. camera->getOrigin().mV[1] < c[1] - s - 0.2f ||
  1876. camera->getOrigin().mV[2] > c[2] + s + 0.2f ||
  1877. camera->getOrigin().mV[2] < c[2] - s - 0.2f)
  1878. { //draw box if camera is outside box
  1879. if (render_local)
  1880. {
  1881. if (volume->getLightTexture())
  1882. {
  1883. drawablep->getVOVolume()->updateSpotLightPriority();
  1884. spot_lights.push_back(drawablep);
  1885. continue;
  1886. }
  1887. LLFastTimer ftm(FTM_LOCAL_LIGHTS);
  1888. glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
  1889. glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
  1890. glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
  1891. GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center));
  1892. stop_glerror();
  1893. }
  1894. }
  1895. else if (render_fullscreen)
  1896. {
  1897. if (volume->getLightTexture())
  1898. {
  1899. drawablep->getVOVolume()->updateSpotLightPriority();
  1900. fullscreen_spot_lights.push_back(drawablep);
  1901. continue;
  1902. }
  1903. fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s));
  1904. light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
  1905. }
  1906. }
  1907. unbindDeferredShader(gDeferredLightProgram);
  1908. }
  1909. if (!spot_lights.empty())
  1910. {
  1911. LLGLDepthTest depth(GL_TRUE, GL_FALSE);
  1912. bindDeferredShader(gDeferredSpotLightProgram);
  1913. gDeferredSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
  1914. for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
  1915. {
  1916. LLFastTimer ftm(FTM_PROJECTORS);
  1917. LLDrawable* drawablep = *iter;
  1918. LLVOVolume* volume = drawablep->getVOVolume();
  1919. LLVector3 center = drawablep->getPositionAgent();
  1920. F32* c = center.mV;
  1921. F32 s = volume->getLightRadius()*1.5f;
  1922. sVisibleLightCount++;
  1923. glh::vec3f tc(c);
  1924. mat.mult_matrix_vec(tc);
  1925. setupSpotLight(gDeferredSpotLightProgram, drawablep);
  1926. LLColor3 col = volume->getLightColor();
  1927. col *= volume->getLightIntensity();
  1928. //vertex positions are encoded so the 3 bits of their vertex index 
  1929. //correspond to their axis facing, with bit position 3,2,1 matching
  1930. //axis facing x,y,z, bit set meaning positive facing, bit clear 
  1931. //meaning negative facing
  1932. v[0] = c[0]-s; v[1]  = c[1]-s; v[2]  = c[2]-s;  // 0 - 0000 
  1933. v[3] = c[0]-s; v[4]  = c[1]-s; v[5]  = c[2]+s;  // 1 - 0001
  1934. v[6] = c[0]-s; v[7]  = c[1]+s; v[8]  = c[2]-s;  // 2 - 0010
  1935. v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s;  // 3 - 0011
  1936.    
  1937. v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100
  1938. v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101
  1939. v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110
  1940. v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111
  1941. glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
  1942. glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
  1943. glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
  1944. GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center));
  1945. }
  1946. gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
  1947. unbindDeferredShader(gDeferredSpotLightProgram);
  1948. }
  1949. {
  1950. bindDeferredShader(gDeferredMultiLightProgram);
  1951. LLGLDepthTest depth(GL_FALSE);
  1952. //full screen blit
  1953. glPushMatrix();
  1954. glLoadIdentity();
  1955. glMatrixMode(GL_PROJECTION);
  1956. glPushMatrix();
  1957. glLoadIdentity();
  1958. U32 count = 0;
  1959. const U32 max_count = 8;
  1960. LLVector4 light[max_count];
  1961. LLVector4 col[max_count];
  1962. glVertexPointer(2, GL_FLOAT, 0, vert);
  1963. F32 far_z = 0.f;
  1964. while (!fullscreen_lights.empty())
  1965. {
  1966. LLFastTimer ftm(FTM_FULLSCREEN_LIGHTS);
  1967. light[count] = fullscreen_lights.front();
  1968. fullscreen_lights.pop_front();
  1969. col[count] = light_colors.front();
  1970. light_colors.pop_front();
  1971. far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z);
  1972. count++;
  1973. if (count == max_count || fullscreen_lights.empty())
  1974. {
  1975. gDeferredMultiLightProgram.uniform1i("light_count", count);
  1976. gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light);
  1977. gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light);
  1978. gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col);
  1979. gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col);
  1980. gDeferredMultiLightProgram.uniform1f("far_z", far_z);
  1981. far_z = 0.f;
  1982. count = 0;
  1983. glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  1984. }
  1985. }
  1986. unbindDeferredShader(gDeferredMultiLightProgram);
  1987. bindDeferredShader(gDeferredMultiSpotLightProgram);
  1988. gDeferredMultiSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
  1989. for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
  1990. {
  1991. LLFastTimer ftm(FTM_PROJECTORS);
  1992. LLDrawable* drawablep = *iter;
  1993. LLVOVolume* volume = drawablep->getVOVolume();
  1994. LLVector3 center = drawablep->getPositionAgent();
  1995. F32* c = center.mV;
  1996. F32 s = volume->getLightRadius()*1.5f;
  1997. sVisibleLightCount++;
  1998. glh::vec3f tc(c);
  1999. mat.mult_matrix_vec(tc);
  2000. setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
  2001. LLColor3 col = volume->getLightColor();
  2002. col *= volume->getLightIntensity();
  2003. glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
  2004. glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
  2005. glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
  2006. }
  2007. gDeferredMultiSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
  2008. unbindDeferredShader(gDeferredMultiSpotLightProgram);
  2009. glPopMatrix();
  2010. glMatrixMode(GL_MODELVIEW);
  2011. glPopMatrix();
  2012. }
  2013. }
  2014. gGL.setColorMask(true, true);
  2015. if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
  2016. {
  2017. mDeferredLight[2].flush();
  2018. mScreen.bindTarget();
  2019. mScreen.clear(GL_COLOR_BUFFER_BIT);
  2020. gGL.setSceneBlendType(LLRender::BT_ALPHA);
  2021. { //mix various light maps (local, sun, gi)
  2022. LLFastTimer ftm(FTM_POST);
  2023. LLGLDisable blend(GL_BLEND);
  2024. LLGLDisable test(GL_ALPHA_TEST);
  2025. LLGLDepthTest depth(GL_FALSE);
  2026. LLGLDisable stencil(GL_STENCIL_TEST);
  2027. bindDeferredShader(gDeferredPostProgram, 0, &mGIMapPost[0]);
  2028. gDeferredPostProgram.bind();
  2029. LLVertexBuffer::unbind();
  2030. glVertexPointer(2, GL_FLOAT, 0, vert);
  2031. glColor3f(1,1,1);
  2032. glPushMatrix();
  2033. glLoadIdentity();
  2034. glMatrixMode(GL_PROJECTION);
  2035. glPushMatrix();
  2036. glLoadIdentity();
  2037. glDrawArrays(GL_TRIANGLES, 0, 3);
  2038. glPopMatrix();
  2039. glMatrixMode(GL_MODELVIEW);
  2040. glPopMatrix();
  2041. unbindDeferredShader(gDeferredPostProgram);
  2042. }
  2043. }
  2044. }
  2045. { //render non-deferred geometry (alpha, fullbright, glow)
  2046. LLGLDisable blend(GL_BLEND);
  2047. LLGLDisable stencil(GL_STENCIL_TEST);
  2048. U32 render_mask = mRenderTypeMask;
  2049. mRenderTypeMask = mRenderTypeMask & 
  2050. ((1 << LLPipeline::RENDER_TYPE_ALPHA) |
  2051. (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) |
  2052. (1 << LLPipeline::RENDER_TYPE_VOLUME) |
  2053. (1 << LLPipeline::RENDER_TYPE_GLOW) |
  2054. (1 << LLPipeline::RENDER_TYPE_BUMP) |
  2055. (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) |
  2056. (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) |
  2057. (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) |
  2058. (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) |
  2059. (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) |
  2060. (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) |
  2061. (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) |
  2062. (1 << LLPipeline::RENDER_TYPE_PASS_GLOW) |
  2063. (1 << LLPipeline::RENDER_TYPE_PASS_GRASS) |
  2064. (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) |
  2065. (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) |
  2066. (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY) |
  2067. (1 << LLPipeline::RENDER_TYPE_AVATAR));
  2068. renderGeomPostDeferred(*LLViewerCamera::getInstance());
  2069. mRenderTypeMask = render_mask;
  2070. }
  2071. mScreen.flush();
  2072. }
  2073. void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
  2074. {
  2075. //construct frustum
  2076. LLVOVolume* volume = drawablep->getVOVolume();
  2077. LLVector3 params = volume->getSpotLightParams();
  2078. F32 fov = params.mV[0];
  2079. F32 focus = params.mV[1];
  2080. LLVector3 pos = drawablep->getPositionAgent();
  2081. LLQuaternion quat = volume->getRenderRotation();
  2082. LLVector3 scale = volume->getScale();
  2083. //get near clip plane
  2084. LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
  2085. at_axis *= quat;
  2086. LLVector3 np = pos+at_axis;
  2087. at_axis.normVec();
  2088. //get origin that has given fov for plane np, at_axis, and given scale
  2089. F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
  2090. LLVector3 origin = np - at_axis*dist;
  2091. //matrix from volume space to agent space
  2092. LLMatrix4 light_mat(quat, LLVector4(origin,1.f));
  2093. glh::matrix4f light_to_agent((F32*) light_mat.mMatrix);
  2094. glh::matrix4f light_to_screen = glh_get_current_modelview() * light_to_agent;
  2095. glh::matrix4f screen_to_light = light_to_screen.inverse();
  2096. F32 s = volume->getLightRadius()*1.5f;
  2097. F32 near_clip = dist;
  2098. F32 width = scale.mV[VX];
  2099. F32 height = scale.mV[VY];
  2100. F32 far_clip = s+dist-scale.mV[VZ];
  2101. F32 fovy = fov * RAD_TO_DEG;
  2102. F32 aspect = width/height;
  2103. glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
  2104. 0.f, 0.5f, 0.f, 0.5f,
  2105. 0.f, 0.f, 0.5f, 0.5f,
  2106. 0.f, 0.f, 0.f, 1.f);
  2107. glh::vec3f p1(0, 0, -(near_clip+0.01f));
  2108. glh::vec3f p2(0, 0, -(near_clip+1.f));
  2109. glh::vec3f screen_origin(0, 0, 0);
  2110. light_to_screen.mult_matrix_vec(p1);
  2111. light_to_screen.mult_matrix_vec(p2);
  2112. light_to_screen.mult_matrix_vec(screen_origin);
  2113. glh::vec3f n = p2-p1;
  2114. n.normalize();
  2115. F32 proj_range = far_clip - near_clip;
  2116. glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip);
  2117. screen_to_light = trans * light_proj * screen_to_light;
  2118. shader.uniformMatrix4fv("proj_mat", 1, FALSE, screen_to_light.m);
  2119. shader.uniform1f("proj_near", near_clip);
  2120. shader.uniform3fv("proj_p", 1, p1.v);
  2121. shader.uniform3fv("proj_n", 1, n.v);
  2122. shader.uniform3fv("proj_origin", 1, screen_origin.v);
  2123. shader.uniform1f("proj_range", proj_range);
  2124. shader.uniform1f("proj_ambiance", params.mV[2]);
  2125. S32 s_idx = -1;
  2126. for (U32 i = 0; i < 2; i++)
  2127. {
  2128. if (mShadowSpotLight[i] == drawablep)
  2129. {
  2130. s_idx = i;
  2131. }
  2132. }
  2133. shader.uniform1i("proj_shadow_idx", s_idx);
  2134. if (s_idx >= 0)
  2135. {
  2136. shader.uniform1f("shadow_fade", 1.f-mSpotLightFade[s_idx]);
  2137. }
  2138. else
  2139. {
  2140. shader.uniform1f("shadow_fade", 1.f);
  2141. }
  2142. {
  2143. LLDrawable* potential = drawablep;
  2144. //determine if this is a good light for casting shadows
  2145. F32 m_pri = volume->getSpotLightPriority();
  2146. for (U32 i = 0; i < 2; i++)
  2147. {
  2148. F32 pri = 0.f;
  2149. if (mTargetShadowSpotLight[i].notNull())
  2150. {
  2151. pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority();
  2152. }
  2153. if (m_pri > pri)
  2154. {
  2155. LLDrawable* temp = mTargetShadowSpotLight[i];
  2156. mTargetShadowSpotLight[i] = potential;
  2157. potential = temp;
  2158. m_pri = pri;
  2159. }
  2160. }
  2161. }
  2162. LLViewerTexture* img = volume->getLightTexture();
  2163. S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
  2164. if (channel > -1 && img)
  2165. {
  2166. gGL.getTexUnit(channel)->bind(img);
  2167. F32 lod_range = logf(img->getWidth())/logf(2.f);
  2168. shader.uniform1f("proj_focus", focus);
  2169. shader.uniform1f("proj_lod", lod_range);
  2170. shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f));
  2171. }
  2172. }
  2173. void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
  2174. {
  2175. stop_glerror();
  2176. shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE);
  2177. shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE);
  2178. shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
  2179. shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE);
  2180. shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);
  2181. shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
  2182. shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
  2183. shader.disableTexture(LLViewerShaderMgr::DEFERRED_EDGE, LLTexUnit::TT_RECT_TEXTURE);
  2184. shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
  2185. shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
  2186. shader.disableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE);
  2187. shader.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
  2188. shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIP);
  2189. shader.disableTexture(LLViewerShaderMgr::DEFERRED_BLOOM);
  2190. shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL);
  2191. shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE);
  2192. shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR);
  2193. shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH);
  2194. shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS);
  2195. shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS);
  2196. shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL);
  2197. shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE);
  2198. shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS);
  2199. shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS);
  2200. for (U32 i = 0; i < 4; i++)
  2201. {
  2202. if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1)
  2203. {
  2204. glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  2205. }
  2206. }
  2207. for (U32 i = 4; i < 6; i++)
  2208. {
  2209. if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i) > -1)
  2210. {
  2211. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  2212. }
  2213. }
  2214. shader.disableTexture(LLViewerShaderMgr::DEFERRED_NOISE);
  2215. shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC);
  2216. S32 channel = shader.disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
  2217. if (channel > -1)
  2218. {
  2219. LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
  2220. if (cube_map)
  2221. {
  2222. cube_map->disable();
  2223. }
  2224. }
  2225. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  2226. gGL.getTexUnit(0)->activate();
  2227. shader.unbind();
  2228. LLGLState::checkTextureChannels();
  2229. }
  2230. inline float sgn(float a)
  2231. {
  2232.     if (a > 0.0F) return (1.0F);
  2233.     if (a < 0.0F) return (-1.0F);
  2234.     return (0.0F);
  2235. }
  2236. void LLPipeline::generateWaterReflection(LLCamera& camera_in)
  2237. {
  2238. if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
  2239. {
  2240. LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
  2241. if (gAgent.getCameraAnimating() || gAgent.getCameraMode() != CAMERA_MODE_MOUSELOOK)
  2242. {
  2243. avatar = NULL;
  2244. }
  2245. if (avatar)
  2246. {
  2247. avatar->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON);
  2248. }
  2249. LLVertexBuffer::unbind();
  2250. LLGLState::checkStates();
  2251. LLGLState::checkTextureChannels();
  2252. LLGLState::checkClientArrays();
  2253. LLCamera camera = camera_in;
  2254. camera.setFar(camera.getFar()*0.87654321f);
  2255. LLPipeline::sReflectionRender = TRUE;
  2256. S32 occlusion = LLPipeline::sUseOcclusion;
  2257. LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
  2258. LLPipeline::sUseOcclusion = llmin(occlusion, 1);
  2259. U32 type_mask = gPipeline.mRenderTypeMask;
  2260. glh::matrix4f projection = glh_get_current_projection();
  2261. glh::matrix4f mat;
  2262. stop_glerror();
  2263. LLPlane plane;
  2264. F32 height = gAgent.getRegion()->getWaterHeight(); 
  2265. F32 to_clip = fabsf(camera.getOrigin().mV[2]-height);
  2266. F32 pad = -to_clip*0.05f; //amount to "pad" clip plane by
  2267. //plane params
  2268. LLVector3 pnorm;
  2269. F32 pd;
  2270. S32 water_clip = 0;
  2271. if (!LLViewerCamera::getInstance()->cameraUnderWater())
  2272. { //camera is above water, clip plane points up
  2273. pnorm.setVec(0,0,1);
  2274. pd = -height;
  2275. plane.setVec(pnorm, pd);
  2276. water_clip = -1;
  2277. }
  2278. else
  2279. { //camera is below water, clip plane points down
  2280. pnorm = LLVector3(0,0,-1);
  2281. pd = height;
  2282. plane.setVec(pnorm, pd);
  2283. water_clip = 1;
  2284. }
  2285. if (!LLViewerCamera::getInstance()->cameraUnderWater())
  2286. { //generate planar reflection map
  2287. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  2288. glClearColor(0,0,0,0);
  2289. mWaterRef.bindTarget();
  2290. gGL.setColorMask(true, true);
  2291. mWaterRef.clear();
  2292. gGL.setColorMask(true, false);
  2293. mWaterRef.getViewport(gGLViewport);
  2294. stop_glerror();
  2295. glPushMatrix();
  2296. mat.set_scale(glh::vec3f(1,1,-1));
  2297. mat.set_translate(glh::vec3f(0,0,height*2.f));
  2298. glh::matrix4f current = glh_get_current_modelview();
  2299. mat = current * mat;
  2300. glh_set_current_modelview(mat);
  2301. glLoadMatrixf(mat.m);
  2302. LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
  2303. glh::matrix4f inv_mat = mat.inverse();
  2304. glh::vec3f origin(0,0,0);
  2305. inv_mat.mult_matrix_vec(origin);
  2306. camera.setOrigin(origin.v);
  2307. glCullFace(GL_FRONT);
  2308. static LLCullResult ref_result;
  2309. U32 ref_mask = 0;
  2310. if (LLDrawPoolWater::sNeedsDistortionUpdate)
  2311. {
  2312. //initial sky pass (no user clip plane)
  2313. { //mask out everything but the sky
  2314. U32 tmp = mRenderTypeMask;
  2315. mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) |
  2316. (1 << LLPipeline::RENDER_TYPE_WL_SKY));
  2317. static LLCullResult result;
  2318. updateCull(camera, result);
  2319. stateSort(camera, result);
  2320. mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) |
  2321. (1 << LLPipeline::RENDER_TYPE_CLOUDS) |
  2322. (1 << LLPipeline::RENDER_TYPE_WL_SKY));
  2323. renderGeom(camera, TRUE);
  2324. mRenderTypeMask = tmp;
  2325. }
  2326. U32 mask = mRenderTypeMask;
  2327. mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_WATER) |
  2328.   (1<<LLPipeline::RENDER_TYPE_GROUND) |
  2329.   (1<<LLPipeline::RENDER_TYPE_SKY) |
  2330.   (1<<LLPipeline::RENDER_TYPE_CLOUDS));
  2331. if (gSavedSettings.getBOOL("RenderWaterReflections"))
  2332. { //mask out selected geometry based on reflection detail
  2333. S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
  2334. if (detail < 3)
  2335. {
  2336. mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_PARTICLES);
  2337. if (detail < 2)
  2338. {
  2339. mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_AVATAR);
  2340. if (detail < 1)
  2341. {
  2342. mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_VOLUME);
  2343. }
  2344. }
  2345. }
  2346. LLGLUserClipPlane clip_plane(plane, mat, projection);
  2347. LLGLDisable cull(GL_CULL_FACE);
  2348. updateCull(camera, ref_result, 1);
  2349. stateSort(camera, ref_result);
  2350. }
  2351. ref_mask = mRenderTypeMask;
  2352. mRenderTypeMask = mask;
  2353. }
  2354. if (LLDrawPoolWater::sNeedsDistortionUpdate)
  2355. {
  2356. mRenderTypeMask = ref_mask;
  2357. if (gSavedSettings.getBOOL("RenderWaterReflections"))
  2358. {
  2359. gPipeline.grabReferences(ref_result);
  2360. LLGLUserClipPlane clip_plane(plane, mat, projection);
  2361. renderGeom(camera);
  2362. }
  2363. }
  2364. glCullFace(GL_BACK);
  2365. glPopMatrix();
  2366. mWaterRef.flush();
  2367. glh_set_current_modelview(current);
  2368. }
  2369. camera.setOrigin(camera_in.getOrigin());
  2370. //render distortion map
  2371. static BOOL last_update = TRUE;
  2372. if (last_update)
  2373. {
  2374. camera.setFar(camera_in.getFar());
  2375. mRenderTypeMask = type_mask & (~(1<<LLPipeline::RENDER_TYPE_WATER) |
  2376. (1<<LLPipeline::RENDER_TYPE_GROUND));
  2377. stop_glerror();
  2378. LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? FALSE : TRUE;
  2379. if (LLPipeline::sUnderWaterRender)
  2380. {
  2381. mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_GROUND) |
  2382.   (1<<LLPipeline::RENDER_TYPE_SKY) |
  2383.   (1<<LLPipeline::RENDER_TYPE_CLOUDS) |
  2384.   (1<<LLPipeline::RENDER_TYPE_WL_SKY));
  2385. }
  2386. LLViewerCamera::updateFrustumPlanes(camera);
  2387. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  2388. LLColor4& col = LLDrawPoolWater::sWaterFogColor;
  2389. glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
  2390. mWaterDis.bindTarget();
  2391. mWaterDis.getViewport(gGLViewport);
  2392. if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate)
  2393. {
  2394. //clip out geometry on the same side of water as the camera
  2395. mat = glh_get_current_modelview();
  2396. LLGLUserClipPlane clip_plane(LLPlane(-pnorm, -(pd+pad)), mat, projection);
  2397. static LLCullResult result;
  2398. updateCull(camera, result, water_clip);
  2399. stateSort(camera, result);
  2400. gGL.setColorMask(true, true);
  2401. mWaterDis.clear();
  2402. gGL.setColorMask(true, false);
  2403. renderGeom(camera);
  2404. }
  2405. LLPipeline::sUnderWaterRender = FALSE;
  2406. mWaterDis.flush();
  2407. }
  2408. last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
  2409. LLRenderTarget::unbindTarget();
  2410. LLPipeline::sReflectionRender = FALSE;
  2411. if (!LLRenderTarget::sUseFBO)
  2412. {
  2413. glClear(GL_DEPTH_BUFFER_BIT);
  2414. }
  2415. glClearColor(0.f, 0.f, 0.f, 0.f);
  2416. gViewerWindow->setup3DViewport();
  2417. mRenderTypeMask = type_mask;
  2418. LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
  2419. LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
  2420. LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd));
  2421. LLPipeline::sUseOcclusion = occlusion;
  2422. LLGLState::checkStates();
  2423. LLGLState::checkTextureChannels();
  2424. LLGLState::checkClientArrays();
  2425. if (avatar)
  2426. {
  2427. avatar->updateAttachmentVisibility(gAgent.getCameraMode());
  2428. }
  2429. }
  2430. }
  2431. glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up)
  2432. {
  2433. glh::matrix4f ret;
  2434. LLVector3 dirN;
  2435. LLVector3 upN;
  2436. LLVector3 lftN;
  2437. lftN = dir % up;
  2438. lftN.normVec();
  2439. upN = lftN % dir;
  2440. upN.normVec();
  2441. dirN = dir;
  2442. dirN.normVec();
  2443. ret.m[ 0] = lftN[0];
  2444. ret.m[ 1] = upN[0];
  2445. ret.m[ 2] = -dirN[0];
  2446. ret.m[ 3] = 0.f;
  2447. ret.m[ 4] = lftN[1];
  2448. ret.m[ 5] = upN[1];
  2449. ret.m[ 6] = -dirN[1];
  2450. ret.m[ 7] = 0.f;
  2451. ret.m[ 8] = lftN[2];
  2452. ret.m[ 9] = upN[2];
  2453. ret.m[10] = -dirN[2];
  2454. ret.m[11] = 0.f;
  2455. ret.m[12] = -(lftN*pos);
  2456. ret.m[13] = -(upN*pos);
  2457. ret.m[14] = dirN*pos;
  2458. ret.m[15] = 1.f;
  2459. return ret;
  2460. }
  2461. glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max)
  2462. {
  2463. glh::matrix4f ret;
  2464. ret.m[ 0] = 2/(max[0]-min[0]);
  2465. ret.m[ 4] = 0;
  2466. ret.m[ 8] = 0;
  2467. ret.m[12] = -(max[0]+min[0])/(max[0]-min[0]);
  2468. ret.m[ 1] = 0;
  2469. ret.m[ 5] = 2/(max[1]-min[1]);
  2470. ret.m[ 9] = 0;
  2471. ret.m[13] = -(max[1]+min[1])/(max[1]-min[1]);
  2472. ret.m[ 2] = 0;
  2473. ret.m[ 6] = 0;
  2474. ret.m[10] = 2/(max[2]-min[2]);
  2475. ret.m[14] = -(max[2]+min[2])/(max[2]-min[2]);
  2476. ret.m[ 3] = 0;
  2477. ret.m[ 7] = 0;
  2478. ret.m[11] = 0;
  2479. ret.m[15] = 1;
  2480. return ret;
  2481. }
  2482. static LLFastTimer::DeclareTimer FTM_SHADOW_RENDER("Render Shadows");
  2483. static LLFastTimer::DeclareTimer FTM_SHADOW_ALPHA("Alpha Shadow");
  2484. static LLFastTimer::DeclareTimer FTM_SHADOW_SIMPLE("Simple Shadow");
  2485. void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, BOOL use_shader, BOOL use_occlusion)
  2486. {
  2487. LLFastTimer t(FTM_SHADOW_RENDER);
  2488. //clip out geometry on the same side of water as the camera
  2489. S32 occlude = LLPipeline::sUseOcclusion;
  2490. if (!use_occlusion)
  2491. {
  2492. LLPipeline::sUseOcclusion = 0;
  2493. }
  2494. LLPipeline::sShadowRender = TRUE;
  2495. U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP, LLRenderPass::PASS_FULLBRIGHT_SHINY };
  2496. LLGLEnable cull(GL_CULL_FACE);
  2497. if (use_shader)
  2498. {
  2499. gDeferredShadowProgram.bind();
  2500. }
  2501. updateCull(shadow_cam, result);
  2502. stateSort(shadow_cam, result);
  2503. //generate shadow map
  2504. glMatrixMode(GL_PROJECTION);
  2505. glPushMatrix();
  2506. glLoadMatrixf(proj.m);
  2507. glMatrixMode(GL_MODELVIEW);
  2508. glPushMatrix();
  2509. glLoadMatrixf(view.m);
  2510. stop_glerror();
  2511. gGLLastMatrix = NULL;
  2512. {
  2513. LLGLDepthTest depth(GL_TRUE);
  2514. glClear(GL_DEPTH_BUFFER_BIT);
  2515. }
  2516. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  2517. glColor4f(1,1,1,1);
  2518. stop_glerror();
  2519. gGL.setColorMask(false, false);
  2520. //glCullFace(GL_FRONT);
  2521. {
  2522. LLFastTimer ftm(FTM_SHADOW_SIMPLE);
  2523. LLGLDisable test(GL_ALPHA_TEST);
  2524. gGL.getTexUnit(0)->disable();
  2525. for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i)
  2526. {
  2527. renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
  2528. }
  2529. gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
  2530. }
  2531. if (use_shader)
  2532. {
  2533. gDeferredShadowProgram.unbind();
  2534. renderGeomShadow(shadow_cam);
  2535. gDeferredShadowProgram.bind();
  2536. }
  2537. else
  2538. {
  2539. renderGeomShadow(shadow_cam);
  2540. }
  2541. {
  2542. LLFastTimer ftm(FTM_SHADOW_ALPHA);
  2543. LLGLEnable test(GL_ALPHA_TEST);
  2544. gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f);
  2545. renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE);
  2546. glColor4f(1,1,1,1);
  2547. renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
  2548. gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
  2549. }
  2550. //glCullFace(GL_BACK);
  2551. gGLLastMatrix = NULL;
  2552. glLoadMatrixd(gGLModelView);
  2553. doOcclusion(shadow_cam);
  2554. if (use_shader)
  2555. {
  2556. gDeferredShadowProgram.unbind();
  2557. }
  2558. gGL.setColorMask(true, true);
  2559. glMatrixMode(GL_PROJECTION);
  2560. glPopMatrix();
  2561. glMatrixMode(GL_MODELVIEW);
  2562. glPopMatrix();
  2563. gGLLastMatrix = NULL;
  2564. LLPipeline::sUseOcclusion = occlude;
  2565. LLPipeline::sShadowRender = FALSE;
  2566. }
  2567. BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir)
  2568. {
  2569. //get point cloud of intersection of frust and min, max
  2570. //get set of planes
  2571. std::vector<LLPlane> ps;
  2572. if (getVisibleExtents(camera, min, max))
  2573. {
  2574. return FALSE;
  2575. }
  2576. ps.push_back(LLPlane(min, LLVector3(-1,0,0)));
  2577. ps.push_back(LLPlane(min, LLVector3(0,-1,0)));
  2578. ps.push_back(LLPlane(min, LLVector3(0,0,-1)));
  2579. ps.push_back(LLPlane(max, LLVector3(1,0,0)));
  2580. ps.push_back(LLPlane(max, LLVector3(0,1,0)));
  2581. ps.push_back(LLPlane(max, LLVector3(0,0,1)));
  2582. /*if (!light_dir.isExactlyZero())
  2583. {
  2584. LLPlane ucp;
  2585. LLPlane mcp;
  2586. F32 maxd = -1.f;
  2587. F32 mind = 1.f;
  2588. for (U32 i = 0; i < ps.size(); ++i)
  2589. {  //pick the plane most aligned to lightDir for user clip plane
  2590. LLVector3 n(ps[i].mV);
  2591. F32 da = n*light_dir;
  2592. if (da > maxd)
  2593. {
  2594. maxd = da;
  2595. ucp = ps[i];
  2596. }
  2597. if (da < mind)
  2598. {
  2599. mind = da;
  2600. mcp = ps[i];
  2601. }
  2602. }
  2603. camera.setUserClipPlane(ucp);
  2604. ps.clear();
  2605. ps.push_back(ucp);
  2606. ps.push_back(mcp);
  2607. }*/
  2608. for (U32 i = 0; i < 6; i++)
  2609. {
  2610. ps.push_back(camera.getAgentPlane(i));
  2611. }
  2612. //get set of points where planes intersect and points are not above any plane
  2613. fp.clear();
  2614. for (U32 i = 0; i < ps.size(); ++i)
  2615. {
  2616. for (U32 j = 0; j < ps.size(); ++j)
  2617. {
  2618. for (U32 k = 0; k < ps.size(); ++k)
  2619. {
  2620. if (i == j ||
  2621. i == k ||
  2622. k == j)
  2623. {
  2624. continue;
  2625. }
  2626. LLVector3 n1,n2,n3;
  2627. F32 d1,d2,d3;
  2628. n1.setVec(ps[i].mV);
  2629. n2.setVec(ps[j].mV);
  2630. n3.setVec(ps[k].mV);
  2631. d1 = ps[i].mV[3];
  2632. d2 = ps[j].mV[3];
  2633. d3 = ps[k].mV[3];
  2634. //get point of intersection of 3 planes "p"
  2635. LLVector3 p = (-d1*(n2%n3)-d2*(n3%n1)-d3*(n1%n2))/(n1*(n2%n3));
  2636. if (llround(p*n1+d1, 0.0001f) == 0.f &&
  2637. llround(p*n2+d2, 0.0001f) == 0.f &&
  2638. llround(p*n3+d3, 0.0001f) == 0.f)
  2639. { //point is on all three planes
  2640. BOOL found = TRUE;
  2641. for (U32 l = 0; l < ps.size() && found; ++l)
  2642. {
  2643. if (llround(ps[l].dist(p), 0.0001f) > 0.0f)
  2644. { //point is above some plane, not contained
  2645. found = FALSE;
  2646. }
  2647. }
  2648. if (found)
  2649. {
  2650. fp.push_back(p);
  2651. }
  2652. }
  2653. }
  2654. }
  2655. }
  2656. if (fp.empty())
  2657. {
  2658. return FALSE;
  2659. }
  2660. return TRUE;
  2661. }
  2662. void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<LLVector3>& vpc)
  2663. {
  2664. if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) < 3)
  2665. {
  2666. return;
  2667. }
  2668. LLVector3 up;
  2669. //LLGLEnable depth_clamp(GL_DEPTH_CLAMP_NV);
  2670. if (lightDir.mV[2] > 0.5f)
  2671. {
  2672. up = LLVector3(1,0,0);
  2673. }
  2674. else
  2675. {
  2676. up = LLVector3(0, 0, 1);
  2677. }
  2678. F32 gi_range = gSavedSettings.getF32("RenderGIRange");
  2679. U32 res = mGIMap.getWidth();
  2680. F32 atten = llmax(gSavedSettings.getF32("RenderGIAttenuation"), 0.001f);
  2681. //set radius to range at which distance attenuation of incoming photons is near 0
  2682. F32 lrad = sqrtf(1.f/(atten*0.01f));
  2683. F32 lrange = lrad+gi_range*0.5f;
  2684. LLVector3 pad(lrange,lrange,lrange);
  2685. glh::matrix4f view = look(LLVector3(128.f,128.f,128.f), lightDir, up);
  2686. LLVector3 cp = camera.getOrigin()+camera.getAtAxis()*(gi_range*0.5f);
  2687. glh::vec3f scp(cp.mV);
  2688. view.mult_matrix_vec(scp);
  2689. cp.setVec(scp.v);
  2690. F32 pix_width = lrange/(res*0.5f);
  2691. //move cp to the nearest pix_width
  2692. for (U32 i = 0; i < 3; i++)
  2693. {
  2694. cp.mV[i] = llround(cp.mV[i], pix_width);
  2695. }
  2696. LLVector3 min = cp-pad;
  2697. LLVector3 max = cp+pad;
  2698. //set mGIRange to range in tc space[0,1] that covers texture block of intersecting lights around a point
  2699. mGIRange.mV[0] = (max.mV[0]-min.mV[0])/res;
  2700. mGIRange.mV[1] = (max.mV[1]-min.mV[1])/res;
  2701. mGILightRadius = lrad/lrange*0.5f;
  2702. glh::matrix4f proj = gl_ortho(min.mV[0], max.mV[0],
  2703. min.mV[1], max.mV[1],
  2704. -max.mV[2], -min.mV[2]);
  2705. LLCamera sun_cam = camera;
  2706. glh::matrix4f eye_view = glh_get_current_modelview();
  2707. //get eye space to camera space matrix
  2708. mGIMatrix = view*eye_view.inverse();
  2709. mGINormalMatrix = mGIMatrix.inverse().transpose();
  2710. mGIInvProj = proj.inverse();
  2711. mGIMatrixProj = proj*mGIMatrix;
  2712. //translate and scale to [0,1]
  2713. glh::matrix4f trans(.5f, 0.f, 0.f, .5f,
  2714. 0.f, 0.5f, 0.f, 0.5f,
  2715. 0.f, 0.f, 0.5f, 0.5f,
  2716. 0.f, 0.f, 0.f, 1.f);
  2717. mGIMatrixProj = trans*mGIMatrixProj;
  2718. glh_set_current_modelview(view);
  2719. glh_set_current_projection(proj);
  2720. LLViewerCamera::updateFrustumPlanes(sun_cam, TRUE, FALSE, TRUE);
  2721. sun_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);
  2722. static LLCullResult result;
  2723. U32 type_mask = mRenderTypeMask;
  2724. mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) |
  2725.    (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |
  2726.    (1<<LLPipeline::RENDER_TYPE_BUMP) |
  2727.    (1<<LLPipeline::RENDER_TYPE_VOLUME) |
  2728.    (1<<LLPipeline::RENDER_TYPE_TREE) | 
  2729.    (1<<LLPipeline::RENDER_TYPE_TERRAIN) |
  2730.    (1<<LLPipeline::RENDER_TYPE_WATER) |
  2731.    (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) |
  2732.    (1<<LLPipeline::RENDER_TYPE_AVATAR) |
  2733.    (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) |
  2734. (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) |
  2735. (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) |
  2736. (1 << LLPipeline::RENDER_TYPE_PASS_SHINY));
  2737. S32 occlude = LLPipeline::sUseOcclusion;
  2738. //LLPipeline::sUseOcclusion = 0;
  2739. LLPipeline::sShadowRender = TRUE;
  2740. //only render large objects into GI map
  2741. sMinRenderSize = gSavedSettings.getF32("RenderGIMinRenderSize");
  2742. LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_GI_SOURCE;
  2743. mGIMap.bindTarget();
  2744. F64 last_modelview[16];
  2745. F64 last_projection[16];
  2746. for (U32 i = 0; i < 16; i++)
  2747. {
  2748. last_modelview[i] = gGLLastModelView[i];
  2749. last_projection[i] = gGLLastProjection[i];
  2750. gGLLastModelView[i] = mGIModelview.m[i];
  2751. gGLLastProjection[i] = mGIProjection.m[i];
  2752. }
  2753. sun_cam.setOrigin(0.f, 0.f, 0.f);
  2754. updateCull(sun_cam, result);
  2755. stateSort(sun_cam, result);
  2756. for (U32 i = 0; i < 16; i++)
  2757. {
  2758. gGLLastModelView[i] = last_modelview[i];
  2759. gGLLastProjection[i] = last_projection[i];
  2760. }
  2761. mGIProjection = proj;
  2762. mGIModelview = view;
  2763. LLGLEnable cull(GL_CULL_FACE);
  2764. //generate GI map
  2765. glMatrixMode(GL_PROJECTION);
  2766. glPushMatrix();
  2767. glLoadMatrixf(proj.m);
  2768. glMatrixMode(GL_MODELVIEW);
  2769. glPushMatrix();
  2770. glLoadMatrixf(view.m);
  2771. stop_glerror();
  2772. gGLLastMatrix = NULL;
  2773. mGIMap.clear();
  2774. {
  2775. //LLGLEnable enable(GL_DEPTH_CLAMP_NV);
  2776. renderGeomDeferred(camera);
  2777. }
  2778. mGIMap.flush();
  2779. glMatrixMode(GL_PROJECTION);
  2780. glPopMatrix();
  2781. glMatrixMode(GL_MODELVIEW);
  2782. glPopMatrix();
  2783. gGLLastMatrix = NULL;
  2784. LLPipeline::sUseOcclusion = occlude;
  2785. LLPipeline::sShadowRender = FALSE;
  2786. sMinRenderSize = 0.f;
  2787. mRenderTypeMask = type_mask;
  2788. }
  2789. void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade)
  2790. {
  2791. if (obj && obj->getVolume())
  2792. {
  2793. for (LLViewerObject::child_list_t::const_iterator iter = obj->getChildren().begin(); iter != obj->getChildren().end(); ++iter)
  2794. {
  2795. renderHighlight(*iter, fade);
  2796. }
  2797. LLDrawable* drawable = obj->mDrawable;
  2798. if (drawable)
  2799. {
  2800. for (S32 i = 0; i < drawable->getNumFaces(); ++i)
  2801. {
  2802. LLFace* face = drawable->getFace(i);
  2803. if (face)
  2804. {
  2805. face->renderSelected(LLViewerTexture::sNullImagep, LLColor4(1,1,1,fade));
  2806. }
  2807. }
  2808. }
  2809. }
  2810. }
  2811. void LLPipeline::generateHighlight(LLCamera& camera)
  2812. {
  2813. //render highlighted object as white into offscreen render target
  2814. if (mHighlightObject.notNull())
  2815. {
  2816. mHighlightSet.insert(HighlightItem(mHighlightObject));
  2817. }
  2818. if (!mHighlightSet.empty())
  2819. {
  2820. F32 transition = gFrameIntervalSeconds/gSavedSettings.getF32("RenderHighlightFadeTime");
  2821. LLGLDisable test(GL_ALPHA_TEST);
  2822. LLGLDepthTest depth(GL_FALSE);
  2823. mHighlight.bindTarget();
  2824. disableLights();
  2825. gGL.setColorMask(true, true);
  2826. mHighlight.clear();
  2827. gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
  2828. for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); )
  2829. {
  2830. std::set<HighlightItem>::iterator cur_iter = iter++;
  2831. if (cur_iter->mItem.isNull())
  2832. {
  2833. mHighlightSet.erase(cur_iter);
  2834. continue;
  2835. }
  2836. if (cur_iter->mItem == mHighlightObject)
  2837. {
  2838. cur_iter->incrFade(transition); 
  2839. }
  2840. else
  2841. {
  2842. cur_iter->incrFade(-transition);
  2843. if (cur_iter->mFade <= 0.f)
  2844. {
  2845. mHighlightSet.erase(cur_iter);
  2846. continue;
  2847. }
  2848. }
  2849. renderHighlight(cur_iter->mItem->getVObj(), cur_iter->mFade);
  2850. }
  2851. mHighlight.flush();
  2852. gGL.setColorMask(true, false);
  2853. gViewerWindow->setup3DViewport();
  2854. }
  2855. }
  2856. void LLPipeline::generateSunShadow(LLCamera& camera)
  2857. {
  2858. if (!sRenderDeferred || !gSavedSettings.getBOOL("RenderDeferredShadow"))
  2859. {
  2860. return;
  2861. }
  2862. //temporary hack to disable shadows but keep local lights
  2863. static BOOL clear = TRUE;
  2864. BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow");
  2865. if (!gen_shadow)
  2866. {
  2867. if (clear)
  2868. {
  2869. clear = FALSE;
  2870. for (U32 i = 0; i < 6; i++)
  2871. {
  2872. mShadow[i].bindTarget();
  2873. mShadow[i].clear();
  2874. mShadow[i].flush();
  2875. }
  2876. }
  2877. return;
  2878. }
  2879. clear = TRUE;
  2880. F64 last_modelview[16];
  2881. F64 last_projection[16];
  2882. for (U32 i = 0; i < 16; i++)
  2883. { //store last_modelview of world camera
  2884. last_modelview[i] = gGLLastModelView[i];
  2885. last_projection[i] = gGLLastProjection[i];
  2886. }
  2887. U32 type_mask = mRenderTypeMask;
  2888. mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) |
  2889.    (1<<LLPipeline::RENDER_TYPE_ALPHA) |
  2890.    (1<<LLPipeline::RENDER_TYPE_GRASS) |
  2891.    (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |
  2892.    (1<<LLPipeline::RENDER_TYPE_BUMP) |
  2893.    (1<<LLPipeline::RENDER_TYPE_VOLUME) |
  2894.    (1<<LLPipeline::RENDER_TYPE_AVATAR) |
  2895.    (1<<LLPipeline::RENDER_TYPE_TREE) | 
  2896.    (1<<LLPipeline::RENDER_TYPE_TERRAIN) |
  2897.    (1<<LLPipeline::RENDER_TYPE_WATER) |
  2898.    (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) |
  2899.    (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) |
  2900.    (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) |
  2901.    (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) |
  2902.    (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) |
  2903.    (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY));
  2904. gGL.setColorMask(false, false);
  2905. //get sun view matrix
  2906. //store current projection/modelview matrix
  2907. glh::matrix4f saved_proj = glh_get_current_projection();
  2908. glh::matrix4f saved_view = glh_get_current_modelview();
  2909. glh::matrix4f inv_view = saved_view.inverse();
  2910. glh::matrix4f view[6];
  2911. glh::matrix4f proj[6];
  2912. //clip contains parallel split distances for 3 splits
  2913. LLVector3 clip = gSavedSettings.getVector3("RenderShadowClipPlanes");
  2914. //F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold");
  2915. //far clip on last split is minimum of camera view distance and 128
  2916. mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]);
  2917. clip = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes");
  2918. mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]);
  2919. //currently used for amount to extrude frusta corners for constructing shadow frusta
  2920. LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist");
  2921. //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
  2922. LLVector3 lightDir = -mSunDir;
  2923. lightDir.normVec();
  2924. glh::vec3f light_dir(lightDir.mV);
  2925. //create light space camera matrix
  2926. LLVector3 at = lightDir;
  2927. LLVector3 up = camera.getAtAxis();
  2928. if (fabsf(up*lightDir) > 0.75f)
  2929. {
  2930. up = camera.getUpAxis();
  2931. }
  2932. /*LLVector3 left = up%at;
  2933. up = at%left;*/
  2934. up.normVec();
  2935. at.normVec();
  2936. F32 near_clip = 0.f;
  2937. {
  2938. //get visible point cloud
  2939. std::vector<LLVector3> fp;
  2940. LLVector3 min,max;
  2941. getVisiblePointCloud(camera,min,max,fp);
  2942. if (fp.empty())
  2943. {
  2944. mRenderTypeMask = type_mask;
  2945. return;
  2946. }
  2947. generateGI(camera, lightDir, fp);
  2948. //get good split distances for frustum
  2949. for (U32 i = 0; i < fp.size(); ++i)
  2950. {
  2951. glh::vec3f v(fp[i].mV);
  2952. saved_view.mult_matrix_vec(v);
  2953. fp[i].setVec(v.v);
  2954. }
  2955. min = fp[0];
  2956. max = fp[0];
  2957. //get camera space bounding box
  2958. for (U32 i = 1; i < fp.size(); ++i)
  2959. {
  2960. update_min_max(min, max, fp[i]);
  2961. }
  2962. near_clip = -max.mV[2];
  2963. F32 far_clip = -min.mV[2]*2.f;
  2964. far_clip = llmin(far_clip, 128.f);
  2965. far_clip = llmin(far_clip, camera.getFar());
  2966. F32 range = far_clip-near_clip;
  2967. LLVector3 split_exp = gSavedSettings.getVector3("RenderShadowSplitExponent");
  2968. F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) );
  2969. da = powf(da, split_exp.mV[2]);
  2970. F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da;
  2971. for (U32 i = 0; i < 4; ++i)
  2972. {
  2973. F32 x = (F32)(i+1)/4.f;
  2974. x = powf(x, sxp);
  2975. mSunClipPlanes.mV[i] = near_clip+range*x;
  2976. }
  2977. }
  2978. // convenience array of 4 near clip plane distances
  2979. F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
  2980. for (S32 j = 0; j < 4; j++)
  2981. {
  2982. if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
  2983. {
  2984. mShadowFrustPoints[j].clear();
  2985. }
  2986. LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+j;
  2987. //restore render matrices
  2988. glh_set_current_modelview(saved_view);
  2989. glh_set_current_projection(saved_proj);
  2990. LLVector3 eye = camera.getOrigin();
  2991. //camera used for shadow cull/render
  2992. LLCamera shadow_cam;
  2993. //create world space camera frustum for this split
  2994. shadow_cam = camera;
  2995. shadow_cam.setFar(16.f);
  2996. LLViewerCamera::updateFrustumPlanes(shadow_cam);
  2997. LLVector3* frust = shadow_cam.mAgentFrustum;
  2998. LLVector3 pn = shadow_cam.getAtAxis();
  2999. LLVector3 min, max;
  3000. //construct 8 corners of split frustum section
  3001. for (U32 i = 0; i < 4; i++)
  3002. {
  3003. LLVector3 delta = frust[i+4]-eye;
  3004. delta.normVec();
  3005. F32 dp = delta*pn;
  3006. frust[i] = eye + (delta*dist[j])/dp;
  3007. frust[i+4] = eye + (delta*dist[j+1])/dp;
  3008. }
  3009. shadow_cam.calcAgentFrustumPlanes(frust);
  3010. shadow_cam.mFrustumCornerDist = 0.f;
  3011. if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
  3012. {
  3013. mShadowCamera[j] = shadow_cam;
  3014. }
  3015. std::vector<LLVector3> fp;
  3016. if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir))
  3017. {
  3018. //no possible shadow receivers
  3019. if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
  3020. {
  3021. mShadowExtents[j][0] = LLVector3();
  3022. mShadowExtents[j][1] = LLVector3();
  3023. mShadowCamera[j+4] = shadow_cam;
  3024. }
  3025. mShadow[j].bindTarget();
  3026. {
  3027. LLGLDepthTest depth(GL_TRUE);
  3028. mShadow[j].clear();
  3029. }
  3030. mShadow[j].flush();
  3031. mShadowError.mV[j] = 0.f;
  3032. mShadowFOV.mV[j] = 0.f;
  3033. continue;
  3034. }
  3035. if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
  3036. {
  3037. mShadowExtents[j][0] = min;
  3038. mShadowExtents[j][1] = max;
  3039. mShadowFrustPoints[j] = fp;
  3040. }
  3041. //find a good origin for shadow projection
  3042. LLVector3 origin;
  3043. //get a temporary view projection
  3044. view[j] = look(camera.getOrigin(), lightDir, -up);
  3045. std::vector<LLVector3> wpf;
  3046. for (U32 i = 0; i < fp.size(); i++)
  3047. {
  3048. glh::vec3f p = glh::vec3f(fp[i].mV);
  3049. view[j].mult_matrix_vec(p);
  3050. wpf.push_back(LLVector3(p.v));
  3051. }
  3052. min = wpf[0];
  3053. max = wpf[0];
  3054. for (U32 i = 0; i < fp.size(); ++i)
  3055. { //get AABB in camera space
  3056. update_min_max(min, max, wpf[i]);
  3057. }
  3058. // Construct a perspective transform with perspective along y-axis that contains
  3059. // points in wpf
  3060. //Known:
  3061. // - far clip plane
  3062. // - near clip plane
  3063. // - points in frustum
  3064. //Find:
  3065. // - origin
  3066. //get some "interesting" points of reference
  3067. LLVector3 center = (min+max)*0.5f;
  3068. LLVector3 size = (max-min)*0.5f;
  3069. LLVector3 near_center = center;
  3070. near_center.mV[1] += size.mV[1]*2.f;
  3071. //put all points in wpf in quadrant 0, reletive to center of min/max
  3072. //get the best fit line using least squares
  3073. F32 bfm = 0.f;
  3074. F32 bfb = 0.f;
  3075. for (U32 i = 0; i < wpf.size(); ++i)
  3076. {
  3077. wpf[i] -= center;
  3078. wpf[i].mV[0] = fabsf(wpf[i].mV[0]);
  3079. wpf[i].mV[2] = fabsf(wpf[i].mV[2]);
  3080. }
  3081. if (!wpf.empty())
  3082. F32 sx = 0.f;
  3083. F32 sx2 = 0.f;
  3084. F32 sy = 0.f;
  3085. F32 sxy = 0.f;
  3086. for (U32 i = 0; i < wpf.size(); ++i)
  3087. {
  3088. sx += wpf[i].mV[0];
  3089. sx2 += wpf[i].mV[0]*wpf[i].mV[0];
  3090. sy += wpf[i].mV[1];
  3091. sxy += wpf[i].mV[0]*wpf[i].mV[1]; 
  3092. }
  3093. bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2);
  3094. bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2);
  3095. }
  3096. {
  3097. // best fit line is y=bfm*x+bfb
  3098. //find point that is furthest to the right of line
  3099. F32 off_x = -1.f;
  3100. LLVector3 lp;
  3101. for (U32 i = 0; i < wpf.size(); ++i)
  3102. {
  3103. //y = bfm*x+bfb
  3104. //x = (y-bfb)/bfm
  3105. F32 lx = (wpf[i].mV[1]-bfb)/bfm;
  3106. lx = wpf[i].mV[0]-lx;
  3107. if (off_x < lx)
  3108. {
  3109. off_x = lx;
  3110. lp = wpf[i];
  3111. }
  3112. }
  3113. //get line with slope bfm through lp
  3114. // bfb = y-bfm*x
  3115. bfb = lp.mV[1]-bfm*lp.mV[0];
  3116. //calculate error
  3117. mShadowError.mV[j] = 0.f;
  3118. for (U32 i = 0; i < wpf.size(); ++i)
  3119. {
  3120. F32 lx = (wpf[i].mV[1]-bfb)/bfm;
  3121. mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx);
  3122. }
  3123. mShadowError.mV[j] /= wpf.size();
  3124. mShadowError.mV[j] /= size.mV[0];
  3125. if (mShadowError.mV[j] > gSavedSettings.getF32("RenderShadowErrorCutoff"))
  3126. { //just use ortho projection
  3127. mShadowFOV.mV[j] = -1.f;
  3128. origin.clearVec();
  3129. proj[j] = gl_ortho(min.mV[0], max.mV[0],
  3130. min.mV[1], max.mV[1],
  3131. -max.mV[2], -min.mV[2]);
  3132. }
  3133. else
  3134. {
  3135. //origin is where line x = 0;
  3136. origin.setVec(0,bfb,0);
  3137. F32 fovz = 1.f;
  3138. F32 fovx = 1.f;
  3139. LLVector3 zp;
  3140. LLVector3 xp;
  3141. for (U32 i = 0; i < wpf.size(); ++i)
  3142. {
  3143. LLVector3 atz = wpf[i]-origin;
  3144. atz.mV[0] = 0.f;
  3145. atz.normVec();
  3146. if (fovz > -atz.mV[1])
  3147. {
  3148. zp = wpf[i];
  3149. fovz = -atz.mV[1];
  3150. }
  3151. LLVector3 atx = wpf[i]-origin;
  3152. atx.mV[2] = 0.f;
  3153. atx.normVec();
  3154. if (fovx > -atx.mV[1])
  3155. {
  3156. fovx = -atx.mV[1];
  3157. xp = wpf[i];
  3158. }
  3159. }
  3160. fovx = acos(fovx);
  3161. fovz = acos(fovz);
  3162. F32 cutoff = llmin(gSavedSettings.getF32("RenderShadowFOVCutoff"), 1.4f);
  3163. mShadowFOV.mV[j] = fovx;
  3164. if (fovx < cutoff && fovz > cutoff)
  3165. {
  3166. //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff
  3167. F32 d = zp.mV[2]/tan(cutoff);
  3168. F32 ny = zp.mV[1] + fabsf(d);
  3169. origin.mV[1] = ny;
  3170. fovz = 1.f;
  3171. fovx = 1.f;
  3172. for (U32 i = 0; i < wpf.size(); ++i)
  3173. {
  3174. LLVector3 atz = wpf[i]-origin;
  3175. atz.mV[0] = 0.f;
  3176. atz.normVec();
  3177. fovz = llmin(fovz, -atz.mV[1]);
  3178. LLVector3 atx = wpf[i]-origin;
  3179. atx.mV[2] = 0.f;
  3180. atx.normVec();
  3181. fovx = llmin(fovx, -atx.mV[1]);
  3182. }
  3183. fovx = acos(fovx);
  3184. fovz = acos(fovz);
  3185. if (fovx > cutoff || llround(fovz, 0.01f) > cutoff)
  3186. {
  3187. // llerrs << "WTF?" << llendl;
  3188. }
  3189. mShadowFOV.mV[j] = cutoff;
  3190. }
  3191. origin += center;
  3192. F32 ynear = -(max.mV[1]-origin.mV[1]);
  3193. F32 yfar = -(min.mV[1]-origin.mV[1]);
  3194. if (ynear < 0.1f) //keep a sensible near clip plane
  3195. {
  3196. F32 diff = 0.1f-ynear;
  3197. origin.mV[1] += diff;
  3198. ynear += diff;
  3199. yfar += diff;
  3200. }
  3201. if (fovx > cutoff)
  3202. { //just use ortho projection
  3203. origin.clearVec();
  3204. mShadowError.mV[j] = -1.f;
  3205. proj[j] = gl_ortho(min.mV[0], max.mV[0],
  3206. min.mV[1], max.mV[1],
  3207. -max.mV[2], -min.mV[2]);
  3208. }
  3209. else
  3210. {
  3211. //get perspective projection
  3212. view[j] = view[j].inverse();
  3213. glh::vec3f origin_agent(origin.mV);
  3214. //translate view to origin
  3215. view[j].mult_matrix_vec(origin_agent);
  3216. eye = LLVector3(origin_agent.v);
  3217. if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
  3218. {
  3219. mShadowFrustOrigin[j] = eye;
  3220. }
  3221. view[j] = look(LLVector3(origin_agent.v), lightDir, -up);
  3222. F32 fx = 1.f/tanf(fovx);
  3223. F32 fz = 1.f/tanf(fovz);
  3224. proj[j] = glh::matrix4f(-fx, 0, 0, 0,
  3225. 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar),
  3226. 0, 0, -fz, 0,
  3227. 0, -1.f, 0, 0);
  3228. }
  3229. }
  3230. }
  3231. shadow_cam.setFar(128.f);
  3232. shadow_cam.setOriginAndLookAt(eye, up, center);
  3233. shadow_cam.setOrigin(0,0,0);
  3234. glh_set_current_modelview(view[j]);
  3235. glh_set_current_projection(proj[j]);
  3236. LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
  3237. shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);
  3238. //translate and scale to from [-1, 1] to [0, 1]
  3239. glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
  3240. 0.f, 0.5f, 0.f, 0.5f,
  3241. 0.f, 0.f, 0.5f, 0.5f,
  3242. 0.f, 0.f, 0.f, 1.f);
  3243. glh_set_current_modelview(view[j]);
  3244. glh_set_current_projection(proj[j]);
  3245. for (U32 i = 0; i < 16; i++)
  3246. {
  3247. gGLLastModelView[i] = mShadowModelview[j].m[i];
  3248. gGLLastProjection[i] = mShadowProjection[j].m[i];
  3249. }
  3250. mShadowModelview[j] = view[j];
  3251. mShadowProjection[j] = proj[j];
  3252. mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view;
  3253. stop_glerror();
  3254. mShadow[j].bindTarget();
  3255. mShadow[j].getViewport(gGLViewport);
  3256. {
  3257. static LLCullResult result[4];
  3258. //LLGLEnable enable(GL_DEPTH_CLAMP_NV);
  3259. renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE);
  3260. }
  3261. mShadow[j].flush();
  3262.  
  3263. if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
  3264. {
  3265. LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
  3266. mShadowCamera[j+4] = shadow_cam;
  3267. }
  3268. }
  3269. F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f);
  3270. //update shadow targets
  3271. for (U32 i = 0; i < 2; i++)
  3272. { //for each current shadow
  3273. LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i;
  3274. if (mShadowSpotLight[i].notNull() && 
  3275. (mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
  3276. mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
  3277. { //keep this spotlight
  3278. mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f);
  3279. }
  3280. else
  3281. { //fade out this light
  3282. mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f);
  3283. if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
  3284. { //faded out, grab one of the pending spots (whichever one isn't already taken)
  3285. if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2])
  3286. {
  3287. mShadowSpotLight[i] = mTargetShadowSpotLight[0];
  3288. }
  3289. else
  3290. {
  3291. mShadowSpotLight[i] = mTargetShadowSpotLight[1];
  3292. }
  3293. }
  3294. }
  3295. }
  3296. for (S32 i = 0; i < 2; i++)
  3297. {
  3298. glh_set_current_modelview(saved_view);
  3299. glh_set_current_projection(saved_proj);
  3300. if (mShadowSpotLight[i].isNull())
  3301. {
  3302. continue;
  3303. }
  3304. LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
  3305. if (!volume)
  3306. {
  3307. mShadowSpotLight[i] = NULL;
  3308. continue;
  3309. }
  3310. LLDrawable* drawable = mShadowSpotLight[i];
  3311. LLVector3 params = volume->getSpotLightParams();
  3312. F32 fov = params.mV[0];
  3313. //get agent->light space matrix (modelview)
  3314. LLVector3 center = drawable->getPositionAgent();
  3315. LLQuaternion quat = volume->getRenderRotation();
  3316. //get near clip plane
  3317. LLVector3 scale = volume->getScale();
  3318. LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
  3319. at_axis *= quat;
  3320. LLVector3 np = center+at_axis;
  3321. at_axis.normVec();
  3322. //get origin that has given fov for plane np, at_axis, and given scale
  3323. F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
  3324. LLVector3 origin = np - at_axis*dist;
  3325. LLMatrix4 mat(quat, LLVector4(origin, 1.f));
  3326. view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
  3327. view[i+4] = view[i+4].inverse();
  3328. //get perspective matrix
  3329. F32 near_clip = dist+0.01f;
  3330. F32 width = scale.mV[VX];
  3331. F32 height = scale.mV[VY];
  3332. F32 far_clip = dist+volume->getLightRadius()*1.5f;
  3333. F32 fovy = fov * RAD_TO_DEG;
  3334. F32 aspect = width/height;
  3335. proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
  3336. //translate and scale to from [-1, 1] to [0, 1]
  3337. glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
  3338. 0.f, 0.5f, 0.f, 0.5f,
  3339. 0.f, 0.f, 0.5f, 0.5f,
  3340. 0.f, 0.f, 0.f, 1.f);
  3341. glh_set_current_modelview(view[i+4]);
  3342. glh_set_current_projection(proj[i+4]);
  3343. mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
  3344. for (U32 j = 0; j < 16; j++)
  3345. {
  3346. gGLLastModelView[j] = mShadowModelview[i+4].m[j];
  3347. gGLLastProjection[j] = mShadowProjection[i+4].m[j];
  3348. }
  3349. mShadowModelview[i+4] = view[i+4];
  3350. mShadowProjection[i+4] = proj[i+4];
  3351. LLCamera shadow_cam = camera;
  3352. shadow_cam.setFar(far_clip);
  3353. shadow_cam.setOrigin(origin);
  3354. LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
  3355. stop_glerror();
  3356. mShadow[i+4].bindTarget();
  3357. mShadow[i+4].getViewport(gGLViewport);
  3358. static LLCullResult result[2];
  3359. LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4;
  3360. renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE);
  3361. mShadow[i+4].flush();
  3362.   }
  3363. if (!gSavedSettings.getBOOL("CameraOffset"))
  3364. {
  3365. glh_set_current_modelview(saved_view);
  3366. glh_set_current_projection(saved_proj);
  3367. }
  3368. else
  3369. {
  3370. glh_set_current_modelview(view[1]);
  3371. glh_set_current_projection(proj[1]);
  3372. glLoadMatrixf(view[1].m);
  3373. glMatrixMode(GL_PROJECTION);
  3374. glLoadMatrixf(proj[1].m);
  3375. glMatrixMode(GL_MODELVIEW);
  3376. }
  3377. gGL.setColorMask(true, false);
  3378. for (U32 i = 0; i < 16; i++)
  3379. {
  3380. gGLLastModelView[i] = last_modelview[i];
  3381. gGLLastProjection[i] = last_projection[i];
  3382. }
  3383. mRenderTypeMask = type_mask;
  3384. }
  3385. void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture)
  3386. {
  3387. for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
  3388. {
  3389. LLSpatialGroup* group = *i;
  3390. if (!group->isDead() &&
  3391. (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) &&
  3392. gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) &&
  3393. group->mDrawMap.find(type) != group->mDrawMap.end())
  3394. {
  3395. pass->renderGroup(group,type,mask,texture);
  3396. }
  3397. }
  3398. }
  3399. void LLPipeline::generateImpostor(LLVOAvatar* avatar)
  3400. {
  3401. LLMemType mt_gi(LLMemType::MTYPE_PIPELINE_GENERATE_IMPOSTOR);
  3402. LLGLState::checkStates();
  3403. LLGLState::checkTextureChannels();
  3404. LLGLState::checkClientArrays();
  3405. static LLCullResult result;
  3406. result.clear();
  3407. grabReferences(result);
  3408. if (!avatar || !avatar->mDrawable)
  3409. {
  3410. return;
  3411. }
  3412. assertInitialized();
  3413. U32 mask;
  3414. BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID());
  3415. if (muted)
  3416. {
  3417. mask  = 1 << LLPipeline::RENDER_TYPE_AVATAR;
  3418. }
  3419. else
  3420. {
  3421. mask  = (1<<LLPipeline::RENDER_TYPE_VOLUME) |
  3422. (1<<LLPipeline::RENDER_TYPE_AVATAR) |
  3423. (1<<LLPipeline::RENDER_TYPE_BUMP) |
  3424. (1<<LLPipeline::RENDER_TYPE_GRASS) |
  3425. (1<<LLPipeline::RENDER_TYPE_SIMPLE) |
  3426. (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |
  3427. (1<<LLPipeline::RENDER_TYPE_ALPHA) | 
  3428. (1<<LLPipeline::RENDER_TYPE_INVISIBLE) |
  3429. (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) |
  3430. (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) |
  3431. (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) |
  3432. (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) |
  3433. (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) |
  3434. (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) |
  3435. (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) |
  3436. (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) |
  3437. (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY);
  3438. }
  3439. mask = mask & gPipeline.getRenderTypeMask();
  3440. U32 saved_mask = gPipeline.mRenderTypeMask;
  3441. gPipeline.mRenderTypeMask = mask;
  3442. S32 occlusion = sUseOcclusion;
  3443. sUseOcclusion = 0;
  3444. sReflectionRender = sRenderDeferred ? FALSE : TRUE;
  3445. sShadowRender = TRUE;
  3446. sImpostorRender = TRUE;
  3447. LLViewerCamera* viewer_camera = LLViewerCamera::getInstance();
  3448. markVisible(avatar->mDrawable, *viewer_camera);
  3449. LLVOAvatar::sUseImpostors = FALSE;
  3450. LLVOAvatar::attachment_map_t::iterator iter;
  3451. for (iter = avatar->mAttachmentPoints.begin();
  3452. iter != avatar->mAttachmentPoints.end();
  3453. ++iter)
  3454. {
  3455. LLViewerJointAttachment *attachment = iter->second;
  3456. for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
  3457.  attachment_iter != attachment->mAttachedObjects.end();
  3458.  ++attachment_iter)
  3459. {
  3460. if (LLViewerObject* attached_object = (*attachment_iter))
  3461. {
  3462. markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
  3463. }
  3464. }
  3465. }
  3466. stateSort(*LLViewerCamera::getInstance(), result);
  3467. const LLVector3* ext = avatar->mDrawable->getSpatialExtents();
  3468. LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
  3469. LLCamera camera = *viewer_camera;
  3470. camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis());
  3471. LLVector2 tdim;
  3472. LLVector3 half_height = (ext[1]-ext[0])*0.5f;
  3473. LLVector3 left = camera.getLeftAxis();
  3474. left *= left;
  3475. left.normalize();
  3476. LLVector3 up = camera.getUpAxis();
  3477. up *= up;
  3478. up.normalize();
  3479. tdim.mV[0] = fabsf(half_height * left);
  3480. tdim.mV[1] = fabsf(half_height * up);
  3481. glMatrixMode(GL_PROJECTION);
  3482. glPushMatrix();
  3483. //glh::matrix4f ortho = gl_ortho(-tdim.mV[0], tdim.mV[0], -tdim.mV[1], tdim.mV[1], 1.0, 256.0);
  3484. F32 distance = (pos-camera.getOrigin()).length();
  3485. F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG;
  3486. F32 aspect = tdim.mV[0]/tdim.mV[1]; //128.f/256.f;
  3487. glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f);
  3488. glh_set_current_projection(persp);
  3489. glLoadMatrixf(persp.m);
  3490. glMatrixMode(GL_MODELVIEW);
  3491. glPushMatrix();
  3492. glh::matrix4f mat;
  3493. camera.getOpenGLTransform(mat.m);
  3494. mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
  3495. glLoadMatrixf(mat.m);
  3496. glh_set_current_modelview(mat);
  3497. glClearColor(0.0f,0.0f,0.0f,0.0f);
  3498. gGL.setColorMask(true, true);
  3499. glStencilMask(0xFFFFFFFF);
  3500. glClearStencil(0);
  3501. // get the number of pixels per angle
  3502. F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView());
  3503. //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing)
  3504. U32 resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);
  3505. U32 resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512);
  3506. if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() ||
  3507. resY != avatar->mImpostor.getHeight())
  3508. {
  3509. avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,TRUE);
  3510. if (LLPipeline::sRenderDeferred)
  3511. {
  3512. addDeferredAttachments(avatar->mImpostor);
  3513. }
  3514. gGL.getTexUnit(0)->bind(&avatar->mImpostor);
  3515. gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
  3516. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  3517. }
  3518. LLGLEnable stencil(GL_STENCIL_TEST);
  3519. glStencilMask(0xFFFFFFFF);
  3520. glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
  3521. glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
  3522. {
  3523. LLGLEnable scissor(GL_SCISSOR_TEST);
  3524. glScissor(0, 0, resX, resY);
  3525. avatar->mImpostor.bindTarget();
  3526. avatar->mImpostor.clear();
  3527. }
  3528. if (LLPipeline::sRenderDeferred)
  3529. {
  3530. stop_glerror();
  3531. renderGeomDeferred(camera);
  3532. renderGeomPostDeferred(camera);
  3533. }
  3534. else
  3535. {
  3536. renderGeom(camera);
  3537. }
  3538. glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  3539. glStencilFunc(GL_EQUAL, 1, 0xFFFFFF);
  3540. { //create alpha mask based on stencil buffer (grey out if muted)
  3541. LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f;
  3542. LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f;
  3543. if (LLPipeline::sRenderDeferred)
  3544. {
  3545. GLuint buff = GL_COLOR_ATTACHMENT0_EXT;
  3546. glDrawBuffersARB(1, &buff);
  3547. }
  3548. LLGLEnable blend(muted ? 0 : GL_BLEND);
  3549. if (muted)
  3550. {
  3551. gGL.setColorMask(true, true);
  3552. }
  3553. else
  3554. {
  3555. gGL.setColorMask(false, true);
  3556. }
  3557. gGL.setSceneBlendType(LLRender::BT_ADD);
  3558. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  3559. LLGLDepthTest depth(GL_FALSE, GL_FALSE);
  3560. gGL.color4f(1,1,1,1);
  3561. gGL.color4ub(64,64,64,255);
  3562. gGL.begin(LLRender::QUADS);
  3563. gGL.vertex3fv((pos+left-up).mV);
  3564. gGL.vertex3fv((pos-left-up).mV);
  3565. gGL.vertex3fv((pos-left+up).mV);
  3566. gGL.vertex3fv((pos+left+up).mV);
  3567. gGL.end();
  3568. gGL.flush();
  3569. gGL.setSceneBlendType(LLRender::BT_ALPHA);
  3570. }
  3571. avatar->mImpostor.flush();
  3572. avatar->setImpostorDim(tdim);
  3573. LLVOAvatar::sUseImpostors = TRUE;
  3574. sUseOcclusion = occlusion;
  3575. sReflectionRender = FALSE;
  3576. sImpostorRender = FALSE;
  3577. sShadowRender = FALSE;
  3578. gPipeline.mRenderTypeMask = saved_mask;
  3579. glMatrixMode(GL_PROJECTION);
  3580. glPopMatrix();
  3581. glMatrixMode(GL_MODELVIEW);
  3582. glPopMatrix();
  3583. avatar->mNeedsImpostorUpdate = FALSE;
  3584. avatar->cacheImpostorValues();
  3585. LLVertexBuffer::unbind();
  3586. LLGLState::checkStates();
  3587. LLGLState::checkTextureChannels();
  3588. LLGLState::checkClientArrays();
  3589. }
  3590. BOOL LLPipeline::hasRenderBatches(const U32 type) const
  3591. {
  3592. return sCull->getRenderMapSize(type) > 0;
  3593. }
  3594. LLCullResult::drawinfo_list_t::iterator LLPipeline::beginRenderMap(U32 type)
  3595. {
  3596. return sCull->beginRenderMap(type);
  3597. }
  3598. LLCullResult::drawinfo_list_t::iterator LLPipeline::endRenderMap(U32 type)
  3599. {
  3600. return sCull->endRenderMap(type);
  3601. }
  3602. LLCullResult::sg_list_t::iterator LLPipeline::beginAlphaGroups()
  3603. {
  3604. return sCull->beginAlphaGroups();
  3605. }
  3606. LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups()
  3607. {
  3608. return sCull->endAlphaGroups();
  3609. }