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