mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
glfilter: add a gl3 code path using vao's and vbo's
This commit is contained in:
parent
414a319f03
commit
8e98591153
2 changed files with 124 additions and 31 deletions
|
@ -347,10 +347,21 @@ gst_gl_filter_start_gl (GstGLContext * context, gpointer data)
|
||||||
static void
|
static void
|
||||||
gst_gl_filter_stop_gl (GstGLContext * context, gpointer data)
|
gst_gl_filter_stop_gl (GstGLContext * context, gpointer data)
|
||||||
{
|
{
|
||||||
|
const GstGLFuncs *gl = context->gl_vtable;
|
||||||
GstGLFilter *filter = GST_GL_FILTER (data);
|
GstGLFilter *filter = GST_GL_FILTER (data);
|
||||||
GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
||||||
|
|
||||||
filter_class->display_reset_cb (filter);
|
filter_class->display_reset_cb (filter);
|
||||||
|
|
||||||
|
if (filter->vao) {
|
||||||
|
gl->DeleteVertexArrays (1, &filter->vao);
|
||||||
|
filter->vao = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter->vertex_buffer) {
|
||||||
|
gl->DeleteBuffers (1, &filter->vertex_buffer);
|
||||||
|
filter->vertex_buffer = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
|
@ -1307,7 +1318,24 @@ gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf,
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct glcb2
|
||||||
|
{
|
||||||
|
GLCB func;
|
||||||
|
gpointer data;
|
||||||
|
guint texture;
|
||||||
|
guint width;
|
||||||
|
guint height;
|
||||||
|
};
|
||||||
|
|
||||||
/* convenience functions to simplify filter development */
|
/* convenience functions to simplify filter development */
|
||||||
|
static void
|
||||||
|
_glcb2 (gpointer data)
|
||||||
|
{
|
||||||
|
struct glcb2 *cb = data;
|
||||||
|
|
||||||
|
cb->func (cb->width, cb->height, cb->texture, cb->data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_gl_filter_render_to_target:
|
* gst_gl_filter_render_to_target:
|
||||||
* @filter: a #GstGLFilter
|
* @filter: a #GstGLFilter
|
||||||
|
@ -1326,6 +1354,7 @@ gst_gl_filter_render_to_target (GstGLFilter * filter, gboolean resize,
|
||||||
GLuint input, GLuint target, GLCB func, gpointer data)
|
GLuint input, GLuint target, GLCB func, gpointer data)
|
||||||
{
|
{
|
||||||
guint in_width, in_height, out_width, out_height;
|
guint in_width, in_height, out_width, out_height;
|
||||||
|
struct glcb2 cb;
|
||||||
|
|
||||||
out_width = GST_VIDEO_INFO_WIDTH (&filter->out_info);
|
out_width = GST_VIDEO_INFO_WIDTH (&filter->out_info);
|
||||||
out_height = GST_VIDEO_INFO_HEIGHT (&filter->out_info);
|
out_height = GST_VIDEO_INFO_HEIGHT (&filter->out_info);
|
||||||
|
@ -1340,11 +1369,14 @@ gst_gl_filter_render_to_target (GstGLFilter * filter, gboolean resize,
|
||||||
GST_LOG ("rendering to target. in %u, %ux%u out %u, %ux%u", input, in_width,
|
GST_LOG ("rendering to target. in %u, %ux%u out %u, %ux%u", input, in_width,
|
||||||
in_height, target, out_width, out_height);
|
in_height, target, out_width, out_height);
|
||||||
|
|
||||||
gst_gl_context_use_fbo (filter->context,
|
cb.func = func;
|
||||||
out_width, out_height,
|
cb.data = data;
|
||||||
filter->fbo, filter->depthbuffer, target,
|
cb.texture = input;
|
||||||
func, in_width, in_height, input, 0,
|
cb.width = in_width;
|
||||||
in_width, 0, in_height, GST_GL_DISPLAY_PROJECTION_ORTHO2D, data);
|
cb.height = in_height;
|
||||||
|
|
||||||
|
gst_gl_context_use_fbo_v2 (filter->context, out_width, out_height,
|
||||||
|
filter->fbo, filter->depthbuffer, target, _glcb2, &cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1372,6 +1404,23 @@ _draw_with_shader_cb (gint width, gint height, guint texture, gpointer stuff)
|
||||||
gst_gl_filter_draw_texture (filter, texture, width, height);
|
gst_gl_filter_draw_texture (filter, texture, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_get_attributes (GstGLFilter * filter)
|
||||||
|
{
|
||||||
|
if (!filter->default_shader)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!filter->draw_attr_position_loc)
|
||||||
|
filter->draw_attr_position_loc =
|
||||||
|
gst_gl_shader_get_attribute_location (filter->default_shader,
|
||||||
|
"a_position");
|
||||||
|
|
||||||
|
if (!filter->draw_attr_texture_loc)
|
||||||
|
filter->draw_attr_texture_loc =
|
||||||
|
gst_gl_shader_get_attribute_location (filter->default_shader,
|
||||||
|
"a_texcoord");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_gl_filter_render_to_target_with_shader:
|
* gst_gl_filter_render_to_target_with_shader:
|
||||||
* @filter: a #GstGLFilter
|
* @filter: a #GstGLFilter
|
||||||
|
@ -1393,10 +1442,53 @@ gst_gl_filter_render_to_target_with_shader (GstGLFilter * filter,
|
||||||
gboolean resize, GLuint input, GLuint target, GstGLShader * shader)
|
gboolean resize, GLuint input, GLuint target, GstGLShader * shader)
|
||||||
{
|
{
|
||||||
filter->default_shader = shader;
|
filter->default_shader = shader;
|
||||||
|
_get_attributes (filter);
|
||||||
|
|
||||||
gst_gl_filter_render_to_target (filter, resize, input, target,
|
gst_gl_filter_render_to_target (filter, resize, input, target,
|
||||||
_draw_with_shader_cb, filter);
|
_draw_with_shader_cb, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
static const GLfloat vertices[] = {
|
||||||
|
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
1.0f, -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
|
||||||
|
};
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
static void
|
||||||
|
_bind_buffer (GstGLFilter * filter)
|
||||||
|
{
|
||||||
|
const GstGLFuncs *gl = filter->context->gl_vtable;
|
||||||
|
|
||||||
|
gl->BindBuffer (GL_ARRAY_BUFFER, filter->vertex_buffer);
|
||||||
|
|
||||||
|
/* Load the vertex position */
|
||||||
|
gl->VertexAttribPointer (filter->draw_attr_position_loc, 3, GL_FLOAT,
|
||||||
|
GL_FALSE, 5 * sizeof (GLfloat), (void *) 0);
|
||||||
|
|
||||||
|
/* Load the texture coordinate */
|
||||||
|
gl->VertexAttribPointer (filter->draw_attr_texture_loc, 2, GL_FLOAT, GL_FALSE,
|
||||||
|
5 * sizeof (GLfloat), (void *) (3 * sizeof (GLfloat)));
|
||||||
|
|
||||||
|
_get_attributes (filter);
|
||||||
|
|
||||||
|
gl->EnableVertexAttribArray (filter->draw_attr_position_loc);
|
||||||
|
gl->EnableVertexAttribArray (filter->draw_attr_texture_loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_unbind_buffer (GstGLFilter * filter)
|
||||||
|
{
|
||||||
|
const GstGLFuncs *gl = filter->context->gl_vtable;
|
||||||
|
|
||||||
|
gl->BindBuffer (GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
gl->DisableVertexAttribArray (filter->draw_attr_position_loc);
|
||||||
|
gl->DisableVertexAttribArray (filter->draw_attr_texture_loc);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_gl_filter_draw_texture:
|
* gst_gl_filter_draw_texture:
|
||||||
* @filter: a #GstGLFilter
|
* @filter: a #GstGLFilter
|
||||||
|
@ -1447,35 +1539,36 @@ gst_gl_filter_draw_texture (GstGLFilter * filter, GLuint texture,
|
||||||
gl->DisableClientState (GL_TEXTURE_COORD_ARRAY);
|
gl->DisableClientState (GL_TEXTURE_COORD_ARRAY);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if GST_GL_HAVE_GLES2
|
if (gst_gl_context_get_gl_api (context) & (GST_GL_API_GLES2 |
|
||||||
if (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2) {
|
GST_GL_API_OPENGL3)) {
|
||||||
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 };
|
GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
|
||||||
|
|
||||||
/* glClear (GL_COLOR_BUFFER_BIT); */
|
if (!filter->vertex_buffer) {
|
||||||
|
if (gl->GenVertexArrays) {
|
||||||
|
gl->GenVertexArrays (1, &filter->vao);
|
||||||
|
gl->BindVertexArray (filter->vao);
|
||||||
|
}
|
||||||
|
|
||||||
/* Load the vertex position */
|
gl->GenBuffers (1, &filter->vertex_buffer);
|
||||||
gl->VertexAttribPointer (filter->draw_attr_position_loc, 3, GL_FLOAT,
|
gl->BindBuffer (GL_ARRAY_BUFFER, filter->vertex_buffer);
|
||||||
GL_FALSE, 5 * sizeof (GLfloat), vVertices);
|
gl->BufferData (GL_ARRAY_BUFFER, 4 * 5 * sizeof (GLfloat), vertices,
|
||||||
|
GL_STATIC_DRAW);
|
||||||
|
|
||||||
/* Load the texture coordinate */
|
if (gl->GenVertexArrays) {
|
||||||
gl->VertexAttribPointer (filter->draw_attr_texture_loc, 2, GL_FLOAT,
|
_bind_buffer (filter);
|
||||||
GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gl->EnableVertexAttribArray (filter->draw_attr_position_loc);
|
if (gl->GenVertexArrays)
|
||||||
gl->EnableVertexAttribArray (filter->draw_attr_texture_loc);
|
gl->BindVertexArray (filter->vao);
|
||||||
|
else
|
||||||
|
_bind_buffer (filter);
|
||||||
|
|
||||||
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
|
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
|
||||||
|
|
||||||
gl->DisableVertexAttribArray (filter->draw_attr_position_loc);
|
if (gl->GenVertexArrays)
|
||||||
gl->DisableVertexAttribArray (filter->draw_attr_texture_loc);
|
gl->BindVertexArray (0);
|
||||||
|
else
|
||||||
|
_unbind_buffer (filter);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,10 +90,10 @@ struct _GstGLFilter
|
||||||
|
|
||||||
GstCaps *in_gl_caps;
|
GstCaps *in_gl_caps;
|
||||||
|
|
||||||
#if GST_GL_HAVE_GLES2
|
GLuint vao;
|
||||||
GLint draw_attr_position_loc;
|
GLuint vertex_buffer;
|
||||||
GLint draw_attr_texture_loc;
|
GLint draw_attr_position_loc;
|
||||||
#endif
|
GLint draw_attr_texture_loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue