diff options
-rw-r--r-- | gst/gl/effects/gstgleffectglow.c | 20 | ||||
-rw-r--r-- | gst/gl/effects/gstgleffectssources.c | 56 | ||||
-rw-r--r-- | gst/gl/effects/gstgleffectssources.h | 2 | ||||
-rw-r--r-- | gst/gl/effects/gstgleffectxray.c | 18 | ||||
-rw-r--r-- | gst/gl/gstgldifferencematte.c | 39 | ||||
-rw-r--r-- | gst/gl/gstgldifferencematte.h | 1 | ||||
-rw-r--r-- | gst/gl/gstglfilterblur.c | 30 | ||||
-rw-r--r-- | gst/gl/gstglfilterblur.h | 1 |
8 files changed, 74 insertions, 93 deletions
diff --git a/gst/gl/effects/gstgleffectglow.c b/gst/gl/effects/gstgleffectglow.c index 4930249..d6422e6 100644 --- a/gst/gl/effects/gstgleffectglow.c +++ b/gst/gl/effects/gstgleffectglow.c @@ -20,10 +20,8 @@ #include <gstgleffects.h> -static gfloat gauss_kernel[9] = { 0.060493f, 0.075284f, 0.088016f, - 0.096667f, 0.099736f, 0.096667f, - 0.088016f, 0.075284f, 0.060493f -}; +static gboolean kernel_ready = FALSE; +static float gauss_kernel[9]; static void gst_gl_effects_glow_step_one (gint width, gint height, guint texture, @@ -64,9 +62,6 @@ gst_gl_effects_glow_step_two (gint width, gint height, guint texture, GstGLEffects *effects = GST_GL_EFFECTS (stuff); GstGLShader *shader; - /* hard coded kernel, it could be easily generated at runtime with a - * property to change standard deviation */ - shader = g_hash_table_lookup (effects->shaderstable, "glow1"); if (!shader) { @@ -74,6 +69,11 @@ gst_gl_effects_glow_step_two (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "glow1", shader); } + if (!kernel_ready) { + fill_gaussian_kernel (gauss_kernel, 9, 10.0); + kernel_ready = TRUE; + } + g_return_if_fail (gst_gl_shader_compile_and_check (shader, hconv9_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); @@ -88,10 +88,7 @@ gst_gl_effects_glow_step_two (gint width, gint height, guint texture, glDisable (GL_TEXTURE_RECTANGLE_ARB); gst_gl_shader_set_uniform_1i (shader, "tex", 1); - gst_gl_shader_set_uniform_1fv (shader, "kernel", 9, gauss_kernel); - gst_gl_shader_set_uniform_1f (shader, "norm_const", 0.740656f); - gst_gl_shader_set_uniform_1f (shader, "norm_offset", 0.0f); gst_gl_effects_draw_texture (effects, texture); } @@ -124,10 +121,7 @@ gst_gl_effects_glow_step_three (gint width, gint height, guint texture, glDisable (GL_TEXTURE_RECTANGLE_ARB); gst_gl_shader_set_uniform_1i (shader, "tex", 1); - gst_gl_shader_set_uniform_1fv (shader, "kernel", 9, gauss_kernel); - gst_gl_shader_set_uniform_1f (shader, "norm_const", 0.740656f); - gst_gl_shader_set_uniform_1f (shader, "norm_offset", 0.0f); gst_gl_effects_draw_texture (effects, texture); } diff --git a/gst/gl/effects/gstgleffectssources.c b/gst/gl/effects/gstgleffectssources.c index 9ed7560..4defe95 100644 --- a/gst/gl/effects/gstgleffectssources.c +++ b/gst/gl/effects/gstgleffectssources.c @@ -20,6 +20,7 @@ #include <gstgleffects.h> #include <gstgleffectssources.h> +#include <math.h> /* A common file for sources is needed since shader sources can be * generic and reused by several effects */ @@ -28,6 +29,33 @@ /* Move sooner or later into single .frag .vert files and either bake * them into a c file at compile time or load them at run time */ + +/* fill a normalized and zero centered gaussian vector for separable + * gaussian convolution */ + +void +fill_gaussian_kernel (float *kernel, int size, float sigma) +{ + int i; + float sum; + int l; + + /* need an odd sized vector to center it at zero */ + g_return_if_fail ((size % 2) != 0); + + sum = 0.0; + l = (size - 1) / 2.0; + + for (i = 0; i < size; i++) { + kernel[i] = exp (-pow ((i - l), 2.0) / (2 * sigma)); + sum += kernel[i]; + } + + for (i = 0; i < size; i++) { + kernel[i] /= sum; + } +} + /* *INDENT-OFF* */ /* Vertex shader */ @@ -276,44 +304,36 @@ const gchar *sobel_fragment_source = const gchar *hconv9_fragment_source = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;" - "uniform float norm_const;" - "uniform float norm_offset;" "uniform float kernel[9];" "void main () {" -/* "float offset[9] = float[9] (-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0);" */ -/* don't use array constructor so we don't have to depend on #version 120 */ - " float offset = - 4.0;" " vec2 texturecoord = gl_TexCoord[0].st;" + " texturecoord.s -= 4.0;" " int i;" " vec4 sum = vec4 (0.0);" " for (i = 0; i < 9; i++) { " - " ++offset;" - " vec4 neighbor = texture2DRect(tex, vec2(texturecoord.s+offset, texturecoord.t)); " - " sum += neighbor * kernel[i]/norm_const; " + " vec4 neighbor = texture2DRect(tex, texturecoord); " + " ++texturecoord.s;" + " sum += neighbor * kernel[i];" " }" - " gl_FragColor = sum + norm_offset;" + " gl_FragColor = sum;" "}"; /* vertical convolution */ const gchar *vconv9_fragment_source = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;" - "uniform float norm_const;" - "uniform float norm_offset;" "uniform float kernel[9];" "void main () {" -/* "float offset[9] = float[9] (-4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0);" */ -/* don't use array constructor so we don't have to depend on #version 120 */ - " float offset = - 4.0;" " vec2 texturecoord = gl_TexCoord[0].st;" + " texturecoord.t -= 4.0;" " int i;" " vec4 sum = vec4 (0.0);" " for (i = 0; i < 9; i++) { " - " ++offset;" - " vec4 neighbor = texture2DRect(tex, vec2(texturecoord.s, texturecoord.t+offset)); " - " sum += neighbor * kernel[i]/norm_const; " + " vec4 neighbor = texture2DRect(tex, texturecoord); " + " ++texturecoord.t;" + " sum += neighbor * kernel[i]; " " }" - " gl_FragColor = sum + norm_offset;" + " gl_FragColor = sum;" "}"; diff --git a/gst/gl/effects/gstgleffectssources.h b/gst/gl/effects/gstgleffectssources.h index c93c59b..20bc991 100644 --- a/gst/gl/effects/gstgleffectssources.h +++ b/gst/gl/effects/gstgleffectssources.h @@ -44,4 +44,6 @@ extern const gchar *texture_interp_fragment_source; extern const gchar *difference_fragment_source; extern const gchar *multiply_fragment_source; +void fill_gaussian_kernel (float *kernel, int size, float sigma); + #endif /* __GST_GL_EFFECTS_SOURCES_H__ */ diff --git a/gst/gl/effects/gstgleffectxray.c b/gst/gl/effects/gstgleffectxray.c index d086843..d5f9e16 100644 --- a/gst/gl/effects/gstgleffectxray.c +++ b/gst/gl/effects/gstgleffectxray.c @@ -22,11 +22,8 @@ #include <gstgleffectscurves.h> #include <gstgleffectlumatocurve.h> -/* Gaussian Kernel: std = 1.200000, size = 9x1 */ -static gfloat gauss_kernel[9] = { 0.001285f, 0.014607f, 0.082898f, - 0.234927f, 0.332452f, 0.234927f, - 0.082898f, 0.014607f, 0.001285f -}; +static gboolean kernel_ready = FALSE; +static float gauss_kernel[9]; /* Normalization Constant = 0.999885 */ @@ -54,6 +51,11 @@ gst_gl_effects_xray_step_two (gint width, gint height, guint texture, g_hash_table_insert (effects->shaderstable, "xray1", shader); } + if (!kernel_ready) { + fill_gaussian_kernel (gauss_kernel, 9, 1.5); + kernel_ready = TRUE; + } + g_return_if_fail (gst_gl_shader_compile_and_check (shader, hconv9_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)); @@ -68,10 +70,7 @@ gst_gl_effects_xray_step_two (gint width, gint height, guint texture, glDisable (GL_TEXTURE_RECTANGLE_ARB); gst_gl_shader_set_uniform_1i (shader, "tex", 1); - gst_gl_shader_set_uniform_1fv (shader, "kernel", 9, gauss_kernel); - gst_gl_shader_set_uniform_1f (shader, "norm_const", 0.999885f); - gst_gl_shader_set_uniform_1f (shader, "norm_offset", 0.0f); gst_gl_effects_draw_texture (effects, texture); } @@ -104,10 +103,7 @@ gst_gl_effects_xray_step_three (gint width, gint height, guint texture, glDisable (GL_TEXTURE_RECTANGLE_ARB); gst_gl_shader_set_uniform_1i (shader, "tex", 1); - gst_gl_shader_set_uniform_1fv (shader, "kernel", 9, gauss_kernel); - gst_gl_shader_set_uniform_1f (shader, "norm_const", 0.999885f); - gst_gl_shader_set_uniform_1f (shader, "norm_offset", 0.0f); gst_gl_effects_draw_texture (effects, texture); } diff --git a/gst/gl/gstgldifferencematte.c b/gst/gl/gstgldifferencematte.c index 59cfc25..4e3f7a8 100644 --- a/gst/gl/gstgldifferencematte.c +++ b/gst/gl/gstgldifferencematte.c @@ -203,6 +203,8 @@ gst_gl_differencematte_init (GstGLDifferenceMatte * differencematte, differencematte->savedbgtexture = 0; differencematte->newbgtexture = 0; differencematte->bg_has_changed = FALSE; + + fill_gaussian_kernel (differencematte->kernel, 9, 3.0); } static void @@ -274,8 +276,8 @@ init_pixbuf_texture (GstGLDisplay * display, gpointer data) glGenTextures (1, &differencematte->newbgtexture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, differencematte->newbgtexture); glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, - (gint) differencematte->pbuf_width, (gint) differencematte->pbuf_height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, differencematte->pixbuf); + (gint) differencematte->pbuf_width, (gint) differencematte->pbuf_height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, differencematte->pixbuf); if (differencematte->savedbgtexture == 0) { glGenTextures (1, &differencematte->savedbgtexture); @@ -326,11 +328,6 @@ gst_gl_differencematte_hblur (gint width, gint height, guint texture, gpointer stuff) { GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff); - gfloat gauss_kernel[9] = { - 0.026995f, 0.064759f, 0.120985f, - 0.176033f, 0.199471f, 0.176033f, - 0.120985f, 0.064759f, 0.026995f - }; glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -345,11 +342,7 @@ gst_gl_differencematte_hblur (gint width, gint height, guint texture, 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); + differencematte->kernel); gst_gl_differencematte_draw_texture (differencematte, texture); } @@ -359,11 +352,6 @@ gst_gl_differencematte_vblur (gint width, gint height, guint texture, gpointer stuff) { GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff); - gfloat gauss_kernel[9] = { - 0.026995f, 0.064759f, 0.120985f, - 0.176033f, 0.199471f, 0.176033f, - 0.120985f, 0.064759f, 0.026995f - }; glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -378,11 +366,7 @@ gst_gl_differencematte_vblur (gint width, gint height, guint texture, 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); + differencematte->kernel); gst_gl_differencematte_draw_texture (differencematte, texture); } @@ -413,14 +397,14 @@ gst_gl_differencematte_interp (gint width, gint height, guint texture, gst_gl_shader_set_uniform_1i (differencematte->shader[3], "base", 1); gst_gl_shader_set_uniform_1f (differencematte->shader[3], - "base_width", (gfloat) differencematte->pbuf_width); + "base_width", (gfloat) differencematte->pbuf_width); gst_gl_shader_set_uniform_1f (differencematte->shader[3], - "base_height", (gfloat) differencematte->pbuf_height); + "base_height", (gfloat) differencematte->pbuf_height); gst_gl_shader_set_uniform_1f (differencematte->shader[3], - "final_width", (gfloat) filter->width); + "final_width", (gfloat) filter->width); gst_gl_shader_set_uniform_1f (differencematte->shader[3], - "final_height", (gfloat) filter->height); + "final_height", (gfloat) filter->height); glActiveTexture (GL_TEXTURE2); glEnable (GL_TEXTURE_RECTANGLE_ARB); @@ -572,7 +556,8 @@ gst_gl_differencematte_loader (GstGLFilter * filter) differencematte->pbuf_width = width; differencematte->pbuf_height = height; - differencematte->pixbuf = (guchar *) malloc (sizeof (guchar) * width * height * 4); + differencematte->pixbuf = + (guchar *) malloc (sizeof (guchar) * width * height * 4); rows = (guchar **) malloc (sizeof (guchar *) * height); diff --git a/gst/gl/gstgldifferencematte.h b/gst/gl/gstgldifferencematte.h index 50c7070..06f1d0a 100644 --- a/gst/gl/gstgldifferencematte.h +++ b/gst/gl/gstgldifferencematte.h @@ -48,6 +48,7 @@ struct _GstGLDifferenceMatte GLuint newbgtexture; GLuint midtexture[4]; GLuint intexture; + float kernel[9]; }; struct _GstGLDifferenceMatteClass diff --git a/gst/gl/gstglfilterblur.c b/gst/gl/gstglfilterblur.c index 8853a5c..f2c561f 100644 --- a/gst/gl/gstglfilterblur.c +++ b/gst/gl/gstglfilterblur.c @@ -125,6 +125,10 @@ gst_gl_filterblur_init (GstGLFilterBlur * filterblur, filterblur->shader0 = NULL; filterblur->shader1 = NULL; filterblur->midtexture = 0; + /* gaussian kernel (well, actually vector), size 9, standard + * deviation 3.0 */ + /* FIXME: eventually make this a runtime property */ + fill_gaussian_kernel (filterblur->gauss_kernel, 9, 3.0); } static void @@ -223,14 +227,6 @@ gst_gl_filterblur_hcallback (gint width, gint height, guint texture, { GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (stuff); - /* hard coded kernel, it could be easily generated at runtime with a - * property to change standard deviation */ - gfloat gauss_kernel[9] = { - 0.026995f, 0.064759f, 0.120985f, - 0.176033f, 0.199471f, 0.176033f, - 0.120985f, 0.064759f, 0.026995f - }; - glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -242,11 +238,8 @@ gst_gl_filterblur_hcallback (gint width, gint height, guint texture, glDisable (GL_TEXTURE_RECTANGLE_ARB); gst_gl_shader_set_uniform_1i (filterblur->shader0, "tex", 1); - gst_gl_shader_set_uniform_1fv (filterblur->shader0, "kernel", 9, - gauss_kernel); - gst_gl_shader_set_uniform_1f (filterblur->shader0, "norm_const", 0.977016f); - gst_gl_shader_set_uniform_1f (filterblur->shader0, "norm_offset", 0.0f); + filterblur->gauss_kernel); gst_gl_filterblur_draw_texture (filterblur, texture); } @@ -258,14 +251,6 @@ gst_gl_filterblur_vcallback (gint width, gint height, guint texture, { GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (stuff); - /* hard coded kernel, it could be easily generated at runtime with a - * property to change standard deviation */ - gfloat gauss_kernel[9] = { - 0.026995f, 0.064759f, 0.120985f, - 0.176033f, 0.199471f, 0.176033f, - 0.120985f, 0.064759f, 0.026995f - }; - glMatrixMode (GL_PROJECTION); glLoadIdentity (); @@ -277,11 +262,8 @@ gst_gl_filterblur_vcallback (gint width, gint height, guint texture, glDisable (GL_TEXTURE_RECTANGLE_ARB); gst_gl_shader_set_uniform_1i (filterblur->shader1, "tex", 1); - gst_gl_shader_set_uniform_1fv (filterblur->shader1, "kernel", 9, - gauss_kernel); - gst_gl_shader_set_uniform_1f (filterblur->shader1, "norm_const", 0.977016f); - gst_gl_shader_set_uniform_1f (filterblur->shader1, "norm_offset", 0.0f); + filterblur->gauss_kernel); gst_gl_filterblur_draw_texture (filterblur, texture); } diff --git a/gst/gl/gstglfilterblur.h b/gst/gl/gstglfilterblur.h index 7a5f8ae..7157281 100644 --- a/gst/gl/gstglfilterblur.h +++ b/gst/gl/gstglfilterblur.h @@ -40,6 +40,7 @@ struct _GstGLFilterBlur GstGLShader *shader1; GLuint midtexture; + float gauss_kernel[9]; }; struct _GstGLFilterBlurClass |