错误的访问代码 1 glDrawElements
Bad access code 1 glDrawElements
我正在尝试通过批处理来绘制每一帧的内容。这意味着我必须使用我不熟悉的glBufferSubData()
。我认为我在替换数据时做错了什么,导致调用glDrawElements
时访问冲突。
我的设置代码:
GL_TRY(glGenVertexArrays(1, &mVao));
GL_TRY(glBindVertexArray(mVao));
GL_TRY(glGenBuffers(1, &mEbo));
GL_TRY(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mEbo));
GL_TRY(glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, NULL, GL_STREAM_DRAW));
GL_TRY(glGenBuffers(1, &mVbo));
GL_TRY(glBindBuffer(GL_ARRAY_BUFFER, mVbo));
GL_TRY(glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_STREAM_DRAW));
GLint posAttrib;
GL_TRY(posAttrib = glGetAttribLocation(mShader.getProgram(), "position"));
GL_TRY(glEnableVertexAttribArray(posAttrib));
GL_TRY(glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0));
GLint texAttrib;
GL_TRY(texAttrib = glGetAttribLocation(mShader.getProgram(), "texCoords"));
GL_TRY(glEnableVertexAttribArray(texAttrib));
GL_TRY(glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))));
GL_TRY(glBindVertexArray(0));
我的绘图代码:
GL_TRY(glBindVertexArray(mVao));
GL_TRY(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mEbo));
GL_TRY(glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, NULL, GL_STREAM_DRAW));
GL_TRY(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices.size() * sizeof(GLuint), &indices[0]));
GL_TRY(glBindBuffer(GL_ARRAY_BUFFER, mVbo));
GL_TRY(glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_STREAM_DRAW));
GL_TRY(glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(Vertex), &vertices[0]));
GL_TRY(glDrawElements(GL_TRIANGLES, (GLsizei)indices.size(), GL_UNSIGNED_INT, 0));
GL_TRY(glBindVertexArray(0));
我一直在检查所有内容并尝试调试一段时间,但我就是找不到我做错了什么。
为了记录,GL_TRY
是一个报告任何 OpenGL 错误的宏。我什么都没有得到。
缓冲区
的大小始终为 0:
GL_TRY(glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_STREAM_DRAW));
GL_TRY(glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(Vertex), &vertices[0]));
要glBufferData()
的第二个参数指定缓冲区的大小,在本例中为 0。
顾名思义,glBufferSubData()
只能替换缓冲区的子部分。它无法更改大小。所以在此调用后大小仍然是 0。您实际上应该从此调用中得到一个GL_INVALID_VALUE
错误。
查看这些入口点的一种方法是:
-
glBufferData()
分配缓冲区内存,并选择性地用数据填充它。当使用NULL
作为数据指针调用时,对 CPU 内存的类似调用是malloc()
。 -
glBufferSubData()
将数据写入已分配的缓冲区内存。它不会更改分配的内存量。对 CPU 内存的类似调用是memcpy()
。
要完成这项工作,您需要将大小传递给 glBufferData()
:
GL_TRY(glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), NULL, GL_STREAM_DRAW));
GL_TRY(glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(Vertex), &vertices[0]));
在这种情况下,使用 glBufferSubData()
并没有多大意义。您也可以将数据传递给此处glBufferData()
。 glBufferSubData()
主要在只想替换部分缓冲区时有用。
若要在机箱中使用glBufferSubData()
,只需在设置过程中调用glBufferData()
一次。只要大小恒定,这将很好地工作,或者您至少可以建立一个良好的上限。否则,当大小更改时,您将不得不再次调用它。但是,如果您想有效地使用glBufferSubData()
,这仍然必须比每次绘制调用的频率低得多。否则,最好将数据指定为glBufferData()
调用的一部分:
GL_TRY(glBufferData(GL_ARRAY_BUFFER,
vertices.size() * sizeof(Vertex), &vertices[0]), GL_STREAM_DRAW));
相关文章:
- glDrawElements GL 错误类型 = 0x824c,严重性 = 0x9146,消息 = GL_INVALID
- 使用 glDrawElements 绘制一个 std::vector
- GLSL C++ glVertexAttribPointer & glDrawElements return GL_INVALID_OPERATION
- glDrawElements成功,但glDrawElementsInstance失败并GL_INVALID_OPERAT
- 将VAO与glDrawElements一起使用
- glDrawElements 具有每个刻面颜色
- glDrawElements() 不起作用
- iOS GL ES exc_bad_access on glDrawElements
- OSX上的Gldrawelements具有很高的CPU使用情况
- 无法让 openGL 的 glDrawElements 与几何着色器一起使用
- 调用glDrawElements时出现Segfault
- glDrawElements not drawing
- glDrawElements 在驱动程序中崩溃 | 调试提示
- 在gldrawelements中,索引参数的含义是什么
- glDrawElements只会导致与GL_PATCHES的访问冲突
- glDrawElements中的第四个论点是WHAT
- glDrawElements 失败并出现错误GL_INVALID_OPERATION
- gldrawelements仅画一半四分之一
- OpenGL and GL_Blend with glDrawElements
- 如何在使用glDrawElements时将法线传递到GLSL中的顶点着色器