mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-12-28 18:41:14 +00:00
project: Remove unused content
This commit is contained in:
parent
21eef998ec
commit
8e9e39a88e
5 changed files with 7 additions and 734 deletions
|
@ -234,7 +234,6 @@ SET(PROJECT_DATA_EFFECTS
|
|||
"${PROJECT_SOURCE_DIR}/data/effects/sdf-shadow.effect"
|
||||
|
||||
# Blur
|
||||
"${PROJECT_SOURCE_DIR}/data/effects/blur.effect"
|
||||
"${PROJECT_SOURCE_DIR}/data/effects/blur/box.effect"
|
||||
"${PROJECT_SOURCE_DIR}/data/effects/blur/box-linear.effect"
|
||||
"${PROJECT_SOURCE_DIR}/data/effects/blur/dual-filtering.effect"
|
||||
|
@ -304,6 +303,7 @@ SET(PROJECT_PRIVATE_SOURCE
|
|||
"${PROJECT_SOURCE_DIR}/source/gfx/blur/gfx-blur-gaussian.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/gfx/blur/gfx-blur-gaussian-linear.hpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/gfx/blur/gfx-blur-gaussian-linear.cpp"
|
||||
|
||||
# OBS
|
||||
"${PROJECT_SOURCE_DIR}/source/obs/gs/gs-helper.hpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/obs/gs/gs-helper.cpp"
|
||||
|
@ -338,18 +338,16 @@ SET(PROJECT_PRIVATE_SOURCE
|
|||
"${PROJECT_SOURCE_DIR}/source/sources/source-mirror.cpp"
|
||||
|
||||
# Filters
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-displacement.hpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-displacement.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-blur.hpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-blur.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-sdf-effects.hpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-sdf-effects.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-shape.hpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-shape.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-transform.hpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-transform.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-custom-shader.hpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-custom-shader.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-displacement.hpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-displacement.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-sdf-effects.hpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-sdf-effects.cpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-transform.hpp"
|
||||
"${PROJECT_SOURCE_DIR}/source/filters/filter-transform.cpp"
|
||||
|
||||
# Transitions
|
||||
)
|
||||
|
|
|
@ -1,269 +0,0 @@
|
|||
// OBS Default
|
||||
uniform float4x4 ViewProj;
|
||||
|
||||
// Settings (Shared)
|
||||
uniform texture2d u_image;
|
||||
uniform float2 u_imageSize;
|
||||
uniform float2 u_imageTexel;
|
||||
uniform int u_radius;
|
||||
uniform int u_diameter;
|
||||
uniform float2 u_texelDelta;
|
||||
|
||||
// Kernel Settings
|
||||
uniform float4 kernel[8]; // max kernel radius 31+center.
|
||||
|
||||
// Bilateral Settings
|
||||
uniform float bilateralSmoothing;
|
||||
uniform float bilateralSharpness;
|
||||
|
||||
// Data
|
||||
sampler_state pointSampler {
|
||||
Filter = Point;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
MinLOD = 0;
|
||||
MaxLOD = 0;
|
||||
};
|
||||
|
||||
sampler_state linearSampler {
|
||||
Filter = Linear;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
MinLOD = 0;
|
||||
MaxLOD = 0;
|
||||
};
|
||||
|
||||
struct VertDataIn {
|
||||
float4 pos : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct VertDataOut {
|
||||
float4 pos : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
VertDataOut VSDefault(VertDataIn vtx)
|
||||
{
|
||||
VertDataOut vert_out;
|
||||
vert_out.pos = mul(float4(vtx.pos.xyz, 1.0), ViewProj);
|
||||
vert_out.uv = vtx.uv;
|
||||
return vert_out;
|
||||
}
|
||||
|
||||
/// Utility
|
||||
float GetKernelAt(int i) {
|
||||
return ((float[4])(kernel[floor(i/4)]))[i%4];
|
||||
}
|
||||
|
||||
/// Blur: Box
|
||||
float4 PSBoxBlur(VertDataOut vtx) : TARGET {
|
||||
float4 origin = u_image.SampleLevel(pointSampler, vtx.uv, 0);
|
||||
|
||||
float4 final = origin;
|
||||
for (int k = 1; k <= u_radius; k++) {
|
||||
final += u_image.SampleLevel(pointSampler, vtx.uv + (u_texelDelta * k), 0);
|
||||
final += u_image.SampleLevel(pointSampler, vtx.uv - (u_texelDelta * k), 0);
|
||||
}
|
||||
final /= u_diameter;
|
||||
|
||||
return final;
|
||||
}
|
||||
|
||||
technique Box
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_shader = VSDefault(vtx);
|
||||
pixel_shader = PSBoxBlur(vtx);
|
||||
}
|
||||
}
|
||||
|
||||
/// Blur: Box (Linear Optimized)
|
||||
// By abusing Linear sampling we can reduce the necessary samples, halving the total samples.
|
||||
float4 PSBoxBlurLinear(VertDataOut vtx) : TARGET {
|
||||
// Radius 4 (Even):
|
||||
// [-4, -3, -2, -1, 0, +1, +2, +3, +4]
|
||||
// ^-S-^ ^-S-^ S ^-S-^ ^-S-^
|
||||
// Total Samples: 5 (n+1)
|
||||
|
||||
// Radius 3 (Odd):
|
||||
// [-3, -2, -1, 0, +1, +2, +3]
|
||||
// ^-S-^ ^-S-^ S ^-S-^
|
||||
// Total Samples: 4 (n)
|
||||
|
||||
// Radius 2 (Even):
|
||||
// [-2, -1, 0, +1, +2]
|
||||
// ^-S-^ S ^-S-^
|
||||
|
||||
float4 final = float4(0, 0, 0, 0);
|
||||
float2 halfTexelDelta = u_texelDelta / 2.0;
|
||||
if (u_radius % 2 == 0) {
|
||||
// Even Numbers require the origin sample in the middle.
|
||||
float4 origin = u_image.SampleLevel(pointSampler, vtx.uv, 0);
|
||||
final = origin;
|
||||
for (int k = 1; k <= u_radius; k+=2) {
|
||||
float2 offset = k * u_texelDelta + halfTexelDelta;
|
||||
final += u_image.SampleLevel(linearSampler, vtx.uv + offset, 0) * 2;
|
||||
final += u_image.SampleLevel(linearSampler, vtx.uv - offset, 0) * 2;
|
||||
}
|
||||
} else {
|
||||
// Odd Numbers put the origin sample in another location.
|
||||
float4 origin = u_image.SampleLevel(pointSampler, vtx.uv + u_texelDelta, 0);
|
||||
float4 group = u_image.SampleLevel(linearSampler, vtx.uv - halfTexelDelta, 0);
|
||||
final = origin + group * 2;
|
||||
|
||||
for (int k = 2; k <= u_radius; k+=2) {
|
||||
float2 offset = k * u_texelDelta + halfTexelDelta;
|
||||
final += u_image.SampleLevel(linearSampler, vtx.uv + offset, 0) * 2;
|
||||
final += u_image.SampleLevel(linearSampler, vtx.uv - offset, 0) * 2;
|
||||
}
|
||||
}
|
||||
final /= u_diameter;
|
||||
|
||||
return final;
|
||||
}
|
||||
|
||||
technique BoxLinear
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_shader = VSDefault(vtx);
|
||||
pixel_shader = PSBoxBlurLinear(vtx);
|
||||
}
|
||||
}
|
||||
|
||||
/// Blur: Gaussian
|
||||
float4 PSGaussianBlur(VertDataOut vtx) : TARGET {
|
||||
float2 uvOffset = float2(0, 0);
|
||||
float4 final = u_image.SampleLevel(pointSampler, vtx.uv, 0)
|
||||
* GetKernelAt(0);
|
||||
for (int k = 1; k <= u_radius; k++) {
|
||||
uvOffset += u_texelDelta;
|
||||
float l_g = GetKernelAt(k);
|
||||
float4 l_p = u_image.SampleLevel(pointSampler, vtx.uv + uvOffset, 0);
|
||||
float4 l_n = u_image.SampleLevel(pointSampler, vtx.uv - uvOffset, 0);
|
||||
final += (l_p + l_n) * l_g;
|
||||
}
|
||||
return final;
|
||||
}
|
||||
|
||||
technique Gaussian
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_shader = VSDefault(vtx);
|
||||
pixel_shader = PSGaussianBlur(vtx);
|
||||
}
|
||||
}
|
||||
|
||||
/// Blur: Gaussian Linear
|
||||
float4 PSGaussianLinearBlur(VertDataOut vtx) : TARGET {
|
||||
// Origin sample must always be sampled.
|
||||
// Even, Odd must decide differently than Box Blur
|
||||
|
||||
// Radius 5 (Odd):
|
||||
// [-5, -4, -3, -2, -1, 0, +1, +2, +3, +4, +5]
|
||||
// S ^-S-^ ^-S-^ S ^-S-^ ^-S-^ S
|
||||
// S ^-S-^ ^-S-^ S ^-S-^ ^-S-^ S
|
||||
// Total Samples: 7 (n+2)
|
||||
|
||||
// Radius 4 (Even):
|
||||
// [-4, -3, -2, -1, 0, +1, +2, +3, +4]
|
||||
// ^-S-^ ^-S-^ S ^-S-^ ^-S-^
|
||||
// Total Samples: 5 (n+1)
|
||||
|
||||
// Radius 3 (Odd):
|
||||
// [-3, -2, -1, 0, +1, +2, +3]
|
||||
// S ^-S-^ S ^-S-^ S
|
||||
// Total Samples: 5 (n+2)
|
||||
|
||||
// Radius 2 (Even):
|
||||
// [-2, -1, 0, +1, +2]
|
||||
// ^-S-^ S ^-S-^
|
||||
// Total Samples: 3 (n+1)
|
||||
|
||||
float4 origin = u_image.SampleLevel(pointSampler, vtx.uv, 0);
|
||||
float4 final = origin * GetKernelAt(0);
|
||||
float2 halfTexelDelta = u_texelDelta / 2.0;
|
||||
|
||||
for (int k = 1; k < u_radius; k+=2) {
|
||||
float2 offset = k * u_texelDelta + halfTexelDelta;
|
||||
float l_g0 = GetKernelAt(k);
|
||||
float l_g1 = GetKernelAt(k +1);
|
||||
float4 l_p = u_image.SampleLevel(linearSampler, vtx.uv + offset, 0);
|
||||
float4 l_n = u_image.SampleLevel(linearSampler, vtx.uv - offset, 0);
|
||||
final += (l_p + l_n) * l_g0;
|
||||
final += (l_p + l_n) * l_g1;
|
||||
}
|
||||
|
||||
if (u_radius % 2 == 1) {
|
||||
// Odd numbers require treatment of ends.
|
||||
float4 left = u_image.SampleLevel(pointSampler, vtx.uv + u_texelDelta * u_radius, 0);
|
||||
float4 right = u_image.SampleLevel(pointSampler, vtx.uv - u_texelDelta * u_radius, 0);
|
||||
float krn = GetKernelAt(u_radius);
|
||||
final += (left + right) * krn;
|
||||
}
|
||||
|
||||
return final;
|
||||
}
|
||||
|
||||
technique GaussianLinear
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_shader = VSDefault(vtx);
|
||||
pixel_shader = PSGaussianLinearBlur(vtx);
|
||||
}
|
||||
}
|
||||
|
||||
/// Blur: Bilateral
|
||||
float Bilateral(float x, float sigma) {
|
||||
return 0.39894 * exp(-0.5 * (x*x) / (sigma*sigma)) / sigma;
|
||||
}
|
||||
|
||||
float Bilateral3(float3 v, float sigma) {
|
||||
// First part is Bilateral function (1.0 / (o * sqrt(2.0 * pivalue))) with o = 1
|
||||
return 0.39894 * exp(-0.5 * dot(v,v) / (sigma*sigma)) / sigma;
|
||||
}
|
||||
|
||||
float4 PSBilateralBlur(VertDataOut vtx) : TARGET {
|
||||
float4 origin = u_image.SampleLevel(pointSampler, vtx.uv, 0);
|
||||
float2 uvOffset = float2(0, 0);
|
||||
|
||||
float Z = 0.0;
|
||||
float bZ = 1.0 / Bilateral(0.0, bilateralSharpness);
|
||||
float3 color = float3(0, 0, 0);
|
||||
for (int k = 1; k <= u_radius; k++) {
|
||||
uvOffset += u_texelDelta;
|
||||
|
||||
// Bilateral Kernel
|
||||
float bKernel = Bilateral(abs(k), bilateralSmoothing);
|
||||
bKernel *= bKernel;
|
||||
float bZKernel = bZ * bKernel;
|
||||
|
||||
// Sample Color
|
||||
float3 l_p = u_image.SampleLevel(pointSampler, vtx.uv + uvOffset, 0).rgb;
|
||||
float3 l_n = u_image.SampleLevel(pointSampler, vtx.uv - uvOffset, 0).rgb;
|
||||
|
||||
// Bilateral Stuff
|
||||
float l_factor_p = Bilateral3(l_p - origin.rgb, bilateralSharpness) * bZKernel;
|
||||
float l_factor_n = Bilateral3(l_n - origin.rgb, bilateralSharpness) * bZKernel;
|
||||
Z = Z + l_factor_p + l_factor_n;
|
||||
|
||||
// Store Color
|
||||
color += l_p * l_factor_p;
|
||||
color += l_n * l_factor_n;
|
||||
}
|
||||
|
||||
return float4(color.rgb / Z, origin.a);
|
||||
}
|
||||
|
||||
technique Bilateral
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_shader = VSDefault(vtx);
|
||||
pixel_shader = PSBilateralBlur(vtx);
|
||||
}
|
||||
}
|
|
@ -50,11 +50,6 @@ CustomShader.Texture.Type.Source="Source"
|
|||
Filter.Blur="Blur"
|
||||
Filter.Blur.Type="Type"
|
||||
Filter.Blur.Type.Description="The type of blur to apply."
|
||||
Filter.Blur.Type.Box="Box"
|
||||
Filter.Blur.Type.BoxLinear="Box Linear"
|
||||
Filter.Blur.Type.Gaussian="Gaussian"
|
||||
Filter.Blur.Type.GaussianLinear="Gaussian Linear"
|
||||
Filter.Blur.Type.Bilateral="Bilateral"
|
||||
Filter.Blur.Subtype="Subtype"
|
||||
Filter.Blur.Subtype.Description="The way this blur should be applied."
|
||||
Filter.Blur.Size="Size"
|
||||
|
@ -137,15 +132,6 @@ Filter.SDFEffects.Shadow.Outer.Alpha="Outer Alpha"
|
|||
Filter.SDFEffects.SDF.Scale="SDF Texture Scale"
|
||||
Filter.SDFEffects.SDF.Scale.Description="Percentage to scale the SDF Texture Size by, relative to the Source Size.\nA higher value results in better quality, but slower updates,\n while lower values result in faster updates, but lower quality."
|
||||
|
||||
# Filter - Shape
|
||||
Filter.Shape="Shape"
|
||||
Filter.Shape.Loop="Repeat last Point"
|
||||
Filter.Shape.Points="Points"
|
||||
Filter.Shape.Point.X="Point %llu X"
|
||||
Filter.Shape.Point.Y="Point %llu Y"
|
||||
Filter.Shape.Point.U="Point %llu U"
|
||||
Filter.Shape.Point.V="Point %llu V"
|
||||
|
||||
# Filter - Transform
|
||||
Filter.Transform="3D Transform"
|
||||
Filter.Transform.Camera="Camera"
|
||||
|
|
|
@ -1,356 +0,0 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "filter-shape.hpp"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "strings.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
// OBS
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4201)
|
||||
#endif
|
||||
#include <graphics/graphics.h>
|
||||
#include <graphics/matrix4.h>
|
||||
#include <util/platform.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// Initializer & Finalizer
|
||||
static filter::Shape* filterShapeInstance;
|
||||
INITIALIZER(FilterShapeInit)
|
||||
{
|
||||
initializerFunctions.push_back([] { filterShapeInstance = new filter::Shape(); });
|
||||
finalizerFunctions.push_back([] { delete filterShapeInstance; });
|
||||
}
|
||||
|
||||
typedef std::pair<uint32_t, std::string> cacheKey;
|
||||
typedef std::pair<std::string, std::string> cacheValue;
|
||||
static std::map<cacheKey, cacheValue> cache;
|
||||
static const uint32_t minimumPoints = 3;
|
||||
static const uint32_t maximumPoints = 16;
|
||||
|
||||
static void initialize()
|
||||
{
|
||||
if (cache.size() != 0)
|
||||
return;
|
||||
for (uint32_t point = 0; point < maximumPoints; point++) {
|
||||
std::vector<char> handle(1024), name(1024);
|
||||
const char* vals[] = {P_SHAPE_POINT_X, P_SHAPE_POINT_Y, P_SHAPE_POINT_U, P_SHAPE_POINT_V};
|
||||
for (const char* v : vals) {
|
||||
snprintf(handle.data(), handle.size(), "%s.%" PRIu32, v, point);
|
||||
snprintf(name.data(), name.size(), P_TRANSLATE(v), point);
|
||||
cacheValue x = std::make_pair(std::string(handle.data()), std::string(name.data()));
|
||||
cache.insert(std::make_pair(std::make_pair(point, v), x));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filter::Shape::Shape()
|
||||
{
|
||||
return; // Disabled for the time being. 3D Transform is better for this.
|
||||
memset(&sourceInfo, 0, sizeof(obs_source_info));
|
||||
sourceInfo.id = "obs-stream-effects-filter-shape";
|
||||
sourceInfo.type = OBS_SOURCE_TYPE_FILTER;
|
||||
sourceInfo.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_DEPRECATED;
|
||||
sourceInfo.get_name = get_name;
|
||||
sourceInfo.get_defaults = get_defaults;
|
||||
sourceInfo.get_properties = get_properties;
|
||||
|
||||
sourceInfo.create = create;
|
||||
sourceInfo.destroy = destroy;
|
||||
sourceInfo.update = update;
|
||||
sourceInfo.activate = activate;
|
||||
sourceInfo.deactivate = deactivate;
|
||||
sourceInfo.show = show;
|
||||
sourceInfo.hide = hide;
|
||||
sourceInfo.video_tick = video_tick;
|
||||
sourceInfo.video_render = video_render;
|
||||
|
||||
obs_register_source(&sourceInfo);
|
||||
|
||||
initialize();
|
||||
}
|
||||
|
||||
filter::Shape::~Shape() {}
|
||||
|
||||
const char* filter::Shape::get_name(void*)
|
||||
{
|
||||
return "Shape";
|
||||
}
|
||||
|
||||
void filter::Shape::get_defaults(obs_data_t* data)
|
||||
{
|
||||
obs_data_set_default_bool(data, P_SHAPE_LOOP, true);
|
||||
obs_data_set_default_int(data, P_SHAPE_POINTS, minimumPoints);
|
||||
|
||||
for (uint32_t point = 0; point < maximumPoints; point++) {
|
||||
const char* vals[] = {P_SHAPE_POINT_X, P_SHAPE_POINT_Y, P_SHAPE_POINT_U, P_SHAPE_POINT_V};
|
||||
for (const char* v : vals) {
|
||||
auto strings = cache.find(std::make_pair(point, v));
|
||||
if (strings != cache.end()) {
|
||||
obs_data_set_default_double(data, strings->second.first.c_str(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
obs_properties_t* filter::Shape::get_properties(void*)
|
||||
{
|
||||
obs_properties_t* pr = obs_properties_create();
|
||||
obs_property_t* p = NULL;
|
||||
|
||||
p = obs_properties_add_bool(pr, P_SHAPE_LOOP, P_TRANSLATE(P_SHAPE_LOOP));
|
||||
obs_property_set_long_description(p, P_DESC(P_SHAPE_LOOP));
|
||||
|
||||
p = obs_properties_add_list(pr, P_SHAPE_MODE, P_TRANSLATE(P_SHAPE_MODE), obs_combo_type::OBS_COMBO_TYPE_LIST,
|
||||
obs_combo_format::OBS_COMBO_FORMAT_INT);
|
||||
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SHAPE_MODE)));
|
||||
obs_property_list_add_int(p, P_TRANSLATE(P_SHAPE_MODE_TRIS), GS_TRIS);
|
||||
obs_property_list_add_int(p, P_TRANSLATE(P_SHAPE_MODE_TRISTRIP), GS_TRISTRIP);
|
||||
|
||||
p = obs_properties_add_int_slider(pr, P_SHAPE_POINTS, P_TRANSLATE(P_SHAPE_POINTS), minimumPoints, maximumPoints, 1);
|
||||
obs_property_set_long_description(p, P_DESC(P_SHAPE_POINTS));
|
||||
obs_property_set_modified_callback(p, modified_properties);
|
||||
|
||||
for (uint32_t point = 0; point < maximumPoints; point++) {
|
||||
std::pair<const char*, const char*> vals[] = {{P_SHAPE_POINT_X, P_TRANSLATE(P_DESC(P_SHAPE_POINT_X))},
|
||||
{P_SHAPE_POINT_Y, P_TRANSLATE(P_DESC(P_SHAPE_POINT_Y))},
|
||||
{P_SHAPE_POINT_U, P_TRANSLATE(P_DESC(P_SHAPE_POINT_U))},
|
||||
{P_SHAPE_POINT_V, P_TRANSLATE(P_DESC(P_SHAPE_POINT_V))}};
|
||||
for (std::pair<const char*, const char*> v : vals) {
|
||||
auto strings = cache.find(std::make_pair(point, v.first));
|
||||
if (strings != cache.end()) {
|
||||
p = obs_properties_add_float_slider(pr, strings->second.first.c_str(), strings->second.second.c_str(),
|
||||
0, 100.0, 0.01);
|
||||
obs_property_set_long_description(p, v.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pr;
|
||||
}
|
||||
|
||||
bool filter::Shape::modified_properties(obs_properties_t* pr, obs_property_t*, obs_data_t* data)
|
||||
{
|
||||
uint32_t points = (uint32_t)obs_data_get_int(data, P_SHAPE_POINTS);
|
||||
for (uint32_t point = 0; point < maximumPoints; point++) {
|
||||
bool visible = point < points ? true : false;
|
||||
const char* vals[] = {P_SHAPE_POINT_X, P_SHAPE_POINT_Y, P_SHAPE_POINT_U, P_SHAPE_POINT_V};
|
||||
for (const char* v : vals) {
|
||||
auto strings = cache.find(std::make_pair(point, v));
|
||||
if (strings != cache.end()) {
|
||||
obs_property_set_visible(obs_properties_get(pr, strings->second.first.c_str()), visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void* filter::Shape::create(obs_data_t* data, obs_source_t* source)
|
||||
{
|
||||
return new Instance(data, source);
|
||||
}
|
||||
|
||||
void filter::Shape::destroy(void* ptr)
|
||||
{
|
||||
delete reinterpret_cast<Instance*>(ptr);
|
||||
}
|
||||
|
||||
uint32_t filter::Shape::get_width(void* ptr)
|
||||
{
|
||||
return reinterpret_cast<Instance*>(ptr)->get_width();
|
||||
}
|
||||
|
||||
uint32_t filter::Shape::get_height(void* ptr)
|
||||
{
|
||||
return reinterpret_cast<Instance*>(ptr)->get_height();
|
||||
}
|
||||
|
||||
void filter::Shape::update(void* ptr, obs_data_t* data)
|
||||
{
|
||||
reinterpret_cast<Instance*>(ptr)->update(data);
|
||||
}
|
||||
|
||||
void filter::Shape::activate(void* ptr)
|
||||
{
|
||||
reinterpret_cast<Instance*>(ptr)->activate();
|
||||
}
|
||||
|
||||
void filter::Shape::deactivate(void* ptr)
|
||||
{
|
||||
reinterpret_cast<Instance*>(ptr)->deactivate();
|
||||
}
|
||||
|
||||
void filter::Shape::show(void* ptr)
|
||||
{
|
||||
reinterpret_cast<Instance*>(ptr)->show();
|
||||
}
|
||||
|
||||
void filter::Shape::hide(void* ptr)
|
||||
{
|
||||
reinterpret_cast<Instance*>(ptr)->hide();
|
||||
}
|
||||
|
||||
void filter::Shape::video_tick(void* ptr, float time)
|
||||
{
|
||||
reinterpret_cast<Instance*>(ptr)->video_tick(time);
|
||||
}
|
||||
|
||||
void filter::Shape::video_render(void* ptr, gs_effect_t* effect)
|
||||
{
|
||||
reinterpret_cast<Instance*>(ptr)->video_render(effect);
|
||||
}
|
||||
|
||||
filter::Shape::Instance::Instance(obs_data_t* data, obs_source_t* context) : context(context)
|
||||
{
|
||||
obs_enter_graphics();
|
||||
m_vertexHelper = new gs::vertex_buffer(maximumPoints);
|
||||
m_vertexHelper->set_uv_layers(1);
|
||||
m_texRender = gs_texrender_create(GS_RGBA, GS_Z32F);
|
||||
obs_leave_graphics();
|
||||
|
||||
update(data);
|
||||
}
|
||||
|
||||
filter::Shape::Instance::~Instance()
|
||||
{
|
||||
obs_enter_graphics();
|
||||
delete m_vertexHelper;
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
void filter::Shape::Instance::update(obs_data_t* data)
|
||||
{
|
||||
uint32_t points = (uint32_t)obs_data_get_int(data, P_SHAPE_POINTS);
|
||||
m_vertexHelper->resize(points);
|
||||
for (uint32_t point = 0; point < points; point++) {
|
||||
gs::vertex v = m_vertexHelper->at(point);
|
||||
{
|
||||
auto strings = cache.find(std::make_pair(point, P_SHAPE_POINT_X));
|
||||
if (strings != cache.end()) {
|
||||
v.position->x = (float)(obs_data_get_double(data, strings->second.first.c_str()) / 100.0);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto strings = cache.find(std::make_pair(point, P_SHAPE_POINT_Y));
|
||||
if (strings != cache.end()) {
|
||||
v.position->y = (float)(obs_data_get_double(data, strings->second.first.c_str()) / 100.0);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto strings = cache.find(std::make_pair(point, P_SHAPE_POINT_U));
|
||||
if (strings != cache.end()) {
|
||||
v.uv[0]->x = (float)(obs_data_get_double(data, strings->second.first.c_str()) / 100.0);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto strings = cache.find(std::make_pair(point, P_SHAPE_POINT_V));
|
||||
if (strings != cache.end()) {
|
||||
v.uv[0]->y = (float)(obs_data_get_double(data, strings->second.first.c_str()) / 100.0);
|
||||
}
|
||||
}
|
||||
*v.color = 0xFFFFFFFF;
|
||||
v.position->z = 0.0f;
|
||||
}
|
||||
drawmode = (gs_draw_mode)obs_data_get_int(data, P_SHAPE_MODE);
|
||||
obs_enter_graphics();
|
||||
m_vertexBuffer = m_vertexHelper->update();
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
uint32_t filter::Shape::Instance::get_width()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t filter::Shape::Instance::get_height()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void filter::Shape::Instance::activate() {}
|
||||
|
||||
void filter::Shape::Instance::deactivate() {}
|
||||
|
||||
void filter::Shape::Instance::show() {}
|
||||
|
||||
void filter::Shape::Instance::hide() {}
|
||||
|
||||
void filter::Shape::Instance::video_tick(float) {}
|
||||
|
||||
void filter::Shape::Instance::video_render(gs_effect_t* effect)
|
||||
{
|
||||
obs_source_t* parent = obs_filter_get_parent(context);
|
||||
obs_source_t* target = obs_filter_get_target(context);
|
||||
uint32_t baseW = obs_source_get_base_width(target), baseH = obs_source_get_base_height(target);
|
||||
|
||||
// Skip rendering if our target, parent or context is not valid.
|
||||
if (!target || !parent || !context || !m_vertexBuffer || !m_texRender || !baseW || !baseH) {
|
||||
obs_source_skip_video_filter(context);
|
||||
return;
|
||||
}
|
||||
|
||||
gs_texrender_reset(m_texRender);
|
||||
if (!gs_texrender_begin(m_texRender, baseW, baseH)) {
|
||||
obs_source_skip_video_filter(context);
|
||||
return;
|
||||
}
|
||||
if (!obs_source_process_filter_begin(context, GS_RGBA, OBS_NO_DIRECT_RENDERING)) {
|
||||
obs_source_skip_video_filter(context);
|
||||
} else {
|
||||
obs_source_process_filter_end(context, effect ? effect : obs_get_base_effect(OBS_EFFECT_OPAQUE), baseW, baseH);
|
||||
}
|
||||
gs_texrender_end(m_texRender);
|
||||
gs_texture* tex = gs_texrender_get_texture(m_texRender);
|
||||
|
||||
//gs_projection_push();
|
||||
//gs_viewport_push();
|
||||
|
||||
matrix4 alignedMatrix;
|
||||
gs_matrix_get(&alignedMatrix);
|
||||
gs_matrix_push();
|
||||
gs_matrix_set(&alignedMatrix);
|
||||
gs_matrix_scale3f((float)baseW, (float)baseH, 1.0);
|
||||
|
||||
gs_set_cull_mode(GS_NEITHER);
|
||||
gs_enable_blending(false);
|
||||
gs_enable_depth_test(false);
|
||||
gs_enable_stencil_test(false);
|
||||
gs_enable_stencil_write(false);
|
||||
gs_enable_color(true, true, true, true);
|
||||
gs_enable_depth_test(false);
|
||||
|
||||
gs_effect_t* eff = obs_get_base_effect(OBS_EFFECT_OPAQUE);
|
||||
while (gs_effect_loop(eff, "Draw")) {
|
||||
gs_effect_set_texture(gs_effect_get_param_by_name(eff, "image"), tex);
|
||||
gs_load_vertexbuffer(m_vertexBuffer);
|
||||
gs_load_indexbuffer(nullptr);
|
||||
gs_draw(drawmode, 0, (uint32_t)m_vertexHelper->size());
|
||||
}
|
||||
|
||||
gs_matrix_pop();
|
||||
//gs_viewport_pop();
|
||||
//gs_projection_pop();
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Modern effects for a modern Streamer
|
||||
* Copyright (C) 2017 Michael Fabian Dirks
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "obs/gs/gs-vertexbuffer.hpp"
|
||||
#include "plugin.hpp"
|
||||
|
||||
#define P_SHAPE "Shape"
|
||||
#define P_SHAPE_LOOP "Shape.Loop"
|
||||
#define P_SHAPE_MODE "Shape.Mode"
|
||||
#define P_SHAPE_MODE_TRIS "Shape.Mode.Tris"
|
||||
#define P_SHAPE_MODE_TRISTRIP "Shape.Mode.TriStrip"
|
||||
#define P_SHAPE_MODE "Shape.Mode"
|
||||
#define P_SHAPE_POINTS "Shape.Points"
|
||||
#define P_SHAPE_POINT_X "Shape.Point.X"
|
||||
#define P_SHAPE_POINT_Y "Shape.Point.Y"
|
||||
#define P_SHAPE_POINT_U "Shape.Point.U"
|
||||
#define P_SHAPE_POINT_V "Shape.Point.V"
|
||||
|
||||
namespace filter {
|
||||
class Shape {
|
||||
public:
|
||||
Shape();
|
||||
~Shape();
|
||||
|
||||
static const char* get_name(void*);
|
||||
static void get_defaults(obs_data_t*);
|
||||
static obs_properties_t* get_properties(void*);
|
||||
static bool modified_properties(obs_properties_t*, obs_property_t*, obs_data_t*);
|
||||
|
||||
static void* create(obs_data_t*, obs_source_t*);
|
||||
static void destroy(void*);
|
||||
static uint32_t get_width(void*);
|
||||
static uint32_t get_height(void*);
|
||||
static void update(void*, obs_data_t*);
|
||||
static void activate(void*);
|
||||
static void deactivate(void*);
|
||||
static void show(void*);
|
||||
static void hide(void*);
|
||||
static void video_tick(void*, float);
|
||||
static void video_render(void*, gs_effect_t*);
|
||||
|
||||
private:
|
||||
obs_source_info sourceInfo;
|
||||
|
||||
private:
|
||||
class Instance {
|
||||
public:
|
||||
Instance(obs_data_t*, obs_source_t*);
|
||||
~Instance();
|
||||
|
||||
void update(obs_data_t*);
|
||||
uint32_t get_width();
|
||||
uint32_t get_height();
|
||||
void activate();
|
||||
void deactivate();
|
||||
void show();
|
||||
void hide();
|
||||
void video_tick(float);
|
||||
void video_render(gs_effect_t*);
|
||||
|
||||
private:
|
||||
obs_source_t* context;
|
||||
gs::vertex_buffer* m_vertexHelper;
|
||||
gs_vertbuffer_t* m_vertexBuffer;
|
||||
gs_draw_mode drawmode;
|
||||
gs_texrender_t* m_texRender;
|
||||
};
|
||||
};
|
||||
} // namespace filter
|
Loading…
Reference in a new issue