From 3772c83f949ebed31785077e3ac495d00c4d4e6c Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Thu, 13 Nov 2014 12:12:46 +1100 Subject: [PATCH] gltransformation: support gl3 --- ext/gl/gstgltransformation.c | 144 +++++++++++++++++++++++++++++++------------ ext/gl/gstgltransformation.h | 6 ++ 2 files changed, 111 insertions(+), 39 deletions(-) diff --git a/ext/gl/gstgltransformation.c b/ext/gl/gstgltransformation.c index 6a58f6e..4420724 100644 --- a/ext/gl/gstgltransformation.c +++ b/ext/gl/gstgltransformation.c @@ -81,6 +81,7 @@ static void gst_gl_transformation_get_property (GObject * object, guint prop_id, static gboolean gst_gl_transformation_set_caps (GstGLFilter * filter, GstCaps * incaps, GstCaps * outcaps); +static void gst_gl_transformation_reset_gl (GstGLFilter * filter); static void gst_gl_transformation_reset (GstGLFilter * filter); static gboolean gst_gl_transformation_init_shader (GstGLFilter * filter); static void gst_gl_transformation_callback (gpointer stuff); @@ -127,6 +128,8 @@ gst_gl_transformation_class_init (GstGLTransformationClass * klass) gobject_class->get_property = gst_gl_transformation_get_property; GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_transformation_init_shader; + GST_GL_FILTER_CLASS (klass)->display_reset_cb = + gst_gl_transformation_reset_gl; GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_transformation_reset; GST_GL_FILTER_CLASS (klass)->set_caps = gst_gl_transformation_set_caps; GST_GL_FILTER_CLASS (klass)->filter_texture = @@ -374,12 +377,31 @@ gst_gl_transformation_set_caps (GstGLFilter * filter, GstCaps * incaps, (gdouble) GST_VIDEO_INFO_WIDTH (&filter->out_info) / (gdouble) GST_VIDEO_INFO_HEIGHT (&filter->out_info); + transformation->caps_change = TRUE; + gst_gl_transformation_build_mvp (transformation); return TRUE; } static void +gst_gl_transformation_reset_gl (GstGLFilter * filter) +{ + GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter); + const GstGLFuncs *gl = filter->context->gl_vtable; + + if (transformation->vao) { + gl->DeleteVertexArrays (1, &transformation->vao); + transformation->vao = 0; + } + + if (transformation->vertex_buffer) { + gl->DeleteBuffers (1, &transformation->vertex_buffer); + transformation->vertex_buffer = 0; + } +} + +static void gst_gl_transformation_reset (GstGLFilter * filter) { GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter); @@ -421,38 +443,70 @@ gst_gl_transformation_filter_texture (GstGLFilter * filter, guint in_tex, return TRUE; } + static void -gst_gl_transformation_callback (gpointer stuff) +_upload_vertices (GstGLTransformation * transformation) { - GstGLFilter *filter = GST_GL_FILTER (stuff); - GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter); - GstGLFuncs *gl = filter->context->gl_vtable; + const GstGLFuncs *gl = GST_GL_FILTER (transformation)->context->gl_vtable; /* *INDENT-OFF* */ - - const GLfloat positions[] = { - -transformation->aspect, 1.0, 0.0, 1.0, - transformation->aspect, 1.0, 0.0, 1.0, - transformation->aspect, -1.0, 0.0, 1.0, - -transformation->aspect, -1.0, 0.0, 1.0, + GLfloat vertices[] = { + -transformation->aspect, 1.0, 0.0, 1.0, 0.0, 1.0, + transformation->aspect, 1.0, 0.0, 1.0, 1.0, 1.0, + transformation->aspect, -1.0, 0.0, 1.0, 1.0, 0.0, + -transformation->aspect, -1.0, 0.0, 1.0, 0.0, 0.0 }; + /* *INDENT-ON* */ - const GLfloat texture_coordinates[] = { - 0.0, 1.0, - 1.0, 1.0, - 1.0, 0.0, - 0.0, 0.0, - }; + gl->BindBuffer (GL_ARRAY_BUFFER, transformation->vertex_buffer); + + gl->BufferData (GL_ARRAY_BUFFER, 4 * 6 * sizeof (GLfloat), vertices, + GL_STATIC_DRAW); + + gl->BindBuffer (GL_ARRAY_BUFFER, 0); +} + +static void +_bind_buffer (GstGLTransformation * transformation) +{ + const GstGLFuncs *gl = GST_GL_FILTER (transformation)->context->gl_vtable; + + gl->BindBuffer (GL_ARRAY_BUFFER, transformation->vertex_buffer); + + /* Load the vertex position */ + gl->VertexAttribPointer (transformation->attr_position, 4, GL_FLOAT, + GL_FALSE, 6 * sizeof (GLfloat), (void *) 0); + + /* Load the texture coordinate */ + gl->VertexAttribPointer (transformation->attr_texture, 2, GL_FLOAT, GL_FALSE, + 6 * sizeof (GLfloat), (void *) (4 * sizeof (GLfloat))); + + gl->EnableVertexAttribArray (transformation->attr_position); + gl->EnableVertexAttribArray (transformation->attr_texture); +} + +static void +_unbind_buffer (GstGLTransformation * transformation) +{ + const GstGLFuncs *gl = GST_GL_FILTER (transformation)->context->gl_vtable; -/* *INDENT-ON* */ + gl->BindBuffer (GL_ARRAY_BUFFER, 0); + + gl->DisableVertexAttribArray (transformation->attr_position); + gl->DisableVertexAttribArray (transformation->attr_texture); +} + +static void +gst_gl_transformation_callback (gpointer stuff) +{ + GstGLFilter *filter = GST_GL_FILTER (stuff); + GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter); + GstGLFuncs *gl = filter->context->gl_vtable; GLushort indices[] = { 0, 1, 2, 3, 0 }; GLfloat temp_matrix[16]; - GLint attr_position_loc = 0; - GLint attr_texture_loc = 0; - gst_gl_context_clear_shader (filter->context); gl->BindTexture (GL_TEXTURE_2D, 0); @@ -461,23 +515,6 @@ gst_gl_transformation_callback (gpointer stuff) gst_gl_shader_use (transformation->shader); - attr_position_loc = - gst_gl_shader_get_attribute_location (transformation->shader, "position"); - - attr_texture_loc = - gst_gl_shader_get_attribute_location (transformation->shader, "uv"); - - /* Load the vertex position */ - gl->VertexAttribPointer (attr_position_loc, 4, GL_FLOAT, - GL_FALSE, 0, positions); - - /* Load the texture coordinate */ - gl->VertexAttribPointer (attr_texture_loc, 2, GL_FLOAT, - GL_FALSE, 0, texture_coordinates); - - gl->EnableVertexAttribArray (attr_position_loc); - gl->EnableVertexAttribArray (attr_texture_loc); - gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, transformation->in_tex); gst_gl_shader_set_uniform_1i (transformation->shader, "texture", 0); @@ -486,10 +523,39 @@ gst_gl_transformation_callback (gpointer stuff) gst_gl_shader_set_uniform_matrix_4fv (transformation->shader, "mvp", 1, GL_FALSE, temp_matrix); + if (!transformation->vertex_buffer) { + transformation->attr_position = + gst_gl_shader_get_attribute_location (transformation->shader, + "position"); + + transformation->attr_texture = + gst_gl_shader_get_attribute_location (transformation->shader, "uv"); + + if (gl->GenVertexArrays) { + gl->GenVertexArrays (1, &transformation->vao); + gl->BindVertexArray (transformation->vao); + } + + gl->GenBuffers (1, &transformation->vertex_buffer); + transformation->caps_change = TRUE; + } + + if (gl->GenVertexArrays) + gl->BindVertexArray (transformation->vao); + + if (transformation->caps_change) + _upload_vertices (transformation); + + if (!gl->GenVertexArrays || transformation->caps_change) + _bind_buffer (transformation); + gl->DrawElements (GL_TRIANGLE_STRIP, 5, GL_UNSIGNED_SHORT, indices); - gl->DisableVertexAttribArray (attr_position_loc); - gl->DisableVertexAttribArray (attr_texture_loc); + if (gl->GenVertexArrays) + gl->BindVertexArray (0); + else + _unbind_buffer (transformation); gst_gl_context_clear_shader (filter->context); + transformation->caps_change = FALSE; } diff --git a/ext/gl/gstgltransformation.h b/ext/gl/gstgltransformation.h index 891817b..e8a5ce6 100644 --- a/ext/gl/gstgltransformation.h +++ b/ext/gl/gstgltransformation.h @@ -41,6 +41,10 @@ struct _GstGLTransformation GstGLFilter filter; GstGLShader *shader; + GLuint vao; + GLuint vertex_buffer; + GLint attr_position; + GLint attr_texture; guint in_tex; @@ -63,6 +67,8 @@ struct _GstGLTransformation gboolean ortho; graphene_matrix_t mvp_matrix; + + gboolean caps_change; }; struct _GstGLTransformationClass -- 2.7.4