Started abstracting overlay locations (dashboard, behind controller, etc).
This commit is contained in:
parent
e625b24851
commit
91e5abe425
|
|
@ -82,7 +82,7 @@ namespace VRDash
|
||||||
{
|
{
|
||||||
public static ILog GetLogger(this object instance)
|
public static ILog GetLogger(this object instance)
|
||||||
{
|
{
|
||||||
return LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
return LogManager.GetLogger(instance.GetType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,9 @@ namespace VRDash.Overlay.Config
|
||||||
string Name { get; set; }
|
string Name { get; set; }
|
||||||
string Key { get; set; }
|
string Key { get; set; }
|
||||||
float OverlayWidth { get; set; }
|
float OverlayWidth { get; set; }
|
||||||
|
OverlayLocation.IOverlayLocation Location { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
void Initialize(IOverlay overlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using VRDash.Overlay.Config.OverlayLocation;
|
||||||
|
|
||||||
namespace VRDash.Overlay.Config
|
namespace VRDash.Overlay.Config
|
||||||
{
|
{
|
||||||
|
|
@ -11,10 +12,9 @@ namespace VRDash.Overlay.Config
|
||||||
public event EventHandler WidthUpdated;
|
public event EventHandler WidthUpdated;
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
public string MonitorName {
|
public IOverlayLocation Location { get; set; }
|
||||||
get;
|
|
||||||
set;
|
public string MonitorName { get; set; }
|
||||||
}
|
|
||||||
float m_Width = 2.5f;
|
float m_Width = 2.5f;
|
||||||
public float OverlayWidth
|
public float OverlayWidth
|
||||||
{
|
{
|
||||||
|
|
@ -25,5 +25,10 @@ namespace VRDash.Overlay.Config
|
||||||
WidthUpdated?.Invoke(this, null);
|
WidthUpdated?.Invoke(this, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Initialize(IOverlay overlay)
|
||||||
|
{
|
||||||
|
//Nothing needs to happen here
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Valve.VR;
|
||||||
|
|
||||||
|
namespace VRDash.Overlay.Config.OverlayLocation
|
||||||
|
{
|
||||||
|
public class ControllerLocation : IOverlayLocation
|
||||||
|
{
|
||||||
|
public ControllerHand Controller { get; private set; } = ControllerHand.Left;
|
||||||
|
|
||||||
|
|
||||||
|
ulong m_ControllerIndex = OpenVR.k_unTrackedDeviceIndexInvalid;
|
||||||
|
DateTime m_LastCheck = DateTime.MinValue;
|
||||||
|
|
||||||
|
IOverlay m_Overlay = null;
|
||||||
|
|
||||||
|
public OverlayHandles CreateOverlay(string key, string name, IOverlay overlay)
|
||||||
|
{
|
||||||
|
ulong overlayHandle = 0;
|
||||||
|
EVROverlayError err = OpenVR.Overlay.CreateOverlay(key, name, ref overlayHandle);
|
||||||
|
|
||||||
|
if (err != EVROverlayError.None){
|
||||||
|
throw new Exception($"Error creating overlay: {err}");
|
||||||
|
}
|
||||||
|
|
||||||
|
ETrackedDeviceClass type = OpenVR.System.GetTrackedDeviceClass(0);
|
||||||
|
|
||||||
|
overlay.Update += Overlay_Update;
|
||||||
|
|
||||||
|
m_Overlay = overlay;
|
||||||
|
|
||||||
|
return new OverlayHandles(overlayHandle, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Overlay_Update(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
//Check if handle is invalid or if we should just refresh just in case.
|
||||||
|
if(m_ControllerIndex == OpenVR.k_unTrackedDeviceIndexInvalid || DateTime.Now.Subtract(m_LastCheck).TotalSeconds >= 10)
|
||||||
|
{
|
||||||
|
//Get proper hand
|
||||||
|
ETrackedControllerRole role = Controller == ControllerHand.Left ? ETrackedControllerRole.LeftHand : ETrackedControllerRole.RightHand;
|
||||||
|
|
||||||
|
var controllerIndex = OpenVR.System.GetTrackedDeviceIndexForControllerRole(role);
|
||||||
|
|
||||||
|
//Index changed, need to update the overlay
|
||||||
|
if (controllerIndex != m_ControllerIndex)
|
||||||
|
{
|
||||||
|
m_ControllerIndex = controllerIndex;
|
||||||
|
HmdMatrix34_t matrix = new HmdMatrix34_t();
|
||||||
|
var err = OpenVR.Overlay.SetOverlayTransformOverlayRelative(m_Overlay.OverlayHandle, m_ControllerIndex, ref matrix);
|
||||||
|
if (err != EVROverlayError.None)
|
||||||
|
{
|
||||||
|
this.GetLogger().Warn($"Error setting tracked device relative to {Controller} hand: {err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_LastCheck = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetCheckTimer()
|
||||||
|
{
|
||||||
|
m_LastCheck = DateTime.MinValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ControllerHand
|
||||||
|
{
|
||||||
|
Left = 0,
|
||||||
|
Right = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Valve.VR;
|
||||||
|
|
||||||
|
namespace VRDash.Overlay.Config.OverlayLocation
|
||||||
|
{
|
||||||
|
[OverlayLocationInfo("SteamVR Dashboard", null)]
|
||||||
|
public class DashboardLocation : IOverlayLocation
|
||||||
|
{
|
||||||
|
public OverlayHandles CreateOverlay(string key, string name, IOverlay overlay)
|
||||||
|
{
|
||||||
|
ulong overalyHandle = 0;
|
||||||
|
ulong thumbnailHandle = 0;
|
||||||
|
|
||||||
|
//Actually create the overlay
|
||||||
|
EVROverlayError err = OpenVR.Overlay.CreateDashboardOverlay(key, name, ref overalyHandle, ref thumbnailHandle);
|
||||||
|
|
||||||
|
if (err != EVROverlayError.None)
|
||||||
|
{
|
||||||
|
throw new Exception($"Error creating overlay: {err}");
|
||||||
|
}
|
||||||
|
|
||||||
|
OverlayHandles handles = new OverlayHandles(overalyHandle, thumbnailHandle);
|
||||||
|
return handles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VRDash.Overlay.Config.OverlayLocation
|
||||||
|
{
|
||||||
|
public interface IOverlayLocation
|
||||||
|
{
|
||||||
|
OverlayHandles CreateOverlay(string key, string name, IOverlay overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OverlayLocationInfo : System.Attribute
|
||||||
|
{
|
||||||
|
public OverlayLocationInfo(string description, Type locationEditorType)
|
||||||
|
{
|
||||||
|
Description = description;
|
||||||
|
LocationEditorType = locationEditorType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Description { get; private set; }
|
||||||
|
public Type LocationEditorType { get; private set; }
|
||||||
|
|
||||||
|
public static IEnumerable<Type> GetTypesWithAttribute()
|
||||||
|
{
|
||||||
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
foreach (Type type in assembly.GetTypes())
|
||||||
|
{
|
||||||
|
if (type.GetCustomAttributes(typeof(OverlayLocationInfo), true).Length > 0)
|
||||||
|
{
|
||||||
|
yield return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OverlayLocationAttributeInfo
|
||||||
|
{
|
||||||
|
public OverlayLocationAttributeInfo(Type type, OverlayLocationInfo info)
|
||||||
|
{
|
||||||
|
OverlayLocationType = type;
|
||||||
|
Info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type OverlayLocationType { get; private set; }
|
||||||
|
public OverlayLocationInfo Info { get; private set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Info.Description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OverlayLocationAttributeInfo[] GetOverlayLocationInfos()
|
||||||
|
{
|
||||||
|
List<OverlayLocationAttributeInfo> infos = new List<OverlayLocationAttributeInfo>();
|
||||||
|
var attrs = GetTypesWithAttribute();
|
||||||
|
foreach (var attr in attrs)
|
||||||
|
{
|
||||||
|
OverlayLocationInfo thingInfo = (OverlayLocationInfo)attr.GetCustomAttribute(typeof(OverlayLocationInfo), true);
|
||||||
|
infos.Add(new OverlayLocationAttributeInfo(attr, thingInfo));
|
||||||
|
}
|
||||||
|
return infos.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OverlayHandles
|
||||||
|
{
|
||||||
|
public OverlayHandles(ulong overlayHandle, ulong thumbnailHandle)
|
||||||
|
{
|
||||||
|
OverlayHandle = overlayHandle;
|
||||||
|
ThumbnailHandle = thumbnailHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong OverlayHandle { get; private set; }
|
||||||
|
public ulong ThumbnailHandle { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using VRDash.Overlay.Actions;
|
using VRDash.Overlay.Actions;
|
||||||
|
using VRDash.Overlay.Config.OverlayLocation;
|
||||||
using VRDash.WindowSelectors;
|
using VRDash.WindowSelectors;
|
||||||
|
|
||||||
namespace VRDash.Overlay.Config
|
namespace VRDash.Overlay.Config
|
||||||
|
|
@ -25,6 +26,8 @@ namespace VRDash.Overlay.Config
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
public IOverlayLocation Location { get; set; }
|
||||||
|
|
||||||
public ObservableCollection<IWindowAction> OverlayShownActions { get; private set; } = new ObservableCollection<IWindowAction>();
|
public ObservableCollection<IWindowAction> OverlayShownActions { get; private set; } = new ObservableCollection<IWindowAction>();
|
||||||
public ObservableCollection<IWindowAction> OverlayHiddenActions { get; private set; } = new ObservableCollection<IWindowAction>();
|
public ObservableCollection<IWindowAction> OverlayHiddenActions { get; private set; } = new ObservableCollection<IWindowAction>();
|
||||||
|
|
||||||
|
|
@ -41,5 +44,10 @@ namespace VRDash.Overlay.Config
|
||||||
WidthUpdated?.Invoke(this, null);
|
WidthUpdated?.Invoke(this, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Initialize(IOverlay overlay)
|
||||||
|
{
|
||||||
|
//Nothing needs to happen here
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,12 @@ namespace VRDash.Overlay
|
||||||
{
|
{
|
||||||
event EventHandler OverlayShown;
|
event EventHandler OverlayShown;
|
||||||
event EventHandler OverlayHidden;
|
event EventHandler OverlayHidden;
|
||||||
|
event EventHandler Update;
|
||||||
|
|
||||||
ulong OverlayHandle { get; }
|
ulong OverlayHandle { get; }
|
||||||
IOverlayConfig OverlayConfig { get; }
|
IOverlayConfig OverlayConfig { get; }
|
||||||
|
int CurrentFPS { get; }
|
||||||
|
bool IsDisposed { get; }
|
||||||
|
|
||||||
void Create();
|
void Create();
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
@ -21,8 +24,6 @@ namespace VRDash.Overlay
|
||||||
float GetOverlayWidth();
|
float GetOverlayWidth();
|
||||||
void SetOverlayWidth(float width);
|
void SetOverlayWidth(float width);
|
||||||
void SetOverlayName(string newName);
|
void SetOverlayName(string newName);
|
||||||
|
|
||||||
int CurrentFPS { get; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OverlayInfo : System.Attribute
|
public class OverlayInfo : System.Attribute
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,12 @@ namespace VRDash.Overlay
|
||||||
{
|
{
|
||||||
public event EventHandler OverlayShown;
|
public event EventHandler OverlayShown;
|
||||||
public event EventHandler OverlayHidden;
|
public event EventHandler OverlayHidden;
|
||||||
|
public event EventHandler Update;
|
||||||
|
|
||||||
//public event EventHandler Rendered;
|
//public event EventHandler Rendered;
|
||||||
|
|
||||||
public int CurrentFPS { get; private set; }
|
public int CurrentFPS { get; private set; }
|
||||||
|
public bool IsDisposed { get; private set; } = false;
|
||||||
|
|
||||||
private Task m_EventPumpTask = null;
|
private Task m_EventPumpTask = null;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -50,10 +52,6 @@ namespace VRDash.Overlay
|
||||||
internal ulong m_ThumbnailIcon;
|
internal ulong m_ThumbnailIcon;
|
||||||
public ulong ThumbnailIcon { get { return m_ThumbnailIcon; } }
|
public ulong ThumbnailIcon { get { return m_ThumbnailIcon; } }
|
||||||
|
|
||||||
|
|
||||||
public List<IOverlayAction> OverlayShownActions { get; private set; } = new List<IOverlayAction>();
|
|
||||||
public List<IOverlayAction> OverlayHiddenActions { get; private set; } = new List<IOverlayAction>();
|
|
||||||
|
|
||||||
public IOverlayConfig OverlayConfig { get { return Config; } }
|
public IOverlayConfig OverlayConfig { get { return Config; } }
|
||||||
public MonitorOverlayConfig Config { get; }
|
public MonitorOverlayConfig Config { get; }
|
||||||
|
|
||||||
|
|
@ -121,14 +119,24 @@ namespace VRDash.Overlay
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Config.Initialize(this);
|
||||||
|
|
||||||
//Actually create the overlay
|
//Actually create the overlay
|
||||||
var overlay = OpenVR.Overlay;
|
var overlay = OpenVR.Overlay;
|
||||||
EVROverlayError err = overlay.CreateDashboardOverlay(Config.Key, Config.Name, ref m_OverlayHandle, ref m_ThumbnailIcon);
|
|
||||||
|
|
||||||
if (err != EVROverlayError.None)
|
Config.OverlayLocation.OverlayHandles overlayHandles = Config.Location.CreateOverlay(Config.Key, Config.Name, this);
|
||||||
{
|
|
||||||
throw new Exception($"Error creating overlay: {err}");
|
m_OverlayHandle = overlayHandles.OverlayHandle;
|
||||||
}
|
m_ThumbnailIcon = overlayHandles.ThumbnailHandle;
|
||||||
|
|
||||||
|
//EVROverlayError err = overlay.CreateDashboardOverlay(Config.Key, Config.Name, ref m_OverlayHandle, ref m_ThumbnailIcon);
|
||||||
|
|
||||||
|
//if (err != EVROverlayError.None)
|
||||||
|
//{
|
||||||
|
// throw new Exception($"Error creating overlay: {err}");
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
overlay.SetOverlayInputMethod(m_OverlayHandle, VROverlayInputMethod.Mouse);
|
overlay.SetOverlayInputMethod(m_OverlayHandle, VROverlayInputMethod.Mouse);
|
||||||
|
|
||||||
DateTime lastClick = DateTime.MinValue;
|
DateTime lastClick = DateTime.MinValue;
|
||||||
|
|
@ -162,6 +170,7 @@ namespace VRDash.Overlay
|
||||||
|
|
||||||
while (m_Running)
|
while (m_Running)
|
||||||
{
|
{
|
||||||
|
Update?.Invoke(this, null);
|
||||||
//TODO: implement thumbnail rendering...
|
//TODO: implement thumbnail rendering...
|
||||||
//#region Thumbnail rendering
|
//#region Thumbnail rendering
|
||||||
//using (var icon = User32.GetAppIcon(windowHandle))
|
//using (var icon = User32.GetAppIcon(windowHandle))
|
||||||
|
|
@ -282,20 +291,20 @@ namespace VRDash.Overlay
|
||||||
{
|
{
|
||||||
OverlayShown?.Invoke(this, new EventArgs());
|
OverlayShown?.Invoke(this, new EventArgs());
|
||||||
|
|
||||||
foreach (var action in OverlayShownActions)
|
//foreach (var action in OverlayShownActions)
|
||||||
{
|
//{
|
||||||
action.PreformAction(this);
|
// action.PreformAction(this);
|
||||||
}
|
//}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVREventType.VREvent_OverlayHidden:
|
case EVREventType.VREvent_OverlayHidden:
|
||||||
{
|
{
|
||||||
OverlayHidden?.Invoke(this, new EventArgs());
|
OverlayHidden?.Invoke(this, new EventArgs());
|
||||||
|
|
||||||
foreach (var action in OverlayHiddenActions)
|
//foreach (var action in OverlayHiddenActions)
|
||||||
{
|
//{
|
||||||
action.PreformAction(this);
|
// action.PreformAction(this);
|
||||||
}
|
//}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EVREventType.VREvent_KeyboardCharInput:
|
case EVREventType.VREvent_KeyboardCharInput:
|
||||||
|
|
@ -459,36 +468,36 @@ namespace VRDash.Overlay
|
||||||
{
|
{
|
||||||
int count = 4 * data.Width * data.Height;
|
int count = 4 * data.Width * data.Height;
|
||||||
|
|
||||||
// //Stride compensation. Sometimes the BMP and DX texture strides are different. This fixes it.
|
//Stride compensation. Sometimes the BMP and DX texture strides are different. This fixes it.
|
||||||
// if (databox.RowPitch == data.Stride)
|
if (databox.RowPitch == data.Stride)
|
||||||
// {
|
{
|
||||||
// stream.Write(data.Scan0, 0, count);
|
stream.Write(data.Scan0, 0, count);
|
||||||
// }
|
}
|
||||||
// //Truncate the extra BMP bytes.
|
//Truncate the extra BMP bytes.
|
||||||
// else if (databox.RowPitch < data.Stride)
|
else if (databox.RowPitch < data.Stride)
|
||||||
// {
|
{
|
||||||
// for (int i = 0; i < data.Height; i++)
|
for (int i = 0; i < data.Height; i++)
|
||||||
// {
|
{
|
||||||
// stream.Write(data.Scan0, (data.Stride * i), databox.RowPitch);
|
stream.Write(data.Scan0, (data.Stride * i), databox.RowPitch);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// //Add some junk on empty bytes on the end to make everyone happy.
|
//Add some junk on empty bytes on the end to make everyone happy.
|
||||||
// else if (databox.RowPitch > data.Stride)
|
else if (databox.RowPitch > data.Stride)
|
||||||
// {
|
{
|
||||||
// int difference = databox.RowPitch - data.Stride;
|
int difference = databox.RowPitch - data.Stride;
|
||||||
// byte[] junk = new byte[difference];
|
byte[] junk = new byte[difference];
|
||||||
// for (int i = 0; i < data.Height; i++)
|
for (int i = 0; i < data.Height; i++)
|
||||||
// {
|
{
|
||||||
// stream.Write(data.Scan0, (data.Stride * i), data.Stride);
|
stream.Write(data.Scan0, (data.Stride * i), data.Stride);
|
||||||
// stream.Write(junk, 0, difference);
|
stream.Write(junk, 0, difference);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
stream.Write(data.Scan0, 0, count);
|
//stream.Write(data.Scan0, 0, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
device.ImmediateContext.UpdateSubresource(ref databox, screenTexture, 0, width, 1);
|
device.ImmediateContext.UpdateSubresource(ref databox, screenTexture, 0, data.Stride, 1);
|
||||||
|
|
||||||
var texture = new Texture_t();
|
var texture = new Texture_t();
|
||||||
texture.handle = screenTexture.NativePointer;
|
texture.handle = screenTexture.NativePointer;
|
||||||
|
|
@ -541,7 +550,9 @@ namespace VRDash.Overlay
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
if (IsDisposed) { return; }
|
||||||
Destroy();
|
Destroy();
|
||||||
|
IsDisposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetOverlayName()
|
public string GetOverlayName()
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ namespace VRDash.Overlay
|
||||||
{
|
{
|
||||||
public event EventHandler OverlayShown;
|
public event EventHandler OverlayShown;
|
||||||
public event EventHandler OverlayHidden;
|
public event EventHandler OverlayHidden;
|
||||||
|
public event EventHandler Update;
|
||||||
|
|
||||||
public int CurrentFPS { get; private set; }
|
public int CurrentFPS { get; private set; }
|
||||||
|
public bool IsDisposed { get; private set; } = false;
|
||||||
|
|
||||||
private Task m_EventPumpTask = null;
|
private Task m_EventPumpTask = null;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -81,13 +84,12 @@ namespace VRDash.Overlay
|
||||||
|
|
||||||
//Actually create the overlay
|
//Actually create the overlay
|
||||||
var overlay = OpenVR.Overlay;
|
var overlay = OpenVR.Overlay;
|
||||||
EVROverlayError err = overlay.CreateDashboardOverlay(Config.Key, Config.Name, ref m_OverlayHandle, ref m_ThumbnailIcon);
|
|
||||||
|
|
||||||
if (err != EVROverlayError.None)
|
Config.OverlayLocation.OverlayHandles overlayHandles = Config.Location.CreateOverlay(Config.Key, Config.Name, this);
|
||||||
{
|
|
||||||
throw new Exception($"Error creating overlay: {err}");
|
m_OverlayHandle = overlayHandles.OverlayHandle;
|
||||||
}
|
m_ThumbnailIcon = overlayHandles.ThumbnailHandle;
|
||||||
overlay.SetOverlayInputMethod(m_OverlayHandle, VROverlayInputMethod.Mouse);
|
|
||||||
|
|
||||||
m_Running = true;
|
m_Running = true;
|
||||||
m_EventPumpTask = Task.Factory.StartNew(() => { EventPump(); });
|
m_EventPumpTask = Task.Factory.StartNew(() => { EventPump(); });
|
||||||
|
|
@ -131,6 +133,10 @@ namespace VRDash.Overlay
|
||||||
|
|
||||||
DateTime lastClick = DateTime.MinValue;
|
DateTime lastClick = DateTime.MinValue;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Config.Initialize(this);
|
||||||
|
|
||||||
#region Rendering setup
|
#region Rendering setup
|
||||||
|
|
||||||
//Partially taken from here: https://stackoverflow.com/questions/6812068/c-sharp-which-is-the-fastest-way-to-take-a-screen-shot
|
//Partially taken from here: https://stackoverflow.com/questions/6812068/c-sharp-which-is-the-fastest-way-to-take-a-screen-shot
|
||||||
|
|
@ -160,6 +166,8 @@ namespace VRDash.Overlay
|
||||||
|
|
||||||
while (m_Running)
|
while (m_Running)
|
||||||
{
|
{
|
||||||
|
Update?.Invoke(this, null);
|
||||||
|
|
||||||
if (Config.DestroyOnNoWindowFound)
|
if (Config.DestroyOnNoWindowFound)
|
||||||
{
|
{
|
||||||
//Check to see if the window actually exists. Act accordingly.
|
//Check to see if the window actually exists. Act accordingly.
|
||||||
|
|
@ -528,36 +536,36 @@ namespace VRDash.Overlay
|
||||||
{
|
{
|
||||||
int count = 4 * data.Width * data.Height;
|
int count = 4 * data.Width * data.Height;
|
||||||
|
|
||||||
// //Stride compensation. Sometimes the BMP and DX texture strides are different. This fixes it.
|
//Stride compensation. Sometimes the BMP and DX texture strides are different. This fixes it.
|
||||||
// if (databox.RowPitch == data.Stride)
|
if (databox.RowPitch == data.Stride)
|
||||||
// {
|
{
|
||||||
// stream.Write(data.Scan0, 0, count);
|
stream.Write(data.Scan0, 0, count);
|
||||||
// }
|
}
|
||||||
// //Truncate the extra BMP bytes.
|
//Truncate the extra BMP bytes.
|
||||||
// else if (databox.RowPitch < data.Stride)
|
else if (databox.RowPitch < data.Stride)
|
||||||
// {
|
{
|
||||||
// for (int i = 0; i < data.Height; i++)
|
for (int i = 0; i < data.Height; i++)
|
||||||
// {
|
{
|
||||||
// stream.Write(data.Scan0, (data.Stride * i), databox.RowPitch);
|
stream.Write(data.Scan0, (data.Stride * i), databox.RowPitch);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// //Add some junk on empty bytes on the end to make everyone happy.
|
//Add some junk on empty bytes on the end to make everyone happy.
|
||||||
// else if (databox.RowPitch > data.Stride)
|
else if (databox.RowPitch > data.Stride)
|
||||||
// {
|
{
|
||||||
// int difference = databox.RowPitch - data.Stride;
|
int difference = databox.RowPitch - data.Stride;
|
||||||
// byte[] junk = new byte[difference];
|
byte[] junk = new byte[difference];
|
||||||
// for (int i = 0; i < data.Height; i++)
|
for (int i = 0; i < data.Height; i++)
|
||||||
// {
|
{
|
||||||
// stream.Write(data.Scan0, (data.Stride * i), data.Stride);
|
stream.Write(data.Scan0, (data.Stride * i), data.Stride);
|
||||||
// stream.Write(junk, 0, difference);
|
stream.Write(junk, 0, difference);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
stream.Write(data.Scan0, 0, count);
|
//stream.Write(data.Scan0, 0, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
device.ImmediateContext.UpdateSubresource(ref databox, screenTexture, 0, width, 1);
|
device.ImmediateContext.UpdateSubresource(ref databox, screenTexture, 0, data.Stride, 1);
|
||||||
|
|
||||||
var texture = new Texture_t();
|
var texture = new Texture_t();
|
||||||
texture.handle = screenTexture.NativePointer;
|
texture.handle = screenTexture.NativePointer;
|
||||||
|
|
@ -609,7 +617,9 @@ namespace VRDash.Overlay
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
if (IsDisposed) { return; }
|
||||||
Destroy();
|
Destroy();
|
||||||
|
IsDisposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetOverlayName()
|
public string GetOverlayName()
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
d:DesignHeight="450" d:DesignWidth="800">
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="34" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
<RowDefinition Height="25" />
|
<RowDefinition Height="25" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
@ -18,10 +18,19 @@
|
||||||
<ColumnDefinition Width="104"/>
|
<ColumnDefinition Width="104"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<TextBlock Grid.Column="0" Margin="0,0,5,0" VerticalAlignment="Center">New Overlay Type:</TextBlock>
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<TextBlock Grid.Column="0" Margin="0,0,5,0" VerticalAlignment="Center" HorizontalAlignment="Right">New Overlay Type:</TextBlock>
|
||||||
<ComboBox x:Name="cbOverlayType" Grid.Column="1" ItemsSource="{Binding EligibleOverlays}"
|
<ComboBox x:Name="cbOverlayType" Grid.Column="1" ItemsSource="{Binding EligibleOverlays}"
|
||||||
SelectionChanged="cbOverlayType_SelectionChanged"></ComboBox>
|
SelectionChanged="cbOverlayType_SelectionChanged"></ComboBox>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="1" Grid.Column="0" Margin="0,0,5,0" VerticalAlignment="Center" HorizontalAlignment="Right">Overlay Location:</TextBlock>
|
||||||
|
<ComboBox x:Name="cbLocation" Grid.Row="1" Grid.Column="1" ItemsSource="{Binding LocationInfos}"
|
||||||
|
SelectionChanged="cbLocation_SelectionChanged" Margin="0,5,0,0"></ComboBox>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Border x:Name="bdrContent" Grid.Row="1" Background="White" BorderBrush="Gainsboro" Margin="5" BorderThickness="1" Padding="5"/>
|
<Border x:Name="bdrContent" Grid.Row="1" Background="White" BorderBrush="Gainsboro" Margin="5" BorderThickness="1" Padding="5"/>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ using System.Windows.Navigation;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
using VRDash.Overlay;
|
using VRDash.Overlay;
|
||||||
using VRDash.Overlay.Config;
|
using VRDash.Overlay.Config;
|
||||||
|
using VRDash.Overlay.Config.OverlayLocation;
|
||||||
|
|
||||||
namespace VRDash.UI
|
namespace VRDash.UI
|
||||||
{
|
{
|
||||||
|
|
@ -26,6 +27,7 @@ namespace VRDash.UI
|
||||||
public event CreatedEventHandler Created;
|
public event CreatedEventHandler Created;
|
||||||
|
|
||||||
public List<OverlayTypeWrapper> EligibleOverlays { get; private set; } = new List<OverlayTypeWrapper>();
|
public List<OverlayTypeWrapper> EligibleOverlays { get; private set; } = new List<OverlayTypeWrapper>();
|
||||||
|
public List<OverlayLocationInfo.OverlayLocationAttributeInfo> LocationInfos { get; private set; } = new List<OverlayLocationInfo.OverlayLocationAttributeInfo>();
|
||||||
|
|
||||||
public CreateNewOverlay()
|
public CreateNewOverlay()
|
||||||
{
|
{
|
||||||
|
|
@ -40,15 +42,31 @@ namespace VRDash.UI
|
||||||
{
|
{
|
||||||
((WindowOverlayConfig)newWrapper.Config).OverlayShownActions.Add(new Overlay.Actions.BringWindowToFrontAction());
|
((WindowOverlayConfig)newWrapper.Config).OverlayShownActions.Add(new Overlay.Actions.BringWindowToFrontAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
EligibleOverlays.Add(newWrapper);
|
EligibleOverlays.Add(newWrapper);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocationInfos.AddRange(OverlayLocationInfo.GetOverlayLocationInfos());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cbOverlayType_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void cbOverlayType_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
bdrContent.Child = ((OverlayTypeWrapper)cbOverlayType.SelectedItem).Control;
|
if (cbOverlayType.SelectedItem == null) { return; }
|
||||||
|
var selectedOverlayType = ((OverlayTypeWrapper)cbOverlayType.SelectedItem);
|
||||||
|
bdrContent.Child = selectedOverlayType.Control;
|
||||||
|
cbLocation_SelectionChanged(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cbLocation_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (cbOverlayType.SelectedItem == null) { return; }
|
||||||
|
if (cbLocation.SelectedItem == null) { return; }
|
||||||
|
|
||||||
|
var selectedOverlayType = ((OverlayTypeWrapper)cbOverlayType.SelectedItem);
|
||||||
|
var selectedLocationType = ((OverlayLocationInfo.OverlayLocationAttributeInfo)cbLocation.SelectedItem);
|
||||||
|
IOverlayLocation location = (IOverlayLocation)Activator.CreateInstance(selectedLocationType.OverlayLocationType);
|
||||||
|
selectedOverlayType.Config.Location = location;
|
||||||
|
selectedOverlayType.ResetControl();
|
||||||
|
bdrContent.Child = selectedOverlayType.Control;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void btnCreate_Click(object sender, RoutedEventArgs e)
|
private void btnCreate_Click(object sender, RoutedEventArgs e)
|
||||||
|
|
@ -78,8 +96,6 @@ namespace VRDash.UI
|
||||||
IOverlay overlay = (IOverlay)Activator.CreateInstance(wrapper.OverlayInfo.OverlayType, new object[] { config });
|
IOverlay overlay = (IOverlay)Activator.CreateInstance(wrapper.OverlayInfo.OverlayType, new object[] { config });
|
||||||
overlay.Create();
|
overlay.Create();
|
||||||
|
|
||||||
//MainWindow.OverlayManager.Overlays.Add(overlay);
|
|
||||||
|
|
||||||
Created?.Invoke(this, overlay);
|
Created?.Invoke(this, overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,7 +123,12 @@ namespace VRDash.UI
|
||||||
{
|
{
|
||||||
OverlayInfo = overlayInfo;
|
OverlayInfo = overlayInfo;
|
||||||
Config = (IOverlayConfig)Activator.CreateInstance(OverlayInfo.Info.ConfigType);
|
Config = (IOverlayConfig)Activator.CreateInstance(OverlayInfo.Info.ConfigType);
|
||||||
Control = (UserControl)Activator.CreateInstance(OverlayInfo.Info.EditorType, new object[] { Config });
|
//ResetControl();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetControl()
|
||||||
|
{
|
||||||
|
Control = new OverlayEditor((IOverlayEditor)Activator.CreateInstance(OverlayInfo.Info.EditorType, new object[] { Config }));
|
||||||
}
|
}
|
||||||
|
|
||||||
public OverlayInfo.OverlayAttributeInfo OverlayInfo { get; private set; }
|
public OverlayInfo.OverlayAttributeInfo OverlayInfo { get; private set; }
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
d:DesignHeight="450" d:DesignWidth="800">
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
<RowDefinition Height="25" />
|
<RowDefinition Height="25" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
@ -16,10 +17,12 @@
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="60" />
|
<ColumnDefinition Width="60" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Border x:Name="bdrContent" Grid.Row="0" Grid.ColumnSpan="3"/>
|
<Border x:Name="bdrLocationEditor" Grid.Row="0" Grid.ColumnSpan="3"/>
|
||||||
|
|
||||||
|
<Border x:Name="bdrContent" Grid.Row="1" Grid.ColumnSpan="3"/>
|
||||||
|
|
||||||
<TextBlock Grid.Row="2" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Center">Overlay Width:</TextBlock>
|
<TextBlock Grid.Row="2" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Center">Overlay Width:</TextBlock>
|
||||||
<Slider x:Name="slWidth" Maximum="10" Grid.Row="1" Grid.Column="1" Value="{Binding OverlayWidth}" VerticalAlignment="Center" Margin="5,0,5,0"/>
|
<Slider x:Name="slWidth" Maximum="10" Grid.Row="2" Grid.Column="1" Value="{Binding OverlayWidth}" VerticalAlignment="Center" Margin="5,0,5,0"/>
|
||||||
<TextBox x:Name="tbWidth" Grid.Row="2" Grid.Column="2" PreviewTextInput="tbWidth_PreviewTextInput" PreviewKeyDown="tbWidth_PreviewKeyDown" Text="{Binding OverlayWidth}"/>
|
<TextBox x:Name="tbWidth" Grid.Row="2" Grid.Column="2" PreviewTextInput="tbWidth_PreviewTextInput" PreviewKeyDown="tbWidth_PreviewKeyDown" Text="{Binding OverlayWidth}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ using System.Windows.Media.Imaging;
|
||||||
using System.Windows.Navigation;
|
using System.Windows.Navigation;
|
||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
using VRDash.Overlay.Config;
|
using VRDash.Overlay.Config;
|
||||||
|
using VRDash.Overlay.Config.OverlayLocation;
|
||||||
|
|
||||||
namespace VRDash.UI
|
namespace VRDash.UI
|
||||||
{
|
{
|
||||||
|
|
@ -31,6 +32,22 @@ namespace VRDash.UI
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Editor = editor;
|
Editor = editor;
|
||||||
DataContext = Config;
|
DataContext = Config;
|
||||||
|
OverlayLocationInfo.OverlayLocationAttributeInfo[] overlayLocationAttributes = OverlayLocationInfo.GetOverlayLocationInfos();
|
||||||
|
|
||||||
|
OverlayLocationInfo locationInfo = overlayLocationAttributes.Single(x => x.OverlayLocationType == Config.Location.GetType()).Info;
|
||||||
|
if (locationInfo.LocationEditorType != null)
|
||||||
|
{
|
||||||
|
UserControl locationEditor = (UserControl)Activator.CreateInstance(locationInfo.LocationEditorType);
|
||||||
|
bdrLocationEditor.Child = locationEditor;
|
||||||
|
}
|
||||||
|
#if DEBUG
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var textBlock = new TextBlock();
|
||||||
|
textBlock.Text = "No location editor!";
|
||||||
|
bdrLocationEditor.Child = textBlock;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tbWidth_PreviewTextInput(object sender, TextCompositionEventArgs e)
|
private void tbWidth_PreviewTextInput(object sender, TextCompositionEventArgs e)
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,9 @@
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</ApplicationDefinition>
|
</ApplicationDefinition>
|
||||||
<Compile Include="Logger.cs" />
|
<Compile Include="Logger.cs" />
|
||||||
|
<Compile Include="Overlay\Config\OverlayLocation\ControllerLocation.cs" />
|
||||||
|
<Compile Include="Overlay\Config\OverlayLocation\DashboardLocation.cs" />
|
||||||
|
<Compile Include="Overlay\Config\OverlayLocation\IOverlayLocation.cs" />
|
||||||
<Compile Include="ProfileManager.cs" />
|
<Compile Include="ProfileManager.cs" />
|
||||||
<Compile Include="JsonNet.PrivateSettersContractResolvers\PrivateSettersContractResolvers.cs" />
|
<Compile Include="JsonNet.PrivateSettersContractResolvers\PrivateSettersContractResolvers.cs" />
|
||||||
<Compile Include="OverlayManager.cs" />
|
<Compile Include="OverlayManager.cs" />
|
||||||
|
|
@ -226,5 +229,6 @@
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
Loading…
Reference in New Issue