Port VR Overlay to Silk.NET

This commit is contained in:
BenjaminZehowlt
2025-10-19 18:32:33 -04:00
committed by Natsumi
parent 090395bb61
commit b4cafe2f3d
5 changed files with 318 additions and 245 deletions

View File

@@ -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();
}
} }
} }

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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" />