もう少しOpenGLの理解を深めるためにネットに転がっているサンプルをやってみようと思います。
ということで今回は以下。
http://utage.headwaters.co.jp/blog/?p=1724
サンプルソースもすべて公開されており、ソースにコメントもあるので
大変勉強になったのですが、初心者にとっては理解ができないところがあったので、メモを残したいと思います。
renderMainでglMatrixModeを2回設定しているのはなぜ?
座標系としては透視投影(奥行きによって、大きさが変わる)ような表示をしたいので、
視体積を設定するglFrustumfの前にGL_PROJECTIONとして設定し、それ移行のオブジェクトはモデルビューで設定したいからっぽい。
テクスチャ画像ファイルは2の階乗になっていないといけない (128px*128pxなど)??
と書いてあったが以下の解像度を試しましたがリードできてました。
1600x1200
278x204
1333x1000
1600x1600
使った画像は以下です。一応著作権フリーのもの。
キャラの周りが透明にならない。
上記のキャラの周りは透明(アルファ=0)にも関わらず以下のように周りが黒くなってしまいました。
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 | ||
実験1 | -0.5f, 0.5f, -0.2f, 0.2f, 0.5f, 20.0f | 透視投影だと遠くにいくほど大きくなるので、奥行き感がなくなると想定していたが、逆に奥行き感が増えた。よくわからない。 | |
実験2 | -0.3f, 0.3f, -0.5f, 0.5f, 0.5f, 20.0f | Nearの縦方向を大きくすることでFar方向の縦の距離の差が減るので縦方向が狭まった。 | |
実験3 | -0.3f, 0.3f, -0.2f, 0.2f, 1.0f, 20.0f | 見ている視点がZ=1.0fの為か手前側しか見えない | |
実験4 | -0.3f, 0.3f, -0.2f, 0.2f, 0.2f, 20.0f | オリジナルよりNearとFarの距離が増えたので奥行きが広がった? | |
実験5 | -0.3f, 0.3f, -0.2f, 0.2f, 0.5f, 10.0f | オリジナルと変わらない。10.0fも20.0fも同じ? 試しに5.0fにしても変わらなかった。 | |
実験6 | -0.3f, 0.3f, -0.2f, 0.2f, 0.5f, 1.0f | ねこより後ろが表示されていない | |
実験7 | -0.3f, 0.3f, -0.2f, 0.2f, 0.5f, 2.0f | ねこより後ろが表示されるようになったが、空が表示されていない | |
実験8 | -0.3f, 0.3f, -0.2f, 0.2f, 0.5f, 3.0f | オリジナルと同じになった |
参考
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 | ||
実験1 | 0.0f, 0.0f, 0.0f | ||
実験2 | 0.0f, 0.0f, -2.0f | ||
実験3 | -1.0f, 0.0f, -1.0f | 左に移動したので右半分がでていない。 | |
実験4 | 0.0f, -1.0f, -1.0f | 下に移動したので、上のほうがでていない |
gl.glRotatefで-70.0fってなぜ-70.0f?
回転。X,Y,,Zどの軸を基準に回転させるか?
以下のように実験してみたが、-70.0fは結構いい感じで奥行き感がでている。
実験 | 変数 | 画像 | コメント |
---|---|---|---|
オリジナル | -70.0f,1.0f, 0.0f, -1.0f | ||
実験1 | 0.0f,1.0f, 0.0f, -1.0f | ||
実験2 | -45.0f,1.0f, 0.0f, -1.0f | ||
実験3 | -90.0f,1.0f, 0.0f, -1.0f | ||
実験4 | 90.0f,1.0f, 0.0f, -1.0f | ||
実験5 | -80.0f,1.0f, 0.0f, -1.0f | ||
実験6 | -60.0f,1.0f, 0.0f, -1.0f |
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ならテクスチャのアルファをそのまま表示 |
型 | 引数 | 説明 |
---|---|---|
オリジナル | ||
実験1 | width,hightを1.0f,1.0fに変更 | |
実験2 | width,hightを3.0f,1.0fに変更 | |
実験3 | width,hightを1.0f,3.0fに変更 |
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なので、こうしているっぽい。
0 件のコメント :
コメントを投稿