ClutterImage

今回は Clutter で画像をクルクル回してみよう。
3D ライブラリの定番ですね、ClutterImage を使うようだ。

ClutterImage: Clutter Reference Manual

画像ファイルをセットする方法は公式のサンプルコードがある。
コレを clutter_actor_set_content すればテクスチャになるってことかな。
画像の原寸と ClutterActor のサイズはどんな関係なんだろう。
チャチャッと実験コードを書いて試してみよう。

このサンプルを作っている時に気が付いたけど ClutterScore は deprecated だ。
CLutterTimeline に同様の property がある時点で気が付けよって感じですが。

#!/usr/bin/gjs

const Clutter = imports.gi.Clutter;
const GdkPixbuf = imports.gi.GdkPixbuf;
const Cogl = imports.gi.Cogl;
const Lang = imports.lang;

// Own Rewrite
const FILENAME = "/home/sasakima-nao/pic/game/gf/nae_yuki_ssr/ [ハロウィン13]優木苗.jpg";

const ImageTest = new Lang.Class({
    Name: 'ImageTest',
    Extends: Clutter.Stage,

    _init: function() {
        this.parent();
        // Image
        let image = new Clutter.Image();
        let pixbuf = GdkPixbuf.Pixbuf.new_from_file(FILENAME);
        let alpha = pixbuf.get_has_alpha() ? Cogl.PixelFormat.RGBA_8888 : Cogl.PixelFormat.RGB_888;
        image.set_data(
            pixbuf.get_pixels(),
            alpha,
            pixbuf.get_width(),
            pixbuf.get_height(),
            pixbuf.get_rowstride
        );
        // Rotate Actor
        this.actor = new Clutter.Actor();
        this.actor.set_pivot_point(0.5, 0.5);
        let xy = pixbuf.get_height() / pixbuf.get_width();
        this.actor.set_size(200, 200 * xy);
        this.actor.set_position(70, 50);
        this.actor.set_content(image);
        // Timer
        this.timeline = new Clutter.Timeline({
            duration: 100,
            loop: true
        });
        this.rotation = 0;
        this.timeline.connect("new-frame", Lang.bind(this, function() {
            this.rotation += 0.3
            this.actor.set_rotation_angle(Clutter.RotateAxis.Y_AXIS, this.rotation);
            this.actor.set_rotation_angle(Clutter.RotateAxis.Z_AXIS, this.rotation);
        }));
        this.timeline.start();
        // this
        this.add_child(this.actor);
        this.connect("hide", Clutter.main_quit);
        //this.set_user_resizable(true);
        this.show_all();
    }
});

Clutter.init(null);
new ImageTest();
Clutter.main();

clutter_image

公式サンプルの方法で画像全体のデータは取り込めるようだ。
ClutterActor の大きさに合わせてアスペクト比無視で拡縮される。
上記は一応大雑把にアスペクト比を合わせるようにしている。

PivotPoint や回転は全部 ClutterActor 側の仕事。
ClutterImage は ClutterActor の角度に合わせてレンダリングされる。
簡単すぎて拍子抜け、3D ってもっと面倒なイメージがあったのにな。