diff options
Diffstat (limited to 'tests/examples/gtk/glliveshader.c')
-rw-r--r-- | tests/examples/gtk/glliveshader.c | 350 |
1 files changed, 0 insertions, 350 deletions
diff --git a/tests/examples/gtk/glliveshader.c b/tests/examples/gtk/glliveshader.c deleted file mode 100644 index 03e745ee3..000000000 --- a/tests/examples/gtk/glliveshader.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2015 Matthew Waters <matthew@centricular.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include <gst/gst.h> -#include <gst/gl/gl.h> -#include <gst/gl/gstglfuncs.h> -#include <gtk/gtk.h> -#if GST_GL_HAVE_WINDOW_X11 -#include <X11/Xlib.h> -#endif - -#ifndef GL_GEOMETRY_SHADER -#define GL_GEOMETRY_SHADER 0x8DD9 -#endif - -static GMainLoop *loop; - -static const gchar *vert = "#version 330\n\ -in vec4 a_position;\n\ -in vec2 a_texcoord;\n\ -out vec2 v_texcoord;\n\ -uniform float time;\n\ -uniform float width;\n\ -uniform float height;\n\ -void main()\n\ -{\n\ - gl_Position = a_position;\n\ - v_texcoord = a_texcoord;\n\ -}\n"; - -static const gchar *geom = "#version 330\n\ -\n\ -layout(triangles) in;\n\ -layout(triangle_strip, max_vertices = 3) out;\n\ -in vec2 v_texcoord[];\n\ -out vec2 g_texcoord;\n\ -\n\ -void main() {\n\ - for(int i = 0; i < 3; i++) {\n\ - gl_Position = gl_in[i].gl_Position;\n\ - g_texcoord = v_texcoord[i];\n\ - EmitVertex();\n\ - }\n\ - EndPrimitive();\n\ -}\n"; - -static const gchar *frag = "#version 330\n\ -in vec2 g_texcoord;\n\ -uniform sampler2D tex;\n\ -uniform float time;\n\ -uniform float width;\n\ -uniform float height;\n\ -void main()\n\ -{\n\ - gl_FragColor = texture2D(tex, g_texcoord);\n\ -}\n"; - -#define MAX_SHADER_STAGES 8 -struct shader_state; - -struct text_view_state -{ - struct shader_state *state; - - GLenum type; - gchar *str; -}; - -struct shader_state -{ - GstGLContext *context; - GstElement *shader; - gboolean shader_linked; - GtkWidget *label; - struct text_view_state text_states[MAX_SHADER_STAGES]; - gint n_stages; -}; - -static gboolean -bus_call (GstBus * bus, GstMessage * msg, gpointer data) -{ - switch (GST_MESSAGE_TYPE (msg)) { - case GST_MESSAGE_EOS: - g_print ("End of stream\n"); - g_main_loop_quit (loop); - break; - case GST_MESSAGE_ERROR:{ - gchar *debug; - GError *error; - - gst_message_parse_error (msg, &error, &debug); - g_free (debug); - - g_printerr ("Error: %s\n", error->message); - g_error_free (error); - - g_main_loop_quit (loop); - break; - } - default: - break; - } - - return TRUE; -} - -static gchar * -_find_source_for_shader_type (struct shader_state *state, GLenum type) -{ - int i = 0; - - for (i = 0; i < state->n_stages; i++) { - if (state->text_states[i].type == type) - return state->text_states[i].str; - } - - return NULL; -} - -static gboolean -_add_stage_to_shader (GstGLShader * shader, struct shader_state *state, - GLenum type, const gchar * default_src) -{ - GError *error = NULL; - GstGLSLVersion version; - GstGLSLProfile profile; - GstGLSLStage *stage; - const gchar *src; - - src = _find_source_for_shader_type (state, type); - if (!src) - src = default_src; - if (!src) - /* FIXME: assume this stage is not needed */ - return TRUE; - - if (!gst_glsl_string_get_version_profile (src, &version, &profile)) { - g_print ("Warning: failed to retreive GLSL version and profile for " - "shader type 0x%x\nsrc:\n%s\n", type, src); - } - - if (!(stage = gst_glsl_stage_new_with_string (shader->context, type, - version, profile, src))) { - g_print ("Error: Failed to create GLSL Stage from src:\n%s\n", src); - return FALSE; - } - - if (!gst_gl_shader_compile_attach_stage (shader, stage, &error)) { - /* ignore failed shader compilations */ - g_print ("%s", error->message); - return FALSE; - } - - return TRUE; -} - -static GstGLShader * -_new_shader (GstGLContext * context, struct shader_state *state) -{ - GstGLShader *shader = gst_gl_shader_new (context); - GError *error = NULL; - - if (!_add_stage_to_shader (shader, state, GL_VERTEX_SHADER, vert)) { - gst_object_unref (shader); - return NULL; - } - if (!_add_stage_to_shader (shader, state, GL_GEOMETRY_SHADER, geom)) { - gst_object_unref (shader); - return NULL; - } - if (!_add_stage_to_shader (shader, state, GL_FRAGMENT_SHADER, frag)) { - gst_object_unref (shader); - return NULL; - } - - if (!gst_gl_shader_link (shader, &error)) { - /* ignore failed shader compilations */ - g_print ("%s", error->message); - gst_object_unref (shader); - return NULL; - } - - return shader; -} - -static gboolean -_set_compilation_state (struct shader_state *state) -{ - gtk_label_set_text (GTK_LABEL (state->label), - state->shader_linked ? "Success" : "Failure"); - - return G_SOURCE_REMOVE; -} - -static GstGLShader * -_create_shader (GstElement * element, struct shader_state *state) -{ - GstGLContext *context; - GstGLShader *shader, *new_shader; - - g_object_get (G_OBJECT (element), "context", &context, "shader", &shader, - NULL); - - new_shader = _new_shader (context, state); - if (!shader && !new_shader) - g_warning ("Failed to create a shader!"); - state->shader_linked = new_shader != NULL; - - if (shader) - gst_object_unref (shader); - gst_object_unref (context); - - g_main_context_invoke (NULL, (GSourceFunc) _set_compilation_state, state); - - return new_shader; -} - -static void -_on_text_changed (GtkTextBuffer * text, struct text_view_state *state) -{ - GtkTextIter start, end; - - gtk_text_buffer_get_bounds (text, &start, &end); - g_free (state->str); - state->str = gtk_text_buffer_get_text (text, &start, &end, FALSE); - g_object_set (state->state->shader, "update-shader", TRUE, NULL); -} - -static GtkWidget * -_new_source_view (struct shader_state *state, GLenum type, const gchar * templ) -{ - static int i = 0; - GtkWidget *scroll, *text_view; - GtkTextBuffer *text; - - g_return_val_if_fail (i < MAX_SHADER_STAGES, NULL); - - state->text_states[i].state = state; - state->text_states[i].type = type; - state->text_states[i].str = g_strdup (templ); - - scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_set_size_request (scroll, 20, 20); - text_view = gtk_text_view_new (); - gtk_container_add (GTK_CONTAINER (scroll), text_view); - text = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); - if (state->text_states[i].str) - gtk_text_buffer_set_text (text, state->text_states[i].str, -1); - g_signal_connect (text, "changed", G_CALLBACK (_on_text_changed), - &state->text_states[i]); - state->n_stages++; - i++; - - return scroll; -} - -int -main (int argc, char *argv[]) -{ - GstElement *pipeline, *src, *upload, *shader, *sink; - GtkWidget *window, *paned, *video, *right_box, *book; - struct shader_state state = { 0, }; - GstBus *bus; - -#if GST_GL_HAVE_WINDOW_X11 - XInitThreads (); -#endif - - gst_init (&argc, &argv); - gtk_init (&argc, &argv); - - loop = g_main_loop_new (NULL, FALSE); - - pipeline = gst_pipeline_new (NULL); - src = gst_element_factory_make ("videotestsrc", NULL); - upload = gst_element_factory_make ("glupload", NULL); - shader = gst_element_factory_make ("glshader", NULL); - sink = gst_element_factory_make ("gtkglsink", NULL); - g_object_get (sink, "widget", &video, NULL); - - g_assert (src && shader && sink); - gst_bin_add_many (GST_BIN (pipeline), src, upload, shader, sink, NULL); - g_assert (gst_element_link_many (src, upload, shader, sink, NULL)); - - bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); - gst_bus_add_watch (bus, bus_call, loop); - gst_object_unref (bus); - - state.shader = gst_object_ref (shader); - g_signal_connect (shader, "create-shader", G_CALLBACK (_create_shader), - &state); - - book = gtk_notebook_new (); - /* text view inside a scroll view */ - gtk_notebook_append_page (GTK_NOTEBOOK (book), _new_source_view (&state, - GL_VERTEX_SHADER, vert), gtk_label_new ("Vertex")); - gtk_notebook_append_page (GTK_NOTEBOOK (book), _new_source_view (&state, - GL_GEOMETRY_SHADER, geom), gtk_label_new ("Geometry")); - gtk_notebook_append_page (GTK_NOTEBOOK (book), _new_source_view (&state, - GL_FRAGMENT_SHADER, frag), gtk_label_new ("Fragment")); - /* status label */ - state.label = gtk_label_new ("Success"); - - /* right side source code editor */ - right_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_box_pack_start (GTK_BOX (right_box), book, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (right_box), state.label, FALSE, TRUE, 0); - - paned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); - gtk_paned_pack1 (GTK_PANED (paned), video, TRUE, FALSE); - gtk_widget_set_size_request (video, 20, 20); - gtk_paned_pack2 (GTK_PANED (paned), right_box, TRUE, FALSE); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size (GTK_WINDOW (window), 640, 480); - gtk_container_add (GTK_CONTAINER (window), paned); - - gtk_widget_show_all (window); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - g_main_loop_run (loop); - - gst_element_set_state (pipeline, GST_STATE_NULL); - - /*shader strings leaked here */ - /*g_free (state.str); */ - gst_object_unref (state.shader); - - gst_object_unref (pipeline); - - return 0; -} |