VBO должен быть связан после VAO - PullRequest
0 голосов
/ 09 сентября 2018

Код:

void render()
{
    glClear(GL_COLOR_BUFFER_BIT);

    GLfloat vertices[6][4] = {
        { 1.0f, 1.0f, 1.0f, 1.0f },
        { 1.0f, 1.0f, 1.0f, 1.0f },
        { 1.0f, 1.0f, 1.0f, 1.0f },

        { 1.0f, 1.0f, 1.0f, 1.0f },
        { 1.0f, 1.0f, 1.0f, 1.0f },
        { 1.0f, 1.0f, 1.0f, 1.0f }
    };

    glUseProgram(shadptr->progGraphics);
    glBindVertexArray(vao_g);
    glBindBuffer(GL_ARRAY_BUFFER, vbo_g);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, vertices, GL_DYNAMIC_DRAW);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    glUseProgram(shadptr->progText);
    glBindVertexArray(vao_t);
    glBindBuffer(GL_ARRAY_BUFFER, vbo_t);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, vertices, GL_DYNAMIC_DRAW);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    SDL_GL_SwapWindow(winptr->window);
}

void set_buffers()
{
    glGenVertexArrays(1, &vao_g);
    glBindVertexArray(vao_g);

    glGenBuffers(1, &vbo_g);
    glBindBuffer(GL_ARRAY_BUFFER, vbo_g);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr);

    glGenVertexArrays(1, &vao_t);
    glBindVertexArray(vao_t);

    glGenBuffers(1, &vbo_t);
    glBindBuffer(GL_ARRAY_BUFFER, vbo_t);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr);
}

У меня проблема. Я не знаю, почему я должен связать vbo после связывания vao в функции рендеринга. Когда я не связываю vbo, в RenderDoc у меня появляется ошибка "glDrawArrays сгенерировал ошибку (GL_OUT_OF_MEMORY)", и в выводе сетки, во входе VS я вижу неправильные значения или --- значение.

1 Ответ

0 голосов
/ 09 сентября 2018

Я не знаю, почему я должен связывать vbo после связывания vao в функции рендеринга "

Поскольку вы пытаетесь создать и инициализировать хранилище данных объекта буфера с помощью glBufferData, и для этого необходимо связать буфер.

Я рекомендую переместить код, который создает и инициализирует буфер, на set_buffers. Тогда будет достаточно связать только объект массива вершин в функции render:

void render()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(shadptr->progGraphics);
    glBindVertexArray(vao_g);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    glUseProgram(shadptr->progText);
    glBindVertexArray(vao_t);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    SDL_GL_SwapWindow(winptr->window);
}

void set_buffers()
{
    ....

    GLfloat vertices[6][4] = {
        { 1.0f, 1.0f, 1.0f, 1.0f },
        { 1.0f, 1.0f, 1.0f, 1.0f },
        { 1.0f, 1.0f, 1.0f, 1.0f },

        { 1.0f, 1.0f, 1.0f, 1.0f },
        { 1.0f, 1.0f, 1.0f, 1.0f },
        { 1.0f, 1.0f, 1.0f, 1.0f }
    };

    glBindBuffer(GL_ARRAY_BUFFER, vbo_g);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, vertices, GL_DYNAMIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, vbo_t);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, vertices, GL_DYNAMIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

Я рекомендую использовать glBufferSubData, чтобы изменить содержимое буфера. Это обновит буфер, но не создаст и не инициализирует совершенно новое хранилище данных и, следовательно, будет гораздо более эффективным.

...