diff --git a/apps/openmw/mwrender/navmesh.cpp b/apps/openmw/mwrender/navmesh.cpp index d4a42fa37e..a3c26aeb59 100644 --- a/apps/openmw/mwrender/navmesh.cpp +++ b/apps/openmw/mwrender/navmesh.cpp @@ -5,8 +5,10 @@ #include #include #include +#include #include +#include #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" @@ -17,6 +19,8 @@ namespace MWRender { NavMesh::NavMesh(const osg::ref_ptr& root, bool enabled) : mRootNode(root) + , mGroupStateSet(SceneUtil::makeNavMeshTileStateSet()) + , mDebugDrawStateSet(SceneUtil::DebugDraw::makeStateSet()) , mEnabled(enabled) , mId(std::numeric_limits::max()) { @@ -64,7 +68,8 @@ namespace MWRender return; if (tile.mGroup != nullptr) mRootNode->removeChild(tile.mGroup); - tile.mGroup = SceneUtil::createNavMeshTileGroup(navMesh.getImpl(), meshTile, settings); + tile.mGroup = SceneUtil::createNavMeshTileGroup(navMesh.getImpl(), meshTile, settings, + mGroupStateSet, mDebugDrawStateSet); if (tile.mGroup == nullptr) return; MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(tile.mGroup, "debug"); diff --git a/apps/openmw/mwrender/navmesh.hpp b/apps/openmw/mwrender/navmesh.hpp index cdfa05d9e8..fd69a3e487 100644 --- a/apps/openmw/mwrender/navmesh.hpp +++ b/apps/openmw/mwrender/navmesh.hpp @@ -15,6 +15,7 @@ namespace osg { class Group; class Geometry; + class StateSet; } namespace DetourNavigator @@ -55,6 +56,8 @@ namespace MWRender }; osg::ref_ptr mRootNode; + osg::ref_ptr mGroupStateSet; + osg::ref_ptr mDebugDrawStateSet; bool mEnabled; std::size_t mId; DetourNavigator::Version mVersion; diff --git a/components/sceneutil/agentpath.cpp b/components/sceneutil/agentpath.cpp index 5f9b574e7d..5721110f77 100644 --- a/components/sceneutil/agentpath.cpp +++ b/components/sceneutil/agentpath.cpp @@ -43,7 +43,7 @@ namespace SceneUtil const osg::ref_ptr group(new osg::Group); - DebugDraw debugDraw(*group, osg::Vec3f(0, 0, 0), 1); + DebugDraw debugDraw(*group, DebugDraw::makeStateSet(), osg::Vec3f(0, 0, 0), 1); const auto agentRadius = halfExtents.x(); const auto agentHeight = 2.0f * halfExtents.z(); diff --git a/components/sceneutil/detourdebugdraw.cpp b/components/sceneutil/detourdebugdraw.cpp index 0b374846d1..f1325340ea 100644 --- a/components/sceneutil/detourdebugdraw.cpp +++ b/components/sceneutil/detourdebugdraw.cpp @@ -32,19 +32,19 @@ namespace namespace SceneUtil { - DebugDraw::DebugDraw(osg::Group& group, const osg::Vec3f& shift, float recastInvertedScaleFactor) + DebugDraw::DebugDraw(osg::Group& group, const osg::ref_ptr& stateSet, + const osg::Vec3f& shift, float recastInvertedScaleFactor) : mGroup(group) + , mStateSet(stateSet) , mShift(shift) , mRecastInvertedScaleFactor(recastInvertedScaleFactor) - , mDepthMask(false) , mMode(osg::PrimitiveSet::POINTS) , mSize(1.0f) { } - void DebugDraw::depthMask(bool state) + void DebugDraw::depthMask(bool) { - mDepthMask = state; } void DebugDraw::texture(bool) @@ -88,17 +88,8 @@ namespace SceneUtil void DebugDraw::end() { - osg::ref_ptr stateSet(new osg::StateSet); - stateSet->setMode(GL_BLEND, osg::StateAttribute::ON); - stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - stateSet->setMode(GL_DEPTH, (mDepthMask ? osg::StateAttribute::ON : osg::StateAttribute::OFF)); - stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - // TODO: mSize has to be used for the line width, but not for glLineWidth because of the spec limitations - stateSet->setAttributeAndModes(new osg::LineWidth()); - stateSet->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - osg::ref_ptr geometry(new osg::Geometry); - geometry->setStateSet(stateSet); + geometry->setStateSet(mStateSet); geometry->setVertexArray(mVertices); geometry->setColorArray(mColors, osg::Array::BIND_PER_VERTEX); geometry->addPrimitiveSet(new osg::DrawArrays(mMode, 0, static_cast(mVertices->size()))); @@ -118,4 +109,16 @@ namespace SceneUtil { mColors->push_back(value); } + + osg::ref_ptr DebugDraw::makeStateSet() + { + osg::ref_ptr stateSet = new osg::StateSet; + stateSet->setMode(GL_BLEND, osg::StateAttribute::ON); + stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + stateSet->setMode(GL_DEPTH, osg::StateAttribute::OFF); + stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + stateSet->setAttributeAndModes(new osg::LineWidth()); + stateSet->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + return stateSet; + } } diff --git a/components/sceneutil/detourdebugdraw.hpp b/components/sceneutil/detourdebugdraw.hpp index 79975cacbc..1d00735ea0 100644 --- a/components/sceneutil/detourdebugdraw.hpp +++ b/components/sceneutil/detourdebugdraw.hpp @@ -15,7 +15,10 @@ namespace SceneUtil class DebugDraw : public duDebugDraw { public: - explicit DebugDraw(osg::Group& group, const osg::Vec3f& shift, float recastInvertedScaleFactor); + explicit DebugDraw(osg::Group& group, const osg::ref_ptr& stateSet, + const osg::Vec3f& shift, float recastInvertedScaleFactor); + + static osg::ref_ptr makeStateSet(); void depthMask(bool state) override; @@ -38,9 +41,9 @@ namespace SceneUtil private: osg::Group& mGroup; + osg::ref_ptr mStateSet; osg::Vec3f mShift; float mRecastInvertedScaleFactor; - bool mDepthMask; osg::PrimitiveSet::Mode mMode; float mSize; osg::ref_ptr mVertices; diff --git a/components/sceneutil/navmesh.cpp b/components/sceneutil/navmesh.cpp index 3f91d41d51..d66f95381c 100644 --- a/components/sceneutil/navmesh.cpp +++ b/components/sceneutil/navmesh.cpp @@ -229,18 +229,8 @@ namespace namespace SceneUtil { - osg::ref_ptr createNavMeshTileGroup(const dtNavMesh& navMesh, const dtMeshTile& meshTile, - const DetourNavigator::Settings& settings) + osg::ref_ptr makeNavMeshTileStateSet() { - if (meshTile.header == nullptr) - return nullptr; - - osg::ref_ptr group(new osg::Group); - DebugDraw debugDraw(*group, osg::Vec3f(0, 0, 10), 1.0f / settings.mRecastScaleFactor); - dtNavMeshQuery navMeshQuery; - navMeshQuery.init(&navMesh, settings.mMaxNavMeshQueryNodes); - drawMeshTile(&debugDraw, navMesh, &navMeshQuery, &meshTile, DU_DRAWNAVMESH_OFFMESHCONS | DU_DRAWNAVMESH_CLOSEDLIST); - osg::ref_ptr material = new osg::Material; material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); @@ -248,9 +238,26 @@ namespace SceneUtil const float polygonOffsetUnits = SceneUtil::AutoDepth::isReversed() ? 1.0 : -1.0; osg::ref_ptr polygonOffset = new osg::PolygonOffset(polygonOffsetFactor, polygonOffsetUnits); - osg::ref_ptr stateSet = group->getOrCreateStateSet(); + osg::ref_ptr stateSet = new osg::StateSet; stateSet->setAttribute(material); stateSet->setAttributeAndModes(polygonOffset); + return stateSet; + } + + osg::ref_ptr createNavMeshTileGroup(const dtNavMesh& navMesh, const dtMeshTile& meshTile, + const DetourNavigator::Settings& settings, const osg::ref_ptr& groupStateSet, + const osg::ref_ptr& debugDrawStateSet) + { + if (meshTile.header == nullptr) + return nullptr; + + osg::ref_ptr group(new osg::Group); + group->setStateSet(groupStateSet); + constexpr float shift = 10.0f; + DebugDraw debugDraw(*group, debugDrawStateSet, osg::Vec3f(0, 0, shift), 1.0f / settings.mRecastScaleFactor); + dtNavMeshQuery navMeshQuery; + navMeshQuery.init(&navMesh, settings.mMaxNavMeshQueryNodes); + drawMeshTile(&debugDraw, navMesh, &navMeshQuery, &meshTile, DU_DRAWNAVMESH_OFFMESHCONS | DU_DRAWNAVMESH_CLOSEDLIST); return group; } diff --git a/components/sceneutil/navmesh.hpp b/components/sceneutil/navmesh.hpp index acfb583eba..ca9b8bd570 100644 --- a/components/sceneutil/navmesh.hpp +++ b/components/sceneutil/navmesh.hpp @@ -9,6 +9,7 @@ struct dtMeshTile; namespace osg { class Group; + class StateSet; } namespace DetourNavigator @@ -18,8 +19,11 @@ namespace DetourNavigator namespace SceneUtil { + osg::ref_ptr makeNavMeshTileStateSet(); + osg::ref_ptr createNavMeshTileGroup(const dtNavMesh& navMesh, const dtMeshTile& meshTile, - const DetourNavigator::Settings& settings); + const DetourNavigator::Settings& settings, const osg::ref_ptr& groupStateSet, + const osg::ref_ptr& debugDrawStateSet); } #endif diff --git a/components/sceneutil/recastmesh.cpp b/components/sceneutil/recastmesh.cpp index ed40bfedf7..9614673a64 100644 --- a/components/sceneutil/recastmesh.cpp +++ b/components/sceneutil/recastmesh.cpp @@ -47,7 +47,7 @@ namespace SceneUtil using namespace DetourNavigator; const osg::ref_ptr group(new osg::Group); - DebugDraw debugDraw(*group, osg::Vec3f(0, 0, 0), 1.0f); + DebugDraw debugDraw(*group, DebugDraw::makeStateSet(), osg::Vec3f(0, 0, 0), 1.0f); const DetourNavigator::Mesh& mesh = recastMesh.getMesh(); std::vector indices = mesh.getIndices(); std::vector vertices = mesh.getVertices();