alphablending & billboardfix

Signed-off-by: Bret Curtis <psi29a@gmail.com>
pull/578/head
bzzt lost a hitlab login 5 years ago committed by Bret Curtis
parent 4e2efb3cdb
commit daa2761c2d

@ -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<const osg::Node*> 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<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
@ -414,11 +412,11 @@ namespace MWRender
}
}
if (activeGrid)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> 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<OpenThreads::Mutex> 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<OpenThreads::Mutex> 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<osg::MatrixTransform> 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);

@ -22,6 +22,7 @@
#include <osg/CullFace>
#include <osg/Geometry>
#include <osg/io_utils>
#include <osg/Depth>
#include <sstream>
@ -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<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->setRenderBinDetails(osg::StateSet::OPAQUE_BIN, "RenderBin", osg::StateSet::OVERRIDE_PROTECTED_RENDERBIN_DETAILS);

@ -28,6 +28,7 @@
#include <osg/Notify>
#include <osg/Timer>
#include <osg/io_utils>
#include <osg/Depth>
#include <osgUtil/TransformAttributeFunctor>
#include <osgUtil/Statistics>
@ -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);
}
}
}

Loading…
Cancel
Save