EAGL.Buffer (eagl v0.4.0)
View SourceOpenGL buffer and vertex array object management.
Provides Wings3D-inspired helper functions for common VAO/VBO/EBO operations with meaningful abstractions for vertex attribute setup.
The module includes type-safe helpers for common vertex attributes like position, color, texture coordinates, and normals.
Original Source
Buffer management patterns and helper functions are inspired by Wings3D's
wings_gl.erl
module:
https://github.com/dgud/wings/blob/master/src/wings_gl.erl
Usage
import EAGL.Buffer
# Simple position-only vertices
vertices = [-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.0, 0.5, 0.0]
{vao, vbo} = create_position_array(vertices)
# Custom vertex attributes with type-safe configuration
attributes = [
vertex_attribute(location: 0, size: 3, type: :float, stride: 24, offset: 0), # position
vertex_attribute(location: 1, size: 3, type: :float, stride: 24, offset: 12) # color
]
{vao, vbo} = create_vertex_array(vertices, attributes)
# Or use standard attribute helpers
attributes = [
position_attribute(stride: 24, offset: 0),
color_attribute(stride: 24, offset: 12)
]
{vao, vbo} = create_vertex_array(vertices, attributes)
# Indexed geometry (rectangles, models)
vertices = [0.5, 0.5, 0.0, 0.5, -0.5, 0.0, -0.5, -0.5, 0.0, -0.5, 0.5, 0.0]
indices = [0, 1, 3, 1, 2, 3]
{vao, vbo, ebo} = create_indexed_position_array(vertices, indices)
# Use OpenGL directly for rendering
:gl.bindVertexArray(vao)
:gl.drawElements(@gl_triangles, 6, @gl_unsigned_int, 0)
# Clean up
delete_vertex_array(vao, vbo)
Summary
Functions
Creates a standard colour attribute configuration (location 1, vec3, float).
Creates a VAO with VBO and EBO for indexed geometry. Returns {vao, vbo, ebo} tuple.
Creates a simple indexed VAO with position-only vertices (3 floats per vertex). Convenience wrapper for indexed geometry with positions only.
Creates a simple VAO with position-only vertices (3 floats per vertex). Convenience wrapper for the most common case.
Creates a VAO with a single VBO containing vertex data. Returns {vao, vbo} tuple.
Deletes a VAO and its associated VBO and EBO.
Deletes a VAO and its associated VBOs.
Converts a list of indices to binary format for OpenGL.
Creates a standard normal attribute configuration (location 3, vec3, float).
Creates a standard position attribute configuration (location 0, vec3, float).
Creates a standard texture coordinate attribute configuration (location 2, vec2, float).
Creates a vertex attribute configuration with type safety and sensible defaults.
Creates a list of vertex attributes with automatic stride and offset calculation. This is a higher-level helper that eliminates the redundancy of manually specifying stride and offset for common interleaved vertex layouts.
Converts a list of vertex floats to binary format for OpenGL.
Types
@type buffer_id() :: non_neg_integer()
@type buffer_usage() ::
:stream_draw
| :stream_read
| :stream_copy
| :static_draw
| :static_read
| :static_copy
| :dynamic_draw
| :dynamic_read
| :dynamic_copy
@type vao_id() :: non_neg_integer()
@type vertex_attribute() :: %{ location: non_neg_integer(), size: 1..4, type: vertex_attribute_type(), normalized: boolean(), stride: non_neg_integer(), offset: non_neg_integer() }
@type vertex_attribute_name() :: :position | :color | :texture_coordinate | :normal
@type vertex_attribute_type() ::
:byte
| :unsigned_byte
| :short
| :unsigned_short
| :int
| :unsigned_int
| :fixed
| :float
| :half_float
| :double
Functions
@spec color_attribute(keyword()) :: vertex_attribute()
Creates a standard colour attribute configuration (location 1, vec3, float).
@spec create_indexed_array([float()], [integer()], [vertex_attribute()], keyword()) :: {vao_id(), buffer_id(), buffer_id()}
Creates a VAO with VBO and EBO for indexed geometry. Returns {vao, vbo, ebo} tuple.
Parameters
- vertices: List of floats representing vertex data
- indices: List of integers representing vertex indices
- attributes: List of vertex_attribute structs
- opts: Options for buffer creation
Options
usage
: Buffer usage pattern (default: :static_draw)
Example
vertices = [0.5, 0.5, 0.0, 0.5, -0.5, 0.0, -0.5, -0.5, 0.0, -0.5, 0.5, 0.0]
indices = [0, 1, 3, 1, 2, 3]
attributes = [position_attribute()]
{vao, vbo, ebo} = create_indexed_array(vertices, indices, attributes)
Creates a simple indexed VAO with position-only vertices (3 floats per vertex). Convenience wrapper for indexed geometry with positions only.
Example
vertices = [0.5, 0.5, 0.0, 0.5, -0.5, 0.0, -0.5, -0.5, 0.0, -0.5, 0.5, 0.0]
indices = [0, 1, 3, 1, 2, 3] # Two triangles forming a rectangle
{vao, vbo, ebo} = create_indexed_position_array(vertices, indices)
Creates a simple VAO with position-only vertices (3 floats per vertex). Convenience wrapper for the most common case.
Example
vertices = [-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.0, 0.5, 0.0]
{vao, vbo} = create_position_array(vertices)
@spec create_vertex_array([float()], [vertex_attribute()], keyword()) :: {vao_id(), buffer_id()}
Creates a VAO with a single VBO containing vertex data. Returns {vao, vbo} tuple.
Parameters
- vertices: List of floats representing vertex data
- attributes: List of vertex_attribute structs
- opts: Options for buffer creation
Options
usage
: Buffer usage pattern (default: :static_draw)
Example
vertices = [-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.0, 0.5, 0.0]
# Type-safe approach
attributes = [
position_attribute(),
color_attribute(stride: 24, offset: 12)
]
{vao, vbo} = create_vertex_array(vertices, attributes)
Deletes a VAO and its associated VBO and EBO.
@spec delete_vertex_array(integer(), [integer()]) :: :ok
@spec delete_vertex_array(integer(), integer()) :: :ok
Deletes a VAO and its associated VBOs.
Converts a list of indices to binary format for OpenGL.
@spec normal_attribute(keyword()) :: vertex_attribute()
Creates a standard normal attribute configuration (location 3, vec3, float).
@spec position_attribute(keyword()) :: vertex_attribute()
Creates a standard position attribute configuration (location 0, vec3, float).
@spec texture_coordinate_attribute(keyword()) :: vertex_attribute()
Creates a standard texture coordinate attribute configuration (location 2, vec2, float).
@spec vertex_attribute(keyword()) :: vertex_attribute()
Creates a vertex attribute configuration with type safety and sensible defaults.
Options
location
: Attribute location in shader (required)size
: Number of components (1-4, required)type
: Data type (default: :float)normalized
: Whether to normalize fixed-point data (default: false)stride
: Byte offset between consecutive attributes (default: 0 for tightly packed)offset
: Byte offset of first component in buffer (default: 0)
Examples
# Position attribute (vec3)
pos_attr = vertex_attribute(location: 0, size: 3)
# Color attribute with custom stride and offset
color_attr = vertex_attribute(location: 1, size: 3, type: :float, stride: 24, offset: 12)
# Normalized integer attribute
normal_attr = vertex_attribute(location: 2, size: 3, type: :byte, normalized: true)
@spec vertex_attributes([vertex_attribute_name()]) :: [vertex_attribute()]
Creates a list of vertex attributes with automatic stride and offset calculation. This is a higher-level helper that eliminates the redundancy of manually specifying stride and offset for common interleaved vertex layouts.
Usage
# List syntax
attributes = vertex_attributes([:position, :color])
# Multiple arguments syntax
attributes = vertex_attributes(:position, :color, :texture_coordinate)
Supported Attribute Types
See vertex_attribute_name/0
for the complete type definition.
:position
- 3 floats (x, y, z) at location 0:color
- 3 floats (r, g, b) at location 1:texture_coordinate
- 2 floats (s, t) at location 2:normal
- 3 floats (nx, ny, nz) at location 3
Examples
# Position and color (stride=24, offsets: 0, 12)
{vao, vbo} = create_vertex_array(vertices, vertex_attributes([:position, :color]))
# Position, color, texture (stride=32, offsets: 0, 12, 24)
attributes = vertex_attributes(:position, :color, :texture_coordinate)
{vao, vbo} = create_vertex_array(vertices, attributes)
The function automatically calculates:
- Stride: Total size of one vertex (sum of all attribute sizes)
- Offsets: Cumulative byte offset for each attribute
- Locations: Sequential starting from 0
@spec vertex_attributes(vertex_attribute_name(), vertex_attribute_name()) :: [ vertex_attribute() ]
@spec vertex_attributes( vertex_attribute_name(), vertex_attribute_name(), vertex_attribute_name() ) :: [ vertex_attribute() ]
@spec vertex_attributes( vertex_attribute_name(), vertex_attribute_name(), vertex_attribute_name(), vertex_attribute_name() ) :: [vertex_attribute()]
Converts a list of vertex floats to binary format for OpenGL.