summaryrefslogtreecommitdiff
path: root/ext/libvisual
diff options
context:
space:
mode:
authorJulien Isorce <julien.isorce@gmail.com>2012-04-04 16:22:40 +0200
committerMatthew Waters <ystreet00@gmail.com>2014-03-15 18:36:43 +0100
commitb88351ad0c367ea862a3d6e744b006ae13f40ea5 (patch)
treed85f34ad1b6bceddddece02469791bde37aa80ec /ext/libvisual
parent6bb3f66c4255136c827df39495ef0ea7ad9eec1c (diff)
downloadgstreamer-plugins-bad-b88351ad0c367ea862a3d6e744b006ae13f40ea5.tar.gz
[488/906] libvisual-gl: full compatibility with projectM-libvisual if libprojectM >= 2.0.1
Fix bug #310775
Diffstat (limited to 'ext/libvisual')
-rw-r--r--ext/libvisual/visual-gl.c78
1 files changed, 57 insertions, 21 deletions
diff --git a/ext/libvisual/visual-gl.c b/ext/libvisual/visual-gl.c
index ac0862893..f590d864f 100644
--- a/ext/libvisual/visual-gl.c
+++ b/ext/libvisual/visual-gl.c
@@ -80,6 +80,7 @@ struct _GstVisualGL
GstGLDisplay *display;
GLuint fbo;
GLuint depthbuffer;
+ GLuint midtexture;
GLdouble actor_projection_matrix[16];
GLdouble actor_modelview_matrix[16];
GLboolean is_enabled_gl_depth_test;
@@ -254,6 +255,7 @@ gst_visual_gl_init (GstVisualGL * visual)
visual->display = NULL;
visual->fbo = 0;
visual->depthbuffer = 0;
+ visual->midtexture = 0;
visual->is_enabled_gl_depth_test = GL_FALSE;
visual->gl_depth_func = GL_LESS;
@@ -362,6 +364,9 @@ gst_visual_gl_src_setcaps (GstPad * pad, GstCaps * caps)
visual->duration =
gst_util_uint64_scale_int (GST_SECOND, visual->fps_d, visual->fps_n);
+ gst_gl_display_gen_texture (visual->display, &visual->midtexture,
+ visual->width, visual->height);
+
gst_gl_display_gen_fbo (visual->display, visual->width, visual->height,
&visual->fbo, &visual->depthbuffer);
@@ -735,13 +740,12 @@ check_gl_matrix (void)
}
static void
-render_frame (gint width, gint height, guint texture, GstVisualGL * visual)
+render_frame (GstVisualGL * visual)
{
const guint16 *data;
VisBuffer *lbuf, *rbuf;
guint16 ldata[VISUAL_SAMPLES], rdata[VISUAL_SAMPLES];
guint i;
- //GLint current_fbo = 0;
/* Read VISUAL_SAMPLES samples per channel */
data =
@@ -787,15 +791,16 @@ render_frame (gint width, gint height, guint texture, GstVisualGL * visual)
glLoadMatrixd (visual->actor_modelview_matrix);
/* This line try to hacks compatiblity with libprojectM
- * You have to do that before calling glDrawBuffer(GL_BACK)
- * Actually, at this point the current fbo is attached.
- * then the folowing line unbind it.
- * TODO: We have to rebind it just before final drawing
- * if we want to append other glfilters after it.
+ * If libprojectM version <= 2.0.0 then we have to unbind our current
+ * fbo to see something. But it's incorrect and we cannot use fbo chainning (append other glfilters
+ * after libvisual_gl_projectM will not work)
+ * To have full compatibility, libprojectM needs to take care of our fbo.
+ * Indeed libprojectM has to unbind it before the first rendering pass
+ * and then rebind it before the final pass. It's done from 2.0.1
*/
- //glGetIntegerv(GL_FRAMEBUFFER_BINDING, &current_fbo);
if (g_ascii_strncasecmp (gst_element_get_name (GST_ELEMENT (visual)),
- "visualglprojectm", 16) == 0)
+ "visualglprojectm", 16) == 0
+ && !HAVE_PROJECTM_TAKING_CARE_OF_EXTERNAL_FBO)
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
actor_negotiate (visual->display, visual);
@@ -810,16 +815,6 @@ render_frame (gint width, gint height, guint texture, GstVisualGL * visual)
glBlendFunc (visual->gl_blend_src_alpha, GL_ZERO);
}
- glMatrixMode (GL_MODELVIEW);
- glScaled (1.0, -1.0, 1.0);
-
- /* TODO: It should be possible to split libvisual rendering:
- * framebuffer pass1,2,3 ... and final rendering
- * This way we could rebind our fbo just before the
- * final libvisual rendering
- */
- //glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, current_fbo);
-
visual_actor_run (visual->actor, visual->audio);
check_gl_matrix ();
@@ -844,6 +839,36 @@ render_frame (gint width, gint height, guint texture, GstVisualGL * visual)
GST_DEBUG_OBJECT (visual, "rendered one frame");
}
+static void
+bottom_up_to_top_down (gint width, gint height, guint texture,
+ GstVisualGL * visual)
+{
+
+ glEnable (GL_TEXTURE_RECTANGLE_ARB);
+ glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
+
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+
+ glBegin (GL_QUADS);
+ glTexCoord2i (0, 0);
+ glVertex2i (-1, 1);
+ glTexCoord2i (width, 0);
+ glVertex2i (1, 1);
+ glTexCoord2i (width, height);
+ glVertex2i (1, -1);
+ glTexCoord2i (0, height);
+ glVertex2i (-1, -1);
+ glEnd ();
+
+ glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0);
+ glDisable (GL_TEXTURE_RECTANGLE_ARB);
+
+ GST_DEBUG_OBJECT (visual, "bottom up to top down");
+}
+
static GstFlowReturn
gst_visual_gl_chain (GstPad * pad, GstBuffer * buffer)
{
@@ -931,10 +956,16 @@ gst_visual_gl_chain (GstPad * pad, GstBuffer * buffer)
}
}
- /* this is a pretty weird API */
+ /* render libvisual plugin to our target */
+ gst_gl_display_use_fbo_v2 (visual->display,
+ visual->width, visual->height, visual->fbo, visual->depthbuffer,
+ visual->midtexture, (GLCB_V2) render_frame, (gpointer *) visual);
+
+ /* gst video is top-down whereas opengl plan is bottom up */
gst_gl_display_use_fbo (visual->display,
visual->width, visual->height, visual->fbo, visual->depthbuffer,
- outbuf->texture, (GLCB) render_frame, 0, 0, 0,
+ outbuf->texture, (GLCB) bottom_up_to_top_down,
+ visual->width, visual->height, visual->midtexture,
0, visual->width, 0, visual->height, GST_GL_DISPLAY_PROJECTION_ORTHO2D,
(gpointer *) visual);
@@ -1053,6 +1084,11 @@ gst_visual_gl_change_state (GstElement * element, GstStateChange transition)
visual->fbo = 0;
visual->depthbuffer = 0;
}
+ if (visual->midtexture) {
+ gst_gl_display_del_texture (visual->display, visual->midtexture,
+ visual->width, visual->height);
+ visual->midtexture = 0;
+ }
if (visual->display) {
g_object_unref (visual->display);
visual->display = NULL;