glGenBuffers

#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/glfw3.h>
#include <iostream>
using namespace std;

GLuint VBO[2], VAO[2];

void init()
{
    static const GLfloat vertices[] =
    {
        // First triangle
        -0.9f, -0.5f, 0.0f,  // Left
        -0.0f, -0.5f, 0.0f,  // Right
        -0.45f, 0.5f, 0.0f,  // Top
    };

    static const GLfloat vertices2[] =
    {
        // Second triangle
        0.0f, -0.5f, 0.0f,  // Left
        0.9f, -0.5f, 0.0f,  // Right
        0.45f, 0.5f, 0.0f   // Top
    };

    glGenVertexArrays(2, VAO);

    glBindVertexArray(VAO[0]);
    //glGenBuffers(2, VBO);
    VBO[0]=1; VBO[1]=2;
    glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    glBindVertexArray(VAO[1]);
    glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    cout << glGetError();
}

static void render()
{
    glClearColor(0, 0, 0.2, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(VAO[0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(VAO[1]);
    glDrawArrays(GL_TRIANGLES, 0, 6);
}

int main()
{
    glfwInit();
    GLFWwindow *window = glfwCreateWindow(640, 480, "VAO", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glewInit();
    init();

    while (!glfwWindowShouldClose(window))
    {
        render();

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

Why does everything work OK when I use

VBO[0]=1; VBO[1]=2;

instead of

glGenBuffers(2, VBO);

?

[QUOTE=ctrlf5;1293188]

#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/glfw3.h>
#include <iostream>
using namespace std;

GLuint VBO[2], VAO[2];

void init()
{
    static const GLfloat vertices[] =
    {
        // First triangle
        -0.9f, -0.5f, 0.0f,  // Left
        -0.0f, -0.5f, 0.0f,  // Right
        -0.45f, 0.5f, 0.0f,  // Top
    };

    static const GLfloat vertices2[] =
    {
        // Second triangle
        0.0f, -0.5f, 0.0f,  // Left
        0.9f, -0.5f, 0.0f,  // Right
        0.45f, 0.5f, 0.0f   // Top
    };

    glGenVertexArrays(2, VAO);

    glBindVertexArray(VAO[0]);
    //glGenBuffers(2, VBO);
    VBO[0]=1; VBO[1]=2;
    glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    glBindVertexArray(VAO[1]);
    glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    cout << glGetError();
}

static void render()
{
    glClearColor(0, 0, 0.2, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(VAO[0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(VAO[1]);
    glDrawArrays(GL_TRIANGLES, 0, 6);
}

int main()
{
    glfwInit();
    GLFWwindow *window = glfwCreateWindow(640, 480, "VAO", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glewInit();
    init();

    while (!glfwWindowShouldClose(window))
    {
        render();

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

Why does everything work OK when I use

VBO[0]=1; VBO[1]=2;

instead of

glGenBuffers(2, VBO);

?[/QUOTE]

Probably because you did:


cout << glGetError();

This will just print a number because glGetError returns a error code enum. Even if they are the same in both cases it doesn’t mean that there is no error. Replace it with:


if(glGetError != GL_NO_ERROR)
    throw std::runtime_error("Something went wrong!");

Even if you don’t see any differences in the output it does not mean your code is correct. As GClements wrote in your other thread:

As for why your program partially works, it’s possible that something (maybe GLEW or GLFW, or maybe the driver itself) uses VAO 1 for its own purposes, so using that name in your own code conflicts with that.

Just replace VAO with VBO in the quote. In this case there even might be any OpenGL error cause you are just writing to an existing buffer, but I am not sure about that.

Here are two tutorials about how to debug OpenGL:

http://in2gpu.com/2015/05/27/debugging-opengl-glgeterror/ <— the easy and simple, but not so helpful way
http://in2gpu.com/2015/05/29/debugging-opengl-part-ii-debug-output/ <— the more complicated but also much better way (needs OpenGL 4.3)

I know, such things are boring and you wont see any triangles dance, but learning good debugging strategies will save you a lot of time in the long run. So invest the time now. Its takes 1, maximal 2 days to understand the stuff and to implement into your own code but it will pay off really fast.

What does glGenBuffers do besides initializing GLuint variables?

You basically tell the OpenGL API that you are going to need memory for an (buffer) object. It will register your request internally and give you the corresponding ID. Think of it like a dynamically sized array of pointers. With a pointer you can use new and delete to allocate and deallocate memory on the heap. So if you have an array with two pointers, you can allocate 2 individual pieces of memory. However, most compilers won’t complain if you do the following:


int* myArray[2];
myArray[10] = new int{1};

You access the 11th element of an array that only has space for 2! Interestingly even the program will run most of the times without producing any errors. But sometimes it might fail with an access violation. So if you access a VBO with a number that was not provided by glGenBuffers, you access a non existing element. Might work, might fail, but it is for sure wrong. I already gave you a more detailed answer on this topic in your other thread.

What does glGenBuffers call write to graphics memory? I can’t find the answer in the OpenGL specification.
How could GPU vendors implement this function if it isn’t described properly in the specification?

[QUOTE=ctrlf5;1293192]What does glGenBuffers call write to graphics memory? I can’t find the answer in the OpenGL specification.
How could GPU vendors implement this function if it isn’t described properly in the specification?[/QUOTE]

It is described properly in the specification. How implementers implement the behavior is entirely up to them and need not be described by the standard. glGenBuffers generates a series of buffer object names, and after the point of generation, you are permitted to use those names to refer to the underlying buffer objects. That’s what the standard says, and that’s all it needs to.

In short, treat glGenBuffers like you treat new; you don’t try to use an object until you’ve allocated it.