[gtk/snazzy-demo: 1/4] gtk-demo: Make gltransitions demo a bit snazzier
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/snazzy-demo: 1/4] gtk-demo: Make gltransitions demo a bit snazzier
- Date: Wed, 30 Sep 2020 14:26:53 +0000 (UTC)
commit e9885f9cdee2121f927f3b5b0c5603cf148acd3b
Author: Alexander Larsson <alexl redhat com>
Date: Wed Sep 30 11:40:37 2020 +0200
gtk-demo: Make gltransitions demo a bit snazzier
This adds a bunch of snazz to the gltransitions demo. It is perhaps
a bit overloaded now, but it demos everything that we can do.
Changes:
* The fire shader is now not a bin, it just renders an animating
background with no textures involved.
* The stacks don't all start on the same page.
* The shaderbin passes the mouse coordinate to the shader.
* The shaderbin allows specifying a "border" so that you can
cause effects outside the bin child (something that is new to gtk4).
* All the buttons and the stacks are now in shader-bins that runs
a wobbly-widget effect based on the mouse position that
wobbles outside the child allocation.
demos/gtk-demo/demo.gresource.xml | 3 ++-
demos/gtk-demo/fire.glsl | 4 +---
demos/gtk-demo/gltransition.c | 44 ++++++++++++++++++++++++++++-----------
demos/gtk-demo/gtkshaderbin.c | 27 ++++++++++++++++++++++--
demos/gtk-demo/gtkshaderbin.h | 3 ++-
demos/gtk-demo/gtkshaderstack.c | 9 ++++++++
demos/gtk-demo/gtkshaderstack.h | 4 +++-
demos/gtk-demo/ripple.glsl | 43 ++++++++++++++++++++++++++++++++++++++
8 files changed, 117 insertions(+), 20 deletions(-)
---
diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml
index cc9727481c..d279d08af5 100644
--- a/demos/gtk-demo/demo.gresource.xml
+++ b/demos/gtk-demo/demo.gresource.xml
@@ -138,8 +138,9 @@
<file>gtkshaderstack.h</file>
<file>gtkshaderbin.h</file>
<file>gtkshaderbin.c</file>
+ <file>ripple.glsl</file>
<file>fire.glsl</file>
- <file>transition1.glsl</file>
+ <file>transition1.glsl</file>
<file>transition2.glsl</file>
<file>transition3.glsl</file>
<file>transition4.glsl</file>
diff --git a/demos/gtk-demo/fire.glsl b/demos/gtk-demo/fire.glsl
index e62fe1bd39..1992688206 100644
--- a/demos/gtk-demo/fire.glsl
+++ b/demos/gtk-demo/fire.glsl
@@ -1,5 +1,4 @@
uniform float u_time;
-uniform sampler2D u_texture1;
/* 2D -> [0..1] random number generator */
float random(vec2 st) {
@@ -67,6 +66,5 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec
vec3 color = 1.0 / (w*w/c + 1.0);
// Mix in widget
- vec4 widget = GskTexture(u_texture1,uv);
- fragColor = gsk_premultiply(mix(vec4(color,1), widget, 1.0-color.x));
+ fragColor = gsk_premultiply(vec4(color, color.x));
}
diff --git a/demos/gtk-demo/gltransition.c b/demos/gtk-demo/gltransition.c
index 24b6f96f30..8106e4ea89 100644
--- a/demos/gtk-demo/gltransition.c
+++ b/demos/gtk-demo/gltransition.c
@@ -85,15 +85,15 @@ clicked_cb (GtkGestureClick *gesture,
}
static GtkWidget *
-fire_bin_new (void)
+ripple_bin_new (void)
{
GtkWidget *bin = gtk_shader_bin_new ();
static GskGLShader *shader = NULL;
if (shader == NULL)
- shader = gsk_gl_shader_new_from_resource ("/gltransition/fire.glsl");
+ shader = gsk_gl_shader_new_from_resource ("/gltransition/ripple.glsl");
- gtk_shader_bin_add_shader (GTK_SHADER_BIN (bin), shader, GTK_STATE_FLAG_PRELIGHT, GTK_STATE_FLAG_PRELIGHT);
+ gtk_shader_bin_add_shader (GTK_SHADER_BIN (bin), shader, GTK_STATE_FLAG_PRELIGHT, GTK_STATE_FLAG_PRELIGHT,
20);
return bin;
}
@@ -131,6 +131,7 @@ update_paintable (GtkWidget *widget,
static GtkWidget *
make_shader_stack (const char *name,
const char *resource_path,
+ int active_child,
GtkWidget *scale)
{
GtkWidget *stack, *child, *widget, *vbox, *hbox, *bin;
@@ -219,6 +220,8 @@ make_shader_stack (const char *name,
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
+ gtk_shader_stack_set_active (GTK_SHADER_STACK (stack), active_child);
+
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
widget = gtk_center_box_new ();
@@ -245,7 +248,10 @@ make_shader_stack (const char *name,
gtk_box_append (GTK_BOX (vbox), widget);
- gtk_box_append (GTK_BOX (vbox), stack);
+ GtkWidget *bin2 = ripple_bin_new ();
+ gtk_shader_bin_set_child (GTK_SHADER_BIN (bin2), stack);
+
+ gtk_box_append (GTK_BOX (vbox), bin2);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
@@ -254,13 +260,13 @@ make_shader_stack (const char *name,
button = gtk_button_new_from_icon_name ("go-previous");
g_signal_connect (button, "clicked", G_CALLBACK (go_back), stack);
- bin = fire_bin_new ();
+ bin = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin), button);
gtk_box_append (GTK_BOX (hbox), bin);
button = gtk_button_new_from_icon_name ("go-next");
g_signal_connect (button, "clicked", G_CALLBACK (go_forward), stack);
- bin = fire_bin_new ();
+ bin = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin), button);
gtk_box_append (GTK_BOX (hbox), bin);
@@ -270,7 +276,8 @@ make_shader_stack (const char *name,
static GtkWidget *
create_gltransition_window (GtkWidget *do_widget)
{
- GtkWidget *window, *headerbar, *scale, *grid;
+ GtkWidget *window, *headerbar, *scale, *outer_grid, *grid, *background;
+ GdkPaintable *paintable;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
@@ -284,8 +291,21 @@ create_gltransition_window (GtkWidget *do_widget)
gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
+ outer_grid = gtk_grid_new ();
+ gtk_window_set_child (GTK_WINDOW (window), outer_grid);
+
+ paintable = gsk_shader_paintable_new (gsk_gl_shader_new_from_resource ("/gltransition/fire.glsl"), NULL);
+ background = gtk_picture_new_for_paintable (paintable);
+ gtk_widget_add_tick_callback (background, update_paintable, NULL, NULL);
+
+ gtk_grid_attach (GTK_GRID (outer_grid),
+ background,
+ 0, 0, 1, 1);
+
grid = gtk_grid_new ();
- gtk_window_set_child (GTK_WINDOW (window), grid);
+ gtk_grid_attach (GTK_GRID (outer_grid),
+ grid,
+ 0, 0, 1, 1);
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
gtk_widget_set_valign (grid, GTK_ALIGN_CENTER);
@@ -299,16 +319,16 @@ create_gltransition_window (GtkWidget *do_widget)
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_attach (GTK_GRID (grid),
- make_shader_stack ("Wind", "/gltransition/transition1.glsl", scale),
+ make_shader_stack ("Wind", "/gltransition/transition1.glsl", 0, scale),
0, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
- make_shader_stack ("Radial", "/gltransition/transition2.glsl", scale),
+ make_shader_stack ("Radial", "/gltransition/transition2.glsl", 1, scale),
1, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
- make_shader_stack ("Crosswarp", "/gltransition/transition3.glsl", scale),
+ make_shader_stack ("Crosswarp", "/gltransition/transition3.glsl", 2, scale),
0, 1, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
- make_shader_stack ("Kaleidoscope", "/gltransition/transition4.glsl", scale),
+ make_shader_stack ("Kaleidoscope", "/gltransition/transition4.glsl", 3, scale),
1, 1, 1, 1);
return window;
diff --git a/demos/gtk-demo/gtkshaderbin.c b/demos/gtk-demo/gtkshaderbin.c
index 3a97311c3e..9148e292a3 100644
--- a/demos/gtk-demo/gtkshaderbin.c
+++ b/demos/gtk-demo/gtkshaderbin.c
@@ -4,6 +4,7 @@ typedef struct {
GskGLShader *shader;
GtkStateFlags state;
GtkStateFlags state_mask;
+ float extra_border;
gboolean compiled;
gboolean compiled_ok;
} ShaderInfo;
@@ -16,6 +17,7 @@ struct _GtkShaderBin
GPtrArray *shaders;
guint tick_id;
float time;
+ float mouse_x, mouse_y;
gint64 first_frame_time;
};
@@ -71,10 +73,25 @@ gtk_shader_bin_tick (GtkWidget *widget,
return G_SOURCE_CONTINUE;
}
+static void
+motion_cb (GtkEventControllerMotion *controller,
+ double x,
+ double y,
+ GtkShaderBin *self)
+{
+ self->mouse_x = x;
+ self->mouse_y = y;
+}
+
static void
gtk_shader_bin_init (GtkShaderBin *self)
{
+ GtkEventController *controller;
self->shaders = g_ptr_array_new_with_free_func ((GDestroyNotify)shader_info_free);
+
+ controller = gtk_event_controller_motion_new ();
+ g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self);
+ gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
void
@@ -132,12 +149,14 @@ void
gtk_shader_bin_add_shader (GtkShaderBin *self,
GskGLShader *shader,
GtkStateFlags state,
- GtkStateFlags state_mask)
+ GtkStateFlags state_mask,
+ float extra_border)
{
ShaderInfo *info = g_new0 (ShaderInfo, 1);
info->shader = g_object_ref (shader);
info->state = state;
info->state_mask = state_mask;
+ info->extra_border = extra_border;
g_ptr_array_add (self->shaders, info);
@@ -198,10 +217,14 @@ gtk_shader_bin_snapshot (GtkWidget *widget,
if (self->active_shader->compiled_ok)
{
+ float border = self->active_shader->extra_border;
+ graphene_vec2_t mouse;
+ graphene_vec2_init (&mouse, self->mouse_x + border, self->mouse_y + border);
gtk_snapshot_push_gl_shader (snapshot, self->active_shader->shader,
- &GRAPHENE_RECT_INIT(0, 0, width, height),
+ &GRAPHENE_RECT_INIT(-border, -border, width+2*border,
height+2*border),
gsk_gl_shader_format_args (self->active_shader->shader,
"u_time", self->time,
+ "u_mouse", &mouse,
NULL));
gtk_widget_snapshot_child (widget, self->child, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot);
diff --git a/demos/gtk-demo/gtkshaderbin.h b/demos/gtk-demo/gtkshaderbin.h
index eabac8f0d6..32ed18fe6f 100644
--- a/demos/gtk-demo/gtkshaderbin.h
+++ b/demos/gtk-demo/gtkshaderbin.h
@@ -12,7 +12,8 @@ GtkWidget *gtk_shader_bin_new (void);
void gtk_shader_bin_add_shader (GtkShaderBin *self,
GskGLShader *shader,
GtkStateFlags state,
- GtkStateFlags state_mask);
+ GtkStateFlags state_mask,
+ float extra_border);
void gtk_shader_bin_set_child (GtkShaderBin *self,
GtkWidget *child);
GtkWidget *gtk_shader_bin_get_child (GtkShaderBin *self);
diff --git a/demos/gtk-demo/gtkshaderstack.c b/demos/gtk-demo/gtkshaderstack.c
index 27194df3b1..9b71c22855 100644
--- a/demos/gtk-demo/gtkshaderstack.c
+++ b/demos/gtk-demo/gtkshaderstack.c
@@ -350,3 +350,12 @@ gtk_shader_stack_add_child (GtkShaderStack *self,
else
gtk_widget_set_child_visible (child, FALSE);
}
+
+void
+gtk_shader_stack_set_active (GtkShaderStack *self,
+ int index)
+{
+ stop_transition (self);
+ self->current = MIN (index, self->children->len);
+ update_child_visible (self);
+}
diff --git a/demos/gtk-demo/gtkshaderstack.h b/demos/gtk-demo/gtkshaderstack.h
index 9f8e4e45e5..16d1fe9e3f 100644
--- a/demos/gtk-demo/gtkshaderstack.h
+++ b/demos/gtk-demo/gtkshaderstack.h
@@ -14,7 +14,9 @@ void gtk_shader_stack_set_shader (GtkShaderStack *self,
void gtk_shader_stack_add_child (GtkShaderStack *self,
GtkWidget *child);
void gtk_shader_stack_transition (GtkShaderStack *self,
- gboolean forward);
+ gboolean forward);
+void gtk_shader_stack_set_active (GtkShaderStack *self,
+ int index);
G_END_DECLS
diff --git a/demos/gtk-demo/ripple.glsl b/demos/gtk-demo/ripple.glsl
new file mode 100644
index 0000000000..028c14c159
--- /dev/null
+++ b/demos/gtk-demo/ripple.glsl
@@ -0,0 +1,43 @@
+uniform float u_time;
+uniform vec2 u_mouse;
+uniform sampler2D u_texture1;
+
+#define PI 3.141592654
+
+float decay(float v, float t)
+{
+ return v * (1.0 / (1.0 + t*t));
+}
+
+void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
+{
+ // Temporary to loop time every 1 sec
+ float time = u_time;
+ // we normalize all the effects according to the min height/width
+ float size = min(resolution.x, resolution.y);
+
+ // Animate one wave over size in 0.3 sec
+ float wave_speed = size / 0.3;
+ float wave_length = size / 1.0;
+ float wave_height = size * 0.1;
+
+ vec2 center = u_mouse;
+ vec2 direction_from_center = fragCoord - center;
+ float distance_from_center = length(direction_from_center);
+
+ /* Normalize direction */
+ direction_from_center = direction_from_center / distance_from_center;
+
+ float propagation_length = time * wave_speed;
+
+ float t = (propagation_length - distance_from_center) / wave_length;
+ float offset_magnitude = 0;
+ if (t > 0.0)
+ offset_magnitude = decay(wave_height * sin(t * 2.0 * PI), t);
+
+ vec2 offset = direction_from_center * min(offset_magnitude, distance_from_center);
+ vec2 source = fragCoord - offset;
+
+ vec2 uv2 = source / resolution;
+ fragColor = GskTexture(u_texture1, vec2(uv2.x, 1.0-uv2.y));
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]