[gtk+/wip/baedert/gl: 47/95] gl renderer: Implement simple shadow nodes
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/gl: 47/95] gl renderer: Implement simple shadow nodes
- Date: Tue, 19 Dec 2017 14:46:23 +0000 (UTC)
commit 3cb8fba358aae140d02d841ddf87b468e4e2a001
Author: Timm Bäder <mail baedert org>
Date: Fri Dec 1 10:27:31 2017 +0100
gl renderer: Implement simple shadow nodes
gsk/gl/gskglrenderer.c | 77 +++++++++++++++++++++++++++++++++++--
gsk/gl/gskglrenderopsprivate.h | 8 +++-
gsk/meson.build | 1 +
gsk/resources/glsl/shadow.fs.glsl | 13 ++++++
4 files changed, 94 insertions(+), 5 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index d421734..d3c59fc 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -171,6 +171,7 @@ struct _GskGLRenderer
Program blur_program;
Program inset_shadow_program;
Program outset_shadow_program;
+ Program shadow_program;
};
};
@@ -321,6 +322,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
{ "blur", "blit.vs.glsl", "blur.fs.glsl" },
{ "inset shadow", "blit.vs.glsl", "inset_shadow.fs.glsl" },
{ "outset shadow", "blit.vs.glsl", "outset_shadow.fs.glsl" },
+ { "shadow", "blit.vs.glsl", "shadow.fs.glsl" },
};
builder = gsk_shader_builder_new ();
@@ -431,6 +433,9 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, corner_widths);
INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, corner_heights);
+ /* shadow */
+ INIT_PROGRAM_UNIFORM_LOCATION2 (shadow, color);
+
g_object_unref (builder);
return TRUE;
}
@@ -664,7 +669,7 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
float max_y = min_y + node->bounds.size.height;
/* Default vertex data */
- GskQuadVertex vertex_data[GL_N_VERTICES] = {
+ const GskQuadVertex vertex_data[GL_N_VERTICES] = {
{ { min_x, min_y }, { 0, 0 }, },
{ { min_x, max_y }, { 0, 1 }, },
{ { max_x, min_y }, { 1, 0 }, },
@@ -967,6 +972,7 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
}
break;
+
case GSK_COLOR_MATRIX_NODE:
{
int texture_id;
@@ -1100,10 +1106,70 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
}
break;
-do_default:
+ case GSK_SHADOW_NODE:
+ {
+ GskRenderNode *child = gsk_shadow_node_get_child (node);
+ gsize n_shadows = gsk_shadow_node_get_n_shadows (node);
+ guint i;
+
+ /* TODO: shadow nodes are most commonly used for text and icon shadows.
+ * In both cases, we can avoit the RTT case!
+ * if the child is neither a text node nor a texture node though, we need
+ * to fall back to rendering it to a texture and then applying the shadow on that one.*/
+
+ for (i = 0; i < n_shadows; i ++)
+ {
+ const GskShadow *shadow = gsk_shadow_node_peek_shadow (node, i);
+ int texture_id;
+ gboolean is_offscreen;
+ graphene_matrix_t offset_matrix;
+ graphene_matrix_t prev_modelview;
+
+ /* TODO: Implement blurred shadow nodes */;
+ if (shadow->radius > 0)
+ {
+ /* TODO: This draws the entire node, not just one shadow. */
+ render_fallback_node (self, node, builder, vertex_data);
+ continue;
+ }
+
+ add_offscreen_ops (self, builder, min_x, max_x, min_y, max_y, child, &texture_id, &is_offscreen);
+
+ ops_set_program (builder, &self->shadow_program);
+ ops_set_color (builder, &shadow->color);
+ ops_set_texture (builder, texture_id);
+
+ offset_matrix = builder->current_modelview;
+ graphene_matrix_translate (&offset_matrix, &GRAPHENE_POINT3D_INIT (shadow->dx, shadow->dy, 0));
+ prev_modelview = ops_set_modelview (builder, &offset_matrix);
+
+ if (is_offscreen)
+ {
+ GskQuadVertex vertex_data[GL_N_VERTICES] = {
+ { { min_x, min_y }, { 0, 1 }, },
+ { { min_x, max_y }, { 0, 0 }, },
+ { { max_x, min_y }, { 1, 1 }, },
+
+ { { max_x, max_y }, { 1, 0 }, },
+ { { min_x, max_y }, { 0, 0 }, },
+ { { max_x, min_y }, { 1, 1 }, },
+ };
+ ops_draw (builder, vertex_data);
+ }
+ else
+ {
+ ops_draw (builder, vertex_data);
+ }
+
+ ops_set_modelview (builder, &prev_modelview);
+ }
+
+ /* Now draw the child normally */
+ gsk_gl_renderer_add_render_ops (self, child, builder);
+ }
+ break;
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
- case GSK_SHADOW_NODE:
case GSK_BORDER_NODE:
case GSK_CROSS_FADE_NODE:
case GSK_BLEND_NODE:
@@ -1307,7 +1373,10 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
case OP_CHANGE_COLOR:
OP_PRINT (" -> Color: (%f, %f, %f, %f)", op->color.red, op->color.green, op->color.blue,
op->color.alpha);
- g_assert (program == &self->color_program || program == &self->coloring_program);
+ g_assert (program == &self->color_program || program == &self->coloring_program ||
+ program == &self->shadow_program);
+ /* TODO: We use color.color_location here and this is right for all three of the programs above,
+ * but that's just a coincidence. */
glUniform4f (program->color.color_location,
op->color.red, op->color.green, op->color.blue, op->color.alpha);
break;
diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h
index ec9bc94..f577bd7 100644
--- a/gsk/gl/gskglrenderopsprivate.h
+++ b/gsk/gl/gskglrenderopsprivate.h
@@ -10,7 +10,7 @@
#include "gskglrendererprivate.h"
#define GL_N_VERTICES 6
-#define GL_N_PROGRAMS 9
+#define GL_N_PROGRAMS 10
enum {
OP_NONE,
@@ -60,6 +60,9 @@ typedef struct
int color_location;
} coloring;
struct {
+ int color_location;
+ } shadow;
+ struct {
int color_matrix_location;
int color_offset_location;
} color_matrix;
@@ -146,6 +149,9 @@ typedef struct
float offset[2];
float color[4];
} outset_shadow;
+ struct {
+ float color[4];
+ } shadow;
};
} RenderOp;
diff --git a/gsk/meson.build b/gsk/meson.build
index f05cb34..54828e7 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -11,6 +11,7 @@ gsk_private_source_shaders = [
'resources/glsl/blur.fs.glsl',
'resources/glsl/inset_shadow.fs.glsl',
'resources/glsl/outset_shadow.fs.glsl',
+ 'resources/glsl/shadow.fs.glsl',
'resources/glsl/es2_common.fs.glsl',
'resources/glsl/es2_common.vs.glsl',
'resources/glsl/gl3_common.fs.glsl',
diff --git a/gsk/resources/glsl/shadow.fs.glsl b/gsk/resources/glsl/shadow.fs.glsl
new file mode 100644
index 0000000..3426ba3
--- /dev/null
+++ b/gsk/resources/glsl/shadow.fs.glsl
@@ -0,0 +1,13 @@
+uniform vec4 u_color;
+
+void main() {
+ vec4 diffuse = Texture(u_source, vUv);
+ vec4 color = u_color;
+
+ // pre-multiply
+ color.rgb *= color.a;
+
+ color = vec4(u_color.rgb * diffuse.a, diffuse.a);
+
+ setOutputColor(color);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]