C # / XNA는 하드웨어 마우스 위치를 얻습니다


10

C #을 사용하고 하드웨어 마우스 위치를 얻으려고합니다. 가장 먼저 시도한 것은 사용하기 쉬운 간단한 XNA 기능이었습니다.

Vector2 position = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);

그 후 마우스 그리기를 수행하고 Windows 하드웨어 마우스와 비교하여 xna가 제공 한 좌표를 가진이 새로운 마우스는 "느슨해졌습니다". 즉, 몇 프레임 뒤에 있다는 것을 의미합니다. 예를 들어 게임이 600fps에서 실행되는 경우 저주가 반응하지만 60fps 소프트웨어에서는 마우스 지연이 더 이상 허용되지 않습니다. 따라서 하드웨어 마우스라고 생각한 것을 사용해 보았습니다.

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetCursorPos(out POINT lpPoint);

그러나 결과는 정확히 같습니다. 나는 또한 Windows form cursor를 얻으려고 시도했지만 막 다른 길이기도했지만 같은 지연으로 작동했습니다. xna 기능으로 혼란스러워 :

GraphicsDeviceManager.SynchronizeWithVerticalRetrace = true/false
Game.IsFixedTimeStep = true/fale

다소 명백한 이유로 지연 시간을 변경했지만 결론은 기본 Windows 마우스 뒤에 여전히 있다는 것입니다. 나는 일부 게임에서 하드웨어 가속 마우스 옵션을 제공한다는 것을 보았습니다. 다른 게임에서는 이미 기본적으로 사용됩니다. 누구나 그것을 달성하는 방법에 대해 약간의 리드를 줄 수 있습니까?


2
나는 Mouse.GetState()깨진 생각하지 않습니다 . 마우스를 그릴 때와 동일한 프레임에서 마우스 위치를 확인 하시겠습니까? 이 때문에 또한 / 감속이 가능, 윈도우 커서 가속을 가지고 기억 느낌이 더 반응. 하드웨어에 더 가까이 다가 가려면 DirectInput을 눌러야합니다. DirectInput은 절대 마우스 위치 대신 이동 델타를 제공합니다. 그러나 Mouse.GetState()여전히 XNA에서 올바른 방법 이라고 생각 합니다.
Panda Pajama

아니, Mouse.GetState()한 깨진되지 않으며, IsFixedTimeStep == true사람들이 보이는 창 마우스와 직접 비교하지 않는 한 지연을 볼 수 없습니다. 그러나 낮은 프레임 속도에서 IsFixedTimeStep을 false로 설정하면 모든 사람이 볼 수 있습니다. 직접 입력에 대해 나는 가능성 (마지막 수단)을 고려했습니다.
Sunder

원하는지 확실하지 않지만 창에있는 동안 커서 스프라이트를 변경 한 다음 항상 보이도록하려면 어떻게해야합니까?
William Mariager

정확히 내가하고있는 일은, 나는 그것을 보여주고 싶지 않고 마우스의 정확한 위치를 아는 것입니다. 그러나 내가 얻는 것은 그것이 있어야하는 것에 약간 뒤쳐져 있습니다.
Sunder

답변:


17

당신이보고있는 것은 입력 지연 이 아닙니다 .

Windows에서 커서의 위치를 ​​얻으려면 WM_MOUSEMOVE또는 을 사용할 수 있습니다 GetCursorPos. 둘 다 Windows에서 커서를 처리 한 후 커서 위치를 제공하여 가속과 같은 것을 적용합니다. 이것은 그림을 포함하여 Windows가 사용하는 커서 위치입니다. 거의 항상 당신이 사용하고 싶은 것.

이것이 XNA가 사용하는 것 입니다. 특히 GetCursorPos( MSDN ). 즉, 호출 Mouse.GetState하면 Windows에서 보는 것처럼 커서의 실제 위치를 얻습니다. 실제로 지연이 없습니다.

이제는 WM_INPUT(또는 더 이상 사용되지 않지만 DirectInput)을 사용할 수 있습니다 . 이것은 당신에게 원시 포인터 데이터를 제공합니다. 이것은 Windows가 가속과 같은 것을 적용하기 전에 이루어지며 일반적으로 원하는 것이 아닙니다 .

당신이보고있는 것은 출력 지연입니다.

이것은 " 하드웨어 커서 " 때문입니다 . 파이프 라인 의 끝 에서 GPU에 의해 화면에 그려지는 작은 스프라이트입니다 . 그리고 나는 끝을 의미한다 . 프레임 버퍼 다음에옵니다. 이미지가 모니터로 전송 될 때 데이터 스트림에 삽입됩니다. 너무 빨리 반응하는 이유는 GPU 레지스터를 직접 설정하여 위치를 설정하기 때문입니다. 파이프 라인에서 전혀 대기하지 않습니다.

반면에 게임은 GPU 파이프 라인을 거쳐야합니다. 이것은 자체적으로 많은 지연을 추가합니다. 가장 큰 문제는 더블 버퍼링입니다. XNA 4에서 끌 수없는 더블 버퍼링입니다. 프레임 버퍼에 직접 그리지 않고 백 버퍼에 그립니다. ~ 16ms마다 표시됩니다 (60FPS에서). 즉, Mouse.GetState화면에 결과를 기반으로 한 무언가 를 얻은 결과를받는 사이에 최소 약 16ms를보고 있음을 의미합니다 . 아마 더 길다. 하드웨어 커서보다 확실히 느립니다.

그렇다면 해결책은 무엇입니까?

하나는 SetCursor( MSDN ) 을 사용 하여 하드웨어 커서에 의해 표시되는 이미지를 게임에 더 적합한 이미지로 변경하는 것입니다 (또는 Windows 커서와 함께 사용하는 것).

그리고 다른 하나는 훨씬 더 쉬울뿐 아니라 지연을 받아들이고 Game.IsMouseVisible = false상대 지연을 숨기도록 설정 하는 것입니다. 게임 내에서 자신의 커서를 표시합니다. 숨겨진 Windows 커서보다 16ms 느리지 만 누가 신경 쓰나요? 게이머가 익숙합니다. 어쨌든 16ms는 거의 시각적으로 인식 할 수 없습니다 (우리가 60FPS에서 물건을 렌더링하는 이유입니다).


문제에 대한 자세한 설명을 주셔서 감사합니다. XNA 마우스 만 사용하면됩니다. 누군가 추가 해결 방법이있는 경우 수락하기 전에 조금 기다립니다.
Sunder

지연을 수락하는 것은 playtesting으로 대답 해야하는 질문입니다.
Zonko December
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.