diff options
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r-- | indra/newview/pipeline.cpp | 1435 |
1 files changed, 965 insertions, 470 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 3778cae201..e8052aa5a0 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -193,6 +193,7 @@ std::string gPoolNames[] = }; void drawBox(const LLVector3& c, const LLVector3& r); +void drawBoxOutline(const LLVector3& pos, const LLVector3& size); U32 nhpo2(U32 v) { @@ -270,9 +271,12 @@ BOOL LLPipeline::sRenderHighlight = TRUE; BOOL LLPipeline::sForceOldBakedUpload = FALSE; S32 LLPipeline::sUseOcclusion = 0; BOOL LLPipeline::sDelayVBUpdate = TRUE; -BOOL LLPipeline::sFastAlpha = TRUE; +BOOL LLPipeline::sAutoMaskAlphaDeferred = TRUE; +BOOL LLPipeline::sAutoMaskAlphaNonDeferred = FALSE; BOOL LLPipeline::sDisableShaders = FALSE; BOOL LLPipeline::sRenderBump = TRUE; +BOOL LLPipeline::sBakeSunlight = FALSE; +BOOL LLPipeline::sNoAlpha = FALSE; BOOL LLPipeline::sUseTriStrips = TRUE; BOOL LLPipeline::sUseFarClip = TRUE; BOOL LLPipeline::sShadowRender = FALSE; @@ -286,6 +290,7 @@ BOOL LLPipeline::sRenderFrameTest = FALSE; BOOL LLPipeline::sRenderAttachedLights = TRUE; BOOL LLPipeline::sRenderAttachedParticles = TRUE; BOOL LLPipeline::sRenderDeferred = FALSE; +BOOL LLPipeline::sAllowRebuildPriorityGroup = FALSE ; S32 LLPipeline::sVisibleLightCount = 0; F32 LLPipeline::sMinRenderSize = 0.f; @@ -329,7 +334,6 @@ LLPipeline::LLPipeline() : mInitialized(FALSE), mVertexShadersEnabled(FALSE), mVertexShadersLoaded(0), - mRenderTypeMask(0), mRenderDebugFeatureMask(0), mRenderDebugMask(0), mOldRenderDebugMask(0), @@ -383,7 +387,11 @@ void LLPipeline::init() LLViewerStats::getInstance()->mTrianglesDrawnStat.reset(); resetFrameStats(); - mRenderTypeMask = 0xffffffff; // All render types start on + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled + } + mRenderDebugFeatureMask = 0xffffffff; // All debugging features on mRenderDebugMask = 0; // All debug starts off @@ -571,9 +579,12 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale"); + //HACK: make alpha masking work on ATI depth shadows (work around for ATI driver bug) + U32 shadow_fmt = gGLManager.mIsATI ? GL_ALPHA : 0; + for (U32 i = 0; i < 4; i++) { - mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); } @@ -582,11 +593,9 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) for (U32 i = 4; i < 6; i++) { - mShadow[i].allocate(width, height, 0, TRUE, FALSE); + mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE); } - - width = nhpo2(resX)/2; height = nhpo2(resY)/2; mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE); @@ -631,9 +640,11 @@ void LLPipeline::updateRenderDeferred() { BOOL deferred = (gSavedSettings.getBOOL("RenderDeferred") && LLRenderTarget::sUseFBO && + LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && gSavedSettings.getBOOL("VertexShaderEnable") && gSavedSettings.getBOOL("RenderAvatarVP") && - gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE; + (gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE) && + !gUseWireframe; sRenderDeferred = deferred; } @@ -908,13 +919,18 @@ S32 LLPipeline::setLightingDetail(S32 level) if (level < 0) { - level = gSavedSettings.getS32("RenderLightingDetail"); + if (gSavedSettings.getBOOL("VertexShaderEnable")) + { + level = 1; + } + else + { + level = 0; + } } level = llclamp(level, 0, getMaxLightingDetail()); if (level != mLightingDetail) { - gSavedSettings.setS32("RenderLightingDetail", level); - mLightingDetail = level; if (mVertexShadersLoaded == 1) @@ -1498,11 +1514,214 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera return radius*radius * F_PI; } +//static +F32 LLPipeline::calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera) +{ + LLVector4a origin; + origin.load3(camera.getOrigin().mV); + + LLVector4a lookAt; + lookAt.setSub(center, origin); + F32 dist = lookAt.getLength3().getF32(); + + //ramp down distance for nearby objects + //shrink dist by dist/16. + if (dist < 16.f) + { + dist /= 16.f; + dist *= dist; + dist *= 16.f; + } + + //get area of circle around node + F32 app_angle = atanf(size.getLength3().getF32()/dist); + F32 radius = app_angle*LLDrawable::sCurPixelAngle; + return radius*radius * F_PI; +} + void LLPipeline::grabReferences(LLCullResult& result) { sCull = &result; } +void LLPipeline::clearReferences() +{ + sCull = NULL; +} + +void check_references(LLSpatialGroup* group, LLDrawable* drawable) +{ + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + if (drawable == *i) + { + llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl; + } + } +} + +void check_references(LLDrawable* drawable, LLFace* face) +{ + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + if (drawable->getFace(i) == face) + { + llerrs << "LLFace deleted while actively referenced by LLPipeline." << llendl; + } + } +} + +void check_references(LLSpatialGroup* group, LLFace* face) +{ + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + LLDrawable* drawable = *i; + check_references(drawable, face); + } +} + +void LLPipeline::checkReferences(LLFace* face) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + LLDrawable* drawable = *iter; + check_references(drawable, face); + } + } +#endif +} + +void LLPipeline::checkReferences(LLDrawable* drawable) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + if (drawable == *iter) + { + llerrs << "LLDrawable deleted while actively referenced by LLPipeline." << llendl; + } + } + } +#endif +} + +void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info) +{ + for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) + { + LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; + for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) + { + LLDrawInfo* params = *j; + if (params == draw_info) + { + llerrs << "LLDrawInfo deleted while actively referenced by LLPipeline." << llendl; + } + } + } +} + + +void LLPipeline::checkReferences(LLDrawInfo* draw_info) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + } +#endif +} + +void LLPipeline::checkReferences(LLSpatialGroup* group) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + } +#endif +} + + BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); @@ -1531,8 +1750,10 @@ BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& max) { - min = LLVector3(F32_MAX, F32_MAX, F32_MAX); - max = LLVector3(-F32_MAX, -F32_MAX, -F32_MAX); + const F32 X = 65536.f; + + min = LLVector3(X,X,X); + max = LLVector3(-X,-X,-X); U32 saved_camera_id = LLViewerCamera::sCurCameraID; LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; @@ -1702,7 +1923,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) } if (sMinRenderSize > 0.f && - llmax(llmax(group->mBounds[1].mV[0], group->mBounds[1].mV[1]), group->mBounds[1].mV[2]) < sMinRenderSize) + llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize) { return; } @@ -1799,15 +2020,23 @@ void LLPipeline::updateGL() void LLPipeline::rebuildPriorityGroups() { + if(!sAllowRebuildPriorityGroup) + { + return ; + } + sAllowRebuildPriorityGroup = FALSE ; + LLTimer update_timer; LLMemType mt(LLMemType::MTYPE_PIPELINE); assertInitialized(); +#if LL_MESH_ENABLED gMeshRepo.notifyLoadedMeshes(); +#endif // Iterate through all drawables on the priority build queue, - for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin(); + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); iter != mGroupQ1.end(); ++iter) { LLSpatialGroup* group = *iter; @@ -1969,23 +2198,30 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_VISIBLE); - if(!drawablep || drawablep->isDead()) + if(drawablep && !drawablep->isDead()) { - return; - } - if (drawablep->isSpatialBridge()) { - LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; - - if (root && root->getParent() && root->getVObj() && root->getVObj()->isAttachment()) + const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; + llassert(root); // trying to catch a bad assumption + if (root && // // this test may not be needed, see above + root->getVObj()->isAttachment()) + { + LLDrawable* rootparent = root->getParent(); + if (rootparent) // this IS sometimes NULL + { + LLViewerObject *vobj = rootparent->getVObj(); + llassert(vobj); // trying to catch a bad assumption + if (vobj) // this test may not be needed, see above { - LLVOAvatar* av = root->getParent()->getVObj()->asAvatar(); + const LLVOAvatar* av = vobj->asAvatar(); if (av && av->isImpostor()) { return; } } + } + } sCull->pushBridge((LLSpatialBridge*) drawablep); } else @@ -1995,6 +2231,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) drawablep->setVisible(camera); } +} void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) { @@ -2074,6 +2311,9 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) glClear(GL_DEPTH_BUFFER_BIT); gDepthDirty = TRUE; + LLVector4a offseta; + offseta.load3(offset.mV); + for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); iter != mShiftList.end(); iter++) { @@ -2082,7 +2322,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) { continue; } - drawablep->shiftPos(offset); + drawablep->shiftPos(offseta); drawablep->clearState(LLDrawable::ON_SHIFT_LIST); } mShiftList.resize(0); @@ -2096,7 +2336,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) LLSpatialPartition* part = region->getSpatialPartition(i); if (part) { - part->shift(offset); + part->shift(offseta); } } } @@ -2203,14 +2443,13 @@ static LLFastTimer::DeclareTimer FTM_RESET_DRAWORDER("Reset Draw Order"); void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) { - const U32 face_mask = (1 << LLPipeline::RENDER_TYPE_AVATAR) | - (1 << LLPipeline::RENDER_TYPE_GROUND) | - (1 << LLPipeline::RENDER_TYPE_TERRAIN) | - (1 << LLPipeline::RENDER_TYPE_TREE) | - (1 << LLPipeline::RENDER_TYPE_SKY) | - (1 << LLPipeline::RENDER_TYPE_WATER); - - if (mRenderTypeMask & face_mask) + if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::END_RENDER_TYPES)) { //clear faces from face pools LLFastTimer t(FTM_RESET_DRAWORDER); @@ -2223,7 +2462,6 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) //LLVertexBuffer::unbind(); grabReferences(result); - for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; @@ -2241,7 +2479,6 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; @@ -2257,7 +2494,6 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) @@ -2271,7 +2507,6 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } } - { LLFastTimer ftm(FTM_STATESORT_DRAWABLE); for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); @@ -2284,13 +2519,12 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } } - { LLFastTimer ftm(FTM_CLIENT_COPY); LLVertexBuffer::clientCopy(); } - - postSort(camera); + + postSort(camera); } void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) @@ -2560,6 +2794,7 @@ void LLPipeline::postSort(LLCamera& camera) assertInitialized(); + llpushcallstacks ; //rebuild drawable geometry for (LLCullResult::sg_list_t::iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) { @@ -2570,7 +2805,7 @@ void LLPipeline::postSort(LLCamera& camera) group->rebuildGeom(); } } - + llpushcallstacks ; //rebuild groups sCull->assertDrawMapsEmpty(); @@ -2590,6 +2825,7 @@ void LLPipeline::postSort(LLCamera& camera) rebuildPriorityGroups(); + llpushcallstacks ; const S32 bin_count = 1024*8; @@ -2633,8 +2869,10 @@ void LLPipeline::postSort(LLCamera& camera) { if (sMinRenderSize > 0.f) { - LLVector3 bounds = (*k)->mExtents[1]-(*k)->mExtents[0]; - if (llmax(llmax(bounds.mV[0], bounds.mV[1]), bounds.mV[2]) > sMinRenderSize) + LLVector4a bounds; + bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]); + + if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize) { sCull->pushDrawInfo(j->first, *k); } @@ -2691,7 +2929,7 @@ void LLPipeline::postSort(LLCamera& camera) std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater()); } - + llpushcallstacks ; // 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 if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender) { @@ -2739,7 +2977,7 @@ void LLPipeline::postSort(LLCamera& camera) forAllVisibleDrawables(renderSoundHighlights); } } - + llpushcallstacks ; // If managing your telehub, draw beacons at telehub and currently selected spawnpoint. if (LLFloaterTelehub::renderBeacons()) { @@ -2769,6 +3007,7 @@ void LLPipeline::postSort(LLCamera& camera) } //LLSpatialGroup::sNoDelete = FALSE; + llpushcallstacks ; } @@ -2980,6 +3219,9 @@ void LLPipeline::renderHighlights() } } +//debug use +U32 LLPipeline::sCurRenderPoolType = 0 ; + void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) { LLMemType mt(LLMemType::MTYPE_PIPELINE_RENDER_GEOM); @@ -3089,6 +3331,9 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) cur_type = poolp->getType(); + //debug use + sCurRenderPoolType = cur_type ; + if (occlude && cur_type >= LLDrawPool::POOL_GRASS) { occlude = FALSE; @@ -3426,20 +3671,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); - renderHighlights(); - mHighlightFaces.clear(); - - renderDebug(); - - LLVertexBuffer::unbind(); - - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - gObjectList.resetObjectBeacons(); - } - if (occlude) { occlude = FALSE; @@ -3619,6 +3850,7 @@ void LLPipeline::renderDebug() gPipeline.mDebugTextureUploadCost = textures.size() * 10; gPipeline.mDebugSculptUploadCost = sculpts.size()*10; +#if LL_MESH_ENABLED U32 mesh_cost = 0; for (std::set<LLUUID>::iterator iter = meshes.begin(); iter != meshes.end(); ++iter) @@ -3627,6 +3859,7 @@ void LLPipeline::renderDebug() } gPipeline.mDebugMeshUploadCost = mesh_cost; +#endif } for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) @@ -3643,6 +3876,8 @@ void LLPipeline::renderDebug() if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { + LLVertexBuffer::unbind(); + LLGLEnable blend(GL_BLEND); LLGLDepthTest depth(TRUE, FALSE); LLGLDisable cull(GL_CULL_FACE); @@ -3667,12 +3902,17 @@ void LLPipeline::renderDebug() for (U32 i = 0; i < 8; i++) { + LLVector3* frust = mShadowCamera[i].mAgentFrustum; + if (i > 3) + { //render shadow frusta as volumes + if (mShadowFrustPoints[i-4].empty()) { + continue; + } + gGL.color4fv(col+(i-4)*4); - LLVector3* frust = mShadowCamera[i].mAgentFrustum; - gGL.begin(LLRender::TRIANGLE_STRIP); gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); @@ -3700,31 +3940,49 @@ void LLPipeline::renderDebug() if (i < 4) { - gGL.begin(LLRender::LINES); - F32* c = col+i*4; - for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) + //if (i == 0 || !mShadowFrustPoints[i].empty()) { + //render visible point cloud + gGL.flush(); + glPointSize(8.f); + gGL.begin(LLRender::POINTS); + F32* c = col+i*4; gGL.color3fv(c); - for (U32 k = 0; k < mShadowFrustPoints[i].size(); ++k) - { - if (j != k) + for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) { gGL.vertex3fv(mShadowFrustPoints[i][j].mV); - gGL.vertex3fv(mShadowFrustPoints[i][k].mV); + } + gGL.end(); + + gGL.flush(); + glPointSize(1.f); + + LLVector3* ext = mShadowExtents[i]; + LLVector3 pos = (ext[0]+ext[1])*0.5f; + LLVector3 size = (ext[1]-ext[0])*0.5f; + drawBoxOutline(pos, size); + + //render camera frustum splits as outlines + gGL.begin(LLRender::LINES); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV); + gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV); + gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV); + gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV); + gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV); + gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV); + gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); + gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); + gGL.end(); } - if (!mShadowFrustOrigin[i].isExactlyZero()) - { - gGL.vertex3fv(mShadowFrustPoints[i][j].mV); - gGL.color4f(1,1,1,1); - gGL.vertex3fv(mShadowFrustOrigin[i].mV); - } - } - gGL.end(); } /*for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); @@ -4348,7 +4606,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f); + glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f); } else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini) { @@ -4413,7 +4671,7 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_ { return max_dist; } - F32 dist = fsqrtf(dist2); + F32 dist = (F32) sqrt(dist2); dist *= 1.f / inten; dist -= radius; if (selected) @@ -4648,7 +4906,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); glLightf (gllight, GL_LINEAR_ATTENUATION, linatten); glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f); - if (light->isLightSpotlight()) // directional (spot-)light + if (light->isLightSpotlight() // directional (spot-)light + && (LLPipeline::sRenderDeferred || gSavedSettings.getBOOL("RenderSpotLightsInNondeferred"))) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on { LLVector3 spotparams = light->getSpotLightParams(); LLQuaternion quat = light->getRenderRotation(); @@ -4663,8 +4922,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) } else // omnidirectional (point) light { - glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); - glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); + glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); + glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); // we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight const float specular[] = {0.f, 0.f, 0.f, 1.f}; @@ -4697,7 +4956,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) F32 light_radius = 16.f; - F32 x = 3.f; + F32 x = 3.f; float linatten = x / (light_radius); // % of brightness at radius mHWLightColors[2] = light_color; @@ -5028,8 +5287,7 @@ void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light) //static void LLPipeline::toggleRenderType(U32 type) { - U32 bit = (1<<type); - gPipeline.mRenderTypeMask ^= bit; + gPipeline.mRenderTypeEnabled[type] = !gPipeline.mRenderTypeEnabled[type]; } //static @@ -5442,6 +5700,8 @@ void LLPipeline::resetVertexBuffers() sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); + sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight"); + sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha"); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -5922,8 +6182,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) } +static LLFastTimer::DeclareTimer FTM_BIND_DEFERRED("Bind Deferred"); + void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRenderTarget* gi_source, LLRenderTarget* last_gi_post, U32 noise_map) { + LLFastTimer t(FTM_BIND_DEFERRED); + if (noise_map == 0xFFFFFFFF) { noise_map = mNoiseMap; @@ -6261,10 +6525,16 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen matrix_nondiag, matrix_nondiag, matrix_diag}; shader.uniformMatrix3fv("ssao_effect_mat", 1, GL_FALSE, ssao_effect_mat); + F32 shadow_offset_error = 1.f + gSavedSettings.getF32("RenderShadowOffsetError") * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); + F32 shadow_bias_error = 1.f + gSavedSettings.getF32("RenderShadowBiasError") * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); + shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f); - shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset")); - shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias")); + shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset")*shadow_offset_error); + shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias")*shadow_bias_error); + shader.uniform1f ("spot_shadow_offset", gSavedSettings.getF32("RenderSpotShadowOffset")); + shader.uniform1f("spot_shadow_bias", gSavedSettings.getF32("RenderSpotShadowBias")); + shader.uniform1f("lum_scale", gSavedSettings.getF32("RenderLuminanceScale")); shader.uniform1f("sun_lum_scale", gSavedSettings.getF32("RenderSunLuminanceScale")); shader.uniform1f("sun_lum_offset", gSavedSettings.getF32("RenderSunLuminanceOffset")); @@ -6358,13 +6628,13 @@ void LLPipeline::renderDeferredLighting() glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); } - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); - mDeferredLight[0].bindTarget(); + mDeferredLight[0].bindTarget(); if (gSavedSettings.getBOOL("RenderDeferredSSAO") || gSavedSettings.getS32("RenderShadowDetail") > 0) { @@ -6409,19 +6679,19 @@ void LLPipeline::renderDeferredLighting() unbindDeferredShader(gDeferredSunProgram); } } - else - { + else + { glClearColor(1,1,1,1); - mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); + mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); glClearColor(0,0,0,0); - } + } - mDeferredLight[0].flush(); + mDeferredLight[0].flush(); { //global illumination specific block (still experimental) if (gSavedSettings.getBOOL("RenderDeferredBlurLight") && - gSavedSettings.getBOOL("RenderDeferredGI")) - { + gSavedSettings.getBOOL("RenderDeferredGI")) + { LLFastTimer ftm(FTM_EDGE_DETECTION); //generate edge map LLGLDisable blend(GL_BLEND); @@ -6523,75 +6793,75 @@ void LLPipeline::renderDeferredLighting() } if (gSavedSettings.getBOOL("RenderDeferredSSAO")) - { //soften direct lighting lightmap - LLFastTimer ftm(FTM_SOFTEN_SHADOW); - //blur lightmap - mDeferredLight[1].bindTarget(); + { //soften direct lighting lightmap + LLFastTimer ftm(FTM_SOFTEN_SHADOW); + //blur lightmap + mDeferredLight[1].bindTarget(); - glClearColor(1,1,1,1); - mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); - glClearColor(0,0,0,0); - - bindDeferredShader(gDeferredBlurLightProgram); + glClearColor(1,1,1,1); + mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); + glClearColor(0,0,0,0); + + bindDeferredShader(gDeferredBlurLightProgram); - LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); - const U32 kern_length = 4; - F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); - F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); + LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); + const U32 kern_length = 4; + F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); + F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); - // sample symmetrically with the middle sample falling exactly on 0.0 - F32 x = 0.f; + // sample symmetrically with the middle sample falling exactly on 0.0 + F32 x = 0.f; - LLVector3 gauss[32]; // xweight, yweight, offset + 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; - } + 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("delta", 1.f, 0.f); - gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); - - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } + gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); + gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); + gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); - mDeferredLight[1].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + mDeferredLight[1].flush(); + unbindDeferredShader(gDeferredBlurLightProgram); - bindDeferredShader(gDeferredBlurLightProgram, 1); - mDeferredLight[0].bindTarget(); + bindDeferredShader(gDeferredBlurLightProgram, 1); + mDeferredLight[0].bindTarget(); - gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); + gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + mDeferredLight[0].flush(); + unbindDeferredShader(gDeferredBlurLightProgram); } - mDeferredLight[0].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); - } - stop_glerror(); - glPopMatrix(); - stop_glerror(); - glMatrixMode(GL_MODELVIEW); - stop_glerror(); - glPopMatrix(); - stop_glerror(); + stop_glerror(); + glPopMatrix(); + stop_glerror(); + glMatrixMode(GL_MODELVIEW); + stop_glerror(); + glPopMatrix(); + stop_glerror(); //copy depth and stencil from deferred screen //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), @@ -6600,11 +6870,15 @@ void LLPipeline::renderDeferredLighting() if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) { mDeferredLight[1].bindTarget(); - mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); + // clear color buffer here (GI) - zeroing alpha (glow) is important or it will accumulate against sky + glClearColor(0,0,0,0); + mScreen.clear(GL_COLOR_BUFFER_BIT); } else { mScreen.bindTarget(); + // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky + glClearColor(0,0,0,0); mScreen.clear(GL_COLOR_BUFFER_BIT); } @@ -6641,15 +6915,16 @@ void LLPipeline::renderDeferredLighting() LLGLDisable stencil(GL_STENCIL_TEST); gGL.setSceneBlendType(LLRender::BT_ALPHA); - U32 render_mask = mRenderTypeMask; - mRenderTypeMask = mRenderTypeMask & - ((1 << LLPipeline::RENDER_TYPE_SKY) | - (1 << LLPipeline::RENDER_TYPE_CLOUDS) | - (1 << LLPipeline::RENDER_TYPE_WL_SKY)); + gPipeline.pushRenderTypeMask(); + + gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::END_RENDER_TYPES); renderGeomPostDeferred(*LLViewerCamera::getInstance()); - mRenderTypeMask = render_mask; + gPipeline.popRenderTypeMask(); } BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); @@ -6694,8 +6969,18 @@ void LLPipeline::renderDeferredLighting() continue; } - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; + if (volume->isAttachment()) + { + if (!sRenderAttachedLights) + { + continue; + } + } + + + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32* c = center.getF32ptr(); F32 s = volume->getLightRadius()*1.5f; LLColor3 col = volume->getLightColor(); @@ -6711,7 +6996,9 @@ void LLPipeline::renderDeferredLighting() continue; } - if (camera->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) + LLVector4a sa; + sa.splat(s); + if (camera->AABBInFrustumNoFarClip(center, sa) == 0) { continue; } @@ -6789,8 +7076,9 @@ void LLPipeline::renderDeferredLighting() LLVOVolume* volume = drawablep->getVOVolume(); - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32* c = center.getF32ptr(); F32 s = volume->getLightRadius()*1.5f; sVisibleLightCount++; @@ -6962,29 +7250,30 @@ void LLPipeline::renderDeferredLighting() LLGLDisable blend(GL_BLEND); LLGLDisable stencil(GL_STENCIL_TEST); - U32 render_mask = mRenderTypeMask; - mRenderTypeMask = mRenderTypeMask & - ((1 << LLPipeline::RENDER_TYPE_ALPHA) | - (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) | - (1 << LLPipeline::RENDER_TYPE_VOLUME) | - (1 << LLPipeline::RENDER_TYPE_GLOW) | - (1 << LLPipeline::RENDER_TYPE_BUMP) | - (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) | - (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) | - (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) | - (1 << LLPipeline::RENDER_TYPE_PASS_GLOW) | - (1 << LLPipeline::RENDER_TYPE_PASS_GRASS) | - (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) | - (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY) | - (1 << LLPipeline::RENDER_TYPE_AVATAR)); + 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, + END_RENDER_TYPES); renderGeomPostDeferred(*LLViewerCamera::getInstance()); - mRenderTypeMask = render_mask; + popRenderTypeMask(); } { @@ -7000,6 +7289,7 @@ void LLPipeline::renderDeferredLighting() { // Render debugging beacons. gObjectList.renderObjectBeacons(); + LLHUDObject::renderAll(); gObjectList.resetObjectBeacons(); } } @@ -7209,11 +7499,11 @@ inline float sgn(float a) } void LLPipeline::generateWaterReflection(LLCamera& camera_in) -{ +{ if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) { BOOL skip_avatar_update = FALSE; - if (gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) + if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) { skip_avatar_update = TRUE; } @@ -7237,7 +7527,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLPipeline::sUseOcclusion = llmin(occlusion, 1); - U32 type_mask = gPipeline.mRenderTypeMask; + gPipeline.pushRenderTypeMask(); glh::matrix4f projection = glh_get_current_projection(); glh::matrix4f mat; @@ -7305,44 +7595,48 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glCullFace(GL_FRONT); - static LLCullResult ref_result; - U32 ref_mask = 0; + if (LLDrawPoolWater::sNeedsDistortionUpdate) { //initial sky pass (no user clip plane) { //mask out everything but the sky - U32 tmp = mRenderTypeMask; - mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) | - (1 << LLPipeline::RENDER_TYPE_WL_SKY)); + gPipeline.pushRenderTypeMask(); + gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::END_RENDER_TYPES); static LLCullResult result; updateCull(camera, result); stateSort(camera, result); - mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) | - (1 << LLPipeline::RENDER_TYPE_CLOUDS) | - (1 << LLPipeline::RENDER_TYPE_WL_SKY)); + andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::END_RENDER_TYPES); + renderGeom(camera, TRUE); - mRenderTypeMask = tmp; + gPipeline.popRenderTypeMask(); } - U32 mask = mRenderTypeMask; - mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_WATER) | - (1<<LLPipeline::RENDER_TYPE_GROUND) | - (1<<LLPipeline::RENDER_TYPE_SKY) | - (1<<LLPipeline::RENDER_TYPE_CLOUDS)); + gPipeline.pushRenderTypeMask(); - S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); + clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::END_RENDER_TYPES); + + S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); if (detail > 0) { //mask out selected geometry based on reflection detail if (detail < 4) { - mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_PARTICLES); - if (detail < 3) + clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES); + if (detail < 3) + { + clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); + if (detail < 2) { - mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_AVATAR); - if (detail < 2) - { - mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_VOLUME); + clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES); } } } @@ -7353,20 +7647,18 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) stateSort(camera, ref_result); } - ref_mask = mRenderTypeMask; - mRenderTypeMask = mask; - } - if (LLDrawPoolWater::sNeedsDistortionUpdate) { - mRenderTypeMask = ref_mask; - if (gSavedSettings.getS32("RenderReflectionDetail") > 0) + if (gSavedSettings.getS32("RenderReflectionDetail") > 0) { gPipeline.grabReferences(ref_result); LLGLUserClipPlane clip_plane(plane, mat, projection); renderGeom(camera); } } + + gPipeline.popRenderTypeMask(); + } glCullFace(GL_BACK); glPopMatrix(); mWaterRef.flush(); @@ -7374,24 +7666,25 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } camera.setOrigin(camera_in.getOrigin()); - //render distortion map static BOOL last_update = TRUE; if (last_update) { camera.setFar(camera_in.getFar()); - mRenderTypeMask = type_mask & (~(1<<LLPipeline::RENDER_TYPE_WATER) | - (1<<LLPipeline::RENDER_TYPE_GROUND)); + clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_GROUND, + END_RENDER_TYPES); stop_glerror(); LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? FALSE : TRUE; if (LLPipeline::sUnderWaterRender) { - mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_GROUND) | - (1<<LLPipeline::RENDER_TYPE_SKY) | - (1<<LLPipeline::RENDER_TYPE_CLOUDS) | - (1<<LLPipeline::RENDER_TYPE_WL_SKY)); + clearRenderTypeMask(LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::RENDER_TYPE_WL_SKY, + END_RENDER_TYPES); } LLViewerCamera::updateFrustumPlanes(camera); @@ -7431,9 +7724,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glClear(GL_DEPTH_BUFFER_BIT); } glClearColor(0.f, 0.f, 0.f, 0.f); - gViewerWindow->setup3DViewport(); - mRenderTypeMask = type_mask; + gPipeline.popRenderTypeMask(); LLDrawPoolWater::sNeedsReflectionUpdate = FALSE; LLDrawPoolWater::sNeedsDistortionUpdate = FALSE; LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd)); @@ -7624,112 +7916,169 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LLPipeline::sShadowRender = FALSE; } - +static LLFastTimer::DeclareTimer FTM_VISIBLE_CLOUD("Visible Cloud"); BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir) { + LLFastTimer t(FTM_VISIBLE_CLOUD); //get point cloud of intersection of frust and min, max - //get set of planes - std::vector<LLPlane> ps; - if (getVisibleExtents(camera, min, max)) { return FALSE; } - ps.push_back(LLPlane(min, LLVector3(-1,0,0))); - ps.push_back(LLPlane(min, LLVector3(0,-1,0))); - ps.push_back(LLPlane(min, LLVector3(0,0,-1))); - ps.push_back(LLPlane(max, LLVector3(1,0,0))); - ps.push_back(LLPlane(max, LLVector3(0,1,0))); - ps.push_back(LLPlane(max, LLVector3(0,0,1))); + //get set of planes on bounding box + std::vector<LLPlane> bp; + + bp.push_back(LLPlane(min, LLVector3(-1,0,0))); + bp.push_back(LLPlane(min, LLVector3(0,-1,0))); + bp.push_back(LLPlane(min, LLVector3(0,0,-1))); + bp.push_back(LLPlane(max, LLVector3(1,0,0))); + bp.push_back(LLPlane(max, LLVector3(0,1,0))); + bp.push_back(LLPlane(max, LLVector3(0,0,1))); + + //potential points + std::vector<LLVector3> pp; - /*if (!light_dir.isExactlyZero()) + //add corners of AABB + pp.push_back(LLVector3(min.mV[0], min.mV[1], min.mV[2])); + pp.push_back(LLVector3(max.mV[0], min.mV[1], min.mV[2])); + pp.push_back(LLVector3(min.mV[0], max.mV[1], min.mV[2])); + pp.push_back(LLVector3(max.mV[0], max.mV[1], min.mV[2])); + pp.push_back(LLVector3(min.mV[0], min.mV[1], max.mV[2])); + pp.push_back(LLVector3(max.mV[0], min.mV[1], max.mV[2])); + pp.push_back(LLVector3(min.mV[0], max.mV[1], max.mV[2])); + pp.push_back(LLVector3(max.mV[0], max.mV[1], max.mV[2])); + + //add corners of camera frustum + for (U32 i = 0; i < 8; i++) { - LLPlane ucp; - LLPlane mcp; + pp.push_back(camera.mAgentFrustum[i]); + } - F32 maxd = -1.f; - F32 mind = 1.f; - for (U32 i = 0; i < ps.size(); ++i) - { //pick the plane most aligned to lightDir for user clip plane - LLVector3 n(ps[i].mV); - F32 da = n*light_dir; - if (da > maxd) + //bounding box line segments + U32 bs[] = { - maxd = da; - ucp = ps[i]; - } - - if (da < mind) + 0,1, + 1,3, + 3,2, + 2,0, + + 4,5, + 5,7, + 7,6, + 6,4, + + 0,4, + 1,5, + 3,7, + 2,6 + }; + + for (U32 i = 0; i < 12; i++) + { //for each line segment in bounding box + for (U32 j = 0; j < 6; j++) + { //for each plane in camera frustum + const LLPlane& cp = camera.getAgentPlane(j); + const LLVector3& v1 = pp[bs[i*2+0]]; + const LLVector3& v2 = pp[bs[i*2+1]]; + const LLVector3 n(cp.mV); + + LLVector3 line = v1-v2; + + F32 d1 = line*n; + F32 d2 = -cp.dist(v2); + + F32 t = d2/d1; + + if (t > 0.f && t < 1.f) { - mind = da; - mcp = ps[i]; + LLVector3 intersect = v2+line*t; + pp.push_back(intersect); + } } } - camera.setUserClipPlane(ucp); - - ps.clear(); - ps.push_back(ucp); - ps.push_back(mcp); - }*/ + //camera frustum line segments + const U32 fs[] = + { + 0,1, + 1,2, + 2,3, + 3,0, + + 4,5, + 5,6, + 6,7, + 7,4, - for (U32 i = 0; i < 6; i++) - { - ps.push_back(camera.getAgentPlane(i)); - } - - //get set of points where planes intersect and points are not above any plane - fp.clear(); + 0,4, + 1,5, + 2,6, + 3,7 + }; + + LLVector3 center = (max+min)*0.5f; + LLVector3 size = (max-min)*0.5f; - for (U32 i = 0; i < ps.size(); ++i) + for (U32 i = 0; i < 12; i++) { - for (U32 j = 0; j < ps.size(); ++j) + for (U32 j = 0; j < 6; ++j) { - for (U32 k = 0; k < ps.size(); ++k) + const LLVector3& v1 = pp[fs[i*2+0]+8]; + const LLVector3& v2 = pp[fs[i*2+1]+8]; + const LLPlane& cp = bp[j]; + const LLVector3 n(cp.mV); + + LLVector3 line = v1-v2; + + F32 d1 = line*n; + F32 d2 = -cp.dist(v2); + + F32 t = d2/d1; + + if (t > 0.f && t < 1.f) { - if (i == j || - i == k || - k == j) - { - continue; + LLVector3 intersect = v2+line*t; + pp.push_back(intersect); + } + } } - LLVector3 n1,n2,n3; - F32 d1,d2,d3; + LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f), + max+LLVector3(0.05f,0.05f,0.05f) }; - n1.setVec(ps[i].mV); - n2.setVec(ps[j].mV); - n3.setVec(ps[k].mV); + for (U32 i = 0; i < pp.size(); ++i) + { + bool found = true; - d1 = ps[i].mV[3]; - d2 = ps[j].mV[3]; - d3 = ps[k].mV[3]; + const F32* p = pp[i].mV; - //get point of intersection of 3 planes "p" - LLVector3 p = (-d1*(n2%n3)-d2*(n3%n1)-d3*(n1%n2))/(n1*(n2%n3)); + for (U32 j = 0; j < 3; ++j) + { + if (p[j] < ext[0].mV[j] || + p[j] > ext[1].mV[j]) + { + found = false; + break; + } + } - if (llround(p*n1+d1, 0.0001f) == 0.f && - llround(p*n2+d2, 0.0001f) == 0.f && - llround(p*n3+d3, 0.0001f) == 0.f) - { //point is on all three planes - BOOL found = TRUE; - for (U32 l = 0; l < ps.size() && found; ++l) + for (U32 j = 0; j < 6; ++j) + { + const LLPlane& cp = camera.getAgentPlane(j); + F32 dist = cp.dist(pp[i]); + if (dist > 0.05f) //point is above some plane, not contained { - if (llround(ps[l].dist(p), 0.0001f) > 0.0f) - { //point is above some plane, not contained - found = FALSE; + found = false; + break; } } if (found) { - fp.push_back(p); - } - } - } + fp.push_back(pp[i]); } } @@ -7830,21 +8179,22 @@ void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<L sun_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); static LLCullResult result; - U32 type_mask = mRenderTypeMask; + pushRenderTypeMask(); - mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) | - (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | - (1<<LLPipeline::RENDER_TYPE_BUMP) | - (1<<LLPipeline::RENDER_TYPE_VOLUME) | - (1<<LLPipeline::RENDER_TYPE_TREE) | - (1<<LLPipeline::RENDER_TYPE_TERRAIN) | - (1<<LLPipeline::RENDER_TYPE_WATER) | - (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) | - (1<<LLPipeline::RENDER_TYPE_AVATAR) | - (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | - (1 << LLPipeline::RENDER_TYPE_PASS_SHINY)); + andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, + LLPipeline::RENDER_TYPE_FULLBRIGHT, + LLPipeline::RENDER_TYPE_BUMP, + LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW, + LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_PASS_SIMPLE, + LLPipeline::RENDER_TYPE_PASS_BUMP, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, + LLPipeline::RENDER_TYPE_PASS_SHINY, + END_RENDER_TYPES); @@ -7913,7 +8263,7 @@ void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<L LLPipeline::sShadowRender = FALSE; sMinRenderSize = 0.f; - mRenderTypeMask = type_mask; + popRenderTypeMask(); } @@ -7944,7 +8294,6 @@ void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade) void LLPipeline::generateHighlight(LLCamera& camera) { //render highlighted object as white into offscreen render target - if (mHighlightObject.notNull()) { mHighlightSet.insert(HighlightItem(mHighlightObject)); @@ -8011,23 +8360,24 @@ void LLPipeline::generateSunShadow(LLCamera& camera) last_projection[i] = gGLLastProjection[i]; } - U32 type_mask = mRenderTypeMask; - mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) | - (1<<LLPipeline::RENDER_TYPE_ALPHA) | - (1<<LLPipeline::RENDER_TYPE_GRASS) | - (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | - (1<<LLPipeline::RENDER_TYPE_BUMP) | - (1<<LLPipeline::RENDER_TYPE_VOLUME) | - (1<<LLPipeline::RENDER_TYPE_AVATAR) | - (1<<LLPipeline::RENDER_TYPE_TREE) | - (1<<LLPipeline::RENDER_TYPE_TERRAIN) | - (1<<LLPipeline::RENDER_TYPE_WATER) | - (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) | - (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | - (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY)); + pushRenderTypeMask(); + andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, + LLPipeline::RENDER_TYPE_ALPHA, + LLPipeline::RENDER_TYPE_GRASS, + LLPipeline::RENDER_TYPE_FULLBRIGHT, + LLPipeline::RENDER_TYPE_BUMP, + LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW, + LLPipeline::RENDER_TYPE_PASS_SIMPLE, + LLPipeline::RENDER_TYPE_PASS_BUMP, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, + LLPipeline::RENDER_TYPE_PASS_SHINY, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, + END_RENDER_TYPES); gGL.setColorMask(false, false); @@ -8056,6 +8406,14 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist"); //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; + //put together a universal "near clip" plane for shadow frusta + LLPlane shadow_near_clip; + { + LLVector3 p = gAgent.getPositionAgent(); + p += mSunDir * gSavedSettings.getF32("RenderFarClip")*2.f; + shadow_near_clip.setVec(p, mSunDir); + } + LLVector3 lightDir = -mSunDir; lightDir.normVec(); @@ -8079,17 +8437,32 @@ void LLPipeline::generateSunShadow(LLCamera& camera) at.normVec(); + LLCamera main_camera = camera; + F32 near_clip = 0.f; { //get visible point cloud std::vector<LLVector3> fp; + main_camera.calcAgentFrustumPlanes(main_camera.mAgentFrustum); + LLVector3 min,max; - getVisiblePointCloud(camera,min,max,fp); + getVisiblePointCloud(main_camera,min,max,fp); if (fp.empty()) { - mRenderTypeMask = type_mask; + if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowCamera[0] = main_camera; + mShadowExtents[0][0] = min; + mShadowExtents[0][1] = max; + + mShadowFrustPoints[0].clear(); + mShadowFrustPoints[1].clear(); + mShadowFrustPoints[2].clear(); + mShadowFrustPoints[3].clear(); + } + popRenderTypeMask(); return; } @@ -8163,7 +8536,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) shadow_cam = camera; shadow_cam.setFar(16.f); - LLViewerCamera::updateFrustumPlanes(shadow_cam); + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); LLVector3* frust = shadow_cam.mAgentFrustum; @@ -8175,10 +8548,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera) for (U32 i = 0; i < 4; i++) { LLVector3 delta = frust[i+4]-eye; + delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f; delta.normVec(); F32 dp = delta*pn; - frust[i] = eye + (delta*dist[j])/dp; - frust[i+4] = eye + (delta*dist[j+1])/dp; + frust[i] = eye + (delta*dist[j]*0.95f)/dp; + frust[i+4] = eye + (delta*dist[j+1]*1.05f)/dp; } shadow_cam.calcAgentFrustumPlanes(frust); @@ -8474,7 +8848,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); + //shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); + shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip); //translate and scale to from [-1, 1] to [0, 1] glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, @@ -8518,141 +8893,141 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } } - + //hack to disable projector shadows static bool clear = true; bool gen_shadow = gSavedSettings.getS32("RenderShadowDetail") > 1; - + if (gen_shadow) { clear = true; - F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); + F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); - //update shadow targets - for (U32 i = 0; i < 2; i++) - { //for each current shadow - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; + //update shadow targets + for (U32 i = 0; i < 2; i++) + { //for each current shadow + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; - if (mShadowSpotLight[i].notNull() && - (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || - mShadowSpotLight[i] == mTargetShadowSpotLight[1])) - { //keep this spotlight - mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); - } - else - { //fade out this light - mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); - - if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) - { //faded out, grab one of the pending spots (whichever one isn't already taken) - if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) - { - mShadowSpotLight[i] = mTargetShadowSpotLight[0]; - } - else - { - mShadowSpotLight[i] = mTargetShadowSpotLight[1]; - } + if (mShadowSpotLight[i].notNull() && + (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || + mShadowSpotLight[i] == mTargetShadowSpotLight[1])) + { //keep this spotlight + mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); + } + else + { //fade out this light + mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); + + if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) + { //faded out, grab one of the pending spots (whichever one isn't already taken) + if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) + { + mShadowSpotLight[i] = mTargetShadowSpotLight[0]; + } + else + { + mShadowSpotLight[i] = mTargetShadowSpotLight[1]; } } } - - for (S32 i = 0; i < 2; i++) - { - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); + } - if (mShadowSpotLight[i].isNull()) - { - continue; - } + for (S32 i = 0; i < 2; i++) + { + glh_set_current_modelview(saved_view); + glh_set_current_projection(saved_proj); - LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); + if (mShadowSpotLight[i].isNull()) + { + continue; + } - if (!volume) - { - mShadowSpotLight[i] = NULL; - continue; - } + LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); + + if (!volume) + { + mShadowSpotLight[i] = NULL; + continue; + } - LLDrawable* drawable = mShadowSpotLight[i]; + LLDrawable* drawable = mShadowSpotLight[i]; - LLVector3 params = volume->getSpotLightParams(); - F32 fov = params.mV[0]; + LLVector3 params = volume->getSpotLightParams(); + F32 fov = params.mV[0]; - //get agent->light space matrix (modelview) - LLVector3 center = drawable->getPositionAgent(); - LLQuaternion quat = volume->getRenderRotation(); + //get agent->light space matrix (modelview) + LLVector3 center = drawable->getPositionAgent(); + LLQuaternion quat = volume->getRenderRotation(); - //get near clip plane - LLVector3 scale = volume->getScale(); - LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); - at_axis *= quat; + //get near clip plane + LLVector3 scale = volume->getScale(); + LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); + at_axis *= quat; - LLVector3 np = center+at_axis; - at_axis.normVec(); + LLVector3 np = center+at_axis; + at_axis.normVec(); - //get origin that has given fov for plane np, at_axis, and given scale - F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); + //get origin that has given fov for plane np, at_axis, and given scale + F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); - LLVector3 origin = np - at_axis*dist; + LLVector3 origin = np - at_axis*dist; - LLMatrix4 mat(quat, LLVector4(origin, 1.f)); + LLMatrix4 mat(quat, LLVector4(origin, 1.f)); - view[i+4] = glh::matrix4f((F32*) mat.mMatrix); + view[i+4] = glh::matrix4f((F32*) mat.mMatrix); - view[i+4] = view[i+4].inverse(); + view[i+4] = view[i+4].inverse(); - //get perspective matrix - F32 near_clip = dist+0.01f; - F32 width = scale.mV[VX]; - F32 height = scale.mV[VY]; - F32 far_clip = dist+volume->getLightRadius()*1.5f; + //get perspective matrix + F32 near_clip = dist+0.01f; + F32 width = scale.mV[VX]; + F32 height = scale.mV[VY]; + F32 far_clip = dist+volume->getLightRadius()*1.5f; - F32 fovy = fov * RAD_TO_DEG; - F32 aspect = width/height; - - proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width/height; + + proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); - //translate and scale to from [-1, 1] to [0, 1] - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); + //translate and scale to from [-1, 1] to [0, 1] + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); - glh_set_current_modelview(view[i+4]); - glh_set_current_projection(proj[i+4]); + glh_set_current_modelview(view[i+4]); + glh_set_current_projection(proj[i+4]); - mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; - - for (U32 j = 0; j < 16; j++) - { - gGLLastModelView[j] = mShadowModelview[i+4].m[j]; - gGLLastProjection[j] = mShadowProjection[i+4].m[j]; - } + mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; + + for (U32 j = 0; j < 16; j++) + { + gGLLastModelView[j] = mShadowModelview[i+4].m[j]; + gGLLastProjection[j] = mShadowProjection[i+4].m[j]; + } - mShadowModelview[i+4] = view[i+4]; - mShadowProjection[i+4] = proj[i+4]; + mShadowModelview[i+4] = view[i+4]; + mShadowProjection[i+4] = proj[i+4]; - LLCamera shadow_cam = camera; - shadow_cam.setFar(far_clip); - shadow_cam.setOrigin(origin); + LLCamera shadow_cam = camera; + shadow_cam.setFar(far_clip); + shadow_cam.setOrigin(origin); - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - stop_glerror(); + stop_glerror(); - mShadow[i+4].bindTarget(); - mShadow[i+4].getViewport(gGLViewport); + mShadow[i+4].bindTarget(); + mShadow[i+4].getViewport(gGLViewport); - static LLCullResult result[2]; + static LLCullResult result[2]; - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; - renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); + renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); - mShadow[i+4].flush(); - } + mShadow[i+4].flush(); + } } else { @@ -8690,7 +9065,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) gGLLastProjection[i] = last_projection[i]; } - mRenderTypeMask = type_mask; + popRenderTypeMask(); } void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) @@ -8726,38 +9101,36 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) assertInitialized(); - U32 mask; BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID()); + pushRenderTypeMask(); + if (muted) { - mask = 1 << LLPipeline::RENDER_TYPE_AVATAR; + andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); } else { - mask = (1<<LLPipeline::RENDER_TYPE_VOLUME) | - (1<<LLPipeline::RENDER_TYPE_AVATAR) | - (1<<LLPipeline::RENDER_TYPE_BUMP) | - (1<<LLPipeline::RENDER_TYPE_GRASS) | - (1<<LLPipeline::RENDER_TYPE_SIMPLE) | - (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | - (1<<LLPipeline::RENDER_TYPE_ALPHA) | - (1<<LLPipeline::RENDER_TYPE_INVISIBLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) | - (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) | - (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) | - (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) | - (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) | - (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY); + andRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_BUMP, + LLPipeline::RENDER_TYPE_GRASS, + LLPipeline::RENDER_TYPE_SIMPLE, + LLPipeline::RENDER_TYPE_FULLBRIGHT, + LLPipeline::RENDER_TYPE_ALPHA, + LLPipeline::RENDER_TYPE_INVISIBLE, + LLPipeline::RENDER_TYPE_PASS_SIMPLE, + LLPipeline::RENDER_TYPE_PASS_ALPHA, + LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, + LLPipeline::RENDER_TYPE_PASS_SHINY, + LLPipeline::RENDER_TYPE_PASS_INVISIBLE, + LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, + END_RENDER_TYPES); } - mask = mask & gPipeline.getRenderTypeMask(); - U32 saved_mask = gPipeline.mRenderTypeMask; - gPipeline.mRenderTypeMask = mask; - S32 occlusion = sUseOcclusion; sUseOcclusion = 0; sReflectionRender = sRenderDeferred ? FALSE : TRUE; @@ -8787,7 +9160,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) stateSort(*LLViewerCamera::getInstance(), result); - const LLVector3* ext = avatar->mDrawable->getSpatialExtents(); + const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); LLCamera camera = *viewer_camera; @@ -8796,18 +9169,23 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLVector2 tdim; - LLVector3 half_height = (ext[1]-ext[0])*0.5f; - LLVector3 left = camera.getLeftAxis(); - left *= left; - left.normalize(); + LLVector4a half_height; + half_height.setSub(ext[1], ext[0]); + half_height.mul(0.5f); + + LLVector4a left; + left.load3(camera.getLeftAxis().mV); + left.mul(left); + left.normalize3fast(); - LLVector3 up = camera.getUpAxis(); - up *= up; - up.normalize(); + LLVector4a up; + up.load3(camera.getUpAxis().mV); + up.mul(up); + up.normalize3fast(); - tdim.mV[0] = fabsf(half_height * left); - tdim.mV[1] = fabsf(half_height * up); + tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); + tdim.mV[1] = fabsf(half_height.dot3(up).getF32()); glMatrixMode(GL_PROJECTION); glPushMatrix(); @@ -8931,7 +9309,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) sReflectionRender = FALSE; sImpostorRender = FALSE; sShadowRender = FALSE; - gPipeline.mRenderTypeMask = saved_mask; + popRenderTypeMask(); glMatrixMode(GL_PROJECTION); glPopMatrix(); @@ -8972,4 +9350,121 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() return sCull->endAlphaGroups(); } +BOOL LLPipeline::hasRenderType(const U32 type) const +{ + return mRenderTypeEnabled[type]; +} + +void LLPipeline::setRenderTypeMask(U32 type, ...) +{ + va_list args; + + va_start(args, type); + while (type < END_RENDER_TYPES) + { + mRenderTypeEnabled[type] = TRUE; + type = va_arg(args, U32); + } + va_end(args); + + if (type > END_RENDER_TYPES) + { + llerrs << "Invalid render type." << llendl; + } +} + +BOOL LLPipeline::hasAnyRenderType(U32 type, ...) const +{ + va_list args; + + va_start(args, type); + while (type < END_RENDER_TYPES) + { + if (mRenderTypeEnabled[type]) + { + return TRUE; + } + type = va_arg(args, U32); + } + va_end(args); + + if (type > END_RENDER_TYPES) + { + llerrs << "Invalid render type." << llendl; + } + + return FALSE; +} + +void LLPipeline::pushRenderTypeMask() +{ + std::string cur_mask; + cur_mask.assign((const char*) mRenderTypeEnabled, sizeof(mRenderTypeEnabled)); + mRenderTypeEnableStack.push(cur_mask); +} + +void LLPipeline::popRenderTypeMask() +{ + if (mRenderTypeEnableStack.empty()) + { + llerrs << "Depleted render type stack." << llendl; + } + + memcpy(mRenderTypeEnabled, mRenderTypeEnableStack.top().data(), sizeof(mRenderTypeEnabled)); + mRenderTypeEnableStack.pop(); +} + +void LLPipeline::andRenderTypeMask(U32 type, ...) +{ + va_list args; + + BOOL tmp[NUM_RENDER_TYPES]; + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + tmp[i] = FALSE; + } + + va_start(args, type); + while (type < END_RENDER_TYPES) + { + if (mRenderTypeEnabled[type]) + { + tmp[type] = TRUE; + } + + type = va_arg(args, U32); + } + va_end(args); + + if (type > END_RENDER_TYPES) + { + llerrs << "Invalid render type." << llendl; + } + + for (U32 i = 0; i < LLPipeline::NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = tmp[i]; + } + +} + +void LLPipeline::clearRenderTypeMask(U32 type, ...) +{ + va_list args; + + va_start(args, type); + while (type < END_RENDER_TYPES) + { + mRenderTypeEnabled[type] = FALSE; + + type = va_arg(args, U32); + } + va_end(args); + + if (type > END_RENDER_TYPES) + { + llerrs << "Invalid render type." << llendl; + } +} + |