From 95ea174d4310bdb3a2fbe14c2836804a9421eeae Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 29 May 2011 16:28:56 -0500 Subject: [PATCH] Spatial partition updated. Seems to run smoother for me, but may want to test on other systems. --- indra/llrender/llvertexbuffer.cpp | 2 +- indra/newview/lldrawable.cpp | 12 +- indra/newview/llflexibleobject.cpp | 4 +- indra/newview/llspatialpartition.cpp | 190 +++++++++++++++++++-------- indra/newview/llviewerdisplay.cpp | 4 +- indra/newview/pipeline.cpp | 86 ++++++++---- 6 files changed, 205 insertions(+), 93 deletions(-) diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 49c410d27..d697b95dd 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1473,7 +1473,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const { llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask. Missing: "; - static const char* mask_names[] = {"VERTEX","NORMAL","TEXCOORD0","TEXCOORD1","TEXCOORD2","TEXCOORD3","COLOR","BINORMAL","WEIGHT","CLOTH_WEIGHT"}; + static const char* mask_names[] = {"VERTEX","NORMAL","TEXCOORD0","TEXCOORD1","TEXCOORD2","TEXCOORD3","COLOR","BINORMAL","WEIGHT","WEIGHT4","CLOTH_WEIGHT"}; for(int i = 0; i < 32; ++i) { if((data_mask & (1<updateRelativeXform(); - pos = volume->getRelativeXform().getTranslation(); - if (isStatic()) + if (getSpatialGroup()) { - pos += volume->getRegion()->getOriginAgent(); + pos.set(getPositionGroup()); } - + else + { + pos = getPositionAgent(); + } + if (isState(LLDrawable::HAS_ALPHA)) { for (S32 i = 0; i < getNumFaces(); i++) diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index ce55c7a69..317ad0eb9 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -368,8 +368,8 @@ void LLVolumeImplFlexible::doFlexibleUpdate() LLPath *path = &volume->getPath(); if ((mSimulateRes == 0 || !mInitialized)) // if its uninitialized but not visible, what then? - Nyx { - if(!mVO->mDrawable->isVisible()) - return; //avoiding the assert below... + //if(mInitialized && !mVO->mDrawable->isVisible()) + // return; //avoiding the assert below... mVO->markForUpdate(TRUE); if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0)) { diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index e5d22fc22..ca70e52e6 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -297,9 +297,15 @@ LLSpatialGroup::~LLSpatialGroup() sNodeCount--; - if (gGLManager.mHasOcclusionQuery && mOcclusionQuery[LLViewerCamera::sCurCameraID]) + if (gGLManager.mHasOcclusionQuery) { - sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) + { + if (mOcclusionQuery[i]) + { + sQueryPool.release(mOcclusionQuery[i]); + } + } } delete [] mOcclusionVerts; @@ -321,7 +327,7 @@ BOOL LLSpatialGroup::isRecentlyVisible() const BOOL LLSpatialGroup::isVisible() const { - return mVisible[LLViewerCamera::sCurCameraID] == LLDrawable::getCurrentFrame() ? TRUE : FALSE; + return mVisible[LLViewerCamera::sCurCameraID] >= LLDrawable::getCurrentFrame() ? TRUE : FALSE; } void LLSpatialGroup::setVisible() @@ -771,13 +777,14 @@ void LLSpatialGroup::shift(const LLVector3 &offset) if (mOcclusionVerts) { - for (U32 i = 0; i < 8; i++) + setState(OCCLUSION_DIRTY); + /*for (U32 i = 0; i < 8; i++) { F32* v = mOcclusionVerts+i*3; v[0] += offset.mV[0]; v[1] += offset.mV[1]; v[2] += offset.mV[2]; - } + }*/ } } @@ -973,12 +980,23 @@ void LLSpatialGroup::setOcclusionState(eOcclusionState state, S32 mode) for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) { mOcclusionState[i] |= state; + + if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) + { + sQueryPool.release(mOcclusionQuery[i]); + mOcclusionQuery[i] = 0; + } } } } else { mOcclusionState[LLViewerCamera::sCurCameraID] |= state; + if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; + } } } @@ -1057,6 +1075,9 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : sNodeCount++; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); + mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] = + mObjectExtents[0] = mObjectExtents[1] = mViewAngle; + sg_assert(mOctreeNode->getListenerCount() == 0); mOctreeNode->addListener(this); setState(SG_INITIAL_STATE_MASK); @@ -1121,9 +1142,9 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) { if (!group->mSpatialPartition->isBridge()) { - LLVector3 view_angle = LLVector3(eye * LLVector3(1,0,0), + LLVector3 view_angle = eye;/*LLVector3(eye * LLVector3(1,0,0), //WTF is this? eye * LLVector3(0,1,0), - eye * LLVector3(0,0,1)); + eye * LLVector3(0,0,1));*/ if ((view_angle-group->mLastUpdateViewAngle).magVec() > 0.64f) { @@ -1178,7 +1199,9 @@ F32 LLSpatialGroup::getUpdateUrgency() const } else { - return (gFrameTimeSeconds - mLastUpdateTime+4.f)/mDistance; + //return (gFrameTimeSeconds - mLastUpdateTime+4.f)/mDistance; + F32 time = gFrameTimeSeconds-mLastUpdateTime+4.f; + return (time + (mObjectBounds[1]*mObjectBounds[1]) + 1.f)/mDistance; } } @@ -1189,7 +1212,7 @@ BOOL LLSpatialGroup::needsUpdate() BOOL LLSpatialGroup::changeLOD() { - if (isState(ALPHA_DIRTY)) + if (isState(ALPHA_DIRTY | OBJECT_DIRTY)) { ///an alpha sort is going to happen, update distance and LOD return TRUE; } @@ -1203,7 +1226,8 @@ BOOL LLSpatialGroup::changeLOD() return TRUE; } - if (mDistance > mRadius) + //if (mDistance > mRadius) + if (mDistance > mRadius*2.f) { return FALSE; } @@ -1402,12 +1426,29 @@ void LLSpatialGroup::checkOcclusion() } else if (isOcclusionState(QUERY_PENDING)) { //otherwise, if a query is pending, read it back + GLuint available = 0; + if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + } + else + { + available = 1; + } + + if (available) + { //result is available, read it back, otherwise wait until next frame GLuint res = 1; if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) { glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res); - } - + } + else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { //delete the query to avoid holding onto hundreds of pending queries + sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; + } + if (isOcclusionState(DISCARD_QUERY)) { res = 2; @@ -1427,6 +1468,7 @@ void LLSpatialGroup::checkOcclusion() } clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); + } } else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLSpatialGroup::OCCLUDED)) { //check occlusion has been issued for occluded node that has not had a query issued @@ -1443,8 +1485,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) { //static const LLCachedControl render_water_void_culling("RenderWaterVoidCulling", TRUE); // Don't cull hole/edge water, unless RenderWaterVoidCulling is set and we have the GL_ARB_depth_clamp extension. - if ((mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER && !gGLManager.mHasDepthClamp) || - earlyFail(camera, this)) + //if ((mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER && !gGLManager.mHasDepthClamp) || + // earlyFail(camera, this)) + if (earlyFail(camera, this)) { setOcclusionState(LLSpatialGroup::DISCARD_QUERY); assert_states_valid(this); @@ -1453,54 +1496,83 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) } else { + if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY)) { - LLFastTimer t(LLFastTimer::FTM_RENDER_OCCLUSION); + { //no query pending, or previous query to be discarded + //LLFastTimer t(FTM_RENDER_OCCLUSION); - if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); - } + if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); + } - if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY)) - { - buildOcclusion(); - } + if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY)) + { + buildOcclusion(); + } - // Depth clamp all water to avoid it being culled as a result of being - // behind the far clip plane, and in the case of edge water to avoid - // it being culled while still visible. - bool const use_depth_clamp = gGLManager.mHasDepthClamp && - (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || - mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); - if (use_depth_clamp) - { - glEnable(GL_DEPTH_CLAMP); + // Depth clamp all water to avoid it being culled as a result of being + // behind the far clip plane, and in the case of edge water to avoid + // it being culled while still visible. + bool const use_depth_clamp = gGLManager.mHasDepthClamp && + (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || + mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); + + LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); + +#if !LL_DARWIN + U32 mode = gGLManager.mHasOcclusionQuery2 ? /*GL_ANY_SAMPLES_PASSED*/0x8C2F : GL_SAMPLES_PASSED_ARB; +#else + U32 mode = GL_SAMPLES_PASSED_ARB; +#endif + + { + //LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); + glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); + glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); + if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) + { + LLGLSquashToFarClip squash(glh_get_current_projection(), 1); + if (camera->getOrigin().isExactlyZero()) + { //origin is invalid, draw entire box + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, + GL_UNSIGNED_BYTE, sOcclusionIndices); + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, + GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8); + } + else + { + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, + GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0])); + } + } + else + { + if (camera->getOrigin().isExactlyZero()) + { //origin is invalid, draw entire box + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, + GL_UNSIGNED_BYTE, sOcclusionIndices); + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, + GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8); + + } + else + { + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, + GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0])); + } + } + + glEndQueryARB(mode); + } } - glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery[LLViewerCamera::sCurCameraID]); - glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); - if (camera->getOrigin().isExactlyZero()) - { //origin is invalid, draw entire box - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8); - } - else { - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0])); - } - glEndQueryARB(GL_SAMPLES_PASSED_ARB); - - if (use_depth_clamp) - { - glDisable(GL_DEPTH_CLAMP); + //LLFastTimer t(FTM_SET_OCCLUSION_STATE); + setOcclusionState(LLSpatialGroup::QUERY_PENDING); + clearOcclusionState(LLSpatialGroup::DISCARD_QUERY); } } - - setOcclusionState(LLSpatialGroup::QUERY_PENDING); - clearOcclusionState(LLSpatialGroup::DISCARD_QUERY); } } } @@ -1628,13 +1700,12 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL class LLSpatialShift : public LLSpatialGroup::OctreeTraveler { public: - LLSpatialShift(LLVector3 offset) : mOffset(offset) { } + const LLVector3& mOffset; + LLSpatialShift(const LLVector3 &offset) : mOffset(offset) { } virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset); } - - LLVector3 mOffset; }; void LLSpatialPartition::shift(const LLVector3 &offset) @@ -2358,7 +2429,11 @@ void renderOctree(LLSpatialGroup* group) } gGL.color4fv(col.mV); - drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); + + { + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); + } gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -2667,7 +2742,6 @@ void renderPoints(LLDrawable* drawablep) { gGL.begin(LLRender::POINTS); gGL.color3f(1,1,1); - LLVector3 center(drawablep->getPositionGroup()); for (S32 i = 0; i < drawablep->getNumFaces(); i++) { gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 5166416a6..8e62a5753 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -648,10 +648,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo && gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery) ? 2 : 0; - if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred) + /*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred) { //force occlusion on for all render types if doing deferred render LLPipeline::sUseOcclusion = 3; - } + }*/ LLPipeline::sFastAlpha = gSavedSettings.getBOOL("RenderFastAlpha"); LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 92f8df217..89637a691 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2446,10 +2446,10 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { llassert_always(!mGroupQ2Locked); //llerrs << "Non-priority updates not yet supported!" << llendl; - if (std::find(mGroupQ2.begin(), mGroupQ2.end(), group) != mGroupQ2.end()) + /*if (std::find(mGroupQ2.begin(), mGroupQ2.end(), group) != mGroupQ2.end()) { llerrs << "WTF?" << llendl; - } + }*/ mGroupQ2.push_back(group); group->setState(LLSpatialGroup::IN_BUILD_Q2); @@ -2527,6 +2527,42 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { + LLSpatialGroup* last_group = NULL; + for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + { + LLCullResult::bridge_list_t::iterator cur_iter = i; + LLSpatialBridge* bridge = *cur_iter; + LLSpatialGroup* group = bridge->getSpatialGroup(); + + if (last_group == NULL) + { + last_group = group; + } + + if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + stateSort(bridge, camera); + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && + last_group != group && last_group->changeLOD()) + { + last_group->mLastUpdateDistance = last_group->mDistance; + } + + last_group = group; + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && + last_group && last_group->changeLOD()) + { + last_group->mLastUpdateDistance = last_group->mDistance; + } + } + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; @@ -2542,19 +2578,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) - { - LLCullResult::bridge_list_t::iterator cur_iter = i; - LLSpatialBridge* bridge = *cur_iter; - LLSpatialGroup* group = bridge->getSpatialGroup(); - if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - stateSort(bridge, camera); - } - } - } { LLFastTimer ftm(LLFastTimer::FTM_STATESORT_DRAWABLE); for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); @@ -2586,6 +2609,11 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) LLDrawable* drawablep = *i; stateSort(drawablep, camera); } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { //avoid redundant stateSort calls + group->mLastUpdateDistance = group->mDistance; + } } } @@ -2593,7 +2621,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - if (!sShadowRender && !sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) + if (/*!sShadowRender && */!sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) { bool force_update = false; bridge->updateDistance(camera, force_update); @@ -2657,10 +2685,11 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { - LLSpatialGroup* group = drawablep->getSpatialGroup(); + /*LLSpatialGroup* group = drawablep->getSpatialGroup(); if (!group || group->changeLOD()) { - if (drawablep->isVisible() && !sSkipUpdate) + if (drawablep->isVisible() && !sSkipUpdate)*/ + if(!sSkipUpdate) { if (!drawablep->isActive()) { @@ -2673,7 +2702,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() } } - } + //} } if(!drawablep->getVOVolume()) @@ -5832,6 +5861,10 @@ void validate_framebuffer_object() case GL_FRAMEBUFFER_COMPLETE_EXT: //framebuffer OK, no error. break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: + // frame buffer not OK: probably means unsupported depth buffer format + llerrs << "Framebuffer Incomplete Missing Attachment." << llendl; + break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: // frame buffer not OK: probably means unsupported depth buffer format llerrs << "Framebuffer Incomplete Dimensions." << llendl; @@ -7696,11 +7729,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLCamera camera = camera_in; camera.setFar(camera.getFar()*0.87654321f); LLPipeline::sReflectionRender = TRUE; - S32 occlusion = LLPipeline::sUseOcclusion; - - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - - LLPipeline::sUseOcclusion = llmin(occlusion, 1); gPipeline.pushRenderTypeMask(); @@ -7736,9 +7764,14 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) if (!LLViewerCamera::getInstance()->cameraUnderWater()) { //generate planar reflection map + + //disable occlusion culling for reflection map for now + S32 occlusion = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = 0; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); glClearColor(0,0,0,0); mWaterRef.bindTarget(); + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0; gGL.setColorMask(true, true); mWaterRef.clear(); gGL.setColorMask(true, false); @@ -7833,6 +7866,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glPopMatrix(); mWaterRef.flush(); glh_set_current_modelview(current); + LLPipeline::sUseOcclusion = occlusion; } camera.setOrigin(camera_in.getOrigin()); @@ -7864,6 +7898,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLColor4& col = LLDrawPoolWater::sWaterFogColor; glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); mWaterDis.bindTarget(); + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; mWaterDis.getViewport(gGLViewport); if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate) @@ -7904,7 +7939,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLDrawPoolWater::sNeedsReflectionUpdate = FALSE; LLDrawPoolWater::sNeedsDistortionUpdate = FALSE; LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd)); - LLPipeline::sUseOcclusion = occlusion; LLGLState::checkStates(); LLGLState::checkTextureChannels(); @@ -7914,6 +7948,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) { agent->updateAttachmentVisibility(gAgent.getCameraMode()); } + + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; } }