1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-04 02:41:19 +00:00
OpenMW/apps/openmw/mwrender/util.cpp
Alexei Kotov 84f4ba4ca1 Support defining the texture type with a state attribute (#6240)
Named textures are still supported for easier native format compatibility (and so that I don't have to edit the documentation)
2024-05-18 23:11:20 +03:00

77 lines
2.7 KiB
C++

#include "util.hpp"
#include <osg/Node>
#include <osg/ValueObject>
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/imagemanager.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/sceneutil/texturetype.hpp>
#include <components/sceneutil/visitor.hpp>
#include <components/settings/values.hpp>
namespace MWRender
{
namespace
{
class TextureOverrideVisitor : public osg::NodeVisitor
{
public:
TextureOverrideVisitor(std::string_view texture, Resource::ResourceSystem* resourcesystem)
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
, mTexture(texture)
, mResourcesystem(resourcesystem)
{
}
void apply(osg::Node& node) override
{
int index = 0;
if (node.getUserValue("overrideFx", index))
{
if (index == 1)
overrideTexture(mTexture, mResourcesystem, node);
}
traverse(node);
}
std::string_view mTexture;
Resource::ResourceSystem* mResourcesystem;
};
}
void overrideFirstRootTexture(std::string_view texture, Resource::ResourceSystem* resourceSystem, osg::Node& node)
{
TextureOverrideVisitor overrideVisitor(texture, resourceSystem);
node.accept(overrideVisitor);
}
void overrideTexture(std::string_view texture, Resource::ResourceSystem* resourceSystem, osg::Node& node)
{
if (texture.empty())
return;
std::string correctedTexture = Misc::ResourceHelpers::correctTexturePath(texture, resourceSystem->getVFS());
// Not sure if wrap settings should be pulled from the overridden texture?
osg::ref_ptr<osg::Texture2D> tex
= new osg::Texture2D(resourceSystem->getImageManager()->getImage(correctedTexture));
tex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
tex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
osg::ref_ptr<osg::StateSet> stateset;
if (const osg::StateSet* const src = node.getStateSet())
stateset = new osg::StateSet(*src, osg::CopyOp::SHALLOW_COPY);
else
stateset = new osg::StateSet;
stateset->setTextureAttribute(0, tex, osg::StateAttribute::OVERRIDE);
stateset->setTextureAttribute(0, new SceneUtil::TextureType("diffuseMap"), osg::StateAttribute::OVERRIDE);
node.setStateSet(stateset);
}
bool shouldAddMSAAIntermediateTarget()
{
return Settings::shaders().mAntialiasAlphaTest && Settings::video().mAntialiasing > 1;
}
}