easy-gl › Buffer
Buffer
Manages a single OpenGL buffer object (VBO, IBO, UBO, SSBO, etc.). Non-copyable, movable, RAII.
BufferTarget values
| Value | Use |
BufferTarget::Array | Vertex buffer (VBO) |
BufferTarget::ElementArray | Index buffer (IBO/EBO) |
BufferTarget::Uniform | Uniform buffer object (UBO) |
BufferTarget::ShaderStorage | Shader Storage Buffer (SSBO) |
BufferTarget::TransformFeedback | Transform feedback output |
BufferTarget::CopyRead | Buffer copy source |
BufferTarget::CopyWrite | Buffer copy destination |
BufferTarget::PixelPack | Pixel pack (GPU→CPU) |
BufferTarget::PixelUnpack | Pixel unpack (CPU→GPU) |
BufferUsage hints
| Value | Pattern |
BufferUsage::StaticDraw | Uploaded once, drawn many times |
BufferUsage::DynamicDraw | Updated frequently, drawn many times |
BufferUsage::StreamDraw | Updated every frame, drawn once |
BufferUsage::StaticRead | Written by GPU, read by CPU once |
BufferUsage::DynamicRead | Written 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
| Method | Description |
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). |