* clutter/clutter-actor.c (clutter_actor_get_transformed_sizeu):

This is now do-what-I-mean like clutter_actor_get_size so that if
	the allocation box is available it will use that, otherwise it
	will use the preferred size. clutter_actor_transform_vertices has
	been converted to clutter_actor_transform_and_project_box so that
	it can be used by both functions. Based on a patch by Emmanuele
	Bassi.
	(clutter_actor_get_abs_allocation_vertices)
	(clutter_actor_get_allocation_vertices): These two functions now
	force a relayout if the allocation box is not available.

	* tests/test-fbo.c: Fixed the shader to use texture2D instead of
	texture2DRect now that GL_EXT_texture_rectangle is no longer used.
This commit is contained in:
Neil Roberts 2008-07-01 21:52:19 +00:00
parent 9ed5d2577d
commit cfd91cd0ef
3 changed files with 160 additions and 81 deletions

View File

@ -1,3 +1,19 @@
2008-07-01 Neil Roberts <neil@o-hand.com>
* clutter/clutter-actor.c (clutter_actor_get_transformed_sizeu):
This is now do-what-I-mean like clutter_actor_get_size so that if
the allocation box is available it will use that, otherwise it
will use the preferred size. clutter_actor_transform_vertices has
been converted to clutter_actor_transform_and_project_box so that
it can be used by both functions. Based on a patch by Emmanuele
Bassi.
(clutter_actor_get_abs_allocation_vertices)
(clutter_actor_get_allocation_vertices): These two functions now
force a relayout if the allocation box is not available.
* tests/test-fbo.c: Fixed the shader to use texture2D instead of
texture2DRect now that GL_EXT_texture_rectangle is no longer used.
2008-07-01 Chris Lord <chris@openedhand.com> 2008-07-01 Chris Lord <chris@openedhand.com>
* clutter/clutter-stage.c: * clutter/clutter-stage.c:

View File

@ -1019,17 +1019,40 @@ clutter_actor_transform_vertices_relative (ClutterActor *self,
cogl_pop_matrix(); cogl_pop_matrix();
} }
/* Recursively tranform supplied vertices with the tranform for the current /* Recursively tranform supplied box with the tranform for the current
* actor and all its ancestors (like clutter_actor_transform_point() but * actor and all its ancestors (like clutter_actor_transform_point()
* for all the vertices in one go). * but for all the vertices in one go) and project it into screen
* coordinates
*/ */
static void static void
clutter_actor_transform_vertices (ClutterActor *self, clutter_actor_transform_and_project_box (ClutterActor *self,
ClutterVertex verts[4], const ClutterActorBox *box,
ClutterFixed w[4]) ClutterVertex verts[4])
{ {
ClutterActor *stage;
ClutterFixed mtx[16]; ClutterFixed mtx[16];
ClutterFixed mtx_p[16];
ClutterFixed _x, _y, _z, _w; ClutterFixed _x, _y, _z, _w;
ClutterFixed w[4];
ClutterFixed v[4];
/* We essentially have to dupe some code from clutter_redraw() here
* to make sure GL Matrices etc are initialised if we're called and we
* havn't yet rendered anything.
*
* Simply duping code for now in wait for Cogl cleanup that can hopefully
* address this in a nicer way.
*/
stage = clutter_actor_get_stage (self);
/* FIXME: if were not yet added to a stage, its probably unsafe to
* return default - idealy the func should fail.
*/
if (stage == NULL)
stage = clutter_stage_get_default ();
clutter_stage_ensure_current (CLUTTER_STAGE (stage));
_clutter_stage_maybe_setup_viewport (CLUTTER_STAGE (stage));
cogl_push_matrix(); cogl_push_matrix();
_clutter_actor_apply_modelview_transform_recursive (self, NULL); _clutter_actor_apply_modelview_transform_recursive (self, NULL);
@ -1048,7 +1071,7 @@ clutter_actor_transform_vertices (ClutterActor *self,
verts[0].z = _z; verts[0].z = _z;
w[0] = _w; w[0] = _w;
_x = self->priv->allocation.x2 - self->priv->allocation.x1; _x = box->x2 - box->x1;
_y = 0; _y = 0;
_z = 0; _z = 0;
_w = CFX_ONE; _w = CFX_ONE;
@ -1061,7 +1084,7 @@ clutter_actor_transform_vertices (ClutterActor *self,
w[1] = _w; w[1] = _w;
_x = 0; _x = 0;
_y = self->priv->allocation.y2 - self->priv->allocation.y1; _y = box->y2 - box->y1;
_z = 0; _z = 0;
_w = CFX_ONE; _w = CFX_ONE;
@ -1072,8 +1095,8 @@ clutter_actor_transform_vertices (ClutterActor *self,
verts[2].z = _z; verts[2].z = _z;
w[2] = _w; w[2] = _w;
_x = self->priv->allocation.x2 - self->priv->allocation.x1; _x = box->x2 - box->x1;
_y = self->priv->allocation.y2 - self->priv->allocation.y1; _y = box->y2 - box->y1;
_z = 0; _z = 0;
_w = CFX_ONE; _w = CFX_ONE;
@ -1085,6 +1108,49 @@ clutter_actor_transform_vertices (ClutterActor *self,
w[3] = _w; w[3] = _w;
cogl_pop_matrix(); cogl_pop_matrix();
cogl_get_projection_matrix (mtx_p);
cogl_get_viewport (v);
mtx_transform (mtx_p,
&verts[0].x,
&verts[0].y,
&verts[0].z,
&w[0]);
verts[0].x = MTX_GL_SCALE_X (verts[0].x, w[0], v[2], v[0]);
verts[0].y = MTX_GL_SCALE_Y (verts[0].y, w[0], v[3], v[1]);
verts[0].z = MTX_GL_SCALE_Z (verts[0].z, w[0], v[2], v[0]);
mtx_transform (mtx_p,
&verts[1].x,
&verts[1].y,
&verts[1].z,
&w[1]);
verts[1].x = MTX_GL_SCALE_X (verts[1].x, w[1], v[2], v[0]);
verts[1].y = MTX_GL_SCALE_Y (verts[1].y, w[1], v[3], v[1]);
verts[1].z = MTX_GL_SCALE_Z (verts[1].z, w[1], v[2], v[0]);
mtx_transform (mtx_p,
&verts[2].x,
&verts[2].y,
&verts[2].z,
&w[2]);
verts[2].x = MTX_GL_SCALE_X (verts[2].x, w[2], v[2], v[0]);
verts[2].y = MTX_GL_SCALE_Y (verts[2].y, w[2], v[3], v[1]);
verts[2].z = MTX_GL_SCALE_Z (verts[2].z, w[2], v[2], v[0]);
mtx_transform (mtx_p,
&verts[3].x,
&verts[3].y,
&verts[3].z,
&w[3]);
verts[3].x = MTX_GL_SCALE_X (verts[3].x, w[3], v[2], v[0]);
verts[3].y = MTX_GL_SCALE_Y (verts[3].y, w[3], v[3], v[1]);
verts[3].z = MTX_GL_SCALE_Z (verts[3].z, w[3], v[2], v[0]);
} }
/** /**
@ -1145,6 +1211,13 @@ clutter_actor_get_allocation_vertices (ClutterActor *self,
clutter_stage_ensure_current (CLUTTER_STAGE (stage)); clutter_stage_ensure_current (CLUTTER_STAGE (stage));
_clutter_stage_maybe_setup_viewport (CLUTTER_STAGE (stage)); _clutter_stage_maybe_setup_viewport (CLUTTER_STAGE (stage));
/* if the actor needs to be allocated we force a relayout, so that
* clutter_actor_transform_vertices_relative() will have valid values
* to use in the transformations
*/
if (priv->needs_allocation)
_clutter_stage_maybe_relayout (stage);
clutter_actor_transform_vertices_relative (self, ancestor, verts, w); clutter_actor_transform_vertices_relative (self, ancestor, verts, w);
cogl_get_viewport (v); cogl_get_viewport (v);
@ -1191,9 +1264,6 @@ void
clutter_actor_get_abs_allocation_vertices (ClutterActor *self, clutter_actor_get_abs_allocation_vertices (ClutterActor *self,
ClutterVertex verts[4]) ClutterVertex verts[4])
{ {
ClutterFixed mtx_p[16];
ClutterFixed v[4];
ClutterFixed w[4];
ClutterActorPrivate *priv; ClutterActorPrivate *priv;
ClutterActor *stage; ClutterActor *stage;
@ -1201,67 +1271,16 @@ clutter_actor_get_abs_allocation_vertices (ClutterActor *self,
priv = self->priv; priv = self->priv;
/* We essentially have to dupe some code from clutter_redraw() here /* if the actor needs to be allocated we force a relayout, so that
* to make sure GL Matrices etc are initialised if we're called and we * the actor allocation box will be valid for
* havn't yet rendered anything. * clutter_actor_transform_and_project_box()
* */
* Simply duping code for now in wait for Cogl cleanup that can hopefully if (priv->needs_allocation)
* address this in a nicer way. _clutter_stage_maybe_relayout (stage);
*/
stage = clutter_actor_get_stage (self);
/* FIXME: if were not yet added to a stage, its probably unsafe to clutter_actor_transform_and_project_box (self,
* return default - idealy the func should fail. &self->priv->allocation,
*/ verts);
if (stage == NULL)
stage = clutter_stage_get_default ();
clutter_stage_ensure_current (CLUTTER_STAGE (stage));
_clutter_stage_maybe_setup_viewport (CLUTTER_STAGE (stage));
clutter_actor_transform_vertices (self, verts, w);
cogl_get_projection_matrix (mtx_p);
cogl_get_viewport (v);
mtx_transform (mtx_p,
&verts[0].x,
&verts[0].y,
&verts[0].z,
&w[0]);
verts[0].x = MTX_GL_SCALE_X (verts[0].x, w[0], v[2], v[0]);
verts[0].y = MTX_GL_SCALE_Y (verts[0].y, w[0], v[3], v[1]);
verts[0].z = MTX_GL_SCALE_Z (verts[0].z, w[0], v[2], v[0]);
mtx_transform (mtx_p,
&verts[1].x,
&verts[1].y,
&verts[1].z,
&w[1]);
verts[1].x = MTX_GL_SCALE_X (verts[1].x, w[1], v[2], v[0]);
verts[1].y = MTX_GL_SCALE_Y (verts[1].y, w[1], v[3], v[1]);
verts[1].z = MTX_GL_SCALE_Z (verts[1].z, w[1], v[2], v[0]);
mtx_transform (mtx_p,
&verts[2].x,
&verts[2].y,
&verts[2].z,
&w[2]);
verts[2].x = MTX_GL_SCALE_X (verts[2].x, w[2], v[2], v[0]);
verts[2].y = MTX_GL_SCALE_Y (verts[2].y, w[2], v[3], v[1]);
verts[2].z = MTX_GL_SCALE_Z (verts[2].z, w[2], v[2], v[0]);
mtx_transform (mtx_p,
&verts[3].x,
&verts[3].y,
&verts[3].z,
&w[3]);
verts[3].x = MTX_GL_SCALE_X (verts[3].x, w[3], v[2], v[0]);
verts[3].y = MTX_GL_SCALE_Y (verts[3].y, w[3], v[3], v[1]);
verts[3].z = MTX_GL_SCALE_Z (verts[3].z, w[3], v[2], v[0]);
} }
/* Applies the transforms associated with this actor to the /* Applies the transforms associated with this actor to the
@ -4138,6 +4157,13 @@ clutter_actor_get_transformed_position (ClutterActor *self,
* Gets the absolute size of an actor in #ClutterUnits<!-- -->s, taking * Gets the absolute size of an actor in #ClutterUnits<!-- -->s, taking
* into account the scaling factors. * into account the scaling factors.
* *
* If the actor has a valid allocation, the allocated size will be used.
* If the actor has not a valid allocation then the preferred size will
* be transformed and returned.
*
* If you want the transformed allocation, see
* clutter_actor_get_abs_allocation_vertices() instead.
*
* <note>When the actor (or one of its ancestors) is rotated around the * <note>When the actor (or one of its ancestors) is rotated around the
* X or Y axis, it no longer appears as on the stage as a rectangle, but * X or Y axis, it no longer appears as on the stage as a rectangle, but
* as a generic quadrangle; in that case this function returns the size * as a generic quadrangle; in that case this function returns the size
@ -4155,11 +4181,38 @@ clutter_actor_get_transformed_sizeu (ClutterActor *self,
ClutterUnit *width, ClutterUnit *width,
ClutterUnit *height) ClutterUnit *height)
{ {
ClutterActorPrivate *priv;
ClutterVertex v[4]; ClutterVertex v[4];
ClutterFixed x_min, x_max, y_min, y_max; ClutterFixed x_min, x_max, y_min, y_max;
gint i; gint i;
clutter_actor_get_abs_allocation_vertices (self, v); g_return_if_fail (CLUTTER_IS_ACTOR (self));
priv = self->priv;
/* if the actor hasn't been allocated yet, get the preferred
* size and transform that
*/
if (priv->needs_allocation)
{
ClutterUnit natural_width, natural_height;
ClutterActorBox box;
/* make a fake allocation to transform */
clutter_actor_get_positionu (self, &box.x1, &box.y1);
natural_width = natural_height = 0;
clutter_actor_get_preferred_size (self, NULL, NULL,
&natural_width,
&natural_height);
box.x2 = box.x1 + natural_width;
box.y2 = box.y1 + natural_height;
clutter_actor_transform_and_project_box (self, &box, v);
}
else
clutter_actor_get_abs_allocation_vertices (self, v);
x_min = x_max = v[0].x; x_min = x_max = v[0].x;
y_min = y_max = v[0].y; y_min = y_max = v[0].y;

View File

@ -39,18 +39,23 @@ make_shader(void)
clutter_shader_set_fragment_source (shader, clutter_shader_set_fragment_source (shader,
"uniform float radius ;" "uniform float radius ;"
"uniform sampler2DRect rectTexture;" "uniform sampler2D rectTexture;"
"uniform float x_step, y_step;"
"" ""
"void main()" "void main()"
"{" "{"
" vec4 color = texture2DRect(rectTexture, gl_TexCoord[0].st);" " vec4 color = texture2D(rectTexture, gl_TexCoord[0].st);"
" float u;" " float u;"
" float v;" " float v;"
" int count = 1;" " int count = 1;"
" for (u=-radius;u<radius;u++)" " for (u=-radius;u<radius;u++)"
" for (v=-radius;v<radius;v++)" " for (v=-radius;v<radius;v++)"
" {" " {"
" color += texture2DRect(rectTexture, vec2(gl_TexCoord[0].s + u * 2.0, gl_TexCoord[0].t +v * 2.0));" " color += texture2D(rectTexture, "
" vec2(gl_TexCoord[0].s + u"
" * 2.0 * x_step,"
" gl_TexCoord[0].t + v"
" * 2.0 * y_step));"
" count ++;" " count ++;"
" }" " }"
"" ""
@ -76,6 +81,7 @@ main (gint argc,
ClutterActor *clone; ClutterActor *clone;
ClutterShader *shader; ClutterShader *shader;
gint padx, pady; gint padx, pady;
gint fbo_width, fbo_height;
clutter_init (&argc, &argv); clutter_init (&argc, &argv);
@ -91,11 +97,12 @@ main (gint argc,
clutter_group_add (stage, onscreen_source); clutter_group_add (stage, onscreen_source);
/* Basic sizing for alignment */ /* Basic sizing for alignment */
padx = clutter_actor_get_width (onscreen_source) + 10; fbo_width = clutter_actor_get_width (onscreen_source);
pady = clutter_actor_get_height (onscreen_source) + 10; fbo_height = clutter_actor_get_height (onscreen_source);
padx = fbo_width + 10;
pady = fbo_height + 10;
clutter_actor_set_size (stage, padx*4, pady*2); clutter_actor_set_size (stage, padx*4, pady*2);
/* Second hand from fbo onscreen */ /* Second hand from fbo onscreen */
if ((fbo = clutter_texture_new_from_actor (onscreen_source)) == NULL) if ((fbo = clutter_texture_new_from_actor (onscreen_source)) == NULL)
g_error("onscreen fbo creation failed"); g_error("onscreen fbo creation failed");
@ -107,7 +114,10 @@ main (gint argc,
shader = make_shader(); shader = make_shader();
clutter_actor_set_shader (fbo, shader); clutter_actor_set_shader (fbo, shader);
clutter_actor_set_shader_param (fbo, "radius", 2.0); clutter_actor_set_shader_param (fbo, "radius", 2.0);
clutter_actor_set_shader_param (fbo, "x_step",
1.0f / clutter_util_next_p2 (fbo_width));
clutter_actor_set_shader_param (fbo, "y_step",
1.0f / clutter_util_next_p2 (fbo_height));
/* Third from cloning the fbo texture */ /* Third from cloning the fbo texture */
clone = clutter_clone_texture_new (CLUTTER_TEXTURE(fbo)); clone = clutter_clone_texture_new (CLUTTER_TEXTURE(fbo));