rustamethyst

How to load a texture from memory in amethyst engine?


I have read the offical docs but can't find any way to load a texture from memory directly. It currently do have the APIs to load textures from files but what I want exactly is to load a texture from a &[u8] which respresents an RGBA formatted image with fixed size.


Solution

  • There is a solution mentioned slightly in the offical tutorial

    //To load a texture in memory, you can't use [0.; 4].into() as the TextureData anymore. 
    // Use:
    use amethyst::{
        assets::{AssetStorage, Handle, Loader, Prefab, PrefabLoader},
        ecs::World,
        renderer::{
            loaders::load_from_srgba,
            palette::Srgba,
            types::TextureData,
            Texture,
        },
    };
    
    let loader = world.read_resource::<Loader>();
    let texture_assets = world.read_resource::<AssetStorage<Texture>>();
    let texture_builder = load_from_srgba(Srgba::new(0., 0., 0., 0.));
    let texture_handle: Handle<Texture> =
    loader.load_from_data(TextureData::from(texture_builder), (), &texture_assets);
    

    Another way is introduced in the Doc of ImageFormat.

    let loader = res.fetch_mut::<Loader>();
    let texture_storage = res.fetch_mut::<AssetStorage<Texture>>();
    
    let texture_builder = TextureBuilder::new()
        .with_data_width(handle.width)
        .with_data_height(handle.height)
        .with_kind(image::Kind::D2(handle.width, handle.height, 1, 1))
        .with_view_kind(image::ViewKind::D2)
        .with_sampler_info(SamplerInfo {
            min_filter: Filter::Linear,
            mag_filter: Filter::Linear,
            mip_filter: Filter::Linear,
            wrap_mode: (WrapMode::Clamp, WrapMode::Clamp, WrapMode::Clamp),
            lod_bias: 0.0.into(),
            lod_range: std::ops::Range {
                start: 0.0.into(),
                end: 1000.0.into(),
            },
            comparison: None,
            border: PackedColor(0),
            anisotropic: Anisotropic::Off,
        })
        .with_raw_data(handle.pixels, Format::Rgba8Unorm);
    
    let tex: Handle<Texture> = loader.load_from_data(TextureData(texture_builder), (), &texture_storage);
    

    For the version above 0.12, you have to warp the Handle<Texture> into a SpriteRender to display it.