OpenGL で正多面体を回転させてみる(Ruby)

Ruby 用に OpenGL を手軽に使うライブラリ「miniopengl.rb」を書いたので、その例として 5つの正多面体すべてを回転させてみました。
 

 
正多面体のデータはここより頂戴しました。ありがとうございます。polyhedrons_obj.zip をダウンロードして解凍し、フォルダを下のコードと同じディレクトリに置いて下さい。

コードは以下です。miniopengl.rb はこのコードと同じディレクトリに配置して下さい。当然ながら OpenGL が使えるようにしなければなりません。必要な準備はここを参照して下さい。また、並列処理を行う Gem 'parallel' を使っています。これはインストール($ gem install parallel)しておいて下さい。

動作は Linux Mint 18.2, Ruby 2.3.3 で確認しました。Gem 'parallel' でおそらく Kernel.#fork を使っているので、Windows では動かないと思われます。

require_relative 'miniopengl'
require 'parallel'

filenames = []
1.upto(5) {|i| filenames << "./polyhedrons_obj/r" + ("%02d" % i) + ".obj"}
data = []

filenames.each do |fn|
  open(fn, "r") do |io|
    ar = [[], []]
    io.each_line do |l|
      l.chomp!
      a = l[2..-1].split(" ")
      (l[0] == "v") ? ar[0] << a.map(&:to_f) : ar[1] << a.map {|i| i.to_i - 1}
    end
    data << ar
  end
end


Parallel.each(data, in_processes: 5) do |vertex, apexes|
  MiniOpenGL.app width: 400, height: 400 do
    clear_color(0, 0, 0.3)
    
    draw do
      clear
      color(0, 1, 0)
      glEnableClientState(GL_VERTEX_ARRAY)
      glVertexPointer(3, GL_DOUBLE, 0, vertex.flatten)
      apexes.size.times {|i| glDrawElements(GL_LINE_LOOP, apexes[i].size,
         GL_UNSIGNED_BYTE, apexes[i])}
      display
    end
  
    reshape do |w, h|
      viewport(0, 0, w, h)
      init_projection
      perspective(30, w / h.to_f, 3, 10)
      init_modelview
      look_at(3, 4, 5, 0, 0, 0, 0, 1, 0)
    end
  
    repeat(30) do
      modelview
      rotate(5, 0, 1, 0)
      redisplay
    end
  end
end

Gem 'parallel' によって 5つのウィンドウが同時に立ち上がります。


※Gem 'parallel' に関しては下を参照。
rubyで簡単並列処理(Parallel)
マルチスレッド/プロセスまとめ(Ruby編)