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());
}
示例说明
-
视口管理器初始化:首先创建ViewportManager实例,用于管理所有窗口和视口。
-
窗口创建:示例中创建了两个窗口,一个主窗口和一个副窗口。
-
视口布局:在主窗口中设置了左右两个视口,各占50%宽度。
-
图形API集成:使用wgpu进行渲染初始化,创建了表面、适配器、设备和命令队列。
-
事件处理:处理窗口事件和渲染循环,响应窗口大小变化等事件。
-
渲染流程:展示了基本的渲染流程,包括帧获取、命令编码和渲染通道设置。
注意事项
- 确保在主线程上调用窗口管理相关函数
- 处理窗口事件时要注意性能影响
- 在多线程环境中使用时需要适当的同步
- 视口坐标和尺寸是相对于窗口的归一化值(0-1)
这个完整示例展示了re_viewport库的核心功能,包括多窗口管理、视口布局和图形API集成,可以作为开发复杂图形应用的起点。