VBO只是一塊內存,您可以通過將數據存放在顯卡中來使其更快運行。 (有些硬件使用VBO的系統內存,所以在這種情況下不會獲得太多的收益) 我也發現它總是使用VBO更清潔,但這有點個人喜好。
無論如何,你可以創建VBOs,然後改變它們裏面的數據,就像一塊RAM一樣,如果你需要改變每一幀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
}
EDIT得到具有顏色的示例
首先一些示例性數據,在這種情況下,三角形每個頂點的數據交織:
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變成別的東西也更改的數量...
免責聲明 這是在飛行中做,所以龍的提防。
有趣!所以海狸VBO只是幾何圖形,然後當你要畫一幀一幀地在VBO中使用該幾何圖形時,只需指定其他值,如紋理/顏色?如果我想設置單個三角形的顏色,這看起來如何? – dontWatchMyProfile
那麼在我的情況下,我實際上改變的是幾何,基本上將頂點變形爲每個關鍵幀來實現移動。在你的情況下,你將不得不改變每一幀的顏色信息,我會給我的答案添加一些東西。 – led42
感謝您的更新。僅處理2D幾何時,初始數據中是否需要頂點法線?你是什麼意思「創建/綁定/ MapBuffer後」 – dontWatchMyProfile