[408/906] gleffects: start to make it compatible with OpenGL ES 2.0

For now only identity, mirror and squeeze effects are available.
Maybe some factorization is needed about compilation shader
before to put the other effects since only a copy/past is needed,
at least until effect number 9: heat.
The effects from 10:sepia to 15:glow require more work.
This commit is contained in:
Julien Isorce 2009-11-21 21:40:14 +01:00 committed by Matthew Waters
parent 9e22a5e0e6
commit e002f92e6d
9 changed files with 200 additions and 17 deletions

View file

@ -30,17 +30,10 @@ OPENGL_SOURCES = \
gltestsrc.h \
gstgltestsrc.c \
gstgltestsrc.h \
gstgleffects.c \
gstgleffects.h \
gstglmosaic.c \
gstglmosaic.h \
gstgloverlay.h \
effects/gstgleffectssources.c \
effects/gstgleffectssources.h \
effects/gstgleffectscurves.h \
effects/gstgleffectidentity.c \
effects/gstgleffectmirror.c \
effects/gstgleffectsqueeze.c \
effects/gstgleffectstretch.c \
effects/gstgleffecttunnel.c \
effects/gstgleffectfisheye.c \
@ -65,6 +58,13 @@ libgstopengl_la_SOURCES = \
gstgldownload.h \
gstglfiltercube.c \
gstglfiltercube.h \
gstgleffects.c \
gstgleffects.h \
effects/gstgleffectssources.c \
effects/gstgleffectssources.h \
effects/gstgleffectidentity.c \
effects/gstgleffectmirror.c \
effects/gstgleffectsqueeze.c \
$(OPENGL_SOURCES)
# check order of CFLAGS and LIBS, shouldn't the order be the other way around

View file

@ -26,8 +26,45 @@ gst_gl_effects_identity_callback (gint width, gint height, guint texture,
{
GstGLEffects *effects = GST_GL_EFFECTS (data);
#ifndef OPENGL_ES2
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
#else
GstGLShader *shader = g_hash_table_lookup (effects->shaderstable, "identity0");
if (!shader) {
shader = gst_gl_shader_new ();
g_hash_table_insert (effects->shaderstable, "identity0", shader);
if (shader) {
GError *error = NULL;
gst_gl_shader_set_vertex_source (shader, vertex_shader_source);
gst_gl_shader_set_fragment_source (shader, identity_fragment_source);
gst_gl_shader_compile (shader, &error);
if (error) {
GST_ERROR ("%s", error->message);
g_error_free (error);
error = NULL;
gst_gl_shader_use (NULL);
} else {
effects->draw_attr_position_loc =
gst_gl_shader_get_attribute_location (shader, "a_position");
effects->draw_attr_texture_loc =
gst_gl_shader_get_attribute_location (shader, "a_texCoord");
}
}
}
gst_gl_shader_use (shader);
glActiveTexture (GL_TEXTURE0);
glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
gst_gl_shader_set_uniform_1i (shader, "tex", 0);
#endif
gst_gl_effects_draw_texture (effects, texture);
}

View file

@ -33,13 +33,36 @@ gst_gl_effects_mirror_callback (gint width, gint height, guint texture,
if (!shader) {
shader = gst_gl_shader_new ();
g_hash_table_insert (effects->shaderstable, "mirror0", shader);
#ifdef OPENGL_ES2
if (shader) {
GError *error = NULL;
gst_gl_shader_set_vertex_source (shader, vertex_shader_source);
gst_gl_shader_set_fragment_source (shader, mirror_fragment_source);
gst_gl_shader_compile (shader, &error);
if (error) {
GST_ERROR ("%s", error->message);
g_error_free (error);
error = NULL;
gst_gl_shader_use (NULL);
} else {
effects->draw_attr_position_loc =
gst_gl_shader_get_attribute_location (shader, "a_position");
effects->draw_attr_texture_loc =
gst_gl_shader_get_attribute_location (shader, "a_texCoord");
}
}
#endif
}
#ifndef OPENGL_ES2
g_return_if_fail (gst_gl_shader_compile_and_check (shader,
mirror_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
#endif
gst_gl_shader_use (shader);
@ -49,8 +72,10 @@ gst_gl_effects_mirror_callback (gint width, gint height, guint texture,
gst_gl_shader_set_uniform_1i (shader, "tex", 0);
#ifndef OPENGL_ES2
gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
#endif
gst_gl_effects_draw_texture (effects, texture);
}

View file

@ -33,13 +33,36 @@ gst_gl_effects_squeeze_callback (gint width, gint height, guint texture,
if (!shader) {
shader = gst_gl_shader_new ();
g_hash_table_insert (effects->shaderstable, "squeeze0", shader);
#ifdef OPENGL_ES2
if (shader) {
GError *error = NULL;
gst_gl_shader_set_vertex_source (shader, vertex_shader_source);
gst_gl_shader_set_fragment_source (shader, squeeze_fragment_source);
gst_gl_shader_compile (shader, &error);
if (error) {
GST_ERROR ("%s", error->message);
g_error_free (error);
error = NULL;
gst_gl_shader_use (NULL);
} else {
effects->draw_attr_position_loc =
gst_gl_shader_get_attribute_location (shader, "a_position");
effects->draw_attr_texture_loc =
gst_gl_shader_get_attribute_location (shader, "a_texCoord");
}
}
#endif
}
#ifndef OPENGL_ES2
g_return_if_fail (gst_gl_shader_compile_and_check (shader,
squeeze_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE));
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
#endif
gst_gl_shader_use (shader);
@ -49,8 +72,10 @@ gst_gl_effects_squeeze_callback (gint width, gint height, guint texture,
gst_gl_shader_set_uniform_1i (shader, "tex", 0);
#ifndef OPENGL_ES2
gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
#endif
gst_gl_effects_draw_texture (effects, texture);
}

View file

@ -24,29 +24,71 @@
/* A common file for sources is needed since shader sources can be
* generic and reused by several effects */
/* Vertex shader */
const gchar *vertex_shader_source =
"attribute vec4 a_position;"
"attribute vec2 a_texCoord;"
"varying vec2 v_texCoord;"
"void main()"
"{"
" gl_Position = a_position;"
" v_texCoord = a_texCoord;"
"}";
/* Identity effect */
const gchar *identity_fragment_source =
"precision mediump float;"
"varying vec2 v_texCoord;"
"uniform sampler2D tex;"
"void main()"
"{"
" gl_FragColor = texture2D(tex, v_texCoord);"
"}";
/* Mirror effect */
const gchar *mirror_fragment_source =
#ifndef OPENGL_ES2
"#extension GL_ARB_texture_rectangle : enable\n"
"uniform sampler2DRect tex;"
"uniform float width, height;"
#else
"precision mediump float;"
"varying vec2 v_texCoord;"
"uniform sampler2D tex;"
#endif
"void main () {"
#ifndef OPENGL_ES2
" vec2 tex_size = vec2 (width, height);"
" vec2 texturecoord = gl_TexCoord[0].xy;"
" vec2 normcoord;"
" normcoord = texturecoord / tex_size - 1.0;"
" normcoord.x *= sign (normcoord.x);"
" texturecoord = (normcoord + 1.0) * tex_size;"
" vec4 color = texture2DRect (tex, texturecoord); "
" gl_FragColor = color * gl_Color;" "}";
" vec4 color = texture2DRect (tex, texturecoord);"
" gl_FragColor = color * gl_Color;"
#else
" vec2 texturecoord = v_texCoord.xy;"
" float normcoord = texturecoord.x - 0.5;"
" normcoord *= sign (normcoord);"
" texturecoord.x = (normcoord + 0.5);"
" gl_FragColor = texture2D (tex, texturecoord);"
#endif
"}";
/* Squeeze effect */
const gchar *squeeze_fragment_source =
#ifndef OPENGL_ES2
"#extension GL_ARB_texture_rectangle : enable\n"
"uniform sampler2DRect tex;"
"uniform float width, height;"
#else
"precision mediump float;"
"varying vec2 v_texCoord;"
"uniform sampler2D tex;"
#endif
"void main () {"
#ifndef OPENGL_ES2
" vec2 tex_size = vec2 (width, height);"
" vec2 texturecoord = gl_TexCoord[0].xy;"
" vec2 normcoord;"
@ -56,7 +98,17 @@ const gchar *squeeze_fragment_source =
" normcoord = normcoord / r;"
" texturecoord = (normcoord + 1.0) * tex_size;"
" vec4 color = texture2DRect (tex, texturecoord); "
" gl_FragColor = color * gl_Color;" "}";
" gl_FragColor = color * gl_Color;"
#else
" vec2 texturecoord = v_texCoord.xy;"
" vec2 normcoord = texturecoord - 0.5;"
" float r = length (normcoord);"
" r = pow(r, 0.40)*1.3;"
" normcoord = normcoord / r;"
" texturecoord = (normcoord + 0.5);"
" gl_FragColor = texture2D (tex, texturecoord);"
#endif
"}";
/* Stretch Effect */

View file

@ -21,6 +21,8 @@
#ifndef __GST_GL_EFFECTS_SOURCES_H__
#define __GST_GL_EFFECTS_SOURCES_H__
extern const gchar *vertex_shader_source;
extern const gchar *identity_fragment_source;
extern const gchar *mirror_fragment_source;
extern const gchar *squeeze_fragment_source;
extern const gchar *stretch_fragment_source;

View file

@ -103,6 +103,7 @@ 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"},
#ifndef OPENGL_ES2
{GST_GL_EFFECT_STRETCH, "Stretch Effect", "stretch"},
{GST_GL_EFFECT_FISHEYE, "FishEye Effect", "fisheye"},
{GST_GL_EFFECT_TWIRL, "Twirl Effect", "twirl"},
@ -116,6 +117,7 @@ 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}
};
@ -140,6 +142,7 @@ gst_gl_effects_set_effect (GstGLEffects * effects, gint effect_type)
case GST_GL_EFFECT_SQUEEZE:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_squeeze;
break;
#ifndef OPENGL_ES2
case GST_GL_EFFECT_STRETCH:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_stretch;
break;
@ -179,6 +182,7 @@ gst_gl_effects_set_effect (GstGLEffects * effects, gint effect_type)
case GST_GL_EFFECT_GLOW:
effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_glow;
break;
#endif
default:
g_assert_not_reached ();
}
@ -271,6 +275,7 @@ gst_gl_effects_draw_texture (GstGLEffects * effects, GLuint tex)
{
GstGLFilter *filter = GST_GL_FILTER (effects);
#ifndef OPENGL_ES2
glActiveTexture (GL_TEXTURE0);
glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
@ -287,6 +292,36 @@ gst_gl_effects_draw_texture (GstGLEffects * effects, GLuint tex)
glVertex2f (-1.0, 1.0);
glEnd ();
#else
const GLfloat vVertices[] = { -1.0f, -1.0f, 0.0f,
0.0f, 0.0f,
1.0, -1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f,
-1.0f, 1.0f, 0.0f,
0.0f, 1.0f
};
GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
//glClear (GL_COLOR_BUFFER_BIT);
//Load the vertex position
glVertexAttribPointer (effects->draw_attr_position_loc, 3, GL_FLOAT,
GL_FALSE, 5 * sizeof (GLfloat), vVertices);
//Load the texture coordinate
glVertexAttribPointer (effects->draw_attr_texture_loc, 2, GL_FLOAT,
GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]);
glEnableVertexAttribArray (effects->draw_attr_position_loc);
glEnableVertexAttribArray (effects->draw_attr_texture_loc);
glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
#endif
}
static void
@ -301,8 +336,10 @@ set_horizontal_swap (GstGLDisplay * display, gpointer data)
0.0, 0.0, 0.0, 1.0
};
#ifndef OPENGL_ES2
glMatrixMode (GL_MODELVIEW);
glLoadMatrixd (mirrormatrix);
#endif
}
static void

View file

@ -70,6 +70,11 @@ struct _GstGLEffects
GHashTable *shaderstable;
gboolean horizontal_swap; /* switch left to right */
#ifdef OPENGL_ES2
GLint draw_attr_position_loc;
GLint draw_attr_texture_loc;
#endif
};
struct _GstGLEffectsClass

View file

@ -48,8 +48,10 @@
#include "gstglimagesink.h"
#include "gstglfiltercube.h"
#include "gstgleffects.h"
GType gst_gl_filter_cube_get_type (void);
GType gst_gl_effects_get_type (void);
#ifndef OPENGL_ES2
#include "gstgltestsrc.h"
@ -58,11 +60,9 @@ GType gst_gl_filter_cube_get_type (void);
#include "gstglfilterapp.h"
#include "gstglcolorscale.h"
#include "gstgldeinterlace.h"
#include "gstgleffects.h"
#include "gstglbumper.h"
#include "gstglmosaic.h"
GType gst_gl_effects_get_type (void);
GType gst_gl_deinterlace_get_type (void);
GType gst_gl_filter_app_get_type (void);
GType gst_gl_filterblur_get_type (void);
@ -104,6 +104,11 @@ plugin_init (GstPlugin * plugin)
return FALSE;
}
if (!gst_element_register (plugin, "gleffects",
GST_RANK_NONE, gst_gl_effects_get_type ())) {
return FALSE;
}
#ifndef OPENGL_ES2
if (!gst_element_register (plugin, "gltestsrc",
GST_RANK_NONE, GST_TYPE_GL_TEST_SRC)) {
@ -123,11 +128,6 @@ plugin_init (GstPlugin * plugin)
return FALSE;
}
if (!gst_element_register (plugin, "gleffects",
GST_RANK_NONE, gst_gl_effects_get_type ())) {
return FALSE;
}
if (!gst_element_register (plugin, "glfilterblur",
GST_RANK_NONE, gst_gl_filterblur_get_type ())) {
return FALSE;