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; }
/* opengl scene, params: input texture (not the output mixer->texture) */ static void gst_gl_video_mixer_callback (gpointer stuff) { GstGLVideoMixer *video_mixer = GST_GL_VIDEO_MIXER (stuff); GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (stuff); GstGLMixer *mixer = GST_GL_MIXER (video_mixer); GstGLFuncs *gl = GST_GL_BASE_MIXER (mixer)->context->gl_vtable; GLint attr_position_loc = 0; GLint attr_texture_loc = 0; guint out_width, out_height; guint count = 0; out_width = GST_VIDEO_INFO_WIDTH (&vagg->info); out_height = GST_VIDEO_INFO_HEIGHT (&vagg->info); gst_gl_context_clear_shader (GST_GL_BASE_MIXER (mixer)->context); gl->BindTexture (GL_TEXTURE_2D, 0); gl->Disable (GL_DEPTH_TEST); gl->Disable (GL_CULL_FACE); if (gl->GenVertexArrays) { if (!video_mixer->vao) gl->GenVertexArrays (1, &video_mixer->vao); gl->BindVertexArray (video_mixer->vao); } if (!_draw_background (video_mixer)) return; gst_gl_shader_use (video_mixer->shader); attr_position_loc = gst_gl_shader_get_attribute_location (video_mixer->shader, "a_position"); attr_texture_loc = gst_gl_shader_get_attribute_location (video_mixer->shader, "a_texCoord"); gl->Enable (GL_BLEND); while (count < video_mixer->input_frames->len) { GstGLMixerFrameData *frame; GstGLVideoMixerPad *pad; GstVideoInfo *v_info; guint in_tex; guint in_width, in_height; /* *INDENT-OFF* */ gfloat v_vertices[] = { -1.0,-1.0,-1.0f, 0.0f, 0.0f, 1.0,-1.0,-1.0f, 1.0f, 0.0f, 1.0, 1.0,-1.0f, 1.0f, 1.0f, -1.0, 1.0,-1.0f, 0.0f, 1.0f, }; /* *INDENT-ON* */ frame = g_ptr_array_index (video_mixer->input_frames, count); if (!frame) { GST_DEBUG ("skipping texture, null frame"); count++; continue; } pad = (GstGLVideoMixerPad *) frame->pad; v_info = &GST_VIDEO_AGGREGATOR_PAD (pad)->info; in_width = GST_VIDEO_INFO_WIDTH (v_info); in_height = GST_VIDEO_INFO_HEIGHT (v_info); if (!frame->texture || in_width <= 0 || in_height <= 0 || pad->alpha == 0.0f) { GST_DEBUG ("skipping texture:%u frame:%p width:%u height:%u alpha:%f", frame->texture, frame, in_width, in_height, pad->alpha); count++; continue; } in_tex = frame->texture; _init_vbo_indices (video_mixer); if (pad->geometry_change || !pad->vertex_buffer) { gint pad_width, pad_height; gfloat w, h; _mixer_pad_get_output_size (video_mixer, pad, &pad_width, &pad_height); w = ((gfloat) pad_width / (gfloat) out_width); h = ((gfloat) pad_height / (gfloat) out_height); /* top-left */ v_vertices[0] = v_vertices[15] = 2.0f * (gfloat) pad->xpos / (gfloat) out_width - 1.0f; /* bottom-left */ v_vertices[1] = v_vertices[6] = 2.0f * (gfloat) pad->ypos / (gfloat) out_height - 1.0f; /* top-right */ v_vertices[5] = v_vertices[10] = v_vertices[0] + 2.0f * w; /* bottom-right */ v_vertices[11] = v_vertices[16] = v_vertices[1] + 2.0f * h; GST_TRACE ("processing texture:%u dimensions:%ux%u, at %f,%f %fx%f with " "alpha:%f", in_tex, in_width, in_height, v_vertices[0], v_vertices[1], v_vertices[5], v_vertices[11], pad->alpha); if (!pad->vertex_buffer) gl->GenBuffers (1, &pad->vertex_buffer); gl->BindBuffer (GL_ARRAY_BUFFER, pad->vertex_buffer); gl->BufferData (GL_ARRAY_BUFFER, 4 * 5 * sizeof (GLfloat), v_vertices, GL_STATIC_DRAW); pad->geometry_change = FALSE; } else { gl->BindBuffer (GL_ARRAY_BUFFER, pad->vertex_buffer); } gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, video_mixer->vbo_indices); gl->BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl->BlendEquation (GL_FUNC_ADD); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, in_tex); gst_gl_shader_set_uniform_1i (video_mixer->shader, "texture", 0); gst_gl_shader_set_uniform_1f (video_mixer->shader, "alpha", pad->alpha); gl->EnableVertexAttribArray (attr_position_loc); gl->EnableVertexAttribArray (attr_texture_loc); gl->VertexAttribPointer (attr_position_loc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), (void *) 0); gl->VertexAttribPointer (attr_texture_loc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), (void *) (3 * sizeof (GLfloat))); gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); ++count; } gl->DisableVertexAttribArray (attr_position_loc); gl->DisableVertexAttribArray (attr_texture_loc); if (gl->GenVertexArrays) gl->BindVertexArray (0); gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0); gl->BindBuffer (GL_ARRAY_BUFFER, 0); gl->BindTexture (GL_TEXTURE_2D, 0); gl->Disable (GL_BLEND); gst_gl_context_clear_shader (GST_GL_BASE_MIXER (mixer)->context); }
static gboolean _callback (gpointer stuff) { GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; static GLfloat xrot = 0; static GLfloat yrot = 0; static GLfloat zrot = 0; const GLfloat matrix[] = { 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; gl->Enable (GL_DEPTH_TEST); gl->ClearColor (cube_filter->red, cube_filter->green, cube_filter->blue, 0.0); gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gst_gl_shader_use (cube_filter->shader); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, cube_filter->in_tex->tex_id); gst_gl_shader_set_uniform_1i (cube_filter->shader, "s_texture", 0); gst_gl_shader_set_uniform_1f (cube_filter->shader, "xrot_degree", xrot); gst_gl_shader_set_uniform_1f (cube_filter->shader, "yrot_degree", yrot); gst_gl_shader_set_uniform_1f (cube_filter->shader, "zrot_degree", zrot); gst_gl_shader_set_uniform_matrix_4fv (cube_filter->shader, "u_matrix", 1, GL_FALSE, matrix); if (!cube_filter->vertex_buffer) { if (gl->GenVertexArrays) { gl->GenVertexArrays (1, &cube_filter->vao); gl->BindVertexArray (cube_filter->vao); } gl->GenBuffers (1, &cube_filter->vertex_buffer); gl->BindBuffer (GL_ARRAY_BUFFER, cube_filter->vertex_buffer); gl->BufferData (GL_ARRAY_BUFFER, 6 * 4 * 5 * sizeof (GLfloat), vertices, GL_STATIC_DRAW); gl->GenBuffers (1, &cube_filter->vbo_indices); gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, cube_filter->vbo_indices); gl->BufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices, GL_STATIC_DRAW); if (gl->GenVertexArrays) { _bind_buffer (cube_filter); gl->BindVertexArray (0); } gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0); gl->BindBuffer (GL_ARRAY_BUFFER, 0); } if (gl->GenVertexArrays) gl->BindVertexArray (cube_filter->vao); _bind_buffer (cube_filter); gl->DrawElements (GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); if (gl->GenVertexArrays) gl->BindVertexArray (0); _unbind_buffer (cube_filter); gl->Disable (GL_DEPTH_TEST); xrot += 0.3f; yrot += 0.2f; zrot += 0.4f; return TRUE; }