我想在OSX上獲得高分辨率和高幀率的鼠標移動。OSX上的高分辨率和高幀率鼠標座標? (或其他解決方案?)
「高幀率」 = 60幀或更高(優選> 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,然後是0.000,然後是2.000,然後是0.000,然後是3.000,0.000等等。
這意味着視圖將一幀旋轉2.000個單位,然後旋轉0.000個單位,然後旋轉3.000個單位。當鼠標以大致恆定的速度拖動時,會發生這種情況。無情地說,這看起來像廢話。
那麼,我該如何1)增加鼠標的事件幀率?和2)獲得子像素值?
到目前爲止
我已經試過如下:
- (void)mouseMoved:(NSEvent *)theEvent {
CGFloat dx, dy;
dx = [theEvent deltaX];
dy = [theEvent deltaY];
// ...
actOnMouse(dx,dy);
}
那麼,這一個是顯而易見的。 dx
這裏是浮點數,但值總是舍入(0.000,1.000等)。這創建了上圖。
因此,下一步是在進入WindowServer之前嘗試點擊鼠標事件,我想。所以,我創建了一個CGEventTrap:
eventMask = (1 << kCGEventMouseMoved);
eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
0, eventMask, myCGEventCallback, NULL);
//...
myCGEventCallback(...){
double dx = CGEventGetDoubleValueField(event, kCGMouseEventDeltaX);
double dy = CGEventGetDoubleValueField(event, kCGMouseEventDeltaY);
}
儘管如此值n.000
,但我相信事件觸發速率高一點。但它仍未達到60 fps。我仍然看到上面的圖表。
我也嘗試將鼠標的靈敏度設置得非常高,然後將值放在我的身邊。但似乎OSX增加了某種加速度或某種東西 - 這些值真的「不穩定」,因此無法使用,並且火速仍然太低。
沒有運氣,我已經開始關注兔子洞裏的鼠標事件,並且我已經到達了IOKit。這對我來說很可怕。這是瘋子。蘋果的文檔變得很奇怪,似乎在說「如果你深深地思考,你真正需要的是頭文件」。
所以我一直在閱讀頭文件。我發現了一些有趣的花絮。上線377有
在<IOKit/hidsystem/IOLLEvent.h>
是這個結構:
struct { /* For mouse-down and mouse-up events */
UInt8 subx; /* sub-pixel position for x */
UInt8 suby; /* sub-pixel position for y */
// ...
} mouse;
看到,它說,子像素位置!好。然後在線73 <IOKit/hidsystem/IOLLParameter.h>
#define kIOHIDPointerResolutionKey "HIDPointerResolution"
嗯。總而言之,我感受到了OSX深入瞭解亞像素鼠標座標的感覺,並且每一幀都必須有一種讀取原始鼠標移動的方式,但我不知道如何獲得這些信息值。
問題
呃,那麼,我在問什麼?
- 有沒有辦法在OSX中獲得高幀速率的鼠標事件? (示例代碼?)
- 有沒有辦法在OSX中獲取子像素鼠標座標? (示例代碼?)
- 有沒有讀「生」鼠標每個幀的方式? (即不是依賴於一個事件。)
- 或者,我如何獲得NXEvents或設置HIDParameters?示例代碼? (這樣我就可以更深入地瞭解這對我自己的......)
(對不起,長職位)