1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 20:59:55 +00:00

alphablending & billboardfix

Signed-off-by: Bret Curtis <psi29a@gmail.com>
This commit is contained in:
bzzt lost a hitlab login 2020-05-16 13:37:00 +00:00 committed by Bret Curtis
parent 4e2efb3cdb
commit daa2761c2d
3 changed files with 42 additions and 38 deletions

View file

@ -95,21 +95,15 @@ namespace MWRender
} }
virtual bool isOperationPermissibleForObjectImplementation(const SceneUtil::Optimizer* optimizer, const osg::Node* node,unsigned int option) const 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 class CopyOp : public osg::CopyOp
{ {
public: public:
CopyOp(bool deep) : mSqrDistance(0.f) { bool mOptimizeBillboards = true;
unsigned int flags = osg::CopyOp::DEEP_COPY_NODES; float mSqrDistance = 0.f;
if (deep)
flags |= osg::CopyOp::DEEP_COPY_DRAWABLES;
setCopyFlags(flags);
}
float mSqrDistance;
osg::Vec3f mViewVector; osg::Vec3f mViewVector;
mutable std::vector<const osg::Node*> mNodePath; mutable std::vector<const osg::Node*> mNodePath;
@ -157,23 +151,27 @@ namespace MWRender
} }
void handleCallbacks(const osg::Node* node, osg::Node *cloned) const void handleCallbacks(const osg::Node* node, osg::Node *cloned) const
{ {
const osg::Callback* callback = node->getCullCallback(); for (const osg::Callback* callback = node->getCullCallback(); callback != nullptr; callback = callback->getNestedCallback())
while (callback)
{ {
if (callback->className() == std::string("BillboardCallback")) 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); handleBillboard(cloned);
clonedCallback->setNestedCallback(nullptr); continue;
cloned->addCullCallback(clonedCallback);
} }
else else
cloned->addCullCallback(const_cast<osg::Callback*>(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<osg::Callback*>(callback));
} }
} }
void handleBillboard(osg::Node* node) const void handleBillboard(osg::Node* node) const
@ -414,11 +412,11 @@ namespace MWRender
} }
} }
if (activeGrid)
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mRefTrackerMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mRefTrackerMutex);
if (activeGrid) for (auto ref : getRefTracker().mBlacklist)
for (auto ref : getRefTracker().mBlacklist) refs.erase(ref);
refs.erase(ref);
} }
osg::Vec2f minBound = (center - osg::Vec2f(size/2.f, size/2.f)); osg::Vec2f minBound = (center - osg::Vec2f(size/2.f, size/2.f));
@ -444,9 +442,8 @@ namespace MWRender
if (size < 1.f) if (size < 1.f)
{ {
osg::Vec3f cellPos = pos / ESM::Land::REAL_SIZE; 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())) if ((minBound.x() > std::floor(minBound.x()) && cellPos.x() < minBound.x()) || (minBound.y() > std::floor(minBound.y()) && cellPos.y() < minBound.y())
continue; || (maxBound.x() < std::ceil(maxBound.x()) && cellPos.x() >= maxBound.x()) || (minBound.y() < std::ceil(maxBound.y()) && cellPos.y() >= maxBound.y()))
if ((maxBound.x() < std::ceil(maxBound.x()) && cellPos.x() >= maxBound.x()) || (minBound.y() < std::ceil(maxBound.y()) && cellPos.y() >= maxBound.y()))
continue; continue;
} }
@ -455,11 +452,8 @@ namespace MWRender
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mSizeCacheMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mSizeCacheMutex);
SizeCache::iterator found = mSizeCache.find(pair.first); SizeCache::iterator found = mSizeCache.find(pair.first);
if (found != mSizeCache.end()) if (found != mSizeCache.end() && found->second < dSqr*minSize*minSize)
{ continue;
if (found->second < dSqr*minSize*minSize)
continue;
}
} }
std::string id = Misc::StringUtils::lowerCase(ref.mRefID); std::string id = Misc::StringUtils::lowerCase(ref.mRefID);
@ -504,12 +498,10 @@ namespace MWRender
} }
float radius2 = cnode->getBound().radius2() * ref.mScale*ref.mScale; float radius2 = cnode->getBound().radius2() * ref.mScale*ref.mScale;
if (radius2 < dSqr*minSize*minSize) if (radius2 < dSqr*minSize*minSize && !activeGrid)
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mSizeCacheMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mSizeCacheMutex);
{ mSizeCache[pair.first] = radius2;
mSizeCache[pair.first] = radius2;
}
continue; continue;
} }
@ -551,7 +543,7 @@ namespace MWRender
const ESM::CellRef& ref = *cref; const ESM::CellRef& ref = *cref;
osg::Vec3f pos = ref.mPos.asVec3(); 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; continue;
osg::Matrixf matrix; osg::Matrixf matrix;
@ -563,7 +555,9 @@ namespace MWRender
osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform(matrix); osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform(matrix);
trans->setDataVariance(osg::Object::STATIC); 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.mNodePath.push_back(trans);
co.mSqrDistance = (viewPoint - pos).length2(); co.mSqrDistance = (viewPoint - pos).length2();
co.mViewVector = (viewPoint - worldCenter); co.mViewVector = (viewPoint - worldCenter);
@ -611,7 +605,7 @@ namespace MWRender
if (mergeGroup->getNumChildren()) if (mergeGroup->getNumChildren())
{ {
SceneUtil::Optimizer optimizer; SceneUtil::Optimizer optimizer;
if ((relativeViewPoint - mergeGroup->getBound().center()).length2() > mergeGroup->getBound().radius2()*2*2) if (size > 1/8.f)
{ {
optimizer.setViewPoint(relativeViewPoint); optimizer.setViewPoint(relativeViewPoint);
optimizer.setMergeAlphaBlending(true); optimizer.setMergeAlphaBlending(true);

View file

@ -22,6 +22,7 @@
#include <osg/CullFace> #include <osg/CullFace>
#include <osg/Geometry> #include <osg/Geometry>
#include <osg/io_utils> #include <osg/io_utils>
#include <osg/Depth>
#include <sstream> #include <sstream>
@ -1580,7 +1581,9 @@ void MWShadowTechnique::createShaders()
_shadowCastingStateSet->setTextureAttributeAndModes(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON); _shadowCastingStateSet->setTextureAttributeAndModes(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON);
_shadowCastingStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", false)); _shadowCastingStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", false));
_shadowCastingStateSet->addUniform(_shadowMapAlphaTestDisableUniform); _shadowCastingStateSet->addUniform(_shadowMapAlphaTestDisableUniform);
osg::ref_ptr<osg::Depth> 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->setMode(GL_DEPTH_CLAMP, osg::StateAttribute::ON);
_shadowCastingStateSet->setRenderBinDetails(osg::StateSet::OPAQUE_BIN, "RenderBin", osg::StateSet::OVERRIDE_PROTECTED_RENDERBIN_DETAILS); _shadowCastingStateSet->setRenderBinDetails(osg::StateSet::OPAQUE_BIN, "RenderBin", osg::StateSet::OVERRIDE_PROTECTED_RENDERBIN_DETAILS);

View file

@ -28,6 +28,7 @@
#include <osg/Notify> #include <osg/Notify>
#include <osg/Timer> #include <osg/Timer>
#include <osg/io_utils> #include <osg/io_utils>
#include <osg/Depth>
#include <osgUtil/TransformAttributeFunctor> #include <osgUtil/TransformAttributeFunctor>
#include <osgUtil/Statistics> #include <osgUtil/Statistics>
@ -1543,6 +1544,12 @@ bool Optimizer::MergeGeometryVisitor::mergeGroup(osg::Group& group)
geom->setUseVertexBufferObjects(true); geom->setUseVertexBufferObjects(true);
geom->setUseDisplayList(false); geom->setUseDisplayList(false);
} }
if (_alphaBlendingActive && _mergeAlphaBlending && !geom->getStateSet())
{
osg::Depth* d = new osg::Depth;
d->setWriteMask(0);
geom->getOrCreateStateSet()->setAttribute(d);
}
} }
} }