【開発】OpenGL ESで回転行列を追加すると矩形が歪む現象

1,279 views
Skip to first unread message

Tank2005

unread,
Oct 26, 2012, 12:15:59 PM10/26/12
to android-g...@googlegroups.com
オライリージャパンの「初めてのOpenGL ES(山下武志・著)」を読みながら、サンプルプログラムを組んでいます。
今、行列の項目をこなしているのですが、回転行列を試してみたところ、図形がディスプレイのサイズに合わせて伸び、歪んで見えます。解説には「ビューポートの設定上、多少歪んでいます」という注釈があるものの、そのビューポートをどうすればよいかについては、ざっと見る限り言及されていないようで、原因と対策がいまいちわかりません。

書籍のサンプルプログラムは以下の通りですが、どこを改良すれば回転しても長方形を維持することができるのでしょうか。
http://code.google.com/p/learning-opengl-es/source/browse/trunk/OpenGLSampleApps/src/eaglesakura/sample/ogles/OpenGLSample_2_1.java

eaglesakura

unread,
Oct 26, 2012, 7:58:15 PM10/26/12
to android-g...@googlegroups.com
筆者の山下です。
回転行列の説明についてですが、書籍では行列設定の単純化のため、
1. 拡大縮小
2. 回転
3. 移動
の順番で2D描画・3D描画で統一しています。(コマンド発行順番は逆順です)

2D描画で更に正しく描画するためには、アスペクト比を調整するためのスケーリング設定をする必要があります。
1. アスペクト比調整した拡大縮小
2. 回転
3. アスペクト比を正しくするために縦横比調整
4. 移動
コードは次のようになりますので、参考にしてください。
「初めてのOpenGL ES」の説明に比べ、縦横比調整(アスペクト比調整)のコードが追加されています。
これでほぼ見た目を保った回転ができるはずです。

drawImageメソッド(212行目)に同様の歪み抑制コードが記述されています。
行列部分抜粋
        
//! 描画位置を行列で操作する
        {
            float sizeX = (float) dstWidth / (float) displayWidth * 2;
            float sizeY = (float) dstHeight / (float) displayHeight * 2;
            float sx = (float) dstX / (float) displayWidth * 2;
            float sy = (float) dstY / (float) displayHeight * 2;

            gl.glLoadIdentity();
            final float translateX = -1.0f + sizeX / 2.0f + sx;
            final float translateY = 1.0f - sizeY / 2.0f - sy;
            gl.glTranslatef(translateX, translateY, 0);

            // aspectによる歪みを抑制する
            {
                final float aspect = displayWidth / displayHeight;
                gl.glScalef(1.0f / aspect, 1.0f, 1.0f);
                gl.glRotatef(degree, 0, 0, 1);
                gl.glScalef(sizeX * aspect, sizeY, 1.0f);
            }
        }

2012年10月27日土曜日 1時15分59秒 UTC+9 Tank2005:

Tank2005

unread,
Oct 27, 2012, 5:09:55 AM10/27/12
to android-g...@googlegroups.com
筆者直々に回答していただき、恐縮です。アドバイスを元にプログラムを調整し、うまくCanvasの座標系に近づけることができました。おかげさまで既存の画像処理の移植性がよりよくなりました。

インターネットではAndroid×OpenGLの紹介はよく見るものの、内容は「このコードで動くよ」程度で完結していて、なぜそう動くのかが全くわかりませんでした。「初めての~」ではその「なぜそうしなければいけないのか」が丁寧に書かれており、これまでずっと停滞していたプログラムに対する理解が一気に進みました。

ところで、今回の質問と回答の内容をTipsとして、自身のブログで書籍と一緒に紹介したいのですが、許可をいただないでしょうか。

eaglesakura

unread,
Oct 27, 2012, 10:06:31 AM10/27/12
to android-g...@googlegroups.com
山下です。
うまく動いたようで何よりです。
ブログでご紹介していただけると、私自身もうれしいので是非ともよろしくお願いします。
(URLを教えていただけるとありがたいです)

2012年10月27日土曜日 18時09分55秒 UTC+9 Tank2005:
Reply all
Reply to author
Forward
0 new messages