调用 glDrawElements 会导致访问冲突

calling glDrawElements causes access violation

本文关键字:访问冲突 glDrawElements 调用      更新时间:2023-10-16

我目前正在试图弄清楚 VBO 的东西是如何工作的,可悲的是这导致了可怕的问题:/

IM 从 .obj 文件加载数据(请参阅:http://pastebin.com/B8uibDvV .obj 文件)并(试图)将其放入 VBO 中

我绑定数据的代码如下所示:

//Generate Buffers
glGenBuffers(1, &this->glVerticesBufferID);
glGenBuffers(1, &this->glIndexBufferID);
//bind the buffers to set the data
glBindBuffer(GL_ARRAY_BUFFER, this->glVerticesBufferID);
glBufferData(GL_ARRAY_BUFFER, this->verticesList.size() * sizeof(GLfloat), 0, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->glIndexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indexList.size() * sizeof(GLshort), 0, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, this->verticesList.size(), this->verticesList.data()); 
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, this->indexList.size(), this->indexList.data()); 
//Clear binds 
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

最后,我用这个渲染一切:

glBindBuffer(GL_ARRAY_BUFFER, this->glVerticesBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->glIndexBufferID);
glEnableClientState(GL_VERTEX_ARRAY);
    glDrawElements(GL_TRIANGLES, this->indexList.size(), GL_UNSIGNED_SHORT, this->indexList.data());
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

最后,我在VisualStudio 2010的输出中收到访问冲突消息

0xC0000005:访问违规读取位置0x0147fbd8。

所以我的问题是如何解决这个问题?(或者如果我错了,如何做对)

---------------编辑1---------------

http://pastebin.com/DEbZH9iy

绑定数据

 glGenBuffers(1, &this->glVerticesBufferID);
 glBindBuffer(GL_ARRAY_BUFFER, this->glVerticesBufferID);
 glBufferData(GL_ARRAY_BUFFER, (this->verticesList.size() + this->textureCoordList.size() + this->normalsList.size()) * sizeof(GLfloat), 0, GL_STATIC_DRAW);
 glBufferSubData(GL_ARRAY_BUFFER,
                0,
                this->verticesList.size() * sizeof(GLfloat),
                this->verticesList.data()
               );
 glBufferSubData(
                GL_ARRAY_BUFFER, 
                this->verticesList.size() * sizeof(GLfloat), 
                this->normalsList.size() * sizeof(GLfloat), 
                this->normalsList.data()
               );
 glBufferSubData(
                GL_ARRAY_BUFFER, 
                (this->verticesList.size() + this->normalsList.size()) * sizeof(GLfloat), 
                this->textureCoordList.size() * sizeof(GLfloat),
                this->textureCoordList.data()
               );
 glBindBuffer(GL_ARRAY_BUFFER, 0);
 glGenBuffers(1, &this->glIndexBufferID);
 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->glIndexBufferID);
 glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indexList.size() * sizeof(GLushort), this->indexList.data(), GL_STATIC_DRAW);
 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

 pub_glVerticesBufferID = glVerticesBufferID;
 pub_glIndexBufferID = glIndexBufferID;

渲染部分:

 glBindBuffer(GL_ARRAY_BUFFER, this->glVerticesBufferID);
 glVertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), (GLvoid*)0);
 glNormalPointer(GL_FLOAT, 3 * sizeof(GLfloat), (GLvoid*)(this->verticesList.size() * sizeof(GLfloat)));
 glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), (GLvoid*)((this->normalsList.size() + this->verticesList.size()) * sizeof(GLfloat)));
 glBindBuffer(GL_ARRAY_BUFFER, 0);
 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->glIndexBufferID);
 glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);
 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

您可能没有初始化OpenGL-1.1之后引入的功能的入口点。在Windows中,仅指定OpenGL-1.1入口点,超出的所有内容都必须在运行时初始化。否则,将出现访问冲突。看看 GLEW 以获得一种方便的方法,只需 3 行代码即可完成这项繁琐的任务。

话虽如此,您的代码仍然有错误:

你需要告诉OpenGL它应该从缓冲区的确切位置获取它的元素。这是通过调用gl…Pointer函数来完成的,数据元素是缓冲区中的字节偏移量。您的代码错过了这一点。此外,glDrawElements不再期望指针也放置偏移量。

但是,绑定缓冲区对象时,这不应导致段错误/访问冲突。