Rust文本渲染库glyph_brush_draw_cache的使用,高效缓存与绘制2D字形和文本的Rust图形处理工具

Rust文本渲染库glyph_brush_draw_cache的使用,高效缓存与绘制2D字形和文本的Rust图形处理工具

glyph_brush_draw_cache是用于ab_glyph的栅格化缓存库,主要用于glyph_brush中。

主要功能:

  • 管理一个纹理,将字形绘制到其中并提供字形的纹理矩形查找
  • 根据需要自动重用和重新排序

示例代码:

use glyph_brush_draw_cache::DrawCache;

// 使用默认设置构建缓存
let mut draw_cache = DrawCache::builder().build();

// 将一些字形加入队列以存储在缓存中
for (font_id, glyph) in glyphs {
    draw_cache.queue_glyph(font_id, glyph);
}

// 处理队列中的所有内容,根据需要栅格化和上传
draw_cache.cache_queued(&fonts, |rect, tex_data| update_texture(rect, tex_data))?;

// 访问给定字形的纹理位置和像素位置以绘制纹理四边形
match draw_cache.rect_for(font_id, &glyph) {
    Some((tex_coords, px_coords)) => {}
    None => {/* 该字形没有轮廓,或者没有被加入队列进行缓存 */}
}

示例

可以运行draw_cache_guts示例查看其工作原理(从顶层目录运行):

cargo run --example draw_cache_guts

完整示例代码

以下是一个更完整的示例展示如何使用glyph_brush_draw_cache:

use glyph_brush_draw_cache::DrawCache;
use ab_glyph::{FontRef, Glyph};

// 假设我们有一些字体
let fonts = vec![FontRef::try_from_slice(include_bytes!("../fonts/NotoSans-Regular.ttf")).unwrap()];

// 创建绘制缓存
let mut draw_cache = DrawCache::builder()
    .dimensions(512, 512)  // 设置纹理尺寸
    .build();

// 准备要渲染的字形
let glyphs_to_cache = vec![
    (0, Glyph::new('H')),
    (0, Glyph::new('e')),
    (0, Glyph::new('l')),
    (0, Glyph::new('l')),
    (0, Glyph::new('o')),
];

// 将字形加入队列
for (font_id, glyph) in glyphs_to_cache {
    draw_cache.queue_glyph(font_id, glyph);
}

// 模拟纹理更新函数
fn update_texture(rect: glyph_brush_draw_cache::Rectangle, data: &[u8]) {
    println!("更新纹理区域: {:?} 数据长度: {}", rect, data.len());
    // 这里应该将数据上传到GPU纹理
}

// 处理队列中的字形
if let Err(e) = draw_cache.cache_queued(&fonts, update_texture) {
    eprintln!("缓存字形失败: {:?}", e);
}

// 查询字形信息
if let Some((tex_coords, px_coords)) = draw_cache.rect_for(0, &Glyph::new('H')) {
    println!("'H'的纹理坐标: {:?}", tex_coords);
    println!("'H'的像素坐标: {:?}", px_coords);
}

这个示例展示了如何:

  1. 初始化一个DrawCache
  2. 将字形加入队列
  3. 处理队列中的字形
  4. 查询已缓存字形的信息

在实际应用中,您需要:

  • 提供真实的字体数据
  • 实现真正的纹理上传逻辑
  • 可能需要在主渲染循环中重复使用这些缓存字形

1 回复

glyph_brush_draw_cache:高效的2D文本渲染缓存库

介绍

glyph_brush_draw_cache是Rust中一个高效的文本渲染缓存库,专门用于2D字形和文本的缓存与绘制。它是glyph_brush生态系统的一部分,提供了底层缓存实现,可以显著提高文本渲染性能。

这个库的核心功能是缓存已渲染的字形纹理,避免重复渲染相同的字形,特别适合需要频繁更新文本但内容变化不大的场景(如UI、游戏HUD等)。

主要特性

  • 高效的字形纹理缓存
  • 自动纹理图集管理
  • 支持多线程渲染
  • glyph_brush无缝集成
  • 可定制的缓存策略

完整示例代码

use glyph_brush::{GlyphBrush, GlyphBrushBuilder, Section};
use glyph_brush_draw_cache::DrawCache;
use wgpu::{Device, Queue, TextureFormat};
use rusttype::Font;

fn main() {
    // 1. 初始化图形设备
    let instance = wgpu::Instance::new(wgpu::Backends::all());
    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();

    // 2. 加载字体
    let font_data = include_bytes!("../fonts/DejaVuSans.ttf"); // 替换为你的字体文件路径
    let font = Font::try_from_bytes(font_data as &[u8]).unwrap();

    // 3. 创建DrawCache和GlyphBrush
    let glyph_brush = GlyphBrushBuilder::using_font(font)
        .draw_cache(DrawCache::builder()
            .dimensions(1024, 1024)  // 纹理图集大小
            .scale_tolerance(0.1)     // 缩放容差
            .position_tolerance(0.1)  // 位置容差
            .build())
        .build(&device);

    // 4. 游戏/应用主循环
    let mut frame_count = 0;
    loop {
        frame_count += 1;
        
        // 5. 准备要渲染的文本部分
        let section1 = Section {
            text: &format!("Frame: {}", frame_count),
            screen_position: (30.0, 30.0),
            bounds: (400.0, 100.0),
            color: [1.0, 1.0, 1.0, 1.0],
            ..Default::default()
        };

        let section2 = Section {
            text: "Hello, glyph_brush_draw_cache!",
            screen_position: (30.0, 80.0),
            bounds: (400.0, 100.0),
            color: [0.5, 0.8, 0.2, 1.0],
            ..Default::default()
        };

        // 6. 排队要渲染的文本
        glyph_brush.queue(section1);
        glyph_brush.queue(section2);

        // 7. 创建命令编码器
        let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
            label: Some("text_render_encoder"),
        });

        // 8. 渲染文本
        glyph_brush.draw_queued(
            &device,
            &mut encoder,
            &queue,
            &TextureFormat::Bgra8UnormSrgb, // 根据你的实际情况调整纹理格式
            glyph_brush::Extra::default(),
        ).unwrap();

        // 9. 提交命令缓冲区
        queue.submit(std::iter::once(encoder.finish()));

        // 这里应该添加帧率控制和退出逻辑
        // 例如: std::thread::sleep(std::time::Duration::from_millis(16));
    }
}

代码说明

  1. 图形设备初始化:使用wgpu创建图形设备和队列,这是现代图形API的标准做法。

  2. 字体加载:使用rusttype库加载TrueType或OpenType字体。

  3. 创建缓存和画笔:配置DrawCache并创建GlyphBrush实例,这是文本渲染的核心组件。

  4. 主循环:模拟游戏或应用的主循环,每帧更新文本。

  5. 文本部分准备:创建Section结构体定义要渲染的文本内容、位置、颜色等属性。

  6. 排队文本:将要渲染的文本加入队列。

7-9. 渲染流程:创建命令编码器,执行文本渲染,并提交命令缓冲区。

注意事项

  1. 需要添加wgpuglyph-brushglyph_brush_draw_cacherusttype到你的Cargo.toml依赖项。

  2. 实际使用时需要处理窗口创建和表面配置,这里简化了示例。

  3. 确保提供的字体文件路径正确,或者使用系统字体。

  4. 在实际应用中,应该添加适当的帧率控制和退出逻辑。

这个完整示例展示了如何将glyph_brush_draw_cache集成到一个完整的Rust应用中,实现高效的动态文本渲染。通过缓存机制,即使是频繁更新的文本也能保持高性能渲染。

回到顶部