すべてのモデルデータと2つのVBOに1つのVAOを使用するOpenGLコードがあります。最初のものは、位置と法線のような標準的な頂点属性、モデル行列の2番目の属性です。私はインスタンス化された描画を使用しているので、モデル行列をインスタンス化された配列(基本的に頂点属性です)として読み込みます。インスタンス化された配列を使用しているときにglVertexAttribPointer呼び出しを最小限に抑える方法は?
最初に標準頂点属性をVBOにロードし、すべてをglVertexAttribPointer
で設定します。次に、モデル行列を別のVBOにロードします。今私はglVertexAttribPointer
を描画ループに呼び出す必要があります。どうにか私はこれを防ぐことができますか?
コードは次のようになります。
// vertex data of all models in one array
GLfloat myvertexdata[myvertexdatasize];
// matrix data of all models in one array
// (one model can have multiple matrices)
GLfloat mymatrixdata[mymatrixsize];
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, myvertexdatasize*sizeof(GLfloat), myvertexdata, GL_STATIC_DRAW);
glVertexAttribPointer(
glGetAttribLocation(myprogram, "position"),
3,
GL_FLOAT,
GL_FALSE,
24,
(GLvoid*)0
);
glEnableVertexAttribArray(glGetAttribLocation(myprogram, "position"));
glVertexAttribPointer(
glGetAttribLocation(myprogram, "normal"),
3,
GL_FLOAT,
GL_FALSE,
24,
(GLvoid*)12
);
glEnableVertexAttribArray(glGetAttribLocation(myprogram, "normal"));
GLuint matrixbuffer;
glGenBuffers(1, &matrixbuffer);
glBindBuffer(GL_ARRAY_BUFFER, matrixbuffer);
glBufferData(GL_ARRAY_BUFFER, mymatrixsize*sizeof(GLfloat), mymatrixdata, GL_STATIC_DRAW);
glUseProgram(myprogram);
draw loop:
int vertices_offset = 0;
int matrices_offset = 0;
for each model i:
GLuint loc = glGetAttribLocation(myprogram, "model_matrix_column_1");
GLsizei matrixbytes = 4*4*sizeof(GLfloat);
GLsizei columnbytes = 4*sizeof(GLfloat);
glVertexAttribPointer(
loc,
4,
GL_FLOAT,
GL_FALSE,
matrixbytes,
(GLvoid*) (matrices_offset*matrixbytes + 0*columnbytes)
);
glEnableVertexAttribArray(loc);
glVertexAttribDivisor(loc, 1); // matrices are in instanced array
// do this for the other 3 columns too...
glDrawArraysInstanced(GL_TRIANGLES, vertices_offset, models[i]->num_vertices(), models[i]->num_instances());
vertices_offset += models[i]->num_vertices();
matrices_offset += models[i]->num_matrices();
私は1個のVBOで頂点データや行列を格納するアプローチを考えました。問題は、ストライドを正しく設定する方法です。私は解決策を考え出すことができませんでした。
ご協力いただければ幸いです。
場所は常に後続番号ですか? – mak
@mak:あなたはコードのすべてを投稿していないので、あなたの行列属性が実際には完全に受け入れられる 'mat4'だと仮定しました。そうであれば、4つの場所が順番に割り当てられます(https://www.opengl.org/wiki/Vertex_Attribute)。実際には、これらの場所をまったく取得するべきではありません。それらをシェーダで直接指定する必要があります。 –
場所を1回だけ取り出すときに場所を取得すると何が問題になりますか? – mak