effects/gstgleffectidentity.c \
effects/gstgleffectmirror.c \
effects/gstgleffectsqueeze.c \
+ effects/gstgleffectstretch.c \
+ effects/gstgleffectfisheye.c \
+ effects/gstgleffecttwirl.c \
+ effects/gstgleffectbulge.c \
+ effects/gstgleffecttunnel.c \
+ effects/gstgleffectsquare.c \
+ effects/gstgleffectlumatocurve.c \
+ effects/gstgleffectrgbtocurve.c \
+ effects/gstgleffectsin.c \
+ effects/gstgleffectxray.c \
+ effects/gstgleffectglow.c \
gstglcolorscale.c \
gstglmixer.c \
gstglvideomixer.c \
gstgldeinterlace.c \
gltestsrc.c \
gstgltestsrc.c \
- gstglmosaic.c \
- effects/gstgleffectstretch.c \
- effects/gstgleffecttunnel.c \
- effects/gstgleffectfisheye.c \
- effects/gstgleffecttwirl.c \
- effects/gstgleffectbulge.c \
- effects/gstgleffectsquare.c \
- effects/gstgleffectlumatocurve.c \
- effects/gstgleffectrgbtocurve.c \
- effects/gstgleffectsin.c \
- effects/gstgleffectglow.c \
- effects/gstgleffectxray.c
+ gstglmosaic.c
noinst_HEADERS += \
gstglfilterblur.h \
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "bulge0");
+ shader = gst_gl_effects_get_fragment_shader (effects, "bulge",
+ bulge_fragment_source_gles2, bulge_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "bulge0", shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- bulge_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize bulge shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
gst_gl_shader_set_uniform_1i (shader, "tex", 0);
- gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
- gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
-
gst_gl_filter_draw_texture (filter, texture, width, height);
}
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "fisheye0");
+ shader = gst_gl_effects_get_fragment_shader (effects, "fisheye",
+ fisheye_fragment_source_gles2, fisheye_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "fisheye0", shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- fisheye_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize fisheye shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
gst_gl_shader_set_uniform_1i (shader, "tex", 0);
- gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
- gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
-
gst_gl_filter_draw_texture (filter, texture, width, height);
}
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "glow0");
+ shader = gst_gl_effects_get_fragment_shader (effects, "luma_threshold",
+ luma_threshold_fragment_source_gles2,
+ luma_threshold_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "glow0", shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- luma_threshold_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context,
- "Failed to initialize luma threshold shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "glow1");
+ shader = gst_gl_effects_get_fragment_shader (effects, "hconv7",
+ hconv7_fragment_source_gles2, hconv7_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "glow1", shader);
- }
+ if (!shader)
+ return;
if (!kernel_ready) {
fill_gaussian_kernel (gauss_kernel, 7, 10.0);
kernel_ready = TRUE;
}
-
- if (!gst_gl_shader_compile_and_check (shader,
- hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize hconv7 shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
- return;
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
}
-
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#endif
gst_gl_shader_use (shader);
gst_gl_shader_set_uniform_1i (shader, "tex", 1);
gst_gl_shader_set_uniform_1fv (shader, "kernel", 7, gauss_kernel);
- gst_gl_shader_set_uniform_1f (shader, "height", height);
+ gst_gl_shader_set_uniform_1f (shader, "gauss_width", height);
gst_gl_filter_draw_texture (filter, texture, width, height);
}
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "glow2");
-
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "glow2", shader);
- }
+ shader = gst_gl_effects_get_fragment_shader (effects, "vconv7",
+ vconv7_fragment_source_gles2, vconv7_fragment_source_opengl);
- if (!gst_gl_shader_compile_and_check (shader,
- vconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize vcon7 shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
gst_gl_shader_set_uniform_1i (shader, "tex", 1);
gst_gl_shader_set_uniform_1fv (shader, "kernel", 7, gauss_kernel);
- gst_gl_shader_set_uniform_1f (shader, "width", width);
+ gst_gl_shader_set_uniform_1f (shader, "gauss_height", width);
gst_gl_filter_draw_texture (filter, texture, width, height);
}
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "glow3");
-
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "glow3", shader);
- }
+ shader = gst_gl_effects_get_fragment_shader (effects, "sum",
+ sum_fragment_source_gles2, sum_fragment_source_opengl);
- if (!gst_gl_shader_compile_and_check (shader,
- sum_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize sum shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
gl->BindTexture (GL_TEXTURE_2D, effects->intexture);
gl->Disable (GL_TEXTURE_2D);
- gst_gl_shader_set_uniform_1f (shader, "alpha", 1.0);
+ gst_gl_shader_set_uniform_1f (shader, "alpha", 1.0f);
gst_gl_shader_set_uniform_1i (shader, "base", 2);
gl->ActiveTexture (GL_TEXTURE1);
/* threshold */
gst_gl_filter_render_to_target (filter, TRUE, effects->intexture,
effects->midtexture[0], gst_gl_effects_glow_step_one, effects);
+
/* blur */
gst_gl_filter_render_to_target (filter, FALSE, effects->midtexture[0],
effects->midtexture[1], gst_gl_effects_glow_step_two, effects);
+
gst_gl_filter_render_to_target (filter, FALSE, effects->midtexture[1],
effects->midtexture[2], gst_gl_effects_glow_step_three, effects);
+
/* add blurred luma to intexture */
gst_gl_filter_render_to_target (filter, FALSE, effects->midtexture[2],
effects->outtexture, gst_gl_effects_glow_step_four, effects);
#include "../gstgleffects.h"
-#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
-#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
-#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
-#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
-#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
-
static void
gst_gl_effects_identity_callback (gint width, gint height, guint texture,
gpointer data)
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "lumamap0");
+ shader = gst_gl_effects_get_fragment_shader (effects, "luma_to_curve",
+ luma_to_curve_fragment_source_gles2,
+ luma_to_curve_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "lumamap0", shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- luma_to_curve_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context,
- "Failed to initialize luma to curve shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
if (effects->curve[curve_index] == 0) {
/* this parameters are needed to have a right, predictable, mapping */
gl->GenTextures (1, &effects->curve[curve_index]);
- gl->Enable (GL_TEXTURE_1D);
- gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
- gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- gl->TexImage1D (GL_TEXTURE_1D, 0, curve->bytes_per_pixel,
- curve->width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->Enable (GL_TEXTURE_1D);
+ gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
+ gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- gl->Disable (GL_TEXTURE_1D);
+ gl->TexImage1D (GL_TEXTURE_1D, 0, curve->bytes_per_pixel,
+ curve->width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
+
+ gl->Disable (GL_TEXTURE_1D);
+ }
+#endif
+ if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
+ gl->Enable (GL_TEXTURE_2D);
+ gl->BindTexture (GL_TEXTURE_2D, effects->curve[curve_index]);
+ gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ gl->TexImage2D (GL_TEXTURE_2D, 0, GL_RGB,
+ curve->width, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
+ gl->Disable (GL_TEXTURE_2D);
+ }
}
gl->ActiveTexture (GL_TEXTURE2);
gl->Disable (GL_TEXTURE_2D);
- gl->ActiveTexture (GL_TEXTURE1);
- gl->Enable (GL_TEXTURE_1D);
- gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->ActiveTexture (GL_TEXTURE1);
+ gl->Enable (GL_TEXTURE_1D);
+ gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
- gst_gl_shader_set_uniform_1i (shader, "curve", 1);
+ gst_gl_shader_set_uniform_1i (shader, "curve", 1);
- gl->Disable (GL_TEXTURE_1D);
+ gl->Disable (GL_TEXTURE_1D);
+ }
+#endif
+ if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
+ gl->ActiveTexture (GL_TEXTURE1);
+ gl->Enable (GL_TEXTURE_2D);
+ gl->BindTexture (GL_TEXTURE_2D, effects->curve[curve_index]);
+
+ gst_gl_shader_set_uniform_1i (shader, "curve", 1);
+
+ gl->Disable (GL_TEXTURE_2D);
+ }
gst_gl_filter_draw_texture (filter, texture, width, height);
}
#include "../gstgleffects.h"
-#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
-#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
-#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
-#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
-#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
-
static void
gst_gl_effects_mirror_callback (gint width, gint height, guint texture,
gpointer data)
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "mirror0");
-
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "mirror0", shader);
+ shader = gst_gl_effects_get_fragment_shader (effects, "mirror",
+ mirror_fragment_source_gles2, mirror_fragment_source_opengl);
- if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
- if (!gst_gl_shader_compile_with_default_v_and_check (shader,
- mirror_fragment_source_gles2, &filter->draw_attr_position_loc,
- &filter->draw_attr_texture_loc)) {
- /* gst gl context error is already set */
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("Failed to initialize squeeze shader, %s",
- gst_gl_context_get_error ()), (NULL));
- return;
- }
- }
-#if GST_GL_HAVE_OPENGL
- if (USING_OPENGL (context)) {
- if (!gst_gl_shader_compile_and_check (shader,
- mirror_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context,
- "Failed to initialize mirror shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
- return;
- }
+ if (!shader)
+ return;
- }
-#endif
- }
#if GST_GL_HAVE_OPENGL
if (USING_OPENGL (context)) {
gl->MatrixMode (GL_PROJECTION);
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "rgbmap0");
+ shader = gst_gl_effects_get_fragment_shader (effects, "rgb_to_curve",
+ rgb_to_curve_fragment_source_gles2, rgb_to_curve_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "rgbmap0", shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- rgb_to_curve_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context,
- "Failed to initialize rgb to curve shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
if (effects->curve[curve_index] == 0) {
/* this parameters are needed to have a right, predictable, mapping */
gl->GenTextures (1, &effects->curve[curve_index]);
- gl->Enable (GL_TEXTURE_1D);
- gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
- gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-
- gl->TexImage1D (GL_TEXTURE_1D, 0, curve->bytes_per_pixel,
- curve->width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
-
- gl->Disable (GL_TEXTURE_1D);
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->Enable (GL_TEXTURE_1D);
+ gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
+ gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ gl->TexImage1D (GL_TEXTURE_1D, 0, GL_RGB,
+ curve->width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
+
+ gl->Disable (GL_TEXTURE_1D);
+ }
+#endif
+ if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
+ gl->Enable (GL_TEXTURE_2D);
+ gl->BindTexture (GL_TEXTURE_2D, effects->curve[curve_index]);
+ gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ gl->TexImage2D (GL_TEXTURE_2D, 0, GL_RGB,
+ curve->width, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
+ gl->Disable (GL_TEXTURE_2D);
+ }
}
gl->ActiveTexture (GL_TEXTURE0);
gl->Disable (GL_TEXTURE_2D);
- gl->ActiveTexture (GL_TEXTURE1);
- gl->Enable (GL_TEXTURE_1D);
- gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->ActiveTexture (GL_TEXTURE1);
+ gl->Enable (GL_TEXTURE_1D);
+ gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
- gst_gl_shader_set_uniform_1i (shader, "curve", 1);
+ gst_gl_shader_set_uniform_1i (shader, "curve", 1);
- gl->Disable (GL_TEXTURE_1D);
+ gl->Disable (GL_TEXTURE_1D);
+ }
+#endif
+ if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
+ gl->ActiveTexture (GL_TEXTURE1);
+ gl->Enable (GL_TEXTURE_2D);
+ gl->BindTexture (GL_TEXTURE_2D, effects->curve[curve_index]);
+
+ gst_gl_shader_set_uniform_1i (shader, "curve", 1);
+
+ gl->Disable (GL_TEXTURE_2D);
+ }
gst_gl_filter_draw_texture (filter, texture, width, height);
}
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "sin0");
+ shader = gst_gl_effects_get_fragment_shader (effects, "sin",
+ sin_fragment_source_gles2, sin_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "sin0", shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- sin_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize sin shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "square0");
+ shader = gst_gl_effects_get_fragment_shader (effects, "square",
+ square_fragment_source_gles2, square_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "square0", shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- square_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize square shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
gst_gl_shader_set_uniform_1i (shader, "tex", 0);
- gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
- gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
-
gst_gl_filter_draw_texture (filter, texture, width, height);
}
#include "../gstgleffects.h"
-#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
-#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
-#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
-#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
-#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
-
static void
gst_gl_effects_squeeze_callback (gint width, gint height, guint texture,
gpointer data)
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "squeeze0");
+ shader = gst_gl_effects_get_fragment_shader (effects, "squeeze",
+ squeeze_fragment_source_gles2, squeeze_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "squeeze0", shader);
+ if (!shader)
+ return;
- if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
- if (!gst_gl_shader_compile_with_default_v_and_check (shader,
- squeeze_fragment_source_gles2, &filter->draw_attr_position_loc,
- &filter->draw_attr_texture_loc)) {
- /* gst gl context error is already set */
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("Failed to initialize squeeze shader, %s",
- gst_gl_context_get_error ()), (NULL));
- return;
- }
- }
-#if GST_GL_HAVE_OPENGL
- if (USING_OPENGL (context)) {
- if (!gst_gl_shader_compile_and_check (shader,
- squeeze_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context,
- "Failed to initialize squeeze shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
- return;
- }
- }
-#endif
- }
#if GST_GL_HAVE_OPENGL
if (USING_OPENGL (context)) {
gl->MatrixMode (GL_PROJECTION);
gst_gl_shader_use (shader);
gl->ActiveTexture (GL_TEXTURE0);
- if (USING_OPENGL (context))
- gl->Enable (GL_TEXTURE_2D);
+ gl->Enable (GL_TEXTURE_2D);
gl->BindTexture (GL_TEXTURE_2D, texture);
gst_gl_shader_set_uniform_1i (shader, "tex", 0);
/* *INDENT-OFF* */
/* Mirror effect */
-#if GST_GL_HAVE_OPENGL
const gchar *mirror_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
" vec4 color = texture2D (tex, texturecoord);"
" gl_FragColor = color * gl_Color;"
"}";
-#endif
+
const gchar *mirror_fragment_source_gles2 =
"#ifdef GL_ES\n"
"precision mediump float;\n"
"}";
/* Squeeze effect */
-#if GST_GL_HAVE_OPENGL
const gchar *squeeze_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
" texturecoord = (normcoord + 0.5);"
" gl_FragColor = texture2D (tex, texturecoord);"
"}";
-#endif
+
const gchar *squeeze_fragment_source_gles2 =
"#ifdef GL_ES\n"
"precision mediump float;\n"
"}";
/* Stretch Effect */
-const gchar *stretch_fragment_source =
+const gchar *stretch_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
" vec2 texturecoord = gl_TexCoord[0].xy;"
" gl_FragColor = color * gl_Color;"
"}";
+const gchar *stretch_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "void main () {"
+ " vec2 texturecoord = v_texcoord.xy;"
+ " vec2 normcoord;"
+ " normcoord = texturecoord - 0.5;"
+ " float r = length (normcoord);"
+ " normcoord *= 2.0 - smoothstep(0.0, 0.35, r);"
+ " texturecoord = normcoord + 0.5;"
+ " gl_FragColor = texture2D (tex, texturecoord);"
+ "}";
+
/* Light Tunnel effect */
-const gchar *tunnel_fragment_source =
+const gchar *tunnel_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
" vec2 texturecoord = gl_TexCoord[0].xy;"
" gl_FragColor = color;"
"}";
+const gchar *tunnel_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "void main () {"
+ " vec2 texturecoord = v_texcoord.xy;"
+ " vec2 normcoord;"
+ /* little trick with normalized coords to obtain a circle with
+ * rect textures */
+ " normcoord = (texturecoord - 0.5);"
+ " float r = length(normcoord);"
+ " normcoord *= clamp (r, 0.0, 0.275) / r;"
+ " texturecoord = normcoord + 0.5;"
+ " gl_FragColor = texture2D (tex, texturecoord);"
+ "}";
+
/* FishEye effect */
-const gchar *fisheye_fragment_source =
+const gchar *fisheye_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
" vec2 texturecoord = gl_TexCoord[0].xy;"
" gl_FragColor = color;"
"}";
+const gchar *fisheye_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "void main () {"
+ " vec2 texturecoord = v_texcoord.xy;"
+ " vec2 normcoord;"
+ " normcoord = texturecoord - 0.5;"
+ " float r = length (normcoord);"
+ " normcoord *= r * sqrt(2);"
+ " texturecoord = normcoord + 0.5;"
+ " gl_FragColor = texture2D (tex, texturecoord);"
+ "}";
/* Twirl effect */
-const gchar *twirl_fragment_source =
+const gchar *twirl_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
" vec2 texturecoord = gl_TexCoord[0].xy;"
" gl_FragColor = color;"
"}";
+const gchar *twirl_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "void main () {"
+ " vec2 texturecoord = v_texcoord.xy;"
+ " vec2 normcoord;"
+ " normcoord = texturecoord - 0.5;"
+ " float r = length (normcoord);"
+ /* calculate rotation angle: maximum (about pi/2) at the origin and
+ * gradually decrease it up to 0.6 of each quadrant */
+ " float phi = (1.0 - smoothstep (0.0, 0.3, r)) * 1.6;"
+ /* precalculate sin phi and cos phi, save some alu */
+ " float s = sin(phi);"
+ " float c = cos(phi);"
+ /* rotate */
+ " normcoord *= mat2(c, s, -s, c);"
+ " texturecoord = normcoord + 0.5;"
+ " gl_FragColor = texture2D (tex, texturecoord);"
+ "}";
/* Bulge effect */
-const gchar *bulge_fragment_source =
+const gchar *bulge_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
" vec2 texturecoord = gl_TexCoord[0].xy;"
" gl_FragColor = color;"
"}";
+const gchar *bulge_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "void main () {"
+ " vec2 texturecoord = v_texcoord.xy;"
+ " vec2 normcoord;"
+ " normcoord = texturecoord - 0.5;"
+ " float r = length (normcoord);"
+ " normcoord *= smoothstep (-0.05, 0.25, r);"
+ " texturecoord = normcoord + 0.5;"
+ " gl_FragColor = texture2D (tex, texturecoord);"
+ "}";
/* Square Effect */
-const gchar *square_fragment_source =
+const gchar *square_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
" vec2 texturecoord = gl_TexCoord[0].xy;"
" gl_FragColor = color * gl_Color;"
"}";
+const gchar *square_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "void main () {"
+ " vec2 texturecoord = v_texcoord.xy;"
+ " vec2 normcoord;"
+ " normcoord = texturecoord - 0.5;"
+ " float r = length (normcoord);"
+ " normcoord *= 1.0 + smoothstep(0.125, 0.25, abs(normcoord));"
+ " normcoord /= 2.0; /* zoom amount */"
+ " texturecoord = normcoord + 0.5;"
+ " gl_FragColor = texture2D (tex, texturecoord);"
+ "}";
-const gchar *luma_threshold_fragment_source =
+const gchar *luma_threshold_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
" vec2 texturecoord = gl_TexCoord[0].st;"
" gl_FragColor = vec4 (vec3 (smoothstep (0.30, 0.50, luma)), color.a);"
"}";
-const gchar *sep_sobel_length_fragment_source =
+const gchar *luma_threshold_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "void main () {"
+ " vec2 texturecoord = v_texcoord.xy;"
+ " vec4 color = texture2D(tex, texturecoord);"
+ " float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));" /* BT.709 (from orange book) */
+ " gl_FragColor = vec4 (vec3 (smoothstep (0.30, 0.50, luma)), color.a);"
+ "}";
+
+const gchar *sep_sobel_length_fragment_source_opengl =
"uniform sampler2D tex;"
"uniform bool invert;"
"void main () {"
" gl_FragColor = abs(vec4(vec3(float(invert) - len), 1.0));"
"}";
-const gchar *desaturate_fragment_source =
+const gchar *sep_sobel_length_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "uniform bool invert;"
+ "void main () {"
+ " vec4 g = texture2D (tex, v_texcoord.xy);"
+ /* restore black background with grey edges */
+ " g -= vec4(0.5, 0.5, 0.0, 0.0);"
+ " float len = length (g);"
+ /* little trick to avoid IF operator */
+ /* TODO: test if a standalone inverting pass is worth */
+ " gl_FragColor = abs(vec4(vec3(float(invert) - len), 1.0));"
+ "}";
+
+const gchar *desaturate_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
" vec4 color = texture2D (tex, gl_TexCoord[0].st);"
" gl_FragColor = vec4(vec3(luma), color.a);"
"}";
-const gchar *sep_sobel_hconv3_fragment_source =
+const gchar *desaturate_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "void main () {"
+ " vec4 color = texture2D (tex, v_texcoord.xy);"
+ " float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));"
+ " gl_FragColor = vec4(vec3(luma), color.a);"
+ "}";
+
+const gchar *sep_sobel_hconv3_fragment_source_opengl =
"uniform sampler2D tex;"
"uniform float width;"
"void main () {"
" gl_FragColor = sum + vec4(0.0, 0.5, 0.0, 0.0);"
"}";
-const gchar *sep_sobel_vconv3_fragment_source =
+const gchar *sep_sobel_hconv3_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "uniform float width;"
+ "void main () {"
+ " float w = 1.0 / width;"
+ " vec2 texturecoord[3];"
+ " texturecoord[1] = v_texcoord.xy;"
+ " texturecoord[0] = texturecoord[1] - vec2(w, 0.0);"
+ " texturecoord[2] = texturecoord[1] + vec2(w, 0.0);"
+ " float grad_kern[3];"
+ " grad_kern[0] = 1.0;"
+ " grad_kern[1] = 0.0;"
+ " grad_kern[2] = -1.0;"
+ " float blur_kern[3];"
+ " blur_kern[0] = 0.25;"
+ " blur_kern[1] = 0.5;"
+ " blur_kern[2] = 0.25;"
+ " int i;"
+ " vec4 sum = vec4 (0.0);"
+ " for (i = 0; i < 3; i++) { "
+ " vec4 neighbor = texture2D(tex, texturecoord[i]); "
+ " sum.r = neighbor.r * blur_kern[i] + sum.r;"
+ " sum.g = neighbor.g * grad_kern[i] + sum.g;"
+ " }"
+ " gl_FragColor = sum + vec4(0.0, 0.5, 0.0, 0.0);"
+ "}";
+
+const gchar *sep_sobel_vconv3_fragment_source_opengl =
"uniform sampler2D tex;"
"uniform float height;"
"void main () {"
" gl_FragColor = sum + vec4(0.5, 0.0, 0.0, 0.0);"
"}";
+const gchar *sep_sobel_vconv3_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "uniform float height;"
+ "void main () {"
+ " float h = 1.0 / height;"
+ " vec2 texturecoord[3];"
+ " texturecoord[1] = v_texcoord.xy;"
+ " texturecoord[0] = texturecoord[1] - vec2(0.0, h);"
+ " texturecoord[2] = texturecoord[1] + vec2(0.0, h);"
+ " float grad_kern[3];"
+ " grad_kern[0] = 1.0;"
+ " grad_kern[1] = 0.0;"
+ " grad_kern[2] = -1.0;"
+ " float blur_kern[3];"
+ " blur_kern[0] = 0.25;"
+ " blur_kern[1] = 0.5;"
+ " blur_kern[2] = 0.25;"
+ " int i;"
+ " vec4 sum = vec4 (0.0);"
+ " for (i = 0; i < 3; i++) { "
+ " vec4 neighbor = texture2D(tex, texturecoord[i]); "
+ " sum.r = neighbor.r * grad_kern[i] + sum.r;"
+ " sum.g = neighbor.g * blur_kern[i] + sum.g;"
+ " }"
+ " gl_FragColor = sum + vec4(0.5, 0.0, 0.0, 0.0);"
+ "}";
+
/* horizontal convolution 7x7 */
-const gchar *hconv7_fragment_source =
+const gchar *hconv7_fragment_source_opengl =
"uniform sampler2D tex;"
"uniform float kernel[7];"
- "uniform float width;"
+ "uniform float gauss_width;"
"void main () {"
- " float w = 1.0 / width;"
+ " float w = 1.0 / gauss_width;"
" vec2 texturecoord[7];"
" texturecoord[3] = gl_TexCoord[0].st;"
" texturecoord[2] = texturecoord[3] - vec2(w, 0.0);"
" gl_FragColor = sum;"
"}";
+const gchar *hconv7_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "uniform float kernel[7];"
+ "uniform float gauss_width;"
+ "void main () {"
+ " float w = 1.0 / gauss_width;"
+ " vec2 texturecoord[7];"
+ " texturecoord[3] = v_texcoord.xy;"
+ " texturecoord[2] = texturecoord[3] - vec2(w, 0.0);"
+ " texturecoord[1] = texturecoord[2] - vec2(w, 0.0);"
+ " texturecoord[0] = texturecoord[1] - vec2(w, 0.0);"
+ " texturecoord[4] = texturecoord[3] + vec2(w, 0.0);"
+ " texturecoord[5] = texturecoord[4] + vec2(w, 0.0);"
+ " texturecoord[6] = texturecoord[5] + vec2(w, 0.0);"
+ " int i;"
+ " vec4 sum = vec4 (0.0);"
+ " for (i = 0; i < 7; i++) { "
+ " vec4 neighbor = texture2D(tex, texturecoord[i]); "
+ " sum += neighbor * kernel[i];"
+ " }"
+ " gl_FragColor = sum;"
+ "}";
+
/* vertical convolution 7x7 */
-const gchar *vconv7_fragment_source =
+const gchar *vconv7_fragment_source_opengl =
"uniform sampler2D tex;"
"uniform float kernel[7];"
- "uniform float height;"
+ "uniform float gauss_height;"
"void main () {"
- " float h = 1.0 / height;"
+ " float h = 1.0 / gauss_height;"
" vec2 texturecoord[7];"
" texturecoord[3] = gl_TexCoord[0].st;"
" texturecoord[2] = texturecoord[3] - vec2(0.0, h);"
" gl_FragColor = sum;"
"}";
+const gchar *vconv7_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "uniform float kernel[7];"
+ "uniform float gauss_height;"
+ "void main () {"
+ " float h = 1.0 / gauss_height;"
+ " vec2 texturecoord[7];"
+ " texturecoord[3] = v_texcoord.xy;"
+ " texturecoord[2] = texturecoord[3] - vec2(0.0, h);"
+ " texturecoord[1] = texturecoord[2] - vec2(0.0, h);"
+ " texturecoord[0] = texturecoord[1] - vec2(0.0, h);"
+ " texturecoord[4] = texturecoord[3] + vec2(0.0, h);"
+ " texturecoord[5] = texturecoord[4] + vec2(0.0, h);"
+ " texturecoord[6] = texturecoord[5] + vec2(0.0, h);"
+ " int i;"
+ " vec4 sum = vec4 (0.0);"
+ " for (i = 0; i < 7; i++) { "
+ " vec4 neighbor = texture2D(tex, texturecoord[i]);"
+ " sum += neighbor * kernel[i];"
+ " }"
+ " gl_FragColor = sum;"
+ "}";
/* TODO: support several blend modes */
-const gchar *sum_fragment_source =
+const gchar *sum_fragment_source_opengl =
"uniform sampler2D base;"
"uniform sampler2D blend;"
"uniform float alpha;"
" gl_FragColor = alpha * basecolor + beta * blendcolor;"
"}";
-const gchar *multiply_fragment_source =
+const gchar *sum_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D base;"
+ "uniform sampler2D blend;"
+ "uniform float alpha;"
+ "uniform float beta;"
+ "void main () {"
+ " vec4 basecolor = texture2D (base, v_texcoord.xy);"
+ " vec4 blendcolor = texture2D (blend, v_texcoord.xy);"
+ " gl_FragColor = alpha * basecolor + beta * blendcolor;"
+ "}";
+
+const gchar *multiply_fragment_source_opengl =
"uniform sampler2D base;"
"uniform sampler2D blend;"
"uniform float alpha;"
" gl_FragColor = (1.0 - alpha) * basecolor + alpha * basecolor * blendcolor;"
"}";
+const gchar *multiply_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D base;"
+ "uniform sampler2D blend;"
+ "uniform float alpha;"
+ "void main () {"
+ " vec4 basecolor = texture2D (base, v_texcoord.xy);"
+ " vec4 blendcolor = texture2D (blend, v_texcoord.xy);"
+ " gl_FragColor = (1.0 - alpha) * basecolor + alpha * basecolor * blendcolor;"
+ "}";
+
/* lut operations, map luma to tex1d, see orange book (chapter 19) */
-const gchar *luma_to_curve_fragment_source =
+const gchar *luma_to_curve_fragment_source_opengl =
"uniform sampler2D tex;"
"uniform sampler1D curve;"
"void main () {"
" gl_FragColor = color;"
"}";
+const gchar *luma_to_curve_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "uniform sampler2D curve;"
+ "void main () {"
+ " vec2 texturecoord = v_texcoord.xy;"
+ " vec4 color = texture2D (tex, texturecoord);"
+ " float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));"
+ " color = texture2D (curve, vec2(luma, 0.0));"
+ " gl_FragColor = color;"
+ "}";
/* lut operations, map rgb to tex1d, see orange book (chapter 19) */
-const gchar *rgb_to_curve_fragment_source =
+const gchar *rgb_to_curve_fragment_source_opengl =
"uniform sampler2D tex;"
"uniform sampler1D curve;"
"void main () {"
" gl_FragColor = outcolor;"
"}";
-const gchar *sin_fragment_source =
+const gchar *rgb_to_curve_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "uniform sampler2D curve;"
+ "void main () {"
+ " vec4 color = texture2D (tex, v_texcoord.xy);"
+ " vec4 outcolor;"
+ " outcolor.r = texture2D (curve, vec2(color.r, 0.0)).r;"
+ " outcolor.g = texture2D (curve, vec2(color.g, 0.0)).g;"
+ " outcolor.b = texture2D (curve, vec2(color.b, 0.0)).b;"
+ " outcolor.a = color.a;"
+ " gl_FragColor = outcolor;"
+ "}";
+
+const gchar *sin_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
" vec4 color = texture2D (tex, vec2(gl_TexCoord[0].st));"
" gl_FragColor = color * mix + luma * (1.0 - mix);"
"}";
+const gchar *sin_fragment_source_gles2 =
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying vec2 v_texcoord;"
+ "uniform sampler2D tex;"
+ "void main () {"
+ " vec4 color = texture2D (tex, vec2(v_texcoord.xy));"
+ " float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));"
+/* calculate hue with the Preucil formula */
+ " float cosh = color.r - 0.5*(color.g + color.b);"
+/* sqrt(3)/2 = 0.866 */
+ " float sinh = 0.866*(color.g - color.b);"
+/* hue = atan2 h */
+ " float sch = (1.0-sinh)*cosh;"
+/* ok this is a little trick I came up because I didn't find any
+ * detailed proof of the Preucil formula. The issue is that tan(h) is
+ * pi-periodic so the smoothstep thing gives both reds (h = 0) and
+ * cyans (h = 180). I don't want to use atan since it requires
+ * branching and doesn't work on i915. So take only the right half of
+ * the circle where cosine is positive */
+/* take a slightly purple color trying to get rid of human skin reds */
+/* tanh = +-1.0 for h = +-45, where yellow=60, magenta=-60 */
+ " float a = smoothstep (0.3, 1.0, sch);"
+ " float b = smoothstep (-0.4, -0.1, sinh);"
+ " float mix = a * b;"
+ " gl_FragColor = color * mix + luma * (1.0 - mix);"
+ "}";
+
const gchar *interpolate_fragment_source =
"uniform sampler2D base;"
"uniform sampler2D blend;"
#ifndef __GST_GL_EFFECTS_SOURCES_H__
#define __GST_GL_EFFECTS_SOURCES_H__
-#if GST_GL_HAVE_OPENGL
extern const gchar *mirror_fragment_source_opengl;
extern const gchar *squeeze_fragment_source_opengl;
-#endif
+extern const gchar *stretch_fragment_source_opengl;
+extern const gchar *fisheye_fragment_source_opengl;
+extern const gchar *twirl_fragment_source_opengl;
+extern const gchar *bulge_fragment_source_opengl;
+extern const gchar *tunnel_fragment_source_opengl;
+extern const gchar *square_fragment_source_opengl;
+extern const gchar *luma_threshold_fragment_source_opengl;
+extern const gchar *hconv7_fragment_source_opengl;
+extern const gchar *vconv7_fragment_source_opengl;
+extern const gchar *sum_fragment_source_opengl;
+extern const gchar *luma_to_curve_fragment_source_opengl;
+extern const gchar *rgb_to_curve_fragment_source_opengl;
+extern const gchar *sin_fragment_source_opengl;
+extern const gchar *desaturate_fragment_source_opengl;
+extern const gchar *sep_sobel_hconv3_fragment_source_opengl;
+extern const gchar *sep_sobel_vconv3_fragment_source_opengl;
+extern const gchar *sep_sobel_length_fragment_source_opengl;
+extern const gchar *multiply_fragment_source_opengl;
extern const gchar *mirror_fragment_source_gles2;
extern const gchar *squeeze_fragment_source_gles2;
+extern const gchar *stretch_fragment_source_gles2;
+extern const gchar *fisheye_fragment_source_gles2;
+extern const gchar *twirl_fragment_source_gles2;
+extern const gchar *bulge_fragment_source_gles2;
+extern const gchar *tunnel_fragment_source_gles2;
+extern const gchar *square_fragment_source_gles2;
+extern const gchar *luma_threshold_fragment_source_gles2;
+extern const gchar *hconv7_fragment_source_gles2;
+extern const gchar *vconv7_fragment_source_gles2;
+extern const gchar *sum_fragment_source_gles2;
+extern const gchar *luma_to_curve_fragment_source_gles2;
+extern const gchar *rgb_to_curve_fragment_source_gles2;
+extern const gchar *sin_fragment_source_gles2;
+extern const gchar *desaturate_fragment_source_gles2;
+extern const gchar *sep_sobel_hconv3_fragment_source_gles2;
+extern const gchar *sep_sobel_vconv3_fragment_source_gles2;
+extern const gchar *sep_sobel_length_fragment_source_gles2;
+extern const gchar *multiply_fragment_source_gles2;
-extern const gchar *stretch_fragment_source;
-extern const gchar *tunnel_fragment_source;
-extern const gchar *fisheye_fragment_source;
-extern const gchar *twirl_fragment_source;
-extern const gchar *bulge_fragment_source;
-extern const gchar *square_fragment_source;
-extern const gchar *luma_threshold_fragment_source;
-extern const gchar *sep_sobel_length_fragment_source;
-extern const gchar *desaturate_fragment_source;
-extern const gchar *sep_sobel_hconv3_fragment_source;
-extern const gchar *sep_sobel_vconv3_fragment_source;
-extern const gchar *hconv7_fragment_source;
-extern const gchar *vconv7_fragment_source;
-extern const gchar *sum_fragment_source;
-extern const gchar *luma_to_curve_fragment_source;
-extern const gchar *rgb_to_curve_fragment_source;
-extern const gchar *sin_fragment_source;
extern const gchar *interpolate_fragment_source;
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);
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "stretch0");
+ shader = gst_gl_effects_get_fragment_shader (effects, "stretch",
+ stretch_fragment_source_gles2, stretch_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "stretch0", shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- stretch_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize stretch shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
-
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
gl->ActiveTexture (GL_TEXTURE0);
gst_gl_shader_set_uniform_1i (shader, "tex", 0);
- gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
- gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
-
gst_gl_filter_draw_texture (filter, texture, width, height);
}
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "tunnel0");
+ shader = gst_gl_effects_get_fragment_shader (effects, "tunnel",
+ tunnel_fragment_source_gles2, tunnel_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "tunnel0", shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- tunnel_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize tunnel shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
gst_gl_shader_set_uniform_1i (shader, "tex", 0);
- gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
- gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
-
gst_gl_filter_draw_texture (filter, texture, width, height);
}
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "twirl0");
+ shader = gst_gl_effects_get_fragment_shader (effects, "twirl",
+ twirl_fragment_source_gles2, twirl_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "twirl0", shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- twirl_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize twirl shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
gst_gl_shader_set_uniform_1i (shader, "tex", 0);
- gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
- gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
-
gst_gl_filter_draw_texture (filter, texture, width, height);
}
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "xray1");
+ shader = gst_gl_effects_get_fragment_shader (effects, "hconv7",
+ hconv7_fragment_source_gles2, hconv7_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "xray1", shader);
- }
+ if (!shader)
+ return;
if (!kernel_ready) {
fill_gaussian_kernel (gauss_kernel, 7, 1.5);
kernel_ready = TRUE;
}
-
- if (!gst_gl_shader_compile_and_check (shader,
- hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize hconv7 shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
- return;
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
}
-
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#endif
gst_gl_shader_use (shader);
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, "width", width);
+ gst_gl_shader_set_uniform_1f (shader, "gauss_width", width);
gst_gl_filter_draw_texture (filter, texture, width, height);
}
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "xray2");
+ shader = gst_gl_effects_get_fragment_shader (effects, "vconv7",
+ vconv7_fragment_source_gles2, vconv7_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "xray2", shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- vconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize vconv7 shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
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, "height", height);
+ gst_gl_shader_set_uniform_1f (shader, "gauss_height", height);
gst_gl_filter_draw_texture (filter, texture, width, height);
}
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "xray_desat");
-
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "xray_desat", shader);
- }
+ shader = gst_gl_effects_get_fragment_shader (effects, "desaturate",
+ desaturate_fragment_source_gles2, desaturate_fragment_source_opengl);
- if (!gst_gl_shader_compile_and_check (shader,
- desaturate_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context,
- "Failed to initialize desaturate shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_hconv");
-
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "xray_sob_hconv",
- shader);
- }
+ shader = gst_gl_effects_get_fragment_shader (effects, "sobel_hconv3",
+ sep_sobel_hconv3_fragment_source_gles2,
+ sep_sobel_hconv3_fragment_source_opengl);
- if (!gst_gl_shader_compile_and_check (shader,
- sep_sobel_hconv3_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context,
- "Failed to initialize sobel hvonc3 shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_vconv");
-
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "xray_sob_vconv",
- shader);
- }
+ shader = gst_gl_effects_get_fragment_shader (effects, "sobel_vconv3",
+ sep_sobel_vconv3_fragment_source_gles2,
+ sep_sobel_vconv3_fragment_source_opengl);
- if (!gst_gl_shader_compile_and_check (shader,
- sep_sobel_vconv3_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context,
- "Failed to initialize sobel vconv3 shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_len");
+ shader = gst_gl_effects_get_fragment_shader (effects, "sobel_length",
+ sep_sobel_length_fragment_source_gles2,
+ sep_sobel_length_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "xray_sob_len",
- shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- sep_sobel_length_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context,
- "Failed to initialize seobel length shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
- shader = g_hash_table_lookup (effects->shaderstable, "xray4");
+ shader = gst_gl_effects_get_fragment_shader (effects, "multiply",
+ multiply_fragment_source_gles2, multiply_fragment_source_opengl);
- if (!shader) {
- shader = gst_gl_shader_new (context);
- g_hash_table_insert (effects->shaderstable, (gchar *) "xray4", shader);
- }
-
- if (!gst_gl_shader_compile_and_check (shader,
- multiply_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
- gst_gl_context_set_error (context, "Failed to initialize multiply shader");
- GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
- ("%s", gst_gl_context_get_error ()), (NULL));
+ if (!shader)
return;
- }
- gl->MatrixMode (GL_PROJECTION);
- gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+ if (USING_OPENGL (context)) {
+ gl->MatrixMode (GL_PROJECTION);
+ gl->LoadIdentity ();
+ }
+#endif
gst_gl_shader_use (shader);
}
if (!gst_gl_shader_compile_and_check (differencematte->shader[1],
- hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
+ hconv7_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) {
gst_gl_context_set_error (GST_GL_BASE_FILTER (differencematte)->context,
"Failed to initialize hconv7 shader");
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND,
}
if (!gst_gl_shader_compile_and_check (differencematte->shader[2],
- vconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
+ vconv7_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) {
gst_gl_context_set_error (GST_GL_BASE_FILTER (differencematte)->context,
"Failed to initialize vconv7 shader");
GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND,
{GST_GL_EFFECT_IDENTITY, "Do nothing Effect", "identity"},
{GST_GL_EFFECT_MIRROR, "Mirror Effect", "mirror"},
{GST_GL_EFFECT_SQUEEZE, "Squeeze Effect", "squeeze"},
-#if GST_GL_HAVE_OPENGL
{GST_GL_EFFECT_STRETCH, "Stretch Effect", "stretch"},
+ {GST_GL_EFFECT_TUNNEL, "Light Tunnel Effect", "tunnel"},
{GST_GL_EFFECT_FISHEYE, "FishEye Effect", "fisheye"},
{GST_GL_EFFECT_TWIRL, "Twirl Effect", "twirl"},
{GST_GL_EFFECT_BULGE, "Bulge Effect", "bulge"},
- {GST_GL_EFFECT_TUNNEL, "Light Tunnel Effect", "tunnel"},
{GST_GL_EFFECT_SQUARE, "Square Effect", "square"},
{GST_GL_EFFECT_HEAT, "Heat Signature Effect", "heat"},
{GST_GL_EFFECT_SEPIA, "Sepia Toning Effect", "sepia"},
{GST_GL_EFFECT_XRAY, "Glowing negative effect", "xray"},
{GST_GL_EFFECT_SIN, "All Grey but Red Effect", "sin"},
{GST_GL_EFFECT_GLOW, "Glow Lighting Effect", "glow"},
-#endif
{0, NULL, NULL}
};
gst_gl_effects_set_effect (GstGLEffects * effects, gint effect_type)
{
GstGLBaseFilterClass *filter_class = GST_GL_BASE_FILTER_GET_CLASS (effects);
- GstGLContext *context = GST_GL_BASE_FILTER (effects)->context;
switch (effect_type) {
case GST_GL_EFFECT_IDENTITY:
GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
effects->current_effect = effect_type;
break;
- }
-
- if (context
- && (gst_gl_context_get_gl_api (context) & GST_GL_API_OPENGL) ==
- GST_GL_API_NONE) {
- GST_ELEMENT_WARNING (effects, RESOURCE, SETTINGS, ("%s",
- "cannot change effect type"), ("%s",
- "the current OpenGL context does not support the GL API required"));
- return;
- }
-#if GST_GL_HAVE_OPENGL
- switch (effect_type) {
- case GST_GL_EFFECT_IDENTITY:
- case GST_GL_EFFECT_MIRROR:
- case GST_GL_EFFECT_SQUEEZE:
- break;
case GST_GL_EFFECT_STRETCH:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_stretch;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
break;
case GST_GL_EFFECT_TUNNEL:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_tunnel;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
break;
case GST_GL_EFFECT_FISHEYE:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_fisheye;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
break;
case GST_GL_EFFECT_TWIRL:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_twirl;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
break;
case GST_GL_EFFECT_BULGE:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_bulge;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
break;
case GST_GL_EFFECT_SQUARE:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_square;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
break;
case GST_GL_EFFECT_HEAT:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_heat;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
break;
case GST_GL_EFFECT_SEPIA:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sepia;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
break;
case GST_GL_EFFECT_XPRO:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_xpro;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
break;
case GST_GL_EFFECT_LUMA_XPRO:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_luma_xpro;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
- break;
- case GST_GL_EFFECT_XRAY:
- effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_xray;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
break;
case GST_GL_EFFECT_SIN:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sin;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
+ break;
+ case GST_GL_EFFECT_XRAY:
+ effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sin;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
break;
case GST_GL_EFFECT_GLOW:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_glow;
- filter_class->supported_gl_api = GST_GL_API_OPENGL;
+ filter_class->supported_gl_api =
+ GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+ effects->current_effect = effect_type;
break;
default:
g_assert_not_reached ();
}
-#endif
+
effects->current_effect = effect_type;
}
return TRUE;
}
+
+GstGLShader *
+gst_gl_effects_get_fragment_shader (GstGLEffects * effects,
+ const gchar * shader_name, const gchar * shader_source_gles2,
+ const gchar * shader_source_opengl)
+{
+ GstGLShader *shader;
+ GstGLFilter *filter = GST_GL_FILTER (effects);
+ GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
+
+ shader = g_hash_table_lookup (effects->shaderstable, shader_name);
+
+ if (!shader) {
+ shader = gst_gl_shader_new (context);
+ g_hash_table_insert (effects->shaderstable, (gchar *) shader_name, shader);
+
+ if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
+ if (!gst_gl_shader_compile_with_default_v_and_check (shader,
+ shader_source_gles2, &filter->draw_attr_position_loc,
+ &filter->draw_attr_texture_loc)) {
+ /* gst gl context error is already set */
+ GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
+ ("Failed to initialize %s shader, %s",
+ shader_name, gst_gl_context_get_error ()), (NULL));
+ return NULL;
+ }
+ }
+#if GST_GL_HAVE_OPENGL
+ if (!gst_gl_shader_compile_and_check (shader,
+ shader_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) {
+ gst_gl_context_set_error (context, "Failed to initialize %s shader",
+ shader_name);
+ GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s",
+ gst_gl_context_get_error ()), (NULL));
+ return NULL;
+ }
+#endif
+ }
+
+ return shader;
+}
#define GST_IS_GL_EFFECTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) , GST_TYPE_GL_EFFECTS))
#define GST_GL_EFFECTS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) , GST_TYPE_GL_EFFECTS,GstGLEffectsClass))
+#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
+#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
+#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
+#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
+#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
+
typedef struct _GstGLEffects GstGLEffects;
typedef struct _GstGLEffectsClass GstGLEffectsClass;
GType gst_gl_effects_get_type (void);
+GstGLShader* gst_gl_effects_get_fragment_shader (GstGLEffects *effects,
+ const gchar * shader_name, const gchar * shader_source_gles2, const gchar * shader_source_opengl);
void gst_gl_effects_identity (GstGLEffects *effects);
void gst_gl_effects_mirror (GstGLEffects *effects);
//blocking call, wait the opengl thread has compiled the shader
if (!gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
- hconv7_fragment_source, &blur_filter->shader0))
+ hconv7_fragment_source_opengl, &blur_filter->shader0))
return FALSE;
//blocking call, wait the opengl thread has compiled the shader
if (!gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
- vconv7_fragment_source, &blur_filter->shader1))
+ vconv7_fragment_source_opengl, &blur_filter->shader1))
return FALSE;
return TRUE;
//blocking call, wait the opengl thread has compiled the shader
ret =
gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
- desaturate_fragment_source, &filtersobel->desat);
+ desaturate_fragment_source_opengl, &filtersobel->desat);
ret &=
gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
- sep_sobel_hconv3_fragment_source, &filtersobel->hconv);
+ sep_sobel_hconv3_fragment_source_opengl, &filtersobel->hconv);
ret &=
gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
- sep_sobel_vconv3_fragment_source, &filtersobel->vconv);
+ sep_sobel_vconv3_fragment_source_opengl, &filtersobel->vconv);
ret &=
gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
- sep_sobel_length_fragment_source, &filtersobel->len);
+ sep_sobel_length_fragment_source_opengl, &filtersobel->len);
return ret;
}