Use Premultiplied Alpha for Text and Game Capture (#1578)

The GDI+ based Text Source actually uses Premultiplied Alpha. The edges
of the fonts are therefore incorrectly blended, causing ugly artifacts
especially if bright text above a bright background is used. Here's an
image comparing the new text blending (left) to before (right):
![https://i.imgur.com/VhhkQcZ.png](https://i.imgur.com/VhhkQcZ.png)

Additionally, the game capture has the same problem, so premultiplied
alpha is used there as well now.
master
Christopher Serr 2019-01-31 04:54:24 +01:00 committed by Colin Edwards
parent 0d9fb6c8b0
commit 7c53483388
2 changed files with 15 additions and 6 deletions

View File

@ -266,7 +266,7 @@ struct TextSource {
inline void Update(obs_data_t *settings); inline void Update(obs_data_t *settings);
inline void Tick(float seconds); inline void Tick(float seconds);
inline void Render(gs_effect_t *effect); inline void Render();
}; };
static time_t get_modified_timestamp(const char *filename) static time_t get_modified_timestamp(const char *filename)
@ -789,13 +789,22 @@ inline void TextSource::Tick(float seconds)
} }
} }
inline void TextSource::Render(gs_effect_t *effect) inline void TextSource::Render()
{ {
if (!tex) if (!tex)
return; return;
gs_effect_t *effect = obs_get_base_effect(OBS_EFFECT_PREMULTIPLIED_ALPHA);
gs_technique_t *tech = gs_effect_get_technique(effect, "Draw");
gs_technique_begin(tech);
gs_technique_begin_pass(tech, 0);
gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), tex); gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), tex);
gs_draw_sprite(tex, 0, cx, cy); gs_draw_sprite(tex, 0, cx, cy);
gs_technique_end_pass(tech);
gs_technique_end(tech);
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
@ -1017,9 +1026,9 @@ bool obs_module_load(void)
{ {
reinterpret_cast<TextSource*>(data)->Tick(seconds); reinterpret_cast<TextSource*>(data)->Tick(seconds);
}; };
si.video_render = [] (void *data, gs_effect_t *effect) si.video_render = [] (void *data, gs_effect_t*)
{ {
reinterpret_cast<TextSource*>(data)->Render(effect); reinterpret_cast<TextSource*>(data)->Render();
}; };
obs_register_source(&si); obs_register_source(&si);

View File

@ -1771,7 +1771,7 @@ static void game_capture_render(void *data, gs_effect_t *effect)
return; return;
effect = obs_get_base_effect(gc->config.allow_transparency ? effect = obs_get_base_effect(gc->config.allow_transparency ?
OBS_EFFECT_DEFAULT : OBS_EFFECT_OPAQUE); OBS_EFFECT_PREMULTIPLIED_ALPHA : OBS_EFFECT_OPAQUE);
while (gs_effect_loop(effect, "Draw")) { while (gs_effect_loop(effect, "Draw")) {
obs_source_draw(gc->texture, 0, 0, 0, 0, obs_source_draw(gc->texture, 0, 0, 0, 0,