|
@@ -8,9 +8,11 @@
|
|
|
|
|
|
|
|
#define SETTING_IMAGE_PATH "image_path"
|
|
#define SETTING_IMAGE_PATH "image_path"
|
|
|
#define SETTING_CLUT_AMOUNT "clut_amount"
|
|
#define SETTING_CLUT_AMOUNT "clut_amount"
|
|
|
|
|
+#define SETTING_PASSTHROUGH_ALPHA "passthrough_alpha"
|
|
|
|
|
|
|
|
#define TEXT_IMAGE_PATH obs_module_text("Path")
|
|
#define TEXT_IMAGE_PATH obs_module_text("Path")
|
|
|
#define TEXT_AMOUNT obs_module_text("Amount")
|
|
#define TEXT_AMOUNT obs_module_text("Amount")
|
|
|
|
|
+#define TEXT_PASSTHROUGH_ALPHA obs_module_text("PassthroughAlpha")
|
|
|
|
|
|
|
|
/* clang-format on */
|
|
/* clang-format on */
|
|
|
|
|
|
|
@@ -33,11 +35,12 @@ struct lut_filter_data {
|
|
|
|
|
|
|
|
char *file;
|
|
char *file;
|
|
|
float clut_amount;
|
|
float clut_amount;
|
|
|
- enum clut_dimension clut_dim;
|
|
|
|
|
struct vec3 clut_scale;
|
|
struct vec3 clut_scale;
|
|
|
struct vec3 clut_offset;
|
|
struct vec3 clut_offset;
|
|
|
struct vec3 domain_min;
|
|
struct vec3 domain_min;
|
|
|
struct vec3 domain_max;
|
|
struct vec3 domain_max;
|
|
|
|
|
+ const char *clut_texture_name;
|
|
|
|
|
+ const char *tech_name;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
static const char *color_grade_filter_get_name(void *unused)
|
|
static const char *color_grade_filter_get_name(void *unused)
|
|
@@ -253,6 +256,8 @@ static void color_grade_filter_update(void *data, obs_data_t *settings)
|
|
|
|
|
|
|
|
const double clut_amount =
|
|
const double clut_amount =
|
|
|
obs_data_get_double(settings, SETTING_CLUT_AMOUNT);
|
|
obs_data_get_double(settings, SETTING_CLUT_AMOUNT);
|
|
|
|
|
+ const bool passthrough_alpha =
|
|
|
|
|
+ obs_data_get_bool(settings, SETTING_PASSTHROUGH_ALPHA);
|
|
|
|
|
|
|
|
bfree(filter->file);
|
|
bfree(filter->file);
|
|
|
if (path)
|
|
if (path)
|
|
@@ -269,6 +274,10 @@ static void color_grade_filter_update(void *data, obs_data_t *settings)
|
|
|
filter->target = NULL;
|
|
filter->target = NULL;
|
|
|
obs_leave_graphics();
|
|
obs_leave_graphics();
|
|
|
|
|
|
|
|
|
|
+ enum clut_dimension clut_dim = CLUT_3D;
|
|
|
|
|
+ const char *clut_texture_name = "clut_3d";
|
|
|
|
|
+ const char *tech_name = "Draw3D";
|
|
|
|
|
+
|
|
|
if (path) {
|
|
if (path) {
|
|
|
vec3_set(&filter->domain_min, 0.0f, 0.0f, 0.0f);
|
|
vec3_set(&filter->domain_min, 0.0f, 0.0f, 0.0f);
|
|
|
vec3_set(&filter->domain_max, 1.0f, 1.0f, 1.0f);
|
|
vec3_set(&filter->domain_max, 1.0f, 1.0f, 1.0f);
|
|
@@ -277,11 +286,26 @@ static void color_grade_filter_update(void *data, obs_data_t *settings)
|
|
|
if (ext && astrcmpi(ext, ".cube") == 0) {
|
|
if (ext && astrcmpi(ext, ".cube") == 0) {
|
|
|
filter->cube_data = load_cube_file(
|
|
filter->cube_data = load_cube_file(
|
|
|
path, &filter->cube_width, &filter->domain_min,
|
|
path, &filter->cube_width, &filter->domain_min,
|
|
|
- &filter->domain_max, &filter->clut_dim);
|
|
|
|
|
|
|
+ &filter->domain_max, &clut_dim);
|
|
|
} else {
|
|
} else {
|
|
|
gs_image_file_init(&filter->image, path);
|
|
gs_image_file_init(&filter->image, path);
|
|
|
filter->cube_width = LUT_WIDTH;
|
|
filter->cube_width = LUT_WIDTH;
|
|
|
- filter->clut_dim = CLUT_3D;
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (clut_dim == CLUT_1D) {
|
|
|
|
|
+ clut_texture_name = "clut_1d";
|
|
|
|
|
+ tech_name = "Draw1D";
|
|
|
|
|
+ } else if ((filter->domain_min.x > 0.f) ||
|
|
|
|
|
+ (filter->domain_min.y > 0.f) ||
|
|
|
|
|
+ (filter->domain_min.z > 0.f) ||
|
|
|
|
|
+ (filter->domain_max.x < 1.f) ||
|
|
|
|
|
+ (filter->domain_max.y < 1.f) ||
|
|
|
|
|
+ (filter->domain_max.z < 1.f)) {
|
|
|
|
|
+ tech_name = "DrawDomain3D";
|
|
|
|
|
+ } else if (clut_amount < 1.0) {
|
|
|
|
|
+ tech_name = "DrawAmount3D";
|
|
|
|
|
+ } else if (!passthrough_alpha) {
|
|
|
|
|
+ tech_name = "DrawAlpha3D";
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -300,7 +324,7 @@ static void color_grade_filter_update(void *data, obs_data_t *settings)
|
|
|
vec3_set(&filter->clut_offset, offset, offset, offset);
|
|
vec3_set(&filter->clut_offset, offset, offset, offset);
|
|
|
} else if (filter->cube_data) {
|
|
} else if (filter->cube_data) {
|
|
|
const uint32_t width = filter->cube_width;
|
|
const uint32_t width = filter->cube_width;
|
|
|
- if (filter->clut_dim == CLUT_1D) {
|
|
|
|
|
|
|
+ if (clut_dim == CLUT_1D) {
|
|
|
filter->target = gs_texture_create(
|
|
filter->target = gs_texture_create(
|
|
|
width, 1, GS_RGBA16F, 1,
|
|
width, 1, GS_RGBA16F, 1,
|
|
|
(const uint8_t **)&filter->cube_data,
|
|
(const uint8_t **)&filter->cube_data,
|
|
@@ -337,6 +361,8 @@ static void color_grade_filter_update(void *data, obs_data_t *settings)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
filter->clut_amount = (float)clut_amount;
|
|
filter->clut_amount = (float)clut_amount;
|
|
|
|
|
+ filter->clut_texture_name = clut_texture_name;
|
|
|
|
|
+ filter->tech_name = tech_name;
|
|
|
|
|
|
|
|
char *effect_path = obs_module_file("color_grade_filter.effect");
|
|
char *effect_path = obs_module_file("color_grade_filter.effect");
|
|
|
gs_effect_destroy(filter->effect);
|
|
gs_effect_destroy(filter->effect);
|
|
@@ -348,7 +374,8 @@ static void color_grade_filter_update(void *data, obs_data_t *settings)
|
|
|
|
|
|
|
|
static void color_grade_filter_defaults(obs_data_t *settings)
|
|
static void color_grade_filter_defaults(obs_data_t *settings)
|
|
|
{
|
|
{
|
|
|
- obs_data_set_default_double(settings, SETTING_CLUT_AMOUNT, 1);
|
|
|
|
|
|
|
+ obs_data_set_default_double(settings, SETTING_CLUT_AMOUNT, 1.0);
|
|
|
|
|
+ obs_data_set_default_bool(settings, SETTING_PASSTHROUGH_ALPHA, false);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static obs_properties_t *color_grade_filter_properties(void *data)
|
|
static obs_properties_t *color_grade_filter_properties(void *data)
|
|
@@ -380,6 +407,8 @@ static obs_properties_t *color_grade_filter_properties(void *data)
|
|
|
OBS_PATH_FILE, filter_str.array, path.array);
|
|
OBS_PATH_FILE, filter_str.array, path.array);
|
|
|
obs_properties_add_float_slider(props, SETTING_CLUT_AMOUNT, TEXT_AMOUNT,
|
|
obs_properties_add_float_slider(props, SETTING_CLUT_AMOUNT, TEXT_AMOUNT,
|
|
|
0, 1, 0.0001);
|
|
0, 1, 0.0001);
|
|
|
|
|
+ obs_properties_add_bool(props, SETTING_PASSTHROUGH_ALPHA,
|
|
|
|
|
+ TEXT_PASSTHROUGH_ALPHA);
|
|
|
|
|
|
|
|
dstr_free(&filter_str);
|
|
dstr_free(&filter_str);
|
|
|
dstr_free(&path);
|
|
dstr_free(&path);
|
|
@@ -426,17 +455,12 @@ static void color_grade_filter_render(void *data, gs_effect_t *effect)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
|
|
if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
|
|
|
- OBS_ALLOW_DIRECT_RENDERING))
|
|
|
|
|
|
|
+ OBS_ALLOW_DIRECT_RENDERING)) {
|
|
|
return;
|
|
return;
|
|
|
-
|
|
|
|
|
- const char *clut_texture_name = "clut_3d";
|
|
|
|
|
- const char *tech_name = "Draw3D";
|
|
|
|
|
- if (filter->clut_dim == CLUT_1D) {
|
|
|
|
|
- clut_texture_name = "clut_1d";
|
|
|
|
|
- tech_name = "Draw1D";
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- param = gs_effect_get_param_by_name(filter->effect, clut_texture_name);
|
|
|
|
|
|
|
+ param = gs_effect_get_param_by_name(filter->effect,
|
|
|
|
|
+ filter->clut_texture_name);
|
|
|
gs_effect_set_texture_srgb(param, filter->target);
|
|
gs_effect_set_texture_srgb(param, filter->target);
|
|
|
|
|
|
|
|
param = gs_effect_get_param_by_name(filter->effect, "clut_amount");
|
|
param = gs_effect_get_param_by_name(filter->effect, "clut_amount");
|
|
@@ -458,7 +482,7 @@ static void color_grade_filter_render(void *data, gs_effect_t *effect)
|
|
|
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
|
|
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
|
|
|
|
|
|
|
|
obs_source_process_filter_tech_end(filter->context, filter->effect, 0,
|
|
obs_source_process_filter_tech_end(filter->context, filter->effect, 0,
|
|
|
- 0, tech_name);
|
|
|
|
|
|
|
+ 0, filter->tech_name);
|
|
|
|
|
|
|
|
gs_blend_state_pop();
|
|
gs_blend_state_pop();
|
|
|
|
|
|