Clicking now works, and renders cursor on the screen.

This commit is contained in:
jrhodnik 2019-05-24 23:39:44 -04:00
parent 18a59525b9
commit e2f8bb5c7e
2 changed files with 203 additions and 29 deletions

View File

@ -35,12 +35,24 @@ namespace VDash
throw new Exception($"Error connecting to VR: {initError.ToString()}"); throw new Exception($"Error connecting to VR: {initError.ToString()}");
} }
var discordSelector = new WindowSelectors.FromWindowTitle("Discord", WindowSelectors.FromWindowTitle.TitleSearchType.Contains); //ulong desktopOverlay = 0;
Overlay.WindowOverlay discordOverlay = new Overlay.WindowOverlay("discord", "Discord", discordSelector, true);
discordOverlay.Create();
Overlay.WindowOverlay obsOverlay = new Overlay.WindowOverlay("obs", "OBS", new WindowSelectors.FromProcessName("obs64"), false); //var err = OpenVR.Overlay.FindOverlay("valve.steam.desktop", ref desktopOverlay);
obsOverlay.Create();
//HmdVector2_t vec = new HmdVector2_t();
//OpenVR.Overlay.GetOverlayMouseScale(desktopOverlay, ref vec);
//var discordSelector = new WindowSelectors.FromWindowTitle("Discord", WindowSelectors.FromWindowTitle.TitleSearchType.Contains);
//Overlay.WindowOverlay discordOverlay = new Overlay.WindowOverlay("discord", "Discord", discordSelector, true);
//discordOverlay.Create();
var vsSelector = new WindowSelectors.FromWindowTitle("Microsoft Visual Studio", WindowSelectors.FromWindowTitle.TitleSearchType.Contains);
Overlay.WindowOverlay vsOverlay = new Overlay.WindowOverlay("vs", "Visual Studio", vsSelector, true);
vsOverlay.Create();
//Overlay.WindowOverlay obsOverlay = new Overlay.WindowOverlay("obs", "OBS", new WindowSelectors.FromProcessName("obs64"), false);
//obsOverlay.Create();
} }
} }

View File

@ -2,6 +2,7 @@
using SharpDX.Direct3D11; using SharpDX.Direct3D11;
using SharpDX.DXGI; using SharpDX.DXGI;
using System; using System;
using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -53,7 +54,7 @@ namespace VDash.Overlay
public void Create() public void Create()
{ {
if (m_Created) { throw new Exception("This overlay has already been created."); } if (m_Created) { throw new Exception("This overlay has already been created."); }
ConsoleManager.Show(); //ConsoleManager.Show();
ulong thumbHandle = OpenVR.k_ulOverlayHandleInvalid; ulong thumbHandle = OpenVR.k_ulOverlayHandleInvalid;
//Actually create the overlay //Actually create the overlay
@ -64,8 +65,6 @@ namespace VDash.Overlay
{ {
throw new Exception($"Error creating overlay: {err}"); throw new Exception($"Error creating overlay: {err}");
} }
overlay.SetOverlayWidthInMeters(m_Handle, 2.5f);
overlay.SetOverlayInputMethod(m_Handle, VROverlayInputMethod.Mouse); overlay.SetOverlayInputMethod(m_Handle, VROverlayInputMethod.Mouse);
m_Running = true; m_Running = true;
@ -136,12 +135,23 @@ namespace VDash.Overlay
} }
//Skip rendering if overlay isn't visible //Skip rendering if overlay isn't visible
//if ((m_Handle == OpenVR.k_ulOverlayHandleInvalid) || overlay == null || (!overlay.IsOverlayVisible(m_Handle))) #if !DEBUG
//{ if ((m_Handle == Openvr.k_uloverlayhandleinvalid) || overlay == null || (!overlay.isoverlayvisible(m_handle)))
// Thread.Sleep(100); {
// continue; thread.sleep(100);
//} continue;
}
#endif
IntPtr windowHandle = IntPtr.Zero;
try
{
windowHandle = m_Selector.GetWindowHandle();
}
catch (WindowNotFoundException)
{
//Console.WriteLine($"[{m_Key}] {m_Name}: Window not found.");
}
#region VR Events #region VR Events
VREvent_t vrEvent = new VREvent_t(); VREvent_t vrEvent = new VREvent_t();
@ -152,20 +162,92 @@ namespace VDash.Overlay
{ {
case EVREventType.VREvent_MouseMove: case EVREventType.VREvent_MouseMove:
{ {
var x = vrEvent.data.mouse.x; if (windowHandle != IntPtr.Zero)
var y = vrEvent.data.mouse.y; {
var vrX = vrEvent.data.mouse.x;
var vrY = vrEvent.data.mouse.y;
var rect = new User32.Rect();
User32.GetWindowRect(windowHandle, ref rect);
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
var point = new User32.POINT() { x = (int)vrX, y = height - (int)vrY };
var succ = User32.ClientToScreen(windowHandle, ref point);
if (!succ)
{
Console.WriteLine("ClientToScreen failed.");
}
succ = User32.SetCursorPos((int)point.x, (int)point.y);
if (!succ)
{
Console.WriteLine("SetCursorPos failed.");
}
}
break; break;
} }
case EVREventType.VREvent_MouseButtonDown: case EVREventType.VREvent_MouseButtonDown:
{ {
var clickType = (EVRMouseButton)vrEvent.data.mouse.button; var clickType = (EVRMouseButton)vrEvent.data.mouse.button;
Console.WriteLine($"Mouse button down: {clickType}");
var winClickType = User32.MouseEventFlags.MOUSEEVENTF_LEFTDOWN;
switch (clickType)
{
case EVRMouseButton.Left:
{
winClickType = User32.MouseEventFlags.MOUSEEVENTF_LEFTDOWN;
break;
}
case EVRMouseButton.Middle:
{
winClickType = User32.MouseEventFlags.MOUSEEVENTF_MIDDLEDOWN;
break;
}
case EVRMouseButton.Right:
{
winClickType = User32.MouseEventFlags.MOUSEEVENTF_RIGHTDOWN;
break;
}
}
User32.mouse_event(winClickType, 0, 0, 0, UIntPtr.Zero);
break; break;
} }
case EVREventType.VREvent_MouseButtonUp: case EVREventType.VREvent_MouseButtonUp:
{ {
var clickType = (EVRMouseButton)vrEvent.data.mouse.button; var clickType = (EVRMouseButton)vrEvent.data.mouse.button;
Console.WriteLine($"Mouse button up: {clickType}");
var winClickType = User32.MouseEventFlags.MOUSEEVENTF_LEFTUP;
switch (clickType)
{
case EVRMouseButton.Left:
{
winClickType = User32.MouseEventFlags.MOUSEEVENTF_LEFTUP;
break;
}
case EVRMouseButton.Middle:
{
winClickType = User32.MouseEventFlags.MOUSEEVENTF_MIDDLEUP;
break;
}
case EVRMouseButton.Right:
{
winClickType = User32.MouseEventFlags.MOUSEEVENTF_RIGHTUP;
break;
}
}
User32.mouse_event(winClickType, 0, 0, 0, UIntPtr.Zero);
break; break;
} }
case EVREventType.VREvent_OverlayShown: case EVREventType.VREvent_OverlayShown:
@ -181,18 +263,9 @@ namespace VDash.Overlay
} }
} }
#endregion #endregion
#region Acutally Render #region Acutally Render
IntPtr windowHandle = IntPtr.Zero;
try
{
windowHandle = m_Selector.GetWindowHandle();
}
catch (WindowNotFoundException)
{
//Console.WriteLine($"[{m_Key}] {m_Name}: Window not found.");
}
if (windowHandle != IntPtr.Zero) if (windowHandle != IntPtr.Zero)
{ {
@ -210,6 +283,36 @@ namespace VDash.Overlay
{ {
graphics.CopyFromScreen(rect.left, rect.top, 0, 0, new Size(width, height), CopyPixelOperation.SourceCopy); graphics.CopyFromScreen(rect.left, rect.top, 0, 0, new Size(width, height), CopyPixelOperation.SourceCopy);
//Draw cursor
User32.CURSORINFO pci;
pci.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(User32.CURSORINFO));
if (User32.GetCursorInfo(out pci))
{
User32.POINT cursorPoint = new User32.POINT() { x = pci.ptScreenPos.X, y = pci.ptScreenPos.Y};
if (User32.ScreenToClient(windowHandle, ref cursorPoint))
{
if (pci.flags == User32.CURSOR_SHOWING)
{
User32.DrawIcon(graphics.GetHdc(), (int)cursorPoint.x, (int)cursorPoint.y, pci.hCursor);
graphics.ReleaseHdc();
}
}
else
{
Console.WriteLine("Error getting coords to draw cursor.");
}
}
else
{
string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
Console.WriteLine($"Error getting cursor info: {errorMessage}");
}
var data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); var data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
@ -244,6 +347,10 @@ namespace VDash.Overlay
screenTexture = new Texture2D(device, textureDesc); screenTexture = new Texture2D(device, textureDesc);
stream = new DataStream(4 * width * height, true, true); stream = new DataStream(4 * width * height, true, true);
overlay.SetOverlayWidthInMeters(m_Handle, 2.5f);
HmdVector2_t vecWindowSize = new HmdVector2_t() { v0 = width, v1 = height };
OpenVR.Overlay.SetOverlayMouseScale(m_Handle, ref vecWindowSize);
Console.WriteLine("Updated!"); Console.WriteLine("Updated!");
@ -252,7 +359,6 @@ namespace VDash.Overlay
//using () //using ()
{ {
var screenView = new ShaderResourceView(device, screenTexture); var screenView = new ShaderResourceView(device, screenTexture);
device.ImmediateContext.PixelShader.SetShaderResource(0, screenView); device.ImmediateContext.PixelShader.SetShaderResource(0, screenView);
@ -293,6 +399,10 @@ namespace VDash.Overlay
} }
} }
VRTextureBounds_t bounds = new VRTextureBounds_t();
OpenVR.Overlay.GetOverlayTextureBounds(m_Handle, ref bounds);
var texture = new Texture_t(); var texture = new Texture_t();
texture.handle = screenTexture.NativePointer; texture.handle = screenTexture.NativePointer;
texture.eType = ETextureType.DirectX; texture.eType = ETextureType.DirectX;
@ -300,6 +410,7 @@ namespace VDash.Overlay
EVROverlayError result = overlay.SetOverlayTexture(m_Handle, ref texture); EVROverlayError result = overlay.SetOverlayTexture(m_Handle, ref texture);
if (result != EVROverlayError.None) if (result != EVROverlayError.None)
{ {
Console.WriteLine($"Error rendering: {result}"); Console.WriteLine($"Error rendering: {result}");
} }
@ -314,13 +425,13 @@ namespace VDash.Overlay
} }
} }
} }
#endregion #endregion
Thread.Sleep(20); Thread.Sleep(20);
if (DateTime.Now.Subtract(lastFps).TotalMilliseconds > 1000) if (DateTime.Now.Subtract(lastFps).TotalMilliseconds > 1000)
{ {
Console.WriteLine($"{frames} fps."); //Console.WriteLine($"{frames} fps.");
frames = 0; frames = 0;
lastFps = DateTime.Now; lastFps = DateTime.Now;
} }
@ -343,8 +454,59 @@ namespace VDash.Overlay
public int bottom; public int bottom;
} }
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public long x;
public long y;
}
[StructLayout(LayoutKind.Sequential)]
public struct CURSORINFO
{
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public Point ptScreenPos;
}
public const Int32 CURSOR_SHOWING = 0x00000001;
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect); public static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetCursorPos(int x, int y);
[DllImport("user32.dll")]
public static extern bool ClientToScreen(IntPtr hwnd, ref POINT lpPoint);
[DllImport("user32.dll")]
public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
[DllImport("user32.dll")]
public static extern bool GetCursorInfo(out CURSORINFO pci);
[DllImport("user32.dll")]
public static extern bool DrawIcon(IntPtr hDC, int X, int Y, IntPtr hIcon);
[DllImport("user32.dll")]
public static extern void mouse_event(MouseEventFlags dwFlags, int dx, int dy, uint dwData, UIntPtr dwExtraInfo);
public enum MouseEventFlags
{
MOUSEEVENTF_ABSOLUTE = 0x8000,
MOUSEEVENTF_LEFTDOWN = 0x0002,
MOUSEEVENTF_LEFTUP = 0x0004,
MOUSEEVENTF_MIDDLEDOWN = 0x0020,
MOUSEEVENTF_MIDDLEUP = 0x0040,
MOUSEEVENTF_MOVE = 0x0001,
MOUSEEVENTF_RIGHTDOWN = 0x0008,
MOUSEEVENTF_RIGHTUP = 0x0010,
MOUSEEVENTF_XDOWN = 0x0080,
MOUSEEVENTF_XUP = 0x0100,
MOUSEEVENTF_WHEEL = 0x0800,
MOUSEEVENTF_HWHEEL = 0x01000
}
} }
public void Dispose() public void Dispose()