static void gst_gl_effects_twirl_callback (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLFilter *filter = GST_GL_FILTER (effects); GstGLContext *context = GST_GL_BASE_FILTER (filter)->context; GstGLFuncs *gl = context->gl_vtable; shader = gst_gl_effects_get_fragment_shader (effects, "twirl", twirl_fragment_source_gles2); if (!shader) return; #if GST_GL_HAVE_OPENGL if (USING_OPENGL (context)) { gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); } #endif gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (shader, "tex", 0); gst_gl_filter_draw_texture (filter, texture, width, height); }
void gst_3d_renderer_draw_stereo (Gst3DRenderer * self, Gst3DScene * scene) { GstGLFuncs *gl = self->context->gl_vtable; _insert_gl_debug_marker (self->context, "gst_3d_renderer_draw_stereo"); /* aquire current fbo id */ GLint bound_fbo; gl->GetIntegerv (GL_DRAW_FRAMEBUFFER_BINDING, &bound_fbo); if (bound_fbo == 0) return; Gst3DCameraHmd *hmd_cam = GST_3D_CAMERA_HMD (scene->camera); /* left eye */ _draw_eye (self, self->left_fbo, scene, &hmd_cam->left_vp_matrix); /* right eye */ _draw_eye (self, self->right_fbo, scene, &hmd_cam->right_vp_matrix); gst_3d_scene_clear_state (scene); gst_3d_shader_bind (self->shader); gl->BindFramebuffer (GL_FRAMEBUFFER, bound_fbo); gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _draw_framebuffers_on_planes (self); gst_3d_scene_clear_state (scene); }
static void gst_gl_effects_sobel_callback_vconv (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader = NULL; GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLFilter *filter = GST_GL_FILTER (effects); if (NULL != (shader = gst_gl_effects_get_fragment_shader (effects, "vconv0", sep_sobel_vconv3_fragment_source_gles2, sep_sobel_vconv3_fragment_source_opengl))) { GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; #if GST_GL_HAVE_OPENGL if (USING_OPENGL (GST_GL_BASE_FILTER (filter)->context)) { gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); } #endif gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (shader, "tex", 0); gst_gl_shader_set_uniform_1f (shader, "height", height); gst_gl_filter_draw_texture (filter, texture, width, height); } }
/* free resources that need a gl context */ static void gst_gl_differencematte_reset_gl_resources (GstGLFilter * filter) { GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; gint i; gl->DeleteTextures (1, &differencematte->savedbgtexture); gl->DeleteTextures (1, &differencematte->newbgtexture); for (i = 0; i < 4; i++) { if (differencematte->identity_shader) { gst_object_unref (differencematte->identity_shader); differencematte->identity_shader = NULL; } if (differencematte->shader[i]) { gst_object_unref (differencematte->shader[i]); differencematte->shader[i] = NULL; } if (differencematte->midtexture[i]) { gl->DeleteTextures (1, &differencematte->midtexture[i]); differencematte->midtexture[i] = 0; } } differencematte->location = NULL; differencematte->pixbuf = NULL; differencematte->savedbgtexture = 0; differencematte->newbgtexture = 0; differencematte->bg_has_changed = FALSE; }
static void _init_scene (Gst3DScene * scene) { GstGLContext *context = scene->context; GstGLFuncs *gl = context->gl_vtable; GError *error = NULL; Gst3DMesh *sphere_mesh; Gst3DNode *sphere_node; Gst3DShader *sphere_shader = gst_3d_shader_new_vert_frag (context, "mvp_uv.vert", "texture_uv.frag", &error); if (sphere_shader == NULL) { GST_WARNING ("Failed to create VR compositor shaders. Error: %s", error->message); g_clear_error (&error); return; /* FIXME: Add boolean return result */ } sphere_mesh = gst_3d_mesh_new_sphere (context, 800.0, 100, 100); sphere_node = gst_3d_node_new_from_mesh_shader (context, sphere_mesh, sphere_shader); gst_3d_scene_append_node (scene, sphere_node); gl->ClearColor (0.f, 0.f, 0.f, 0.f); gl->ActiveTexture (GL_TEXTURE0); gst_3d_shader_bind (sphere_shader); gst_gl_shader_set_uniform_1i (sphere_shader->shader, "texture", 0); }
void gst_3d_scene_clear_state (Gst3DScene * self) { GstGLFuncs *gl = self->context->gl_vtable; gl->BindVertexArray (0); gl->BindTexture (GL_TEXTURE_2D, 0); gst_gl_context_clear_shader (self->context); }
void _insert_gl_debug_marker (GstGLContext * context, const gchar * message) { GstGLFuncs *gl = context->gl_vtable; gl->DebugMessageInsert (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 1, GL_DEBUG_SEVERITY_HIGH, strlen (message), message); }
//opengl scene, params: input texture (not the output filter->texture) static void gst_gl_filter_glass_callback (gpointer stuff) { static gint64 start_time = 0; gfloat rotation; GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (stuff); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; gint width = GST_VIDEO_INFO_WIDTH (&filter->out_info); gint height = GST_VIDEO_INFO_HEIGHT (&filter->out_info); guint texture = glass_filter->in_tex; if (start_time == 0) start_time = get_time (); else { gint64 time_left = (glass_filter->timestamp / 1000) - (get_time () - start_time); time_left -= 1000000 / 25; if (time_left > 2000) { GST_LOG ("escape"); return; } } gst_gl_shader_use (glass_filter->passthrough_shader); gst_gl_filter_glass_draw_background_gradient (glass_filter); //Rotation if (start_time != 0) { gint64 time_passed = get_time () - start_time; rotation = sin (time_passed / 1200000.0) * 45.0f; } else { rotation = 0.0f; } gl->Enable (GL_BLEND); gl->BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gst_gl_shader_use (glass_filter->shader); //Reflection gst_gl_filter_glass_draw_video_plane (filter, width, height, texture, 0.0f, 2.0f, 0.3f, 0.0f, TRUE, rotation); //Main video gst_gl_filter_glass_draw_video_plane (filter, width, height, texture, 0.0f, 0.0f, 1.0f, 1.0f, FALSE, rotation); gst_gl_context_clear_shader (GST_GL_BASE_FILTER (filter)->context); gl->Disable (GL_BLEND); }
static void _draw_eye (Gst3DRenderer * self, GLuint fbo, Gst3DScene * scene, graphene_matrix_t * mvp) { GstGLFuncs *gl = self->context->gl_vtable; _insert_gl_debug_marker (self->context, "_draw_eye"); gl->BindFramebuffer (GL_FRAMEBUFFER, fbo); gl->Viewport (0, 0, self->eye_width, self->eye_height); gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gst_3d_scene_draw_nodes (scene, mvp); }
static void deinit (gpointer data) { GstGLContext *context = data; GstGLFuncs *gl = context->gl_vtable; gl->DeleteTextures (1, &tex);; gst_object_unref (fbo); #if GST_GL_HAVE_GLES2 if (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2) gst_object_unref (shader); #endif }
static void deinit (gpointer data) { GstGLContext *context = data; GstGLFuncs *gl = context->gl_vtable; if (vao) gl->DeleteVertexArrays (1, &vao); gst_object_unref (fbo); gst_object_unref (shader); gst_memory_unref (GST_MEMORY_CAST (gl_tex)); gst_memory_unref (GST_MEMORY_CAST (gl_tex2)); }
static void gst_gl_differencematte_save_texture (gint width, gint height, guint texture, gpointer stuff) { GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void gst_gl_differencematte_interp (gint width, gint height, guint texture, gpointer stuff) { GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff); GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; gl->MatrixMode (GL_PROJECTION); glLoadIdentity (); gst_gl_shader_use (differencematte->shader[3]); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (differencematte->shader[3], "blend", 0); gl->ActiveTexture (GL_TEXTURE1); gl->BindTexture (GL_TEXTURE_2D, differencematte->newbgtexture); gst_gl_shader_set_uniform_1i (differencematte->shader[3], "base", 1); gl->ActiveTexture (GL_TEXTURE2); gl->BindTexture (GL_TEXTURE_2D, differencematte->midtexture[2]); gst_gl_shader_set_uniform_1i (differencematte->shader[3], "alpha", 2); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void clear_tex (gpointer data) { GstGLContext *context = data; GstGLFuncs *gl = context->gl_vtable; static gfloat r = 0.0, g = 0.0, b = 0.0; gl->ClearColor (r, g, b, 1.0); gl->Clear (GL_COLOR_BUFFER_BIT); r = r > 1.0 ? 0.0 : r + 0.03; g = g > 1.0 ? 0.0 : g + 0.01; b = b > 1.0 ? 0.0 : b + 0.015; }
/** * gst_gl_context_clear_shader: * @context: a #GstGLContext * * Clear's the currently set shader from the GL state machine. * * Note: must be called in the GL thread. */ void gst_gl_context_clear_shader (GstGLContext * context) { GstGLFuncs *gl; g_return_if_fail (GST_IS_GL_CONTEXT (context)); gl = context->gl_vtable; if (gl->CreateProgram) gl->UseProgram (0); else if (gl->CreateProgramObject) gl->UseProgramObject (0); }
/* free resources that need a gl context */ static void gst_gl_effects_reset_gl_resources (GstGLFilter * filter) { GstGLEffects *effects = GST_GL_EFFECTS (filter); GstGLFuncs *gl = filter->context->gl_vtable; gint i = 0; for (i = 0; i < NEEDED_TEXTURES; i++) { gl->DeleteTextures (1, &effects->midtexture[i]); effects->midtexture[i] = 0; } for (i = 0; i < GST_GL_EFFECTS_N_CURVES; i++) { gl->DeleteTextures (1, &effects->curve[i]); effects->curve[i] = 0; } }
/** * gst_gl_shader_bind_attribute_location: * @shader: a #GstGLShader * @index: attribute index to set * @name: name of the attribute * * Bind attribute @name to the specified location @index using * glBindAttributeLocation(). */ void gst_gl_shader_bind_attribute_location (GstGLShader * shader, GLuint index, const gchar * name) { GstGLShaderPrivate *priv; GstGLFuncs *gl; g_return_if_fail (shader != NULL); priv = shader->priv; g_return_if_fail (priv->program_handle != 0); gl = shader->context->gl_vtable; GST_TRACE_OBJECT (shader, "binding program %i attribute \'%s\' location %i", (int) priv->program_handle, name, index); gl->BindAttribLocation (priv->program_handle, index, name); }
static void set_horizontal_swap (GstGLContext * context, gpointer data) { #if GST_GL_HAVE_OPENGL GstGLFuncs *gl = context->gl_vtable; if (gst_gl_context_get_gl_api (context) & GST_GL_API_OPENGL) { const gfloat mirrormatrix[16] = { -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 }; gl->MatrixMode (GL_MODELVIEW); gl->LoadMatrixf (mirrormatrix); } #endif }
static void gst_gl_differencematte_identity (gint width, gint height, guint texture, gpointer stuff) { GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff); GstGLFilter *filter = GST_GL_FILTER (differencematte); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; gst_gl_shader_use (differencematte->identity_shader); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (differencematte->identity_shader, "tex", 0); gst_gl_filter_draw_texture (filter, texture, width, height); }
/** * gst_gl_shader_set_uniform_2fv: * @shader: a #GstGLShader * @name: name of the uniform * @count: number of values to set * @value: (array length=count): values to set * * Perform glUniform2fv() for @name on @shader */ void gst_gl_shader_set_uniform_2fv (GstGLShader * shader, const gchar * name, guint count, const gfloat * value) { GstGLShaderPrivate *priv; GstGLFuncs *gl; GLint location = -1; g_return_if_fail (shader != NULL); priv = shader->priv; g_return_if_fail (priv->program_handle != 0); gl = shader->context->gl_vtable; location = _get_uniform_location (shader, name); gl->Uniform2fv (location, count, value); }
/** * gst_gl_shader_set_uniform_2i: * @shader: a #GstGLShader * @name: name of the uniform * @v0: first value to set * @v1: second value to set * * Perform glUniform2i() for @name on @shader */ void gst_gl_shader_set_uniform_2i (GstGLShader * shader, const gchar * name, gint v0, gint v1) { GstGLShaderPrivate *priv; GstGLFuncs *gl; GLint location = -1; g_return_if_fail (shader != NULL); priv = shader->priv; g_return_if_fail (priv->program_handle != 0); gl = shader->context->gl_vtable; location = _get_uniform_location (shader, name); gl->Uniform2i (location, v0, v1); }
static gboolean _2d_texture_renderer_init (GstAmc2DTextureRenderer * renderer) { GstGLFuncs *gl; gboolean res; gl = renderer->context->gl_vtable; if (renderer->initialized) return TRUE; if (!gl->CreateProgramObject && !gl->CreateProgram) { gst_gl_context_set_error (renderer->context, "Cannot perform conversion without OpenGL shaders"); return FALSE; } _gen_oes_texture (renderer->context, &renderer->oes_tex_id); res = gst_gl_context_gen_shader (renderer->context, vert_COPY_OES, frag_COPY_OES, &renderer->shader); if (!res) return FALSE; renderer->shader_attr_position_loc = gst_gl_shader_get_attribute_location (renderer->shader, "a_position"); renderer->shader_attr_texture_loc = gst_gl_shader_get_attribute_location (renderer->shader, "a_texcoord"); gst_gl_shader_use (renderer->shader); gst_gl_shader_set_uniform_1i (renderer->shader, "u_tex", 0); gst_gl_context_clear_shader (renderer->context); if (!_2d_texture_renderer_init_fbo (renderer)) return FALSE; gl->BindTexture (GL_TEXTURE_2D, 0); renderer->initialized = TRUE; return TRUE; }
/** * gst_gl_shader_bind_frag_data_location: * @shader: a #GstGLShader * @index: attribute index to set * @name: name of the attribute * * Bind attribute @name to the specified location @index using * glBindFragDataLocation(). */ void gst_gl_shader_bind_frag_data_location (GstGLShader * shader, guint index, const gchar * name) { GstGLShaderPrivate *priv; GstGLFuncs *gl; g_return_if_fail (shader != NULL); if (!_ensure_program (shader)) g_return_if_fail (shader->priv->program_handle); priv = shader->priv; gl = shader->context->gl_vtable; g_return_if_fail (gl->BindFragDataLocation); GST_TRACE_OBJECT (shader, "binding program %i frag data \'%s\' location %i", (int) priv->program_handle, name, index); gl->BindFragDataLocation (priv->program_handle, index, name); }
/** * gst_gl_shader_get_attribute_location: * @shader: a #GstGLShader * @name: name of the attribute * * Returns: the attribute index for @name in @shader or -1 on failure */ GLint gst_gl_shader_get_attribute_location (GstGLShader * shader, const gchar * name) { GstGLShaderPrivate *priv; GstGLFuncs *gl; gint ret; g_return_val_if_fail (shader != NULL, -1); priv = shader->priv; g_return_val_if_fail (priv->program_handle != 0, -1); gl = shader->context->gl_vtable; ret = gl->GetAttribLocation (priv->program_handle, name); GST_TRACE_OBJECT (shader, "retreived program %i attribute \'%s\' location %i", (int) priv->program_handle, name, ret); return ret; }
static gboolean _scene_geometry_draw (gpointer impl) { struct GeometryScene *self = impl; g_return_val_if_fail (self->base.context, FALSE); GstGLFuncs *gl = self->base.context->gl_vtable; /* gst_gl_shader_use (self->shader->shader); gst_gl_shader_set_uniform_1f (self->shader->shader, "time", (gfloat) self->base.src->running_time / GST_SECOND); */ gl->Enable (GL_DEPTH_TEST); gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gst_3d_scene_draw (self->scene); gl->Disable (GL_DEPTH_TEST); return TRUE; }
static gboolean gst_gl_filtershader_hcallback (GstGLFilter * filter, GstGLMemory * in_tex, gpointer stuff) { GstGLFilterShader *filtershader = GST_GL_FILTERSHADER (filter); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; GstGLShader *shader; if (!(shader = _maybe_recompile_shader (filtershader))) return FALSE; gl->ClearColor (0.0, 0.0, 0.0, 1.0); gl->Clear (GL_COLOR_BUFFER_BIT); gst_gl_shader_use (shader); /* FIXME: propertise these */ gst_gl_shader_set_uniform_1i (shader, "tex", 0); gst_gl_shader_set_uniform_1f (shader, "width", GST_VIDEO_INFO_WIDTH (&filter->out_info)); gst_gl_shader_set_uniform_1f (shader, "height", GST_VIDEO_INFO_HEIGHT (&filter->out_info)); gst_gl_shader_set_uniform_1f (shader, "time", filtershader->time); /* FIXME: propertise these */ filter->draw_attr_position_loc = gst_gl_shader_get_attribute_location (shader, "a_position"); filter->draw_attr_texture_loc = gst_gl_shader_get_attribute_location (shader, "a_texcoord"); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, gst_gl_memory_get_texture_id (in_tex)); gst_gl_filter_draw_fullscreen_quad (filter); gst_object_unref (shader); return TRUE; }
static void gst_gl_differencematte_vblur (gint width, gint height, guint texture, gpointer stuff) { GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (stuff); GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; gst_gl_shader_use (differencematte->shader[2]); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (differencematte->shader[2], "tex", 0); gst_gl_shader_set_uniform_1fv (differencematte->shader[2], "kernel", 7, differencematte->kernel); gst_gl_shader_set_uniform_1f (differencematte->shader[2], "gauss_height", height); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void gst_gl_effects_squeeze_callback (gint width, gint height, guint texture, gpointer data) { GstGLShader *shader; GstGLFilter *filter = GST_GL_FILTER (data); GstGLEffects *effects = GST_GL_EFFECTS (data); GstGLContext *context = filter->context; GstGLFuncs *gl = context->gl_vtable; shader = g_hash_table_lookup (effects->shaderstable, "squeeze0"); if (!shader) { shader = gst_gl_shader_new (context); g_hash_table_insert (effects->shaderstable, (gchar *) "squeeze0", shader); if (USING_GLES2 (context) || USING_OPENGL3 (context)) { if (!gst_gl_shader_compile_with_default_v_and_check (shader, squeeze_fragment_source_gles2, &filter->draw_attr_position_loc, &filter->draw_attr_texture_loc)) { /* gst gl context error is already set */ GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("Failed to initialize squeeze shader, %s", gst_gl_context_get_error ()), (NULL)); return; } } #if GST_GL_HAVE_OPENGL if (USING_OPENGL (context)) { if (!gst_gl_shader_compile_and_check (shader, squeeze_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) { gst_gl_context_set_error (context, "Failed to initialize squeeze shader"); GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); return; } } #endif } #if GST_GL_HAVE_OPENGL if (USING_OPENGL (context)) { gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); } #endif gst_gl_shader_use (shader); gl->ActiveTexture (GL_TEXTURE0); if (USING_OPENGL (context)) gl->Enable (GL_TEXTURE_2D); gl->BindTexture (GL_TEXTURE_2D, texture); gst_gl_shader_set_uniform_1i (shader, "tex", 0); gst_gl_filter_draw_texture (filter, texture, width, height); }
static void _draw_framebuffers_on_planes (Gst3DRenderer * self) { GstGLFuncs *gl = self->context->gl_vtable; _insert_gl_debug_marker (self->context, "_draw_framebuffers_on_planes"); graphene_matrix_t projection_ortho; graphene_matrix_init_ortho (&projection_ortho, -self->filter_aspect, self->filter_aspect, -1.0, 1.0, -1.0, 1.0); gst_3d_shader_upload_matrix (self->shader, &projection_ortho, "mvp"); gst_3d_mesh_bind (self->render_plane); /* left framebuffer */ gl->Viewport (0, 0, self->eye_width, self->eye_height); glBindTexture (GL_TEXTURE_2D, self->left_color_tex); gst_3d_mesh_draw (self->render_plane); /* right framebuffer */ gl->Viewport (self->eye_width, 0, self->eye_width, self->eye_height); glBindTexture (GL_TEXTURE_2D, self->right_color_tex); gst_3d_mesh_draw (self->render_plane); }
static gboolean gst_gl_deinterlace_greedyh_callback (GstGLFilter * filter, GstGLMemory * in_tex, gpointer user_data) { GstGLShader *shader; GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter); GstGLContext *context = GST_GL_BASE_FILTER (filter)->context; GstGLFuncs *gl = context->gl_vtable; shader = gst_gl_deinterlace_get_fragment_shader (filter, "greedhy", greedyh_fragment_source); if (!shader) return FALSE; #if GST_GL_HAVE_OPENGL if (USING_OPENGL (context)) { gl->MatrixMode (GL_PROJECTION); gl->LoadIdentity (); } #endif gst_gl_shader_use (shader); if (G_LIKELY (deinterlace_filter->prev_tex != NULL)) { gl->ActiveTexture (GL_TEXTURE1); gst_gl_shader_set_uniform_1i (shader, "tex_prev", 1); gl->BindTexture (GL_TEXTURE_2D, gst_gl_memory_get_texture_id (deinterlace_filter->prev_tex)); } gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, gst_gl_memory_get_texture_id (in_tex)); gst_gl_shader_set_uniform_1i (shader, "tex", 0); gst_gl_shader_set_uniform_1f (shader, "max_comb", 5.0f / 255.0f); gst_gl_shader_set_uniform_1f (shader, "motion_threshold", 25.0f / 255.0f); gst_gl_shader_set_uniform_1f (shader, "motion_sense", 30.0f / 255.0f); gst_gl_shader_set_uniform_1f (shader, "width", GST_VIDEO_INFO_WIDTH (&filter->out_info)); gst_gl_shader_set_uniform_1f (shader, "height", GST_VIDEO_INFO_HEIGHT (&filter->out_info)); gst_gl_filter_draw_fullscreen_quad (filter); /* we keep the previous buffer around so this is safe */ deinterlace_filter->prev_tex = in_tex; return TRUE; }