出于某种原因,OpenGL VAO指向地址0

时间:2019-02-15 05:33:26

标签: c++ opengl vbo vao

我的VAO无法正确绑定时遇到了麻烦(至少这是我认为的情况)。

所以,我正在做的是一个类,该类根据一些原始数据创建vbo和vao,在这种情况下,该类指向浮点数数组的指针。

RawModel* Loader::loadToVao(float* positions, int sizeOfPositions) {
    unsigned int vaoID = this->createVao();
    this->storeDataInAttributeList(vaoID, positions, sizeOfPositions);
    this->unbindVao();
    return new RawModel(vaoID, sizeOfPositions / 3);
}

unsigned int Loader::createVao() {
    unsigned int vaoID;
    glGenVertexArrays(1, &vaoID);
    glBindVertexArray(vaoID);

    unsigned int copyOfVaoID = vaoID;
    vaos.push_back(copyOfVaoID);
    return vaoID;
}

void Loader::storeDataInAttributeList(unsigned int attributeNumber, float* data, int dataSize) {
    unsigned int vboID;
    glGenBuffers(1, &vboID);
    glBindBuffer(GL_ARRAY_BUFFER, vboID);
    glBufferData(GL_ARRAY_BUFFER, dataSize * sizeof(float), data, GL_STATIC_DRAW);
    glVertexAttribPointer(attributeNumber, 3, GL_FLOAT, false, 0, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    unsigned int copyOfVboID = vboID;
    vbos.push_back(copyOfVboID);
}

void Loader::unbindVao() {
    glBindVertexArray(0);
}

RawModel只是一个类,应该接受浮点数数组并创建vbo和vao。我正在使用的向量vbosvaos就在那里跟踪所有id,以便在使用完所有数据后就可以删除它们。

我有90%的信心可以正常运行。但是,当我尝试运行一些将其绘制的代码时,OpenGL正在退出,因为它正尝试从地址0x0000000读取并且它不喜欢这样做。我将在此之前从代码创建的原始模型传递给渲染器中的函数,如下所示:

void Renderer::render(RawModel* model) {
    glBindVertexArray(model->getVaoID());
    glEnableVertexAttribArray(0);   
    glDrawArrays(GL_TRIANGLES, 0, model->getVertexCount());
    glDisableVertexAttribArray(0);
    glBindVertexArray(0);
}

我在创建vao以及尝试检索vao时已检查以确保VaoID相同。其实是一样的。

我不知道如何读取OpenGL当前绑定为顶点attrib数组的当前存储的地址,因此我无法测试它是否指向顶点数据。我很确定由于某种原因它还是指向地址0。

编辑:

事实证明,不是硬编码0才是问题。它消除了Visual Studio和OpenGL给我的错误,但实际错误在其他地方。我意识到我应该在上面的某些代码中将vaoID作为attributeNumber进行传递,而本来应该传递硬编码的0。我在这里编辑了代码:

RawModel* Loader::loadToVao(float* positions, int sizeOfPositions) {
    unsigned int vaoID = this->createVao();
    this->storeDataInAttributeList(0, positions, sizeOfPositions);
    this->unbindVao();
    return new RawModel(vaoID, sizeOfPositions / 3);
}

我将行this->storeDataInAttributeList(vaoID, positions, sizeOfPositions);更改为上面的代码,硬编码为0。因此,事实证明,我什至没有将数组绑定到vbo中的正确位置。但是,更改后效果很好。

1 个答案:

答案 0 :(得分:2)

您应该将顶点属性索引与glVertexAttribPointerglEnableVertexAttribArrayglDisableVertexAttribArray结合使用,但是您需要使用的是:

  • glVertexAttribPointer一起使用的VAO ID
  • 0glEnableVertexAttribArray一起使用的硬编码glDisableVertexAttribArray(虽然您不确定该值,但这不一定是错误)

如果不确定索引值(例如,如果未在着色器中指定布局),则可以通过glGetAttribLocation调用获取它:

// The code assumes `program` is created with glCreateProgram
// and `position` is the attribute name in your vertex shader

const auto index = glGetAttribLocation(program, "position");

然后,您可以将index用于上述呼叫。