1
package Clutter::Ex::TextureReflection;
6
use Glib qw( :constants );
13
Clutter::Ex::TextureReflection - Reflection of a texture
17
use Clutter qw( :init );
18
use Clutter::Ex::TextureReflection;
20
my $texture = Clutter::Texture->new($filename);
22
my $reflection = Clutter::Ex::TextureReflection->new();
23
$reflection->set_parent_texture($texture);
27
This page describes the API of C<Clutter::Ex::TextureReflection>, a
28
subclass of L<Clutter::Texture> that efficiently paints a reflection
29
of the parent texture.
34
+----Glib::InitiallyUnowned
37
+----Clutter::Ex::TextureReflection
43
use Glib::Object::Subclass
50
'The height of the reflection, or -1',
52
[ qw( readable writable ) ],
54
Glib::ParamSpec->object(
57
'The texture to do the reflection for',
59
[ qw( readable writable ) ],
63
sub GET_PREFERRED_WIDTH {
64
my ($self, $for_height) = @_;
66
return (0, 0) unless defined $self->{parent_texture};
68
return $self->{parent_texture}->get_preferred_width($for_height);
71
sub GET_PREFERRED_HEIGHT {
72
my ($self, $for_width) = @_;
74
return (0, 0) unless defined $self->{parent_texture};
76
return $self->{parent_texture}->get_preferred_height($for_width);
82
my $parent = $self->get_parent_texture();
83
return unless $parent;
85
# get the handle from the parent texture
86
my $cogl_tex = $parent->get_cogl_texture();
87
return unless $cogl_tex;
89
my $box = $self->get_allocation_box();
91
my ($width, $height) = $box->get_size();
92
return unless $width > 0 and $height > 0;
94
my $r_height = $self->{reflection_height};
96
# clamp the reflection height if needed
97
$r_height = $height if $r_height < 0 or $r_height > $height;
99
my $rty = $r_height / $height;
101
my $opacity = $self->get_paint_opacity() / 255;
103
# the colors of the vertices
104
my $start = [ 1.0, 1.0, 1.0, $opacity ];
105
my $stop = [ 1.0, 1.0, 1.0, 0.0 ];
107
# we need to premultiply the alpha
108
$start = Clutter::Cogl::Color->premultiply($start);
109
$stop = Clutter::Cogl::Color->premultiply($stop);
111
# these are the reflection vertices. each vertex
112
# is an arrayref in the form:
115
# x, y, z: coordinates in the modelview
116
# tx, ty: texture coordinates
117
# color: color of the vertex
120
# to paint the reflection of the parent texture we paint
121
# the texture using four vertices in clockwise order, with
122
# the upper left and the upper right at full opacity and
123
# the lower right and lower left and 0 opacity; OpenGL will
124
# do the gradient for us
126
[ 0, 0, 0, 0.0, $rty, $start ],
127
[ $width, 0, 0, 1.0, $rty, $start ],
128
[ $width, $r_height, 0, 1.0, 0.0, $stop ],
129
[ 0, $r_height, 0, 0.0, 0.0, $stop ],
132
# paint the original texture again, at the new vertices
133
Clutter::Cogl->polygon($vertices, TRUE);
137
my ($self, $pspec, $value) = @_;
139
$self->set_reflection_height($value)
140
if ($pspec->get_name() eq 'reflection_height');
142
$self->set_parent_texture($value)
143
if ($pspec->get_name() eq 'parent_texture');
147
my ($self, $pspec) = @_;
149
return $self->get_reflection_height()
150
if ($pspec->get_name() eq 'reflection_height');
152
return $self->get_parent_texture()
153
if ($pspec->get_name() eq 'parent_texture');
159
$self->{reflection_height} = -1;
160
$self->{parent_texture} = undef;
169
=item B<< actor = Clutter::Ex::TextureReflection->new ($parent_texture) >>
171
* $parent_texture (Clutter::Texture) the parent texture
173
Creates a new Clutter::Ex::TextureReflection actor for the given
179
my ($class, $parent_texture) = @_;
181
return Glib::Object::new(
182
'Clutter::Ex::TextureReflection',
183
parent_texture => $parent_texture,
189
=item B<< $reflection->set_reflection_height ($height) >>
193
Sets the height of the reflection, in pixels. If I<height> is a negative
194
value, the height of the parent texture will be used instead.
198
sub set_reflection_height {
199
my ($self, $height) = @_;
201
$self->{reflection_height} = $height;
203
$self->queue_relayout();
205
$self->notify('reflection-height');
210
=item B<< height = $reflection->get_reflection_height >>
212
Retrieves the height of the reflection.
216
sub get_reflection_height {
219
return $self->{reflection_height};
224
=item B<< $reflection->set_parent_texture ($texturer) >>
226
* $texture (Clutter::Texture)
228
Sets the texture to be reflected.
232
sub set_parent_texture {
233
my ($self, $texture) = @_;
235
$self->{parent_texture} = $texture;
237
$self->queue_relayout();
239
$self->notify('parent-texture');
244
=item B<< texture = $reflection->get_parent_texture >>
246
Retrieves the parent texture.
250
sub get_parent_texture {
253
return $self->{parent_texture};
264
=item 'reflection-height' (integer : readable / writable)
266
Height of the reflection, in pixels, or -1 to use the same height
267
of the parent texture.
269
=item 'parent-texture' (Clutter::Texture : readable / writable)
271
The L<Clutter::Texture> to generate a reflection for.
277
L<Clutter>, L<Glib::Object>, L<Glib::InitiallyUnowned>, L<Clutter::Actor>,
278
L<Clutter::Texture>, L<Clutter::Cogl::Texture>
282
Copyright (C) 2008, 2009 Intel Corporation.
284
This module is free software; you can redistribute it and/or modify it
285
under the terms of the GNU Lesser General Public License version 2.1, or
286
under the terms of the Artistic License. See Clutter for the full copyright
293
use Glib qw( :constants );
294
use Clutter qw( :init );
296
my $filename = defined $ARGV[0] ? $ARGV[0] : 'redhand.png';
298
my $stage = Clutter::Stage->new();
299
$stage->set_size(640, 480);
300
$stage->set_color(Clutter::Color->from_string('Black'));
301
$stage->signal_connect(destroy => sub { Clutter->main_quit() });
302
$stage->set_title('TextureReflection');
304
my $group = Clutter::Group->new();
308
eval { $tex = Clutter::Texture->new($filename) };
310
warn ("Unable to load '$filename': $@");
314
my $reflect = Clutter::Ex::TextureReflection->new($tex);
315
$reflect->set_opacity(100);
317
$group->add($tex, $reflect);
319
$tex->set_position(0, 0);
320
$reflect->set_position(0, $tex->get_height() + 10);
322
my $x_pos = ($stage->get_width() - $tex->get_width()) / 2;
323
$group->set_position($x_pos, 20);
325
my $timeline = Clutter::Timeline->new(3000);
326
$timeline->set_loop(TRUE);
327
my $alpha = Clutter::Alpha->new($timeline, 'linear');
328
my $behaviour = Clutter::Behaviour::Rotate->new($alpha, 'y-axis', 'cw', 0, 360);
329
$behaviour->set_center($group->get_width() / 2, 0, 0);
330
$behaviour->apply($group);