簡単キューブ描画 CreateIndexCube()


やあ子供たち、元気にしてるかい。glDrawArrays()を使ってGL_TRIANGLESでちょっとしたキューブを描くことを考えてみてくれ。この場合、キューブのテセレーションを真面目に考えた上で、似たような頂点座標が実に36個並んだ頂点配列を作成しなくてはならないね。しかも各頂点座標に並んで法線情報も含めたいかも知れず、その場合は更に36本の3次元ベクトル値をそこに追加で埋め込んでいかなくてはならないよな。
しかしそれはあまりにも非人間的だし、馬鹿げた作業だ。いくら勉強がてらとは言え、そんなサンプルプログラムを作るのは誰だってゴメンだ。
そこで今回のCreateIndexCube()を紹介するぞ。これは描画したいキューブの幅、高さ、奥行き情報さえ与えてやれば、一瞬にしてそれを描画するための、頂点座標配列と、それを参照する、ポリゴン定義インデックス列を返してくれるというスグレモノだ。
ソースは以下のようになったよ。

void CreateIndexCube( const float a, const float b, const float c,
                     vector< int >* indices, vector< vec3 >* poslist )
{
    auto& il = indices;
    auto& pl = poslist;
    // キューブ頂点を発生
    pl->push_back( vec3( 0, 0, 0 ) );// polar vertex
    pl->push_back( vec3( a, 0, 0 ) );
    pl->push_back( vec3( a, b, 0 ) );
    pl->push_back( vec3( 0, b, 0 ) );
    pl->push_back( vec3( 0, b, c ) );
    pl->push_back( vec3( 0, 0, c ) );
    pl->push_back( vec3( a, 0, c ) );
    pl->push_back( vec3( a, b, c ) );// polar vertex
    // 中心を原点に
    {
        const vec3 offs( a*.5, b*.5, c*.5 );
        for( auto& ipos: *pl )
            ipos -= offs;
    }
    // キューブ形状表面として三角ポリゴンを紡ぐ
    // (2つのFAN形状を向き合わせる感じでキューブ形状を作ってる)
    int arr[]={0,1,6,5,4,3,2,1};
    int arr2[]={7,6,1,2,3,4,5,6};
    DecodeTriangleFanIndex( 8, arr, il );
    DecodeTriangleFanIndex( 8, arr2, il );
    return;
}

おっと、DecodeTriangleFanIndexは、2009年のこちらの日記→←を参照してほしい。
じゃ今日は手短にこの辺で。もう寝ろ!
(注意:右図の赤い矢印の向きはFANの定義方向を表すつもりだったが、これの向きが逆だった。第一象限から原点を見下ろす図の構図で行くと、赤い矢印の向きは図のCCWではなく、CWである。まあそれは上記ソースのarr, arr2の内容を見ればわかることではある。)
(後日記:で1年後に思ったのであるが、まずはクアッドメッシュとしてのインデックス形式を得てから、そっちのインデックスのとこだけ作りなおすのが速いねとか思ってみたり。その一年後の日記はここだ。)