Skip to content

[Feature] TextureBuilder Image Loading with Mipmap Generation #81

@vmarcella

Description

@vmarcella

Overview

Add convenience methods to TextureBuilder for loading tsxtures directly from image files, with optional mipamp generation and sRGB format handling.

Current State

TextureBuilder requires manual pixel data:

// crates/lambda-rs/src/render/texture.rs
impl TextureBuilder {
  pub fn new_2d(format: TextureFormat) -> Self;
  pub fn with_size(mut self, width: u32, height: u32) -> Self;
  pub fn with_data(mut self, pixels: &[u8]) -> Self;
  // ...
}

Users must manually load images, decode them, and provide raw pixel bytes with the correct format.

Scope

  • Add TextureBuilder::from_image(path) that loads and decodes common formats (PNG, JPEG, etc)
  • Add TextureBuilder::from_image_bytes(bytes) for in-memory image data
  • Automatically detect dimensions and select appropriate format (sRGB by default for color iamges)
  • Add with_mipmaps(bool) to optionally generate mipmaps
  • Add with_srgb(bool) override for explicit format control
  • Investigate crates to use for loading images (Like image)

Proposed API

impl TextureBuilder {
  /// Load a texture from an image file path.
  /// Automatically determines dimensions and uses sRGB format for RGBA images.
  pub fn from_image(path: impl AsRef<Path>) -> Result<Self, ImageLoadError>;

  /// Load a texture from in-memory image bytes (PNG, JPEG, etc.).
  pub fn from_image_bytes(bytes: &[u8]) -> Result<Self, ImageLoadError>;

  /// Generate mipmaps for this texture (default: false).
  pub fn with_mipmaps(mut self, generate: bool) -> Self;

  /// Override the sRGB format selection (default: true for color images).
  pub fn with_srgb(mut self, srgb: bool) -> Self;
}

pub enum ImageLoadError {
  FileNotFound(PathBuf),
  DecodeError(String),
  UnsupportedFormat(String),
}

Example Usage

// Load texture from file with mipmaps
let texture = TextureBuilder::from_image("assets/diffuse.png")?
  .with_mipmaps(true)
  .with_label("diffuse-texture")
  .build(&mut render_context)?;

// Load from embedded bytes, override sRGB
let texture = TextureBuilder::from_image_bytes(include_bytes!("icon.png"))?
  .with_srgb(false)  // Linear color space
  .build(&mut render_context)?;

Acceptance criteria

  • TextureBuilder::from_image(path) loads PNG, JPEG, and other common formats
  • TextureBuilder::from_image_bytes(bytes) loads textures from in-memory data
  • sRGB format selected by default for RGBA images
  • with_srgb(bool) to override format
  • with_mipmaps(bool) to generate mipmap levels
  • ImageLoadError for making debugging issues with textures easier
  • Investigate (and add) image to handle image loading data.
  • Example demonstrating image loading
  • Documentation for supported formats and mipmap behavior

Notes

  • Mipmap generation may use box filtering or higher-quality downsampling
  • Consider putting any newly added dependencies behind a feature
  • Grayscale and other channel layouts should map to appropriate formats

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions