diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/pipeline.cpp | 3191 |
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 | ||
162 | void drawBox(const LLVector3& c, const LLVector3& r); | ||
163 | |||
162 | U32 nhpo2(U32 v) | 164 | U32 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 | ||
268 | void validate_framebuffer_object(); | 270 | void validate_framebuffer_object(); |
269 | 271 | ||
272 | |||
270 | void addDeferredAttachments(LLRenderTarget& target) | 273 | void 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 | ||
277 | LLPipeline::LLPipeline() : | 279 | LLPipeline::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 | ||
318 | void LLPipeline::init() | 322 | void 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 | ||
367 | LLPipeline::~LLPipeline() | 376 | LLPipeline::~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 | ||
485 | void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) | 488 | void 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 | ||
640 | void LLPipeline::restoreGL() | 782 | void 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 | ||
701 | void LLPipeline::assertInitializedDoError() | 843 | void 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 | ||
1011 | U32 LLPipeline::addObject(LLViewerObject *vobj) | 1178 | U32 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 | ||
1294 | BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) | 1461 | BOOL 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 | ||
1726 | void 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 | |||
1737 | void 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 | |||
1756 | void 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 | |||
1559 | void LLPipeline::updateGeom(F32 max_dtime) | 1798 | void 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 | ||
2051 | void LLPipeline::markGLRebuild(LLGLUpdate* glu) | ||
2052 | { | ||
2053 | if (glu && !glu->mInQ) | ||
2054 | { | ||
2055 | LLGLUpdate::sGLQ.push_back(glu); | ||
2056 | glu->mInQ = TRUE; | ||
2057 | } | ||
2058 | } | ||
2059 | |||
2060 | void 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 | |||
1802 | void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority) | 2099 | void 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) | |||
1939 | void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) | 2241 | void 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 | ||
2759 | void LLPipeline::renderGeomDeferred(LLCamera& camera) | 3172 | void 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 | ||
5290 | void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) | 5747 | void 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! | ||
5422 | void LLPipeline::renderDeferredLighting() | 6101 | void 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 | ||
6814 | void 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 | |||
5767 | void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) | 6944 | void 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 | ||
5799 | inline float sgn(float a) | 7005 | inline 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 | ||
6093 | void LLPipeline::generateSunShadow(LLCamera& camera) | 7298 | void 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 | |||
7393 | BOOL 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 | |||
7510 | void 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 | |||
7660 | void 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 | ||
7689 | void 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 | |||
7748 | void 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 | ||
6436 | void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) | 8416 | void 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); |