mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-07 12:54:00 +00:00
4b1c009ffd
With this PR we test out osg's shader define system for a somewhat harmless feature. As we can see, our code becomes more concise and efficient in this case. Most importantly, we no longer create unneeded vertex shader objects.
230 lines
8.7 KiB
C++
230 lines
8.7 KiB
C++
#ifndef OPENMW_COMPONENTS_RESOURCE_SCENEMANAGER_H
|
|
#define OPENMW_COMPONENTS_RESOURCE_SCENEMANAGER_H
|
|
|
|
#include <string>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <mutex>
|
|
|
|
#include <osg/ref_ptr>
|
|
#include <osg/Node>
|
|
#include <osg/Texture>
|
|
|
|
#include "resourcemanager.hpp"
|
|
|
|
#include <components/sceneutil/lightmanager.hpp>
|
|
|
|
namespace Resource
|
|
{
|
|
class ImageManager;
|
|
class NifFileManager;
|
|
class SharedStateManager;
|
|
}
|
|
|
|
namespace osgUtil
|
|
{
|
|
class IncrementalCompileOperation;
|
|
}
|
|
|
|
namespace osgDB
|
|
{
|
|
class SharedStateManager;
|
|
}
|
|
|
|
namespace Shader
|
|
{
|
|
class ShaderManager;
|
|
class ShaderVisitor;
|
|
}
|
|
|
|
namespace Resource
|
|
{
|
|
class TemplateRef : public osg::Object
|
|
{
|
|
public:
|
|
TemplateRef(const Object* object) : mObject(object) {}
|
|
TemplateRef() {}
|
|
TemplateRef(const TemplateRef& copy, const osg::CopyOp&) : mObject(copy.mObject) {}
|
|
|
|
META_Object(Resource, TemplateRef)
|
|
|
|
private:
|
|
osg::ref_ptr<const Object> mObject;
|
|
};
|
|
|
|
class TemplateMultiRef : public osg::Object
|
|
{
|
|
public:
|
|
TemplateMultiRef() {}
|
|
TemplateMultiRef(const TemplateMultiRef& copy, const osg::CopyOp&) : mObjects(copy.mObjects) {}
|
|
void addRef(const osg::Node* node);
|
|
|
|
META_Object(Resource, TemplateMultiRef)
|
|
|
|
private:
|
|
std::vector<osg::ref_ptr<const Object>> mObjects;
|
|
};
|
|
|
|
/// @brief Handles loading and caching of scenes, e.g. .nif files or .osg files
|
|
/// @note Some methods of the scene manager can be used from any thread, see the methods documentation for more details.
|
|
class SceneManager : public ResourceManager
|
|
{
|
|
public:
|
|
SceneManager(const VFS::Manager* vfs, Resource::ImageManager* imageManager, Resource::NifFileManager* nifFileManager);
|
|
~SceneManager();
|
|
|
|
Shader::ShaderManager& getShaderManager();
|
|
|
|
/// Re-create shaders for this node, need to call this if alpha testing, texture stages or vertex color mode have changed.
|
|
void recreateShaders(osg::ref_ptr<osg::Node> node, const std::string& shaderPrefix = "objects", bool forceShadersForNode = false, const osg::Program* programTemplate = nullptr);
|
|
|
|
/// Applying shaders to a node may replace some fixed-function state.
|
|
/// This restores it.
|
|
/// When editing such state, it should be reinstated before the edits, and shaders should be recreated afterwards.
|
|
void reinstateRemovedState(osg::ref_ptr<osg::Node> node);
|
|
|
|
/// @see ShaderVisitor::setForceShaders
|
|
void setForceShaders(bool force);
|
|
bool getForceShaders() const;
|
|
|
|
void setClampLighting(bool clamp);
|
|
bool getClampLighting() const;
|
|
|
|
void setDepthFormat(GLenum format);
|
|
GLenum getDepthFormat() const;
|
|
|
|
/// @see ShaderVisitor::setAutoUseNormalMaps
|
|
void setAutoUseNormalMaps(bool use);
|
|
|
|
/// @see ShaderVisitor::setNormalMapPattern
|
|
void setNormalMapPattern(const std::string& pattern);
|
|
|
|
/// @see ShaderVisitor::setNormalHeightMapPattern
|
|
void setNormalHeightMapPattern(const std::string& pattern);
|
|
|
|
void setAutoUseSpecularMaps(bool use);
|
|
|
|
void setSpecularMapPattern(const std::string& pattern);
|
|
|
|
void setApplyLightingToEnvMaps(bool apply);
|
|
|
|
void setSupportedLightingMethods(const SceneUtil::LightManager::SupportedMethods& supported);
|
|
bool isSupportedLightingMethod(SceneUtil::LightingMethod method) const;
|
|
|
|
enum class UBOBinding
|
|
{
|
|
// If we add more UBO's, we should probably assign their bindings dynamically according to the current count of UBO's in the programTemplate
|
|
LightBuffer
|
|
};
|
|
void setLightingMethod(SceneUtil::LightingMethod method);
|
|
SceneUtil::LightingMethod getLightingMethod() const;
|
|
|
|
void setConvertAlphaTestToAlphaToCoverage(bool convert);
|
|
|
|
void setShaderPath(const std::string& path);
|
|
|
|
/// Check if a given scene is loaded and if so, update its usage timestamp to prevent it from being unloaded
|
|
bool checkLoaded(const std::string& name, double referenceTime);
|
|
|
|
/// Get a read-only copy of this scene "template"
|
|
/// @note If the given filename does not exist or fails to load, an error marker mesh will be used instead.
|
|
/// If even the error marker mesh can not be found, an exception is thrown.
|
|
/// @note Thread safe.
|
|
osg::ref_ptr<const osg::Node> getTemplate(const std::string& name, bool compile=true);
|
|
|
|
osg::ref_ptr<osg::Node> createInstance(const std::string& name);
|
|
|
|
osg::ref_ptr<osg::Node> createInstance(const osg::Node* base);
|
|
void shareState(osg::ref_ptr<osg::Node> node);
|
|
/// Get an instance of the given scene template
|
|
/// @see getTemplate
|
|
/// @note Thread safe.
|
|
osg::ref_ptr<osg::Node> getInstance(const std::string& name);
|
|
|
|
/// Get an instance of the given scene template and immediately attach it to a parent node
|
|
/// @see getTemplate
|
|
/// @note Not thread safe, unless parentNode is not part of the main scene graph yet.
|
|
osg::ref_ptr<osg::Node> getInstance(const std::string& name, osg::Group* parentNode);
|
|
|
|
/// Attach the given scene instance to the given parent node
|
|
/// @note You should have the parentNode in its intended position before calling this method,
|
|
/// so that world space particles of the \a instance get transformed correctly.
|
|
/// @note Assumes the given instance was not attached to any parents before.
|
|
/// @note Not thread safe, unless parentNode is not part of the main scene graph yet.
|
|
void attachTo(osg::Node* instance, osg::Group* parentNode) const;
|
|
|
|
/// Manually release created OpenGL objects for the given graphics context. This may be required
|
|
/// in cases where multiple contexts are used over the lifetime of the application.
|
|
void releaseGLObjects(osg::State* state) override;
|
|
|
|
/// Set up an IncrementalCompileOperation for background compiling of loaded scenes.
|
|
void setIncrementalCompileOperation(osgUtil::IncrementalCompileOperation* ico);
|
|
|
|
osgUtil::IncrementalCompileOperation* getIncrementalCompileOperation();
|
|
|
|
Resource::ImageManager* getImageManager();
|
|
|
|
/// @param mask The node mask to apply to loaded particle system nodes.
|
|
void setParticleSystemMask(unsigned int mask);
|
|
|
|
/// @warning It is unsafe to call this method while the draw thread is using textures! call Viewer::stopThreading first.
|
|
void setFilterSettings(const std::string &magfilter, const std::string &minfilter,
|
|
const std::string &mipmap, int maxAnisotropy);
|
|
|
|
/// Apply filter settings to the given texture. Note, when loading an object through this scene manager (i.e. calling getTemplate or createInstance)
|
|
/// the filter settings are applied automatically. This method is provided for textures that were created outside of the SceneManager.
|
|
void applyFilterSettings (osg::Texture* tex);
|
|
|
|
/// Keep a copy of the texture data around in system memory? This is needed when using multiple graphics contexts,
|
|
/// otherwise should be disabled to reduce memory usage.
|
|
void setUnRefImageDataAfterApply(bool unref);
|
|
|
|
/// @see ResourceManager::updateCache
|
|
void updateCache(double referenceTime) override;
|
|
|
|
void clearCache() override;
|
|
|
|
void reportStats(unsigned int frameNumber, osg::Stats* stats) const override;
|
|
|
|
private:
|
|
|
|
Shader::ShaderVisitor* createShaderVisitor(const std::string& shaderPrefix = "objects");
|
|
|
|
std::unique_ptr<Shader::ShaderManager> mShaderManager;
|
|
bool mForceShaders;
|
|
bool mClampLighting;
|
|
bool mAutoUseNormalMaps;
|
|
std::string mNormalMapPattern;
|
|
std::string mNormalHeightMapPattern;
|
|
bool mAutoUseSpecularMaps;
|
|
std::string mSpecularMapPattern;
|
|
bool mApplyLightingToEnvMaps;
|
|
SceneUtil::LightingMethod mLightingMethod;
|
|
SceneUtil::LightManager::SupportedMethods mSupportedLightingMethods;
|
|
bool mConvertAlphaTestToAlphaToCoverage;
|
|
GLenum mDepthFormat;
|
|
|
|
osg::ref_ptr<Resource::SharedStateManager> mSharedStateManager;
|
|
mutable std::mutex mSharedStateMutex;
|
|
|
|
Resource::ImageManager* mImageManager;
|
|
Resource::NifFileManager* mNifFileManager;
|
|
|
|
osg::Texture::FilterMode mMinFilter;
|
|
osg::Texture::FilterMode mMagFilter;
|
|
int mMaxAnisotropy;
|
|
bool mUnRefImageDataAfterApply;
|
|
|
|
osg::ref_ptr<osgUtil::IncrementalCompileOperation> mIncrementalCompileOperation;
|
|
|
|
unsigned int mParticleSystemMask;
|
|
|
|
SceneManager(const SceneManager&);
|
|
void operator = (const SceneManager&);
|
|
};
|
|
|
|
std::string getFileExtension(const std::string& file);
|
|
}
|
|
|
|
#endif
|