mieki256's diary



2019/03/17() [n年前の日記]

#1 [gosu][ruby] gosu + opengl-bindingsを試していたり

せっかくだから、gosu + opengl の組み合わせだけではなく、gosu + opengl-bindings の組み合わせでもスクリプトが動くように修正作業をしているところ。

環境は以下。
とりあえず、以下のスクリプトは、どちらでも動くように修正できた。

_gosu_examples_mieki256/16_gosu_opengl_test1.rb
_gosu_examples_mieki256/17_gosu_opengl_test2.rb
_gosu_examples_mieki256/opengl_glut_only_test.rb

opengl-bindingsに対応させる際の注意点。 :

opengl 用のスクリプトを、opengl-bindings に対応させる際のポイントを一応メモ。

まず、require や include の書き方が変わる。

opengl の場合。
  # gem install opengl glu glut

  require 'gl'
  require "glu"
  require "glut"

  include Gl
  include Glu
  include Glut

opengl-bindings の場合。
  # gem install opengl-bindings

  require 'opengl'
  require "glu"
  require "glut"

  OpenGL.load_lib
  GLU.load_lib
  GLUT.load_lib

  include OpenGL
  include GLU
  include GLUT

また、glTranslate() や glRotate() も変わる。

opengl は glTranslate() や glRotate() と書けるけど。
glTranslate(x, y, z)
glRotate(angle, 0.0, 1.0, 0.0)

opengl-bindings は glTranslatef() や glRotatef() と書かないといけない。
glTranslatef(x, y, z)
glRotatef(angle, 0.0, 1.0, 0.0)

後者の書き方をすればどちらでも動くので、全部後者で統一しちゃってもいいのかもしれない。

また、opengl は配列をそのまま渡せるけれど。
glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1.0])

opengl-bindings は、場合によっては pack() を使わないとダメらしい。
glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1.0].pack("f*"))

以下のやり取りで解説されてた。

_glLightfv fails - Issue #28 - vaiorabbit/ruby-opengl

ただ、試したところ、毎フレーム呼ばれる処理の中で pack() で変換していると、処理時間がかかってしまって、描画までおかしくなるようで。初期化処理等で、できるだけ事前に pack しておいて、毎フレーム呼ばれる処理の中では pack 済みのデータを指定する、といった工夫が必要になるようだなと。

ライト設定でハマった。 :

以下のスクリプトを opengl-bindings に対応させようとして修正した際に、ライトの設定でハマったり。

_gosu_examples_mieki256/01_gosu_opengl_11.rb
_gosu_examples_mieki256/02_gosu_opengl_15.rb

スクリプトを実行するたびに、何故かオブジェクトが真っ暗になったり、明るくなったりする。動作が不定。条件が分からない。

色々ググってるうちに、なんとなく分かってきた。ライトの位置、もしくは方向を指定する際に、[x,y,z] を指定していたけど。最後に w も追加して [x,y,z,w] を指定しないと動作が不定になるっぽい。

# Light
LIGHT_POS = [1.0, 2.0, 4.0]            # 位置
LIGHT_AMBIENT = [0.5, 0.5, 0.5, 1.0]   # 環境光
LIGHT_DIFFUSE = [1.0, 1.0, 1.0, 1.0]   # 拡散光
LIGHT_SPECULAR = [1.0, 1.0, 1.0, 1.0]  # 鏡面光

LIGHT_POS_PACK = LIGHT_POS.pack("f*")
LIGHT_AMBIENT_PACK = LIGHT_AMBIENT.pack("f*")
LIGHT_DIFFUSE_PACK = LIGHT_DIFFUSE.pack("f*")
LIGHT_SPECULAR_PACK = LIGHT_SPECULAR.pack("f*")

...

    # opengl-bindings
    glLightfv(GL_LIGHT0, GL_AMBIENT, LIGHT_AMBIENT_PACK)
    glLightfv(GL_LIGHT0, GL_DIFFUSE, LIGHT_DIFFUSE_PACK)
    glLightfv(GL_LIGHT0, GL_SPECULAR, LIGHT_SPECULAR_PACK)
    glLightfv(GL_LIGHT0, GL_POSITION, LIGHT_POS_PACK)

    glEnable(GL_LIGHTING)    # ライティングを有効化
    glEnable(GL_LIGHT0)      # GL_LIGHT0 を有効化
LIGHT_POS = [1.0, 2.0, 4.0]            # 位置
↓
LIGHT_POS = [1.0, 2.0, 4.0, 0.0]       # 位置

おそらくだけど、OpenGL側は [x, y, z, w] の4つが指定されてることを前提にして動いてるのに、スクリプト側では [x, y, z] の3つしか渡してなかったから、最後の w は謎の領域から謎の値を読んで動作していたのではないかと。スクリプトを実行するたびに、謎領域のアドレスも値も変化してしまうから、明るくなったり暗くなったりしていたのかなと。

ちなみに、glLightfv(GL_LIGHT0, GL_POSITION, [x, y, z, w]) の w は、0.0 なら平行光源、それ以外なら点光源ということになってる模様。たぶん。

_光源の設定 - OpenGL de プログラミング
_OpenGL ライティング(Lighting)

opengl-bindingsが落ちる。 :

Windows10 x64 + Ruby 2.5.3 p105 上で、以下のスクリプトを opengl-bindings で動かすと、数秒後に Segmentation fault で落ちてしまう。

_opengl_glut_only_test.rb

opengl + glu + glut で動かした場合は落ちないのだけどな。

> ruby opengl_glut_only_test.rb
load opengl-bindings
D:/Ruby/Ruby25/lib/ruby/gems/2.5.0/gems/opengl-bindings-1.6.8/lib/glut.rb:421: [BUG] Segmentation fault

ruby 2.5.3p105 (2018-10-18 revision 65156) [i386-mingw32]

-- Control frame information -----------------------------------------------
c:0004 p:---- s:0016 e:000015 CFUNC  :call
c:0003 p:0021 s:0012 e:000011 METHOD D:/Ruby/Ruby25/lib/ruby/gems/2.5.0/gems/opengl-bindings-1.6.8/lib/
glut.rb:421
c:0002 p:0393 s:0006 e:000005 EVAL   opengl_glut_only_test.rb:154 [FINISH]
c:0001 p:0000 s:0003 E:000100 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
opengl_glut_only_test.rb:154:in `<main>'
D:/Ruby/Ruby25/lib/ruby/gems/2.5.0/gems/opengl-bindings-1.6.8/lib/glut.rb:421:in `glutMainLoop'
D:/Ruby/Ruby25/lib/ruby/gems/2.5.0/gems/opengl-bindings-1.6.8/lib/glut.rb:421:in `call'

-- C level backtrace information -------------------------------------------
C:\WINDOWS\SYSTEM32\ntdll.dll(ZwWaitForSingleObject+0xc) [0x7796a8fc]
C:\WINDOWS\System32\KERNELBASE.dll(WaitForSingleObject+0x12) [0x76d445f2]
C:\Ruby\Ruby25\bin\msvcrt-ruby250.dll(rb_print_backtrace+0x40) [0x62a8b220]
C:\WINDOWS\SYSTEM32\ntdll.dll(RtlCaptureStackContext+0x1e521) [0x7799da71]

-- Other runtime information -----------------------------------------------

...
_全エラーメッセージ - error.txt

なんでだろうな。

VMware Player 12 + Ubuntu 18.04 + Ruby 2.5.1 p57 + opengl-bindings 1.6.8 なら落ちない。Windows上でだけ落ちるということかなあ。

teapot をワイヤー表示するとすぐに落ちるけど、ソリッド表示にしたらちょっと落ちにくくなった気もした。でもまあ、結局は落ちるけど。

以上、1 日分です。

過去ログ表示

Prev - 2019/03 - Next
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project