On Mon, 2010-05-17 at 11:26 +0100, Neil Roberts wrote:
> On Sun, 16 May 2010 14:31:30 -0400, Sam Wilson <tecywiz...@hotmail.com> wrote:
> 
> > Hello knowledgeable clutter people,
> > 
> > I created an actor to handle drawing sprite based animations, and I am
> > wondering if it is the correct way to do it.
> 
> - There's no need to override the pick method if the actor has no
>   children and you are just drawing the color to fill the actor's
>   allocation. The default implementation in ClutterActor will do this
>   for you.


So noted!

> - You might want to make a separate material for each frame that is
>   private to the actor and use that to render the texture rather than
>   using Cogl.set_source_texture. This will help Cogl optimize the
>   rendering better because Cogl.set_source_texture effectively ends up
>   editing a global convenience material which would cause a flush of
>   Cogl's journal. You should also use this material to implement the
>   opacity of the actor. So _frames would become an array of
>   Cogl.Materials and your init function would be something like this
>   (although I don't really know Vala so I'm just guessing the syntax):
> 

Something else I'll change!

>   ...
> 
> - It's currently much more efficient to use Cogl.rectangle rather than
>   the path API to draw the texture. Cogl isn't clever enough to
>   recognise that the path you've created is a simple rectangle and it
>   ends up having to fill the stencil buffer to render the texture into
>   the path. Using Cogl.rectangle instead means it can just directly
>   submit a quad to OpenGL.

I already noticed a significant speed increase when I switched to
Cogl.rectangle_with_texture_coords, on the order of about 20 times, and
on the plus side its compatible with the default bindings.

Would the above material trick still work with the
rectangle_with_texture_coords?

> - You might want to implement the setter for the 'frame' property so
>   that it queues a redraw. Otherwise it would probably be difficult to
>   use ClutterActor.animate to animate the property. I don't know what's
>   the right way to do that in Vala.

I had that implemented (see the commented line in the init function) but
I found that updating all the SpriteActors inside a parent then calling
queue redraw on the parent was much, much faster.

Any easy way I can get both features?

> Hope that helps.
> 
> - Neil
> 
> > Here's my actor:
> > 
> > using Cogl;
> > 
> > public class SpriteActor : Clutter.Actor
> > {
> >   private Texture _tex;
> >   private Texture[] _frames;
> >   
> >   public int frame_width { get; construct set; }
> >   public int frame_height { get; construct set; }
> >   public int n_frames { get; construct set; }
> >   
> >   public int frame { get; set; }
> >   
> >   private SpriteActor()
> >   {
> >     Object();
> >   }
> >   
> >   public SpriteActor.from_file(int width, int height,
> >                                int frames, string path)
> >                                 throws GLib.Error
> >   {
> >     Object(frame_width: width, frame_height: height, n_frames: frames);
> >     
> >     _tex = new Texture.from_file(path,
> >                                  TextureFlags.NO_SLICING,
> >                                  PixelFormat.ANY);
> >     
> >     init();
> >   }
> >   
> >   public SpriteActor.from_bitmap(int width, int height,
> >                                  int frames, Bitmap bit)
> >   {
> >     Object(frame_width: width, frame_height: height, n_frames: frames);
> >     
> >     _tex = new Texture.from_bitmap(bit,
> >                                    TextureFlags.NO_SLICING,
> >                                    PixelFormat.ANY);
> >     
> >     init();
> >   }
> >   
> >   private void init()
> >   {
> >     //this.notify["frame"].connect(() => {queue_redraw();});
> >   
> >     _frames = new Texture[n_frames];
> >     
> >     for (int i = 0; i < n_frames; i++)
> >     {
> >       _frames[i] = new Texture.from_sub_texture(_tex, i * frame_width,
> >                                                 0, frame_width,
> >                                                 frame_height);
> >     }
> >   }
> >   
> >   protected override void paint()
> >   {  
> >     Cogl.set_source_texture(_frames[frame]);
> >     Cogl.path_rectangle(0, 0, width, height);
> >     Cogl.path_fill();
> >   }
> >   
> >   protected override void pick(Clutter.Color c)
> >   {
> >     Cogl.set_source_color4ub(c.red, c.green, c.blue, c.alpha);
> >     Cogl.path_rectangle(0, 0, width, height);
> >     Cogl.path_fill();
> >   }
> > }
> > 
> > 
> > diff --git a/vapi/cogl-1.0.vapi b/vapi/cogl-1.0.vapi
> > index 9f356d3..9c2c807 100644
> > --- a/vapi/cogl-1.0.vapi
> > +++ b/vapi/cogl-1.0.vapi
> > @@ -152,6 +152,7 @@ namespace Cogl {
> >             public Texture.from_bitmap (Cogl.Bitmap bmp_handle, 
> > Cogl.TextureFlags flags, Cogl.PixelFormat internal_format);
> >             public Texture.from_data (uint width, uint height, 
> > Cogl.TextureFlags flags, Cogl.PixelFormat format, Cogl.PixelFormat 
> > internal_format, uint rowstride, [CCode (array_length = false)] uchar[] 
> > data);
> >             public Texture.from_file (string filename, Cogl.TextureFlags 
> > flags, Cogl.PixelFormat internal_format) throws GLib.Error;
> > +           public Texture.from_sub_texture(Cogl.Texture full_texture, int 
> > sub_x, int sub_y, int sub_width, int sub_height);
> >             public int get_data (Cogl.PixelFormat format, uint rowstride, 
> > uchar[] data);
> >             public Cogl.PixelFormat get_format ();
> >             public uint get_height ();
> Attachment: smime.p7s (application/x-pkcs7-signature)

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to