diff options
author | Filippo Argiolas <filippo.argiolas@gmail.com> | 2010-04-29 12:59:42 +0200 |
---|---|---|
committer | Filippo Argiolas <filippo.argiolas@gmail.com> | 2010-04-29 14:06:19 +0200 |
commit | 2f0f2627b6022345625c0476f8d8a3620d929255 (patch) | |
tree | 5318eb1cce72fb687b984bb73f97e11e06ae5e4b | |
parent | 68304b96a1cbea812edefa12ef62af145661905a (diff) |
xray: port to the new separable sobel convolution
Port xray effect to use the same sobel convolution just used in
glfiltersobel. Now xray too works on i915 (a bit slow).
-rw-r--r-- | gst/gl/effects/gstgleffectxray.c | 135 | ||||
-rw-r--r-- | gst/gl/gstgleffects.h | 2 |
2 files changed, 115 insertions, 22 deletions
diff --git a/gst/gl/effects/gstgleffectxray.c b/gst/gl/effects/gstgleffectxray.c index d5f9e16..8abc3c1 100644 --- a/gst/gl/effects/gstgleffectxray.c +++ b/gst/gl/effects/gstgleffectxray.c @@ -108,34 +108,54 @@ gst_gl_effects_xray_step_three (gint width, gint height, guint texture, gst_gl_effects_draw_texture (effects, texture); } +/* multipass separable sobel */ static void -gst_gl_effects_xray_step_four (gint width, gint height, guint texture, +gst_gl_effects_xray_desaturate (gint width, gint height, guint texture, gpointer data) { GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLShader *shader; - gfloat hkern[9] = { - 1.0, 0.0, -1.0, - 2.0, 0.0, -2.0, - 1.0, 0.0, -1.0 - }; + shader = g_hash_table_lookup (effects->shaderstable, "xray_desat"); - gfloat vkern[9] = { - 1.0, 2.0, 1.0, - 0.0, 0.0, 0.0, - -1.0, -2.0, -1.0 - }; + if (!shader) { + shader = gst_gl_shader_new (); + g_hash_table_insert (effects->shaderstable, "xray_desat", shader); + } + + g_return_if_fail (gst_gl_shader_compile_and_check (shader, + desaturate_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + gst_gl_shader_use (shader); + + glActiveTexture (GL_TEXTURE1); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + glDisable (GL_TEXTURE_RECTANGLE_ARB); + + gst_gl_shader_set_uniform_1i (shader, "tex", 1); + gst_gl_effects_draw_texture (effects, texture); +} + +static void +gst_gl_effects_xray_sobel_hconv (gint width, gint height, guint texture, + gpointer data) +{ + GstGLEffects *effects = GST_GL_EFFECTS (data); + GstGLShader *shader; - shader = g_hash_table_lookup (effects->shaderstable, "xray3"); + shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_hconv"); if (!shader) { shader = gst_gl_shader_new (); - g_hash_table_insert (effects->shaderstable, "xray3", shader); + g_hash_table_insert (effects->shaderstable, "xray_sob_hconv", shader); } g_return_if_fail (gst_gl_shader_compile_and_check (shader, - sobel_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + sep_sobel_hconv3_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -148,15 +168,74 @@ gst_gl_effects_xray_step_four (gint width, gint height, guint texture, glDisable (GL_TEXTURE_RECTANGLE_ARB); gst_gl_shader_set_uniform_1i (shader, "tex", 1); + gst_gl_effects_draw_texture (effects, texture); +} - gst_gl_shader_set_uniform_1fv (shader, "hkern", 9, hkern); - gst_gl_shader_set_uniform_1fv (shader, "vkern", 9, vkern); +static void +gst_gl_effects_xray_sobel_vconv (gint width, gint height, guint texture, + gpointer data) +{ + GstGLEffects *effects = GST_GL_EFFECTS (data); + GstGLShader *shader; - gst_gl_shader_set_uniform_1i (shader, "invert", TRUE); + shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_vconv"); + + if (!shader) { + shader = gst_gl_shader_new (); + g_hash_table_insert (effects->shaderstable, "xray_sob_vconv", shader); + } + + g_return_if_fail (gst_gl_shader_compile_and_check (shader, + sep_sobel_vconv3_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + gst_gl_shader_use (shader); + + glActiveTexture (GL_TEXTURE1); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + glDisable (GL_TEXTURE_RECTANGLE_ARB); + + gst_gl_shader_set_uniform_1i (shader, "tex", 1); gst_gl_effects_draw_texture (effects, texture); } +static void +gst_gl_effects_xray_sobel_length (gint width, gint height, guint texture, + gpointer data) +{ + GstGLEffects *effects = GST_GL_EFFECTS (data); + GstGLShader *shader; + + shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_len"); + + if (!shader) { + shader = gst_gl_shader_new (); + g_hash_table_insert (effects->shaderstable, "xray_sob_len", shader); + } + + g_return_if_fail (gst_gl_shader_compile_and_check (shader, + sep_sobel_length_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + gst_gl_shader_use (shader); + + glActiveTexture (GL_TEXTURE1); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + glDisable (GL_TEXTURE_RECTANGLE_ARB); + + gst_gl_shader_set_uniform_1i (shader, "tex", 1); + gst_gl_shader_set_uniform_1i (shader, "invert", TRUE); + gst_gl_effects_draw_texture (effects, texture); +} + +/* end of sobel passes */ + void gst_gl_effects_xray_step_five (gint width, gint height, guint texture, gpointer stuff) @@ -191,7 +270,7 @@ gst_gl_effects_xray_step_five (gint width, gint height, guint texture, glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); glDisable (GL_TEXTURE_RECTANGLE_ARB); - gst_gl_shader_set_uniform_1f (shader, "alpha", (gfloat) 0.28f); + gst_gl_shader_set_uniform_1f (shader, "alpha", (gfloat) 0.4f); gst_gl_shader_set_uniform_1i (shader, "blend", 1); gst_gl_effects_draw_texture (effects, texture); @@ -212,9 +291,23 @@ gst_gl_effects_xray (GstGLEffects * effects) gst_gl_filter_render_to_target (filter, effects->midtexture[1], effects->midtexture[2], gst_gl_effects_xray_step_three, effects); /* detect edges with Sobel */ - gst_gl_filter_render_to_target (filter, effects->midtexture[2], - effects->midtexture[3], gst_gl_effects_xray_step_four, effects); - /* multiply edges with the blurred image */ + /* the old version used edges from the blurred texture, this uses + * the ones from original texture, still not sure what I like + * more. This one gives better edges obviously but behaves badly + * with noise */ + /* desaturate */ + gst_gl_filter_render_to_target (filter, effects->intexture, + effects->midtexture[3], gst_gl_effects_xray_desaturate, effects); + /* horizonal convolution */ gst_gl_filter_render_to_target (filter, effects->midtexture[3], + effects->midtexture[4], gst_gl_effects_xray_sobel_hconv, effects); + /* vertical convolution */ + gst_gl_filter_render_to_target (filter, effects->midtexture[4], + effects->midtexture[3], gst_gl_effects_xray_sobel_vconv, effects); + /* gradient length */ + gst_gl_filter_render_to_target (filter, effects->midtexture[3], + effects->midtexture[4], gst_gl_effects_xray_sobel_length, effects); + /* multiply edges with the blurred image */ + gst_gl_filter_render_to_target (filter, effects->midtexture[4], effects->outtexture, gst_gl_effects_xray_step_five, effects); } diff --git a/gst/gl/gstgleffects.h b/gst/gl/gstgleffects.h index aa219a0..4f38119 100644 --- a/gst/gl/gstgleffects.h +++ b/gst/gl/gstgleffects.h @@ -43,7 +43,7 @@ typedef struct _GstGLEffectsClass GstGLEffectsClass; typedef void (* GstGLEffectProcessFunc) (GstGLEffects *effects); -#define NEEDED_TEXTURES 4 +#define NEEDED_TEXTURES 5 enum { GST_GL_EFFECTS_CURVE_HEAT, |