mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-19 14:53:50 +02:00
Port VR Overlay to Silk.NET
This commit is contained in:
@@ -8,23 +8,21 @@ using CefSharp;
|
|||||||
using CefSharp.Enums;
|
using CefSharp.Enums;
|
||||||
using CefSharp.OffScreen;
|
using CefSharp.OffScreen;
|
||||||
using CefSharp.Structs;
|
using CefSharp.Structs;
|
||||||
using SharpDX.Direct3D11;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using NLog;
|
using NLog;
|
||||||
using SharpDX.Direct3D;
|
using Silk.NET.Core.Native;
|
||||||
using SharpDX.Mathematics.Interop;
|
using Silk.NET.Direct3D11;
|
||||||
using Range = CefSharp.Structs.Range;
|
using Range = CefSharp.Structs.Range;
|
||||||
|
|
||||||
namespace VRCX
|
namespace VRCX
|
||||||
{
|
{
|
||||||
public class OffScreenBrowser : ChromiumWebBrowser, IRenderHandler
|
public class OffScreenBrowser : ChromiumWebBrowser, IRenderHandler
|
||||||
{
|
{
|
||||||
private Device _device;
|
private ComPtr<ID3D11Device1> _device1;
|
||||||
private Device1 _device1;
|
private ComPtr<ID3D11DeviceContext> _deviceContext;
|
||||||
private DeviceMultithread _deviceMultithread;
|
private ComPtr<ID3D11Query> _query;
|
||||||
private Query _query;
|
private ComPtr<ID3D11Texture2D> _renderTarget;
|
||||||
private Texture2D _renderTarget;
|
|
||||||
|
|
||||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
@@ -52,23 +50,19 @@ namespace VRCX
|
|||||||
JavascriptBindings.ApplyVrJavascriptBindings(JavascriptObjectRepository);
|
JavascriptBindings.ApplyVrJavascriptBindings(JavascriptObjectRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateRender(Device device, Texture2D renderTarget)
|
public void UpdateRender(ComPtr<ID3D11Device> device, ComPtr<ID3D11DeviceContext> deviceContext, ComPtr<ID3D11Texture2D> renderTarget)
|
||||||
{
|
{
|
||||||
_device = device;
|
_device1.Dispose();
|
||||||
_device1 = _device.QueryInterface<Device1>();
|
_device1 = device.QueryInterface<ID3D11Device1>();
|
||||||
|
_deviceContext = deviceContext;
|
||||||
_deviceMultithread?.Dispose();
|
|
||||||
_deviceMultithread = _device.QueryInterfaceOrNull<DeviceMultithread>();
|
|
||||||
_deviceMultithread?.SetMultithreadProtected(true);
|
|
||||||
|
|
||||||
_renderTarget = renderTarget;
|
_renderTarget = renderTarget;
|
||||||
|
|
||||||
_query?.Dispose();
|
_query.Dispose();
|
||||||
_query = new Query(_device, new QueryDescription
|
device.CreateQuery(new QueryDesc
|
||||||
{
|
{
|
||||||
Type = QueryType.Event,
|
Query = Query.Event,
|
||||||
Flags = QueryFlags.None
|
MiscFlags = 0
|
||||||
});
|
}, ref _query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public new void Dispose()
|
public new void Dispose()
|
||||||
@@ -102,29 +96,31 @@ namespace VRCX
|
|||||||
if (type != PaintElementType.View)
|
if (type != PaintElementType.View)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_device == null)
|
unsafe
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
using Texture2D cefTexture = _device1.OpenSharedResource1<Texture2D>(paintInfo.SharedTextureHandle);
|
if ((IntPtr)_device1.Handle == IntPtr.Zero)
|
||||||
_device.ImmediateContext.CopyResource(cefTexture, _renderTarget);
|
return;
|
||||||
_device.ImmediateContext.End(_query);
|
|
||||||
_device.ImmediateContext.Flush();
|
if ((IntPtr)_deviceContext.Handle == IntPtr.Zero)
|
||||||
}
|
return;
|
||||||
catch (Exception e)
|
|
||||||
{
|
if ((IntPtr)_query.Handle == IntPtr.Zero)
|
||||||
logger.Error(e);
|
return;
|
||||||
_device = null;
|
|
||||||
return;
|
if ((IntPtr)_renderTarget.Handle == IntPtr.Zero)
|
||||||
}
|
return;
|
||||||
|
|
||||||
RawBool q = _device.ImmediateContext.GetData<RawBool>(_query, AsynchronousFlags.DoNotFlush);
|
_deviceContext.Begin(_query);
|
||||||
|
using ComPtr<ID3D11Texture2D> cefTexture =
|
||||||
while (!q)
|
_device1.OpenSharedResource1<ID3D11Texture2D>(paintInfo.SharedTextureHandle.ToPointer());
|
||||||
{
|
_deviceContext.CopyResource(_renderTarget, cefTexture);
|
||||||
Thread.Yield();
|
_deviceContext.End(_query);
|
||||||
q = _device.ImmediateContext.GetData<RawBool>(_query, AsynchronousFlags.DoNotFlush);
|
_deviceContext.Flush();
|
||||||
|
|
||||||
|
while (_deviceContext.GetData(_query, IntPtr.Zero.ToPointer(), 0, 0) == 1)
|
||||||
|
{
|
||||||
|
Thread.Yield();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ using CefSharp;
|
|||||||
using CefSharp.Enums;
|
using CefSharp.Enums;
|
||||||
using CefSharp.OffScreen;
|
using CefSharp.OffScreen;
|
||||||
using CefSharp.Structs;
|
using CefSharp.Structs;
|
||||||
using SharpDX.Direct3D11;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Silk.NET.Core.Native;
|
||||||
|
using Silk.NET.Direct3D11;
|
||||||
using Range = CefSharp.Structs.Range;
|
using Range = CefSharp.Structs.Range;
|
||||||
|
|
||||||
namespace VRCX
|
namespace VRCX
|
||||||
@@ -61,11 +62,14 @@ namespace VRCX
|
|||||||
_paintBufferLock.Dispose();
|
_paintBufferLock.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RenderToTexture(Texture2D texture)
|
public void RenderToTexture(ComPtr<ID3D11DeviceContext> deviceContext, ComPtr<ID3D11Texture2D> texture)
|
||||||
{
|
{
|
||||||
// Safeguard against uninitialized texture
|
// Safeguard against uninitialized texture
|
||||||
if (texture == null)
|
unsafe
|
||||||
return;
|
{
|
||||||
|
if ((IntPtr)texture.Handle == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_paintBufferLock.EnterReadLock();
|
_paintBufferLock.EnterReadLock();
|
||||||
try
|
try
|
||||||
@@ -73,42 +77,41 @@ namespace VRCX
|
|||||||
if (_width > 0 &&
|
if (_width > 0 &&
|
||||||
_height > 0)
|
_height > 0)
|
||||||
{
|
{
|
||||||
var context = texture.Device.ImmediateContext;
|
MappedSubresource mappedSubresource = default;
|
||||||
var dataBox = context.MapSubresource(
|
deviceContext.Map(texture, 0, Map.WriteDiscard, 0, ref mappedSubresource);
|
||||||
texture,
|
unsafe
|
||||||
0,
|
|
||||||
MapMode.WriteDiscard,
|
|
||||||
MapFlags.None
|
|
||||||
);
|
|
||||||
if (dataBox.IsEmpty == false)
|
|
||||||
{
|
{
|
||||||
var sourcePtr = _paintBuffer.AddrOfPinnedObject();
|
if ((IntPtr)mappedSubresource.PData != IntPtr.Zero)
|
||||||
var destinationPtr = dataBox.DataPointer;
|
|
||||||
var pitch = _width * 4;
|
|
||||||
var rowPitch = dataBox.RowPitch;
|
|
||||||
if (pitch == rowPitch)
|
|
||||||
{
|
{
|
||||||
WinApi.RtlCopyMemory(
|
var sourcePtr = _paintBuffer.AddrOfPinnedObject();
|
||||||
destinationPtr,
|
var destinationPtr = (IntPtr)mappedSubresource.PData;
|
||||||
sourcePtr,
|
var pitch = _width * 4;
|
||||||
(uint)(_width * _height * 4)
|
var rowPitch = mappedSubresource.RowPitch;
|
||||||
);
|
if (pitch == rowPitch)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (var y = _height; y > 0; --y)
|
|
||||||
{
|
{
|
||||||
WinApi.RtlCopyMemory(
|
WinApi.RtlCopyMemory(
|
||||||
destinationPtr,
|
destinationPtr,
|
||||||
sourcePtr,
|
sourcePtr,
|
||||||
(uint)pitch
|
(uint)(_width * _height * 4)
|
||||||
);
|
);
|
||||||
sourcePtr += pitch;
|
}
|
||||||
destinationPtr += rowPitch;
|
else
|
||||||
|
{
|
||||||
|
for (var y = _height; y > 0; --y)
|
||||||
|
{
|
||||||
|
WinApi.RtlCopyMemory(
|
||||||
|
destinationPtr,
|
||||||
|
sourcePtr,
|
||||||
|
(uint)pitch
|
||||||
|
);
|
||||||
|
sourcePtr += pitch;
|
||||||
|
destinationPtr += (IntPtr)rowPitch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deviceContext.Unmap(texture, 0);
|
||||||
}
|
}
|
||||||
context.UnmapSubresource(texture, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|||||||
@@ -8,20 +8,16 @@ using System;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Numerics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using CefSharp;
|
using CefSharp;
|
||||||
using NLog;
|
using NLog;
|
||||||
using SharpDX;
|
using Silk.NET.Core.Native;
|
||||||
using SharpDX.Direct3D11;
|
using Silk.NET.Direct3D11;
|
||||||
using SharpDX.DXGI;
|
using Silk.NET.DXGI;
|
||||||
using Valve.VR;
|
using Valve.VR;
|
||||||
using Device = SharpDX.Direct3D11.Device;
|
|
||||||
using Device1 = SharpDX.Direct3D11.Device1;
|
|
||||||
using Device2 = SharpDX.Direct3D11.Device2;
|
|
||||||
using Device3 = SharpDX.Direct3D11.Device3;
|
|
||||||
using Device4 = SharpDX.Direct3D11.Device4;
|
|
||||||
|
|
||||||
namespace VRCX
|
namespace VRCX
|
||||||
{
|
{
|
||||||
@@ -40,12 +36,8 @@ namespace VRCX
|
|||||||
private readonly List<string[]> _deviceList;
|
private readonly List<string[]> _deviceList;
|
||||||
private readonly ReaderWriterLockSlim _deviceListLock;
|
private readonly ReaderWriterLockSlim _deviceListLock;
|
||||||
private bool _active;
|
private bool _active;
|
||||||
private Device _device;
|
|
||||||
private bool _menuButton;
|
private bool _menuButton;
|
||||||
private int _overlayHand;
|
private int _overlayHand;
|
||||||
private Factory _factory;
|
|
||||||
private Texture2D _texture1;
|
|
||||||
private Texture2D _texture2;
|
|
||||||
private Thread _thread;
|
private Thread _thread;
|
||||||
private DateTime _nextOverlayUpdate;
|
private DateTime _nextOverlayUpdate;
|
||||||
|
|
||||||
@@ -57,6 +49,16 @@ namespace VRCX
|
|||||||
private bool _wristOverlayActive;
|
private bool _wristOverlayActive;
|
||||||
private bool _wristOverlayWasActive;
|
private bool _wristOverlayWasActive;
|
||||||
|
|
||||||
|
private DXGI _dxgi;
|
||||||
|
private D3D11 _d3d11;
|
||||||
|
private ComPtr<IDXGIFactory2> _factory;
|
||||||
|
private ComPtr<IDXGIAdapter> _adapter;
|
||||||
|
private ComPtr<ID3D11Device> _device;
|
||||||
|
private ComPtr<ID3D11Multithread> _multithread;
|
||||||
|
private ComPtr<ID3D11DeviceContext> _deviceContext;
|
||||||
|
|
||||||
|
private ComPtr<ID3D11Texture2D> _texture1;
|
||||||
|
private ComPtr<ID3D11Texture2D> _texture2;
|
||||||
|
|
||||||
static VRCXVRCef()
|
static VRCXVRCef()
|
||||||
{
|
{
|
||||||
@@ -99,81 +101,76 @@ namespace VRCX
|
|||||||
|
|
||||||
private void SetupTextures()
|
private void SetupTextures()
|
||||||
{
|
{
|
||||||
_factory ??= new Factory1();
|
unsafe
|
||||||
|
{
|
||||||
|
_dxgi?.Dispose();
|
||||||
|
_dxgi = DXGI.GetApi(null);
|
||||||
|
_d3d11?.Dispose();
|
||||||
|
_d3d11 = D3D11.GetApi(null);
|
||||||
|
|
||||||
_device?.Dispose();
|
_factory.Dispose();
|
||||||
_device = new Device(_factory.GetAdapter(OpenVR.System.GetD3D9AdapterIndex()),
|
SilkMarshal.ThrowHResult(_dxgi.CreateDXGIFactory<IDXGIFactory2>(out _factory));
|
||||||
DeviceCreationFlags.BgraSupport);
|
_adapter.Dispose();
|
||||||
UpgradeDevice();
|
SilkMarshal.ThrowHResult(_factory.EnumAdapters((uint)OpenVR.System.GetD3D9AdapterIndex(),
|
||||||
|
ref _adapter));
|
||||||
|
|
||||||
_texture1?.Dispose();
|
_device.Dispose();
|
||||||
_texture1 = new Texture2D(
|
_deviceContext.Dispose();
|
||||||
_device,
|
SilkMarshal.ThrowHResult
|
||||||
new Texture2DDescription
|
(
|
||||||
|
_d3d11.CreateDevice
|
||||||
|
(
|
||||||
|
_adapter,
|
||||||
|
D3DDriverType.Unknown,
|
||||||
|
Software: default,
|
||||||
|
(uint)(CreateDeviceFlag.BgraSupport | CreateDeviceFlag.Debug),
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
D3D11.SdkVersion,
|
||||||
|
ref _device,
|
||||||
|
null,
|
||||||
|
ref _deviceContext
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
_multithread = _device.QueryInterface<ID3D11Multithread>();
|
||||||
|
_multithread.SetMultithreadProtected(true);
|
||||||
|
|
||||||
|
_device.SetInfoQueueCallback(msg => logger.Info(SilkMarshal.PtrToString((nint)msg.PDescription)!));
|
||||||
|
|
||||||
|
_texture1.Dispose();
|
||||||
|
_device.CreateTexture2D(new Texture2DDesc
|
||||||
{
|
{
|
||||||
Width = 512,
|
Width = 512,
|
||||||
Height = 512,
|
Height = 512,
|
||||||
MipLevels = 1,
|
MipLevels = 1,
|
||||||
ArraySize = 1,
|
ArraySize = 1,
|
||||||
Format = Format.B8G8R8A8_UNorm,
|
Format = Format.FormatB8G8R8A8Unorm,
|
||||||
SampleDescription = new SampleDescription(1, 0),
|
SampleDesc = new SampleDesc
|
||||||
BindFlags = BindFlags.ShaderResource
|
{
|
||||||
}
|
Count = 1,
|
||||||
);
|
Quality = 0
|
||||||
_wristOverlay?.UpdateRender(_device, _texture1);
|
},
|
||||||
|
BindFlags = (uint)BindFlag.ShaderResource
|
||||||
|
}, null, ref _texture1);
|
||||||
|
_wristOverlay?.UpdateRender(_device, _deviceContext, _texture1);
|
||||||
|
|
||||||
_texture2?.Dispose();
|
_texture2.Dispose();
|
||||||
_texture2 = new Texture2D(
|
_device.CreateTexture2D(new Texture2DDesc
|
||||||
_device,
|
|
||||||
new Texture2DDescription
|
|
||||||
{
|
{
|
||||||
Width = 1024,
|
Width = 1024,
|
||||||
Height = 1024,
|
Height = 1024,
|
||||||
MipLevels = 1,
|
MipLevels = 1,
|
||||||
ArraySize = 1,
|
ArraySize = 1,
|
||||||
Format = Format.B8G8R8A8_UNorm,
|
Format = Format.FormatB8G8R8A8Unorm,
|
||||||
SampleDescription = new SampleDescription(1, 0),
|
SampleDesc = new SampleDesc
|
||||||
BindFlags = BindFlags.ShaderResource
|
{
|
||||||
}
|
Count = 1,
|
||||||
);
|
Quality = 0
|
||||||
_hmdOverlay?.UpdateRender(_device, _texture2);
|
},
|
||||||
}
|
BindFlags = (uint)BindFlag.ShaderResource
|
||||||
|
}, null, ref _texture2);
|
||||||
private void UpgradeDevice()
|
_hmdOverlay?.UpdateRender(_device, _deviceContext, _texture2);
|
||||||
{
|
|
||||||
Device5 device5 = _device.QueryInterfaceOrNull<Device5>();
|
|
||||||
if (device5 != null)
|
|
||||||
{
|
|
||||||
_device.Dispose();
|
|
||||||
_device = device5;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Device4 device4 = _device.QueryInterfaceOrNull<Device4>();
|
|
||||||
if (device4 != null)
|
|
||||||
{
|
|
||||||
_device.Dispose();
|
|
||||||
_device = device4;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Device3 device3 = _device.QueryInterfaceOrNull<Device3>();
|
|
||||||
if (device3 != null)
|
|
||||||
{
|
|
||||||
_device.Dispose();
|
|
||||||
_device = device3;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Device2 device2 = _device.QueryInterfaceOrNull<Device2>();
|
|
||||||
if (device2 != null)
|
|
||||||
{
|
|
||||||
_device.Dispose();
|
|
||||||
_device = device2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Device1 device1 = _device.QueryInterfaceOrNull<Device1>();
|
|
||||||
if (device1 != null)
|
|
||||||
{
|
|
||||||
_device.Dispose();
|
|
||||||
_device = device1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,9 +321,11 @@ namespace VRCX
|
|||||||
|
|
||||||
_hmdOverlay?.Dispose();
|
_hmdOverlay?.Dispose();
|
||||||
_wristOverlay?.Dispose();
|
_wristOverlay?.Dispose();
|
||||||
_texture2?.Dispose();
|
_texture2.Dispose();
|
||||||
_texture1?.Dispose();
|
_texture1.Dispose();
|
||||||
_device?.Dispose();
|
_device.Dispose();
|
||||||
|
_adapter.Dispose();
|
||||||
|
_factory.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetActive(bool active, bool hmdOverlay, bool wristOverlay, bool menuButton, int overlayHand)
|
public override void SetActive(bool active, bool hmdOverlay, bool wristOverlay, bool menuButton, int overlayHand)
|
||||||
@@ -581,6 +580,12 @@ namespace VRCX
|
|||||||
{
|
{
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = overlay.SetOverlayFlag(dashboardHandle, VROverlayFlags.NoDashboardTab, true);
|
||||||
|
if (err != EVROverlayError.None)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,14 +616,17 @@ namespace VRCX
|
|||||||
|
|
||||||
if (dashboardVisible)
|
if (dashboardVisible)
|
||||||
{
|
{
|
||||||
var texture = new Texture_t
|
unsafe
|
||||||
{
|
{
|
||||||
handle = _texture1.NativePointer
|
var texture = new Texture_t
|
||||||
};
|
{
|
||||||
err = overlay.SetOverlayTexture(dashboardHandle, ref texture);
|
handle = (IntPtr)_texture1.Handle
|
||||||
if (err != EVROverlayError.None)
|
};
|
||||||
{
|
err = overlay.SetOverlayTexture(dashboardHandle, ref texture);
|
||||||
return err;
|
if (err != EVROverlayError.None)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -670,11 +678,11 @@ namespace VRCX
|
|||||||
{
|
{
|
||||||
// http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices
|
// http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices
|
||||||
// Scaling-Rotation-Translation
|
// Scaling-Rotation-Translation
|
||||||
var m = Matrix.Scaling(0.25f);
|
var m = Matrix4x4.CreateScale(0.25f);
|
||||||
m *= Matrix.RotationX(_rotation[0]);
|
m *= Matrix4x4.CreateRotationX(_rotation[0]);
|
||||||
m *= Matrix.RotationY(_rotation[1]);
|
m *= Matrix4x4.CreateRotationY(_rotation[1]);
|
||||||
m *= Matrix.RotationZ(_rotation[2]);
|
m *= Matrix4x4.CreateRotationZ(_rotation[2]);
|
||||||
m *= Matrix.Translation(_translation[0], _translation[1], _translation[2]);
|
m *= Matrix4x4.CreateTranslation(new Vector3(_translation[0], _translation[1], _translation[2]));
|
||||||
var hm34 = new HmdMatrix34_t
|
var hm34 = new HmdMatrix34_t
|
||||||
{
|
{
|
||||||
m0 = m.M11,
|
m0 = m.M11,
|
||||||
@@ -700,14 +708,17 @@ namespace VRCX
|
|||||||
if (!dashboardVisible &&
|
if (!dashboardVisible &&
|
||||||
DateTime.UtcNow.CompareTo(_nextOverlayUpdate) <= 0)
|
DateTime.UtcNow.CompareTo(_nextOverlayUpdate) <= 0)
|
||||||
{
|
{
|
||||||
var texture = new Texture_t
|
unsafe
|
||||||
{
|
{
|
||||||
handle = _texture1.NativePointer
|
var texture = new Texture_t
|
||||||
};
|
{
|
||||||
err = overlay.SetOverlayTexture(overlayHandle, ref texture);
|
handle = (IntPtr)_texture1.Handle
|
||||||
if (err != EVROverlayError.None)
|
};
|
||||||
{
|
err = overlay.SetOverlayTexture(overlayHandle, ref texture);
|
||||||
return err;
|
if (err != EVROverlayError.None)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!overlayVisible)
|
if (!overlayVisible)
|
||||||
@@ -774,8 +785,8 @@ namespace VRCX
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
var m = Matrix.Scaling(1f);
|
var m = Matrix4x4.CreateScale(1f);
|
||||||
m *= Matrix.Translation(0, -0.3f, -1.5f);
|
m *= Matrix4x4.CreateTranslation(0, -0.3f, -1.5f);
|
||||||
var hm34 = new HmdMatrix34_t
|
var hm34 = new HmdMatrix34_t
|
||||||
{
|
{
|
||||||
m0 = m.M11,
|
m0 = m.M11,
|
||||||
@@ -801,14 +812,17 @@ namespace VRCX
|
|||||||
|
|
||||||
if (!dashboardVisible)
|
if (!dashboardVisible)
|
||||||
{
|
{
|
||||||
var texture = new Texture_t
|
unsafe
|
||||||
{
|
{
|
||||||
handle = _texture2.NativePointer
|
var texture = new Texture_t
|
||||||
};
|
{
|
||||||
err = overlay.SetOverlayTexture(overlayHandle, ref texture);
|
handle = (IntPtr)_texture2.Handle
|
||||||
if (err != EVROverlayError.None)
|
};
|
||||||
{
|
err = overlay.SetOverlayTexture(overlayHandle, ref texture);
|
||||||
return err;
|
if (err != EVROverlayError.None)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!overlayVisible)
|
if (!overlayVisible)
|
||||||
|
|||||||
@@ -8,16 +8,16 @@ using System;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Numerics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using CefSharp;
|
using CefSharp;
|
||||||
using NLog;
|
using NLog;
|
||||||
using SharpDX;
|
using Silk.NET.Core.Native;
|
||||||
using SharpDX.Direct3D11;
|
using Silk.NET.Direct3D11;
|
||||||
using SharpDX.DXGI;
|
using Silk.NET.DXGI;
|
||||||
using Valve.VR;
|
using Valve.VR;
|
||||||
using Device = SharpDX.Direct3D11.Device;
|
|
||||||
|
|
||||||
namespace VRCX
|
namespace VRCX
|
||||||
{
|
{
|
||||||
@@ -36,15 +36,23 @@ namespace VRCX
|
|||||||
private readonly List<string[]> _deviceList;
|
private readonly List<string[]> _deviceList;
|
||||||
private readonly ReaderWriterLockSlim _deviceListLock;
|
private readonly ReaderWriterLockSlim _deviceListLock;
|
||||||
private bool _active;
|
private bool _active;
|
||||||
private Device _device;
|
|
||||||
private bool _hmdOverlayActive;
|
private bool _hmdOverlayActive;
|
||||||
private bool _menuButton;
|
private bool _menuButton;
|
||||||
private int _overlayHand;
|
private int _overlayHand;
|
||||||
private Texture2D _texture1;
|
|
||||||
private Texture2D _texture2;
|
|
||||||
private Thread _thread;
|
private Thread _thread;
|
||||||
private bool _wristOverlayActive;
|
private bool _wristOverlayActive;
|
||||||
private DateTime _nextOverlayUpdate;
|
private DateTime _nextOverlayUpdate;
|
||||||
|
|
||||||
|
private DXGI _dxgi;
|
||||||
|
private D3D11 _d3d11;
|
||||||
|
private ComPtr<IDXGIFactory2> _factory;
|
||||||
|
private ComPtr<IDXGIAdapter> _adapter;
|
||||||
|
private ComPtr<ID3D11Device> _device;
|
||||||
|
private ComPtr<ID3D11Multithread> _multithread;
|
||||||
|
private ComPtr<ID3D11DeviceContext> _deviceContext;
|
||||||
|
|
||||||
|
private ComPtr<ID3D11Texture2D> _texture1;
|
||||||
|
private ComPtr<ID3D11Texture2D> _texture2;
|
||||||
|
|
||||||
static VRCXVRLegacy()
|
static VRCXVRLegacy()
|
||||||
{
|
{
|
||||||
@@ -87,43 +95,75 @@ namespace VRCX
|
|||||||
|
|
||||||
private void SetupTextures()
|
private void SetupTextures()
|
||||||
{
|
{
|
||||||
Factory f = new Factory1();
|
unsafe
|
||||||
_device = new Device(f.GetAdapter(OpenVR.System.GetD3D9AdapterIndex()),
|
{
|
||||||
DeviceCreationFlags.SingleThreaded | DeviceCreationFlags.BgraSupport);
|
_dxgi?.Dispose();
|
||||||
|
_dxgi = DXGI.GetApi(null);
|
||||||
|
_d3d11?.Dispose();
|
||||||
|
_d3d11 = D3D11.GetApi(null);
|
||||||
|
|
||||||
_texture1?.Dispose();
|
_factory.Dispose();
|
||||||
_texture1 = new Texture2D(
|
SilkMarshal.ThrowHResult(_dxgi.CreateDXGIFactory<IDXGIFactory2>(out _factory));
|
||||||
_device,
|
_adapter.Dispose();
|
||||||
new Texture2DDescription
|
SilkMarshal.ThrowHResult(_factory.EnumAdapters((uint)OpenVR.System.GetD3D9AdapterIndex(),
|
||||||
|
ref _adapter));
|
||||||
|
|
||||||
|
_device.Dispose();
|
||||||
|
_deviceContext.Dispose();
|
||||||
|
SilkMarshal.ThrowHResult
|
||||||
|
(
|
||||||
|
_d3d11.CreateDevice
|
||||||
|
(
|
||||||
|
_adapter,
|
||||||
|
D3DDriverType.Unknown,
|
||||||
|
Software: default,
|
||||||
|
(uint)(CreateDeviceFlag.BgraSupport | CreateDeviceFlag.Debug),
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
D3D11.SdkVersion,
|
||||||
|
ref _device,
|
||||||
|
null,
|
||||||
|
ref _deviceContext
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
_multithread = _device.QueryInterface<ID3D11Multithread>();
|
||||||
|
_multithread.SetMultithreadProtected(true);
|
||||||
|
|
||||||
|
_device.SetInfoQueueCallback(msg => logger.Info(SilkMarshal.PtrToString((nint)msg.PDescription)!));
|
||||||
|
|
||||||
|
_texture1.Dispose();
|
||||||
|
_device.CreateTexture2D(new Texture2DDesc
|
||||||
{
|
{
|
||||||
Width = 512,
|
Width = 512,
|
||||||
Height = 512,
|
Height = 512,
|
||||||
MipLevels = 1,
|
MipLevels = 1,
|
||||||
ArraySize = 1,
|
ArraySize = 1,
|
||||||
Format = Format.B8G8R8A8_UNorm,
|
Format = Format.FormatB8G8R8A8Unorm,
|
||||||
SampleDescription = new SampleDescription(1, 0),
|
SampleDesc = new SampleDesc
|
||||||
Usage = ResourceUsage.Dynamic,
|
{
|
||||||
BindFlags = BindFlags.ShaderResource,
|
Count = 1,
|
||||||
CpuAccessFlags = CpuAccessFlags.Write
|
Quality = 0
|
||||||
}
|
},
|
||||||
);
|
BindFlags = (uint)BindFlag.ShaderResource
|
||||||
|
}, null, ref _texture1);
|
||||||
|
|
||||||
_texture2?.Dispose();
|
_texture2.Dispose();
|
||||||
_texture2 = new Texture2D(
|
_device.CreateTexture2D(new Texture2DDesc
|
||||||
_device,
|
|
||||||
new Texture2DDescription
|
|
||||||
{
|
{
|
||||||
Width = 1024,
|
Width = 1024,
|
||||||
Height = 1024,
|
Height = 1024,
|
||||||
MipLevels = 1,
|
MipLevels = 1,
|
||||||
ArraySize = 1,
|
ArraySize = 1,
|
||||||
Format = Format.B8G8R8A8_UNorm,
|
Format = Format.FormatB8G8R8A8Unorm,
|
||||||
SampleDescription = new SampleDescription(1, 0),
|
SampleDesc = new SampleDesc
|
||||||
Usage = ResourceUsage.Dynamic,
|
{
|
||||||
BindFlags = BindFlags.ShaderResource,
|
Count = 1,
|
||||||
CpuAccessFlags = CpuAccessFlags.Write
|
Quality = 0
|
||||||
}
|
},
|
||||||
);
|
BindFlags = (uint)BindFlag.ShaderResource
|
||||||
|
}, null, ref _texture2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThreadLoop()
|
private void ThreadLoop()
|
||||||
@@ -155,9 +195,9 @@ namespace VRCX
|
|||||||
while (_thread != null)
|
while (_thread != null)
|
||||||
{
|
{
|
||||||
if (_wristOverlayActive)
|
if (_wristOverlayActive)
|
||||||
_wristOverlay.RenderToTexture(_texture1);
|
_wristOverlay.RenderToTexture(_deviceContext, _texture1);
|
||||||
if (_hmdOverlayActive)
|
if (_hmdOverlayActive)
|
||||||
_hmdOverlay.RenderToTexture(_texture2);
|
_hmdOverlay.RenderToTexture(_deviceContext, _texture2);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Thread.Sleep(32);
|
Thread.Sleep(32);
|
||||||
@@ -268,9 +308,11 @@ namespace VRCX
|
|||||||
|
|
||||||
_hmdOverlay?.Dispose();
|
_hmdOverlay?.Dispose();
|
||||||
_wristOverlay?.Dispose();
|
_wristOverlay?.Dispose();
|
||||||
_texture2?.Dispose();
|
_texture2.Dispose();
|
||||||
_texture1?.Dispose();
|
_texture1.Dispose();
|
||||||
_device?.Dispose();
|
_device.Dispose();
|
||||||
|
_adapter.Dispose();
|
||||||
|
_factory.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetActive(bool active, bool hmdOverlay, bool wristOverlay, bool menuButton, int overlayHand)
|
public override void SetActive(bool active, bool hmdOverlay, bool wristOverlay, bool menuButton, int overlayHand)
|
||||||
@@ -509,6 +551,12 @@ namespace VRCX
|
|||||||
{
|
{
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = overlay.SetOverlayFlag(dashboardHandle, VROverlayFlags.NoDashboardTab, true);
|
||||||
|
if (err != EVROverlayError.None)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,14 +587,17 @@ namespace VRCX
|
|||||||
|
|
||||||
if (dashboardVisible)
|
if (dashboardVisible)
|
||||||
{
|
{
|
||||||
var texture = new Texture_t
|
unsafe
|
||||||
{
|
{
|
||||||
handle = _texture1.NativePointer
|
var texture = new Texture_t
|
||||||
};
|
{
|
||||||
err = overlay.SetOverlayTexture(dashboardHandle, ref texture);
|
handle = (IntPtr)_texture1.Handle
|
||||||
if (err != EVROverlayError.None)
|
};
|
||||||
{
|
err = overlay.SetOverlayTexture(dashboardHandle, ref texture);
|
||||||
return err;
|
if (err != EVROverlayError.None)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,11 +649,11 @@ namespace VRCX
|
|||||||
{
|
{
|
||||||
// http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices
|
// http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices
|
||||||
// Scaling-Rotation-Translation
|
// Scaling-Rotation-Translation
|
||||||
var m = Matrix.Scaling(0.25f);
|
var m = Matrix4x4.CreateScale(0.25f);
|
||||||
m *= Matrix.RotationX(_rotation[0]);
|
m *= Matrix4x4.CreateRotationX(_rotation[0]);
|
||||||
m *= Matrix.RotationY(_rotation[1]);
|
m *= Matrix4x4.CreateRotationY(_rotation[1]);
|
||||||
m *= Matrix.RotationZ(_rotation[2]);
|
m *= Matrix4x4.CreateRotationZ(_rotation[2]);
|
||||||
m *= Matrix.Translation(_translation[0], _translation[1], _translation[2]);
|
m *= Matrix4x4.CreateTranslation(new Vector3(_translation[0], _translation[1], _translation[2]));
|
||||||
var hm34 = new HmdMatrix34_t
|
var hm34 = new HmdMatrix34_t
|
||||||
{
|
{
|
||||||
m0 = m.M11,
|
m0 = m.M11,
|
||||||
@@ -628,14 +679,17 @@ namespace VRCX
|
|||||||
if (!dashboardVisible &&
|
if (!dashboardVisible &&
|
||||||
DateTime.UtcNow.CompareTo(_nextOverlayUpdate) <= 0)
|
DateTime.UtcNow.CompareTo(_nextOverlayUpdate) <= 0)
|
||||||
{
|
{
|
||||||
var texture = new Texture_t
|
unsafe
|
||||||
{
|
{
|
||||||
handle = _texture1.NativePointer
|
var texture = new Texture_t
|
||||||
};
|
{
|
||||||
err = overlay.SetOverlayTexture(overlayHandle, ref texture);
|
handle = (IntPtr)_texture1.Handle
|
||||||
if (err != EVROverlayError.None)
|
};
|
||||||
{
|
err = overlay.SetOverlayTexture(overlayHandle, ref texture);
|
||||||
return err;
|
if (err != EVROverlayError.None)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!overlayVisible)
|
if (!overlayVisible)
|
||||||
@@ -702,8 +756,8 @@ namespace VRCX
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
var m = Matrix.Scaling(1f);
|
var m = Matrix4x4.CreateScale(1f);
|
||||||
m *= Matrix.Translation(0, -0.3f, -1.5f);
|
m *= Matrix4x4.CreateTranslation(0, -0.3f, -1.5f);
|
||||||
var hm34 = new HmdMatrix34_t
|
var hm34 = new HmdMatrix34_t
|
||||||
{
|
{
|
||||||
m0 = m.M11,
|
m0 = m.M11,
|
||||||
@@ -729,14 +783,17 @@ namespace VRCX
|
|||||||
|
|
||||||
if (!dashboardVisible)
|
if (!dashboardVisible)
|
||||||
{
|
{
|
||||||
var texture = new Texture_t
|
unsafe
|
||||||
{
|
{
|
||||||
handle = _texture2.NativePointer
|
var texture = new Texture_t
|
||||||
};
|
{
|
||||||
err = overlay.SetOverlayTexture(overlayHandle, ref texture);
|
handle = (IntPtr)_texture2.Handle
|
||||||
if (err != EVROverlayError.None)
|
};
|
||||||
{
|
err = overlay.SetOverlayTexture(overlayHandle, ref texture);
|
||||||
return err;
|
if (err != EVROverlayError.None)
|
||||||
|
{
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!overlayVisible)
|
if (!overlayVisible)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputPath>..\build\Cef\</OutputPath>
|
<OutputPath>..\build\Cef\</OutputPath>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
@@ -95,8 +96,10 @@
|
|||||||
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
<PackageReference Include="NLog" Version="6.0.5" />
|
<PackageReference Include="NLog" Version="6.0.5" />
|
||||||
<PackageReference Include="SharpDX.Direct3D11" Version="4.2.0" />
|
<PackageReference Include="Silk.NET.Direct3D.Compilers" Version="2.22.0" />
|
||||||
<PackageReference Include="SharpDX.Mathematics" Version="4.2.0" />
|
<PackageReference Include="Silk.NET.Direct3D11" Version="2.22.0" />
|
||||||
|
<PackageReference Include="Silk.NET.DXGI" Version="2.22.0" />
|
||||||
|
<PackageReference Include="Silk.NET.Windowing" Version="2.22.0" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
|
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
|
||||||
<PackageReference Include="SourceGear.sqlite3" Version="3.50.4.2" />
|
<PackageReference Include="SourceGear.sqlite3" Version="3.50.4.2" />
|
||||||
|
|||||||
Reference in New Issue
Block a user