13 releases (6 breaking)

0.7.3 Mar 2, 2024
0.7.2 Feb 16, 2024
0.6.0 Jan 17, 2024
0.5.0 Jan 17, 2024
0.1.2 Sep 29, 2023

#233 in Game dev

Download history 68/week @ 2024-01-11 5/week @ 2024-01-18 356/week @ 2024-02-15 48/week @ 2024-02-22 177/week @ 2024-02-29 33/week @ 2024-03-07 10/week @ 2024-03-14 49/week @ 2024-03-28 26/week @ 2024-04-04 1/week @ 2024-04-11

76 downloads per month

MIT license

105KB
2K SLoC

LucentFlux Graphics Library

This crate provides a collection of common utilities when writing wgpu programs. This library is made public since the utilities provided may be useful, but is not intended to be a general-purpose library and features will be added and removed as and when we need them.

Features

Fragment-only fullscreen-quad shader pipelines

Reduced boilerplate for fragment shaders run on fullscreen quads:

use lf_gfx::{LfDeviceExt, LfCommandEncoderExt};
# let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::default());
# let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions::default())).unwrap();
# let (device, queue) = pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor::default(), None)).unwrap();

// Standard pipeline creation pattern, but ending with `create_fragment_only_render_pipeline`:
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { 
    label: Some("layout"), 
    bind_group_layouts: &[/* .. */], 
    push_constant_ranges:  &[/* .. */] 
});
let module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
    label: Some("module"),
    source: wgpu::ShaderSource::Wgsl(
        /* .. */
#       "".into()
    ),
});
let pipeline = device.create_fragment_only_render_pipeline(&lf_gfx::FragmentOnlyRenderPipelineDescriptor {
    label: Some("pipeline"),
    layout: Some(&layout),
    multisample: wgpu::MultisampleState::default(),
    fragment: wgpu::FragmentState { 
        module: &module, 
        entry_point: "main", 
        targets: &[/* .. */] 
    },
    multiview: None,
});

let mut cmd = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
    label: Some("command encoder"),
});
let mut rp = cmd.begin_fragment_only_render_pass(&lf_gfx::FragmentOnlyRenderPassDescriptor {
    label: Some("renderpass"),
    color_attachments: &[/* .. */],
    stencil_attachment: None,
    timestamp_writes: None,
});
// No need to bind vertex buffers or even a unit vertex shader
rp.set_pipeline(&pipeline);
rp.draw();

Local Storage

use lf_gfx::local_storage;

local_storage::store("my_key", "a value").unwrap();

// Persists between runs
let stored = local_storage::load("my_key");
assert_eq!(stored, Some("a value".to_owned()));

Game API

struct MyGameCfg { /* .. */ }
#[derive(serde::Serialize, serde::Deserialize)]
enum MyGameLinearInputs { 
    Forward,
    Jump,
    /* .. */ 
}
#[derive(serde::Serialize, serde::Deserialize)]
enum MyGameVectorInputs { 
    Look,
    /* .. */ 
}

struct MyGame { /* .. */ }

impl lf_gfx::Game for MyGame {
    type InitData = MyGameCfg;
    type LinearInputType = MyGameLinearInputs;
    type VectorInputType = MyGameVectorInputs;

    fn title() -> &'static str {
        "My Game"
    }

    fn default_inputs(&self) -> lf_gfx::input::InputMap<MyGameLinearInputs, MyGameVectorInputs> {
        let mut inputs = lf_gfx::input::InputMap::empty();

        inputs.assign_linear(lf_gfx::input::KeyCode::KeyW, MyGameLinearInputs::Forward);
        inputs.assign_linear(lf_gfx::input::MouseInputType::ScrollUp, MyGameLinearInputs::Jump);

        inputs.assign_vector(lf_gfx::input::VectorInputType::MouseMove, MyGameVectorInputs::Look);

        return inputs;
    }

    fn init(data: &lf_gfx::GameData, init: Self::InitData) -> anyhow::Result<Self> {
        Ok(Self { /* .. */ })
    }

    fn window_resize(&mut self, data: &lf_gfx::GameData, new_size: winit::dpi::PhysicalSize<u32>) {
        /* .. */
    }

    fn handle_linear_input(
        &mut self,
        data: &lf_gfx::GameData,
        input: &Self::LinearInputType,
        activation: lf_gfx::input::LinearInputActivation,
    ) {
        /* .. */
    }

    fn handle_vector_input(
        &mut self,
        data: &lf_gfx::GameData,
        input: &Self::VectorInputType,
        activation: lf_gfx::input::VectorInputActivation,
    ) {
        /* .. */
    }

    fn render_to(&mut self, data: &lf_gfx::GameData, view: wgpu::TextureView) {
        /* .. */
    }
}

fn main() {
    use lf_gfx::LfGameExt;
    MyGame::run(MyGameCfg { /* .. */ });
}

Faster Non-cryptographic Hashing

let mut hs = lf_gfx::FastHashSet::default();
let mut hm = lf_gfx::FastHashMap::default();

hs.insert(10);
hm.insert(20, 30);

Dependencies

~6–46MB
~718K SLoC