この節ではいよいよバッファを用いて描画を行います。前節まででほとんど準備は終わっているので、この節では本当にバッファをコマンドバッファにバインドするだけです。
コマンドバッファに頂点バッファをバインド(結びつけ)するためにはbindVertexBuffersメソッドを使います。bindPipelineでパイプラインを結びつけたのと同じような感じですね。
コマンドバッファに描画コマンドを記録している部分に以下の行を追加しましょう。
cmdBufs[i]->beginRenderPass(renderpassBeginInfo, vk::SubpassContents::eInline);
cmdBufs[i]->bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline.get());
cmdBufs[i]->bindVertexBuffers(0, { vertexBuf.get() }, { 0 }); // 追加
cmdBufs[i]->draw(3, 1, 0, 0);
cmdBufs[i]->endRenderPass();
bindVertexBuffersは一度に複数のバッファを結び付けることができます。(Buffersと複数形になっていますね!)また、バッファの中から用いるデータの位置を指定することもできます。ただし、今回は1つのバッファを単純にバインドしているだけなのでそれらは活用されていません。
第1引数はバッファをバインドする場所を指定します。バインディングというものがいくつもあって0,1,2,3…と番号が振られている、ということを前の節で説明したかと思いますが、その何番目からバインドするかということを示します。
例えば第1引数に「2」という数字を指定し、第2・第3引数でバッファA,B,Cという3つのバッファを指定した場合、
- バインディング2番にバッファA
- バインディング3番にバッファB
- バインディング4番にバッファC
という風にバインドされます。
第2引数・第3引数でバインドするバッファを指定します。それぞれ配列を渡しますが、この2つ配列の長さは等しくなければなりません。第2引数でバッファオブジェクト、第3引数で用いるデータの位置(バイト単位)を指定します。
今回はバッファの先頭からのデータを利用するので「0」を指定していますが、例えば100頂点以上のデータがvertexBufに記録されているとして「sizeof(Vertex) * 100」と指定すれば、101番目からの頂点データが利用されます。
これでシェーダにデータを渡す処理がようやく完成しました。では、渡されたデータを用いて描画するシェーダに変えましょう。5-1節で出した以下のコードに変えてください。glslcでシェーダの再コンパイルも忘れずに!
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec2 inPos;
void main() {
gl_Position = vec4(inPos, 0.0, 1.0);
}
コードを実行してみましょう。

今までと同じく三角形が描画できました。これまでと違うのは、この三角形の座標はデータで管理されているという点です。変数verticesの中身を以下のように変更してみましょう。
std::vector<Vertex> vertices = {
Vertex{-0.5f, -0.5f },
Vertex{ 0.5f, 0.0f },
Vertex{-0.5f, 0.5f }
};

シェーダのコードは変えていないのにデータの変更だけでちゃんと描画内容が変わりました!
今回のコードではまだメインのプログラムに数値を埋め込んでいますが、適切に実装すればファイルに頂点のデータを入れておいてそれを変数に読み込むことも出来るというのが分かるかと思います。モデルの読み込みに向けて大きく前進しました。