easy-gl › Buffer

Buffer

Manages a single OpenGL buffer object (VBO, IBO, UBO, SSBO, etc.). Non-copyable, movable, RAII.

BufferTarget values

ValueUse
BufferTarget::ArrayVertex buffer (VBO)
BufferTarget::ElementArrayIndex buffer (IBO/EBO)
BufferTarget::UniformUniform buffer object (UBO)
BufferTarget::ShaderStorageShader Storage Buffer (SSBO)
BufferTarget::TransformFeedbackTransform feedback output
BufferTarget::CopyReadBuffer copy source
BufferTarget::CopyWriteBuffer copy destination
BufferTarget::PixelPackPixel pack (GPU→CPU)
BufferTarget::PixelUnpackPixel unpack (CPU→GPU)

BufferUsage hints

ValuePattern
BufferUsage::StaticDrawUploaded once, drawn many times
BufferUsage::DynamicDrawUpdated frequently, drawn many times
BufferUsage::StreamDrawUpdated every frame, drawn once
BufferUsage::StaticReadWritten by GPU, read by CPU once
BufferUsage::DynamicReadWritten by GPU, read by CPU often

Creating a vertex buffer

constexpr float vertices[] = {
    -0.5f, -0.5f,  1.0f, 0.0f, 0.0f,
     0.5f, -0.5f,  0.0f, 1.0f, 0.0f,
     0.0f,  0.5f,  0.0f, 0.0f, 1.0f,
};

easygl::Buffer vbo;
vbo.create();
vbo.bind(easygl::BufferTarget::Array);
vbo.set_data(easygl::BufferTarget::Array,
              vertices, sizeof(vertices),
              easygl::BufferUsage::StaticDraw);

Creating an index buffer

constexpr unsigned int indices[] = { 0, 1, 2, 2, 3, 0 };

easygl::Buffer ibo;
ibo.create();
ibo.bind(easygl::BufferTarget::ElementArray);
ibo.set_data(easygl::BufferTarget::ElementArray,
              indices, sizeof(indices),
              easygl::BufferUsage::StaticDraw);

Uniform buffer object (UBO)

struct Matrices {
    float model[16];
    float view[16];
    float projection[16];
};

easygl::Buffer ubo;
ubo.create();
ubo.bind(easygl::BufferTarget::Uniform);
ubo.set_data(easygl::BufferTarget::Uniform,
              nullptr, sizeof(Matrices),
              easygl::BufferUsage::DynamicDraw);

// Bind to binding point 0
ubo.bind_base(easygl::BufferTarget::Uniform, 0);

// Update per-frame
Matrices mats = computeMatrices();
ubo.set_sub_data(easygl::BufferTarget::Uniform,
                  &mats, sizeof(Matrices), 0);

Partial range binding

// Bind bytes [256, 256+sizeof(LightData)) to binding point 1
ubo.bind_range(easygl::BufferTarget::Uniform, 1, 256, sizeof(LightData));

Buffer mapping

using Mask = easygl::MapBufferAccessMask;
void* ptr = vbo.map_range(
    easygl::BufferTarget::Array,
    0,         // offset
    bufferSize,  // length
    Mask::Write | Mask::InvalidateRange);

std::memcpy(ptr, newData, bufferSize);

vbo.flush_mapped_range(easygl::BufferTarget::Array, 0, bufferSize);
vbo.unmap(easygl::BufferTarget::Array);

Copying between buffers

easygl::Buffer::copy_sub_data(
    easygl::BufferTarget::CopyRead,
    easygl::BufferTarget::CopyWrite,
    0,       // source offset
    0,       // dest offset
    copySize);

Method reference

MethodDescription
create()Allocate a new OpenGL buffer handle.
destroy()Free the GL handle. Noexcept.
bind(target)Bind this buffer to target.
bind_base(target, index)Bind to an indexed binding point (UBO, SSBO).
bind_range(target, index, offset, size)Bind a byte range to an indexed point.
set_data(data, size)Upload data to the already-bound target.
set_data(target, data, size)Bind to target then upload.
set_data(target, data, size, usage)Upload with explicit usage hint.
set_sub_data(data, size, offset)Update a sub-range of existing data.
map_range(target, offset, length, access)Map buffer range into CPU address space.
flush_mapped_range(target, offset, length)Flush a mapped write range.
unmap(target)Unmap the buffer. Returns false on data corruption.
copy_sub_data(...) [static]GPU-side buffer copy.
is_created()True if handle is allocated.
native_handle()Raw GL handle integer.
is_valid_for_current_generation()False if context was lost and recreated.
creation_generation()Generation counter at time of create().
reset_handle_no_gl()Clear handle without a GL call (context-loss recovery).