VBO - это просто часть памяти, вы используете ее для ускорения работы, располагая данные на видеокарте. (Некоторое оборудование использует системную память для VBO, поэтому в этом случае выиграть немного)
Я также считаю чище всегда использовать VBO, но это немного личное предпочтение.
В любом случае, вы можете создавать VBO, а затем изменять данные внутри них, так же, как часть оперативной памяти, если вам нужно менять все на VBO каждый кадр снова, это не дает выигрыша в производительности, но если вам нужно только время от времени менять материал или некоторые данные исправлены (скажем, ваши вершинные данные), тогда вы начинаете получать некоторые преимущества ...
например:
glGenBuffers(1, &vboObjects[vboGroupBeaver]);
glBindBuffer(GL_ARRAY_BUFFER, vboObjects[vboGroupBeaver]);
glBufferData(GL_ARRAY_BUFFER, beaverVerts*8*sizeof(GLfloat), 0, GL_STATIC_DRAW);
GLvoid* vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
NSString *path;
path = [[NSBundle mainBundle] pathForResource:@"beaver01" ofType:@"bin"];
NSFileHandle *model = [NSFileHandle fileHandleForReadingAtPath:path];
float vertice[8];
int counter = 0;
while (read([model fileDescriptor], &vertice, 8*sizeof(float))) {
memcpy(vbo_buffer, vertice, 8*sizeof(GLfloat)); // 0
vbo_buffer += 8*sizeof(GLfloat);
counter++;
}
NSLog(@"Vertices %1i",counter);
glUnmapBufferOES(GL_ARRAY_BUFFER);
Этот фрагмент кода загружает модель в VBO (vboGroupBeaver), в данном примере это первый ключевой кадр анимации.
Все данные теперь в VBO, если я сделаю это после:
glVertexPointer(3, GL_FLOAT, 8*sizeof(GLfloat), (GLvoid*)((char*)NULL));
glNormalPointer(GL_FLOAT, 8*sizeof(GLfloat), (GLvoid*)((char*)NULL+3*sizeof(GLfloat)));
glTexCoordPointer(2, GL_FLOAT,8*sizeof(GLfloat), (GLvoid*)((char*)NULL+6*sizeof(GLfloat)));
glDrawArrays(GL_TRIANGLES, 0, beaverVerts);
Я нарисовал бобра ... (Обратите внимание, что я использую данные вершин с чередованием, поэтому вызовы указателей имеют дополнительную информацию).
В вашем случае у вас будет Цветовой указатель вместо Текстурного указателя.
Теперь, если вы хотите изменить что-то, все, что вам нужно сделать, это glMapBufferOES на буфер var и использовать его для изменения только тех частей, которые вам нужны.
Что-то вроде:
vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
for (int i = start; i < end; i++) {
vbo_buffer += 6*sizeof(GLfloat); // offset to position
memcpy(vbo_buffer, whatYouWantToChange, 2*sizeof(GLfloat)); // change what you want, watch the size
}
РЕДАКТИРОВАТЬ приведите пример с цветом
Сначала некоторые примеры данных, в данном случае треугольник с чередованием данных на каждую вершину:
static const ColoredTriangle vertexData[] = {
{
{0.0, 0.0, 0.0}, // Vertex 0
{0.0, 0.0, 1.0}, // Normal
{1.0, 0.0, 0.0, 1.0} // Color
},
{
{0.0, 480.0, 0.0}, // Vertex 1
{0.0, 0.0, 1.0}, // Normal
{1.0, 1.0, 0.0, 1.0} // Color
},
{
{320.0, 0.0, 0.0}, // Vertex 2
{0.0, 0.0, 1.0}, // Normal
{1.0, 1.0, 1.0, 1.0} // Color
}
Скопируйте объект в vbo (после создания / привязки / MapBuffer.
memcpy(vbo_buffer, vertexData, 10*3*sizeof(float));
Нарисуй вещь
glVertexPointer(3, GL_FLOAT, 10*sizeof(GLfloat), (GLvoid*)((char*)NULL));
glNormalPointer(GL_FLOAT, 10*sizeof(GLfloat), (GLvoid*)((char*)NULL+3*sizeof(GLfloat)));
glColorPointer(4, GL_FLOAT, 10*sizeof(GLfloat), (GLvoid*)((char*)NULL+6*sizeof(GLfloat)))
glDrawArrays(GL_TRIANGLES, 0, beaverVerts);
Итак, теперь у вас нарисован треугольник с чередованными данными из VBO.
Теперь на каждом кадре вы хотите что-то сделать, просто измените данные.
GLvoid* vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
vbo_buffer += 6*sizeof(GLfloat); // position the buffer at the first vertex color data
for (int i = 0; i < 3; i++) {
memcpy(vbo_buffer, newColor, 4*sizeof(GLfloat));
vbo_buffer += 10*sizeof(GLfloat); // skip the stripe
}
glUnmapBufferOES(GL_ARRAY_BUFFER);
Затем нарисуйте снова, и вы просто изменили информацию о цвете.
В зависимости от количества изменений, которые вы собираетесь сделать, может быть лучше изменить GL_STATIC_DRAW на что-то еще ...
Ответственность
Это было сделано на лету, так что остерегайтесь драконов.