glDrawElements使用VBO提供EXC_BAD_ACCESS

时间:2014-10-29 17:08:16

标签: c++ opengl glsl

我刚开始学习opengl,我正在尝试实施VBO。

这就是我正在做的事情:

在迭代之前的主方法中,

为每个网格我初始化它的VBO。 网格 - > pos和网格 - >范数包含三角形的点和法线以及网格的四边形。 mesh->三角形和mesh-> quad包含索引。

for (auto mesh : scene->meshes)
{
    mesh->vboPos = 0;
    glGenBuffers (1, &mesh->vboPos);
    glBindBuffer (GL_ARRAY_BUFFER, mesh->vboPos);
    glBufferData (GL_ARRAY_BUFFER, 3 * mesh->pos.size() * sizeof(GL_FLOAT), mesh->pos.data(), GL_STATIC_DRAW);

    mesh->vboNorm = 0;
    glGenBuffers (1, &mesh->vboNorm);
    glBindBuffer (GL_ARRAY_BUFFER, mesh->vboNorm);
    glBufferData (GL_ARRAY_BUFFER, 3 * mesh->norm.size() * sizeof(GL_FLOAT), mesh->norm.data(), GL_STATIC_DRAW);

    mesh->vbiTriangle = 0;
    glGenBuffers (1, &mesh-> vbiTriangle);
    glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh-> vbiTriangle);
    glBufferData (GL_ELEMENT_ARRAY_BUFFER, 3 * mesh->triangle.size() * sizeof(GL_UNSIGNED_INT), mesh->triangle.data(), GL_STATIC_DRAW);

    mesh->vbiQuad = 0;
    glGenBuffers (1, &mesh->vbiQuad);
    glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh->vbiQuad);
    glBufferData (GL_ELEMENT_ARRAY_BUFFER, 4 * mesh->quad.size() * sizeof(GL_UNSIGNED_INT), mesh->quad.data(), GL_STATIC_DRAW);
}

while(not glfwWindowShouldClose(window))
{
    ...
}

在阴影方法内部之后,我为每个网格调用绘图。这就是网格代码的样子:

struct Mesh {
frame3f         frame = identity_frame3f;   // frame
vector<vec3f>   pos;                        // vertex position
vector<vec3f>   norm;                       // vertex normal
vector<vec3i>   triangle;                   // triangle
vector<vec4i>   quad;                       // quad
Material*       mat = new Material();       // material

GLuint vboPos = 0;
GLuint vboNorm = 0;
GLuint vbiTriangle =0;
GLuint vbiQuad =0;

int count = 0;

void draw()
{
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, vboPos);
    glBindBuffer(GL_ARRAY_BUFFER, vboNorm);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbiTriangle);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbiQuad);
    glEnableClientState(GL_VERTEX_ARRAY);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glDrawElements(GL_TRIANGLES, triangle.size() * 3, GL_UNSIGNED_INT, 0);
    glDrawElements(GL_QUADS, quad.size() * 4, GL_UNSIGNED_INT, 0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
}

我真的不知道造成这个问题的原因是什么,但我很确定我不了解VBO是如何工作的。你能开导我吗?

1 个答案:

答案 0 :(得分:3)

你试图在这里做太多事情,我感觉驱动程序正在试图读取错误的元素数组的数组。

您的绘图功能需要重写:

void draw()
{
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    /* Setup your Position array */
    glBindBuffer(GL_ARRAY_BUFFER, vboPos);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    /* Then setup your Normal array */
    glBindBuffer(GL_ARRAY_BUFFER, vboNorm);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);


    /* DO NOT DO THIS -- you are using generic vertex attributes. */
    //glEnableClientState(GL_VERTEX_ARRAY);


    /* First the Triangles */
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbiTriangle);
    glDrawElements(GL_TRIANGLES, triangle.size() * 3, GL_UNSIGNED_INT, 0);

    /* Now the Quads */
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbiQuad);
    glDrawElements(GL_QUADS, quad.size() * 4, GL_UNSIGNED_INT, 0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
}