From: Filippo Argiolas Date: Mon, 18 Aug 2008 19:40:26 +0000 (+0200) Subject: [192/906] complete differencematte filter.. I did it quickly, probably still needs... X-Git-Tag: 1.19.3~507^2~12340 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8024aa7483bbdcc0dad761db3acf14162bbf5ce1;p=platform%2Fupstream%2Fgstreamer.git [192/906] complete differencematte filter.. I did it quickly, probably still needs some work --- diff --git a/gst/gl/effects/gstgleffectssources.c b/gst/gl/effects/gstgleffectssources.c index ce31a25..63b2969 100644 --- a/gst/gl/effects/gstgleffectssources.c +++ b/gst/gl/effects/gstgleffectssources.c @@ -359,6 +359,19 @@ const gchar *interpolate_fragment_source = "gl_FragColor = blendcolor + (1.0 - blendcolor.a) * basecolor;" "}"; +const gchar *texture_interp_fragment_source = + "#extension GL_ARB_texture_rectangle : enable\n" + "uniform sampler2DRect base;" + "uniform sampler2DRect blend;" + "uniform sampler2DRect alpha;" + "void main () {" + "vec4 basecolor = texture2DRect (base, gl_TexCoord[0].st);" + "vec4 blendcolor = texture2DRect (blend, gl_TexCoord[0].st);" + "vec4 alphacolor = texture2DRect (alpha, gl_TexCoord[0].st);" +// "gl_FragColor = alphacolor;" + "gl_FragColor = (alphacolor * blendcolor) + (1.0 - alphacolor) * basecolor;" + "}"; + const gchar *difference_fragment_source = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect saved;" diff --git a/gst/gl/effects/gstgleffectssources.h b/gst/gl/effects/gstgleffectssources.h index 250c7e8..e2ec79e 100644 --- a/gst/gl/effects/gstgleffectssources.h +++ b/gst/gl/effects/gstgleffectssources.h @@ -37,6 +37,7 @@ const gchar *luma_to_curve_fragment_source; const gchar *rgb_to_curve_fragment_source; const gchar *sin_fragment_source; const gchar *interpolate_fragment_source; +const gchar *texture_interp_fragment_source; const gchar *difference_fragment_source; #endif /* __GST_GL_EFFECTS_SOURCES_H__ */ diff --git a/gst/gl/gstgldifferencematte.c b/gst/gl/gstgldifferencematte.c index bf5bf13..9d6c644 100644 --- a/gst/gl/gstgldifferencematte.c +++ b/gst/gl/gstgldifferencematte.c @@ -46,6 +46,7 @@ struct _GstGLDifferenceMatte GLuint savedbgtexture; GLuint newbgtexture; GLuint midtexture[4]; + GLuint intexture; }; struct _GstGLDifferenceMatteClass @@ -96,8 +97,17 @@ gst_gl_differencematte_init_gl_resources (GstGLFilter *filter) GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter); gint i; - for (i=0; i<3; i++) + for (i=0; i<4; i++) { + glGenTextures (1, &differencematte->midtexture[i]); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, differencematte->midtexture[i]); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, + filter->width, filter->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); differencematte->shader[i] = gst_gl_shader_new (); + } g_return_if_fail ( gst_gl_shader_compile_and_check (differencematte->shader[0], @@ -109,12 +119,13 @@ gst_gl_differencematte_init_gl_resources (GstGLFilter *filter) GST_GL_SHADER_FRAGMENT_SOURCE)); g_return_if_fail ( - gst_gl_shader_compile_and_check (differencematte->shader[1], + gst_gl_shader_compile_and_check (differencematte->shader[2], vconv9_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); + g_return_if_fail ( - gst_gl_shader_compile_and_check (differencematte->shader[1], - interpolate_fragment_source, + gst_gl_shader_compile_and_check (differencematte->shader[3], + texture_interp_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); } @@ -127,8 +138,10 @@ gst_gl_differencematte_reset_gl_resources (GstGLFilter *filter) glDeleteTextures (1, &differencematte->savedbgtexture); glDeleteTextures (1, &differencematte->newbgtexture); - for (i=0; i<3; i++) + for (i=0; i<4; i++) { g_object_unref (differencematte->shader[i]); + glDeleteTextures (1, &differencematte->midtexture[i]); + } } static void @@ -258,8 +271,33 @@ gst_gl_differencematte_save_texture (gint width, gint height, guint texture, gpo gst_gl_differencematte_draw_texture (differencematte, texture); } +static void init_pixbuf_texture (GstGLDisplay *display, gpointer data) +{ + GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (data); + GstGLFilter *filter = GST_GL_FILTER (data); + + glDeleteTextures (1, &differencematte->newbgtexture); + glGenTextures (1, &differencematte->newbgtexture); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, differencematte->newbgtexture); + glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, + filter->width, filter->height, 0, + gdk_pixbuf_get_has_alpha (differencematte->pixbuf) ? GL_RGBA : GL_RGB, + GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels (differencematte->pixbuf)); + + if (differencematte->savedbgtexture == 0) { + glGenTextures (1, &differencematte->savedbgtexture); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, differencematte->savedbgtexture); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, + filter->width, filter->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } +} + static void -gst_gl_differencematte_callback (gint width, gint height, guint texture, gpointer stuff) +gst_gl_differencematte_diff (gint width, gint height, guint texture, gpointer stuff) { GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE (stuff); @@ -285,29 +323,97 @@ gst_gl_differencematte_callback (gint width, gint height, guint texture, gpointe gst_gl_differencematte_draw_texture (differencematte, texture); } -static void init_pixbuf_texture (GstGLDisplay *display, gpointer data) +static void +gst_gl_differencematte_hblur (gint width, gint height, guint texture, gpointer stuff) { - GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (data); - GstGLFilter *filter = GST_GL_FILTER (data); + GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE (stuff); + gfloat gauss_kernel[9] = { + 0.026995, 0.064759, 0.120985, + 0.176033, 0.199471, 0.176033, + 0.120985, 0.064759, 0.026995 + }; + - glDeleteTextures (1, &differencematte->newbgtexture); - glGenTextures (1, &differencematte->newbgtexture); + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + gst_gl_shader_use (differencematte->shader[1]); + + glActiveTexture (GL_TEXTURE0); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + glDisable(GL_TEXTURE_RECTANGLE_ARB); + + gst_gl_shader_set_uniform_1i (differencematte->shader[1], "tex", 0); + + gst_gl_shader_set_uniform_1fv (differencematte->shader[1], "kernel", 9, gauss_kernel); + gst_gl_shader_set_uniform_1f (differencematte->shader[1], "norm_const", 0.977016f); + gst_gl_shader_set_uniform_1f (differencematte->shader[1], "norm_offset", 0.0f); + + gst_gl_differencematte_draw_texture (differencematte, texture); +} + +static void +gst_gl_differencematte_vblur (gint width, gint height, guint texture, gpointer stuff) +{ + GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE (stuff); + gfloat gauss_kernel[9] = { + 0.026995, 0.064759, 0.120985, + 0.176033, 0.199471, 0.176033, + 0.120985, 0.064759, 0.026995 + }; + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + gst_gl_shader_use (differencematte->shader[2]); + + glActiveTexture (GL_TEXTURE0); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + glDisable(GL_TEXTURE_RECTANGLE_ARB); + + gst_gl_shader_set_uniform_1i (differencematte->shader[2], "tex", 0); + + gst_gl_shader_set_uniform_1fv (differencematte->shader[2], "kernel", 9, gauss_kernel); + gst_gl_shader_set_uniform_1f (differencematte->shader[2], "norm_const", 0.977016f); + gst_gl_shader_set_uniform_1f (differencematte->shader[2], "norm_offset", 0.0f); + + gst_gl_differencematte_draw_texture (differencematte, texture); +} + +static void +gst_gl_differencematte_interp (gint width, gint height, guint texture, gpointer stuff) +{ + GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE (stuff); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + gst_gl_shader_use (differencematte->shader[3]); + + glActiveTexture (GL_TEXTURE0); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + glDisable(GL_TEXTURE_RECTANGLE_ARB); + + gst_gl_shader_set_uniform_1i (differencematte->shader[3], "base", 0); + + glActiveTexture (GL_TEXTURE1); + glEnable (GL_TEXTURE_RECTANGLE_ARB); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, differencematte->newbgtexture); - glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, - filter->width, filter->height, 0, - gdk_pixbuf_get_has_alpha (differencematte->pixbuf) ? GL_RGBA : GL_RGB, - GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels (differencematte->pixbuf)); + glDisable (GL_TEXTURE_RECTANGLE_ARB); - if (differencematte->savedbgtexture == 0) { - glGenTextures (1, &differencematte->savedbgtexture); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, differencematte->savedbgtexture); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, - filter->width, filter->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } + gst_gl_shader_set_uniform_1i (differencematte->shader[3], "blend", 1); + + glActiveTexture (GL_TEXTURE2); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, differencematte->midtexture[2]); + glDisable (GL_TEXTURE_RECTANGLE_ARB); + + gst_gl_shader_set_uniform_1i (differencematte->shader[3], "alpha", 2); + + gst_gl_differencematte_draw_texture (differencematte, texture); } static gboolean @@ -318,6 +424,8 @@ gst_gl_differencematte_filter (GstGLFilter* filter, GstGLBuffer* inbuf, GdkPixbuf *pixbuf; GError *error = NULL; + differencematte->intexture = inbuf->texture; + if (differencematte->bg_has_changed && (differencematte->location != NULL)) { pixbuf = gdk_pixbuf_new_from_file (differencematte->location, &error); if (pixbuf) { @@ -343,8 +451,20 @@ gst_gl_differencematte_filter (GstGLFilter* filter, GstGLBuffer* inbuf, differencematte->bg_has_changed = FALSE; } - gst_gl_filter_render_to_target (filter, inbuf->texture, outbuf->texture, - gst_gl_differencematte_callback, differencematte); + gst_gl_filter_render_to_target (filter, inbuf->texture, differencematte->midtexture[0], + gst_gl_differencematte_diff, differencematte); + gst_gl_filter_render_to_target (filter, + differencematte->midtexture[0], + differencematte->midtexture[1], + gst_gl_differencematte_hblur, differencematte); + gst_gl_filter_render_to_target (filter, + differencematte->midtexture[1], + differencematte->midtexture[2], + gst_gl_differencematte_vblur, differencematte); + gst_gl_filter_render_to_target (filter, + inbuf->texture, + outbuf->texture, + gst_gl_differencematte_interp, differencematte); return TRUE; }