【问题标题】:OpenGL ES2 Vertex Array Objects helpOpenGL ES2 顶点数组对象帮助
【发布时间】:2011-06-20 13:43:42
【问题描述】:

我无法理解如何在 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 来解决这个问题。

【问题讨论】:

  • 你是在渲染过程中调用glBufferData吗?诚然,我不在移动平台或 ES-2.0 上工作,但我无法想象这怎么可能是个好主意。缓冲区对象保留其数据,直到明确告知包含其他数据。这就像每帧调用malloc 后跟memcpy 只是为了给某人一个数组。你做一次,然后继续把你分配的一个数组交给他们。
  • 我对动态数据执行此操作,对于静态数据,我将其缓冲一次并每帧绘制一次。
  • 我遇到了同样的问题,但无法解决。使用 VAO 时,我不断收到 1282 (GL_INVALID_OPERATION),但是 完全相同的命令glBindBufferglEnableVertexAttribArrayglVertexAttribPointer),当不使用时工作查找一个VAO。我开始得出结论,在 iOS 上使用交错数组时,VAO 的 do not 似乎适用于顶点缓冲区。或者我错过了一些非常小但至关重要的东西。

标签: ios opengl-es-2.0 vertex-buffer vertex-array


【解决方案1】:

很抱歉挖泥机,但我拖延了,你一直在我的谷歌搜索中占据首位。我确定你现在已经解决了...

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

初始化:

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, ...);

希望对您有所帮助。

【讨论】:

  • glBindBuffer(0); 是非法调用(必须先说哪个缓冲区,比如GL_ARRAY_BUFFER)。我看不到在你的绘图调用之前解除绑定缓冲区有什么帮助..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多