aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/pipeline.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2009-04-30 13:04:20 -0500
committerJacek Antonelli2009-04-30 13:07:16 -0500
commitca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch)
tree8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/newview/pipeline.cpp
parentSecond Life viewer sources 1.22.11 (diff)
downloadmeta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.zip
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.gz
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.bz2
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.xz
Second Life viewer sources 1.23.0-RC
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/pipeline.cpp2414
1 files changed, 1801 insertions, 613 deletions
diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp
index 13d8d09..8dec9b9 100644
--- a/linden/indra/newview/pipeline.cpp
+++ b/linden/indra/newview/pipeline.cpp
@@ -17,7 +17,8 @@
17 * There are special exceptions to the terms and conditions of the GPL as 17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception 18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or 19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 * 22 *
22 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
@@ -138,21 +139,22 @@ LLPipeline gPipeline;
138const LLMatrix4* gGLLastMatrix = NULL; 139const LLMatrix4* gGLLastMatrix = NULL;
139 140
140//---------------------------------------- 141//----------------------------------------
141
142std::string gPoolNames[] = 142std::string gPoolNames[] =
143{ 143{
144 // Correspond to LLDrawpool enum render type 144 // Correspond to LLDrawpool enum render type
145 "NONE", 145 "NONE",
146 "POOL_SIMPLE", 146 "POOL_SIMPLE",
147 "POOL_TERRAIN", 147 "POOL_TERRAIN",
148 "POOL_BUMP",
148 "POOL_TREE", 149 "POOL_TREE",
149 "POOL_SKY", 150 "POOL_SKY",
150 "POOL_WL_SKY", 151 "POOL_WL_SKY",
151 "POOL_GROUND", 152 "POOL_GROUND",
152 "POOL_BUMP",
153 "POOL_INVISIBLE", 153 "POOL_INVISIBLE",
154 "POOL_AVATAR", 154 "POOL_AVATAR",
155 "POOL_WATER", 155 "POOL_WATER",
156 "POOL_GRASS",
157 "POOL_FULLBRIGHT",
156 "POOL_GLOW", 158 "POOL_GLOW",
157 "POOL_ALPHA", 159 "POOL_ALPHA",
158}; 160};
@@ -230,11 +232,14 @@ BOOL LLPipeline::sRenderParticleBeacons = FALSE;
230BOOL LLPipeline::sRenderSoundBeacons = FALSE; 232BOOL LLPipeline::sRenderSoundBeacons = FALSE;
231BOOL LLPipeline::sRenderBeacons = FALSE; 233BOOL LLPipeline::sRenderBeacons = FALSE;
232BOOL LLPipeline::sRenderHighlight = TRUE; 234BOOL LLPipeline::sRenderHighlight = TRUE;
235BOOL LLPipeline::sForceOldBakedUpload = FALSE;
233S32 LLPipeline::sUseOcclusion = 0; 236S32 LLPipeline::sUseOcclusion = 0;
237BOOL LLPipeline::sDelayVBUpdate = TRUE;
234BOOL LLPipeline::sFastAlpha = TRUE; 238BOOL LLPipeline::sFastAlpha = TRUE;
235BOOL LLPipeline::sDisableShaders = FALSE; 239BOOL LLPipeline::sDisableShaders = FALSE;
236BOOL LLPipeline::sRenderBump = TRUE; 240BOOL LLPipeline::sRenderBump = TRUE;
237BOOL LLPipeline::sUseFarClip = TRUE; 241BOOL LLPipeline::sUseFarClip = TRUE;
242BOOL LLPipeline::sShadowRender = FALSE;
238BOOL LLPipeline::sSkipUpdate = FALSE; 243BOOL LLPipeline::sSkipUpdate = FALSE;
239BOOL LLPipeline::sWaterReflections = FALSE; 244BOOL LLPipeline::sWaterReflections = FALSE;
240BOOL LLPipeline::sRenderGlow = FALSE; 245BOOL LLPipeline::sRenderGlow = FALSE;
@@ -245,6 +250,8 @@ BOOL LLPipeline::sTextureBindTest = FALSE;
245BOOL LLPipeline::sRenderFrameTest = FALSE; 250BOOL LLPipeline::sRenderFrameTest = FALSE;
246BOOL LLPipeline::sRenderAttachedLights = TRUE; 251BOOL LLPipeline::sRenderAttachedLights = TRUE;
247BOOL LLPipeline::sRenderAttachedParticles = TRUE; 252BOOL LLPipeline::sRenderAttachedParticles = TRUE;
253BOOL LLPipeline::sRenderDeferred = FALSE;
254S32 LLPipeline::sVisibleLightCount = 0;
248 255
249static LLCullResult* sCull = NULL; 256static LLCullResult* sCull = NULL;
250 257
@@ -260,6 +267,13 @@ static const U32 gl_cube_face[] =
260 267
261void validate_framebuffer_object(); 268void validate_framebuffer_object();
262 269
270void addDeferredAttachments(LLRenderTarget& target)
271{
272 target.addColorAttachment(GL_RGBA16F_ARB); //specular
273 target.addColorAttachment(GL_RGBA16F_ARB); //normal+z
274 target.addColorAttachment(GL_RGBA16F_ARB); //position
275}
276
263LLPipeline::LLPipeline() : 277LLPipeline::LLPipeline() :
264 mBackfaceCull(FALSE), 278 mBackfaceCull(FALSE),
265 mBatchCount(0), 279 mBatchCount(0),
@@ -275,9 +289,6 @@ LLPipeline::LLPipeline() :
275 mGeometryChanges(0), 289 mGeometryChanges(0),
276 mNumVisibleFaces(0), 290 mNumVisibleFaces(0),
277 291
278 mCubeBuffer(NULL),
279 mCubeFrameBuffer(0),
280 mCubeDepth(0),
281 mInitialized(FALSE), 292 mInitialized(FALSE),
282 mVertexShadersEnabled(FALSE), 293 mVertexShadersEnabled(FALSE),
283 mVertexShadersLoaded(0), 294 mVertexShadersLoaded(0),
@@ -292,6 +303,7 @@ LLPipeline::LLPipeline() :
292 mWaterPool(NULL), 303 mWaterPool(NULL),
293 mGroundPool(NULL), 304 mGroundPool(NULL),
294 mSimplePool(NULL), 305 mSimplePool(NULL),
306 mFullbrightPool(NULL),
295 mInvisiblePool(NULL), 307 mInvisiblePool(NULL),
296 mGlowPool(NULL), 308 mGlowPool(NULL),
297 mBumpPool(NULL), 309 mBumpPool(NULL),
@@ -300,8 +312,7 @@ LLPipeline::LLPipeline() :
300 mLightMovingMask(0), 312 mLightMovingMask(0),
301 mLightingDetail(0) 313 mLightingDetail(0)
302{ 314{
303 mBlurCubeBuffer[0] = mBlurCubeBuffer[1] = mBlurCubeBuffer[2] = 0; 315 mNoiseMap = 0;
304 mBlurCubeTexture[0] = mBlurCubeTexture[1] = mBlurCubeTexture[2] = 0;
305} 316}
306 317
307void LLPipeline::init() 318void LLPipeline::init()
@@ -320,6 +331,8 @@ void LLPipeline::init()
320 //create render pass pools 331 //create render pass pools
321 getPool(LLDrawPool::POOL_ALPHA); 332 getPool(LLDrawPool::POOL_ALPHA);
322 getPool(LLDrawPool::POOL_SIMPLE); 333 getPool(LLDrawPool::POOL_SIMPLE);
334 getPool(LLDrawPool::POOL_GRASS);
335 getPool(LLDrawPool::POOL_FULLBRIGHT);
323 getPool(LLDrawPool::POOL_INVISIBLE); 336 getPool(LLDrawPool::POOL_INVISIBLE);
324 getPool(LLDrawPool::POOL_BUMP); 337 getPool(LLDrawPool::POOL_BUMP);
325 getPool(LLDrawPool::POOL_GLOW); 338 getPool(LLDrawPool::POOL_GLOW);
@@ -404,6 +417,8 @@ void LLPipeline::cleanup()
404 mGroundPool = NULL; 417 mGroundPool = NULL;
405 delete mSimplePool; 418 delete mSimplePool;
406 mSimplePool = NULL; 419 mSimplePool = NULL;
420 delete mFullbrightPool;
421 mFullbrightPool = NULL;
407 delete mInvisiblePool; 422 delete mInvisiblePool;
408 mInvisiblePool = NULL; 423 mInvisiblePool = NULL;
409 delete mGlowPool; 424 delete mGlowPool;
@@ -455,52 +470,103 @@ void LLPipeline::resizeScreenTexture()
455 GLuint resY = gViewerWindow->getWindowDisplayHeight(); 470 GLuint resY = gViewerWindow->getWindowDisplayHeight();
456 471
457 U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); 472 U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
458 if (res_mod > 1) 473 if (res_mod > 1 && res_mod < resX && res_mod < resY)
459 { 474 {
460 resX /= res_mod; 475 resX /= res_mod;
461 resY /= res_mod; 476 resY /= res_mod;
462 } 477 }
463 478
464 mScreen.release(); 479 allocateScreenBuffer(resX,resY);
465 mScreen.allocate(resX, resY, GL_RGBA, TRUE, LLTexUnit::TT_RECT_TEXTURE);
466 480
467 llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl; 481 llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl;
468 } 482 }
469} 483}
470 484
471 485void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
472void LLPipeline::releaseGLBuffers()
473{ 486{
474 assertInitialized(); 487 U32 samples = gSavedSettings.getU32("RenderFSAASamples");
475 488 if (LLPipeline::sRenderDeferred)
476 if (mCubeBuffer)
477 { 489 {
478 mCubeBuffer = NULL; 490 //allocate deferred rendering color buffers
491 mDeferredScreen.allocate(resX, resY, GL_RGBA16F_ARB, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
492 addDeferredAttachments(mDeferredScreen);
493 mScreen.allocate(resX, resY, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
494
495 for (U32 i = 0; i < 2; i++)
496 {
497 mDeferredLight[i].allocate(resX, resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
498 }
479 } 499 }
480 500 else
481 if (mCubeFrameBuffer)
482 { 501 {
483 glDeleteFramebuffersEXT(1, &mCubeFrameBuffer); 502 mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
484 glDeleteRenderbuffersEXT(1, &mCubeDepth);
485 mCubeDepth = mCubeFrameBuffer = 0;
486 } 503 }
504
487 505
488 if (mBlurCubeBuffer[0]) 506 if (gGLManager.mHasFramebufferMultisample && samples > 1)
489 { 507 {
490 glDeleteFramebuffersEXT(3, mBlurCubeBuffer); 508 if (LLPipeline::sRenderDeferred)
491 mBlurCubeBuffer[0] = mBlurCubeBuffer[1] = mBlurCubeBuffer[2] = 0; 509 {
510 mSampleBuffer.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples);
511 addDeferredAttachments(mSampleBuffer);
512 mDeferredScreen.setSampleBuffer(&mSampleBuffer);
513 }
514 else
515 {
516 mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples);
517 }
518
519 mScreen.setSampleBuffer(&mSampleBuffer);
520 stop_glerror();
521 }
522 else if (LLPipeline::sRenderDeferred)
523 { //share depth buffer between deferred targets
524 mDeferredScreen.shareDepthBuffer(mScreen);
525 for (U32 i = 0; i < 2; i++)
526 {
527 mDeferredScreen.shareDepthBuffer(mDeferredLight[i]);
528 }
492 } 529 }
493 530
494 if (mBlurCubeTexture[0]) 531 gGL.getTexUnit(0)->disable();
532
533 stop_glerror();
534
535}
536
537//static
538void LLPipeline::updateRenderDeferred()
539{
540 BOOL deferred = (gSavedSettings.getBOOL("RenderDeferred") &&
541 LLRenderTarget::sUseFBO &&
542 gSavedSettings.getBOOL("VertexShaderEnable") &&
543 gSavedSettings.getBOOL("RenderAvatarVP") &&
544 gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE;
545
546 sRenderDeferred = deferred;
547}
548
549void LLPipeline::releaseGLBuffers()
550{
551 assertInitialized();
552
553 if (mNoiseMap)
495 { 554 {
496 glDeleteTextures(3, mBlurCubeTexture); 555 LLImageGL::deleteTextures(1, &mNoiseMap);
497 mBlurCubeTexture[0] = mBlurCubeTexture[1] = mBlurCubeTexture[2] = 0; 556 mNoiseMap = 0;
498 } 557 }
499 558
500 mWaterRef.release(); 559 mWaterRef.release();
501 mWaterDis.release(); 560 mWaterDis.release();
502 mScreen.release(); 561 mScreen.release();
503 562 mSampleBuffer.releaseSampleBuffer();
563 mDeferredScreen.release();
564
565
566 for (U32 i = 0; i < 4; i++)
567 {
568 mSunShadow[i].release();
569 }
504 for (U32 i = 0; i < 3; i++) 570 for (U32 i = 0; i < 3; i++)
505 { 571 {
506 mGlow[i].release(); 572 mGlow[i].release();
@@ -513,72 +579,17 @@ void LLPipeline::createGLBuffers()
513{ 579{
514 assertInitialized(); 580 assertInitialized();
515 581
582 updateRenderDeferred();
583
516 if (LLPipeline::sWaterReflections) 584 if (LLPipeline::sWaterReflections)
517 { //water reflection texture 585 { //water reflection texture
518 U32 res = (U32) gSavedSettings.getS32("RenderWaterRefResolution"); 586 U32 res = (U32) gSavedSettings.getS32("RenderWaterRefResolution");
519 587
520 mWaterRef.allocate(res,res,GL_RGBA,TRUE); 588 mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
521 mWaterDis.allocate(res,res,GL_RGBA,TRUE); 589 mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE);
522
523#if 0 //cube map buffers (keep for future work)
524 {
525 //reflection map generation buffers
526 if (mCubeFrameBuffer == 0)
527 {
528 glGenFramebuffersEXT(1, &mCubeFrameBuffer);
529 glGenRenderbuffersEXT(1, &mCubeDepth);
530
531 U32 res = REFLECTION_MAP_RES;
532
533 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mCubeDepth);
534
535 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT,res,res);
536
537 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
538 }
539
540 if (mCubeBuffer.isNull())
541 {
542 res = 128;
543 mCubeBuffer = new LLCubeMap();
544 mCubeBuffer->initGL();
545 mCubeBuffer->setReflection();
546
547 for (U32 i = 0; i < 6; i++)
548 {
549 glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL);
550 }
551 }
552
553 if (mBlurCubeBuffer[0] == 0)
554 {
555 glGenFramebuffersEXT(3, mBlurCubeBuffer);
556 }
557
558 if (mBlurCubeTexture[0] == 0)
559 {
560 glGenTextures(3, mBlurCubeTexture);
561 }
562
563 res = (U32) gSavedSettings.getS32("RenderReflectionRes");
564
565 for (U32 j = 0; j < 3; j++)
566 {
567 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, mBlurCubeTexture[j]);
568 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
569 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
570 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
571 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
572
573 for (U32 i = 0; i < 6; i++)
574 {
575 glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL);
576 }
577 }
578 }
579#endif
580 } 590 }
581 591
592
582 stop_glerror(); 593 stop_glerror();
583 594
584 if (LLPipeline::sRenderGlow) 595 if (LLPipeline::sRenderGlow)
@@ -588,14 +599,41 @@ void LLPipeline::createGLBuffers()
588 599
589 for (U32 i = 0; i < 3; i++) 600 for (U32 i = 0; i < 3; i++)
590 { 601 {
591 mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE); 602 mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
592 } 603 }
593 604 }
594 605
595 GLuint resX = gViewerWindow->getWindowDisplayWidth(); 606 GLuint resX = gViewerWindow->getWindowDisplayWidth();
596 GLuint resY = gViewerWindow->getWindowDisplayHeight(); 607 GLuint resY = gViewerWindow->getWindowDisplayHeight();
597 608
598 mScreen.allocate(resX, resY, GL_RGBA, TRUE, LLTexUnit::TT_RECT_TEXTURE); 609 allocateScreenBuffer(resX,resY);
610
611 if (sRenderDeferred)
612 {
613 mSunShadow[0].allocate(1024,1024, 0, TRUE, FALSE);
614 mSunShadow[1].allocate(1024,1024, 0, TRUE, FALSE);
615 mSunShadow[2].allocate(1024,1024, 0, TRUE, FALSE);
616 mSunShadow[3].allocate(1024,1024, 0, TRUE, FALSE);
617
618 if (!mNoiseMap)
619 {
620 const U32 noiseRes = 128;
621 LLVector3 noise[noiseRes*noiseRes];
622
623 F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f;
624 for (U32 i = 0; i < noiseRes*noiseRes; ++i)
625 {
626 noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f);
627 noise[i].normVec();
628 noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;
629 }
630
631 LLImageGL::generateTextures(1, &mNoiseMap);
632
633 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
634 LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise);
635 gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
636 }
599 } 637 }
600} 638}
601 639
@@ -608,7 +646,7 @@ void LLPipeline::restoreGL()
608 LLViewerShaderMgr::instance()->setShaders(); 646 LLViewerShaderMgr::instance()->setShaders();
609 } 647 }
610 648
611 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); 649 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
612 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 650 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
613 { 651 {
614 LLViewerRegion* region = *iter; 652 LLViewerRegion* region = *iter;
@@ -626,7 +664,8 @@ void LLPipeline::restoreGL()
626 664
627BOOL LLPipeline::canUseVertexShaders() 665BOOL LLPipeline::canUseVertexShaders()
628{ 666{
629 if (!gGLManager.mHasVertexShader || 667 if (sDisableShaders ||
668 !gGLManager.mHasVertexShader ||
630 !gGLManager.mHasFragmentShader || 669 !gGLManager.mHasFragmentShader ||
631 !LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") || 670 !LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") ||
632 (assertInitialized() && mVertexShadersLoaded != 1) ) 671 (assertInitialized() && mVertexShadersLoaded != 1) )
@@ -758,7 +797,7 @@ void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerImage*>& texture
758 } 797 }
759 798
760 LLOctreeDirtyTexture dirty(textures); 799 LLOctreeDirtyTexture dirty(textures);
761 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); 800 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
762 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 801 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
763 { 802 {
764 LLViewerRegion* region = *iter; 803 LLViewerRegion* region = *iter;
@@ -784,6 +823,14 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0)
784 poolp = mSimplePool; 823 poolp = mSimplePool;
785 break; 824 break;
786 825
826 case LLDrawPool::POOL_GRASS:
827 poolp = mGrassPool;
828 break;
829
830 case LLDrawPool::POOL_FULLBRIGHT:
831 poolp = mFullbrightPool;
832 break;
833
787 case LLDrawPool::POOL_INVISIBLE: 834 case LLDrawPool::POOL_INVISIBLE:
788 poolp = mInvisiblePool; 835 poolp = mInvisiblePool;
789 break; 836 break;
@@ -963,19 +1010,61 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
963 1010
964U32 LLPipeline::addObject(LLViewerObject *vobj) 1011U32 LLPipeline::addObject(LLViewerObject *vobj)
965{ 1012{
966 LLMemType mt(LLMemType::MTYPE_DRAWABLE);
967 if (gNoRender) 1013 if (gNoRender)
968 { 1014 {
969 return 0; 1015 return 0;
970 } 1016 }
971 1017
1018 if (gSavedSettings.getBOOL("RenderDelayCreation"))
1019 {
1020 mCreateQ.push_back(vobj);
1021 }
1022 else
1023 {
1024 createObject(vobj);
1025 }
1026
1027 return 1;
1028}
1029
1030void LLPipeline::createObjects(F32 max_dtime)
1031{
1032 LLFastTimer ftm(LLFastTimer::FTM_GEO_UPDATE);
1033 LLMemType mt(LLMemType::MTYPE_DRAWABLE);
1034
1035 LLTimer update_timer;
1036
1037 while (!mCreateQ.empty() && update_timer.getElapsedTimeF32() < max_dtime)
1038 {
1039 LLViewerObject* vobj = mCreateQ.front();
1040 if (!vobj->isDead())
1041 {
1042 createObject(vobj);
1043 }
1044 mCreateQ.pop_front();
1045 }
1046
1047 //for (LLViewerObject::vobj_list_t::iterator iter = mCreateQ.begin(); iter != mCreateQ.end(); ++iter)
1048 //{
1049 // createObject(*iter);
1050 //}
1051
1052 //mCreateQ.clear();
1053}
1054
1055void LLPipeline::createObject(LLViewerObject* vobj)
1056{
972 LLDrawable* drawablep = vobj->mDrawable; 1057 LLDrawable* drawablep = vobj->mDrawable;
973 1058
974 if (!drawablep) 1059 if (!drawablep)
975 { 1060 {
976 drawablep = vobj->createDrawable(this); 1061 drawablep = vobj->createDrawable(this);
977 } 1062 }
978 1063 else
1064 {
1065 llerrs << "Redundant drawable creation!" << llendl;
1066 }
1067
979 llassert(drawablep); 1068 llassert(drawablep);
980 1069
981 if (vobj->getParent()) 1070 if (vobj->getParent())
@@ -989,7 +1078,14 @@ U32 LLPipeline::addObject(LLViewerObject *vobj)
989 1078
990 markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE); 1079 markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE);
991 1080
992 return 1; 1081 if (drawablep->getVOVolume() && gSavedSettings.getBOOL("RenderAnimateRes"))
1082 {
1083 // fun animated res
1084 drawablep->updateXform(TRUE);
1085 drawablep->clearState(LLDrawable::MOVE_UNDAMPED);
1086 drawablep->setScale(LLVector3(0,0,0));
1087 drawablep->makeActive();
1088 }
993} 1089}
994 1090
995 1091
@@ -1149,7 +1245,7 @@ void LLPipeline::updateMove()
1149 { 1245 {
1150 LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE); 1246 LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE);
1151 1247
1152 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); 1248 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
1153 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 1249 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1154 { 1250 {
1155 LLViewerRegion* region = *iter; 1251 LLViewerRegion* region = *iter;
@@ -1194,6 +1290,65 @@ void LLPipeline::grabReferences(LLCullResult& result)
1194 sCull = &result; 1290 sCull = &result;
1195} 1291}
1196 1292
1293BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera)
1294{
1295 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
1296 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1297 {
1298 LLViewerRegion* region = *iter;
1299
1300 for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
1301 {
1302 LLSpatialPartition* part = region->getSpatialPartition(i);
1303 if (part)
1304 {
1305 if (hasRenderType(part->mDrawableType))
1306 {
1307 if (part->visibleObjectsInFrustum(camera))
1308 {
1309 return TRUE;
1310 }
1311 }
1312 }
1313 }
1314 }
1315
1316 return FALSE;
1317}
1318
1319BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& max)
1320{
1321 min = LLVector3(F32_MAX, F32_MAX, F32_MAX);
1322 max = LLVector3(-F32_MAX, -F32_MAX, -F32_MAX);
1323
1324
1325 BOOL res = TRUE;
1326
1327 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
1328 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1329 {
1330 LLViewerRegion* region = *iter;
1331
1332 for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
1333 {
1334 LLSpatialPartition* part = region->getSpatialPartition(i);
1335 if (part)
1336 {
1337 if (hasRenderType(part->mDrawableType))
1338 {
1339 if (!part->getVisibleExtents(camera, min, max))
1340 {
1341 res = FALSE;
1342 }
1343 }
1344 }
1345 }
1346 }
1347
1348 return res;
1349}
1350
1351
1197void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip) 1352void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip)
1198{ 1353{
1199 LLFastTimer t(LLFastTimer::FTM_CULL); 1354 LLFastTimer t(LLFastTimer::FTM_CULL);
@@ -1206,6 +1361,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
1206 BOOL to_texture = LLPipeline::sUseOcclusion > 1 && 1361 BOOL to_texture = LLPipeline::sUseOcclusion > 1 &&
1207 !hasRenderType(LLPipeline::RENDER_TYPE_HUD) && 1362 !hasRenderType(LLPipeline::RENDER_TYPE_HUD) &&
1208 !sReflectionRender && 1363 !sReflectionRender &&
1364 !sShadowRender &&
1209 gPipeline.canUseVertexShaders() && 1365 gPipeline.canUseVertexShaders() &&
1210 sRenderGlow; 1366 sRenderGlow;
1211 1367
@@ -1216,6 +1372,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
1216 1372
1217 glPushMatrix(); 1373 glPushMatrix();
1218 gGLLastMatrix = NULL; 1374 gGLLastMatrix = NULL;
1375 //glLoadMatrixd(gGLModelView);
1219 glLoadMatrixd(gGLLastModelView); 1376 glLoadMatrixd(gGLLastModelView);
1220 1377
1221 LLVertexBuffer::unbind(); 1378 LLVertexBuffer::unbind();
@@ -1223,10 +1380,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
1223 LLGLDisable test(GL_ALPHA_TEST); 1380 LLGLDisable test(GL_ALPHA_TEST);
1224 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); 1381 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
1225 1382
1226 gGL.setColorMask(false, false); 1383 if (sUseOcclusion > 1)
1384 {
1385 gGL.setColorMask(false, false);
1386 }
1387
1227 LLGLDepthTest depth(GL_TRUE, GL_FALSE); 1388 LLGLDepthTest depth(GL_TRUE, GL_FALSE);
1228 1389
1229 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); 1390 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
1230 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 1391 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1231 { 1392 {
1232 LLViewerRegion* region = *iter; 1393 LLViewerRegion* region = *iter;
@@ -1281,13 +1442,17 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
1281 sCull->pushDrawable(gSky.mVOGroundp->mDrawable); 1442 sCull->pushDrawable(gSky.mVOGroundp->mDrawable);
1282 } 1443 }
1283 1444
1284 gGL.setColorMask(true, false); 1445
1285 glPopMatrix(); 1446 glPopMatrix();
1286 1447
1448 if (sUseOcclusion > 1)
1449 {
1450 gGL.setColorMask(true, false);
1451 }
1452
1287 if (to_texture) 1453 if (to_texture)
1288 { 1454 {
1289 mScreen.flush(); 1455 mScreen.flush();
1290 LLRenderTarget::unbindTarget();
1291 } 1456 }
1292 else if (LLPipeline::sUseOcclusion > 1) 1457 else if (LLPipeline::sUseOcclusion > 1)
1293 { 1458 {
@@ -1356,6 +1521,7 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
1356void LLPipeline::doOcclusion(LLCamera& camera) 1521void LLPipeline::doOcclusion(LLCamera& camera)
1357{ 1522{
1358 LLVertexBuffer::unbind(); 1523 LLVertexBuffer::unbind();
1524
1359 if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) 1525 if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
1360 { 1526 {
1361 gGL.setColorMask(true, false, false, false); 1527 gGL.setColorMask(true, false, false, false);
@@ -1524,7 +1690,7 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion)
1524 1690
1525 if (!drawablep) 1691 if (!drawablep)
1526 { 1692 {
1527 llerrs << "Sending null drawable to moved list!" << llendl; 1693 //llerrs << "Sending null drawable to moved list!" << llendl;
1528 return; 1694 return;
1529 } 1695 }
1530 1696
@@ -1594,8 +1760,8 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
1594 assertInitialized(); 1760 assertInitialized();
1595 1761
1596 glClear(GL_DEPTH_BUFFER_BIT); 1762 glClear(GL_DEPTH_BUFFER_BIT);
1597 gDepthDirty = FALSE; 1763 gDepthDirty = TRUE;
1598 1764
1599 for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); 1765 for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
1600 iter != mShiftList.end(); iter++) 1766 iter != mShiftList.end(); iter++)
1601 { 1767 {
@@ -1609,7 +1775,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
1609 } 1775 }
1610 mShiftList.resize(0); 1776 mShiftList.resize(0);
1611 1777
1612 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); 1778 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
1613 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 1779 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1614 { 1780 {
1615 LLViewerRegion* region = *iter; 1781 LLViewerRegion* region = *iter;
@@ -1771,6 +1937,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
1771 stateSort(drawablep, camera); 1937 stateSort(drawablep, camera);
1772 } 1938 }
1773 } 1939 }
1940
1774} 1941}
1775 1942
1776void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) 1943void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera)
@@ -2044,6 +2211,22 @@ void LLPipeline::postSort(LLCamera& camera)
2044 } 2211 }
2045 LLSpatialGroup::sNoDelete = TRUE; 2212 LLSpatialGroup::sNoDelete = TRUE;
2046 2213
2214
2215 const S32 bin_count = 1024*8;
2216
2217 static LLCullResult::drawinfo_list_t alpha_bins[bin_count];
2218 static U32 bin_size[bin_count];
2219
2220 //clear one bin per frame to avoid memory bloat
2221 static S32 clear_idx = 0;
2222 clear_idx = (1+clear_idx)%bin_count;
2223 alpha_bins[clear_idx].clear();
2224
2225 for (U32 j = 0; j < bin_count; j++)
2226 {
2227 bin_size[j] = 0;
2228 }
2229
2047 //build render map 2230 //build render map
2048 for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) 2231 for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
2049 { 2232 {
@@ -2063,7 +2246,7 @@ void LLPipeline::postSort(LLCamera& camera)
2063 sCull->pushDrawInfo(j->first, *k); 2246 sCull->pushDrawInfo(j->first, *k);
2064 } 2247 }
2065 } 2248 }
2066 2249
2067 LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); 2250 LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA);
2068 2251
2069 if (alpha != group->mDrawMap.end()) 2252 if (alpha != group->mDrawMap.end())
@@ -2089,28 +2272,26 @@ void LLPipeline::postSort(LLCamera& camera)
2089 } 2272 }
2090 } 2273 }
2091 2274
2275 if (!sShadowRender)
2092 { 2276 {
2093 //sort by texture or bump map 2277 //sort by texture or bump map
2094 for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; ++i) 2278 for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; ++i)
2095 { 2279 {
2096 //if (!mRenderMap[i].empty()) 2280 if (i == LLRenderPass::PASS_BUMP)
2097 { 2281 {
2098 if (i == LLRenderPass::PASS_BUMP) 2282 std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareBump());
2099 {
2100 std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareBump());
2101 }
2102 else
2103 {
2104 std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareTexturePtrMatrix());
2105 }
2106 } 2283 }
2284 else
2285 {
2286 std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareTexturePtrMatrix());
2287 }
2107 } 2288 }
2108 2289
2109 std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater()); 2290 std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());
2110 } 2291 }
2111 2292
2112 // only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus 2293 // only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus
2113 if (gSavedSettings.getBOOL("BeaconAlwaysOn")) 2294 if (gSavedSettings.getBOOL("BeaconAlwaysOn") && !sShadowRender)
2114 { 2295 {
2115 if (sRenderScriptedTouchBeacons) 2296 if (sRenderScriptedTouchBeacons)
2116 { 2297 {
@@ -2163,23 +2344,26 @@ void LLPipeline::postSort(LLCamera& camera)
2163 LLFloaterTelehub::addBeacons(); 2344 LLFloaterTelehub::addBeacons();
2164 } 2345 }
2165 2346
2166 mSelectedFaces.clear(); 2347 if (!sShadowRender)
2167
2168 // Draw face highlights for selected faces.
2169 if (LLSelectMgr::getInstance()->getTEMode())
2170 { 2348 {
2171 struct f : public LLSelectedTEFunctor 2349 mSelectedFaces.clear();
2350
2351 // Draw face highlights for selected faces.
2352 if (LLSelectMgr::getInstance()->getTEMode())
2172 { 2353 {
2173 virtual bool apply(LLViewerObject* object, S32 te) 2354 struct f : public LLSelectedTEFunctor
2174 { 2355 {
2175 if (object->mDrawable) 2356 virtual bool apply(LLViewerObject* object, S32 te)
2176 { 2357 {
2177 gPipeline.mSelectedFaces.push_back(object->mDrawable->getFace(te)); 2358 if (object->mDrawable)
2359 {
2360 gPipeline.mSelectedFaces.push_back(object->mDrawable->getFace(te));
2361 }
2362 return true;
2178 } 2363 }
2179 return true; 2364 } func;
2180 } 2365 LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func);
2181 } func; 2366 }
2182 LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func);
2183 } 2367 }
2184 2368
2185 LLSpatialGroup::sNoDelete = FALSE; 2369 LLSpatialGroup::sNoDelete = FALSE;
@@ -2327,8 +2511,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2327 stop_glerror(); 2511 stop_glerror();
2328 gFrameStats.start(LLFrameStats::RENDER_SYNC); 2512 gFrameStats.start(LLFrameStats::RENDER_SYNC);
2329 2513
2330 glEnableClientState(GL_VERTEX_ARRAY);
2331
2332 LLVertexBuffer::unbind(); 2514 LLVertexBuffer::unbind();
2333 2515
2334 // Do verification of GL state 2516 // Do verification of GL state
@@ -2378,7 +2560,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2378 } 2560 }
2379 2561
2380 gGL.getTexUnit(0)->bind(LLViewerImage::sDefaultImagep); 2562 gGL.getTexUnit(0)->bind(LLViewerImage::sDefaultImagep);
2381 LLViewerImage::sDefaultImagep->setClamp(FALSE, FALSE); 2563 LLViewerImage::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP);
2382 2564
2383 ////////////////////////////////////////////// 2565 //////////////////////////////////////////////
2384 // 2566 //
@@ -2386,37 +2568,39 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2386 // 2568 //
2387 // 2569 //
2388 stop_glerror(); 2570 stop_glerror();
2389 BOOL occlude = sUseOcclusion > 1;
2390 2571
2391 U32 cur_type = 0;
2392
2393 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools"); 2572 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools");
2394 2573
2395 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING))
2396 {
2397 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderForSelect"); 2574 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderForSelect");
2398 gObjectList.renderObjectsForSelect(camera, gViewerWindow->getVirtualWindowRect()); 2575 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDeferred");
2576 for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
2577 {
2578 LLDrawPool *poolp = *iter;
2579 if (hasRenderType(poolp->getType()))
2580 {
2581 poolp->prerender();
2582 }
2399 } 2583 }
2400 else if (gSavedSettings.getBOOL("RenderDeferred")) 2584
2585 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING))
2401 { 2586 {
2402 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDeferred"); 2587 gObjectList.renderObjectsForSelect(camera, gViewerWindow->getVirtualWindowRect());
2403 renderGeomDeferred();
2404 } 2588 }
2405 else 2589 else
2406 { 2590 {
2407 for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) 2591 LLFastTimer t(LLFastTimer::FTM_POOLS);
2592
2593 // HACK: don't calculate local lights if we're rendering the HUD!
2594 // Removing this check will cause bad flickering when there are
2595 // HUD elements being rendered AND the user is in flycam mode -nyx
2596 if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
2408 { 2597 {
2409 LLDrawPool *poolp = *iter; 2598 calcNearbyLights(camera);
2410 if (hasRenderType(poolp->getType())) 2599 setupHWLights(NULL);
2411 {
2412 poolp->prerender();
2413 }
2414 } 2600 }
2415 2601
2416 2602 BOOL occlude = sUseOcclusion > 1;
2417 LLFastTimer t(LLFastTimer::FTM_POOLS); 2603 U32 cur_type = 0;
2418 calcNearbyLights(camera);
2419 setupHWLights(NULL);
2420 2604
2421 pool_set_t::iterator iter1 = mPools.begin(); 2605 pool_set_t::iterator iter1 = mPools.begin();
2422 while ( iter1 != mPools.end() ) 2606 while ( iter1 != mPools.end() )
@@ -2425,7 +2609,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2425 2609
2426 cur_type = poolp->getType(); 2610 cur_type = poolp->getType();
2427 2611
2428 if (occlude && cur_type > LLDrawPool::POOL_AVATAR) 2612 if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
2429 { 2613 {
2430 occlude = FALSE; 2614 occlude = FALSE;
2431 gGLLastMatrix = NULL; 2615 gGLLastMatrix = NULL;
@@ -2443,6 +2627,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2443 2627
2444 for( S32 i = 0; i < poolp->getNumPasses(); i++ ) 2628 for( S32 i = 0; i < poolp->getNumPasses(); i++ )
2445 { 2629 {
2630 LLVertexBuffer::unbind();
2446 poolp->beginRenderPass(i); 2631 poolp->beginRenderPass(i);
2447 for (iter2 = iter1; iter2 != mPools.end(); iter2++) 2632 for (iter2 = iter1; iter2 != mPools.end(); iter2++)
2448 { 2633 {
@@ -2486,25 +2671,29 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2486 iter1 = iter2; 2671 iter1 = iter2;
2487 stop_glerror(); 2672 stop_glerror();
2488 } 2673 }
2489 }
2490 2674
2491 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd"); 2675 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd");
2492 2676
2493 LLVertexBuffer::unbind(); 2677 LLVertexBuffer::unbind();
2678
2679 gGLLastMatrix = NULL;
2680 glLoadMatrixd(gGLModelView);
2681
2682 if (occlude)
2683 {
2684 occlude = FALSE;
2685 gGLLastMatrix = NULL;
2686 glLoadMatrixd(gGLModelView);
2687 doOcclusion(camera);
2688 }
2689 }
2690
2691 LLVertexBuffer::unbind();
2494 LLGLState::checkStates(); 2692 LLGLState::checkStates();
2495 LLGLState::checkTextureChannels(); 2693 LLGLState::checkTextureChannels();
2496 LLGLState::checkClientArrays(); 2694 LLGLState::checkClientArrays();
2497 2695
2498 gGLLastMatrix = NULL; 2696
2499 glLoadMatrixd(gGLModelView);
2500
2501 if (occlude)
2502 {
2503 occlude = FALSE;
2504 gGLLastMatrix = NULL;
2505 glLoadMatrixd(gGLModelView);
2506 doOcclusion(camera);
2507 }
2508 2697
2509 stop_glerror(); 2698 stop_glerror();
2510 2699
@@ -2529,7 +2718,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2529 2718
2530 LLVertexBuffer::unbind(); 2719 LLVertexBuffer::unbind();
2531 2720
2532 if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) 2721 if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
2533 { 2722 {
2534 // Render debugging beacons. 2723 // Render debugging beacons.
2535 gObjectList.renderObjectBeacons(); 2724 gObjectList.renderObjectBeacons();
@@ -2556,13 +2745,283 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2556 LLGLState::checkClientArrays(); 2745 LLGLState::checkClientArrays();
2557} 2746}
2558 2747
2559void LLPipeline::renderGeomDeferred() 2748void LLPipeline::renderGeomDeferred(LLCamera& camera)
2749{
2750 LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY);
2751
2752 LLFastTimer t2(LLFastTimer::FTM_POOLS);
2753
2754 LLGLEnable cull(GL_CULL_FACE);
2755
2756 LLGLEnable stencil(GL_STENCIL_TEST);
2757 glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
2758 stop_glerror();
2759 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
2760 stop_glerror();
2761
2762 for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
2763 {
2764 LLDrawPool *poolp = *iter;
2765 if (hasRenderType(poolp->getType()))
2766 {
2767 poolp->prerender();
2768 }
2769 }
2770
2771 LLGLEnable multisample(GL_MULTISAMPLE_ARB);
2772
2773 LLVertexBuffer::unbind();
2774
2775 LLGLState::checkStates();
2776 LLGLState::checkTextureChannels();
2777 LLGLState::checkClientArrays();
2778
2779 U32 cur_type = 0;
2780
2781 gGL.setColorMask(true, true);
2782
2783 pool_set_t::iterator iter1 = mPools.begin();
2784
2785 while ( iter1 != mPools.end() )
2786 {
2787 LLDrawPool *poolp = *iter1;
2788
2789 cur_type = poolp->getType();
2790
2791 pool_set_t::iterator iter2 = iter1;
2792 if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
2793 {
2794 LLFastTimer t(LLFastTimer::FTM_POOLRENDER);
2795
2796 gGLLastMatrix = NULL;
2797 glLoadMatrixd(gGLModelView);
2798
2799 for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ )
2800 {
2801 LLVertexBuffer::unbind();
2802 poolp->beginDeferredPass(i);
2803 for (iter2 = iter1; iter2 != mPools.end(); iter2++)
2804 {
2805 LLDrawPool *p = *iter2;
2806 if (p->getType() != cur_type)
2807 {
2808 break;
2809 }
2810
2811 p->renderDeferred(i);
2812 }
2813 poolp->endDeferredPass(i);
2814 LLVertexBuffer::unbind();
2815
2816 GLint depth;
2817 glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
2818 if (depth > 3)
2819 {
2820 llerrs << "GL matrix stack corrupted!" << llendl;
2821 }
2822 LLGLState::checkStates();
2823 LLGLState::checkTextureChannels();
2824 LLGLState::checkClientArrays();
2825 }
2826 }
2827 else
2828 {
2829 // Skip all pools of this type
2830 for (iter2 = iter1; iter2 != mPools.end(); iter2++)
2831 {
2832 LLDrawPool *p = *iter2;
2833 if (p->getType() != cur_type)
2834 {
2835 break;
2836 }
2837 }
2838 }
2839 iter1 = iter2;
2840 stop_glerror();
2841 }
2842
2843 gGLLastMatrix = NULL;
2844 glLoadMatrixd(gGLModelView);
2845
2846 gGL.setColorMask(true, false);
2847}
2848
2849void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
2560{ 2850{
2561 gDeferredDiffuseProgram.bind(); 2851 LLFastTimer t(LLFastTimer::FTM_POOLS);
2562 gPipeline.renderObjects(LLRenderPass::PASS_SIMPLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL, TRUE); 2852 U32 cur_type = 0;
2563 gDeferredDiffuseProgram.unbind(); 2853
2854 LLGLEnable cull(GL_CULL_FACE);
2855
2856 LLGLEnable multisample(GL_MULTISAMPLE_ARB);
2857
2858 calcNearbyLights(camera);
2859 setupHWLights(NULL);
2860
2861 gGL.setColorMask(true, false);
2862
2863 pool_set_t::iterator iter1 = mPools.begin();
2864 BOOL occlude = LLPipeline::sUseOcclusion > 1;
2865
2866 while ( iter1 != mPools.end() )
2867 {
2868 LLDrawPool *poolp = *iter1;
2869
2870 cur_type = poolp->getType();
2871
2872 if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
2873 {
2874 occlude = FALSE;
2875 gGLLastMatrix = NULL;
2876 glLoadMatrixd(gGLModelView);
2877 doOcclusion(camera);
2878 gGL.setColorMask(true, false);
2879 }
2880
2881 pool_set_t::iterator iter2 = iter1;
2882 if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
2883 {
2884 LLFastTimer t(LLFastTimer::FTM_POOLRENDER);
2885
2886 gGLLastMatrix = NULL;
2887 glLoadMatrixd(gGLModelView);
2888
2889 for( S32 i = 0; i < poolp->getNumPostDeferredPasses(); i++ )
2890 {
2891 LLVertexBuffer::unbind();
2892 poolp->beginPostDeferredPass(i);
2893 for (iter2 = iter1; iter2 != mPools.end(); iter2++)
2894 {
2895 LLDrawPool *p = *iter2;
2896 if (p->getType() != cur_type)
2897 {
2898 break;
2899 }
2900
2901 p->renderPostDeferred(i);
2902 }
2903 poolp->endPostDeferredPass(i);
2904 LLVertexBuffer::unbind();
2905
2906 GLint depth;
2907 glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
2908 if (depth > 3)
2909 {
2910 llerrs << "GL matrix stack corrupted!" << llendl;
2911 }
2912 LLGLState::checkStates();
2913 LLGLState::checkTextureChannels();
2914 LLGLState::checkClientArrays();
2915 }
2916 }
2917 else
2918 {
2919 // Skip all pools of this type
2920 for (iter2 = iter1; iter2 != mPools.end(); iter2++)
2921 {
2922 LLDrawPool *p = *iter2;
2923 if (p->getType() != cur_type)
2924 {
2925 break;
2926 }
2927 }
2928 }
2929 iter1 = iter2;
2930 stop_glerror();
2931 }
2932
2933 gGLLastMatrix = NULL;
2934 glLoadMatrixd(gGLModelView);
2935
2936 renderHighlights();
2937 mHighlightFaces.clear();
2938
2939 renderDebug();
2940
2941 LLVertexBuffer::unbind();
2942
2943 if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
2944 {
2945 // Render debugging beacons.
2946 gObjectList.renderObjectBeacons();
2947 LLHUDObject::renderAll();
2948 gObjectList.resetObjectBeacons();
2949 }
2950
2951 if (occlude)
2952 {
2953 occlude = FALSE;
2954 gGLLastMatrix = NULL;
2955 glLoadMatrixd(gGLModelView);
2956 doOcclusion(camera);
2957 }
2564} 2958}
2565 2959
2960void LLPipeline::renderGeomShadow(LLCamera& camera)
2961{
2962 U32 cur_type = 0;
2963
2964 LLGLEnable cull(GL_CULL_FACE);
2965
2966 LLVertexBuffer::unbind();
2967
2968 pool_set_t::iterator iter1 = mPools.begin();
2969
2970 while ( iter1 != mPools.end() )
2971 {
2972 LLDrawPool *poolp = *iter1;
2973
2974 cur_type = poolp->getType();
2975
2976 pool_set_t::iterator iter2 = iter1;
2977 if (hasRenderType(poolp->getType()) && poolp->getNumShadowPasses() > 0)
2978 {
2979 gGLLastMatrix = NULL;
2980 glLoadMatrixd(gGLModelView);
2981
2982 for( S32 i = 0; i < poolp->getNumShadowPasses(); i++ )
2983 {
2984 LLVertexBuffer::unbind();
2985 poolp->beginShadowPass(i);
2986 for (iter2 = iter1; iter2 != mPools.end(); iter2++)
2987 {
2988 LLDrawPool *p = *iter2;
2989 if (p->getType() != cur_type)
2990 {
2991 break;
2992 }
2993
2994 p->renderShadow(i);
2995 }
2996 poolp->endShadowPass(i);
2997 LLVertexBuffer::unbind();
2998
2999 LLGLState::checkStates();
3000 LLGLState::checkTextureChannels();
3001 LLGLState::checkClientArrays();
3002 }
3003 }
3004 else
3005 {
3006 // Skip all pools of this type
3007 for (iter2 = iter1; iter2 != mPools.end(); iter2++)
3008 {
3009 LLDrawPool *p = *iter2;
3010 if (p->getType() != cur_type)
3011 {
3012 break;
3013 }
3014 }
3015 }
3016 iter1 = iter2;
3017 stop_glerror();
3018 }
3019
3020 gGLLastMatrix = NULL;
3021 glLoadMatrixd(gGLModelView);
3022}
3023
3024
2566void LLPipeline::addTrianglesDrawn(S32 count) 3025void LLPipeline::addTrianglesDrawn(S32 count)
2567{ 3026{
2568 assertInitialized(); 3027 assertInitialized();
@@ -2591,7 +3050,7 @@ void LLPipeline::renderDebug()
2591 gGL.setColorMask(true, false); 3050 gGL.setColorMask(true, false);
2592 3051
2593 // Debug stuff. 3052 // Debug stuff.
2594 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); 3053 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
2595 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 3054 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
2596 { 3055 {
2597 LLViewerRegion* region = *iter; 3056 LLViewerRegion* region = *iter;
@@ -2608,7 +3067,7 @@ void LLPipeline::renderDebug()
2608 } 3067 }
2609 } 3068 }
2610 3069
2611 for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) 3070 for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
2612 { 3071 {
2613 LLSpatialBridge* bridge = *i; 3072 LLSpatialBridge* bridge = *i;
2614 if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType)) 3073 if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType))
@@ -2620,6 +3079,99 @@ void LLPipeline::renderDebug()
2620 } 3079 }
2621 } 3080 }
2622 3081
3082 if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
3083 {
3084 gGL.color4f(1,1,1,1);
3085 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
3086
3087 F32 col[] =
3088 {
3089 1,1,0,
3090 0,1,1,
3091 1,0,1,
3092 1,1,1,
3093 1,0,0,
3094 0,1,0,
3095 0,0,1,
3096 0,0,0
3097 };
3098
3099 for (U32 i = 0; i < 8; i++)
3100 {
3101 gGL.color3fv(col+i*3);
3102
3103 gGL.begin(LLRender::LINES);
3104
3105 LLVector3* frust = mShadowCamera[i].mAgentFrustum;
3106
3107 gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV);
3108 gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV);
3109 gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV);
3110 gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV);
3111
3112 gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV);
3113 gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV);
3114 gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV);
3115 gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV);
3116
3117 gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV);
3118 gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV);
3119 gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV);
3120 gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV);
3121
3122 if (i < 4)
3123 {
3124 LLVector3* ext = mShadowExtents[i];
3125
3126 LLVector3 box[] =
3127 {
3128 LLVector3(ext[0][0], ext[0][1], ext[0][2]),
3129 LLVector3(ext[1][0], ext[0][1], ext[0][2]),
3130 LLVector3(ext[1][0], ext[1][1], ext[0][2]),
3131 LLVector3(ext[0][0], ext[1][1], ext[0][2]),
3132 LLVector3(ext[0][0], ext[0][1], ext[1][2]),
3133 LLVector3(ext[1][0], ext[0][1], ext[1][2]),
3134 LLVector3(ext[1][0], ext[1][1], ext[1][2]),
3135 LLVector3(ext[0][0], ext[1][1], ext[1][2]),
3136 };
3137
3138 gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[1].mV);
3139 gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[2].mV);
3140 gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[3].mV);
3141 gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[0].mV);
3142
3143 gGL.vertex3fv(box[4].mV); gGL.vertex3fv(box[5].mV);
3144 gGL.vertex3fv(box[5].mV); gGL.vertex3fv(box[6].mV);
3145 gGL.vertex3fv(box[6].mV); gGL.vertex3fv(box[7].mV);
3146 gGL.vertex3fv(box[7].mV); gGL.vertex3fv(box[4].mV);
3147
3148 gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[4].mV);
3149 gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[5].mV);
3150 gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[6].mV);
3151 gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[7].mV);
3152 }
3153
3154 gGL.end();
3155
3156 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
3157 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
3158 {
3159 LLViewerRegion* region = *iter;
3160 for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++)
3161 {
3162 LLSpatialPartition* part = region->getSpatialPartition(j);
3163 if (part)
3164 {
3165 if (hasRenderType(part->mDrawableType))
3166 {
3167 part->renderIntersectingBBoxes(&mShadowCamera[i]);
3168 }
3169 }
3170 }
3171 }
3172 }
3173 }
3174
2623 if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) 3175 if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION)
2624 { 3176 {
2625 // Debug composition layers 3177 // Debug composition layers
@@ -2652,6 +3204,7 @@ void LLPipeline::renderDebug()
2652 gGL.end(); 3204 gGL.end();
2653 } 3205 }
2654 } 3206 }
3207
2655 gGL.flush(); 3208 gGL.flush();
2656} 3209}
2657 3210
@@ -2734,7 +3287,7 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects, BOOL render
2734 gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA); 3287 gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);
2735 3288
2736 U32 prim_mask = LLVertexBuffer::MAP_VERTEX | 3289 U32 prim_mask = LLVertexBuffer::MAP_VERTEX |
2737 LLVertexBuffer::MAP_TEXCOORD; 3290 LLVertexBuffer::MAP_TEXCOORD0;
2738 3291
2739 for (std::set<LLViewerObject*>::iterator i = objects.begin(); i != objects.end(); ++i) 3292 for (std::set<LLViewerObject*>::iterator i = objects.begin(); i != objects.end(); ++i)
2740 { 3293 {
@@ -2890,6 +3443,30 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
2890 } 3443 }
2891 break; 3444 break;
2892 3445
3446 case LLDrawPool::POOL_GRASS:
3447 if (mGrassPool)
3448 {
3449 llassert(0);
3450 llwarns << "Ignoring duplicate grass pool." << llendl;
3451 }
3452 else
3453 {
3454 mGrassPool = (LLRenderPass*) new_poolp;
3455 }
3456 break;
3457
3458 case LLDrawPool::POOL_FULLBRIGHT:
3459 if (mFullbrightPool)
3460 {
3461 llassert(0);
3462 llwarns << "Ignoring duplicate simple pool." << llendl;
3463 }
3464 else
3465 {
3466 mFullbrightPool = (LLRenderPass*) new_poolp;
3467 }
3468 break;
3469
2893 case LLDrawPool::POOL_INVISIBLE: 3470 case LLDrawPool::POOL_INVISIBLE:
2894 if (mInvisiblePool) 3471 if (mInvisiblePool)
2895 { 3472 {
@@ -3023,6 +3600,16 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
3023 mSimplePool = NULL; 3600 mSimplePool = NULL;
3024 break; 3601 break;
3025 3602
3603 case LLDrawPool::POOL_GRASS:
3604 llassert(mGrassPool == poolp);
3605 mGrassPool = NULL;
3606 break;
3607
3608 case LLDrawPool::POOL_FULLBRIGHT:
3609 llassert(mFullbrightPool == poolp);
3610 mFullbrightPool = NULL;
3611 break;
3612
3026 case LLDrawPool::POOL_INVISIBLE: 3613 case LLDrawPool::POOL_INVISIBLE:
3027 llassert(mInvisiblePool == poolp); 3614 llassert(mInvisiblePool == poolp);
3028 mInvisiblePool = NULL; 3615 mInvisiblePool = NULL;
@@ -3116,7 +3703,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
3116 3703
3117 if (for_edit) 3704 if (for_edit)
3118 { 3705 {
3119 LLColor4 diffuse(0.8f, 0.8f, 0.8f, 0.f); 3706 LLColor4 diffuse(1.f, 1.f, 1.f, 0.f);
3120 LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light 3707 LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light
3121 LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); 3708 LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
3122 LLMatrix4 camera_rot(camera_mat.getMat3()); 3709 LLMatrix4 camera_rot(camera_mat.getMat3());
@@ -3287,6 +3874,10 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
3287 { 3874 {
3288 continue; 3875 continue;
3289 } 3876 }
3877 if (!sRenderAttachedLights && light && light->isAttachment())
3878 {
3879 continue;
3880 }
3290 new_nearby_lights.insert(Light(drawable, dist, 0.f)); 3881 new_nearby_lights.insert(Light(drawable, dist, 0.f));
3291 if (new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS) 3882 if (new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS)
3292 { 3883 {
@@ -4037,7 +4628,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
4037 4628
4038 sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE; 4629 sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE;
4039 4630
4040 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); 4631 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
4041 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 4632 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
4042 { 4633 {
4043 LLViewerRegion* region = *iter; 4634 LLViewerRegion* region = *iter;
@@ -4094,7 +4685,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
4094 4685
4095 //check against avatars 4686 //check against avatars
4096 sPickAvatar = TRUE; 4687 sPickAvatar = TRUE;
4097 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); 4688 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
4098 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 4689 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
4099 { 4690 {
4100 LLViewerRegion* region = *iter; 4691 LLViewerRegion* region = *iter;
@@ -4171,7 +4762,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co
4171{ 4762{
4172 LLDrawable* drawable = NULL; 4763 LLDrawable* drawable = NULL;
4173 4764
4174 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); 4765 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
4175 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 4766 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
4176 { 4767 {
4177 LLViewerRegion* region = *iter; 4768 LLViewerRegion* region = *iter;
@@ -4234,7 +4825,7 @@ void LLPipeline::resetVertexBuffers()
4234{ 4825{
4235 sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); 4826 sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
4236 4827
4237 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); 4828 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
4238 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 4829 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
4239 { 4830 {
4240 LLViewerRegion* region = *iter; 4831 LLViewerRegion* region = *iter;
@@ -4281,11 +4872,11 @@ void LLPipeline::resetVertexBuffers()
4281void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture) 4872void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture)
4282{ 4873{
4283 assertInitialized(); 4874 assertInitialized();
4875 glLoadMatrixd(gGLModelView);
4284 gGLLastMatrix = NULL; 4876 gGLLastMatrix = NULL;
4285 glLoadMatrixd(gGLLastModelView); 4877 mSimplePool->pushBatches(type, mask);
4286 mSimplePool->renderGroups(type, mask, texture); 4878 glLoadMatrixd(gGLModelView);
4287 gGLLastMatrix = NULL; 4879 gGLLastMatrix = NULL;
4288 glLoadMatrixd(gGLLastModelView);
4289} 4880}
4290 4881
4291void LLPipeline::setUseVBO(BOOL use_vbo) 4882void LLPipeline::setUseVBO(BOOL use_vbo)
@@ -4333,191 +4924,6 @@ void apply_cube_face_rotation(U32 face)
4333 break; 4924 break;
4334 } 4925 }
4335} 4926}
4336void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam)
4337{
4338 LLGLState::checkStates();
4339 LLGLState::checkTextureChannels();
4340 LLGLState::checkClientArrays();
4341
4342 assertInitialized();
4343
4344 //render dynamic cube map
4345 U32 type_mask = gPipeline.getRenderTypeMask();
4346 S32 use_occlusion = LLPipeline::sUseOcclusion;
4347 LLPipeline::sUseOcclusion = 0;
4348 LLPipeline::sSkipUpdate = TRUE;
4349 U32 res = REFLECTION_MAP_RES;
4350
4351 LLPipeline::sReflectionRender = TRUE;
4352
4353 gGL.getTexUnit(cube_map->getStage())->bind(cube_map);
4354 gGL.getTexUnit(0)->activate();
4355 GLint width;
4356 glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_TEXTURE_WIDTH, &width);
4357 if (width != res)
4358 {
4359 cube_map->setReflection();
4360
4361 for (U32 i = 0; i < 6; i++)
4362 {
4363 glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL);
4364 }
4365 }
4366 gGL.getTexUnit(cube_map->getStage())->unbind(LLTexUnit::TT_CUBE_MAP);
4367 gGL.getTexUnit(cube_map->getStage())->disable();
4368 gGL.getTexUnit(0)->activate();
4369 gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
4370
4371 BOOL toggle_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
4372 if (toggle_ui)
4373 {
4374 gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
4375 }
4376
4377 U32 cube_mask = (1 << LLPipeline::RENDER_TYPE_SIMPLE) |
4378 (1 << LLPipeline::RENDER_TYPE_WATER) |
4379 //(1 << LLPipeline::RENDER_TYPE_BUMP) |
4380 (1 << LLPipeline::RENDER_TYPE_ALPHA) |
4381 (1 << LLPipeline::RENDER_TYPE_TREE) |
4382 //(1 << LLPipeline::RENDER_TYPE_PARTICLES) |
4383 (1 << LLPipeline::RENDER_TYPE_CLOUDS) |
4384 //(1 << LLPipeline::RENDER_TYPE_STARS) |
4385 //(1 << LLPipeline::RENDER_TYPE_AVATAR) |
4386 (1 << LLPipeline::RENDER_TYPE_GLOW) |
4387 (1 << LLPipeline::RENDER_TYPE_GRASS) |
4388 (1 << LLPipeline::RENDER_TYPE_VOLUME) |
4389 (1 << LLPipeline::RENDER_TYPE_TERRAIN) |
4390 (1 << LLPipeline::RENDER_TYPE_SKY) |
4391 (1 << LLPipeline::RENDER_TYPE_WL_SKY) |
4392 (1 << LLPipeline::RENDER_TYPE_GROUND);
4393
4394 LLDrawPoolWater::sSkipScreenCopy = TRUE;
4395 LLPipeline::sSkipUpdate = TRUE;
4396 cube_mask = cube_mask & type_mask;
4397 gPipeline.setRenderTypeMask(cube_mask);
4398
4399 glMatrixMode(GL_PROJECTION);
4400 glPushMatrix();
4401 glMatrixMode(GL_MODELVIEW);
4402 glPushMatrix();
4403
4404 glViewport(0,0,res,res);
4405
4406 glClearColor(0,0,0,0);
4407
4408 LLVector3 origin = cube_cam.getOrigin();
4409
4410 gPipeline.calcNearbyLights(cube_cam);
4411
4412 stop_glerror();
4413 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
4414 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer);
4415 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
4416 GL_RENDERBUFFER_EXT, mCubeDepth);
4417 stop_glerror();
4418
4419 for (S32 i = 0; i < 6; i++)
4420 {
4421 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer);
4422 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
4423 gl_cube_face[i], cube_map->getGLName(), 0);
4424 validate_framebuffer_object();
4425 glMatrixMode(GL_PROJECTION);
4426 glLoadIdentity();
4427 gluPerspective(90.f, 1.f, 0.1f, 1024.f);
4428 glMatrixMode(GL_MODELVIEW);
4429 glLoadIdentity();
4430
4431 apply_cube_face_rotation(i);
4432
4433 glTranslatef(-origin.mV[0], -origin.mV[1], -origin.mV[2]);
4434 cube_cam.setOrigin(origin);
4435 LLViewerCamera::updateFrustumPlanes(cube_cam);
4436 cube_cam.setOrigin(LLViewerCamera::getInstance()->getOrigin());
4437 static LLCullResult result;
4438 gPipeline.updateCull(cube_cam, result);
4439 gPipeline.stateSort(cube_cam, result);
4440
4441 glClearColor(0,0,0,0);
4442 gGL.setColorMask(true, true);
4443 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
4444 gGL.setColorMask(true, false);
4445 stop_glerror();
4446 gPipeline.renderGeom(cube_cam);
4447 }
4448
4449 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
4450
4451 cube_cam.setOrigin(origin);
4452 gShinyOrigin.setVec(cube_cam.getOrigin(), cube_cam.getFar()*2.f);
4453 glMatrixMode(GL_PROJECTION);
4454 glPopMatrix();
4455 glMatrixMode(GL_MODELVIEW);
4456 glPopMatrix();
4457
4458 gViewerWindow->setupViewport();
4459
4460 gPipeline.setRenderTypeMask(type_mask);
4461 LLPipeline::sUseOcclusion = use_occlusion;
4462 LLPipeline::sSkipUpdate = FALSE;
4463
4464 if (toggle_ui)
4465 {
4466 gPipeline.toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI);
4467 }
4468 LLDrawPoolWater::sSkipScreenCopy = FALSE;
4469 LLPipeline::sSkipUpdate = FALSE;
4470 LLPipeline::sReflectionRender = FALSE;
4471
4472 LLGLState::checkStates();
4473 LLGLState::checkTextureChannels();
4474 LLGLState::checkClientArrays();
4475}
4476
4477//send cube map vertices and texture coordinates
4478void render_cube_map()
4479{
4480 U16 idx[36];
4481
4482 idx[0] = 1; idx[1] = 0; idx[2] = 2; //front
4483 idx[3] = 3; idx[4] = 2; idx[5] = 0;
4484
4485 idx[6] = 4; idx[7] = 5; idx[8] = 1; //top
4486 idx[9] = 0; idx[10] = 1; idx[11] = 5;
4487
4488 idx[12] = 5; idx[13] = 4; idx[14] = 6; //back
4489 idx[15] = 7; idx[16] = 6; idx[17] = 4;
4490
4491 idx[18] = 6; idx[19] = 7; idx[20] = 3; //bottom
4492 idx[21] = 2; idx[22] = 3; idx[23] = 7;
4493
4494 idx[24] = 0; idx[25] = 5; idx[26] = 3; //left
4495 idx[27] = 6; idx[28] = 3; idx[29] = 5;
4496
4497 idx[30] = 4; idx[31] = 1; idx[32] = 7; //right
4498 idx[33] = 2; idx[34] = 7; idx[35] = 1;
4499
4500 LLVector3 vert[8];
4501 LLVector3 r = LLVector3(1,1,1);
4502
4503 vert[0] = r.scaledVec(LLVector3(-1,1,1)); // 0 - left top front
4504 vert[1] = r.scaledVec(LLVector3(1,1,1)); // 1 - right top front
4505 vert[2] = r.scaledVec(LLVector3(1,-1,1)); // 2 - right bottom front
4506 vert[3] = r.scaledVec(LLVector3(-1,-1,1)); // 3 - left bottom front
4507
4508 vert[4] = r.scaledVec(LLVector3(1,1,-1)); // 4 - left top back
4509 vert[5] = r.scaledVec(LLVector3(-1,1,-1)); // 5 - right top back
4510 vert[6] = r.scaledVec(LLVector3(-1,-1,-1)); // 6 - right bottom back
4511 vert[7] = r.scaledVec(LLVector3(1,-1,-1)); // 7 -left bottom back
4512
4513 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4514 glTexCoordPointer(3, GL_FLOAT, 0, vert);
4515 glVertexPointer(3, GL_FLOAT, 0, vert);
4516
4517 glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, (GLushort*) idx);
4518
4519 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4520}
4521 4927
4522void validate_framebuffer_object() 4928void validate_framebuffer_object()
4523{ 4929{
@@ -4546,132 +4952,12 @@ void validate_framebuffer_object()
4546 } 4952 }
4547} 4953}
4548 4954
4549void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out)
4550{
4551 LLGLState::checkStates();
4552 LLGLState::checkTextureChannels();
4553 LLGLState::checkClientArrays();
4554
4555 assertInitialized();
4556
4557 U32 res = (U32) gSavedSettings.getS32("RenderReflectionRes");
4558 enableLightsFullbright(LLColor4::white);
4559 LLGLDepthTest depth(GL_FALSE);
4560 gGL.setColorMask(true, true);
4561 glMatrixMode(GL_PROJECTION);
4562 glPushMatrix();
4563 glLoadIdentity();
4564 gluPerspective(90.f+45.f/res, 1.f, 0.1f, 1024.f);
4565 glMatrixMode(GL_MODELVIEW);
4566 glPushMatrix();
4567
4568 cube_out->enableTexture(0);
4569 gGL.getTexUnit(cube_out->getStage())->bind(cube_out);
4570 gGL.getTexUnit(0)->activate();
4571 GLint width;
4572 glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_TEXTURE_WIDTH, &width);
4573 if (width != res)
4574 {
4575 cube_out->setReflection();
4576
4577 for (U32 i = 0; i < 6; i++)
4578 {
4579 glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL);
4580 }
4581 }
4582 gGL.getTexUnit(cube_out->getStage())->unbind(LLTexUnit::TT_CUBE_MAP);
4583 gGL.getTexUnit(0)->activate();
4584 glViewport(0, 0, res, res);
4585 LLGLEnable blend(GL_BLEND);
4586
4587 S32 kernel = 2;
4588 F32 step = 90.f/res;
4589 F32 alpha = 1.f / ((kernel*2)+1);
4590
4591 gGL.color4f(alpha,alpha,alpha,alpha*1.25f);
4592
4593 LLVector3 axis[] =
4594 {
4595 LLVector3(1,0,0),
4596 LLVector3(0,1,0),
4597 LLVector3(0,0,1)
4598 };
4599
4600 stop_glerror();
4601 glViewport(0,0,res, res);
4602 gGL.setSceneBlendType(LLRender::BT_ADD);
4603 cube_in->enableTexture(0);
4604 //3-axis blur
4605 for (U32 j = 0; j < 3; j++)
4606 {
4607 stop_glerror();
4608
4609 if (j == 0)
4610 {
4611 gGL.getTexUnit(cube_in->getStage())->bind(cube_in);
4612 }
4613 else
4614 {
4615 gGL.getTexUnit(cube_in->getStage())->bindManual(LLTexUnit::TT_CUBE_MAP, mBlurCubeTexture[j-1]);
4616 }
4617 gGL.getTexUnit(0)->activate();
4618
4619 stop_glerror();
4620
4621 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
4622 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mBlurCubeBuffer[j]);
4623 stop_glerror();
4624
4625 for (U32 i = 0; i < 6; i++)
4626 {
4627 stop_glerror();
4628 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
4629 GL_COLOR_ATTACHMENT0_EXT,
4630 gl_cube_face[i],
4631 j < 2 ? mBlurCubeTexture[j] : cube_out->getGLName(), 0);
4632 validate_framebuffer_object();
4633 gGL.setColorMask(true, true);
4634 glClear(GL_COLOR_BUFFER_BIT);
4635 glLoadIdentity();
4636 apply_cube_face_rotation(i);
4637 for (S32 x = -kernel; x <= kernel; ++x)
4638 {
4639 glPushMatrix();
4640 glRotatef(x*step, axis[j].mV[0], axis[j].mV[1], axis[j].mV[2]);
4641 render_cube_map();
4642 glPopMatrix();
4643 }
4644 stop_glerror();
4645 }
4646 }
4647
4648 stop_glerror();
4649
4650 gGL.getTexUnit(cube_in->getStage())->unbind(LLTexUnit::TT_CUBE_MAP);
4651
4652 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
4653 gGL.setColorMask(true, false);
4654 glMatrixMode(GL_PROJECTION);
4655 glPopMatrix();
4656 glMatrixMode(GL_MODELVIEW);
4657 glPopMatrix();
4658
4659 gGL.getTexUnit(cube_in->getStage())->disable();
4660 gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
4661 gViewerWindow->setupViewport();
4662 gGL.setSceneBlendType(LLRender::BT_ALPHA);
4663
4664 LLGLState::checkStates();
4665 LLGLState::checkTextureChannels();
4666 LLGLState::checkClientArrays();
4667}
4668
4669void LLPipeline::bindScreenToTexture() 4955void LLPipeline::bindScreenToTexture()
4670{ 4956{
4671 4957
4672} 4958}
4673 4959
4674void LLPipeline::renderBloom(BOOL for_snapshot) 4960void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
4675{ 4961{
4676 if (!(gPipeline.canUseVertexShaders() && 4962 if (!(gPipeline.canUseVertexShaders() &&
4677 sRenderGlow)) 4963 sRenderGlow))
@@ -4693,8 +4979,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
4693 U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); 4979 U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
4694 4980
4695 LLVector2 tc1(0,0); 4981 LLVector2 tc1(0,0);
4696 LLVector2 tc2((F32) gViewerWindow->getWindowDisplayWidth(), 4982 LLVector2 tc2((F32) gViewerWindow->getWindowDisplayWidth()*2,
4697 (F32) gViewerWindow->getWindowDisplayHeight()); 4983 (F32) gViewerWindow->getWindowDisplayHeight()*2);
4698 4984
4699 if (res_mod > 1) 4985 if (res_mod > 1)
4700 { 4986 {
@@ -4731,9 +5017,22 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
4731 //glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); 5017 //glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF);
4732 //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 5018 //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
4733 //LLGLDisable blend(GL_BLEND); 5019 //LLGLDisable blend(GL_BLEND);
5020
5021 // If the snapshot is constructed from tiles, calculate which
5022 // tile we're in.
5023 const S32 num_horizontal_tiles = llceil(zoom_factor);
5024 const LLVector2 tile(subfield % num_horizontal_tiles,
5025 (S32)(subfield / num_horizontal_tiles));
5026 llassert(zoom_factor > 0.0); // Non-zero, non-negative.
5027 const F32 tile_size = 1.0/zoom_factor;
5028
5029 tc1 = tile*tile_size; // Top left texture coordinates
5030 tc2 = (tile+LLVector2(1,1))*tile_size; // Bottom right texture coordinates
5031
4734 LLGLEnable blend(GL_BLEND); 5032 LLGLEnable blend(GL_BLEND);
4735 gGL.setSceneBlendType(LLRender::BT_ADD); 5033 gGL.setSceneBlendType(LLRender::BT_ADD);
4736 tc2.setVec(1,1); 5034
5035
4737 gGL.begin(LLRender::TRIANGLE_STRIP); 5036 gGL.begin(LLRender::TRIANGLE_STRIP);
4738 gGL.color4f(1,1,1,1); 5037 gGL.color4f(1,1,1,1);
4739 gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); 5038 gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
@@ -4747,6 +5046,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
4747 5046
4748 gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); 5047 gGL.texCoord2f(tc2.mV[0], tc2.mV[1]);
4749 gGL.vertex2f(1,1); 5048 gGL.vertex2f(1,1);
5049
4750 gGL.end(); 5050 gGL.end();
4751 5051
4752 gGL.flush(); 5052 gGL.flush();
@@ -4770,7 +5070,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
4770 } 5070 }
4771 5071
4772 gGlowExtractProgram.bind(); 5072 gGlowExtractProgram.bind();
4773 F32 minLum = llclamp(gSavedSettings.getF32("RenderGlowMinLuminance"), 0.0f, 1.0f); 5073 F32 minLum = llmax(gSavedSettings.getF32("RenderGlowMinLuminance"), 0.0f);
4774 F32 maxAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha"); 5074 F32 maxAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha");
4775 F32 warmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount"); 5075 F32 warmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount");
4776 LLVector3 lumWeights = gSavedSettings.getVector3("RenderGlowLumWeights"); 5076 LLVector3 lumWeights = gSavedSettings.getVector3("RenderGlowLumWeights");
@@ -4797,13 +5097,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
4797 gGL.vertex2f(-1,-1); 5097 gGL.vertex2f(-1,-1);
4798 5098
4799 gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); 5099 gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
4800 gGL.vertex2f(-1,1); 5100 gGL.vertex2f(-1,3);
4801 5101
4802 gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); 5102 gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
4803 gGL.vertex2f(1,-1); 5103 gGL.vertex2f(3,-1);
4804 5104
4805 gGL.texCoord2f(tc2.mV[0], tc2.mV[1]);
4806 gGL.vertex2f(1,1);
4807 gGL.end(); 5105 gGL.end();
4808 5106
4809 gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); 5107 gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
@@ -4812,7 +5110,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
4812 } 5110 }
4813 5111
4814 tc1.setVec(0,0); 5112 tc1.setVec(0,0);
4815 tc2.setVec(1,1); 5113 tc2.setVec(2,2);
4816 5114
4817 5115
4818 5116
@@ -4866,13 +5164,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
4866 gGL.vertex2f(-1,-1); 5164 gGL.vertex2f(-1,-1);
4867 5165
4868 gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); 5166 gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
4869 gGL.vertex2f(-1,1); 5167 gGL.vertex2f(-1,3);
4870 5168
4871 gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); 5169 gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
4872 gGL.vertex2f(1,-1); 5170 gGL.vertex2f(3,-1);
4873 5171
4874 gGL.texCoord2f(tc2.mV[0], tc2.mV[1]);
4875 gGL.vertex2f(1,1);
4876 gGL.end(); 5172 gGL.end();
4877 5173
4878 mGlow[i%2].flush(); 5174 mGlow[i%2].flush();
@@ -4888,81 +5184,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
4888 5184
4889 gViewerWindow->setupViewport(); 5185 gViewerWindow->setupViewport();
4890 5186
4891 /*mGlow[1].bindTexture();
4892 {
4893 LLGLEnable stencil(GL_STENCIL_TEST);
4894 glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF);
4895 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
4896 LLGLDisable blend(GL_BLEND);
4897
4898 gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
4899 gGL.color4f(1,1,1,1);
4900 gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
4901 gGL.vertex2f(-1,-1);
4902
4903 gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
4904 gGL.vertex2f(-1,1);
4905
4906 gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
4907 gGL.vertex2f(1,-1);
4908
4909 gGL.texCoord2f(tc2.mV[0], tc2.mV[1]);
4910 gGL.vertex2f(1,1);
4911 gGL.end();
4912
4913 gGL.flush();
4914 }
4915
4916 if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_GLOW))
4917 {
4918 tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(),
4919 (F32) gViewerWindow->getWindowDisplayHeight());
4920
4921 if (res_mod > 1)
4922 {
4923 tc2 /= (F32) res_mod;
4924 }
4925
4926 LLGLEnable blend(GL_BLEND);
4927 gGL.blendFunc(GL_ONE, GL_ONE);
4928
4929 gGL.getTexUnit(0)->disable();
4930 gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE);
4931 mScreen.bindTexture();
4932
4933 gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
4934 gGL.color4f(1,1,1,1);
4935 gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
4936 gGL.vertex2f(-1,-1);
4937
4938 gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
4939 gGL.vertex2f(-1,1);
4940
4941 gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
4942 gGL.vertex2f(1,-1);
4943
4944 gGL.texCoord2f(tc2.mV[0], tc2.mV[1]);
4945 gGL.vertex2f(1,1);
4946 gGL.end();
4947
4948 gGL.flush();
4949
4950 gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
4951
4952 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
4953 }*/
4954 gGL.flush(); 5187 gGL.flush();
4955 5188
4956 { 5189 {
4957 LLVertexBuffer::unbind(); 5190 LLVertexBuffer::unbind();
4958 5191
4959 F32 uv0[] = 5192
4960 {
4961 tc1.mV[0], tc1.mV[1],
4962 tc1.mV[0], tc2.mV[1],
4963 tc2.mV[0], tc1.mV[1],
4964 tc2.mV[0], tc2.mV[1]
4965 };
4966 5193
4967 tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(), 5194 tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(),
4968 (F32) gViewerWindow->getWindowDisplayHeight()); 5195 (F32) gViewerWindow->getWindowDisplayHeight());
@@ -4972,55 +5199,56 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
4972 tc2 /= (F32) res_mod; 5199 tc2 /= (F32) res_mod;
4973 } 5200 }
4974 5201
4975 F32 uv1[] = 5202 U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
4976 { 5203 LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
4977 tc1.mV[0], tc1.mV[1], 5204 buff->allocateBuffer(3,0,TRUE);
4978 tc1.mV[0], tc2.mV[1],
4979 tc2.mV[0], tc1.mV[1],
4980 tc2.mV[0], tc2.mV[1]
4981 };
4982 5205
4983 F32 v[] = 5206 LLStrider<LLVector3> v;
4984 { 5207 LLStrider<LLVector2> uv1;
4985 -1,-1, 5208 LLStrider<LLVector2> uv2;
4986 -1,1, 5209
4987 1,-1, 5210 buff->getVertexStrider(v);
4988 1,1 5211 buff->getTexCoord0Strider(uv1);
4989 }; 5212 buff->getTexCoord1Strider(uv2);
5213
5214 uv1[0] = LLVector2(0, 0);
5215 uv1[1] = LLVector2(0, 2);
5216 uv1[2] = LLVector2(2, 0);
4990 5217
5218 uv2[0] = LLVector2(0, 0);
5219 uv2[1] = LLVector2(0, tc2.mV[1]*2.f);
5220 uv2[2] = LLVector2(tc2.mV[0]*2.f, 0);
5221
5222 v[0] = LLVector3(-1,-1,0);
5223 v[1] = LLVector3(-1,3,0);
5224 v[2] = LLVector3(3,-1,0);
5225
5226 buff->setBuffer(0);
5227
4991 LLGLDisable blend(GL_BLEND); 5228 LLGLDisable blend(GL_BLEND);
4992 5229
4993 //tex unit 0 5230 //tex unit 0
4994 gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); 5231 gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR);
4995 5232
4996 gGL.getTexUnit(0)->bind(&mGlow[1]); 5233 gGL.getTexUnit(0)->bind(&mGlow[1]);
4997 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4998 glTexCoordPointer(2, GL_FLOAT, 0, uv0);
4999 gGL.getTexUnit(1)->activate(); 5234 gGL.getTexUnit(1)->activate();
5000 gGL.getTexUnit(1)->enable(LLTexUnit::TT_RECT_TEXTURE); 5235 gGL.getTexUnit(1)->enable(LLTexUnit::TT_RECT_TEXTURE);
5001 5236
5002 //tex unit 1 5237 //tex unit 1
5003 gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); 5238 gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
5004 5239
5005 glClientActiveTextureARB(GL_TEXTURE1_ARB);
5006 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
5007 glTexCoordPointer(2, GL_FLOAT, 0, uv1);
5008
5009 glVertexPointer(2, GL_FLOAT, 0, v);
5010
5011 gGL.getTexUnit(1)->bind(&mScreen); 5240 gGL.getTexUnit(1)->bind(&mScreen);
5012 gGL.getTexUnit(1)->activate(); 5241 gGL.getTexUnit(1)->activate();
5013 5242
5014 LLGLEnable multisample(GL_MULTISAMPLE_ARB); 5243 LLGLEnable multisample(GL_MULTISAMPLE_ARB);
5015 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 5244
5245 buff->setBuffer(mask);
5246 buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
5016 5247
5017 gGL.getTexUnit(1)->disable(); 5248 gGL.getTexUnit(1)->disable();
5018 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
5019 gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); 5249 gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT);
5020 5250
5021 glClientActiveTextureARB(GL_TEXTURE0_ARB);
5022 gGL.getTexUnit(0)->activate(); 5251 gGL.getTexUnit(0)->activate();
5023 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
5024 gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); 5252 gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
5025 } 5253 }
5026 5254
@@ -5037,6 +5265,515 @@ void LLPipeline::renderBloom(BOOL for_snapshot)
5037 5265
5038} 5266}
5039 5267
5268void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index)
5269{
5270 shader.bind();
5271 S32 channel = 0;
5272 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
5273 if (channel > -1)
5274 {
5275 mDeferredScreen.bindTexture(0,channel);
5276 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5277 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5278 }
5279
5280 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE);
5281 if (channel > -1)
5282 {
5283 mDeferredScreen.bindTexture(1, channel);
5284 }
5285
5286 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE);
5287 if (channel > -1)
5288 {
5289 mDeferredScreen.bindTexture(2, channel);
5290 }
5291
5292 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE);
5293 if (channel > -1)
5294 {
5295 mDeferredScreen.bindTexture(3, channel);
5296 }
5297
5298 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);
5299 if (channel > -1)
5300 {
5301 gGL.getTexUnit(channel)->bind(&mDeferredScreen, TRUE);
5302 }
5303
5304 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NOISE);
5305 if (channel > -1)
5306 {
5307 gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
5308 }
5309
5310 stop_glerror();
5311
5312 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
5313 if (channel > -1)
5314 {
5315 mDeferredLight[light_index].bindTexture(0, channel);
5316 }
5317
5318 stop_glerror();
5319
5320 for (U32 i = 0; i < 4; i++)
5321 {
5322 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i);
5323 stop_glerror();
5324 if (channel > -1)
5325 {
5326 stop_glerror();
5327 gGL.getTexUnit(channel)->bind(&mSunShadow[i], TRUE);
5328 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
5329 stop_glerror();
5330
5331 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
5332 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
5333 stop_glerror();
5334 }
5335 }
5336
5337 stop_glerror();
5338
5339 F32 mat[64];
5340 for (U32 i = 0; i < 16; i++)
5341 {
5342 mat[i] = mSunShadowMatrix[0].m[i];
5343 mat[i+16] = mSunShadowMatrix[1].m[i];
5344 mat[i+32] = mSunShadowMatrix[2].m[i];
5345 mat[i+48] = mSunShadowMatrix[3].m[i];
5346 }
5347
5348 shader.uniformMatrix4fv("shadow_matrix[0]", 4, FALSE, mat);
5349 shader.uniformMatrix4fv("shadow_matrix", 4, FALSE, mat);
5350
5351 stop_glerror();
5352
5353 channel = shader.enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
5354 if (channel > -1)
5355 {
5356 LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
5357 if (cube_map)
5358 {
5359 cube_map->enable(channel);
5360 cube_map->bind();
5361 F64* m = gGLModelView;
5362
5363
5364 F32 mat[] = { m[0], m[1], m[2],
5365 m[4], m[5], m[6],
5366 m[8], m[9], m[10] };
5367
5368 shader.uniform3fv("env_mat[0]", 3, mat);
5369 shader.uniform3fv("env_mat", 3, mat);
5370 }
5371 }
5372
5373 shader.uniform4fv("shadow_clip", 1, mSunClipPlanes.mV);
5374 shader.uniform1f("sun_wash", gSavedSettings.getF32("RenderDeferredSunWash"));
5375 shader.uniform1f("shadow_noise", gSavedSettings.getF32("RenderShadowNoise"));
5376 shader.uniform1f("blur_size", gSavedSettings.getF32("RenderShadowBlurSize"));
5377
5378 shader.uniform1f("ssao_radius", gSavedSettings.getF32("RenderSSAOScale"));
5379 shader.uniform1f("ssao_max_radius", gSavedSettings.getU32("RenderSSAOMaxScale"));
5380
5381 F32 ssao_factor = gSavedSettings.getF32("RenderSSAOFactor");
5382 shader.uniform1f("ssao_factor", ssao_factor);
5383 shader.uniform1f("ssao_factor_inv", 1.0/ssao_factor);
5384
5385 LLVector3 ssao_effect = gSavedSettings.getVector3("RenderSSAOEffect");
5386 F32 matrix_diag = (ssao_effect[0] + 2.0*ssao_effect[1])/3.0;
5387 F32 matrix_nondiag = (ssao_effect[0] - ssao_effect[1])/3.0;
5388 // This matrix scales (proj of color onto <1/rt(3),1/rt(3),1/rt(3)>) by
5389 // value factor, and scales remainder by saturation factor
5390 F32 ssao_effect_mat[] = { matrix_diag, matrix_nondiag, matrix_nondiag,
5391 matrix_nondiag, matrix_diag, matrix_nondiag,
5392 matrix_nondiag, matrix_nondiag, matrix_diag};
5393 shader.uniformMatrix3fv("ssao_effect_mat", 1, GL_FALSE, ssao_effect_mat);
5394
5395 shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
5396 shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f);
5397 shader.uniform1f("alpha_soften", gSavedSettings.getF32("RenderDeferredAlphaSoften"));
5398}
5399
5400void LLPipeline::renderDeferredLighting()
5401{
5402 if (!sCull)
5403 {
5404 return;
5405 }
5406
5407 LLGLEnable multisample(GL_MULTISAMPLE_ARB);
5408
5409 if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
5410 {
5411 gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
5412 }
5413
5414 //ati doesn't seem to love actually using the stencil buffer on FBO's
5415 LLGLEnable stencil(GL_STENCIL_TEST);
5416 glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
5417 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
5418
5419 gGL.setColorMask(true, true);
5420
5421 mDeferredLight[0].bindTarget();
5422
5423 //mDeferredLight[0].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
5424 // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
5425
5426 //draw a cube around every light
5427 LLVertexBuffer::unbind();
5428
5429 glBlendFunc(GL_ONE, GL_ONE);
5430 LLGLEnable cull(GL_CULL_FACE);
5431 LLGLEnable blend(GL_BLEND);
5432
5433 glh::matrix4f mat = glh_copy_matrix(gGLModelView);
5434
5435 F32 vert[] =
5436 {
5437 -1,1,
5438 -1,-3,
5439 3,1,
5440 };
5441
5442 bindDeferredShader(gDeferredSunProgram);
5443
5444 glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
5445
5446 const U32 slice = 32;
5447 F32 offset[slice*3];
5448 for (U32 i = 0; i < 4; i++)
5449 {
5450 for (U32 j = 0; j < 8; j++)
5451 {
5452 glh::vec3f v;
5453 v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i);
5454 v.normalize();
5455 inv_trans.mult_matrix_vec(v);
5456 v.normalize();
5457 offset[(i*8+j)*3+0] = v.v[0];
5458 offset[(i*8+j)*3+1] = v.v[2];
5459 offset[(i*8+j)*3+2] = v.v[1];
5460 }
5461 }
5462
5463 gDeferredSunProgram.uniform3fv("offset", slice, offset);
5464 gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight());
5465
5466 setupHWLights(NULL); //to set mSunDir;
5467
5468 glPushMatrix();
5469 glLoadIdentity();
5470 glMatrixMode(GL_PROJECTION);
5471 glPushMatrix();
5472 glLoadIdentity();
5473
5474 LLVector4 dir(mSunDir, 0.f);
5475
5476 glh::vec4f tc(dir.mV);
5477 mat.mult_matrix_vec(tc);
5478 glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);
5479 glColor3f(1,1,1);
5480
5481 glVertexPointer(2, GL_FLOAT, 0, vert);
5482 {
5483 LLGLDisable blend(GL_BLEND);
5484 LLGLDepthTest depth(GL_FALSE);
5485 stop_glerror();
5486 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
5487 stop_glerror();
5488 }
5489
5490 unbindDeferredShader(gDeferredSunProgram);
5491
5492 mDeferredLight[0].flush();
5493
5494 //blur lightmap
5495 mDeferredLight[1].bindTarget();
5496
5497 //mDeferredLight[1].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
5498 // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
5499
5500 bindDeferredShader(gDeferredBlurLightProgram);
5501
5502 LLVector3 gauss[32]; // xweight, yweight, offset
5503
5504 LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian");
5505 U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1;
5506 F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize");
5507
5508 // sample symmetrically with the middle sample falling exactly on 0.0
5509 F32 x = -(kern_length/2.0f) + 0.5f;
5510
5511 for (U32 i = 0; i < kern_length; i++)
5512 {
5513 gauss[i].mV[0] = llgaussian(x, go.mV[0]);
5514 gauss[i].mV[1] = llgaussian(x, go.mV[1]);
5515 gauss[i].mV[2] = x;
5516 x += 1.f;
5517 }
5518 /* swap the x=0 position to the start of gauss[] so we can
5519 treat it specially as an optimization. */
5520 LLVector3 swap;
5521 swap = gauss[kern_length/2];
5522 gauss[kern_length/2] = gauss[0];
5523 gauss[0] = swap;
5524 llassert(gauss[0].mV[2] == 0.0f);
5525
5526 gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f);
5527 gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV);
5528 gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
5529 gDeferredBlurLightProgram.uniform1i("kern_length", kern_length);
5530 gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
5531
5532 {
5533 LLGLDisable blend(GL_BLEND);
5534 LLGLDepthTest depth(GL_FALSE);
5535 stop_glerror();
5536 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
5537 stop_glerror();
5538 }
5539
5540 mDeferredLight[1].flush();
5541 unbindDeferredShader(gDeferredBlurLightProgram);
5542
5543 bindDeferredShader(gDeferredBlurLightProgram, 1);
5544 mDeferredLight[0].bindTarget();
5545
5546 gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f);
5547 gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV);
5548 gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
5549 gDeferredBlurLightProgram.uniform1i("kern_length", kern_length);
5550 gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
5551
5552 {
5553 LLGLDisable blend(GL_BLEND);
5554 LLGLDepthTest depth(GL_FALSE);
5555 stop_glerror();
5556 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5557 stop_glerror();
5558 }
5559 mDeferredLight[0].flush();
5560 unbindDeferredShader(gDeferredBlurLightProgram);
5561
5562 stop_glerror();
5563 glPopMatrix();
5564 stop_glerror();
5565 glMatrixMode(GL_MODELVIEW);
5566 stop_glerror();
5567 glPopMatrix();
5568 stop_glerror();
5569
5570 //copy depth and stencil from deferred screen
5571 //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
5572 // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
5573
5574 mScreen.bindTarget();
5575 mScreen.clear(GL_COLOR_BUFFER_BIT);
5576
5577 bindDeferredShader(gDeferredSoftenProgram);
5578 {
5579 LLGLDepthTest depth(GL_FALSE);
5580 LLGLDisable blend(GL_BLEND);
5581 LLGLDisable test(GL_ALPHA_TEST);
5582
5583 //full screen blit
5584 glPushMatrix();
5585 glLoadIdentity();
5586 glMatrixMode(GL_PROJECTION);
5587 glPushMatrix();
5588 glLoadIdentity();
5589
5590 glVertexPointer(2, GL_FLOAT, 0, vert);
5591
5592 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
5593
5594 glPopMatrix();
5595 glMatrixMode(GL_MODELVIEW);
5596 glPopMatrix();
5597 }
5598
5599 unbindDeferredShader(gDeferredSoftenProgram);
5600
5601 bindDeferredShader(gDeferredLightProgram);
5602
5603 std::list<LLVector4> fullscreen_lights;
5604 std::list<LLVector4> light_colors;
5605
5606 F32 v[24];
5607 glVertexPointer(3, GL_FLOAT, 0, v);
5608 {
5609 LLGLDepthTest depth(GL_TRUE, GL_FALSE);
5610 for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
5611 {
5612 LLDrawable* drawablep = *iter;
5613
5614 LLVOVolume* volume = drawablep->getVOVolume();
5615 if (!volume)
5616 {
5617 continue;
5618 }
5619
5620 LLVector3 center = drawablep->getPositionAgent();
5621 F32* c = center.mV;
5622 F32 s = volume->getLightRadius()*1.5f;
5623
5624 if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0)
5625 {
5626 continue;
5627 }
5628
5629 sVisibleLightCount++;
5630 glh::vec3f tc(c);
5631 mat.mult_matrix_vec(tc);
5632
5633 LLColor3 col = volume->getLightColor();
5634 col *= volume->getLightIntensity();
5635
5636 //vertex positions are encoded so the 3 bits of their vertex index
5637 //correspond to their axis facing, with bit position 3,2,1 matching
5638 //axis facing x,y,z, bit set meaning positive facing, bit clear
5639 //meaning negative facing
5640 v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000
5641 v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001
5642 v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010
5643 v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011
5644
5645 v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100
5646 v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101
5647 v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110
5648 v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111
5649
5650 if (LLViewerCamera::getInstance()->getOrigin().mV[0] > c[0] + s + 0.2f ||
5651 LLViewerCamera::getInstance()->getOrigin().mV[0] < c[0] - s - 0.2f ||
5652 LLViewerCamera::getInstance()->getOrigin().mV[1] > c[1] + s + 0.2f ||
5653 LLViewerCamera::getInstance()->getOrigin().mV[1] < c[1] - s - 0.2f ||
5654 LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f ||
5655 LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f)
5656 { //draw box if camera is outside box
5657 glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
5658 glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
5659 glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
5660 GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center));
5661 }
5662 else
5663 {
5664 fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s));
5665 light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
5666 }
5667 }
5668 }
5669
5670 unbindDeferredShader(gDeferredLightProgram);
5671
5672 if (!fullscreen_lights.empty())
5673 {
5674 bindDeferredShader(gDeferredMultiLightProgram);
5675 LLGLDepthTest depth(GL_FALSE);
5676
5677 //full screen blit
5678 glPushMatrix();
5679 glLoadIdentity();
5680 glMatrixMode(GL_PROJECTION);
5681 glPushMatrix();
5682 glLoadIdentity();
5683
5684 U32 count = 0;
5685
5686 LLVector4 light[16];
5687 LLVector4 col[16];
5688
5689 glVertexPointer(2, GL_FLOAT, 0, vert);
5690
5691 while (!fullscreen_lights.empty())
5692 {
5693 light[count] = fullscreen_lights.front();
5694 fullscreen_lights.pop_front();
5695 col[count] = light_colors.front();
5696 light_colors.pop_front();
5697
5698 count++;
5699 if (count == 16 || fullscreen_lights.empty())
5700 {
5701 gDeferredMultiLightProgram.uniform1i("light_count", count);
5702 gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light);
5703 gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light);
5704 gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col);
5705 gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col);
5706 count = 0;
5707 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
5708 }
5709 }
5710
5711
5712 glPopMatrix();
5713 glMatrixMode(GL_MODELVIEW);
5714 glPopMatrix();
5715
5716 unbindDeferredShader(gDeferredMultiLightProgram);
5717 }
5718 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
5719
5720 { //render non-deferred geometry
5721 LLGLDisable blend(GL_BLEND);
5722 LLGLDisable stencil(GL_STENCIL_TEST);
5723
5724 U32 render_mask = mRenderTypeMask;
5725 mRenderTypeMask = mRenderTypeMask &
5726 ((1 << LLPipeline::RENDER_TYPE_SKY) |
5727 (1 << LLPipeline::RENDER_TYPE_CLOUDS) |
5728 (1 << LLPipeline::RENDER_TYPE_WL_SKY) |
5729 (1 << LLPipeline::RENDER_TYPE_ALPHA) |
5730 (1 << LLPipeline::RENDER_TYPE_AVATAR) |
5731 (1 << LLPipeline::RENDER_TYPE_WATER) |
5732 (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) |
5733 (1 << LLPipeline::RENDER_TYPE_VOLUME) |
5734 (1 << LLPipeline::RENDER_TYPE_GLOW) |
5735 (1 << LLPipeline::RENDER_TYPE_BUMP));
5736
5737 renderGeomPostDeferred(*LLViewerCamera::getInstance());
5738 mRenderTypeMask = render_mask;
5739 }
5740
5741 mScreen.flush();
5742
5743}
5744
5745void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
5746{
5747 stop_glerror();
5748 shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE);
5749 shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE);
5750 shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
5751 shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE);
5752 shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);
5753 shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
5754 for (U32 i = 0; i < 4; i++)
5755 {
5756 if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i) > -1)
5757 {
5758 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
5759 }
5760 }
5761 shader.disableTexture(LLViewerShaderMgr::DEFERRED_NOISE);
5762
5763 S32 channel = shader.disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
5764 if (channel > -1)
5765 {
5766 LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
5767 if (cube_map)
5768 {
5769 cube_map->disable();
5770 }
5771 }
5772 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
5773 gGL.getTexUnit(0)->activate();
5774 shader.unbind();
5775}
5776
5040inline float sgn(float a) 5777inline float sgn(float a)
5041{ 5778{
5042 if (a > 0.0F) return (1.0F); 5779 if (a > 0.0F) return (1.0F);
@@ -5048,6 +5785,16 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
5048{ 5785{
5049 if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) 5786 if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
5050 { 5787 {
5788 LLVOAvatar* agent = gAgent.getAvatarObject();
5789 if (gAgent.getCameraAnimating() || gAgent.getCameraMode() != CAMERA_MODE_MOUSELOOK)
5790 {
5791 agent = NULL;
5792 }
5793
5794 if (agent)
5795 {
5796 agent->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON);
5797 }
5051 LLVertexBuffer::unbind(); 5798 LLVertexBuffer::unbind();
5052 5799
5053 LLGLState::checkStates(); 5800 LLGLState::checkStates();
@@ -5059,6 +5806,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
5059 LLPipeline::sReflectionRender = TRUE; 5806 LLPipeline::sReflectionRender = TRUE;
5060 S32 occlusion = LLPipeline::sUseOcclusion; 5807 S32 occlusion = LLPipeline::sUseOcclusion;
5061 LLPipeline::sUseOcclusion = llmin(occlusion, 1); 5808 LLPipeline::sUseOcclusion = llmin(occlusion, 1);
5809
5062 U32 type_mask = gPipeline.mRenderTypeMask; 5810 U32 type_mask = gPipeline.mRenderTypeMask;
5063 5811
5064 glh::matrix4f projection = glh_get_current_projection(); 5812 glh::matrix4f projection = glh_get_current_projection();
@@ -5126,15 +5874,15 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
5126 //initial sky pass (no user clip plane) 5874 //initial sky pass (no user clip plane)
5127 { //mask out everything but the sky 5875 { //mask out everything but the sky
5128 U32 tmp = mRenderTypeMask; 5876 U32 tmp = mRenderTypeMask;
5129 mRenderTypeMask &= ((1 << LLPipeline::RENDER_TYPE_SKY) | 5877 mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) |
5130 (1 << LLPipeline::RENDER_TYPE_CLOUDS) |
5131 (1 << LLPipeline::RENDER_TYPE_WL_SKY)); 5878 (1 << LLPipeline::RENDER_TYPE_WL_SKY));
5132
5133 static LLCullResult result; 5879 static LLCullResult result;
5134 updateCull(camera, result); 5880 updateCull(camera, result);
5135 stateSort(camera, result); 5881 stateSort(camera, result);
5882 mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) |
5883 (1 << LLPipeline::RENDER_TYPE_CLOUDS) |
5884 (1 << LLPipeline::RENDER_TYPE_WL_SKY));
5136 renderGeom(camera, TRUE); 5885 renderGeom(camera, TRUE);
5137
5138 mRenderTypeMask = tmp; 5886 mRenderTypeMask = tmp;
5139 } 5887 }
5140 5888
@@ -5226,6 +5974,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
5226 last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; 5974 last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
5227 5975
5228 LLRenderTarget::unbindTarget(); 5976 LLRenderTarget::unbindTarget();
5977
5229 LLPipeline::sReflectionRender = FALSE; 5978 LLPipeline::sReflectionRender = FALSE;
5230 5979
5231 if (!LLRenderTarget::sUseFBO) 5980 if (!LLRenderTarget::sUseFBO)
@@ -5244,7 +5993,422 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
5244 LLGLState::checkStates(); 5993 LLGLState::checkStates();
5245 LLGLState::checkTextureChannels(); 5994 LLGLState::checkTextureChannels();
5246 LLGLState::checkClientArrays(); 5995 LLGLState::checkClientArrays();
5996
5997 if (agent)
5998 {
5999 agent->updateAttachmentVisibility(gAgent.getCameraMode());
6000 }
6001 }
6002}
6003
6004glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up)
6005{
6006 glh::matrix4f ret;
6007
6008 LLVector3 dirN;
6009 LLVector3 upN;
6010 LLVector3 lftN;
6011
6012 lftN = dir % up;
6013 lftN.normVec();
6014
6015 upN = lftN % dir;
6016 upN.normVec();
6017
6018 dirN = dir;
6019 dirN.normVec();
6020
6021
6022 ret.m[ 0] = lftN[0];
6023 ret.m[ 1] = upN[0];
6024 ret.m[ 2] = -dirN[0];
6025 ret.m[ 3] = 0.f;
6026
6027 ret.m[ 4] = lftN[1];
6028 ret.m[ 5] = upN[1];
6029 ret.m[ 6] = -dirN[1];
6030 ret.m[ 7] = 0.f;
6031
6032 ret.m[ 8] = lftN[2];
6033 ret.m[ 9] = upN[2];
6034 ret.m[10] = -dirN[2];
6035 ret.m[11] = 0.f;
6036
6037 ret.m[12] = -(lftN*pos);
6038 ret.m[13] = -(upN*pos);
6039 ret.m[14] = dirN*pos;
6040 ret.m[15] = 1.f;
6041
6042 return ret;
6043}
6044
6045glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max)
6046{
6047 glh::matrix4f ret;
6048 ret.m[ 0] = 2/(max[0]-min[0]);
6049 ret.m[ 4] = 0;
6050 ret.m[ 8] = 0;
6051 ret.m[12] = -(max[0]+min[0])/(max[0]-min[0]);
6052
6053 ret.m[ 1] = 0;
6054 ret.m[ 5] = 2/(max[1]-min[1]);
6055 ret.m[ 9] = 0;
6056 ret.m[13] = -(max[1]+min[1])/(max[1]-min[1]);
6057
6058 ret.m[ 2] = 0;
6059 ret.m[ 6] = 0;
6060 ret.m[10] = 2/(max[2]-min[2]);
6061 ret.m[14] = -(max[2]+min[2])/(max[2]-min[2]);
6062
6063 ret.m[ 3] = 0;
6064 ret.m[ 7] = 0;
6065 ret.m[11] = 0;
6066 ret.m[15] = 1;
6067
6068 return ret;
6069}
6070
6071void LLPipeline::generateSunShadow(LLCamera& camera)
6072{
6073
6074 if (!sRenderDeferred)
6075 {
6076 return;
6077 }
6078
6079 //temporary hack to disable shadows but keep local lights
6080 static BOOL clear = TRUE;
6081 BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow");
6082 if (!gen_shadow)
6083 {
6084 if (clear)
6085 {
6086 clear = FALSE;
6087 for (U32 i = 0; i < 4; i++)
6088 {
6089 mSunShadow[i].bindTarget();
6090 mSunShadow[i].clear();
6091 mSunShadow[i].flush();
6092 }
6093 }
6094 return;
6095 }
6096 clear = TRUE;
6097
6098 gGL.setColorMask(false, false);
6099
6100 //get sun view matrix
6101
6102 F32 range = 128.f;
6103
6104 //store current projection/modelview matrix
6105 glh::matrix4f saved_proj = glh_get_current_projection();
6106 glh::matrix4f saved_view = glh_get_current_modelview();
6107 glh::matrix4f inv_view = saved_view.inverse();
6108
6109 glh::matrix4f view[4];
6110 glh::matrix4f proj[4];
6111 LLVector3 up;
6112
6113 //clip contains parallel split distances for 3 splits
6114 LLVector3 clip = gSavedSettings.getVector3("RenderShadowClipPlanes");
6115
6116 //far clip on last split is minimum of camera view distance and 128
6117 mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]);
6118
6119 const LLPickInfo& pick_info = gViewerWindow->getLastPick();
6120
6121 if (!pick_info.mPosGlobal.isExactlyZero())
6122 { //squish nearest frustum based on alt-zoom (tighten up nearest frustum when focusing on tiny object
6123 F32 focus_dist = (F32) (pick_info.mPosGlobal + LLVector3d(pick_info.mObjectOffset) - gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin())).magVec();
6124 mSunClipPlanes.mV[0] = llclamp(focus_dist*focus_dist, 2.f, mSunClipPlanes.mV[0]);
5247 } 6125 }
6126
6127 // convenience array of 4 near clip plane distances
6128 F32 dist[] = { 0.1f, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
6129
6130 //currently used for amount to extrude frusta corners for constructing shadow frusta
6131 LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist");
6132 F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
6133
6134 for (S32 j = 0; j < 4; j++)
6135 {
6136 //restore render matrices
6137 glh_set_current_modelview(saved_view);
6138 glh_set_current_projection(saved_proj);
6139
6140 //get center of far clip plane (for point of interest later)
6141 LLVector3 center = camera.getOrigin() + camera.getAtAxis() * range;
6142
6143 LLVector3 eye = camera.getOrigin();
6144
6145 //camera used for shadow cull/render
6146 LLCamera shadow_cam;
6147
6148 // perspective shadow map
6149 glh::vec3f p[16]; //point cloud to be contained by shadow projection (light camera space)
6150 glh::vec3f wp[16]; //point cloud to be contained by shadow projection (world space)
6151
6152 LLVector3 lightDir = -mSunDir;
6153 glh::vec3f light_dir(lightDir.mV);
6154
6155 //create light space camera matrix
6156 LLVector3 at;
6157 F32 dl = camera.getLeftAxis() * lightDir;
6158 F32 du = camera.getUpAxis() * lightDir;
6159
6160 //choose an at axis such that up will be most aligned with lightDir
6161 if (dl*dl < du*du)
6162 {
6163 at = lightDir%camera.getLeftAxis();
6164 }
6165 else
6166 {
6167 at = lightDir%camera.getUpAxis();
6168 }
6169
6170 if (at * camera.getAtAxis() < 0)
6171 {
6172 at = -at;
6173 }
6174
6175 LLVector3 left = lightDir%at;
6176 up = left%lightDir;
6177 up.normVec();
6178
6179 //create world space camera frustum for this split
6180 shadow_cam = camera;
6181 shadow_cam.setFar(16.f);
6182
6183 LLViewerCamera::updateFrustumPlanes(shadow_cam);
6184
6185 LLVector3* frust = shadow_cam.mAgentFrustum;
6186
6187 LLVector3 pn = shadow_cam.getAtAxis();
6188
6189 LLVector3 frust_center;
6190
6191 LLVector3 min, max;
6192
6193 //construct 8 corners of split frustum section
6194 for (U32 i = 0; i < 4; i++)
6195 {
6196 LLVector3 delta = frust[i+4]-eye;
6197 delta.normVec();
6198 F32 dp = delta*pn;
6199 frust[i] = eye + (delta*dist[j])/dp;
6200 frust[i+4] = eye + (delta*dist[j+1])/dp;
6201 frust_center += frust[i] + frust[i+4];
6202 }
6203
6204 //get frustum center
6205 frust_center /= 8.f;
6206
6207 shadow_cam.calcAgentFrustumPlanes(frust);
6208
6209
6210 if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
6211 {
6212 mShadowCamera[j] = shadow_cam;
6213 }
6214
6215 if (gPipeline.getVisibleExtents(shadow_cam, min, max))
6216 {
6217 //no possible shadow receivers
6218 if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
6219 {
6220 mShadowExtents[j][0] = LLVector3();
6221 mShadowExtents[j][1] = LLVector3();
6222 mShadowCamera[j+4] = shadow_cam;
6223 }
6224
6225 continue;
6226 }
6227
6228 if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
6229 {
6230 mShadowExtents[j][0] = min;
6231 mShadowExtents[j][1] = max;
6232 }
6233
6234 view[j] = look(frust_center-lightDir*nearDist[j], lightDir, up);
6235 F32 shadow_dist = nearDist[j];
6236
6237 for (U32 i = 0; i < 8; i++)
6238 {
6239 //points in worldspace (wp) and light camera space (p)
6240 //that must be included in shadow generation
6241 wp[i] = glh::vec3f(frust[i].mV);
6242 wp[i+8] = wp[i] - light_dir*shadow_dist;
6243 view[j].mult_matrix_vec(wp[i], p[i]);
6244 view[j].mult_matrix_vec(wp[i+8], p[i+8]);
6245 }
6246
6247 min = LLVector3(p[0].v);
6248 max = LLVector3(p[0].v);
6249
6250 LLVector3 fmin = min;
6251 LLVector3 fmax = max;
6252
6253 for (U32 i = 1; i < 16; i++)
6254 { //find camera space AABB of frustum in light camera space
6255 update_min_max(min, max, LLVector3(p[i].v));
6256 if (i < 8)
6257 {
6258 update_min_max(fmin, fmax, LLVector3(p[i].v));
6259 }
6260 }
6261
6262 //generate perspective matrix that contains frustum
6263 //proj[j] = matrix_perspective(min, max);
6264 proj[j] = gl_ortho(min.mV[0], max.mV[0],
6265 min.mV[1], max.mV[1],
6266 -max.mV[2], -min.mV[2]);
6267
6268 shadow_cam.setFar(128.f);
6269 shadow_cam.setOriginAndLookAt(eye, up, center);
6270
6271 glh_set_current_modelview(view[j]);
6272 glh_set_current_projection(proj[j]);
6273
6274 LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
6275
6276 proj[j] = gl_ortho(fmin.mV[0], fmax.mV[0],
6277 fmin.mV[1], fmax.mV[1],
6278 -fmax.mV[2], -fmin.mV[2]);
6279
6280 //translate and scale to from [-1, 1] to [0, 1]
6281 glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
6282 0.f, 0.5f, 0.f, 0.5f,
6283 0.f, 0.f, 0.5f, 0.5f,
6284 0.f, 0.f, 0.f, 1.f);
6285
6286 glh_set_current_modelview(view[j]);
6287 glh_set_current_projection(proj[j]);
6288
6289 mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view;
6290
6291 U32 type_mask = mRenderTypeMask;
6292 mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) |
6293 (1<<LLPipeline::RENDER_TYPE_ALPHA) |
6294 (1<<LLPipeline::RENDER_TYPE_GRASS) |
6295 (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |
6296 (1<<LLPipeline::RENDER_TYPE_BUMP) |
6297 (1<<LLPipeline::RENDER_TYPE_VOLUME) |
6298 (1<<LLPipeline::RENDER_TYPE_AVATAR) |
6299 (1<<LLPipeline::RENDER_TYPE_TREE) |
6300 (1<<LLPipeline::RENDER_TYPE_TERRAIN) |
6301 0);
6302
6303 //clip out geometry on the same side of water as the camera
6304 static LLCullResult result;
6305 S32 occlude = LLPipeline::sUseOcclusion;
6306 LLPipeline::sUseOcclusion = 1;
6307 LLPipeline::sShadowRender = TRUE;
6308 //hack to prevent LOD updates from using sun camera origin
6309 shadow_cam.setOrigin(camera.getOrigin());
6310 updateCull(shadow_cam, result);
6311 stateSort(shadow_cam, result);
6312
6313 if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
6314 {
6315 LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
6316 mShadowCamera[j+4] = shadow_cam;
6317 }
6318
6319 LLFastTimer t(LLFastTimer::FTM_SHADOW_RENDER);
6320
6321 stop_glerror();
6322
6323 mSunShadow[j].bindTarget();
6324 mSunShadow[j].getViewport(gGLViewport);
6325
6326 {
6327 LLGLDepthTest depth(GL_TRUE);
6328 mSunShadow[j].clear();
6329 }
6330
6331 U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP };
6332 LLGLEnable cull(GL_CULL_FACE);
6333
6334 //generate sun shadow map
6335 glMatrixMode(GL_PROJECTION);
6336 glPushMatrix();
6337 glLoadMatrixf(proj[j].m);
6338 glMatrixMode(GL_MODELVIEW);
6339 glPushMatrix();
6340 glLoadMatrixf(view[j].m);
6341
6342 stop_glerror();
6343 gGLLastMatrix = NULL;
6344
6345 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
6346
6347 glColor4f(1,1,1,1);
6348
6349 glCullFace(GL_FRONT);
6350
6351 stop_glerror();
6352
6353 gGL.setColorMask(false, false);
6354
6355 gDeferredShadowProgram.bind();
6356 {
6357 LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE);
6358 LLGLDisable test(GL_ALPHA_TEST);
6359 gGL.getTexUnit(0)->disable();
6360 for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i)
6361 {
6362 renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
6363 }
6364 gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
6365 }
6366
6367 {
6368 LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA);
6369 LLGLEnable test(GL_ALPHA_TEST);
6370 gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f);
6371 renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE);
6372 glColor4f(1,1,1,1);
6373 renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
6374 gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
6375 }
6376
6377 gDeferredShadowProgram.unbind();
6378
6379 renderGeomShadow(shadow_cam);
6380
6381 gGL.setColorMask(true, true);
6382
6383 glCullFace(GL_BACK);
6384 LLPipeline::sUseOcclusion = occlude;
6385 LLPipeline::sShadowRender = FALSE;
6386 mRenderTypeMask = type_mask;
6387
6388 glMatrixMode(GL_PROJECTION);
6389 glPopMatrix();
6390 glMatrixMode(GL_MODELVIEW);
6391 glPopMatrix();
6392 gGLLastMatrix = NULL;
6393
6394 mSunShadow[j].flush();
6395 }
6396
6397 if (!gSavedSettings.getBOOL("CameraOffset"))
6398 {
6399 glh_set_current_modelview(saved_view);
6400 glh_set_current_projection(saved_proj);
6401 }
6402 else
6403 {
6404 glh_set_current_modelview(view[1]);
6405 glh_set_current_projection(proj[1]);
6406 glLoadMatrixf(view[1].m);
6407 glMatrixMode(GL_PROJECTION);
6408 glLoadMatrixf(proj[1].m);
6409 glMatrixMode(GL_MODELVIEW);
6410 }
6411 gGL.setColorMask(true, false);
5248} 6412}
5249 6413
5250void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) 6414void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture)
@@ -5264,6 +6428,10 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu
5264 6428
5265void LLPipeline::generateImpostor(LLVOAvatar* avatar) 6429void LLPipeline::generateImpostor(LLVOAvatar* avatar)
5266{ 6430{
6431 LLGLState::checkStates();
6432 LLGLState::checkTextureChannels();
6433 LLGLState::checkClientArrays();
6434
5267 static LLCullResult result; 6435 static LLCullResult result;
5268 result.clear(); 6436 result.clear();
5269 grabReferences(result); 6437 grabReferences(result);
@@ -5289,6 +6457,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
5289 (1<<LLPipeline::RENDER_TYPE_BUMP) | 6457 (1<<LLPipeline::RENDER_TYPE_BUMP) |
5290 (1<<LLPipeline::RENDER_TYPE_GRASS) | 6458 (1<<LLPipeline::RENDER_TYPE_GRASS) |
5291 (1<<LLPipeline::RENDER_TYPE_SIMPLE) | 6459 (1<<LLPipeline::RENDER_TYPE_SIMPLE) |
6460 (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |
5292 (1<<LLPipeline::RENDER_TYPE_ALPHA) | 6461 (1<<LLPipeline::RENDER_TYPE_ALPHA) |
5293 (1<<LLPipeline::RENDER_TYPE_INVISIBLE); 6462 (1<<LLPipeline::RENDER_TYPE_INVISIBLE);
5294 } 6463 }
@@ -5299,7 +6468,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
5299 6468
5300 S32 occlusion = sUseOcclusion; 6469 S32 occlusion = sUseOcclusion;
5301 sUseOcclusion = 0; 6470 sUseOcclusion = 0;
5302 sReflectionRender = TRUE; 6471 sReflectionRender = sRenderDeferred ? FALSE : TRUE;
5303 sImpostorRender = TRUE; 6472 sImpostorRender = TRUE;
5304 6473
5305 markVisible(avatar->mDrawable, *LLViewerCamera::getInstance()); 6474 markVisible(avatar->mDrawable, *LLViewerCamera::getInstance());
@@ -5376,10 +6545,17 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
5376 if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() || 6545 if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() ||
5377 resY != avatar->mImpostor.getHeight()) 6546 resY != avatar->mImpostor.getHeight())
5378 { 6547 {
5379 avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE); 6548 if (LLPipeline::sRenderDeferred)
6549 {
6550 avatar->mImpostor.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE);
6551 addDeferredAttachments(avatar->mImpostor);
6552 }
6553 else
6554 {
6555 avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,TRUE);
6556 }
5380 gGL.getTexUnit(0)->bind(&avatar->mImpostor); 6557 gGL.getTexUnit(0)->bind(&avatar->mImpostor);
5381 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 6558 gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
5382 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5383 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); 6559 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
5384 } 6560 }
5385 6561
@@ -5387,8 +6563,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
5387 LLGLEnable scissor(GL_SCISSOR_TEST); 6563 LLGLEnable scissor(GL_SCISSOR_TEST);
5388 glScissor(0, 0, resX, resY); 6564 glScissor(0, 0, resX, resY);
5389 avatar->mImpostor.bindTarget(); 6565 avatar->mImpostor.bindTarget();
5390 avatar->mImpostor.getViewport(gGLViewport); 6566 avatar->mImpostor.clear();
5391 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
5392 } 6567 }
5393 6568
5394 LLGLEnable stencil(GL_STENCIL_TEST); 6569 LLGLEnable stencil(GL_STENCIL_TEST);
@@ -5396,11 +6571,20 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
5396 glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); 6571 glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
5397 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 6572 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
5398 6573
5399 renderGeom(camera); 6574 if (LLPipeline::sRenderDeferred)
6575 {
6576 stop_glerror();
6577 renderGeomDeferred(camera);
6578 }
6579 else
6580 {
6581 renderGeom(camera);
6582 }
5400 6583
5401 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 6584 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
5402 glStencilFunc(GL_EQUAL, 1, 0xFFFFFF); 6585 glStencilFunc(GL_EQUAL, 1, 0xFFFFFF);
5403 6586
6587 if (!sRenderDeferred || muted)
5404 { 6588 {
5405 LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f; 6589 LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f;
5406 LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f; 6590 LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f;
@@ -5431,7 +6615,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
5431 gGL.end(); 6615 gGL.end();
5432 gGL.flush(); 6616 gGL.flush();
5433 6617
5434
5435 gGL.setSceneBlendType(LLRender::BT_ALPHA); 6618 gGL.setSceneBlendType(LLRender::BT_ALPHA);
5436 } 6619 }
5437 6620
@@ -5453,6 +6636,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
5453 6636
5454 avatar->mNeedsImpostorUpdate = FALSE; 6637 avatar->mNeedsImpostorUpdate = FALSE;
5455 avatar->cacheImpostorValues(); 6638 avatar->cacheImpostorValues();
6639
6640 LLVertexBuffer::unbind();
6641 LLGLState::checkStates();
6642 LLGLState::checkTextureChannels();
6643 LLGLState::checkClientArrays();
5456} 6644}
5457 6645
5458BOOL LLPipeline::hasRenderBatches(const U32 type) const 6646BOOL LLPipeline::hasRenderBatches(const U32 type) const