[][src]Module cala::graphics

Render (draw) graphics using the GPU and/or SIMD.

Getting Started

This API is designed to be high-level without sacrificing optimization. Graphics are complicated though, so before you start, a few things need to be defined.

Shader

A Shader is a program that runs on the GPU for the purpose of drawing Shapes. When you make your program, start by creating a shader. Shaders are built at compile time, so you'll need to make a build.rs and depend on the res crate. Calling generate() in your build.rs will generate your shaders.

Shape

A shape is a collection of vertices that when connected make a 2D or 3D shape. Shapes can only be used with one Shader because they may have shader-specific additional information attached to them like color or graphic coordinates.

Group

Shapes themselves can't be drawn, first you must make put them into a Group. When putting a shape into a group you may attach a transform and optionally texture coordinates to it.

Coordinate System

X goes from 0 to 1, Y goes from 0 to Canvas.height()

Example

Open a window with a triangle that rotates once a second:

use cala::*;

use cala::graphics::{
    color::SRgb32, shader, Group, Shader, ShaderBuilder, ShapeBuilder,
    Transform,
};
use cala::input::{GameInput, Input, TextInput, UiInput};

pub struct Context {
    colors: Shader,
    triangle: Group,
    timed: f64,
}

// Initialize & set loop to `init()`.
cala::exec!(init);

async fn init() {
    let timed = 0.0;
    // Load a shader.
    let colors = Shader::new(shader!("color"));

    // Build triangle Shape
    let triangle = Group::new();
    let mut context = Context {
        colors,
        triangle,
        timed,
    };

    // Game loop
    while [canvas(&mut context).fut(), input().fut()].select().await.1 {}
}

fn animate_triangle(context: &mut Context, time: f32, aspect: f32) {
    #[rustfmt::skip]
    let vertices = [
         -1.0,  1.0,  1.0, 0.5, 0.0,
          1.0,  1.0,  0.0, 0.0, 1.0,
          0.0, -1.0,  1.0, 1.0, 1.0,

          0.0, -1.0,  1.0, 0.7, 0.0,
          1.0,  1.0,  1.0, 0.7, 0.0,
         -1.0,  1.0,  1.0, 0.7, 0.0,
    ];

    let triangle_shape = ShapeBuilder::new()
        .vert(&vertices)
        .face(Transform::new())
        .finish(&context.colors);
    let transform = Transform::new()
        .rotate(0.0, 1.0, 0.0, time)
        .scale(0.25, 0.25 * aspect, 0.25)
        .translate(0.5, 0.5 * aspect, 0.0);
    context.triangle.write(0, &triangle_shape, &transform);
}

// Function that runs while your app runs.
pub async fn canvas(context: &mut Context) -> bool {
    // Set the background color.
    let mut canvas = pixels::canvas(SRgb32::new(0.0, 0.5, 0.0)).await;

    // Update triangle
    context.timed = (context.timed + canvas.elapsed().as_secs_f64()) % 1.0;
    animate_triangle(context, context.timed as f32, canvas.aspect());

    // Draw triangle
    canvas.draw(&context.colors, &context.triangle);

    true
}

async fn input<'a>() -> bool {
    match cala::input::input().await {
        Input::Ui(UiInput::Back) => return false,
        Input::Game(_id, GameInput::Back) => return false,
        Input::Text(TextInput::Back) => return false,
        input => println!("{:?}", input),
    }
    true
}

Modules

color

Color Models and types.

Macros

shader

Load a generated shader from the res crate.

Structs

Group

A Group.

Raster

A 2D rectangular image.

Region

Location and dimensions of a rectangular region within a Raster.

Shader

A Shader.

ShaderBuilder

A builder for portable shaders.

Shape

A Shape.

ShapeBuilder

Builder for a shape.

Texture

Raster stored on the GPU.

Transform

A 4x4 transformation matrix.

Traits

Canvas

Something that can be drawn on.

Functions

draw_thread

Run the infinite event loop. You should only call this on the main thread.