mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 08:26:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			170 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef OPENMW_COMPONENTS_SETTINGS_SHADERMANAGER_H
 | 
						|
#define OPENMW_COMPONENTS_SETTINGS_SHADERMANAGER_H
 | 
						|
 | 
						|
#include <filesystem>
 | 
						|
#include <fstream>
 | 
						|
#include <optional>
 | 
						|
#include <unordered_map>
 | 
						|
#include <vector>
 | 
						|
 | 
						|
#include <yaml-cpp/yaml.h>
 | 
						|
 | 
						|
#include <osg/Vec2f>
 | 
						|
#include <osg/Vec3f>
 | 
						|
#include <osg/Vec4f>
 | 
						|
 | 
						|
#include <components/debug/debuglog.hpp>
 | 
						|
#include <components/files/conversion.hpp>
 | 
						|
#include <components/serialization/osgyaml.hpp>
 | 
						|
 | 
						|
namespace Settings
 | 
						|
{
 | 
						|
    /*
 | 
						|
     * Manages the shader.yaml file which is auto-generated and lives next to settings.cfg.
 | 
						|
     * This YAML file is simply a mapping of technique name to a list of uniforms and their values.
 | 
						|
     * Currently only vec2f, vec3f, vec4f, int, and float uniforms are supported.
 | 
						|
     *
 | 
						|
     * config:
 | 
						|
     *   TECHNIQUE:
 | 
						|
     *    MY_FLOAT: 10.34
 | 
						|
     *    MY_VEC2: [0.23, 0.34]
 | 
						|
     *   TECHNIQUE2:
 | 
						|
     *    MY_VEC3: [0.22, 0.33, 0.20]
 | 
						|
     */
 | 
						|
    class ShaderManager
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        enum class Mode
 | 
						|
        {
 | 
						|
            Normal,
 | 
						|
            Debug
 | 
						|
        };
 | 
						|
 | 
						|
        ShaderManager() = default;
 | 
						|
        ShaderManager(ShaderManager const&) = delete;
 | 
						|
        void operator=(ShaderManager const&) = delete;
 | 
						|
 | 
						|
        static ShaderManager& get()
 | 
						|
        {
 | 
						|
            static ShaderManager instance;
 | 
						|
            return instance;
 | 
						|
        }
 | 
						|
 | 
						|
        Mode getMode() { return mMode; }
 | 
						|
 | 
						|
        void setMode(Mode mode) { mMode = mode; }
 | 
						|
 | 
						|
        const YAML::Node& getRoot() { return mData; }
 | 
						|
 | 
						|
        template <class T>
 | 
						|
        bool setValue(const std::string& tname, const std::string& uname, const T& value)
 | 
						|
        {
 | 
						|
            if (mData.IsNull())
 | 
						|
            {
 | 
						|
                Log(Debug::Warning) << "Failed setting " << tname << ", " << uname
 | 
						|
                                    << " : shader settings failed to load";
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
 | 
						|
            mData["config"][tname][uname] = value;
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
 | 
						|
        template <class T>
 | 
						|
        std::optional<T> getValue(const std::string& tname, const std::string& uname)
 | 
						|
        {
 | 
						|
            if (mData.IsNull())
 | 
						|
            {
 | 
						|
                Log(Debug::Warning) << "Failed getting " << tname << ", " << uname
 | 
						|
                                    << " : shader settings failed to load";
 | 
						|
                return std::nullopt;
 | 
						|
            }
 | 
						|
 | 
						|
            try
 | 
						|
            {
 | 
						|
                auto value = mData["config"][tname][uname];
 | 
						|
 | 
						|
                if (!value)
 | 
						|
                    return std::nullopt;
 | 
						|
 | 
						|
                return value.as<T>();
 | 
						|
            }
 | 
						|
            catch (const YAML::BadConversion&)
 | 
						|
            {
 | 
						|
                Log(Debug::Warning) << "Failed retrieving " << tname << ", " << uname
 | 
						|
                                    << " : mismatched types in config file.";
 | 
						|
            }
 | 
						|
 | 
						|
            return std::nullopt;
 | 
						|
        }
 | 
						|
 | 
						|
        bool load(const std::filesystem::path& path)
 | 
						|
        {
 | 
						|
            mData = YAML::Null;
 | 
						|
            mPath = path;
 | 
						|
 | 
						|
            Log(Debug::Info) << "Loading shader settings file: " << mPath;
 | 
						|
 | 
						|
            if (!std::filesystem::exists(mPath))
 | 
						|
            {
 | 
						|
                std::ofstream fout(mPath);
 | 
						|
                if (!fout)
 | 
						|
                {
 | 
						|
                    Log(Debug::Error) << "Failed creating shader settings file: " << mPath;
 | 
						|
                    return false;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            try
 | 
						|
            {
 | 
						|
                std::ifstream file{ mPath };
 | 
						|
                mData = YAML::Load(file);
 | 
						|
                mData.SetStyle(YAML::EmitterStyle::Block);
 | 
						|
 | 
						|
                if (!mData["config"])
 | 
						|
                    mData["config"] = YAML::Node();
 | 
						|
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
            catch (const YAML::Exception& e)
 | 
						|
            {
 | 
						|
                Log(Debug::Error) << "Shader settings failed to load, " << e.msg;
 | 
						|
            }
 | 
						|
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
        bool save()
 | 
						|
        {
 | 
						|
            if (mData.IsNull())
 | 
						|
            {
 | 
						|
                Log(Debug::Error) << "Shader settings failed to load, settings will not be saved: " << mPath;
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
 | 
						|
            Log(Debug::Info) << "Saving shader settings file: " << mPath;
 | 
						|
 | 
						|
            YAML::Emitter out;
 | 
						|
            out.SetMapFormat(YAML::Block);
 | 
						|
            out << mData;
 | 
						|
 | 
						|
            std::ofstream fout(mPath);
 | 
						|
            fout << out.c_str();
 | 
						|
 | 
						|
            if (!fout)
 | 
						|
            {
 | 
						|
                Log(Debug::Error) << "Failed saving shader settings file: " << mPath;
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
 | 
						|
    private:
 | 
						|
        std::filesystem::path mPath;
 | 
						|
        YAML::Node mData;
 | 
						|
        Mode mMode = Mode::Normal;
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |