mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 19:20:35 +00:00
[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:
parent
9e22a5e0e6
commit
e002f92e6d
9 changed files with 200 additions and 17 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue