【问题标题】:OpenGL VAO is pointing to address 0 for some reason由于某种原因,OpenGL VAO 指向地址 0
【发布时间】:2019-07-09 05:39:29
【问题描述】:

我的 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 当前绑定为顶点属性数组中的地址,因此我无法测试它是否指向顶点数据。我很确定它出于某种原因指向地址 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 中的正确位置。但是,更改后它工作正常。

【问题讨论】:

  • 不要在你的问题中添加你认为可以解决问题的东西。在问题的答案部分为此创建一个答案。而glEnableVertexAttribArray(model->getVaoID()); 肯定是不对的,如果你用一个参数调用glEnableVertexAttribArray 那么这是通用顶点属性的索引,而不是顶点数组的名称(id)。
  • 正如@t.niese 所说,您的修复不正确。如果您可以将着色器添加到帖子中,我将更新我的答案,以便您可以复制/粘贴它。
  • @MarcinZawiejski 我修复了代码。原来它不是硬编码的 0,而且我做的第一个编辑是完全错误的。我将您的回答保留为已接受,因为您的 cmets 很有帮助。
  • @GabeAmbrosio 正如我在回答中所说,硬编码的 0 不一定是错误,因为如果您的着色器在 0 索引处定义属性但您没有包含您帖子中的着色器,所以我无法准确回答。

标签: c++ opengl vbo vao


【解决方案1】:

您应该使用带有glVertexAttribPointerglEnableVertexAttribArrayglDisableVertexAttribArray 的顶点属性索引,但您得到的是:

  • glVertexAttribPointer 一起使用的VAO id
  • 硬编码0glEnableVertexAttribArrayglDisableVertexAttribArray 一起使用(如果您确定值,这不一定是错误)

如果您不确定索引值(例如,如果您没有在着色器中指定布局),那么您可以通过 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 与上述调用一起使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-09
    • 2021-08-05
    • 2021-04-13
    • 1970-01-01
    • 2020-03-26
    相关资源
    最近更新 更多