У меня есть некоторая путаница с использованием VAO (объект массива вершин) для нескольких объектов (около 200 объектов, 15 из которых видимы одновременно, каждый из которых имеет свою собственную вершину и буфер индекса). Ниже моя функция рендеринга
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(0.50f, 0.50f, 0.50f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[super drawLines];
for(int i=0; i< self.numberofBars; i++) //numberofBars
{
// Render the object
[self.barShaderProg use];
iVBarNode *temp = [theBars objectAtIndex:i];
_modelViewProjectionMatrix = GLKMatrix4Multiply(ProjectionView, modelMatrix);
_modelViewProjectionMatrix = GLKMatrix4Multiply(_modelViewProjectionMatrix, temp.modelMatrix);
GLKMatrix4 modeltotalMatrix = GLKMatrix4Multiply(modelMatrix, temp.modelMatrix);
GLKMatrix4 modelViewMatrix = GLKMatrix4Multiply(ViewMatrix, modeltotalMatrix);
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0,_normalMatrix.m);//
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEW_MATRIX], 1, 0, modelViewMatrix.m);
glUniform4f(uniforms[COLOR_VECTOR], temp.barColor.r, temp.barColor.g, temp.barColor.b, temp.barColor.a);
//bind corresponding buffer before drawing
glBindBuffer(GL_ARRAY_BUFFER, [temp getVertexID]);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), BUFFER_OFFSET(12));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, [temp getIndexID]);
glDrawElements(GL_TRIANGLES, [temp.bar getIndicesSize], GL_UNSIGNED_SHORT, (void*)0);
}
if(self.translation>0)
{
self.paused = NO;
}
else{
self.paused = YES;
}
}
Это прекрасно работает. После анализа моего кода в анализаторе OpenGLES он показал, что для получения выгоды от них можно использовать VAO, поскольку вызовы glVertexAttribPointer были избыточными (одинаково для всех). Но я просто не могу понять, можно ли их использовать с разными объектами буфера вершин. Большинство примеров, которые я нашел в Интернете, используют их только с одним VBO или двумя VBO, где второй VBO определяет другой атрибут, а не тот же атрибут, что и в моем случае. Я попытался привязать каждый индекс буфера вершин, который я генерировал для своего объекта с одним VAO, но он не работал, как показано ниже
-(void) configureVertexArrayObject
{
// Create and bind the vertex array object.
glGenVertexArraysOES(1,&vertexArrayObject);
glBindVertexArrayOES(vertexArrayObject);
for(int i=0;i<self.numberofBars;i++)
{
iVBarNode *myNode = [theBars objectAtIndex:i];
glBindBuffer(GL_ARRAY_BUFFER, [myNode getVertexID]);
// Configure the attributes in the VAO
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), BUFFER_OFFSET(12));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, [myNode getIndexID]);
}
// Bind back to the default state.
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArrayOES(0);
}
вот как я рендер
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glClearColor(0.50f, 0.50f, 0.50f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[super drawLines];
glBindVertexArrayOES(vertexArrayObject);
for(int i=0; i< self.numberofBars; i++) //numberofBars
{
// Render the object
[self.barShaderProg use];
iVBarNode *temp = [theBars objectAtIndex:i];
_modelViewProjectionMatrix = GLKMatrix4Multiply(ProjectionView, modelMatrix);
_modelViewProjectionMatrix = GLKMatrix4Multiply(_modelViewProjectionMatrix, temp.modelMatrix);
GLKMatrix4 modeltotalMatrix = GLKMatrix4Multiply(modelMatrix, temp.modelMatrix);
GLKMatrix4 modelViewMatrix = GLKMatrix4Multiply(ViewMatrix, modeltotalMatrix);
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0,_normalMatrix.m);//
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEW_MATRIX], 1, 0, modelViewMatrix.m);
glUniform4f(uniforms[COLOR_VECTOR], temp.barColor.r, temp.barColor.g, temp.barColor.b, temp.barColor.a);
//all buffer associated with VAO now
glDrawElements(GL_TRIANGLES, [temp.bar getIndicesSize], GL_UNSIGNED_SHORT, (void*)0);
}
glBindVertexArrayOES(0);
if(self.translation>0)
{
self.paused = NO;
}
else{
self.paused = YES;
}
}
Во второй попытке я попытался указать только макет для VAO, используя glVertexAttribPointer () для вершин и нормалей (без указания идентификаторов VBO и IBO), и выполнить рендеринг, как я делал без VAO (первый код рендеринга выше), но теперь я не указывал макет вершин с помощью glVertexAttribPointer (), поскольку я уже упоминал об этом в VAO (на самом деле, это был весь смысл использования VAO). Оба этих подхода дали мне объекты одинакового размера, заставив меня подумать, что каким-то образом VAO дублирует геометрию для всех моих объектов. Все мои объекты имеют одинаковую геометрию, но разную высоту. Теперь у меня есть один вариант - иметь одну вершину и объект буфера индекса, и я могу масштабировать по высоте и позиционировать объекты в зависимости от того, что мне нужно. Тем не менее, я хотел бы знать, что на самом деле содержит VAO, а что нет, и есть ли способ заставить его работать.