transition-fade-to-color.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include <obs-module.h>
  2. #define S_COLOR "color"
  3. #define S_SWITCH_POINT "switch_point"
  4. #define S_COLOR_TEXT obs_module_text("Color")
  5. #define S_SWITCH_POINT_TEXT obs_module_text("SwitchPoint")
  6. struct fade_to_color_info {
  7. obs_source_t *source;
  8. gs_effect_t *effect;
  9. gs_eparam_t *ep_tex;
  10. gs_eparam_t *ep_swp;
  11. gs_eparam_t *ep_color;
  12. struct vec4 color;
  13. float switch_point;
  14. };
  15. static inline float lerp(float a, float b, float x)
  16. {
  17. return (1.0f - x) * a + x * b;
  18. }
  19. static inline float clamp(float x, float min, float max)
  20. {
  21. if (x < min)
  22. return min;
  23. else if (x > max)
  24. return max;
  25. return x;
  26. }
  27. static inline float smoothstep(float min, float max, float x)
  28. {
  29. x = clamp((x - min) / (max - min), 0.0f, 1.0f);
  30. return x*x*(3 - 2 * x);
  31. }
  32. static const char *fade_to_color_get_name(void *type_data)
  33. {
  34. UNUSED_PARAMETER(type_data);
  35. return obs_module_text("FadeToColorTransition");
  36. }
  37. static void fade_to_color_update(void *data, obs_data_t *settings)
  38. {
  39. struct fade_to_color_info *fade_to_color = data;
  40. uint32_t color = (uint32_t)obs_data_get_int(settings, S_COLOR);
  41. uint32_t swp = (uint32_t)obs_data_get_int(settings, S_SWITCH_POINT);
  42. color |= 0xFF000000;
  43. vec4_from_rgba(&fade_to_color->color, color);
  44. fade_to_color->switch_point = (float)swp / 100.0f;
  45. }
  46. static void *fade_to_color_create(obs_data_t *settings, obs_source_t *source)
  47. {
  48. struct fade_to_color_info *fade_to_color;
  49. char *file = obs_module_file("fade_to_color_transition.effect");
  50. gs_effect_t *effect;
  51. obs_enter_graphics();
  52. effect = gs_effect_create_from_file(file, NULL);
  53. obs_leave_graphics();
  54. bfree(file);
  55. if (!effect) {
  56. blog(LOG_ERROR, "Could not find fade_to_color_transition.effect");
  57. return NULL;
  58. }
  59. fade_to_color = bzalloc(sizeof(struct fade_to_color_info));
  60. fade_to_color->source = source;
  61. fade_to_color->effect = effect;
  62. fade_to_color->ep_tex = gs_effect_get_param_by_name(effect, "tex");
  63. fade_to_color->ep_swp = gs_effect_get_param_by_name(effect, "swp");
  64. fade_to_color->ep_color = gs_effect_get_param_by_name(effect, "color");
  65. obs_source_update(source, settings);
  66. return fade_to_color;
  67. }
  68. static void fade_to_color_destroy(void *data)
  69. {
  70. struct fade_to_color_info *fade_to_color = data;
  71. bfree(fade_to_color);
  72. }
  73. static void fade_to_color_callback(void *data, gs_texture_t *a, gs_texture_t *b,
  74. float t, uint32_t cx, uint32_t cy)
  75. {
  76. struct fade_to_color_info *fade_to_color = data;
  77. float sa = smoothstep(0.0f, fade_to_color->switch_point, t);
  78. float sb = smoothstep(fade_to_color->switch_point, 1.0f, t);
  79. float swp = t < fade_to_color->switch_point ? sa : 1.0f - sb;
  80. gs_effect_set_texture(fade_to_color->ep_tex,
  81. t < fade_to_color->switch_point ? a : b);
  82. gs_effect_set_float(fade_to_color->ep_swp, swp);
  83. gs_effect_set_vec4(fade_to_color->ep_color, &fade_to_color->color);
  84. while (gs_effect_loop(fade_to_color->effect, "FadeToColor"))
  85. gs_draw_sprite(NULL, 0, cx, cy);
  86. }
  87. static void fade_to_color_video_render(void *data, gs_effect_t *effect)
  88. {
  89. struct fade_to_color_info *fade_to_color = data;
  90. obs_transition_video_render(fade_to_color->source,
  91. fade_to_color_callback);
  92. UNUSED_PARAMETER(effect);
  93. }
  94. static float mix_a(void *data, float t)
  95. {
  96. struct fade_to_color_info *fade_to_color = data;
  97. float sp = fade_to_color->switch_point;
  98. return lerp(1.0f - t , 0.0f, smoothstep(0.0f, sp, t));
  99. }
  100. static float mix_b(void *data, float t)
  101. {
  102. struct fade_to_color_info *fade_to_color = data;
  103. float sp = fade_to_color->switch_point;
  104. return lerp(0.0f, t, smoothstep(sp, 1.0f, t));
  105. }
  106. static bool fade_to_color_audio_render(void *data, uint64_t *ts_out,
  107. struct obs_source_audio_mix *audio, uint32_t mixers,
  108. size_t channels, size_t sample_rate)
  109. {
  110. struct fade_to_color_info *fade_to_color = data;
  111. return obs_transition_audio_render(fade_to_color->source, ts_out,
  112. audio, mixers, channels, sample_rate, mix_a, mix_b);
  113. }
  114. static obs_properties_t *fade_to_color_properties(void *data)
  115. {
  116. obs_properties_t *props = obs_properties_create();
  117. obs_properties_add_color(props, S_COLOR, S_COLOR_TEXT);
  118. obs_properties_add_int_slider(props, S_SWITCH_POINT,
  119. S_SWITCH_POINT_TEXT, 0, 100, 1);
  120. UNUSED_PARAMETER(data);
  121. return props;
  122. }
  123. static void fade_to_color_defaults(obs_data_t *settings)
  124. {
  125. obs_data_set_default_int(settings, S_COLOR, 0xFF000000);
  126. obs_data_set_default_int(settings, S_SWITCH_POINT, 50);
  127. }
  128. struct obs_source_info fade_to_color_transition = {
  129. .id = "fade_to_color_transition",
  130. .type = OBS_SOURCE_TYPE_TRANSITION,
  131. .get_name = fade_to_color_get_name,
  132. .create = fade_to_color_create,
  133. .destroy = fade_to_color_destroy,
  134. .update = fade_to_color_update,
  135. .video_render = fade_to_color_video_render,
  136. .audio_render = fade_to_color_audio_render,
  137. .get_properties = fade_to_color_properties,
  138. .get_defaults = fade_to_color_defaults
  139. };