如何在Glium+Glutin中获取鼠标的X和Y坐标?
获取Glium中鼠标点击坐标并转换为OpenGL坐标
一、获取窗口像素坐标
要获取鼠标点击位置,需在事件循环中监听两类窗口事件:
CursorMoved:实时更新鼠标在窗口内的像素坐标MouseInput:检测鼠标按键点击动作,读取已记录的鼠标坐标
修改你的事件处理代码,添加鼠标位置存储和事件匹配逻辑:
/* ... */ // 在event.run外部定义变量存储鼠标位置 let mut mouse_pos = (0.0, 0.0); // 获取窗口尺寸(用于后续坐标转换) let window = /* 你的Glium窗口实例 */; let mut window_size = window.get_inner_size().unwrap().to_logical::<f32>(window.scale_factor()); event.run(move |event, _, control_flow| { match event { glutin::event::Event::WindowEvent { event, .. } => match event { glutin::event::WindowEvent::CloseRequested => { println!("Received termination signal."); *control_flow = glutin::event_loop::ControlFlow::Exit; return; }, // 监听鼠标移动,更新位置(适配高DPI窗口) glutin::event::WindowEvent::CursorMoved { position, .. } => { let logical_pos = position.to_logical::<f32>(window.scale_factor()); mouse_pos = (logical_pos.x, logical_pos.y); }, // 监听左键点击事件 glutin::event::WindowEvent::MouseInput { state, button, .. } => { if button == glutin::event::MouseButton::Left && state == glutin::event::ElementState::Pressed { println!("点击位置(窗口像素坐标):X={}, Y={}", mouse_pos.0, mouse_pos.1); // 在此处执行渲染图片到该位置的逻辑 } }, // 监听窗口大小变化,更新尺寸 glutin::event::WindowEvent::Resized(size) => { window_size = size.to_logical::<f32>(window.scale_factor()); }, _ => return, }, glutin::event::Event::NewEvents(cause) => match cause { glutin::event::StartCause::ResumeTimeReached { .. } => (), glutin::event::StartCause::Init => (), _ => return, }, _ => return, } });
二、转换为OpenGL标准化设备坐标(NDC)
如果需要直接使用OpenGL的坐标范围(-1到1),可通过以下公式将窗口像素坐标转换为NDC坐标:
- X轴:
ndc_x = (2.0 * window_x) / window_width - 1.0 - Y轴:
ndc_y = 1.0 - (2.0 * window_y) / window_height(窗口Y轴向上递增,而OpenGL NDC Y轴向下递增,需反转)
在点击事件中添加转换逻辑:
// 鼠标点击事件内 if button == glutin::event::MouseButton::Left && state == glutin::event::ElementState::Pressed { let (win_x, win_y) = mouse_pos; let (win_width, win_height) = (window_size.width, window_size.height); let ndc_x = (2.0 * win_x) / win_width - 1.0; let ndc_y = 1.0 - (2.0 * win_y) / win_height; println!("点击位置(OpenGL NDC坐标):X={}, Y={}", ndc_x, ndc_y); // 直接使用ndc_x和ndc_y构建顶点缓冲区,无需额外矩阵变换即可渲染到对应位置 }
关键说明
- 高DPI适配:使用
to_logical方法将物理坐标转换为逻辑坐标,避免高分辨率屏幕下的坐标偏移 - 窗口尺寸更新:监听
Resized事件同步窗口尺寸,确保坐标转换的准确性 - 简化顶点缓冲区:使用NDC坐标时,可直接将其作为图片顶点位置,省去视图/投影矩阵的额外计算
内容的提问来源于stack exchange,提问作者AggelosT
相关产品推荐
相关产品推荐

