static void obs_source_draw_async_texture(struct obs_source *source) { effect_t effect = gs_geteffect(); bool yuv = format_is_yuv(source->async_format); bool limited_range = yuv && !source->async_full_range; const char *type = yuv ? "DrawMatrix" : "Draw"; bool def_draw = (!effect); technique_t tech; if (def_draw) { effect = obs_get_default_effect(); tech = effect_gettechnique(effect, type); technique_begin(tech); technique_beginpass(tech, 0); } obs_source_draw_texture(source, effect, yuv ? source->async_color_matrix : NULL, limited_range ? source->async_color_range_min : NULL, limited_range ? source->async_color_range_max : NULL); if (def_draw) { technique_endpass(tech); technique_end(tech); } }
static void obs_source_draw_texture(texture_t tex, struct source_frame *frame) { effect_t effect = obs->video.default_effect; bool yuv = is_yuv(frame->format); const char *type = yuv ? "DrawYUV" : "DrawRGB"; technique_t tech; eparam_t param; if (!upload_frame(tex, frame)) return; tech = effect_gettechnique(effect, type); technique_begin(tech); technique_beginpass(tech, 0); if (yuv) { param = effect_getparambyname(effect, "yuv_matrix"); effect_setval(effect, param, frame->yuv_matrix, sizeof(float) * 16); } param = effect_getparambyname(effect, "diffuse"); effect_settexture(effect, param, tex); gs_draw_sprite(tex, frame->flip ? GS_FLIP_V : 0, 0, 0); technique_endpass(tech); technique_end(tech); }
static inline void obs_source_default_render(obs_source_t source, bool yuv) { effect_t effect = obs->video.default_effect; const char *tech_name = yuv ? "DrawYUV" : "DrawRGB"; technique_t tech = effect_gettechnique(effect, tech_name); size_t passes, i; passes = technique_begin(tech); for (i = 0; i < passes; i++) { technique_beginpass(tech, i); source->callbacks.video_render(source->data); technique_endpass(tech); } technique_end(tech); }
static inline void render_filter_bypass(obs_source_t target, effect_t effect, bool use_matrix) { const char *tech_name = use_matrix ? "DrawMatrix" : "Draw"; technique_t tech = effect_gettechnique(effect, tech_name); size_t passes, i; passes = technique_begin(tech); for (i = 0; i < passes; i++) { technique_beginpass(tech, i); obs_source_video_render(target); technique_endpass(tech); } technique_end(tech); }
static inline void render_filter_bypass(obs_source_t target, effect_t effect, uint32_t width, uint32_t height, bool yuv) { const char *tech_name = yuv ? "DrawYUV" : "DrawRGB"; technique_t tech = effect_gettechnique(effect, tech_name); eparam_t diffuse = effect_getparambyname(effect, "diffuse"); size_t passes, i; passes = technique_begin(tech); for (i = 0; i < passes; i++) { technique_beginpass(tech, i); obs_source_video_render(target); technique_endpass(tech); } technique_end(tech); }
static inline void obs_source_default_render(obs_source_t source, bool color_matrix) { effect_t effect = obs->video.default_effect; const char *tech_name = color_matrix ? "DrawMatrix" : "Draw"; technique_t tech = effect_gettechnique(effect, tech_name); size_t passes, i; passes = technique_begin(tech); for (i = 0; i < passes; i++) { technique_beginpass(tech, i); source->info.video_render(source->context.data, effect); technique_endpass(tech); } technique_end(tech); }
static bool update_async_texrender(struct obs_source *source, const struct source_frame *frame) { texture_t tex = source->async_texture; texrender_t texrender = source->async_convert_texrender; texrender_reset(texrender); upload_raw_frame(tex, frame); uint32_t cx = source->async_width; uint32_t cy = source->async_height; effect_t conv = obs->video.conversion_effect; technique_t tech = effect_gettechnique(conv, select_conversion_technique(frame->format)); if (!texrender_begin(texrender, cx, cy)) return false; technique_begin(tech); technique_beginpass(tech, 0); effect_settexture(conv, effect_getparambyname(conv, "image"), tex); set_eparam(conv, "width", (float)cx); set_eparam(conv, "height", (float)cy); set_eparam(conv, "width_i", 1.0f / cx); set_eparam(conv, "height_i", 1.0f / cy); set_eparam(conv, "width_d2", cx * 0.5f); set_eparam(conv, "height_d2", cy * 0.5f); set_eparam(conv, "width_d2_i", 1.0f / (cx * 0.5f)); set_eparam(conv, "height_d2_i", 1.0f / (cy * 0.5f)); set_eparam(conv, "input_height", (float)cy); gs_ortho(0.f, (float)cx, 0.f, (float)cy, -100.f, 100.f); gs_draw_sprite(tex, 0, cx, cy); technique_endpass(tech); technique_end(tech); texrender_end(texrender); return true; }
static void render_convert_texture(struct obs_core_video *video, int cur_texture, int prev_texture) { texture_t texture = video->output_textures[prev_texture]; texture_t target = video->convert_textures[cur_texture]; float fwidth = (float)video->output_width; float fheight = (float)video->output_height; size_t passes, i; effect_t effect = video->conversion_effect; eparam_t image = effect_getparambyname(effect, "image"); technique_t tech = effect_gettechnique(effect, video->conversion_tech); if (!video->textures_output[prev_texture]) return; set_eparam(effect, "u_plane_offset", (float)video->plane_offsets[1]); set_eparam(effect, "v_plane_offset", (float)video->plane_offsets[2]); set_eparam(effect, "width", fwidth); set_eparam(effect, "height", fheight); set_eparam(effect, "width_i", 1.0f / fwidth); set_eparam(effect, "height_i", 1.0f / fheight); set_eparam(effect, "width_d2", fwidth * 0.5f); set_eparam(effect, "height_d2", fheight * 0.5f); set_eparam(effect, "width_d2_i", 1.0f / (fwidth * 0.5f)); set_eparam(effect, "height_d2_i", 1.0f / (fheight * 0.5f)); set_eparam(effect, "input_height", (float)video->conversion_height); effect_settexture(effect, image, texture); gs_setrendertarget(target, NULL); set_render_size(video->output_width, video->conversion_height); passes = technique_begin(tech); for (i = 0; i < passes; i++) { technique_beginpass(tech, i); gs_draw_sprite(texture, 0, video->output_width, video->conversion_height); technique_endpass(tech); } technique_end(tech); video->textures_converted[cur_texture] = true; }
static inline void render_filter_tex(texture_t tex, effect_t effect, uint32_t width, uint32_t height, bool yuv) { const char *tech_name = yuv ? "DrawYUV" : "DrawRGB"; technique_t tech = effect_gettechnique(effect, tech_name); eparam_t diffuse = effect_getparambyname(effect, "diffuse"); size_t passes, i; effect_settexture(effect, diffuse, tex); passes = technique_begin(tech); for (i = 0; i < passes; i++) { technique_beginpass(tech, i); gs_draw_sprite(tex, width, height, 0); technique_endpass(tech); } technique_end(tech); }
static inline void render_filter_tex(texture_t tex, effect_t effect, uint32_t width, uint32_t height, bool use_matrix) { const char *tech_name = use_matrix ? "DrawMatrix" : "Draw"; technique_t tech = effect_gettechnique(effect, tech_name); eparam_t image = effect_getparambyname(effect, "image"); size_t passes, i; effect_settexture(effect, image, tex); passes = technique_begin(tech); for (i = 0; i < passes; i++) { technique_beginpass(tech, i); gs_draw_sprite(tex, width, height, 0); technique_endpass(tech); } technique_end(tech); }
static inline void render_output_texture(struct obs_core_video *video, int cur_texture, int prev_texture) { texture_t texture = video->render_textures[prev_texture]; texture_t target = video->output_textures[cur_texture]; uint32_t width = texture_getwidth(target); uint32_t height = texture_getheight(target); /* TODO: replace with actual downscalers or unpackers */ effect_t effect = video->default_effect; technique_t tech = effect_gettechnique(effect, "DrawMatrix"); eparam_t image = effect_getparambyname(effect, "image"); eparam_t matrix = effect_getparambyname(effect, "color_matrix"); size_t passes, i; if (!video->textures_rendered[prev_texture]) return; gs_setrendertarget(target, NULL); set_render_size(width, height); /* TODO: replace with programmable code */ const float mat_val[16] = { -0.100644f, -0.338572f, 0.439216f, 0.501961f, 0.182586f, 0.614231f, 0.062007f, 0.062745f, 0.439216f, -0.398942f, -0.040274f, 0.501961f, 0.000000f, 0.000000f, 0.000000f, 1.000000f }; effect_setval(effect, matrix, mat_val, sizeof(mat_val)); effect_settexture(effect, image, texture); passes = technique_begin(tech); for (i = 0; i < passes; i++) { technique_beginpass(tech, i); gs_draw_sprite(texture, 0, width, height); technique_endpass(tech); } technique_end(tech); video->textures_output[cur_texture] = true; }
static void draw_texture(struct dc_capture *capture, int id, effect_t effect) { texture_t texture = capture->textures[id]; technique_t tech = effect_gettechnique(effect, "Draw"); eparam_t image = effect_getparambyname(effect, "image"); size_t passes; effect_settexture(effect, image, texture); passes = technique_begin(tech); for (size_t i = 0; i < passes; i++) { if (technique_beginpass(tech, i)) { if (capture->compatibility) gs_draw_sprite(texture, GS_FLIP_V, 0, 0); else gs_draw_sprite(texture, 0, 0, 0); technique_endpass(tech); } } technique_end(tech); }
void OBSBasicPreview::DrawSceneEditing() { OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); effect_t solid = obs_get_solid_effect(); technique_t tech = effect_gettechnique(solid, "Solid"); vec4 color; vec4_set(&color, 1.0f, 0.0f, 0.0f, 1.0f); effect_setvec4(solid, effect_getparambyname(solid, "color"), &color); technique_begin(tech); technique_beginpass(tech, 0); OBSScene scene = main->GetCurrentScene(); if (scene) obs_scene_enum_items(scene, DrawSelectedItem, this); gs_load_vertexbuffer(nullptr); technique_endpass(tech); technique_end(tech); }