Vala プログラミング

WebGPU プログラミング

おなが@京都先端科学大

Genie Image Viewer

f:id:onagat12:20150606235236p:plain

(プログラムを実行したところ)

f:id:onagat12:20150606235237p:plain

(画像一覧で画像を選択するとウィンドウ全体に表示される。再度クリックすると、

一覧表示に戻る。)

 

GNOME Developer Platform Demos にある clutter を利用したサンプル photo-wall.c をGenieで書き直してみました。
Genieで使い易いように、以下の箇所を変更しています。
・ファイルの読み込みには、gio libaryのGLib.FileとGLib.FileInfoを使用している。
・ファイルパスリストには、gee libraryのlistを使用している。

・imageの表示には、Clutter.ImageとGdk.Pixbufを使用している。
(写真は、「フリー写真素材 Futta.NET」の写真を利用しています。)

 

## image-viewer-gs.gs

uses
    Clutter

stage : Stage
filename : string
image : Image

STAGE_WIDTH : int = 800
STAGE_HEIGHT : int = 600
THUMBNAIL_SIZE : int = 200
is_focused : bool = false
orig_x : float = 0.0f
orig_y : float = 0.0f

init
    var IMAGE_DIR_PATH = "./images/"

    if Clutter.init(ref args) != InitError.SUCCESS
    print "Clutter init error"

   stage = new Stage ()
   stage.title = "ImageView"
   stage.set_size (STAGE_WIDTH, STAGE_HEIGHT)
   stage.set_user_resizable (true)
   stage.destroy.connect(Clutter.main_quit)

   var img_path_list = new list of string

   try
       var directory = File.new_for_path (IMAGE_DIR_PATH)
       var enumerator = directory.enumerate_children (FileAttribute.STANDARD_NAME, 0)

       file_info : FileInfo
       while (file_info = enumerator.next_file ()) != null
           filename = file_info.get_name ()
           //stdout.printf ("%s\n", file_info.get_name ());
           stdout.printf ("%s\n", filename)
           img_path_list.add (filename)
   except e:Error
       print "Message: %s", e.message

    //stdout.printf ("%s\n", filename)
   print ""
   for s in img_path_list
       print s

   var row_count = STAGE_WIDTH / THUMBNAIL_SIZE
   var col_count = STAGE_HEIGHT / THUMBNAIL_SIZE

   for var row = 0 to (row_count - 1)
       for var col = 0 to (col_count - 1)
            var s = img_path_list[row * col_count + col]

            try
                 var pixbuf = new Gdk.Pixbuf.from_file (IMAGE_DIR_PATH + s)
                 image = new Image ()
                 image.set_data (pixbuf.get_pixels (),
                                            pixbuf.has_alpha ? Cogl.PixelFormat.RGBA_8888 :  Cogl.PixelFormat.RGB_888,
                                            pixbuf.width,
                                            pixbuf.height,
                                            pixbuf.rowstride)
          except e:Error
               print "Message: %s", e.message

         var actor = new Actor ()
         actor.content = image
         actor.set_size (THUMBNAIL_SIZE, THUMBNAIL_SIZE)
         actor.set_position (row * THUMBNAIL_SIZE, col * THUMBNAIL_SIZE)
         actor.reactive = true
         actor.button_press_event.connect (actor_clicked_cb)
         stage.add_child (actor);

    stage.show()
    Clutter.main()

def actor_clicked_cb (actor:Actor, evt:ButtonEvent) : bool
    print "Clicked"
    print "x: %d", (int)actor.x
    print "y: %d", (int)actor.y
    print "z: %d", (int)actor.z_position

    stage.remove_child (actor)
    stage.add_child (actor)

    if is_focused == false
        orig_x = actor.x
        orig_y = actor.y

    print "orig_x: %d", (int)orig_x
    print "orig_y: %d", (int)orig_y

    if is_focused == false
       actor.x = 0
       actor.y = 0
       actor.z_position = 10.0f
       actor.reactive = true
       actor.width = STAGE_WIDTH
       actor.height = STAGE_HEIGHT
   else
      actor.x = orig_x
      actor.y = orig_y
      actor.z_position = 0.0f
      actor.reactive = true
      actor.width = THUMBNAIL_SIZE
      actor.height = THUMBNAIL_SIZE

   is_focused = !is_focused

   return true

 

ビルド
valac --pkg clutter-1.0 --pkg gee-0.8 image-viewer-gs.gs

 

Vala言語とOpenGL (4)

f:id:onagat12:20150302021004p:plain

GUIをGladeで作成しました。
Gladeでの作成画面

f:id:onagat12:20150302020143p:plain

adjustmentの設定画面

f:id:onagat12:20150302020220p:plain

Scale上のスライダの表示方法は、下に書いてあります。

 

gtkcluttergl4.vala
using Gtk;
using GtkClutter;
using Clutter;

public class Main : Object
{
    const string UI_FILE = "mainwindow.ui";
    private Builder builder;

    private Clutter.Actor coglbox;
    private static float alpha;

    public Main ()
    {
        try
        {
             builder = new Builder ();
             builder.add_from_file (UI_FILE);
             builder.connect_signals (this);

             CreateUI ();

             var window = builder.get_object ("window1") as Gtk.Window;
             window.title = "GtkClutterGL4";
             window.destroy.connect (Gtk.main_quit);
             window.show_all ();
        }
        catch (Error e) {
            stderr.printf ("Could not load UI: %s\n", e.message);
        }
    }

    private void CreateUI ()
    {
          var box = builder.get_object ("box1") as Gtk.Box;
           var widget = new Embed ();
           box.pack_start (widget, true, true, 0);

           var stage = widget.get_stage ();
           stage.width = stage.height = 400;
           stage.background_color = Clutter.Color () { alpha = 255 };

           coglbox = new Clutter.Actor ();
           stage.add_actor (coglbox);
           coglbox.paint.connect (paint_cb);

           var button = builder.get_object ("button1") as Button;
           button.clicked.connect (Gtk.main_quit);

           var scale = builder.get_object ("scale1") as Scale;
           scale.value_changed.connect *1;
                alpha = (float)scale.get_value ();
                coglbox.queue_redraw ();
           });
     }

    private void paint_cb ()
    {
          //stdout.printf("paint-cb \n");
         Cogl.TextureVertex vertices1[3];

         Cogl.push_matrix ();
         Cogl.translate (200, 200, 0);
         Cogl.rotate (alpha, 0, 0, 1);

         vertices1[0].x = 0;
         vertices1[0].y = -150;
         vertices1[0].z = 0;
         vertices1[0].color.set_from_4f (1.0f, 0.0f, 0.0f, 1.0f);

         vertices1[1].x = -150;
         vertices1[1].y = 150;
         vertices1[1].z = 0;
         vertices1[1].color.set_from_4f (0.0f, 1.0f, 0.0f, 1.0f);

         vertices1[2].x = 150;
         vertices1[2].y = 150;
         vertices1[2].z = 0;
         vertices1[2].color.set_from_4f (0.0f, 0.0f, 1.0f, 1.0f);

        Cogl.polygon (vertices1, true);

        Cogl.pop_matrix();
    }
}

void main (string[] args)
{
     GtkClutter.init (ref args);

     new Main ();

     Gtk.main ();
}
ビルド
valac --pkg gtk+-3.0 --pkg clutter-gtk-1.0 gtkcluttergl4.vala

Scaleのスライダの表示
スライダを表示する方法は、gladeで設定する方法とプログラム内で設定する
方法があります。
1 galdeで設定
 glade上でスライダを表示するには、Scaleにアジャストメントを設定する。
 設定の方法
    1    Scaleを選択。
    2 Scaleプロパティ内のアジャストメントの右側のアイコンをクリック。
    3 アジャストメントの選択ダイアログで、新規(New)をクリック。
    4 ajdjustment1オブジェクトが生成される。
    5 ajdjustment1を選択し、必要な設定をする。

2 プログラム内で設定
 gladeのuiファイルからScaleを取り出し、set_rangeメソッドで設定する。
 例 var scale = builder.get_object ("scale1") as Scale;
            scale.set_range (0, 100);

 

注意 このブログでは、引数なしの無名関数の表示が変になります。注釈のようになっています。

*1:) => {
                stdout.printf ("%f\n", scale.get_value (

Vala言語とOpenGL (3)

f:id:onagat12:20150301021658p:plain

三角形の回転にScaleウィジェを利用しています。

gtkclutter3.vala
using Gtk;
using GtkClutter;
using Clutter;

public class MainWindow : Gtk.Window
{
   private Clutter.Actor coglbox;
   private static float alpha;

   public MainWindow ()
   {
        title = "GtkClutterGL";
        set_default_size (400, 460);
        destroy.connect (Gtk.main_quit);

        var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
        var box2 = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
        var scale = new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL, 0, 360, 2);
        var button = new Gtk.Button.with_label ("Quit");
        button.clicked.connect (Gtk.main_quit);

        vbox.pack_start (box2, true, true, 0);
        vbox.pack_start (scale, false, false, 0);
        vbox.pack_start (button, false, false, 0);
        add (vbox);

        var widget = new Embed ();
        box2.pack_start (widget, true, true, 0);

        var stage = widget.get_stage ();
        stage.width = stage.height = 400;
        stage.background_color = Clutter.Color () { alpha = 255 };

        coglbox = new Clutter.Actor ();
        stage.add_actor (coglbox);
        coglbox.paint.connect (paint_cb);

        scale.value_changed.connect *1;
             alpha = (float)scale.get_value ();
             coglbox.queue_redraw ();
        });
   }

   private void paint_cb ()
   {
       Cogl.TextureVertex vertices1[3];

       Cogl.push_matrix ();
       Cogl.translate (200, 200, 0);
       Cogl.rotate (alpha, 0, 0, 1);

       vertices1[0].x = 0;
       vertices1[0].y = -150;
       vertices1[0].z = 0;
       vertices1[0].color.set_from_4f (1.0f, 0.0f, 0.0f, 1.0f);

       vertices1[1].x = -150;
       vertices1[1].y = 150;
       vertices1[1].z = 0;
       vertices1[1].color.set_from_4f (0.0f, 1.0f, 0.0f, 1.0f);

       vertices1[2].x = 150;
       vertices1[2].y = 150;
       vertices1[2].z = 0;
       vertices1[2].color.set_from_4f (0.0f, 0.0f, 1.0f, 1.0f);

       Cogl.polygon (vertices1, true);

       Cogl.pop_matrix();
    }
}

void main (string[] args)
{
     GtkClutter.init (ref args);
     var window = new MainWindow ();
     window.show_all ();
     Gtk.main ();
}
ビルド
valac --pkg gtk+-3.0 --pkg clutter-gtk-1.0 gtkcluttergl3.vala

Scaleの使い方
1 Scaleウィジェの生成には、Scale.with_rangeメソッドを使います。
        var scale = new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL, 0, 360, 2);
    Scaleの方向、初めの値、終りの値、ステップの値を設定します。
2 Scaleの値によって三角形を回転させるには、value_changedシグナルを使います。
    これは、Scaleの親クラスであるRangeのシグナルです。
        scale.value_changed.connect *2;
            alpha = (float)scale.get_value ();
            coglbox.queue_redraw ();
        });

*1:) => {;
             stdout.printf ("%f\n", scale.get_value (

*2:) => {
            stdout.printf ("%f\n", scale.get_value (

Vala言語とOpenGL (2)

f:id:onagat12:20150301012106p:plain

GtkウィンドウにOpenGLを描画していることが分かるように、ボタン(Button)を
ウィンドウに追加しました。
また、Stageのmotion_eventシグナルを使って、Stage上でマウスを動かすと
三角形が回転するようにしました。コールバック関数には、無名関数を使っています。

gtkcluttergl2.vala
using Gtk;
using GtkClutter;
using Clutter;

public class MainWindow : Gtk.Window
{
    private Clutter.Actor coglbox;
    private static float alpha;

    public MainWindow ()

    {
         title = "GtkClutterGL";
         set_default_size (300, 300);
         destroy.connect (Gtk.main_quit);

         var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
         var box2 = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
         var button = new Gtk.Button.with_label ("Quit");
         button.clicked.connect (Gtk.main_quit);

         vbox.pack_start (box2, true, true, 0);
         vbox.pack_start (button, false, false, 0);
         add (vbox);

         var widget = new Embed ();
         box2.pack_start (widget, true, true, 0);

         var stage = widget.get_stage ();
         stage.width = stage.height = 300;
         stage.background_color = Clutter.Color () { alpha = 255 };

         coglbox = new Clutter.Actor ();
         stage.add_actor (coglbox);
         coglbox.paint.connect (paint_cb);

         stage.motion_event.connect ((evt) => {
              GLib.message ("Motion event - Stage");
              stdout.printf ("x = %f y = %f\n", evt.x, evt.y);
              alpha = alpha + 0.5f;
              coglbox.queue_redraw ();
              return true;
        });
     }

    private void paint_cb ()

    {
         Cogl.TextureVertex vertices1[3];

         Cogl.push_matrix ();
         Cogl.translate (150, 150, 0);
         Cogl.rotate (alpha, 0, 0, 1);

         vertices1[0].x = 0;
         vertices1[0].y = -150;
         vertices1[0].z = 0;
         vertices1[0].color.set_from_4f (1.0f, 0.0f, 0.0f, 1.0f);

         vertices1[1].x = -150;
         vertices1[1].y = 150;
         vertices1[1].z = 0;
         vertices1[1].color.set_from_4f (0.0f, 1.0f, 0.0f, 1.0f);

         vertices1[2].x = 150;
         vertices1[2].y = 150;
         vertices1[2].z = 0;
         vertices1[2].color.set_from_4f (0.0f, 0.0f, 1.0f, 1.0f);

         Cogl.polygon (vertices1, true);

         Cogl.pop_matrix();
     }

}

void main (string[] args)
{
     GtkClutter.init (ref args);
     var window = new MainWindow ();
     window.show_all ();
     Gtk.main ();
}
ビルド
valac --pkg gtk+-3.0 --pkg clutter-gtk-1.0 gtkcluttergl2.vala

説明
1 メインのウィンドウに縦方向のBox(vbox)を配置します。その中に、Box(box2)と
  ボタン(button)を配置します。また、box2にEmbedウィジェを貼り付けます。
       var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
          var box2 = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
          var button = new Gtk.Button.with_label ("Quit");
          button.clicked.connect (Gtk.main_quit);
          vbox.pack_start (box2, true, true, 0);
          vbox.pack_start (button, false, false, 0);
          add (vbox);

          var widget = new Embed ();
          box2.pack_start (widget, true, true, 0);
2 Stageのmotion_eventシグナルを使った三角形の回転
          stage.motion_event.connect ((evt) => {
               GLib.message ("Motion event - Stage");
               stdout.printf ("x = %f y = %f\n", evt.x, evt.y);
               alpha = alpha + 0.5f;
               coglbox.queue_redraw ();
               return true;
           });
  paint_cbコールバック関数(coglboxアクターのコールバック関数)
     ここでopenglのrotate関数で回転させる。
           Cogl.rotate (alpha, 0, 0, 1);

Vala言語とOpenGL

f:id:onagat12:20150227190934p:plain

Vala言語を使ったOpenGLによる描画について書いています。
プログラムのサンプルが、GNOME Wiki! のページにあります。
Vala OpenGL Samples(https://wiki.gnome.org/Projects/Vala/OpenGLSamples

GLFW、GtkGLExt、GLX、GLUTライブラリを使ったサンプルです。
プログラムのビルドには、vapi(C言語とのバインディング)が必要です。

External Vala Bindings(https://wiki.gnome.org/Projects/Vala/ExternalBindings

Gtkウィンドウ内でOpenGLを使う時には、GtkGLExtとGLXを利用することになります。
・GtkGLExt
 Ubuntu等のパッケージリポジットリにあるライブラリはgtk+-2.0用で、
 gtk+-3.0で使うには自分でビルドしなければなりません。ライブラリの修正が必要となります。
・GLX
 GLXを利用したプログラムは、EWGENYのサイトで紹介しています。
 Turorial for OpenGL and Gtk3+ combined, written in Vala(https://ewgeny.wordpress.com/2012/12/11/turorial-for-opengl-and-gtk3-combined-written-in-vala/)
 GLXを使う時には、プログラム内でGLXの設定をしなければなりません。これは割と複雑な設定です。

この他に、Gtkウィンドウ内でOpenGLを使う方法として、ClutterとCoglがあります。
下のプログラムは、ClutterとCoglを使ってColoured Triangleを描画するものです。
gtkcluttergl.vala
using Gtk;
using GtkClutter;
using Clutter;

public class MainWindow : Gtk.Window
{
    private Clutter.Actor coglbox;

    public MainWindow ()
    {
         title = "GtkClutterGL";
         set_default_size (300, 300);
         destroy.connect (Gtk.main_quit);

         var widget = new Embed ();
         add(widget);

         var stage = widget.get_stage ();
         stage.width = stage.height = 300;
         stage.background_color = Clutter.Color () { alpha = 255 };

         coglbox = new Clutter.Actor ();
         stage.add_actor (coglbox);
         coglbox.paint.connect (paint_cb);
    }

    private void paint_cb ()

    {
        Cogl.TextureVertex vertices1[3];

        vertices1[0].x = 150;
        vertices1[0].y = 0;
        vertices1[0].z = 0;
        vertices1[0].color.set_from_4f (1.0f, 0.0f, 0.0f, 1.0f);

        vertices1[1].x = 0;
        vertices1[1].y = 300;
        vertices1[1].z = 0;
        vertices1[1].color.set_from_4f (0.0f, 1.0f, 0.0f, 1.0f);

        vertices1[2].x = 300;
        vertices1[2].y = 300;
        vertices1[2].z = 0;
        vertices1[2].color.set_from_4f (0.0f, 0.0f, 1.0f, 1.0f);

        Cogl.polygon (vertices1, true);
    }
}

void main (string[] args)
{
    GtkClutter.init (ref args);
    var window = new MainWindow ();
    window.show_all ();
    Gtk.main ();
}

ビルド
valac --pkg gtk+-3.0 --pkg clutter-gtk-1.0 gtkcluttergl.vala

 

描画の方法
GtkウィンドウにClutterで描画する時には、Embedクラスのウィジェを使います。
  var widget = new Embed ();
  add(widget);
2 EmbedウィジェにはStageが組み込まれているので、それを取り出します。
  var stage = widget.get_stage ();
3 直接描画するActorを作成し、Stageに貼り付けます。
  coglbox = new Clutter.Actor ();
  stage.add_actor (coglbox);
4 Actorのpaintシグナルを使って、描画するコールバック関数を呼び出して、
  描画します。
  coglbox.paint.connect (paint_cb);

Vala + Cogl Cube(4)

f:id:onagat12:20141226010905p:plain

f:id:onagat12:20141226010913p:plain

ポリゴンの法線ベクトルと光線方向のベクトル(z方向)の内積を作り、

ポリゴン面の色の強さに設定しています。(上はマウスで回転している様子)

 

プログラム

private static float alpha;
private static float beta;

void paint_cb () {
   Cogl.push_matrix ();
   Cogl.translate (300, 200, -200);
   Cogl.rotate (alpha, 1, 0, 0);
   stdout.printf("alpha = %f \n", alpha);
   Cogl.rotate (beta, 0, 1, 0);
   stdout.printf("beta = %f \n", beta);

   Cogl.TextureVertex vertices1[4];
   Cogl.TextureVertex vertices2[4];
   Cogl.TextureVertex vertices3[4];
   Cogl.TextureVertex vertices4[4];
   Cogl.TextureVertex vertices5[4];
   Cogl.TextureVertex vertices6[4];

   Cogl.set_depth_test_enabled (true);

   //Front
   var x1 = Math.cos(beta / 180.0f * Math.PI) * Math.cos(alpha / 180.0f * Math.PI);
   var front_color = Cogl.Color.from_4f ((float)x1, 0.0f, 0.0f, 1.0f);

   vertices1[0].x = -100;
   vertices1[0].y = -100;
   vertices1[0].z = 100;
   vertices1[0].color = front_color;

   vertices1[1].x = 100;
   vertices1[1].y = -100;
   vertices1[1].z = 100;
   vertices1[1].color = front_color;

   vertices1[2].x = 100;
   vertices1[2].y = 100;
   vertices1[2].z = 100;
   vertices1[2].color= front_color;

   vertices1[3].x = -100;
   vertices1[3].y = 100;
   vertices1[3].z = 100;
   vertices1[3].color= front_color;

   Cogl.polygon (vertices1, true);

   //Back
   var x2 = -Math.cos(beta / 180.0f * Math.PI) * Math.cos(alpha / 180.0f * Math.PI);
   var back_color = Cogl.Color.from_4f ((float)x2, 0.0f, 0.0f, 1.0f);

   vertices2[0].x = -100;
   vertices2[0].y = -100;
   vertices2[0].z = -100;
   vertices2[0].color = back_color;

   vertices2[1].x = 100;
   vertices2[1].y = -100;
   vertices2[1].z = -100;
   vertices2[1].color = back_color;

   vertices2[2].x = 100;
   vertices2[2].y = 100;
   vertices2[2].z = -100;
   vertices2[2].color = back_color;

   vertices2[3].x = -100;
   vertices2[3].y = 100;
   vertices2[3].z = -100;
   vertices2[3].color = back_color;

   Cogl.polygon (vertices2, true);

   //Left
   var x3 = Math.sin(beta / 180.0f * Math.PI) * Math.cos(alpha / 180.0f * Math.PI);
   var left_color = Cogl.Color.from_4f ((float)x3, 0.0f, 0.0f, 1.0f);

   vertices3[0].x = -100;
   vertices3[0].y = -100;
   vertices3[0].z = 100;
   vertices3[0].color = left_color;

   vertices3[1].x = -100;
   vertices3[1].y = -100;
   vertices3[1].z = -100;
   vertices3[1].color = left_color;

   vertices3[2].x = -100;
   vertices3[2].y = 100;
   vertices3[2].z = -100;
   vertices3[2].color = left_color;

   vertices3[3].x = -100;
   vertices3[3].y = 100;
   vertices3[3].z = 100;
   vertices3[3].color = left_color;

   Cogl.polygon (vertices3, true);

   //Right
   var x4 = -Math.sin(beta / 180.0f * Math.PI) * Math.cos(alpha / 180.0f * Math.PI);
   var right_color = Cogl.Color.from_4f ((float)x4, 0.0f, 0.0f, 1.0f);

   vertices4[0].x = 100;
   vertices4[0].y = -100;
   vertices4[0].z = 100;
   vertices4[0].color = right_color;

   vertices4[1].x = 100;
   vertices4[1].y = -100;
   vertices4[1].z = -100;
   vertices4[1].color = right_color;

   vertices4[2].x = 100;
   vertices4[2].y = 100;
   vertices4[2].z = -100;
   vertices4[2].color = right_color;

   vertices4[3].x = 100;
   vertices4[3].y = 100;
   vertices4[3].z = 100;
   vertices4[3].color = right_color;

   Cogl.polygon (vertices4, true);

   //Top
   var x5 = -Math.sin(alpha / 180.0f * Math.PI);
   var top_color = Cogl.Color.from_4f ((float)x5, 0.0f, 0.0f, 1.0f);

   vertices5[0].x = -100;
   vertices5[0].y = -100;
   vertices5[0].z = 100;
   vertices5[0].color = top_color;

   vertices5[1].x = -100;
   vertices5[1].y = -100;
   vertices5[1].z = -100;
   vertices5[1].color = top_color;

   vertices5[2].x = 100;
   vertices5[2].y = -100;
   vertices5[2].z = -100;
   vertices5[2].color = top_color;

   vertices5[3].x = 100;
   vertices5[3].y = -100;
   vertices5[3].z = 100;
   vertices5[3].color = top_color;

   Cogl.polygon (vertices5, true);

   //Bottom
   var x6 = Math.sin(alpha / 180.0f * Math.PI);
   var bottom_color = Cogl.Color.from_4f ((float)x6, 0.0f, 0.0f, 1.0f);

   vertices6[0].x = -100;
   vertices6[0].y = 100;
   vertices6[0].z = 100;
   vertices6[0].color = bottom_color;

   vertices6[1].x = -100;
   vertices6[1].y = 100;
   vertices6[1].z = -100;
   vertices6[1].color = bottom_color;

   vertices6[2].x = 100;
   vertices6[2].y = 100;
   vertices6[2].z = -100;
   vertices6[2].color = bottom_color;

   vertices6[3].x = 100;
   vertices6[3].y = 100;
   vertices6[3].z = 100;
   vertices6[3].color = bottom_color;

  Cogl.polygon (vertices6, true);

  Cogl.pop_matrix();
}

int main (string[] args)
{
   Clutter.init (ref args);

   var stage = Clutter.Stage.get_default ();
   stage.background_color = Clutter.Color () { alpha = 255 };

   var coglbox = new Clutter.Actor ();
   stage.add_actor (coglbox);

   coglbox.paint.connect (paint_cb);

   stage.motion_event.connect ((evt) => {
      GLib.message ("Motion event - Stage");
      stdout.printf ("x0 = %f y0 = %f\n", evt.x, evt.y);
      alpha = alpha + 0.5f;
      //stdout.printf("alpha = %f \n", alpha);
      beta = beta + 0.5f;

      coglbox.queue_redraw ();
      return true;
   });

   stage.show ();

   Clutter.main ();

   return 0;
}

 

ビルド

コマンドライン

 valac --pkg clutter-1.0 -X -lm cube4.vala

 Cの数値ライブラリを使用しますので、"-X -lm" のオプションを付けています。

Valencia-gedit-plugin

Makefile

 SRCS = cube4.vala
 PROGRAM = cube4
 VALAPKGS = --pkg clutter-1.0
 VALAOPTS =
 CFLAGS = -X -lm

 all: $(PROGRAM)

 $(PROGRAM): $(SRCS)
 (tab) valac $(VALAOPTS) $(VALAPKGS) $(CFLAGS) -o $(PROGRAM) $(SRCS)

 run: $(PROGRAM)
 (tab) ./$(PROGRAM)

 clean:
 (tab) rm -f $(PROGRAM)

 

Vala + Cogl Cube(3)

f:id:onagat12:20141226004949p:plain

Materialを設定し、材質の色(diffuse, ambient, specular)を設定しています。

いろいろ調べましたが、光源の設定、法線ベクトルの設定が分かりません。

OpenGLライブラリを使用しています。

 

プログラム

cube3.vala

using GL;

private static float alpha;
private static float beta;

void paint_cb () {
   Cogl.push_matrix ();
   Cogl.translate (300, 200, -200);
   Cogl.rotate (alpha, 1, 0, 0);
    //stdout.printf("alpha = %f \n", alpha);
   Cogl.rotate (beta, 0, 1, 0);

   Cogl.TextureVertex vertices1[4];
   Cogl.TextureVertex vertices2[4];
   Cogl.TextureVertex vertices3[4];
   Cogl.TextureVertex vertices4[4];
   Cogl.TextureVertex vertices5[4];
   Cogl.TextureVertex vertices6[4];

   Cogl.set_depth_test_enabled (true);

   var material = new Cogl.Material ();
   Cogl.set_source (material);

   Cogl.begin_gl ();
      glEnable (GL_LIGHTING);
   Cogl.end_gl ();

   var diffuse_color = Cogl.Color.from_4f (1.0f, 0.0f, 0.0f, 1.0f);
   var ambient_color = Cogl.Color.from_4f (0.8f, 0.8f, 0.8f, 1.0f);
   var specular_color = Cogl.Color.from_4f (1.0f, 1.0f, 1.0f, 1.0f);

   material.set_diffuse (diffuse_color);
   material.set_ambient (ambient_color);
   material.set_specular (specular_color);
   material.set_shininess (50.0f);

   //var emission_color = Cogl.Color.from_4f (0.8f, 0.0f, 0.0f, 1.0f);
   //material.set_emission (emission_color);

   //Front
   vertices1[0].x = -100;
   vertices1[0].y = -100;
   vertices1[0].z = 100;

   vertices1[1].x = 100;
   vertices1[1].y = -100;
   vertices1[1].z = 100;

   vertices1[2].x = 100;
   vertices1[2].y = 100;
   vertices1[2].z = 100;

   vertices1[3].x = -100;
   vertices1[3].y = 100;
   vertices1[3].z = 100;

   Cogl.polygon (vertices1, false);

   //Back
   vertices2[0].x = -100;
   vertices2[0].y = -100;
   vertices2[0].z = -100;

   vertices2[1].x = 100;
   vertices2[1].y = -100;
   vertices2[1].z = -100;

   vertices2[2].x = 100;
   vertices2[2].y = 100;
   vertices2[2].z = -100;

   vertices2[3].x = -100;
   vertices2[3].y = 100;
   vertices2[3].z = -100;

   Cogl.polygon (vertices2, false);

   //Left
   vertices3[0].x = -100;
   vertices3[0].y = -100;
   vertices3[0].z = 100;

   vertices3[1].x = -100;
   vertices3[1].y = -100;
   vertices3[1].z = -100;

   vertices3[2].x = -100;
   vertices3[2].y = 100;
   vertices3[2].z = -100;

   vertices3[3].x = -100;
   vertices3[3].y = 100;
   vertices3[3].z = 100;

   Cogl.polygon (vertices3, false);

   //Right
   vertices4[0].x = 100;
   vertices4[0].y = -100;
   vertices4[0].z = 100;

   vertices4[1].x = 100;
   vertices4[1].y = -100;
   vertices4[1].z = -100;

   vertices4[2].x = 100;
   vertices4[2].y = 100;
   vertices4[2].z = -100;

   vertices4[3].x = 100;
   vertices4[3].y = 100;
   vertices4[3].z = 100;

   Cogl.polygon (vertices4, false);

   //Top
   vertices5[0].x = -100;
   vertices5[0].y = -100;
   vertices5[0].z = 100;

   vertices5[1].x = -100;
   vertices5[1].y = -100;
   vertices5[1].z = -100;

   vertices5[2].x = 100;
   vertices5[2].y = -100;
   vertices5[2].z = -100;

   vertices5[3].x = 100;
   vertices5[3].y = -100;
   vertices5[3].z = 100;

   Cogl.polygon (vertices5, false);

   //Bottom
   vertices6[0].x = -100;
   vertices6[0].y = 100;
   vertices6[0].z = 100;

   vertices6[1].x = -100;
   vertices6[1].y = 100;
   vertices6[1].z = -100;

   vertices6[2].x = 100; 

   vertices6[2].y = 100;
   vertices6[2].z = -100;

   vertices6[3].x = 100;
   vertices6[3].y = 100;
   vertices6[3].z = 100;

   Cogl.polygon (vertices6, false);

   Cogl.pop_matrix();

}

int main (string[] args)
{
   Clutter.init (ref args);

   var stage = Clutter.Stage.get_default ();
   stage.background_color = Clutter.Color () { alpha = 255 };

   var coglbox = new Clutter.Actor ();
   stage.add_actor (coglbox);

   coglbox.paint.connect (paint_cb);

   stage.motion_event.connect ((evt) => {
      GLib.message ("Motion event - Stage");
      stdout.printf ("x0 = %f y0 = %f\n", evt.x, evt.y);
      alpha = alpha + 1;
      stdout.printf("alpha = %f \n", alpha);
      beta = beta + 1;
      stdout.printf("beta = %f \n", beta);

      coglbox.queue_redraw ();
      return true;
   });

   stage.show ();

   Clutter.main ();

   return 0;
}

 

ビルド

コマンドライン

   valac --vapidir=../vapi --pkg clutter-1.0 --pkg gl cube3.vala

   (vapiフォルダには、gl.vapiファイルが入っている。)

Valencia-gedit-plugin

Makefile

 SRCS = cube3.vala
 PROGRAM = cube3
 VALAPKGS = --pkg clutter-1.0 --pkg gl
 VALAOPTS = --vapidir=../vapi
 CFLAGS =

 all: $(PROGRAM)

 $(PROGRAM): $(SRCS)
 (tab) valac $(VALAOPTS) $(VALAPKGS) $(CFLAGS) -o $(PROGRAM) $(SRCS)

 run: $(PROGRAM)
 (tab) ./$(PROGRAM)

 clean:
 (tab) rm -f $(PROGRAM)