gleffects: port all effects to GLES2.0

https://bugzilla.gnome.org/show_bug.cgi?id=745955
This commit is contained in:
Anton Obzhirov 2015-03-30 13:49:01 +01:00 committed by Julien Isorce
parent f00aec48fa
commit 4504356dda
22 changed files with 811 additions and 525 deletions

View file

@ -17,6 +17,17 @@ libgstopengl_la_SOURCES = \
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 \
@ -52,18 +63,7 @@ libgstopengl_la_SOURCES += \
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 \

View file

@ -33,23 +33,18 @@ gst_gl_effects_bulge_callback (gint width, gint height, guint texture,
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);
@ -59,9 +54,6 @@ gst_gl_effects_bulge_callback (gint width, gint height, guint texture,
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);
}

View file

@ -33,23 +33,18 @@ gst_gl_effects_fisheye_callback (gint width, gint height, guint texture,
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);
@ -59,9 +54,6 @@ gst_gl_effects_fisheye_callback (gint width, gint height, guint texture,
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);
}

View file

@ -36,24 +36,19 @@ gst_gl_effects_glow_step_one (gint width, gint height, guint texture,
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);
@ -76,28 +71,22 @@ gst_gl_effects_glow_step_two (gint width, gint height, guint texture,
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);
@ -108,7 +97,7 @@ gst_gl_effects_glow_step_two (gint width, gint height, guint texture,
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);
}
@ -123,23 +112,18 @@ gst_gl_effects_glow_step_three (gint width, gint height, guint texture,
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
shader = g_hash_table_lookup (effects->shaderstable, "glow2");
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 *) "glow2", 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 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);
@ -150,7 +134,7 @@ gst_gl_effects_glow_step_three (gint width, gint height, guint texture,
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);
}
@ -165,23 +149,18 @@ gst_gl_effects_glow_step_four (gint width, gint height, guint texture,
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
shader = g_hash_table_lookup (effects->shaderstable, "glow3");
shader = gst_gl_effects_get_fragment_shader (effects, "sum",
sum_fragment_source_gles2, sum_fragment_source_opengl);
if (!shader) {
shader = gst_gl_shader_new (context);
g_hash_table_insert (effects->shaderstable, (gchar *) "glow3", shader);
}
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);
@ -190,7 +169,7 @@ gst_gl_effects_glow_step_four (gint width, gint height, guint texture,
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);
@ -212,11 +191,14 @@ gst_gl_effects_glow (GstGLEffects * effects)
/* 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);

View file

@ -23,12 +23,6 @@
#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)

View file

@ -34,41 +34,53 @@ gst_gl_effects_luma_to_curve (GstGLEffects * effects,
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);
@ -79,13 +91,26 @@ gst_gl_effects_luma_to_curve (GstGLEffects * effects,
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);
}

View file

@ -23,12 +23,6 @@
#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)
@ -39,37 +33,12 @@ gst_gl_effects_mirror_callback (gint width, gint height, guint texture,
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
shader = g_hash_table_lookup (effects->shaderstable, "mirror0");
shader = gst_gl_effects_get_fragment_shader (effects, "mirror",
mirror_fragment_source_gles2, mirror_fragment_source_opengl);
if (!shader) {
shader = gst_gl_shader_new (context);
g_hash_table_insert (effects->shaderstable, (gchar *) "mirror0", shader);
if (!shader)
return;
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;
}
}
#endif
}
#if GST_GL_HAVE_OPENGL
if (USING_OPENGL (context)) {
gl->MatrixMode (GL_PROJECTION);

View file

@ -34,41 +34,51 @@ gst_gl_effects_rgb_to_curve (GstGLEffects * effects,
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);
#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, curve->bytes_per_pixel,
curve->width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
gl->TexImage1D (GL_TEXTURE_1D, 0, GL_RGB,
curve->width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
gl->Disable (GL_TEXTURE_1D);
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);
@ -79,13 +89,26 @@ gst_gl_effects_rgb_to_curve (GstGLEffects * effects,
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);
}

View file

@ -33,23 +33,18 @@ gst_gl_effects_sin_callback (gint width, gint height, guint texture,
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);

View file

@ -33,23 +33,18 @@ gst_gl_effects_square_callback (gint width, gint height, guint texture,
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);
@ -59,9 +54,6 @@ gst_gl_effects_square_callback (gint width, gint height, guint texture,
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);
}

View file

@ -23,12 +23,6 @@
#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)
@ -39,36 +33,12 @@ gst_gl_effects_squeeze_callback (gint width, gint height, guint texture,
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);
@ -79,8 +49,7 @@ gst_gl_effects_squeeze_callback (gint width, gint height, guint texture,
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);

View file

@ -65,7 +65,6 @@ fill_gaussian_kernel (float *kernel, int size, float sigma)
/* *INDENT-OFF* */
/* Mirror effect */
#if GST_GL_HAVE_OPENGL
const gchar *mirror_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
@ -77,7 +76,7 @@ const gchar *mirror_fragment_source_opengl =
" 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"
@ -93,7 +92,6 @@ const gchar *mirror_fragment_source_gles2 =
"}";
/* Squeeze effect */
#if GST_GL_HAVE_OPENGL
const gchar *squeeze_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
@ -105,7 +103,7 @@ const gchar *squeeze_fragment_source_opengl =
" texturecoord = (normcoord + 0.5);"
" gl_FragColor = texture2D (tex, texturecoord);"
"}";
#endif
const gchar *squeeze_fragment_source_gles2 =
"#ifdef GL_ES\n"
"precision mediump float;\n"
@ -123,7 +121,7 @@ const gchar *squeeze_fragment_source_gles2 =
"}";
/* Stretch Effect */
const gchar *stretch_fragment_source =
const gchar *stretch_fragment_source_opengl =
"uniform sampler2D tex;"
"void main () {"
" vec2 texturecoord = gl_TexCoord[0].xy;"
@ -136,8 +134,24 @@ const gchar *stretch_fragment_source =
" 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;"
@ -152,8 +166,26 @@ const gchar *tunnel_fragment_source =
" 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;"
@ -166,9 +198,24 @@ const gchar *fisheye_fragment_source =
" 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;"
@ -188,9 +235,31 @@ const gchar *twirl_fragment_source =
" 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;"
@ -203,9 +272,24 @@ const gchar *bulge_fragment_source =
" 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;"
@ -219,8 +303,24 @@ const gchar *square_fragment_source =
" 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;"
@ -229,7 +329,20 @@ const gchar *luma_threshold_fragment_source =
" 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 () {"
@ -242,7 +355,24 @@ const gchar *sep_sobel_length_fragment_source =
" 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);"
@ -250,7 +380,19 @@ const gchar *desaturate_fragment_source =
" 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 () {"
@ -277,7 +419,38 @@ const gchar *sep_sobel_hconv3_fragment_source =
" 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 () {"
@ -304,13 +477,44 @@ const gchar *sep_sobel_vconv3_fragment_source =
" 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);"
@ -328,13 +532,40 @@ const gchar *hconv7_fragment_source =
" gl_FragColor = sum;"
"}";
/* vertical convolution 7x7 */
const gchar *vconv7_fragment_source =
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 height;"
"uniform float gauss_width;"
"void main () {"
" float h = 1.0 / height;"
" 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_opengl =
"uniform sampler2D tex;"
"uniform float kernel[7];"
"uniform float gauss_height;"
"void main () {"
" float h = 1.0 / gauss_height;"
" vec2 texturecoord[7];"
" texturecoord[3] = gl_TexCoord[0].st;"
" texturecoord[2] = texturecoord[3] - vec2(0.0, h);"
@ -352,9 +583,35 @@ const gchar *vconv7_fragment_source =
" 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;"
@ -365,7 +622,22 @@ const gchar *sum_fragment_source =
" 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;"
@ -375,8 +647,22 @@ const gchar *multiply_fragment_source =
" 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 () {"
@ -387,9 +673,23 @@ const gchar *luma_to_curve_fragment_source =
" 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 () {"
@ -402,7 +702,24 @@ const gchar *rgb_to_curve_fragment_source =
" 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));"
@ -427,6 +744,35 @@ const gchar *sin_fragment_source =
" 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;"

View file

@ -21,35 +21,51 @@
#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);

View file

@ -33,24 +33,18 @@ gst_gl_effects_stretch_callback (gint width, gint height, guint texture,
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;
#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);
gl->ActiveTexture (GL_TEXTURE0);
@ -59,9 +53,6 @@ gst_gl_effects_stretch_callback (gint width, gint height, guint texture,
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);
}

View file

@ -33,23 +33,18 @@ gst_gl_effects_tunnel_callback (gint width, gint height, guint texture,
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);
@ -59,9 +54,6 @@ gst_gl_effects_tunnel_callback (gint width, gint height, guint texture,
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);
}

View file

@ -33,23 +33,18 @@ gst_gl_effects_twirl_callback (gint width, gint height, guint texture,
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);
@ -59,9 +54,6 @@ gst_gl_effects_twirl_callback (gint width, gint height, guint texture,
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);
}

View file

@ -48,28 +48,22 @@ gst_gl_effects_xray_step_two (gint width, gint height, guint texture,
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);
@ -80,7 +74,7 @@ gst_gl_effects_xray_step_two (gint width, gint height, guint texture,
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);
}
@ -95,23 +89,18 @@ gst_gl_effects_xray_step_three (gint width, gint height, guint texture,
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);
@ -122,7 +111,7 @@ gst_gl_effects_xray_step_three (gint width, gint height, guint texture,
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);
}
@ -138,24 +127,18 @@ gst_gl_effects_xray_desaturate (gint width, gint height, guint texture,
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
shader = g_hash_table_lookup (effects->shaderstable, "xray_desat");
shader = gst_gl_effects_get_fragment_shader (effects, "desaturate",
desaturate_fragment_source_gles2, desaturate_fragment_source_opengl);
if (!shader) {
shader = gst_gl_shader_new (context);
g_hash_table_insert (effects->shaderstable, (gchar *) "xray_desat", shader);
}
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);
@ -178,25 +161,19 @@ gst_gl_effects_xray_sobel_hconv (gint width, gint height, guint texture,
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_hconv");
shader = gst_gl_effects_get_fragment_shader (effects, "sobel_hconv3",
sep_sobel_hconv3_fragment_source_gles2,
sep_sobel_hconv3_fragment_source_opengl);
if (!shader) {
shader = gst_gl_shader_new (context);
g_hash_table_insert (effects->shaderstable, (gchar *) "xray_sob_hconv",
shader);
}
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);
@ -221,25 +198,19 @@ gst_gl_effects_xray_sobel_vconv (gint width, gint height, guint texture,
GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
GstGLFuncs *gl = context->gl_vtable;
shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_vconv");
shader = gst_gl_effects_get_fragment_shader (effects, "sobel_vconv3",
sep_sobel_vconv3_fragment_source_gles2,
sep_sobel_vconv3_fragment_source_opengl);
if (!shader) {
shader = gst_gl_shader_new (context);
g_hash_table_insert (effects->shaderstable, (gchar *) "xray_sob_vconv",
shader);
}
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);
@ -264,25 +235,19 @@ gst_gl_effects_xray_sobel_length (gint width, gint height, guint texture,
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);
@ -308,23 +273,18 @@ gst_gl_effects_xray_step_five (gint width, gint height, guint texture,
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);

View file

@ -109,7 +109,7 @@ gst_gl_differencematte_init_gl_resources (GstGLFilter * filter)
}
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,
@ -118,7 +118,7 @@ gst_gl_differencematte_init_gl_resources (GstGLFilter * filter)
}
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,

View file

@ -102,12 +102,11 @@ gst_gl_effects_effect_get_type (void)
{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"},
@ -116,7 +115,6 @@ gst_gl_effects_effect_get_type (void)
{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}
};
@ -131,7 +129,6 @@ static void
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:
@ -152,78 +149,88 @@ gst_gl_effects_set_effect (GstGLEffects * effects, gint effect_type)
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;
}
@ -447,3 +454,44 @@ gst_gl_effects_filter_texture (GstGLFilter * filter, guint in_tex,
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;
}

View file

@ -34,6 +34,12 @@ G_BEGIN_DECLS
#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;
@ -82,6 +88,8 @@ enum
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);

View file

@ -181,12 +181,12 @@ gst_gl_filterblur_init_shader (GstGLFilter * filter)
//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;

View file

@ -215,16 +215,16 @@ gst_gl_filtersobel_init_shader (GstGLFilter * filter)
//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;
}