OpenGL も現在は 4.4 までバージョンが上がりました。自分が知っているのは 3.3 の頃までで、そのときですらジオメトリシェーダーを扱うプログラムに関して調べた程度でした。最近のものでは DirectX 11との対抗もあってか、ずいぶんと機能が増えて、また、描画の方法も従来とは変わってきたので、改めて勉強をしてみます。
VertexArrayObject (VAO)
DirectX9でいうところの VertexDeclaration に相当する物は OpenGL では存在せず、代わりに自分で glVertexAttribPointer や glEnableVertexAttribArray で指定していました。これは今も変わらないのですが、設定を VAO (Vertex Array Object)というもので保存しておけるようになっています。この VAO は DirectXでいうところの VertexDeclaration や、InputLayout に相当するんじゃないかと思います。
そのVAOの使い方はこのような感じです。頂点バッファとしての VBO を作成し、バインドした状態で VAO の設定を行います。
Vertex vertices[] = { { 0.0f, 0.0f, 0.0f, 0xFFFFFFFFu }, { 0.0f,-1.0f, 0.0f, 0xFF00FFFFu }, { 1.0f, 0.0f, 0.0f, 0xFFFFFF00u }, }; glGenBuffers( 1, &vboId ); glBindBuffer( GL_ARRAY_BUFFER, vboId ); glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW ); glGenVertexArrays( 1, &vaoId ); glBindVertexArray( vaoId ); int32_t offset = 0; glVertexAttribPointer( locPos, 3, GL_FLOAT, false, sizeof(Vertex), (NULL)+offset ); offset += sizeof(float)*3; glVertexAttribPointer( locCol, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (NULL)+offset ); offset += sizeof(uint8_t)*4; glEnableVertexAttribArray( locPos ); glEnableVertexAttribArray( locCol );
そしてこのVAO を使っているときには、頂点バッファの設定まで終わっているようなので、描画の際には以下のようにして描画することができます。
glBindVertexArray( vaoId ); glUseProgram( shaderProgram ); glDrawArrays( GL_TRIANGLES, 0, 3 );
簡単になりました。 vao をバインドして、シェーダーをセットして、描画コマンド発行で終わりです。
今までは 頂点バッファのセットとVertexAttribPointerの設定の部分が行数として多めにあったので、ずいぶんとすっきりした印象です。
(ただしインデックスバッファはこのVAOに含まれない点は注意しておくべきポイントとなります)
シェーダーについて
”#version 130” 以降が設定されているとするならば、attribute や varying の指定がなくなり、in, out で設定するようになったところが大きな変更といえると思います。
他にも、ピクセルシェーダーの色出力について、gl_FragColor に出力しないで、出力変数をプログラムで指定するようになっています。なお次回以降に説明するであろう定数バッファ(Uniform Block)については、”#version 140”の指定が必要となります。
glBindFragDataLocation( shaderProgram, 0, "out_color0" ); // 色が格納されるout変数名
次回予定
今回はとりあえずの三角形が描画できるまでのAPIまでをやってみました。3Dグラフィックスとなると行列を設定したりライティング用のパラメータがあったりとするので、それを次回にやってみたいと思います。
コメント