obs-StreamFX/source/gfx/shader/gfx-shader.hpp
Michael Fabian 'Xaymar' Dirks 4c5a7018a3 gfx-shader: Add file watching and dynamic UI updates
Thanks to the workaround in obs::tools, gfx::shader::shader now supports dynamically rebuilding the properties with new properties without crashing OBS Studio. This effectively allows you to have an up to date view of the current parameters for the shader technique.

Additionally with file watching, live development of shaders is possible at very little cost. Currently only file times and size is looked at every 333ms, but in the future it is possible to also watch for file renames and more.
2019-12-22 06:14:26 +01:00

118 lines
3.1 KiB
C++

// Modern effects for a modern Streamer
// Copyright (C) 2017 Michael Fabian Dirks
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#pragma once
#include <filesystem>
#include <list>
#include <map>
#include <random>
#include <string>
#include "gfx/shader/gfx-shader-param.hpp"
#include "obs/gs/gs-effect.hpp"
// OBS
extern "C" {
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <obs.h>
#include <util/platform.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
}
namespace gfx {
namespace shader {
enum class size_type {
Pixel,
Percent,
};
enum class shader_mode {
Source,
Filter,
Transition,
};
class shader {
obs_source_t* _self;
// Inputs
shader_mode _mode;
uint32_t _base_width;
uint32_t _base_height;
std::shared_ptr<gs::texture> _input_a;
std::shared_ptr<gs::texture> _input_b;
// Shader
gs::effect _shader;
std::filesystem::path _shader_file;
std::string _shader_tech;
std::filesystem::file_time_type _shader_file_mt;
uintmax_t _shader_file_sz;
float_t _shader_file_tick;
std::map<std::string, std::shared_ptr<parameter>> _shader_params;
// Options
size_type _width_type;
double_t _width_value;
size_type _height_type;
double_t _height_value;
// Cache
float_t _time;
std::mt19937_64 _random;
bool _have_current_params;
public:
shader(obs_source_t* self, shader_mode mode);
~shader();
bool is_shader_different(const std::filesystem::path& file);
bool is_technique_different(const std::string& tech);
bool load_shader(const std::filesystem::path& file, const std::string& tech, bool& shader_dirty,
bool& param_dirty);
void properties(obs_properties_t* props);
bool on_properties_modified(obs_properties_t* props, obs_property_t* prop, obs_data_t* data);
bool update_shader(obs_data_t* data, bool& shader_dirty, bool& param_dirty);
void update(obs_data_t* data);
uint32_t width();
uint32_t height();
bool tick(float_t time);
void render();
public:
void set_size(uint32_t w, uint32_t h);
void set_input_a(std::shared_ptr<gs::texture> tex);
void set_input_b(std::shared_ptr<gs::texture> tex);
};
} // namespace shader
} // namespace gfx