mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
[714/906] Add GstGLFramebuffer to replace _display_gen_fbo and friends
This version is simply API compatible with _display_gen_fbo. The next version will likely revamp the API
This commit is contained in:
parent
09496fc8a1
commit
4646a1e95e
5 changed files with 525 additions and 330 deletions
|
@ -16,7 +16,8 @@ libgstgl_@GST_API_VERSION@_la_SOURCES = \
|
|||
gstglwindow.c \
|
||||
gstglapi.c \
|
||||
gstglfeature.c \
|
||||
gstglutils.c
|
||||
gstglutils.c \
|
||||
gstglframebuffer.c
|
||||
|
||||
libgstgl_@GST_API_VERSION@_la_LIBADD = \
|
||||
$(GST_PLUGINS_BASE_LIBS) \
|
||||
|
@ -61,7 +62,8 @@ libgstgl_@GST_API_VERSION@include_HEADERS = \
|
|||
gstglupload.h \
|
||||
gstglapi.h \
|
||||
gstglfeature.h \
|
||||
gstglutils.h
|
||||
gstglutils.h \
|
||||
gstglframebuffer.h
|
||||
|
||||
libgstgl_@GST_API_VERSION@_la_CFLAGS = \
|
||||
$(GL_CFLAGS) \
|
||||
|
|
335
gst-libs/gst/gl/gstglframebuffer.c
Normal file
335
gst-libs/gst/gl/gstglframebuffer.c
Normal file
|
@ -0,0 +1,335 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2013 Matthew Waters <ystreet00@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., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "gstglframebuffer.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_gl_framebuffer_debug);
|
||||
#define GST_CAT_DEFAULT gst_gl_framebuffer_debug
|
||||
|
||||
#define DEBUG_INIT \
|
||||
GST_DEBUG_CATEGORY_INIT (gst_gl_framebuffer_debug, "glframebuffer", 0, "GL Framebuffer");
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GstGLFramebuffer, gst_gl_framebuffer, G_TYPE_OBJECT,
|
||||
DEBUG_INIT);
|
||||
|
||||
#define GST_GL_FRAMEBUFFER_GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_FRAMEBUFFER, GstGLFramebufferPrivate))
|
||||
|
||||
static void gst_gl_framebuffer_finalize (GObject * object);
|
||||
|
||||
struct _GstGLFramebufferPrivate
|
||||
{
|
||||
gint width;
|
||||
gint height;
|
||||
|
||||
guint fbo;
|
||||
guint depth;
|
||||
};
|
||||
|
||||
static void
|
||||
gst_gl_framebuffer_class_init (GstGLFramebufferClass * klass)
|
||||
{
|
||||
g_type_class_add_private (klass, sizeof (GstGLFramebufferPrivate));
|
||||
|
||||
G_OBJECT_CLASS (klass)->finalize = gst_gl_framebuffer_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_framebuffer_init (GstGLFramebuffer * fbo)
|
||||
{
|
||||
fbo->priv = GST_GL_FRAMEBUFFER_GET_PRIVATE (fbo);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_framebuffer_finalize (GObject * object)
|
||||
{
|
||||
GstGLFramebuffer *fbo = GST_GL_FRAMEBUFFER (object);
|
||||
|
||||
if (fbo->display) {
|
||||
gst_object_unref (fbo->display);
|
||||
fbo->display = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gst_gl_framebuffer_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
GstGLFramebuffer *
|
||||
gst_gl_framebuffer_new (GstGLDisplay * display)
|
||||
{
|
||||
GstGLFramebuffer *fbo = g_object_new (GST_TYPE_GL_FRAMEBUFFER, NULL);
|
||||
|
||||
fbo->display = gst_object_ref (display);
|
||||
|
||||
return fbo;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_framebuffer_generate (GstGLFramebuffer * frame, gint width, gint height,
|
||||
guint * fbo, guint * depth)
|
||||
{
|
||||
GLuint fake_texture = 0;
|
||||
const GstGLFuncs *gl;
|
||||
|
||||
g_return_val_if_fail (GST_IS_GL_FRAMEBUFFER (frame), FALSE);
|
||||
g_return_val_if_fail (fbo != NULL && depth != NULL, FALSE);
|
||||
g_return_val_if_fail (width > 0 && height > 0, FALSE);
|
||||
|
||||
gl = gst_gl_display_get_gl_vtable (frame->display);
|
||||
|
||||
GST_TRACE ("creating FBO dimensions:%ux%u", width, height);
|
||||
|
||||
if (!gl->GenFramebuffers) {
|
||||
gst_gl_display_set_error (frame->display,
|
||||
"Context, EXT_framebuffer_object not supported");
|
||||
return FALSE;
|
||||
}
|
||||
/* setup FBO */
|
||||
gl->GenFramebuffers (1, fbo);
|
||||
gl->BindFramebuffer (GL_FRAMEBUFFER, *fbo);
|
||||
|
||||
/* setup the render buffer for depth */
|
||||
gl->GenRenderbuffers (1, depth);
|
||||
gl->BindRenderbuffer (GL_RENDERBUFFER, *depth);
|
||||
|
||||
if (gst_gl_display_get_gl_api (frame->display) & GST_GL_API_OPENGL) {
|
||||
gl->RenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT,
|
||||
width, height);
|
||||
gl->RenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
|
||||
width, height);
|
||||
}
|
||||
if (gst_gl_display_get_gl_api (frame->display) & GST_GL_API_GLES2) {
|
||||
gl->RenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
|
||||
width, height);
|
||||
}
|
||||
|
||||
/* setup a texture to render to */
|
||||
gl->GenTextures (1, &fake_texture);
|
||||
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, fake_texture);
|
||||
gl->TexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
|
||||
width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
gl->TexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
|
||||
GL_LINEAR);
|
||||
gl->TexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR);
|
||||
gl->TexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
gl->TexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
|
||||
/* attach the texture to the FBO to renderer to */
|
||||
gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_RECTANGLE_ARB, fake_texture, 0);
|
||||
|
||||
/* attach the depth render buffer to the FBO */
|
||||
gl->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
GL_RENDERBUFFER, *depth);
|
||||
|
||||
if (gst_gl_display_get_gl_api (frame->display) & GST_GL_API_OPENGL) {
|
||||
gl->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, *depth);
|
||||
}
|
||||
|
||||
if (gl->CheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
gst_gl_display_set_error (frame->display,
|
||||
"GL framebuffer status incomplete");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* unbind the FBO */
|
||||
gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||
|
||||
gl->DeleteTextures (1, &fake_texture);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_framebuffer_use (GstGLFramebuffer * frame, gint texture_fbo_width,
|
||||
gint texture_fbo_height, GLuint fbo, GLuint depth_buffer,
|
||||
GLuint texture_fbo, GLCB cb, gint input_tex_width,
|
||||
gint input_tex_height, GLuint input_tex, gdouble proj_param1,
|
||||
gdouble proj_param2, gdouble proj_param3, gdouble proj_param4,
|
||||
GstGLDisplayProjection projection, gpointer stuff)
|
||||
{
|
||||
const GstGLFuncs *gl;
|
||||
#if GST_GL_HAVE_GLES2
|
||||
GLint viewport_dim[4];
|
||||
#endif
|
||||
|
||||
g_return_val_if_fail (GST_IS_GL_FRAMEBUFFER (frame), FALSE);
|
||||
g_return_val_if_fail (input_tex_width > 0 && input_tex_height > 0, FALSE);
|
||||
g_return_val_if_fail (texture_fbo_width > 0 && texture_fbo_height > 0, FALSE);
|
||||
g_return_val_if_fail (input_tex != 0, FALSE);
|
||||
g_return_val_if_fail (fbo != 0, FALSE);
|
||||
g_return_val_if_fail (texture_fbo != 0, FALSE);
|
||||
g_return_val_if_fail (cb != NULL, FALSE);
|
||||
|
||||
gl = frame->display->gl_vtable;
|
||||
|
||||
GST_TRACE ("Binding v1 FBO %u dimensions:%ux%u with texture:%u "
|
||||
"dimensions:%ux%u", fbo, texture_fbo_width,
|
||||
texture_fbo_height, texture_fbo, input_tex_width, input_tex_height);
|
||||
|
||||
gl->BindFramebuffer (GL_FRAMEBUFFER, fbo);
|
||||
|
||||
/*setup a texture to render to */
|
||||
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_fbo);
|
||||
|
||||
/* attach the texture to the FBO to renderer to */
|
||||
gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_RECTANGLE_ARB, texture_fbo, 0);
|
||||
|
||||
gst_gl_display_clear_shader (frame->display);
|
||||
|
||||
#if GST_GL_HAVE_OPENGL
|
||||
if (gst_gl_display_get_gl_api (frame->display) & GST_GL_API_OPENGL) {
|
||||
gl->PushAttrib (GL_VIEWPORT_BIT);
|
||||
gl->MatrixMode (GL_PROJECTION);
|
||||
gl->PushMatrix ();
|
||||
gl->LoadIdentity ();
|
||||
|
||||
switch (projection) {
|
||||
case GST_GL_DISPLAY_PROJECTION_ORTHO2D:
|
||||
gluOrtho2D (proj_param1, proj_param2, proj_param3, proj_param4);
|
||||
break;
|
||||
case GST_GL_DISPLAY_PROJECTION_PERSPECTIVE:
|
||||
gluPerspective (proj_param1, proj_param2, proj_param3, proj_param4);
|
||||
break;
|
||||
default:
|
||||
gst_gl_display_set_error (frame->display, "Unknow fbo projection %d",
|
||||
projection);
|
||||
}
|
||||
|
||||
gl->MatrixMode (GL_MODELVIEW);
|
||||
gl->PushMatrix ();
|
||||
gl->LoadIdentity ();
|
||||
}
|
||||
#endif
|
||||
#if GST_GL_HAVE_GLES2
|
||||
if (gst_gl_display_get_gl_api (frame->display) & GST_GL_API_GLES2)
|
||||
gl->GetIntegerv (GL_VIEWPORT, viewport_dim);
|
||||
#endif
|
||||
|
||||
gl->Viewport (0, 0, texture_fbo_width, texture_fbo_height);
|
||||
|
||||
#if GST_GL_HAVE_OPENGL
|
||||
if (gst_gl_display_get_gl_api (frame->display) & GST_GL_API_OPENGL) {
|
||||
const GLenum rt[] = { GL_COLOR_ATTACHMENT0 };
|
||||
gl->DrawBuffers (1, rt);
|
||||
}
|
||||
#endif
|
||||
|
||||
gl->ClearColor (0.0, 0.0, 0.0, 0.0);
|
||||
gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
cb (input_tex_width, input_tex_height, input_tex, stuff);
|
||||
|
||||
#if GST_GL_HAVE_OPENGL
|
||||
if (gst_gl_display_get_gl_api (frame->display) & GST_GL_API_OPENGL) {
|
||||
const GLenum rt[] = { GL_NONE };
|
||||
gl->DrawBuffers (1, rt);
|
||||
gl->MatrixMode (GL_PROJECTION);
|
||||
gl->PopMatrix ();
|
||||
gl->MatrixMode (GL_MODELVIEW);
|
||||
gl->PopMatrix ();
|
||||
gl->PopAttrib ();
|
||||
}
|
||||
#endif
|
||||
#if GST_GL_HAVE_GLES2
|
||||
if (gst_gl_display_get_gl_api (frame->display) & GST_GL_API_GLES2) {
|
||||
gl->Viewport (viewport_dim[0], viewport_dim[1], viewport_dim[2],
|
||||
viewport_dim[3]);
|
||||
}
|
||||
#endif
|
||||
|
||||
gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_framebuffer_use_v2 (GstGLFramebuffer * frame, gint texture_fbo_width,
|
||||
gint texture_fbo_height, GLuint fbo, GLuint depth_buffer,
|
||||
GLuint texture_fbo, GLCB_V2 cb, gpointer stuff)
|
||||
{
|
||||
const GstGLFuncs *gl;
|
||||
GLint viewport_dim[4];
|
||||
|
||||
g_return_val_if_fail (GST_IS_GL_FRAMEBUFFER (frame), FALSE);
|
||||
g_return_val_if_fail (texture_fbo_width > 0 && texture_fbo_height > 0, FALSE);
|
||||
g_return_val_if_fail (fbo != 0, FALSE);
|
||||
g_return_val_if_fail (texture_fbo != 0, FALSE);
|
||||
g_return_val_if_fail (cb != NULL, FALSE);
|
||||
|
||||
gl = frame->display->gl_vtable;
|
||||
|
||||
GST_TRACE ("Binding v2 FBO %u dimensions:%ux%u with texture:%u ",
|
||||
fbo, texture_fbo_width, texture_fbo_height, texture_fbo);
|
||||
|
||||
gl->BindFramebuffer (GL_FRAMEBUFFER, fbo);
|
||||
|
||||
/* setup a texture to render to */
|
||||
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_fbo);
|
||||
|
||||
/* attach the texture to the FBO to renderer to */
|
||||
gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_RECTANGLE_ARB, texture_fbo, 0);
|
||||
|
||||
gl->GetIntegerv (GL_VIEWPORT, viewport_dim);
|
||||
|
||||
gl->Viewport (0, 0, texture_fbo_width, texture_fbo_height);
|
||||
|
||||
gl->DrawBuffer (GL_COLOR_ATTACHMENT0);
|
||||
|
||||
gl->ClearColor (0.0, 0.0, 0.0, 0.0);
|
||||
gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/* the opengl scene */
|
||||
cb (stuff);
|
||||
|
||||
gl->DrawBuffer (GL_NONE);
|
||||
|
||||
gl->Viewport (viewport_dim[0], viewport_dim[1],
|
||||
viewport_dim[2], viewport_dim[3]);
|
||||
|
||||
gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_gl_framebuffer_delete (GstGLFramebuffer * frame, guint fbo, guint depth)
|
||||
{
|
||||
const GstGLFuncs *gl;
|
||||
|
||||
g_return_if_fail (GST_IS_GL_FRAMEBUFFER (frame));
|
||||
|
||||
gl = frame->display->gl_vtable;
|
||||
|
||||
GST_TRACE ("Deleting FBO %u", fbo);
|
||||
|
||||
if (fbo) {
|
||||
gl->DeleteFramebuffers (1, &fbo);
|
||||
}
|
||||
if (depth) {
|
||||
gl->DeleteRenderbuffers (1, &depth);
|
||||
}
|
||||
}
|
76
gst-libs/gst/gl/gstglframebuffer.h
Normal file
76
gst-libs/gst/gl/gstglframebuffer.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2013 Matthew Waters <ystreet00@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., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_GL_FRAMEBUFFER_H__
|
||||
#define __GST_GL_FRAMEBUFFER_H__
|
||||
|
||||
#include "gstgldisplay.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GType gst_gl_framebuffer_get_type (void);
|
||||
|
||||
#define GST_TYPE_GL_FRAMEBUFFER (gst_gl_framebuffer_get_type())
|
||||
#define GST_GL_FRAMEBUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FRAMEBUFFER,GstGLFramebuffer))
|
||||
#define GST_GL_FRAMEBUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_GL_FRAMEBUFFER,GstGLFramebufferClass))
|
||||
#define GST_IS_GL_FRAMEBUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FRAMEBUFFER))
|
||||
#define GST_IS_GL_FRAMEBUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_GL_FRAMEBUFFER))
|
||||
#define GST_GL_FRAMEBUFFER_CAST(obj) ((GstGLFramebuffer*)(obj))
|
||||
|
||||
typedef struct _GstGLFramebuffer GstGLFramebuffer;
|
||||
typedef struct _GstGLFramebufferClass GstGLFramebufferClass;
|
||||
typedef struct _GstGLFramebufferPrivate GstGLFramebufferPrivate;
|
||||
|
||||
struct _GstGLFramebuffer
|
||||
{
|
||||
GObject object;
|
||||
|
||||
/* <private> */
|
||||
GstGLDisplay *display;
|
||||
|
||||
GstGLFramebufferPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GstGLFramebufferClass
|
||||
{
|
||||
GObjectClass object_class;
|
||||
};
|
||||
|
||||
GstGLFramebuffer *gst_gl_framebuffer_new (GstGLDisplay *display);
|
||||
|
||||
gboolean gst_gl_framebuffer_generate (GstGLFramebuffer *frame, gint width, gint height,
|
||||
guint * fbo, guint * depthbuffer);
|
||||
|
||||
gboolean gst_gl_framebuffer_use (GstGLFramebuffer * frame, gint texture_fbo_width,
|
||||
gint texture_fbo_height, GLuint fbo, GLuint depth_buffer,
|
||||
GLuint texture_fbo, GLCB cb, gint input_tex_width,
|
||||
gint input_tex_height, GLuint input_tex, gdouble proj_param1,
|
||||
gdouble proj_param2, gdouble proj_param3, gdouble proj_param4,
|
||||
GstGLDisplayProjection projection, gpointer stuff);
|
||||
|
||||
gboolean gst_gl_framebuffer_use_v2 (GstGLFramebuffer * frame, gint texture_fbo_width,
|
||||
gint texture_fbo_height, GLuint fbo, GLuint depth_buffer,
|
||||
GLuint texture_fbo, GLCB_V2 cb, gpointer stuff);
|
||||
|
||||
void gst_gl_framebuffer_delete (GstGLFramebuffer *frame, guint fbo, guint depth);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "gstglutils.h"
|
||||
#include "gstglfeature.h"
|
||||
#include "gstglframebuffer.h"
|
||||
|
||||
#ifndef GL_FRAMEBUFFER_UNDEFINED
|
||||
#define GL_FRAMEBUFFER_UNDEFINED 0x8219
|
||||
|
@ -54,44 +55,12 @@ static GstVideoFormat gen_texture_video_format;
|
|||
|
||||
static GLuint *del_texture;
|
||||
|
||||
/* filter gen fbo */
|
||||
static GLuint gen_fbo_width;
|
||||
static GLuint gen_fbo_height;
|
||||
static GLuint generated_fbo;
|
||||
static GLuint generated_depth_buffer;
|
||||
|
||||
/* filter use fbo */
|
||||
static GLuint use_fbo;
|
||||
static GLuint use_depth_buffer;
|
||||
static GLuint use_fbo_texture;
|
||||
static GLuint use_fbo_width;
|
||||
static GLuint use_fbo_height;
|
||||
static GLCB use_fbo_scene_cb;
|
||||
static GLCB_V2 use_fbo_scene_cb_v2;
|
||||
static gdouble use_fbo_proj_param1;
|
||||
static gdouble use_fbo_proj_param2;
|
||||
static gdouble use_fbo_proj_param3;
|
||||
static gdouble use_fbo_proj_param4;
|
||||
static GstGLDisplayProjection use_fbo_projection;
|
||||
static gpointer *use_fbo_stuff;
|
||||
static GLuint input_texture_width;
|
||||
static GLuint input_texture_height;
|
||||
static GLuint input_texture;
|
||||
|
||||
/* filter del fbo */
|
||||
static GLuint del_fbo;
|
||||
static GLuint del_depth_buffer;
|
||||
|
||||
/* action gen and del shader */
|
||||
static const gchar *gen_shader_fragment_source;
|
||||
static const gchar *gen_shader_vertex_source;
|
||||
static GstGLShader *gen_shader;
|
||||
static GstGLShader *del_shader;
|
||||
|
||||
static void _gen_fbo (GstGLDisplay * display);
|
||||
static void _use_fbo (GstGLDisplay * display);
|
||||
static void _use_fbo_v2 (GstGLDisplay * display);
|
||||
static void _del_fbo (GstGLDisplay * display);
|
||||
static void _gen_shader (GstGLDisplay * display);
|
||||
static void _del_shader (GstGLDisplay * display);
|
||||
|
||||
|
@ -298,32 +267,65 @@ gst_gl_display_del_texture (GstGLDisplay * display, GLuint * pTexture)
|
|||
gst_gl_display_unlock (display);
|
||||
}
|
||||
|
||||
typedef struct _GenFBO
|
||||
{
|
||||
GstGLFramebuffer *frame;
|
||||
gint width, height;
|
||||
GLuint *fbo, *depth;
|
||||
} GenFBO;
|
||||
|
||||
static void
|
||||
_gen_fbo (GstGLDisplay * display, GenFBO * data)
|
||||
{
|
||||
gst_gl_framebuffer_generate (data->frame, data->width, data->height,
|
||||
data->fbo, data->depth);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_display_gen_fbo (GstGLDisplay * display, gint width, gint height,
|
||||
GLuint * fbo, GLuint * depthbuffer)
|
||||
{
|
||||
gboolean alive = FALSE;
|
||||
GstGLWindow *window;
|
||||
GstGLFramebuffer *frame = gst_gl_framebuffer_new (display);
|
||||
|
||||
gst_gl_display_lock (display);
|
||||
GenFBO data = { frame, width, height, fbo, depthbuffer };
|
||||
|
||||
window = gst_gl_display_get_window_unlocked (display);
|
||||
gst_gl_display_thread_add (display, (GstGLDisplayThreadFunc) _gen_fbo, &data);
|
||||
|
||||
if (gst_gl_window_is_running (window)) {
|
||||
gen_fbo_width = width;
|
||||
gen_fbo_height = height;
|
||||
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (_gen_fbo), display);
|
||||
*fbo = generated_fbo;
|
||||
*depthbuffer = generated_depth_buffer;
|
||||
}
|
||||
alive = gst_gl_window_is_running (window);
|
||||
gst_object_unref (frame);
|
||||
|
||||
gst_object_unref (window);
|
||||
gst_gl_display_unlock (display);
|
||||
|
||||
return alive;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct _UseFBO
|
||||
{
|
||||
GstGLFramebuffer *frame;
|
||||
gint texture_fbo_width;
|
||||
gint texture_fbo_height;
|
||||
GLuint fbo;
|
||||
GLuint depth_buffer;
|
||||
GLuint texture_fbo;
|
||||
GLCB cb;
|
||||
gint input_tex_width;
|
||||
gint input_tex_height;
|
||||
GLuint input_tex;
|
||||
gdouble proj_param1;
|
||||
gdouble proj_param2;
|
||||
gdouble proj_param3;
|
||||
gdouble proj_param4;
|
||||
GstGLDisplayProjection projection;
|
||||
gpointer stuff;
|
||||
} UseFBO;
|
||||
|
||||
static void
|
||||
_use_fbo (GstGLDisplay * display, UseFBO * data)
|
||||
{
|
||||
gst_gl_framebuffer_use (data->frame, data->texture_fbo_width,
|
||||
data->texture_fbo_height, data->fbo, data->depth_buffer,
|
||||
data->texture_fbo, data->cb, data->input_tex_width,
|
||||
data->input_tex_height, data->input_tex, data->proj_param1,
|
||||
data->proj_param2, data->proj_param3, data->proj_param4, data->projection,
|
||||
data->stuff);
|
||||
}
|
||||
|
||||
/* Called by glfilter */
|
||||
/* this function really has to be simplified... do we really need to
|
||||
|
@ -339,87 +341,88 @@ gst_gl_display_use_fbo (GstGLDisplay * display, gint texture_fbo_width,
|
|||
GLuint texture_fbo, GLCB cb, gint input_tex_width,
|
||||
gint input_tex_height, GLuint input_tex, gdouble proj_param1,
|
||||
gdouble proj_param2, gdouble proj_param3, gdouble proj_param4,
|
||||
GstGLDisplayProjection projection, gpointer * stuff)
|
||||
GstGLDisplayProjection projection, gpointer stuff)
|
||||
{
|
||||
gboolean alive;
|
||||
GstGLWindow *window;
|
||||
GstGLFramebuffer *frame = gst_gl_framebuffer_new (display);
|
||||
|
||||
gst_gl_display_lock (display);
|
||||
UseFBO data =
|
||||
{ frame, texture_fbo_width, texture_fbo_height, fbo, depth_buffer,
|
||||
texture_fbo, cb, input_tex_width, input_tex_height, input_tex,
|
||||
proj_param1, proj_param2, proj_param3, proj_param4, projection, stuff
|
||||
};
|
||||
|
||||
window = gst_gl_display_get_window_unlocked (display);
|
||||
if (gst_gl_window_is_running (window)) {
|
||||
use_fbo = fbo;
|
||||
use_depth_buffer = depth_buffer;
|
||||
use_fbo_texture = texture_fbo;
|
||||
use_fbo_width = texture_fbo_width;
|
||||
use_fbo_height = texture_fbo_height;
|
||||
use_fbo_scene_cb = cb;
|
||||
use_fbo_proj_param1 = proj_param1;
|
||||
use_fbo_proj_param2 = proj_param2;
|
||||
use_fbo_proj_param3 = proj_param3;
|
||||
use_fbo_proj_param4 = proj_param4;
|
||||
use_fbo_projection = projection;
|
||||
use_fbo_stuff = stuff;
|
||||
input_texture_width = input_tex_width;
|
||||
input_texture_height = input_tex_height;
|
||||
input_texture = input_tex;
|
||||
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (_use_fbo), display);
|
||||
}
|
||||
alive = gst_gl_window_is_running (window);
|
||||
gst_gl_display_thread_add (display, (GstGLDisplayThreadFunc) _use_fbo, &data);
|
||||
|
||||
gst_object_unref (window);
|
||||
gst_gl_display_unlock (display);
|
||||
gst_object_unref (frame);
|
||||
|
||||
return alive;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct _UseFBO2
|
||||
{
|
||||
GstGLFramebuffer *frame;
|
||||
gint texture_fbo_width;
|
||||
gint texture_fbo_height;
|
||||
GLuint fbo;
|
||||
GLuint depth_buffer;
|
||||
GLuint texture_fbo;
|
||||
GLCB_V2 cb;
|
||||
gpointer stuff;
|
||||
} UseFBO2;
|
||||
|
||||
static void
|
||||
_use_fbo_v2 (GstGLDisplay * display, UseFBO2 * data)
|
||||
{
|
||||
gst_gl_framebuffer_use_v2 (data->frame, data->texture_fbo_width,
|
||||
data->texture_fbo_height, data->fbo, data->depth_buffer,
|
||||
data->texture_fbo, data->cb, data->stuff);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_display_use_fbo_v2 (GstGLDisplay * display, gint texture_fbo_width,
|
||||
gint texture_fbo_height, GLuint fbo, GLuint depth_buffer,
|
||||
GLuint texture_fbo, GLCB_V2 cb, gpointer * stuff)
|
||||
GLuint texture_fbo, GLCB_V2 cb, gpointer stuff)
|
||||
{
|
||||
gboolean alive;
|
||||
GstGLWindow *window;
|
||||
GstGLFramebuffer *frame = gst_gl_framebuffer_new (display);
|
||||
|
||||
gst_gl_display_lock (display);
|
||||
UseFBO2 data =
|
||||
{ frame, texture_fbo_width, texture_fbo_height, fbo, depth_buffer,
|
||||
texture_fbo, cb, stuff
|
||||
};
|
||||
|
||||
window = gst_gl_display_get_window_unlocked (display);
|
||||
if (gst_gl_window_is_running (window)) {
|
||||
use_fbo = fbo;
|
||||
use_depth_buffer = depth_buffer;
|
||||
use_fbo_texture = texture_fbo;
|
||||
use_fbo_width = texture_fbo_width;
|
||||
use_fbo_height = texture_fbo_height;
|
||||
use_fbo_scene_cb_v2 = cb;
|
||||
use_fbo_stuff = stuff;
|
||||
gst_gl_window_send_message (window,
|
||||
GST_GL_WINDOW_CB (_use_fbo_v2), display);
|
||||
}
|
||||
alive = gst_gl_window_is_running (window);
|
||||
gst_gl_display_thread_add (display, (GstGLDisplayThreadFunc) _use_fbo_v2,
|
||||
&data);
|
||||
|
||||
gst_object_unref (window);
|
||||
gst_gl_display_unlock (display);
|
||||
gst_object_unref (frame);
|
||||
|
||||
return alive;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct _DelFBO
|
||||
{
|
||||
GstGLFramebuffer *frame;
|
||||
GLuint fbo;
|
||||
GLuint depth;
|
||||
} DelFBO;
|
||||
|
||||
/* Called in the gl thread */
|
||||
static void
|
||||
_del_fbo (GstGLDisplay * display, DelFBO * data)
|
||||
{
|
||||
gst_gl_framebuffer_delete (data->frame, data->fbo, data->depth);
|
||||
}
|
||||
|
||||
/* Called by gltestsrc and glfilter */
|
||||
void
|
||||
gst_gl_display_del_fbo (GstGLDisplay * display, GLuint fbo, GLuint depth_buffer)
|
||||
{
|
||||
GstGLWindow *window;
|
||||
GstGLFramebuffer *frame = gst_gl_framebuffer_new (display);
|
||||
|
||||
gst_gl_display_lock (display);
|
||||
DelFBO data = { frame, fbo, depth_buffer };
|
||||
|
||||
window = gst_gl_display_get_window_unlocked (display);
|
||||
if (gst_gl_window_is_running (window)) {
|
||||
del_fbo = fbo;
|
||||
del_depth_buffer = depth_buffer;
|
||||
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (_del_fbo), display);
|
||||
}
|
||||
gst_gl_display_thread_add (display, (GstGLDisplayThreadFunc) _del_fbo, &data);
|
||||
|
||||
gst_object_unref (window);
|
||||
gst_gl_display_unlock (display);
|
||||
gst_object_unref (frame);
|
||||
}
|
||||
|
||||
|
||||
|
@ -494,227 +497,6 @@ gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader)
|
|||
gst_gl_display_unlock (display);
|
||||
}
|
||||
|
||||
void
|
||||
_gen_fbo (GstGLDisplay * display)
|
||||
{
|
||||
/* a texture must be attached to the FBO */
|
||||
const GstGLFuncs *gl = display->gl_vtable;
|
||||
GLuint fake_texture = 0;
|
||||
|
||||
GST_TRACE ("creating FBO dimensions:%ux%u", gen_fbo_width, gen_fbo_height);
|
||||
|
||||
/* -- generate frame buffer object */
|
||||
|
||||
if (!gl->GenFramebuffers) {
|
||||
gst_gl_display_set_error (display,
|
||||
"Context, EXT_framebuffer_object not supported");
|
||||
return;
|
||||
}
|
||||
/* setup FBO */
|
||||
gl->GenFramebuffers (1, &generated_fbo);
|
||||
gl->BindFramebuffer (GL_FRAMEBUFFER, generated_fbo);
|
||||
|
||||
/* setup the render buffer for depth */
|
||||
gl->GenRenderbuffers (1, &generated_depth_buffer);
|
||||
gl->BindRenderbuffer (GL_RENDERBUFFER, generated_depth_buffer);
|
||||
|
||||
if (USING_OPENGL (display)) {
|
||||
gl->RenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT,
|
||||
gen_fbo_width, gen_fbo_height);
|
||||
gl->RenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
|
||||
gen_fbo_width, gen_fbo_height);
|
||||
}
|
||||
if (USING_GLES2 (display)) {
|
||||
gl->RenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
|
||||
gen_fbo_width, gen_fbo_height);
|
||||
}
|
||||
|
||||
/* setup a texture to render to */
|
||||
gl->GenTextures (1, &fake_texture);
|
||||
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, fake_texture);
|
||||
gl->TexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8,
|
||||
gen_fbo_width, gen_fbo_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
gl->TexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
|
||||
GL_LINEAR);
|
||||
gl->TexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR);
|
||||
gl->TexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
gl->TexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
|
||||
/* attach the texture to the FBO to renderer to */
|
||||
gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_RECTANGLE_ARB, fake_texture, 0);
|
||||
|
||||
/* attach the depth render buffer to the FBO */
|
||||
gl->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
GL_RENDERBUFFER, generated_depth_buffer);
|
||||
|
||||
if (USING_OPENGL (display)) {
|
||||
gl->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, generated_depth_buffer);
|
||||
}
|
||||
|
||||
if (gl->CheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
gst_gl_display_set_error (display, "GL framebuffer status incomplete");
|
||||
|
||||
/* unbind the FBO */
|
||||
gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||
|
||||
gl->DeleteTextures (1, &fake_texture);
|
||||
}
|
||||
|
||||
static void
|
||||
_use_fbo (GstGLDisplay * display)
|
||||
{
|
||||
const GstGLFuncs *gl = display->gl_vtable;
|
||||
#if GST_GL_HAVE_GLES2
|
||||
GLint viewport_dim[4];
|
||||
#endif
|
||||
|
||||
GST_TRACE ("Binding v1 FBO %u dimensions:%ux%u with texture:%u "
|
||||
"dimensions:%ux%u", use_fbo, use_fbo_width,
|
||||
use_fbo_height, use_fbo_texture,
|
||||
input_texture_width, input_texture_height);
|
||||
|
||||
gl->BindFramebuffer (GL_FRAMEBUFFER, use_fbo);
|
||||
|
||||
/*setup a texture to render to */
|
||||
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, use_fbo_texture);
|
||||
|
||||
/* attach the texture to the FBO to renderer to */
|
||||
gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_RECTANGLE_ARB, use_fbo_texture, 0);
|
||||
|
||||
gst_gl_display_clear_shader (display);
|
||||
|
||||
|
||||
#if GST_GL_HAVE_OPENGL
|
||||
if (USING_OPENGL (display)) {
|
||||
gl->PushAttrib (GL_VIEWPORT_BIT);
|
||||
gl->MatrixMode (GL_PROJECTION);
|
||||
gl->PushMatrix ();
|
||||
gl->LoadIdentity ();
|
||||
|
||||
switch (use_fbo_projection) {
|
||||
case GST_GL_DISPLAY_PROJECTION_ORTHO2D:
|
||||
gluOrtho2D (use_fbo_proj_param1,
|
||||
use_fbo_proj_param2, use_fbo_proj_param3, use_fbo_proj_param4);
|
||||
break;
|
||||
case GST_GL_DISPLAY_PROJECTION_PERSPECTIVE:
|
||||
gluPerspective (use_fbo_proj_param1,
|
||||
use_fbo_proj_param2, use_fbo_proj_param3, use_fbo_proj_param4);
|
||||
break;
|
||||
default:
|
||||
gst_gl_display_set_error (display, "Unknow fbo projection %d",
|
||||
use_fbo_projection);
|
||||
}
|
||||
|
||||
gl->MatrixMode (GL_MODELVIEW);
|
||||
gl->PushMatrix ();
|
||||
gl->LoadIdentity ();
|
||||
}
|
||||
#endif
|
||||
#if GST_GL_HAVE_GLES2
|
||||
if (USING_GLES2 (display))
|
||||
gl->GetIntegerv (GL_VIEWPORT, viewport_dim);
|
||||
#endif
|
||||
|
||||
gl->Viewport (0, 0, use_fbo_width, use_fbo_height);
|
||||
|
||||
#if GST_GL_HAVE_OPENGL
|
||||
if (USING_OPENGL (display)) {
|
||||
const GLenum rt[] = { GL_COLOR_ATTACHMENT0 };
|
||||
gl->DrawBuffers (1, rt);
|
||||
}
|
||||
#endif
|
||||
|
||||
gl->ClearColor (0.0, 0.0, 0.0, 0.0);
|
||||
gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
use_fbo_scene_cb (input_texture_width,
|
||||
input_texture_height, input_texture, use_fbo_stuff);
|
||||
|
||||
#if GST_GL_HAVE_OPENGL
|
||||
if (USING_OPENGL (display)) {
|
||||
const GLenum rt[] = { GL_NONE };
|
||||
gl->DrawBuffers (1, rt);
|
||||
gl->MatrixMode (GL_PROJECTION);
|
||||
gl->PopMatrix ();
|
||||
gl->MatrixMode (GL_MODELVIEW);
|
||||
gl->PopMatrix ();
|
||||
gl->PopAttrib ();
|
||||
}
|
||||
#endif
|
||||
#if GST_GL_HAVE_GLES2
|
||||
if (USING_GLES2 (display)) {
|
||||
gl->Viewport (viewport_dim[0], viewport_dim[1], viewport_dim[2],
|
||||
viewport_dim[3]);
|
||||
}
|
||||
#endif
|
||||
|
||||
gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
/* Called in a gl thread
|
||||
* Need full shader support */
|
||||
static void
|
||||
_use_fbo_v2 (GstGLDisplay * display)
|
||||
{
|
||||
const GstGLFuncs *gl = display->gl_vtable;
|
||||
GLint viewport_dim[4];
|
||||
|
||||
GST_TRACE ("Binding v2 FBO %u dimensions:%ux%u with texture:%u ",
|
||||
use_fbo, use_fbo_width, use_fbo_height, use_fbo_texture);
|
||||
|
||||
gl->BindFramebuffer (GL_FRAMEBUFFER, use_fbo);
|
||||
|
||||
/* setup a texture to render to */
|
||||
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, use_fbo_texture);
|
||||
|
||||
/* attach the texture to the FBO to renderer to */
|
||||
gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_RECTANGLE_ARB, use_fbo_texture, 0);
|
||||
|
||||
gl->GetIntegerv (GL_VIEWPORT, viewport_dim);
|
||||
|
||||
gl->Viewport (0, 0, use_fbo_width, use_fbo_height);
|
||||
|
||||
gl->DrawBuffer (GL_COLOR_ATTACHMENT0);
|
||||
|
||||
gl->ClearColor (0.0, 0.0, 0.0, 0.0);
|
||||
gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
/* the opengl scene */
|
||||
use_fbo_scene_cb_v2 (use_fbo_stuff);
|
||||
|
||||
gl->DrawBuffer (GL_NONE);
|
||||
|
||||
gl->Viewport (viewport_dim[0], viewport_dim[1],
|
||||
viewport_dim[2], viewport_dim[3]);
|
||||
|
||||
gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
/* Called in the gl thread */
|
||||
static void
|
||||
_del_fbo (GstGLDisplay * display)
|
||||
{
|
||||
const GstGLFuncs *gl = display->gl_vtable;
|
||||
|
||||
GST_TRACE ("Deleting FBO %u", del_fbo);
|
||||
|
||||
if (del_fbo) {
|
||||
gl->DeleteFramebuffers (1, &del_fbo);
|
||||
del_fbo = 0;
|
||||
}
|
||||
if (del_depth_buffer) {
|
||||
gl->DeleteRenderbuffers (1, &del_depth_buffer);
|
||||
del_depth_buffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Called in the gl thread */
|
||||
static void
|
||||
_gen_shader (GstGLDisplay * display)
|
||||
|
|
|
@ -91,10 +91,10 @@ gboolean gst_gl_display_use_fbo (GstGLDisplay * display, gint texture_fbo_width,
|
|||
GLuint texture_fbo, GLCB cb, gint input_texture_width,
|
||||
gint input_texture_height, GLuint input_texture, gdouble proj_param1,
|
||||
gdouble proj_param2, gdouble proj_param3, gdouble proj_param4,
|
||||
GstGLDisplayProjection projection, gpointer * stuff);
|
||||
GstGLDisplayProjection projection, gpointer stuff);
|
||||
gboolean gst_gl_display_use_fbo_v2 (GstGLDisplay * display, gint texture_fbo_width,
|
||||
gint texture_fbo_height, GLuint fbo, GLuint depth_buffer,
|
||||
GLuint texture_fbo, GLCB_V2 cb, gpointer * stuff);
|
||||
GLuint texture_fbo, GLCB_V2 cb, gpointer stuff);
|
||||
void gst_gl_display_del_fbo (GstGLDisplay * display, GLuint fbo,
|
||||
GLuint depth_buffer);
|
||||
|
||||
|
|
Loading…
Reference in a new issue