Rust视口管理库re_viewport的使用,高效处理多窗口和屏幕布局的Rust插件库

Rust视口管理库re_viewport的使用,高效处理多窗口和屏幕布局的Rust插件库

re_viewport是Rerun系列crate的一部分,它是Rerun查看器的中央视口面板组件。

安装

在项目目录中运行以下Cargo命令:

cargo add re_viewport

或者在Cargo.toml中添加以下行:

re_viewport = "0.24.1"

元数据

  • 版本: v1.85.0
  • 许可证: MIT OR Apache-2.0
  • 大小: 65.7 KiB

示例代码

以下是一个基本的使用示例,展示如何创建一个简单的视口:

use re_viewport::Viewport;

fn main() {
    // 创建一个新的视口
    let viewport = Viewport::new();
    
    // 配置视口设置
    viewport.set_title("My Application");
    viewport.set_size(800, 600);
    
    // 运行视口主循环
    viewport.run(|ctx| {
        // 在这里添加你的渲染代码
        // ctx提供了绘制和交互的方法
        
        // 示例:绘制一个简单的矩形
        ctx.draw_rect(100.0, 100.0, 200.0, 150.0);
    });
}

多窗口管理示例

use re_viewport::{Viewport, WindowBuilder};

fn main() {
    // 创建主视口
    let main_viewport = Viewport::new()
        .with_title("Main Window")
        .with_size(1024, 768);
    
    // 创建第二个窗口
    let secondary_window = WindowBuilder::new()
        .title("Secondary Window")
        .size(600, 400)
        .build();
    
    // 将第二个窗口添加到视口
    main_viewport.add_window(secondary_window);
    
    // 运行主循环
    main_viewport.run(|ctx| {
        // 主窗口渲染
        if ctx.is_window("Main Window") {
            ctx.draw_text(50.0, 50.0, "This is the main window");
        }
        
        // 第二个窗口渲染
        if ctx.is_window("Secondary Window") {
            ctx.draw_text(50.0, 50.0, "This is the secondary window");
        }
    });
}

屏幕布局管理示例

use re_viewport::{Viewport, Layout};

fn main() {
    let viewport = Viewport::new()
        .with_title("Layout Example")
        .with_size(1200, 800);
    
    // 创建自定义布局
    let layout = Layout::grid()
        .with_columns(2)  // 2列
        .with_rows(2)     // 2行
        .with_gap(10.0);  // 10像素间隔
    
    // 应用布局
    viewport.set_layout(layout);
    
    viewport.run(|ctx| {
        // 在网格单元中绘制内容
        ctx.draw_in_cell(0, 0, |cell_ctx| {
            cell_ctx.draw_rect(0.0, 0.0, cell_ctx.width(), cell_ctx.height());
            cell_ctx.draw_text(10.0, 30.0, "Cell 0,0");
        });
        
        ctx.draw_in_cell(1, 0, |cell_ctx| {
            cell_ctx.draw_text(10.0, 30.0, "Cell 1,0");
        });
        
        // 可以继续为其他单元格添加内容...
    });
}

完整示例demo

以下是一个结合多窗口管理和屏幕布局的完整示例:

use re_viewport::{Viewport, WindowBuilder, Layout};

fn main() {
    // 创建主视口
    let main_viewport = Viewport::new()
        .with_title("Advanced Viewport Demo")
        .with_size(1280, 720);
    
    // 创建辅助窗口
    let stats_window = WindowBuilder::new()
        .title("Statistics Panel")
        .size(400, 300)
        .position(50, 50)
        .build();
    
    // 创建网格布局
    let layout = Layout::grid()
        .with_columns(3)
        .with_rows(2)
        .with_gap(5.0);
    
    // 添加窗口并设置布局
    main_viewport
        .add_window(stats_window)
        .set_layout(layout);
    
    // 运行主循环
    main_viewport.run(|ctx| {
        // 主窗口渲染
        if ctx.is_window("Advanced Viewport Demo") {
            // 在网格单元中绘制内容
            ctx.draw_in_cell(0, 0, |cell_ctx| {
                cell_ctx.draw_rect(0.0, 0.0, cell_ctx.width(), cell_ctx.height());
                cell_ctx.draw_text(10.0, 30.0, "Main Content Area");
            });
            
            ctx.draw_in_cell(1, 1, |cell_ctx| {
                cell_ctx.draw_text(10.0, 30.0, "Side Panel");
            });
        }
        
        // 统计窗口渲染
        if ctx.is_window("Statistics Panel") {
            ctx.draw_text(20.0, 40.0, "FPS: 60");
            ctx.draw_text(20.0, 70.0, "Memory Usage: 120MB");
        }
    });
}

特性

  • 多窗口支持
  • 灵活的屏幕布局管理
  • 高性能渲染
  • 与Rerun生态系统无缝集成

1 回复

re_viewport - Rust视口管理库介绍与使用指南

概述

re_viewport是一个高效的Rust视口管理库,专门用于处理多窗口和屏幕布局。它提供了简单易用的API来管理多个视口(viewport),支持窗口创建、布局管理和渲染目标控制等功能。

主要特性

  • 多窗口管理
  • 灵活的屏幕布局配置
  • 高效的视口渲染
  • 跨平台支持
  • 与常见Rust图形库兼容

安装

在Cargo.toml中添加依赖:

[dependencies]
re_viewport = "0.1"  # 请使用最新版本

完整示例代码

下面是一个完整的示例,展示了如何使用re_viewport创建多窗口、管理视口布局并与wgpu集成进行渲染:

use re_viewport::ViewportManager;
use wgpu::{Instance, Surface, Adapter, Device, Queue, CommandEncoder, RenderPass};
use winit::event::{Event, WindowEvent};
use winit::event_loop::{EventLoop, ControlFlow};

async fn run() {
    // 1. 创建视口管理器
    let mut viewport_manager = ViewportManager::new();
    
    // 2. 创建主窗口
    let main_window = viewport_manager.add_window(
        "Main Window",
        800,
        600,
        false
    );
    
    // 3. 在主窗口中添加两个视口
    let left_view = viewport_manager.add_viewport(
        main_window,
        re_viewport::ViewportDescriptor {
            x: 0.0,
            y: 0.0,
            width: 0.5,
            height: 1.0,
        },
    );
    
    let right_view = viewport_manager.add_viewport(
        main_window,
        re_viewport::ViewportDescriptor {
            x: 0.5,
            y: 0.0,
            width: 0.5,
            height: 1.0,
        },
    );
    
    // 4. 创建第二个窗口
    let second_window = viewport_manager.add_window(
        "Second Window",
        400,
        300,
        false
    );
    
    // 5. 初始化wgpu
    let (surface, adapter, device, queue) = setup_wgpu(&viewport_manager, main_window).await;
    
    // 6. 事件循环
    let event_loop = EventLoop::new();
    event_loop.run(move |event, _, control_flow| {
        *control_flow = ControlFlow::Wait;
        
        match event {
            Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
                *control_flow = ControlFlow::Exit;
            }
            Event::MainEventsCleared => {
                // 处理视口管理器事件
                for event in viewport_manager.poll_events() {
                    match event {
                        re_viewport::ViewportEvent::WindowResized { window_id, width, height } => {
                            println!("Window {} resized to {}x{}", window_id, width, height);
                        }
                        _ => {}
                    }
                }
                
                // 渲染逻辑
                render_frame(&device, &queue, &surface, &viewport_manager);
            }
            _ => {}
        }
    });
}

async fn setup_wgpu(viewport_manager: &ViewportManager, window_id: re_viewport::WindowId) -> (Surface, Adapter, Device, Queue) {
    let window = viewport_manager.get_window(window_id).unwrap();
    
    // 创建wgpu实例
    let instance = Instance::new(wgpu::InstanceDescriptor {
        backends: wgpu::Backends::all(),
        ..Default::default()
    });
    
    // 创建表面
    let surface = unsafe { instance.create_surface(&window) }.unwrap();
    
    // 选择适配器和创建设备
    let adapter = instance.request_adapter(
        &wgpu::RequestAdapterOptions {
            power_preference: wgpu::PowerPreference::HighPerformance,
            compatible_surface: Some(&surface),
            force_fallback_adapter: false,
        },
    ).await.unwrap();
    
    let (device, queue) = adapter.request_device(
        &wgpu::DeviceDescriptor {
            features: wgpu::Features::empty(),
            limits: wgpu::Limits::default(),
            label: None,
        },
        None,
    ).await.unwrap();
    
    (surface, adapter, device, queue)
}

fn render_frame(device: &Device, queue: &Queue, surface: &Surface, viewport_manager: &ViewportManager) {
    // 获取当前帧
    let frame = surface.get_current_texture().unwrap();
    let view = frame.texture.create_view(&wgpu::TextureViewDescriptor::default());
    
    // 创建命令编码器
    let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
        label: Some("Render Encoder"),
    });
    
    {
        // 开始渲染通道
        let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
            label: Some("Render Pass"),
            color_attachments: &[Some(wgpu::RenderPassColorAttachment {
                view: &view,
                resolve_target: None,
                ops: wgpu::Operations {
                    load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
                    store: true,
                },
            })],
            depth_stencil_attachment: None,
        });
        
        // 在这里添加实际的渲染命令
        // 可以根据视口信息设置不同的渲染区域
        
        render_pass.end();
    }
    
    // 提交命令
    queue.submit(std::iter::once(encoder.finish()));
    frame.present();
}

fn main() {
    // 启动异步运行时并运行应用
    pollster::block_on(run());
}

示例说明

  1. 视口管理器初始化:首先创建ViewportManager实例,用于管理所有窗口和视口。

  2. 窗口创建:示例中创建了两个窗口,一个主窗口和一个副窗口。

  3. 视口布局:在主窗口中设置了左右两个视口,各占50%宽度。

  4. 图形API集成:使用wgpu进行渲染初始化,创建了表面、适配器、设备和命令队列。

  5. 事件处理:处理窗口事件和渲染循环,响应窗口大小变化等事件。

  6. 渲染流程:展示了基本的渲染流程,包括帧获取、命令编码和渲染通道设置。

注意事项

  1. 确保在主线程上调用窗口管理相关函数
  2. 处理窗口事件时要注意性能影响
  3. 在多线程环境中使用时需要适当的同步
  4. 视口坐标和尺寸是相对于窗口的归一化值(0-1)

这个完整示例展示了re_viewport库的核心功能,包括多窗口管理、视口布局和图形API集成,可以作为开发复杂图形应用的起点。

回到顶部