mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 17:59:56 +00:00
alphablending & billboardfix
Signed-off-by: Bret Curtis <psi29a@gmail.com>
This commit is contained in:
parent
4e2efb3cdb
commit
daa2761c2d
3 changed files with 42 additions and 38 deletions
|
@ -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,13 +151,19 @@ 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 (mOptimizeBillboards)
|
||||
{
|
||||
handleBillboard(cloned);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
cloned->setDataVariance(osg::Object::DYNAMIC);
|
||||
}
|
||||
|
||||
if (node->getCullCallback()->getNestedCallback())
|
||||
{
|
||||
osg::Callback *clonedCallback = osg::clone(callback, osg::CopyOp::SHALLOW_COPY);
|
||||
|
@ -173,8 +173,6 @@ namespace MWRender
|
|||
else
|
||||
cloned->addCullCallback(const_cast<osg::Callback*>(callback));
|
||||
}
|
||||
callback = callback->getNestedCallback();
|
||||
}
|
||||
}
|
||||
void handleBillboard(osg::Node* node) const
|
||||
{
|
||||
|
@ -414,9 +412,9 @@ namespace MWRender
|
|||
}
|
||||
}
|
||||
|
||||
if (activeGrid)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mRefTrackerMutex);
|
||||
if (activeGrid)
|
||||
for (auto ref : getRefTracker().mBlacklist)
|
||||
refs.erase(ref);
|
||||
}
|
||||
|
@ -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,12 +452,9 @@ 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)
|
||||
if (found != mSizeCache.end() && found->second < dSqr*minSize*minSize)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::string id = Misc::StringUtils::lowerCase(ref.mRefID);
|
||||
if (id == "prisonmarker" || id == "divinemarker" || id == "templemarker" || id == "northmarker")
|
||||
|
@ -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;
|
||||
}
|
||||
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…
Reference in a new issue