diff options
-rw-r--r-- | gst/gl/Makefile.am | 4 | ||||
-rw-r--r-- | gst/gl/effects/gstgleffectscurves.h | 42 | ||||
-rw-r--r-- | gst/gl/effects/gstgleffectxray.c | 218 | ||||
-rw-r--r-- | gst/gl/gstgleffects.c | 5 | ||||
-rw-r--r-- | gst/gl/gstgleffects.h | 2 | ||||
-rw-r--r-- | tests/examples/gtk/fxtest/fxtest.c | 1 |
6 files changed, 269 insertions, 3 deletions
diff --git a/gst/gl/Makefile.am b/gst/gl/Makefile.am index 7215f8197..1b359bf2a 100644 --- a/gst/gl/Makefile.am +++ b/gst/gl/Makefile.am @@ -43,9 +43,11 @@ libgstopengl_la_SOURCES = \ effects/gstgleffectbulge.c \ effects/gstgleffectsquare.c \ effects/gstgleffectlumatocurve.c \ + effects/gstgleffectlumatocurve.h \ effects/gstgleffectrgbtocurve.c \ effects/gstgleffectsin.c \ - effects/gstgleffectglow.c + effects/gstgleffectglow.c \ + effects/gstgleffectxray.c if HAVE_GDKPIXBUF libgstopengl_la_SOURCES += gstglpixbufoverlay.c \ diff --git a/gst/gl/effects/gstgleffectscurves.h b/gst/gl/effects/gstgleffectscurves.h index e5a6432a2..8bbf345f8 100644 --- a/gst/gl/effects/gstgleffectscurves.h +++ b/gst/gl/effects/gstgleffectscurves.h @@ -18,8 +18,8 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __GST_GL_EFFECTS_TEXTURES__ -#define __GST_GL_EFFECTS_TEXTURES__ +#ifndef __GST_GL_EFFECTS_TEXTURES_H__ +#define __GST_GL_EFFECTS_TEXTURES_H__ struct _GstGLEffectsCurve { @@ -171,4 +171,42 @@ static const GstGLEffectsCurve sepia_curve = { "\352\376\375\353\376\376\355\376\376\356\376\376\357\377\377\357", }; +static const GstGLEffectsCurve xray_curve = { + 256, 1, 3, + "\377\377\377\377\377\377\376\376\376\375\375\376\374\375\375\373\374\375" + "\372\374\374\371\374\374\370\373\373\366\373\372\366\372\372\365\372\371" + "\363\371\371\363\371\370\362\370\370\360\370\367\360\367\366\357\367\365" + "\356\366\365\355\366\364\353\365\363\353\365\363\352\364\362\351\363\362" + "\347\363\361\346\362\361\345\362\361\344\362\360\343\361\357\343\361\356" + "\342\360\356\341\360\356\340\357\355\336\356\354\336\356\354\335\355\353" + "\334\355\353\333\355\352\331\354\351\331\353\351\330\353\350\327\353\350" + "\325\352\347\325\351\347\324\350\346\323\350\345\322\347\344\321\347\344" + "\320\347\344\317\346\343\316\346\342\315\345\341\314\344\341\313\344\340" + "\312\344\340\311\343\337\310\342\337\307\342\335\306\341\335\305\341\335" + "\303\340\334\303\337\333\302\337\333\301\337\332\300\336\331\276\335\331" + "\276\334\330\274\334\330\274\334\327\273\333\327\272\333\326\271\332\325" + "\270\332\325\267\331\324\266\330\323\265\330\323\264\327\322\263\327\321" + "\262\326\320\261\325\320\257\325\317\257\324\317\256\324\316\254\323\315" + "\254\322\315\253\322\314\252\321\313\251\321\313\250\320\312\246\317\311" + "\245\317\311\245\316\310\244\316\307\243\315\307\242\314\306\241\314\305" + "\240\312\305\237\312\304\236\312\303\235\311\303\234\311\302\233\307\301" + "\232\307\300\231\307\300\230\306\277\227\305\276\226\305\276\225\304\275" + "\224\303\274\223\303\273\222\302\273\221\301\272\220\301\271\217\300\270" + "\216\277\270\215\277\267\214\276\266\213\275\265\212\275\265\211\274\264" + "\210\273\263\207\273\262\206\272\262\205\271\261\204\270\260\203\270\257" + "\202\267\257\201\266\256\200\266\255\177\265\254~\264\253}\263\253|\263\252" + "{\262\251z\261\250y\260\247x\260\247w\257\246v\256\245u\255\244t\255\243" + "s\254\243r\253\242q\252\241p\252\240o\251\237n\250\236m\247\235l\246\235" + "l\246\235j\245\233i\244\232h\243\231g\242\230f\242\227e\241\226d\240\226" + "c\237\225b\236\224a\235\223`\234\222_\234\221_\233\220]\232\217\\\231\216" + "\\\230\215Z\227\214Y\226\214X\226\213W\225\212V\224\211U\223\210T\222\207" + "S\221\206R\221\205Q\217\204P\216\203O\215\202N\215\201M\214\200M\213\177" + "K\212~J\211}I\211|H\210|G\206zG\205zE\204xD\203vC\203vB\201tA\200s@\200q" + "@~p>}o>|o<{l<yk;xi9wh8wg8te6sd5qd4pa3n_2m]1k\\0j\\0hY.fW-dU,cT+aR*_P)_O(" + "]M'YK'XI%VI$TF$RD\"OB!M@\40K?\37I=\37G=\35E9\34C9\34A5\33>5\31<2\31<0\27" + ":.\27""5,\26""3*\24""1*\23.&\22.&\22*\"\21'\40\17%\36\16\"\34\15\"\32\14" + "\36\32\13\33\26\13\31\24\11\26\22\11\24\20\7\24\16\6\21\16\5\14\14\4\12\10" + "\3\7\6\3\5\4\1\2\2", +}; + #endif diff --git a/gst/gl/effects/gstgleffectxray.c b/gst/gl/effects/gstgleffectxray.c new file mode 100644 index 000000000..6d6c5d51c --- /dev/null +++ b/gst/gl/effects/gstgleffectxray.c @@ -0,0 +1,218 @@ +/* + * GStreamer + * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <gstgleffects.h> +#include <gstgleffectscurves.h> +#include <gstgleffectlumatocurve.h> + +/* Gaussian Kernel: std = 1.200000, size = 9x1 */ +static gfloat gauss_kernel[9] = { 0.001285, 0.014607, 0.082898, + 0.234927, 0.332452, 0.234927, + 0.082898, 0.014607, 0.001285 }; +/* Normalization Constant = 0.999885 */ + +static void gst_gl_effects_xray_step_one (gint width, gint height, guint texture, gpointer data) +{ + GstGLEffects* effects = GST_GL_EFFECTS (data); + + gst_gl_effects_luma_to_curve (effects, xray_curve, GST_GL_EFFECTS_CURVE_XRAY, + width, height, texture); +} + +static void +gst_gl_effects_xray_step_two (gint width, gint height, guint texture, gpointer data) +{ + GstGLEffects* effects = GST_GL_EFFECTS (data); + GstGLShader *shader; + + shader = g_hash_table_lookup (effects->shaderstable, "xray1"); + + if (!shader) { + shader = gst_gl_shader_new (); + g_hash_table_insert (effects->shaderstable, "xray1", shader); + } + + g_return_if_fail ( + gst_gl_shader_compile_and_check (shader, hconv9_fragment_source, + GST_GL_SHADER_FRAGMENT_SOURCE)); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + gst_gl_shader_use (shader); + + glActiveTexture (GL_TEXTURE1); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + glDisable (GL_TEXTURE_RECTANGLE_ARB); + + gst_gl_shader_set_uniform_1i (shader, "tex", 1); + + gst_gl_shader_set_uniform_1fv (shader, "kernel", 9, gauss_kernel); + gst_gl_shader_set_uniform_1f (shader, "norm_const", 0.999885); + gst_gl_shader_set_uniform_1f (shader, "norm_offset", 0.0f); + + gst_gl_effects_draw_texture (effects, texture); +} + +static void +gst_gl_effects_xray_step_three (gint width, gint height, guint texture, gpointer data) +{ + GstGLEffects* effects = GST_GL_EFFECTS (data); + GstGLShader *shader; + + shader = g_hash_table_lookup (effects->shaderstable, "xray2"); + + if (!shader) { + shader = gst_gl_shader_new (); + g_hash_table_insert (effects->shaderstable, "xray2", shader); + } + + g_return_if_fail ( + gst_gl_shader_compile_and_check (shader, vconv9_fragment_source, + GST_GL_SHADER_FRAGMENT_SOURCE)); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + gst_gl_shader_use (shader); + + glActiveTexture (GL_TEXTURE1); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + glDisable (GL_TEXTURE_RECTANGLE_ARB); + + gst_gl_shader_set_uniform_1i (shader, "tex", 1); + + gst_gl_shader_set_uniform_1fv (shader, "kernel", 9, gauss_kernel); + gst_gl_shader_set_uniform_1f (shader, "norm_const", 0.999885); + gst_gl_shader_set_uniform_1f (shader, "norm_offset", 0.0f); + + gst_gl_effects_draw_texture (effects, texture); +} + +static void +gst_gl_effects_xray_step_four (gint width, gint height, guint texture, gpointer data) +{ + GstGLEffects* effects = GST_GL_EFFECTS (data); + GstGLShader *shader; + + gfloat hkern[9] = { + 1.0, 0.0, -1.0, + 2.0, 0.0, -2.0, + 1.0, 0.0, -1.0 + }; + + gfloat vkern[9] = { + 1.0, 2.0, 1.0, + 0.0, 0.0, 0.0, + -1.0, -2.0, -1.0 + }; + + shader = g_hash_table_lookup (effects->shaderstable, "xray3"); + + if (!shader) { + shader = gst_gl_shader_new (); + g_hash_table_insert (effects->shaderstable, "xray3", shader); + } + + g_return_if_fail ( + gst_gl_shader_compile_and_check (shader, sobel_fragment_source, + GST_GL_SHADER_FRAGMENT_SOURCE)); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + gst_gl_shader_use (shader); + + glActiveTexture (GL_TEXTURE1); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + glDisable (GL_TEXTURE_RECTANGLE_ARB); + + gst_gl_shader_set_uniform_1i (shader, "tex", 1); + + gst_gl_shader_set_uniform_1fv (shader, "hkern", 9, hkern); + gst_gl_shader_set_uniform_1fv (shader, "vkern", 9, vkern); + + gst_gl_shader_set_uniform_1i (shader, "invert", TRUE); + + gst_gl_effects_draw_texture (effects, texture); +} + +void +gst_gl_effects_xray_step_five (gint width, gint height, guint texture, gpointer stuff) +{ + GstGLEffects* effects = GST_GL_EFFECTS (stuff); + GstGLShader *shader; + + shader = g_hash_table_lookup (effects->shaderstable, "xray4"); + + if (!shader) { + shader = gst_gl_shader_new (); + g_hash_table_insert (effects->shaderstable, "xray4", shader); + } + + g_return_if_fail ( + gst_gl_shader_compile_and_check (shader, multiply_fragment_source, + GST_GL_SHADER_FRAGMENT_SOURCE)); + + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + + gst_gl_shader_use (shader); + + glActiveTexture (GL_TEXTURE2); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, effects->midtexture[2]); + glDisable(GL_TEXTURE_RECTANGLE_ARB); + + gst_gl_shader_set_uniform_1i (shader, "base", 2); + + glActiveTexture (GL_TEXTURE1); + glEnable (GL_TEXTURE_RECTANGLE_ARB); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture); + glDisable(GL_TEXTURE_RECTANGLE_ARB); + + gst_gl_shader_set_uniform_1f (shader, "alpha", (gfloat) 0.28f); + gst_gl_shader_set_uniform_1i (shader, "blend", 1); + + gst_gl_effects_draw_texture (effects, texture); +} + +void gst_gl_effects_xray (GstGLEffects *effects) { + GstGLFilter *filter = GST_GL_FILTER (effects); + + /* map luma to xray curve */ + gst_gl_filter_render_to_target (filter, effects->intexture, effects->midtexture[0], + gst_gl_effects_xray_step_one, effects); + /* horizontal blur */ + gst_gl_filter_render_to_target (filter, effects->midtexture[0], effects->midtexture[1], + gst_gl_effects_xray_step_two, effects); + /* vertical blur */ + gst_gl_filter_render_to_target (filter, effects->midtexture[1], effects->midtexture[2], + gst_gl_effects_xray_step_three, effects); + /* detect edges with Sobel */ + gst_gl_filter_render_to_target (filter, effects->midtexture[2], effects->midtexture[3], + gst_gl_effects_xray_step_four, effects); + /* multiply edges with the blurred image */ + gst_gl_filter_render_to_target (filter, effects->midtexture[3], effects->outtexture, + gst_gl_effects_xray_step_five, effects); +} diff --git a/gst/gl/gstgleffects.c b/gst/gl/gstgleffects.c index 248d35dc7..5d569ffc8 100644 --- a/gst/gl/gstgleffects.c +++ b/gst/gl/gstgleffects.c @@ -72,6 +72,7 @@ typedef enum { GST_GL_EFFECT_SEPIA, GST_GL_EFFECT_XPRO, GST_GL_EFFECT_LUMA_XPRO, + GST_GL_EFFECT_XRAY, GST_GL_EFFECT_SIN, GST_GL_EFFECT_GLOW, GST_GL_N_EFFECTS @@ -96,6 +97,7 @@ gst_gl_effects_effect_get_type (void) { GST_GL_EFFECT_SEPIA, "Sepia Toning Effect", "sepia" }, { GST_GL_EFFECT_XPRO, "Cross Processing Effect", "xpro" }, { GST_GL_EFFECT_LUMA_XPRO, "Luma Cross Processing Effect", "lumaxpro" }, + { 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" }, { 0, NULL, NULL } @@ -151,6 +153,9 @@ gst_gl_effects_set_effect (GstGLEffects *effects, gint effect_type) { case GST_GL_EFFECT_LUMA_XPRO: effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_luma_xpro; break; + case GST_GL_EFFECT_XRAY: + effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_xray; + break; case GST_GL_EFFECT_SIN: effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sin; break; diff --git a/gst/gl/gstgleffects.h b/gst/gl/gstgleffects.h index e0d3fa01f..5caf9b87e 100644 --- a/gst/gl/gstgleffects.h +++ b/gst/gl/gstgleffects.h @@ -50,6 +50,7 @@ enum { GST_GL_EFFECTS_CURVE_SEPIA, GST_GL_EFFECTS_CURVE_XPRO, GST_GL_EFFECTS_CURVE_LUMA_XPRO, + GST_GL_EFFECTS_CURVE_XRAY, GST_GL_EFFECTS_N_CURVES }; @@ -100,6 +101,7 @@ void gst_gl_effects_square (GstGLEffects *effects); void gst_gl_effects_heat (GstGLEffects *effects); void gst_gl_effects_sepia (GstGLEffects *effects); void gst_gl_effects_xpro (GstGLEffects *effects); +void gst_gl_effects_xray (GstGLEffects *effects); void gst_gl_effects_luma_xpro (GstGLEffects *effects); void gst_gl_effects_sin (GstGLEffects *effects); void gst_gl_effects_glow (GstGLEffects *effects); diff --git a/tests/examples/gtk/fxtest/fxtest.c b/tests/examples/gtk/fxtest/fxtest.c index f3c2bfa98..36dd2c162 100644 --- a/tests/examples/gtk/fxtest/fxtest.c +++ b/tests/examples/gtk/fxtest/fxtest.c @@ -190,6 +190,7 @@ main (gint argc, gchar * argv[]) gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "xpro"); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "lumaxpro"); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "sepia"); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "xray"); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "sin"); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "glow"); |