diff options
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r-- | indra/newview/pipeline.cpp | 2340 |
1 files changed, 1170 insertions, 1170 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 01438bfb9f..bd667acb53 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -329,6 +329,7 @@ bool LLPipeline::sDelayVBUpdate = true; bool LLPipeline::sAutoMaskAlphaDeferred = true; bool LLPipeline::sAutoMaskAlphaNonDeferred = false; bool LLPipeline::sDisableShaders = false; +bool LLPipeline::sRenderTransparentWater = true; bool LLPipeline::sRenderBump = true; bool LLPipeline::sBakeSunlight = false; bool LLPipeline::sNoAlpha = false; @@ -1044,30 +1045,31 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) } //static +void LLPipeline::updateRenderTransparentWater() +{ + sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater"); +} + +//static void LLPipeline::updateRenderBump() { sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); } -//static +// static void LLPipeline::updateRenderDeferred() { - bool deferred = (bool(RenderDeferred && - LLRenderTarget::sUseFBO && - LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && - LLPipeline::sRenderBump && - RenderAvatarVP && - WindLightUseAtmosShaders)) && - !gUseWireframe; - - sRenderDeferred = deferred; - if (deferred) - { //must render glow when rendering deferred since post effect pass is needed to present any lighting at all - sRenderGlow = true; - } + sRenderDeferred = !gUseWireframe && + RenderDeferred && + LLRenderTarget::sUseFBO && + LLPipeline::sRenderBump && + LLPipeline::sRenderTransparentWater && + RenderAvatarVP && + WindLightUseAtmosShaders && + (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"); } -//static +// static void LLPipeline::refreshCachedSettings() { LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); @@ -1259,24 +1261,20 @@ void LLPipeline::createGLBuffers() GLuint resX = gViewerWindow->getWorldViewWidthRaw(); GLuint resY = gViewerWindow->getWorldViewHeightRaw(); - - if (LLPipeline::sRenderGlow) - { //screen space glow buffers - const U32 glow_res = llmax(1, - llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); - for (U32 i = 0; i < 3; i++) - { - mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); - } + // allocate screen space glow buffers + const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); + for (U32 i = 0; i < 3; i++) + { + mGlow[i].allocate(512, glow_res, GL_RGBA, FALSE, FALSE); + } - allocateScreenBuffer(resX,resY); - mScreenWidth = 0; - mScreenHeight = 0; - } - - if (sRenderDeferred) - { + allocateScreenBuffer(resX, resY); + mScreenWidth = 0; + mScreenHeight = 0; + + if (sRenderDeferred) + { if (!mNoiseMap) { const U32 noiseRes = 128; @@ -1609,6 +1607,7 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0) break; case LLDrawPool::POOL_AVATAR: + case LLDrawPool::POOL_CONTROL_AV: break; // Do nothing case LLDrawPool::POOL_SKY: @@ -1678,7 +1677,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima if (alpha && mat) { - switch (mat->getDiffuseAlphaMode()) + switch (mat->getDiffuseAlphaModeRender()) { case 1: alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool. @@ -1995,7 +1994,7 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED); if (done) { - if (drawablep->isRoot()) + if (drawablep->isRoot() && !drawablep->isState(LLDrawable::ACTIVE)) { drawablep->makeStatic(); } @@ -3084,9 +3083,10 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) if (vobj) // this test may not be needed, see above { LLVOAvatar* av = vobj->asAvatar(); - if (av && (av->isImpostor() - || av->isInMuteList() - || (LLVOAvatar::AV_DO_NOT_RENDER == av->getVisualMuteSettings() && !av->needsImpostorUpdate()) )) + if (av && + ((!sImpostorRender && av->isImpostor()) //ignore impostor flag during impostor pass + || av->isInMuteList() + || (LLVOAvatar::AOA_JELLYDOLL == av->getOverallAppearance() && !av->needsImpostorUpdate()) )) { return; } @@ -3362,6 +3362,7 @@ static LLTrace::BlockTimerStatHandle FTM_RESET_DRAWORDER("Reset Draw Order"); void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) { if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_CONTROL_AV, LLPipeline::RENDER_TYPE_GROUND, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::RENDER_TYPE_TREE, @@ -5774,6 +5775,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) break; case LLDrawPool::POOL_AVATAR: + case LLDrawPool::POOL_CONTROL_AV: break; // Do nothing case LLDrawPool::POOL_SKY: @@ -5922,6 +5924,7 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) break; case LLDrawPool::POOL_AVATAR: + case LLDrawPool::POOL_CONTROL_AV: break; // Do nothing case LLDrawPool::POOL_SKY: @@ -6059,25 +6062,18 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_ { return max_dist; } - F32 radius = light->getLightRadius(); bool selected = light->isSelected(); - LLVector3 dpos = light->getRenderPosition() - cam_pos; - F32 dist2 = dpos.lengthSquared(); - if (!selected && dist2 > (max_dist + radius)*(max_dist + radius)) - { - return max_dist; - } - F32 dist = (F32) sqrt(dist2); - dist *= 1.f / inten; - dist -= radius; if (selected) { - dist -= 10000.f; // selected lights get highest priority + return 0.f; // selected lights get highest priority } + F32 radius = light->getLightRadius(); + F32 dist = dist_vec(light->getRenderPosition(), cam_pos); + dist = llmax(dist - radius, 0.f); if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE)) { // moving lights get a little higher priority (too much causes artifacts) - dist -= light->getLightRadius()*0.25f; + dist = llmax(dist - light->getLightRadius()*0.25f, 0.f); } return dist; } @@ -6096,13 +6092,18 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) // mNearbyLight (and all light_set_t's) are sorted such that // begin() == the closest light and rbegin() == the farthest light const S32 MAX_LOCAL_LIGHTS = 6; -// LLVector3 cam_pos = gAgent.getCameraPositionAgent(); - LLVector3 cam_pos = LLViewerJoystick::getInstance()->getOverrideCamera() ? - camera.getOrigin() : - gAgent.getPositionAgent(); - - F32 max_dist = LIGHT_MAX_RADIUS * 4.f; // ignore enitrely lights > 4 * max light rad + LLVector3 cam_pos = camera.getOrigin(); + F32 max_dist; + if (LLPipeline::sRenderDeferred) + { + max_dist = RenderFarClip; + } + else + { + max_dist = llmin(RenderFarClip, LIGHT_MAX_RADIUS * 4.f); + } + // UPDATE THE EXISTING NEARBY LIGHTS light_set_t cur_nearby_lights; for (light_set_t::iterator iter = mNearbyLights.begin(); @@ -6136,8 +6137,38 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) continue; } - F32 dist = calc_light_dist(volight, cam_pos, max_dist); - cur_nearby_lights.insert(Light(drawable, dist, light->fade)); + F32 dist = calc_light_dist(volight, cam_pos, max_dist); + F32 fade = light->fade; + // actual fade gets decreased/increased by setupHWLights + // light->fade value is 'time'. + // >=0 and light will become visible as value increases + // <0 and light will fade out + if (dist < max_dist) + { + if (fade < 0) + { + // mark light to fade in + // if fade was -LIGHT_FADE_TIME - it was fully invisible + // if fade -0 - it was fully visible + // visibility goes up from 0 to LIGHT_FADE_TIME. + fade += LIGHT_FADE_TIME; + } + } + else + { + // mark light to fade out + // visibility goes down from -0 to -LIGHT_FADE_TIME. + if (fade >= LIGHT_FADE_TIME) + { + fade = -0.0001f; // was fully visible + } + else if (fade >= 0) + { + // 0.75 visible light should stay 0.75 visible, but should reverse direction + fade -= LIGHT_FADE_TIME; + } + } + cur_nearby_lights.insert(Light(drawable, dist, fade)); } mNearbyLights = cur_nearby_lights; @@ -6156,17 +6187,23 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) { continue; // no lighting from HUD objects } - F32 dist = calc_light_dist(light, cam_pos, max_dist); - if (dist >= max_dist) + if (!sRenderAttachedLights && light && light->isAttachment()) { continue; } - if (!sRenderAttachedLights && light && light->isAttachment()) + LLVOAvatar * av = light->getAvatar(); + if (av && (av->isTooComplex() || av->isInMuteList())) + { + // avatars that are already in the list will be removed by removeMutedAVsLights + continue; + } + F32 dist = calc_light_dist(light, cam_pos, max_dist); + if (dist >= max_dist) { continue; } new_nearby_lights.insert(Light(drawable, dist, 0.f)); - if (new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS) + if (!LLPipeline::sRenderDeferred && new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS) { new_nearby_lights.erase(--new_nearby_lights.end()); const Light& last = *new_nearby_lights.rbegin(); @@ -6179,7 +6216,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) iter != new_nearby_lights.end(); iter++) { const Light* light = &(*iter); - if (mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS) + if (LLPipeline::sRenderDeferred || mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS) { mNearbyLights.insert(*light); ((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT); @@ -6192,10 +6229,22 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) Light* farthest_light = (const_cast<Light*>(&(*(mNearbyLights.rbegin())))); if (light->dist < farthest_light->dist) { - if (farthest_light->fade >= 0.f) - { - farthest_light->fade = -(gFrameIntervalSeconds.value()); - } + // mark light to fade out + // visibility goes down from -0 to -LIGHT_FADE_TIME. + // + // This is a mess, but for now it needs to be in sync + // with fade code above. Ex: code above detects distance < max, + // sets fade time to positive, this code then detects closer + // lights and sets fade time negative, fully compensating + // for the code above + if (farthest_light->fade >= LIGHT_FADE_TIME) + { + farthest_light->fade = -0.0001f; // was fully visible + } + else if (farthest_light->fade >= 0) + { + farthest_light->fade -= LIGHT_FADE_TIME; + } } else { @@ -6315,12 +6364,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) } } - const LLViewerObject *vobj = drawable->getVObj(); - if(vobj && vobj->getAvatar() && vobj->getAvatar()->isInMuteList()) - { - continue; - } - if (drawable->isState(LLDrawable::ACTIVE)) { mLightMovingMask |= (1<<cur_light); @@ -6427,41 +6470,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) light->setAmbient(LLColor4::black); light->setSpecular(LLColor4::black); } - if (gAgentAvatarp && - gAgentAvatarp->mSpecialRenderMode == 3) - { - LLColor4 light_color = LLColor4::white; - light_color.mV[3] = 0.0f; - - LLVector3 light_pos(LLViewerCamera::getInstance()->getOrigin()); - LLVector4 light_pos_gl(light_pos, 1.0f); - F32 light_radius = 16.f; - - F32 x = 3.f; - float linatten = x / (light_radius); // % of brightness at radius - - if (LLPipeline::sRenderDeferred) - { - /*light_color.mV[0] = powf(light_color.mV[0], 2.2f); - light_color.mV[1] = powf(light_color.mV[1], 2.2f); - light_color.mV[2] = powf(light_color.mV[2], 2.2f);*/ - } - - mHWLightColors[2] = light_color; - LLLightState* light = gGL.getLight(2); - - light->setPosition(light_pos_gl); - light->setDiffuse(light_color); - light->setDiffuseB(light_color * 0.25f); - light->setAmbient(LLColor4::black); - light->setSpecular(LLColor4::black); - light->setQuadraticAttenuation(0.f); - light->setConstantAttenuation(0.f); - light->setLinearAttenuation(linatten); - light->setSpotExponent(0.f); - light->setSpotCutoff(180.f); - } + // Bookmark comment to allow searching for mSpecialRenderMode == 3 (avatar edit mode), + // prev site of forward (non-deferred) character light injection, removed by SL-13522 09/20 // Init GL state if (!LLGLSLShader::sNoFixedFunction) @@ -6552,7 +6563,7 @@ void LLPipeline::enableLightsDynamic() { gPipeline.enableLightsAvatar(); } - else if (gAgentAvatarp->mSpecialRenderMode >= 1) // anim preview + else if (gAgentAvatarp->mSpecialRenderMode == 2) // anim preview { gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f)); } @@ -6600,7 +6611,7 @@ void LLPipeline::enableLightsPreview() light->enable(); light->setPosition(light_pos); light->setDiffuse(diffuse0); - light->setAmbient(LLColor4::black); + light->setAmbient(ambient); light->setSpecular(specular0); light->setSpotExponent(0.f); light->setSpotCutoff(180.f); @@ -6611,7 +6622,7 @@ void LLPipeline::enableLightsPreview() light->enable(); light->setPosition(light_pos); light->setDiffuse(diffuse1); - light->setAmbient(LLColor4::black); + light->setAmbient(ambient); light->setSpecular(specular1); light->setSpotExponent(0.f); light->setSpotCutoff(180.f); @@ -6621,7 +6632,7 @@ void LLPipeline::enableLightsPreview() light->enable(); light->setPosition(light_pos); light->setDiffuse(diffuse2); - light->setAmbient(LLColor4::black); + light->setAmbient(ambient); light->setSpecular(specular2); light->setSpotExponent(0.f); light->setSpotCutoff(180.f); @@ -7151,7 +7162,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) { if ((j == LLViewerRegion::PARTITION_VOLUME) || - (j == LLViewerRegion::PARTITION_BRIDGE) || + (j == LLViewerRegion::PARTITION_BRIDGE) || + (j == LLViewerRegion::PARTITION_CONTROL_AV) || (j == LLViewerRegion::PARTITION_TERRAIN) || (j == LLViewerRegion::PARTITION_TREE) || (j == LLViewerRegion::PARTITION_GRASS)) // only check these partitions for now @@ -7213,7 +7225,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, { LLViewerRegion* region = *iter; - LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE); + LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_AVATAR); if (part && hasRenderType(part->mDrawableType)) { LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent); @@ -7539,641 +7551,633 @@ void LLPipeline::bindScreenToTexture() static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom"); -void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) +void LLPipeline::renderFinalize() { - if (!(gPipeline.canUseVertexShaders() && - sRenderGlow)) - { - return; - } + LLVertexBuffer::unbind(); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); - LLVertexBuffer::unbind(); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); + assertInitialized(); - assertInitialized(); + if (gUseWireframe) + { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } - if (gUseWireframe) - { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } + LLVector2 tc1(0, 0); + LLVector2 tc2((F32) mScreen.getWidth() * 2, (F32) mScreen.getHeight() * 2); - LLVector2 tc1(0,0); - LLVector2 tc2((F32) mScreen.getWidth()*2, - (F32) mScreen.getHeight()*2); + LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); + gGL.color4f(1, 1, 1, 1); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable blend(GL_BLEND); + LLGLDisable cull(GL_CULL_FACE); - LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); - gGL.color4f(1,1,1,1); - LLGLDepthTest depth(GL_FALSE); - LLGLDisable blend(GL_BLEND); - LLGLDisable cull(GL_CULL_FACE); - - enableLightsFullbright(); + enableLightsFullbright(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadIdentity(); - LLGLDisable test(GL_ALPHA_TEST); + LLGLDisable test(GL_ALPHA_TEST); - gGL.setColorMask(true, true); - glClearColor(0,0,0,0); - - { - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); - mGlow[2].bindTarget(); - mGlow[2].clear(); - } - - gGlowExtractProgram.bind(); - F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f); - F32 maxAlpha = RenderGlowMaxExtractAlpha; - F32 warmthAmount = RenderGlowWarmthAmount; - LLVector3 lumWeights = RenderGlowLumWeights; - LLVector3 warmthWeights = RenderGlowWarmthWeights; - - - gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum); - gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); - gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]); - gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]); - gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); - LLGLEnable blend_on(GL_BLEND); - LLGLEnable test(GL_ALPHA_TEST); - - gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - - mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT); - - gGL.color4f(1,1,1,1); - gPipeline.enableLightsFullbright(); - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); - - gGL.getTexUnit(0)->unbind(mScreen.getUsage()); + gGL.setColorMask(true, true); + glClearColor(0, 0, 0, 0); - mGlow[2].flush(); - } + if (sRenderGlow) + { + { + LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); + mGlow[2].bindTarget(); + mGlow[2].clear(); + } - tc1.setVec(0,0); - tc2.setVec(2,2); + gGlowExtractProgram.bind(); + F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f); + F32 maxAlpha = RenderGlowMaxExtractAlpha; + F32 warmthAmount = RenderGlowWarmthAmount; + LLVector3 lumWeights = RenderGlowLumWeights; + LLVector3 warmthWeights = RenderGlowWarmthWeights; + + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum); + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); + gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], + lumWeights.mV[2]); + gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], + warmthWeights.mV[2]); + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); + + { + LLGLEnable blend_on(GL_BLEND); + LLGLEnable test(GL_ALPHA_TEST); - // power of two between 1 and 1024 - U32 glowResPow = RenderGlowResolutionPow; - const U32 glow_res = llmax(1, - llmin(1024, 1 << glowResPow)); + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - S32 kernel = RenderGlowIterations*2; - F32 delta = RenderGlowWidth / glow_res; - // Use half the glow width if we have the res set to less than 9 so that it looks - // almost the same in either case. - if (glowResPow < 9) - { - delta *= 0.5f; - } - F32 strength = RenderGlowStrength; + mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT); - gGlowProgram.bind(); - gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); + gGL.color4f(1, 1, 1, 1); + gPipeline.enableLightsFullbright(); + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); - for (S32 i = 0; i < kernel; i++) - { - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); - mGlow[i%2].bindTarget(); - mGlow[i%2].clear(); - } - - if (i == 0) - { - gGL.getTexUnit(0)->bind(&mGlow[2]); - } - else - { - gGL.getTexUnit(0)->bind(&mGlow[(i-1)%2]); - } + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); - if (i%2 == 0) - { - gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); - } - else - { - gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); - } + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); - - mGlow[i%2].flush(); - } + gGL.end(); - gGlowProgram.unbind(); + gGL.getTexUnit(0)->unbind(mScreen.getUsage()); - /*if (LLRenderTarget::sUseFBO) - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - }*/ + mGlow[2].flush(); - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + tc1.setVec(0, 0); + tc2.setVec(2, 2); + } - tc2.setVec((F32) mScreen.getWidth(), - (F32) mScreen.getHeight()); + // power of two between 1 and 1024 + U32 glowResPow = RenderGlowResolutionPow; + const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow)); - gGL.flush(); - - LLVertexBuffer::unbind(); + S32 kernel = RenderGlowIterations * 2; + F32 delta = RenderGlowWidth / glow_res; + // Use half the glow width if we have the res set to less than 9 so that it looks + // almost the same in either case. + if (glowResPow < 9) + { + delta *= 0.5f; + } + F32 strength = RenderGlowStrength; - if (LLPipeline::sRenderDeferred) - { + gGlowProgram.bind(); + gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); - bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && - (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && - RenderDepthOfField; + for (S32 i = 0; i < kernel; i++) + { + { + LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); + mGlow[i % 2].bindTarget(); + mGlow[i % 2].clear(); + } + if (i == 0) + { + gGL.getTexUnit(0)->bind(&mGlow[2]); + } + else + { + gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]); + } - bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete(); + if (i % 2 == 0) + { + gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); + } + else + { + gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); + } - gViewerWindow->setup3DViewport(); - - if (dof_enabled) - { - LLGLSLShader* shader = &gDeferredPostProgram; - LLGLDisable blend(GL_BLEND); + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); - //depth of field focal plane calculations - static F32 current_distance = 16.f; - static F32 start_distance = 16.f; - static F32 transition_time = 1.f; + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); - LLVector3 focus_point; + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); - LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); - if (obj && obj->mDrawable && obj->isSelected()) - { //focus on selected media object - S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); - if (obj && obj->mDrawable) - { - LLFace* face = obj->mDrawable->getFace(face_idx); - if (face) - { - focus_point = face->getPositionAgent(); - } - } - } - - if (focus_point.isExactlyZero()) - { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { //focus on point under cursor - focus_point.set(gDebugRaycastIntersection.getF32ptr()); - } - else if (gAgentCamera.cameraMouselook()) - { //focus on point under mouselook crosshairs - LLVector4a result; - result.clear(); + gGL.end(); - gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, - NULL, - &result); + mGlow[i % 2].flush(); + } - focus_point.set(result.getF32ptr()); - } - else - { - //focus on alt-zoom target - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal()); - } - } - } + gGlowProgram.unbind(); + } + else // !sRenderGlow, skip the glow ping-pong and just clear the result target + { + mGlow[1].bindTarget(); + mGlow[1].clear(); + mGlow[1].flush(); + } - LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); - F32 target_distance = 16.f; - if (!focus_point.isExactlyZero()) - { - target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye); - } + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - if (transition_time >= 1.f && - fabsf(current_distance-target_distance)/current_distance > 0.01f) - { //large shift happened, interpolate smoothly to new target distance - transition_time = 0.f; - start_distance = current_distance; - } - else if (transition_time < 1.f) - { //currently in a transition, continue interpolating - transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value(); - transition_time = llmin(transition_time, 1.f); + tc2.setVec((F32) mScreen.getWidth(), (F32) mScreen.getHeight()); - F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; - current_distance = start_distance + (target_distance-start_distance)*t; - } - else - { //small or no change, just snap to target distance - current_distance = target_distance; - } + gGL.flush(); - //convert to mm - F32 subject_distance = current_distance*1000.f; - F32 fnumber = CameraFNumber; - F32 default_focal_length = CameraFocalLength; + LLVertexBuffer::unbind(); - F32 fov = LLViewerCamera::getInstance()->getView(); - - const F32 default_fov = CameraFieldOfView * F_PI/180.f; - - //F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); - - F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f); + if (LLPipeline::sRenderDeferred) + { - F32 focal_length = dv/(2*tanf(fov/2.f)); - - //F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); - - // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) - // where N = fnumber - // s2 = dot distance - // s1 = subject distance - // f = focal length - // + bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && + (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && + RenderDepthOfField; - F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length)); - blur_constant /= 1000.f; //convert to meters for shader - F32 magnification = focal_length/(subject_distance-focal_length); + bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete(); - { //build diffuse+bloom+CoF - mDeferredLight.bindTarget(); - shader = &gDeferredCoFProgram; + gViewerWindow->setup3DViewport(); - bindDeferredShader(*shader); + if (dof_enabled) + { + LLGLSLShader *shader = &gDeferredPostProgram; + LLGLDisable blend(GL_BLEND); - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); - if (channel > -1) - { - mScreen.bindTexture(0, channel); - } + // depth of field focal plane calculations + static F32 current_distance = 16.f; + static F32 start_distance = 16.f; + static F32 transition_time = 1.f; - shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f); - shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); - shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f/LLDrawable::sCurPixelAngle)); - shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); - shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + LLVector3 focus_point; - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); + LLViewerObject *obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); + if (obj && obj->mDrawable && obj->isSelected()) + { // focus on selected media object + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); + if (obj && obj->mDrawable) + { + LLFace *face = obj->mDrawable->getFace(face_idx); + if (face) + { + focus_point = face->getPositionAgent(); + } + } + } - unbindDeferredShader(*shader); - mDeferredLight.flush(); - } + if (focus_point.isExactlyZero()) + { + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { // focus on point under cursor + focus_point.set(gDebugRaycastIntersection.getF32ptr()); + } + else if (gAgentCamera.cameraMouselook()) + { // focus on point under mouselook crosshairs + LLVector4a result; + result.clear(); - U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale); - U32 dof_height = (U32) (mScreen.getHeight()*CameraDoFResScale); - - { //perform DoF sampling at half-res (preserve alpha channel) - mScreen.bindTarget(); - glViewport(0,0, dof_width, dof_height); - gGL.setColorMask(true, false); + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, NULL, &result); - shader = &gDeferredPostProgram; - bindDeferredShader(*shader); - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); - if (channel > -1) - { - mDeferredLight.bindTexture(0, channel); - } + focus_point.set(result.getF32ptr()); + } + else + { + // focus on alt-zoom target + LLViewerRegion *region = gAgent.getRegion(); + if (region) + { + focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); + } + } + } - shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); + LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); + F32 target_distance = 16.f; + if (!focus_point.isExactlyZero()) + { + target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); + } - unbindDeferredShader(*shader); - mScreen.flush(); - gGL.setColorMask(true, true); - } - - { //combine result based on alpha - if (multisample) - { - mDeferredLight.bindTarget(); - glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); - } - else - { - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - } + if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f) + { // large shift happened, interpolate smoothly to new target distance + transition_time = 0.f; + start_distance = current_distance; + } + else if (transition_time < 1.f) + { // currently in a transition, continue interpolating + transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value(); + transition_time = llmin(transition_time, 1.f); - shader = &gDeferredDoFCombineProgram; - bindDeferredShader(*shader); - - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); - if (channel > -1) - { - mScreen.bindTexture(0, channel); - } + F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f; + current_distance = start_distance + (target_distance - start_distance) * t; + } + else + { // small or no change, just snap to target distance + current_distance = target_distance; + } - shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1); - shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height-1); + // convert to mm + F32 subject_distance = current_distance * 1000.f; + F32 fnumber = CameraFNumber; + F32 default_focal_length = CameraFocalLength; - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); + F32 fov = LLViewerCamera::getInstance()->getView(); - unbindDeferredShader(*shader); + const F32 default_fov = CameraFieldOfView * F_PI / 180.f; - if (multisample) - { - mDeferredLight.flush(); - } - } - } - else - { - if (multisample) - { - mDeferredLight.bindTarget(); - } - LLGLSLShader* shader = &gDeferredPostNoDoFProgram; - - bindDeferredShader(*shader); - - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); - if (channel > -1) - { - mScreen.bindTexture(0, channel); - } + // F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); + F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); - unbindDeferredShader(*shader); + F32 focal_length = dv / (2 * tanf(fov / 2.f)); - if (multisample) - { - mDeferredLight.flush(); - } - } + // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); - if (multisample) - { - //bake out texture2D with RGBL for FXAA shader - mFXAABuffer.bindTarget(); - - S32 width = mScreen.getWidth(); - S32 height = mScreen.getHeight(); - glViewport(0, 0, width, height); + // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) + // where N = fnumber + // s2 = dot distance + // s1 = subject distance + // f = focal length + // - LLGLSLShader* shader = &gGlowCombineFXAAProgram; + F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length)); + blur_constant /= 1000.f; // convert to meters for shader + F32 magnification = focal_length / (subject_distance - focal_length); - shader->bind(); - shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); + { // build diffuse+bloom+CoF + mDeferredLight.bindTarget(); + shader = &gDeferredCoFProgram; - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); - if (channel > -1) - { - mDeferredLight.bindTexture(0, channel); - } - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex2f(-1,-1); - gGL.vertex2f(-1,3); - gGL.vertex2f(3,-1); - gGL.end(); + bindDeferredShader(*shader); - gGL.flush(); + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + if (channel > -1) + { + mScreen.bindTexture(0, channel); + } - shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); - shader->unbind(); - - mFXAABuffer.flush(); + shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); + shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); + shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle)); + shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); + shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - shader = &gFXAAProgram; - shader->bind(); + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); - channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); - if (channel > -1) - { - mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); - } - - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - - F32 scale_x = (F32) width/mFXAABuffer.getWidth(); - F32 scale_y = (F32) height/mFXAABuffer.getHeight(); - shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); - shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f/width*scale_x, 1.f/height*scale_y); - shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f/width*scale_x, -0.5f/height*scale_y, 0.5f/width*scale_x, 0.5f/height*scale_y); - shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex2f(-1,-1); - gGL.vertex2f(-1,3); - gGL.vertex2f(3,-1); - gGL.end(); + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); - gGL.flush(); - shader->unbind(); - } - } - else - { - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; - LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0); - buff->allocateBuffer(3,0,TRUE); + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); - LLStrider<LLVector3> v; - LLStrider<LLVector2> uv1; - LLStrider<LLVector2> uv2; + gGL.end(); - buff->getVertexStrider(v); - buff->getTexCoord0Strider(uv1); - buff->getTexCoord1Strider(uv2); - - uv1[0] = LLVector2(0, 0); - uv1[1] = LLVector2(0, 2); - uv1[2] = LLVector2(2, 0); - - uv2[0] = LLVector2(0, 0); - uv2[1] = LLVector2(0, tc2.mV[1]*2.f); - uv2[2] = LLVector2(tc2.mV[0]*2.f, 0); - - v[0] = LLVector3(-1,-1,0); - v[1] = LLVector3(-1,3,0); - v[2] = LLVector3(3,-1,0); - - buff->flush(); + unbindDeferredShader(*shader); + mDeferredLight.flush(); + } - LLGLDisable blend(GL_BLEND); + U32 dof_width = (U32)(mScreen.getWidth() * CameraDoFResScale); + U32 dof_height = (U32)(mScreen.getHeight() * CameraDoFResScale); - if (LLGLSLShader::sNoFixedFunction) - { - gGlowCombineProgram.bind(); - } - else - { - //tex unit 0 - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); - //tex unit 1 - gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); - } - - gGL.getTexUnit(0)->bind(&mGlow[1]); - gGL.getTexUnit(1)->bind(&mScreen); - - LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - - buff->setBuffer(mask); - buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); - - if (LLGLSLShader::sNoFixedFunction) - { - gGlowCombineProgram.unbind(); - } - else - { - gGL.getTexUnit(1)->disable(); - gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); + { // perform DoF sampling at half-res (preserve alpha channel) + mScreen.bindTarget(); + glViewport(0, 0, dof_width, dof_height); + gGL.setColorMask(true, false); - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - } - - } + shader = &gDeferredPostProgram; + bindDeferredShader(*shader); + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); + if (channel > -1) + { + mDeferredLight.bindTexture(0, channel); + } - gGL.setSceneBlendType(LLRender::BT_ALPHA); + shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) - { - if (LLGLSLShader::sNoFixedFunction) - { - gSplatTextureRectProgram.bind(); - } + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); - gGL.setColorMask(true, false); + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); - LLVector2 tc1(0,0); - LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2, - (F32) gViewerWindow->getWorldViewHeightRaw()*2); + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); - LLGLEnable blend(GL_BLEND); - gGL.color4f(1,1,1,0.75f); + gGL.end(); - gGL.getTexUnit(0)->bind(&mPhysicsDisplay); + unbindDeferredShader(*shader); + mScreen.flush(); + gGL.setColorMask(true, true); + } - gGL.begin(LLRender::TRIANGLES); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); - gGL.flush(); + { // combine result based on alpha + if (multisample) + { + mDeferredLight.bindTarget(); + glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); + } + else + { + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + } - if (LLGLSLShader::sNoFixedFunction) - { - gSplatTextureRectProgram.unbind(); - } - } + shader = &gDeferredDoFCombineProgram; + bindDeferredShader(*shader); - - if (LLRenderTarget::sUseFBO) - { //copy depth buffer from mScreen to framebuffer - LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), - 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - } - + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + if (channel > -1) + { + mScreen.bindTexture(0, channel); + } - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); + shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width - 1); + shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height - 1); - LLVertexBuffer::unbind(); + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); + + gGL.end(); + + unbindDeferredShader(*shader); + + if (multisample) + { + mDeferredLight.flush(); + } + } + } + else + { + if (multisample) + { + mDeferredLight.bindTarget(); + } + LLGLSLShader *shader = &gDeferredPostNoDoFProgram; + + bindDeferredShader(*shader); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + if (channel > -1) + { + mScreen.bindTexture(0, channel); + } + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); + + gGL.end(); + + unbindDeferredShader(*shader); + + if (multisample) + { + mDeferredLight.flush(); + } + } + + if (multisample) + { + // bake out texture2D with RGBL for FXAA shader + mFXAABuffer.bindTarget(); + + S32 width = mScreen.getWidth(); + S32 height = mScreen.getHeight(); + glViewport(0, 0, width, height); + + LLGLSLShader *shader = &gGlowCombineFXAAProgram; + + shader->bind(); + shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); + if (channel > -1) + { + mDeferredLight.bindTexture(0, channel); + } + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex2f(-1, -1); + gGL.vertex2f(-1, 3); + gGL.vertex2f(3, -1); + gGL.end(); + + gGL.flush(); + + shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); + shader->unbind(); + + mFXAABuffer.flush(); + + shader = &gFXAAProgram; + shader->bind(); + + channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); + if (channel > -1) + { + mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + } + + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + + F32 scale_x = (F32) width / mFXAABuffer.getWidth(); + F32 scale_y = (F32) height / mFXAABuffer.getHeight(); + shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); + shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, + 0.5f / width * scale_x, 0.5f / height * scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y, + 2.f / width * scale_x, 2.f / height * scale_y); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex2f(-1, -1); + gGL.vertex2f(-1, 3); + gGL.vertex2f(3, -1); + gGL.end(); + + gGL.flush(); + shader->unbind(); + } + } + else // not deferred + { + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; + LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0); + buff->allocateBuffer(3, 0, TRUE); + + LLStrider<LLVector3> v; + LLStrider<LLVector2> uv1; + LLStrider<LLVector2> uv2; + + buff->getVertexStrider(v); + buff->getTexCoord0Strider(uv1); + buff->getTexCoord1Strider(uv2); + + uv1[0] = LLVector2(0, 0); + uv1[1] = LLVector2(0, 2); + uv1[2] = LLVector2(2, 0); + + uv2[0] = LLVector2(0, 0); + uv2[1] = LLVector2(0, tc2.mV[1] * 2.f); + uv2[2] = LLVector2(tc2.mV[0] * 2.f, 0); + + v[0] = LLVector3(-1, -1, 0); + v[1] = LLVector3(-1, 3, 0); + v[2] = LLVector3(3, -1, 0); + + buff->flush(); + + LLGLDisable blend(GL_BLEND); + + if (LLGLSLShader::sNoFixedFunction) + { + gGlowCombineProgram.bind(); + } + else + { + // tex unit 0 + gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); + // tex unit 1 + gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, + LLTexUnit::TBS_PREV_COLOR); + } + + gGL.getTexUnit(0)->bind(&mGlow[1]); + gGL.getTexUnit(1)->bind(&mScreen); + + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + + buff->setBuffer(mask); + buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); + + if (LLGLSLShader::sNoFixedFunction) + { + gGlowCombineProgram.unbind(); + } + else + { + gGL.getTexUnit(1)->disable(); + gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); + + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + } + } + + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + { + if (LLGLSLShader::sNoFixedFunction) + { + gSplatTextureRectProgram.bind(); + } + + gGL.setColorMask(true, false); + + LLVector2 tc1(0, 0); + LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw() * 2, + (F32) gViewerWindow->getWorldViewHeightRaw() * 2); + + LLGLEnable blend(GL_BLEND); + gGL.color4f(1, 1, 1, 0.75f); + + gGL.getTexUnit(0)->bind(&mPhysicsDisplay); + + gGL.begin(LLRender::TRIANGLES); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); + + gGL.end(); + gGL.flush(); + + if (LLGLSLShader::sNoFixedFunction) + { + gSplatTextureRectProgram.unbind(); + } + } + + if (LLRenderTarget::sUseFBO) + { // copy depth buffer from mScreen to framebuffer + LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 0, 0, + mScreen.getWidth(), mScreen.getHeight(), + GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); + } + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + + LLVertexBuffer::unbind(); + + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); } static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred"); @@ -8453,628 +8457,622 @@ static LLTrace::BlockTimerStatHandle FTM_FULLSCREEN_LIGHTS("Fullscreen Lights"); static LLTrace::BlockTimerStatHandle FTM_PROJECTORS("Projectors"); static LLTrace::BlockTimerStatHandle FTM_POST("Post"); - -void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target) +void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target) { - if (!sCull) - { - return; - } + if (!sCull) + { + return; + } - LLRenderTarget* deferred_target = &mDeferredScreen; - LLRenderTarget* deferred_depth_target = &mDeferredDepth; - LLRenderTarget* deferred_light_target = &mDeferredLight; + LLRenderTarget *deferred_target = &mDeferredScreen; + LLRenderTarget *deferred_depth_target = &mDeferredDepth; + LLRenderTarget *deferred_light_target = &mDeferredLight; - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED); - LLViewerCamera* camera = LLViewerCamera::getInstance(); - { - LLGLDepthTest depth(GL_TRUE); - deferred_depth_target->copyContents(*deferred_target, 0, 0, deferred_target->getWidth(), deferred_target->getHeight(), - 0, 0, deferred_depth_target->getWidth(), deferred_depth_target->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); - } + { + LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED); + LLViewerCamera *camera = LLViewerCamera::getInstance(); + { + LLGLDepthTest depth(GL_TRUE); + deferred_depth_target->copyContents(*deferred_target, + 0, + 0, + deferred_target->getWidth(), + deferred_target->getHeight(), + 0, + 0, + deferred_depth_target->getWidth(), + deferred_depth_target->getHeight(), + GL_DEPTH_BUFFER_BIT, + GL_NEAREST); + } - LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); - } + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); + } - //ati doesn't seem to love actually using the stencil buffer on FBO's - LLGLDisable stencil(GL_STENCIL_TEST); - //glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); - //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + // ati doesn't seem to love actually using the stencil buffer on FBO's + LLGLDisable stencil(GL_STENCIL_TEST); + // glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); + // glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - gGL.setColorMask(true, true); - - //draw a cube around every light - LLVertexBuffer::unbind(); + gGL.setColorMask(true, true); - LLGLEnable cull(GL_CULL_FACE); - LLGLEnable blend(GL_BLEND); + // draw a cube around every light + LLVertexBuffer::unbind(); + + LLGLEnable cull(GL_CULL_FACE); + LLGLEnable blend(GL_BLEND); glh::matrix4f mat = copy_matrix(gGLModelView); - LLStrider<LLVector3> vert; - mDeferredVB->getVertexStrider(vert); - - vert[0].set(-1,1,0); - vert[1].set(-1,-3,0); - vert[2].set(3,1,0); - - setupHWLights(NULL); //to set mSun/MoonDir; + LLStrider<LLVector3> vert; + mDeferredVB->getVertexStrider(vert); + + vert[0].set(-1, 1, 0); + vert[1].set(-1, -3, 0); + vert[2].set(3, 1, 0); + + setupHWLights(NULL); // to set mSun/MoonDir; glh::vec4f tc(mSunDir.mV); - mat.mult_matrix_vec(tc); - mTransformedSunDir.set(tc.v); + mat.mult_matrix_vec(tc); + mTransformedSunDir.set(tc.v); glh::vec4f tc_moon(mMoonDir.mV); mat.mult_matrix_vec(tc_moon); mTransformedMoonDir.set(tc_moon.v); - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); - if (RenderDeferredSSAO || RenderShadowDetail > 0) - { + if (RenderDeferredSSAO || RenderShadowDetail > 0) + { deferred_light_target->bindTarget(); - { //paint shadow/SSAO light map (direct lighting lightmap) - LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW); + { // paint shadow/SSAO light map (direct lighting lightmap) + LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW); bindDeferredShader(gDeferredSunProgram, deferred_light_target); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - glClearColor(1,1,1,1); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + glClearColor(1, 1, 1, 1); deferred_light_target->clear(GL_COLOR_BUFFER_BIT); - glClearColor(0,0,0,0); + glClearColor(0, 0, 0, 0); glh::matrix4f inv_trans = get_current_modelview().inverse().transpose(); - const U32 slice = 32; - F32 offset[slice*3]; - for (U32 i = 0; i < 4; i++) - { - for (U32 j = 0; j < 8; j++) - { - glh::vec3f v; - v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); - v.normalize(); - inv_trans.mult_matrix_vec(v); - v.normalize(); - offset[(i*8+j)*3+0] = v.v[0]; - offset[(i*8+j)*3+1] = v.v[2]; - offset[(i*8+j)*3+2] = v.v[1]; - } - } + const U32 slice = 32; + F32 offset[slice * 3]; + for (U32 i = 0; i < 4; i++) + { + for (U32 j = 0; j < 8; j++) + { + glh::vec3f v; + v.set_value(sinf(6.284f / 8 * j), cosf(6.284f / 8 * j), -(F32) i); + v.normalize(); + inv_trans.mult_matrix_vec(v); + v.normalize(); + offset[(i * 8 + j) * 3 + 0] = v.v[0]; + offset[(i * 8 + j) * 3 + 1] = v.v[2]; + offset[(i * 8 + j) * 3 + 2] = v.v[1]; + } + } - gDeferredSunProgram.uniform3fv(sOffset, slice, offset); - gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, deferred_light_target->getWidth(), deferred_light_target->getHeight()); - - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); - } - - unbindDeferredShader(gDeferredSunProgram); - } + gDeferredSunProgram.uniform3fv(sOffset, slice, offset); + gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, + deferred_light_target->getWidth(), + deferred_light_target->getHeight()); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + stop_glerror(); + } + + unbindDeferredShader(gDeferredSunProgram); + } deferred_light_target->flush(); - } - - if (RenderDeferredSSAO) - { //soften direct lighting lightmap - LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW); - //blur lightmap + } + + if (RenderDeferredSSAO) + { // soften direct lighting lightmap + LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW); + // blur lightmap screen_target->bindTarget(); - glClearColor(1,1,1,1); + glClearColor(1, 1, 1, 1); screen_target->clear(GL_COLOR_BUFFER_BIT); - glClearColor(0,0,0,0); - - bindDeferredShader(gDeferredBlurLightProgram); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - LLVector3 go = RenderShadowGaussian; - const U32 kern_length = 4; - F32 blur_size = RenderShadowBlurSize; - F32 dist_factor = RenderShadowBlurDistFactor; + glClearColor(0, 0, 0, 0); - // sample symmetrically with the middle sample falling exactly on 0.0 - F32 x = 0.f; + bindDeferredShader(gDeferredBlurLightProgram); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + LLVector3 go = RenderShadowGaussian; + const U32 kern_length = 4; + F32 blur_size = RenderShadowBlurSize; + F32 dist_factor = RenderShadowBlurDistFactor; - LLVector3 gauss[32]; // xweight, yweight, offset + // sample symmetrically with the middle sample falling exactly on 0.0 + F32 x = 0.f; - for (U32 i = 0; i < kern_length; i++) - { - gauss[i].mV[0] = llgaussian(x, go.mV[0]); - gauss[i].mV[1] = llgaussian(x, go.mV[1]); - gauss[i].mV[2] = x; - x += 1.f; - } + LLVector3 gauss[32]; // xweight, yweight, offset + + for (U32 i = 0; i < kern_length; i++) + { + gauss[i].mV[0] = llgaussian(x, go.mV[0]); + gauss[i].mV[1] = llgaussian(x, go.mV[1]); + gauss[i].mV[2] = x; + x += 1.f; + } + + gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f); + gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor); + gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length / 2.f - 0.5f)); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + stop_glerror(); + } - gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f); - gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor); - gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length/2.f - 0.5f)); - - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); - } - screen_target->flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + unbindDeferredShader(gDeferredBlurLightProgram); bindDeferredShader(gDeferredBlurLightProgram, screen_target); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); deferred_light_target->bindTarget(); - gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); + gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); - } + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + stop_glerror(); + } deferred_light_target->flush(); - unbindDeferredShader(gDeferredBlurLightProgram); - } + unbindDeferredShader(gDeferredBlurLightProgram); + } - stop_glerror(); - gGL.popMatrix(); - stop_glerror(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - stop_glerror(); - gGL.popMatrix(); - stop_glerror(); + stop_glerror(); + gGL.popMatrix(); + stop_glerror(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + stop_glerror(); + gGL.popMatrix(); + stop_glerror(); screen_target->bindTarget(); - // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky - glClearColor(0,0,0,0); + // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky + glClearColor(0, 0, 0, 0); screen_target->clear(GL_COLOR_BUFFER_BIT); - - if (RenderDeferredAtmospheric) - { //apply sunlight contribution - LLGLSLShader& soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram; - LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS); - bindDeferredShader(soften_shader); + if (RenderDeferredAtmospheric) + { // apply sunlight contribution + LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram; + + LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS); + bindDeferredShader(soften_shader); - LLEnvironment& environment = LLEnvironment::instance(); + LLEnvironment &environment = LLEnvironment::instance(); soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); soften_shader.uniform4fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV); - { - LLGLDepthTest depth(GL_FALSE); - LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); + { + LLGLDepthTest depth(GL_FALSE); + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); - //full screen blit - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); + // full screen blit + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - } + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram); - } + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + } - { //render non-deferred geometry (fullbright, alpha, etc) - LLGLDisable blend(GL_BLEND); - LLGLDisable stencil(GL_STENCIL_TEST); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram); + } - gPipeline.pushRenderTypeMask(); - - gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLOUDS, - LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::END_RENDER_TYPES); - - - renderGeomPostDeferred(*LLViewerCamera::getInstance(), false); - gPipeline.popRenderTypeMask(); - } + { // render non-deferred geometry (fullbright, alpha, etc) + LLGLDisable blend(GL_BLEND); + LLGLDisable stencil(GL_STENCIL_TEST); + gGL.setSceneBlendType(LLRender::BT_ALPHA); - bool render_local = RenderLocalLights; - - if (render_local) - { - gGL.setSceneBlendType(LLRender::BT_ADD); - std::list<LLVector4> fullscreen_lights; - LLDrawable::drawable_list_t spot_lights; - LLDrawable::drawable_list_t fullscreen_spot_lights; + gPipeline.pushRenderTypeMask(); - for (U32 i = 0; i < 2; i++) - { - mTargetShadowSpotLight[i] = NULL; - } + gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::END_RENDER_TYPES); - std::list<LLVector4> light_colors; + renderGeomPostDeferred(*LLViewerCamera::getInstance(), false); + gPipeline.popRenderTypeMask(); + } - LLVertexBuffer::unbind(); + bool render_local = RenderLocalLights; - { - bindDeferredShader(gDeferredLightProgram); - - if (mCubeVB.isNull()) - { - mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); - } + if (render_local) + { + gGL.setSceneBlendType(LLRender::BT_ADD); + std::list<LLVector4> fullscreen_lights; + LLDrawable::drawable_list_t spot_lights; + LLDrawable::drawable_list_t fullscreen_spot_lights; - mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) - { - LLDrawable* drawablep = *iter; - - LLVOVolume* volume = drawablep->getVOVolume(); - if (!volume) - { - continue; - } + for (U32 i = 0; i < 2; i++) + { + mTargetShadowSpotLight[i] = NULL; + } - if (volume->isAttachment()) - { - if (!sRenderAttachedLights) - { - continue; - } - } + std::list<LLVector4> light_colors; + + LLVertexBuffer::unbind(); + + { + bindDeferredShader(gDeferredLightProgram); + + if (mCubeVB.isNull()) + { + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); + } + + mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - const LLViewerObject *vobj = drawablep->getVObj(); - if (vobj) + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + // mNearbyLights already includes distance calculation and excludes muted avatars. + // It is calculated from mLights + // mNearbyLights also provides fade value to gracefully fade-out out of range lights + for (light_set_t::iterator iter = mNearbyLights.begin(); iter != mNearbyLights.end(); ++iter) + { + LLDrawable * drawablep = iter->drawable; + LLVOVolume * volume = drawablep->getVOVolume(); + if (!volume) + { + continue; + } + + if (volume->isAttachment()) { - LLVOAvatar *av = vobj->getAvatar(); - if (av && (av->isTooComplex() || av->isInMuteList())) + if (!sRenderAttachedLights) { continue; } } - const LLVector3 position = drawablep->getPositionAgent(); - if (dist_vec(position, LLViewerCamera::getInstance()->getOrigin()) > RenderFarClip + volume->getLightRadius()) + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32 *c = center.getF32ptr(); + F32 s = volume->getLightRadius() * 1.5f; + + // send light color to shader in linear space + LLColor3 col = volume->getLightLinearColor(); + + if (col.magVecSquared() < 0.001f) { continue; } - LLVector4a center; - center.load3(position.mV); - const F32* c = center.getF32ptr(); - F32 s = volume->getLightRadius()*1.5f; - - //send light color to shader in linear space - LLColor3 col = volume->getLightLinearColor(); - - if (col.magVecSquared() < 0.001f) - { - continue; - } + if (s <= 0.001f) + { + continue; + } - if (s <= 0.001f) - { - continue; - } + LLVector4a sa; + sa.splat(s); + if (camera->AABBInFrustumNoFarClip(center, sa) == 0) + { + continue; + } - LLVector4a sa; - sa.splat(s); - if (camera->AABBInFrustumNoFarClip(center, sa) == 0) - { - continue; - } + sVisibleLightCount++; - sVisibleLightCount++; - - if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || - camera->getOrigin().mV[0] < c[0] - s - 0.2f || - camera->getOrigin().mV[1] > c[1] + s + 0.2f || - camera->getOrigin().mV[1] < c[1] - s - 0.2f || - camera->getOrigin().mV[2] > c[2] + s + 0.2f || - camera->getOrigin().mV[2] < c[2] - s - 0.2f) - { //draw box if camera is outside box - if (render_local) - { - if (volume->isLightSpotlight()) - { - drawablep->getVOVolume()->updateSpotLightPriority(); - spot_lights.push_back(drawablep); - continue; - } - - LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS); - gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); - gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); - gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); + if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || camera->getOrigin().mV[0] < c[0] - s - 0.2f || + camera->getOrigin().mV[1] > c[1] + s + 0.2f || camera->getOrigin().mV[1] < c[1] - s - 0.2f || + camera->getOrigin().mV[2] > c[2] + s + 0.2f || camera->getOrigin().mV[2] < c[2] - s - 0.2f) + { // draw box if camera is outside box + if (render_local) + { + if (volume->isLightSpotlight()) + { + drawablep->getVOVolume()->updateSpotLightPriority(); + spot_lights.push_back(drawablep); + continue; + } + + LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS); + gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); + gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); + gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF)); - gGL.syncMatrices(); - - mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); - stop_glerror(); - } - } - else - { - if (volume->isLightSpotlight()) - { - drawablep->getVOVolume()->updateSpotLightPriority(); - fullscreen_spot_lights.push_back(drawablep); - continue; - } + gGL.syncMatrices(); - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); - - fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s)); + mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); + stop_glerror(); + } + } + else + { + if (volume->isLightSpotlight()) + { + drawablep->getVOVolume()->updateSpotLightPriority(); + fullscreen_spot_lights.push_back(drawablep); + continue; + } + + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + + fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s)); light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF))); - } - } - unbindDeferredShader(gDeferredLightProgram); - } + } + } - if (!spot_lights.empty()) - { - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - bindDeferredShader(gDeferredSpotLightProgram); + // Bookmark comment to allow searching for mSpecialRenderMode == 3 (avatar edit mode), + // prev site of appended deferred character light, removed by SL-13522 09/20 - mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + unbindDeferredShader(gDeferredLightProgram); + } - gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); + if (!spot_lights.empty()) + { + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + bindDeferredShader(gDeferredSpotLightProgram); - for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) - { - LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); - LLDrawable* drawablep = *iter; + mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + + gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); - LLVOVolume* volume = drawablep->getVOVolume(); + for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) + { + LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); + LLDrawable *drawablep = *iter; - LLVector4a center; - center.load3(drawablep->getPositionAgent().mV); - const F32* c = center.getF32ptr(); - F32 s = volume->getLightRadius()*1.5f; + LLVOVolume *volume = drawablep->getVOVolume(); - sVisibleLightCount++; + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32 *c = center.getF32ptr(); + F32 s = volume->getLightRadius() * 1.5f; - setupSpotLight(gDeferredSpotLightProgram, drawablep); - - //send light color to shader in linear space + sVisibleLightCount++; + + setupSpotLight(gDeferredSpotLightProgram, drawablep); + + // send light color to shader in linear space LLColor3 col = volume->getLightLinearColor(); - - gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); - gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); - gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); + + gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); + gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); + gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF)); - gGL.syncMatrices(); - - mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); - } - gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); - unbindDeferredShader(gDeferredSpotLightProgram); - } + gGL.syncMatrices(); + + mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); + } + gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); + unbindDeferredShader(gDeferredSpotLightProgram); + } - //reset mDeferredVB to fullscreen triangle - mDeferredVB->getVertexStrider(vert); - vert[0].set(-1,1,0); - vert[1].set(-1,-3,0); - vert[2].set(3,1,0); + // reset mDeferredVB to fullscreen triangle + mDeferredVB->getVertexStrider(vert); + vert[0].set(-1, 1, 0); + vert[1].set(-1, -3, 0); + vert[2].set(3, 1, 0); - { - LLGLDepthTest depth(GL_FALSE); + { + LLGLDepthTest depth(GL_FALSE); - //full screen blit - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); + // full screen blit + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); - U32 count = 0; + U32 count = 0; - const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT; - LLVector4 light[max_count]; - LLVector4 col[max_count]; + const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT; + LLVector4 light[max_count]; + LLVector4 col[max_count]; - F32 far_z = 0.f; + F32 far_z = 0.f; - while (!fullscreen_lights.empty()) - { - LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS); - light[count] = fullscreen_lights.front(); - fullscreen_lights.pop_front(); - col[count] = light_colors.front(); - light_colors.pop_front(); - - far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z); - count++; - if (count == max_count || fullscreen_lights.empty()) - { - U32 idx = count-1; - bindDeferredShader(gDeferredMultiLightProgram[idx]); - gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); - gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); - gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); - gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); - far_z = 0.f; - count = 0; - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - unbindDeferredShader(gDeferredMultiLightProgram[idx]); - } - } - - bindDeferredShader(gDeferredMultiSpotLightProgram); + while (!fullscreen_lights.empty()) + { + LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS); + light[count] = fullscreen_lights.front(); + fullscreen_lights.pop_front(); + col[count] = light_colors.front(); + light_colors.pop_front(); + + far_z = llmin(light[count].mV[2] - light[count].mV[3], far_z); + count++; + if (count == max_count || fullscreen_lights.empty()) + { + U32 idx = count - 1; + bindDeferredShader(gDeferredMultiLightProgram[idx]); + gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); + gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat *) light); + gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat *) col); + gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); + far_z = 0.f; + count = 0; + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + unbindDeferredShader(gDeferredMultiLightProgram[idx]); + } + } - gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); + bindDeferredShader(gDeferredMultiSpotLightProgram); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); - for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) - { - LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); - LLDrawable* drawablep = *iter; - - LLVOVolume* volume = drawablep->getVOVolume(); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; - F32 light_size_final = volume->getLightRadius()*1.5f; - F32 light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF); + for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) + { + LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); + LLDrawable *drawablep = *iter; + LLVOVolume *volume = drawablep->getVOVolume(); + LLVector3 center = drawablep->getPositionAgent(); + F32 * c = center.mV; + F32 light_size_final = volume->getLightRadius() * 1.5f; + F32 light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF); - sVisibleLightCount++; + sVisibleLightCount++; - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); - - setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); - //send light color to shader in linear space + setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); + + // send light color to shader in linear space LLColor3 col = volume->getLightLinearColor(); - - gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); + + gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, light_size_final); - gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); + gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, light_falloff_final); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } - gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); - unbindDeferredShader(gDeferredMultiSpotLightProgram); + gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); + unbindDeferredShader(gDeferredMultiSpotLightProgram); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - } - } + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + } + } - gGL.setColorMask(true, true); - } + gGL.setColorMask(true, true); + } screen_target->flush(); - //gamma correct lighting - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.loadIdentity(); + // gamma correct lighting + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadIdentity(); - { - LLGLDepthTest depth(GL_FALSE, GL_FALSE); + { + LLGLDepthTest depth(GL_FALSE, GL_FALSE); - LLVector2 tc1(0,0); - LLVector2 tc2((F32) screen_target->getWidth()*2, - (F32) screen_target->getHeight()*2); + LLVector2 tc1(0, 0); + LLVector2 tc2((F32) screen_target->getWidth() * 2, (F32) screen_target->getHeight() * 2); screen_target->bindTarget(); - // Apply gamma correction to the frame here. - gDeferredPostGammaCorrectProgram.bind(); - //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - S32 channel = 0; - channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage()); - if (channel > -1) - { + // Apply gamma correction to the frame here. + gDeferredPostGammaCorrectProgram.bind(); + // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + S32 channel = 0; + channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage()); + if (channel > -1) + { screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT); - } - + } + gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight()); - - F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); - gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); - + F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); + + gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); + + gGL.end(); + gGL.getTexUnit(channel)->unbind(screen_target->getUsage()); - gDeferredPostGammaCorrectProgram.unbind(); + gDeferredPostGammaCorrectProgram.unbind(); screen_target->flush(); - } + } - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); screen_target->bindTarget(); - { //render non-deferred geometry (alpha, fullbright, glow) - LLGLDisable blend(GL_BLEND); - LLGLDisable stencil(GL_STENCIL_TEST); - - pushRenderTypeMask(); - andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, - LLPipeline::RENDER_TYPE_FULLBRIGHT, - LLPipeline::RENDER_TYPE_VOLUME, - LLPipeline::RENDER_TYPE_GLOW, - LLPipeline::RENDER_TYPE_BUMP, - LLPipeline::RENDER_TYPE_PASS_SIMPLE, - LLPipeline::RENDER_TYPE_PASS_ALPHA, - LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_BUMP, - LLPipeline::RENDER_TYPE_PASS_POST_BUMP, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, - LLPipeline::RENDER_TYPE_PASS_GLOW, - LLPipeline::RENDER_TYPE_PASS_GRASS, - LLPipeline::RENDER_TYPE_PASS_SHINY, - LLPipeline::RENDER_TYPE_PASS_INVISIBLE, - LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, - LLPipeline::RENDER_TYPE_AVATAR, - LLPipeline::RENDER_TYPE_ALPHA_MASK, - LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, - END_RENDER_TYPES); - - renderGeomPostDeferred(*LLViewerCamera::getInstance()); - popRenderTypeMask(); - } + { // render non-deferred geometry (alpha, fullbright, glow) + LLGLDisable blend(GL_BLEND); + LLGLDisable stencil(GL_STENCIL_TEST); + + pushRenderTypeMask(); + andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, + LLPipeline::RENDER_TYPE_FULLBRIGHT, + LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_GLOW, + LLPipeline::RENDER_TYPE_BUMP, + LLPipeline::RENDER_TYPE_PASS_SIMPLE, + LLPipeline::RENDER_TYPE_PASS_ALPHA, + LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_BUMP, + LLPipeline::RENDER_TYPE_PASS_POST_BUMP, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, + LLPipeline::RENDER_TYPE_PASS_GLOW, + LLPipeline::RENDER_TYPE_PASS_GRASS, + LLPipeline::RENDER_TYPE_PASS_SHINY, + LLPipeline::RENDER_TYPE_PASS_INVISIBLE, + LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, + LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_CONTROL_AV, + LLPipeline::RENDER_TYPE_ALPHA_MASK, + LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, + END_RENDER_TYPES); + + renderGeomPostDeferred(*LLViewerCamera::getInstance()); + popRenderTypeMask(); + } - { - //render highlights, etc. - renderHighlights(); - mHighlightFaces.clear(); + { + // render highlights, etc. + renderHighlights(); + mHighlightFaces.clear(); - renderDebug(); + renderDebug(); - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - gObjectList.resetObjectBeacons(); + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + // Render debugging beacons. + gObjectList.renderObjectBeacons(); + gObjectList.resetObjectBeacons(); gSky.addSunMoonBeacons(); - } - } + } + } - screen_target->flush(); + screen_target->flush(); } void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) @@ -9291,7 +9289,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.pushRenderTypeMask(); - glh::matrix4f projection = get_current_projection(); + glh::matrix4f saved_modelview = get_current_modelview(); + glh::matrix4f saved_projection = get_current_projection(); glh::matrix4f mat; S32 detail = RenderReflectionDetail; @@ -9330,8 +9329,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) //disable occlusion culling for reflection map for now LLPipeline::sUseOcclusion = 0; - glh::matrix4f current = get_current_modelview(); - if (!camera_is_underwater) { //generate planar reflection map @@ -9340,15 +9337,10 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); - glh::matrix4f mat; - camera.getOpenGLTransform(mat.m); - - glh::matrix4f scal; - scal.set_scale(glh::vec3f(1, 1, -1)); - mat = scal * mat; + mat.set_scale(glh::vec3f(1, 1, -1)); + mat.set_translate(glh::vec3f(0,0,water_height*2.f)); + mat = saved_modelview * mat; - // convert from CFR to OGL coord sys... - mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; mReflectionModelView = mat; @@ -9357,6 +9349,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE); + glh::vec3f origin(0, 0, 0); + glh::matrix4f inv_mat = mat.inverse(); + inv_mat.mult_matrix_vec(origin); + + camera.setOrigin(origin.v); + glCullFace(GL_FRONT); if (LLDrawPoolWater::sNeedsReflectionUpdate) @@ -9401,7 +9399,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES); if (detail < 3) { - clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); + clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_CONTROL_AV, END_RENDER_TYPES); if (detail < 2) { clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES); @@ -9409,7 +9407,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } } - LLGLUserClipPlane clip_plane(plane, mReflectionModelView, projection); + LLGLUserClipPlane clip_plane(plane, mReflectionModelView, saved_projection); LLGLDisable cull(GL_CULL_FACE); updateCull(camera, mReflectedObjects, -water_clip, &plane); stateSort(camera, mReflectedObjects); @@ -9423,7 +9421,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.popMatrix(); - set_current_modelview(current); + set_current_modelview(saved_modelview); } //LLPipeline::sUseOcclusion = occlusion; @@ -9479,7 +9477,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) //clip out geometry on the same side of water as the camera w/ enough margin to not include the water geo itself, // but not so much as to clip out parts of avatars that should be seen under the water in the distortion map LLPlane plane(-pnorm, water_dist); - LLGLUserClipPlane clip_plane(plane, current, projection); + LLGLUserClipPlane clip_plane(plane, saved_modelview, saved_projection); gGL.setColorMask(true, true); mWaterDis.clear(); @@ -10116,6 +10114,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLPipeline::RENDER_TYPE_BUMP, LLPipeline::RENDER_TYPE_VOLUME, LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_CONTROL_AV, LLPipeline::RENDER_TYPE_TREE, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::RENDER_TYPE_WATER, @@ -10909,7 +10908,9 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (visually_muted || too_complex) { - andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); + andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_CONTROL_AV, + END_RENDER_TYPES); } else { @@ -10932,6 +10933,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLPipeline::RENDER_TYPE_PASS_INVISIBLE, LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_CONTROL_AV, LLPipeline::RENDER_TYPE_ALPHA_MASK, LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, LLPipeline::RENDER_TYPE_INVISIBLE, @@ -10952,7 +10954,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) { LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_MARK_VISIBLE); markVisible(avatar->mDrawable, *viewer_camera); - LLVOAvatar::sUseImpostors = false; // @TODO ??? LLVOAvatar::attachment_map_t::iterator iter; for (iter = avatar->mAttachmentPoints.begin(); @@ -11192,7 +11193,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) avatar->setImpostorDim(tdim); - LLVOAvatar::sUseImpostors = (0 != LLVOAvatar::sMaxNonImpostors); sUseOcclusion = occlusion; sReflectionRender = false; sImpostorRender = false; |