如何在SDL2 Rust绑定中管理绘图表面?解决白板程序卡顿问题
解决方案:增量绘制优化白板程序性能
核心思路
不再每次清空画布并重绘所有点,而是仅绘制新增的点,同时处理窗口重绘场景(如窗口最小化恢复)时的全量重绘需求。
修改后的代码框架
#[derive(Copy, Clone, PartialEq, Eq)] struct Center { point: Point, radius: i32, } fn main() { //... let mut canvas = window.into_canvas().build().unwrap(); let mut points: Vec<Center> = Vec::new(); // 记录上一次绘制完成的点数量,用于增量绘制 let mut last_drawn_count = 0; // 初始化:先绘制白色背景,确保初始缓冲区是正确的 canvas.set_draw_color(Color::RGB(255, 255, 255)); canvas.clear(); canvas.present(); 'running: loop { for event in event_pump.poll_iter() { match event { // 处理退出事件 Event::Quit { .. } => break 'running, // 处理窗口重绘事件:需要重新全量绘制所有内容 Event::Window { win_event: WindowEvent::Exposed, .. } => { canvas.set_draw_color(Color::RGB(255, 255, 255)); canvas.clear(); canvas.set_draw_color(Color::RGB(0, 0, 0)); draw_centers(&mut canvas, &points); last_drawn_count = points.len(); canvas.present(); } Event::MouseMotion { x, y, mousestate, .. } => { // 鼠标按下时添加新点 if mousestate.is_pressed(MouseButton::Left) { points.push(Center { point: Point::new(x, y), radius: 2, // 示例半径 }); } } // 其他事件处理... _ => {} } } // 增量绘制新增的点 if last_drawn_count < points.len() { let new_points = &points[last_drawn_count..]; canvas.set_draw_color(Color::RGB(0, 0, 0)); draw_centers(&mut canvas, new_points); last_drawn_count = points.len(); } canvas.present(); } }
关键细节说明
- 初始背景绘制:程序启动时先绘制一次白色背景并
present,确保缓冲区中保存了正确的背景内容,后续无需重复清空。 - 增量绘制逻辑:通过
last_drawn_count记录已绘制的点数量,每次循环只绘制新增的点(从last_drawn_count到当前points长度的部分),避免全量重绘。 - 窗口重绘处理:当窗口收到
Exposed事件(如被遮挡后恢复、窗口大小调整),需要重新清空画布并全量绘制所有点,否则窗口内容会丢失。
为什么直接去掉canvas.clear()会变黑?
SDL的Canvas默认使用双缓冲机制:每次present()会交换前台(显示)和后台(绘制)缓冲区。如果不执行clear(),后台缓冲区的内容是未初始化的(通常为黑色),交换后前台就会显示黑色。初始时先绘制背景并present,就能让后台缓冲区保留正确的背景内容,后续增量绘制时直接在这个基础上添加新点即可。
内容的提问来源于stack exchange,提问作者Manuel
相关产品推荐
相关产品推荐

