Skip to content

Rendering with Vertex Array Objects

Willy Scheibel edited this page Sep 26, 2013 · 6 revisions

The new way to render primitives in OpenGL is using Vertex Array Objects.

Here is typical OpenGL code to create a simple program with simple shaders to build a screen aligned quad and render it.

GLuint vaoId;
glGenVertexArrays(1, &vaoId);
glGenBuffers(1, &cornerBufferId);
GLuint cornerBufferId;
GLuint programId = glCreateProgram();

GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
const char* vertexShaderSource = "...";
glShaderSource(vertexShaderId, 1, &vertexShaderSource, 0);
glCompileShader(vertexShaderId);

GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
const char* fragmentShaderSource = "...";
glShaderSource(fragmentShaderId, 1, &fragmentShaderSource, 0);
glCompileShader(fragmentShaderId);

glAttachShader(programId, vertexShaderId);
glAttachShader(programId, fragmentShaderId);
glLinkProgram(programId);

const glm::vec2 cornerData[4] = {
    glm::vec2(0, 0),
    glm::vec2(1, 0),
    glm::vec2(0, 1),
    glm::vec2(1, 1)
};

glBindBuffer(GL_ARRAY_BUFFER, cornerBufferId);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2)*4, cornerData, GL_STATIC_DRAW);

glBindVertexArray(vaoId);

GLint attributeIndex = glGetAttribLocation(programId, "corner");
GLint bindingIndex = 0;
glVertexAttribBinding(attributeIndex, bindingIndex);
glBindVertexBuffer(bindingIndex, cornerBufferId, 0, sizeof(glm::vec2));
glVertexAttribFormat(attributeIndex, 2, GL_FLOAT, GL_FALSE, 0);
glEnableVertexAttribArray(attributeIndex);

glUseProgram(programId);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glDeleteProgram(&programId);
glDeleteBuffers(1, &cornerBufferId);
glDeleteVertexArrays(1, &vaoId);

And now the GLOW variant of the above code.

glow::VertexArrayObject vao;
glow::Buffer cornerBuffer(GL_ARRAY_BUFFER);
glow::Program program;

program.attach(
    glow::Shader::fromString(GL_VERTEX_SHADER, "..."),
    glow::Shader::fromString(GL_FRAGMENT_SHADER, "...")
);

cornerBuffer.setData(glow::Array<glm::vec2>({
    glm::vec2(0, 0),
    glm::vec2(1, 0),
    glm::vec2(0, 1),
    glm::vec2(1, 1)
}));

vao.binding(0)->setAttribute(program->getAttributeLocation("corner"));
vao.binding(0)->setBuffer(cornerBuffer, 0, sizeof(glm::vec2));
vao.binding(0)->setFormat(2, GL_FLOAT);
vao.enable(program->getAttributeLocation("corner"));

program.use();
vao.drawArrays(GL_TRIANGLE_STRIP, 0, 4);

Clone this wiki locally