or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

attributes-uniforms.mdbuffer-management.mdcontext-creation.mdextensions.mdframebuffer-operations.mdindex.mdshader-programs.mdtexture-operations.mdwebgl-rendering.md
tile.json

buffer-management.mddocs/

Buffer Management

WebGL buffer operations for vertex data, index data, and GPU memory management with support for various data types and usage patterns.

Capabilities

Buffer Creation and Deletion

Methods for creating and destroying WebGL buffer objects.

/**
 * Create a new WebGL buffer object
 * @returns WebGLBuffer object or null if creation fails
 */
createBuffer(): WebGLBuffer | null;

/**
 * Delete a WebGL buffer object
 * @param buffer - Buffer to delete
 */
deleteBuffer(buffer: WebGLBuffer): void;

/**
 * Test if object is a valid buffer
 * @param buffer - Object to test
 * @returns true if valid buffer
 */
isBuffer(buffer: any): boolean;

Usage Examples:

// Create vertex buffer
const vertexBuffer = context.createBuffer();
if (!vertexBuffer) {
  console.error('Failed to create vertex buffer');
  return;
}

// Create index buffer
const indexBuffer = context.createBuffer();

// Clean up when done
context.deleteBuffer(vertexBuffer);
context.deleteBuffer(indexBuffer);

Buffer Binding

Methods for binding buffers to different targets.

/**
 * Bind a buffer to a target
 * @param target - Buffer target (ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER)
 * @param buffer - Buffer to bind, or null to unbind
 */
bindBuffer(target: number, buffer: WebGLBuffer | null): void;

Usage Examples:

// Bind vertex buffer for vertex data
context.bindBuffer(context.ARRAY_BUFFER, vertexBuffer);

// Bind index buffer for element indices
context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexBuffer);

// Unbind current buffer
context.bindBuffer(context.ARRAY_BUFFER, null);

Buffer Data Operations

Methods for uploading and updating buffer data.

/**
 * Set buffer data from array or allocate size
 * @param target - Buffer target
 * @param data - Data array, ArrayBuffer, or size in bytes
 * @param usage - Usage pattern hint
 */
bufferData(target: number, data: ArrayBuffer | ArrayBufferView | number, usage: number): void;

/**
 * Update a portion of buffer data
 * @param target - Buffer target
 * @param offset - Byte offset into buffer
 * @param data - Data to upload
 */
bufferSubData(target: number, offset: number, data: ArrayBuffer | ArrayBufferView): void;

Usage Examples:

// Upload vertex data
const vertices = new Float32Array([
  -1.0, -1.0, 0.0,  // Bottom left
   1.0, -1.0, 0.0,  // Bottom right
   0.0,  1.0, 0.0   // Top center
]);

context.bindBuffer(context.ARRAY_BUFFER, vertexBuffer);
context.bufferData(context.ARRAY_BUFFER, vertices, context.STATIC_DRAW);

// Upload index data
const indices = new Uint16Array([0, 1, 2]);
context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexBuffer);
context.bufferData(context.ELEMENT_ARRAY_BUFFER, indices, context.STATIC_DRAW);

// Update part of buffer
const newVertices = new Float32Array([0.0, 1.5, 0.0]);
context.bufferSubData(context.ARRAY_BUFFER, 6 * 4, newVertices); // Offset by 6 floats

Buffer Allocation

Allocate buffer storage without initial data.

// Allocate 1KB buffer
context.bindBuffer(context.ARRAY_BUFFER, buffer);
context.bufferData(context.ARRAY_BUFFER, 1024, context.DYNAMIC_DRAW);

// Later update with actual data
const data = new Float32Array([1, 2, 3, 4]);
context.bufferSubData(context.ARRAY_BUFFER, 0, data);

Buffer Parameters

Query buffer parameters and properties.

/**
 * Get buffer parameter
 * @param target - Buffer target
 * @param pname - Parameter name
 * @returns Parameter value
 */
getBufferParameter(target: number, pname: number): any;

Usage Examples:

// Get buffer size
const size = context.getBufferParameter(context.ARRAY_BUFFER, context.BUFFER_SIZE);

// Get buffer usage pattern
const usage = context.getBufferParameter(context.ARRAY_BUFFER, context.BUFFER_USAGE);

console.log(`Buffer size: ${size} bytes, usage: ${usage}`);

Usage Patterns

Buffer usage pattern constants for optimization hints.

// Usage pattern constants
const STATIC_DRAW: number;  // Data uploaded once, drawn many times
const DYNAMIC_DRAW: number; // Data updated frequently, drawn many times
const STREAM_DRAW: number;  // Data updated once per frame, drawn once

Usage Guidelines:

  • STATIC_DRAW: Use for geometry that doesn't change (models, terrain)
  • DYNAMIC_DRAW: Use for data that changes occasionally (animated objects)
  • STREAM_DRAW: Use for data that changes every frame (particle systems)

Buffer Targets

Buffer binding target constants.

// Buffer target constants
const ARRAY_BUFFER: number;         // Vertex attribute data
const ELEMENT_ARRAY_BUFFER: number; // Index data for drawElements

Data Types

Supported typed array types for buffer data.

// Integer types
const vertices = new Int8Array(data);    // 8-bit signed
const indices = new Uint8Array(data);    // 8-bit unsigned
const indices = new Uint16Array(data);   // 16-bit unsigned (most common for indices)
const indices = new Uint32Array(data);   // 32-bit unsigned (requires OES_element_index_uint)

// Float types
const vertices = new Float32Array(data); // 32-bit float (most common for vertices)

// Using ArrayBuffer directly
const buffer = new ArrayBuffer(256);
context.bufferData(context.ARRAY_BUFFER, buffer, context.STATIC_DRAW);

Common Patterns

Typical buffer management patterns for different use cases.

Static Mesh Data:

// Create and upload static mesh
function createStaticMesh(positions, indices) {
  const vertexBuffer = context.createBuffer();
  const indexBuffer = context.createBuffer();
  
  // Upload position data
  context.bindBuffer(context.ARRAY_BUFFER, vertexBuffer);
  context.bufferData(context.ARRAY_BUFFER, new Float32Array(positions), context.STATIC_DRAW);
  
  // Upload index data
  context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexBuffer);
  context.bufferData(context.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), context.STATIC_DRAW);
  
  return { vertexBuffer, indexBuffer };
}

Dynamic Buffer Updates:

// Update buffer data each frame
function updateDynamicBuffer(buffer, newData, offset = 0) {
  context.bindBuffer(context.ARRAY_BUFFER, buffer);
  
  if (offset === 0 && newData.byteLength <= bufferSize) {
    // Replace entire buffer or grow
    context.bufferData(context.ARRAY_BUFFER, newData, context.DYNAMIC_DRAW);
  } else {
    // Update portion of buffer
    context.bufferSubData(context.ARRAY_BUFFER, offset, newData);
  }
}