2008-02-03 Matthew Allum <mallum@openedhand.com>

* clutter/clutter-shader.c:
        Minor formatting cleanups to fit in 80 cols.

        * clutter/clutter-texture.c:
        More safety checks, clean ups in clutter_texture_new_from_actor()

        * clutter/cogl/gl/cogl.c:
        Always clear the FBO initially when rendering

        * tests/test-fbo.c:
        Overhall the test as to be more useful (and show current issues)
This commit is contained in:
Matthew Allum 2008-02-03 01:53:10 +00:00
parent f6602ad265
commit 9026b8f976
5 changed files with 226 additions and 110 deletions

View File

@ -1,3 +1,17 @@
2008-02-03 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-shader.c:
Minor formatting cleanups to fit in 80 cols.
* clutter/clutter-texture.c:
More safety checks, clean ups in clutter_texture_new_from_actor()
* clutter/cogl/gl/cogl.c:
Always clear the FBO initially when rendering
* tests/test-fbo.c:
Overhall the test as to be more useful (and show current issues)
2008-02-02 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-timeline.c:

View File

@ -93,8 +93,6 @@ enum
PROP_ENABLED
};
G_DEFINE_TYPE (ClutterShader, clutter_shader, G_TYPE_OBJECT);
G_CONST_RETURN gchar *clutter_shader_get_source (ClutterShader *shader,
@ -130,10 +128,12 @@ clutter_shader_set_property (GObject *object,
switch (prop_id)
{
case PROP_VERTEX_SOURCE:
clutter_shader_set_vertex_source (shader, g_value_get_string (value), -1);
clutter_shader_set_vertex_source (shader,
g_value_get_string (value), -1);
break;
case PROP_FRAGMENT_SOURCE:
clutter_shader_set_fragment_source (shader, g_value_get_string (value), -1);
clutter_shader_set_fragment_source (shader,
g_value_get_string (value), -1);
break;
case PROP_ENABLED:
clutter_shader_set_is_enabled (shader, g_value_get_boolean (value));
@ -183,7 +183,10 @@ clutter_shader_constructor (GType type,
{
GObject *object;
object = G_OBJECT_CLASS (clutter_shader_parent_class)->constructor (type, n_params, params);
object
= G_OBJECT_CLASS (clutter_shader_parent_class)->constructor (type,
n_params,
params);
/* add this instance to the global list of shaders */
clutter_shaders_list = g_list_prepend (clutter_shaders_list, object);
@ -211,13 +214,14 @@ clutter_shader_class_init (ClutterShaderClass *klass)
*
* Since: 0.6
*/
g_object_class_install_property (object_class,
PROP_VERTEX_SOURCE,
g_param_spec_string ("vertex-source",
"Vertex Source",
"Source of vertex shader",
NULL,
CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(object_class,
PROP_VERTEX_SOURCE,
g_param_spec_string ("vertex-source",
"Vertex Source",
"Source of vertex shader",
NULL,
CLUTTER_PARAM_READWRITE));
/**
* ClutterShader:fragment-source:
*
@ -225,27 +229,30 @@ clutter_shader_class_init (ClutterShaderClass *klass)
*
* Since: 0.6
*/
g_object_class_install_property (object_class,
PROP_FRAGMENT_SOURCE,
g_param_spec_string ("fragment-source",
"Fragment Source",
"Source of fragment shader",
NULL,
CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(object_class,
PROP_FRAGMENT_SOURCE,
g_param_spec_string ("fragment-source",
"Fragment Source",
"Source of fragment shader",
NULL,
CLUTTER_PARAM_READWRITE));
/**
* ClutterShader:bound:
*
* Whether the shader is bound (compiled and linked, ready for use in the GL context).
* Whether the shader is bound (compiled and linked, ready for use
* in the GL context).
*
* Since: 0.6
*/
g_object_class_install_property (object_class,
PROP_BOUND,
g_param_spec_boolean ("bound",
"Bound",
"Whether the shader is bound",
FALSE,
CLUTTER_PARAM_READABLE));
g_object_class_install_property
(object_class,
PROP_BOUND,
g_param_spec_boolean ("bound",
"Bound",
"Whether the shader is bound",
FALSE,
CLUTTER_PARAM_READABLE));
/**
* ClutterShader:enabled:
*
@ -253,13 +260,14 @@ clutter_shader_class_init (ClutterShaderClass *klass)
*
* Since: 0.6
*/
g_object_class_install_property (object_class,
PROP_ENABLED,
g_param_spec_boolean ("enabled",
"Enabled",
"Whether the shader is enabled",
FALSE,
CLUTTER_PARAM_READWRITE));
g_object_class_install_property
(object_class,
PROP_ENABLED,
g_param_spec_boolean ("enabled",
"Enabled",
"Whether the shader is enabled",
FALSE,
CLUTTER_PARAM_READWRITE));
}
static void
@ -337,7 +345,8 @@ clutter_shader_set_fragment_source (ClutterShader *shader,
g_free (priv->fragment_source);
}
CLUTTER_NOTE (SHADER, "setting fragment shader (GLSL:%s, len:%" G_GSSIZE_FORMAT ")",
CLUTTER_NOTE (SHADER, "setting fragment shader (GLSL:%s, len:%"
G_GSSIZE_FORMAT ")",
is_glsl ? "yes" : "no",
length);
@ -345,7 +354,6 @@ clutter_shader_set_fragment_source (ClutterShader *shader,
priv->fragment_is_glsl = is_glsl;
}
/**
* clutter_shader_set_vertex_source:
* @shader: a #ClutterShader
@ -387,7 +395,8 @@ clutter_shader_set_vertex_source (ClutterShader *shader,
g_free (priv->vertex_source);
}
CLUTTER_NOTE (SHADER, "setting vertex shader (GLSL:%s, len:%" G_GSSIZE_FORMAT ")",
CLUTTER_NOTE (SHADER, "setting vertex shader (GLSL:%s, len:%"
G_GSSIZE_FORMAT ")",
is_glsl ? "yes" : "no",
length);
@ -548,7 +557,8 @@ clutter_shader_release (ClutterShader *shader)
* clutter_shader_is_bound:
* @shader: a #ClutterShader
*
* Checks whether @shader is is currently compiled, linked and bound to the GL context.
* Checks whether @shader is is currently compiled, linked and bound
* to the GL context.
*
* Return value: %TRUE if the shader is compiled, linked and ready for use.
*
@ -679,9 +689,9 @@ clutter_shader_release_all (void)
*
* Query the current GLSL fragment source set on @shader.
*
* Return value: the source of the fragment shader for this ClutterShader object
* or %NULL. The returned string is owned by the shader object and should never
* be modified or freed
* Return value: the source of the fragment shader for this
* ClutterShader object or %NULL. The returned string is owned by the
* shader object and should never be modified or freed
*
* Since: 0.6
*/
@ -698,9 +708,9 @@ clutter_shader_get_fragment_source (ClutterShader *shader)
*
* Query the current GLSL vertex source set on @shader.
*
* Return value: the source of the vertex shader for this ClutterShader object
* or %NULL. The returned string is owned by the shader object and should never
* be modified or freed
* Return value: the source of the vertex shader for this
* ClutterShader object or %NULL. The returned string is owned by the
* shader object and should never be modified or freed
*
* Since: 0.6
*/

View File

@ -2103,6 +2103,7 @@ clutter_texture_set_area_from_rgb_data (ClutterTexture *texture,
return TRUE;
}
/**
* clutter_texture_new_from_actor:
* @actor: A #ClutterActor
@ -2136,36 +2137,47 @@ clutter_texture_new_from_actor (ClutterActor *actor)
* - Have the source actor as a prop?
*/
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL);
if (clutter_feature_available (CLUTTER_FEATURE_TEXTURE_RECTANGLE) == FALSE)
return NULL;
if (clutter_feature_available (CLUTTER_FEATURE_OFFSCREEN) == FALSE)
return NULL;
if (!CLUTTER_ACTOR_IS_REALIZED (actor))
{
clutter_actor_realize (actor);
if (!CLUTTER_ACTOR_IS_REALIZED (actor))
return NULL;
}
/* FIXME abs size - usually fails with 0,0 */
clutter_actor_get_abs_size (actor, &w, &h);
// printf("abs size is %ix%i\n", w, h);
/* Wont work with any kind of transform on actor */
clutter_actor_get_size (actor, &w, &h);
if (w == 0 || h == 0)
return NULL;
if (!cogl_texture_can_size (CGL_TEXTURE_RECTANGLE_ARB,
CGL_RGBA, PIXEL_TYPE, w, h))
return NULL;
texture = g_object_new (CLUTTER_TYPE_TEXTURE, NULL);
priv = texture->priv;
priv->fbo_source = actor;
if (!CLUTTER_ACTOR_IS_REALIZED (priv->fbo_source))
clutter_actor_realize (priv->fbo_source);
/* FIXME: just ref ? */
clutter_actor_set_parent (actor, CLUTTER_ACTOR(texture));
/* FIXME abs size */
/*clutter_actor_get_abs_size (priv->fbo_source, &w, &h);*/
clutter_actor_get_size (actor, &w, &h);
/* FIXME: Check we can actually create a texture this large */
priv->width = w;
priv->height = h;
priv->fbo_source = g_object_ref(actor);
priv->width = w;
priv->height = h;
priv->target_type = CGL_TEXTURE_RECTANGLE_ARB;
priv->pixel_format = CGL_RGBA;
priv->pixel_type = PIXEL_TYPE;
priv->pixel_type = PIXEL_TYPE;
priv->is_tiled = 0;
priv->tiles = g_new (COGLuint, 1);
@ -2185,7 +2197,7 @@ clutter_texture_new_from_actor (ClutterActor *actor)
priv->fbo_handle = cogl_offscreen_create (priv->tiles[0]);
clutter_actor_set_size (texture, w, h);
clutter_actor_set_size (CLUTTER_ACTOR(texture), w, h);
return CLUTTER_ACTOR(texture);
}

View File

@ -909,6 +909,11 @@ cogl_offscreen_redirect_start (COGLuint offscreen_handle,
glTranslatef (-1.0f, -1.0f, 0.0f);
glScalef (2.0f / (float)width, 2.0f / (float)height, 1.0f);
/* Clear the scene, appears needed on some backends - OSX */
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
#endif
}

View File

@ -6,60 +6,36 @@
#include <stdlib.h>
#include <glib.h>
gint
main (gint argc,
gchar *argv[])
ClutterActor*
make_source(void)
{
ClutterColor color={0x33, 0x44, 0x55, 0xff};
ClutterActor *fbo;
ClutterActor *actor;
ClutterActor *actor2;
ClutterActor *group;
ClutterShader *shader;
ClutterActor *stage;
ClutterActor *rectangle;
ClutterActor *clone;
ClutterActor *source, *actor;
GdkPixbuf *pixbuf;
GError *error = NULL;
clutter_init (&argc, &argv);
stage = clutter_stage_get_default ();
clutter_stage_set_color (CLUTTER_STAGE (stage), &color);
ClutterColor yellow = {0xff, 0xff, 0x00, 0xff};
pixbuf = gdk_pixbuf_new_from_file ("redhand.png", &error);
if (!pixbuf)
g_error("pixbuf load failed: %s", error ? error->message : "Unknown");
/* actor = clutter_texture_new_from_pixbuf (pixbuf);*/
source = clutter_group_new();
actor = clutter_texture_new_from_pixbuf (pixbuf);
clutter_group_add (source, actor);
group = clutter_group_new ();
{
ClutterColor nothing = {0, 0,0,0};
rectangle = clutter_rectangle_new_with_color (&nothing);
clutter_actor_set_size (rectangle, 800, 270);
}
actor2 = clutter_texture_new_from_pixbuf (pixbuf);
clutter_container_add_actor (CLUTTER_CONTAINER (group), actor2);
{
ClutterColor yellow = {0xff, 0xff, 0x00, 0xff};
actor = clutter_label_new_with_text ("Sans 50px", "Hello hadyness");
clutter_label_set_color (CLUTTER_LABEL (actor), &yellow);
}
actor = clutter_label_new_with_text ("Sans Bold 50px", "Clutter");
clutter_container_add_actor (CLUTTER_CONTAINER (group), actor);
clutter_container_add_actor (CLUTTER_CONTAINER (group), rectangle);
clutter_actor_set_position (actor, 0, 15);
clutter_label_set_color (CLUTTER_LABEL (actor), &yellow);
clutter_actor_set_y (actor, clutter_actor_get_height(source) + 5);
clutter_group_add (source, actor);
clutter_actor_show_all (group);
return source;
}
fbo = clutter_texture_new_from_actor (group);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), fbo);
clutter_actor_set_position (fbo, 20, 120);
clutter_actor_set_position (actor2, 130, 20);
ClutterShader*
make_shader(void)
{
ClutterShader *shader;
shader = clutter_shader_new ();
clutter_shader_set_fragment_source (shader,
@ -86,14 +62,113 @@ main (gint argc,
-1
);
clone = clutter_clone_texture_new (fbo);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), clone);
clutter_actor_set_position (clone, 40, 300);
return shader;
}
gint
main (gint argc,
gchar *argv[])
{
ClutterColor blue = {0x33, 0x44, 0x55, 0xff};
ClutterActor *fbo;
ClutterActor *onscreen_source, *offscreen_source, *trans_source;
ClutterActor *foo_source;
ClutterActor *stage;
ClutterActor *clone;
ClutterShader *shader;
gint padx, pady;
clutter_init (&argc, &argv);
if (clutter_feature_available (CLUTTER_FEATURE_OFFSCREEN) == FALSE)
g_error("This test requires CLUTTER_FEATURE_OFFSCREEN");
stage = clutter_stage_get_default ();
clutter_stage_set_color (CLUTTER_STAGE (stage), &blue);
/* Create the first source */
onscreen_source = make_source();
clutter_actor_show_all (onscreen_source);
clutter_group_add (stage, onscreen_source);
/* Basic sizing for alignment */
padx = clutter_actor_get_width (onscreen_source) + 10;
pady = clutter_actor_get_height (onscreen_source) + 10;
clutter_actor_set_size (stage, padx*4, pady*2);
/* Second hand from fbo onscreen */
if ((fbo = clutter_texture_new_from_actor (onscreen_source)) == NULL)
g_error("onscreen fbo creation failed");
clutter_actor_set_position (fbo, padx, 0);
clutter_group_add (stage, fbo);
/* apply a shader to it */
shader = make_shader();
clutter_actor_apply_shader (fbo, shader);
clutter_actor_set_shader_param (fbo, "radius", 2.0);
/* Third from cloning the fbo texture */
clone = clutter_clone_texture_new (CLUTTER_TEXTURE(fbo));
clutter_container_add_actor (CLUTTER_CONTAINER (stage), clone);
clutter_actor_set_position (clone, padx*2, 0);
/* Forth - an offscreen source */
offscreen_source = make_source();
clutter_actor_show_all (offscreen_source); /* need to show() offscreen */
if ((fbo = clutter_texture_new_from_actor (offscreen_source)) == NULL)
g_error("offscreen fbo creation failed");
clutter_actor_set_position (fbo, padx*3, 0);
clutter_group_add (stage, fbo);
/* 5th transformed */
trans_source = make_source();
clutter_actor_show_all (trans_source); /* need to show() offscreen */
clutter_actor_set_scale (trans_source, 2.5, 2.5);
#if 0
/* Rotate about center by 90 degrees - FIXME: fbo seems to get nothing*/
clutter_actor_move_anchor_point_from_gravity (trans_source,
CLUTTER_GRAVITY_CENTER);
clutter_actor_set_rotation (trans_source, CLUTTER_Z_AXIS, 90.0, 0, 0, 0);
#endif
if ((fbo = clutter_texture_new_from_actor (trans_source)) == NULL)
g_error("transformed fbo creation failed");
clutter_actor_set_position (fbo, 0, pady);
clutter_group_add (stage, fbo);
/* 6th resized bigger, but after fbo creation */
trans_source = make_source();
clutter_actor_show_all (trans_source); /* need to show() offscreen */
if ((fbo = clutter_texture_new_from_actor (trans_source)) == NULL)
g_error("transformed fbo creation failed");
clutter_actor_set_width (trans_source, 2*padx);
clutter_actor_set_position (fbo, padx, pady);
clutter_group_add (stage, fbo);
/* non visual breaks */
foo_source = make_source();
clutter_actor_show_all (foo_source);
if ((fbo = clutter_texture_new_from_actor (foo_source)) == NULL)
g_error("foo fbo creation failed");
g_object_unref (foo_source); /* fbo should keep it around */
clutter_actor_set_position (fbo, padx*3, pady);
clutter_group_add (stage, fbo);
if(1)clutter_actor_apply_shader (clone, shader);
if(1)clutter_actor_set_shader_param (clone, "radius", 2.0);
clutter_actor_show_all (stage);
clutter_main ();