【问题标题】:Windows mouse coordinates VS OpenGL mouse coordinatesWindows 鼠标坐标 VS OpenGL 鼠标坐标
【发布时间】:2013-04-30 00:25:09
【问题描述】:

我如何确定(我知道这不是正确使用的术语)对于window space 中鼠标的每个 位置,它会转换为OGL space(-1 , 1)。在这种情况下,用户移动鼠标的速度非常快,我假设 所有 它之前的位置都被转换为 OGL 坐标。我想说的是……即使我的C++ OGL coordinates converter 的计算成本非常高,普通 CPU 的速度也足以做到这一点(跟踪所有以前的事件)?可以说我在那里放了非常耗时的循环?或者.. 非常快method()。如果我移动鼠标足够快,如何确保不会跳过任何 OGL 坐标? 我不会在这里草率下任何结论或假设您可能会想到其他东西。

编辑:

我的程序主循环是这样的(伪代码):

void Pollevents()
{
    for everyt_obj in this
    {
        if Not Collide()
        {

            Move(x, y) //

        }
    }
}

void MousePos()
{
    mouse.pos = To_OGL_Coord2f()
}

这些是要执行的单独线程(但实际上不是真正的线程) 假设mouse.pos = (0, 0) 然后我将鼠标移动得足够快,以使新的mouse.pos 变为 (10, 10)。在单次执行循环中,鼠标位置与之前的位置相差甚远。现在,我如何通过执行 Christian Rau 提到的Bresenham's line algorithm 告诉我的程序,由该算法生成的那些值(未被跟踪)已被鼠标越过。我会为所有这些位置添加另一个循环吗?

【问题讨论】:

  • 如果您的计算机在 13 年前 之前被认为很慢,它仍然能够每秒执行超过 1 亿次 百万 次计算。将一对数字转换成另一对数字是否会让您认为您的计算机无法处理?
  • 我的意思是,程序当前正在运行。不是处理器计算的操作系统。看看this
  • @NicolBolas 当我将鼠标悬停在窗口中时,您可以在我给出的链接中看到鼠标位置的巨大差异。除非这是将其打印到 bash 的问题
  • @mr5:能否请您向我们展示您的 GLFW 事件处理源代码? Nicol Bolas 是对的,即使是古代计算机也足够快,可以处理像将两个整数处理成两个浮点数这样简单的事情,甚至每秒一百万次,无论它实际执行的是哪个代码。请注意,如果您的鼠标输入分辨率跟不上您实际移动它的速度,您所看到的可能只是一个伪影(游戏玩家专用鼠标的存在是有原因的)。
  • @mr5:所以本质上你想存储鼠标指针在窗口中的路径。好吧,只需使用一个 std::vector 来添加struct{float x, y; int timestamp}; 的元素。即使只有 1 MB 的数据,您也需要使用鼠标很长时间。在 60 Hz 的更新速率和 12 字节的结构大小下,将日志增长到 MB 需要 25 分钟。您可以使用此日志来插入其间的位置。大多数交互式应用程序实际上都会保留(短)鼠标移动日志,并使用它以完全这种方式平滑移动。

标签: c++ opengl mouse-coordinates


【解决方案1】:

如何确保在我移动坐标时不会跳过任何 OGL 坐标 鼠标够快吗?

这是不可能的,因为当以理论上无限的精度进行跟踪时,无法让操作系统为鼠标移动经过的每个点生成鼠标事件。

确保这一点的唯一方法是自己填充两个(可能很远)鼠标位置之间的缺失点。如果您只想为鼠标移动的每个位置绘制一个点(可能使用 OpenGL),请改为绘制一条线。

另一方面,如果您自己需要这些中间鼠标位置以进行进一步计算,您将无法使用一些常见的线光栅化算法(如Bresenham Algorithm 学校自己计算它们用于线光栅化的书籍算法)。这基本上做的是计算离散网格上的每个点,从一个点到另一个点的线会交叉(类似于您的显卡在将一条线转换为离散像素时所做的),因此这将生成您的虚拟的每个离散鼠标位置鼠标路径已交叉(忽略测量点之间的任何非线性鼠标移动)。

编辑:如果您不需要具有适当等宽特性的离散线,那么比弄乱线光栅化更容易的方法也就是使用浮点位置并做一个简单的端点的线性插值,就像 datenwolf 在他的评论中所写。这也将为您提供比离散鼠标位置更好的计时精度。但这一切都取决于您实际上想对这些鼠标位置做什么(现在是告诉我们的好方法)。

编辑:从您更新的问题看来,您需要高粒度的鼠标位置才能计算鼠标与某些对象的碰撞。在这种情况下,您实际上根本不需要中间点。只需从当前鼠标位置到前一个鼠标位置的线(表示为一对点,或任何理论线表示)并计算对象与该线而不是单个点的碰撞。

【讨论】:

  • 在指定的时间内,我该怎么做?假设在一毫秒内。啊,我的意思是我的程序主要由鼠标事件驱动。我怎么能告诉我的程序这个位置已经被鼠标越过了。另外,请注意,这不仅仅是一次要执行的刷新。
  • @mr5 与时间无关(如果您自己不需要一些特定的时间)。如果你得到一个鼠标事件,只需计算你得到的鼠标位置和最后一个事件的鼠标位置(你存储在某个地方)之间的所有点。如果您正在谈论自己为这些中间点生成虚拟鼠标事件,那么我认为这不是特别好的主意。
  • @mr5 你想用这些点做什么?如果您只想对每个鼠标点进行一些特定的计算,那么只需等待普通的移动事件,计算每个事件的(可能多个)中间点到最后一个跟踪位置(从最后一个事件开始)并调用计算对于每个计算点。谁说您需要在单个点的粒度上发生实际事件?如果您需要对这些点进行更高级的处理,那么也许可以对其进行重组,甚至根本不需要中间点?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-18
  • 2019-11-04
  • 2016-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多