Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa OSX上的高分辨率和高帧率鼠标坐标?(或其他解决方案?)_Cocoa_Macos_Mouse_Iokit - Fatal编程技术网

Cocoa OSX上的高分辨率和高帧率鼠标坐标?(或其他解决方案?)

Cocoa OSX上的高分辨率和高帧率鼠标坐标?(或其他解决方案?),cocoa,macos,mouse,iokit,Cocoa,Macos,Mouse,Iokit,我想在OSX上获得高分辨率和高帧率的鼠标移动 “高帧率”=60 fps或更高(最好>120) “高分辨率”=亚像素值 问题 我有一个opengl视图以大约监视器刷新率运行,所以它是~60 fps。我用鼠标环视四周,所以我隐藏了鼠标光标,我依赖于鼠标的增量值 问题是鼠标事件的帧率太低,值被捕捉为整数(整像素)。这会造成“起伏”的观看体验。以下是鼠标增量值随时间变化的可视化: mouse delta X ^ xx 2 | x x x

我想在OSX上获得高分辨率和高帧率的鼠标移动

“高帧率”=60 fps或更高(最好>120)
“高分辨率”=亚像素值

问题
我有一个opengl视图以大约监视器刷新率运行,所以它是~60 fps。我用鼠标环视四周,所以我隐藏了鼠标光标,我依赖于鼠标的增量值

问题是鼠标事件的帧率太低,值被捕捉为整数(整像素)。这会造成“起伏”的观看体验。以下是鼠标增量值随时间变化的可视化:

    mouse delta X
    ^                xx
  2 |      x    x x     x xx
    | x x x   x             xx x  x x
  0 |x-x-x--xx-x-x-xx--x-x----x-xx-x-----> frame
    |
-2  |
    v
这是一条典型的(缩短的)曲线,由用户向右移动鼠标创建。每个x代表每个帧的deltaX值,由于deltaX值四舍五入为整数,因此该图实际上相当准确。我们可以看到,deltaX值在一帧为0.000,在下一帧为1.000,但随后又是0.000,然后是2.000,然后是0.000,然后是3.000,0.000,依此类推

这意味着该视图将在一帧中旋转2.000个单位,然后在下一帧中旋转0.000个单位,然后旋转3.000个单位。当鼠标以或多或少的恒定速度拖动时,会发生这种情况。说实话,这看起来像是废话

那么,我该如何提高鼠标的事件帧率呢?2)获得亚像素值

到目前为止
我尝试了以下方法:

- (void)mouseMoved:(NSEvent *)theEvent {
    CGFloat dx, dy;
    dx = [theEvent deltaX];
    dy = [theEvent deltaY];
    // ...
    actOnMouse(dx,dy);
}
这一点很明显
dx
这里是浮点,但值总是四舍五入(0.000、1.000等)。这将创建上面的图表

我想,下一步是在鼠标事件进入Windows服务器之前尝试点击鼠标事件。所以我创建了一个CGEventTrap:

eventMask = (1 << kCGEventMouseMoved);
eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
            0, eventMask, myCGEventCallback, NULL);
//...
myCGEventCallback(...){
    double dx = CGEventGetDoubleValueField(event, kCGMouseEventDeltaX);
    double dy = CGEventGetDoubleValueField(event, kCGMouseEventDeltaY);
}
看,上面写着亚像素位置!好啊然后在

总之,我感觉OSX对亚像素鼠标坐标了如指掌,必须有办法读取每帧鼠标的原始运动,但我不知道如何获取这些值

问题
呃,那么,我有什么要求

  • 有没有办法在OSX中获取高帧率鼠标事件?(示例代码?)
  • 有没有办法在OSX中获得亚像素鼠标坐标?(示例代码?)
  • 有没有办法读取每帧“原始”鼠标增量?(不依赖事件)
  • 或者,如何获取NXEvents或设置HIDParameters?示例代码?(这样我就可以自己更深入地研究这个问题了……)

(很抱歉发了这么长的帖子)

存在亚像素坐标的可能性,因为Mac OS X的设计与分辨率无关。屏幕上2x2硬件像素的正方形可以表示软件中的单个虚拟像素,允许将光标放置在
(x+0.5,y+0.5)


在任何使用正常1x缩放的实际Mac上,您将永远看不到亚像素坐标,因为鼠标光标无法移动到屏幕上的分数像素位置——鼠标移动量正好是1像素。

如果您需要在低于事件调度系统提供的级别访问指针设备增量信息,那么您可能需要使用.

如果您正在使用鼠标的IOHIDDevice回调,则可以使用此方法获得双倍值:

double doubleValue = IOHIDValueGetScaledValue(inIOHIDValueRef, kIOHIDTransactionDirectionTypeOutput);
(这是一个非常晚的答案,但我认为对于其他偶然发现这一点的人来说仍然有用。)

你试过过滤鼠标输入吗?这可能很棘手,因为过滤往往是滞后和精度之间的权衡。然而,几年前我写了一篇文章,解释了我如何过滤我的鼠标移动,并为一个游戏开发网站写了一篇文章。链接是

由于该网站不再处于积极开发阶段(可能会消失),以下是相关摘录:


几乎在所有情况下,过滤都意味着平均。然而,如果我们简单地平均鼠标移动时间,我们将引入滞后。那么,我们如何在不引入任何副作用的情况下进行过滤呢?好吧,我们仍然会使用平均值,但我们会使用一些智能。同时,我们将为用户提供对过滤的精细控制,以便他们可以自行调整

我们将使用随时间推移的平均鼠标输入的非线性过滤器,其中较旧的值对过滤结果的影响较小

工作原理

每一帧,无论您是否移动鼠标,我们都将当前鼠标移动放入历史缓冲区,并删除最早的历史值。因此,我们的历史记录总是包含X个样本,其中X是“历史缓冲区大小”,表示最近一次采样的鼠标移动

如果我们使用10的历史缓冲区大小,以及整个缓冲区的标准平均值,则过滤器将引入大量延迟。在每秒60帧的机器上,鼠标的快速移动将落后于1/6秒。在快速动作游戏中,这将是非常平滑的,但实际上无法使用。在相同的场景中,历史缓冲区大小为2会给我们带来很小的延迟,但过滤效果很差(玩家的反应粗糙和急促)

非线性滤波器旨在对抗这种相互排斥的情况。这个想法很简单。我们不是盲目地平均历史缓冲区中的所有值,而是用权重来平均它们。我们从权重1.0开始。因此历史缓冲区中的第一个值(当前帧的鼠标输入)具有全权重。然后我们将这个权重乘以一个“权重修饰符”(比如说…0.2),然后转到历史缓冲区中的下一个值。随着时间的推移(通过历史缓冲区),这些值对最终结果的影响越来越小

更详细地说,如果权重修改器为0.5,当前帧的样本将具有100%的权重,上一个样本将具有50%的权重,下一个最旧的样本将具有25%的权重,下一个样本将具有12.5%的权重,依此类推
#define kIOHIDPointerResolutionKey      "HIDPointerResolution"
double doubleValue = IOHIDValueGetScaledValue(inIOHIDValueRef, kIOHIDTransactionDirectionTypeOutput);