gs-effect: Use std::shared_ptr and track effect lifetime

This fixes the case where the effect vanishes, but we still hold an invalid pointer to a parameter of that effect. With the new code, the effect will not vanish as long as an effect pointer exists.

However, all effects must be created either through std::shared_ptr or std::make_shared. If they were not made through one of those means, the code will crash on the ->shared_from_this() call.
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2019-08-04 23:12:30 +02:00
parent ff6f4d5ddf
commit 0c447f4055
13 changed files with 215 additions and 210 deletions

View file

@ -337,31 +337,31 @@ bool filter::blur::blur_instance::apply_mask_parameters(std::shared_ptr<gs::effe
gs_texture_t* original_texture, gs_texture_t* blurred_texture) gs_texture_t* original_texture, gs_texture_t* blurred_texture)
{ {
if (effect->has_parameter("image_orig")) { if (effect->has_parameter("image_orig")) {
effect->get_parameter("image_orig").set_texture(original_texture); effect->get_parameter("image_orig")->set_texture(original_texture);
} }
if (effect->has_parameter("image_blur")) { if (effect->has_parameter("image_blur")) {
effect->get_parameter("image_blur").set_texture(blurred_texture); effect->get_parameter("image_blur")->set_texture(blurred_texture);
} }
// Region // Region
if (_mask.type == mask_type::Region) { if (_mask.type == mask_type::Region) {
if (effect->has_parameter("mask_region_left")) { if (effect->has_parameter("mask_region_left")) {
effect->get_parameter("mask_region_left").set_float(_mask.region.left); effect->get_parameter("mask_region_left")->set_float(_mask.region.left);
} }
if (effect->has_parameter("mask_region_right")) { if (effect->has_parameter("mask_region_right")) {
effect->get_parameter("mask_region_right").set_float(_mask.region.right); effect->get_parameter("mask_region_right")->set_float(_mask.region.right);
} }
if (effect->has_parameter("mask_region_top")) { if (effect->has_parameter("mask_region_top")) {
effect->get_parameter("mask_region_top").set_float(_mask.region.top); effect->get_parameter("mask_region_top")->set_float(_mask.region.top);
} }
if (effect->has_parameter("mask_region_bottom")) { if (effect->has_parameter("mask_region_bottom")) {
effect->get_parameter("mask_region_bottom").set_float(_mask.region.bottom); effect->get_parameter("mask_region_bottom")->set_float(_mask.region.bottom);
} }
if (effect->has_parameter("mask_region_feather")) { if (effect->has_parameter("mask_region_feather")) {
effect->get_parameter("mask_region_feather").set_float(_mask.region.feather); effect->get_parameter("mask_region_feather")->set_float(_mask.region.feather);
} }
if (effect->has_parameter("mask_region_feather_shift")) { if (effect->has_parameter("mask_region_feather_shift")) {
effect->get_parameter("mask_region_feather_shift").set_float(_mask.region.feather_shift); effect->get_parameter("mask_region_feather_shift")->set_float(_mask.region.feather_shift);
} }
} }
@ -369,9 +369,9 @@ bool filter::blur::blur_instance::apply_mask_parameters(std::shared_ptr<gs::effe
if (_mask.type == mask_type::Image) { if (_mask.type == mask_type::Image) {
if (effect->has_parameter("mask_image")) { if (effect->has_parameter("mask_image")) {
if (_mask.image.texture) { if (_mask.image.texture) {
effect->get_parameter("mask_image").set_texture(_mask.image.texture); effect->get_parameter("mask_image")->set_texture(_mask.image.texture);
} else { } else {
effect->get_parameter("mask_image").set_texture(nullptr); effect->get_parameter("mask_image")->set_texture(nullptr);
} }
} }
} }
@ -380,19 +380,19 @@ bool filter::blur::blur_instance::apply_mask_parameters(std::shared_ptr<gs::effe
if (_mask.type == mask_type::Source) { if (_mask.type == mask_type::Source) {
if (effect->has_parameter("mask_image")) { if (effect->has_parameter("mask_image")) {
if (_mask.source.texture) { if (_mask.source.texture) {
effect->get_parameter("mask_image").set_texture(_mask.source.texture); effect->get_parameter("mask_image")->set_texture(_mask.source.texture);
} else { } else {
effect->get_parameter("mask_image").set_texture(nullptr); effect->get_parameter("mask_image")->set_texture(nullptr);
} }
} }
} }
// Shared // Shared
if (effect->has_parameter("mask_color")) { if (effect->has_parameter("mask_color")) {
effect->get_parameter("mask_color").set_float4(_mask.color.r, _mask.color.g, _mask.color.b, _mask.color.a); effect->get_parameter("mask_color")->set_float4(_mask.color.r, _mask.color.g, _mask.color.b, _mask.color.a);
} }
if (effect->has_parameter("mask_multiplier")) { if (effect->has_parameter("mask_multiplier")) {
effect->get_parameter("mask_multiplier").set_float(_mask.multiplier); effect->get_parameter("mask_multiplier")->set_float(_mask.multiplier);
} }
return true; return true;

View file

@ -517,23 +517,23 @@ void filter::color_grade::color_grade_instance::video_render(gs_effect_t*)
gs_ortho(0, static_cast<float_t>(width), 0, static_cast<float_t>(height), -1., 1.); gs_ortho(0, static_cast<float_t>(width), 0, static_cast<float_t>(height), -1., 1.);
if (_effect->has_parameter("image")) if (_effect->has_parameter("image"))
_effect->get_parameter("image").set_texture(_tex_source); _effect->get_parameter("image")->set_texture(_tex_source);
if (_effect->has_parameter("pLift")) if (_effect->has_parameter("pLift"))
_effect->get_parameter("pLift").set_float4(_lift); _effect->get_parameter("pLift")->set_float4(_lift);
if (_effect->has_parameter("pGamma")) if (_effect->has_parameter("pGamma"))
_effect->get_parameter("pGamma").set_float4(_gamma); _effect->get_parameter("pGamma")->set_float4(_gamma);
if (_effect->has_parameter("pGain")) if (_effect->has_parameter("pGain"))
_effect->get_parameter("pGain").set_float4(_gain); _effect->get_parameter("pGain")->set_float4(_gain);
if (_effect->has_parameter("pOffset")) if (_effect->has_parameter("pOffset"))
_effect->get_parameter("pOffset").set_float4(_offset); _effect->get_parameter("pOffset")->set_float4(_offset);
if (_effect->has_parameter("pTintLow")) if (_effect->has_parameter("pTintLow"))
_effect->get_parameter("pTintLow").set_float3(_tint_low); _effect->get_parameter("pTintLow")->set_float3(_tint_low);
if (_effect->has_parameter("pTintMid")) if (_effect->has_parameter("pTintMid"))
_effect->get_parameter("pTintMid").set_float3(_tint_mid); _effect->get_parameter("pTintMid")->set_float3(_tint_mid);
if (_effect->has_parameter("pTintHig")) if (_effect->has_parameter("pTintHig"))
_effect->get_parameter("pTintHig").set_float3(_tint_hig); _effect->get_parameter("pTintHig")->set_float3(_tint_hig);
if (_effect->has_parameter("pCorrection")) if (_effect->has_parameter("pCorrection"))
_effect->get_parameter("pCorrection").set_float4(_correction); _effect->get_parameter("pCorrection")->set_float4(_correction);
while (gs_effect_loop(_effect->get_object(), "Draw")) { while (gs_effect_loop(_effect->get_object(), "Draw")) {
gs_draw_sprite(nullptr, 0, width, height); gs_draw_sprite(nullptr, 0, width, height);

View file

@ -279,13 +279,13 @@ void filter::displacement::displacement_instance::video_render(gs_effect_t*)
if (_effect->has_parameter("texelScale")) { if (_effect->has_parameter("texelScale")) {
_effect->get_parameter("texelScale") _effect->get_parameter("texelScale")
.set_float2(interp((1.0f / baseW), 1.0f, _distance), interp((1.0f / baseH), 1.0f, _distance)); ->set_float2(interp((1.0f / baseW), 1.0f, _distance), interp((1.0f / baseH), 1.0f, _distance));
} }
if (_effect->has_parameter("displacementScale")) { if (_effect->has_parameter("displacementScale")) {
_effect->get_parameter("displacementScale").set_float2(_displacement_scale); _effect->get_parameter("displacementScale")->set_float2(_displacement_scale);
} }
if (_effect->has_parameter("displacementMap")) { if (_effect->has_parameter("displacementMap")) {
_effect->get_parameter("displacementMap").set_texture(_file_texture); _effect->get_parameter("displacementMap")->set_texture(_file_texture);
} }
obs_source_process_filter_end(_self, _effect->get_object(), baseW, baseH); obs_source_process_filter_end(_self, _effect->get_object(), baseW, baseH);

View file

@ -451,12 +451,12 @@ void filter::dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_e
gs_stencil_op(GS_STENCIL_BOTH, GS_KEEP, GS_KEEP, GS_KEEP); gs_stencil_op(GS_STENCIL_BOTH, GS_KEEP, GS_KEEP, GS_KEEP);
gs_ortho(0, (float)width, 0, (float)height, -1., 1.); gs_ortho(0, (float)width, 0, (float)height, -1., 1.);
this->_effect->get_parameter("pMaskInputA").set_texture(this->_filter_texture); this->_effect->get_parameter("pMaskInputA")->set_texture(this->_filter_texture);
this->_effect->get_parameter("pMaskInputB").set_texture(this->_input_texture); this->_effect->get_parameter("pMaskInputB")->set_texture(this->_input_texture);
this->_effect->get_parameter("pMaskBase").set_float4(this->_precalc.base); this->_effect->get_parameter("pMaskBase")->set_float4(this->_precalc.base);
this->_effect->get_parameter("pMaskMatrix").set_matrix(this->_precalc.matrix); this->_effect->get_parameter("pMaskMatrix")->set_matrix(this->_precalc.matrix);
this->_effect->get_parameter("pMaskMultiplier").set_float4(this->_precalc.scale); this->_effect->get_parameter("pMaskMultiplier")->set_float4(this->_precalc.scale);
while (gs_effect_loop(this->_effect->get_object(), "Mask")) { while (gs_effect_loop(this->_effect->get_object(), "Mask")) {
gs_draw_sprite(0, 0, width, height); gs_draw_sprite(0, 0, width, height);

View file

@ -725,10 +725,10 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
gs_ortho(0, (float)sdfW, 0, (float)sdfH, -1, 1); gs_ortho(0, (float)sdfW, 0, (float)sdfH, -1, 1);
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &color_transparent, 0, 0); gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &color_transparent, 0, 0);
sdf_effect->get_parameter("_image").set_texture(this->_source_texture); sdf_effect->get_parameter("_image")->set_texture(this->_source_texture);
sdf_effect->get_parameter("_size").set_float2(float_t(sdfW), float_t(sdfH)); sdf_effect->get_parameter("_size")->set_float2(float_t(sdfW), float_t(sdfH));
sdf_effect->get_parameter("_sdf").set_texture(this->_sdf_texture); sdf_effect->get_parameter("_sdf")->set_texture(this->_sdf_texture);
sdf_effect->get_parameter("_threshold").set_float(this->_sdf_threshold); sdf_effect->get_parameter("_threshold")->set_float(this->_sdf_threshold);
while (gs_effect_loop(sdf_effect->get_object(), "Draw")) { while (gs_effect_loop(sdf_effect->get_object(), "Draw")) {
gs_draw_sprite(this->_sdf_texture->get_object(), 0, uint32_t(sdfW), uint32_t(sdfH)); gs_draw_sprite(this->_sdf_texture->get_object(), 0, uint32_t(sdfW), uint32_t(sdfH));
@ -793,66 +793,66 @@ void filter::sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect
gs_enable_blending(true); gs_enable_blending(true);
gs_blend_function_separate(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, GS_BLEND_ONE, GS_BLEND_ONE); gs_blend_function_separate(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, GS_BLEND_ONE, GS_BLEND_ONE);
if (this->_outer_shadow) { if (this->_outer_shadow) {
consumer_effect->get_parameter("pSDFTexture").set_texture(this->_sdf_texture); consumer_effect->get_parameter("pSDFTexture")->set_texture(this->_sdf_texture);
consumer_effect->get_parameter("pSDFThreshold").set_float(this->_sdf_threshold); consumer_effect->get_parameter("pSDFThreshold")->set_float(this->_sdf_threshold);
consumer_effect->get_parameter("pImageTexture").set_texture(this->_source_texture->get_object()); consumer_effect->get_parameter("pImageTexture")->set_texture(this->_source_texture->get_object());
consumer_effect->get_parameter("pShadowColor").set_float4(this->_outer_shadow_color); consumer_effect->get_parameter("pShadowColor")->set_float4(this->_outer_shadow_color);
consumer_effect->get_parameter("pShadowMin").set_float(this->_outer_shadow_range_min); consumer_effect->get_parameter("pShadowMin")->set_float(this->_outer_shadow_range_min);
consumer_effect->get_parameter("pShadowMax").set_float(this->_outer_shadow_range_max); consumer_effect->get_parameter("pShadowMax")->set_float(this->_outer_shadow_range_max);
consumer_effect->get_parameter("pShadowOffset") consumer_effect->get_parameter("pShadowOffset")
.set_float2(this->_outer_shadow_offset_x / float_t(baseW), ->set_float2(this->_outer_shadow_offset_x / float_t(baseW),
this->_outer_shadow_offset_y / float_t(baseH)); this->_outer_shadow_offset_y / float_t(baseH));
while (gs_effect_loop(consumer_effect->get_object(), "ShadowOuter")) { while (gs_effect_loop(consumer_effect->get_object(), "ShadowOuter")) {
gs_draw_sprite(0, 0, 1, 1); gs_draw_sprite(0, 0, 1, 1);
} }
} }
if (this->_inner_shadow) { if (this->_inner_shadow) {
consumer_effect->get_parameter("pSDFTexture").set_texture(this->_sdf_texture); consumer_effect->get_parameter("pSDFTexture")->set_texture(this->_sdf_texture);
consumer_effect->get_parameter("pSDFThreshold").set_float(this->_sdf_threshold); consumer_effect->get_parameter("pSDFThreshold")->set_float(this->_sdf_threshold);
consumer_effect->get_parameter("pImageTexture").set_texture(this->_source_texture->get_object()); consumer_effect->get_parameter("pImageTexture")->set_texture(this->_source_texture->get_object());
consumer_effect->get_parameter("pShadowColor").set_float4(this->_inner_shadow_color); consumer_effect->get_parameter("pShadowColor")->set_float4(this->_inner_shadow_color);
consumer_effect->get_parameter("pShadowMin").set_float(this->_inner_shadow_range_min); consumer_effect->get_parameter("pShadowMin")->set_float(this->_inner_shadow_range_min);
consumer_effect->get_parameter("pShadowMax").set_float(this->_inner_shadow_range_max); consumer_effect->get_parameter("pShadowMax")->set_float(this->_inner_shadow_range_max);
consumer_effect->get_parameter("pShadowOffset") consumer_effect->get_parameter("pShadowOffset")
.set_float2(this->_inner_shadow_offset_x / float_t(baseW), ->set_float2(this->_inner_shadow_offset_x / float_t(baseW),
this->_inner_shadow_offset_y / float_t(baseH)); this->_inner_shadow_offset_y / float_t(baseH));
while (gs_effect_loop(consumer_effect->get_object(), "ShadowInner")) { while (gs_effect_loop(consumer_effect->get_object(), "ShadowInner")) {
gs_draw_sprite(0, 0, 1, 1); gs_draw_sprite(0, 0, 1, 1);
} }
} }
if (this->_outer_glow) { if (this->_outer_glow) {
consumer_effect->get_parameter("pSDFTexture").set_texture(this->_sdf_texture); consumer_effect->get_parameter("pSDFTexture")->set_texture(this->_sdf_texture);
consumer_effect->get_parameter("pSDFThreshold").set_float(this->_sdf_threshold); consumer_effect->get_parameter("pSDFThreshold")->set_float(this->_sdf_threshold);
consumer_effect->get_parameter("pImageTexture").set_texture(this->_source_texture->get_object()); consumer_effect->get_parameter("pImageTexture")->set_texture(this->_source_texture->get_object());
consumer_effect->get_parameter("pGlowColor").set_float4(this->_outer_glow_color); consumer_effect->get_parameter("pGlowColor")->set_float4(this->_outer_glow_color);
consumer_effect->get_parameter("pGlowWidth").set_float(this->_outer_glow_width); consumer_effect->get_parameter("pGlowWidth")->set_float(this->_outer_glow_width);
consumer_effect->get_parameter("pGlowSharpness").set_float(this->_outer_glow_sharpness); consumer_effect->get_parameter("pGlowSharpness")->set_float(this->_outer_glow_sharpness);
consumer_effect->get_parameter("pGlowSharpnessInverse").set_float(this->_outer_glow_sharpness_inv); consumer_effect->get_parameter("pGlowSharpnessInverse")->set_float(this->_outer_glow_sharpness_inv);
while (gs_effect_loop(consumer_effect->get_object(), "GlowOuter")) { while (gs_effect_loop(consumer_effect->get_object(), "GlowOuter")) {
gs_draw_sprite(0, 0, 1, 1); gs_draw_sprite(0, 0, 1, 1);
} }
} }
if (this->_inner_glow) { if (this->_inner_glow) {
consumer_effect->get_parameter("pSDFTexture").set_texture(this->_sdf_texture); consumer_effect->get_parameter("pSDFTexture")->set_texture(this->_sdf_texture);
consumer_effect->get_parameter("pSDFThreshold").set_float(this->_sdf_threshold); consumer_effect->get_parameter("pSDFThreshold")->set_float(this->_sdf_threshold);
consumer_effect->get_parameter("pImageTexture").set_texture(this->_source_texture->get_object()); consumer_effect->get_parameter("pImageTexture")->set_texture(this->_source_texture->get_object());
consumer_effect->get_parameter("pGlowColor").set_float4(this->_inner_glow_color); consumer_effect->get_parameter("pGlowColor")->set_float4(this->_inner_glow_color);
consumer_effect->get_parameter("pGlowWidth").set_float(this->_inner_glow_width); consumer_effect->get_parameter("pGlowWidth")->set_float(this->_inner_glow_width);
consumer_effect->get_parameter("pGlowSharpness").set_float(this->_inner_glow_sharpness); consumer_effect->get_parameter("pGlowSharpness")->set_float(this->_inner_glow_sharpness);
consumer_effect->get_parameter("pGlowSharpnessInverse").set_float(this->_inner_glow_sharpness_inv); consumer_effect->get_parameter("pGlowSharpnessInverse")->set_float(this->_inner_glow_sharpness_inv);
while (gs_effect_loop(consumer_effect->get_object(), "GlowInner")) { while (gs_effect_loop(consumer_effect->get_object(), "GlowInner")) {
gs_draw_sprite(0, 0, 1, 1); gs_draw_sprite(0, 0, 1, 1);
} }
} }
if (this->_outline) { if (this->_outline) {
consumer_effect->get_parameter("pSDFTexture").set_texture(this->_sdf_texture); consumer_effect->get_parameter("pSDFTexture")->set_texture(this->_sdf_texture);
consumer_effect->get_parameter("pSDFThreshold").set_float(this->_sdf_threshold); consumer_effect->get_parameter("pSDFThreshold")->set_float(this->_sdf_threshold);
consumer_effect->get_parameter("pImageTexture").set_texture(this->_source_texture->get_object()); consumer_effect->get_parameter("pImageTexture")->set_texture(this->_source_texture->get_object());
consumer_effect->get_parameter("pOutlineColor").set_float4(this->_outline_color); consumer_effect->get_parameter("pOutlineColor")->set_float4(this->_outline_color);
consumer_effect->get_parameter("pOutlineWidth").set_float(this->_outline_width); consumer_effect->get_parameter("pOutlineWidth")->set_float(this->_outline_width);
consumer_effect->get_parameter("pOutlineOffset").set_float(this->_outline_offset); consumer_effect->get_parameter("pOutlineOffset")->set_float(this->_outline_offset);
consumer_effect->get_parameter("pOutlineSharpness").set_float(this->_outline_sharpness); consumer_effect->get_parameter("pOutlineSharpness")->set_float(this->_outline_sharpness);
consumer_effect->get_parameter("pOutlineSharpnessInverse").set_float(this->_outline_sharpness_inv); consumer_effect->get_parameter("pOutlineSharpnessInverse")->set_float(this->_outline_sharpness_inv);
while (gs_effect_loop(consumer_effect->get_object(), "Outline")) { while (gs_effect_loop(consumer_effect->get_object(), "Outline")) {
gs_draw_sprite(0, 0, 1, 1); gs_draw_sprite(0, 0, 1, 1);
} }

View file

@ -265,11 +265,11 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear::render()
std::shared_ptr<::gs::effect> effect = _data->get_effect(); std::shared_ptr<::gs::effect> effect = _data->get_effect();
if (effect) { if (effect) {
// Pass 1 // Pass 1
effect->get_parameter("pImage").set_texture(_input_texture); effect->get_parameter("pImage")->set_texture(_input_texture);
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), 0.f); effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), 0.f);
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size)); effect->get_parameter("pSize")->set_float(float_t(_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); effect->get_parameter("pSizeInverseMul")->set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f)));
{ {
auto op = _rendertarget2->render(uint32_t(width), uint32_t(height)); auto op = _rendertarget2->render(uint32_t(width), uint32_t(height));
@ -280,8 +280,8 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear::render()
} }
// Pass 2 // Pass 2
effect->get_parameter("pImage").set_texture(_rendertarget2->get_texture()); effect->get_parameter("pImage")->set_texture(_rendertarget2->get_texture());
effect->get_parameter("pImageTexel").set_float2(0., float_t(1.f / height)); effect->get_parameter("pImageTexel")->set_float2(0., float_t(1.f / height));
{ {
auto op = _rendertarget->render(uint32_t(width), uint32_t(height)); auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
@ -341,12 +341,12 @@ std::shared_ptr<::gs::texture> gfx::blur::box_linear_directional::render()
// One Pass Blur // One Pass Blur
std::shared_ptr<::gs::effect> effect = _data->get_effect(); std::shared_ptr<::gs::effect> effect = _data->get_effect();
if (effect) { if (effect) {
effect->get_parameter("pImage").set_texture(_input_texture); effect->get_parameter("pImage")->set_texture(_input_texture);
effect->get_parameter("pImageTexel") effect->get_parameter("pImageTexel")
.set_float2(float_t(1. / width * cos(_angle)), float_t(1.f / height * sin(_angle))); ->set_float2(float_t(1. / width * cos(_angle)), float_t(1.f / height * sin(_angle)));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size)); effect->get_parameter("pSize")->set_float(float_t(_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); effect->get_parameter("pSizeInverseMul")->set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f)));
{ {
auto op = _rendertarget->render(uint32_t(width), uint32_t(height)); auto op = _rendertarget->render(uint32_t(width), uint32_t(height));

View file

@ -273,11 +273,11 @@ std::shared_ptr<::gs::texture> gfx::blur::box::render()
std::shared_ptr<::gs::effect> effect = _data->get_effect(); std::shared_ptr<::gs::effect> effect = _data->get_effect();
if (effect) { if (effect) {
// Pass 1 // Pass 1
effect->get_parameter("pImage").set_texture(_input_texture); effect->get_parameter("pImage")->set_texture(_input_texture);
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), 0.f); effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), 0.f);
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size)); effect->get_parameter("pSize")->set_float(float_t(_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); effect->get_parameter("pSizeInverseMul")->set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f)));
{ {
auto op = _rendertarget2->render(uint32_t(width), uint32_t(height)); auto op = _rendertarget2->render(uint32_t(width), uint32_t(height));
@ -288,8 +288,8 @@ std::shared_ptr<::gs::texture> gfx::blur::box::render()
} }
// Pass 2 // Pass 2
effect->get_parameter("pImage").set_texture(_rendertarget2->get_texture()); effect->get_parameter("pImage")->set_texture(_rendertarget2->get_texture());
effect->get_parameter("pImageTexel").set_float2(0.f, float_t(1.f / height)); effect->get_parameter("pImageTexel")->set_float2(0.f, float_t(1.f / height));
{ {
auto op = _rendertarget->render(uint32_t(width), uint32_t(height)); auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
@ -349,12 +349,12 @@ std::shared_ptr<::gs::texture> gfx::blur::box_directional::render()
// One Pass Blur // One Pass Blur
std::shared_ptr<::gs::effect> effect = _data->get_effect(); std::shared_ptr<::gs::effect> effect = _data->get_effect();
if (effect) { if (effect) {
effect->get_parameter("pImage").set_texture(_input_texture); effect->get_parameter("pImage")->set_texture(_input_texture);
effect->get_parameter("pImageTexel") effect->get_parameter("pImageTexel")
.set_float2(float_t(1. / width * cos(_angle)), float_t(1.f / height * sin(_angle))); ->set_float2(float_t(1. / width * cos(_angle)), float_t(1.f / height * sin(_angle)));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size)); effect->get_parameter("pSize")->set_float(float_t(_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); effect->get_parameter("pSizeInverseMul")->set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f)));
{ {
auto op = _rendertarget->render(uint32_t(width), uint32_t(height)); auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
@ -419,13 +419,13 @@ std::shared_ptr<::gs::texture> gfx::blur::box_rotational::render()
// One Pass Blur // One Pass Blur
std::shared_ptr<::gs::effect> effect = _data->get_effect(); std::shared_ptr<::gs::effect> effect = _data->get_effect();
if (effect) { if (effect) {
effect->get_parameter("pImage").set_texture(_input_texture); effect->get_parameter("pImage")->set_texture(_input_texture);
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), float_t(1.f / height)); effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), float_t(1.f / height));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size)); effect->get_parameter("pSize")->set_float(float_t(_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); effect->get_parameter("pSizeInverseMul")->set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f)));
effect->get_parameter("pAngle").set_float(float_t(_angle / _size)); effect->get_parameter("pAngle")->set_float(float_t(_angle / _size));
effect->get_parameter("pCenter").set_float2(float_t(_center.first), float_t(_center.second)); effect->get_parameter("pCenter")->set_float2(float_t(_center.first), float_t(_center.second));
{ {
auto op = _rendertarget->render(uint32_t(width), uint32_t(height)); auto op = _rendertarget->render(uint32_t(width), uint32_t(height));
@ -480,12 +480,12 @@ std::shared_ptr<::gs::texture> gfx::blur::box_zoom::render()
// One Pass Blur // One Pass Blur
std::shared_ptr<::gs::effect> effect = _data->get_effect(); std::shared_ptr<::gs::effect> effect = _data->get_effect();
if (effect) { if (effect) {
effect->get_parameter("pImage").set_texture(_input_texture); effect->get_parameter("pImage")->set_texture(_input_texture);
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), float_t(1.f / height)); effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), float_t(1.f / height));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size)); effect->get_parameter("pSize")->set_float(float_t(_size));
effect->get_parameter("pSizeInverseMul").set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f))); effect->get_parameter("pSizeInverseMul")->set_float(float_t(1.0f / (float_t(_size) * 2.0f + 1.0f)));
effect->get_parameter("pCenter").set_float2(float_t(_center.first), float_t(_center.second)); effect->get_parameter("pCenter")->set_float2(float_t(_center.first), float_t(_center.second));
{ {
auto op = _rendertarget->render(uint32_t(width), uint32_t(height)); auto op = _rendertarget->render(uint32_t(width), uint32_t(height));

View file

@ -263,10 +263,10 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
} }
// Apply // Apply
effect->get_parameter("pImage").set_texture(tex_cur); effect->get_parameter("pImage")->set_texture(tex_cur);
effect->get_parameter("pImageSize").set_float2(float_t(width), float_t(height)); effect->get_parameter("pImageSize")->set_float2(float_t(width), float_t(height));
effect->get_parameter("pImageTexel").set_float2(1.0f / width, 1.0f / height); effect->get_parameter("pImageTexel")->set_float2(1.0f / width, 1.0f / height);
effect->get_parameter("pImageHalfTexel").set_float2(0.5f / width, 0.5f / height); effect->get_parameter("pImageHalfTexel")->set_float2(0.5f / width, 0.5f / height);
{ {
auto op = _rendertargets[n]->render(width, height); auto op = _rendertargets[n]->render(width, height);
@ -287,10 +287,10 @@ std::shared_ptr<::gs::texture> gfx::blur::dual_filtering::render()
uint32_t height = tex_cur->get_height(); uint32_t height = tex_cur->get_height();
// Apply // Apply
effect->get_parameter("pImage").set_texture(tex_cur); effect->get_parameter("pImage")->set_texture(tex_cur);
effect->get_parameter("pImageSize").set_float2(float_t(width), float_t(height)); effect->get_parameter("pImageSize")->set_float2(float_t(width), float_t(height));
effect->get_parameter("pImageTexel").set_float2(1.0f / width, 1.0f / height); effect->get_parameter("pImageTexel")->set_float2(1.0f / width, 1.0f / height);
effect->get_parameter("pImageHalfTexel").set_float2(0.5f / width, 0.5f / height); effect->get_parameter("pImageHalfTexel")->set_float2(0.5f / width, 0.5f / height);
// Increase Size // Increase Size
width *= 2; width *= 2;

View file

@ -316,14 +316,14 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::render()
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS); gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO); gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
effect->get_parameter("pImage").set_texture(_input_texture); effect->get_parameter("pImage")->set_texture(_input_texture);
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size)); effect->get_parameter("pSize")->set_float(float_t(_size));
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE); effect->get_parameter("pKernel")->set_float_array(kernel.data(), MAX_KERNEL_SIZE);
// First Pass // First Pass
if (_step_scale.first > std::numeric_limits<double_t>::epsilon()) { if (_step_scale.first > std::numeric_limits<double_t>::epsilon()) {
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), 0.f); effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), 0.f);
{ {
auto op = _rendertarget2->render(uint32_t(width), uint32_t(height)); auto op = _rendertarget2->render(uint32_t(width), uint32_t(height));
@ -334,12 +334,12 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear::render()
} }
std::swap(_rendertarget, _rendertarget2); std::swap(_rendertarget, _rendertarget2);
effect->get_parameter("pImage").set_texture(_rendertarget->get_texture()); effect->get_parameter("pImage")->set_texture(_rendertarget->get_texture());
} }
// Second Pass // Second Pass
if (_step_scale.second > std::numeric_limits<double_t>::epsilon()) { if (_step_scale.second > std::numeric_limits<double_t>::epsilon()) {
effect->get_parameter("pImageTexel").set_float2(0.f, float_t(1.f / height)); effect->get_parameter("pImageTexel")->set_float2(0.f, float_t(1.f / height));
{ {
auto op = _rendertarget2->render(uint32_t(width), uint32_t(height)); auto op = _rendertarget2->render(uint32_t(width), uint32_t(height));
@ -409,12 +409,12 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_linear_directional::render()
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS); gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO); gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
effect->get_parameter("pImage").set_texture(_input_texture); effect->get_parameter("pImage")->set_texture(_input_texture);
effect->get_parameter("pImageTexel") effect->get_parameter("pImageTexel")
.set_float2(float_t(1.f / width * cos(_angle)), float_t(1.f / height * sin(_angle))); ->set_float2(float_t(1.f / width * cos(_angle)), float_t(1.f / height * sin(_angle)));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size)); effect->get_parameter("pSize")->set_float(float_t(_size));
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE); effect->get_parameter("pKernel")->set_float_array(kernel.data(), MAX_KERNEL_SIZE);
// First Pass // First Pass
{ {

View file

@ -323,14 +323,14 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian::render()
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS); gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO); gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
effect->get_parameter("pImage").set_texture(_input_texture); effect->get_parameter("pImage")->set_texture(_input_texture);
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size)); effect->get_parameter("pSize")->set_float(float_t(_size));
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE); effect->get_parameter("pKernel")->set_float_array(kernel.data(), MAX_KERNEL_SIZE);
// First Pass // First Pass
if (_step_scale.first > std::numeric_limits<double_t>::epsilon()) { if (_step_scale.first > std::numeric_limits<double_t>::epsilon()) {
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), 0.f); effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), 0.f);
{ {
auto op = _rendertarget2->render(uint32_t(width), uint32_t(height)); auto op = _rendertarget2->render(uint32_t(width), uint32_t(height));
@ -341,12 +341,12 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian::render()
} }
std::swap(_rendertarget, _rendertarget2); std::swap(_rendertarget, _rendertarget2);
effect->get_parameter("pImage").set_texture(_rendertarget->get_texture()); effect->get_parameter("pImage")->set_texture(_rendertarget->get_texture());
} }
// Second Pass // Second Pass
if (_step_scale.second > std::numeric_limits<double_t>::epsilon()) { if (_step_scale.second > std::numeric_limits<double_t>::epsilon()) {
effect->get_parameter("pImageTexel").set_float2(0.f, float_t(1.f / height)); effect->get_parameter("pImageTexel")->set_float2(0.f, float_t(1.f / height));
{ {
auto op = _rendertarget2->render(uint32_t(width), uint32_t(height)); auto op = _rendertarget2->render(uint32_t(width), uint32_t(height));
@ -417,12 +417,12 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_directional::render()
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS); gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO); gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
effect->get_parameter("pImage").set_texture(_input_texture); effect->get_parameter("pImage")->set_texture(_input_texture);
effect->get_parameter("pImageTexel") effect->get_parameter("pImageTexel")
.set_float2(float_t(1.f / width * cos(m_angle)), float_t(1.f / height * sin(m_angle))); ->set_float2(float_t(1.f / width * cos(m_angle)), float_t(1.f / height * sin(m_angle)));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size)); effect->get_parameter("pSize")->set_float(float_t(_size));
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE); effect->get_parameter("pKernel")->set_float_array(kernel.data(), MAX_KERNEL_SIZE);
// First Pass // First Pass
{ {
@ -471,13 +471,13 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_rotational::render()
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS); gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO); gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
effect->get_parameter("pImage").set_texture(_input_texture); effect->get_parameter("pImage")->set_texture(_input_texture);
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), float_t(1.f / height)); effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), float_t(1.f / height));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size)); effect->get_parameter("pSize")->set_float(float_t(_size));
effect->get_parameter("pAngle").set_float(float_t(m_angle / _size)); effect->get_parameter("pAngle")->set_float(float_t(m_angle / _size));
effect->get_parameter("pCenter").set_float2(float_t(m_center.first), float_t(m_center.second)); effect->get_parameter("pCenter")->set_float2(float_t(m_center.first), float_t(m_center.second));
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE); effect->get_parameter("pKernel")->set_float_array(kernel.data(), MAX_KERNEL_SIZE);
// First Pass // First Pass
{ {
@ -548,12 +548,12 @@ std::shared_ptr<::gs::texture> gfx::blur::gaussian_zoom::render()
gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS); gs_stencil_function(GS_STENCIL_BOTH, GS_ALWAYS);
gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO); gs_stencil_op(GS_STENCIL_BOTH, GS_ZERO, GS_ZERO, GS_ZERO);
effect->get_parameter("pImage").set_texture(_input_texture); effect->get_parameter("pImage")->set_texture(_input_texture);
effect->get_parameter("pImageTexel").set_float2(float_t(1.f / width), float_t(1.f / height)); effect->get_parameter("pImageTexel")->set_float2(float_t(1.f / width), float_t(1.f / height));
effect->get_parameter("pStepScale").set_float2(float_t(_step_scale.first), float_t(_step_scale.second)); effect->get_parameter("pStepScale")->set_float2(float_t(_step_scale.first), float_t(_step_scale.second));
effect->get_parameter("pSize").set_float(float_t(_size)); effect->get_parameter("pSize")->set_float(float_t(_size));
effect->get_parameter("pCenter").set_float2(float_t(m_center.first), float_t(m_center.second)); effect->get_parameter("pCenter")->set_float2(float_t(m_center.first), float_t(m_center.second));
effect->get_parameter("pKernel").set_float_array(kernel.data(), MAX_KERNEL_SIZE); effect->get_parameter("pKernel")->set_float_array(kernel.data(), MAX_KERNEL_SIZE);
// First Pass // First Pass
{ {

View file

@ -115,51 +115,55 @@ size_t gs::effect::count_parameters()
return (size_t)gs_effect_get_num_params(_effect); return (size_t)gs_effect_get_num_params(_effect);
} }
std::list<gs::effect_parameter> gs::effect::get_parameters() std::list<std::shared_ptr<gs::effect_parameter>> gs::effect::get_parameters()
{ {
size_t num = gs_effect_get_num_params(_effect); size_t num = gs_effect_get_num_params(_effect);
std::list<gs::effect_parameter> ps; std::list<std::shared_ptr<gs::effect_parameter>> ps;
for (size_t idx = 0; idx < num; idx++) { for (size_t idx = 0; idx < num; idx++) {
ps.emplace_back(get_parameter(idx)); ps.emplace_back(get_parameter(idx));
} }
return ps; return ps;
} }
gs::effect_parameter gs::effect::get_parameter(size_t idx) std::shared_ptr<gs::effect_parameter> gs::effect::get_parameter(size_t idx)
{ {
gs_eparam_t* param = gs_effect_get_param_by_idx(_effect, idx); gs_eparam_t* param = gs_effect_get_param_by_idx(_effect, idx);
if (!param) if (!param)
throw std::invalid_argument("parameter with index not found"); return nullptr;
return effect_parameter(param); return std::make_shared<effect_parameter>(this->shared_from_this(), param);
}
std::shared_ptr<gs::effect_parameter> gs::effect::get_parameter(std::string name)
{
gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str());
if (!param)
return nullptr;
return std::make_shared<effect_parameter>(this->shared_from_this(), param);
} }
bool gs::effect::has_parameter(std::string name) bool gs::effect::has_parameter(std::string name)
{ {
gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str()); auto eprm = get_parameter(name);
return (param != nullptr); if (eprm)
return true;
return false;
} }
bool gs::effect::has_parameter(std::string name, effect_parameter::type type) bool gs::effect::has_parameter(std::string name, effect_parameter::type type)
{ {
gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str()); auto eprm = get_parameter(name);
if (param == nullptr) if (eprm)
return false; return eprm->get_type() == type;
gs::effect_parameter eprm(param); return false;
return eprm.get_type() == type;
} }
gs::effect_parameter gs::effect::get_parameter(std::string name) gs::effect_parameter::effect_parameter(std::shared_ptr<gs::effect> effect, gs_eparam_t* param)
: _effect(effect), _param(param)
{ {
gs_eparam_t* param = gs_effect_get_param_by_name(_effect, name.c_str()); if (effect)
throw std::invalid_argument("effect");
if (!param) if (!param)
throw std::invalid_argument("parameter with name not found"); throw std::invalid_argument("param");
return effect_parameter(param);
}
gs::effect_parameter::effect_parameter(gs_eparam_t* param) : _param(param)
{
if (!param)
throw std::invalid_argument("param is null");
gs_effect_get_param_info(_param, &_param_info); gs_effect_get_param_info(_param, &_param_info);
} }
@ -712,7 +716,7 @@ void gs::effect_parameter::get_string(std::string& v)
if (get_type() != type::Matrix) if (get_type() != type::Matrix)
throw std::bad_cast(); throw std::bad_cast();
size_t ptr_len = gs_effect_get_val_size(_param); size_t ptr_len = gs_effect_get_val_size(_param);
uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_val(_param)); uint8_t* ptr = static_cast<uint8_t*>(gs_effect_get_val(_param));
if (ptr) { if (ptr) {
v = std::string(ptr, ptr + ptr_len); v = std::string(ptr, ptr + ptr_len);
bfree(ptr); bfree(ptr);
@ -740,36 +744,34 @@ size_t gs::effect_parameter::count_annotations()
return gs_param_get_num_annotations(_param); return gs_param_get_num_annotations(_param);
} }
gs::effect_parameter gs::effect_parameter::get_annotation(size_t idx) std::shared_ptr<gs::effect_parameter> gs::effect_parameter::get_annotation(size_t idx)
{ {
gs_eparam_t* param = gs_param_get_annotation_by_idx(_param, idx); gs_eparam_t* param = gs_param_get_annotation_by_idx(_param, idx);
if (!param) if (!param)
throw std::invalid_argument("annotation with index not found"); return nullptr;
return effect_parameter(param); return std::make_shared<effect_parameter>(_effect, param);
} }
gs::effect_parameter gs::effect_parameter::get_annotation(std::string name) std::shared_ptr<gs::effect_parameter> gs::effect_parameter::get_annotation(std::string name)
{ {
gs_eparam_t* param = gs_param_get_annotation_by_name(_param, name.c_str()); gs_eparam_t* param = gs_param_get_annotation_by_name(_param, name.c_str());
if (!param) if (!param)
throw std::invalid_argument("annotation with name not found"); return nullptr;
return effect_parameter(param); return std::make_shared<effect_parameter>(_effect, param);
} }
bool gs::effect_parameter::has_annotation(std::string name) bool gs::effect_parameter::has_annotation(std::string name)
{ {
gs_eparam_t* param = gs_param_get_annotation_by_name(_param, name.c_str()); auto eprm = get_annotation(name);
if (!param) if (eprm)
return false; return true;
return true; return false;
} }
bool gs::effect_parameter::has_annotation(std::string name, effect_parameter::type type) bool gs::effect_parameter::has_annotation(std::string name, effect_parameter::type type)
{ {
try { auto eprm = get_annotation(name);
auto eprm = get_annotation(name); if (eprm)
return eprm.get_type() == type; return eprm->get_type() == type;
} catch (...) { return false;
return false;
}
} }

View file

@ -40,7 +40,10 @@
#endif #endif
namespace gs { namespace gs {
class effect;
class effect_parameter { class effect_parameter {
std::shared_ptr<::gs::effect> _effect;
gs_eparam_t* _param; gs_eparam_t* _param;
gs_effect_param_info _param_info; gs_effect_param_info _param_info;
@ -62,7 +65,7 @@ namespace gs {
}; };
public: public:
effect_parameter(gs_eparam_t* param); effect_parameter(std::shared_ptr<gs::effect> effect, gs_eparam_t* param);
std::string get_name(); std::string get_name();
type get_type(); type get_type();
@ -132,14 +135,14 @@ namespace gs {
void get_string(std::string& v); void get_string(std::string& v);
void get_default_string(std::string& v); void get_default_string(std::string& v);
size_t count_annotations(); size_t count_annotations();
effect_parameter get_annotation(size_t idx); std::shared_ptr<effect_parameter> get_annotation(size_t idx);
effect_parameter get_annotation(std::string name); std::shared_ptr<effect_parameter> get_annotation(std::string name);
bool has_annotation(std::string name); bool has_annotation(std::string name);
bool has_annotation(std::string name, effect_parameter::type type); bool has_annotation(std::string name, effect_parameter::type type);
}; };
class effect { class effect : std::enable_shared_from_this<::gs::effect> {
protected: protected:
gs_effect_t* _effect; gs_effect_t* _effect;
@ -151,11 +154,11 @@ namespace gs {
gs_effect_t* get_object(); gs_effect_t* get_object();
size_t count_parameters(); size_t count_parameters();
std::list<effect_parameter> get_parameters(); std::list<std::shared_ptr<effect_parameter>> get_parameters();
effect_parameter get_parameter(size_t idx); std::shared_ptr<effect_parameter> get_parameter(size_t idx);
effect_parameter get_parameter(std::string name); std::shared_ptr<effect_parameter> get_parameter(std::string name);
bool has_parameter(std::string name); bool has_parameter(std::string name);
bool has_parameter(std::string name, effect_parameter::type type); bool has_parameter(std::string name, effect_parameter::type type);
}; };
} // namespace gs } // namespace gs

View file

@ -252,10 +252,10 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
vec4_zero(&black); vec4_zero(&black);
gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &black, 0, 0); gs_clear(GS_CLEAR_COLOR | GS_CLEAR_DEPTH, &black, 0, 0);
_effect->get_parameter("image").set_texture(target); _effect->get_parameter("image")->set_texture(target);
_effect->get_parameter("level").set_int(int32_t(mip - 1)); _effect->get_parameter("level")->set_int(int32_t(mip - 1));
_effect->get_parameter("imageTexel").set_float2(texel_width, texel_height); _effect->get_parameter("imageTexel")->set_float2(texel_width, texel_height);
_effect->get_parameter("strength").set_float(strength); _effect->get_parameter("strength")->set_float(strength);
while (gs_effect_loop(_effect->get_object(), technique.c_str())) { while (gs_effect_loop(_effect->get_object(), technique.c_str())) {
gs_draw(gs_draw_mode::GS_TRIS, 0, _vb->size()); gs_draw(gs_draw_mode::GS_TRIS, 0, _vb->size());