c++ - SDL 鼠标移动事件在鼠标按钮按下事件类型下提供不一致的 xrel、yrel 值
问题描述
我尝试使用 SDL2 和 OpenGL 4.6 核心模式制作 3D 游戏,但我发现了一个让我感到困惑的问题,我不知道如何解决它,代码如下:
// SDL2 initialize
// Create a SDL2 window
// Create a OpenGL 4.6 core context
// GLAD initialize
// ImGui initialize
// SDL Settings
SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1", SDL_HINT_OVERRIDE);
// main loop
bool done = false;
bool relative = false;
while (!done) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
if (event.type == SDL_MOUSEBUTTONDOWN) {
if (event.button.button == SDL_BUTTON_LEFT) {
relative = true;
}
}
if (event.type == SDL_MOUSEBUTTONUP) {
if (event.button.button == SDL_BUTTON_LEFT) {
relative = false;
}
}
if (event.type == SDL_MOUSEMOTION) {
std::cout << "Mouse Motion Triggered: (" + std::to_string(event.motion.xrel) + " ," + std::to_string(event.motion.yrel) + ")" << std::endl;
}
}
if (relative) {
SDL_SetRelativeMouseMode(SDL_TRUE);
} else {
SDL_SetRelativeMouseMode(SDL_FALSE);
}
// Render ImGui
SDL_GL_SwapWindow(window);
}
如您所见,当我一直按住鼠标左键,然后将鼠标从屏幕的左上角移动到屏幕的右下角时,我希望鼠标的相对运动返回是这样的.
Mouse Motion Triggered: (11 ,6)
Mouse Motion Triggered: (13 ,8)
Mouse Motion Triggered: (14 ,8)
Mouse Motion Triggered: (14 ,8)
Mouse Motion Triggered: (16 ,9)
Mouse Motion Triggered: (15 ,7)
Mouse Motion Triggered: (11 ,6)
Mouse Motion Triggered: (10 ,6)
相对坐标 x 和 y 值都应该是正数,但不是,实际结果是这样的:
Mouse Motion Triggered: (1 ,1)
Mouse Motion Triggered: (2 ,2)
Mouse Motion Triggered: (-6 ,-4)
Mouse Motion Triggered: (3 ,3)
Mouse Motion Triggered: (1 ,1)
Mouse Motion Triggered: (-2 ,-3)
Mouse Motion Triggered: (2 ,2)
Mouse Motion Triggered: (1 ,1)
Mouse Motion Triggered: (-4 ,-4)
Mouse Motion Triggered: (3 ,3)
Mouse Motion Triggered: (-3 ,-3)
Mouse Motion Triggered: (1 ,1)
Mouse Motion Triggered: (-2 ,-2)
Mouse Motion Triggered: (1 ,2)
Mouse Motion Triggered: (-2 ,-2)
这导致我的鼠标位置强制锁定在屏幕中间,然后我尝试解决这个问题,我重写了事件处理程序的代码,如下所示:
if (event.type == SDL_MOUSEBUTTONDOWN) {
if (event.button.button == SDL_BUTTON_LEFT) {
relative = true;
std::cout << "relative: " << relative << std::endl;
}
if (event.button.button == SDL_BUTTON_RIGHT) {
relative = false;
std::cout << "relative: " << relative << std::endl;
}
}
if (event.type == SDL_MOUSEBUTTONUP) {
// Now this event is empty.
}
我意识到如果我只是按下鼠标左键一次,然后向同一个方向移动鼠标,整个功能可以正常工作,但是如果我一直按住鼠标左键并向同一个方向移动鼠标呢?相对鼠标返回值event.motion.xrel
会event.motion.yrel
很奇怪,这些会给出一个相反的方向,迫使我的鼠标位置回到屏幕的中心,我不知道为什么会发生这种情况。
问题是什么?
环境细节
- 操作系统:窗口 10
- C++:2017
- 编译器:MSVC
- IDE:克莱恩
- SDL2:2.0.14#3(vcpkg 安装)
解决方案
我找到了导致xrel
andyrel
值变得如此扭曲的主要原因,那就是ImGui_ImplSDL2_NewFrame(window)
. 当我注释掉这段代码时,相对鼠标报告正常,但是如果我将此行添加到主循环中,相对鼠标会报告奇怪的坐标,迫使我的鼠标回到屏幕中心,我怀疑可能是 ImGui尝试控制鼠标事件,它与我完全不知道的东西有控制冲突。
我看到了源代码imgui_impl_sdl.cpp
,但我仍然不知道为什么会发生这种情况,解决这个问题的方法是我制作了一个切换键,点击 TAB 键来控制相机或 GUI 的鼠标。
这是我的最新代码:
// SDL2 initialize
// Create a SDL2 window
// Create a OpenGL 4.6 core context
// GLAD initialize
// ImGui initialize
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGui_ImplSDL2_InitForOpenGL(window, context);
ImGui_ImplOpenGL3_Init("#version 330");
ImGui::StyleColorsDark();
ImGuiIO &io = ImGui::GetIO();
// SDL Settings
SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1", SDL_HINT_OVERRIDE);
SDL_SetRelativeMouseMode(SDL_TRUE);
// main loop
bool done = false;
while (!done) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
ImGui_ImplSDL2_ProcessEvent(&event);
if (event.type == SDL_MOUSEMOTION) {
std::cout << "Mouse Motion Triggered: (" + std::to_string(event.motion.xrel) + " ," + std::to_string(event.motion.yrel) + ")" << std::endl;
}
}
// Render ImGui
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL2_NewFrame(window); // <-- this is the main reason
//ImGui::NewFrame();
//ImGui::Render();
//ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(window);
}
// Delete ImGui and SDL Context, Window and SDL_QUIT()
ImGui 版本:1.83
推荐阅读
- sql - 在 teradata 过程中创建表会导致 SELECT 错误
- spring-boot - RestBindingMode.auto 出现 Camel 错误
- sql - 列可用时的 Sql 连接,否则与剩余的列连接?
- arrays - 将数组插入到 mongoDB 中的字段中
- java - DeploymentDescriptorLoadException:片段合并失败
- python - 在烧瓶中验证用户输入
- c# - 如何在 C# 中访问和查找 OneDrive 文件
- javascript - 停止反应显示更多按钮滚动到内容底部
- javascript - 如何使用java脚本显示url照片
- java - 我们如何在安卓中删除文件夹以及应用程序卸载?