トップ
ソフトウェア
陶芸
陶芸
OpenGL
大戦略1208攻略
リンク
3 物体を変化させる
OpenGLを使う以上、3次元描画、特に動的な描画をしないともったいない。ということで、今回から3次元的な処理に近づけていく。
例えば、物体が回って見える場合、3Dの世界では物体自体が回る場合と、カメラが周りを回る場合が考えられる。OpenGLではどちらも再現できるが、実際には陰影や他の物体との兼ね合いから、それぞれ別に使いこなす必要がある。まずは簡単にできる、物体の変化をここでおこなう。
座標系を知っておく
OpenGLの座標系は以下の通りである。これは、通常の数学で使う座標系と同じなので、ベクトル計算などは、そのまま数学用の公式を用いても問題ないことを意味する。(蛇足になるが、VB.netは異なる座標系なので、VB.netのグラフィックス描画(Drawlineなど)では注意が必要である)
x y z
+
-
直接、板を回転・平行移動させる
以下のコードを追記する。
初期設定部(内部はすべて変更)
Protected Overrides Sub InitGLContext()
 
 GL.glClearColor(1.0, 1.0, 0, 1.0) ’背景色
  GL.glLoadIdentity()

End Sub
描画部分
Public Overrides Sub glDraw()
  GL.glClear(Convert.ToUInt32(GLFlags.GL_COLOR_BUFFER_BIT))
  
GL.glScalef(0.999, 1, 1)
  GL.glBegin(Convert.ToUInt32(GLFlags.GL_POLYGON))

End Sub
実行すると、だんだんプレートが小さくなり、消えてしまう。
 
次は平行移動をする。以下のコードに変更する。
描画部分
Public Overrides Sub glDraw()
  GL.glClear(Convert.ToUInt32(GLFlags.GL_COLOR_BUFFER_BIT))
  
GL.glTranslatef(0.001, 0, 0)
  GL.glBegin(Convert.ToUInt32(GLFlags.GL_POLYGON))

End Sub
実行すると、プレートが右に移動し、範囲外に消えてしまう。
 
描画部分
Public Overrides Sub glDraw()
  GL.glClear(Convert.ToUInt32(GLFlags.GL_COLOR_BUFFER_BIT))
  
GL.glRotatef(5.0, 0, 0, 1.0)
  GL.glBegin(Convert.ToUInt32(GLFlags.GL_POLYGON))

End Sub
実行すると、プレートが回転し続ける。試しに、0と1.0の順番を入れ替えて実行すると、板の回転が変わってくることが分かる。また、5.0を変えると、回転速度が変わる。ここまで不思議なのが、どのコマンドも一回だけなのに、変化し続けるかである。描画で指定している座標は固定、回転角度も一定ならば、ここではz軸に5度回転した位置で止まるような気がする。
 
実は、OpenGLでは、物体用変換行列(MODELVIEW行列)が存在し、これを指定座標に掛けて算出している。ここで挙げた3つのコマンドは、いずれも変換行列を変化させる。この行列は、自分でリセットするまで保持されるので、変化はどんどん蓄積される。このため、サンプルプログラムではどんどん変化しつづけるのである。行列の指定、リセットについてはカメラの解説と併せて後述する。
GL.glScalef(0.999, 1, 1) GL.glScale!( x, y, z):!はf、d
座標系を拡大・縮小させる。x、y、zは倍率を入れる。マイナスの場合、線対称移動(鏡面のような変換)となる。
 
GL.glTranslatef(0.001, 0, 0) GL.glTranslate!( x, y, z):!はf、d
座標系を平行移動させる。x、y、zは移動量を入れる。
 
GL.glRotatef(5.0, 0, 0, 1.0) GL.glRotate!(deg, x, y, z):!はf、d 
座標系を回転させる。degは回転角度を入れる。VB.netでは基本的にラジアン(360度=2πで表現)を使用するが、ここでは普通に度で入れる。x、y、zは回転軸の方向を示すベクトルを指定する。
 
試しに、各変更コマンドの前にGL.glLoadIdentity()を挿入すれば、一回移動した位置で停止したままになる。
回転・平行移動しているものは何?
続いて、以下のコードに変更してどう変わるかをみる。
初期設定部
Protected Overrides Sub InitGLContext()
  GL.glClearColor(1.0, 1.0, 0, 1.0) ’背景色
  GL.glLoadIdentity()
  GL.glTranslatef(0.5, 0, 0)
End Sub
描画部分(Rotateを最後におこなっていたら、変更無し)
Public Overrides Sub glDraw()
  GL.glClear(Convert.ToUInt32(GLFlags.GL_COLOR_BUFFER_BIT))
  
GL.glRotatef5.0, 0, 0, 1.0)
  GL.glBegin(Convert.ToUInt32(GLFlags.GL_POLYGON))

End Sub
実行すると、右にずれた位置(左画像)でプレートが回転し続ける。もし、コマンドで物体が移動しているだけなら、Rotateコマンドではz軸を中心として回転するのだから、z軸である画面中心を軸にぐるぐる回るはずである。
実は、この行列が変換しているのは、パーツ単体ではなく、パーツを含む座標系全体である。このことを踏まえると、例えばy軸中心に90度回転した後、x軸中心に回転させると、見かけ上はz軸中心に回転しているように見える。
この、座標系ごと移動する方法は、3Dグラフィックスではなにかと便利である。

 
前へ 次へ
  
Copyright Lichu since 2008 all rights reserved