aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/pipeline.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/pipeline.cpp3191
1 files changed, 2591 insertions, 600 deletions
diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp
index 72da3c6..4bf53af 100644
--- a/linden/indra/newview/pipeline.cpp
+++ b/linden/indra/newview/pipeline.cpp
@@ -159,6 +159,8 @@ std::string gPoolNames[] =
159 "POOL_ALPHA", 159 "POOL_ALPHA",
160}; 160};
161 161
162void drawBox(const LLVector3& c, const LLVector3& r);
163
162U32 nhpo2(U32 v) 164U32 nhpo2(U32 v)
163{ 165{
164 U32 r = 1; 166 U32 r = 1;
@@ -267,11 +269,11 @@ static const U32 gl_cube_face[] =
267 269
268void validate_framebuffer_object(); 270void validate_framebuffer_object();
269 271
272
270void addDeferredAttachments(LLRenderTarget& target) 273void addDeferredAttachments(LLRenderTarget& target)
271{ 274{
272 target.addColorAttachment(GL_RGBA16F_ARB); //specular 275 target.addColorAttachment(GL_RGBA); //specular //target.addColorAttachment(GL_RGBA16F_ARB); //specular // KL
273 target.addColorAttachment(GL_RGBA16F_ARB); //normal+z 276 target.addColorAttachment(GL_RGBA); //normal+z //target.addColorAttachment(GL_RGBA16F_ARB); //normal+z
274 target.addColorAttachment(GL_RGBA16F_ARB); //position
275} 277}
276 278
277LLPipeline::LLPipeline() : 279LLPipeline::LLPipeline() :
@@ -313,6 +315,8 @@ LLPipeline::LLPipeline() :
313 mLightingDetail(0) 315 mLightingDetail(0)
314{ 316{
315 mNoiseMap = 0; 317 mNoiseMap = 0;
318 //mTrueNoiseMap = 0; // KL SD
319 mLightFunc = 0; // KL SD
316} 320}
317 321
318void LLPipeline::init() 322void LLPipeline::init()
@@ -362,6 +366,11 @@ void LLPipeline::init()
362 LLViewerShaderMgr::instance()->setShaders(); 366 LLViewerShaderMgr::instance()->setShaders();
363 367
364 stop_glerror(); 368 stop_glerror();
369
370 for (U32 i = 0; i < 2; ++i)
371 {
372 mSpotLightFade[i] = 1.f;
373 }
365} 374}
366 375
367LLPipeline::~LLPipeline() 376LLPipeline::~LLPipeline()
@@ -373,6 +382,9 @@ void LLPipeline::cleanup()
373{ 382{
374 assertInitialized(); 383 assertInitialized();
375 384
385 mGroupQ1.clear() ;
386 mGroupQ2.clear() ;
387
376 for(pool_set_t::iterator iter = mPools.begin(); 388 for(pool_set_t::iterator iter = mPools.begin();
377 iter != mPools.end(); ) 389 iter != mPools.end(); )
378 { 390 {
@@ -469,33 +481,69 @@ void LLPipeline::resizeScreenTexture()
469 GLuint resX = gViewerWindow->getWindowDisplayWidth(); 481 GLuint resX = gViewerWindow->getWindowDisplayWidth();
470 GLuint resY = gViewerWindow->getWindowDisplayHeight(); 482 GLuint resY = gViewerWindow->getWindowDisplayHeight();
471 483
472 U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
473 if (res_mod > 1 && res_mod < resX && res_mod < resY)
474 {
475 resX /= res_mod;
476 resY /= res_mod;
477 }
478
479 allocateScreenBuffer(resX,resY); 484 allocateScreenBuffer(resX,resY);
480
481 llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl;
482 } 485 }
483} 486}
484 487
485void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) 488void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
486{ 489{
490
487 U32 samples = gSavedSettings.getU32("RenderFSAASamples"); 491 U32 samples = gSavedSettings.getU32("RenderFSAASamples");
492 U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
493
494 if (res_mod > 1 && res_mod < resX && res_mod < resY)
495 {
496 resX /= res_mod;
497 resY /= res_mod;
498 }
499
500 if (gSavedSettings.getBOOL("RenderUIBuffer"))
501 {
502 //mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
503 }
504
488 if (LLPipeline::sRenderDeferred) 505 if (LLPipeline::sRenderDeferred)
489 { 506 {
490 //allocate deferred rendering color buffers 507 //allocate deferred rendering color buffers
491 mDeferredScreen.allocate(resX, resY, GL_RGBA16F_ARB, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); 508 mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
509 mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
492 addDeferredAttachments(mDeferredScreen); 510 addDeferredAttachments(mDeferredScreen);
493 mScreen.allocate(resX, resY, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); 511
494 512 // always set viewport to desired size, since allocate resets the viewport
513
514 mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
515
516 for (U32 i = 0; i < 3; i++)
517 {
518 mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
519 }
520
495 for (U32 i = 0; i < 2; i++) 521 for (U32 i = 0; i < 2; i++)
496 { 522 {
497 mDeferredLight[i].allocate(resX, resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); 523 mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
524 }
525
526 F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale");
527
528 for (U32 i = 0; i < 4; i++)
529 {
530 mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
531 }
532
533
534 U32 width = nhpo2(U32(resX*scale))/2;
535 U32 height = width;
536
537 for (U32 i = 4; i < 6; i++)
538 {
539 mShadow[i].allocate(width, height, 0, TRUE, FALSE);
498 } 540 }
541
542
543
544 width = nhpo2(resX)/2;
545 height = nhpo2(resY)/2;
546 mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE);
499 } 547 }
500 else 548 else
501 { 549 {
@@ -505,25 +553,23 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
505 553
506 if (gGLManager.mHasFramebufferMultisample && samples > 1) 554 if (gGLManager.mHasFramebufferMultisample && samples > 1)
507 { 555 {
556 mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples);
508 if (LLPipeline::sRenderDeferred) 557 if (LLPipeline::sRenderDeferred)
509 { 558 {
510 mSampleBuffer.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples);
511 addDeferredAttachments(mSampleBuffer); 559 addDeferredAttachments(mSampleBuffer);
512 mDeferredScreen.setSampleBuffer(&mSampleBuffer); 560 mDeferredScreen.setSampleBuffer(&mSampleBuffer);
513 } 561 }
514 else
515 {
516 mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples);
517 }
518 562
519 mScreen.setSampleBuffer(&mSampleBuffer); 563 mScreen.setSampleBuffer(&mSampleBuffer);
564
520 stop_glerror(); 565 stop_glerror();
521 } 566 }
522 else if (LLPipeline::sRenderDeferred) 567
568 if (LLPipeline::sRenderDeferred)
523 { //share depth buffer between deferred targets 569 { //share depth buffer between deferred targets
524 mDeferredScreen.shareDepthBuffer(mScreen); 570 mDeferredScreen.shareDepthBuffer(mScreen);
525 for (U32 i = 0; i < 2; i++) 571 for (U32 i = 0; i < 3; i++)
526 { 572 { //share stencil buffer with screen space lightmap to stencil out sky
527 mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); 573 mDeferredScreen.shareDepthBuffer(mDeferredLight[i]);
528 } 574 }
529 } 575 }
@@ -556,17 +602,40 @@ void LLPipeline::releaseGLBuffers()
556 mNoiseMap = 0; 602 mNoiseMap = 0;
557 } 603 }
558 604
605/* if (mTrueNoiseMap)
606 {
607 LLImageGL::deleteTextures(1, &mTrueNoiseMap);
608 mTrueNoiseMap = 0;
609 }
610*/
611 if (mLightFunc)
612 {
613 LLImageGL::deleteTextures(1, &mLightFunc);
614 mLightFunc = 0;
615 }
616
559 mWaterRef.release(); 617 mWaterRef.release();
560 mWaterDis.release(); 618 mWaterDis.release();
561 mScreen.release(); 619 mScreen.release();
562 mSampleBuffer.releaseSampleBuffer(); 620 mSampleBuffer.releaseSampleBuffer();
563 mDeferredScreen.release(); 621 mDeferredScreen.release();
622 mDeferredDepth.release();
623 for (U32 i = 0; i < 3; i++)
624 {
625 mDeferredLight[i].release();
626 }
627
628 mGIMap.release();
629 mGIMapPost[0].release();
630 mGIMapPost[1].release();
631 mHighlight.release();
632// mLuminanceMap.release();
564 633
565 634 for (U32 i = 0; i < 6; i++) // KL 6 in SD
566 for (U32 i = 0; i < 4; i++)
567 { 635 {
568 mSunShadow[i].release(); 636 mShadow[i].release();
569 } 637 }
638
570 for (U32 i = 0; i < 3; i++) 639 for (U32 i = 0; i < 3; i++)
571 { 640 {
572 mGlow[i].release(); 641 mGlow[i].release();
@@ -589,9 +658,13 @@ void LLPipeline::createGLBuffers()
589 mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE); 658 mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE);
590 } 659 }
591 660
661 mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE);
592 662
593 stop_glerror(); 663 stop_glerror();
594 664
665 GLuint resX = gViewerWindow->getWindowDisplayWidth();
666 GLuint resY = gViewerWindow->getWindowDisplayHeight();
667
595 if (LLPipeline::sRenderGlow) 668 if (LLPipeline::sRenderGlow)
596 { //screen space glow buffers 669 { //screen space glow buffers
597 const U32 glow_res = llmax(1, 670 const U32 glow_res = llmax(1,
@@ -601,20 +674,13 @@ void LLPipeline::createGLBuffers()
601 { 674 {
602 mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); 675 mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
603 } 676 }
604 }
605 677
606 GLuint resX = gViewerWindow->getWindowDisplayWidth(); 678 allocateScreenBuffer(resX,resY);
607 GLuint resY = gViewerWindow->getWindowDisplayHeight();
608
609 allocateScreenBuffer(resX,resY);
610 679
680 }
681
611 if (sRenderDeferred) 682 if (sRenderDeferred)
612 { 683 {
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) 684 if (!mNoiseMap)
619 { 685 {
620 const U32 noiseRes = 128; 686 const U32 noiseRes = 128;
@@ -634,7 +700,83 @@ void LLPipeline::createGLBuffers()
634 LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise); 700 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); 701 gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
636 } 702 }
637 } 703
704/* if (!mTrueNoiseMap)
705 {
706 const U32 noiseRes = 128;
707 F32 noise[noiseRes*noiseRes*3];
708 for (U32 i = 0; i < noiseRes*noiseRes*3; i++)
709 {
710 noise[i] = ll_frand()*2.0-1.0;
711 }
712
713 LLImageGL::generateTextures(1, &mTrueNoiseMap);
714 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
715 LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise);
716 gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
717 }
718*/
719 if (!mLightFunc)
720 {
721 U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
722 U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
723 U8* lg = new U8[lightResX*lightResY];
724
725 for (U32 y = 0; y < lightResY; ++y)
726 {
727 for (U32 x = 0; x < lightResX; ++x)
728 {
729 //spec func
730 F32 sa = (F32) x/(lightResX-1);
731 F32 spec = (F32) y/(lightResY-1);
732 //lg[y*lightResX+x] = (U8) (powf(sa, 128.f*spec*spec)*255);
733
734 //F32 sp = acosf(sa)/(1.f-spec);
735
736 sa = powf(sa, gSavedSettings.getF32("RenderSpecularExponent"));
737 F32 a = acosf(sa*0.25f+0.75f);
738 F32 m = llmax(0.5f-spec*0.5f, 0.001f);
739 F32 t2 = tanf(a)/m;
740 t2 *= t2;
741
742 F32 c4a = (3.f+4.f*cosf(2.f*a)+cosf(4.f*a))/8.f;
743 F32 bd = 1.f/(4.f*m*m*c4a)*powf(F_E, -t2);
744
745 lg[y*lightResX+x] = (U8) (llclamp(bd, 0.f, 1.f)*255);
746 }
747 }
748
749 LLImageGL::generateTextures(1, &mLightFunc);
750 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
751 LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_ALPHA, lightResX, lightResY, GL_ALPHA, GL_UNSIGNED_BYTE, lg);
752 gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
753 gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
754
755 delete [] lg;
756/* }
757
758 if (gSavedSettings.getBOOL("RenderDeferredGI"))
759 { */
760 mGIMap.allocate(1024,1024,GL_RGBA, TRUE, FALSE);
761 addDeferredAttachments(mGIMap);
762
763 {
764 LLGLDepthTest depth(GL_TRUE);
765 gGL.setColorMask(true, true);
766 for (U32 i = 0; i < 2; i++)
767 {
768 mGIMapPost[i].allocate(128,128,GL_RGB16F_ARB, FALSE, FALSE);
769 mGIMapPost[i].addColorAttachment(GL_RGB16F_ARB);
770 mGIMapPost[i].addColorAttachment(GL_RGB16F_ARB);
771 mGIMapPost[i].addColorAttachment(GL_RGB16F_ARB);
772
773 mGIMapPost[i].bindTarget();
774 mGIMapPost[i].clear();
775 mGIMapPost[i].flush();
776 }
777 }
778 }
779 } //mLuminanceMap.allocate(128,128, GL_RGBA, FALSE, FALSE);
638} 780}
639 781
640void LLPipeline::restoreGL() 782void LLPipeline::restoreGL()
@@ -646,7 +788,7 @@ void LLPipeline::restoreGL()
646 LLViewerShaderMgr::instance()->setShaders(); 788 LLViewerShaderMgr::instance()->setShaders();
647 } 789 }
648 790
649 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 791 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
650 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 792 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
651 { 793 {
652 LLViewerRegion* region = *iter; 794 LLViewerRegion* region = *iter;
@@ -700,7 +842,7 @@ void LLPipeline::unloadShaders()
700 842
701void LLPipeline::assertInitializedDoError() 843void LLPipeline::assertInitializedDoError()
702{ 844{
703 llerrs << "LLPipeline used when uninitialized." << llendl; 845 llwarns << "LLPipeline used when uninitialized." << llendl;
704} 846}
705 847
706//============================================================================ 848//============================================================================
@@ -763,7 +905,7 @@ public:
763 for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) 905 for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
764 { 906 {
765 LLDrawInfo* params = *j; 907 LLDrawInfo* params = *j;
766 if (mTextures.find(params->mTexture) != mTextures.end()) 908 if (mTextures.find(params->mViewerTexture) != mTextures.end())
767 { 909 {
768 group->setState(LLSpatialGroup::GEOM_DIRTY); 910 group->setState(LLSpatialGroup::GEOM_DIRTY);
769 } 911 }
@@ -797,7 +939,7 @@ void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerImage*>& texture
797 } 939 }
798 940
799 LLOctreeDirtyTexture dirty(textures); 941 LLOctreeDirtyTexture dirty(textures);
800 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 942 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
801 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 943 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
802 { 944 {
803 LLViewerRegion* region = *iter; 945 LLViewerRegion* region = *iter;
@@ -876,7 +1018,7 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0)
876 1018
877 default: 1019 default:
878 llassert(0); 1020 llassert(0);
879 llerrs << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl; 1021 llwarns << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl;
880 break; 1022 break;
881 } 1023 }
882 1024
@@ -991,7 +1133,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
991#ifdef LL_RELEASE_FOR_DOWNLOAD 1133#ifdef LL_RELEASE_FOR_DOWNLOAD
992 llwarns << "Couldn't remove object from spatial group!" << llendl; 1134 llwarns << "Couldn't remove object from spatial group!" << llendl;
993#else 1135#else
994 llerrs << "Couldn't remove object from spatial group!" << llendl; 1136 llwarns << "Couldn't remove object from spatial group!" << llendl;
995#endif 1137#endif
996 } 1138 }
997 } 1139 }
@@ -1006,6 +1148,31 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
1006 break; 1148 break;
1007 } 1149 }
1008 } 1150 }
1151
1152 {
1153 HighlightItem item(drawablep);
1154 mHighlightSet.erase(item);
1155
1156 if (mHighlightObject == drawablep)
1157 {
1158 mHighlightObject = NULL;
1159 }
1160 }
1161
1162 for (U32 i = 0; i < 2; ++i)
1163 {
1164 if (mShadowSpotLight[i] == drawablep)
1165 {
1166 mShadowSpotLight[i] = NULL;
1167 }
1168
1169 if (mTargetShadowSpotLight[i] == drawablep)
1170 {
1171 mTargetShadowSpotLight[i] = NULL;
1172 }
1173 }
1174
1175
1009} 1176}
1010 1177
1011U32 LLPipeline::addObject(LLViewerObject *vobj) 1178U32 LLPipeline::addObject(LLViewerObject *vobj)
@@ -1062,7 +1229,7 @@ void LLPipeline::createObject(LLViewerObject* vobj)
1062 } 1229 }
1063 else 1230 else
1064 { 1231 {
1065 llerrs << "Redundant drawable creation!" << llendl; 1232 llwarns << "Redundant drawable creation!" << llendl;
1066 } 1233 }
1067 1234
1068 llassert(drawablep); 1235 llassert(drawablep);
@@ -1123,7 +1290,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep)
1123 } 1290 }
1124 if (!drawablep) 1291 if (!drawablep)
1125 { 1292 {
1126 llerrs << "updateMove called with NULL drawablep" << llendl; 1293 llwarns << "updateMove called with NULL drawablep" << llendl;
1127 return; 1294 return;
1128 } 1295 }
1129 if (drawablep->isState(LLDrawable::EARLY_MOVE)) 1296 if (drawablep->isState(LLDrawable::EARLY_MOVE))
@@ -1153,7 +1320,8 @@ void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep)
1153 } 1320 }
1154 if (!drawablep) 1321 if (!drawablep)
1155 { 1322 {
1156 llerrs << "updateMove called with NULL drawablep" << llendl; 1323 llwarns << "updateMove called with NULL drawablep" << llendl;
1324 return;
1157 } 1325 }
1158 if (drawablep->isState(LLDrawable::EARLY_MOVE)) 1326 if (drawablep->isState(LLDrawable::EARLY_MOVE))
1159 { 1327 {
@@ -1245,7 +1413,7 @@ void LLPipeline::updateMove()
1245 { 1413 {
1246 LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE); 1414 LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE);
1247 1415
1248 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 1416 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
1249 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 1417 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1250 { 1418 {
1251 LLViewerRegion* region = *iter; 1419 LLViewerRegion* region = *iter;
@@ -1272,7 +1440,6 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera
1272 F32 dist = lookAt.length(); 1440 F32 dist = lookAt.length();
1273 1441
1274 //ramp down distance for nearby objects 1442 //ramp down distance for nearby objects
1275 //shrink dist by dist/16.
1276 if (dist < 16.f) 1443 if (dist < 16.f)
1277 { 1444 {
1278 dist /= 16.f; 1445 dist /= 16.f;
@@ -1293,7 +1460,7 @@ void LLPipeline::grabReferences(LLCullResult& result)
1293 1460
1294BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) 1461BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera)
1295{ 1462{
1296 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 1463 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
1297 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 1464 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1298 { 1465 {
1299 LLViewerRegion* region = *iter; 1466 LLViewerRegion* region = *iter;
@@ -1325,7 +1492,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
1325 1492
1326 BOOL res = TRUE; 1493 BOOL res = TRUE;
1327 1494
1328 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 1495 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
1329 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 1496 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1330 { 1497 {
1331 LLViewerRegion* region = *iter; 1498 LLViewerRegion* region = *iter;
@@ -1388,7 +1555,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
1388 1555
1389 LLGLDepthTest depth(GL_TRUE, GL_FALSE); 1556 LLGLDepthTest depth(GL_TRUE, GL_FALSE);
1390 1557
1391 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 1558 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
1392 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 1559 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1393 { 1560 {
1394 LLViewerRegion* region = *iter; 1561 LLViewerRegion* region = *iter;
@@ -1465,7 +1632,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
1465 1632
1466 group->setVisible(); 1633 group->setVisible();
1467 1634
1468 if (!sSkipUpdate) 1635 if (!sSkipUpdate) // && !sShadowRender) KL?
1469 { 1636 {
1470 group->updateDistance(camera); 1637 group->updateDistance(camera);
1471 } 1638 }
@@ -1556,6 +1723,78 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority)
1556 return update_complete; 1723 return update_complete;
1557} 1724}
1558 1725
1726void LLPipeline::updateGL() // KL SD
1727{
1728 while (!LLGLUpdate::sGLQ.empty())
1729 {
1730 LLGLUpdate* glu = LLGLUpdate::sGLQ.front();
1731 glu->updateGL();
1732 glu->mInQ = FALSE;
1733 LLGLUpdate::sGLQ.pop_front();
1734 }
1735} // KL updateGL SD
1736
1737void LLPipeline::rebuildPriorityGroups()
1738{
1739 LLTimer update_timer;
1740 LLMemType mt(LLMemType::MTYPE_PIPELINE);
1741
1742 assertInitialized();
1743
1744 // Iterate through all drawables on the priority build queue,
1745 for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin();
1746 iter != mGroupQ1.end(); ++iter)
1747 {
1748 LLSpatialGroup* group = *iter;
1749 group->rebuildGeom();
1750 group->clearState(LLSpatialGroup::IN_BUILD_Q1);
1751 }
1752
1753 mGroupQ1.clear();
1754}
1755
1756void LLPipeline::rebuildGroups()
1757{
1758 // Iterate through some drawables on the non-priority build queue
1759 S32 size = (S32) mGroupQ2.size();
1760 S32 min_count = llclamp((S32) ((F32) (size * size)/4096*0.25f), 1, size);
1761
1762 S32 count = 0;
1763
1764 std::sort(mGroupQ2.begin(), mGroupQ2.end(), LLSpatialGroup::CompareUpdateUrgency()); // KL
1765
1766 LLSpatialGroup::sg_vector_t::iterator iter;
1767 for (iter = mGroupQ2.begin();
1768 iter != mGroupQ2.end(); ++iter)
1769 {
1770 LLSpatialGroup* group = *iter;
1771
1772 if (group->isDead())
1773 {
1774 continue;
1775 }
1776
1777 group->rebuildGeom();
1778
1779 if (group->mSpatialPartition->mRenderByGroup)
1780 {
1781 count++;
1782 }
1783
1784 group->clearState(LLSpatialGroup::IN_BUILD_Q2);
1785
1786 if (count > min_count)
1787 {
1788 ++iter;
1789 break;
1790 }
1791 }
1792
1793 mGroupQ2.erase(mGroupQ2.begin(), iter);
1794
1795 updateMovedList(mMovedBridge);
1796}
1797
1559void LLPipeline::updateGeom(F32 max_dtime) 1798void LLPipeline::updateGeom(F32 max_dtime)
1560{ 1799{
1561 LLTimer update_timer; 1800 LLTimer update_timer;
@@ -1670,6 +1909,16 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
1670 1909
1671 if (drawablep->isSpatialBridge()) 1910 if (drawablep->isSpatialBridge())
1672 { 1911 {
1912 LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable;
1913
1914 if (root && root->getParent() && root->getVObj() && root->getVObj()->isAttachment())
1915 {
1916 LLVOAvatar* av = root->getParent()->getVObj()->asAvatar();
1917 if (av->isImpostor())
1918 {
1919 return;
1920 }
1921 }
1673 sCull->pushBridge((LLSpatialBridge*) drawablep); 1922 sCull->pushBridge((LLSpatialBridge*) drawablep);
1674 } 1923 }
1675 else 1924 else
@@ -1686,7 +1935,7 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion)
1686 1935
1687 if (!drawablep) 1936 if (!drawablep)
1688 { 1937 {
1689 //llerrs << "Sending null drawable to moved list!" << llendl; 1938 //llwarns << "Sending null drawable to moved list!" << llendl;
1690 return; 1939 return;
1691 } 1940 }
1692 1941
@@ -1771,7 +2020,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
1771 } 2020 }
1772 mShiftList.resize(0); 2021 mShiftList.resize(0);
1773 2022
1774 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 2023 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
1775 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 2024 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1776 { 2025 {
1777 LLViewerRegion* region = *iter; 2026 LLViewerRegion* region = *iter;
@@ -1799,6 +2048,54 @@ void LLPipeline::markTextured(LLDrawable *drawablep)
1799 } 2048 }
1800} 2049}
1801 2050
2051void LLPipeline::markGLRebuild(LLGLUpdate* glu)
2052{
2053 if (glu && !glu->mInQ)
2054 {
2055 LLGLUpdate::sGLQ.push_back(glu);
2056 glu->mInQ = TRUE;
2057 }
2058}
2059
2060void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)
2061{
2062 LLMemType mt(LLMemType::MTYPE_PIPELINE);
2063 //assert_main_thread();
2064
2065 if (group && !group->isDead() && group->mSpatialPartition)
2066 {
2067 if (priority)
2068 {
2069 if (!group->isState(LLSpatialGroup::IN_BUILD_Q1))
2070 {
2071 mGroupQ1.push_back(group);
2072 group->setState(LLSpatialGroup::IN_BUILD_Q1);
2073
2074 if (group->isState(LLSpatialGroup::IN_BUILD_Q2))
2075 {
2076 LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group);
2077 if (iter != mGroupQ2.end())
2078 {
2079 mGroupQ2.erase(iter);
2080 }
2081 group->clearState(LLSpatialGroup::IN_BUILD_Q2);
2082 }
2083 }
2084 }
2085 else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1))
2086 {
2087 //llwarns << "Non-priority updates not yet supported!" << llendl;
2088 if (std::find(mGroupQ2.begin(), mGroupQ2.end(), group) != mGroupQ2.end())
2089 {
2090 llwarns << "WTF?" << llendl;
2091 }
2092 mGroupQ2.push_back(group);
2093 group->setState(LLSpatialGroup::IN_BUILD_Q2);
2094
2095 }
2096 }
2097}
2098
1802void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority) 2099void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority)
1803{ 2100{
1804 LLMemType mt(LLMemType::MTYPE_PIPELINE); 2101 LLMemType mt(LLMemType::MTYPE_PIPELINE);
@@ -1853,12 +2150,13 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
1853 2150
1854 grabReferences(result); 2151 grabReferences(result);
1855 2152
2153 //if (!LLPipeline::sShadowRender)
1856 { 2154 {
1857 for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) 2155 for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
1858 { 2156 {
1859 LLSpatialGroup* group = *iter; 2157 LLSpatialGroup* group = *iter;
1860 group->checkOcclusion(); 2158 group->checkOcclusion();
1861 if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) 2159 if (sUseOcclusion > 1 && group->isState(LLSpatialGroup::OCCLUDED))
1862 { 2160 {
1863 markOccluder(group); 2161 markOccluder(group);
1864 } 2162 }
@@ -1871,12 +2169,15 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
1871 } 2169 }
1872 } 2170 }
1873 } 2171 }
2172 }
1874 2173
2174 if (!LLPipeline::sShadowRender)
2175 {
1875 for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) 2176 for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
1876 { 2177 {
1877 LLSpatialGroup* group = *iter; 2178 LLSpatialGroup* group = *iter;
1878 group->checkOcclusion(); 2179 group->checkOcclusion();
1879 if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) 2180 if (sUseOcclusion > 1 && group->isState(LLSpatialGroup::OCCLUDED))
1880 { 2181 {
1881 markOccluder(group); 2182 markOccluder(group);
1882 } 2183 }
@@ -1888,6 +2189,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
1888 } 2189 }
1889 } 2190 }
1890 2191
2192 if (!LLPipeline::sShadowRender)
1891 { 2193 {
1892 for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) 2194 for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
1893 { 2195 {
@@ -1939,7 +2241,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
1939void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) 2241void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera)
1940{ 2242{
1941 LLMemType mt(LLMemType::MTYPE_PIPELINE); 2243 LLMemType mt(LLMemType::MTYPE_PIPELINE);
1942 if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) 2244 if (!sSkipUpdate && !sShadowRender && bridge->getSpatialGroup()->changeLOD())
1943 { 2245 {
1944 bool force_update = false; 2246 bool force_update = false;
1945 bridge->updateDistance(camera, force_update); 2247 bridge->updateDistance(camera, force_update);
@@ -2001,41 +2303,46 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
2001 } 2303 }
2002 } 2304 }
2003 2305
2004 LLSpatialGroup* group = drawablep->getSpatialGroup(); 2306 if (!sShadowRender)
2005 if (!group || group->changeLOD())
2006 { 2307 {
2007 if (drawablep->isVisible() && !sSkipUpdate) 2308 LLSpatialGroup* group = drawablep->getSpatialGroup();
2309 if (!group || group->changeLOD())
2008 { 2310 {
2009 if (!drawablep->isActive()) 2311 if (drawablep->isVisible() && !sSkipUpdate)
2010 { 2312 {
2011 bool force_update = false; 2313 if (!drawablep->isActive())
2012 drawablep->updateDistance(camera, force_update); 2314 {
2315 drawablep->updateDistance(camera, TRUE);
2316 }
2317 else if (drawablep->isAvatar())
2318 {
2319 drawablep->updateDistance(camera, TRUE); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility()
2320 }
2013 } 2321 }
2014 else if (drawablep->isAvatar())
2015 {
2016 bool force_update = false;
2017 drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility()
2018 }
2019 } 2322 }
2020 } 2323 }
2021 2324
2022 for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); 2325 if (!drawablep->getVOVolume())
2023 iter != drawablep->mFaces.end(); iter++)
2024 { 2326 {
2025 LLFace* facep = *iter; 2327 for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin();
2026 2328 iter != drawablep->mFaces.end(); iter++)
2027 if (facep->hasGeometry())
2028 { 2329 {
2029 if (facep->getPool()) 2330 LLFace* facep = *iter;
2030 { 2331
2031 facep->getPool()->enqueue(facep); 2332 if (facep->hasGeometry())
2032 }
2033 else
2034 { 2333 {
2035 break; 2334 if (facep->getPool())
2335 {
2336 facep->getPool()->enqueue(facep);
2337 }
2338 else
2339 {
2340 break;
2341 }
2036 } 2342 }
2037 } 2343 }
2038 } 2344 }
2345
2039 2346
2040 mNumVisibleFaces += drawablep->getNumFaces(); 2347 mNumVisibleFaces += drawablep->getNumFaces();
2041} 2348}
@@ -2201,7 +2508,7 @@ void LLPipeline::postSort(LLCamera& camera)
2201 //rebuild groups 2508 //rebuild groups
2202 sCull->assertDrawMapsEmpty(); 2509 sCull->assertDrawMapsEmpty();
2203 2510
2204 LLSpatialGroup::sNoDelete = FALSE; 2511 /*LLSpatialGroup::sNoDelete = FALSE;
2205 for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) 2512 for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
2206 { 2513 {
2207 LLSpatialGroup* group = *i; 2514 LLSpatialGroup* group = *i;
@@ -2213,8 +2520,10 @@ void LLPipeline::postSort(LLCamera& camera)
2213 2520
2214 group->rebuildGeom(); 2521 group->rebuildGeom();
2215 } 2522 }
2216 LLSpatialGroup::sNoDelete = TRUE; 2523 LLSpatialGroup::sNoDelete = TRUE;*/
2524
2217 2525
2526 rebuildPriorityGroups();
2218 2527
2219 const S32 bin_count = 1024*8; 2528 const S32 bin_count = 1024*8;
2220 2529
@@ -2240,39 +2549,51 @@ void LLPipeline::postSort(LLCamera& camera)
2240 { 2549 {
2241 continue; 2550 continue;
2242 } 2551 }
2243 2552
2553 if (group->isState(LLSpatialGroup::NEW_DRAWINFO) && group->isState(LLSpatialGroup::GEOM_DIRTY))
2554 { //no way this group is going to be drawable without a rebuild
2555 group->rebuildGeom();
2556 }
2557
2244 for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) 2558 for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j)
2245 { 2559 {
2246 LLSpatialGroup::drawmap_elem_t& src_vec = j->second; 2560 LLSpatialGroup::drawmap_elem_t& src_vec = j->second;
2247 2561 if (!hasRenderType(j->first))
2562 {
2563 continue;
2564 }
2565
2248 for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) 2566 for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k)
2249 { 2567 {
2250 sCull->pushDrawInfo(j->first, *k); 2568 sCull->pushDrawInfo(j->first, *k);
2251 } 2569 }
2252 } 2570 }
2253 2571
2254 LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); 2572 if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA))
2255 2573 {
2256 if (alpha != group->mDrawMap.end()) 2574 LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA);
2257 { //store alpha groups for sorting 2575
2258 LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); 2576 if (alpha != group->mDrawMap.end())
2259 if (!sSkipUpdate) 2577 { //store alpha groups for sorting
2260 { 2578 LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
2261 if (bridge) 2579 if (!sSkipUpdate)
2262 { 2580 {
2263 LLCamera trans_camera = bridge->transformCamera(camera); 2581 if (bridge)
2264 group->updateDistance(trans_camera); 2582 {
2583 LLCamera trans_camera = bridge->transformCamera(camera);
2584 group->updateDistance(trans_camera);
2585 }
2586 else
2587 {
2588 group->updateDistance(camera);
2589 }
2265 } 2590 }
2266 else 2591
2592 if (hasRenderType(LLDrawPool::POOL_ALPHA))
2267 { 2593 {
2268 group->updateDistance(camera); 2594 sCull->pushAlphaGroup(group);
2269 } 2595 }
2270 } 2596 }
2271
2272 if (hasRenderType(LLDrawPool::POOL_ALPHA))
2273 {
2274 sCull->pushAlphaGroup(group);
2275 }
2276 } 2597 }
2277 } 2598 }
2278 2599
@@ -2370,7 +2691,7 @@ void LLPipeline::postSort(LLCamera& camera)
2370 } 2691 }
2371 } 2692 }
2372 2693
2373 LLSpatialGroup::sNoDelete = FALSE; 2694 //LLSpatialGroup::sNoDelete = FALSE;
2374} 2695}
2375 2696
2376 2697
@@ -2431,6 +2752,103 @@ void LLPipeline::renderHighlights()
2431 LLGLEnable color_mat(GL_COLOR_MATERIAL); 2752 LLGLEnable color_mat(GL_COLOR_MATERIAL);
2432 disableLights(); 2753 disableLights();
2433 2754
2755 if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD) && !mHighlightSet.empty())
2756 { //draw blurry highlight image over screen
2757 LLGLEnable blend(GL_BLEND);
2758 LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
2759 LLGLDisable test(GL_ALPHA_TEST);
2760
2761 LLGLEnable stencil(GL_STENCIL_TEST);
2762 gGL.flush();
2763 glStencilMask(0xFFFFFFFF);
2764 glClearStencil(1);
2765 glClear(GL_STENCIL_BUFFER_BIT);
2766
2767 glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
2768 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2769
2770 gGL.setColorMask(false, false);
2771 for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ++iter)
2772 {
2773 renderHighlight(iter->mItem->getVObj(), 1.f);
2774 }
2775 gGL.setColorMask(true, false);
2776
2777 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2778 glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
2779
2780 //gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
2781
2782 gGL.pushMatrix();
2783 glLoadIdentity();
2784 glMatrixMode(GL_PROJECTION);
2785 gGL.pushMatrix();
2786 glLoadIdentity();
2787
2788 gGL.getTexUnit(0)->bind(&mHighlight);
2789
2790 LLVector2 tc1;
2791 LLVector2 tc2;
2792
2793 tc1.setVec(0,0);
2794 tc2.setVec(2,2);
2795
2796 gGL.begin(LLRender::TRIANGLES);
2797
2798 F32 scale = gSavedSettings.getF32("RenderHighlightBrightness");
2799 LLColor4 color = gSavedSettings.getColor4("RenderHighlightColor");
2800 F32 thickness = gSavedSettings.getF32("RenderHighlightThickness");
2801
2802 for (S32 pass = 0; pass < 2; ++pass)
2803 {
2804 if (pass == 0)
2805 {
2806 gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
2807 }
2808 else
2809 {
2810 gGL.setSceneBlendType(LLRender::BT_ALPHA);
2811 }
2812
2813 for (S32 i = 0; i < 8; ++i)
2814 {
2815 for (S32 j = 0; j < 8; ++j)
2816 {
2817 LLVector2 tc(i-4+0.5f, j-4+0.5f);
2818
2819 F32 dist = 1.f-(tc.length()/sqrtf(32.f));
2820 dist *= scale/64.f;
2821
2822 tc *= thickness;
2823 tc.mV[0] = (tc.mV[0])/mHighlight.getWidth();
2824 tc.mV[1] = (tc.mV[1])/mHighlight.getHeight();
2825
2826 gGL.color4f(color.mV[0],
2827 color.mV[1],
2828 color.mV[2],
2829 color.mV[3]*dist);
2830
2831 gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc2.mV[1]);
2832 gGL.vertex2f(-1,3);
2833
2834 gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc1.mV[1]);
2835 gGL.vertex2f(-1,-1);
2836
2837 gGL.texCoord2f(tc.mV[0]+tc2.mV[0], tc.mV[1]+tc1.mV[1]);
2838 gGL.vertex2f(3,-1);
2839 }
2840 }
2841 }
2842
2843 gGL.end();
2844
2845 gGL.popMatrix();
2846 glMatrixMode(GL_MODELVIEW);
2847 gGL.popMatrix();
2848
2849 //gGL.setSceneBlendType(LLRender::BT_ALPHA);
2850 }
2851
2434 if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) 2852 if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
2435 { 2853 {
2436 gHighlightProgram.bind(); 2854 gHighlightProgram.bind();
@@ -2453,7 +2871,7 @@ void LLPipeline::renderHighlights()
2453 LLFace *facep = mSelectedFaces[i]; 2871 LLFace *facep = mSelectedFaces[i];
2454 if (!facep || facep->getDrawable()->isDead()) 2872 if (!facep || facep->getDrawable()->isDead())
2455 { 2873 {
2456 llerrs << "Bad face on selection" << llendl; 2874 llwarns << "Bad face on selection" << llendl;
2457 return; 2875 return;
2458 } 2876 }
2459 2877
@@ -2526,7 +2944,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2526 { 2944 {
2527 if (!verify()) 2945 if (!verify())
2528 { 2946 {
2529 llerrs << "Pipeline verification failed!" << llendl; 2947 llwarns << "Pipeline verification failed!" << llendl;
2530 } 2948 }
2531 } 2949 }
2532 2950
@@ -2575,6 +2993,9 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2575 stop_glerror(); 2993 stop_glerror();
2576 2994
2577 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools"); 2995 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools");
2996 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderForSelect");
2997 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDeferred");
2998
2578 for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) 2999 for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
2579 { 3000 {
2580 LLDrawPool *poolp = *iter; 3001 LLDrawPool *poolp = *iter;
@@ -2586,7 +3007,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2586 3007
2587 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING)) 3008 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING))
2588 { 3009 {
2589 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderForSelect");
2590 gObjectList.renderObjectsForSelect(camera, gViewerWindow->getVirtualWindowRect()); 3010 gObjectList.renderObjectsForSelect(camera, gViewerWindow->getVirtualWindowRect());
2591 } 3011 }
2592 else 3012 else
@@ -2650,7 +3070,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2650 glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); 3070 glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
2651 if (depth > 3) 3071 if (depth > 3)
2652 { 3072 {
2653 llerrs << "GL matrix stack corrupted!" << llendl; 3073
3074 llwarns << "GL matrix stack corrupted!" << llendl;
2654 } 3075 }
2655 std::string msg = llformat("%s pass %d", gPoolNames[cur_type].c_str(), i); 3076 std::string msg = llformat("%s pass %d", gPoolNames[cur_type].c_str(), i);
2656 LLGLState::checkStates(msg); 3077 LLGLState::checkStates(msg);
@@ -2721,20 +3142,12 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2721 3142
2722 LLVertexBuffer::unbind(); 3143 LLVertexBuffer::unbind();
2723 3144
2724 if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred) 3145 if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
2725 { 3146 {
2726 if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) 3147 // Render debugging beacons.
2727 { 3148 gObjectList.renderObjectBeacons();
2728 // Render debugging beacons. 3149 LLHUDObject::renderAll();
2729 gObjectList.renderObjectBeacons(); 3150 gObjectList.resetObjectBeacons();
2730 LLHUDObject::renderAll();
2731 gObjectList.resetObjectBeacons();
2732 }
2733 else
2734 {
2735 // Make sure particle effects disappear
2736 LLHUDObject::renderAllForTimer();
2737 }
2738 } 3151 }
2739 3152
2740 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd"); 3153 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd");
@@ -2758,7 +3171,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
2758 3171
2759void LLPipeline::renderGeomDeferred(LLCamera& camera) 3172void LLPipeline::renderGeomDeferred(LLCamera& camera)
2760{ 3173{
2761 LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
2762 LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY); 3174 LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY);
2763 3175
2764 LLFastTimer t2(LLFastTimer::FTM_POOLS); 3176 LLFastTimer t2(LLFastTimer::FTM_POOLS);
@@ -2825,15 +3237,18 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
2825 poolp->endDeferredPass(i); 3237 poolp->endDeferredPass(i);
2826 LLVertexBuffer::unbind(); 3238 LLVertexBuffer::unbind();
2827 3239
2828 GLint depth; 3240 if (gDebugGL || gDebugPipeline)
2829 glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
2830 if (depth > 3)
2831 { 3241 {
2832 llerrs << "GL matrix stack corrupted!" << llendl; 3242 GLint depth;
3243 glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
3244 if (depth > 3)
3245 {
3246 llwarns << "GL matrix stack corrupted!" << llendl;
3247 }
3248 LLGLState::checkStates();
3249 LLGLState::checkTextureChannels();
3250 LLGLState::checkClientArrays();
2833 } 3251 }
2834 LLGLState::checkStates();
2835 LLGLState::checkTextureChannels();
2836 LLGLState::checkClientArrays();
2837 } 3252 }
2838 } 3253 }
2839 else 3254 else
@@ -2915,15 +3330,18 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
2915 poolp->endPostDeferredPass(i); 3330 poolp->endPostDeferredPass(i);
2916 LLVertexBuffer::unbind(); 3331 LLVertexBuffer::unbind();
2917 3332
2918 GLint depth; 3333 if (gDebugGL || gDebugPipeline)
2919 glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
2920 if (depth > 3)
2921 { 3334 {
2922 llerrs << "GL matrix stack corrupted!" << llendl; 3335 GLint depth;
3336 glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
3337 if (depth > 3)
3338 {
3339 llwarns << "GL matrix stack corrupted!" << llendl;
3340 }
3341 LLGLState::checkStates();
3342 LLGLState::checkTextureChannels();
3343 LLGLState::checkClientArrays();
2923 } 3344 }
2924 LLGLState::checkStates();
2925 LLGLState::checkTextureChannels();
2926 LLGLState::checkClientArrays();
2927 } 3345 }
2928 } 3346 }
2929 else 3347 else
@@ -2959,11 +3377,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
2959 LLHUDObject::renderAll(); 3377 LLHUDObject::renderAll();
2960 gObjectList.resetObjectBeacons(); 3378 gObjectList.resetObjectBeacons();
2961 } 3379 }
2962 else
2963 {
2964 // Make sure particle effects disappear
2965 LLHUDObject::renderAllForTimer();
2966 }
2967 3380
2968 if (occlude) 3381 if (occlude)
2969 { 3382 {
@@ -3067,7 +3480,7 @@ void LLPipeline::renderDebug()
3067 gGL.setColorMask(true, false); 3480 gGL.setColorMask(true, false);
3068 3481
3069 // Debug stuff. 3482 // Debug stuff.
3070 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 3483 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
3071 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 3484 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
3072 { 3485 {
3073 LLViewerRegion* region = *iter; 3486 LLViewerRegion* region = *iter;
@@ -3084,7 +3497,7 @@ void LLPipeline::renderDebug()
3084 } 3497 }
3085 } 3498 }
3086 3499
3087 for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) 3500 for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
3088 { 3501 {
3089 LLSpatialBridge* bridge = *i; 3502 LLSpatialBridge* bridge = *i;
3090 if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType)) 3503 if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType))
@@ -3098,93 +3511,88 @@ void LLPipeline::renderDebug()
3098 3511
3099 if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) 3512 if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
3100 { 3513 {
3514 LLGLEnable blend(GL_BLEND); // kl sd
3515 LLGLDepthTest depth(TRUE, FALSE);
3516 LLGLDisable cull(GL_CULL_FACE); // kl
3517
3101 gGL.color4f(1,1,1,1); 3518 gGL.color4f(1,1,1,1);
3102 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); 3519 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
3103 3520
3521 F32 a = 0.1f;
3522
3104 F32 col[] = 3523 F32 col[] =
3105 { 3524 {
3106 1,1,0, 3525 1,0,0,a,
3107 0,1,1, 3526 0,1,0,a,
3108 1,0,1, 3527 0,0,1,a,
3109 1,1,1, 3528 1,0,1,a,
3110 1,0,0, 3529
3111 0,1,0, 3530 1,1,0,a,
3112 0,0,1, 3531 0,1,1,a,
3113 0,0,0 3532 1,1,1,a,
3533 1,0,1,a,
3114 }; 3534 };
3115 3535
3116 for (U32 i = 0; i < 8; i++) 3536 for (U32 i = 0; i < 8; i++)
3117 { 3537 {
3118 gGL.color3fv(col+i*3); 3538 if (i > 3)
3119 3539 {
3120 gGL.begin(LLRender::LINES); 3540 gGL.color4fv(col+(i-4)*4);
3121
3122 LLVector3* frust = mShadowCamera[i].mAgentFrustum;
3123
3124 gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV);
3125 gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV);
3126 gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV);
3127 gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV);
3128
3129 gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV);
3130 gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV);
3131 gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV);
3132 gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV);
3133
3134 gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV);
3135 gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV);
3136 gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV);
3137 gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV);
3138 3541
3542 LLVector3* frust = mShadowCamera[i].mAgentFrustum;
3543
3544 gGL.begin(LLRender::TRIANGLE_STRIP);
3545 gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV);
3546 gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV);
3547 gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV);
3548 gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV);
3549 gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV);
3550 gGL.end();
3551
3552
3553 gGL.begin(LLRender::TRIANGLE_STRIP);
3554 gGL.vertex3fv(frust[0].mV);
3555 gGL.vertex3fv(frust[1].mV);
3556 gGL.vertex3fv(frust[3].mV);
3557 gGL.vertex3fv(frust[2].mV);
3558 gGL.end();
3559
3560 gGL.begin(LLRender::TRIANGLE_STRIP);
3561 gGL.vertex3fv(frust[4].mV);
3562 gGL.vertex3fv(frust[5].mV);
3563 gGL.vertex3fv(frust[7].mV);
3564 gGL.vertex3fv(frust[6].mV);
3565 gGL.end();
3566 }
3567
3568
3139 if (i < 4) 3569 if (i < 4)
3140 { 3570 {
3141 LLVector3* ext = mShadowExtents[i]; 3571 gGL.begin(LLRender::LINES);
3142 3572
3143 LLVector3 box[] = 3573 F32* c = col+i*4;
3574 for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j)
3144 { 3575 {
3145 LLVector3(ext[0][0], ext[0][1], ext[0][2]),
3146 LLVector3(ext[1][0], ext[0][1], ext[0][2]),
3147 LLVector3(ext[1][0], ext[1][1], ext[0][2]),
3148 LLVector3(ext[0][0], ext[1][1], ext[0][2]),
3149 LLVector3(ext[0][0], ext[0][1], ext[1][2]),
3150 LLVector3(ext[1][0], ext[0][1], ext[1][2]),
3151 LLVector3(ext[1][0], ext[1][1], ext[1][2]),
3152 LLVector3(ext[0][0], ext[1][1], ext[1][2]),
3153 };
3154 3576
3155 gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[1].mV); 3577 gGL.color3fv(c);
3156 gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[2].mV);
3157 gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[3].mV);
3158 gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[0].mV);
3159
3160 gGL.vertex3fv(box[4].mV); gGL.vertex3fv(box[5].mV);
3161 gGL.vertex3fv(box[5].mV); gGL.vertex3fv(box[6].mV);
3162 gGL.vertex3fv(box[6].mV); gGL.vertex3fv(box[7].mV);
3163 gGL.vertex3fv(box[7].mV); gGL.vertex3fv(box[4].mV);
3164
3165 gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[4].mV);
3166 gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[5].mV);
3167 gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[6].mV);
3168 gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[7].mV);
3169 }
3170 3578
3171 gGL.end(); 3579 for (U32 k = 0; k < mShadowFrustPoints[i].size(); ++k)
3172
3173 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
3174 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
3175 {
3176 LLViewerRegion* region = *iter;
3177 for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++)
3178 {
3179 LLSpatialPartition* part = region->getSpatialPartition(j);
3180 if (part)
3181 { 3580 {
3182 if (hasRenderType(part->mDrawableType)) 3581 if (j != k)
3183 { 3582 {
3184 part->renderIntersectingBBoxes(&mShadowCamera[i]); 3583 gGL.vertex3fv(mShadowFrustPoints[i][j].mV);
3584 gGL.vertex3fv(mShadowFrustPoints[i][k].mV);
3185 } 3585 }
3186 } 3586 }
3587
3588 if (!mShadowFrustOrigin[i].isExactlyZero())
3589 {
3590 gGL.vertex3fv(mShadowFrustPoints[i][j].mV);
3591 gGL.color4f(1,1,1,1);
3592 gGL.vertex3fv(mShadowFrustOrigin[i].mV);
3593 }
3187 } 3594 }
3595 gGL.end();
3188 } 3596 }
3189 } 3597 }
3190 } 3598 }
@@ -3222,6 +3630,55 @@ void LLPipeline::renderDebug()
3222 } 3630 }
3223 } 3631 }
3224 3632
3633 if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_BUILD_QUEUE)
3634 {
3635 U32 count = 0;
3636 U32 size = mBuildQ2.size();
3637 LLColor4 col;
3638
3639 LLGLEnable blend(GL_BLEND);
3640 LLGLDepthTest depth(GL_TRUE, GL_FALSE);
3641 gGL.getTexUnit(0)->bind(LLViewerImage::sWhiteImagep);
3642
3643 for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter)
3644 {
3645 LLSpatialGroup* group = *iter;
3646 if (group->isDead())
3647 {
3648 continue;
3649 }
3650
3651 LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
3652
3653 if (bridge && (!bridge->mDrawable || bridge->mDrawable->isDead()))
3654 {
3655 continue;
3656 }
3657
3658 if (bridge)
3659 {
3660 gGL.pushMatrix();
3661 glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
3662 }
3663
3664 F32 alpha = (F32) (size-count)/size;
3665
3666
3667 LLVector2 c(1.f-alpha, alpha);
3668 c.normVec();
3669
3670
3671 ++count;
3672 col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.1f);
3673 group->drawObjectBox(col);
3674
3675 if (bridge)
3676 {
3677 gGL.popMatrix();
3678 }
3679 }
3680 }
3681
3225 gGL.flush(); 3682 gGL.flush();
3226} 3683}
3227 3684
@@ -4650,7 +5107,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
4650 5107
4651 sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE; 5108 sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE;
4652 5109
4653 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 5110 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
4654 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 5111 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
4655 { 5112 {
4656 LLViewerRegion* region = *iter; 5113 LLViewerRegion* region = *iter;
@@ -4707,7 +5164,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
4707 5164
4708 //check against avatars 5165 //check against avatars
4709 sPickAvatar = TRUE; 5166 sPickAvatar = TRUE;
4710 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 5167 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
4711 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 5168 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
4712 { 5169 {
4713 LLViewerRegion* region = *iter; 5170 LLViewerRegion* region = *iter;
@@ -4784,7 +5241,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co
4784{ 5241{
4785 LLDrawable* drawable = NULL; 5242 LLDrawable* drawable = NULL;
4786 5243
4787 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 5244 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
4788 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 5245 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
4789 { 5246 {
4790 LLViewerRegion* region = *iter; 5247 LLViewerRegion* region = *iter;
@@ -4847,7 +5304,7 @@ void LLPipeline::resetVertexBuffers()
4847{ 5304{
4848 sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); 5305 sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
4849 5306
4850 for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 5307 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
4851 iter != LLWorld::getInstance()->getRegionList().end(); ++iter) 5308 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
4852 { 5309 {
4853 LLViewerRegion* region = *iter; 5310 LLViewerRegion* region = *iter;
@@ -4958,18 +5415,18 @@ void validate_framebuffer_object()
4958 break; 5415 break;
4959 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: 5416 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
4960 // frame buffer not OK: probably means unsupported depth buffer format 5417 // frame buffer not OK: probably means unsupported depth buffer format
4961 llerrs << "Framebuffer Incomplete Dimensions." << llendl; 5418 llwarns << "Framebuffer Incomplete Dimensions." << llendl;
4962 break; 5419 break;
4963 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: 5420 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
4964 // frame buffer not OK: probably means unsupported depth buffer format 5421 // frame buffer not OK: probably means unsupported depth buffer format
4965 llerrs << "Framebuffer Incomplete Attachment." << llendl; 5422 llwarns << "Framebuffer Incomplete Attachment." << llendl;
4966 break; 5423 break;
4967 case GL_FRAMEBUFFER_UNSUPPORTED_EXT: 5424 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
4968 /* choose different formats */ 5425 /* choose different formats */
4969 llerrs << "Framebuffer unsupported." << llendl; 5426 llwarns << "Framebuffer unsupported." << llendl;
4970 break; 5427 break;
4971 default: 5428 default:
4972 llerrs << "Unknown framebuffer status." << llendl; 5429 llwarns << "Unknown framebuffer status." << llendl;
4973 break; 5430 break;
4974 } 5431 }
4975} 5432}
@@ -5287,46 +5744,202 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
5287 5744
5288} 5745}
5289 5746
5290void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) 5747void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRenderTarget* gi_source, LLRenderTarget* last_gi_post) //, U32 noise_map)
5291{ 5748{
5749/* if (noise_map == 0xFFFFFFFF)
5750 {
5751 noise_map = mNoiseMap;
5752 }
5753*/
5754 LLFastTimer ftm(LLFastTimer::FTM_TEMP3);
5755 LLGLState::checkTextureChannels();
5756
5292 shader.bind(); 5757 shader.bind();
5293 S32 channel = 0; 5758 S32 channel = 0;
5294 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); 5759 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
5295 if (channel > -1) 5760 if (channel > -1)
5296 { 5761 {
5297 mDeferredScreen.bindTexture(0,channel); 5762 mDeferredScreen.bindTexture(0,channel);
5298 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 5763 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
5299 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5300 } 5764 }
5301 5765
5302 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); 5766 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE);
5303 if (channel > -1) 5767 if (channel > -1)
5304 { 5768 {
5305 mDeferredScreen.bindTexture(1, channel); 5769 mDeferredScreen.bindTexture(1, channel);
5770 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
5306 } 5771 }
5307 5772
5308 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); 5773 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE);
5309 if (channel > -1) 5774 if (channel > -1)
5310 { 5775 {
5311 mDeferredScreen.bindTexture(2, channel); 5776 mDeferredScreen.bindTexture(2, channel);
5777 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
5312 } 5778 }
5313 5779
5314 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); 5780 if (gi_source)
5315 if (channel > -1)
5316 { 5781 {
5317 mDeferredScreen.bindTexture(3, channel); 5782 BOOL has_gi = FALSE;
5783 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE);
5784 if (channel > -1)
5785 {
5786 has_gi = TRUE;
5787 gi_source->bindTexture(0, channel);
5788 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
5789 }
5790
5791 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR);
5792 if (channel > -1)
5793 {
5794 has_gi = TRUE;
5795 gi_source->bindTexture(1, channel);
5796 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
5797 }
5798
5799 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL);
5800 if (channel > -1)
5801 {
5802 has_gi = TRUE;
5803 gi_source->bindTexture(2, channel);
5804 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
5805 }
5806
5807 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS);
5808 if (channel > -1)
5809 {
5810 has_gi = TRUE;
5811 gi_source->bindTexture(1, channel);
5812 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
5813 }
5814
5815 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS);
5816 if (channel > -1)
5817 {
5818 has_gi = TRUE;
5819 gi_source->bindTexture(3, channel);
5820 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
5821 }
5822
5823 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE);
5824 if (channel > -1)
5825 {
5826 has_gi = TRUE;
5827 last_gi_post->bindTexture(0, channel);
5828 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
5829 }
5830
5831 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL);
5832 if (channel > -1)
5833 {
5834 has_gi = TRUE;
5835 last_gi_post->bindTexture(2, channel);
5836 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
5837 }
5838
5839 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS);
5840 if (channel > -1)
5841 {
5842 has_gi = TRUE;
5843 last_gi_post->bindTexture(1, channel);
5844 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
5845 }
5846
5847 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS);
5848 if (channel > -1)
5849 {
5850 has_gi = TRUE;
5851 last_gi_post->bindTexture(3, channel);
5852 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
5853 }
5854
5855 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH);
5856 if (channel > -1)
5857 {
5858 has_gi = TRUE;
5859 gGL.getTexUnit(channel)->bind(gi_source, TRUE);
5860 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
5861 stop_glerror();
5862
5863 glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
5864 glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);
5865
5866 stop_glerror();
5867 }
5868
5869 if (has_gi)
5870 {
5871 U32 gi_samples = llclamp(gSavedSettings.getU32("RenderGISamples"), (U32) 1, (U32) 8);
5872
5873 F32 range_x = llmin(mGIRange.mV[0], 1.f);
5874 F32 range_y = llmin(mGIRange.mV[1], 1.f);
5875
5876 LLVector2 scale(range_x,range_y);
5877
5878 LLVector2 kern[25];
5879
5880 for (S32 i = 0; i < 5; ++i)
5881 {
5882 for (S32 j = 0; j < 5; ++j)
5883 {
5884 S32 idx = i*5+j;
5885 kern[idx].mV[0] = (i-2)*0.5f;
5886 kern[idx].mV[1] = (j-2)*0.5f;
5887 kern[idx].scaleVec(scale);
5888 }
5889 }
5890
5891 F32 gi_radius = mGILightRadius; //gSavedSettings.getF32("RenderGILightRadius");
5892
5893 shader.uniform2f("gi_scale", scale.mV[0], scale.mV[1]);
5894 shader.uniform2fv("gi_kern", 25, (F32*) kern);
5895 shader.uniformMatrix4fv("gi_mat", 1, FALSE, mGIMatrix.m);
5896 shader.uniformMatrix4fv("gi_mat_proj", 1, FALSE, mGIMatrixProj.m);
5897 shader.uniformMatrix4fv("gi_inv_proj", 1, FALSE, mGIInvProj.m);
5898 shader.uniformMatrix4fv("gi_norm_mat", 1, FALSE, mGINormalMatrix.m);
5899 shader.uniform1f("gi_radius", gi_radius);
5900 shader.uniform1i("gi_samples", (GLint) gSavedSettings.getU32("RenderGISamples"));
5901 shader.uniform1f("gi_intensity", gSavedSettings.getF32("RenderGIIntensity")/(gi_samples*gi_samples));
5902 shader.uniform3fv("gi_quad", 1, gSavedSettings.getVector3("RenderGIColorCurve").mV);
5903 shader.uniform3fv("gi_spec", 1, gSavedSettings.getVector3("RenderGISpecularCurve").mV);
5904 shader.uniform1f("gi_direction_weight", gSavedSettings.getF32("RenderGIDirectionWeight"));
5905 shader.uniform1f("gi_light_offset", gSavedSettings.getF32("RenderGILightOffset"));
5906 shader.uniform1f("gi_blend", gFrameIntervalSeconds);
5907 }
5318 } 5908 }
5319 5909
5320 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); 5910 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);
5321 if (channel > -1) 5911 if (channel > -1)
5322 { 5912 {
5323 gGL.getTexUnit(channel)->bind(&mDeferredScreen, TRUE); 5913 gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE);
5914 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
5915 stop_glerror();
5916
5917 glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
5918 glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);
5919
5920 stop_glerror();
5921
5922 glh::matrix4f projection = glh_get_current_projection();
5923 glh::matrix4f inv_proj = projection.inverse();
5924
5925 shader.uniformMatrix4fv("inv_proj", 1, FALSE, inv_proj.m);
5926 shader.uniform4f("viewport", (F32) gGLViewport[0],
5927 (F32) gGLViewport[1],
5928 (F32) gGLViewport[2],
5929 (F32) gGLViewport[3]);
5324 } 5930 }
5325 5931
5326 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NOISE); 5932 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NOISE);
5327 if (channel > -1) 5933 if (channel > -1)
5328 { 5934 {
5329 gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); 5935 gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); // was noise_map KL
5936 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
5937 }
5938
5939 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC);
5940 if (channel > -1)
5941 {
5942 gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
5330 } 5943 }
5331 5944
5332 stop_glerror(); 5945 stop_glerror();
@@ -5335,19 +5948,68 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index)
5335 if (channel > -1) 5948 if (channel > -1)
5336 { 5949 {
5337 mDeferredLight[light_index].bindTexture(0, channel); 5950 mDeferredLight[light_index].bindTexture(0, channel);
5951 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
5952 }
5953
5954 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE);
5955 if (channel > -1)
5956 {
5957 gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true);
5958 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
5338 } 5959 }
5339 5960
5961 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
5962 if (channel > -1)
5963 {
5964 gi_source->bindTexture(0, channel);
5965 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
5966 }
5967
5968 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
5969 if (channel > -1)
5970 {
5971 mDeferredLight[1].bindTexture(0, channel);
5972 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
5973 }
5974
5975 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
5976 if (channel > -1)
5977 {
5978 mDeferredLight[2].bindTexture(0, channel);
5979 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
5980 }
5981
5982
5340 stop_glerror(); 5983 stop_glerror();
5341 5984
5342 for (U32 i = 0; i < 4; i++) 5985 for (U32 i = 0; i < 4; i++)
5343 { 5986 {
5987 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE);
5988 stop_glerror();
5989 if (channel > -1)
5990 {
5991 stop_glerror();
5992 gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE);
5993 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
5994 gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
5995 stop_glerror();
5996
5997 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
5998 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
5999 stop_glerror();
6000 }
6001 }
6002
6003 for (U32 i = 4; i < 6; i++)
6004 {
5344 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i); 6005 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i);
5345 stop_glerror(); 6006 stop_glerror();
5346 if (channel > -1) 6007 if (channel > -1)
5347 { 6008 {
5348 stop_glerror(); 6009 stop_glerror();
5349 gGL.getTexUnit(channel)->bind(&mSunShadow[i], TRUE); 6010 gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE);
5350 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); 6011 gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
6012 gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
5351 stop_glerror(); 6013 stop_glerror();
5352 6014
5353 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); 6015 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
@@ -5358,17 +6020,19 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index)
5358 6020
5359 stop_glerror(); 6021 stop_glerror();
5360 6022
5361 F32 mat[64]; 6023 F32 mat[16*6];
5362 for (U32 i = 0; i < 16; i++) 6024 for (U32 i = 0; i < 16; i++)
5363 { 6025 {
5364 mat[i] = mSunShadowMatrix[0].m[i]; 6026 mat[i] = mSunShadowMatrix[0].m[i];
5365 mat[i+16] = mSunShadowMatrix[1].m[i]; 6027 mat[i+16] = mSunShadowMatrix[1].m[i];
5366 mat[i+32] = mSunShadowMatrix[2].m[i]; 6028 mat[i+32] = mSunShadowMatrix[2].m[i];
5367 mat[i+48] = mSunShadowMatrix[3].m[i]; 6029 mat[i+48] = mSunShadowMatrix[3].m[i];
6030 mat[i+64] = mSunShadowMatrix[4].m[i];
6031 mat[i+80] = mSunShadowMatrix[5].m[i];
5368 } 6032 }
5369 6033
5370 shader.uniformMatrix4fv("shadow_matrix[0]", 4, FALSE, mat); 6034 shader.uniformMatrix4fv("shadow_matrix[0]", 6, FALSE, mat);
5371 shader.uniformMatrix4fv("shadow_matrix", 4, FALSE, mat); 6035 shader.uniformMatrix4fv("shadow_matrix", 6, FALSE, mat);
5372 6036
5373 stop_glerror(); 6037 stop_glerror();
5374 6038
@@ -5417,8 +6081,23 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index)
5417 shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); 6081 shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
5418 shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f); 6082 shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f);
5419 shader.uniform1f("alpha_soften", gSavedSettings.getF32("RenderDeferredAlphaSoften")); 6083 shader.uniform1f("alpha_soften", gSavedSettings.getF32("RenderDeferredAlphaSoften"));
6084 shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset"));
6085 shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias"));
6086/* shader.uniform3fv("gi_quad", 1, gSavedSettings.getVector3("RenderGIColorCurve").mV);
6087 shader.uniform3fv("lum_quad", 1, gSavedSettings.getVector3("RenderLuminanceColorCurve").mV);
6088 shader.uniform3fv("gi_lum_quad", 1, gSavedSettings.getVector3("RenderGILuminanceColorCurve").mV);
6089 shader.uniform3fv("sun_lum_quad", 1, gSavedSettings.getVector3("RenderSunLuminanceColorCurve").mV);
6090 shader.uniform1f("lum_lod", gSavedSettings.getF32("RenderLuminanceDetail"));
6091 shader.uniform1f("gi_range", gSavedSettings.getF32("RenderGIRange"));
6092
6093 if (shader.getUniformLocation("norm_mat") >= 0)
6094 {
6095 glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose();
6096 shader.uniformMatrix4fv("norm_mat", 1, FALSE, norm_mat.m);
6097 } */
5420} 6098}
5421 6099
6100// KL The Deffered Pipeline begins here!
5422void LLPipeline::renderDeferredLighting() 6101void LLPipeline::renderDeferredLighting()
5423{ 6102{
5424 if (!sCull) 6103 if (!sCull)
@@ -5426,6 +6105,12 @@ void LLPipeline::renderDeferredLighting()
5426 return; 6105 return;
5427 } 6106 }
5428 6107
6108 {
6109 LLGLDepthTest depth(GL_TRUE);
6110 mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
6111 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
6112 }
6113
5429 LLGLEnable multisample(GL_MULTISAMPLE_ARB); 6114 LLGLEnable multisample(GL_MULTISAMPLE_ARB);
5430 6115
5431 if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) 6116 if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
@@ -5439,16 +6124,10 @@ void LLPipeline::renderDeferredLighting()
5439 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 6124 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
5440 6125
5441 gGL.setColorMask(true, true); 6126 gGL.setColorMask(true, true);
5442
5443 mDeferredLight[0].bindTarget();
5444
5445 //mDeferredLight[0].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
5446 // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
5447 6127
5448 //draw a cube around every light 6128 //draw a cube around every light
5449 LLVertexBuffer::unbind(); 6129 LLVertexBuffer::unbind();
5450 6130
5451 glBlendFunc(GL_ONE, GL_ONE);
5452 LLGLEnable cull(GL_CULL_FACE); 6131 LLGLEnable cull(GL_CULL_FACE);
5453 LLGLEnable blend(GL_BLEND); 6132 LLGLEnable blend(GL_BLEND);
5454 6133
@@ -5460,126 +6139,271 @@ void LLPipeline::renderDeferredLighting()
5460 -1,-3, 6139 -1,-3,
5461 3,1, 6140 3,1,
5462 }; 6141 };
6142 glVertexPointer(2, GL_FLOAT, 0, vert);
6143 glColor3f(1,1,1);
6144 //Set mSunDir KL This makes sense to have it here. Still calculated EVEN if Deferred Sun is FALSE!
6145 {
6146 setupHWLights(NULL); //to set mSunDir;
6147 LLVector4 dir(mSunDir, 0.f);
6148 glh::vec4f tc(dir.mV);
6149 mat.mult_matrix_vec(tc);
6150 glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);
6151 }
6152
6153 if (gSavedSettings.getBOOL("RenderDeferredShadow"))
6154 {
6155 glPushMatrix();
6156 glLoadIdentity();
6157 glMatrixMode(GL_PROJECTION);
6158 glPushMatrix();
6159 glLoadIdentity();
5463 6160
5464 bindDeferredShader(gDeferredSunProgram); 6161 mDeferredLight[0].bindTarget();
6162// KL Bind to 0 next section Deferred Sun !
6163 if (gSavedSettings.getBOOL("RenderDeferredSun"))
6164 { //paint shadow/SSAO light map (direct lighting lightmap)
6165 bindDeferredShader(gDeferredSunProgram, 0);
5465 6166
5466 glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); 6167 glClearColor(1,1,1,1);
6168 mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT);
6169 glClearColor(0,0,0,0);
5467 6170
5468 const U32 slice = 32; 6171 glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
5469 F32 offset[slice*3]; 6172
5470 for (U32 i = 0; i < 4; i++) 6173 const U32 slice = 32;
5471 { 6174 F32 offset[slice*3];
5472 for (U32 j = 0; j < 8; j++) 6175 for (U32 i = 0; i < 4; i++)
6176 {
6177 for (U32 j = 0; j < 8; j++)
6178 {
6179 glh::vec3f v;
6180 v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i);
6181 v.normalize();
6182 inv_trans.mult_matrix_vec(v);
6183 v.normalize();
6184 offset[(i*8+j)*3+0] = v.v[0];
6185 offset[(i*8+j)*3+1] = v.v[2];
6186 offset[(i*8+j)*3+2] = v.v[1];
6187 }
6188 }
6189
6190 gDeferredSunProgram.uniform3fv("offset", slice, offset);
6191 gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight());
6192
5473 { 6193 {
5474 glh::vec3f v; 6194 LLGLDisable blend(GL_BLEND);
5475 v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); 6195 LLGLDepthTest depth(GL_FALSE);
5476 v.normalize(); 6196 stop_glerror();
5477 inv_trans.mult_matrix_vec(v); 6197 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
5478 v.normalize(); 6198 stop_glerror();
5479 offset[(i*8+j)*3+0] = v.v[0];
5480 offset[(i*8+j)*3+1] = v.v[2];
5481 offset[(i*8+j)*3+2] = v.v[1];
5482 } 6199 }
6200
6201 unbindDeferredShader(gDeferredSunProgram);
6202 }
6203 else
6204 {
6205 mDeferredLight[0].clear();
5483 } 6206 }
5484 6207
5485 gDeferredSunProgram.uniform3fv("offset", slice, offset); 6208 mDeferredLight[0].flush();
5486 gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); 6209 mDeferredLight[1].bindTarget();
6210 }
6211// KL Bind to 1 next section GI
6212/* if (gSavedSettings.getBOOL("RenderDeferredGI"))
6213 {
6214 { //get luminance map from previous frame's light map
6215 LLGLEnable blend(GL_BLEND);
6216 LLGLDisable test(GL_ALPHA_TEST);
6217 LLGLDepthTest depth(GL_FALSE);
6218 LLGLDisable stencil(GL_STENCIL_TEST);
5487 6219
5488 setupHWLights(NULL); //to set mSunDir; 6220 //static F32 fade = 1.f;
5489 6221
5490 glPushMatrix(); 6222 F32 fade = gSavedSettings.getF32("RenderLuminanceFade");
5491 glLoadIdentity(); 6223 {
5492 glMatrixMode(GL_PROJECTION); 6224 gGL.setSceneBlendType(LLRender::BT_ALPHA);
5493 glPushMatrix(); 6225 gLuminanceGatherProgram.bind();
5494 glLoadIdentity(); 6226 gLuminanceGatherProgram.uniform2f("screen_res", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight());
6227 gLuminanceGatherProgram.uniform1f("fade", llclamp(fade, 0.f, 1.f));
6228 mLuminanceMap.bindTarget();
6229 gGL.getTexUnit(0)->bind(&mDeferredLight[0]);
6230 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
6231 gLuminanceGatherProgram.unbind();
6232 mLuminanceMap.flush();
6233 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true);
6234 gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
6235 glGenerateMipmapEXT(GL_TEXTURE_2D);
6236 }
5495 6237
5496 LLVector4 dir(mSunDir, 0.f); 6238 }
5497 6239
5498 glh::vec4f tc(dir.mV); 6240 { //paint noisy GI map (bounce lighting lightmap)
5499 mat.mult_matrix_vec(tc); 6241 LLGLDisable blend(GL_BLEND);
5500 glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); 6242 LLGLDepthTest depth(GL_FALSE);
5501 glColor3f(1,1,1); 6243 LLGLDisable test(GL_ALPHA_TEST);
5502 6244
5503 glVertexPointer(2, GL_FLOAT, 0, vert); 6245 mGIMapPost[0].bindTarget();
5504 {
5505 LLGLDisable blend(GL_BLEND);
5506 LLGLDepthTest depth(GL_FALSE);
5507 stop_glerror();
5508 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
5509 stop_glerror();
5510 }
5511
5512 unbindDeferredShader(gDeferredSunProgram);
5513 6246
5514 mDeferredLight[0].flush(); 6247 bindDeferredShader(gDeferredGIProgram, 0, &mGIMap, 0);//, mTrueNoiseMap);
6248 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
6249 unbindDeferredShader(gDeferredGIProgram);
6250 mGIMapPost[0].flush();
5515 6251
5516 //blur lightmap
5517 mDeferredLight[1].bindTarget();
5518 6252
5519 //mDeferredLight[1].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), 6253 }
5520 // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
5521
5522 bindDeferredShader(gDeferredBlurLightProgram);
5523 6254
5524 LLVector3 gauss[32]; // xweight, yweight, offset 6255 U32 pass_count = 0;
6256 if (gSavedSettings.getBOOL("RenderDeferredBlurLight"))
6257 {
6258 pass_count = llclamp(gSavedSettings.getU32("RenderGIBlurPasses"), (U32) 1, (U32) 128);
6259 }
5525 6260
5526 LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); 6261 for (U32 i = 0; i < pass_count; ++i)
5527 U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1; 6262 { //gather/soften indirect lighting map
5528 F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); 6263 bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[0], NULL); //, mTrueNoiseMap);
5529 6264
5530 // sample symmetrically with the middle sample falling exactly on 0.0 6265 LLVector2 gauss[32]; // xweight, yweight, offset
5531 F32 x = -(kern_length/2.0f) + 0.5f;
5532 6266
5533 for (U32 i = 0; i < kern_length; i++) 6267 F32 sc = 1.f;
5534 {
5535 gauss[i].mV[0] = llgaussian(x, go.mV[0]);
5536 gauss[i].mV[1] = llgaussian(x, go.mV[1]);
5537 gauss[i].mV[2] = x;
5538 x += 1.f;
5539 }
5540 /* swap the x=0 position to the start of gauss[] so we can
5541 treat it specially as an optimization. */
5542 LLVector3 swap;
5543 swap = gauss[kern_length/2];
5544 gauss[kern_length/2] = gauss[0];
5545 gauss[0] = swap;
5546 llassert(gauss[0].mV[2] == 0.0f);
5547 6268
5548 gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); 6269 F32 go = gSavedSettings.getF32("RenderGIGaussian");
5549 gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); 6270 U32 kern_length = llclamp(gSavedSettings.getU32("RenderGIBlurSamples"), (U32) 1, (U32) 16)*2 - 1;
5550 gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); 6271 F32 blur_size = gSavedSettings.getF32("RenderGIBlurSize")*sc;
5551 gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); 6272 F32 dist_factor = gSavedSettings.getF32("RenderGIBlurDistFactor");
5552 gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
5553 6273
5554 { 6274 // sample symmetrically with the middle sample falling exactly on 0.0
5555 LLGLDisable blend(GL_BLEND); 6275 F32 x = -(kern_length/2.0f) + 0.5f;
5556 LLGLDepthTest depth(GL_FALSE); 6276
5557 stop_glerror(); 6277 for (U32 i = 0; i < kern_length; i++)
5558 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); 6278 {
5559 stop_glerror(); 6279 gauss[i].mV[0] = llgaussian(x, go);
5560 } 6280 gauss[i].mV[1] = x;
5561 6281 x += 1.f;
5562 mDeferredLight[1].flush(); 6282 }
5563 unbindDeferredShader(gDeferredBlurLightProgram); 6283 // swap the x=0 position to the start of gauss[] so we can
6284 // treat it specially as an optimization.
6285 LLVector2 swap;
6286 swap = gauss[kern_length/2];
6287 gauss[kern_length/2] = gauss[0];
6288 gauss[0] = swap;
6289 llassert(gauss[0].mV[2] == 0.0f);
6290
6291 gDeferredPostGIProgram.uniform2f("delta", 1.f, 0.f);
6292 gDeferredPostGIProgram.uniform1f("dist_factor", dist_factor);
6293 gDeferredPostGIProgram.uniform2fv("kern[0]", kern_length, gauss[0].mV);
6294 gDeferredPostGIProgram.uniform2fv("kern", kern_length, gauss[0].mV);
6295 gDeferredPostGIProgram.uniform1i("kern_length", kern_length);
6296 gDeferredPostGIProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
6297 gDeferredPostGIProgram.uniform3fv("blur_quad", 1, gSavedSettings.getVector3("RenderGIBlurColorCurve").mV);
6298
6299 mGIMapPost[1].bindTarget();
6300 {
6301 LLGLDisable blend(GL_BLEND);
6302 LLGLDepthTest depth(GL_FALSE);
6303 stop_glerror();
6304 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
6305 stop_glerror();
6306 }
6307
6308 mGIMapPost[1].flush();
6309 unbindDeferredShader(gDeferredPostGIProgram);
5564 6310
5565 bindDeferredShader(gDeferredBlurLightProgram, 1); 6311 bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[1], NULL);//, mTrueNoiseMap);
5566 mDeferredLight[0].bindTarget(); 6312 mGIMapPost[0].bindTarget();
5567 6313
5568 gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); 6314 gDeferredPostGIProgram.uniform2f("delta", 0.f, 1.f);
5569 gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); 6315 gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor);
5570 gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); 6316 gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV);
5571 gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); 6317 gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
5572 gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); 6318 gDeferredBlurLightProgram.uniform1i("kern_length", kern_length);
6319 gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
5573 6320
5574 { 6321 {
5575 LLGLDisable blend(GL_BLEND); 6322 LLGLDisable blend(GL_BLEND);
5576 LLGLDepthTest depth(GL_FALSE); 6323 LLGLDepthTest depth(GL_FALSE);
5577 stop_glerror(); 6324 stop_glerror();
5578 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 6325 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5579 stop_glerror(); 6326 stop_glerror();
5580 } 6327 }
6328 mGIMapPost[0].flush();
6329 unbindDeferredShader(gDeferredPostGIProgram);
6330 }
6331 } */
6332
6333 if (gSavedSettings.getBOOL("RenderDeferredBlurLight"))
6334 { //soften direct lighting lightmap
6335 //blur lightmap
6336 mDeferredLight[1].bindTarget();
6337
6338 glClearColor(1,1,1,1);
6339 mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT);
6340 glClearColor(0,0,0,0);
6341
6342 bindDeferredShader(gDeferredBlurLightProgram);
6343
6344 LLVector3 gauss[32]; // xweight, yweight, offset
6345
6346 LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian");
6347 U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1;
6348 F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize");
6349 F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
6350
6351 // sample symmetrically with the middle sample falling exactly on 0.0
6352 F32 x = -(kern_length/2.0f) + 0.5f;
6353
6354 for (U32 i = 0; i < kern_length; i++)
6355 {
6356 gauss[i].mV[0] = llgaussian(x, go.mV[0]);
6357 gauss[i].mV[1] = llgaussian(x, go.mV[1]);
6358 gauss[i].mV[2] = x;
6359 x += 1.f;
6360 }
6361 /* swap the x=0 position to the start of gauss[] so we can
6362 treat it specially as an optimization. */
6363 LLVector3 swap;
6364 swap = gauss[kern_length/2];
6365 gauss[kern_length/2] = gauss[0];
6366 gauss[0] = swap;
6367 llassert(gauss[0].mV[2] == 0.0f);
6368
6369 gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f);
6370 gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor);
6371 gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV);
6372 gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
6373 gDeferredBlurLightProgram.uniform1i("kern_length", kern_length);
6374 gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
6375
6376 {
6377 LLGLDisable blend(GL_BLEND);
6378 LLGLDepthTest depth(GL_FALSE);
6379 stop_glerror();
6380 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
6381 stop_glerror();
6382 }
6383
6384 mDeferredLight[1].flush();
6385 unbindDeferredShader(gDeferredBlurLightProgram);
6386
6387 bindDeferredShader(gDeferredBlurLightProgram, 1);
6388 mDeferredLight[0].bindTarget();
6389
6390 gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f);
6391 gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor);
6392 gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV);
6393 gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
6394 gDeferredBlurLightProgram.uniform1i("kern_length", kern_length);
6395 gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
6396
6397 {
6398 LLGLDisable blend(GL_BLEND);
6399 LLGLDepthTest depth(GL_FALSE);
6400 stop_glerror();
6401 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); // KL 4?
6402 stop_glerror();
6403 }
5581 mDeferredLight[0].flush(); 6404 mDeferredLight[0].flush();
5582 unbindDeferredShader(gDeferredBlurLightProgram); 6405 unbindDeferredShader(gDeferredBlurLightProgram);
6406 }
5583 6407
5584 stop_glerror(); 6408 stop_glerror();
5585 glPopMatrix(); 6409 glPopMatrix();
@@ -5588,15 +6412,26 @@ void LLPipeline::renderDeferredLighting()
5588 stop_glerror(); 6412 stop_glerror();
5589 glPopMatrix(); 6413 glPopMatrix();
5590 stop_glerror(); 6414 stop_glerror();
6415// }
5591 6416
5592 //copy depth and stencil from deferred screen 6417 //copy depth and stencil from deferred screen
5593 //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), 6418 //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
5594 // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); 6419 // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
5595 6420
5596 mScreen.bindTarget(); 6421/* if (gSavedSettings.getBOOL("RenderDeferredGI"))
5597 mScreen.clear(GL_COLOR_BUFFER_BIT); 6422 {
5598 6423 mDeferredLight[1].bindTarget();
5599 bindDeferredShader(gDeferredSoftenProgram); 6424 mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT);
6425 }
6426 else
6427 { */
6428 mScreen.bindTarget();
6429 mScreen.clear(GL_COLOR_BUFFER_BIT);
6430// }
6431
6432 if (gSavedSettings.getBOOL("RenderDeferredAtmospheric"))
6433 { //apply sunlight contribution
6434 bindDeferredShader(gDeferredSoftenProgram, 0, &mGIMapPost[0]); // may not be using GI but still need this KL
5600 { 6435 {
5601 LLGLDepthTest depth(GL_FALSE); 6436 LLGLDepthTest depth(GL_FALSE);
5602 LLGLDisable blend(GL_BLEND); 6437 LLGLDisable blend(GL_BLEND);
@@ -5619,130 +6454,330 @@ void LLPipeline::renderDeferredLighting()
5619 } 6454 }
5620 6455
5621 unbindDeferredShader(gDeferredSoftenProgram); 6456 unbindDeferredShader(gDeferredSoftenProgram);
6457 }
6458// KL this code is a tad buggered atm it obliterates local lights......
6459/* { //render sky/water/hair/skirts
6460 LLGLDisable blend(GL_BLEND);
6461 LLGLDisable stencil(GL_STENCIL_TEST);
6462 gGL.setSceneBlendType(LLRender::BT_ALPHA);
5622 6463
5623 bindDeferredShader(gDeferredLightProgram); 6464 U32 render_mask = mRenderTypeMask;
5624 6465 mRenderTypeMask = mRenderTypeMask &
5625 std::list<LLVector4> fullscreen_lights; 6466 ((1 << LLPipeline::RENDER_TYPE_SKY) |
5626 std::list<LLVector4> light_colors; 6467 (1 << LLPipeline::RENDER_TYPE_CLOUDS) |
6468 (1 << LLPipeline::RENDER_TYPE_WL_SKY) |
6469 (1 << LLPipeline::RENDER_TYPE_AVATAR) |
6470 (1 << LLPipeline::RENDER_TYPE_WATER));
6471
6472 renderGeomPostDeferred(*LLViewerCamera::getInstance());
6473 mRenderTypeMask = render_mask;
6474 } */
5627 6475
5628 F32 v[24]; 6476 BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights");
5629 glVertexPointer(3, GL_FLOAT, 0, v); 6477 BOOL render_fullscreen = gSavedSettings.getBOOL("RenderDeferredFullscreenLights");
6478
6479/*
6480 if (gSavedSettings.getBOOL("RenderDeferredGI"))
5630 { 6481 {
5631 LLGLDepthTest depth(GL_TRUE, GL_FALSE); 6482 mDeferredLight[1].flush();
5632 for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) 6483 mDeferredLight[2].bindTarget();
6484 mDeferredLight[2].clear(GL_COLOR_BUFFER_BIT);
6485 }
6486*/
6487 if (render_local || render_fullscreen)
6488 {
6489 gGL.setSceneBlendType(LLRender::BT_ADD);
6490 std::list<LLVector4> fullscreen_lights;
6491 LLDrawable::drawable_list_t spot_lights;
6492 LLDrawable::drawable_list_t fullscreen_spot_lights;
6493
6494 for (U32 i = 0; i < 2; i++)
5633 { 6495 {
5634 LLDrawable* drawablep = *iter; 6496 mTargetShadowSpotLight[i] = NULL;
5635 6497 }
5636 LLVOVolume* volume = drawablep->getVOVolume(); 6498
5637 if (!volume) 6499 std::list<LLVector4> light_colors;
6500
6501 F32 v[24];
6502 glVertexPointer(3, GL_FLOAT, 0, v);
6503 BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights");
6504
6505 {
6506 bindDeferredShader(gDeferredLightProgram);
6507 LLGLDepthTest depth(GL_TRUE, GL_FALSE);
6508 for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
5638 { 6509 {
5639 continue; 6510 LLDrawable* drawablep = *iter;
6511
6512 LLVOVolume* volume = drawablep->getVOVolume();
6513 if (!volume)
6514 {
6515 continue;
6516 }
6517
6518 LLVector3 center = drawablep->getPositionAgent();
6519 F32* c = center.mV;
6520 F32 s = volume->getLightRadius()*1.5f;
6521
6522 LLColor3 col = volume->getLightColor();
6523 col *= volume->getLightIntensity();
6524
6525 if (col.magVecSquared() < 0.001f)
6526 {
6527 continue;
6528 }
6529
6530 if (s <= 0.001f)
6531 {
6532 continue;
6533 }
6534
6535 if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0)
6536 {
6537 continue;
6538 }
6539
6540 sVisibleLightCount++;
6541
6542 glh::vec3f tc(c);
6543 mat.mult_matrix_vec(tc);
6544
6545 //vertex positions are encoded so the 3 bits of their vertex index
6546 //correspond to their axis facing, with bit position 3,2,1 matching
6547 //axis facing x,y,z, bit set meaning positive facing, bit clear
6548 //meaning negative facing
6549 v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000
6550 v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001
6551 v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010
6552 v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011
6553
6554 v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100
6555 v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101
6556 v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110
6557 v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111
6558
6559 if (LLViewerCamera::getInstance()->getOrigin().mV[0] > c[0] + s + 0.2f ||
6560 LLViewerCamera::getInstance()->getOrigin().mV[0] < c[0] - s - 0.2f ||
6561 LLViewerCamera::getInstance()->getOrigin().mV[1] > c[1] + s + 0.2f ||
6562 LLViewerCamera::getInstance()->getOrigin().mV[1] < c[1] - s - 0.2f ||
6563 LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f ||
6564 LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f)
6565 { //draw box if camera is outside box
6566 if (render_local)
6567 {
6568 if (volume->getLightTexture())
6569 {
6570 drawablep->getVOVolume()->updateSpotLightPriority();
6571 spot_lights.push_back(drawablep);
6572 continue;
6573 }
6574
6575 glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
6576 glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
6577 glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
6578 GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center));
6579 }
6580 }
6581 else if (render_fullscreen)
6582 {
6583 if (volume->getLightTexture())
6584 {
6585 drawablep->getVOVolume()->updateSpotLightPriority();
6586 fullscreen_spot_lights.push_back(drawablep);
6587 continue;
6588 }
6589
6590 fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s));
6591 light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
6592 }
5640 } 6593 }
6594 unbindDeferredShader(gDeferredLightProgram);
6595 }
6596
6597 if (!spot_lights.empty())
6598 {
6599 LLGLDepthTest depth(GL_TRUE, GL_FALSE);
6600 bindDeferredShader(gDeferredSpotLightProgram);
5641 6601
5642 LLVector3 center = drawablep->getPositionAgent(); 6602 gDeferredSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
5643 F32* c = center.mV;
5644 F32 s = volume->getLightRadius()*1.5f;
5645 6603
5646 if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) 6604 for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
5647 { 6605 {
5648 continue; 6606 LLDrawable* drawablep = *iter;
5649 } 6607
6608 LLVOVolume* volume = drawablep->getVOVolume();
6609
6610 LLVector3 center = drawablep->getPositionAgent();
6611 F32* c = center.mV;
6612 F32 s = volume->getLightRadius()*1.5f;
6613
6614 sVisibleLightCount++;
6615
6616 glh::vec3f tc(c);
6617 mat.mult_matrix_vec(tc);
6618
6619 setupSpotLight(gDeferredSpotLightProgram, drawablep);
6620
6621 LLColor3 col = volume->getLightColor();
6622 col *= volume->getLightIntensity();
6623
6624 //vertex positions are encoded so the 3 bits of their vertex index
6625 //correspond to their axis facing, with bit position 3,2,1 matching
6626 //axis facing x,y,z, bit set meaning positive facing, bit clear
6627 //meaning negative facing
6628 v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000
6629 v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001
6630 v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010
6631 v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011
6632
6633 v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100
6634 v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101
6635 v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110
6636 v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111
5650 6637
5651 sVisibleLightCount++;
5652 glh::vec3f tc(c);
5653 mat.mult_matrix_vec(tc);
5654
5655 LLColor3 col = volume->getLightColor();
5656 col *= volume->getLightIntensity();
5657
5658 //vertex positions are encoded so the 3 bits of their vertex index
5659 //correspond to their axis facing, with bit position 3,2,1 matching
5660 //axis facing x,y,z, bit set meaning positive facing, bit clear
5661 //meaning negative facing
5662 v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000
5663 v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001
5664 v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010
5665 v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011
5666
5667 v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100
5668 v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101
5669 v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110
5670 v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111
5671
5672 if (LLViewerCamera::getInstance()->getOrigin().mV[0] > c[0] + s + 0.2f ||
5673 LLViewerCamera::getInstance()->getOrigin().mV[0] < c[0] - s - 0.2f ||
5674 LLViewerCamera::getInstance()->getOrigin().mV[1] > c[1] + s + 0.2f ||
5675 LLViewerCamera::getInstance()->getOrigin().mV[1] < c[1] - s - 0.2f ||
5676 LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f ||
5677 LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f)
5678 { //draw box if camera is outside box
5679 glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); 6638 glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
5680 glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); 6639 glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
5681 glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, 6640 glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
5682 GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center)); 6641 GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center));
5683 }
5684 else
5685 {
5686 fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s));
5687 light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
5688 } 6642 }
6643 gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
6644 unbindDeferredShader(gDeferredSpotLightProgram);
5689 } 6645 }
5690 }
5691 6646
5692 unbindDeferredShader(gDeferredLightProgram); 6647 {
6648 bindDeferredShader(gDeferredMultiLightProgram);
6649
6650 LLGLDepthTest depth(GL_FALSE);
5693 6651
5694 if (!fullscreen_lights.empty()) 6652 //full screen blit
5695 { 6653 glPushMatrix();
5696 bindDeferredShader(gDeferredMultiLightProgram); 6654 glLoadIdentity();
5697 LLGLDepthTest depth(GL_FALSE); 6655 glMatrixMode(GL_PROJECTION);
6656 glPushMatrix();
6657 glLoadIdentity();
5698 6658
5699 //full screen blit 6659 U32 count = 0;
5700 glPushMatrix();
5701 glLoadIdentity();
5702 glMatrixMode(GL_PROJECTION);
5703 glPushMatrix();
5704 glLoadIdentity();
5705 6660
5706 U32 count = 0; 6661 const U32 max_count = 8; // KL poss 16?
6662 LLVector4 light[max_count];
6663 LLVector4 col[max_count];
5707 6664
5708 LLVector4 light[16]; 6665 glVertexPointer(2, GL_FLOAT, 0, vert);
5709 LLVector4 col[16];
5710 6666
5711 glVertexPointer(2, GL_FLOAT, 0, vert); 6667 F32 far_z = 0.f;
5712 6668
5713 while (!fullscreen_lights.empty()) 6669 while (!fullscreen_lights.empty())
5714 { 6670 {
5715 light[count] = fullscreen_lights.front(); 6671 light[count] = fullscreen_lights.front();
5716 fullscreen_lights.pop_front(); 6672 fullscreen_lights.pop_front();
5717 col[count] = light_colors.front(); 6673 col[count] = light_colors.front();
5718 light_colors.pop_front(); 6674 light_colors.pop_front();
5719 6675
5720 count++; 6676 far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z);
5721 if (count == 16 || fullscreen_lights.empty()) 6677
6678 count++;
6679 if (count == max_count || fullscreen_lights.empty())
6680 {
6681 gDeferredMultiLightProgram.uniform1i("light_count", count);
6682 gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light);
6683 gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light);
6684 gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col);
6685 gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col);
6686 gDeferredMultiLightProgram.uniform1f("far_z", far_z);
6687 far_z = 0.f;
6688 count = 0;
6689 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
6690 }
6691 }
6692
6693 unbindDeferredShader(gDeferredMultiLightProgram);
6694
6695 bindDeferredShader(gDeferredMultiSpotLightProgram);
6696
6697 gDeferredMultiSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
6698
6699 for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
5722 { 6700 {
5723 gDeferredMultiLightProgram.uniform1i("light_count", count); 6701 LLDrawable* drawablep = *iter;
5724 gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); 6702
5725 gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light); 6703 LLVOVolume* volume = drawablep->getVOVolume();
5726 gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col); 6704
5727 gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); 6705 LLVector3 center = drawablep->getPositionAgent();
5728 count = 0; 6706 F32* c = center.mV;
6707 F32 s = volume->getLightRadius()*1.5f;
6708
6709 sVisibleLightCount++;
6710
6711 glh::vec3f tc(c);
6712 mat.mult_matrix_vec(tc);
6713
6714 setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
6715
6716 LLColor3 col = volume->getLightColor();
6717 col *= volume->getLightIntensity();
6718
6719 glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
6720 glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
5729 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); 6721 glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
5730 } 6722 }
5731 }
5732
5733
5734 glPopMatrix();
5735 glMatrixMode(GL_MODELVIEW);
5736 glPopMatrix();
5737 6723
5738 unbindDeferredShader(gDeferredMultiLightProgram); 6724 gDeferredMultiSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
6725 unbindDeferredShader(gDeferredMultiSpotLightProgram);
6726
6727 glPopMatrix();
6728 glMatrixMode(GL_MODELVIEW);
6729 glPopMatrix();
6730 }
5739 } 6731 }
6732
5740 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 6733 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6734 gGL.setColorMask(true, true);
6735/*
6736 if (gSavedSettings.getBOOL("RenderDeferredGI"))
6737 {
6738 mDeferredLight[2].flush();
6739 mScreen.bindTarget();
6740 mScreen.clear(GL_COLOR_BUFFER_BIT);
6741
6742 gGL.setSceneBlendType(LLRender::BT_ALPHA);
6743
6744 { //mix various light maps (local, sun, gi)
6745 LLGLDisable blend(GL_BLEND);
6746 LLGLDisable test(GL_ALPHA_TEST);
6747 LLGLDepthTest depth(GL_FALSE);
6748 LLGLDisable stencil(GL_STENCIL_TEST);
6749
6750 gViewerWindow->setupViewport();
6751
6752 bindDeferredShader(gDeferredPostProgram, 0, &mGIMapPost[0]);
6753
6754 gDeferredPostProgram.bind();
6755
6756 LLVertexBuffer::unbind();
6757
6758 glVertexPointer(2, GL_FLOAT, 0, vert);
6759 glColor3f(1,1,1);
5741 6760
5742 { //render non-deferred geometry 6761 glPushMatrix();
6762 glLoadIdentity();
6763 glMatrixMode(GL_PROJECTION);
6764 glPushMatrix();
6765 glLoadIdentity();
6766
6767 glDrawArrays(GL_TRIANGLES, 0, 3);
6768
6769 glPopMatrix();
6770 glMatrixMode(GL_MODELVIEW);
6771 glPopMatrix();
6772
6773 unbindDeferredShader(gDeferredPostProgram);
6774 }
6775 }
6776*/
6777 { //render non-deferred geometry (alpha, fullbright, glow) KL issues with render pipeline merge needs work.. here
5743 LLGLDisable blend(GL_BLEND); 6778 LLGLDisable blend(GL_BLEND);
5744 LLGLDisable stencil(GL_STENCIL_TEST); 6779 LLGLDisable stencil(GL_STENCIL_TEST);
5745 6780 gGL.setSceneBlendType(LLRender::BT_ALPHA);
5746 U32 render_mask = mRenderTypeMask; 6781 U32 render_mask = mRenderTypeMask;
5747 mRenderTypeMask = mRenderTypeMask & 6782 mRenderTypeMask = mRenderTypeMask &
5748 ((1 << LLPipeline::RENDER_TYPE_SKY) | 6783 ((1 << LLPipeline::RENDER_TYPE_SKY) |
@@ -5754,18 +6789,161 @@ void LLPipeline::renderDeferredLighting()
5754 (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) | 6789 (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) |
5755 (1 << LLPipeline::RENDER_TYPE_VOLUME) | 6790 (1 << LLPipeline::RENDER_TYPE_VOLUME) |
5756 (1 << LLPipeline::RENDER_TYPE_GLOW) | 6791 (1 << LLPipeline::RENDER_TYPE_GLOW) |
5757 (1 << LLPipeline::RENDER_TYPE_BUMP)); 6792 (1 << LLPipeline::RENDER_TYPE_BUMP) |
6793 (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) |
6794 (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) |
6795 (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) |
6796 (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) |
6797 (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) |
6798 (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) |
6799 (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) |
6800 (1 << LLPipeline::RENDER_TYPE_PASS_GLOW) |
6801 (1 << LLPipeline::RENDER_TYPE_PASS_GRASS) |
6802 (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) |
6803 (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) |
6804 (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY));
5758 6805
5759 renderGeomPostDeferred(*LLViewerCamera::getInstance()); 6806 renderGeomPostDeferred(*LLViewerCamera::getInstance());
5760 mRenderTypeMask = render_mask; 6807 mRenderTypeMask = render_mask;
5761 } 6808 }
5762 6809
5763 mScreen.flush(); 6810 mScreen.flush(); // We are FLUSHED alright ! end of deferred render YAY!
5764 6811
5765} 6812}
5766 6813
6814void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
6815{
6816 //construct frustum
6817 LLVOVolume* volume = drawablep->getVOVolume();
6818 LLVector3 params = volume->getSpotLightParams();
6819
6820 F32 fov = params.mV[0];
6821 F32 focus = params.mV[1];
6822
6823 LLVector3 pos = drawablep->getPositionAgent();
6824 LLQuaternion quat = volume->getRenderRotation();
6825 LLVector3 scale = volume->getScale();
6826
6827 //get near clip plane
6828 LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
6829 at_axis *= quat;
6830
6831 LLVector3 np = pos+at_axis;
6832 at_axis.normVec();
6833
6834 //get origin that has given fov for plane np, at_axis, and given scale
6835 F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
6836
6837 LLVector3 origin = np - at_axis*dist;
6838
6839 //matrix from volume space to agent space
6840 LLMatrix4 light_mat(quat, LLVector4(origin,1.f));
6841
6842 glh::matrix4f light_to_agent((F32*) light_mat.mMatrix);
6843 glh::matrix4f light_to_screen = glh_get_current_modelview() * light_to_agent;
6844
6845 glh::matrix4f screen_to_light = light_to_screen.inverse();
6846
6847 F32 s = volume->getLightRadius()*1.5f;
6848 F32 near_clip = dist;
6849 F32 width = scale.mV[VX];
6850 F32 height = scale.mV[VY];
6851 F32 far_clip = s+dist-scale.mV[VZ];
6852
6853 F32 fovy = fov * RAD_TO_DEG;
6854 F32 aspect = width/height;
6855
6856 glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
6857 0.f, 0.5f, 0.f, 0.5f,
6858 0.f, 0.f, 0.5f, 0.5f,
6859 0.f, 0.f, 0.f, 1.f);
6860
6861 glh::vec3f p1(0, 0, -(near_clip+0.01f));
6862 glh::vec3f p2(0, 0, -(near_clip+1.f));
6863
6864 glh::vec3f screen_origin(0, 0, 0);
6865
6866 light_to_screen.mult_matrix_vec(p1);
6867 light_to_screen.mult_matrix_vec(p2);
6868 light_to_screen.mult_matrix_vec(screen_origin);
6869
6870 glh::vec3f n = p2-p1;
6871 n.normalize();
6872
6873 F32 proj_range = far_clip - near_clip;
6874 glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip);
6875 screen_to_light = trans * light_proj * screen_to_light;
6876 shader.uniformMatrix4fv("proj_mat", 1, FALSE, screen_to_light.m);
6877 shader.uniform1f("proj_near", near_clip);
6878 shader.uniform3fv("proj_p", 1, p1.v);
6879 shader.uniform3fv("proj_n", 1, n.v);
6880 shader.uniform3fv("proj_origin", 1, screen_origin.v);
6881 shader.uniform1f("proj_range", proj_range);
6882 shader.uniform1f("proj_ambiance", params.mV[2]);
6883 S32 s_idx = -1;
6884
6885 for (U32 i = 0; i < 2; i++)
6886 {
6887 if (mShadowSpotLight[i] == drawablep)
6888 {
6889 s_idx = i;
6890 }
6891 }
6892
6893 shader.uniform1i("proj_shadow_idx", s_idx);
6894
6895 if (s_idx >= 0)
6896 {
6897 shader.uniform1f("shadow_fade", 1.f-mSpotLightFade[s_idx]);
6898 }
6899 else
6900 {
6901 shader.uniform1f("shadow_fade", 1.f);
6902 }
6903
6904 {
6905 LLDrawable* potential = drawablep;
6906 //determine if this is a good light for casting shadows
6907 F32 m_pri = volume->getSpotLightPriority();
6908
6909 for (U32 i = 0; i < 2; i++)
6910 {
6911 F32 pri = 0.f;
6912
6913 if (mTargetShadowSpotLight[i].notNull())
6914 {
6915 pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority();
6916 }
6917
6918 if (m_pri > pri)
6919 {
6920 LLDrawable* temp = mTargetShadowSpotLight[i];
6921 mTargetShadowSpotLight[i] = potential;
6922 potential = temp;
6923 m_pri = pri;
6924 }
6925 }
6926 }
6927
6928 LLViewerImage* img = volume->getLightTexture();
6929
6930 S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
6931
6932 if (channel > -1 && img)
6933 {
6934 gGL.getTexUnit(channel)->bind(img);
6935
6936 F32 lod_range = logf(img->getWidth())/logf(2.f);
6937
6938 shader.uniform1f("proj_focus", focus);
6939 shader.uniform1f("proj_lod", lod_range);
6940 shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f));
6941 }
6942}
6943
5767void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) 6944void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
5768{ 6945{
6946 LLFastTimer ftm(LLFastTimer::FTM_TEMP4);
5769 stop_glerror(); 6947 stop_glerror();
5770 shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); 6948 shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE);
5771 shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); 6949 shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE);
@@ -5773,14 +6951,40 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
5773 shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); 6951 shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE);
5774 shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); 6952 shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);
5775 shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); 6953 shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
6954 shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
6955 shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
6956 shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE);
6957 shader.disableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE);
6958 shader.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
6959 shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL);
6960 shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE);
6961 shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR);
6962 shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH);
6963 shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS);
6964 shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS);
6965 shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL);
6966 shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE);
6967 shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS);
6968 shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS);
6969
5776 for (U32 i = 0; i < 4; i++) 6970 for (U32 i = 0; i < 4; i++)
5777 { 6971 {
6972 if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1)
6973 {
6974 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
6975 }
6976 }
6977
6978 for (U32 i = 4; i < 6; i++)
6979 {
5778 if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i) > -1) 6980 if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i) > -1)
5779 { 6981 {
5780 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); 6982 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
5781 } 6983 }
5782 } 6984 }
6985
5783 shader.disableTexture(LLViewerShaderMgr::DEFERRED_NOISE); 6986 shader.disableTexture(LLViewerShaderMgr::DEFERRED_NOISE);
6987 shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC);
5784 6988
5785 S32 channel = shader.disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); 6989 S32 channel = shader.disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
5786 if (channel > -1) 6990 if (channel > -1)
@@ -5794,6 +6998,8 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
5794 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); 6998 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
5795 gGL.getTexUnit(0)->activate(); 6999 gGL.getTexUnit(0)->activate();
5796 shader.unbind(); 7000 shader.unbind();
7001
7002 LLGLState::checkTextureChannels();
5797} 7003}
5798 7004
5799inline float sgn(float a) 7005inline float sgn(float a)
@@ -5932,15 +7138,15 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
5932 } 7138 }
5933 } 7139 }
5934 7140
5935 LLSpatialPartition::sFreezeState = TRUE; 7141 //LLSpatialPartition::sFreezeState = TRUE;
5936 LLPipeline::sSkipUpdate = TRUE; 7142 //LLPipeline::sSkipUpdate = TRUE;
5937 LLGLUserClipPlane clip_plane(plane, mat, projection); 7143 LLGLUserClipPlane clip_plane(plane, mat, projection);
5938 static LLCullResult result; 7144 static LLCullResult result;
5939 updateCull(camera, result, 1); 7145 updateCull(camera, result, 1);
5940 stateSort(camera, result); 7146 stateSort(camera, result);
5941 renderGeom(camera); 7147 renderGeom(camera);
5942 LLSpatialPartition::sFreezeState = FALSE; 7148 //LLSpatialPartition::sFreezeState = FALSE;
5943 LLPipeline::sSkipUpdate = FALSE; 7149 //LLPipeline::sSkipUpdate = FALSE;
5944 } 7150 }
5945 } 7151 }
5946 glCullFace(GL_BACK); 7152 glCullFace(GL_BACK);
@@ -6039,7 +7245,6 @@ glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up)
6039 7245
6040 dirN = dir; 7246 dirN = dir;
6041 dirN.normVec(); 7247 dirN.normVec();
6042
6043 7248
6044 ret.m[ 0] = lftN[0]; 7249 ret.m[ 0] = lftN[0];
6045 ret.m[ 1] = upN[0]; 7250 ret.m[ 1] = upN[0];
@@ -6090,14 +7295,465 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max)
6090 return ret; 7295 return ret;
6091} 7296}
6092 7297
6093void LLPipeline::generateSunShadow(LLCamera& camera) 7298void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, BOOL use_shader)
7299{
7300 LLFastTimer t(LLFastTimer::FTM_SHADOW_RENDER);
7301
7302 //clip out geometry on the same side of water as the camera
7303 static LLCullResult result;
7304 S32 occlude = LLPipeline::sUseOcclusion;
7305 LLPipeline::sUseOcclusion = 1;
7306 LLPipeline::sShadowRender = TRUE;
7307
7308 updateCull(shadow_cam, result);
7309 stateSort(shadow_cam, result);
7310
7311 U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP };
7312 LLGLEnable cull(GL_CULL_FACE);
7313
7314 //generate shadow map
7315 glMatrixMode(GL_PROJECTION);
7316 glPushMatrix();
7317 glLoadMatrixf(proj.m);
7318 glMatrixMode(GL_MODELVIEW);
7319 glPushMatrix();
7320 glLoadMatrixf(view.m);
7321
7322 stop_glerror();
7323 gGLLastMatrix = NULL;
7324
7325 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
7326
7327 glColor4f(1,1,1,1);
7328
7329 stop_glerror();
7330
7331 gGL.setColorMask(false, false);
7332
7333 if (use_shader)
7334 {
7335 gDeferredShadowProgram.bind();
7336 }
7337
7338 //glCullFace(GL_FRONT);
7339
7340 {
7341 LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE);
7342 LLGLDisable test(GL_ALPHA_TEST);
7343 gGL.getTexUnit(0)->disable();
7344 for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i)
7345 {
7346 renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
7347 }
7348 gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
7349 }
7350
7351 if (use_shader)
7352 {
7353 gDeferredShadowProgram.unbind();
7354 renderGeomShadow(shadow_cam);
7355 gDeferredShadowProgram.bind();
7356 }
7357 else
7358 {
7359 renderGeomShadow(shadow_cam);
7360 }
7361
7362 {
7363 LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA);
7364 LLGLEnable test(GL_ALPHA_TEST);
7365 gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f);
7366 renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE);
7367 glColor4f(1,1,1,1);
7368 renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
7369 gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
7370 }
7371
7372 //glCullFace(GL_BACK);
7373
7374 if (use_shader)
7375 {
7376 gDeferredShadowProgram.unbind();
7377 }
7378
7379 gGL.setColorMask(true, true);
7380
7381
7382 glMatrixMode(GL_PROJECTION);
7383 glPopMatrix();
7384 glMatrixMode(GL_MODELVIEW);
7385 glPopMatrix();
7386 gGLLastMatrix = NULL;
7387
7388 LLPipeline::sUseOcclusion = occlude;
7389 LLPipeline::sShadowRender = FALSE;
7390}
7391
7392
7393BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir)
7394{
7395 LLFastTimer ftm(LLFastTimer::FTM_TEMP2);
7396 //get point cloud of intersection of frust and min, max
7397
7398 //get set of planes
7399 std::vector<LLPlane> ps;
7400
7401 if (getVisibleExtents(camera, min, max))
7402 {
7403 return FALSE;
7404 }
7405
7406 ps.push_back(LLPlane(min, LLVector3(-1,0,0)));
7407 ps.push_back(LLPlane(min, LLVector3(0,-1,0)));
7408 ps.push_back(LLPlane(min, LLVector3(0,0,-1)));
7409 ps.push_back(LLPlane(max, LLVector3(1,0,0)));
7410 ps.push_back(LLPlane(max, LLVector3(0,1,0)));
7411 ps.push_back(LLPlane(max, LLVector3(0,0,1)));
7412
7413 if (!light_dir.isExactlyZero())
7414 {
7415 LLPlane ucp;
7416 LLPlane mcp;
7417
7418 F32 maxd = -1.f;
7419 F32 mind = 1.f;
7420
7421 for (U32 i = 0; i < ps.size(); ++i)
7422 { //pick the plane most aligned to lightDir for user clip plane
7423 LLVector3 n(ps[i].mV);
7424 F32 da = n*light_dir;
7425 if (da > maxd)
7426 {
7427 maxd = da;
7428 ucp = ps[i];
7429 }
7430
7431 if (da < mind)
7432 {
7433 mind = da;
7434 mcp = ps[i];
7435 }
7436 }
7437
7438 camera.setUserClipPlane(ucp);
7439
7440 ps.clear();
7441 ps.push_back(ucp);
7442 ps.push_back(mcp);
7443 }
7444
7445 for (U32 i = 0; i < 6; i++)
7446 {
7447 ps.push_back(camera.getAgentPlane(i));
7448 }
7449
7450 //get set of points where planes intersect and points are not above any plane
7451 fp.clear();
7452
7453 for (U32 i = 0; i < ps.size(); ++i)
7454 {
7455 for (U32 j = 0; j < ps.size(); ++j)
7456 {
7457 for (U32 k = 0; k < ps.size(); ++k)
7458 {
7459 if (i == j ||
7460 i == k ||
7461 k == j)
7462 {
7463 continue;
7464 }
7465
7466 LLVector3 n1,n2,n3;
7467 F32 d1,d2,d3;
7468
7469 n1.setVec(ps[i].mV);
7470 n2.setVec(ps[j].mV);
7471 n3.setVec(ps[k].mV);
7472
7473 d1 = ps[i].mV[3];
7474 d2 = ps[j].mV[3];
7475 d3 = ps[k].mV[3];
7476
7477 //get point of intersection of 3 planes "p"
7478 LLVector3 p = (-d1*(n2%n3)-d2*(n3%n1)-d3*(n1%n2))/(n1*(n2%n3));
7479
7480 if (llround(p*n1+d1, 0.0001f) == 0.f &&
7481 llround(p*n2+d2, 0.0001f) == 0.f &&
7482 llround(p*n3+d3, 0.0001f) == 0.f)
7483 { //point is on all three planes
7484 BOOL found = TRUE;
7485 for (U32 l = 0; l < ps.size() && found; ++l)
7486 {
7487 if (llround(ps[l].dist(p), 0.0001f) > 0.0f)
7488 { //point is above some plane, not contained
7489 found = FALSE;
7490 }
7491 }
7492
7493 if (found)
7494 {
7495 fp.push_back(p);
7496 }
7497 }
7498 }
7499 }
7500 }
7501
7502 if (fp.empty())
7503 {
7504 return FALSE;
7505 }
7506
7507 return TRUE;
7508}
7509
7510void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<LLVector3>& vpc)
7511{
7512/* if (!gSavedSettings.getBOOL("RenderDeferredGI"))
7513 {
7514 return;
7515 } */
7516
7517 LLVector3 up;
7518
7519 if (lightDir.mV[2] > 0.5f)
7520 {
7521 up = LLVector3(1,0,0);
7522 }
7523 else
7524 {
7525 up = LLVector3(0, 0, 1);
7526 }
7527
7528
7529 F32 lrad = gSavedSettings.getF32("RenderGILightRadius");
7530
7531 F32 samples = (F32) gSavedSettings.getU32("RenderGISamples");
7532
7533 F32 gi_range = gSavedSettings.getF32("RenderGIRange");
7534
7535 U32 res = 1024;
7536
7537 lrad = samples*gi_range/(res-samples)*0.5f;
7538
7539 F32 lrange = lrad+gi_range*0.5f;
7540
7541 LLVector3 pad(lrange,lrange,lrange);
7542
7543 glh::matrix4f view = look(LLVector3(128.f,128.f,128.f), lightDir, up);
7544
7545 LLVector3 cp = camera.getOrigin()+camera.getAtAxis()*(gi_range*0.5f);
7546
7547 glh::vec3f scp(cp.mV);
7548 view.mult_matrix_vec(scp);
7549 cp.setVec(scp.v);
7550
7551 F32 pix_width = lrange/(res*0.5f);
7552
7553 //lrad = llround(lrad, pix_width);
7554
7555 //move cp to the nearest pix_width
7556 for (U32 i = 0; i < 3; i++)
7557 {
7558 cp.mV[i] = llround(cp.mV[i], pix_width);
7559 }
7560
7561 LLVector3 min = cp-pad;
7562 LLVector3 max = cp+pad;
7563
7564 //set mGIRange to range in tc space[0,1] that covers texture block of intersecting lights around a point
7565 mGIRange.mV[0] = (max.mV[0]-min.mV[0])/res;
7566 mGIRange.mV[1] = (max.mV[1]-min.mV[1])/res;
7567 mGILightRadius = lrad;
7568
7569 glh::matrix4f proj = gl_ortho(min.mV[0], max.mV[0],
7570 min.mV[1], max.mV[1],
7571 -max.mV[2], -min.mV[2]);
7572
7573 LLCamera sun_cam = camera;
7574
7575 glh::matrix4f eye_view = glh_get_current_modelview();
7576
7577 //get eye space to camera space matrix
7578 mGIMatrix = view*eye_view.inverse();
7579 mGINormalMatrix = mGIMatrix.inverse().transpose();
7580 mGIInvProj = proj.inverse();
7581 mGIMatrixProj = proj*mGIMatrix;
7582
7583 //translate and scale to [0,1]
7584 glh::matrix4f trans(.5f, 0.f, 0.f, .5f,
7585 0.f, 0.5f, 0.f, 0.5f,
7586 0.f, 0.f, 0.5f, 0.5f,
7587 0.f, 0.f, 0.f, 1.f);
7588
7589 mGIMatrixProj = trans*mGIMatrixProj;
7590
7591 glh_set_current_modelview(view);
7592 glh_set_current_projection(proj);
7593
7594 LLViewerCamera::updateFrustumPlanes(sun_cam, TRUE, FALSE, TRUE);
7595
7596 sun_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);
7597 static LLCullResult result;
7598
7599 U32 type_mask = mRenderTypeMask;
7600
7601 mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) |
7602 (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |
7603 (1<<LLPipeline::RENDER_TYPE_BUMP) |
7604 (1<<LLPipeline::RENDER_TYPE_VOLUME) |
7605 (1<<LLPipeline::RENDER_TYPE_TREE) |
7606 (1<<LLPipeline::RENDER_TYPE_TERRAIN) |
7607 (1<<LLPipeline::RENDER_TYPE_WATER) |
7608 (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) |
7609 (1<<LLPipeline::RENDER_TYPE_AVATAR) |
7610 (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) |
7611 (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) |
7612 (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) |
7613 (1 << LLPipeline::RENDER_TYPE_PASS_SHINY));
7614
7615
7616
7617 S32 occlude = LLPipeline::sUseOcclusion;
7618 LLPipeline::sUseOcclusion = 0;
7619 LLPipeline::sShadowRender = TRUE;
7620
7621 updateCull(sun_cam, result);
7622 stateSort(sun_cam, result);
7623
7624 LLGLEnable cull(GL_CULL_FACE);
7625
7626 //generate GI map
7627 glMatrixMode(GL_PROJECTION);
7628 glPushMatrix();
7629 glLoadMatrixf(proj.m);
7630 glMatrixMode(GL_MODELVIEW);
7631 glPushMatrix();
7632 glLoadMatrixf(view.m);
7633
7634 stop_glerror();
7635 gGLLastMatrix = NULL;
7636
7637 mGIMap.clear();
7638
7639 {
7640 LLGLEnable enable(GL_DEPTH_CLAMP_NV);
7641 renderGeomDeferred(camera);
7642 }
7643
7644 mGIMap.flush();
7645
7646 glMatrixMode(GL_PROJECTION);
7647 glPopMatrix();
7648 glMatrixMode(GL_MODELVIEW);
7649 glPopMatrix();
7650 gGLLastMatrix = NULL;
7651
7652 LLPipeline::sUseOcclusion = occlude;
7653 LLPipeline::sShadowRender = FALSE;
7654
7655
7656 mRenderTypeMask = type_mask;
7657
7658}
7659
7660void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade)
6094{ 7661{
7662 if (!gSavedSettings.getBOOL("renderhighlights")) // KL need this to make the mouseover Highlights toggle ^^
7663 {
7664 return;
7665 }
7666
7667 if (obj && obj->getVolume())
7668 {
7669 for (LLViewerObject::child_list_t::const_iterator iter = obj->getChildren().begin(); iter != obj->getChildren().end(); ++iter)
7670 {
7671 renderHighlight(*iter, fade);
7672 }
7673
7674 LLDrawable* drawable = obj->mDrawable;
7675 if (drawable)
7676 {
7677 for (S32 i = 0; i < drawable->getNumFaces(); ++i)
7678 {
7679 LLFace* face = drawable->getFace(i);
7680 if (face)
7681 {
7682 face->renderSelected(LLViewerImage::sNullImagep, LLColor4(1,1,1,fade));
7683 }
7684 }
7685 }
7686 }
7687}
6095 7688
7689void LLPipeline::generateHighlight(LLCamera& camera)
7690{
7691 if (!gSavedSettings.getBOOL("renderhighlights")) // KL need this to make the mouseover Highlights toggle ^^
7692 {
7693 return;
7694 }
7695 //render highlighted object as white into offscreen render target
7696
7697 if (mHighlightObject.notNull())
7698 {
7699 mHighlightSet.insert(HighlightItem(mHighlightObject));
7700 }
7701
7702 if (!mHighlightSet.empty())
7703 {
7704 F32 transition = gFrameIntervalSeconds/gSavedSettings.getF32("RenderHighlightFadeTime");
7705
7706 LLGLDisable test(GL_ALPHA_TEST);
7707 LLGLDepthTest depth(GL_FALSE);
7708 mHighlight.bindTarget();
7709 disableLights();
7710 gGL.setColorMask(true, true);
7711 mHighlight.clear();
7712
7713 gGL.getTexUnit(0)->bind(LLViewerImage::sWhiteImagep);
7714 for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); )
7715 {
7716 std::set<HighlightItem>::iterator cur_iter = iter++;
7717
7718 if (cur_iter->mItem.isNull())
7719 {
7720 mHighlightSet.erase(cur_iter);
7721 continue;
7722 }
7723
7724 if (cur_iter->mItem == mHighlightObject)
7725 {
7726 cur_iter->incrFade(transition);
7727 }
7728 else
7729 {
7730 cur_iter->incrFade(-transition);
7731 if (cur_iter->mFade <= 0.f)
7732 {
7733 mHighlightSet.erase(cur_iter);
7734 continue;
7735 }
7736 }
7737
7738 renderHighlight(cur_iter->mItem->getVObj(), cur_iter->mFade);
7739 }
7740
7741 mHighlight.flush();
7742 gGL.setColorMask(true, false);
7743 gViewerWindow->setupViewport();
7744 }
7745}
7746
7747
7748void LLPipeline::generateSunShadow(LLCamera& camera)
7749{
6096 if (!sRenderDeferred) 7750 if (!sRenderDeferred)
6097 { 7751 {
6098 return; 7752 return;
6099 } 7753 }
6100 7754
7755 LLFastTimer ftm(LLFastTimer::FTM_TEMP1);
7756
6101 //temporary hack to disable shadows but keep local lights 7757 //temporary hack to disable shadows but keep local lights
6102 static BOOL clear = TRUE; 7758 static BOOL clear = TRUE;
6103 BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow"); 7759 BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow");
@@ -6106,98 +7762,162 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
6106 if (clear) 7762 if (clear)
6107 { 7763 {
6108 clear = FALSE; 7764 clear = FALSE;
6109 for (U32 i = 0; i < 4; i++) 7765 for (U32 i = 0; i < 6; i++)
6110 { 7766 {
6111 mSunShadow[i].bindTarget(); 7767 mShadow[i].bindTarget();
6112 mSunShadow[i].clear(); 7768 mShadow[i].clear();
6113 mSunShadow[i].flush(); 7769 mShadow[i].flush();
6114 } 7770 }
6115 } 7771 }
6116 return; 7772 return;
6117 } 7773 }
6118 clear = TRUE; 7774 clear = TRUE;
6119 7775
7776 U32 type_mask = mRenderTypeMask;
7777 mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) |
7778 (1<<LLPipeline::RENDER_TYPE_ALPHA) |
7779 (1<<LLPipeline::RENDER_TYPE_GRASS) |
7780 (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |
7781 (1<<LLPipeline::RENDER_TYPE_BUMP) |
7782 (1<<LLPipeline::RENDER_TYPE_VOLUME) |
7783 (1<<LLPipeline::RENDER_TYPE_AVATAR) |
7784 (1<<LLPipeline::RENDER_TYPE_TREE) |
7785 (1<<LLPipeline::RENDER_TYPE_TERRAIN) |
7786 (1<<LLPipeline::RENDER_TYPE_WATER) |
7787 (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) |
7788 (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) |
7789 (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) |
7790 (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) |
7791 (1 << LLPipeline::RENDER_TYPE_PASS_SHINY));
7792
6120 gGL.setColorMask(false, false); 7793 gGL.setColorMask(false, false);
6121 7794
6122 //get sun view matrix 7795 //get sun view matrix
6123 7796
6124 F32 range = 128.f;
6125
6126 //store current projection/modelview matrix 7797 //store current projection/modelview matrix
6127 glh::matrix4f saved_proj = glh_get_current_projection(); 7798 glh::matrix4f saved_proj = glh_get_current_projection();
6128 glh::matrix4f saved_view = glh_get_current_modelview(); 7799 glh::matrix4f saved_view = glh_get_current_modelview();
6129 glh::matrix4f inv_view = saved_view.inverse(); 7800 glh::matrix4f inv_view = saved_view.inverse();
6130 7801
6131 glh::matrix4f view[4]; 7802 glh::matrix4f view[6];
6132 glh::matrix4f proj[4]; 7803 glh::matrix4f proj[6];
6133 LLVector3 up; 7804
6134
6135 //clip contains parallel split distances for 3 splits 7805 //clip contains parallel split distances for 3 splits
6136 LLVector3 clip = gSavedSettings.getVector3("RenderShadowClipPlanes"); 7806 LLVector3 clip = gSavedSettings.getVector3("RenderShadowClipPlanes");
6137 7807
7808 //F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold");
7809
6138 //far clip on last split is minimum of camera view distance and 128 7810 //far clip on last split is minimum of camera view distance and 128
6139 mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]); 7811 mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]);
6140 7812
6141 const LLPickInfo& pick_info = gViewerWindow->getLastPick(); 7813 clip = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes");
6142 7814 mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]);
6143 if (!pick_info.mPosGlobal.isExactlyZero())
6144 { //squish nearest frustum based on alt-zoom (tighten up nearest frustum when focusing on tiny object
6145 F32 focus_dist = (F32) (pick_info.mPosGlobal + LLVector3d(pick_info.mObjectOffset) - gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin())).magVec();
6146 mSunClipPlanes.mV[0] = llclamp(focus_dist*focus_dist, 2.f, mSunClipPlanes.mV[0]);
6147 }
6148
6149 // convenience array of 4 near clip plane distances
6150 F32 dist[] = { 0.1f, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
6151 7815
6152 //currently used for amount to extrude frusta corners for constructing shadow frusta 7816 //currently used for amount to extrude frusta corners for constructing shadow frusta
6153 LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist"); 7817 LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist");
6154 F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; 7818 //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
6155 7819
6156 for (S32 j = 0; j < 4; j++) 7820 LLVector3 lightDir = -mSunDir;
6157 { 7821 lightDir.normVec();
6158 //restore render matrices
6159 glh_set_current_modelview(saved_view);
6160 glh_set_current_projection(saved_proj);
6161 7822
6162 //get center of far clip plane (for point of interest later) 7823 glh::vec3f light_dir(lightDir.mV);
6163 LLVector3 center = camera.getOrigin() + camera.getAtAxis() * range;
6164 7824
6165 LLVector3 eye = camera.getOrigin(); 7825 //create light space camera matrix
7826
7827 LLVector3 at = lightDir;
6166 7828
6167 //camera used for shadow cull/render 7829 LLVector3 up = camera.getAtAxis();
6168 LLCamera shadow_cam; 7830
6169 7831 if (fabsf(up*lightDir) > 0.75f)
6170 // perspective shadow map 7832 {
6171 glh::vec3f p[16]; //point cloud to be contained by shadow projection (light camera space) 7833 up = camera.getUpAxis();
6172 glh::vec3f wp[16]; //point cloud to be contained by shadow projection (world space) 7834 }
6173 7835
6174 LLVector3 lightDir = -mSunDir; 7836 /*LLVector3 left = up%at;
6175 glh::vec3f light_dir(lightDir.mV); 7837 up = at%left;*/
7838
7839 up.normVec();
7840 at.normVec();
7841
7842
7843 F32 near_clip = 0.f;
7844 {
7845 //get visible point cloud
7846 std::vector<LLVector3> fp;
6176 7847
6177 //create light space camera matrix 7848 LLVector3 min,max;
6178 LLVector3 at; 7849 getVisiblePointCloud(camera,min,max,fp);
6179 F32 dl = camera.getLeftAxis() * lightDir;
6180 F32 du = camera.getUpAxis() * lightDir;
6181 7850
6182 //choose an at axis such that up will be most aligned with lightDir 7851 if (fp.empty())
6183 if (dl*dl < du*du)
6184 { 7852 {
6185 at = lightDir%camera.getLeftAxis(); 7853 mRenderTypeMask = type_mask;
7854 return;
6186 } 7855 }
6187 else 7856
7857 generateGI(camera, lightDir, fp);
7858
7859 //get good split distances for frustum
7860 for (U32 i = 0; i < fp.size(); ++i)
6188 { 7861 {
6189 at = lightDir%camera.getUpAxis(); 7862 glh::vec3f v(fp[i].mV);
7863 saved_view.mult_matrix_vec(v);
7864 fp[i].setVec(v.v);
6190 } 7865 }
6191 7866
6192 if (at * camera.getAtAxis() < 0) 7867 min = fp[0];
7868 max = fp[0];
7869
7870 //get camera space bounding box
7871 for (U32 i = 1; i < fp.size(); ++i)
6193 { 7872 {
6194 at = -at; 7873 update_min_max(min, max, fp[i]);
6195 } 7874 }
7875
7876 near_clip = -max.mV[2];
7877 F32 far_clip = -min.mV[2]*2.f;
7878
7879 far_clip = llmin(far_clip, 128.f);
7880 far_clip = llmin(far_clip, camera.getFar());
7881
7882 F32 range = far_clip-near_clip;
7883
7884 LLVector3 split_exp = gSavedSettings.getVector3("RenderShadowSplitExponent");
7885
7886 F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) );
6196 7887
6197 LLVector3 left = lightDir%at; 7888 da = powf(da, split_exp.mV[2]);
6198 up = left%lightDir; 7889
6199 up.normVec(); 7890
7891 F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da;
7892
7893
7894 for (U32 i = 0; i < 4; ++i)
7895 {
7896 F32 x = (F32)(i+1)/4.f;
7897 x = powf(x, sxp);
7898 mSunClipPlanes.mV[i] = near_clip+range*x;
7899 }
7900 }
7901
7902 // convenience array of 4 near clip plane distances
7903 F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
7904
7905 for (S32 j = 0; j < 4; j++)
7906 {
7907 if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
7908 {
7909 mShadowFrustPoints[j].clear();
7910 }
7911
7912 //restore render matrices
7913 glh_set_current_modelview(saved_view);
7914 glh_set_current_projection(saved_proj);
6200 7915
7916 LLVector3 eye = camera.getOrigin();
7917
7918 //camera used for shadow cull/render
7919 LLCamera shadow_cam;
7920
6201 //create world space camera frustum for this split 7921 //create world space camera frustum for this split
6202 shadow_cam = camera; 7922 shadow_cam = camera;
6203 shadow_cam.setFar(16.f); 7923 shadow_cam.setFar(16.f);
@@ -6208,8 +7928,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
6208 7928
6209 LLVector3 pn = shadow_cam.getAtAxis(); 7929 LLVector3 pn = shadow_cam.getAtAxis();
6210 7930
6211 LLVector3 frust_center;
6212
6213 LLVector3 min, max; 7931 LLVector3 min, max;
6214 7932
6215 //construct 8 corners of split frustum section 7933 //construct 8 corners of split frustum section
@@ -6220,21 +7938,19 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
6220 F32 dp = delta*pn; 7938 F32 dp = delta*pn;
6221 frust[i] = eye + (delta*dist[j])/dp; 7939 frust[i] = eye + (delta*dist[j])/dp;
6222 frust[i+4] = eye + (delta*dist[j+1])/dp; 7940 frust[i+4] = eye + (delta*dist[j+1])/dp;
6223 frust_center += frust[i] + frust[i+4];
6224 } 7941 }
6225
6226 //get frustum center
6227 frust_center /= 8.f;
6228 7942
6229 shadow_cam.calcAgentFrustumPlanes(frust); 7943 shadow_cam.calcAgentFrustumPlanes(frust);
6230 7944 shadow_cam.mFrustumCornerDist = 0.f;
6231 7945
6232 if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) 7946 if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
6233 { 7947 {
6234 mShadowCamera[j] = shadow_cam; 7948 mShadowCamera[j] = shadow_cam;
6235 } 7949 }
6236 7950
6237 if (gPipeline.getVisibleExtents(shadow_cam, min, max)) 7951 std::vector<LLVector3> fp;
7952
7953 if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir))
6238 { 7954 {
6239 //no possible shadow receivers 7955 //no possible shadow receivers
6240 if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) 7956 if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
@@ -6244,6 +7960,16 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
6244 mShadowCamera[j+4] = shadow_cam; 7960 mShadowCamera[j+4] = shadow_cam;
6245 } 7961 }
6246 7962
7963 mShadow[j].bindTarget();
7964 {
7965 LLGLDepthTest depth(GL_TRUE);
7966 mShadow[j].clear();
7967 }
7968 mShadow[j].flush();
7969
7970 mShadowError.mV[j] = 0.f;
7971 mShadowFOV.mV[j] = 0.f;
7972
6247 continue; 7973 continue;
6248 } 7974 }
6249 7975
@@ -6251,42 +7977,252 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
6251 { 7977 {
6252 mShadowExtents[j][0] = min; 7978 mShadowExtents[j][0] = min;
6253 mShadowExtents[j][1] = max; 7979 mShadowExtents[j][1] = max;
7980 mShadowFrustPoints[j] = fp;
6254 } 7981 }
6255 7982
6256 view[j] = look(frust_center-lightDir*nearDist[j], lightDir, up);
6257 F32 shadow_dist = nearDist[j];
6258 7983
6259 for (U32 i = 0; i < 8; i++) 7984 //find a good origin for shadow projection
7985 LLVector3 origin;
7986
7987 //get a temporary view projection
7988 view[j] = look(camera.getOrigin(), lightDir, -up);
7989
7990 std::vector<LLVector3> wpf;
7991
7992 for (U32 i = 0; i < fp.size(); i++)
6260 { 7993 {
6261 //points in worldspace (wp) and light camera space (p) 7994 glh::vec3f p = glh::vec3f(fp[i].mV);
6262 //that must be included in shadow generation 7995 view[j].mult_matrix_vec(p);
6263 wp[i] = glh::vec3f(frust[i].mV); 7996 wpf.push_back(LLVector3(p.v));
6264 wp[i+8] = wp[i] - light_dir*shadow_dist;
6265 view[j].mult_matrix_vec(wp[i], p[i]);
6266 view[j].mult_matrix_vec(wp[i+8], p[i+8]);
6267 } 7997 }
6268
6269 min = LLVector3(p[0].v);
6270 max = LLVector3(p[0].v);
6271 7998
6272 LLVector3 fmin = min; 7999 min = wpf[0];
6273 LLVector3 fmax = max; 8000 max = wpf[0];
6274 8001
6275 for (U32 i = 1; i < 16; i++) 8002 for (U32 i = 0; i < fp.size(); ++i)
6276 { //find camera space AABB of frustum in light camera space 8003 { //get AABB in camera space
6277 update_min_max(min, max, LLVector3(p[i].v)); 8004 update_min_max(min, max, wpf[i]);
6278 if (i < 8) 8005 }
6279 { 8006
6280 update_min_max(fmin, fmax, LLVector3(p[i].v)); 8007 // Construct a perspective transform with perspective along y-axis that contains
8008 // points in wpf
8009 //Known:
8010 // - far clip plane
8011 // - near clip plane
8012 // - points in frustum
8013 //Find:
8014 // - origin
8015
8016 //get some "interesting" points of reference
8017 LLVector3 center = (min+max)*0.5f;
8018 LLVector3 size = (max-min)*0.5f;
8019 LLVector3 near_center = center;
8020 near_center.mV[1] += size.mV[1]*2.f;
8021
8022
8023 //put all points in wpf in quadrant 0, reletive to center of min/max
8024 //get the best fit line using least squares
8025 F32 bfm = 0.f;
8026 F32 bfb = 0.f;
8027
8028 for (U32 i = 0; i < wpf.size(); ++i)
8029 {
8030 wpf[i] -= center;
8031 wpf[i].mV[0] = fabsf(wpf[i].mV[0]);
8032 wpf[i].mV[2] = fabsf(wpf[i].mV[2]);
8033 }
8034
8035 if (!wpf.empty())
8036 {
8037 F32 sx = 0.f;
8038 F32 sx2 = 0.f;
8039 F32 sy = 0.f;
8040 F32 sxy = 0.f;
8041
8042 for (U32 i = 0; i < wpf.size(); ++i)
8043 {
8044 sx += wpf[i].mV[0];
8045 sx2 += wpf[i].mV[0]*wpf[i].mV[0];
8046 sy += wpf[i].mV[1];
8047 sxy += wpf[i].mV[0]*wpf[i].mV[1];
6281 } 8048 }
8049
8050 bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2);
8051 bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2);
6282 } 8052 }
8053
8054 {
8055 // best fit line is y=bfm*x+bfb
8056
8057 //find point that is furthest to the right of line
8058 F32 off_x = -1.f;
8059 LLVector3 lp;
8060
8061 for (U32 i = 0; i < wpf.size(); ++i)
8062 {
8063 //y = bfm*x+bfb
8064 //x = (y-bfb)/bfm
8065 F32 lx = (wpf[i].mV[1]-bfb)/bfm;
8066
8067 lx = wpf[i].mV[0]-lx;
8068
8069 if (off_x < lx)
8070 {
8071 off_x = lx;
8072 lp = wpf[i];
8073 }
8074 }
8075
8076 //get line with slope bfm through lp
8077 // bfb = y-bfm*x
8078 bfb = lp.mV[1]-bfm*lp.mV[0];
8079
8080 //calculate error
8081 mShadowError.mV[j] = 0.f;
8082
8083 for (U32 i = 0; i < wpf.size(); ++i)
8084 {
8085 F32 lx = (wpf[i].mV[1]-bfb)/bfm;
8086 mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx);
8087 }
8088
8089 mShadowError.mV[j] /= wpf.size();
8090 mShadowError.mV[j] /= size.mV[0];
8091
8092 if (mShadowError.mV[j] > gSavedSettings.getF32("RenderShadowErrorCutoff"))
8093 { //just use ortho projection
8094 mShadowFOV.mV[j] = -1.f;
8095 origin.clearVec();
8096 proj[j] = gl_ortho(min.mV[0], max.mV[0],
8097 min.mV[1], max.mV[1],
8098 -max.mV[2], -min.mV[2]);
8099 }
8100 else
8101 {
8102 //origin is where line x = 0;
8103 origin.setVec(0,bfb,0);
8104
8105 F32 fovz = 1.f;
8106 F32 fovx = 1.f;
8107
8108 LLVector3 zp;
8109 LLVector3 xp;
8110
8111 for (U32 i = 0; i < wpf.size(); ++i)
8112 {
8113 LLVector3 atz = wpf[i]-origin;
8114 atz.mV[0] = 0.f;
8115 atz.normVec();
8116 if (fovz > -atz.mV[1])
8117 {
8118 zp = wpf[i];
8119 fovz = -atz.mV[1];
8120 }
8121
8122 LLVector3 atx = wpf[i]-origin;
8123 atx.mV[2] = 0.f;
8124 atx.normVec();
8125 if (fovx > -atx.mV[1])
8126 {
8127 fovx = -atx.mV[1];
8128 xp = wpf[i];
8129 }
8130 }
8131
8132 fovx = acos(fovx);
8133 fovz = acos(fovz);
8134
8135 F32 cutoff = llmin(gSavedSettings.getF32("RenderShadowFOVCutoff"), 1.4f);
8136
8137 mShadowFOV.mV[j] = fovx;
8138
8139 if (fovx < cutoff && fovz > cutoff)
8140 {
8141 //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff
8142 F32 d = zp.mV[2]/tan(cutoff);
8143 F32 ny = zp.mV[1] + fabsf(d);
8144
8145 origin.mV[1] = ny;
8146
8147 fovz = 1.f;
8148 fovx = 1.f;
8149
8150 for (U32 i = 0; i < wpf.size(); ++i)
8151 {
8152 LLVector3 atz = wpf[i]-origin;
8153 atz.mV[0] = 0.f;
8154 atz.normVec();
8155 fovz = llmin(fovz, -atz.mV[1]);
8156
8157 LLVector3 atx = wpf[i]-origin;
8158 atx.mV[2] = 0.f;
8159 atx.normVec();
8160 fovx = llmin(fovx, -atx.mV[1]);
8161 }
6283 8162
6284 //generate perspective matrix that contains frustum 8163 fovx = acos(fovx);
6285 //proj[j] = matrix_perspective(min, max); 8164 fovz = acos(fovz);
6286 proj[j] = gl_ortho(min.mV[0], max.mV[0], 8165
8166 if (fovx > cutoff || llround(fovz, 0.01f) > cutoff)
8167 {
8168 // llwarns << "WTF?" << llendl;
8169 }
8170
8171 mShadowFOV.mV[j] = cutoff;
8172 }
8173
8174
8175 origin += center;
8176
8177 F32 ynear = -(max.mV[1]-origin.mV[1]);
8178 F32 yfar = -(min.mV[1]-origin.mV[1]);
8179
8180 if (ynear < 0.1f) //keep a sensible near clip plane
8181 {
8182 F32 diff = 0.1f-ynear;
8183 origin.mV[1] += diff;
8184 ynear += diff;
8185 yfar += diff;
8186 }
8187
8188 if (fovx > cutoff)
8189 { //just use ortho projection
8190 origin.clearVec();
8191 mShadowError.mV[j] = -1.f;
8192 proj[j] = gl_ortho(min.mV[0], max.mV[0],
6287 min.mV[1], max.mV[1], 8193 min.mV[1], max.mV[1],
6288 -max.mV[2], -min.mV[2]); 8194 -max.mV[2], -min.mV[2]);
6289 8195 }
8196 else
8197 {
8198 //get perspective projection
8199 view[j] = view[j].inverse();
8200
8201 glh::vec3f origin_agent(origin.mV);
8202
8203 //translate view to origin
8204 view[j].mult_matrix_vec(origin_agent);
8205
8206 eye = LLVector3(origin_agent.v);
8207
8208 if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
8209 {
8210 mShadowFrustOrigin[j] = eye;
8211 }
8212
8213 view[j] = look(LLVector3(origin_agent.v), lightDir, -up);
8214
8215 F32 fx = 1.f/tanf(fovx);
8216 F32 fz = 1.f/tanf(fovz);
8217
8218 proj[j] = glh::matrix4f(-fx, 0, 0, 0,
8219 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar),
8220 0, 0, -fz, 0,
8221 0, -1.f, 0, 0);
8222 }
8223 }
8224 }
8225
6290 shadow_cam.setFar(128.f); 8226 shadow_cam.setFar(128.f);
6291 shadow_cam.setOriginAndLookAt(eye, up, center); 8227 shadow_cam.setOriginAndLookAt(eye, up, center);
6292 8228
@@ -6295,9 +8231,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
6295 8231
6296 LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); 8232 LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
6297 8233
6298 proj[j] = gl_ortho(fmin.mV[0], fmax.mV[0], 8234 shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);
6299 fmin.mV[1], fmax.mV[1],
6300 -fmax.mV[2], -fmin.mV[2]);
6301 8235
6302 //translate and scale to from [-1, 1] to [0, 1] 8236 //translate and scale to from [-1, 1] to [0, 1]
6303 glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, 8237 glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
@@ -6310,111 +8244,155 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
6310 8244
6311 mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; 8245 mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view;
6312 8246
6313 U32 type_mask = mRenderTypeMask;
6314 mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) |
6315 (1<<LLPipeline::RENDER_TYPE_ALPHA) |
6316 (1<<LLPipeline::RENDER_TYPE_GRASS) |
6317 (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |
6318 (1<<LLPipeline::RENDER_TYPE_BUMP) |
6319 (1<<LLPipeline::RENDER_TYPE_VOLUME) |
6320 (1<<LLPipeline::RENDER_TYPE_AVATAR) |
6321 (1<<LLPipeline::RENDER_TYPE_TREE) |
6322 (1<<LLPipeline::RENDER_TYPE_TERRAIN) |
6323 0);
6324
6325 //clip out geometry on the same side of water as the camera
6326 static LLCullResult result;
6327 S32 occlude = LLPipeline::sUseOcclusion;
6328 LLPipeline::sUseOcclusion = 1;
6329 LLPipeline::sShadowRender = TRUE;
6330 //hack to prevent LOD updates from using sun camera origin 8247 //hack to prevent LOD updates from using sun camera origin
6331 shadow_cam.setOrigin(camera.getOrigin()); 8248 shadow_cam.setOrigin(camera.getOrigin());
6332 updateCull(shadow_cam, result);
6333 stateSort(shadow_cam, result);
6334
6335 if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
6336 {
6337 LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
6338 mShadowCamera[j+4] = shadow_cam;
6339 }
6340
6341 LLFastTimer t(LLFastTimer::FTM_SHADOW_RENDER);
6342 8249
6343 stop_glerror(); 8250 stop_glerror();
6344 8251
6345 mSunShadow[j].bindTarget(); 8252 mShadow[j].bindTarget();
6346 mSunShadow[j].getViewport(gGLViewport); 8253 mShadow[j].getViewport(gGLViewport);
6347 8254
6348 { 8255 {
6349 LLGLDepthTest depth(GL_TRUE); 8256 LLGLDepthTest depth(GL_TRUE);
6350 mSunShadow[j].clear(); 8257 mShadow[j].clear();
6351 } 8258 }
6352 8259
6353 U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP }; 8260 {
6354 LLGLEnable cull(GL_CULL_FACE); 8261 LLGLEnable enable(GL_DEPTH_CLAMP_NV);
8262 renderShadow(view[j], proj[j], shadow_cam, FALSE);
8263 }
6355 8264
6356 //generate sun shadow map 8265 mShadow[j].flush();
6357 glMatrixMode(GL_PROJECTION); 8266
6358 glPushMatrix(); 8267 if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
6359 glLoadMatrixf(proj[j].m); 8268 {
6360 glMatrixMode(GL_MODELVIEW); 8269 LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
6361 glPushMatrix(); 8270 mShadowCamera[j+4] = shadow_cam;
6362 glLoadMatrixf(view[j].m); 8271 }
8272 }
6363 8273
6364 stop_glerror(); 8274 //llinfos << "Shadow error: " << error << " Slope: " << best_fit_slope << llendl;
6365 gGLLastMatrix = NULL; 8275
6366 8276
6367 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); 8277 F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f);
6368
6369 glColor4f(1,1,1,1);
6370
6371 glCullFace(GL_FRONT);
6372 8278
6373 stop_glerror(); 8279 //update shadow targets
8280 for (U32 i = 0; i < 2; i++)
8281 { //for each current shadow
8282 if (mShadowSpotLight[i].notNull() &&
8283 (mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
8284 mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
8285 { //keep this spotlight
8286 mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f);
8287 }
8288 else
8289 { //fade out this light
8290 mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f);
8291
8292 if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
8293 { //faded out, grab one of the pending spots (whichever one isn't already taken)
8294 if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2])
8295 {
8296 mShadowSpotLight[i] = mTargetShadowSpotLight[0];
8297 }
8298 else
8299 {
8300 mShadowSpotLight[i] = mTargetShadowSpotLight[1];
8301 }
8302 }
8303 }
8304 }
6374 8305
6375 gGL.setColorMask(false, false); 8306 for (S32 i = 0; i < 2; i++)
8307 {
8308 glh_set_current_modelview(saved_view);
8309 glh_set_current_projection(saved_proj);
6376 8310
6377 gDeferredShadowProgram.bind(); 8311 if (mShadowSpotLight[i].isNull())
6378 { 8312 {
6379 LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE); 8313 continue;
6380 LLGLDisable test(GL_ALPHA_TEST);
6381 gGL.getTexUnit(0)->disable();
6382 for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i)
6383 {
6384 renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
6385 }
6386 gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
6387 } 8314 }
6388 8315
8316 LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
8317
8318 if (!volume)
6389 { 8319 {
6390 LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA); 8320 mShadowSpotLight[i] = NULL;
6391 LLGLEnable test(GL_ALPHA_TEST); 8321 continue;
6392 gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f);
6393 renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE);
6394 glColor4f(1,1,1,1);
6395 renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
6396 gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
6397 } 8322 }
8323
8324 LLDrawable* drawable = mShadowSpotLight[i];
8325
8326 LLVector3 params = volume->getSpotLightParams();
8327 F32 fov = params.mV[0];
8328
8329 //get agent->light space matrix (modelview)
8330 LLVector3 center = drawable->getPositionAgent();
8331 LLQuaternion quat = volume->getRenderRotation();
8332
8333 //get near clip plane
8334 LLVector3 scale = volume->getScale();
8335 LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
8336 at_axis *= quat;
8337
8338 LLVector3 np = center+at_axis;
8339 at_axis.normVec();
8340
8341 //get origin that has given fov for plane np, at_axis, and given scale
8342 F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
8343
8344 LLVector3 origin = np - at_axis*dist;
8345
8346 LLMatrix4 mat(quat, LLVector4(origin, 1.f));
8347
8348 view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
8349
8350 view[i+4] = view[i+4].inverse();
8351
8352 //get perspective matrix
8353 F32 near_clip = dist+0.01f;
8354 F32 width = scale.mV[VX];
8355 F32 height = scale.mV[VY];
8356 F32 far_clip = dist+volume->getLightRadius()*1.5f;
8357
8358 F32 fovy = fov * RAD_TO_DEG;
8359 F32 aspect = width/height;
6398 8360
6399 gDeferredShadowProgram.unbind(); 8361 proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
6400 8362
6401 renderGeomShadow(shadow_cam); 8363 //translate and scale to from [-1, 1] to [0, 1]
8364 glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
8365 0.f, 0.5f, 0.f, 0.5f,
8366 0.f, 0.f, 0.5f, 0.5f,
8367 0.f, 0.f, 0.f, 1.f);
6402 8368
6403 gGL.setColorMask(true, true); 8369 glh_set_current_modelview(view[i+4]);
8370 glh_set_current_projection(proj[i+4]);
6404 8371
6405 glCullFace(GL_BACK); 8372 mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
6406 LLPipeline::sUseOcclusion = occlude;
6407 LLPipeline::sShadowRender = FALSE;
6408 mRenderTypeMask = type_mask;
6409 8373
6410 glMatrixMode(GL_PROJECTION); 8374 LLCamera shadow_cam = camera;
6411 glPopMatrix(); 8375 shadow_cam.setFar(far_clip);
6412 glMatrixMode(GL_MODELVIEW); 8376 shadow_cam.setOrigin(origin);
6413 glPopMatrix();
6414 gGLLastMatrix = NULL;
6415 8377
6416 mSunShadow[j].flush(); 8378 LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
6417 } 8379
8380 shadow_cam.setOrigin(camera.getOrigin());
8381
8382 stop_glerror();
8383
8384 mShadow[i+4].bindTarget();
8385 mShadow[i+4].getViewport(gGLViewport);
8386
8387 {
8388 LLGLDepthTest depth(GL_TRUE);
8389 mShadow[i+4].clear();
8390 }
8391
8392 renderShadow(view[i+4], proj[i+4], shadow_cam, FALSE);
8393
8394 mShadow[i+4].flush();
8395 }
6418 8396
6419 if (!gSavedSettings.getBOOL("CameraOffset")) 8397 if (!gSavedSettings.getBOOL("CameraOffset"))
6420 { 8398 {
@@ -6431,6 +8409,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
6431 glMatrixMode(GL_MODELVIEW); 8409 glMatrixMode(GL_MODELVIEW);
6432 } 8410 }
6433 gGL.setColorMask(true, false); 8411 gGL.setColorMask(true, false);
8412
8413 mRenderTypeMask = type_mask;
6434} 8414}
6435 8415
6436void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) 8416void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture)
@@ -6470,7 +8450,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
6470 8450
6471 if (muted) 8451 if (muted)
6472 { 8452 {
6473 mask = 1 << LLPipeline::RENDER_TYPE_AVATAR; 8453 mask = 1 << LLPipeline::RENDER_TYPE_INVISIBLE; // Peachy ;)
6474 } 8454 }
6475 else 8455 else
6476 { 8456 {
@@ -6481,7 +8461,16 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
6481 (1<<LLPipeline::RENDER_TYPE_SIMPLE) | 8461 (1<<LLPipeline::RENDER_TYPE_SIMPLE) |
6482 (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | 8462 (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |
6483 (1<<LLPipeline::RENDER_TYPE_ALPHA) | 8463 (1<<LLPipeline::RENDER_TYPE_ALPHA) |
6484 (1<<LLPipeline::RENDER_TYPE_INVISIBLE); 8464 (1<<LLPipeline::RENDER_TYPE_INVISIBLE) |
8465 (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) |
8466 (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) |
8467 (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) |
8468 (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) |
8469 (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) |
8470 (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) |
8471 (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) |
8472 (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) |
8473 (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY);
6485 } 8474 }
6486 8475
6487 mask = mask & gPipeline.getRenderTypeMask(); 8476 mask = mask & gPipeline.getRenderTypeMask();
@@ -6491,6 +8480,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
6491 S32 occlusion = sUseOcclusion; 8480 S32 occlusion = sUseOcclusion;
6492 sUseOcclusion = 0; 8481 sUseOcclusion = 0;
6493 sReflectionRender = sRenderDeferred ? FALSE : TRUE; 8482 sReflectionRender = sRenderDeferred ? FALSE : TRUE;
8483 sShadowRender = TRUE;
6494 sImpostorRender = TRUE; 8484 sImpostorRender = TRUE;
6495 8485
6496 markVisible(avatar->mDrawable, *LLViewerCamera::getInstance()); 8486 markVisible(avatar->mDrawable, *LLViewerCamera::getInstance());
@@ -6570,7 +8560,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
6570 if (LLPipeline::sRenderDeferred) 8560 if (LLPipeline::sRenderDeferred)
6571 { 8561 {
6572 avatar->mImpostor.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE); 8562 avatar->mImpostor.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE);
6573 addDeferredAttachments(avatar->mImpostor); 8563 //addDeferredAttachments(avatar->mImpostor);
6574 } 8564 }
6575 else 8565 else
6576 { 8566 {
@@ -6649,6 +8639,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
6649 sUseOcclusion = occlusion; 8639 sUseOcclusion = occlusion;
6650 sReflectionRender = FALSE; 8640 sReflectionRender = FALSE;
6651 sImpostorRender = FALSE; 8641 sImpostorRender = FALSE;
8642 sShadowRender = FALSE;
6652 gPipeline.mRenderTypeMask = saved_mask; 8643 gPipeline.mRenderTypeMask = saved_mask;
6653 8644
6654 glMatrixMode(GL_PROJECTION); 8645 glMatrixMode(GL_PROJECTION);