1

我无法理解如何在 OpenGL ES2(在 iOS 上)中使用 VAO 并让它们工作。我当前的渲染设置如下所示(在伪代码中):

初始化:

foreach VBO:
    glGenBuffers();

渲染一个框架:

// Render VBO 1
glClear(color | depth);
glBindBuffer(GL_ARRAY_BUFFER, arrayVBO1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO1);
foreach vertex attribute:
    glVertexAttribPointer();
    glEnableVertexAttribArray();
glBufferData(GL_ARRAY_BUFFER, ...);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ...);
glDrawElements(GL_TRIANGLE_STRIP, ...);

// Render VBO 2
glClear(color | depth);
glBindBuffer(GL_ARRAY_BUFFER, arrayVBO2);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO2);
foreach vertex attribute:
    glVertexAttribPointer();
    glEnableVertexAttribArray();
glBufferData(GL_ARRAY_BUFFER, ...);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ...);
glDrawElements(GL_TRIANGLE_STRIP, ...);

这很好用,但是,两个 VBO 都具有完全相同的交错顶点属性结构,并且如您所见,我正在为每个 VBO 的每一帧设置和启用每个属性。Instruments 抱怨对 glVertexAttribPointer() 和 glEnableVertexAttribArray() 的冗余调用,但是当我将其中一个或两个移动到初始化阶段时,我要么在调用 glDrawElements 时得到 EXC_BAD_ACCESS,要么什么都没有绘制。

我的问题是我是否需要在每一帧都这样做,如果我不这样做为什么它不起作用,以及我将如何使用 VAO 来解决这个问题。

4

1 回答 1

0

很抱歉疏浚,但我拖延了,你一直在我的谷歌搜索中名列前茅。我确定你现在已经解决了...

正确的方法是只在数据变化时更新缓冲区,而不是每一帧。理想情况下,您只会更新已更改的缓冲区部分。此外,如果缓冲区被绑定,属性指针是缓冲区的偏移量。

初始化:

glGenBuffers()
foreach VBO:
   glBufferData()

更新/动画等:

glMapBuffer() //or something like this
buffer->vertex = vec3(1,2,3) // etc
glUnmapBuffer()

并渲染:

glBindFBO()
glClear(color | depth);

glBindBuffer(GL_ARRAY_BUFFER, arrayVBO1)
glVertexAttribPointer(GL_VERTEX,..., 0) // Buffer Offset = 0
glVertexAttribPointer(GL_TEXCOORD,..., sizeof(vertex)) // Buffer Offset = size of vertex

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO1);
glEnableVertexAttribArray(..., 0) // Buffer Offset = 0

glBindBuffer(0); // Unbind buffers, you don't need them here
glDrawElements(GL_TRIANGLE_STRIP, ...);

希望有帮助。

于 2012-03-19T06:39:42.160 回答