generated at
GLFLによるOpenGL入門:第5章 図形の描画
5.1 OpenGL の図形データ
図形データは頂点属性(attributeで表す)
位置、色、法線ベクトル
attributeを転送されるGPUメモリを頂点バッファという
頂点バッファを管理する仕組みを頂点バッファオブジェクトという
多分これは誤植で頂点バッファなのでは?基素

attributeにはいろいろ与えられる
複数の頂点バッファオブジェクトを組み合わせ管理するためにVertex Array Object(VAO)を使う
「図形データ」の描画
描画手順
>(1) glGenVertexArrays() で頂点配列オブジェクトを作成する。
>(2) 作成した頂点配列オブジェクトを glBindVertexArray() で結合する
構造体を登録する
>(3) glGenBuffers() で頂点バッファオブジェクトを作成する。
>(4) 作成した頂点バッファオブジェクトを glBindBuffer() で結合する
>(5) glBufferData() で頂点バッファオブジェクトにデータ (頂点属性) を転送する
>(6) 頂点バッファオブジェクトを glVertexAttribPointer() で attribute 変数に関連づける
>(7) 頂点配列オブジェクトを結合して描画命令 (ドローコール) を実行する

完成したプログラムを眺めてみると、1-6は図形データObjectのコンストラクタで実装されている
cpp
glGenVertexArrays(1, &vao); // (1) glBindVertexArray(vao); // (2) glGenBuffers( // (3) 1, //作成するVBOの数 &vbo // VBOを格納する配列の先頭アドレス ); // VBOの内容を描画に使う頂点属性として使うのでGL_ARRAY_BUFFERを指定する glBindBuffer(GL_ARRAY_BUFFER, vbo); // (4) // VBOのメモリを確保し、データ(ここではvertex)を転送する glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertexcount, vertex, GL_STATIC_DRAW); //(5) // 結合されているVBOをvertex shaderのin変数(attribute変数)から参照できるようにする // attribute変数がデータを取り出すVBOを設定する glVertexAttribPointer( // (6) // glBindAttribLocation で指定したattribute変数の場所 // vertex shaderのメンバpositionのindexは0に指定しているのでこっちも0にする 0, size, GL_FLOAT, GL_FALSE, 0, 0);
(7)は Shape->draw() で実行される
作成したプログラムのよくわからない点は、(2)がObjectのコンストラクタ以外の他にdraw()の直前に再度指定していること
5.2.4 頂点配列オブジェクトの作成

VBOとattribute変数の紐付け
glVertexAttribPointer でのindexを glBindAttribLocation のindexと同じにしなければいけない
まず、これらがvertex shaderとプログラムのオブジェクト(position)が紐づいている
point.vert
#version 150 core in vec4 position; void main() { gl_Position = position; }
cpp
glBindAttribLocation( program, 0, // index "position" // point.vertのattribute変数の名前(in vec4 position) );
Object.h
Class Object { // VAO, VBOを定義 public: Object(GLint size, GLsizei vertexcount, const Vertex *vertex) { // 略 glVertexAttribPointer( // glBindAttribLocation で指定したattribute変数の場所 // vertex shaderのメンバpositionのindexは0に指定しているのでこっちも0にする 0, // index size, GL_FLOAT, GL_FALSE, 0, 0);
このObjectがどうつながるのかわかっていない基素
>頂点バッファに関する処理がどのような流れで行なわれていくのかを時系列に並べてみると、おおよそ次のような流れになります。
>
> 頂点の各情報をいったん配列に格納
> WebGL のメソッドを使って VBO を生成
> WebGL のメソッドを使い VBO に配列のデータを転送
> 頂点シェーダ内の attribute 変数と VBO を紐付ける
VBOのindex 0と、vertex shaderのin変数 position glBindAttribLocation() でinexを指定してbindされる
glBindAttribLocation()のindexはなんのindexなんだっけ?
objectの使い方
Object::Vertex型の配列 rectangleVertex を作るときの型の指定に利用
main.cpp
// 矩形の頂点の位置 constexpr Object::Vertex rectangleVertex[] = { {-0.5f, -0.5f}, {0.5f, -0.5f}, {0.5f, 0.5f}, { -0.5f, 0.5f } };
図形の描画クラスのコンストラクタ
Shape.h.cpp
Shape(GLint size, GLsizei vertexcount, const Object::Vertex *vertex) : // 初期化する object(new Object(size, vertexcount, vertex)), vertexcount(vertexcount) { }
変数objectをObjectで補完している
図形を描画する時にはあらかじめVAOを結合しておく必要がある
Shapeを作成するときにObjectのコンストラクタで
Shapeをdrawすると glBindVertexArray(vao) が呼ばれる
これ呼ぶ必要あるの?基素
ある。別の図形を書く前にbindしなおしておかないと他の図形の頂点情報が混じる可能性がある
vaoとvboがどう紐づいているの?陽に紐づけていないけど基素
vaoをbindするとそのあとはvaoに頂点情報が登録されるようだ
>バインドが完了すると、ここから先に行うすべての頂点関連処理(主に Attribute 系)を通じて VAO に頂点情報が登録されていきます。先ほど登場した自前の関数の中身で行っていたように、gl.bindBufferやgl.enableVertexAttribArray、gl.vertexAttribPointerなどを適宜呼び出しましょう。これらのメソッドが呼び出されるたびに VAO に情報がひとまとめにされて格納されていきます。
Shape->draw() でvaoをバインドし直しているのも別の図形を書く前にbindしなおしておかないと他の図形の頂点情報が混じる可能性があるということだろう
この文章は、vaoをbindした後にvboをbindするとvaoの管理下にvboがおかれるという意味
>頂点配列オブジェクトを結合 (glBindVertexArray()) した後、頂点バッファオブジェクトを結合 (glBindBuffer()) することによって、頂点配列オブジェクトに頂点バッファオブジェクトが組み込まれます。

5.2.5 描画の実行

描画する図形データを保持したVAOを基本図形の種類を選んで描画する
やっと図形を出すことができた
ここまで書かないと試せないのは嫌だなぁ