goldy 0.1.0

Goldy - Modern Graphics Library
Documentation
# Command Encoding

Commands are recorded into an encoder, then executed by rendering a frame.

## Command Encoder

```rust
use goldy::CommandEncoder;

let mut encoder = CommandEncoder::new();
```

The encoder records GPU commands without executing them immediately.

## Render Pass

A render pass groups drawing commands:

```rust
let mut encoder = CommandEncoder::new();
{
    let mut pass = encoder.begin_render_pass();
    
    // Drawing commands go here
    pass.clear(Color::BLACK);
    pass.set_pipeline(&pipeline);
    pass.set_vertex_buffer(0, &vertices);
    pass.draw(0..3, 0..1);
    
} // Pass ends when `pass` is dropped
```

## Render Pass Commands

### Clear

Clear the render target:

```rust
pass.clear(Color::BLACK);
pass.clear(Color { r: 0.1, g: 0.2, b: 0.3, a: 1.0 });
```

### Set Pipeline

Bind a render pipeline:

```rust
pass.set_pipeline(&pipeline);
```

### Set Vertex Buffer

Bind a vertex buffer to a slot:

```rust
pass.set_vertex_buffer(0, &buffer);  // Slot 0

// Multiple buffers (for instancing)
pass.set_vertex_buffer(0, &vertices);
pass.set_vertex_buffer(1, &instances);
```

### Draw

Draw primitives:

```rust
// draw(vertices, instances)
pass.draw(0..3, 0..1);      // 3 vertices, 1 instance
pass.draw(0..100, 0..1);    // 100 vertices, 1 instance
pass.draw(0..6, 0..10);     // 6 vertices, 10 instances
```

### Draw Indexed (future)

```rust
pass.set_index_buffer(&indices, IndexFormat::Uint16);
pass.draw_indexed(0..36, 0, 0..1);  // indices, base vertex, instances
```

## Command Order

Commands are executed in order within a pass:

```rust
{
    let mut pass = encoder.begin_render_pass();
    
    // 1. Clear first
    pass.clear(Color::BLACK);
    
    // 2. Draw background
    pass.set_pipeline(&bg_pipeline);
    pass.set_vertex_buffer(0, &bg_vertices);
    pass.draw(0..6, 0..1);
    
    // 3. Draw foreground (on top)
    pass.set_pipeline(&fg_pipeline);
    pass.set_vertex_buffer(0, &fg_vertices);
    pass.draw(0..triangle_count, 0..1);
}
```

## Multiple Draw Calls

You can issue multiple draws per pass:

```rust
{
    let mut pass = encoder.begin_render_pass();
    pass.clear(Color::BLACK);
    pass.set_pipeline(&pipeline);
    
    // Draw each object
    for (buffer, count) in objects {
        pass.set_vertex_buffer(0, buffer);
        pass.draw(0..count, 0..1);
    }
}
```

## Multiple Passes (future)

For effects requiring multiple render targets:

```rust
// Pass 1: Render scene to texture
{
    let mut pass = encoder.begin_render_pass_to(&scene_texture);
    pass.set_pipeline(&scene_pipeline);
    // ...
}

// Pass 2: Post-process
{
    let mut pass = encoder.begin_render_pass();
    pass.set_pipeline(&postprocess_pipeline);
    // Use scene_texture as input
    // ...
}
```

## Executing Commands

Commands are executed when you render to a surface or render target:

```rust
// For window display (zero-copy)
let frame = surface.acquire()?;
frame.render(encoder)?;
surface.present(frame)?;

// For headless/streaming (with optional CPU readback)
let target = RenderTarget::new(&device, width, height, format)?;
target.render(encoder)?;
let pixels = target.read_to_cpu()?;  // Only when needed
```

## Best Practices

### Batch Similar Draws

```rust
// Good: few state changes
pass.set_pipeline(&pipeline);
for object in &objects {
    pass.set_vertex_buffer(0, &object.vertices);
    pass.draw(0..object.count, 0..1);
}

// Less efficient: many state changes
for object in &objects {
    pass.set_pipeline(&object.pipeline);  // Changes every iteration
    pass.set_vertex_buffer(0, &object.vertices);
    pass.draw(0..object.count, 0..1);
}
```

### Minimize Clear Operations

```rust
// Clear once at start
pass.clear(Color::BLACK);

// Draw all objects
for object in &objects {
    pass.draw(...);
}
```

### Use Appropriate Draw Counts

```rust
// Good: draw what you need
pass.draw(0..actual_vertex_count, 0..1);

// Wasteful: drawing extra vertices
pass.draw(0..buffer_capacity, 0..1);
```

## Debug Tips

If nothing renders:

1. Check vertex buffer data
2. Check pipeline topology matches your data
3. Check shader locations match vertex layout
4. Ensure `draw()` range is correct
5. Check clear color isn't same as object color