static void gst_gl_transformation_reset_gl (GstGLFilter * filter) { GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter); const GstGLFuncs *gl = GST_GL_BASE_FILTER (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; } if (transformation->vbo_indices) { gl->DeleteBuffers (1, &transformation->vbo_indices); transformation->vbo_indices = 0; } if (transformation->shader) { gst_object_unref (transformation->shader); transformation->shader = NULL; } }
static void gst_gl_transformation_reset (GstGLFilter * filter) { GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter); /* blocking call, wait until the opengl thread has destroyed the shader */ if (transformation->shader) gst_gl_context_del_shader (filter->context, transformation->shader); transformation->shader = NULL; }
static gboolean gst_gl_transformation_init_shader (GstGLFilter * filter) { GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter); if (gst_gl_context_get_gl_api (filter->context)) { /* blocking call, wait until the opengl thread has compiled the shader */ return gst_gl_context_gen_shader (filter->context, cube_v_src, cube_f_src, &transformation->shader); } return TRUE; }
static gboolean gst_gl_transformation_stop (GstBaseTransform * trans) { GstGLBaseFilter *basefilter = GST_GL_BASE_FILTER (trans); GstGLTransformation *transformation = GST_GL_TRANSFORMATION (trans); /* blocking call, wait until the opengl thread has destroyed the shader */ if (basefilter->context && transformation->shader) { gst_gl_context_del_shader (basefilter->context, transformation->shader); transformation->shader = NULL; } return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans); }
static gboolean gst_gl_transformation_set_caps (GstGLFilter * filter, GstCaps * incaps, GstCaps * outcaps) { GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter); transformation->aspect = (gdouble) GST_VIDEO_INFO_WIDTH (&filter->out_info) / (gdouble) GST_VIDEO_INFO_HEIGHT (&filter->out_info); gst_gl_transformation_build_mvp (transformation); return TRUE; }
static void gst_gl_transformation_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstGLTransformation *filter = GST_GL_TRANSFORMATION (object); switch (prop_id) { case PROP_FOV: filter->fov = g_value_get_float (value); break; case PROP_ORTHO: filter->ortho = g_value_get_boolean (value); break; case PROP_TRANSLATION_X: filter->xtranslation = g_value_get_float (value); break; case PROP_TRANSLATION_Y: filter->ytranslation = g_value_get_float (value); break; case PROP_TRANSLATION_Z: filter->ztranslation = g_value_get_float (value); break; case PROP_ROTATION_X: filter->xrotation = g_value_get_float (value); break; case PROP_ROTATION_Y: filter->yrotation = g_value_get_float (value); break; case PROP_ROTATION_Z: filter->zrotation = g_value_get_float (value); break; case PROP_SCALE_X: filter->xscale = g_value_get_float (value); break; case PROP_SCALE_Y: filter->yscale = g_value_get_float (value); break; case PROP_MVP: if (g_value_get_boxed (value) != NULL) filter->mvp_matrix = *((graphene_matrix_t *) g_value_get_boxed (value)); return; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } gst_gl_transformation_build_mvp (filter); }
static gboolean gst_gl_transformation_filter_texture (GstGLFilter * filter, guint in_tex, guint out_tex) { GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter); transformation->in_tex = in_tex; /* blocking call, use a FBO */ gst_gl_context_use_fbo_v2 (GST_GL_BASE_FILTER (filter)->context, GST_VIDEO_INFO_WIDTH (&filter->out_info), GST_VIDEO_INFO_HEIGHT (&filter->out_info), filter->fbo, filter->depthbuffer, out_tex, gst_gl_transformation_callback, (gpointer) transformation); return TRUE; }
static void gst_gl_transformation_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstGLTransformation *filter = GST_GL_TRANSFORMATION (object); switch (prop_id) { case PROP_FOV: g_value_set_float (value, filter->fov); break; case PROP_ORTHO: g_value_set_boolean (value, filter->ortho); break; case PROP_TRANSLATION_X: g_value_set_float (value, filter->xtranslation); break; case PROP_TRANSLATION_Y: g_value_set_float (value, filter->ytranslation); break; case PROP_TRANSLATION_Z: g_value_set_float (value, filter->ztranslation); break; case PROP_ROTATION_X: g_value_set_float (value, filter->xrotation); break; case PROP_ROTATION_Y: g_value_set_float (value, filter->yrotation); break; case PROP_ROTATION_Z: g_value_set_float (value, filter->zrotation); break; case PROP_SCALE_X: g_value_set_float (value, filter->xscale); break; case PROP_SCALE_Y: g_value_set_float (value, filter->yscale); break; case PROP_MVP: g_value_set_boxed (value, (gconstpointer) & filter->mvp_matrix); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void gst_gl_transformation_callback (gpointer stuff) { GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; GLfloat temp_matrix[16]; gst_gl_context_clear_shader (GST_GL_BASE_FILTER (filter)->context); gl->BindTexture (GL_TEXTURE_2D, 0); gl->ClearColor (0.f, 0.f, 0.f, 1.f); gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gst_gl_shader_use (transformation->shader); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, transformation->in_tex); gst_gl_shader_set_uniform_1i (transformation->shader, "texture", 0); graphene_matrix_to_float (&transformation->mvp_matrix, temp_matrix); 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); gl->GenBuffers (1, &transformation->vbo_indices); gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, transformation->vbo_indices); gl->BufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices, GL_STATIC_DRAW); transformation->caps_change = TRUE; } if (gl->GenVertexArrays) gl->BindVertexArray (transformation->vao); if (transformation->caps_change) { _upload_vertices (transformation); _bind_buffer (transformation); if (gl->GenVertexArrays) { gl->BindVertexArray (0); gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0); gl->BindBuffer (GL_ARRAY_BUFFER, 0); } } else if (!gl->GenVertexArrays) { _bind_buffer (transformation); } gl->DrawElements (GL_TRIANGLE_STRIP, 5, GL_UNSIGNED_SHORT, indices); if (gl->GenVertexArrays) gl->BindVertexArray (0); else _unbind_buffer (transformation); gst_gl_context_clear_shader (GST_GL_BASE_FILTER (filter)->context); transformation->caps_change = FALSE; }
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; /* *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, }; const GLfloat texture_coordinates[] = { 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, }; /* *INDENT-ON* */ 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); gl->ClearColor (0.f, 0.f, 0.f, 0.f); gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 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); graphene_matrix_to_float (&transformation->mvp_matrix, temp_matrix); gst_gl_shader_set_uniform_matrix_4fv (transformation->shader, "mvp", 1, GL_FALSE, temp_matrix); gl->DrawElements (GL_TRIANGLE_STRIP, 5, GL_UNSIGNED_SHORT, indices); gl->DisableVertexAttribArray (attr_position_loc); gl->DisableVertexAttribArray (attr_texture_loc); gst_gl_context_clear_shader (filter->context); }