OpenGL VAO почему-то указывает на адрес 0 - PullRequest
0 голосов
/ 15 февраля 2019

У меня проблемы с тем, что мой 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.Векторы vbos и vaos, которые я использую, просто предназначены для отслеживания всех идентификаторов, чтобы я мог удалить их, как только закончу, используя все данные.

Я на 90% уверен, что все это должно работать правильно.Тем не менее, когда я пытаюсь запустить какой-то код, который его рисует, OpenGL завершает работу, потому что он пытается читать по адресу 0x0000000, и ему это не нравится.Я передаю необработанную модель, которую я создал из кода до этого, в функцию моего рендерера, которая выглядит следующим образом:

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

Я проверил, чтобы убедиться, что VaoID одинаков при созданииvao, и когда я пытаюсь получить vao.На самом деле это то же самое.

Я понятия не имею, как прочитать, какой адрес в настоящий момент хранится в том, что 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.Но после изменения все заработало нормально.

1 Ответ

0 голосов
/ 15 февраля 2019

Вы должны использовать свой индекс атрибута вершины с glVertexAttribPointer, glEnableVertexAttribArray и glDisableVertexAttribArray, но вы получите:

  • Идентификатор VAO, используемый с glVertexAttribPointer
  • жестко запрограммировано 0 используется с glEnableVertexAttribArray и 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 с упомянутыми вызовамивыше. * * тысяча двадцать-одна

...