[gtk+/wip/ebassi/gsk-renderer: 4/4] gsk: Allow sampling between parent and child nodes
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/ebassi/gsk-renderer: 4/4] gsk: Allow sampling between parent and child nodes
- Date: Thu, 30 Jun 2016 16:07:44 +0000 (UTC)
commit 5ea4b6757bde28eda0180d1d32d0690468d166a7
Author: Emmanuele Bassi <ebassi gnome org>
Date: Thu Jun 30 17:06:31 2016 +0100
gsk: Allow sampling between parent and child nodes
gsk/gskglrenderer.c | 58 ++++++++++++++++++++++++----------
gsk/gskrendernode.c | 18 +++++++++++
gsk/gskrendernodeprivate.h | 2 +
gsk/resources/glsl/gl3-base.fs.glsl | 11 ++++++-
4 files changed, 71 insertions(+), 18 deletions(-)
---
diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c
index b5573f0..a4ea324 100644
--- a/gsk/gskglrenderer.c
+++ b/gsk/gskglrenderer.c
@@ -43,6 +43,7 @@ typedef struct {
const char *name;
RenderData render_data;
+ RenderData *parent_data;
} RenderItem;
struct _GskGLRenderer
@@ -482,9 +483,12 @@ gsk_gl_renderer_update_frustum (GskGLRenderer *self,
{
GSK_NOTE (OPENGL, g_print ("Updating the modelview/projection\n"));
- graphene_matrix_multiply (modelview, projection, &self->mvp);
+ graphene_matrix_multiply (projection, modelview, &self->mvp);
graphene_frustum_init_from_matrix (&self->frustum, &self->mvp);
+
+ GSK_NOTE (OPENGL, g_print ("Renderer MVP:\n"));
+ GSK_NOTE (OPENGL, graphene_matrix_print (&self->mvp));
}
static void
@@ -568,6 +572,16 @@ render_item (RenderItem *item)
glBindTexture (GL_TEXTURE_2D, item->render_data.texture_id);
glUniform1i (item->render_data.map_location, 0);
+ if (item->parent_data != NULL)
+ {
+ if (item->parent_data->texture_id != 0)
+ {
+ glActiveTexture (GL_TEXTURE1);
+ glBindTexture (GL_TEXTURE_2D, item->parent_data->texture_id);
+ glUniform1i (item->render_data.map_location, 1);
+ }
+ }
+
/* Pass the opacity component */
glUniform1f (item->render_data.alpha_location, item->opaque ? 1 : item->opacity);
@@ -692,7 +706,8 @@ project_item (const graphene_matrix_t *projection,
static void
gsk_gl_renderer_add_render_item (GskGLRenderer *self,
- GskRenderNode *node)
+ GskRenderNode *node,
+ RenderItem *parent)
{
graphene_rect_t viewport;
int gl_min_filter, gl_mag_filter;
@@ -711,6 +726,8 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
return;
}
+ memset (&item, 0, sizeof (RenderItem));
+
gsk_renderer_get_viewport (GSK_RENDERER (self), &viewport);
gsk_render_node_get_bounds (node, &bounds);
@@ -724,17 +741,17 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
/* Each render item is an axis-aligned bounding box that we
* transform using the given transformation matrix
*/
- item.min.x = (bounds.origin.x * 2) / bounds.size.width - 1;
- item.min.y = (bounds.origin.y * 2) / bounds.size.height - 1;
+ item.min.x = bounds.origin.x;
+ item.min.y = bounds.origin.y;
item.min.z = 0.f;
- item.max.x = (bounds.origin.x + bounds.size.width) * 2 / bounds.size.width - 1;
- item.max.y = (bounds.origin.y + bounds.size.height) * 2 / bounds.size.height - 1;
+ item.max.x = bounds.origin.x + bounds.size.width;
+ item.max.y = bounds.origin.y + bounds.size.height;
item.max.z = 0.f;
/* The location of the item, in normalized world coordinates */
gsk_render_node_get_world_matrix (node, &mv);
- item.mvp = mv;
+ graphene_matrix_multiply (&mv, &self->mvp, &item.mvp);
item.opaque = gsk_render_node_get_opacity (node);
item.opacity = gsk_render_node_get_opacity (node);
@@ -749,6 +766,11 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
item.render_data.position_location = self->position_location;
item.render_data.alpha_location = self->alpha_location;
+ if (parent != NULL)
+ item.parent_data = &(parent->render_data);
+ else
+ item.parent_data = NULL;
+
gsk_renderer_get_projection (GSK_RENDERER (self), &projection);
item.z = project_item (&projection, &mv);
@@ -783,35 +805,37 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self,
recurse_children:
gsk_render_node_iter_init (&iter, node);
while (gsk_render_node_iter_next (&iter, &child))
- gsk_gl_renderer_add_render_item (self, child);
+ gsk_gl_renderer_add_render_item (self, child, &item);
}
static gboolean
gsk_gl_renderer_validate_tree (GskGLRenderer *self,
GskRenderNode *root)
{
- int n_children;
+ int n_nodes;
if (self->context == NULL)
- return FALSE;
+ {
+ GSK_NOTE (OPENGL, g_print ("No valid GL context associated to the renderer"));
+ return FALSE;
+ }
- n_children = gsk_render_node_get_n_children (root);
- if (n_children == 0)
- return FALSE;
+ n_nodes = gsk_render_node_get_size (root);
gdk_gl_context_make_current (self->context);
- self->opaque_render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), n_children);
- self->transparent_render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), n_children);
+ self->opaque_render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), n_nodes);
+ self->transparent_render_items = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), n_nodes);
g_array_set_clear_func (self->opaque_render_items, render_item_clear);
g_array_set_clear_func (self->transparent_render_items, render_item_clear);
GSK_NOTE (OPENGL, g_print ("RenderNode -> RenderItem\n"));
- gsk_gl_renderer_add_render_item (self, root);
+ gsk_gl_renderer_add_render_item (self, root, NULL);
- GSK_NOTE (OPENGL, g_print ("Total render items: %d (opaque:%d, transparent:%d)\n",
+ GSK_NOTE (OPENGL, g_print ("Total render items: %d of %d (opaque:%d, transparent:%d)\n",
self->opaque_render_items->len + self->transparent_render_items->len,
+ n_nodes,
self->opaque_render_items->len,
self->transparent_render_items->len));
diff --git a/gsk/gskrendernode.c b/gsk/gskrendernode.c
index 4618c5a..2de6506 100644
--- a/gsk/gskrendernode.c
+++ b/gsk/gskrendernode.c
@@ -157,6 +157,7 @@ gsk_render_node_init (GskRenderNode *self)
self->opacity = 1.0;
self->is_mutable = TRUE;
+ self->needs_world_matrix_update = TRUE;
}
GType
@@ -1277,6 +1278,23 @@ gsk_render_node_make_immutable (GskRenderNode *node)
gsk_render_node_make_immutable (child);
}
+int
+gsk_render_node_get_size (GskRenderNode *root)
+{
+ GskRenderNodeIter iter;
+ GskRenderNode *child;
+ int res;
+
+ g_return_val_if_fail (GSK_IS_RENDER_NODE (root), 0);
+
+ res = 1;
+ gsk_render_node_iter_init (&iter, root);
+ while (gsk_render_node_iter_next (&iter, &child))
+ res += gsk_render_node_get_size (child);
+
+ return res;
+}
+
void
gsk_value_set_render_node (GValue *value,
GskRenderNode *node)
diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h
index 16b7cf9..7aa100b 100644
--- a/gsk/gskrendernodeprivate.h
+++ b/gsk/gskrendernodeprivate.h
@@ -83,6 +83,8 @@ void gsk_render_node_update_world_matrix (GskRenderNode *node,
void gsk_render_node_get_world_matrix (GskRenderNode *node,
graphene_matrix_t *mv);
+int gsk_render_node_get_size (GskRenderNode *root);
+
G_END_DECLS
#endif /* __GSK_RENDER_NODE_PRIVATE_H__ */
diff --git a/gsk/resources/glsl/gl3-base.fs.glsl b/gsk/resources/glsl/gl3-base.fs.glsl
index 07458db..9dd36cd 100644
--- a/gsk/resources/glsl/gl3-base.fs.glsl
+++ b/gsk/resources/glsl/gl3-base.fs.glsl
@@ -6,8 +6,17 @@ out vec4 outputColor;
uniform mat4 mvp;
uniform sampler2D map;
+uniform sampler2D parentMap;
uniform float alpha;
+vec3 BlendMultiply(vec3 Csrc, vec3 Cdst) {
+ return Csrc * Cdst;
+}
+
void main() {
- outputColor = texture2D(map, vUv) * vec4(alpha);
+ vec3 src = texture2D(map, vUv).xyz;
+ vec3 dst = texture2D(parentMap, vUv).xyz;
+ vec3 res = BlendMultiply(src, dst);
+
+ outputColor = vec4(res, alpha);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]