gpt4 book ai didi

c++ - 错误的访问代码 1 glDrawElements

转载 作者:行者123 更新时间:2023-11-28 06:30:58 28 4
gpt4 key购买 nike

我试图通过批处理来绘制每一帧的东西。这意味着我必须使用我不熟悉的 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));

关于c++ - 错误的访问代码 1 glDrawElements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27590842/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com