From: Filippo Argiolas Date: Sat, 16 Aug 2008 07:13:39 +0000 (+0200) Subject: [175/906] add sin effect (desaturate everything but red shades). still needs some... X-Git-Tag: 1.19.3~507^2~12357 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=85502ef8cdc7f6631849aa18e9c9af064214e1d2;p=platform%2Fupstream%2Fgstreamer.git [175/906] add sin effect (desaturate everything but red shades). still needs some tuning. --- diff --git a/gst/gl/Makefile.am b/gst/gl/Makefile.am index 4a1780d..8168fc1 100644 --- a/gst/gl/Makefile.am +++ b/gst/gl/Makefile.am @@ -41,6 +41,7 @@ libgstopengl_la_SOURCES = \ effects/gstgleffectsquare.c \ effects/gstgleffectlumatocurve.c \ effects/gstgleffectrgbtocurve.c \ + effects/gstgleffectsin.c \ effects/gstgleffectglow.c diff --git a/gst/gl/effects/gstgleffectsin.c b/gst/gl/effects/gstgleffectsin.c new file mode 100644 index 0000000..8be7210 --- /dev/null +++ b/gst/gl/effects/gstgleffectsin.c @@ -0,0 +1,61 @@ +/* + * GStreamer + * Copyright (C) 2008 Filippo Argiolas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +static void +gst_gl_effects_sin_callback (gint width, gint height, guint texture, gpointer data) +{ + GstGLEffects* effects = GST_GL_EFFECTS (data); + + GstGLShader *shader; + + shader = g_hash_table_lookup (effects->shaderstable, "sin0"); + + if (!shader) { + shader = gst_gl_shader_new (); + g_hash_table_insert (effects->shaderstable, "sin0", shader); + } + + g_return_if_fail ( + gst_gl_shader_compile_and_check (shader, sin_fragment_source, + GST_GL_SHADER_FRAGMENT_SOURCE)); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + gst_gl_shader_use (shader); + + glActiveTexture (GL_TEXTURE0); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + + gst_gl_shader_set_uniform_1i (shader, "tex", 0); + + gst_gl_effects_draw_texture (effects, texture); +} + +void +gst_gl_effects_sin (GstGLEffects *effects) { + GstGLFilter *filter = GST_GL_FILTER (effects); + + gst_gl_filter_render_to_target (filter, effects->intexture, effects->outtexture, + gst_gl_effects_sin_callback, effects); +} diff --git a/gst/gl/effects/gstgleffectssources.c b/gst/gl/effects/gstgleffectssources.c index dd6ce69..8c752ec 100644 --- a/gst/gl/effects/gstgleffectssources.c +++ b/gst/gl/effects/gstgleffectssources.c @@ -277,3 +277,50 @@ const gchar *rgb_to_curve_fragment_source = " outcolor.a = color.a;" " gl_FragColor = outcolor;" "}"; + +const gchar *sin_fragment_source = +"#extension GL_ARB_texture_rectangle : enable\n" +"uniform sampler2DRect tex;" +"vec3 rgb2hsl (vec3 v) " +"{" +/* TODO: check this algorythm */ +" float MIN, MAX;" +" float r, g, b;" +" float h, l, s;" +" float delta;" +" h = 0.0; l = 0.0; s = 0.0;" +" r = v.r; g = v.g; b = v.b;" +" MIN = min (r, min (g, b));" +" MAX = max (r, max (g, b));" +" delta = MAX - MIN;" +" l = (MAX + MIN) / 2.0;" +" if ((MAX - MIN) < 0.0001) { h = 0.0; s = 0.0; }" +" else {" +" if (l <= 0.5) s = (MAX - MIN) / (MAX + MIN);" +" else s = (MAX - MIN) / (2.0 - MAX - MIN);" +" if (r == MAX) h = (g - b) / delta;" +" else if (g == MAX) h = 2.0 + (b - r) / delta;" +" else h = 4.0 + (r - g) / delta;" +" h *= 60.0;" +" if (h < 0.0) h += 360.0;" +" }" +" return vec3 (h, l, s);" +"}" +"void main () {" +" vec3 HSL, RGB;" +" vec4 color = texture2DRect (tex, vec2(gl_TexCoord[0].st));" +" float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));" +" HSL = rgb2hsl (color.rgb);" +/* move hls discontinuity away from the desired red zone so we can use + * smoothstep.. to try: convert degrees in radiants, divide by 2 and + * smoothstep sine */ +" HSL.x += 180.0;" +" if ((HSL.x) > 360.0) HSL.x -= 360.0;" +/* damn, it is extremely hard to get rid of human face reds! */ +/* picked hue is slightly shifted towards violet to prevent this but + * still fails.. maybe hsl is not well suited for this */ +" float a = smoothstep (110.0, 150.0, HSL.x);" +" float b = smoothstep (170.0, 210.0, HSL.x);" +" float alpha = a - b;" +" gl_FragColor = color * alpha + luma * (1.0 - alpha);" +"}"; diff --git a/gst/gl/effects/gstgleffectssources.h b/gst/gl/effects/gstgleffectssources.h index e8d0e32..f3f364d 100644 --- a/gst/gl/effects/gstgleffectssources.h +++ b/gst/gl/effects/gstgleffectssources.h @@ -37,5 +37,6 @@ const gchar *vconv9_fragment_source; const gchar *sum_fragment_source; const gchar *luma_to_curve_fragment_source; const gchar *rgb_to_curve_fragment_source; +const gchar *sin_fragment_source; #endif /* __GST_GL_EFFECTS_SOURCES_H__ */ diff --git a/gst/gl/gstgleffects.c b/gst/gl/gstgleffects.c index 465ef4c..8374cfe 100644 --- a/gst/gl/gstgleffects.c +++ b/gst/gl/gstgleffects.c @@ -68,6 +68,7 @@ typedef enum { GST_GL_EFFECT_SEPIA, GST_GL_EFFECT_XPRO, GST_GL_EFFECT_LUMA_XPRO, + GST_GL_EFFECT_SIN, GST_GL_EFFECT_GLOW, GST_GL_N_EFFECTS } GstGLEffectsEffect; @@ -91,6 +92,7 @@ gst_gl_effects_effect_get_type (void) { GST_GL_EFFECT_SEPIA, "Sepia Toning Effect", "sepia" }, { GST_GL_EFFECT_XPRO, "Cross Processing Effect", "xpro" }, { GST_GL_EFFECT_LUMA_XPRO, "Luma Cross Processing Effect", "lumaxpro" }, + { GST_GL_EFFECT_SIN, "All Grey but Red Effect", "sin" }, { GST_GL_EFFECT_GLOW, "Glow Lighting Effect", "glow" }, { 0, NULL, NULL } }; @@ -145,6 +147,9 @@ gst_gl_effects_set_effect (GstGLEffects *effects, gint effect_type) { case GST_GL_EFFECT_LUMA_XPRO: effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_luma_xpro; break; + case GST_GL_EFFECT_SIN: + effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sin; + break; case GST_GL_EFFECT_GLOW: effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_glow; break; diff --git a/gst/gl/gstgleffects.h b/gst/gl/gstgleffects.h index 3781ded..e0d3fa0 100644 --- a/gst/gl/gstgleffects.h +++ b/gst/gl/gstgleffects.h @@ -101,6 +101,7 @@ void gst_gl_effects_heat (GstGLEffects *effects); void gst_gl_effects_sepia (GstGLEffects *effects); void gst_gl_effects_xpro (GstGLEffects *effects); void gst_gl_effects_luma_xpro (GstGLEffects *effects); +void gst_gl_effects_sin (GstGLEffects *effects); void gst_gl_effects_glow (GstGLEffects *effects); G_END_DECLS diff --git a/tests/examples/gtk/fxtest/fxtest.c b/tests/examples/gtk/fxtest/fxtest.c index cc1c46a..f739540 100644 --- a/tests/examples/gtk/fxtest/fxtest.c +++ b/tests/examples/gtk/fxtest/fxtest.c @@ -176,6 +176,7 @@ main (gint argc, gchar * argv[]) gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "xpro"); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "lumaxpro"); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "sepia"); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "sin"); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "glow"); g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (apply_fx), filter);