2015年6月29日月曜日

OpenGLのサンプルをやってみたPart2

OpenGLのサンプルをやってみたPart2

もう少しOpenGLの理解を深めるためにネットに転がっているサンプルをやってみようと思います。
ということで今回は以下。
http://utage.headwaters.co.jp/blog/?p=1724

サンプルソースもすべて公開されており、ソースにコメントもあるので
大変勉強になったのですが、初心者にとっては理解ができないところがあったので、メモを残したいと思います。

renderMainでglMatrixModeを2回設定しているのはなぜ?

座標系としては透視投影(奥行きによって、大きさが変わる)ような表示をしたいので、
視体積を設定するglFrustumfの前にGL_PROJECTIONとして設定し、それ移行のオブジェクトはモデルビューで設定したいからっぽい。

テクスチャ画像ファイルは2の階乗になっていないといけない (128px*128pxなど)??

 と書いてあったが以下の解像度を試しましたがリードできてました。
 1600x1200
 278x204
 1333x1000
 1600x1600

使った画像は以下です。一応著作権フリーのもの。
enter image description here

キャラの周りが透明にならない。

上記のキャラの周りは透明(アルファ=0)にも関わらず以下のように周りが黒くなってしまいました。

enter image description here

renderMainに以下を追加することで解決しました。

gl.glEnable(GL10.GL_ALPHA_TEST);
gl.glAlphaFunc(GL10.GL_GEQUAL, 0.1f);

これはアルファ値が0.1f以上は描画するということなので、逆にいうとアルファ値が0の部分は描画されなくなったということです。ちなみに黒となっていたのはアルファ値が0の部分のRGB値がすべて0となっていたためです。

gl.glFrustumfって何?

 透視投影への視体積の設定。  引数は、以下の順。
  Nearの左側の座標
  Nearの右側の座標
  Nearの上側の座標
  Nearの下側の座標
  Nearの距離
  Farの距離

  gl.glFrustumfの引数を変えて見え方がどう変わるかを実験をしてみました。
     

実験 変数 画像 コメント
オリジナル -0.3f, 0.3f, -0.2f, 0.2f, 0.5f, 20.0f enter image description here
実験1 -0.5f, 0.5f, -0.2f, 0.2f, 0.5f, 20.0f enter image description here 透視投影だと遠くにいくほど大きくなるので、奥行き感がなくなると想定していたが、逆に奥行き感が増えた。よくわからない。
実験2 -0.3f, 0.3f, -0.5f, 0.5f, 0.5f, 20.0f enter image description here Nearの縦方向を大きくすることでFar方向の縦の距離の差が減るので縦方向が狭まった。
実験3 -0.3f, 0.3f, -0.2f, 0.2f, 1.0f, 20.0f enter image description here 見ている視点がZ=1.0fの為か手前側しか見えない
実験4 -0.3f, 0.3f, -0.2f, 0.2f, 0.2f, 20.0f enter image description here オリジナルよりNearとFarの距離が増えたので奥行きが広がった?
実験5 -0.3f, 0.3f, -0.2f, 0.2f, 0.5f, 10.0f enter image description here オリジナルと変わらない。10.0fも20.0fも同じ? 試しに5.0fにしても変わらなかった。
実験6 -0.3f, 0.3f, -0.2f, 0.2f, 0.5f, 1.0f enter image description here ねこより後ろが表示されていない
実験7 -0.3f, 0.3f, -0.2f, 0.2f, 0.5f, 2.0f enter image description here ねこより後ろが表示されるようになったが、空が表示されていない
実験8 -0.3f, 0.3f, -0.2f, 0.2f, 0.5f, 3.0f enter image description here オリジナルと同じになった

参考
http://seesaawiki.jp/w/mikk_ni3_92/d/%BC%C2%C1%A9%CA%D407
https://sites.google.com/a/gclue.jp/android-docs-2009/openglno-kiso
http://www.kameda-lab.org/lecture/2012-tsukuba-ic2/chapter08-j.html
http://ameblo.jp/xcc/entry-10276958074.html

gl.glTranslatefって何?

移動の設定。

実験 変数 画像 コメント
オリジナル 0.0f, 0.0f, -1.0f enter image description here
実験1 0.0f, 0.0f, 0.0f enter image description here
実験2 0.0f, 0.0f, -2.0f enter image description here
実験3 -1.0f, 0.0f, -1.0f enter image description here 左に移動したので右半分がでていない。
実験4 0.0f, -1.0f, -1.0f enter image description here 下に移動したので、上のほうがでていない

gl.glRotatefで-70.0fってなぜ-70.0f?

回転。X,Y,,Zどの軸を基準に回転させるか?
以下のように実験してみたが、-70.0fは結構いい感じで奥行き感がでている。

実験 変数 画像 コメント
オリジナル -70.0f,1.0f, 0.0f, -1.0f enter image description here
実験1 0.0f,1.0f, 0.0f, -1.0f enter image description here
実験2 -45.0f,1.0f, 0.0f, -1.0f enter image description here
実験3 -90.0f,1.0f, 0.0f, -1.0f enter image description here
実験4 90.0f,1.0f, 0.0f, -1.0f enter image description here
実験5 -80.0f,1.0f, 0.0f, -1.0f enter image description here
実験6 -60.0f,1.0f, 0.0f, -1.0f enter image description here

GraphicUtil.drawTextureって何?

ウインドウにテクスチャを貼り付ける方法の設定。

引数 説明
GL10 gl
float x テクスチャを貼り付けるウインドウの座標(x)左が0
float y テクスチャを貼り付けるウインドウの座標(y)上が0
float width 1倍なら1.0f?
float height 1倍なら1.0f?
int texture テクスチャのID。GraphicUtil.loadTextureで取得
float u テクスチャの横座標。左が0.0f
float v テクスチャの縦座標。上が0.0f
float tex_w テクスチャの横幅。最大1.0f
float tex_h テクスチャの縦幅。最大1.0f
float r 赤。 1.0fならテクスチャの赤をそのまま表示
float g 緑。 1.0fならテクスチャの緑をそのまま表示
float b 青。 1.0fならテクスチャの青をそのまま表示
float a アルファ 1.0fならテクスチャのアルファをそのまま表示
引数 説明
オリジナル enter image description here
実験1 width,hightを1.0f,1.0fに変更 enter image description here
実験2 width,hightを3.0f,1.0fに変更 enter image description here
実験3 width,hightを1.0f,3.0fに変更 enter image description here

gl.glPushMatrixって何?

行列スタックの一番上の行列をコピーして、その上に積む。
積まれた行列をスタックからとりだすときは、gl.PopMatrixで取り出す。

なぜ必要?

複数のオブジェクトを描画するときに、基準となる座標を1つ前に描画されたオブジェクト基準ではなく、常に同じ座標を基準に描画するようにする手段っぽい。

もう少し具体的にいうと
描画されるのは一番上のスタックにある行列で、
Translate, Rotateなどに描画に必要な操作はスタックの一番上の行列に対して計算されている。

この状態で次のオブジェクトを描画しようとすると、座標は1つ前の座標基準に考えなければならない。

Push,Popを使うことで
Push(コピー)されたものに対してTranslate, Rotateなどに描画するための演算をし、描画されたらその行列をPopで取り除くことで元の座標基準で描画できるというしくみ。
このサンプルでは地面を最初に描画しているが、地面は、座標をいじっていないのでPush/Popはしていない?

OpenGLでゲームを作る 図形の描画に非常にわかりやすく書いてあります。

使い方としては、以下のような形でPushとPopの間で描画する。

 gl.glPushMatrix();
{
            gl.glTranslatef(0.0f,1.5f,0.5f);  // y軸方向に1.5f,z軸方向に0.5f移動させる
            gl.glRotatef(90.0f, 1.0f,0.0f,0.0f);  // x軸を中心に90度回転
            // 奥背景の描画
            GraphicUtil.drawTexture(gl, 0.0f, 0.0f,
                    2.0f,1.0f,  // width, height
                    backTex,
                    0.0f,0.0f,
                    1.0f,1.0f,
                    1.0f,1.0f,1.0f,1.0f);
        }
        gl.glPopMatrix();

gl.glOrthofって何?

正射影の設定。
画面上の中央が(0, 0)、画面横の長さが2.0、画面縦の長さが3.0という座標系を指定している。奥行きに関しては手前が-1.0fで奥が1.0f。
だいたい画面縦横比は2:3なので、こうしているっぽい。

参考
http://news.mynavi.jp/column/iphone/019/

0 件のコメント :

コメントを投稿