From ab5a76901bae7feb9d0404c7b14046a2c74e8ff6 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Mon, 10 Nov 2014 01:01:57 -0800 Subject: [PATCH] Add obs_source_draw helper function This function simplifies drawing textures for sources in order to help reduce boilerplate code. If a source is a custom drawn source, it will automatically set up the effect to draw the sprite. If it's not a custom drawn source, it will simply draw the sprite as per normal. If the source uses a specific color matrix, it will also handle that as well. --- libobs/obs-source.c | 85 +++++++++++++++++++++++++++++++++++++++++++++ libobs/obs.h | 7 ++++ 2 files changed, 92 insertions(+) diff --git a/libobs/obs-source.c b/libobs/obs-source.c index f9ae3a407..42465ef92 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -2115,3 +2115,88 @@ uint32_t obs_source_get_flags(const obs_source_t *source) { return source ? source->flags : 0; } + +static inline void render_custom(gs_texture_t *texture, gs_effect_t *effect, + const char *tech_name, uint32_t cx, uint32_t cy, bool flip) +{ + gs_technique_t *tech; + size_t passes; + + tech = gs_effect_get_technique(effect, tech_name); + passes = gs_technique_begin(tech); + for (size_t i = 0; i < passes; i++) { + if (gs_technique_begin_pass(tech, i)) { + gs_draw_sprite(texture, flip ? GS_FLIP_V : 0, cx, cy); + gs_technique_end_pass(tech); + } + } + gs_technique_end(tech); +} + +static inline void render_chained(gs_texture_t *texture, gs_effect_t *effect, + const char *tech_name, uint32_t cx, uint32_t cy, bool flip) +{ + gs_draw_sprite(texture, flip ? GS_FLIP_V : 0, cx, cy); +} + +void obs_source_draw(obs_source_t *source, gs_effect_t *effect, + gs_texture_t *texture, uint32_t cx, uint32_t cy, bool flip, + const struct matrix4 *color_matrix, + const struct vec3 *color_range_min, + const struct vec3 *color_range_max) +{ + uint32_t flags = source->info.output_flags; + bool use_custom = (flags & OBS_SOURCE_CUSTOM_DRAW) != 0; + bool use_matrix = (flags & OBS_SOURCE_COLOR_MATRIX) != 0; + const char *tech_name = use_matrix ? "DrawMatrix" : "Draw"; + gs_eparam_t *image; + + if (!effect) { + blog(LOG_WARNING, "obs_source_draw_texture: NULL effect"); + return; + } + + if (!texture) { + blog(LOG_WARNING, "obs_source_draw_texture: NULL texture"); + return; + } + + if (use_matrix && !color_matrix) { + blog(LOG_WARNING, "obs_source_draw_texture: NULL color_matrix"); + return; + } + + if (use_matrix && !color_range_min) { + blog(LOG_WARNING, "obs_source_draw_texture: NULL " + "color_range_min"); + return; + } + + if (use_matrix && !color_range_max) { + blog(LOG_WARNING, "obs_source_draw_texture: NULL " + "color_range_max"); + return; + } + + image = gs_effect_get_param_by_name(effect, "image"); + gs_effect_set_texture(image, texture); + + if (use_matrix) { + gs_eparam_t *matrix = gs_effect_get_param_by_name(effect, + "color_matrix"); + gs_eparam_t *range_min = gs_effect_get_param_by_name(effect, + "color_range_min"); + gs_eparam_t *range_max = gs_effect_get_param_by_name(effect, + "color_range_max"); + + gs_effect_set_matrix4(matrix, color_matrix); + gs_effect_set_val(range_min, color_range_min, sizeof(float)*3); + gs_effect_set_val(range_max, color_range_max, sizeof(float)*3); + } + + if (use_custom) { + render_custom(texture, effect, tech_name, cx, cy, flip); + } else { + render_chained(texture, effect, tech_name, cx, cy, flip); + } +} diff --git a/libobs/obs.h b/libobs/obs.h index af4a90a5d..dab14cb5c 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -742,6 +742,13 @@ EXPORT uint32_t obs_source_get_flags(const obs_source_t *source); /* ------------------------------------------------------------------------- */ /* Functions used by sources */ +/** Helper function to draw a texture for a source (synchronous video) */ +EXPORT void obs_source_draw(obs_source_t *source, gs_effect_t *effect, + gs_texture_t *texture, uint32_t cx, uint32_t cy, bool flip, + const struct matrix4 *color_matrix, + const struct vec3 *color_range_min, + const struct vec3 *color_range_max); + /** Outputs asynchronous video data */ EXPORT void obs_source_output_video(obs_source_t *source, const struct obs_source_frame *frame);