diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index dbe99b0e17..d65fffde88 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -95,21 +95,15 @@ namespace MWRender } virtual bool isOperationPermissibleForObjectImplementation(const SceneUtil::Optimizer* optimizer, const osg::Node* node,unsigned int option) const { - return true; + return (node->getDataVariance() != osg::Object::DYNAMIC); } }; class CopyOp : public osg::CopyOp { public: - CopyOp(bool deep) : mSqrDistance(0.f) { - unsigned int flags = osg::CopyOp::DEEP_COPY_NODES; - if (deep) - flags |= osg::CopyOp::DEEP_COPY_DRAWABLES; - setCopyFlags(flags); - } - - float mSqrDistance; + bool mOptimizeBillboards = true; + float mSqrDistance = 0.f; osg::Vec3f mViewVector; mutable std::vector mNodePath; @@ -157,23 +151,27 @@ namespace MWRender } void handleCallbacks(const osg::Node* node, osg::Node *cloned) const { - const osg::Callback* callback = node->getCullCallback(); - while (callback) + for (const osg::Callback* callback = node->getCullCallback(); callback != nullptr; callback = callback->getNestedCallback()) { if (callback->className() == std::string("BillboardCallback")) - handleBillboard(cloned); - else { - if (node->getCullCallback()->getNestedCallback()) + if (mOptimizeBillboards) { - osg::Callback *clonedCallback = osg::clone(callback, osg::CopyOp::SHALLOW_COPY); - clonedCallback->setNestedCallback(nullptr); - cloned->addCullCallback(clonedCallback); + handleBillboard(cloned); + continue; } else - cloned->addCullCallback(const_cast(callback)); + cloned->setDataVariance(osg::Object::DYNAMIC); } - callback = callback->getNestedCallback(); + + if (node->getCullCallback()->getNestedCallback()) + { + osg::Callback *clonedCallback = osg::clone(callback, osg::CopyOp::SHALLOW_COPY); + clonedCallback->setNestedCallback(nullptr); + cloned->addCullCallback(clonedCallback); + } + else + cloned->addCullCallback(const_cast(callback)); } } void handleBillboard(osg::Node* node) const @@ -414,11 +412,11 @@ namespace MWRender } } + if (activeGrid) { OpenThreads::ScopedLock lock(mRefTrackerMutex); - if (activeGrid) - for (auto ref : getRefTracker().mBlacklist) - refs.erase(ref); + for (auto ref : getRefTracker().mBlacklist) + refs.erase(ref); } osg::Vec2f minBound = (center - osg::Vec2f(size/2.f, size/2.f)); @@ -444,9 +442,8 @@ namespace MWRender if (size < 1.f) { osg::Vec3f cellPos = pos / ESM::Land::REAL_SIZE; - if ((minBound.x() > std::floor(minBound.x()) && cellPos.x() < minBound.x()) || (minBound.y() > std::floor(minBound.y()) && cellPos.y() < minBound.y())) - continue; - if ((maxBound.x() < std::ceil(maxBound.x()) && cellPos.x() >= maxBound.x()) || (minBound.y() < std::ceil(maxBound.y()) && cellPos.y() >= maxBound.y())) + if ((minBound.x() > std::floor(minBound.x()) && cellPos.x() < minBound.x()) || (minBound.y() > std::floor(minBound.y()) && cellPos.y() < minBound.y()) + || (maxBound.x() < std::ceil(maxBound.x()) && cellPos.x() >= maxBound.x()) || (minBound.y() < std::ceil(maxBound.y()) && cellPos.y() >= maxBound.y())) continue; } @@ -455,11 +452,8 @@ namespace MWRender { OpenThreads::ScopedLock lock(mSizeCacheMutex); SizeCache::iterator found = mSizeCache.find(pair.first); - if (found != mSizeCache.end()) - { - if (found->second < dSqr*minSize*minSize) - continue; - } + if (found != mSizeCache.end() && found->second < dSqr*minSize*minSize) + continue; } std::string id = Misc::StringUtils::lowerCase(ref.mRefID); @@ -504,12 +498,10 @@ namespace MWRender } float radius2 = cnode->getBound().radius2() * ref.mScale*ref.mScale; - if (radius2 < dSqr*minSize*minSize) + if (radius2 < dSqr*minSize*minSize && !activeGrid) { OpenThreads::ScopedLock lock(mSizeCacheMutex); - { - mSizeCache[pair.first] = radius2; - } + mSizeCache[pair.first] = radius2; continue; } @@ -551,7 +543,7 @@ namespace MWRender const ESM::CellRef& ref = *cref; osg::Vec3f pos = ref.mPos.asVec3(); - if (minSizeMerged != minSize && cnode->getBound().radius2() * cref->mScale*cref->mScale < (viewPoint-pos).length2()*minSizeMerged*minSizeMerged) + if (!activeGrid && minSizeMerged != minSize && cnode->getBound().radius2() * cref->mScale*cref->mScale < (viewPoint-pos).length2()*minSizeMerged*minSizeMerged) continue; osg::Matrixf matrix; @@ -563,7 +555,9 @@ namespace MWRender osg::ref_ptr trans = new osg::MatrixTransform(matrix); trans->setDataVariance(osg::Object::STATIC); - CopyOp co = CopyOp(merge); + CopyOp co; + co.setCopyFlags(merge ? osg::CopyOp::DEEP_COPY_NODES|osg::CopyOp::DEEP_COPY_DRAWABLES : osg::CopyOp::DEEP_COPY_NODES); + co.mOptimizeBillboards = (size > 1/4.f); co.mNodePath.push_back(trans); co.mSqrDistance = (viewPoint - pos).length2(); co.mViewVector = (viewPoint - worldCenter); @@ -611,7 +605,7 @@ namespace MWRender if (mergeGroup->getNumChildren()) { SceneUtil::Optimizer optimizer; - if ((relativeViewPoint - mergeGroup->getBound().center()).length2() > mergeGroup->getBound().radius2()*2*2) + if (size > 1/8.f) { optimizer.setViewPoint(relativeViewPoint); optimizer.setMergeAlphaBlending(true); diff --git a/components/sceneutil/mwshadowtechnique.cpp b/components/sceneutil/mwshadowtechnique.cpp index cb3a1b278b..98771bbb42 100644 --- a/components/sceneutil/mwshadowtechnique.cpp +++ b/components/sceneutil/mwshadowtechnique.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -1580,7 +1581,9 @@ void MWShadowTechnique::createShaders() _shadowCastingStateSet->setTextureAttributeAndModes(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON); _shadowCastingStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", false)); _shadowCastingStateSet->addUniform(_shadowMapAlphaTestDisableUniform); - + osg::ref_ptr depth = new osg::Depth; + depth->setWriteMask(true); + _shadowCastingStateSet->setAttribute(depth, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); _shadowCastingStateSet->setMode(GL_DEPTH_CLAMP, osg::StateAttribute::ON); _shadowCastingStateSet->setRenderBinDetails(osg::StateSet::OPAQUE_BIN, "RenderBin", osg::StateSet::OVERRIDE_PROTECTED_RENDERBIN_DETAILS); diff --git a/components/sceneutil/optimizer.cpp b/components/sceneutil/optimizer.cpp index f0da9e7e24..71cb8a2e52 100644 --- a/components/sceneutil/optimizer.cpp +++ b/components/sceneutil/optimizer.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -1543,6 +1544,12 @@ bool Optimizer::MergeGeometryVisitor::mergeGroup(osg::Group& group) geom->setUseVertexBufferObjects(true); geom->setUseDisplayList(false); } + if (_alphaBlendingActive && _mergeAlphaBlending && !geom->getStateSet()) + { + osg::Depth* d = new osg::Depth; + d->setWriteMask(0); + geom->getOrCreateStateSet()->setAttribute(d); + } } }