Buffers

:)

Buffer objects store memory allocated by the OpenGL context. They are used to store data that you wish to use in or get from OpenGL. The normal OpenGL creation functions exists for buffers.

Set the target

When using glBindBuffer a target is always specified. The first time a buffer is bound it is used to create the buffer to be of that type.

void glBindBuffer(GLenum target, GLuint buffer);

GL_ARRAY_BUFFER​

The buffer is used as source for vertex data to the shaders.

GL_ELEMENT_ARRAY_BUFFER

This buffer is used to contain vertices indices when using indexed draw commands.

GL_UNIFORM_BUFFER

Used to feed the shaders with uniform data that stay to same over a whole draw call for many vertices.

GL_COPY_READ_BUFFER & GL_COPY_WRITE_BUFFER

Target names useful when copying buffer data with glCopyBufferSubData.

GL_DRAW_INDERECT_BUFFER

GL_PIXEL_PACK_BUFFER

GL_PIXEL_UNPACK_BUFFER

GL_TEXTURE_BUFFER

A buffer that can be accessed as large array of data.

GL_TRANSFORM_FEEDBACK_BUFFER

Allocating Memory

OpenGl now know the name of the buffer and what it will be used for so the next step is to allocate memory for it. For that glBufferData is used. It acts on the currently bound buffer for the selected target so there is no need to give it the name of the buffer. The size parameter will be use to allocate that amount of space for the buffer. If the buffer already has memory allocated this command can also be used to change it. If data is non-NULL the buffer will be initialized with the content of the memory addressed by data.

The final parameter is an enum that are used to hint to opengl on how to handle the buffer. The token for the enum is in the form of GL_X_Y where X and Y can have the following values and meanings. X Specify how often we plan to change the content of the buffer and Y how we will use it in opengl.

    • _STATIC_: Data will not change at all or very rarely.

    • _DYNAMIC_: Data will change often.

    • _STREAM_: Data will have change each time it is used.

    • _DRAW: The content are modifed by the application and then used to draw things.

    • _READ: The content are modifed by reading things from opengl and then read by the application.

    • _COPY: The content are modifed by reading things from opengl and then used for drawing things.

void glBufferData​(enum target, sizeiptr size, const void *data, enum usage)

Write & Read

To fill in only a section of a buffer use glBufferSubData​. To clear the content of a buffer to a know value use glClearBufferData or glClearBufferSubData. To read back data from a buffer to your application use glGetBufferSubData.

*** glCopyBufferSubData​ ***

void glBufferSubData​(enum target, intptr offset, sizeiptr size, const void *data)

void glClearBufferData​(GLenum target​​, GLenum internalformat​, GLenum format​, GLenum type​, const void * data​);

void glClearBufferSubData​(GLenum target​, GLenum internalformat​, GLintptr offset​, GLsizeiptr size​, GLenum format​, GLenum type​, const void * data​);

void glGetBufferSubData(GLenum target​, GLintptr offset​,GLsizeiptr size​, const void *data);

void glCopyBufferSubData​(GLenum readtarget​, GLenum writetarget​, GLintptr readoffset​, GLintptr writeoffset​, GLsizeiptr size​);

Map

Using glMapBuffer you can get a pointer to a buffer so you can access it direcly. The access parameter is used to tell opengl what you will do with the buffer. The options are GL_READ_ONLY, GL_WRITE_ONLY and GL_READ_WRITE. If you do other things then you said you would bad things will happen. If OpenGl fails to map the buffer the function will return NULL. When done call glUnmapBuffer to release your access to the buffer.

void * glMapBuffer(GLenum target​, GLenum access​);

GLboolean glUnmapBuffer(GLenum target​);

void *glMapBufferRange​(GLenum target​, GLintptr offset​, GLsizeiptr length​, GLbitfield access​);

void glFlushMappedBufferRangeGLenum target​, GLintptr offset​, GLsizeiptr length​);

void glInvalidateBufferData(...)

void glInvalidateBufferSubData(...)

Vertex buffer object (VBO)

Buffer objects of the type GL_ARRAY_BUFFER are also known as Vertex buffer objects. They are used to feed data to vertices at the start of the OpenGL pipeline.

Vertex Array Objects (VAO)

VAO acts like the middle man between a VBO and a shader program. It handles the mapping of the data in the buffer to the vertex attributes in the program. The normal functions exist to manage them.

A variable in a shader program have a attribute location and to get it use glGetAttribLocation. Attribute location must be enabled to be used. Disabled locations will get a constant value in the shader.

GLint glGetAttribLocation(GLuint program​, const GLchar *name​);

void glEnableVertexAttribArray(GLuint index​);

void glDisableVertexAttribArray(GLuint index​);

There are two ways to setup the data in the VAO, the old attribute format and the newer separate attribute format added in OpenGl 4.3.

Separate attribute format 4.3

void glBindVertexBuffer(GLuint bindingindex​, GLuint buffer​, GLintptr offset​, GLintptr stride​);

void glVertexAttrib*Format(GLuint attribindex​, GLint size​, GLenum type​, GLboolean normalized​, GLuint relativeoffset​);

void glVertexAttribBinding(GLuint attribindex​, GLuint bindingindex​);

Attribute format 3.0

The old way use glVertexAttribPointer to set both the buffer to read from and the vertex format in the buffer.

void glVertexAttribPointer(GLuint index​,GLint size​,GLenum type​,GLboolean normalized​,GLsizei stride​,const GLvoid * pointer​);

Reference