Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
/*
|
|
|
|
* Clutter.
|
|
|
|
*
|
|
|
|
* An OpenGL based 'interactive canvas' library.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2011 Intel Corporation.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser 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
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* Author:
|
|
|
|
* Emmanuele Bassi <ebassi@linux.intel.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SECTION:clutter-paint-nodes
|
|
|
|
* @Title: Paint Nodes
|
|
|
|
* @Short_Description: ClutterPaintNode implementations
|
|
|
|
*
|
|
|
|
* Clutter provides a set of predefined #ClutterPaintNode implementations
|
|
|
|
* that cover all the state changes available.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
|
|
|
|
|
|
|
#include "clutter-paint-node-private.h"
|
|
|
|
|
|
|
|
#include <pango/pango.h>
|
|
|
|
#include <cogl/cogl.h>
|
|
|
|
|
2012-03-16 16:16:40 +00:00
|
|
|
#include "clutter-actor-private.h"
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
#include "clutter-color.h"
|
|
|
|
#include "clutter-debug.h"
|
|
|
|
#include "clutter-private.h"
|
|
|
|
|
|
|
|
#include "clutter-paint-nodes.h"
|
|
|
|
|
|
|
|
static CoglPipeline *default_color_pipeline = NULL;
|
|
|
|
static CoglPipeline *default_texture_pipeline = NULL;
|
|
|
|
|
|
|
|
/*< private >
|
|
|
|
* _clutter_paint_node_init_types:
|
|
|
|
*
|
|
|
|
* Initializes the required types for ClutterPaintNode subclasses
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
_clutter_paint_node_init_types (void)
|
|
|
|
{
|
|
|
|
CoglContext *ctx;
|
|
|
|
CoglColor cogl_color;
|
|
|
|
GType node_type G_GNUC_UNUSED;
|
|
|
|
|
|
|
|
if (G_LIKELY (default_color_pipeline != NULL))
|
|
|
|
return;
|
|
|
|
|
|
|
|
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
|
|
|
|
|
|
|
node_type = clutter_paint_node_get_type ();
|
|
|
|
|
|
|
|
cogl_color_init_from_4f (&cogl_color, 1.0, 1.0, 1.0, 1.0);
|
|
|
|
|
|
|
|
default_color_pipeline = cogl_pipeline_new (ctx);
|
|
|
|
cogl_pipeline_set_color (default_color_pipeline, &cogl_color);
|
|
|
|
|
|
|
|
default_texture_pipeline = cogl_pipeline_new (ctx);
|
|
|
|
cogl_pipeline_set_layer_null_texture (default_texture_pipeline, 0,
|
|
|
|
COGL_TEXTURE_TYPE_2D);
|
|
|
|
cogl_pipeline_set_color (default_texture_pipeline, &cogl_color);
|
2012-03-12 15:52:55 +00:00
|
|
|
cogl_pipeline_set_layer_wrap_mode (default_texture_pipeline, 0,
|
2013-07-04 15:32:58 +00:00
|
|
|
COGL_PIPELINE_WRAP_MODE_AUTOMATIC);
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Root node, private
|
|
|
|
*
|
|
|
|
* any frame can only have a since RootNode instance for each
|
|
|
|
* top-level actor.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define clutter_root_node_get_type _clutter_root_node_get_type
|
|
|
|
|
|
|
|
typedef struct _ClutterRootNode ClutterRootNode;
|
|
|
|
typedef struct _ClutterPaintNodeClass ClutterRootNodeClass;
|
|
|
|
|
|
|
|
struct _ClutterRootNode
|
|
|
|
{
|
|
|
|
ClutterPaintNode parent_instance;
|
|
|
|
|
|
|
|
CoglFramebuffer *framebuffer;
|
|
|
|
|
|
|
|
CoglBufferBit clear_flags;
|
|
|
|
CoglColor clear_color;
|
|
|
|
};
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (ClutterRootNode, clutter_root_node, CLUTTER_TYPE_PAINT_NODE)
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
clutter_root_node_pre_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterRootNode *rnode = (ClutterRootNode *) node;
|
|
|
|
|
|
|
|
cogl_framebuffer_clear (rnode->framebuffer,
|
|
|
|
rnode->clear_flags,
|
|
|
|
&rnode->clear_color);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_root_node_post_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_root_node_finalize (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterRootNode *rnode = (ClutterRootNode *) node;
|
|
|
|
|
|
|
|
cogl_object_unref (rnode->framebuffer);
|
|
|
|
|
|
|
|
CLUTTER_PAINT_NODE_CLASS (clutter_root_node_parent_class)->finalize (node);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_root_node_class_init (ClutterRootNodeClass *klass)
|
|
|
|
{
|
|
|
|
ClutterPaintNodeClass *node_class = CLUTTER_PAINT_NODE_CLASS (klass);
|
|
|
|
|
|
|
|
node_class->pre_draw = clutter_root_node_pre_draw;
|
|
|
|
node_class->post_draw = clutter_root_node_post_draw;
|
|
|
|
node_class->finalize = clutter_root_node_finalize;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_root_node_init (ClutterRootNode *self)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ClutterPaintNode *
|
|
|
|
_clutter_root_node_new (CoglFramebuffer *framebuffer,
|
|
|
|
const ClutterColor *clear_color,
|
2013-07-20 23:47:15 +00:00
|
|
|
CoglBufferBit clear_flags)
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
{
|
|
|
|
ClutterRootNode *res;
|
|
|
|
|
2012-03-16 11:57:34 +00:00
|
|
|
res = _clutter_paint_node_create (_clutter_root_node_get_type ());
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
|
|
|
cogl_color_init_from_4ub (&res->clear_color,
|
|
|
|
clear_color->red,
|
|
|
|
clear_color->green,
|
|
|
|
clear_color->blue,
|
|
|
|
clear_color->alpha);
|
|
|
|
cogl_color_premultiply (&res->clear_color);
|
|
|
|
|
|
|
|
res->framebuffer = cogl_object_ref (framebuffer);
|
|
|
|
res->clear_flags = clear_flags;
|
|
|
|
|
|
|
|
return (ClutterPaintNode *) res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Transform node
|
|
|
|
*
|
|
|
|
* A private PaintNode, that changes the modelview of its child
|
|
|
|
* nodes.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define clutter_transform_node_get_type _clutter_transform_node_get_type
|
|
|
|
|
|
|
|
typedef struct _ClutterTransformNode {
|
|
|
|
ClutterPaintNode parent_instance;
|
|
|
|
|
|
|
|
CoglMatrix modelview;
|
|
|
|
} ClutterTransformNode;
|
|
|
|
|
|
|
|
typedef struct _ClutterPaintNodeClass ClutterTransformNodeClass;
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (ClutterTransformNode, clutter_transform_node, CLUTTER_TYPE_PAINT_NODE)
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
clutter_transform_node_pre_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterTransformNode *tnode = (ClutterTransformNode *) node;
|
|
|
|
CoglMatrix matrix;
|
|
|
|
|
|
|
|
cogl_push_matrix ();
|
|
|
|
|
|
|
|
cogl_get_modelview_matrix (&matrix);
|
|
|
|
cogl_matrix_multiply (&matrix, &matrix, &tnode->modelview);
|
|
|
|
cogl_set_modelview_matrix (&matrix);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_transform_node_post_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
cogl_pop_matrix ();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_transform_node_class_init (ClutterTransformNodeClass *klass)
|
|
|
|
{
|
|
|
|
ClutterPaintNodeClass *node_class;
|
|
|
|
|
|
|
|
node_class = CLUTTER_PAINT_NODE_CLASS (klass);
|
|
|
|
node_class->pre_draw = clutter_transform_node_pre_draw;
|
|
|
|
node_class->post_draw = clutter_transform_node_post_draw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_transform_node_init (ClutterTransformNode *self)
|
|
|
|
{
|
|
|
|
cogl_matrix_init_identity (&self->modelview);
|
|
|
|
}
|
|
|
|
|
|
|
|
ClutterPaintNode *
|
|
|
|
_clutter_transform_node_new (const CoglMatrix *modelview)
|
|
|
|
{
|
|
|
|
ClutterTransformNode *res;
|
|
|
|
|
2012-03-16 11:57:34 +00:00
|
|
|
res = _clutter_paint_node_create (_clutter_transform_node_get_type ());
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
|
|
|
if (modelview != NULL)
|
|
|
|
res->modelview = *modelview;
|
|
|
|
|
|
|
|
return (ClutterPaintNode *) res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Dummy node, private
|
|
|
|
*
|
|
|
|
* an empty node, used temporarily until we can drop API compatibility,
|
|
|
|
* and we'll be able to build a full render tree for each frame.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define clutter_dummy_node_get_type _clutter_dummy_node_get_type
|
|
|
|
|
|
|
|
typedef struct _ClutterDummyNode ClutterDummyNode;
|
|
|
|
typedef struct _ClutterPaintNodeClass ClutterDummyNodeClass;
|
|
|
|
|
|
|
|
struct _ClutterDummyNode
|
|
|
|
{
|
|
|
|
ClutterPaintNode parent_instance;
|
2012-03-16 16:16:40 +00:00
|
|
|
|
|
|
|
ClutterActor *actor;
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (ClutterDummyNode, clutter_dummy_node, CLUTTER_TYPE_PAINT_NODE)
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
clutter_dummy_node_pre_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2012-03-16 16:16:40 +00:00
|
|
|
static JsonNode *
|
|
|
|
clutter_dummy_node_serialize (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterDummyNode *dnode = (ClutterDummyNode *) node;
|
|
|
|
JsonBuilder *builder;
|
|
|
|
JsonNode *res;
|
|
|
|
|
|
|
|
if (dnode->actor == NULL)
|
|
|
|
return json_node_new (JSON_NODE_NULL);
|
|
|
|
|
|
|
|
builder = json_builder_new ();
|
|
|
|
json_builder_begin_object (builder);
|
|
|
|
|
|
|
|
json_builder_set_member_name (builder, "actor");
|
|
|
|
json_builder_add_string_value (builder, _clutter_actor_get_debug_name (dnode->actor));
|
|
|
|
|
|
|
|
json_builder_end_object (builder);
|
|
|
|
|
|
|
|
res = json_builder_get_root (builder);
|
|
|
|
g_object_unref (builder);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
static void
|
|
|
|
clutter_dummy_node_class_init (ClutterDummyNodeClass *klass)
|
|
|
|
{
|
|
|
|
ClutterPaintNodeClass *node_class = CLUTTER_PAINT_NODE_CLASS (klass);
|
|
|
|
|
|
|
|
node_class->pre_draw = clutter_dummy_node_pre_draw;
|
2012-03-16 16:16:40 +00:00
|
|
|
node_class->serialize = clutter_dummy_node_serialize;
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_dummy_node_init (ClutterDummyNode *self)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ClutterPaintNode *
|
2012-03-16 16:16:40 +00:00
|
|
|
_clutter_dummy_node_new (ClutterActor *actor)
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
{
|
2012-03-16 16:16:40 +00:00
|
|
|
ClutterPaintNode *res;
|
|
|
|
|
|
|
|
res = _clutter_paint_node_create (_clutter_dummy_node_get_type ());
|
|
|
|
|
|
|
|
((ClutterDummyNode *) res)->actor = actor;
|
|
|
|
|
|
|
|
return res;
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pipeline node
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct _ClutterPipelineNode
|
|
|
|
{
|
|
|
|
ClutterPaintNode parent_instance;
|
|
|
|
|
|
|
|
CoglPipeline *pipeline;
|
|
|
|
};
|
|
|
|
|
2012-04-30 16:12:12 +00:00
|
|
|
/**
|
|
|
|
* ClutterPipelineNodeClass:
|
|
|
|
*
|
|
|
|
* The <structname>ClutterPipelineNodeClass</structname> structure is an opaque
|
|
|
|
* type whose members cannot be directly accessed.
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
*/
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
struct _ClutterPipelineNodeClass
|
|
|
|
{
|
|
|
|
ClutterPaintNodeClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (ClutterPipelineNode, clutter_pipeline_node, CLUTTER_TYPE_PAINT_NODE)
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_pipeline_node_finalize (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node);
|
|
|
|
|
|
|
|
if (pnode->pipeline != NULL)
|
|
|
|
cogl_object_unref (pnode->pipeline);
|
|
|
|
|
|
|
|
CLUTTER_PAINT_NODE_CLASS (clutter_pipeline_node_parent_class)->finalize (node);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
clutter_pipeline_node_pre_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node);
|
|
|
|
|
|
|
|
if (node->operations != NULL &&
|
|
|
|
pnode->pipeline != NULL)
|
|
|
|
{
|
|
|
|
cogl_push_source (pnode->pipeline);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_pipeline_node_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node);
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
if (pnode->pipeline == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (node->operations == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < node->operations->len; i++)
|
|
|
|
{
|
|
|
|
const ClutterPaintOperation *op;
|
|
|
|
|
|
|
|
op = &g_array_index (node->operations, ClutterPaintOperation, i);
|
|
|
|
|
|
|
|
switch (op->opcode)
|
|
|
|
{
|
|
|
|
case PAINT_OP_INVALID:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PAINT_OP_TEX_RECT:
|
|
|
|
cogl_rectangle_with_texture_coords (op->op.texrect[0],
|
|
|
|
op->op.texrect[1],
|
|
|
|
op->op.texrect[2],
|
|
|
|
op->op.texrect[3],
|
|
|
|
op->op.texrect[4],
|
|
|
|
op->op.texrect[5],
|
|
|
|
op->op.texrect[6],
|
|
|
|
op->op.texrect[7]);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PAINT_OP_PATH:
|
|
|
|
cogl_path_fill (op->op.path);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PAINT_OP_PRIMITIVE:
|
|
|
|
{
|
|
|
|
CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
|
|
|
|
|
|
|
|
cogl_framebuffer_draw_primitive (fb, pnode->pipeline,
|
|
|
|
op->op.primitive);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_pipeline_node_post_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
cogl_pop_source ();
|
|
|
|
}
|
|
|
|
|
2012-02-03 13:51:29 +00:00
|
|
|
static JsonNode *
|
|
|
|
clutter_pipeline_node_serialize (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (node);
|
|
|
|
JsonBuilder *builder;
|
|
|
|
CoglColor color;
|
|
|
|
JsonNode *res;
|
|
|
|
|
|
|
|
if (pnode->pipeline == NULL)
|
|
|
|
return json_node_new (JSON_NODE_NULL);
|
|
|
|
|
|
|
|
builder = json_builder_new ();
|
|
|
|
json_builder_begin_object (builder);
|
|
|
|
|
|
|
|
cogl_pipeline_get_color (pnode->pipeline, &color);
|
|
|
|
json_builder_set_member_name (builder, "color");
|
|
|
|
json_builder_begin_array (builder);
|
|
|
|
json_builder_add_double_value (builder, cogl_color_get_red (&color));
|
|
|
|
json_builder_add_double_value (builder, cogl_color_get_green (&color));
|
|
|
|
json_builder_add_double_value (builder, cogl_color_get_blue (&color));
|
|
|
|
json_builder_add_double_value (builder, cogl_color_get_alpha (&color));
|
|
|
|
json_builder_end_array (builder);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
json_builder_set_member_name (builder, "layers");
|
|
|
|
json_builder_begin_array (builder);
|
|
|
|
cogl_pipeline_foreach_layer (pnode->pipeline,
|
|
|
|
clutter_pipeline_node_serialize_layer,
|
|
|
|
builder);
|
|
|
|
json_builder_end_array (builder);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
json_builder_end_object (builder);
|
|
|
|
|
|
|
|
res = json_builder_get_root (builder);
|
|
|
|
g_object_unref (builder);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
static void
|
|
|
|
clutter_pipeline_node_class_init (ClutterPipelineNodeClass *klass)
|
|
|
|
{
|
|
|
|
ClutterPaintNodeClass *node_class;
|
|
|
|
|
|
|
|
node_class = CLUTTER_PAINT_NODE_CLASS (klass);
|
|
|
|
node_class->pre_draw = clutter_pipeline_node_pre_draw;
|
|
|
|
node_class->draw = clutter_pipeline_node_draw;
|
|
|
|
node_class->post_draw = clutter_pipeline_node_post_draw;
|
|
|
|
node_class->finalize = clutter_pipeline_node_finalize;
|
2012-02-03 13:51:29 +00:00
|
|
|
node_class->serialize = clutter_pipeline_node_serialize;
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_pipeline_node_init (ClutterPipelineNode *self)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_pipeline_node_new:
|
|
|
|
* @pipeline: (allow-none): a Cogl pipeline state object, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #ClutterPaintNode that will use the @pipeline to
|
|
|
|
* paint its contents.
|
|
|
|
*
|
|
|
|
* This function will acquire a reference on the passed @pipeline,
|
|
|
|
* so it is safe to call cogl_object_unref() when it returns.
|
|
|
|
*
|
|
|
|
* Return value: (transfer full): the newly created #ClutterPaintNode.
|
|
|
|
* Use clutter_paint_node_unref() when done.
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
*/
|
|
|
|
ClutterPaintNode *
|
|
|
|
clutter_pipeline_node_new (CoglPipeline *pipeline)
|
|
|
|
{
|
|
|
|
ClutterPipelineNode *res;
|
|
|
|
|
|
|
|
g_return_val_if_fail (pipeline == NULL || cogl_is_pipeline (pipeline), NULL);
|
|
|
|
|
2012-03-16 11:57:34 +00:00
|
|
|
res = _clutter_paint_node_create (CLUTTER_TYPE_PIPELINE_NODE);
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
|
|
|
if (pipeline != NULL)
|
|
|
|
res->pipeline = cogl_object_ref (pipeline);
|
|
|
|
|
|
|
|
return (ClutterPaintNode *) res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Color node
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct _ClutterColorNode
|
|
|
|
{
|
|
|
|
ClutterPipelineNode parent_instance;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2012-04-30 16:12:12 +00:00
|
|
|
* ClutterColorNodeClass:
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
*
|
|
|
|
* The <structname>ClutterColorNodeClass</structname> structure is an
|
|
|
|
* opaque type whose members cannot be directly accessed.
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
*/
|
|
|
|
struct _ClutterColorNodeClass
|
|
|
|
{
|
|
|
|
ClutterPipelineNodeClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (ClutterColorNode, clutter_color_node, CLUTTER_TYPE_PIPELINE_NODE)
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_color_node_class_init (ClutterColorNodeClass *klass)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_color_node_init (ClutterColorNode *cnode)
|
|
|
|
{
|
|
|
|
ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (cnode);
|
|
|
|
|
|
|
|
g_assert (default_color_pipeline != NULL);
|
|
|
|
pnode->pipeline = cogl_pipeline_copy (default_color_pipeline);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_color_node_new:
|
|
|
|
* @color: (allow-none): the color to paint, or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #ClutterPaintNode that will paint a solid color
|
|
|
|
* fill using @color.
|
|
|
|
*
|
|
|
|
* Return value: (transfer full): the newly created #ClutterPaintNode. Use
|
|
|
|
* clutter_paint_node_unref() when done
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
*/
|
|
|
|
ClutterPaintNode *
|
|
|
|
clutter_color_node_new (const ClutterColor *color)
|
|
|
|
{
|
|
|
|
ClutterPipelineNode *cnode;
|
|
|
|
|
2012-03-16 11:57:34 +00:00
|
|
|
cnode = _clutter_paint_node_create (CLUTTER_TYPE_COLOR_NODE);
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
|
|
|
if (color != NULL)
|
|
|
|
{
|
|
|
|
CoglColor cogl_color;
|
|
|
|
|
|
|
|
cogl_color_init_from_4ub (&cogl_color,
|
|
|
|
color->red,
|
|
|
|
color->green,
|
|
|
|
color->blue,
|
|
|
|
color->alpha);
|
|
|
|
cogl_color_premultiply (&cogl_color);
|
|
|
|
|
|
|
|
cogl_pipeline_set_color (cnode->pipeline, &cogl_color);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (ClutterPaintNode *) cnode;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Texture node
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct _ClutterTextureNode
|
|
|
|
{
|
|
|
|
ClutterPipelineNode parent_instance;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2012-04-30 16:12:12 +00:00
|
|
|
* ClutterTextureNodeClass:
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
*
|
|
|
|
* The <structname>ClutterTextureNodeClass</structname> structure is an
|
|
|
|
* opaque type whose members cannot be directly accessed.
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
*/
|
|
|
|
struct _ClutterTextureNodeClass
|
|
|
|
{
|
|
|
|
ClutterPipelineNodeClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (ClutterTextureNode, clutter_texture_node, CLUTTER_TYPE_PIPELINE_NODE)
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_texture_node_class_init (ClutterTextureNodeClass *klass)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_texture_node_init (ClutterTextureNode *self)
|
|
|
|
{
|
|
|
|
ClutterPipelineNode *pnode = CLUTTER_PIPELINE_NODE (self);
|
|
|
|
|
|
|
|
g_assert (default_texture_pipeline != NULL);
|
|
|
|
pnode->pipeline = cogl_pipeline_copy (default_texture_pipeline);
|
|
|
|
}
|
|
|
|
|
2012-03-08 17:19:12 +00:00
|
|
|
static CoglPipelineFilter
|
|
|
|
clutter_scaling_filter_to_cogl_pipeline_filter (ClutterScalingFilter filter)
|
|
|
|
{
|
|
|
|
switch (filter)
|
|
|
|
{
|
|
|
|
case CLUTTER_SCALING_FILTER_NEAREST:
|
|
|
|
return COGL_PIPELINE_FILTER_NEAREST;
|
|
|
|
|
|
|
|
case CLUTTER_SCALING_FILTER_LINEAR:
|
|
|
|
return COGL_PIPELINE_FILTER_LINEAR;
|
|
|
|
|
Rename 'bilinear' scaling filter to 'trilinear'
Yes, it's not really the proper GL name for a linear-on-every-axis of a
texture plus linear-between-mipmap-levels minification filter, but it
has three redeeming qualities as a name:
- LINEAR_MIPMAP_LINEAR sucks, as it introduces GL concepts like
mipmaps in the API naming, while we're trying to avoid that;
- people using GL already know what 'trilinear' means in this context
without going all Khronos on their asses;
- we're using 2D textures anyway, so 'linear on two axes and linear
between mipmap levels' can be effectively approximated to
'trilinear'.
I mean, if even the OpenGL official wiki says:
Unfortunately, what most people think of as "trilinear" is not linear
filtering of a 3D texture, but what in OpenGL terms is GL_LINEAR mag
filter and GL_LINEAR_MIPMAP_LINEAR in the min filter in a 2D texture.
That is, it is bilinear filtering of each appropriate mipmap level,
and doing a third linear filter between the adjacent mipmap levels.
Hence the term "trilinear".
-- http://www.opengl.org/wiki/Texture
then the horse has already been flogged to death, and I don't intend to
be accused of necrophilia and sadism by flogging it some more.
Prior art: every single GL tutorial in the history of ever;
CoreAnimation's scaling filter enumerations.
If people want to start using 1D or 3D textures they they are probably
going to be using Cogl API directly, and that has the GL naming scheme
for minification and magnification filters anyway.
2012-03-16 12:05:11 +00:00
|
|
|
case CLUTTER_SCALING_FILTER_TRILINEAR:
|
2012-03-08 17:19:12 +00:00
|
|
|
return COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return COGL_PIPELINE_FILTER_LINEAR;
|
|
|
|
}
|
|
|
|
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
/**
|
|
|
|
* clutter_texture_node_new:
|
2012-03-08 17:19:12 +00:00
|
|
|
* @texture: a #CoglTexture
|
|
|
|
* @color: a #ClutterColor
|
|
|
|
* @min_filter: the minification filter for the texture
|
|
|
|
* @mag_filter: the magnification filter for the texture
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
*
|
|
|
|
* Creates a new #ClutterPaintNode that will paint the passed @texture.
|
|
|
|
*
|
|
|
|
* This function will take a reference on @texture, so it is safe to
|
|
|
|
* call cogl_object_unref() on @texture when it returns.
|
|
|
|
*
|
|
|
|
* Return value: (transfer full): the newly created #ClutterPaintNode.
|
|
|
|
* Use clutter_paint_node_unref() when done
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
*/
|
|
|
|
ClutterPaintNode *
|
2012-03-08 17:19:12 +00:00
|
|
|
clutter_texture_node_new (CoglTexture *texture,
|
|
|
|
const ClutterColor *color,
|
|
|
|
ClutterScalingFilter min_filter,
|
|
|
|
ClutterScalingFilter mag_filter)
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
{
|
|
|
|
ClutterPipelineNode *tnode;
|
2012-03-08 17:19:12 +00:00
|
|
|
CoglColor cogl_color;
|
|
|
|
CoglPipelineFilter min_f, mag_f;
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
2012-03-08 17:19:12 +00:00
|
|
|
g_return_val_if_fail (cogl_is_texture (texture), NULL);
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
2012-03-16 11:57:34 +00:00
|
|
|
tnode = _clutter_paint_node_create (CLUTTER_TYPE_TEXTURE_NODE);
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
2012-03-08 17:19:12 +00:00
|
|
|
cogl_pipeline_set_layer_texture (tnode->pipeline, 0, texture);
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
2012-03-08 17:19:12 +00:00
|
|
|
min_f = clutter_scaling_filter_to_cogl_pipeline_filter (min_filter);
|
|
|
|
mag_f = clutter_scaling_filter_to_cogl_pipeline_filter (mag_filter);
|
|
|
|
cogl_pipeline_set_layer_filters (tnode->pipeline, 0, min_f, mag_f);
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
2012-03-08 17:19:12 +00:00
|
|
|
cogl_color_init_from_4ub (&cogl_color,
|
|
|
|
color->red,
|
|
|
|
color->green,
|
|
|
|
color->blue,
|
|
|
|
color->alpha);
|
|
|
|
cogl_color_premultiply (&cogl_color);
|
|
|
|
cogl_pipeline_set_color (tnode->pipeline, &cogl_color);
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
|
|
|
return (ClutterPaintNode *) tnode;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Text node
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct _ClutterTextNode
|
|
|
|
{
|
|
|
|
ClutterPaintNode parent_instance;
|
|
|
|
|
|
|
|
PangoLayout *layout;
|
|
|
|
CoglColor color;
|
|
|
|
};
|
|
|
|
|
2012-04-30 16:12:12 +00:00
|
|
|
/**
|
|
|
|
* ClutterTextNodeClass:
|
|
|
|
*
|
2012-04-30 16:45:01 +00:00
|
|
|
* The <structname>ClutterTextNodeClass</structname> structure is an opaque
|
2012-04-30 16:12:12 +00:00
|
|
|
* type whose contents cannot be directly accessed.
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
*/
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
struct _ClutterTextNodeClass
|
|
|
|
{
|
|
|
|
ClutterPaintNodeClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (ClutterTextNode, clutter_text_node, CLUTTER_TYPE_PAINT_NODE)
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_text_node_finalize (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
|
|
|
|
|
|
|
|
if (tnode->layout != NULL)
|
|
|
|
g_object_unref (tnode->layout);
|
|
|
|
|
|
|
|
CLUTTER_PAINT_NODE_CLASS (clutter_text_node_parent_class)->finalize (node);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
clutter_text_node_pre_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
|
|
|
|
|
|
|
|
return tnode->layout != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_text_node_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
|
2012-02-20 10:09:05 +00:00
|
|
|
PangoRectangle extents;
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
guint i;
|
|
|
|
|
|
|
|
if (node->operations == NULL)
|
|
|
|
return;
|
|
|
|
|
2012-02-20 10:09:05 +00:00
|
|
|
pango_layout_get_pixel_extents (tnode->layout, NULL, &extents);
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
|
|
|
for (i = 0; i < node->operations->len; i++)
|
|
|
|
{
|
|
|
|
const ClutterPaintOperation *op;
|
|
|
|
float op_width, op_height;
|
|
|
|
gboolean clipped = FALSE;
|
|
|
|
|
|
|
|
op = &g_array_index (node->operations, ClutterPaintOperation, i);
|
|
|
|
|
|
|
|
switch (op->opcode)
|
|
|
|
{
|
|
|
|
case PAINT_OP_TEX_RECT:
|
|
|
|
op_width = op->op.texrect[2] - op->op.texrect[0];
|
|
|
|
op_height = op->op.texrect[3] - op->op.texrect[1];
|
|
|
|
|
|
|
|
/* if the primitive size was smaller than the layout,
|
|
|
|
* we clip the layout when drawin, to avoid spilling
|
|
|
|
* it out
|
|
|
|
*/
|
2012-02-20 10:09:05 +00:00
|
|
|
if (extents.width > op_width ||
|
|
|
|
extents.height > op_height)
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
{
|
|
|
|
cogl_clip_push_rectangle (op->op.texrect[0],
|
|
|
|
op->op.texrect[1],
|
|
|
|
op->op.texrect[2],
|
|
|
|
op->op.texrect[3]);
|
|
|
|
clipped = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
cogl_pango_render_layout (tnode->layout,
|
|
|
|
op->op.texrect[0],
|
|
|
|
op->op.texrect[1],
|
|
|
|
&tnode->color,
|
|
|
|
0);
|
|
|
|
|
|
|
|
if (clipped)
|
|
|
|
cogl_clip_pop ();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PAINT_OP_PATH:
|
|
|
|
case PAINT_OP_PRIMITIVE:
|
|
|
|
case PAINT_OP_INVALID:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-03 13:51:29 +00:00
|
|
|
static JsonNode *
|
|
|
|
clutter_text_node_serialize (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterTextNode *tnode = CLUTTER_TEXT_NODE (node);
|
|
|
|
JsonBuilder *builder;
|
|
|
|
JsonNode *res;
|
|
|
|
|
|
|
|
builder = json_builder_new ();
|
|
|
|
|
|
|
|
json_builder_begin_object (builder);
|
|
|
|
|
|
|
|
json_builder_set_member_name (builder, "layout");
|
|
|
|
|
|
|
|
if (pango_layout_get_character_count (tnode->layout) > 12)
|
|
|
|
{
|
|
|
|
const char *text = pango_layout_get_text (tnode->layout);
|
|
|
|
char *str;
|
|
|
|
|
|
|
|
str = g_strndup (text, 12);
|
|
|
|
json_builder_add_string_value (builder, str);
|
|
|
|
g_free (str);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
json_builder_add_string_value (builder, pango_layout_get_text (tnode->layout));
|
|
|
|
|
|
|
|
json_builder_set_member_name (builder, "color");
|
|
|
|
json_builder_begin_array (builder);
|
|
|
|
json_builder_add_double_value (builder, cogl_color_get_red (&tnode->color));
|
|
|
|
json_builder_add_double_value (builder, cogl_color_get_green (&tnode->color));
|
|
|
|
json_builder_add_double_value (builder, cogl_color_get_blue (&tnode->color));
|
|
|
|
json_builder_add_double_value (builder, cogl_color_get_alpha (&tnode->color));
|
|
|
|
json_builder_end_array (builder);
|
|
|
|
|
|
|
|
json_builder_end_object (builder);
|
|
|
|
|
|
|
|
res = json_builder_get_root (builder);
|
|
|
|
g_object_unref (builder);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
static void
|
|
|
|
clutter_text_node_class_init (ClutterTextNodeClass *klass)
|
|
|
|
{
|
|
|
|
ClutterPaintNodeClass *node_class = CLUTTER_PAINT_NODE_CLASS (klass);
|
|
|
|
|
|
|
|
node_class->pre_draw = clutter_text_node_pre_draw;
|
|
|
|
node_class->draw = clutter_text_node_draw;
|
|
|
|
node_class->finalize = clutter_text_node_finalize;
|
2012-02-03 13:51:29 +00:00
|
|
|
node_class->serialize = clutter_text_node_serialize;
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_text_node_init (ClutterTextNode *self)
|
|
|
|
{
|
|
|
|
cogl_color_init_from_4f (&self->color, 0.0, 0.0, 0.0, 1.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_text_node_new:
|
|
|
|
* @layout: (allow-none): a #PangoLayout, or %NULL
|
|
|
|
* @color: (allow-none): the color used to paint the layout,
|
|
|
|
* or %NULL
|
|
|
|
*
|
|
|
|
* Creates a new #ClutterPaintNode that will paint a #PangoLayout
|
|
|
|
* with the given color.
|
|
|
|
*
|
|
|
|
* This function takes a reference on the passed @layout, so it
|
|
|
|
* is safe to call g_object_unref() after it returns.
|
|
|
|
*
|
|
|
|
* Return value: (transfer full): the newly created #ClutterPaintNode.
|
|
|
|
* Use clutter_paint_node_unref() when done
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
*/
|
|
|
|
ClutterPaintNode *
|
|
|
|
clutter_text_node_new (PangoLayout *layout,
|
|
|
|
const ClutterColor *color)
|
|
|
|
{
|
|
|
|
ClutterTextNode *res;
|
|
|
|
|
|
|
|
g_return_val_if_fail (layout == NULL || PANGO_IS_LAYOUT (layout), NULL);
|
|
|
|
|
2012-03-16 11:57:34 +00:00
|
|
|
res = _clutter_paint_node_create (CLUTTER_TYPE_TEXT_NODE);
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
|
|
|
if (layout != NULL)
|
|
|
|
res->layout = g_object_ref (layout);
|
|
|
|
|
|
|
|
if (color != NULL)
|
|
|
|
{
|
|
|
|
cogl_color_init_from_4ub (&res->color,
|
|
|
|
color->red,
|
|
|
|
color->green,
|
|
|
|
color->blue,
|
|
|
|
color->alpha);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (ClutterPaintNode *) res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Clip node
|
|
|
|
*/
|
|
|
|
struct _ClutterClipNode
|
|
|
|
{
|
|
|
|
ClutterPaintNode parent_instance;
|
|
|
|
};
|
|
|
|
|
2012-04-30 16:12:12 +00:00
|
|
|
/**
|
|
|
|
* ClutterClipNodeClass:
|
|
|
|
*
|
|
|
|
* The <structname>ClutterClipNodeClass</structname> structure is an opaque
|
|
|
|
* type whose members cannot be directly accessed.
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
*/
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
struct _ClutterClipNodeClass
|
|
|
|
{
|
|
|
|
ClutterPaintNodeClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (ClutterClipNode, clutter_clip_node, CLUTTER_TYPE_PAINT_NODE)
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
clutter_clip_node_pre_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
gboolean retval = FALSE;
|
|
|
|
CoglFramebuffer *fb;
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
if (node->operations == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
fb = cogl_get_draw_framebuffer ();
|
|
|
|
|
|
|
|
for (i = 0; i < node->operations->len; i++)
|
|
|
|
{
|
|
|
|
const ClutterPaintOperation *op;
|
|
|
|
|
|
|
|
op = &g_array_index (node->operations, ClutterPaintOperation, i);
|
|
|
|
|
|
|
|
switch (op->opcode)
|
|
|
|
{
|
|
|
|
case PAINT_OP_TEX_RECT:
|
|
|
|
cogl_framebuffer_push_rectangle_clip (fb,
|
|
|
|
op->op.texrect[0],
|
|
|
|
op->op.texrect[1],
|
|
|
|
op->op.texrect[2],
|
|
|
|
op->op.texrect[3]);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PAINT_OP_PATH:
|
|
|
|
cogl_framebuffer_push_path_clip (fb, op->op.path);
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PAINT_OP_PRIMITIVE:
|
|
|
|
case PAINT_OP_INVALID:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_clip_node_post_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
CoglFramebuffer *fb;
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
if (node->operations == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
fb = cogl_get_draw_framebuffer ();
|
|
|
|
|
|
|
|
for (i = 0; i < node->operations->len; i++)
|
|
|
|
{
|
|
|
|
const ClutterPaintOperation *op;
|
|
|
|
|
|
|
|
op = &g_array_index (node->operations, ClutterPaintOperation, i);
|
|
|
|
|
|
|
|
switch (op->opcode)
|
|
|
|
{
|
|
|
|
case PAINT_OP_PATH:
|
|
|
|
case PAINT_OP_TEX_RECT:
|
|
|
|
cogl_framebuffer_pop_clip (fb);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PAINT_OP_PRIMITIVE:
|
|
|
|
case PAINT_OP_INVALID:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_clip_node_class_init (ClutterClipNodeClass *klass)
|
|
|
|
{
|
|
|
|
ClutterPaintNodeClass *node_class;
|
|
|
|
|
|
|
|
node_class = CLUTTER_PAINT_NODE_CLASS (klass);
|
|
|
|
node_class->pre_draw = clutter_clip_node_pre_draw;
|
|
|
|
node_class->post_draw = clutter_clip_node_post_draw;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_clip_node_init (ClutterClipNode *self)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* clutter_clip_node_new:
|
|
|
|
*
|
|
|
|
* Creates a new #ClutterPaintNode that will clip its child
|
|
|
|
* nodes to the 2D regions added to it.
|
|
|
|
*
|
|
|
|
* Return value: (transfer full): the newly created #ClutterPaintNode.
|
|
|
|
* Use clutter_paint_node_unref() when done.
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
*/
|
|
|
|
ClutterPaintNode *
|
|
|
|
clutter_clip_node_new (void)
|
|
|
|
{
|
2012-03-16 11:57:34 +00:00
|
|
|
return _clutter_paint_node_create (CLUTTER_TYPE_CLIP_NODE);
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-03-16 11:57:34 +00:00
|
|
|
* ClutterLayerNode (private)
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
*/
|
|
|
|
|
2012-03-16 11:57:34 +00:00
|
|
|
#define clutter_layer_node_get_type _clutter_layer_node_get_type
|
|
|
|
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
struct _ClutterLayerNode
|
|
|
|
{
|
|
|
|
ClutterPaintNode parent_instance;
|
|
|
|
|
|
|
|
cairo_rectangle_t viewport;
|
|
|
|
|
|
|
|
CoglMatrix projection;
|
|
|
|
|
|
|
|
float fbo_width;
|
|
|
|
float fbo_height;
|
|
|
|
|
|
|
|
CoglPipeline *state;
|
|
|
|
CoglFramebuffer *offscreen;
|
|
|
|
CoglTexture *texture;
|
|
|
|
|
|
|
|
guint8 opacity;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _ClutterLayerNodeClass
|
|
|
|
{
|
|
|
|
ClutterPaintNodeClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (ClutterLayerNode, clutter_layer_node, CLUTTER_TYPE_PAINT_NODE)
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
clutter_layer_node_pre_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterLayerNode *lnode = (ClutterLayerNode *) node;
|
|
|
|
CoglMatrix matrix;
|
|
|
|
|
|
|
|
/* if we were unable to create an offscreen buffer for this node, then
|
|
|
|
* we simply ignore it
|
|
|
|
*/
|
|
|
|
if (lnode->offscreen == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* if no geometry was submitted for this node then we simply ignore it */
|
|
|
|
if (node->operations == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* copy the same modelview from the current framebuffer to the one we
|
|
|
|
* are going to use
|
|
|
|
*/
|
|
|
|
cogl_get_modelview_matrix (&matrix);
|
|
|
|
|
|
|
|
cogl_push_framebuffer (lnode->offscreen);
|
|
|
|
|
|
|
|
cogl_framebuffer_set_modelview_matrix (lnode->offscreen, &matrix);
|
|
|
|
|
|
|
|
cogl_framebuffer_set_viewport (lnode->offscreen,
|
|
|
|
lnode->viewport.x,
|
|
|
|
lnode->viewport.y,
|
|
|
|
lnode->viewport.width,
|
|
|
|
lnode->viewport.height);
|
|
|
|
|
|
|
|
cogl_framebuffer_set_projection_matrix (lnode->offscreen,
|
|
|
|
&lnode->projection);
|
|
|
|
|
|
|
|
/* clear out the target framebuffer */
|
|
|
|
cogl_framebuffer_clear4f (lnode->offscreen,
|
|
|
|
COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH,
|
|
|
|
0.f, 0.f, 0.f, 0.f);
|
|
|
|
|
|
|
|
cogl_push_matrix ();
|
|
|
|
|
|
|
|
/* every draw operation after this point will happen an offscreen
|
|
|
|
* framebuffer
|
|
|
|
*/
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_layer_node_post_draw (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterLayerNode *lnode = CLUTTER_LAYER_NODE (node);
|
|
|
|
CoglFramebuffer *fb;
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
/* switch to the previous framebuffer */
|
|
|
|
cogl_pop_matrix ();
|
|
|
|
cogl_pop_framebuffer ();
|
|
|
|
|
|
|
|
fb = cogl_get_draw_framebuffer ();
|
|
|
|
|
|
|
|
for (i = 0; i < node->operations->len; i++)
|
|
|
|
{
|
|
|
|
const ClutterPaintOperation *op;
|
|
|
|
|
|
|
|
op = &g_array_index (node->operations, ClutterPaintOperation, i);
|
|
|
|
switch (op->opcode)
|
|
|
|
{
|
|
|
|
case PAINT_OP_INVALID:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PAINT_OP_TEX_RECT:
|
|
|
|
/* now we need to paint the texture */
|
|
|
|
cogl_push_source (lnode->state);
|
|
|
|
cogl_rectangle_with_texture_coords (op->op.texrect[0],
|
|
|
|
op->op.texrect[1],
|
|
|
|
op->op.texrect[2],
|
|
|
|
op->op.texrect[3],
|
|
|
|
op->op.texrect[4],
|
|
|
|
op->op.texrect[5],
|
|
|
|
op->op.texrect[6],
|
|
|
|
op->op.texrect[7]);
|
|
|
|
cogl_pop_source ();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PAINT_OP_PATH:
|
|
|
|
cogl_push_source (lnode->state);
|
|
|
|
cogl_path_fill (op->op.path);
|
|
|
|
cogl_pop_source ();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PAINT_OP_PRIMITIVE:
|
|
|
|
cogl_framebuffer_draw_primitive (fb, lnode->state, op->op.primitive);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_layer_node_finalize (ClutterPaintNode *node)
|
|
|
|
{
|
|
|
|
ClutterLayerNode *lnode = CLUTTER_LAYER_NODE (node);
|
|
|
|
|
|
|
|
if (lnode->state != NULL)
|
|
|
|
cogl_object_unref (lnode->state);
|
|
|
|
|
|
|
|
if (lnode->offscreen != NULL)
|
|
|
|
cogl_object_unref (lnode->offscreen);
|
|
|
|
|
|
|
|
CLUTTER_PAINT_NODE_CLASS (clutter_layer_node_parent_class)->finalize (node);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_layer_node_class_init (ClutterLayerNodeClass *klass)
|
|
|
|
{
|
|
|
|
ClutterPaintNodeClass *node_class;
|
|
|
|
|
|
|
|
node_class = CLUTTER_PAINT_NODE_CLASS (klass);
|
|
|
|
node_class->pre_draw = clutter_layer_node_pre_draw;
|
|
|
|
node_class->post_draw = clutter_layer_node_post_draw;
|
|
|
|
node_class->finalize = clutter_layer_node_finalize;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_layer_node_init (ClutterLayerNode *self)
|
|
|
|
{
|
|
|
|
cogl_matrix_init_identity (&self->projection);
|
|
|
|
}
|
|
|
|
|
2012-03-16 11:57:34 +00:00
|
|
|
/*
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
* clutter_layer_node_new:
|
|
|
|
* @projection: the projection matrix to use to set up the layer
|
|
|
|
* @viewport: (type cairo.Rectangle): the viewport to use to set up the layer
|
|
|
|
* @width: the width of the layer
|
|
|
|
* @height: the height of the layer
|
|
|
|
* @opacity: the opacity to be used when drawing the layer
|
|
|
|
*
|
|
|
|
* Creates a new #ClutterLayerNode.
|
|
|
|
*
|
|
|
|
* All children of this node will be painted inside a separate
|
|
|
|
* framebuffer; the framebuffer will then be painted using the
|
|
|
|
* given @opacity.
|
|
|
|
*
|
|
|
|
* Return value: (transfer full): the newly created #ClutterLayerNode.
|
|
|
|
* Use clutter_paint_node_unref() when done.
|
|
|
|
*
|
|
|
|
* Since: 1.10
|
|
|
|
*/
|
|
|
|
ClutterPaintNode *
|
2012-03-16 11:57:34 +00:00
|
|
|
_clutter_layer_node_new (const CoglMatrix *projection,
|
|
|
|
const cairo_rectangle_t *viewport,
|
|
|
|
float width,
|
|
|
|
float height,
|
|
|
|
guint8 opacity)
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
{
|
|
|
|
ClutterLayerNode *res;
|
|
|
|
CoglColor color;
|
|
|
|
|
2012-03-16 11:57:34 +00:00
|
|
|
res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE);
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
|
|
|
|
res->projection = *projection;
|
|
|
|
res->viewport = *viewport;
|
|
|
|
res->fbo_width = width;
|
|
|
|
res->fbo_height = height;
|
|
|
|
res->opacity = opacity;
|
|
|
|
|
|
|
|
/* the texture backing the FBO */
|
|
|
|
res->texture = cogl_texture_new_with_size (MAX (res->fbo_width, 1),
|
|
|
|
MAX (res->fbo_height, 1),
|
|
|
|
COGL_TEXTURE_NO_SLICING,
|
|
|
|
COGL_PIXEL_FORMAT_RGBA_8888_PRE);
|
|
|
|
|
2012-03-05 18:32:02 +00:00
|
|
|
res->offscreen = COGL_FRAMEBUFFER (cogl_offscreen_new_to_texture (res->texture));
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
if (res->offscreen == NULL)
|
|
|
|
{
|
|
|
|
g_critical ("%s: Unable to create an offscreen buffer", G_STRLOC);
|
|
|
|
|
|
|
|
cogl_object_unref (res->texture);
|
|
|
|
res->texture = NULL;
|
|
|
|
|
2012-03-16 11:57:34 +00:00
|
|
|
goto out;
|
Add PaintNode, an element on the render object tree
Now that we have a proper scene graph API, we should split out the
rendering part from the logical and event handling part.
ClutterPaintNode is a lightweight fundamental type that encodes only the
paint operations: pipeline state and geometry. At its most simple, is a
way to structure setting up the programmable pipeline using a
CoglPipeline, and submitting Cogl primitives. The important take away
from this API is that you are not allowed to call Cogl API like
cogl_set_source() or cogl_primitive_draw() directly.
The interesting approach to this is that, in the future, we should be
able to move to a purely retained mode: we will decide which actors need
to be painted, they will update their own branch of the render graph,
and we'll take the render graph and build all the rendering commands
from that.
For the 1.x API, we will have to maintain invariants and the existing
behaviour, but as soon as we can break API, the old paint signal will
just go away, and Actors will only be allowed to manipulate the render
tree.
2012-02-01 15:51:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
|
|
|
|
|
|
|
|
/* the pipeline used to paint the texture; we use nearest
|
|
|
|
* interpolation filters because the texture is always
|
|
|
|
* going to be painted at a 1:1 texel:pixel ratio
|
|
|
|
*/
|
|
|
|
res->state = cogl_pipeline_copy (default_texture_pipeline);
|
|
|
|
cogl_pipeline_set_layer_filters (res->state, 0,
|
|
|
|
COGL_PIPELINE_FILTER_NEAREST,
|
|
|
|
COGL_PIPELINE_FILTER_NEAREST);
|
|
|
|
cogl_pipeline_set_layer_texture (res->state, 0, res->texture);
|
|
|
|
cogl_pipeline_set_color (res->state, &color);
|
|
|
|
cogl_object_unref (res->texture);
|
|
|
|
|
|
|
|
out:
|
|
|
|
return (ClutterPaintNode *) res;
|
|
|
|
}
|