summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippo Argiolas <filippo.argiolas@gmail.com>2010-04-29 12:59:42 +0200
committerFilippo Argiolas <filippo.argiolas@gmail.com>2010-04-29 14:06:19 +0200
commit2f0f2627b6022345625c0476f8d8a3620d929255 (patch)
tree5318eb1cce72fb687b984bb73f97e11e06ae5e4b
parent68304b96a1cbea812edefa12ef62af145661905a (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.c135
-rw-r--r--gst/gl/gstgleffects.h2
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,