3 * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * SECTION:element-glfilterlaplacian
24 * Laplacian Convolution Demo Filter.
27 * <title>Examples</title>
29 * gst-launch videotestsrc ! glupload ! glfilterlaplacian ! glimagesink
31 * FBO (Frame Buffer Object) and GLSL (OpenGL Shading Language) are required.
39 #include "gstglfilterlaplacian.h"
41 #define GST_CAT_DEFAULT gst_gl_filter_laplacian_debug
42 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
49 #define DEBUG_INIT(bla) \
50 GST_DEBUG_CATEGORY_INIT (gst_gl_filter_laplacian_debug, "glfilterlaplacian", 0, "glfilterlaplacian element");
52 GST_BOILERPLATE_FULL (GstGLFilterLaplacian, gst_gl_filter_laplacian,
53 GstGLFilter, GST_TYPE_GL_FILTER, DEBUG_INIT);
55 static void gst_gl_filter_laplacian_set_property (GObject * object,
56 guint prop_id, const GValue * value, GParamSpec * pspec);
57 static void gst_gl_filter_laplacian_get_property (GObject * object,
58 guint prop_id, GValue * value, GParamSpec * pspec);
60 static void gst_gl_filter_laplacian_reset (GstGLFilter * filter);
61 static void gst_gl_filter_laplacian_init_shader (GstGLFilter * filter);
62 static gboolean gst_gl_filter_laplacian_filter (GstGLFilter * filter,
63 GstGLBuffer * inbuf, GstGLBuffer * outbuf);
64 static void gst_gl_filter_laplacian_callback (gint width, gint height,
65 guint texture, gpointer stuff);
67 static const gchar *convolution_fragment_source =
68 "#extension GL_ARB_texture_rectangle : enable\n"
69 "uniform sampler2DRect tex;"
70 "uniform float norm_const;"
71 "uniform float norm_offset;"
72 "uniform float kernel[9];"
75 " offset[0] = vec2(-1.0,-1.0);"
76 " offset[1] = vec2( 0.0,-1.0);"
77 " offset[2] = vec2( 1.0,-1.0);"
78 " offset[3] = vec2(-1.0, 0.0);"
79 " offset[4] = vec2( 0.0, 0.0);"
80 " offset[5] = vec2( 1.0, 0.0);"
81 " offset[6] = vec2(-1.0, 1.0);"
82 " offset[7] = vec2( 0.0, 1.0);"
83 " offset[8] = vec2( 1.0, 1.0);"
84 " vec2 texturecoord = gl_TexCoord[0].st;"
86 " vec4 sum = vec4 (0.0);"
87 " for (i = 0; i < 9; i++) { "
88 " if (kernel[i] != 0.0) {"
89 " vec4 neighbor = texture2DRect(tex, texturecoord + vec2(offset[i])); "
90 " sum += neighbor * kernel[i]/norm_const; "
91 " }" " }" " gl_FragColor = sum + norm_offset;" "}";
94 gst_gl_filter_laplacian_base_init (gpointer klass)
96 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
98 gst_element_class_set_details_simple (element_class,
99 "OpenGL laplacian filter", "Filter/Effect",
100 "Laplacian Convolution Demo Filter",
101 "Filippo Argiolas <filippo.argiolas@gmail.com>");
105 gst_gl_filter_laplacian_class_init (GstGLFilterLaplacianClass * klass)
107 GObjectClass *gobject_class;
109 gobject_class = (GObjectClass *) klass;
110 gobject_class->set_property = gst_gl_filter_laplacian_set_property;
111 gobject_class->get_property = gst_gl_filter_laplacian_get_property;
113 GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filter_laplacian_filter;
114 GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filter_laplacian_init_shader;
115 GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_laplacian_reset;
119 gst_gl_filter_laplacian_init (GstGLFilterLaplacian * filter,
120 GstGLFilterLaplacianClass * klass)
122 filter->shader = NULL;
126 gst_gl_filter_laplacian_reset (GstGLFilter * filter)
128 GstGLFilterLaplacian *laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter);
130 //blocking call, wait the opengl thread has destroyed the shader
131 gst_gl_display_del_shader (filter->display, laplacian_filter->shader);
135 gst_gl_filter_laplacian_set_property (GObject * object, guint prop_id,
136 const GValue * value, GParamSpec * pspec)
138 //GstGLFilterLaplacian *filter = GST_GL_FILTER_LAPLACIAN (object);
142 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
148 gst_gl_filter_laplacian_get_property (GObject * object, guint prop_id,
149 GValue * value, GParamSpec * pspec)
151 //GstGLFilterLaplacian *filter = GST_GL_FILTER_LAPLACIAN (object);
155 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
161 gst_gl_filter_laplacian_init_shader (GstGLFilter * filter)
163 GstGLFilterLaplacian *laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter);
165 //blocking call, wait the opengl thread has compiled the shader
166 gst_gl_display_gen_shader (filter->display, 0, convolution_fragment_source,
167 &laplacian_filter->shader);
171 gst_gl_filter_laplacian_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
172 GstGLBuffer * outbuf)
174 gpointer laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter);
176 //blocking call, use a FBO
177 gst_gl_display_use_fbo (filter->display, filter->width, filter->height,
178 filter->fbo, filter->depthbuffer, outbuf->texture,
179 gst_gl_filter_laplacian_callback, inbuf->width, inbuf->height,
180 inbuf->texture, 0, filter->width, 0, filter->height,
181 GST_GL_DISPLAY_PROJECTION_ORTHO2D, laplacian_filter);
186 //opengl scene, params: input texture (not the output filter->texture)
188 gst_gl_filter_laplacian_callback (gint width, gint height, guint texture,
191 GstGLFilterLaplacian *laplacian_filter = GST_GL_FILTER_LAPLACIAN (stuff);
193 gfloat kernel[9] = { 0.0, -1.0, 0.0,
198 glMatrixMode (GL_PROJECTION);
201 gst_gl_shader_use (laplacian_filter->shader);
203 glActiveTexture (GL_TEXTURE0);
204 glEnable (GL_TEXTURE_RECTANGLE_ARB);
205 glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
207 gst_gl_shader_set_uniform_1i (laplacian_filter->shader, "tex", 0);
208 gst_gl_shader_set_uniform_1fv (laplacian_filter->shader, "kernel", 9, kernel);
209 gst_gl_shader_set_uniform_1f (laplacian_filter->shader, "norm_const", 1.0);
210 gst_gl_shader_set_uniform_1f (laplacian_filter->shader, "norm_offset", 0.0); //set to 0.5 to preserve overall greylevel
215 glVertex2f (-1.0f, -1.0f);
216 glTexCoord2i (width, 0);
217 glVertex2f (1.0f, -1.0f);
218 glTexCoord2i (width, height);
219 glVertex2f (1.0f, 1.0f);
220 glTexCoord2i (0, height);
221 glVertex2f (-1.0f, 1.0f);