Started implementing BrowserOverlay.

This commit is contained in:
jrhodnik 2019-06-03 21:12:13 -04:00
parent 7ca043edba
commit 3ef6bd79e1
10 changed files with 333 additions and 45 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
</startup> </startup>
</configuration> </configuration>

View File

@ -5,6 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:VRDash" xmlns:local="clr-namespace:VRDash"
mc:Ignorable="d" mc:Ignorable="d"
KeyDown="Window_KeyDown"
Title="VRDash" Height="700" Width="800"> Title="VRDash" Height="700" Width="800">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>

View File

@ -217,6 +217,20 @@ namespace VRDash
var profile = ProfileManager.LoadProfile(); var profile = ProfileManager.LoadProfile();
LoadProfile(profile); LoadProfile(profile);
} }
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if(e.Key == Key.F1)
{
var conf = new MonitorOverlayConfig();
conf.Name = "Test Browser";
conf.Key = "asdfasdf";
conf.Location = new Overlay.Config.OverlayLocation.DashboardLocation();
var overlay = new Overlay.BrowserOverlay(conf);
overlay.Create();
overlay.Show();
}
}
} }
public class EditorMap public class EditorMap

View File

@ -0,0 +1,13 @@
<Window x:Class="VRDash.Overlay.BrowserOverlay"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:VRDash.Overlay"
xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
mc:Ignorable="d"
Title="BrowserOverlay" Height="450" Width="800">
<Grid>
<cefSharp:ChromiumWebBrowser x:Name="cwbBrowser" IsBrowserInitializedChanged="cwbBrowser_IsBrowserInitializedChanged" Paint="cwbBrowser_Paint"/>
</Grid>
</Window>

View File

@ -0,0 +1,241 @@
using CefSharp;
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Valve.VR;
using VRDash.Overlay.Config;
namespace VRDash.Overlay
{
/// <summary>
/// Interaction logic for BrowserOverlay.xaml
/// </summary>
public partial class BrowserOverlay : Window, IOverlay
{
ulong m_OverlayHandle = OpenVR.k_ulOverlayHandleInvalid;
public ulong OverlayHandle { get { return m_OverlayHandle; } }
ulong m_ThumbnailHandle = OpenVR.k_ulOverlayHandleInvalid;
public IOverlayConfig OverlayConfig { get { return Config; } }
//CHANGEME to the BrowserOverlayCOnfig you make later
public IOverlayConfig Config { get; }
public int CurrentFPS { get; private set; } = 0;
public bool IsDisposed { get; private set; } = false;
public event EventHandler OverlayShown;
public event EventHandler OverlayHidden;
public event EventHandler Update;
bool m_Created = false;
//CHANGEME to the BrowserOverlayCOnfig you make later
public BrowserOverlay(IOverlayConfig config)
{
Config = config;
InitializeComponent();
}
Factory1 m_Factory = null;
Adapter1 m_Adapter = null;
SharpDX.Direct3D11.Device m_Device = null;
int m_LastWidth = 0;
int m_LastHeight = 0;
Texture2D m_ScreenTexture = null;
DataStream m_Stream = null;
int frames = 0;
DateTime lastFps = DateTime.MinValue;
DateTime lastNameCheck = DateTime.MinValue;
public void Create()
{
if (m_Created) { throw new Exception("This overlay has already been created."); }
Config.OverlayLocation.OverlayHandles overlayHandles = Config.Location.CreateOverlay(Config.Key, Config.Name, this);
m_OverlayHandle = overlayHandles.OverlayHandle;
m_ThumbnailHandle = overlayHandles.ThumbnailHandle;
OpenVR.Overlay.ShowOverlay(m_OverlayHandle);
m_Created = true;
#region Rendering setup
m_Factory = new Factory1();
//Get first adapter
m_Adapter = m_Factory.GetAdapter1(0);
//Get device from adapter
m_Device = new SharpDX.Direct3D11.Device(m_Adapter);
#endregion
}
public void Destroy()
{
throw new NotImplementedException();
}
public void Dispose()
{
if (IsDisposed) { return; }
Destroy();
IsDisposed = true;
}
public string GetOverlayName()
{
EVROverlayError err = EVROverlayError.None;
StringBuilder sb = new StringBuilder(255);
uint res = OpenVR.Overlay.GetOverlayName(m_OverlayHandle, sb, 255, ref err);
return sb.ToString();
}
public void SetOverlayName(string newName)
{
OpenVR.Overlay.SetOverlayName(m_OverlayHandle, newName);
}
public float GetOverlayWidth()
{
float width = 0f;
OpenVR.Overlay.GetOverlayWidthInMeters(m_OverlayHandle, ref width);
return width;
}
public void SetOverlayWidth(float width)
{
OpenVR.Overlay.SetOverlayWidthInMeters(m_OverlayHandle, width);
}
private void cwbBrowser_IsBrowserInitializedChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if ((bool)e.NewValue)
{
cwbBrowser.LoadHtml("<iframe frameborder=\"0\"\r\n scrolling=\"no\"\r\n id=\"chat_embed\"\r\n src=\"https://www.twitch.tv/embed/meteos/chat\"\r\n height=\"500\"\r\n width=\"350\">\r\n</iframe>");
}
}
#region Rendering shit
private void cwbBrowser_Paint(object sender, CefSharp.Wpf.PaintEventArgs e)
{
if (!m_Created) { return; }
Update?.Invoke(this, null);
if (m_ScreenTexture == null || (m_LastWidth != e.Width || m_LastHeight != e.Height))
{
m_LastWidth = e.Width;
m_LastHeight = e.Height;
if (m_ScreenTexture != null)
{
m_ScreenTexture.Dispose();
//Dispose not freeing screenTexture: https://gamedev.stackexchange.com/questions/93311/freeing-texture-memory-in-sharpdx-what-am-i-missing
m_Device.ImmediateContext.ClearState();
m_Device.ImmediateContext.Flush();
}
var textureDesc = new Texture2DDescription
{
CpuAccessFlags = CpuAccessFlags.Write,
BindFlags = BindFlags.ShaderResource,
Format = Format.B8G8R8A8_UNorm,
//Format = Format.B8G8R8A8_UNorm_SRgb,
Width = e.Width,
Height = e.Height,
OptionFlags = ResourceOptionFlags.None,
MipLevels = 1,
ArraySize = 1,
SampleDescription = { Count = 1, Quality = 0 },
Usage = ResourceUsage.Dynamic
};
m_ScreenTexture = new Texture2D(m_Device, textureDesc);
m_Stream = new DataStream(4 * e.Width * e.Height, true, true);
OpenVR.Overlay.SetOverlayWidthInMeters(m_OverlayHandle, Config.OverlayWidth);
HmdVector2_t vecWindowSize = new HmdVector2_t() { v0 = e.Width, v1 = e.Height };
OpenVR.Overlay.SetOverlayMouseScale(m_OverlayHandle, ref vecWindowSize);
this.GetLogger().Info($"Browser resized, texture updated. ({e.Width}x{e.Height})");
}
DataBox databox = m_Device.ImmediateContext.MapSubresource(m_ScreenTexture, 0, MapMode.WriteDiscard,
SharpDX.Direct3D11.MapFlags.None, out m_Stream);
int stride = e.Width * 4;
if (!databox.IsEmpty)
{
int count = 4 * e.Width * e.Height;
//Stride compensation. Sometimes the BMP and DX texture strides are different. This fixes it.
if (databox.RowPitch == stride)
{
m_Stream.Write(e.Buffer, 0, count);
}
//Truncate the extra BMP bytes.
else if (databox.RowPitch < stride)
{
for (int i = 0; i < e.Height; i++)
{
m_Stream.Write(e.Buffer, (stride * i), databox.RowPitch);
}
}
//Add some junk on empty bytes on the end to make everyone happy.
else if (databox.RowPitch > stride)
{
int difference = databox.RowPitch - stride;
byte[] junk = new byte[difference];
for (int i = 0; i < e.Height; i++)
{
m_Stream.Write(e.Buffer, (stride * i), stride);
m_Stream.Write(junk, 0, difference);
}
}
//stream.Write(data.Scan0, 0, count);
}
m_Device.ImmediateContext.UpdateSubresource(ref databox, m_ScreenTexture, 0, stride, 1);
var texture = new Texture_t();
texture.handle = m_ScreenTexture.NativePointer;
texture.eType = ETextureType.DirectX;
texture.eColorSpace = EColorSpace.Auto;
EVROverlayError result = OpenVR.Overlay.SetOverlayTexture(m_OverlayHandle, ref texture);
if (result != EVROverlayError.None)
{
this.GetLogger().Warn($"Error rendering: {result}");
}
m_Device.ImmediateContext.UnmapSubresource(m_ScreenTexture, 0);
//FIXME Later...
//frames++;
}
#endregion
}
}

View File

@ -44,7 +44,7 @@ namespace VRDash.Overlay
public ulong ThumbnailIcon { get { return m_ThumbnailIcon; } } public ulong ThumbnailIcon { get { return m_ThumbnailIcon; } }
public IOverlayConfig OverlayConfig { get { return Config; } } public IOverlayConfig OverlayConfig { get { return Config; } }
public WindowOverlayConfig Config { get; } public WindowOverlayConfig Config { get; private set; }
//internal string m_Key; //internal string m_Key;

View File

@ -8,8 +8,8 @@
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace VRDash.Properties namespace VRDash.Properties {
{ using System;
/// <summary> /// <summary>
@ -19,32 +19,27 @@ namespace VRDash.Properties
// class via a tool like ResGen or Visual Studio. // class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen // To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project. // with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources internal class Resources {
{
private static global::System.Resources.ResourceManager resourceMan; private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture; private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() internal Resources() {
{
} }
/// <summary> /// <summary>
/// Returns the cached ResourceManager instance used by this class. /// Returns the cached ResourceManager instance used by this class.
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager internal static global::System.Resources.ResourceManager ResourceManager {
{ get {
get if (object.ReferenceEquals(resourceMan, null)) {
{ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VRDash.Properties.Resources", typeof(Resources).Assembly);
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VDash.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
@ -56,14 +51,11 @@ namespace VRDash.Properties
/// resource lookups using this strongly typed resource class. /// resource lookups using this strongly typed resource class.
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture internal static global::System.Globalization.CultureInfo Culture {
{ get {
get
{
return resourceCulture; return resourceCulture;
} }
set set {
{
resourceCulture = value; resourceCulture = value;
} }
} }

View File

@ -8,21 +8,17 @@
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace VRDash.Properties namespace VRDash.Properties {
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default public static Settings Default {
{ get {
get
{
return defaultInstance; return defaultInstance;
} }
} }

View File

@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\CefSharp.Wpf.73.1.130\build\CefSharp.Wpf.props" Condition="Exists('..\packages\CefSharp.Wpf.73.1.130\build\CefSharp.Wpf.props')" />
<Import Project="..\packages\CefSharp.Common.73.1.130\build\CefSharp.Common.props" Condition="Exists('..\packages\CefSharp.Common.73.1.130\build\CefSharp.Common.props')" />
<Import Project="..\packages\cef.redist.x86.73.1.13\build\cef.redist.x86.props" Condition="Exists('..\packages\cef.redist.x86.73.1.13\build\cef.redist.x86.props')" />
<Import Project="..\packages\cef.redist.x64.73.1.13\build\cef.redist.x64.props" Condition="Exists('..\packages\cef.redist.x64.73.1.13\build\cef.redist.x64.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -8,11 +12,14 @@
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<RootNamespace>VRDash</RootNamespace> <RootNamespace>VRDash</RootNamespace>
<AssemblyName>VRDash</AssemblyName> <AssemblyName>VRDash</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<Deterministic>true</Deterministic> <Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
@ -95,6 +102,9 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="Logger.cs" /> <Compile Include="Logger.cs" />
<Compile Include="Overlay\BrowserOverlay.xaml.cs">
<DependentUpon>BrowserOverlay.xaml</DependentUpon>
</Compile>
<Compile Include="Overlay\Config\OverlayLocation\ControllerLocation.cs" /> <Compile Include="Overlay\Config\OverlayLocation\ControllerLocation.cs" />
<Compile Include="Overlay\Config\OverlayLocation\DashboardLocation.cs" /> <Compile Include="Overlay\Config\OverlayLocation\DashboardLocation.cs" />
<Compile Include="Overlay\Config\OverlayLocation\IOverlayLocation.cs" /> <Compile Include="Overlay\Config\OverlayLocation\IOverlayLocation.cs" />
@ -165,6 +175,10 @@
<DependentUpon>MainWindow.xaml</DependentUpon> <DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Page Include="Overlay\BrowserOverlay.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="UI\ActionEditors\ResizeWindowActionEditor.xaml"> <Page Include="UI\ActionEditors\ResizeWindowActionEditor.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
@ -243,4 +257,17 @@
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\cef.redist.x64.73.1.13\build\cef.redist.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cef.redist.x64.73.1.13\build\cef.redist.x64.props'))" />
<Error Condition="!Exists('..\packages\cef.redist.x86.73.1.13\build\cef.redist.x86.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\cef.redist.x86.73.1.13\build\cef.redist.x86.props'))" />
<Error Condition="!Exists('..\packages\CefSharp.Common.73.1.130\build\CefSharp.Common.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\CefSharp.Common.73.1.130\build\CefSharp.Common.props'))" />
<Error Condition="!Exists('..\packages\CefSharp.Common.73.1.130\build\CefSharp.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\CefSharp.Common.73.1.130\build\CefSharp.Common.targets'))" />
<Error Condition="!Exists('..\packages\CefSharp.Wpf.73.1.130\build\CefSharp.Wpf.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\CefSharp.Wpf.73.1.130\build\CefSharp.Wpf.props'))" />
<Error Condition="!Exists('..\packages\CefSharp.Wpf.73.1.130\build\CefSharp.Wpf.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\CefSharp.Wpf.73.1.130\build\CefSharp.Wpf.targets'))" />
</Target>
<Import Project="..\packages\CefSharp.Common.73.1.130\build\CefSharp.Common.targets" Condition="Exists('..\packages\CefSharp.Common.73.1.130\build\CefSharp.Common.targets')" />
<Import Project="..\packages\CefSharp.Wpf.73.1.130\build\CefSharp.Wpf.targets" Condition="Exists('..\packages\CefSharp.Wpf.73.1.130\build\CefSharp.Wpf.targets')" />
</Project> </Project>

View File

@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="cef.redist.x64" version="73.1.13" targetFramework="net452" />
<package id="cef.redist.x86" version="73.1.13" targetFramework="net452" />
<package id="CefSharp.Common" version="73.1.130" targetFramework="net452" />
<package id="CefSharp.Wpf" version="73.1.130" targetFramework="net452" />
<package id="JsonNet.PrivateSettersContractResolvers.Source" version="0.1.0" targetFramework="net45" developmentDependency="true" /> <package id="JsonNet.PrivateSettersContractResolvers.Source" version="0.1.0" targetFramework="net45" developmentDependency="true" />
<package id="log4net" version="2.0.8" targetFramework="net45" /> <package id="log4net" version="2.0.8" targetFramework="net45" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net45" /> <package id="Newtonsoft.Json" version="12.0.2" targetFramework="net45" />