Androidアプリ開発 OpenGL 陰面消去する [Android OpenGL]
さて、一応3DCGらしいことはできるようになった。三角形をたくさん作ってやれば、もっと3DCGらしくみえるようになるであろう。しかし、3DCGの入り口に立ったに過ぎない。もっと多くの学ぶべき技術がある。
陰面消去
3DCGの基本的なテクニックに、陰面消去がある。隠れている面を表示しない、といったものである。隠れた面はどうせ見えないのだから、表示しない方が計算量を減らすことができる、という考え。
サンプルで作成した三角形のモデルには「面」といった概念がない。データとしてあるのは頂点座標のみである。陰面消去を行うには、面をデータとして持たせる必要がある。
面は、それを構成する点を頂点座標データの番号で指定していく。今現在、頂点座標データとして3つのデータがある。頂点番号0、1、2の3つの頂点が存在している。
面の頂点は、表からみて、反時計まわりに順番に指定していく。OpenGL ESでは、四角形や五角形のような頂点数が4以上の多角形(いわゆるポリゴン)を扱うことができない。三角形にしないと描画できない。そのため、面の頂点数はみな3になる。
関連記事
Androidアプリ開発 OBJ形式のファイルを開くために「ファイル選択ダイアログ」が欲しい
面データが必要と書いたが、特に指定しない場合、頂点データの順で面が構成されることになる。なので、面データを作成しなくても陰面消去が可能である。陰面消去は、glEnableでGL_CULL_FACEを有効にすることで行うことができる。さっそくやってみよう。
レンダラーでモデルを回転させている。三角形が表を向いているときだけ表示され、裏側になったときには表示されなくなる。
消去する面を逆転させることもできる。glCullFace(GL_FRONT)とすると表面が消去される。GL_BACKなら裏面が表示されない。使い道がわからないが、GL_FRONT_AND_BACKを指定すると両方表示されない。デフォルトは、GL_BACK。
ふたつ並べてみる
ひとつの三角形だけだとこれらの違いがよくわからないので、横にふたつ並べて、一方はGL_FRONTで、もうひとつはGL_BACKで描画してみることにしよう。
onDrawFrameの中で同じモデルを何回も描画させてかまわない。全く同じ状況で何回も描画させる必要はないが、位置を変えて描画、色を変えて描画、といったことをやってもぜんぜんかまわない。
移動は、glTranslatefでできるので、一度描画した後glTranslatefしてからもう一度drawを呼び出して描画してみよう。
横に並べたいので、最初のglTranslatefでは1,0,-3に移動し、2回目のglTranslateでは、-1,0,-3に移動している。
回転させる角度は変えたくないので、glRotatefは1回のみ。
実行させると、意図したとおりには回転してくれない(以下の動画を参照)。移動はできているが、それぞれがコマのように回っていて欲しかった。
なんでこうなるかというと、2回目の描画では、移動、回転、移動とマトリックスに設定した一連のパラメータが有効になってしまうから。それぞれをコマのように回したいのなら、「回転して移動」を2セット行ってやる必要がある。
マトリックスのプッシュとポップ
OpenGLでは、アフィン変換に使うマトリックスを一時的にスタックにプッシュして記憶することができる。描画オブジェクトに対して、移動や回転をかけたいときは、まず、その時点でのマトリックスをプッシュして記憶しておく。
移動やら回転が終わったら、次の描画のためにポップして戻しておく。といった使い方が間違いないと思う。では、早速そのように変更してみよう。
これで思い通りに回転する。
サイト内を検索
陰面消去
3DCGの基本的なテクニックに、陰面消去がある。隠れている面を表示しない、といったものである。隠れた面はどうせ見えないのだから、表示しない方が計算量を減らすことができる、という考え。
サンプルで作成した三角形のモデルには「面」といった概念がない。データとしてあるのは頂点座標のみである。陰面消去を行うには、面をデータとして持たせる必要がある。
面は、それを構成する点を頂点座標データの番号で指定していく。今現在、頂点座標データとして3つのデータがある。頂点番号0、1、2の3つの頂点が存在している。
面の頂点は、表からみて、反時計まわりに順番に指定していく。OpenGL ESでは、四角形や五角形のような頂点数が4以上の多角形(いわゆるポリゴン)を扱うことができない。三角形にしないと描画できない。そのため、面の頂点数はみな3になる。
関連記事
Androidアプリ開発 OBJ形式のファイルを開くために「ファイル選択ダイアログ」が欲しい
面データが必要と書いたが、特に指定しない場合、頂点データの順で面が構成されることになる。なので、面データを作成しなくても陰面消去が可能である。陰面消去は、glEnableでGL_CULL_FACEを有効にすることで行うことができる。さっそくやってみよう。
@Override public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0, 0, -3f); gl.glRotatef(angle, 0, 1, 0); angle += 0.5; gl.glEnable(GL10.GL_CULL_FACE); gl.glCullFace(GL10.GL_BACK); model.draw(gl); }
レンダラーでモデルを回転させている。三角形が表を向いているときだけ表示され、裏側になったときには表示されなくなる。
消去する面を逆転させることもできる。glCullFace(GL_FRONT)とすると表面が消去される。GL_BACKなら裏面が表示されない。使い道がわからないが、GL_FRONT_AND_BACKを指定すると両方表示されない。デフォルトは、GL_BACK。
ふたつ並べてみる
ひとつの三角形だけだとこれらの違いがよくわからないので、横にふたつ並べて、一方はGL_FRONTで、もうひとつはGL_BACKで描画してみることにしよう。
onDrawFrameの中で同じモデルを何回も描画させてかまわない。全く同じ状況で何回も描画させる必要はないが、位置を変えて描画、色を変えて描画、といったことをやってもぜんぜんかまわない。
移動は、glTranslatefでできるので、一度描画した後glTranslatefしてからもう一度drawを呼び出して描画してみよう。
@Override public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(1f, 0, -3f); gl.glRotatef(angle, 0, 1, 0); angle += 0.5; gl.glEnable(GL10.GL_CULL_FACE); gl.glCullFace(GL10.GL_FRONT); model.draw(gl); // ふたつめの描画 gl.glTranslatef(-1f, 0, -3f); gl.glCullFace(GL10.GL_BACK); model.draw(gl); }
横に並べたいので、最初のglTranslatefでは1,0,-3に移動し、2回目のglTranslateでは、-1,0,-3に移動している。
回転させる角度は変えたくないので、glRotatefは1回のみ。
実行させると、意図したとおりには回転してくれない(以下の動画を参照)。移動はできているが、それぞれがコマのように回っていて欲しかった。
なんでこうなるかというと、2回目の描画では、移動、回転、移動とマトリックスに設定した一連のパラメータが有効になってしまうから。それぞれをコマのように回したいのなら、「回転して移動」を2セット行ってやる必要がある。
マトリックスのプッシュとポップ
OpenGLでは、アフィン変換に使うマトリックスを一時的にスタックにプッシュして記憶することができる。描画オブジェクトに対して、移動や回転をかけたいときは、まず、その時点でのマトリックスをプッシュして記憶しておく。
移動やら回転が終わったら、次の描画のためにポップして戻しておく。といった使い方が間違いないと思う。では、早速そのように変更してみよう。
@Override public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glPushMatrix(); // マトリックス記憶 gl.glTranslatef(1f, 0, -3f); gl.glRotatef(angle, 0, 1, 0); gl.glEnable(GL10.GL_CULL_FACE); gl.glCullFace(GL10.GL_FRONT); model.draw(gl); gl.glPopMatrix(); // マトリックスを戻す // ふたつめの描画 gl.glPushMatrix(); // マトリックス記憶 gl.glTranslatef(-1f, 0, -3f); gl.glRotatef(angle, 0, 1, 0); gl.glCullFace(GL10.GL_BACK); model.draw(gl); gl.glPopMatrix(); // マトリックスを戻す angle += 0.5; // 回転角度は最後に計算 }
これで思い通りに回転する。
サイト内を検索
2012-04-07 07:54
nice!(0)
コメント(0)
Copyright Atsushi Asai Google+朝井淳
[データベースの気持ちがわかる]SQLはじめの一歩 (WEB+DB PRESS plus)
- 作者: 朝井 淳
- 出版社/メーカー: 技術評論社
- 発売日: 2015/03/03
- メディア: 単行本(ソフトカバー)
Access クエリ 徹底活用ガイド ~仕事の現場で即使える
- 作者: 朝井 淳
- 出版社/メーカー: 技術評論社
- 発売日: 2018/05/25
- メディア: 大型本
コメント 0