我有一个错误使我花了很多时间进行修复。
我不断得到EXC_BAD_ACCESS和对memmove错误的引用,没有任何进一步的描述,直到我评论了以下行:
[self loadShaders];
glGenVertexArraysOES(1, &_vao);
glBindVertexArrayOES(_vao);
// Vertex Buffer
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glEnableVertexAttribArray(ATTRIB_TEXTURE);
glVertexAttribPointer(ATTRIB_TEXTURE, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7));
// Index Buffer
glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,0);
////////// COMMENTED THIS ONE //////////////
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);//
////////////////////////////////////////////
glBindVertexArrayOES(0);
我以为将缓冲区绑定到0意味着要取消绑定它,所以我真的不明白如何使我的应用程序崩溃。
感谢您的信息!我只是不留这个顾虑...
我的结构:
const Vertex Vertices[4] = {
{{0.75, -1, 0}, {1, 0, 0, 1}, {0.125, 0.833496}},
{{0.75, 1, 0}, {0, 1, 0, 1}, {0.125, 1}},
{{-0.75, 1, 0}, {0, 0, 1, 1}, {0, 1}},
{{-0.75, -1, 0}, {0, 0, 0, 1}, {0, 0.833496}},
};
const GLushort Indices[6] =
{
0, 1, 2,
2, 3, 0
};
最佳答案
从代码中看,该函数似乎在某个初始化例程中,在此例程中初始化属性数据,该属性数据存储在绑定的VAO中,因此在绘制时只需要绑定VAO。
VAO依次封装绘制VBO所需的所有状态,这些状态是您的属性(由gl(En/Dis)ableVertexAttribArray
设置),属性源和属性(由glVertexAttribPointer
设置),和(当前绑定的索引缓冲区)(由glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)
设置)的启用标志)。请注意,它不存储当前绑定的顶点缓冲区,因为此信息存储在属性状态中。
因此,发生的事情是,您创建并绑定了索引缓冲区,设置了它的数据,然后取消绑定它,而VAO仍然处于 Activity 状态。因此,VAO状态将存储GL_ELEMENT_ARRAY_BUFFER
的0
绑定。当你现在用
glBindVertexArrayOES(_vao);
glDrawElements(...);
没有绑定的缓冲区,并且
glDrawElements
失败,因为VAO不能与客户端数组一起使用。您要么必须对索引数据使用VBO,要么绘制未索引的基元(使用glDrawArrays
)。都不会
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBindVertexArrayOES(_vao);
glDrawElements(...);
之所以起作用,是因为绑定索引缓冲区在绑定时被VAO覆盖(其索引缓冲区是
0
)。如果先绑定VAO,然后绑定索引缓冲区,则该方法将起作用,但这只能避免该问题。从概念上讲,绑定的
GL_ELEMENT_ARRAY_BUFFER
是VAO状态的一部分,因此,不应在VAO初始化例程中将其绑定到0
(仅在不需要任何索引数据的情况下)。使用VAO时,也不允许将客户端数组用于索引或顶点数据。如果您不想绘制索引的几何图形,则只需使用glDrawArrays
而不是glDrawElements
,但无论如何索引缓冲区都已过时。关于ios - 为什么将GL_ELEMENT_ARRAY_BUFFER绑定(bind)到0会产生内存错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10545479/