[471/906] glshader: add dynamic fragment shader filter

Also add fragment shader parser
Fix bug #600195
This commit is contained in:
Luc Deschenaux 2011-11-17 17:36:44 +01:00 committed by Matthew Waters
parent 7d4de78102
commit 268f1a30b2
14 changed files with 2382 additions and 1 deletions

View file

@ -24,6 +24,7 @@ add_library (gstgl STATIC
gstglbuffer.c
gstglfilter.c
gstglmixer.c
gstglshadervariables.c
gstglshader.c)
target_link_libraries(gstgl
@ -47,6 +48,7 @@ else (WIN32)
gstglbuffer.c
gstglfilter.c
gstglmixer.c
gstglshadervariables.c
gstglshader.c)
target_link_libraries(gstgl
@ -70,6 +72,7 @@ else (WIN32)
gstglbuffer.c
gstglfilter.c
gstglmixer.c
gstglshadervariables.c
gstglshader.c)
target_link_libraries(gstgl

View file

@ -7,6 +7,7 @@ gstlibsgstgl_C_FILES = \
gstglbuffer.c \
gstglfilter.c \
gstglmixer.c \
gstglshadervariables.c \
gstglshader.c
gstlibsgstgl_OBJC_FILES = gstglwindow_cocoa.m

View file

@ -13,7 +13,8 @@ libgstgl_@GST_MAJORMINOR@_la_SOURCES = \
gstglbuffer.c \
gstglfilter.c \
gstglmixer.c \
gstglshader.c
gstglshader.c \
gstglshadervariables.c
if GL_BACKEND_WIN32
libgstgl_@GST_MAJORMINOR@_la_SOURCES += gstglwindow_win32.c
@ -37,6 +38,7 @@ libgstgl_@GST_MAJORMINOR@include_HEADERS = \
gstglfilter.h \
gstglmixer.h \
gstglmixerpad.h \
gstglshadervariables.h \
gstglshader.h
libgstgl_@GST_MAJORMINOR@_la_LIBADD = \

View file

@ -94,7 +94,28 @@ G_BEGIN_DECLS
#define glUniform1fARB glUniform1f
#define glUniform1fvARB glUniform1fv
#define glUniform1iARB glUniform1i
#define glUniform1ivARB glUniform1iv
#define glUniform2fARB glUniform2f
#define glUniform2fvARB glUniform2fv
#define glUniform2iARB glUniform2i
#define glUniform2ivARB glUniform2iv
#define glUniform3fARB glUniform3f
#define glUniform3fvARB glUniform3fv
#define glUniform3iARB glUniform3i
#define glUniform3ivARB glUniform3iv
#define glUniform4fARB glUniform4f
#define glUniform4fvARB glUniform4fv
#define glUniform4iARB glUniform4i
#define glUniform4ivARB glUniform4iv
#define glUniformMatrix2fvARB glUniformMatrix2fv
#define glUniformMatrix3fvARB glUniformMatrix3fv
#define glUniformMatrix4fvARB glUniformMatrix4fv
#define glUniformMatrix2x3fvARB glUniformMatrix2x3fv
#define glUniformMatrix2x4fvARB glUniformMatrix2x4fv
#define glUniformMatrix3x2fvARB glUniformMatrix3x2fv
#define glUniformMatrix3x3fvARB glUniformMatrix3x4fv
#define glUniformMatrix4x2fvARB glUniformMatrix4x2fv
#define glUniformMatrix4x3fvARB glUniformMatrix4x3fv
#define glGetUniformLocationARB glGetUniformLocation
#define glGetAttribLocationARB glGetAttribLocation
#define glBindAttribLocationARB glBindAttribLocation

View file

@ -518,6 +518,314 @@ gst_gl_shader_set_uniform_1i (GstGLShader * shader, const gchar * name,
glUniform1iARB (location, value);
}
void
gst_gl_shader_set_uniform_1iv (GstGLShader * shader, const gchar * name,
guint count, gint * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform1ivARB (location, count, value);
}
void
gst_gl_shader_set_uniform_2f (GstGLShader * shader, const gchar * name,
gfloat value0, gfloat value1)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform2fARB (location, value0, value1);
}
void
gst_gl_shader_set_uniform_2fv (GstGLShader * shader, const gchar * name,
guint count, gfloat * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform2fvARB (location, count, value);
}
void
gst_gl_shader_set_uniform_2i (GstGLShader * shader, const gchar * name,
gint v0, gint v1)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform2iARB (location, v0, v1);
}
void
gst_gl_shader_set_uniform_2iv (GstGLShader * shader, const gchar * name,
guint count, gint * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform2ivARB (location, count, value);
}
void
gst_gl_shader_set_uniform_3f (GstGLShader * shader, const gchar * name,
gfloat v0, gfloat v1, gfloat v2)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform3fARB (location, v0, v1, v2);
}
void
gst_gl_shader_set_uniform_3fv (GstGLShader * shader, const gchar * name,
guint count, gfloat * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform3fvARB (location, count, value);
}
void
gst_gl_shader_set_uniform_3i (GstGLShader * shader, const gchar * name,
gint v0, gint v1, gint v2)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform3iARB (location, v0, v1, v2);
}
void
gst_gl_shader_set_uniform_3iv (GstGLShader * shader, const gchar * name,
guint count, gint * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform3ivARB (location, count, value);
}
void
gst_gl_shader_set_uniform_4f (GstGLShader * shader, const gchar * name,
gfloat v0, gfloat v1, gfloat v2, gfloat v3)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform4fARB (location, v0, v1, v2, v3);
}
void
gst_gl_shader_set_uniform_4fv (GstGLShader * shader, const gchar * name,
guint count, gfloat * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform4fvARB (location, count, value);
}
void
gst_gl_shader_set_uniform_4i (GstGLShader * shader, const gchar * name,
gint v0, gint v1, gint v2, gint v3)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform4iARB (location, v0, v1, v2, v3);
}
void
gst_gl_shader_set_uniform_4iv (GstGLShader * shader, const gchar * name,
guint count, gint * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniform4ivARB (location, count, value);
}
void
gst_gl_shader_set_uniform_matrix_2fv (GstGLShader * shader, const gchar * name,
GLsizei count, GLboolean transpose, const GLfloat * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniformMatrix2fvARB (location, count, transpose, value);
}
void
gst_gl_shader_set_uniform_matrix_2x3fv (GstGLShader * shader,
const gchar * name, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniformMatrix2x3fv (location, count, transpose, value);
}
void
gst_gl_shader_set_uniform_matrix_2x4fv (GstGLShader * shader,
const gchar * name, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniformMatrix2x4fv (location, count, transpose, value);
}
void
gst_gl_shader_set_uniform_matrix_3fv (GstGLShader * shader, const gchar * name,
GLsizei count, GLboolean transpose, const GLfloat * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniformMatrix3fvARB (location, count, transpose, value);
}
void
gst_gl_shader_set_uniform_matrix_3x2fv (GstGLShader * shader,
const gchar * name, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniformMatrix3x2fv (location, count, transpose, value);
}
void
gst_gl_shader_set_uniform_matrix_3x4fv (GstGLShader * shader,
const gchar * name, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniformMatrix3x4fv (location, count, transpose, value);
}
void
gst_gl_shader_set_uniform_matrix_4fv (GstGLShader * shader, const gchar * name,
GLsizei count, GLboolean transpose, const GLfloat * value)
@ -534,6 +842,40 @@ gst_gl_shader_set_uniform_matrix_4fv (GstGLShader * shader, const gchar * name,
glUniformMatrix4fvARB (location, count, transpose, value);
}
void
gst_gl_shader_set_uniform_matrix_4x2fv (GstGLShader * shader,
const gchar * name, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniformMatrix4x2fv (location, count, transpose, value);
}
void
gst_gl_shader_set_uniform_matrix_4x3fv (GstGLShader * shader,
const gchar * name, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
GstGLShaderPrivate *priv;
GLint location = -1;
priv = shader->priv;
g_return_if_fail (priv->program_handle != 0);
location = glGetUniformLocationARB (priv->program_handle, name);
glUniformMatrix4x3fv (location, count, transpose, value);
}
GLint
gst_gl_shader_get_attribute_location (GstGLShader * shader, const gchar * name)
{

View file

@ -93,10 +93,39 @@ void gst_gl_shader_release (GstGLShader *shader);
void gst_gl_shader_use (GstGLShader *shader);
void gst_gl_shader_set_uniform_1i (GstGLShader *shader, const gchar *name, gint value);
void gst_gl_shader_set_uniform_1iv (GstGLShader *shader, const gchar *name, guint count, gint * value);
void gst_gl_shader_set_uniform_1f (GstGLShader *shader, const gchar *name, gfloat value);
void gst_gl_shader_set_uniform_1fv (GstGLShader *shader, const gchar *name, guint count, gfloat * value);
void gst_gl_shader_set_uniform_2i (GstGLShader *shader, const gchar *name, gint v0, gint v1);
void gst_gl_shader_set_uniform_2iv (GstGLShader *shader, const gchar *name, guint count, gint * value);
void gst_gl_shader_set_uniform_2f (GstGLShader *shader, const gchar *name, gfloat v0, gfloat v1);
void gst_gl_shader_set_uniform_2fv (GstGLShader *shader, const gchar *name, guint count, gfloat * value);
void gst_gl_shader_set_uniform_3i (GstGLShader *shader, const gchar *name, gint v0, gint v1, gint v2);
void gst_gl_shader_set_uniform_3iv (GstGLShader *shader, const gchar *name, guint count, gint * value);
void gst_gl_shader_set_uniform_3f (GstGLShader *shader, const gchar *name, gfloat v0, gfloat v1, gfloat v2);
void gst_gl_shader_set_uniform_3fv (GstGLShader *shader, const gchar *name, guint count, gfloat * value);
void gst_gl_shader_set_uniform_4i (GstGLShader *shader, const gchar *name, gint v0, gint v1, gint v2, gint v3);
void gst_gl_shader_set_uniform_4iv (GstGLShader *shader, const gchar *name, guint count, gint * value);
void gst_gl_shader_set_uniform_4f (GstGLShader *shader, const gchar *name, gfloat v0, gfloat v1, gfloat v2, gfloat v3);
void gst_gl_shader_set_uniform_4fv (GstGLShader *shader, const gchar *name, guint count, gfloat * value);
void gst_gl_shader_set_uniform_matrix_2fv (GstGLShader * shader, const gchar * name,
GLsizei count, GLboolean transpose, const GLfloat* value);
void gst_gl_shader_set_uniform_matrix_2x3fv (GstGLShader * shader, const gchar * name,
GLsizei count, GLboolean transpose, const GLfloat* value);
void gst_gl_shader_set_uniform_matrix_2x4fv (GstGLShader * shader, const gchar * name,
GLsizei count, GLboolean transpose, const GLfloat* value);
void gst_gl_shader_set_uniform_matrix_3fv (GstGLShader * shader, const gchar * name,
GLsizei count, GLboolean transpose, const GLfloat* value);
void gst_gl_shader_set_uniform_matrix_3x2fv (GstGLShader * shader, const gchar * name,
GLsizei count, GLboolean transpose, const GLfloat* value);
void gst_gl_shader_set_uniform_matrix_3x4fv (GstGLShader * shader, const gchar * name,
GLsizei count, GLboolean transpose, const GLfloat* value);
void gst_gl_shader_set_uniform_matrix_4fv (GstGLShader * shader, const gchar * name,
GLsizei count, GLboolean transpose, const GLfloat* value);
void gst_gl_shader_set_uniform_matrix_4x2fv (GstGLShader * shader, const gchar * name,
GLsizei count, GLboolean transpose, const GLfloat* value);
void gst_gl_shader_set_uniform_matrix_4x3fv (GstGLShader * shader, const gchar * name,
GLsizei count, GLboolean transpose, const GLfloat* value);
GLint gst_gl_shader_get_attribute_location (GstGLShader *shader, const gchar *name);
void gst_gl_shader_bind_attribute_location (GstGLShader * shader, GLuint index, const gchar * name);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,39 @@
/*
* GStreamer
* Copyright (C) 2009 Luc Deschenaux <luc.deschenaux@freesurf.ch>
*
* 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.
*/
#ifndef GST_GLSHADER_VARIABLES
#define GST_GLSHADER_VARIABLES
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <gstglshader.h>
#define VALID_VARNAME_CHARS "abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
struct gst_gl_shadervariable_desc;
int gst_gl_shadervariables_parse (GstGLShader * shader, char *variables,
int (*_setvariable) (GstGLShader * shader,
struct gst_gl_shadervariable_desc * v));
int gst_gl_shadervariable_set (GstGLShader * shader,
struct gst_gl_shadervariable_desc *ret);
#endif

View file

@ -34,6 +34,7 @@ add_library (gstopengl MODULE
gstglfilterglass.c
gstglfilterapp.c
gstglfilterreflectedscreen.c
gstglfiltershader.c
gstglcolorscale.c
gltestsrc.c
gstgltestsrc.c

View file

@ -14,6 +14,7 @@ gstgl_C_FILES += \
gstglfilterglass.c \
gstglfilterapp.c \
gstglfilterreflectedscreen.c \
gstglfiltershader.c \
gstglcolorscale.c \
gltestsrc.c \
gstgltestsrc.c \

View file

@ -9,6 +9,8 @@ if GL_IS_OPENGL
OPENGL_SOURCES = \
gstglbumper.c \
gstglbumper.h \
gstglfiltershader.c \
gstglfiltershader.h \
gstglfilterblur.c \
gstglfilterblur.h \
gstglfiltersobel.c \

405
gst/gl/gstglfiltershader.c Normal file
View file

@ -0,0 +1,405 @@
/*
* glshader gstreamer plugin
* Copyrithg (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com>
* Copyright (C) 2009 Luc Deschenaux <luc.deschenaux@freesurf.ch>
*
* 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.
*/
/**
* SECTION:element-glshader
*
* Filter loading OpenGL fragment shader from file
*
* <refsect2>
* <title>Examples</title>
* |[
* gst-launch videotestsrc ! glupload ! glshader location=myshader.fs ! glimagesink
* ]|
* FBO (Frame Buffer Object) and GLSL (OpenGL Shading Language) are required.
* </refsect2>
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/controller/gstcontroller.h>
#include "gstglfiltershader.h"
#include <gstglshadervariables.h>
/* horizontal filter */
static gchar *hfilter_fragment_source;
static gchar *hfilter_fragment_variables[2];
enum
{
PROP_0,
PROP_LOCATION,
PROP_PRESET,
PROP_VARIABLES
};
#define GST_CAT_DEFAULT gst_gl_filtershader_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define DEBUG_INIT(bla) \
GST_DEBUG_CATEGORY_INIT (gst_gl_filtershader_debug, "glshader", 0, "glshader element");
GST_BOILERPLATE_FULL (GstGLFilterShader, gst_gl_filtershader, GstGLFilter,
GST_TYPE_GL_FILTER, DEBUG_INIT);
static void gst_gl_filtershader_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_gl_filtershader_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_gl_filter_filtershader_reset (GstGLFilter * filter);
static void gst_gl_filtershader_load_shader (char *filename, char **storage);
static void gst_gl_filtershader_load_variables (char *filename, char **storage);
static void gst_gl_filtershader_init_shader (GstGLFilter * filter);
static gboolean gst_gl_filtershader_filter (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static void gst_gl_filtershader_hcallback (gint width, gint height,
guint texture, gpointer stuff);
static void
gst_gl_filtershader_init_resources (GstGLFilter * filter)
{
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
filter->width, filter->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
}
static void
gst_gl_filtershader_reset_resources (GstGLFilter * filter)
{
//GstGLFilterShader *filtershader = GST_GL_FILTERSHADER (filter);
}
static void
gst_gl_filtershader_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_set_details_simple (element_class,
"OpenGL fragment shader filter", "Filter/Effect",
"Load GLSL fragment shader from file", "<luc.deschenaux@freesurf.ch>");
/* initialize library */
gst_controller_init (NULL, NULL);
}
static void
gst_gl_filtershader_class_init (GstGLFilterShaderClass * klass)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_filtershader_set_property;
gobject_class->get_property = gst_gl_filtershader_get_property;
g_object_class_install_property (gobject_class, PROP_LOCATION,
g_param_spec_string ("location", "File Location",
"Location of the GLSL file to load", NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_PRESET,
g_param_spec_string ("preset", "Preset File Location",
"Location of the shader uniform variables preset file", NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_VARIABLES,
g_param_spec_string ("vars", "Uniform variables",
"Set the shader uniform variables", NULL,
G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filtershader_filter;
GST_GL_FILTER_CLASS (klass)->display_init_cb =
gst_gl_filtershader_init_resources;
GST_GL_FILTER_CLASS (klass)->display_reset_cb =
gst_gl_filtershader_reset_resources;
GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filtershader_init_shader;
GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_filtershader_reset;
}
static void
gst_gl_filtershader_init (GstGLFilterShader * filtershader,
GstGLFilterShaderClass * klass)
{
filtershader->shader0 = NULL;
}
static void
gst_gl_filter_filtershader_reset (GstGLFilter * filter)
{
GstGLFilterShader *filtershader = GST_GL_FILTERSHADER (filter);
//blocking call, wait the opengl thread has destroyed the shader
gst_gl_display_del_shader (filter->display, filtershader->shader0);
}
static void
gst_gl_filtershader_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstGLFilterShader *filtershader = GST_GL_FILTERSHADER (object);
switch (prop_id) {
case PROP_LOCATION:
if (filtershader->filename) {
g_free (filtershader->filename);
}
if (filtershader->compiled) {
//gst_gl_display_del_shader (filtershader->filter.display, filtershader->shader0);
gst_gl_filter_filtershader_reset (&filtershader->filter);
filtershader->shader0 = 0;
}
filtershader->filename = g_strdup (g_value_get_string (value));
filtershader->compiled = 0;
filtershader->texSet = 0;
break;
case PROP_PRESET:
if (filtershader->presetfile) {
g_free (filtershader->presetfile);
}
filtershader->presetfile = g_strdup (g_value_get_string (value));
if (hfilter_fragment_variables[0]) {
g_free (hfilter_fragment_variables[0]);
hfilter_fragment_variables[0] = 0;
}
if (!filtershader->presetfile[0]) {
g_free (filtershader->presetfile);
filtershader->presetfile = 0;
}
break;
case PROP_VARIABLES:
if (hfilter_fragment_variables[1]) {
g_free (hfilter_fragment_variables[1]);
}
hfilter_fragment_variables[1] = g_strdup (g_value_get_string (value));
if (!hfilter_fragment_variables[1][0]) {
g_free (hfilter_fragment_variables[1]);
hfilter_fragment_variables[1] = 0;
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_gl_filtershader_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstGLFilterShader *filtershader = GST_GL_FILTERSHADER (object);
switch (prop_id) {
case PROP_LOCATION:
g_value_set_string (value, filtershader->filename);
break;
case PROP_PRESET:
g_value_set_string (value, filtershader->presetfile);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static int
gst_gl_filtershader_load_file (char *filename, char **storage)
{
size_t count;
ssize_t bytes;
int f;
// read the filter from file
GST_INFO ("loading file: %s", filename);
f = open (filename, O_RDONLY);
if (f < 0) {
GST_ERROR ("could not open file: %s", filename);
return -1;
}
if (*storage) {
g_free (*storage);
*storage = 0;
}
count = lseek (f, 0, SEEK_END);
*storage = g_malloc (count + 1);
if (!*storage) {
GST_ERROR ("g_malloc failed: %u", count);
return -1;
}
lseek (f, 0, SEEK_SET);
bytes = read (f, (void *) *storage, count);
if (bytes < 0 || bytes != count) {
GST_ERROR ("read failed: %u/%u", bytes, count);
return -1;
}
((char *) *storage)[count] = 0;
close (f);
GST_INFO ("read: %u", bytes);
return 0;
}
static void
gst_gl_filtershader_load_shader (char *filename, char **storage)
{
if (gst_gl_filtershader_load_file (filename, storage)) {
exit (1);
}
}
static void
gst_gl_filtershader_load_variables (char *filename, char **storage)
{
if (storage[0]) {
g_free (storage[0]);
storage[0] = 0;
}
if (!filename)
return;
if (gst_gl_filtershader_load_file (filename, storage)) {
exit (1);
}
}
static void
gst_gl_filtershader_variables_parse (GstGLShader * shader, gchar * variables)
{
gst_gl_shadervariables_parse (shader, variables, 0);
}
static void
gst_gl_filtershader_init_shader (GstGLFilter * filter)
{
GstGLFilterShader *filtershader = GST_GL_FILTERSHADER (filter);
gst_gl_filtershader_load_shader (filtershader->filename,
&hfilter_fragment_source);
//blocking call, wait the opengl thread has compiled the shader
gst_gl_display_gen_shader (filter->display, 0, hfilter_fragment_source,
&filtershader->shader0);
if (!filtershader->shader0) {
GST_ERROR ("Fragment Shader compilation failed.");
exit (1);
}
filtershader->compiled = 1;
gst_gl_filtershader_load_variables (filtershader->presetfile,
&hfilter_fragment_variables[0]);
}
static gboolean
gst_gl_filtershader_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer * outbuf)
{
GstGLFilterShader *filtershader = GST_GL_FILTERSHADER (filter);
if (!filtershader->compiled) {
gst_gl_filtershader_init_shader (filter);
}
gst_gl_filter_render_to_target (filter, inbuf->texture, ///
outbuf->texture, gst_gl_filtershader_hcallback, filtershader); ///
return TRUE;
}
static void
gst_gl_filtershader_hcallback (gint width, gint height, guint texture,
gpointer stuff)
{
GstGLFilter *filter = GST_GL_FILTER (stuff);
GstGLFilterShader *filtershader = GST_GL_FILTERSHADER (filter);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gst_gl_shader_use (filtershader->shader0);
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 (filtershader->shader0, "tex", 1);
if (hfilter_fragment_variables[0]) {
gst_gl_filtershader_variables_parse (filtershader->shader0,
hfilter_fragment_variables[0]);
g_free (hfilter_fragment_variables[0]);
hfilter_fragment_variables[0] = 0;
}
if (hfilter_fragment_variables[1]) {
gst_gl_filtershader_variables_parse (filtershader->shader0,
hfilter_fragment_variables[1]);
g_free (hfilter_fragment_variables[1]);
hfilter_fragment_variables[1] = 0;
}
gst_gl_filter_draw_texture (filter, texture);
}

View file

@ -0,0 +1,55 @@
/*
* glshader gstreamer plugin
* Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com>
* Copyright (C) 2009 Luc Deschenaux <luc.deschenaux@freesurf.ch>
*
* 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.
*/
#ifndef _GST_GL_FILTERSHADER_H_
#define _GST_GL_FILTERSHADER_H_
#include <gstglfilter.h>
#define GST_TYPE_GL_FILTERSHADER (gst_gl_filtershader_get_type())
#define GST_GL_FILTERSHADER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTERSHADER,GstGLFilterShader))
#define GST_IS_GL_FILTERSHADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTERSHADER))
#define GST_GL_FILTERSHADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_FILTERSHADER,GstGLFilterShaderClass))
#define GST_IS_GL_FILTERSHADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_FILTERSHADER))
#define GST_GL_FILTERSHADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_FILTERSHADER,GstGLFilterShaderClass))
typedef struct _GstGLFilterShader GstGLFilterShader;
typedef struct _GstGLFilterShaderClass GstGLFilterShaderClass;
struct _GstGLFilterShader
{
GstGLFilter filter;
GstGLShader *shader0;
int compiled;
gchar *filename;
gchar *presetfile;
int texSet;
};
struct _GstGLFilterShaderClass
{
GstGLFilterClass filter_class;
};
GType gst_gl_glfiltershader_get_type (void);
#endif /* _GST_GL_FILTERSHADER_H_ */

View file

@ -59,6 +59,7 @@ GType gst_gl_effects_get_type (void);
#include "gstglfilterglass.h"
#include "gstglfilterapp.h"
#include "gstglfilterreflectedscreen.h"
#include "gstglfiltershader.h"
#include "gstglcolorscale.h"
#include "gstgldeinterlace.h"
#include "gstglbumper.h"
@ -68,6 +69,7 @@ GType gst_gl_deinterlace_get_type (void);
GType gst_gl_filter_app_get_type (void);
GType gst_gl_filter_reflected_screen_get_type (void);
GType gst_gl_filterblur_get_type (void);
GType gst_gl_filtershader_get_type (void);
GType gst_gl_filtersobel_get_type (void);
GType gst_gl_filter_laplacian_get_type (void);
GType gst_gl_filter_glass_get_type (void);
@ -134,6 +136,11 @@ plugin_init (GstPlugin * plugin)
return FALSE;
}
if (!gst_element_register (plugin, "glshader",
GST_RANK_NONE, gst_gl_filtershader_get_type ())) {
return FALSE;
}
if (!gst_element_register (plugin, "glfiltersobel",
GST_RANK_NONE, gst_gl_filtersobel_get_type ())) {
return FALSE;