EAGL.Buffer (eagl v0.6.0)

View Source

OpenGL 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

buffer_id()

@type buffer_id() :: non_neg_integer()

buffer_usage()

@type buffer_usage() ::
  :stream_draw
  | :stream_read
  | :stream_copy
  | :static_draw
  | :static_read
  | :static_copy
  | :dynamic_draw
  | :dynamic_read
  | :dynamic_copy

vao_id()

@type vao_id() :: non_neg_integer()

vertex_attribute()

@type vertex_attribute() :: %{
  location: non_neg_integer(),
  size: 1..4,
  type: vertex_attribute_type(),
  normalized: boolean(),
  stride: non_neg_integer(),
  offset: non_neg_integer()
}

vertex_attribute_name()

@type vertex_attribute_name() :: :position | :color | :texture_coordinate | :normal

vertex_attribute_type()

@type vertex_attribute_type() ::
  :byte
  | :unsigned_byte
  | :short
  | :unsigned_short
  | :int
  | :unsigned_int
  | :fixed
  | :float
  | :half_float
  | :double

Functions

color_attribute(opts \\ [])

@spec color_attribute(keyword()) :: vertex_attribute()

Creates a standard colour attribute configuration (location 1, vec3, float).

create_indexed_array(vertices, indices, attributes, opts \\ [])

@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)

create_indexed_position_array(vertices, indices)

@spec create_indexed_position_array([float()], [integer()]) ::
  {vao_id(), buffer_id(), buffer_id()}

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)

create_position_array(vertices)

@spec create_position_array([float()]) :: {vao_id(), buffer_id()}

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)

create_vertex_array(vertices, attributes, opts \\ [])

@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)

delete_indexed_array(vao, vbo, ebo)

@spec delete_indexed_array(integer(), integer(), integer()) :: :ok

Deletes a VAO and its associated VBO and EBO.

delete_vertex_array(vao, vbos)

@spec delete_vertex_array(integer(), [integer()]) :: :ok
@spec delete_vertex_array(integer(), integer()) :: :ok

Deletes a VAO and its associated VBOs.

indices_to_binary(indices)

@spec indices_to_binary([integer()]) :: binary()

Converts a list of indices to binary format for OpenGL.

normal_attribute(opts \\ [])

@spec normal_attribute(keyword()) :: vertex_attribute()

Creates a standard normal attribute configuration (location 3, vec3, float).

position_attribute(opts \\ [])

@spec position_attribute(keyword()) :: vertex_attribute()

Creates a standard position attribute configuration (location 0, vec3, float).

texture_coordinate_attribute(opts \\ [])

@spec texture_coordinate_attribute(keyword()) :: vertex_attribute()

Creates a standard texture coordinate attribute configuration (location 2, vec2, float).

vertex_attribute(opts)

@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)

vertex_attributes(attr_types)

@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

vertex_attributes(first_type, second_type)

@spec vertex_attributes(vertex_attribute_name(), vertex_attribute_name()) :: [
  vertex_attribute()
]

vertex_attributes(first_type, second_type, third_type)

vertex_attributes(first_type, second_type, third_type, fourth_type)

vertices_to_binary(vertices)

@spec vertices_to_binary([float()]) :: binary()

Converts a list of vertex floats to binary format for OpenGL.