1

I am using GLEW to create an OpenGL context and "standard" win32 to create the window.

If I set up my VBO and VAO (both global variables) every frame then my geometry renders correctly. both program and positions are global and set before this loop happens.

    while (!done)
    {
        PeekMessage(&msg, hwnd, NULL, NULL, PM_REMOVE);

        if (msg.message == WM_QUIT)
            done = true;
        else
        {
            glClear(GL_COLOR_BUFFER_BIT);

            glGenVertexArrays(1, &vao);
            glGenBuffers(1, &vbo);

            glBindBuffer(GL_ARRAY_BUFFER, vbo);
            glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);

            glBindVertexArray(vao);

            glVertexAttribBinding(0, vao);
            glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(glm::vec4));
            glVertexArrayAttribFormat(vao, 0, 4, GL_FLOAT, GL_FALSE, 0);
            glEnableVertexAttribArray(0);

            glUseProgram(program);

            glDrawArrays(GL_TRIANGLES, 0, 3);

            glBindVertexArray(0);
            glUseProgram(0);

            SwapBuffers(g_HDC);

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return msg.wParam;
}

However, I want initialise the VBO/VAO outside of the render block and instead bind the VAO every frame. Here is what I have currently but I still cannot get it to work. All that is rendered is a black screen.

    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);

    glBindVertexArray(vao);

    glVertexAttribBinding(0, vao);
    glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(glm::vec4));
    glVertexArrayAttribFormat(vao, 0, 4, GL_FLOAT, GL_FALSE, 0);
    glEnableVertexAttribArray(0);

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    while (!done)
    {
        PeekMessage(&msg, hwnd, NULL, NULL, PM_REMOVE);

        if (msg.message == WM_QUIT)
            done = true;
        else
        {
            glClear(GL_COLOR_BUFFER_BIT);

            glUseProgram(program);
            glBindVertexArray(vao);

            glDrawArrays(GL_TRIANGLES, 0, 3);

            glBindVertexArray(0);
            glUseProgram(0);

            SwapBuffers(g_HDC);

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return msg.wParam;
}

I am under the impression that once the buffer data has been set it is permanent until explicitly deleted? Am I missing something here?

All help is much appreciated.

1 Answers1

0

glVertexArrayVertexBuffer binds a buffer to the vertex buffer binding point, but not to an attribute index. The assocaition between the binding point and the attribute index is established by glVertexAttribBinding:

glVertexAttribBinding(0, vao);

glVertexAttribBinding(0, 0);

Respectively the DSA version:

glVertexArrayAttribBinding(vao, 0, 0);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thanks for this! I understand why the first argument is 0 but why the second? what is the bindingIndex as described in the documentation you have linked? – Connor Hemingway Nov 09 '20 at 22:59
  • @ConnorHemingway Please read [glVertexAttribPointer and glVertexAttribFormat: What's the difference?](https://stackoverflow.com/questions/37972229/glvertexattribpointer-and-glvertexattribformat-whats-the-difference). The excellent answer to this question explains all in detail. There's makes no sense in doing it all over again here or even copy / paste it. – Rabbid76 Nov 09 '20 at 23:01