mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-10 22:05:06 +00:00
gs-helper: Add managed obs graphics context
To further distance the code from having to do too much manually, the graphics context is now available as a managed class. All places that previously used obs_enter_graphics and obs_leave_graphics are now using the new gs::context class instead.
This commit is contained in:
parent
8ebdde5d36
commit
b1d7814c64
14 changed files with 108 additions and 207 deletions
|
@ -27,6 +27,7 @@
|
||||||
#include "gfx/blur/gfx-blur-dual-filtering.hpp"
|
#include "gfx/blur/gfx-blur-dual-filtering.hpp"
|
||||||
#include "gfx/blur/gfx-blur-gaussian-linear.hpp"
|
#include "gfx/blur/gfx-blur-gaussian-linear.hpp"
|
||||||
#include "gfx/blur/gfx-blur-gaussian.hpp"
|
#include "gfx/blur/gfx-blur-gaussian.hpp"
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
#include "obs/obs-source-tracker.hpp"
|
#include "obs/obs-source-tracker.hpp"
|
||||||
#include "strings.hpp"
|
#include "strings.hpp"
|
||||||
#include "util-math.hpp"
|
#include "util-math.hpp"
|
||||||
|
@ -154,7 +155,7 @@ filter::blur::blur_factory::~blur_factory() {}
|
||||||
|
|
||||||
void filter::blur::blur_factory::on_list_fill()
|
void filter::blur::blur_factory::on_list_fill()
|
||||||
{
|
{
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
|
|
||||||
{
|
{
|
||||||
char* file = obs_module_file("effects/color-conversion.effect");
|
char* file = obs_module_file("effects/color-conversion.effect");
|
||||||
|
@ -174,16 +175,13 @@ void filter::blur::blur_factory::on_list_fill()
|
||||||
}
|
}
|
||||||
bfree(file);
|
bfree(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void filter::blur::blur_factory::on_list_empty()
|
void filter::blur::blur_factory::on_list_empty()
|
||||||
{
|
{
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
color_converter_effect.reset();
|
color_converter_effect.reset();
|
||||||
mask_effect.reset();
|
mask_effect.reset();
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const& filter::blur::blur_factory::get_translation(std::string const key)
|
std::string const& filter::blur::blur_factory::get_translation(std::string const key)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "gfx-blur-box-linear.hpp"
|
#include "gfx-blur-box-linear.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
#include "util-math.hpp"
|
#include "util-math.hpp"
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
|
|
||||||
gfx::blur::box_linear_data::box_linear_data()
|
gfx::blur::box_linear_data::box_linear_data()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
try {
|
try {
|
||||||
char* file = obs_module_file("effects/blur/box-linear.effect");
|
char* file = obs_module_file("effects/blur/box-linear.effect");
|
||||||
m_effect = std::make_shared<::gs::effect>(file);
|
m_effect = std::make_shared<::gs::effect>(file);
|
||||||
|
@ -46,6 +48,7 @@ gfx::blur::box_linear_data::box_linear_data()
|
||||||
|
|
||||||
gfx::blur::box_linear_data::~box_linear_data()
|
gfx::blur::box_linear_data::~box_linear_data()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
m_effect.reset();
|
m_effect.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +171,7 @@ double_t gfx::blur::box_linear_factory::get_max_step_scale_y(::gfx::blur::type)
|
||||||
|
|
||||||
std::shared_ptr<::gfx::blur::box_linear_data> gfx::blur::box_linear_factory::data()
|
std::shared_ptr<::gfx::blur::box_linear_data> gfx::blur::box_linear_factory::data()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> ulock(m_data_lock);
|
std::unique_lock<std::mutex> ulock(m_data_lock);
|
||||||
std::shared_ptr<::gfx::blur::box_linear_data> data = m_data.lock();
|
std::shared_ptr<::gfx::blur::box_linear_data> data = m_data.lock();
|
||||||
if (!data) {
|
if (!data) {
|
||||||
data = std::make_shared<::gfx::blur::box_linear_data>();
|
data = std::make_shared<::gfx::blur::box_linear_data>();
|
||||||
|
@ -183,7 +186,8 @@ std::shared_ptr<::gfx::blur::box_linear_data> gfx::blur::box_linear_factory::dat
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::blur::box_linear::box_linear() : m_size(1.), m_step_scale({1., 1.}), m_data(::gfx::blur::box_linear_factory::get().data())
|
gfx::blur::box_linear::box_linear()
|
||||||
|
: m_size(1.), m_step_scale({1., 1.}), m_data(::gfx::blur::box_linear_factory::get().data())
|
||||||
{
|
{
|
||||||
m_rendertarget = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
m_rendertarget = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
m_rendertarget2 = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
m_rendertarget2 = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
|
@ -240,11 +244,10 @@ double_t gfx::blur::box_linear::get_step_scale_y()
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::box_linear::render()
|
std::shared_ptr<::gs::texture> gfx::blur::box_linear::render()
|
||||||
{
|
{
|
||||||
float_t width, height;
|
auto gctx = gs::context();
|
||||||
width = float_t(m_input_texture->get_width());
|
float_t width = float_t(m_input_texture->get_width());
|
||||||
height = float_t(m_input_texture->get_height());
|
float_t height = float_t(m_input_texture->get_height());
|
||||||
|
|
||||||
obs_enter_graphics();
|
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
gs_set_cull_mode(GS_NEITHER);
|
||||||
gs_enable_color(true, true, true, true);
|
gs_enable_color(true, true, true, true);
|
||||||
gs_enable_depth_test(false);
|
gs_enable_depth_test(false);
|
||||||
|
@ -290,7 +293,6 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return m_rendertarget->get_texture();
|
return m_rendertarget->get_texture();
|
||||||
}
|
}
|
||||||
|
@ -319,11 +321,10 @@ void gfx::blur::box_linear_directional::set_angle(double_t angle)
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::box_linear_directional::render()
|
std::shared_ptr<::gs::texture> gfx::blur::box_linear_directional::render()
|
||||||
{
|
{
|
||||||
float_t width, height;
|
auto gctx = gs::context();
|
||||||
width = float_t(m_input_texture->get_width());
|
float_t width = float_t(m_input_texture->get_width());
|
||||||
height = float_t(m_input_texture->get_height());
|
float_t height = float_t(m_input_texture->get_height());
|
||||||
|
|
||||||
obs_enter_graphics();
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_reset_blend_state();
|
gs_reset_blend_state();
|
||||||
gs_enable_color(true, true, true, true);
|
gs_enable_color(true, true, true, true);
|
||||||
|
@ -357,7 +358,6 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear_directional::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return m_rendertarget->get_texture();
|
return m_rendertarget->get_texture();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "gfx-blur-box.hpp"
|
#include "gfx-blur-box.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
#include "util-math.hpp"
|
#include "util-math.hpp"
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
|
|
||||||
gfx::blur::box_data::box_data()
|
gfx::blur::box_data::box_data()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
try {
|
try {
|
||||||
char* file = obs_module_file("effects/blur/box.effect");
|
char* file = obs_module_file("effects/blur/box.effect");
|
||||||
m_effect = std::make_shared<::gs::effect>(file);
|
m_effect = std::make_shared<::gs::effect>(file);
|
||||||
|
@ -46,6 +48,7 @@ gfx::blur::box_data::box_data()
|
||||||
|
|
||||||
gfx::blur::box_data::~box_data()
|
gfx::blur::box_data::~box_data()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
m_effect.reset();
|
m_effect.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,6 +196,7 @@ std::shared_ptr<::gfx::blur::box_data> gfx::blur::box_factory::data()
|
||||||
|
|
||||||
gfx::blur::box::box() : m_size(1.), m_step_scale({1., 1.}), m_data(::gfx::blur::box_factory::get().data())
|
gfx::blur::box::box() : m_size(1.), m_step_scale({1., 1.}), m_data(::gfx::blur::box_factory::get().data())
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
m_rendertarget = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
m_rendertarget = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
m_rendertarget2 = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
m_rendertarget2 = std::make_shared<::gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
}
|
}
|
||||||
|
@ -248,11 +252,10 @@ double_t gfx::blur::box::get_step_scale_y()
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::box::render()
|
std::shared_ptr<::gs::texture> gfx::blur::box::render()
|
||||||
{
|
{
|
||||||
float_t width, height;
|
auto gctx = gs::context();
|
||||||
width = float_t(m_input_texture->get_width());
|
float_t width = float_t(m_input_texture->get_width());
|
||||||
height = float_t(m_input_texture->get_height());
|
float_t height = float_t(m_input_texture->get_height());
|
||||||
|
|
||||||
obs_enter_graphics();
|
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
gs_set_cull_mode(GS_NEITHER);
|
||||||
gs_enable_color(true, true, true, true);
|
gs_enable_color(true, true, true, true);
|
||||||
gs_enable_depth_test(false);
|
gs_enable_depth_test(false);
|
||||||
|
@ -298,7 +301,6 @@ std::shared_ptr<::gs::texture> gfx::blur::box::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return m_rendertarget->get_texture();
|
return m_rendertarget->get_texture();
|
||||||
}
|
}
|
||||||
|
@ -327,11 +329,10 @@ void gfx::blur::box_directional::set_angle(double_t angle)
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::box_directional::render()
|
std::shared_ptr<::gs::texture> gfx::blur::box_directional::render()
|
||||||
{
|
{
|
||||||
float_t width, height;
|
auto gctx = gs::context();
|
||||||
width = float_t(m_input_texture->get_width());
|
float_t width = float_t(m_input_texture->get_width());
|
||||||
height = float_t(m_input_texture->get_height());
|
float_t height = float_t(m_input_texture->get_height());
|
||||||
|
|
||||||
obs_enter_graphics();
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_reset_blend_state();
|
gs_reset_blend_state();
|
||||||
gs_enable_color(true, true, true, true);
|
gs_enable_color(true, true, true, true);
|
||||||
|
@ -365,7 +366,6 @@ std::shared_ptr<::gs::texture> gfx::blur::box_directional::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return m_rendertarget->get_texture();
|
return m_rendertarget->get_texture();
|
||||||
}
|
}
|
||||||
|
@ -399,11 +399,10 @@ void gfx::blur::box_rotational::set_angle(double_t angle)
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::box_rotational::render()
|
std::shared_ptr<::gs::texture> gfx::blur::box_rotational::render()
|
||||||
{
|
{
|
||||||
float_t width, height;
|
auto gctx = gs::context();
|
||||||
width = float_t(m_input_texture->get_width());
|
float_t width = float_t(m_input_texture->get_width());
|
||||||
height = float_t(m_input_texture->get_height());
|
float_t height = float_t(m_input_texture->get_height());
|
||||||
|
|
||||||
obs_enter_graphics();
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_reset_blend_state();
|
gs_reset_blend_state();
|
||||||
gs_enable_color(true, true, true, true);
|
gs_enable_color(true, true, true, true);
|
||||||
|
@ -438,7 +437,6 @@ std::shared_ptr<::gs::texture> gfx::blur::box_rotational::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return m_rendertarget->get_texture();
|
return m_rendertarget->get_texture();
|
||||||
}
|
}
|
||||||
|
@ -462,11 +460,10 @@ void gfx::blur::box_zoom::get_center(double_t& x, double_t& y)
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::box_zoom::render()
|
std::shared_ptr<::gs::texture> gfx::blur::box_zoom::render()
|
||||||
{
|
{
|
||||||
float_t width, height;
|
auto gctx = gs::context();
|
||||||
width = float_t(m_input_texture->get_width());
|
float_t width = float_t(m_input_texture->get_width());
|
||||||
height = float_t(m_input_texture->get_height());
|
float_t height = float_t(m_input_texture->get_height());
|
||||||
|
|
||||||
obs_enter_graphics();
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_reset_blend_state();
|
gs_reset_blend_state();
|
||||||
gs_enable_color(true, true, true, true);
|
gs_enable_color(true, true, true, true);
|
||||||
|
@ -500,7 +497,6 @@ std::shared_ptr<::gs::texture> gfx::blur::box_zoom::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return m_rendertarget->get_texture();
|
return m_rendertarget->get_texture();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "gfx-blur-dual-filtering.hpp"
|
#include "gfx-blur-dual-filtering.hpp"
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
#include "util-math.hpp"
|
#include "util-math.hpp"
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
@ -51,6 +52,7 @@
|
||||||
|
|
||||||
gfx::blur::dual_filtering_data::dual_filtering_data()
|
gfx::blur::dual_filtering_data::dual_filtering_data()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
try {
|
try {
|
||||||
char* file = obs_module_file("effects/blur/dual-filtering.effect");
|
char* file = obs_module_file("effects/blur/dual-filtering.effect");
|
||||||
m_effect = std::make_shared<::gs::effect>(file);
|
m_effect = std::make_shared<::gs::effect>(file);
|
||||||
|
@ -62,6 +64,7 @@ gfx::blur::dual_filtering_data::dual_filtering_data()
|
||||||
|
|
||||||
gfx::blur::dual_filtering_data::~dual_filtering_data()
|
gfx::blur::dual_filtering_data::~dual_filtering_data()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
m_effect.reset();
|
m_effect.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,12 +182,11 @@ std::shared_ptr<::gfx::blur::dual_filtering_data> gfx::blur::dual_filtering_fact
|
||||||
gfx::blur::dual_filtering::dual_filtering()
|
gfx::blur::dual_filtering::dual_filtering()
|
||||||
: m_size(0), m_size_iterations(0), m_data(::gfx::blur::dual_filtering_factory::get().data())
|
: m_size(0), m_size_iterations(0), m_data(::gfx::blur::dual_filtering_factory::get().data())
|
||||||
{
|
{
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
m_rendertargets.resize(MAX_LEVELS + 1);
|
m_rendertargets.resize(MAX_LEVELS + 1);
|
||||||
for (size_t n = 0; n <= MAX_LEVELS; n++) {
|
for (size_t n = 0; n <= MAX_LEVELS; n++) {
|
||||||
m_rendertargets[n] = std::make_shared<gs::rendertarget>(GS_RGBA32F, GS_ZS_NONE);
|
m_rendertargets[n] = std::make_shared<gs::rendertarget>(GS_RGBA32F, GS_ZS_NONE);
|
||||||
}
|
}
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::blur::dual_filtering::~dual_filtering() {}
|
gfx::blur::dual_filtering::~dual_filtering() {}
|
||||||
|
@ -219,6 +221,7 @@ void gfx::blur::dual_filtering::get_step_scale(double_t&, double_t&) {}
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
|
std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
auto effect = m_data->get_effect();
|
auto effect = m_data->get_effect();
|
||||||
if (!effect) {
|
if (!effect) {
|
||||||
return m_input_texture;
|
return m_input_texture;
|
||||||
|
@ -226,7 +229,6 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
|
||||||
|
|
||||||
size_t actual_iterations = m_size_iterations;
|
size_t actual_iterations = m_size_iterations;
|
||||||
|
|
||||||
obs_enter_graphics();
|
|
||||||
gs_blend_state_push();
|
gs_blend_state_push();
|
||||||
gs_reset_blend_state();
|
gs_reset_blend_state();
|
||||||
gs_enable_color(true, true, true, true);
|
gs_enable_color(true, true, true, true);
|
||||||
|
@ -281,7 +283,7 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
|
||||||
std::shared_ptr<gs::texture> tex_cur = m_rendertargets[n]->get_texture();
|
std::shared_ptr<gs::texture> tex_cur = m_rendertargets[n]->get_texture();
|
||||||
|
|
||||||
// Get Size
|
// Get Size
|
||||||
uint32_t width = tex_cur->get_width();
|
uint32_t width = tex_cur->get_width();
|
||||||
uint32_t height = tex_cur->get_height();
|
uint32_t height = tex_cur->get_height();
|
||||||
|
|
||||||
// Apply
|
// Apply
|
||||||
|
@ -304,7 +306,6 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return m_rendertargets[0]->get_texture();
|
return m_rendertargets[0]->get_texture();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
|
||||||
#include "gfx-blur-gaussian-linear.hpp"
|
#include "gfx-blur-gaussian-linear.hpp"
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
#include "util-math.hpp"
|
#include "util-math.hpp"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -41,6 +42,8 @@
|
||||||
|
|
||||||
gfx::blur::gaussian_linear_data::gaussian_linear_data()
|
gfx::blur::gaussian_linear_data::gaussian_linear_data()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
|
|
||||||
{
|
{
|
||||||
char* file = obs_module_file("effects/blur/gaussian-linear.effect");
|
char* file = obs_module_file("effects/blur/gaussian-linear.effect");
|
||||||
m_effect = std::make_shared<gs::effect>(file);
|
m_effect = std::make_shared<gs::effect>(file);
|
||||||
|
@ -120,7 +123,8 @@ std::shared_ptr<::gfx::blur::ibase> gfx::blur::gaussian_linear_factory::create(:
|
||||||
case ::gfx::blur::type::Area:
|
case ::gfx::blur::type::Area:
|
||||||
return std::make_shared<::gfx::blur::gaussian_linear>();
|
return std::make_shared<::gfx::blur::gaussian_linear>();
|
||||||
case ::gfx::blur::type::Directional:
|
case ::gfx::blur::type::Directional:
|
||||||
return std::static_pointer_cast<::gfx::blur::gaussian_linear>(std::make_shared<::gfx::blur::gaussian_linear_directional>());
|
return std::static_pointer_cast<::gfx::blur::gaussian_linear>(
|
||||||
|
std::make_shared<::gfx::blur::gaussian_linear_directional>());
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Invalid type.");
|
throw std::runtime_error("Invalid type.");
|
||||||
}
|
}
|
||||||
|
@ -212,7 +216,7 @@ double_t gfx::blur::gaussian_linear_factory::get_max_step_scale_y(::gfx::blur::t
|
||||||
|
|
||||||
std::shared_ptr<::gfx::blur::gaussian_linear_data> gfx::blur::gaussian_linear_factory::data()
|
std::shared_ptr<::gfx::blur::gaussian_linear_data> gfx::blur::gaussian_linear_factory::data()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> ulock(m_data_lock);
|
std::unique_lock<std::mutex> ulock(m_data_lock);
|
||||||
std::shared_ptr<::gfx::blur::gaussian_linear_data> data = m_data.lock();
|
std::shared_ptr<::gfx::blur::gaussian_linear_data> data = m_data.lock();
|
||||||
if (!data) {
|
if (!data) {
|
||||||
data = std::make_shared<::gfx::blur::gaussian_linear_data>();
|
data = std::make_shared<::gfx::blur::gaussian_linear_data>();
|
||||||
|
@ -230,6 +234,8 @@ std::shared_ptr<::gfx::blur::gaussian_linear_data> gfx::blur::gaussian_linear_fa
|
||||||
gfx::blur::gaussian_linear::gaussian_linear()
|
gfx::blur::gaussian_linear::gaussian_linear()
|
||||||
: m_size(1.), m_step_scale({1., 1.}), m_data(::gfx::blur::gaussian_linear_factory::get().data())
|
: m_size(1.), m_step_scale({1., 1.}), m_data(::gfx::blur::gaussian_linear_factory::get().data())
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
|
|
||||||
m_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
m_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
m_rendertarget2 = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
m_rendertarget2 = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
}
|
}
|
||||||
|
@ -284,6 +290,8 @@ double_t gfx::blur::gaussian_linear::get_step_scale_y()
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::render()
|
std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::render()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
||||||
auto kernel = m_data->get_kernel(size_t(m_size));
|
auto kernel = m_data->get_kernel(size_t(m_size));
|
||||||
|
|
||||||
|
@ -295,7 +303,6 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::render()
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(m_input_texture->get_height());
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
obs_enter_graphics();
|
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
gs_set_cull_mode(GS_NEITHER);
|
||||||
gs_enable_color(true, true, true, true);
|
gs_enable_color(true, true, true, true);
|
||||||
gs_enable_depth_test(false);
|
gs_enable_depth_test(false);
|
||||||
|
@ -346,7 +353,6 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return this->get();
|
return this->get();
|
||||||
}
|
}
|
||||||
|
@ -377,6 +383,8 @@ void gfx::blur::gaussian_linear_directional::set_angle(double_t angle)
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear_directional::render()
|
std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear_directional::render()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
||||||
auto kernel = m_data->get_kernel(size_t(m_size));
|
auto kernel = m_data->get_kernel(size_t(m_size));
|
||||||
|
|
||||||
|
@ -388,7 +396,6 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear_directional::render()
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(m_input_texture->get_height());
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
obs_enter_graphics();
|
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
gs_set_cull_mode(GS_NEITHER);
|
||||||
gs_enable_color(true, true, true, true);
|
gs_enable_color(true, true, true, true);
|
||||||
gs_enable_depth_test(false);
|
gs_enable_depth_test(false);
|
||||||
|
@ -419,7 +426,6 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear_directional::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return this->get();
|
return this->get();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
|
||||||
#include "gfx-blur-gaussian.hpp"
|
#include "gfx-blur-gaussian.hpp"
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
#include "util-math.hpp"
|
#include "util-math.hpp"
|
||||||
|
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
|
|
||||||
gfx::blur::gaussian_data::gaussian_data()
|
gfx::blur::gaussian_data::gaussian_data()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
{
|
{
|
||||||
char* file = obs_module_file("effects/blur/gaussian.effect");
|
char* file = obs_module_file("effects/blur/gaussian.effect");
|
||||||
m_effect = std::make_shared<gs::effect>(file);
|
m_effect = std::make_shared<gs::effect>(file);
|
||||||
|
@ -81,6 +83,7 @@ gfx::blur::gaussian_data::gaussian_data()
|
||||||
|
|
||||||
gfx::blur::gaussian_data::~gaussian_data()
|
gfx::blur::gaussian_data::~gaussian_data()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
m_effect.reset();
|
m_effect.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,6 +242,7 @@ std::shared_ptr<::gfx::blur::gaussian_data> gfx::blur::gaussian_factory::data()
|
||||||
gfx::blur::gaussian::gaussian()
|
gfx::blur::gaussian::gaussian()
|
||||||
: m_size(1.), m_step_scale({1., 1.}), m_data(::gfx::blur::gaussian_factory::get().data())
|
: m_size(1.), m_step_scale({1., 1.}), m_data(::gfx::blur::gaussian_factory::get().data())
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
m_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
m_rendertarget = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
m_rendertarget2 = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
m_rendertarget2 = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
|
||||||
}
|
}
|
||||||
|
@ -293,6 +297,8 @@ double_t gfx::blur::gaussian::get_step_scale_y()
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::gaussian::render()
|
std::shared_ptr<::gs::texture> gfx::blur::gaussian::render()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
||||||
auto kernel = m_data->get_kernel(size_t(m_size));
|
auto kernel = m_data->get_kernel(size_t(m_size));
|
||||||
|
|
||||||
|
@ -304,7 +310,6 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian::render()
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(m_input_texture->get_height());
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
obs_enter_graphics();
|
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
gs_set_cull_mode(GS_NEITHER);
|
||||||
gs_enable_color(true, true, true, true);
|
gs_enable_color(true, true, true, true);
|
||||||
gs_enable_depth_test(false);
|
gs_enable_depth_test(false);
|
||||||
|
@ -355,7 +360,6 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return this->get();
|
return this->get();
|
||||||
}
|
}
|
||||||
|
@ -386,6 +390,8 @@ void gfx::blur::gaussian_directional::set_angle(double_t angle)
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::gaussian_directional::render()
|
std::shared_ptr<::gs::texture> gfx::blur::gaussian_directional::render()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
||||||
auto kernel = m_data->get_kernel(size_t(m_size));
|
auto kernel = m_data->get_kernel(size_t(m_size));
|
||||||
|
|
||||||
|
@ -428,7 +434,6 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_directional::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return this->get();
|
return this->get();
|
||||||
}
|
}
|
||||||
|
@ -440,6 +445,8 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_directional::render()
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::gaussian_rotational::render()
|
std::shared_ptr<::gs::texture> gfx::blur::gaussian_rotational::render()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
||||||
auto kernel = m_data->get_kernel(size_t(m_size));
|
auto kernel = m_data->get_kernel(size_t(m_size));
|
||||||
|
|
||||||
|
@ -451,7 +458,6 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_rotational::render()
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(m_input_texture->get_height());
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
obs_enter_graphics();
|
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
gs_set_cull_mode(GS_NEITHER);
|
||||||
gs_enable_color(true, true, true, true);
|
gs_enable_color(true, true, true, true);
|
||||||
gs_enable_depth_test(false);
|
gs_enable_depth_test(false);
|
||||||
|
@ -483,7 +489,6 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_rotational::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return this->get();
|
return this->get();
|
||||||
}
|
}
|
||||||
|
@ -517,6 +522,8 @@ void gfx::blur::gaussian_rotational::set_angle(double_t angle)
|
||||||
|
|
||||||
std::shared_ptr<::gs::texture> gfx::blur::gaussian_zoom::render()
|
std::shared_ptr<::gs::texture> gfx::blur::gaussian_zoom::render()
|
||||||
{
|
{
|
||||||
|
auto gctx = gs::context();
|
||||||
|
|
||||||
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
std::shared_ptr<::gs::effect> effect = m_data->get_effect();
|
||||||
auto kernel = m_data->get_kernel(size_t(m_size));
|
auto kernel = m_data->get_kernel(size_t(m_size));
|
||||||
|
|
||||||
|
@ -528,7 +535,6 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_zoom::render()
|
||||||
float_t height = float_t(m_input_texture->get_height());
|
float_t height = float_t(m_input_texture->get_height());
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
obs_enter_graphics();
|
|
||||||
gs_set_cull_mode(GS_NEITHER);
|
gs_set_cull_mode(GS_NEITHER);
|
||||||
gs_enable_color(true, true, true, true);
|
gs_enable_color(true, true, true, true);
|
||||||
gs_enable_depth_test(false);
|
gs_enable_depth_test(false);
|
||||||
|
@ -559,7 +565,6 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_zoom::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_blend_state_pop();
|
gs_blend_state_pop();
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
return this->get();
|
return this->get();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gs-effect.hpp"
|
#include "gs-effect.hpp"
|
||||||
#include <stdexcept>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
|
|
||||||
// OBS
|
// OBS
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -40,8 +41,8 @@ gs::effect::effect() : m_effect(nullptr) {}
|
||||||
gs::effect::effect(std::string file)
|
gs::effect::effect(std::string file)
|
||||||
{
|
{
|
||||||
#ifdef OBS_LOAD_EFFECT_FILE
|
#ifdef OBS_LOAD_EFFECT_FILE
|
||||||
obs_enter_graphics();
|
|
||||||
char* errorMessage = nullptr;
|
char* errorMessage = nullptr;
|
||||||
|
auto gctx = gs::context();
|
||||||
m_effect = gs_effect_create_from_file(file.c_str(), &errorMessage);
|
m_effect = gs_effect_create_from_file(file.c_str(), &errorMessage);
|
||||||
if (!m_effect || errorMessage) {
|
if (!m_effect || errorMessage) {
|
||||||
std::string error = "Generic Error";
|
std::string error = "Generic Error";
|
||||||
|
@ -49,10 +50,8 @@ gs::effect::effect(std::string file)
|
||||||
error = std::string(errorMessage);
|
error = std::string(errorMessage);
|
||||||
bfree((void*)errorMessage);
|
bfree((void*)errorMessage);
|
||||||
}
|
}
|
||||||
obs_leave_graphics();
|
|
||||||
throw std::runtime_error(error);
|
throw std::runtime_error(error);
|
||||||
}
|
}
|
||||||
obs_leave_graphics();
|
|
||||||
#else
|
#else
|
||||||
std::ifstream filestream = std::ifstream(file, std::ios::binary);
|
std::ifstream filestream = std::ifstream(file, std::ios::binary);
|
||||||
if (!filestream.is_open()) {
|
if (!filestream.is_open()) {
|
||||||
|
@ -68,11 +67,11 @@ gs::effect::effect(std::string file)
|
||||||
throw std::runtime_error("Shader too large (>256mb)");
|
throw std::runtime_error("Shader too large (>256mb)");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<char> shader_buf(length+1);
|
std::vector<char> shader_buf(length + 1);
|
||||||
filestream.read(shader_buf.data(), length);
|
filestream.read(shader_buf.data(), length);
|
||||||
|
|
||||||
obs_enter_graphics();
|
|
||||||
char* errorMessage = nullptr;
|
char* errorMessage = nullptr;
|
||||||
|
auto gctx = gs::context();
|
||||||
m_effect = gs_effect_create(shader_buf.data(), file.c_str(), &errorMessage);
|
m_effect = gs_effect_create(shader_buf.data(), file.c_str(), &errorMessage);
|
||||||
if (!m_effect || errorMessage) {
|
if (!m_effect || errorMessage) {
|
||||||
std::string error = "Generic Error";
|
std::string error = "Generic Error";
|
||||||
|
@ -80,17 +79,15 @@ gs::effect::effect(std::string file)
|
||||||
error = std::string(errorMessage);
|
error = std::string(errorMessage);
|
||||||
bfree((void*)errorMessage);
|
bfree((void*)errorMessage);
|
||||||
}
|
}
|
||||||
obs_leave_graphics();
|
|
||||||
throw std::runtime_error(error);
|
throw std::runtime_error(error);
|
||||||
}
|
}
|
||||||
obs_leave_graphics();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
gs::effect::effect(std::string code, std::string name)
|
gs::effect::effect(std::string code, std::string name)
|
||||||
{
|
{
|
||||||
obs_enter_graphics();
|
|
||||||
char* errorMessage = nullptr;
|
char* errorMessage = nullptr;
|
||||||
|
auto gctx = gs::context();
|
||||||
m_effect = gs_effect_create(code.c_str(), name.c_str(), &errorMessage);
|
m_effect = gs_effect_create(code.c_str(), name.c_str(), &errorMessage);
|
||||||
if (!m_effect || errorMessage) {
|
if (!m_effect || errorMessage) {
|
||||||
std::string error = "Generic Error";
|
std::string error = "Generic Error";
|
||||||
|
@ -98,17 +95,14 @@ gs::effect::effect(std::string code, std::string name)
|
||||||
error = std::string(errorMessage);
|
error = std::string(errorMessage);
|
||||||
bfree((void*)errorMessage);
|
bfree((void*)errorMessage);
|
||||||
}
|
}
|
||||||
obs_leave_graphics();
|
|
||||||
throw std::runtime_error(error);
|
throw std::runtime_error(error);
|
||||||
}
|
}
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gs::effect::~effect()
|
gs::effect::~effect()
|
||||||
{
|
{
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
gs_effect_destroy(m_effect);
|
gs_effect_destroy(m_effect);
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_effect_t* gs::effect::get_object()
|
gs_effect_t* gs::effect::get_object()
|
||||||
|
|
|
@ -19,94 +19,12 @@
|
||||||
|
|
||||||
#include "gs-helper.hpp"
|
#include "gs-helper.hpp"
|
||||||
|
|
||||||
gs_effect_param* gs_effect_get_param(gs_effect_t* effect, const char* name)
|
gs::context::context()
|
||||||
{
|
{
|
||||||
gs_effect_param* p = gs_effect_get_param_by_name(effect, name);
|
obs_enter_graphics();
|
||||||
if (!p)
|
|
||||||
P_LOG_ERROR("Failed to find parameter %s in effect.", name);
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gs_set_param_int(gs_effect_t* effect, const char* name, int value)
|
gs::context::~context()
|
||||||
{
|
{
|
||||||
gs_effect_param* p = nullptr;
|
obs_leave_graphics();
|
||||||
if (nullptr != (p = gs_effect_get_param(effect, name))) {
|
|
||||||
gs_effect_set_int(p, value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
P_LOG_ERROR(
|
|
||||||
"Failed to set value %d for parameter %s in"
|
|
||||||
" effect.",
|
|
||||||
value, name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gs_set_param_float(gs_effect_t* effect, const char* name, float value)
|
|
||||||
{
|
|
||||||
gs_effect_param* p = nullptr;
|
|
||||||
if (nullptr != (p = gs_effect_get_param(effect, name))) {
|
|
||||||
gs_effect_set_float(p, value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
P_LOG_ERROR(
|
|
||||||
"Failed to set value %f for parameter %s in"
|
|
||||||
" effect.",
|
|
||||||
value, name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gs_set_param_float2(gs_effect_t* effect, const char* name, vec2* value)
|
|
||||||
{
|
|
||||||
gs_effect_param* p = nullptr;
|
|
||||||
if (nullptr != (p = gs_effect_get_param(effect, name))) {
|
|
||||||
gs_effect_set_vec2(p, value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
P_LOG_ERROR(
|
|
||||||
"Failed to set value {%f,%f} for parameter %s"
|
|
||||||
" in effect.",
|
|
||||||
value->x, value->y, name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gs_set_param_float3(gs_effect_t* effect, const char* name, vec3* value)
|
|
||||||
{
|
|
||||||
gs_effect_param* p = nullptr;
|
|
||||||
if (nullptr != (p = gs_effect_get_param(effect, name))) {
|
|
||||||
gs_effect_set_vec3(p, value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
P_LOG_ERROR(
|
|
||||||
"Failed to set value {%f,%f,%f} for parameter"
|
|
||||||
"%s in effect.",
|
|
||||||
value->x, value->y, value->z, name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gs_set_param_float4(gs_effect_t* effect, const char* name, vec4* value)
|
|
||||||
{
|
|
||||||
gs_effect_param* p = nullptr;
|
|
||||||
if (nullptr != (p = gs_effect_get_param(effect, name))) {
|
|
||||||
gs_effect_set_vec4(p, value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
P_LOG_ERROR(
|
|
||||||
"Failed to set value {%f,%f,%f,%f} for"
|
|
||||||
" parameter %s in effect.",
|
|
||||||
value->x, value->y, value->z, value->w, name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gs_set_param_texture(gs_effect_t* effect, const char* name, gs_texture_t* value)
|
|
||||||
{
|
|
||||||
gs_effect_param* p = nullptr;
|
|
||||||
if (nullptr != (p = gs_effect_get_param(effect, name))) {
|
|
||||||
gs_effect_set_texture(p, value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
P_LOG_ERROR(
|
|
||||||
"Failed to set texture for"
|
|
||||||
" parameter %s in effect.",
|
|
||||||
name);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,10 @@
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gs_effect_param* gs_effect_get_param(gs_effect_t* effect, const char* name);
|
namespace gs {
|
||||||
bool gs_set_param_int(gs_effect_t* effect, const char* name, int value);
|
class context {
|
||||||
bool gs_set_param_float(gs_effect_t* effect, const char* name, float value);
|
public:
|
||||||
bool gs_set_param_float2(gs_effect_t* effect, const char* name, vec2* value);
|
context();
|
||||||
bool gs_set_param_float3(gs_effect_t* effect, const char* name, vec3* value);
|
~context();
|
||||||
bool gs_set_param_float4(gs_effect_t* effect, const char* name, vec4* value);
|
};
|
||||||
bool gs_set_param_texture(gs_effect_t* effect, const char* name, gs_texture_t* value);
|
} // namespace gs
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "gs-indexbuffer.hpp"
|
#include "gs-indexbuffer.hpp"
|
||||||
#include "gs-limits.hpp"
|
#include "gs-limits.hpp"
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
|
|
||||||
// OBS
|
// OBS
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -33,10 +34,8 @@
|
||||||
gs::index_buffer::index_buffer(uint32_t maximumVertices)
|
gs::index_buffer::index_buffer(uint32_t maximumVertices)
|
||||||
{
|
{
|
||||||
this->reserve(maximumVertices);
|
this->reserve(maximumVertices);
|
||||||
|
auto gctx = gs::context();
|
||||||
obs_enter_graphics();
|
|
||||||
m_indexBuffer = gs_indexbuffer_create(gs_index_type::GS_UNSIGNED_LONG, this->data(), maximumVertices, GS_DYNAMIC);
|
m_indexBuffer = gs_indexbuffer_create(gs_index_type::GS_UNSIGNED_LONG, this->data(), maximumVertices, GS_DYNAMIC);
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gs::index_buffer::index_buffer() : index_buffer(MAXIMUM_VERTICES) {}
|
gs::index_buffer::index_buffer() : index_buffer(MAXIMUM_VERTICES) {}
|
||||||
|
@ -53,9 +52,8 @@ gs::index_buffer::index_buffer(std::vector<uint32_t>& other) : index_buffer((uin
|
||||||
|
|
||||||
gs::index_buffer::~index_buffer()
|
gs::index_buffer::~index_buffer()
|
||||||
{
|
{
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
gs_indexbuffer_destroy(m_indexBuffer);
|
gs_indexbuffer_destroy(m_indexBuffer);
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_indexbuffer_t* gs::index_buffer::get()
|
gs_indexbuffer_t* gs::index_buffer::get()
|
||||||
|
@ -66,9 +64,8 @@ gs_indexbuffer_t* gs::index_buffer::get()
|
||||||
gs_indexbuffer_t* gs::index_buffer::get(bool refreshGPU)
|
gs_indexbuffer_t* gs::index_buffer::get(bool refreshGPU)
|
||||||
{
|
{
|
||||||
if (refreshGPU) {
|
if (refreshGPU) {
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
gs_indexbuffer_flush(m_indexBuffer);
|
gs_indexbuffer_flush(m_indexBuffer);
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
return m_indexBuffer;
|
return m_indexBuffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gs-mipmapper.hpp"
|
#include "gs-mipmapper.hpp"
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
|
|
||||||
// OBS
|
// OBS
|
||||||
|
@ -147,7 +148,7 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
|
||||||
throw std::invalid_argument("source and target must have same format");
|
throw std::invalid_argument("source and target must have same format");
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
|
|
||||||
// Copy original texture
|
// Copy original texture
|
||||||
//gs_copy_texture(target->get_object(), source->get_object());
|
//gs_copy_texture(target->get_object(), source->get_object());
|
||||||
|
@ -217,7 +218,6 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
|
||||||
|
|
||||||
// If we do not have any miplevels, just stop now.
|
// If we do not have any miplevels, just stop now.
|
||||||
if (mip_levels == 1) {
|
if (mip_levels == 1) {
|
||||||
obs_leave_graphics();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,6 +278,4 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
|
||||||
|
|
||||||
gs_load_indexbuffer(nullptr);
|
gs_load_indexbuffer(nullptr);
|
||||||
gs_load_vertexbuffer(nullptr);
|
gs_load_vertexbuffer(nullptr);
|
||||||
|
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "gs-rendertarget.hpp"
|
#include "gs-rendertarget.hpp"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
|
|
||||||
// OBS
|
// OBS
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -33,18 +34,16 @@
|
||||||
|
|
||||||
gs::rendertarget::~rendertarget()
|
gs::rendertarget::~rendertarget()
|
||||||
{
|
{
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
gs_texrender_destroy(render_target);
|
gs_texrender_destroy(render_target);
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gs::rendertarget::rendertarget(gs_color_format colorFormat, gs_zstencil_format zsFormat)
|
gs::rendertarget::rendertarget(gs_color_format colorFormat, gs_zstencil_format zsFormat)
|
||||||
: color_format(colorFormat), zstencil_format(zsFormat)
|
: color_format(colorFormat), zstencil_format(zsFormat)
|
||||||
{
|
{
|
||||||
is_being_rendered = false;
|
is_being_rendered = false;
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
render_target = gs_texrender_create(colorFormat, zsFormat);
|
render_target = gs_texrender_create(colorFormat, zsFormat);
|
||||||
obs_leave_graphics();
|
|
||||||
if (!render_target) {
|
if (!render_target) {
|
||||||
throw std::runtime_error("Failed to create render target.");
|
throw std::runtime_error("Failed to create render target.");
|
||||||
}
|
}
|
||||||
|
@ -57,9 +56,8 @@ gs::rendertarget_op gs::rendertarget::render(uint32_t width, uint32_t height)
|
||||||
|
|
||||||
gs_texture_t* gs::rendertarget::get_object()
|
gs_texture_t* gs::rendertarget::get_object()
|
||||||
{
|
{
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
gs_texture_t* tex = gs_texrender_get_texture(render_target);
|
gs_texture_t* tex = gs_texrender_get_texture(render_target);
|
||||||
obs_leave_graphics();
|
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,13 +97,12 @@ gs::rendertarget_op::rendertarget_op(gs::rendertarget* rt, uint32_t width, uint3
|
||||||
throw std::invalid_argument("rt");
|
throw std::invalid_argument("rt");
|
||||||
if (parent->is_being_rendered)
|
if (parent->is_being_rendered)
|
||||||
throw std::logic_error("Can't start rendering to the same render target twice.");
|
throw std::logic_error("Can't start rendering to the same render target twice.");
|
||||||
obs_enter_graphics();
|
|
||||||
|
auto gctx = gs::context();
|
||||||
gs_texrender_reset(parent->render_target);
|
gs_texrender_reset(parent->render_target);
|
||||||
if (!gs_texrender_begin(parent->render_target, width, height)) {
|
if (!gs_texrender_begin(parent->render_target, width, height)) {
|
||||||
obs_leave_graphics();
|
|
||||||
throw std::runtime_error("Failed to begin rendering to render target.");
|
throw std::runtime_error("Failed to begin rendering to render target.");
|
||||||
}
|
}
|
||||||
obs_leave_graphics();
|
|
||||||
parent->is_being_rendered = true;
|
parent->is_being_rendered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,8 +116,8 @@ gs::rendertarget_op::~rendertarget_op()
|
||||||
{
|
{
|
||||||
if (parent == nullptr)
|
if (parent == nullptr)
|
||||||
return;
|
return;
|
||||||
obs_enter_graphics();
|
|
||||||
|
auto gctx = gs::context();
|
||||||
gs_texrender_end(parent->render_target);
|
gs_texrender_end(parent->render_target);
|
||||||
obs_leave_graphics();
|
|
||||||
parent->is_being_rendered = false;
|
parent->is_being_rendered = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include "util-math.hpp"
|
#include "util-math.hpp"
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
|
|
||||||
// OBS
|
// OBS
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -50,12 +51,11 @@ gs::texture::texture(uint32_t width, uint32_t height, gs_color_format format, ui
|
||||||
throw std::logic_error("mip mapping requires power of two dimensions");
|
throw std::logic_error("mip mapping requires power of two dimensions");
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
m_texture = gs_texture_create(
|
m_texture = gs_texture_create(
|
||||||
width, height, format, mip_levels, mip_data,
|
width, height, format, mip_levels, mip_data,
|
||||||
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
|
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
|
||||||
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
|
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
if (!m_texture)
|
if (!m_texture)
|
||||||
throw std::runtime_error("Failed to create texture.");
|
throw std::runtime_error("Failed to create texture.");
|
||||||
|
@ -83,12 +83,11 @@ gs::texture::texture(uint32_t width, uint32_t height, uint32_t depth, gs_color_f
|
||||||
throw std::logic_error("mip mapping requires power of two dimensions");
|
throw std::logic_error("mip mapping requires power of two dimensions");
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
m_texture = gs_voltexture_create(
|
m_texture = gs_voltexture_create(
|
||||||
width, height, depth, format, mip_levels, mip_data,
|
width, height, depth, format, mip_levels, mip_data,
|
||||||
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
|
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
|
||||||
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
|
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
if (!m_texture)
|
if (!m_texture)
|
||||||
throw std::runtime_error("Failed to create texture.");
|
throw std::runtime_error("Failed to create texture.");
|
||||||
|
@ -110,12 +109,11 @@ gs::texture::texture(uint32_t size, gs_color_format format, uint32_t mip_levels,
|
||||||
throw std::logic_error("mip mapping requires power of two dimensions");
|
throw std::logic_error("mip mapping requires power of two dimensions");
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
m_texture = gs_cubetexture_create(
|
m_texture = gs_cubetexture_create(
|
||||||
size, format, mip_levels, mip_data,
|
size, format, mip_levels, mip_data,
|
||||||
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
|
(((texture_flags & flags::Dynamic) == flags::Dynamic) ? GS_DYNAMIC : 0)
|
||||||
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
|
| (((texture_flags & flags::BuildMipMaps) == flags::BuildMipMaps) ? GS_BUILD_MIPMAPS : 0));
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
if (!m_texture)
|
if (!m_texture)
|
||||||
throw std::runtime_error("Failed to create texture.");
|
throw std::runtime_error("Failed to create texture.");
|
||||||
|
@ -129,9 +127,8 @@ gs::texture::texture(std::string file)
|
||||||
if (os_stat(file.c_str(), &st) != 0)
|
if (os_stat(file.c_str(), &st) != 0)
|
||||||
throw std::ios_base::failure(file);
|
throw std::ios_base::failure(file);
|
||||||
|
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
m_texture = gs_texture_create_from_file(file.c_str());
|
m_texture = gs_texture_create_from_file(file.c_str());
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
if (!m_texture)
|
if (!m_texture)
|
||||||
throw std::runtime_error("Failed to load texture.");
|
throw std::runtime_error("Failed to load texture.");
|
||||||
|
@ -140,7 +137,7 @@ gs::texture::texture(std::string file)
|
||||||
gs::texture::~texture()
|
gs::texture::~texture()
|
||||||
{
|
{
|
||||||
if (m_isOwner && m_texture) {
|
if (m_isOwner && m_texture) {
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
switch (gs_get_texture_type(m_texture)) {
|
switch (gs_get_texture_type(m_texture)) {
|
||||||
case GS_TEXTURE_2D:
|
case GS_TEXTURE_2D:
|
||||||
gs_texture_destroy(m_texture);
|
gs_texture_destroy(m_texture);
|
||||||
|
@ -152,16 +149,14 @@ gs::texture::~texture()
|
||||||
gs_cubetexture_destroy(m_texture);
|
gs_cubetexture_destroy(m_texture);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
m_texture = nullptr;
|
m_texture = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gs::texture::load(int unit)
|
void gs::texture::load(int unit)
|
||||||
{
|
{
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
gs_load_texture(m_texture, unit);
|
gs_load_texture(m_texture, unit);
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gs_texture_t* gs::texture::get_object()
|
gs_texture_t* gs::texture::get_object()
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "gs-vertexbuffer.hpp"
|
#include "gs-vertexbuffer.hpp"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "util-memory.hpp"
|
#include "util-memory.hpp"
|
||||||
|
#include "obs/gs/gs-helper.hpp"
|
||||||
|
|
||||||
// OBS
|
// OBS
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -67,9 +68,8 @@ gs::vertex_buffer::~vertex_buffer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_vertexbuffer) {
|
if (m_vertexbuffer) {
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
gs_vertexbuffer_destroy(m_vertexbuffer);
|
gs_vertexbuffer_destroy(m_vertexbuffer);
|
||||||
obs_leave_graphics();
|
|
||||||
m_vertexbuffer = nullptr;
|
m_vertexbuffer = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,12 +119,11 @@ gs::vertex_buffer::vertex_buffer(uint32_t vertices, uint8_t uvlayers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate GPU
|
// Allocate GPU
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
m_vertexbuffer = gs_vertexbuffer_create(m_vertexbufferdata, GS_DYNAMIC);
|
m_vertexbuffer = gs_vertexbuffer_create(m_vertexbufferdata, GS_DYNAMIC);
|
||||||
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
|
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
|
||||||
m_vertexbufferdata->num = m_capacity;
|
m_vertexbufferdata->num = m_capacity;
|
||||||
m_vertexbufferdata->num_tex = m_layers;
|
m_vertexbufferdata->num_tex = m_layers;
|
||||||
obs_leave_graphics();
|
|
||||||
if (!m_vertexbuffer) {
|
if (!m_vertexbuffer) {
|
||||||
throw std::runtime_error("Failed to create vertex buffer.");
|
throw std::runtime_error("Failed to create vertex buffer.");
|
||||||
}
|
}
|
||||||
|
@ -133,7 +132,7 @@ gs::vertex_buffer::vertex_buffer(uint32_t vertices, uint8_t uvlayers)
|
||||||
// cppcheck-suppress uninitMemberVar
|
// cppcheck-suppress uninitMemberVar
|
||||||
gs::vertex_buffer::vertex_buffer(gs_vertbuffer_t* vb)
|
gs::vertex_buffer::vertex_buffer(gs_vertbuffer_t* vb)
|
||||||
{
|
{
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
gs_vb_data* vbd = gs_vertexbuffer_get_data(vb);
|
gs_vb_data* vbd = gs_vertexbuffer_get_data(vb);
|
||||||
if (!vbd)
|
if (!vbd)
|
||||||
throw std::runtime_error("vertex buffer with no data");
|
throw std::runtime_error("vertex buffer with no data");
|
||||||
|
@ -165,7 +164,6 @@ gs::vertex_buffer::vertex_buffer(gs_vertbuffer_t* vb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
obs_leave_graphics();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// cppcheck-suppress uninitMemberVar
|
// cppcheck-suppress uninitMemberVar
|
||||||
|
@ -236,9 +234,8 @@ void gs::vertex_buffer::operator=(vertex_buffer const&& other)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_vertexbuffer) {
|
if (m_vertexbuffer) {
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
gs_vertexbuffer_destroy(m_vertexbuffer);
|
gs_vertexbuffer_destroy(m_vertexbuffer);
|
||||||
obs_leave_graphics();
|
|
||||||
m_vertexbuffer = nullptr;
|
m_vertexbuffer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +337,7 @@ gs_vertbuffer_t* gs::vertex_buffer::update(bool refreshGPU)
|
||||||
throw std::out_of_range("size is larger than capacity");
|
throw std::out_of_range("size is larger than capacity");
|
||||||
|
|
||||||
// Update VertexBuffer data.
|
// Update VertexBuffer data.
|
||||||
obs_enter_graphics();
|
auto gctx = gs::context();
|
||||||
m_vertexbufferdata = gs_vertexbuffer_get_data(m_vertexbuffer);
|
m_vertexbufferdata = gs_vertexbuffer_get_data(m_vertexbuffer);
|
||||||
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
|
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
|
||||||
m_vertexbufferdata->num = m_capacity;
|
m_vertexbufferdata->num = m_capacity;
|
||||||
|
@ -357,7 +354,6 @@ gs_vertbuffer_t* gs::vertex_buffer::update(bool refreshGPU)
|
||||||
|
|
||||||
// Update GPU
|
// Update GPU
|
||||||
gs_vertexbuffer_flush(m_vertexbuffer);
|
gs_vertexbuffer_flush(m_vertexbuffer);
|
||||||
obs_leave_graphics();
|
|
||||||
|
|
||||||
// WORKAROUND: OBS Studio 20.x and below incorrectly deletes data that it doesn't own.
|
// WORKAROUND: OBS Studio 20.x and below incorrectly deletes data that it doesn't own.
|
||||||
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
|
memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
|
||||||
|
|
Loading…
Reference in a new issue