Holographic Remoting version 2.1.0 (#6)
* version 2.1.0 * updated .gitignore file Co-authored-by: Florian Bagar <flbagar@microsoft.com>
|
@ -23,6 +23,9 @@ bld/
|
|||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
*.dir/
|
||||
player/sample/shaders/
|
||||
remote/uwp/src/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
|
|
|
@ -1,251 +0,0 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "CameraResources.h"
|
||||
#include "DeviceResources.h"
|
||||
#include "DirectXHelper.h"
|
||||
|
||||
#include <windows.graphics.directx.direct3d11.interop.h>
|
||||
|
||||
using namespace DirectX;
|
||||
using namespace winrt::Windows::Graphics::Holographic;
|
||||
using namespace winrt::Windows::Perception::Spatial;
|
||||
|
||||
DXHelper::CameraResources::CameraResources(const HolographicCamera& camera)
|
||||
: m_holographicCamera(camera)
|
||||
, m_isStereo(camera.IsStereo())
|
||||
, m_d3dRenderTargetSize(camera.RenderTargetSize())
|
||||
{
|
||||
m_d3dViewport = CD3D11_VIEWPORT(0.f, 0.f, m_d3dRenderTargetSize.Width, m_d3dRenderTargetSize.Height);
|
||||
};
|
||||
|
||||
// Updates resources associated with a holographic camera's swap chain.
|
||||
// The app does not access the swap chain directly, but it does create
|
||||
// resource views for the back buffer.
|
||||
void DXHelper::CameraResources::CreateResourcesForBackBuffer(
|
||||
DXHelper::DeviceResources* pDeviceResources, const HolographicCameraRenderingParameters& cameraParameters)
|
||||
{
|
||||
const auto device = pDeviceResources->GetD3DDevice();
|
||||
|
||||
// Get a DXGI interface for the holographic camera's back buffer.
|
||||
// Holographic cameras do not provide the DXGI swap chain, which is owned
|
||||
// by the system. The Direct3D back buffer resource is provided using WinRT
|
||||
// interop APIs.
|
||||
winrt::com_ptr<ID3D11Resource> resource;
|
||||
{
|
||||
winrt::com_ptr<::IInspectable> inspectable = cameraParameters.Direct3D11BackBuffer().as<::IInspectable>();
|
||||
winrt::com_ptr<Windows::Graphics::DirectX::Direct3D11::IDirect3DDxgiInterfaceAccess> dxgiInterfaceAccess;
|
||||
|
||||
HRESULT hr = inspectable->QueryInterface(__uuidof(dxgiInterfaceAccess), dxgiInterfaceAccess.put_void());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
winrt::throw_hresult(hr);
|
||||
}
|
||||
|
||||
hr = dxgiInterfaceAccess->GetInterface(__uuidof(resource), resource.put_void());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
winrt::throw_hresult(hr);
|
||||
}
|
||||
}
|
||||
|
||||
// Get a Direct3D interface for the holographic camera's back buffer.
|
||||
winrt::com_ptr<ID3D11Texture2D> cameraBackBuffer;
|
||||
resource.as(cameraBackBuffer);
|
||||
|
||||
// Determine if the back buffer has changed. If so, ensure that the render target view
|
||||
// is for the current back buffer.
|
||||
if (m_d3dBackBuffer != cameraBackBuffer)
|
||||
{
|
||||
// This can change every frame as the system moves to the next buffer in the
|
||||
// swap chain. This mode of operation will occur when certain rendering modes
|
||||
// are activated.
|
||||
m_d3dBackBuffer = cameraBackBuffer;
|
||||
|
||||
// Get the DXGI format for the back buffer.
|
||||
// This information can be accessed by the app using CameraResources::GetBackBufferDXGIFormat().
|
||||
D3D11_TEXTURE2D_DESC backBufferDesc;
|
||||
m_d3dBackBuffer->GetDesc(&backBufferDesc);
|
||||
m_dxgiFormat = backBufferDesc.Format;
|
||||
|
||||
D3D11_RENDER_TARGET_VIEW_DESC viewDesc = {};
|
||||
viewDesc.ViewDimension = backBufferDesc.ArraySize > 1 ? D3D11_RTV_DIMENSION_TEXTURE2DARRAY : D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
viewDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
||||
if (backBufferDesc.ArraySize > 1)
|
||||
{
|
||||
viewDesc.Texture2DArray.ArraySize = backBufferDesc.ArraySize;
|
||||
}
|
||||
|
||||
// Create a render target view of the back buffer.
|
||||
// Creating this resource is inexpensive, and is better than keeping track of
|
||||
// the back buffers in order to pre-allocate render target views for each one.
|
||||
m_d3dRenderTargetView = nullptr;
|
||||
winrt::check_hresult(device->CreateRenderTargetView(m_d3dBackBuffer.get(), &viewDesc, m_d3dRenderTargetView.put()));
|
||||
|
||||
// Check for render target size changes.
|
||||
winrt::Windows::Foundation::Size currentSize = m_holographicCamera.RenderTargetSize();
|
||||
if (m_d3dRenderTargetSize != currentSize)
|
||||
{
|
||||
// Set render target size.
|
||||
m_d3dRenderTargetSize = currentSize;
|
||||
|
||||
// A new depth stencil view is also needed.
|
||||
m_d3dDepthStencilView = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh depth stencil resources, if needed.
|
||||
if (m_d3dDepthStencilView == nullptr)
|
||||
{
|
||||
// Create a depth stencil view for use with 3D rendering if needed.
|
||||
CD3D11_TEXTURE2D_DESC depthStencilDesc(
|
||||
DXGI_FORMAT_D16_UNORM,
|
||||
static_cast<UINT>(m_d3dRenderTargetSize.Width),
|
||||
static_cast<UINT>(m_d3dRenderTargetSize.Height),
|
||||
m_isStereo ? 2 : 1, // Create two textures when rendering in stereo.
|
||||
1, // Use a single mipmap level.
|
||||
D3D11_BIND_DEPTH_STENCIL);
|
||||
|
||||
winrt::com_ptr<ID3D11Texture2D> depthStencil;
|
||||
winrt::check_hresult(device->CreateTexture2D(&depthStencilDesc, nullptr, depthStencil.put()));
|
||||
|
||||
CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(
|
||||
m_isStereo ? D3D11_DSV_DIMENSION_TEXTURE2DARRAY : D3D11_DSV_DIMENSION_TEXTURE2D);
|
||||
|
||||
winrt::check_hresult(device->CreateDepthStencilView(depthStencil.get(), &depthStencilViewDesc, m_d3dDepthStencilView.put()));
|
||||
}
|
||||
|
||||
// Create the constant buffer, if needed.
|
||||
if (m_viewProjectionConstantBuffer == nullptr)
|
||||
{
|
||||
// Create a constant buffer to store view and projection matrices for the camera.
|
||||
CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(device->CreateBuffer(&constantBufferDesc, nullptr, m_viewProjectionConstantBuffer.put()));
|
||||
}
|
||||
}
|
||||
|
||||
// Releases resources associated with a back buffer.
|
||||
void DXHelper::CameraResources::ReleaseResourcesForBackBuffer(DXHelper::DeviceResources* pDeviceResources)
|
||||
{
|
||||
// Release camera-specific resources.
|
||||
m_d3dBackBuffer = nullptr;
|
||||
m_d3dRenderTargetView = nullptr;
|
||||
m_d3dDepthStencilView = nullptr;
|
||||
m_viewProjectionConstantBuffer = nullptr;
|
||||
|
||||
// Ensure system references to the back buffer are released by clearing the render
|
||||
// target from the graphics pipeline state, and then flushing the Direct3D context.
|
||||
pDeviceResources->UseD3DDeviceContext([](auto context) {
|
||||
ID3D11RenderTargetView* nullViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {nullptr};
|
||||
context->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
|
||||
context->Flush();
|
||||
});
|
||||
}
|
||||
|
||||
// Updates the view/projection constant buffer for a holographic camera.
|
||||
void DXHelper::CameraResources::UpdateViewProjectionBuffer(
|
||||
std::shared_ptr<DXHelper::DeviceResources> deviceResources,
|
||||
const HolographicCameraPose& cameraPose,
|
||||
const SpatialCoordinateSystem& coordinateSystem)
|
||||
{
|
||||
// The system changes the viewport on a per-frame basis for system optimizations.
|
||||
m_d3dViewport =
|
||||
CD3D11_VIEWPORT(cameraPose.Viewport().X, cameraPose.Viewport().Y, cameraPose.Viewport().Width, cameraPose.Viewport().Height);
|
||||
|
||||
// The projection transform for each frame is provided by the HolographicCameraPose.
|
||||
auto cameraProjectionTransform = cameraPose.ProjectionTransform();
|
||||
|
||||
// Get a container object with the view and projection matrices for the given
|
||||
// pose in the given coordinate system.
|
||||
auto viewTransformContainer = cameraPose.TryGetViewTransform(coordinateSystem);
|
||||
|
||||
// If TryGetViewTransform returns a null pointer, that means the pose and coordinate
|
||||
// system cannot be understood relative to one another; content cannot be rendered
|
||||
// in this coordinate system for the duration of the current frame.
|
||||
// This usually means that positional tracking is not active for the current frame, in
|
||||
// which case it is possible to use a SpatialLocatorAttachedFrameOfReference to render
|
||||
// content that is not world-locked instead.
|
||||
DXHelper::ViewProjectionConstantBuffer viewProjectionConstantBufferData = {};
|
||||
bool viewTransformAcquired = viewTransformContainer != nullptr;
|
||||
if (viewTransformAcquired)
|
||||
{
|
||||
// Otherwise, the set of view transforms can be retrieved.
|
||||
auto viewCoordinateSystemTransform = viewTransformContainer.Value();
|
||||
|
||||
// Update the view matrices. Holographic cameras (such as Microsoft HoloLens) are
|
||||
// constantly moving relative to the world. The view matrices need to be updated
|
||||
// every frame.
|
||||
XMStoreFloat4x4(
|
||||
&viewProjectionConstantBufferData.viewProjection[0],
|
||||
XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Left) * XMLoadFloat4x4(&cameraProjectionTransform.Left)));
|
||||
XMStoreFloat4x4(
|
||||
&viewProjectionConstantBufferData.viewProjection[1],
|
||||
XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Right) * XMLoadFloat4x4(&cameraProjectionTransform.Right)));
|
||||
}
|
||||
|
||||
// Use the D3D device context to update Direct3D device-based resources.
|
||||
deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
// Loading is asynchronous. Resources must be created before they can be updated.
|
||||
if (context == nullptr || m_viewProjectionConstantBuffer == nullptr || !viewTransformAcquired)
|
||||
{
|
||||
m_framePending = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update the view and projection matrices.
|
||||
context->UpdateSubresource(m_viewProjectionConstantBuffer.get(), 0, nullptr, &viewProjectionConstantBufferData, 0, 0);
|
||||
|
||||
m_framePending = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Gets the view-projection constant buffer for the HolographicCamera and attaches it
|
||||
// to the shader pipeline.
|
||||
bool DXHelper::CameraResources::AttachViewProjectionBuffer(std::shared_ptr<DXHelper::DeviceResources> deviceResources)
|
||||
{
|
||||
// This method uses Direct3D device-based resources.
|
||||
return deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
// Loading is asynchronous. Resources must be created before they can be updated.
|
||||
// Cameras can also be added asynchronously, in which case they must be initialized
|
||||
// before they can be used.
|
||||
if (context == nullptr || m_viewProjectionConstantBuffer == nullptr || m_framePending == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the viewport for this camera.
|
||||
context->RSSetViewports(1, &m_d3dViewport);
|
||||
|
||||
// Send the constant buffer to the vertex shader.
|
||||
ID3D11Buffer* pBuffer = m_viewProjectionConstantBuffer.get();
|
||||
context->VSSetConstantBuffers(1, 1, &pBuffer);
|
||||
|
||||
// The template includes a pass-through geometry shader that is used by
|
||||
// default on systems that don't support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer extension. The shader
|
||||
// will be enabled at run-time on systems that require it.
|
||||
// If your app will also use the geometry shader for other tasks and those
|
||||
// tasks require the view/projection matrix, uncomment the following line
|
||||
// of code to send the constant buffer to the geometry shader as well.
|
||||
/*context->GSSetConstantBuffers(
|
||||
1,
|
||||
1,
|
||||
m_viewProjectionConstantBuffer.GetAddressOf()
|
||||
);*/
|
||||
|
||||
m_framePending = false;
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.645
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HolographicHostSample", "HolographicHostSample.vcxproj", "{59F48F16-7CF3-36AB-AE6D-B56A9DA89747}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
RelWithDebInfo|x64 = RelWithDebInfo|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{59F48F16-7CF3-36AB-AE6D-B56A9DA89747}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{59F48F16-7CF3-36AB-AE6D-B56A9DA89747}.Debug|x64.Build.0 = Debug|x64
|
||||
{59F48F16-7CF3-36AB-AE6D-B56A9DA89747}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{59F48F16-7CF3-36AB-AE6D-B56A9DA89747}.Release|x64.ActiveCfg = Release|x64
|
||||
{59F48F16-7CF3-36AB-AE6D-B56A9DA89747}.Release|x64.Build.0 = Release|x64
|
||||
{59F48F16-7CF3-36AB-AE6D-B56A9DA89747}.Release|x64.Deploy.0 = Release|x64
|
||||
{59F48F16-7CF3-36AB-AE6D-B56A9DA89747}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
|
||||
{59F48F16-7CF3-36AB-AE6D-B56A9DA89747}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
|
||||
{59F48F16-7CF3-36AB-AE6D-B56A9DA89747}.RelWithDebInfo|x64.Deploy.0 = RelWithDebInfo|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E8A3A1EC-E636-40D6-9E3D-C22347CC8162}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp rescap">
|
||||
<Identity Name="b0cf2e39-8f6e-4238-b33a-868c9b1122ce" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="2.0.14.0" />
|
||||
<mp:PhoneIdentity PhoneProductId="b0cf2e39-8f6e-4238-b33a-868c9b1122ce" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Properties>
|
||||
<DisplayName>RemotingHostSample</DisplayName>
|
||||
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="SampleHostWindowUWPView">
|
||||
<uap:VisualElements DisplayName="RemotingHostSampleUWP" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="RemotingHostSampleUWP" BackgroundColor="transparent">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
|
||||
</uap:DefaultTile>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
<Capability Name="internetClientServer" />
|
||||
<Capability Name="privateNetworkClientServer" />
|
||||
<rescap:Capability Name="perceptionMonitoring" />
|
||||
<DeviceCapability Name="microphone" />
|
||||
</Capabilities>
|
||||
</Package>
|
|
@ -1,242 +0,0 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "SampleHostWindowWin32.h"
|
||||
|
||||
#include <HolographicAppRemoting\Streamer.h>
|
||||
|
||||
#include "Common\DbgLog.h"
|
||||
#include <DirectXColors.h>
|
||||
|
||||
#include <windows.graphics.directx.direct3d11.interop.h>
|
||||
|
||||
#define WINDOWCLASSNAME L"SampleHostWindowWin32Class"
|
||||
|
||||
LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static SampleHostWindowWin32* s_sampleHostWindow;
|
||||
|
||||
LRESULT result = 0;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CREATE: {
|
||||
CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lParam);
|
||||
s_sampleHostWindow = reinterpret_cast<SampleHostWindowWin32*>(cs->lpCreateParams);
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect(hWnd, &clientRect);
|
||||
|
||||
s_sampleHostWindow->OnResize(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
|
||||
result = 0;
|
||||
}
|
||||
break;
|
||||
case WM_WINDOWPOSCHANGED: {
|
||||
auto windowPos = reinterpret_cast<WINDOWPOS*>(lParam);
|
||||
if ((windowPos->flags & SWP_NOSIZE) == 0)
|
||||
{
|
||||
RECT clientRect;
|
||||
GetClientRect(hWnd, &clientRect);
|
||||
|
||||
s_sampleHostWindow->OnResize(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
|
||||
}
|
||||
result = 0;
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY: {
|
||||
s_sampleHostWindow = nullptr;
|
||||
result = 0;
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
break;
|
||||
case WM_CLOSE: {
|
||||
DestroyWindow(hWnd);
|
||||
result = 0;
|
||||
}
|
||||
break;
|
||||
case WM_CHAR: {
|
||||
const int key = tolower(static_cast<int>(wParam));
|
||||
s_sampleHostWindow->OnKeyPress(static_cast<char>(key));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SampleHostWindowWin32::Initialize(bool listen, const std::wstring& hostname, uint32_t port)
|
||||
{
|
||||
m_main = std::make_shared<SampleHostMain>(weak_from_this());
|
||||
m_main->SetHostOptions(listen, hostname, port);
|
||||
}
|
||||
|
||||
void SampleHostWindowWin32::InitializeHwnd(HWND hWnd)
|
||||
{
|
||||
m_hWnd = hWnd;
|
||||
}
|
||||
|
||||
void SampleHostWindowWin32::Tick()
|
||||
{
|
||||
if (const HolographicFrame& holographicFrame = m_main->Update())
|
||||
{
|
||||
m_main->Render(holographicFrame);
|
||||
}
|
||||
}
|
||||
|
||||
void SampleHostWindowWin32::OnKeyPress(char key)
|
||||
{
|
||||
m_main->OnKeyPress(key);
|
||||
}
|
||||
|
||||
|
||||
void SampleHostWindowWin32::OnResize(int width, int height)
|
||||
{
|
||||
m_main->OnResize(width, height);
|
||||
}
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain1>
|
||||
SampleHostWindowWin32::CreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device, const DXGI_SWAP_CHAIN_DESC1* desc)
|
||||
{
|
||||
winrt::com_ptr<IDXGIDevice1> dxgiDevice;
|
||||
device.as(dxgiDevice);
|
||||
|
||||
winrt::com_ptr<IDXGIAdapter> dxgiAdapter;
|
||||
winrt::check_hresult(dxgiDevice->GetAdapter(dxgiAdapter.put()));
|
||||
|
||||
winrt::com_ptr<IDXGIFactory2> dxgiFactory;
|
||||
winrt::check_hresult(dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), dxgiFactory.put_void()));
|
||||
|
||||
winrt::check_hresult(dxgiFactory->MakeWindowAssociation(m_hWnd, DXGI_MWA_NO_ALT_ENTER));
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain1> swapChain = nullptr;
|
||||
winrt::check_hresult(dxgiFactory->CreateSwapChainForHwnd(device.get(), m_hWnd, desc, nullptr, nullptr, swapChain.put()));
|
||||
|
||||
return swapChain;
|
||||
}
|
||||
|
||||
void SampleHostWindowWin32::SetWindowTitle(std::wstring title)
|
||||
{
|
||||
if (m_hWnd)
|
||||
{
|
||||
if (!SetWindowTextW(m_hWnd, title.c_str()))
|
||||
{
|
||||
winrt::check_hresult(HRESULT_FROM_WIN32(GetLastError()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(Platform::Array<Platform::String ^> ^ args)
|
||||
{
|
||||
winrt::init_apartment();
|
||||
|
||||
bool listen{false};
|
||||
std::wstring host;
|
||||
uint32_t port{0};
|
||||
|
||||
for (unsigned int i = 1; i < args->Length; ++i)
|
||||
{
|
||||
if (args[i]->Length() == 0)
|
||||
continue;
|
||||
|
||||
std::wstring arg = args[i]->Data();
|
||||
if (arg[0] == '-')
|
||||
{
|
||||
std::wstring param = arg.substr(1);
|
||||
std::transform(param.begin(), param.end(), param.begin(), ::tolower);
|
||||
|
||||
if (param == L"listen")
|
||||
{
|
||||
listen = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t colonPos = arg.find(L':');
|
||||
if (colonPos != std::wstring::npos)
|
||||
{
|
||||
std::wstring portStr = arg.substr(colonPos + 1);
|
||||
|
||||
host = arg.substr(0, colonPos);
|
||||
port = std::wcstol(portStr.c_str(), nullptr, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
host = arg.c_str();
|
||||
port = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<SampleHostWindowWin32> sampleHostWindow = std::make_shared<SampleHostWindowWin32>();
|
||||
sampleHostWindow->Initialize(listen, host, port);
|
||||
|
||||
WNDCLASSEXW wcex = {};
|
||||
wcex.cbSize = sizeof(wcex);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = wndProc;
|
||||
wcex.hInstance = 0;
|
||||
wcex.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wcex.hbrBackground = static_cast<HBRUSH>(GetStockObject(NULL_BRUSH));
|
||||
wcex.lpszClassName = WINDOWCLASSNAME;
|
||||
RegisterClassExW(&wcex);
|
||||
|
||||
RECT rc = {0, 0, INITIAL_WINDOW_WIDTH, INITIAL_WINDOW_HEIGHT};
|
||||
AdjustWindowRectEx(&rc, WS_OVERLAPPEDWINDOW, FALSE, 0);
|
||||
|
||||
std::wstring windowName = TITLE_TEXT;
|
||||
|
||||
HWND hWnd = CreateWindowW(
|
||||
WINDOWCLASSNAME,
|
||||
windowName.c_str(),
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
rc.right - rc.left,
|
||||
rc.bottom - rc.top,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0,
|
||||
sampleHostWindow.get());
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect(hWnd, &clientRect);
|
||||
|
||||
sampleHostWindow->InitializeHwnd(hWnd);
|
||||
|
||||
ShowWindow(hWnd, SW_SHOWNORMAL);
|
||||
bool quit = false;
|
||||
while (!quit)
|
||||
{
|
||||
MSG msg = {0};
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.message == WM_QUIT)
|
||||
{
|
||||
quit = true;
|
||||
}
|
||||
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
sampleHostWindow->Tick();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Holographic.Remoting" version="2.0.14" targetFramework="native" />
|
||||
</packages>
|
Двоичные данные
hostsampleapp/uwp/Assets/LockScreenLogo.scale-200.png
До Ширина: | Высота: | Размер: 1.4 KiB |
Двоичные данные
hostsampleapp/uwp/Assets/SplashScreen.scale-200.png
До Ширина: | Высота: | Размер: 7.5 KiB |
Двоичные данные
hostsampleapp/uwp/Assets/Square150x150Logo.scale-200.png
До Ширина: | Высота: | Размер: 2.9 KiB |
Двоичные данные
hostsampleapp/uwp/Assets/Square44x44Logo.scale-200.png
До Ширина: | Высота: | Размер: 1.6 KiB |
До Ширина: | Высота: | Размер: 1.2 KiB |
Двоичные данные
hostsampleapp/uwp/Assets/StoreLogo.png
До Ширина: | Высота: | Размер: 1.4 KiB |
Двоичные данные
hostsampleapp/uwp/Assets/Wide310x150Logo.scale-200.png
До Ширина: | Высота: | Размер: 3.1 KiB |
|
@ -1,251 +0,0 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "CameraResources.h"
|
||||
#include "DeviceResources.h"
|
||||
#include "DirectXHelper.h"
|
||||
|
||||
#include <windows.graphics.directx.direct3d11.interop.h>
|
||||
|
||||
using namespace DirectX;
|
||||
using namespace winrt::Windows::Graphics::Holographic;
|
||||
using namespace winrt::Windows::Perception::Spatial;
|
||||
|
||||
DXHelper::CameraResources::CameraResources(const HolographicCamera& camera)
|
||||
: m_holographicCamera(camera)
|
||||
, m_isStereo(camera.IsStereo())
|
||||
, m_d3dRenderTargetSize(camera.RenderTargetSize())
|
||||
{
|
||||
m_d3dViewport = CD3D11_VIEWPORT(0.f, 0.f, m_d3dRenderTargetSize.Width, m_d3dRenderTargetSize.Height);
|
||||
};
|
||||
|
||||
// Updates resources associated with a holographic camera's swap chain.
|
||||
// The app does not access the swap chain directly, but it does create
|
||||
// resource views for the back buffer.
|
||||
void DXHelper::CameraResources::CreateResourcesForBackBuffer(
|
||||
DXHelper::DeviceResources* pDeviceResources, const HolographicCameraRenderingParameters& cameraParameters)
|
||||
{
|
||||
const auto device = pDeviceResources->GetD3DDevice();
|
||||
|
||||
// Get a DXGI interface for the holographic camera's back buffer.
|
||||
// Holographic cameras do not provide the DXGI swap chain, which is owned
|
||||
// by the system. The Direct3D back buffer resource is provided using WinRT
|
||||
// interop APIs.
|
||||
winrt::com_ptr<ID3D11Resource> resource;
|
||||
{
|
||||
winrt::com_ptr<::IInspectable> inspectable = cameraParameters.Direct3D11BackBuffer().as<::IInspectable>();
|
||||
winrt::com_ptr<Windows::Graphics::DirectX::Direct3D11::IDirect3DDxgiInterfaceAccess> dxgiInterfaceAccess;
|
||||
|
||||
HRESULT hr = inspectable->QueryInterface(__uuidof(dxgiInterfaceAccess), dxgiInterfaceAccess.put_void());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
winrt::throw_hresult(hr);
|
||||
}
|
||||
|
||||
hr = dxgiInterfaceAccess->GetInterface(__uuidof(resource), resource.put_void());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
winrt::throw_hresult(hr);
|
||||
}
|
||||
}
|
||||
|
||||
// Get a Direct3D interface for the holographic camera's back buffer.
|
||||
winrt::com_ptr<ID3D11Texture2D> cameraBackBuffer;
|
||||
resource.as(cameraBackBuffer);
|
||||
|
||||
// Determine if the back buffer has changed. If so, ensure that the render target view
|
||||
// is for the current back buffer.
|
||||
if (m_d3dBackBuffer != cameraBackBuffer)
|
||||
{
|
||||
// This can change every frame as the system moves to the next buffer in the
|
||||
// swap chain. This mode of operation will occur when certain rendering modes
|
||||
// are activated.
|
||||
m_d3dBackBuffer = cameraBackBuffer;
|
||||
|
||||
// Get the DXGI format for the back buffer.
|
||||
// This information can be accessed by the app using CameraResources::GetBackBufferDXGIFormat().
|
||||
D3D11_TEXTURE2D_DESC backBufferDesc;
|
||||
m_d3dBackBuffer->GetDesc(&backBufferDesc);
|
||||
m_dxgiFormat = backBufferDesc.Format;
|
||||
|
||||
D3D11_RENDER_TARGET_VIEW_DESC viewDesc = {};
|
||||
viewDesc.ViewDimension = backBufferDesc.ArraySize > 1 ? D3D11_RTV_DIMENSION_TEXTURE2DARRAY : D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
viewDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
||||
if (backBufferDesc.ArraySize > 1)
|
||||
{
|
||||
viewDesc.Texture2DArray.ArraySize = backBufferDesc.ArraySize;
|
||||
}
|
||||
|
||||
// Create a render target view of the back buffer.
|
||||
// Creating this resource is inexpensive, and is better than keeping track of
|
||||
// the back buffers in order to pre-allocate render target views for each one.
|
||||
m_d3dRenderTargetView = nullptr;
|
||||
winrt::check_hresult(device->CreateRenderTargetView(m_d3dBackBuffer.get(), &viewDesc, m_d3dRenderTargetView.put()));
|
||||
|
||||
// Check for render target size changes.
|
||||
winrt::Windows::Foundation::Size currentSize = m_holographicCamera.RenderTargetSize();
|
||||
if (m_d3dRenderTargetSize != currentSize)
|
||||
{
|
||||
// Set render target size.
|
||||
m_d3dRenderTargetSize = currentSize;
|
||||
|
||||
// A new depth stencil view is also needed.
|
||||
m_d3dDepthStencilView = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh depth stencil resources, if needed.
|
||||
if (m_d3dDepthStencilView == nullptr)
|
||||
{
|
||||
// Create a depth stencil view for use with 3D rendering if needed.
|
||||
CD3D11_TEXTURE2D_DESC depthStencilDesc(
|
||||
DXGI_FORMAT_D16_UNORM,
|
||||
static_cast<UINT>(m_d3dRenderTargetSize.Width),
|
||||
static_cast<UINT>(m_d3dRenderTargetSize.Height),
|
||||
m_isStereo ? 2 : 1, // Create two textures when rendering in stereo.
|
||||
1, // Use a single mipmap level.
|
||||
D3D11_BIND_DEPTH_STENCIL);
|
||||
|
||||
winrt::com_ptr<ID3D11Texture2D> depthStencil;
|
||||
winrt::check_hresult(device->CreateTexture2D(&depthStencilDesc, nullptr, depthStencil.put()));
|
||||
|
||||
CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(
|
||||
m_isStereo ? D3D11_DSV_DIMENSION_TEXTURE2DARRAY : D3D11_DSV_DIMENSION_TEXTURE2D);
|
||||
|
||||
winrt::check_hresult(device->CreateDepthStencilView(depthStencil.get(), &depthStencilViewDesc, m_d3dDepthStencilView.put()));
|
||||
}
|
||||
|
||||
// Create the constant buffer, if needed.
|
||||
if (m_viewProjectionConstantBuffer == nullptr)
|
||||
{
|
||||
// Create a constant buffer to store view and projection matrices for the camera.
|
||||
CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(device->CreateBuffer(&constantBufferDesc, nullptr, m_viewProjectionConstantBuffer.put()));
|
||||
}
|
||||
}
|
||||
|
||||
// Releases resources associated with a back buffer.
|
||||
void DXHelper::CameraResources::ReleaseResourcesForBackBuffer(DXHelper::DeviceResources* pDeviceResources)
|
||||
{
|
||||
// Release camera-specific resources.
|
||||
m_d3dBackBuffer = nullptr;
|
||||
m_d3dRenderTargetView = nullptr;
|
||||
m_d3dDepthStencilView = nullptr;
|
||||
m_viewProjectionConstantBuffer = nullptr;
|
||||
|
||||
// Ensure system references to the back buffer are released by clearing the render
|
||||
// target from the graphics pipeline state, and then flushing the Direct3D context.
|
||||
pDeviceResources->UseD3DDeviceContext([](auto context) {
|
||||
ID3D11RenderTargetView* nullViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {nullptr};
|
||||
context->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
|
||||
context->Flush();
|
||||
});
|
||||
}
|
||||
|
||||
// Updates the view/projection constant buffer for a holographic camera.
|
||||
void DXHelper::CameraResources::UpdateViewProjectionBuffer(
|
||||
std::shared_ptr<DXHelper::DeviceResources> deviceResources,
|
||||
const HolographicCameraPose& cameraPose,
|
||||
const SpatialCoordinateSystem& coordinateSystem)
|
||||
{
|
||||
// The system changes the viewport on a per-frame basis for system optimizations.
|
||||
m_d3dViewport =
|
||||
CD3D11_VIEWPORT(cameraPose.Viewport().X, cameraPose.Viewport().Y, cameraPose.Viewport().Width, cameraPose.Viewport().Height);
|
||||
|
||||
// The projection transform for each frame is provided by the HolographicCameraPose.
|
||||
auto cameraProjectionTransform = cameraPose.ProjectionTransform();
|
||||
|
||||
// Get a container object with the view and projection matrices for the given
|
||||
// pose in the given coordinate system.
|
||||
auto viewTransformContainer = cameraPose.TryGetViewTransform(coordinateSystem);
|
||||
|
||||
// If TryGetViewTransform returns a null pointer, that means the pose and coordinate
|
||||
// system cannot be understood relative to one another; content cannot be rendered
|
||||
// in this coordinate system for the duration of the current frame.
|
||||
// This usually means that positional tracking is not active for the current frame, in
|
||||
// which case it is possible to use a SpatialLocatorAttachedFrameOfReference to render
|
||||
// content that is not world-locked instead.
|
||||
DXHelper::ViewProjectionConstantBuffer viewProjectionConstantBufferData = {};
|
||||
bool viewTransformAcquired = viewTransformContainer != nullptr;
|
||||
if (viewTransformAcquired)
|
||||
{
|
||||
// Otherwise, the set of view transforms can be retrieved.
|
||||
auto viewCoordinateSystemTransform = viewTransformContainer.Value();
|
||||
|
||||
// Update the view matrices. Holographic cameras (such as Microsoft HoloLens) are
|
||||
// constantly moving relative to the world. The view matrices need to be updated
|
||||
// every frame.
|
||||
XMStoreFloat4x4(
|
||||
&viewProjectionConstantBufferData.viewProjection[0],
|
||||
XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Left) * XMLoadFloat4x4(&cameraProjectionTransform.Left)));
|
||||
XMStoreFloat4x4(
|
||||
&viewProjectionConstantBufferData.viewProjection[1],
|
||||
XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Right) * XMLoadFloat4x4(&cameraProjectionTransform.Right)));
|
||||
}
|
||||
|
||||
// Use the D3D device context to update Direct3D device-based resources.
|
||||
deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
// Loading is asynchronous. Resources must be created before they can be updated.
|
||||
if (context == nullptr || m_viewProjectionConstantBuffer == nullptr || !viewTransformAcquired)
|
||||
{
|
||||
m_framePending = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update the view and projection matrices.
|
||||
context->UpdateSubresource(m_viewProjectionConstantBuffer.get(), 0, nullptr, &viewProjectionConstantBufferData, 0, 0);
|
||||
|
||||
m_framePending = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Gets the view-projection constant buffer for the HolographicCamera and attaches it
|
||||
// to the shader pipeline.
|
||||
bool DXHelper::CameraResources::AttachViewProjectionBuffer(std::shared_ptr<DXHelper::DeviceResources> deviceResources)
|
||||
{
|
||||
// This method uses Direct3D device-based resources.
|
||||
return deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
// Loading is asynchronous. Resources must be created before they can be updated.
|
||||
// Cameras can also be added asynchronously, in which case they must be initialized
|
||||
// before they can be used.
|
||||
if (context == nullptr || m_viewProjectionConstantBuffer == nullptr || m_framePending == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the viewport for this camera.
|
||||
context->RSSetViewports(1, &m_d3dViewport);
|
||||
|
||||
// Send the constant buffer to the vertex shader.
|
||||
ID3D11Buffer* pBuffer = m_viewProjectionConstantBuffer.get();
|
||||
context->VSSetConstantBuffers(1, 1, &pBuffer);
|
||||
|
||||
// The template includes a pass-through geometry shader that is used by
|
||||
// default on systems that don't support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer extension. The shader
|
||||
// will be enabled at run-time on systems that require it.
|
||||
// If your app will also use the geometry shader for other tasks and those
|
||||
// tasks require the view/projection matrix, uncomment the following line
|
||||
// of code to send the constant buffer to the geometry shader as well.
|
||||
/*context->GSSetConstantBuffers(
|
||||
1,
|
||||
1,
|
||||
m_viewProjectionConstantBuffer.GetAddressOf()
|
||||
);*/
|
||||
|
||||
m_framePending = false;
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.645
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HolographicHostSample", "HolographicHostSample.vcxproj", "{8933B2A2-C780-3CC9-8B26-0CCB3E806E54}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
RelWithDebInfo|x64 = RelWithDebInfo|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8933B2A2-C780-3CC9-8B26-0CCB3E806E54}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8933B2A2-C780-3CC9-8B26-0CCB3E806E54}.Debug|x64.Build.0 = Debug|x64
|
||||
{8933B2A2-C780-3CC9-8B26-0CCB3E806E54}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{8933B2A2-C780-3CC9-8B26-0CCB3E806E54}.Release|x64.ActiveCfg = Release|x64
|
||||
{8933B2A2-C780-3CC9-8B26-0CCB3E806E54}.Release|x64.Build.0 = Release|x64
|
||||
{8933B2A2-C780-3CC9-8B26-0CCB3E806E54}.Release|x64.Deploy.0 = Release|x64
|
||||
{8933B2A2-C780-3CC9-8B26-0CCB3E806E54}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
|
||||
{8933B2A2-C780-3CC9-8B26-0CCB3E806E54}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
|
||||
{8933B2A2-C780-3CC9-8B26-0CCB3E806E54}.RelWithDebInfo|x64.Deploy.0 = RelWithDebInfo|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E8A3A1EC-E636-40D6-9E3D-C22347CC8162}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp rescap">
|
||||
<Identity Name="b0cf2e39-8f6e-4238-b33a-868c9b1122ce" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="2.0.14.0" />
|
||||
<mp:PhoneIdentity PhoneProductId="b0cf2e39-8f6e-4238-b33a-868c9b1122ce" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Properties>
|
||||
<DisplayName>RemotingHostSample</DisplayName>
|
||||
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="SampleHostWindowUWPView">
|
||||
<uap:VisualElements DisplayName="RemotingHostSampleUWP" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="RemotingHostSampleUWP" BackgroundColor="transparent">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
|
||||
</uap:DefaultTile>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
<Capability Name="internetClientServer" />
|
||||
<Capability Name="privateNetworkClientServer" />
|
||||
<rescap:Capability Name="perceptionMonitoring" />
|
||||
<DeviceCapability Name="microphone" />
|
||||
</Capabilities>
|
||||
</Package>
|
|
@ -1,242 +0,0 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "SampleHostWindowWin32.h"
|
||||
|
||||
#include <HolographicAppRemoting\Streamer.h>
|
||||
|
||||
#include "Common\DbgLog.h"
|
||||
#include <DirectXColors.h>
|
||||
|
||||
#include <windows.graphics.directx.direct3d11.interop.h>
|
||||
|
||||
#define WINDOWCLASSNAME L"SampleHostWindowWin32Class"
|
||||
|
||||
LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static SampleHostWindowWin32* s_sampleHostWindow;
|
||||
|
||||
LRESULT result = 0;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CREATE: {
|
||||
CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lParam);
|
||||
s_sampleHostWindow = reinterpret_cast<SampleHostWindowWin32*>(cs->lpCreateParams);
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect(hWnd, &clientRect);
|
||||
|
||||
s_sampleHostWindow->OnResize(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
|
||||
result = 0;
|
||||
}
|
||||
break;
|
||||
case WM_WINDOWPOSCHANGED: {
|
||||
auto windowPos = reinterpret_cast<WINDOWPOS*>(lParam);
|
||||
if ((windowPos->flags & SWP_NOSIZE) == 0)
|
||||
{
|
||||
RECT clientRect;
|
||||
GetClientRect(hWnd, &clientRect);
|
||||
|
||||
s_sampleHostWindow->OnResize(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
|
||||
}
|
||||
result = 0;
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY: {
|
||||
s_sampleHostWindow = nullptr;
|
||||
result = 0;
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
break;
|
||||
case WM_CLOSE: {
|
||||
DestroyWindow(hWnd);
|
||||
result = 0;
|
||||
}
|
||||
break;
|
||||
case WM_CHAR: {
|
||||
const int key = tolower(static_cast<int>(wParam));
|
||||
s_sampleHostWindow->OnKeyPress(static_cast<char>(key));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SampleHostWindowWin32::Initialize(bool listen, const std::wstring& hostname, uint32_t port)
|
||||
{
|
||||
m_main = std::make_shared<SampleHostMain>(weak_from_this());
|
||||
m_main->SetHostOptions(listen, hostname, port);
|
||||
}
|
||||
|
||||
void SampleHostWindowWin32::InitializeHwnd(HWND hWnd)
|
||||
{
|
||||
m_hWnd = hWnd;
|
||||
}
|
||||
|
||||
void SampleHostWindowWin32::Tick()
|
||||
{
|
||||
if (const HolographicFrame& holographicFrame = m_main->Update())
|
||||
{
|
||||
m_main->Render(holographicFrame);
|
||||
}
|
||||
}
|
||||
|
||||
void SampleHostWindowWin32::OnKeyPress(char key)
|
||||
{
|
||||
m_main->OnKeyPress(key);
|
||||
}
|
||||
|
||||
|
||||
void SampleHostWindowWin32::OnResize(int width, int height)
|
||||
{
|
||||
m_main->OnResize(width, height);
|
||||
}
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain1>
|
||||
SampleHostWindowWin32::CreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device, const DXGI_SWAP_CHAIN_DESC1* desc)
|
||||
{
|
||||
winrt::com_ptr<IDXGIDevice1> dxgiDevice;
|
||||
device.as(dxgiDevice);
|
||||
|
||||
winrt::com_ptr<IDXGIAdapter> dxgiAdapter;
|
||||
winrt::check_hresult(dxgiDevice->GetAdapter(dxgiAdapter.put()));
|
||||
|
||||
winrt::com_ptr<IDXGIFactory2> dxgiFactory;
|
||||
winrt::check_hresult(dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), dxgiFactory.put_void()));
|
||||
|
||||
winrt::check_hresult(dxgiFactory->MakeWindowAssociation(m_hWnd, DXGI_MWA_NO_ALT_ENTER));
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain1> swapChain = nullptr;
|
||||
winrt::check_hresult(dxgiFactory->CreateSwapChainForHwnd(device.get(), m_hWnd, desc, nullptr, nullptr, swapChain.put()));
|
||||
|
||||
return swapChain;
|
||||
}
|
||||
|
||||
void SampleHostWindowWin32::SetWindowTitle(std::wstring title)
|
||||
{
|
||||
if (m_hWnd)
|
||||
{
|
||||
if (!SetWindowTextW(m_hWnd, title.c_str()))
|
||||
{
|
||||
winrt::check_hresult(HRESULT_FROM_WIN32(GetLastError()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(Platform::Array<Platform::String ^> ^ args)
|
||||
{
|
||||
winrt::init_apartment();
|
||||
|
||||
bool listen{false};
|
||||
std::wstring host;
|
||||
uint32_t port{0};
|
||||
|
||||
for (unsigned int i = 1; i < args->Length; ++i)
|
||||
{
|
||||
if (args[i]->Length() == 0)
|
||||
continue;
|
||||
|
||||
std::wstring arg = args[i]->Data();
|
||||
if (arg[0] == '-')
|
||||
{
|
||||
std::wstring param = arg.substr(1);
|
||||
std::transform(param.begin(), param.end(), param.begin(), ::tolower);
|
||||
|
||||
if (param == L"listen")
|
||||
{
|
||||
listen = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t colonPos = arg.find(L':');
|
||||
if (colonPos != std::wstring::npos)
|
||||
{
|
||||
std::wstring portStr = arg.substr(colonPos + 1);
|
||||
|
||||
host = arg.substr(0, colonPos);
|
||||
port = std::wcstol(portStr.c_str(), nullptr, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
host = arg.c_str();
|
||||
port = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<SampleHostWindowWin32> sampleHostWindow = std::make_shared<SampleHostWindowWin32>();
|
||||
sampleHostWindow->Initialize(listen, host, port);
|
||||
|
||||
WNDCLASSEXW wcex = {};
|
||||
wcex.cbSize = sizeof(wcex);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = wndProc;
|
||||
wcex.hInstance = 0;
|
||||
wcex.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wcex.hbrBackground = static_cast<HBRUSH>(GetStockObject(NULL_BRUSH));
|
||||
wcex.lpszClassName = WINDOWCLASSNAME;
|
||||
RegisterClassExW(&wcex);
|
||||
|
||||
RECT rc = {0, 0, INITIAL_WINDOW_WIDTH, INITIAL_WINDOW_HEIGHT};
|
||||
AdjustWindowRectEx(&rc, WS_OVERLAPPEDWINDOW, FALSE, 0);
|
||||
|
||||
std::wstring windowName = TITLE_TEXT;
|
||||
|
||||
HWND hWnd = CreateWindowW(
|
||||
WINDOWCLASSNAME,
|
||||
windowName.c_str(),
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
rc.right - rc.left,
|
||||
rc.bottom - rc.top,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0,
|
||||
sampleHostWindow.get());
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect(hWnd, &clientRect);
|
||||
|
||||
sampleHostWindow->InitializeHwnd(hWnd);
|
||||
|
||||
ShowWindow(hWnd, SW_SHOWNORMAL);
|
||||
bool quit = false;
|
||||
while (!quit)
|
||||
{
|
||||
MSG msg = {0};
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.message == WM_QUIT)
|
||||
{
|
||||
quit = true;
|
||||
}
|
||||
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
sampleHostWindow->Tick();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Holographic.Remoting" version="2.0.14" targetFramework="native" />
|
||||
</packages>
|
|
@ -12,7 +12,7 @@
|
|||
#include "pch.h"
|
||||
|
||||
#include "CameraResources.h"
|
||||
#include "DeviceResources.h"
|
||||
#include "DeviceResourcesUWP.h"
|
||||
|
||||
using namespace DirectX;
|
||||
using namespace winrt::Windows::Foundation::Numerics;
|
||||
|
@ -35,7 +35,7 @@ namespace DXHelper
|
|||
// The app does not access the swap chain directly, but it does create
|
||||
// resource views for the back buffer.
|
||||
void CameraResources::CreateResourcesForBackBuffer(
|
||||
DeviceResources* pDeviceResources, HolographicCameraRenderingParameters const& cameraParameters)
|
||||
DeviceResourcesUWP* pDeviceResources, HolographicCameraRenderingParameters const& cameraParameters)
|
||||
{
|
||||
ID3D11Device* device = pDeviceResources->GetD3DDevice();
|
||||
|
||||
|
@ -105,6 +105,10 @@ namespace DXHelper
|
|||
1, // Use a single mipmap level.
|
||||
D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE);
|
||||
|
||||
// Allow sharing by default for easier interop with future D3D12 components for processing the remote or local frame.
|
||||
// This is optional, but without the flag any D3D12 components need to perform an additional copy.
|
||||
depthStencilDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
|
||||
|
||||
m_d3dDepthStencil = nullptr;
|
||||
winrt::check_hresult(device->CreateTexture2D(&depthStencilDesc, nullptr, m_d3dDepthStencil.put()));
|
||||
|
||||
|
@ -119,12 +123,14 @@ namespace DXHelper
|
|||
{
|
||||
// Create a constant buffer to store view and projection matrices for the camera.
|
||||
CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
|
||||
constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
winrt::check_hresult(device->CreateBuffer(&constantBufferDesc, nullptr, m_viewProjectionConstantBuffer.put()));
|
||||
}
|
||||
}
|
||||
|
||||
// Releases resources associated with a back buffer.
|
||||
void CameraResources::ReleaseResourcesForBackBuffer(DeviceResources* pDeviceResources)
|
||||
void CameraResources::ReleaseResourcesForBackBuffer(DeviceResourcesUWP* pDeviceResources)
|
||||
{
|
||||
// Release camera-specific resources.
|
||||
m_d3dBackBuffer = nullptr;
|
||||
|
@ -144,7 +150,7 @@ namespace DXHelper
|
|||
|
||||
// Updates the view/projection constant buffer for a holographic camera.
|
||||
void CameraResources::UpdateViewProjectionBuffer(
|
||||
std::shared_ptr<DeviceResources> deviceResources,
|
||||
std::shared_ptr<DeviceResourcesUWP> deviceResources,
|
||||
HolographicCameraPose const& cameraPose,
|
||||
SpatialCoordinateSystem const& coordinateSystem)
|
||||
{
|
||||
|
@ -153,7 +159,7 @@ namespace DXHelper
|
|||
m_d3dViewport = CD3D11_VIEWPORT(viewport.X, viewport.Y, viewport.Width, viewport.Height);
|
||||
|
||||
// The projection transform for each frame is provided by the HolographicCameraPose.
|
||||
HolographicStereoTransform cameraProjectionTransform = cameraPose.ProjectionTransform();
|
||||
m_cameraProjectionTransform = cameraPose.ProjectionTransform();
|
||||
|
||||
// Get a container object with the view and projection matrices for the given
|
||||
// pose in the given coordinate system.
|
||||
|
@ -166,6 +172,7 @@ namespace DXHelper
|
|||
// which case it is possible to use a SpatialLocatorAttachedFrameOfReference to render
|
||||
// content that is not world-locked instead.
|
||||
ViewProjectionConstantBuffer viewProjectionConstantBufferData;
|
||||
|
||||
bool viewTransformAcquired = viewTransformContainer != nullptr;
|
||||
if (viewTransformAcquired)
|
||||
{
|
||||
|
@ -175,12 +182,14 @@ namespace DXHelper
|
|||
// Update the view matrices. Holographic cameras (such as Microsoft HoloLens) are
|
||||
// constantly moving relative to the world. The view matrices need to be updated
|
||||
// every frame.
|
||||
|
||||
XMStoreFloat4x4(
|
||||
&viewProjectionConstantBufferData.viewProjection[0],
|
||||
XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Left) * XMLoadFloat4x4(&cameraProjectionTransform.Left)));
|
||||
XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Left) * XMLoadFloat4x4(&m_cameraProjectionTransform.Left)));
|
||||
XMStoreFloat4x4(
|
||||
&viewProjectionConstantBufferData.viewProjection[1],
|
||||
XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Right) * XMLoadFloat4x4(&cameraProjectionTransform.Right)));
|
||||
XMMatrixTranspose(
|
||||
XMLoadFloat4x4(&viewCoordinateSystemTransform.Right) * XMLoadFloat4x4(&m_cameraProjectionTransform.Right)));
|
||||
}
|
||||
|
||||
// Use the D3D device context to update Direct3D device-based resources.
|
||||
|
@ -193,7 +202,10 @@ namespace DXHelper
|
|||
else
|
||||
{
|
||||
// Update the view and projection matrices.
|
||||
context->UpdateSubresource(m_viewProjectionConstantBuffer.get(), 0, nullptr, &viewProjectionConstantBufferData, 0, 0);
|
||||
D3D11_MAPPED_SUBRESOURCE resource;
|
||||
context->Map(m_viewProjectionConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
|
||||
memcpy(resource.pData, &viewProjectionConstantBufferData, sizeof(viewProjectionConstantBufferData));
|
||||
context->Unmap(m_viewProjectionConstantBuffer.get(), 0);
|
||||
|
||||
m_framePending = true;
|
||||
}
|
||||
|
@ -202,7 +214,7 @@ namespace DXHelper
|
|||
|
||||
// Gets the view-projection constant buffer for the HolographicCamera and attaches it
|
||||
// to the shader pipeline.
|
||||
bool CameraResources::AttachViewProjectionBuffer(std::shared_ptr<DeviceResources>& deviceResources)
|
||||
bool CameraResources::AttachViewProjectionBuffer(std::shared_ptr<DeviceResourcesUWP>& deviceResources)
|
||||
{
|
||||
// This method uses Direct3D device-based resources.
|
||||
return deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
|
@ -221,22 +233,22 @@ namespace DXHelper
|
|||
ID3D11Buffer* viewProjectionConstantBuffers[1] = {m_viewProjectionConstantBuffer.get()};
|
||||
context->VSSetConstantBuffers(1, 1, viewProjectionConstantBuffers);
|
||||
|
||||
// The template includes a pass-through geometry shader that is used by
|
||||
// default on systems that don't support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer extension. The shader
|
||||
// will be enabled at run-time on systems that require it.
|
||||
// If your app will also use the geometry shader for other tasks and those
|
||||
// tasks require the view/projection matrix, uncomment the following line
|
||||
// of code to send the constant buffer to the geometry shader as well.
|
||||
/*context->GSSetConstantBuffers(
|
||||
1,
|
||||
1,
|
||||
m_viewProjectionConstantBuffer.GetAddressOf()
|
||||
);*/
|
||||
|
||||
m_framePending = false;
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface CameraResources::GetDepthStencilTextureInteropObject()
|
||||
{
|
||||
// Direct3D interop APIs are used to provide the buffer to the WinRT API.
|
||||
winrt::com_ptr<IDXGIResource1> depthStencilResource;
|
||||
winrt::check_bool(m_d3dDepthStencil.try_as(depthStencilResource));
|
||||
winrt::com_ptr<IDXGISurface2> depthDxgiSurface;
|
||||
winrt::check_hresult(depthStencilResource->CreateSubresourceSurface(0, depthDxgiSurface.put()));
|
||||
winrt::com_ptr<::IInspectable> inspectableSurface;
|
||||
winrt::check_hresult(CreateDirect3D11SurfaceFromDXGISurface(
|
||||
depthDxgiSurface.get(), reinterpret_cast<IInspectable**>(winrt::put_abi(inspectableSurface))));
|
||||
return inspectableSurface.as<winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface>();
|
||||
}
|
||||
} // namespace DXHelper
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
namespace DXHelper
|
||||
{
|
||||
class DeviceResources;
|
||||
class DeviceResourcesUWP;
|
||||
|
||||
// Constant buffer used to send the view-projection matrices to the shader pipeline.
|
||||
struct ViewProjectionConstantBuffer
|
||||
|
@ -33,16 +33,16 @@ namespace DXHelper
|
|||
CameraResources(winrt::Windows::Graphics::Holographic::HolographicCamera const& holographicCamera);
|
||||
|
||||
void CreateResourcesForBackBuffer(
|
||||
DeviceResources* pDeviceResources,
|
||||
DeviceResourcesUWP* pDeviceResources,
|
||||
winrt::Windows::Graphics::Holographic::HolographicCameraRenderingParameters const& cameraParameters);
|
||||
void ReleaseResourcesForBackBuffer(DeviceResources* pDeviceResources);
|
||||
void ReleaseResourcesForBackBuffer(DeviceResourcesUWP* pDeviceResources);
|
||||
|
||||
void UpdateViewProjectionBuffer(
|
||||
std::shared_ptr<DeviceResources> deviceResources,
|
||||
std::shared_ptr<DeviceResourcesUWP> deviceResources,
|
||||
winrt::Windows::Graphics::Holographic::HolographicCameraPose const& cameraPose,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem const& coordinateSystem);
|
||||
|
||||
bool AttachViewProjectionBuffer(std::shared_ptr<DeviceResources>& deviceResources);
|
||||
bool AttachViewProjectionBuffer(std::shared_ptr<DeviceResourcesUWP>& deviceResources);
|
||||
|
||||
// Direct3D device resources.
|
||||
ID3D11RenderTargetView* GetBackBufferRenderTargetView() const
|
||||
|
@ -86,6 +86,12 @@ namespace DXHelper
|
|||
return m_holographicCamera;
|
||||
}
|
||||
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface GetDepthStencilTextureInteropObject();
|
||||
winrt::Windows::Graphics::Holographic::HolographicStereoTransform GetProjectionTransform()
|
||||
{
|
||||
return m_cameraProjectionTransform;
|
||||
}
|
||||
|
||||
private:
|
||||
// Direct3D rendering objects. Required for 3D.
|
||||
winrt::com_ptr<ID3D11RenderTargetView> m_d3dRenderTargetView;
|
||||
|
@ -109,5 +115,7 @@ namespace DXHelper
|
|||
|
||||
// Pointer to the holographic camera these resources are for.
|
||||
winrt::Windows::Graphics::Holographic::HolographicCamera m_holographicCamera = nullptr;
|
||||
|
||||
winrt::Windows::Graphics::Holographic::HolographicStereoTransform m_cameraProjectionTransform;
|
||||
};
|
||||
} // namespace DXHelper
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
|
||||
#include "pch.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <memory>
|
||||
|
||||
#include "DDSTextureLoader.h"
|
||||
|
@ -256,7 +256,6 @@ static HRESULT LoadTextureDataFromFile(
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Return the BPP for a particular format
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
@ -419,7 +418,6 @@ static size_t BitsPerPixel(_In_ DXGI_FORMAT fmt)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Get surface information for a particular format
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
@ -563,7 +561,6 @@ static void GetSurfaceInfo(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
#define ISBITMASK(r, g, b, a) (ddpf.RBitMask == r && ddpf.GBitMask == g && ddpf.BBitMask == b && ddpf.ABitMask == a)
|
||||
|
||||
|
@ -777,7 +774,6 @@ static DXGI_FORMAT GetDXGIFormat(const DDS_PIXELFORMAT& ddpf)
|
|||
return DXGI_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
static DXGI_FORMAT MakeSRGB(_In_ DXGI_FORMAT format)
|
||||
{
|
||||
|
@ -809,7 +805,6 @@ static DXGI_FORMAT MakeSRGB(_In_ DXGI_FORMAT format)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
static HRESULT FillInitData(
|
||||
_In_ size_t width,
|
||||
|
@ -902,7 +897,6 @@ static HRESULT FillInitData(
|
|||
return (index > 0) ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
static HRESULT CreateD3DResources(
|
||||
_In_ ID3D11Device* d3dDevice,
|
||||
|
@ -1122,7 +1116,6 @@ static HRESULT CreateD3DResources(
|
|||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
static HRESULT CreateTextureFromDDS(
|
||||
_In_ ID3D11Device* d3dDevice,
|
||||
|
@ -1528,7 +1521,6 @@ static HRESULT CreateTextureFromDDS(
|
|||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
static DDS_ALPHA_MODE GetAlphaMode(_In_ const DDS_HEADER* header)
|
||||
{
|
||||
|
@ -1556,7 +1548,6 @@ static DDS_ALPHA_MODE GetAlphaMode(_In_ const DDS_HEADER* header)
|
|||
return DDS_ALPHA_MODE_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_ HRESULT DirectX::CreateDDSTextureFromMemory(
|
||||
ID3D11Device* d3dDevice,
|
||||
|
|
|
@ -46,67 +46,81 @@ bool ErrorHelper::ProcessOnDisconnect(const ConnectionFailureReason& reason)
|
|||
{
|
||||
switch (reason)
|
||||
{
|
||||
case ConnectionFailureReason::Unknown:
|
||||
AddError(L"Disconnect: Unknown reason");
|
||||
return true;
|
||||
case ConnectionFailureReason::Unknown:
|
||||
AddError(L"Disconnect: Unknown reason");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::HandshakeUnreachable:
|
||||
AddError(L"Disconnect: Handshake server is unreachable");
|
||||
return true;
|
||||
case ConnectionFailureReason::HandshakeUnreachable:
|
||||
AddError(L"Disconnect: Handshake server is unreachable");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::HandshakeConnectionFailed:
|
||||
AddError(L"Disconnect: Handshake server closed the connection prematurely; likely due to TLS/Plain mismatch "
|
||||
L"or invalid certificate");
|
||||
return true;
|
||||
case ConnectionFailureReason::HandshakeConnectionFailed:
|
||||
AddError(L"Disconnect: Handshake server closed the connection prematurely; likely due to TLS/Plain mismatch "
|
||||
L"or invalid certificate");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::AuthenticationFailed:
|
||||
AddError(L"Disconnect: Authentication with the handshake server failed");
|
||||
return true;
|
||||
case ConnectionFailureReason::AuthenticationFailed:
|
||||
AddError(L"Disconnect: Authentication with the handshake server failed");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::RemotingVersionMismatch:
|
||||
AddError(L"Disconnect: No common compatible remoting version could be determined during handshake");
|
||||
return true;
|
||||
case ConnectionFailureReason::RemotingVersionMismatch:
|
||||
AddError(L"Disconnect: No common compatible remoting version could be determined during handshake");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::IncompatibleTransportProtocols:
|
||||
AddError(L"Disconnect: No common transport protocol could be determined during handshake");
|
||||
return true;
|
||||
case ConnectionFailureReason::IncompatibleTransportProtocols:
|
||||
AddError(L"Disconnect: No common transport protocol could be determined during handshake");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::HandshakeFailed:
|
||||
AddError(L"Disconnect: Handshake failed for any other reason");
|
||||
return true;
|
||||
case ConnectionFailureReason::HandshakeFailed:
|
||||
AddError(L"Disconnect: Handshake failed for any other reason");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::TransportUnreachable:
|
||||
AddError(L"Disconnect: Transport server is unreachable");
|
||||
return true;
|
||||
case ConnectionFailureReason::TransportUnreachable:
|
||||
AddError(L"Disconnect: Transport server is unreachable");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::TransportConnectionFailed:
|
||||
AddError(L"Disconnect: Transport connection was closed before all communication channels had been set up");
|
||||
return true;
|
||||
case ConnectionFailureReason::TransportConnectionFailed:
|
||||
AddError(L"Disconnect: Transport connection was closed before all communication channels had been set up");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::ProtocolVersionMismatch:
|
||||
AddError(L"Disconnect: Transport connection was closed due to protocol version mismatch");
|
||||
return true;
|
||||
case ConnectionFailureReason::ProtocolVersionMismatch:
|
||||
AddError(L"Disconnect: Transport connection was closed due to protocol version mismatch. "
|
||||
L"Please go to the store app and check for any updates and install them to potentially resolve "
|
||||
L"this error.");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::ProtocolError:
|
||||
AddError(L"Disconnect: A protocol error occurred that was severe enough to invalidate the current connection "
|
||||
L"or connection attempt");
|
||||
return true;
|
||||
case ConnectionFailureReason::ProtocolError:
|
||||
AddError(L"Disconnect: A protocol error occurred that was severe enough to invalidate the current connection "
|
||||
L"or connection attempt");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::VideoCodecNotAvailable:
|
||||
AddError(L"Disconnect: Transport connection was closed due to the requested video codec not being available");
|
||||
return true;
|
||||
case ConnectionFailureReason::VideoCodecNotAvailable:
|
||||
AddError(L"Disconnect: Transport connection was closed due to the requested video codec not being available");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::Canceled:
|
||||
AddError(L"Disconnect: Connection attempt has been canceled");
|
||||
return true;
|
||||
case ConnectionFailureReason::Canceled:
|
||||
AddError(L"Disconnect: Connection attempt has been canceled");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::ConnectionLost:
|
||||
AddError(L"Disconnect: Connection has been lost or closed by remote side");
|
||||
return false;
|
||||
case ConnectionFailureReason::ConnectionLost:
|
||||
AddError(L"Disconnect: Connection has been lost or closed by remote side");
|
||||
return false;
|
||||
|
||||
case ConnectionFailureReason::DeviceLost:
|
||||
AddError(L"Disconnect: Connection has been closed due to graphics device loss");
|
||||
return true;
|
||||
case ConnectionFailureReason::DeviceLost:
|
||||
AddError(L"Disconnect: Connection has been closed due to graphics device loss");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::HandshakeNetworkUnreachable:
|
||||
AddError(L"Disconnect: Handshake - Network unreachable");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::HandshakeConnectionRefused:
|
||||
AddError(L"Disconnect: Handshake - Connection has been refused by remote host");
|
||||
return true;
|
||||
|
||||
case ConnectionFailureReason::VideoFormatNotAvailable:
|
||||
AddError(L"Disconnect: Transport connection was closed due to the requested video format not being available");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -22,7 +22,6 @@ static_assert(
|
|||
(sizeof(ModelConstantBuffer) % (sizeof(float) * 4)) == 0,
|
||||
"Model constant buffer size must be multiple of 16-bytes (16 bytes is the length of four floats).");
|
||||
|
||||
|
||||
// Used to send per-vertex data to the vertex shader.
|
||||
struct VertexBufferElement
|
||||
{
|
||||
|
|
|
@ -18,13 +18,14 @@
|
|||
#include <shaders\VPRTVertexShader.h>
|
||||
#include <shaders\VertexShader.h>
|
||||
|
||||
#define TEXTURE_WIDTH 650
|
||||
#define TEXTURE_HEIGHT 650
|
||||
|
||||
#define Font L"Segoe UI"
|
||||
#define FontSizeLarge 32.0f
|
||||
#define FontSizeSmall 22.0f
|
||||
#define FontLanguage L"en-US"
|
||||
constexpr const wchar_t Font[] = L"Segoe UI";
|
||||
// Font size in percent.
|
||||
constexpr float FontSizeLarge = 0.06f;
|
||||
constexpr float FontSizeMedium = 0.04f;
|
||||
constexpr float FontSizeSmall = 0.035f;
|
||||
constexpr const wchar_t FontLanguage[] = L"en-US";
|
||||
constexpr const float Degree2Rad = 3.14159265359f / 180.0f;
|
||||
constexpr const float Meter2Inch = 39.37f;
|
||||
|
||||
using namespace DirectX;
|
||||
using namespace Concurrency;
|
||||
|
@ -32,7 +33,7 @@ using namespace winrt::Windows::Foundation::Numerics;
|
|||
using namespace winrt::Windows::UI::Input::Spatial;
|
||||
|
||||
// Initializes D2D resources used for text rendering.
|
||||
StatusDisplay::StatusDisplay(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources)
|
||||
StatusDisplay::StatusDisplay(const std::shared_ptr<DXHelper::DeviceResourcesCommon>& deviceResources)
|
||||
: m_deviceResources(deviceResources)
|
||||
{
|
||||
CreateDeviceDependentResources();
|
||||
|
@ -55,134 +56,142 @@ void StatusDisplay::Render()
|
|||
return;
|
||||
}
|
||||
|
||||
// First render all text using direct2D
|
||||
m_deviceResources->UseD3DDeviceContext(
|
||||
[&](auto context) { context->ClearRenderTargetView(m_textRenderTarget.get(), DirectX::Colors::Transparent); });
|
||||
|
||||
m_d2dTextRenderTarget->BeginDraw();
|
||||
bool linesChanged = false;
|
||||
|
||||
// First render all text using direct2D.
|
||||
{
|
||||
std::scoped_lock lock(m_lineMutex);
|
||||
if (m_lines.size() > 0)
|
||||
{
|
||||
float top = m_lines[0].metrics.height;
|
||||
linesChanged = true;
|
||||
m_deviceResources->UseD3DDeviceContext(
|
||||
[&](auto context) { context->ClearRenderTargetView(m_textRenderTarget.get(), DirectX::Colors::Transparent); });
|
||||
|
||||
m_d2dTextRenderTarget->BeginDraw();
|
||||
float height = 0;
|
||||
for (auto& line : m_lines)
|
||||
{
|
||||
height += line.metrics.height * line.lineHeightMultiplier;
|
||||
}
|
||||
|
||||
// Vertical centered for the whole text with ~1/4 logical inch offset. In DIP.
|
||||
float top = ((m_virtualDisplaySizeInchY / 2.0f) * 96.0f) - (height / 2.0f) - 48;
|
||||
|
||||
for (auto& line : m_lines)
|
||||
{
|
||||
if (line.alignBottom)
|
||||
{
|
||||
top = TEXTURE_HEIGHT - line.metrics.height;
|
||||
top = m_textTextureHeight - line.metrics.height;
|
||||
}
|
||||
|
||||
m_d2dTextRenderTarget->DrawTextLayout(D2D1::Point2F(0, top), line.layout.get(), m_brushes[line.color].get());
|
||||
top += line.metrics.height * line.lineHeightMultiplier;
|
||||
}
|
||||
|
||||
// Ignore D2DERR_RECREATE_TARGET here. This error indicates that the device
|
||||
// is lost. It will be handled during the next call to Present.
|
||||
const HRESULT hr = m_d2dTextRenderTarget->EndDraw();
|
||||
if (hr != D2DERR_RECREATE_TARGET)
|
||||
{
|
||||
winrt::check_hresult(hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore D2DERR_RECREATE_TARGET here. This error indicates that the device
|
||||
// is lost. It will be handled during the next call to Present.
|
||||
const HRESULT hr = m_d2dTextRenderTarget->EndDraw();
|
||||
if (hr != D2DERR_RECREATE_TARGET)
|
||||
{
|
||||
winrt::check_hresult(hr);
|
||||
}
|
||||
|
||||
// Now render the quads into 3d space
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
// Each vertex is one instance of the VertexBufferElement struct.
|
||||
const UINT stride = sizeof(VertexBufferElement);
|
||||
const UINT offset = 0;
|
||||
ID3D11Buffer* pBufferToSet = m_vertexBufferImage.get();
|
||||
context->IASetVertexBuffers(0, 1, &pBufferToSet, &stride, &offset);
|
||||
context->IASetIndexBuffer(
|
||||
m_indexBuffer.get(),
|
||||
DXGI_FORMAT_R16_UINT, // Each index is one 16-bit unsigned integer (short).
|
||||
0);
|
||||
DXHelper::D3D11StoreAndRestoreState(context, [&]() {
|
||||
// Each vertex is one instance of the VertexBufferElement struct.
|
||||
const UINT stride = sizeof(VertexBufferElement);
|
||||
const UINT offset = 0;
|
||||
ID3D11Buffer* pBufferToSet = m_vertexBufferImage.get();
|
||||
context->IASetVertexBuffers(0, 1, &pBufferToSet, &stride, &offset);
|
||||
context->IASetIndexBuffer(m_indexBuffer.get(), DXGI_FORMAT_R16_UINT, 0);
|
||||
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
context->IASetInputLayout(m_inputLayout.get());
|
||||
context->OMSetBlendState(m_textAlphaBlendState.get(), nullptr, 0xffffffff);
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
context->IASetInputLayout(m_inputLayout.get());
|
||||
context->OMSetBlendState(m_textAlphaBlendState.get(), nullptr, 0xffffffff);
|
||||
context->OMSetDepthStencilState(m_depthStencilState.get(), 0);
|
||||
|
||||
// Attach the vertex shader.
|
||||
context->VSSetShader(m_vertexShader.get(), nullptr, 0);
|
||||
context->UpdateSubresource(m_modelConstantBuffer.get(), 0, nullptr, &m_modelConstantBufferDataImage, 0, 0);
|
||||
|
||||
context->UpdateSubresource(m_modelConstantBuffer.get(), 0, nullptr, &m_modelConstantBufferDataImage, 0, 0);
|
||||
// Apply the model constant buffer to the vertex shader.
|
||||
pBufferToSet = m_modelConstantBuffer.get();
|
||||
context->VSSetConstantBuffers(0, 1, &pBufferToSet);
|
||||
|
||||
// Apply the model constant buffer to the vertex shader.
|
||||
pBufferToSet = m_modelConstantBuffer.get();
|
||||
context->VSSetConstantBuffers(0, 1, &pBufferToSet);
|
||||
// Attach the vertex shader.
|
||||
context->VSSetShader(m_vertexShader.get(), nullptr, 0);
|
||||
|
||||
// On devices that do not support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature,
|
||||
// a pass-through geometry shader sets the render target ID.
|
||||
context->GSSetShader(!m_usingVprtShaders ? m_geometryShader.get() : nullptr, nullptr, 0);
|
||||
// On devices that do not support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature,
|
||||
// a pass-through geometry shader sets the render target ID.
|
||||
context->GSSetShader(!m_usingVprtShaders ? m_geometryShader.get() : nullptr, nullptr, 0);
|
||||
|
||||
// Attach the pixel shader.
|
||||
context->PSSetShader(m_pixelShader.get(), nullptr, 0);
|
||||
// Attach the pixel shader.
|
||||
context->PSSetShader(m_pixelShader.get(), nullptr, 0);
|
||||
|
||||
// Draw the image.
|
||||
if (m_imageEnabled && m_imageView)
|
||||
{
|
||||
ID3D11ShaderResourceView* pShaderViewToSet = m_imageView.get();
|
||||
context->PSSetShaderResources(0, 1, &pShaderViewToSet);
|
||||
// Draw the image.
|
||||
if (m_imageEnabled && m_imageView)
|
||||
{
|
||||
ID3D11ShaderResourceView* pShaderViewToSet = m_imageView.get();
|
||||
context->PSSetShaderResources(0, 1, &pShaderViewToSet);
|
||||
|
||||
ID3D11SamplerState* pSamplerToSet = m_imageSamplerState.get();
|
||||
context->PSSetSamplers(0, 1, &pSamplerToSet);
|
||||
ID3D11SamplerState* pSamplerToSet = m_imageSamplerState.get();
|
||||
context->PSSetSamplers(0, 1, &pSamplerToSet);
|
||||
|
||||
context->DrawIndexedInstanced(
|
||||
m_indexCount, // Index count per instance.
|
||||
2, // Instance count.
|
||||
0, // Start index location.
|
||||
0, // Base vertex location.
|
||||
0 // Start instance location.
|
||||
);
|
||||
}
|
||||
context->DrawIndexedInstanced(
|
||||
m_indexCount, // Index count per instance.
|
||||
2, // Instance count.
|
||||
0, // Start index location.
|
||||
0, // Base vertex location.
|
||||
0 // Start instance location.
|
||||
);
|
||||
}
|
||||
|
||||
// Set up for rendering the texture that contains the text
|
||||
pBufferToSet = m_vertexBufferText.get();
|
||||
context->IASetVertexBuffers(0, 1, &pBufferToSet, &stride, &offset);
|
||||
// Draw the text.
|
||||
{
|
||||
if (linesChanged == true)
|
||||
{
|
||||
// Set up for rendering the texture that contains the text
|
||||
pBufferToSet = m_vertexBufferText.get();
|
||||
context->IASetVertexBuffers(0, 1, &pBufferToSet, &stride, &offset);
|
||||
|
||||
ID3D11ShaderResourceView* pShaderViewToSet = m_textShaderResourceView.get();
|
||||
context->PSSetShaderResources(0, 1, &pShaderViewToSet);
|
||||
ID3D11ShaderResourceView* pShaderViewToSet = m_textShaderResourceView.get();
|
||||
context->PSSetShaderResources(0, 1, &pShaderViewToSet);
|
||||
|
||||
ID3D11SamplerState* pSamplerToSet = m_textSamplerState.get();
|
||||
context->PSSetSamplers(0, 1, &pSamplerToSet);
|
||||
ID3D11SamplerState* pSamplerToSet = m_textSamplerState.get();
|
||||
context->PSSetSamplers(0, 1, &pSamplerToSet);
|
||||
|
||||
context->UpdateSubresource(m_modelConstantBuffer.get(), 0, nullptr, &m_modelConstantBufferDataText, 0, 0);
|
||||
context->UpdateSubresource(m_modelConstantBuffer.get(), 0, nullptr, &m_modelConstantBufferDataText, 0, 0);
|
||||
|
||||
// Draw the text.
|
||||
context->DrawIndexedInstanced(
|
||||
m_indexCount, // Index count per instance.
|
||||
2, // Instance count.
|
||||
0, // Start index location.
|
||||
0, // Base vertex location.
|
||||
0 // Start instance location.
|
||||
);
|
||||
|
||||
// Reset the blend state.
|
||||
context->OMSetBlendState(nullptr, nullptr, 0xffffffff);
|
||||
|
||||
// Detach our texture.
|
||||
ID3D11ShaderResourceView* emptyResource = nullptr;
|
||||
context->PSSetShaderResources(0, 1, &emptyResource);
|
||||
context->DrawIndexedInstanced(
|
||||
m_indexCount, // Index count per instance.
|
||||
2, // Instance count.
|
||||
0, // Start index location.
|
||||
0, // Base vertex location.
|
||||
0 // Start instance location.
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void StatusDisplay::CreateDeviceDependentResources()
|
||||
{
|
||||
CD3D11_SAMPLER_DESC desc(D3D11_DEFAULT);
|
||||
auto device = m_deviceResources->GetD3DDevice();
|
||||
|
||||
CD3D11_TEXTURE2D_DESC textureDesc(
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM, TEXTURE_WIDTH, TEXTURE_HEIGHT, 1, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM, m_textTextureWidth, m_textTextureHeight, 1, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
|
||||
|
||||
m_textTexture = nullptr;
|
||||
m_deviceResources->GetD3DDevice()->CreateTexture2D(&textureDesc, nullptr, m_textTexture.put());
|
||||
device->CreateTexture2D(&textureDesc, nullptr, m_textTexture.put());
|
||||
|
||||
m_textShaderResourceView = nullptr;
|
||||
m_deviceResources->GetD3DDevice()->CreateShaderResourceView(m_textTexture.get(), nullptr, m_textShaderResourceView.put());
|
||||
device->CreateShaderResourceView(m_textTexture.get(), nullptr, m_textShaderResourceView.put());
|
||||
|
||||
m_textRenderTarget = nullptr;
|
||||
m_deviceResources->GetD3DDevice()->CreateRenderTargetView(m_textTexture.get(), nullptr, m_textRenderTarget.put());
|
||||
device->CreateRenderTargetView(m_textTexture.get(), nullptr, m_textRenderTarget.put());
|
||||
|
||||
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
|
||||
D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), 96, 96);
|
||||
|
@ -190,7 +199,6 @@ void StatusDisplay::CreateDeviceDependentResources()
|
|||
winrt::com_ptr<IDXGISurface> dxgiSurface;
|
||||
m_textTexture.as(dxgiSurface);
|
||||
|
||||
|
||||
m_d2dTextRenderTarget = nullptr;
|
||||
winrt::check_hresult(
|
||||
m_deviceResources->GetD2DFactory()->CreateDxgiSurfaceRenderTarget(dxgiSurface.get(), &props, m_d2dTextRenderTarget.put()));
|
||||
|
@ -206,78 +214,38 @@ void StatusDisplay::CreateDeviceDependentResources()
|
|||
const auto vertexShaderDataSize = m_usingVprtShaders ? sizeof(VPRTVertexShader) : sizeof(VertexShader);
|
||||
|
||||
// create the vertex shader and input layout.
|
||||
task<void> createVSTask = task<void>([this, vertexShaderData, vertexShaderDataSize]() {
|
||||
winrt::check_hresult(
|
||||
m_deviceResources->GetD3DDevice()->CreateVertexShader(vertexShaderData, vertexShaderDataSize, nullptr, m_vertexShader.put()));
|
||||
task<void> createVSTask = task<void>([this, device, vertexShaderData, vertexShaderDataSize]() {
|
||||
winrt::check_hresult(device->CreateVertexShader(vertexShaderData, vertexShaderDataSize, nullptr, m_vertexShader.put()));
|
||||
|
||||
static const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = {
|
||||
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
};
|
||||
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateInputLayout(
|
||||
vertexDesc, ARRAYSIZE(vertexDesc), vertexShaderData, vertexShaderDataSize, m_inputLayout.put()));
|
||||
winrt::check_hresult(
|
||||
device->CreateInputLayout(vertexDesc, ARRAYSIZE(vertexDesc), vertexShaderData, vertexShaderDataSize, m_inputLayout.put()));
|
||||
});
|
||||
|
||||
// create the pixel shader and constant buffer.
|
||||
task<void> createPSTask([this]() {
|
||||
winrt::check_hresult(
|
||||
m_deviceResources->GetD3DDevice()->CreatePixelShader(PixelShader, sizeof(PixelShader), nullptr, m_pixelShader.put()));
|
||||
task<void> createPSTask([this, device]() {
|
||||
winrt::check_hresult(device->CreatePixelShader(PixelShader, sizeof(PixelShader), nullptr, m_pixelShader.put()));
|
||||
|
||||
const CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&constantBufferDesc, nullptr, m_modelConstantBuffer.put()));
|
||||
winrt::check_hresult(device->CreateBuffer(&constantBufferDesc, nullptr, m_modelConstantBuffer.put()));
|
||||
});
|
||||
|
||||
task<void> createGSTask;
|
||||
if (!m_usingVprtShaders)
|
||||
{
|
||||
// create the geometry shader.
|
||||
createGSTask = task<void>([this]() {
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateGeometryShader(
|
||||
GeometryShader, sizeof(GeometryShader), nullptr, m_geometryShader.put()));
|
||||
createGSTask = task<void>([this, device]() {
|
||||
winrt::check_hresult(device->CreateGeometryShader(GeometryShader, sizeof(GeometryShader), nullptr, m_geometryShader.put()));
|
||||
});
|
||||
}
|
||||
|
||||
// Once all shaders are loaded, create the mesh.
|
||||
task<void> shaderTaskGroup = m_usingVprtShaders ? (createPSTask && createVSTask) : (createPSTask && createVSTask && createGSTask);
|
||||
task<void> createQuadTask = shaderTaskGroup.then([this]() {
|
||||
// Load mesh vertices. Each vertex has a position and a color.
|
||||
// Note that the quad size has changed from the default DirectX app
|
||||
// template. Windows Holographic is scaled in meters, so to draw the
|
||||
// quad at a comfortable size we made the quad width 0.2 m (20 cm).
|
||||
static const float imageQuadExtent = 0.23f;
|
||||
static const VertexBufferElement quadVertices[] = {
|
||||
{XMFLOAT3(-imageQuadExtent, imageQuadExtent, 0.f), XMFLOAT2(0.f, 0.f)},
|
||||
{XMFLOAT3(imageQuadExtent, imageQuadExtent, 0.f), XMFLOAT2(1.f, 0.f)},
|
||||
{XMFLOAT3(imageQuadExtent, -imageQuadExtent, 0.f), XMFLOAT2(1.f, 1.f)},
|
||||
{XMFLOAT3(-imageQuadExtent, -imageQuadExtent, 0.f), XMFLOAT2(0.f, 1.f)},
|
||||
};
|
||||
|
||||
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
|
||||
vertexBufferData.pSysMem = quadVertices;
|
||||
vertexBufferData.SysMemPitch = 0;
|
||||
vertexBufferData.SysMemSlicePitch = 0;
|
||||
const CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(quadVertices), D3D11_BIND_VERTEX_BUFFER);
|
||||
winrt::check_hresult(
|
||||
m_deviceResources->GetD3DDevice()->CreateBuffer(&vertexBufferDesc, &vertexBufferData, m_vertexBufferImage.put()));
|
||||
|
||||
static const float textQuadExtent = 0.3f;
|
||||
static const VertexBufferElement quadVerticesText[] = {
|
||||
{XMFLOAT3(-textQuadExtent, textQuadExtent, 0.f), XMFLOAT2(0.f, 0.f)},
|
||||
{XMFLOAT3(textQuadExtent, textQuadExtent, 0.f), XMFLOAT2(1.f, 0.f)},
|
||||
{XMFLOAT3(textQuadExtent, -textQuadExtent, 0.f), XMFLOAT2(1.f, 1.f)},
|
||||
{XMFLOAT3(-textQuadExtent, -textQuadExtent, 0.f), XMFLOAT2(0.f, 1.f)},
|
||||
};
|
||||
|
||||
D3D11_SUBRESOURCE_DATA vertexBufferDataText = {0};
|
||||
vertexBufferDataText.pSysMem = quadVerticesText;
|
||||
vertexBufferDataText.SysMemPitch = 0;
|
||||
vertexBufferDataText.SysMemSlicePitch = 0;
|
||||
const CD3D11_BUFFER_DESC vertexBufferDescText(sizeof(quadVerticesText), D3D11_BIND_VERTEX_BUFFER);
|
||||
winrt::check_hresult(
|
||||
m_deviceResources->GetD3DDevice()->CreateBuffer(&vertexBufferDescText, &vertexBufferDataText, m_vertexBufferText.put()));
|
||||
|
||||
|
||||
task<void> createQuadTask = shaderTaskGroup.then([this, device]() {
|
||||
// Load mesh indices. Each trio of indices represents
|
||||
// a triangle to be rendered on the screen.
|
||||
// For example: 2,1,0 means that the vertices with indexes
|
||||
|
@ -300,34 +268,32 @@ void StatusDisplay::CreateDeviceDependentResources()
|
|||
indexBufferData.SysMemPitch = 0;
|
||||
indexBufferData.SysMemSlicePitch = 0;
|
||||
const CD3D11_BUFFER_DESC indexBufferDesc(sizeof(quadIndices), D3D11_BIND_INDEX_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&indexBufferDesc, &indexBufferData, m_indexBuffer.put()));
|
||||
winrt::check_hresult(device->CreateBuffer(&indexBufferDesc, &indexBufferData, m_indexBuffer.put()));
|
||||
});
|
||||
|
||||
// Create image sampler state
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc = {};
|
||||
|
||||
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.MaxAnisotropy = 1;
|
||||
desc.MinLOD = 0;
|
||||
desc.MaxLOD = 3;
|
||||
desc.MipLODBias = 0.f;
|
||||
desc.BorderColor[0] = 0.f;
|
||||
desc.BorderColor[1] = 0.f;
|
||||
desc.BorderColor[2] = 0.f;
|
||||
desc.BorderColor[3] = 0.f;
|
||||
desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateSamplerState(&desc, m_imageSamplerState.put()));
|
||||
D3D11_SAMPLER_DESC samplerDesc = {};
|
||||
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.MaxAnisotropy = 1;
|
||||
samplerDesc.MinLOD = 0;
|
||||
samplerDesc.MaxLOD = 3;
|
||||
samplerDesc.MipLODBias = 0.f;
|
||||
samplerDesc.BorderColor[0] = 0.f;
|
||||
samplerDesc.BorderColor[1] = 0.f;
|
||||
samplerDesc.BorderColor[2] = 0.f;
|
||||
samplerDesc.BorderColor[3] = 0.f;
|
||||
samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||
winrt::check_hresult(device->CreateSamplerState(&samplerDesc, m_imageSamplerState.put()));
|
||||
}
|
||||
|
||||
// Create text sampler state
|
||||
{
|
||||
CD3D11_SAMPLER_DESC samplerDesc(D3D11_DEFAULT);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateSamplerState(&samplerDesc, m_textSamplerState.put()));
|
||||
winrt::check_hresult(device->CreateSamplerState(&samplerDesc, m_textSamplerState.put()));
|
||||
}
|
||||
|
||||
// Create the blend state. This sets up a blend state for pre-multiplied alpha produced by TextRenderer.cpp's Direct2D text
|
||||
|
@ -352,7 +318,10 @@ void StatusDisplay::CreateDeviceDependentResources()
|
|||
blendStateDesc.RenderTarget[i] = rtBlendDesc;
|
||||
}
|
||||
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBlendState(&blendStateDesc, m_textAlphaBlendState.put()));
|
||||
winrt::check_hresult(device->CreateBlendState(&blendStateDesc, m_textAlphaBlendState.put()));
|
||||
|
||||
D3D11_DEPTH_STENCIL_DESC depthStencilDesc = {};
|
||||
device->CreateDepthStencilState(&depthStencilDesc, m_depthStencilState.put());
|
||||
|
||||
// Once the quad is loaded, the object is ready to be rendered.
|
||||
auto loadCompleteCallback = createQuadTask.then([this]() { m_loadingComplete = true; });
|
||||
|
@ -412,7 +381,10 @@ void StatusDisplay::SetLines(winrt::array_view<Line> lines)
|
|||
void StatusDisplay::UpdateLineText(size_t index, std::wstring text)
|
||||
{
|
||||
std::scoped_lock lock(m_lineMutex);
|
||||
assert(index < m_lines.size() && "Line index out of bounds");
|
||||
if (index >= m_lines.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& runtimeLine = m_lines[index];
|
||||
|
||||
|
@ -423,7 +395,7 @@ void StatusDisplay::UpdateLineText(size_t index, std::wstring text)
|
|||
size_t StatusDisplay::AddLine(const Line& line)
|
||||
{
|
||||
std::scoped_lock lock(m_lineMutex);
|
||||
auto newIndex = m_lines.size();
|
||||
size_t newIndex = m_lines.size();
|
||||
m_lines.resize(newIndex + 1);
|
||||
UpdateLineInternal(m_lines[newIndex], line);
|
||||
return newIndex;
|
||||
|
@ -437,6 +409,11 @@ bool StatusDisplay::HasLine(size_t index)
|
|||
|
||||
void StatusDisplay::CreateFonts()
|
||||
{
|
||||
// DIP font size, based on the horizontal size of the virtual display.
|
||||
float fontSizeLargeDIP = (m_virtualDisplaySizeInchX * FontSizeLarge) * 96;
|
||||
float fontSizeMediumDIP = (m_virtualDisplaySizeInchX * FontSizeMedium) * 96;
|
||||
float fontSizeSmallDIP = (m_virtualDisplaySizeInchX * FontSizeSmall) * 96;
|
||||
|
||||
// Create Large font
|
||||
m_textFormats[Large] = nullptr;
|
||||
winrt::check_hresult(m_deviceResources->GetDWriteFactory()->CreateTextFormat(
|
||||
|
@ -445,7 +422,7 @@ void StatusDisplay::CreateFonts()
|
|||
DWRITE_FONT_WEIGHT_NORMAL,
|
||||
DWRITE_FONT_STYLE_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
FontSizeLarge,
|
||||
fontSizeLargeDIP,
|
||||
FontLanguage,
|
||||
m_textFormats[Large].put()));
|
||||
winrt::check_hresult(m_textFormats[Large]->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR));
|
||||
|
@ -459,7 +436,7 @@ void StatusDisplay::CreateFonts()
|
|||
DWRITE_FONT_WEIGHT_BOLD,
|
||||
DWRITE_FONT_STYLE_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
FontSizeLarge,
|
||||
fontSizeLargeDIP,
|
||||
FontLanguage,
|
||||
m_textFormats[LargeBold].put()));
|
||||
winrt::check_hresult(m_textFormats[LargeBold]->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR));
|
||||
|
@ -473,13 +450,27 @@ void StatusDisplay::CreateFonts()
|
|||
DWRITE_FONT_WEIGHT_MEDIUM,
|
||||
DWRITE_FONT_STYLE_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
FontSizeSmall,
|
||||
fontSizeSmallDIP,
|
||||
FontLanguage,
|
||||
m_textFormats[Small].put()));
|
||||
winrt::check_hresult(m_textFormats[Small]->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR));
|
||||
winrt::check_hresult(m_textFormats[Small]->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER));
|
||||
|
||||
static_assert(TextFormatCount == 3, "Expected 3 text formats");
|
||||
// Create medium font
|
||||
m_textFormats[Medium] = nullptr;
|
||||
winrt::check_hresult(m_deviceResources->GetDWriteFactory()->CreateTextFormat(
|
||||
Font,
|
||||
nullptr,
|
||||
DWRITE_FONT_WEIGHT_MEDIUM,
|
||||
DWRITE_FONT_STYLE_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
fontSizeMediumDIP,
|
||||
FontLanguage,
|
||||
m_textFormats[Medium].put()));
|
||||
winrt::check_hresult(m_textFormats[Medium]->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR));
|
||||
winrt::check_hresult(m_textFormats[Medium]->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER));
|
||||
|
||||
static_assert(TextFormatCount == 4, "Expected 4 text formats");
|
||||
}
|
||||
|
||||
void StatusDisplay::CreateBrushes()
|
||||
|
@ -504,13 +495,19 @@ void StatusDisplay::UpdateLineInternal(RuntimeLine& runtimeLine, const Line& lin
|
|||
runtimeLine.format = line.format;
|
||||
runtimeLine.text = line.text;
|
||||
|
||||
const float virtualDisplayDPIx = m_textTextureWidth / m_virtualDisplaySizeInchX;
|
||||
const float virtualDisplayDPIy = m_textTextureHeight / m_virtualDisplaySizeInchY;
|
||||
|
||||
const float dpiScaleX = virtualDisplayDPIx / 96.0f;
|
||||
const float dpiScaleY = virtualDisplayDPIy / 96.0f;
|
||||
|
||||
runtimeLine.layout = nullptr;
|
||||
winrt::check_hresult(m_deviceResources->GetDWriteFactory()->CreateTextLayout(
|
||||
line.text.c_str(),
|
||||
static_cast<UINT32>(line.text.length()),
|
||||
m_textFormats[line.format].get(),
|
||||
TEXTURE_WIDTH, // Max width of the input text.
|
||||
TEXTURE_HEIGHT, // Max height of the input text.
|
||||
static_cast<float>(m_textTextureWidth / dpiScaleX), // Max width of the input text.
|
||||
static_cast<float>(m_textTextureHeight / dpiScaleY), // Max height of the input text.
|
||||
runtimeLine.layout.put()));
|
||||
|
||||
winrt::check_hresult(runtimeLine.layout->GetMetrics(&runtimeLine.metrics));
|
||||
|
@ -536,11 +533,11 @@ void StatusDisplay::PositionDisplay(float deltaTimeInSeconds, const SpatialPoint
|
|||
const float3 headPosition = pointerPose.Head().Position();
|
||||
const float3 headDirection = pointerPose.Head().ForwardDirection();
|
||||
|
||||
const float3 offsetImage = float3(0.0f, -0.02f, 0.0f);
|
||||
const float3 gazeAtTwoMetersImage = headPosition + (2.05f * (headDirection + offsetImage));
|
||||
const float3 offsetImage = float3(0.0f, m_virtualDisplaySizeInchY * 0.002f, 0.0f);
|
||||
const float3 gazeAtTwoMetersImage = headPosition + ((m_statusDisplayDistance + 0.05f) * (headDirection + offsetImage));
|
||||
|
||||
const float3 offsetText = float3(0.0f, -0.035f, 0.0f);
|
||||
const float3 gazeAtTwoMetersText = headPosition + (2.0f * (headDirection + offsetText));
|
||||
const float3 offsetText = float3(0.0f, 0.0f, 0.0f);
|
||||
const float3 gazeAtTwoMetersText = headPosition + (m_statusDisplayDistance * (headDirection + offsetText));
|
||||
|
||||
// Lerp the position, to keep the hologram comfortably stable.
|
||||
auto imagePosition = lerp(m_positionImage, gazeAtTwoMetersImage, deltaTimeInSeconds * c_lerpRate);
|
||||
|
@ -597,3 +594,159 @@ void StatusDisplay::UpdateConstantBuffer(
|
|||
auto& deltaX = position - lastPosition; // meters
|
||||
m_velocity = deltaX / deltaTimeInSeconds; // meters per second
|
||||
}
|
||||
|
||||
void StatusDisplay::UpdateTextScale(
|
||||
winrt::Windows::Graphics::Holographic::HolographicStereoTransform holoTransform,
|
||||
float screenWidth,
|
||||
float screenHeight,
|
||||
float quadFov,
|
||||
float heightRatio)
|
||||
{
|
||||
DirectX::XMMATRIX projMat = XMLoadFloat4x4(&holoTransform.Left);
|
||||
DirectX::XMFLOAT4X4 proj;
|
||||
DirectX::XMStoreFloat4x4(&proj, projMat);
|
||||
// Check if the projection matrix has changed.
|
||||
bool projHasChanged = false;
|
||||
for (int x = 0; x < 4; ++x)
|
||||
{
|
||||
for (int y = 0; y < 4; ++y)
|
||||
{
|
||||
if (proj.m[x][y] != m_projection.m[x][y])
|
||||
{
|
||||
projHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (projHasChanged)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const float fovDiff = m_currentQuadFov - quadFov;
|
||||
const float fovEpsilon = 0.1f;
|
||||
const bool quadFovHasChanged = std::abs(fovDiff) > fovEpsilon;
|
||||
m_currentQuadFov = quadFov;
|
||||
|
||||
const float heightRatioDiff = m_currentHeightRatio - heightRatio;
|
||||
const float heightRatioEpsilon = 0.1f;
|
||||
const bool quadRatioHasChanged = std::abs(heightRatioDiff) > heightRatioEpsilon;
|
||||
m_currentHeightRatio = heightRatio;
|
||||
|
||||
// Only update the StatusDisplay resolution and size if something has changed.
|
||||
if (projHasChanged || quadFovHasChanged || quadRatioHasChanged)
|
||||
{
|
||||
// Quad extent based on FOV.
|
||||
const float quadExtentX = tan((m_currentQuadFov / 2.0f) * Degree2Rad) * m_statusDisplayDistance;
|
||||
const float quadExtentY = m_currentHeightRatio * quadExtentX;
|
||||
|
||||
// Calculate the virtual display size in inch.
|
||||
m_virtualDisplaySizeInchX = (quadExtentX * 2.0f) * Meter2Inch;
|
||||
m_virtualDisplaySizeInchY = (quadExtentY * 2.0f) * Meter2Inch;
|
||||
|
||||
// Pixel perfect resolution.
|
||||
const float resX = screenWidth * quadExtentX / m_statusDisplayDistance * proj._11;
|
||||
const float resY = screenHeight * quadExtentY / m_statusDisplayDistance * proj._22;
|
||||
|
||||
// sample with double resolution for multi sampling.
|
||||
m_textTextureWidth = static_cast<int>(resX * 2.0f);
|
||||
m_textTextureHeight = static_cast<int>(resY * 2.0f);
|
||||
|
||||
m_projection = proj;
|
||||
|
||||
// Create the new texture.
|
||||
auto device = m_deviceResources->GetD3DDevice();
|
||||
|
||||
// Load mesh vertices. Each vertex has a position and a color.
|
||||
// Note that the quad size has changed from the default DirectX app
|
||||
// template. The quad size is based on the target FOV.
|
||||
const VertexBufferElement quadVerticesText[] = {
|
||||
{XMFLOAT3(-quadExtentX, quadExtentY, 0.f), XMFLOAT2(0.f, 0.f)},
|
||||
{XMFLOAT3(quadExtentX, quadExtentY, 0.f), XMFLOAT2(1.f, 0.f)},
|
||||
{XMFLOAT3(quadExtentX, -quadExtentY, 0.f), XMFLOAT2(1.f, 1.f)},
|
||||
{XMFLOAT3(-quadExtentX, -quadExtentY, 0.f), XMFLOAT2(0.f, 1.f)},
|
||||
};
|
||||
|
||||
D3D11_SUBRESOURCE_DATA vertexBufferDataText = {0};
|
||||
vertexBufferDataText.pSysMem = quadVerticesText;
|
||||
vertexBufferDataText.SysMemPitch = 0;
|
||||
vertexBufferDataText.SysMemSlicePitch = 0;
|
||||
const CD3D11_BUFFER_DESC vertexBufferDescText(sizeof(quadVerticesText), D3D11_BIND_VERTEX_BUFFER);
|
||||
|
||||
m_vertexBufferText = nullptr;
|
||||
winrt::check_hresult(device->CreateBuffer(&vertexBufferDescText, &vertexBufferDataText, m_vertexBufferText.put()));
|
||||
|
||||
// Create image buffer
|
||||
// The image contains 50% of the textFOV.
|
||||
const float imageFOVDegree = 0.4f * (m_currentQuadFov * 0.5f);
|
||||
const float imageQuadExtent = m_statusDisplayDistance / tan((90.0f - imageFOVDegree) * Degree2Rad);
|
||||
|
||||
const VertexBufferElement quadVertices[] = {
|
||||
{XMFLOAT3(-imageQuadExtent, imageQuadExtent, 0.f), XMFLOAT2(0.f, 0.f)},
|
||||
{XMFLOAT3(imageQuadExtent, imageQuadExtent, 0.f), XMFLOAT2(1.f, 0.f)},
|
||||
{XMFLOAT3(imageQuadExtent, -imageQuadExtent, 0.f), XMFLOAT2(1.f, 1.f)},
|
||||
{XMFLOAT3(-imageQuadExtent, -imageQuadExtent, 0.f), XMFLOAT2(0.f, 1.f)},
|
||||
};
|
||||
|
||||
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
|
||||
vertexBufferData.pSysMem = quadVertices;
|
||||
vertexBufferData.SysMemPitch = 0;
|
||||
vertexBufferData.SysMemSlicePitch = 0;
|
||||
const CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(quadVertices), D3D11_BIND_VERTEX_BUFFER);
|
||||
m_vertexBufferImage = nullptr;
|
||||
winrt::check_hresult(device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, m_vertexBufferImage.put()));
|
||||
|
||||
CD3D11_TEXTURE2D_DESC textureDesc(
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
m_textTextureWidth,
|
||||
m_textTextureHeight,
|
||||
1,
|
||||
1,
|
||||
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
|
||||
|
||||
m_textTexture = nullptr;
|
||||
device->CreateTexture2D(&textureDesc, nullptr, m_textTexture.put());
|
||||
|
||||
m_textShaderResourceView = nullptr;
|
||||
device->CreateShaderResourceView(m_textTexture.get(), nullptr, m_textShaderResourceView.put());
|
||||
|
||||
m_textRenderTarget = nullptr;
|
||||
device->CreateRenderTargetView(m_textTexture.get(), nullptr, m_textRenderTarget.put());
|
||||
|
||||
const float virtualDisplayDPIx = m_textTextureWidth / m_virtualDisplaySizeInchX;
|
||||
const float virtualDisplayDPIy = m_textTextureHeight / m_virtualDisplaySizeInchY;
|
||||
|
||||
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
|
||||
D2D1_RENDER_TARGET_TYPE_DEFAULT,
|
||||
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
|
||||
virtualDisplayDPIx,
|
||||
virtualDisplayDPIy);
|
||||
|
||||
winrt::com_ptr<IDXGISurface> dxgiSurface;
|
||||
m_textTexture.as(dxgiSurface);
|
||||
|
||||
m_d2dTextRenderTarget = nullptr;
|
||||
winrt::check_hresult(
|
||||
m_deviceResources->GetD2DFactory()->CreateDxgiSurfaceRenderTarget(dxgiSurface.get(), &props, m_d2dTextRenderTarget.put()));
|
||||
|
||||
// Update the fonts.
|
||||
CreateFonts();
|
||||
|
||||
// Update the text layout.
|
||||
for (RuntimeLine& runtimeLine : m_lines)
|
||||
{
|
||||
|
||||
const float dpiScaleX = virtualDisplayDPIx / 96.0f;
|
||||
const float dpiScaleY = virtualDisplayDPIy / 96.0f;
|
||||
runtimeLine.layout = nullptr;
|
||||
winrt::check_hresult(m_deviceResources->GetDWriteFactory()->CreateTextLayout(
|
||||
runtimeLine.text.c_str(),
|
||||
static_cast<UINT32>(runtimeLine.text.length()),
|
||||
m_textFormats[runtimeLine.format].get(),
|
||||
static_cast<float>(m_textTextureWidth / dpiScaleX), // Max width of the input text.
|
||||
static_cast<float>(m_textTextureHeight / dpiScaleY), // Max height of the input text.
|
||||
runtimeLine.layout.put()));
|
||||
winrt::check_hresult(runtimeLine.layout->GetMetrics(&runtimeLine.metrics));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "..\Common\DeviceResources.h"
|
||||
#include "..\Common\DeviceResourcesCommon.h"
|
||||
#include "ShaderStructures.h"
|
||||
|
||||
#include <string>
|
||||
|
@ -27,6 +27,7 @@ public:
|
|||
Small = 0,
|
||||
Large,
|
||||
LargeBold,
|
||||
Medium,
|
||||
|
||||
TextFormatCount
|
||||
};
|
||||
|
@ -52,7 +53,7 @@ public:
|
|||
};
|
||||
|
||||
public:
|
||||
StatusDisplay(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources);
|
||||
StatusDisplay(const std::shared_ptr<DXHelper::DeviceResourcesCommon>& deviceResources);
|
||||
|
||||
void Update(float deltaTimeInSeconds);
|
||||
|
||||
|
@ -102,6 +103,29 @@ public:
|
|||
return m_positionImage;
|
||||
}
|
||||
|
||||
void UpdateTextScale(
|
||||
winrt::Windows::Graphics::Holographic::HolographicStereoTransform holoTransform,
|
||||
float screenWidth,
|
||||
float screenHeight,
|
||||
float quadFov,
|
||||
float heightRatio = 1.0f);
|
||||
|
||||
// Get default FOV for the text quad in degree.
|
||||
float GetDefaultQuadFov()
|
||||
{
|
||||
return m_defaultQuadFov;
|
||||
}
|
||||
// Get statistics FOV for the text quad in degree.
|
||||
float GetStatisticsFov()
|
||||
{
|
||||
return m_statisticsFov;
|
||||
}
|
||||
// Get the statistics height ratio.
|
||||
float GetStatisticsHeightRatio()
|
||||
{
|
||||
return m_statisticsHeightRatio;
|
||||
}
|
||||
|
||||
private:
|
||||
// Runtime representation of a text line.
|
||||
struct RuntimeLine
|
||||
|
@ -124,14 +148,13 @@ private:
|
|||
winrt::Windows::Foundation::Numerics::float3 position,
|
||||
winrt::Windows::Foundation::Numerics::float3 lastPosition);
|
||||
|
||||
|
||||
winrt::com_ptr<ID2D1SolidColorBrush> m_brushes[TextColorCount] = {};
|
||||
winrt::com_ptr<IDWriteTextFormat> m_textFormats[TextFormatCount] = {};
|
||||
std::vector<RuntimeLine> m_lines;
|
||||
std::mutex m_lineMutex;
|
||||
|
||||
// Cached pointer to device resources.
|
||||
std::shared_ptr<DXHelper::DeviceResources> m_deviceResources;
|
||||
std::shared_ptr<DXHelper::DeviceResourcesCommon> m_deviceResources;
|
||||
|
||||
// Resources related to text rendering.
|
||||
winrt::com_ptr<ID3D11Texture2D> m_textTexture;
|
||||
|
@ -155,6 +178,7 @@ private:
|
|||
|
||||
winrt::com_ptr<ID3D11SamplerState> m_textSamplerState;
|
||||
winrt::com_ptr<ID3D11BlendState> m_textAlphaBlendState;
|
||||
winrt::com_ptr<ID3D11DepthStencilState> m_depthStencilState;
|
||||
|
||||
// System resources for quad geometry.
|
||||
ModelConstantBuffer m_modelConstantBufferDataImage = {};
|
||||
|
@ -178,4 +202,28 @@ private:
|
|||
const float c_lerpRate = 4.0f;
|
||||
|
||||
bool m_imageEnabled = true;
|
||||
|
||||
// The distance to the camera in fwd-direction.
|
||||
float m_statusDisplayDistance = 1.0f;
|
||||
// The view Projection matrix.
|
||||
DirectX::XMFLOAT4X4 m_projection;
|
||||
|
||||
// Default size, gets adjusted based on HMD.
|
||||
int m_textTextureWidth = 128;
|
||||
int m_textTextureHeight = 128;
|
||||
|
||||
// Default size, gets adjusted based on the HMD and FOV.
|
||||
float m_virtualDisplaySizeInchX = 10.0f;
|
||||
float m_virtualDisplaySizeInchY = 10.0f;
|
||||
|
||||
// The current FOV for the text quad in degree.
|
||||
float m_currentQuadFov{};
|
||||
// The current height ratio of the quad.
|
||||
float m_currentHeightRatio{};
|
||||
// The default FOV for the text quad in degree.
|
||||
float m_defaultQuadFov = 25.0f;
|
||||
// The statistics FOV for the text quad in degree.
|
||||
float m_statisticsFov = 23.0f;
|
||||
// The height ratio for the statistics quad in percent.
|
||||
float m_statisticsHeightRatio = 0.4f;
|
||||
};
|
||||
|
|
|
@ -1,395 +0,0 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "DeviceResources.h"
|
||||
|
||||
using namespace D2D1;
|
||||
using namespace winrt::Windows::Graphics::DirectX::Direct3D11;
|
||||
using namespace winrt::Windows::Graphics::Display;
|
||||
using namespace winrt::Windows::Graphics::Holographic;
|
||||
|
||||
namespace DXHelper
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
// Check for SDK Layer support.
|
||||
inline bool SdkLayersAvailable()
|
||||
{
|
||||
HRESULT hr = D3D11CreateDevice(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device.
|
||||
0,
|
||||
D3D11_CREATE_DEVICE_DEBUG, // Check for the SDK layers.
|
||||
nullptr, // Any feature level will do.
|
||||
0,
|
||||
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
|
||||
nullptr, // No need to keep the D3D device reference.
|
||||
nullptr, // No need to know the feature level.
|
||||
nullptr // No need to keep the D3D device context reference.
|
||||
);
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Constructor for DeviceResources.
|
||||
DeviceResources::DeviceResources()
|
||||
{
|
||||
CreateDeviceIndependentResources();
|
||||
}
|
||||
|
||||
DeviceResources::~DeviceResources()
|
||||
{
|
||||
UnregisterHolographicEventHandlers();
|
||||
}
|
||||
|
||||
// Configures resources that don't depend on the Direct3D device.
|
||||
void DeviceResources::CreateDeviceIndependentResources()
|
||||
{
|
||||
// Initialize Direct2D resources.
|
||||
D2D1_FACTORY_OPTIONS options{};
|
||||
|
||||
#if defined(_DEBUG)
|
||||
// If the project is in a debug build, enable Direct2D debugging via SDK Layers.
|
||||
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
|
||||
#endif
|
||||
|
||||
// Initialize the Direct2D Factory.
|
||||
m_d2dFactory = nullptr;
|
||||
winrt::check_hresult(
|
||||
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory2), &options, m_d2dFactory.put_void()));
|
||||
|
||||
// Initialize the DirectWrite Factory.
|
||||
m_dwriteFactory = nullptr;
|
||||
winrt::check_hresult(DWriteCreateFactory(
|
||||
DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory2), reinterpret_cast<IUnknown**>(m_dwriteFactory.put_void())));
|
||||
|
||||
// Initialize the Windows Imaging Component (WIC) Factory.
|
||||
m_wicFactory = nullptr;
|
||||
winrt::check_hresult(CoCreateInstance(CLSID_WICImagingFactory2, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(m_wicFactory.put())));
|
||||
}
|
||||
|
||||
void DeviceResources::SetWindow(const winrt::Windows::UI::Core::CoreWindow& window)
|
||||
{
|
||||
UnregisterHolographicEventHandlers();
|
||||
|
||||
m_holographicSpace = HolographicSpace::CreateForCoreWindow(window);
|
||||
|
||||
InitializeUsingHolographicSpace();
|
||||
|
||||
m_cameraAddedToken = m_holographicSpace.CameraAdded({this, &DeviceResources::OnCameraAdded});
|
||||
m_cameraRemovedToken = m_holographicSpace.CameraRemoved({this, &DeviceResources::OnCameraRemoved});
|
||||
}
|
||||
|
||||
void DeviceResources::InitializeUsingHolographicSpace()
|
||||
{
|
||||
// The holographic space might need to determine which adapter supports
|
||||
// holograms, in which case it will specify a non-zero PrimaryAdapterId.
|
||||
LUID id = {m_holographicSpace.PrimaryAdapterId().LowPart, m_holographicSpace.PrimaryAdapterId().HighPart};
|
||||
|
||||
// When a primary adapter ID is given to the app, the app should find
|
||||
// the corresponding DXGI adapter and use it to create Direct3D devices
|
||||
// and device contexts. Otherwise, there is no restriction on the DXGI
|
||||
// adapter the app can use.
|
||||
if ((id.HighPart != 0) || (id.LowPart != 0))
|
||||
{
|
||||
UINT createFlags = 0;
|
||||
#ifdef DEBUG
|
||||
if (SdkLayersAvailable())
|
||||
{
|
||||
createFlags |= DXGI_CREATE_FACTORY_DEBUG;
|
||||
}
|
||||
#endif
|
||||
// Create the DXGI factory.
|
||||
winrt::com_ptr<IDXGIFactory1> dxgiFactory;
|
||||
winrt::check_hresult(CreateDXGIFactory2(createFlags, IID_PPV_ARGS(dxgiFactory.put())));
|
||||
winrt::com_ptr<IDXGIFactory4> dxgiFactory4;
|
||||
dxgiFactory.as(dxgiFactory4);
|
||||
|
||||
// Retrieve the adapter specified by the holographic space.
|
||||
m_dxgiAdapter = nullptr;
|
||||
winrt::check_hresult(dxgiFactory4->EnumAdapterByLuid(id, IID_PPV_ARGS(m_dxgiAdapter.put())));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dxgiAdapter = nullptr;
|
||||
}
|
||||
|
||||
CreateDeviceResources();
|
||||
|
||||
m_holographicSpace.SetDirect3D11Device(m_d3dInteropDevice);
|
||||
}
|
||||
|
||||
// Configures the Direct3D device, and stores handles to it and the device context.
|
||||
void DeviceResources::CreateDeviceResources()
|
||||
{
|
||||
// This flag adds support for surfaces with a different color channel ordering
|
||||
// than the API default. It is required for compatibility with Direct2D.
|
||||
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
|
||||
#if defined(_DEBUG)
|
||||
if (SdkLayersAvailable())
|
||||
{
|
||||
// If the project is in a debug build, enable debugging via SDK Layers with this flag.
|
||||
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
}
|
||||
#endif
|
||||
|
||||
// This array defines the set of DirectX hardware feature levels this app will support.
|
||||
// Note the ordering should be preserved.
|
||||
// Note that HoloLens supports feature level 11.1. The HoloLens emulator is also capable
|
||||
// of running on graphics cards starting with feature level 10.0.
|
||||
D3D_FEATURE_LEVEL featureLevels[] = {D3D_FEATURE_LEVEL_12_1,
|
||||
D3D_FEATURE_LEVEL_12_0,
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0};
|
||||
|
||||
// Create the Direct3D 11 API device object and a corresponding context.
|
||||
winrt::com_ptr<ID3D11Device> device;
|
||||
winrt::com_ptr<ID3D11DeviceContext> context;
|
||||
|
||||
const D3D_DRIVER_TYPE driverType = m_dxgiAdapter == nullptr ? D3D_DRIVER_TYPE_HARDWARE : D3D_DRIVER_TYPE_UNKNOWN;
|
||||
const HRESULT hr = D3D11CreateDevice(
|
||||
m_dxgiAdapter.get(), // Either nullptr, or the primary adapter determined by Windows Holographic.
|
||||
driverType, // Create a device using the hardware graphics driver.
|
||||
0, // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE.
|
||||
creationFlags, // Set debug and Direct2D compatibility flags.
|
||||
featureLevels, // List of feature levels this app can support.
|
||||
ARRAYSIZE(featureLevels), // Size of the list above.
|
||||
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
|
||||
device.put(), // Returns the Direct3D device created.
|
||||
&m_d3dFeatureLevel, // Returns feature level of device created.
|
||||
context.put() // Returns the device immediate context.
|
||||
);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// If the initialization fails, fall back to the WARP device.
|
||||
// For more information on WARP, see:
|
||||
// http://go.microsoft.com/fwlink/?LinkId=286690
|
||||
winrt::check_hresult(D3D11CreateDevice(
|
||||
nullptr, // Use the default DXGI adapter for WARP.
|
||||
D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device.
|
||||
0,
|
||||
creationFlags,
|
||||
featureLevels,
|
||||
ARRAYSIZE(featureLevels),
|
||||
D3D11_SDK_VERSION,
|
||||
device.put(),
|
||||
&m_d3dFeatureLevel,
|
||||
context.put()));
|
||||
}
|
||||
|
||||
// Store pointers to the Direct3D device and immediate context.
|
||||
device.as(m_d3dDevice);
|
||||
context.as(m_d3dContext);
|
||||
|
||||
|
||||
// Enable multithread protection for video decoding.
|
||||
winrt::com_ptr<ID3D10Multithread> multithread;
|
||||
device.as(multithread);
|
||||
multithread->SetMultithreadProtected(true);
|
||||
|
||||
// Acquire the DXGI interface for the Direct3D device.
|
||||
winrt::com_ptr<IDXGIDevice3> dxgiDevice;
|
||||
m_d3dDevice.as(dxgiDevice);
|
||||
|
||||
// Wrap the native device using a WinRT interop object.
|
||||
winrt::com_ptr<::IInspectable> object;
|
||||
winrt::check_hresult(
|
||||
CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.get(), reinterpret_cast<IInspectable**>(winrt::put_abi(object))));
|
||||
m_d3dInteropDevice = object.as<IDirect3DDevice>();
|
||||
|
||||
// Cache the DXGI adapter.
|
||||
// This is for the case of no preferred DXGI adapter, or fallback to WARP.
|
||||
winrt::com_ptr<IDXGIAdapter> dxgiAdapter;
|
||||
winrt::check_hresult(dxgiDevice->GetAdapter(dxgiAdapter.put()));
|
||||
dxgiAdapter.as(m_dxgiAdapter);
|
||||
|
||||
// Check for device support for the optional feature that allows setting the render target array index from the vertex shader stage.
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS3 options;
|
||||
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &options, sizeof(options));
|
||||
if (options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer)
|
||||
{
|
||||
m_supportsVprt = true;
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceResources::OnCameraAdded(
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace const& sender,
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpaceCameraAddedEventArgs const& args)
|
||||
{
|
||||
UseHolographicCameraResources(
|
||||
[this, camera = args.Camera()](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
cameraResourceMap[camera.Id()] = std::make_unique<CameraResources>(camera);
|
||||
});
|
||||
}
|
||||
|
||||
void DeviceResources::OnCameraRemoved(
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace const& sender,
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpaceCameraRemovedEventArgs const& args)
|
||||
{
|
||||
UseHolographicCameraResources(
|
||||
[this, camera = args.Camera()](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
CameraResources* pCameraResources = cameraResourceMap[camera.Id()].get();
|
||||
|
||||
if (pCameraResources != nullptr)
|
||||
{
|
||||
pCameraResources->ReleaseResourcesForBackBuffer(this);
|
||||
cameraResourceMap.erase(camera.Id());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void DeviceResources::UnregisterHolographicEventHandlers()
|
||||
{
|
||||
if (m_holographicSpace != nullptr)
|
||||
{
|
||||
// Clear previous event registrations.
|
||||
m_holographicSpace.CameraAdded(m_cameraAddedToken);
|
||||
m_cameraAddedToken = {};
|
||||
m_holographicSpace.CameraRemoved(m_cameraRemovedToken);
|
||||
m_cameraRemovedToken = {};
|
||||
}
|
||||
}
|
||||
|
||||
// Validates the back buffer for each HolographicCamera and recreates
|
||||
// resources for back buffers that have changed.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DeviceResources::EnsureCameraResources(HolographicFrame frame, HolographicFramePrediction prediction)
|
||||
{
|
||||
UseHolographicCameraResources([this, frame, prediction](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
for (HolographicCameraPose const& cameraPose : prediction.CameraPoses())
|
||||
{
|
||||
HolographicCameraRenderingParameters renderingParameters = frame.GetRenderingParameters(cameraPose);
|
||||
CameraResources* pCameraResources = cameraResourceMap[cameraPose.HolographicCamera().Id()].get();
|
||||
|
||||
pCameraResources->CreateResourcesForBackBuffer(this, renderingParameters);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Recreate all device resources and set them back to the current state.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DeviceResources::HandleDeviceLost()
|
||||
{
|
||||
if (m_deviceNotify != nullptr)
|
||||
{
|
||||
m_deviceNotify->OnDeviceLost();
|
||||
}
|
||||
|
||||
UseHolographicCameraResources([this](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
for (auto& pair : cameraResourceMap)
|
||||
{
|
||||
CameraResources* pCameraResources = pair.second.get();
|
||||
pCameraResources->ReleaseResourcesForBackBuffer(this);
|
||||
}
|
||||
});
|
||||
|
||||
InitializeUsingHolographicSpace();
|
||||
|
||||
if (m_deviceNotify != nullptr)
|
||||
{
|
||||
m_deviceNotify->OnDeviceRestored();
|
||||
}
|
||||
}
|
||||
|
||||
// Register our DeviceNotify to be informed on device lost and creation.
|
||||
void DeviceResources::RegisterDeviceNotify(IDeviceNotify* deviceNotify)
|
||||
{
|
||||
m_deviceNotify = deviceNotify;
|
||||
}
|
||||
|
||||
// Call this method when the app suspends. It provides a hint to the driver that the app
|
||||
// is entering an idle state and that temporary buffers can be reclaimed for use by other apps.
|
||||
void DeviceResources::Trim()
|
||||
{
|
||||
if (m_d3dContext)
|
||||
{
|
||||
m_d3dContext->ClearState();
|
||||
}
|
||||
|
||||
if (m_d3dDevice)
|
||||
{
|
||||
winrt::com_ptr<IDXGIDevice3> dxgiDevice;
|
||||
m_d3dDevice.as(dxgiDevice);
|
||||
dxgiDevice->Trim();
|
||||
}
|
||||
}
|
||||
|
||||
// Present the contents of the swap chain to the screen.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DeviceResources::Present(HolographicFrame frame)
|
||||
{
|
||||
HolographicFramePresentResult presentResult =
|
||||
frame.PresentUsingCurrentPrediction(HolographicFramePresentWaitBehavior::DoNotWaitForFrameToFinish);
|
||||
|
||||
// Note, by not waiting on PresentUsingCurrentPrediction and instead using WaitForNextFrameReadyWithHeadStart we avoid going into
|
||||
// pipelined mode.
|
||||
try
|
||||
{
|
||||
// WaitForNextFrameReadyWithHeadStart has been added in 10.0.17763.0.
|
||||
if (!m_useLegacyWaitBehavior)
|
||||
{
|
||||
m_holographicSpace.WaitForNextFrameReadyWithHeadStart(winrt::Windows::Foundation::TimeSpan(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.WaitForFrameToFinish();
|
||||
}
|
||||
}
|
||||
catch (winrt::hresult_error& err)
|
||||
{
|
||||
switch (err.code())
|
||||
{
|
||||
case DXGI_ERROR_DEVICE_HUNG:
|
||||
case DXGI_ERROR_DEVICE_REMOVED:
|
||||
case DXGI_ERROR_DEVICE_RESET:
|
||||
presentResult = HolographicFramePresentResult::DeviceRemoved;
|
||||
break;
|
||||
|
||||
default:
|
||||
try
|
||||
{
|
||||
m_useLegacyWaitBehavior = true;
|
||||
frame.WaitForFrameToFinish();
|
||||
}
|
||||
catch (winrt::hresult_error& err2)
|
||||
{
|
||||
switch (err2.code())
|
||||
{
|
||||
case DXGI_ERROR_DEVICE_HUNG:
|
||||
case DXGI_ERROR_DEVICE_REMOVED:
|
||||
case DXGI_ERROR_DEVICE_RESET:
|
||||
presentResult = HolographicFramePresentResult::DeviceRemoved;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw err2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// The PresentUsingCurrentPrediction API will detect when the graphics device
|
||||
// changes or becomes invalid. When this happens, it is considered a Direct3D
|
||||
// device lost scenario.
|
||||
if (presentResult == HolographicFramePresentResult::DeviceRemoved)
|
||||
{
|
||||
// The Direct3D device, context, and resources should be recreated.
|
||||
HandleDeviceLost();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace DXHelper
|
|
@ -1,182 +0,0 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CameraResources.h"
|
||||
#include <winrt/Windows.Graphics.Holographic.h>
|
||||
|
||||
namespace DXHelper
|
||||
{
|
||||
// Provides an interface for an application that owns DeviceResources to be notified of the device being lost or created.
|
||||
interface IDeviceNotify
|
||||
{
|
||||
virtual void OnDeviceLost() = 0;
|
||||
virtual void OnDeviceRestored() = 0;
|
||||
};
|
||||
|
||||
// Creates and manages a Direct3D device and immediate context, Direct2D device and context (for debug), and the holographic swap chain.
|
||||
class DeviceResources
|
||||
{
|
||||
public:
|
||||
DeviceResources();
|
||||
~DeviceResources();
|
||||
|
||||
// Public methods related to Direct3D devices.
|
||||
void HandleDeviceLost();
|
||||
void RegisterDeviceNotify(IDeviceNotify* deviceNotify);
|
||||
void Trim();
|
||||
void Present(winrt::Windows::Graphics::Holographic::HolographicFrame frame);
|
||||
|
||||
void SetWindow(const winrt::Windows::UI::Core::CoreWindow& window);
|
||||
|
||||
void EnsureCameraResources(
|
||||
winrt::Windows::Graphics::Holographic::HolographicFrame frame,
|
||||
winrt::Windows::Graphics::Holographic::HolographicFramePrediction prediction);
|
||||
|
||||
// Holographic accessors.
|
||||
template <typename LCallback>
|
||||
void UseHolographicCameraResources(LCallback const& callback);
|
||||
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice GetD3DInteropDevice() const
|
||||
{
|
||||
return m_d3dInteropDevice;
|
||||
}
|
||||
|
||||
// D3D accessors.
|
||||
ID3D11Device4* GetD3DDevice() const
|
||||
{
|
||||
return m_d3dDevice.get();
|
||||
}
|
||||
template <typename F>
|
||||
auto UseD3DDeviceContext(F func) const
|
||||
{
|
||||
std::scoped_lock lock(m_d3dContextMutex);
|
||||
return func(m_d3dContext.get());
|
||||
}
|
||||
D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const
|
||||
{
|
||||
return m_d3dFeatureLevel;
|
||||
}
|
||||
bool GetDeviceSupportsVprt() const
|
||||
{
|
||||
return m_supportsVprt;
|
||||
}
|
||||
|
||||
// DXGI acessors.
|
||||
IDXGIAdapter3* GetDXGIAdapter() const
|
||||
{
|
||||
return m_dxgiAdapter.get();
|
||||
}
|
||||
|
||||
// D2D accessors.
|
||||
ID2D1Factory2* GetD2DFactory() const
|
||||
{
|
||||
return m_d2dFactory.get();
|
||||
}
|
||||
IDWriteFactory2* GetDWriteFactory() const
|
||||
{
|
||||
return m_dwriteFactory.get();
|
||||
}
|
||||
IWICImagingFactory2* GetWicImagingFactory() const
|
||||
{
|
||||
return m_wicFactory.get();
|
||||
}
|
||||
|
||||
// Holographic accessors.
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace GetHolographicSpace()
|
||||
{
|
||||
return m_holographicSpace;
|
||||
}
|
||||
|
||||
private:
|
||||
// Private methods related to the Direct3D device, and resources based on that device.
|
||||
void CreateDeviceIndependentResources();
|
||||
void InitializeUsingHolographicSpace();
|
||||
void CreateDeviceResources();
|
||||
|
||||
void OnCameraAdded(
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace const& sender,
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpaceCameraAddedEventArgs const& args);
|
||||
|
||||
void OnCameraRemoved(
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace const& sender,
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpaceCameraRemovedEventArgs const& args);
|
||||
|
||||
void UnregisterHolographicEventHandlers();
|
||||
|
||||
// Direct3D objects.
|
||||
winrt::com_ptr<ID3D11Device4> m_d3dDevice;
|
||||
mutable std::recursive_mutex m_d3dContextMutex;
|
||||
winrt::com_ptr<ID3D11DeviceContext3> m_d3dContext;
|
||||
winrt::com_ptr<IDXGIAdapter3> m_dxgiAdapter;
|
||||
|
||||
// Direct3D interop objects.
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice m_d3dInteropDevice;
|
||||
|
||||
// Direct2D factories.
|
||||
winrt::com_ptr<ID2D1Factory2> m_d2dFactory;
|
||||
winrt::com_ptr<IDWriteFactory2> m_dwriteFactory;
|
||||
winrt::com_ptr<IWICImagingFactory2> m_wicFactory;
|
||||
|
||||
// The holographic space provides a preferred DXGI adapter ID.
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace m_holographicSpace = nullptr;
|
||||
|
||||
// Properties of the Direct3D device currently in use.
|
||||
D3D_FEATURE_LEVEL m_d3dFeatureLevel = D3D_FEATURE_LEVEL_10_0;
|
||||
|
||||
// The IDeviceNotify can be held directly as it owns the DeviceResources.
|
||||
IDeviceNotify* m_deviceNotify = nullptr;
|
||||
|
||||
// Whether or not the current Direct3D device supports the optional feature
|
||||
// for setting the render target array index from the vertex shader stage.
|
||||
bool m_supportsVprt = false;
|
||||
|
||||
bool m_useLegacyWaitBehavior = false;
|
||||
|
||||
// Back buffer resources, etc. for attached holographic cameras.
|
||||
std::map<UINT32, std::unique_ptr<CameraResources>> m_cameraResources;
|
||||
std::mutex m_cameraResourcesLock;
|
||||
|
||||
winrt::event_token m_cameraAddedToken;
|
||||
winrt::event_token m_cameraRemovedToken;
|
||||
};
|
||||
} // namespace DXHelper
|
||||
|
||||
// Device-based resources for holographic cameras are stored in a std::map. Access this list by providing a
|
||||
// callback to this function, and the std::map will be guarded from add and remove
|
||||
// events until the callback returns. The callback is processed immediately and must
|
||||
// not contain any nested calls to UseHolographicCameraResources.
|
||||
// The callback takes a parameter of type std::map<UINT32, std::unique_ptr<CameraResources>>&
|
||||
// through which the list of cameras will be accessed.
|
||||
template <typename LCallback>
|
||||
void DXHelper::DeviceResources::UseHolographicCameraResources(LCallback const& callback)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_cameraResourcesLock);
|
||||
callback(m_cameraResources);
|
||||
}
|
||||
catch (const winrt::hresult_error& err)
|
||||
{
|
||||
switch (err.code())
|
||||
{
|
||||
case DXGI_ERROR_DEVICE_HUNG:
|
||||
case DXGI_ERROR_DEVICE_REMOVED:
|
||||
case DXGI_ERROR_DEVICE_RESET:
|
||||
HandleDeviceLost();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "DeviceResourcesCommon.h"
|
||||
|
||||
#include <d2d1_2.h>
|
||||
#include <d3d11_4.h>
|
||||
#include <dwrite_2.h>
|
||||
#include <dxgi1_4.h>
|
||||
#include <wincodec.h>
|
||||
|
||||
namespace DXHelper
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
// Check for SDK Layer support.
|
||||
inline bool SdkLayersAvailable()
|
||||
{
|
||||
HRESULT hr = D3D11CreateDevice(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device.
|
||||
0,
|
||||
D3D11_CREATE_DEVICE_DEBUG, // Check for the SDK layers.
|
||||
nullptr, // Any feature level will do.
|
||||
0,
|
||||
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
|
||||
nullptr, // No need to keep the D3D device reference.
|
||||
nullptr, // No need to know the feature level.
|
||||
nullptr // No need to keep the D3D device context reference.
|
||||
);
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Constructor for DeviceResources.
|
||||
DeviceResourcesCommon::DeviceResourcesCommon()
|
||||
{
|
||||
CreateDeviceIndependentResources();
|
||||
}
|
||||
|
||||
DeviceResourcesCommon::~DeviceResourcesCommon()
|
||||
{
|
||||
}
|
||||
|
||||
// Configures resources that don't depend on the Direct3D device.
|
||||
void DeviceResourcesCommon::CreateDeviceIndependentResources()
|
||||
{
|
||||
// Initialize Direct2D resources.
|
||||
D2D1_FACTORY_OPTIONS options{};
|
||||
|
||||
#if defined(_DEBUG)
|
||||
// If the project is in a debug build, enable Direct2D debugging via SDK Layers.
|
||||
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
|
||||
#endif
|
||||
|
||||
// Initialize the Direct2D Factory.
|
||||
m_d2dFactory = nullptr;
|
||||
winrt::check_hresult(
|
||||
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory2), &options, m_d2dFactory.put_void()));
|
||||
|
||||
// Initialize the DirectWrite Factory.
|
||||
m_dwriteFactory = nullptr;
|
||||
winrt::check_hresult(DWriteCreateFactory(
|
||||
DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory2), reinterpret_cast<IUnknown**>(m_dwriteFactory.put_void())));
|
||||
|
||||
// Initialize the Windows Imaging Component (WIC) Factory.
|
||||
m_wicFactory = nullptr;
|
||||
winrt::check_hresult(CoCreateInstance(CLSID_WICImagingFactory2, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(m_wicFactory.put())));
|
||||
}
|
||||
|
||||
// Configures the Direct3D device, and stores handles to it and the device context.
|
||||
void DeviceResourcesCommon::CreateDeviceResources()
|
||||
{
|
||||
// This flag adds support for surfaces with a different color channel ordering
|
||||
// than the API default. It is required for compatibility with Direct2D.
|
||||
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
|
||||
#if defined(_DEBUG)
|
||||
if (SdkLayersAvailable())
|
||||
{
|
||||
// If the project is in a debug build, enable debugging via SDK Layers with this flag.
|
||||
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
}
|
||||
#endif
|
||||
|
||||
// This array defines the set of DirectX hardware feature levels this app will support.
|
||||
// Note the ordering should be preserved.
|
||||
// Note that HoloLens supports feature level 11.1. The HoloLens emulator is also capable
|
||||
// of running on graphics cards starting with feature level 10.0.
|
||||
D3D_FEATURE_LEVEL featureLevels[] = {
|
||||
D3D_FEATURE_LEVEL_12_1,
|
||||
D3D_FEATURE_LEVEL_12_0,
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0};
|
||||
|
||||
// Create the Direct3D 11 API device object and a corresponding context.
|
||||
winrt::com_ptr<ID3D11Device> device;
|
||||
winrt::com_ptr<ID3D11DeviceContext> context;
|
||||
|
||||
const D3D_DRIVER_TYPE driverType = m_dxgiAdapter == nullptr ? D3D_DRIVER_TYPE_HARDWARE : D3D_DRIVER_TYPE_UNKNOWN;
|
||||
const HRESULT hr = D3D11CreateDevice(
|
||||
m_dxgiAdapter.get(), // Either nullptr, or the primary adapter determined by Windows Holographic.
|
||||
driverType, // Create a device using the hardware graphics driver.
|
||||
0, // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE.
|
||||
creationFlags, // Set debug and Direct2D compatibility flags.
|
||||
featureLevels, // List of feature levels this app can support.
|
||||
ARRAYSIZE(featureLevels), // Size of the list above.
|
||||
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
|
||||
device.put(), // Returns the Direct3D device created.
|
||||
&m_d3dFeatureLevel, // Returns feature level of device created.
|
||||
context.put() // Returns the device immediate context.
|
||||
);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// If the initialization fails, fall back to the WARP device.
|
||||
// For more information on WARP, see:
|
||||
// http://go.microsoft.com/fwlink/?LinkId=286690
|
||||
winrt::check_hresult(D3D11CreateDevice(
|
||||
nullptr, // Use the default DXGI adapter for WARP.
|
||||
D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device.
|
||||
0,
|
||||
creationFlags,
|
||||
featureLevels,
|
||||
ARRAYSIZE(featureLevels),
|
||||
D3D11_SDK_VERSION,
|
||||
device.put(),
|
||||
&m_d3dFeatureLevel,
|
||||
context.put()));
|
||||
}
|
||||
|
||||
// Store pointers to the Direct3D device and immediate context.
|
||||
device.as(m_d3dDevice);
|
||||
context.as(m_d3dContext);
|
||||
|
||||
// Enable multithread protection for video decoding.
|
||||
winrt::com_ptr<ID3D10Multithread> multithread;
|
||||
device.as(multithread);
|
||||
multithread->SetMultithreadProtected(true);
|
||||
|
||||
// Acquire the DXGI interface for the Direct3D device.
|
||||
winrt::com_ptr<IDXGIDevice3> dxgiDevice;
|
||||
m_d3dDevice.as(dxgiDevice);
|
||||
|
||||
// Cache the DXGI adapter.
|
||||
// This is for the case of no preferred DXGI adapter, or fallback to WARP.
|
||||
winrt::com_ptr<IDXGIAdapter> dxgiAdapter;
|
||||
winrt::check_hresult(dxgiDevice->GetAdapter(dxgiAdapter.put()));
|
||||
dxgiAdapter.as(m_dxgiAdapter);
|
||||
|
||||
// Check for device support for the optional feature that allows setting the render target array index from the vertex shader stage.
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS3 options;
|
||||
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &options, sizeof(options));
|
||||
if (options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer)
|
||||
{
|
||||
m_supportsVprt = true;
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceResourcesCommon::NotifyDeviceLost()
|
||||
{
|
||||
if (m_deviceNotify != nullptr)
|
||||
{
|
||||
m_deviceNotify->OnDeviceLost();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceResourcesCommon::NotifyDeviceRestored()
|
||||
{
|
||||
if (m_deviceNotify != nullptr)
|
||||
{
|
||||
m_deviceNotify->OnDeviceRestored();
|
||||
}
|
||||
}
|
||||
|
||||
// Register our DeviceNotify to be informed on device lost and creation.
|
||||
void DeviceResourcesCommon::RegisterDeviceNotify(IDeviceNotify* deviceNotify)
|
||||
{
|
||||
m_deviceNotify = deviceNotify;
|
||||
}
|
||||
|
||||
// Call this method when the app suspends. It provides a hint to the driver that the app
|
||||
// is entering an idle state and that temporary buffers can be reclaimed for use by other apps.
|
||||
void DeviceResourcesCommon::Trim()
|
||||
{
|
||||
if (m_d3dContext)
|
||||
{
|
||||
m_d3dContext->ClearState();
|
||||
}
|
||||
|
||||
if (m_d3dDevice)
|
||||
{
|
||||
winrt::com_ptr<IDXGIDevice3> dxgiDevice;
|
||||
m_d3dDevice.as(dxgiDevice);
|
||||
dxgiDevice->Trim();
|
||||
}
|
||||
}
|
||||
} // namespace DXHelper
|
|
@ -0,0 +1,169 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
#include <winrt/base.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (std::extent<decltype(a)>::value)
|
||||
|
||||
struct ID3D11Device4;
|
||||
struct IDXGIAdapter3;
|
||||
struct ID2D1Factory2;
|
||||
struct IDWriteFactory2;
|
||||
struct IWICImagingFactory2;
|
||||
struct ID3D11DeviceContext3;
|
||||
|
||||
namespace DXHelper
|
||||
{
|
||||
// Provides an interface for an application that owns DeviceResources to be notified of the device being lost or created.
|
||||
struct IDeviceNotify
|
||||
{
|
||||
virtual void OnDeviceLost() = 0;
|
||||
virtual void OnDeviceRestored() = 0;
|
||||
};
|
||||
|
||||
// Creates and manages a Direct3D device and immediate context, Direct2D device and context (for debug), and the holographic swap chain.
|
||||
class DeviceResourcesCommon
|
||||
{
|
||||
public:
|
||||
DeviceResourcesCommon();
|
||||
virtual ~DeviceResourcesCommon();
|
||||
|
||||
// Public methods related to Direct3D devices.
|
||||
void RegisterDeviceNotify(IDeviceNotify* deviceNotify);
|
||||
void Trim();
|
||||
|
||||
// D3D accessors.
|
||||
ID3D11Device4* GetD3DDevice() const
|
||||
{
|
||||
return m_d3dDevice.get();
|
||||
}
|
||||
template <typename F>
|
||||
auto UseD3DDeviceContext(F func) const
|
||||
{
|
||||
std::scoped_lock lock(m_d3dContextMutex);
|
||||
return func(m_d3dContext.get());
|
||||
}
|
||||
D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const
|
||||
{
|
||||
return m_d3dFeatureLevel;
|
||||
}
|
||||
bool GetDeviceSupportsVprt() const
|
||||
{
|
||||
return m_supportsVprt;
|
||||
}
|
||||
|
||||
// DXGI acessors.
|
||||
IDXGIAdapter3* GetDXGIAdapter() const
|
||||
{
|
||||
return m_dxgiAdapter.get();
|
||||
}
|
||||
|
||||
// D2D accessors.
|
||||
ID2D1Factory2* GetD2DFactory() const
|
||||
{
|
||||
return m_d2dFactory.get();
|
||||
}
|
||||
IDWriteFactory2* GetDWriteFactory() const
|
||||
{
|
||||
return m_dwriteFactory.get();
|
||||
}
|
||||
IWICImagingFactory2* GetWicImagingFactory() const
|
||||
{
|
||||
return m_wicFactory.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
// Private methods related to the Direct3D device, and resources based on that device.
|
||||
void CreateDeviceIndependentResources();
|
||||
virtual void CreateDeviceResources();
|
||||
|
||||
void NotifyDeviceLost();
|
||||
void NotifyDeviceRestored();
|
||||
|
||||
// Direct3D objects.
|
||||
winrt::com_ptr<ID3D11Device4> m_d3dDevice;
|
||||
mutable std::recursive_mutex m_d3dContextMutex;
|
||||
winrt::com_ptr<ID3D11DeviceContext3> m_d3dContext;
|
||||
winrt::com_ptr<IDXGIAdapter3> m_dxgiAdapter;
|
||||
|
||||
// Direct2D factories.
|
||||
winrt::com_ptr<ID2D1Factory2> m_d2dFactory;
|
||||
winrt::com_ptr<IDWriteFactory2> m_dwriteFactory;
|
||||
winrt::com_ptr<IWICImagingFactory2> m_wicFactory;
|
||||
|
||||
// Properties of the Direct3D device currently in use.
|
||||
D3D_FEATURE_LEVEL m_d3dFeatureLevel = D3D_FEATURE_LEVEL_10_0;
|
||||
|
||||
// The IDeviceNotify can be held directly as it owns the DeviceResources.
|
||||
IDeviceNotify* m_deviceNotify = nullptr;
|
||||
|
||||
// Whether or not the current Direct3D device supports the optional feature
|
||||
// for setting the render target array index from the vertex shader stage.
|
||||
bool m_supportsVprt = false;
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
void D3D11StoreAndRestoreState(ID3D11DeviceContext* immediateContext, F customRenderingCode)
|
||||
{
|
||||
// Query the d3d11 state before rendering
|
||||
static_assert(
|
||||
sizeof(winrt::com_ptr<ID3D11ShaderResourceView>) == sizeof(void*),
|
||||
"Below code reiles on winrt::com_ptr being exactly one pointer in size");
|
||||
|
||||
winrt::com_ptr<ID3D11VertexShader> vertexShader;
|
||||
winrt::com_ptr<ID3D11GeometryShader> geometryShader;
|
||||
winrt::com_ptr<ID3D11PixelShader> pixelShader;
|
||||
winrt::com_ptr<ID3D11Buffer> vsConstantBuffers[2], psConstantBuffers[3];
|
||||
winrt::com_ptr<ID3D11ShaderResourceView> views[4] = {};
|
||||
winrt::com_ptr<ID3D11SamplerState> psSampler;
|
||||
winrt::com_ptr<ID3D11RasterizerState> rasterizerState;
|
||||
winrt::com_ptr<ID3D11DepthStencilState> depthStencilState;
|
||||
winrt::com_ptr<ID3D11BlendState> blendState;
|
||||
winrt::com_ptr<ID3D11InputLayout> inputLayout;
|
||||
FLOAT blendFactor[4] = {};
|
||||
UINT sampleMask = 0;
|
||||
D3D11_PRIMITIVE_TOPOLOGY primitiveTopoloy = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
UINT stencilRef = 0;
|
||||
|
||||
immediateContext->VSGetShader(vertexShader.put(), nullptr, nullptr);
|
||||
immediateContext->VSGetConstantBuffers(0, ARRAY_SIZE(vsConstantBuffers), reinterpret_cast<ID3D11Buffer**>(vsConstantBuffers));
|
||||
immediateContext->GSGetShader(geometryShader.put(), nullptr, nullptr);
|
||||
immediateContext->PSGetShader(pixelShader.put(), nullptr, nullptr);
|
||||
immediateContext->PSGetShaderResources(0, ARRAY_SIZE(views), reinterpret_cast<ID3D11ShaderResourceView**>(views));
|
||||
immediateContext->PSGetConstantBuffers(0, ARRAY_SIZE(psConstantBuffers), reinterpret_cast<ID3D11Buffer**>(psConstantBuffers));
|
||||
immediateContext->PSGetSamplers(0, 1, psSampler.put());
|
||||
immediateContext->RSGetState(rasterizerState.put());
|
||||
immediateContext->OMGetDepthStencilState(depthStencilState.put(), &stencilRef);
|
||||
immediateContext->OMGetBlendState(blendState.put(), blendFactor, &sampleMask);
|
||||
immediateContext->IAGetPrimitiveTopology(&primitiveTopoloy);
|
||||
immediateContext->IAGetInputLayout(inputLayout.put());
|
||||
|
||||
customRenderingCode();
|
||||
|
||||
// Restore the d3d11 state.
|
||||
immediateContext->VSSetShader(vertexShader.get(), nullptr, 0);
|
||||
immediateContext->VSSetConstantBuffers(0, ARRAY_SIZE(vsConstantBuffers), reinterpret_cast<ID3D11Buffer**>(vsConstantBuffers));
|
||||
immediateContext->GSSetShader(geometryShader.get(), nullptr, 0);
|
||||
immediateContext->PSSetShader(pixelShader.get(), nullptr, 0);
|
||||
immediateContext->PSSetShaderResources(0, ARRAY_SIZE(views), reinterpret_cast<ID3D11ShaderResourceView**>(views));
|
||||
immediateContext->PSSetConstantBuffers(0, ARRAY_SIZE(psConstantBuffers), reinterpret_cast<ID3D11Buffer**>(psConstantBuffers));
|
||||
immediateContext->PSSetSamplers(0, 1, reinterpret_cast<ID3D11SamplerState**>(&psSampler));
|
||||
immediateContext->RSSetState(rasterizerState.get());
|
||||
immediateContext->OMSetDepthStencilState(depthStencilState.get(), stencilRef);
|
||||
immediateContext->OMSetBlendState(blendState.get(), blendFactor, sampleMask);
|
||||
immediateContext->IASetPrimitiveTopology(primitiveTopoloy);
|
||||
immediateContext->IASetInputLayout(inputLayout.get());
|
||||
}
|
||||
} // namespace DXHelper
|
|
@ -0,0 +1,217 @@
|
|||
#include <pch.h>
|
||||
|
||||
#include "CameraResources.h"
|
||||
#include "DeviceResourcesUWP.h"
|
||||
|
||||
using namespace D2D1;
|
||||
using namespace winrt::Windows::Graphics::DirectX::Direct3D11;
|
||||
using namespace winrt::Windows::Graphics::Display;
|
||||
using namespace winrt::Windows::Graphics::Holographic;
|
||||
|
||||
using namespace DXHelper;
|
||||
|
||||
void DeviceResourcesUWP::SetWindow(const winrt::Windows::UI::Core::CoreWindow& window)
|
||||
{
|
||||
UnregisterHolographicEventHandlers();
|
||||
|
||||
m_holographicSpace = HolographicSpace::CreateForCoreWindow(window);
|
||||
|
||||
InitializeUsingHolographicSpace();
|
||||
|
||||
m_cameraAddedToken = m_holographicSpace.CameraAdded({this, &DeviceResourcesUWP::OnCameraAdded});
|
||||
m_cameraRemovedToken = m_holographicSpace.CameraRemoved({this, &DeviceResourcesUWP::OnCameraRemoved});
|
||||
}
|
||||
|
||||
void DeviceResourcesUWP::InitializeUsingHolographicSpace()
|
||||
{
|
||||
// The holographic space might need to determine which adapter supports
|
||||
// holograms, in which case it will specify a non-zero PrimaryAdapterId.
|
||||
LUID id = {m_holographicSpace.PrimaryAdapterId().LowPart, m_holographicSpace.PrimaryAdapterId().HighPart};
|
||||
|
||||
// When a primary adapter ID is given to the app, the app should find
|
||||
// the corresponding DXGI adapter and use it to create Direct3D devices
|
||||
// and device contexts. Otherwise, there is no restriction on the DXGI
|
||||
// adapter the app can use.
|
||||
if ((id.HighPart != 0) || (id.LowPart != 0))
|
||||
{
|
||||
UINT createFlags = 0;
|
||||
#ifdef DEBUG
|
||||
if (SdkLayersAvailable())
|
||||
{
|
||||
createFlags |= DXGI_CREATE_FACTORY_DEBUG;
|
||||
}
|
||||
#endif
|
||||
// Create the DXGI factory.
|
||||
winrt::com_ptr<IDXGIFactory1> dxgiFactory;
|
||||
winrt::check_hresult(CreateDXGIFactory2(createFlags, IID_PPV_ARGS(dxgiFactory.put())));
|
||||
winrt::com_ptr<IDXGIFactory4> dxgiFactory4;
|
||||
dxgiFactory.as(dxgiFactory4);
|
||||
|
||||
// Retrieve the adapter specified by the holographic space.
|
||||
m_dxgiAdapter = nullptr;
|
||||
winrt::check_hresult(dxgiFactory4->EnumAdapterByLuid(id, IID_PPV_ARGS(m_dxgiAdapter.put())));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dxgiAdapter = nullptr;
|
||||
}
|
||||
|
||||
CreateDeviceResources();
|
||||
|
||||
m_holographicSpace.SetDirect3D11Device(m_d3dInteropDevice);
|
||||
}
|
||||
|
||||
void DeviceResourcesUWP::OnCameraAdded(
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace const& sender,
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpaceCameraAddedEventArgs const& args)
|
||||
{
|
||||
UseHolographicCameraResources([this, camera = args.Camera()](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
cameraResourceMap[camera.Id()] = std::make_unique<CameraResources>(camera);
|
||||
});
|
||||
}
|
||||
|
||||
void DeviceResourcesUWP::OnCameraRemoved(
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace const& sender,
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpaceCameraRemovedEventArgs const& args)
|
||||
{
|
||||
UseHolographicCameraResources([this, camera = args.Camera()](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
CameraResources* pCameraResources = cameraResourceMap[camera.Id()].get();
|
||||
|
||||
if (pCameraResources != nullptr)
|
||||
{
|
||||
pCameraResources->ReleaseResourcesForBackBuffer(this);
|
||||
cameraResourceMap.erase(camera.Id());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void DeviceResourcesUWP::UnregisterHolographicEventHandlers()
|
||||
{
|
||||
if (m_holographicSpace != nullptr)
|
||||
{
|
||||
// Clear previous event registrations.
|
||||
m_holographicSpace.CameraAdded(m_cameraAddedToken);
|
||||
m_cameraAddedToken = {};
|
||||
m_holographicSpace.CameraRemoved(m_cameraRemovedToken);
|
||||
m_cameraRemovedToken = {};
|
||||
}
|
||||
}
|
||||
|
||||
// Validates the back buffer for each HolographicCamera and recreates
|
||||
// resources for back buffers that have changed.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DeviceResourcesUWP::EnsureCameraResources(HolographicFrame frame, HolographicFramePrediction prediction)
|
||||
{
|
||||
UseHolographicCameraResources([this, frame, prediction](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
for (HolographicCameraPose const& cameraPose : prediction.CameraPoses())
|
||||
{
|
||||
HolographicCameraRenderingParameters renderingParameters = frame.GetRenderingParameters(cameraPose);
|
||||
CameraResources* pCameraResources = cameraResourceMap[cameraPose.HolographicCamera().Id()].get();
|
||||
|
||||
pCameraResources->CreateResourcesForBackBuffer(this, renderingParameters);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
DeviceResourcesUWP::~DeviceResourcesUWP()
|
||||
{
|
||||
UnregisterHolographicEventHandlers();
|
||||
}
|
||||
|
||||
// Recreate all device resources and set them back to the current state.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DeviceResourcesUWP::HandleDeviceLost()
|
||||
{
|
||||
NotifyDeviceLost();
|
||||
|
||||
UseHolographicCameraResources([this](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
for (auto& pair : cameraResourceMap)
|
||||
{
|
||||
CameraResources* pCameraResources = pair.second.get();
|
||||
pCameraResources->ReleaseResourcesForBackBuffer(this);
|
||||
}
|
||||
});
|
||||
|
||||
InitializeUsingHolographicSpace();
|
||||
|
||||
NotifyDeviceRestored();
|
||||
}
|
||||
|
||||
void DeviceResourcesUWP::CreateDeviceResources()
|
||||
{
|
||||
DeviceResourcesCommon::CreateDeviceResources();
|
||||
|
||||
// Acquire the DXGI interface for the Direct3D device.
|
||||
winrt::com_ptr<IDXGIDevice3> dxgiDevice;
|
||||
m_d3dDevice.as(dxgiDevice);
|
||||
|
||||
// Wrap the native device using a WinRT interop object.
|
||||
winrt::com_ptr<::IInspectable> object;
|
||||
winrt::check_hresult(CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.get(), reinterpret_cast<IInspectable**>(winrt::put_abi(object))));
|
||||
m_d3dInteropDevice = object.as<IDirect3DDevice>();
|
||||
}
|
||||
|
||||
// Present the contents of the swap chain to the screen.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DeviceResourcesUWP::Present(HolographicFrame frame)
|
||||
{
|
||||
HolographicFramePresentResult presentResult =
|
||||
frame.PresentUsingCurrentPrediction(HolographicFramePresentWaitBehavior::DoNotWaitForFrameToFinish);
|
||||
|
||||
// Note, by not waiting on PresentUsingCurrentPrediction and instead using WaitForNextFrameReadyWithHeadStart we avoid going into
|
||||
// pipelined mode.
|
||||
try
|
||||
{
|
||||
// WaitForNextFrameReadyWithHeadStart has been added in 10.0.17763.0.
|
||||
if (!m_useLegacyWaitBehavior)
|
||||
{
|
||||
m_holographicSpace.WaitForNextFrameReadyWithHeadStart(winrt::Windows::Foundation::TimeSpan(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.WaitForFrameToFinish();
|
||||
}
|
||||
}
|
||||
catch (winrt::hresult_error& err)
|
||||
{
|
||||
switch (err.code())
|
||||
{
|
||||
case DXGI_ERROR_DEVICE_HUNG:
|
||||
case DXGI_ERROR_DEVICE_REMOVED:
|
||||
case DXGI_ERROR_DEVICE_RESET:
|
||||
presentResult = HolographicFramePresentResult::DeviceRemoved;
|
||||
break;
|
||||
|
||||
default:
|
||||
try
|
||||
{
|
||||
m_useLegacyWaitBehavior = true;
|
||||
frame.WaitForFrameToFinish();
|
||||
}
|
||||
catch (winrt::hresult_error& err2)
|
||||
{
|
||||
switch (err2.code())
|
||||
{
|
||||
case DXGI_ERROR_DEVICE_HUNG:
|
||||
case DXGI_ERROR_DEVICE_REMOVED:
|
||||
case DXGI_ERROR_DEVICE_RESET:
|
||||
presentResult = HolographicFramePresentResult::DeviceRemoved;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw err2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// The PresentUsingCurrentPrediction API will detect when the graphics device
|
||||
// changes or becomes invalid. When this happens, it is considered a Direct3D
|
||||
// device lost scenario.
|
||||
if (presentResult == HolographicFramePresentResult::DeviceRemoved)
|
||||
{
|
||||
// The Direct3D device, context, and resources should be recreated.
|
||||
HandleDeviceLost();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
#pragma once
|
||||
|
||||
#include "DeviceResourcesCommon.h"
|
||||
|
||||
#include <winrt/Windows.Graphics.Holographic.h>
|
||||
|
||||
namespace DXHelper
|
||||
{
|
||||
class CameraResources;
|
||||
|
||||
class DeviceResourcesUWP : public DeviceResourcesCommon
|
||||
{
|
||||
public:
|
||||
~DeviceResourcesUWP();
|
||||
|
||||
void HandleDeviceLost();
|
||||
void Present(winrt::Windows::Graphics::Holographic::HolographicFrame frame);
|
||||
|
||||
void SetWindow(const winrt::Windows::UI::Core::CoreWindow& window);
|
||||
|
||||
void EnsureCameraResources(
|
||||
winrt::Windows::Graphics::Holographic::HolographicFrame frame,
|
||||
winrt::Windows::Graphics::Holographic::HolographicFramePrediction prediction);
|
||||
|
||||
// Holographic accessors.
|
||||
template <typename LCallback>
|
||||
void UseHolographicCameraResources(LCallback const& callback);
|
||||
|
||||
// Holographic accessors.
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace GetHolographicSpace()
|
||||
{
|
||||
return m_holographicSpace;
|
||||
}
|
||||
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice GetD3DInteropDevice() const
|
||||
{
|
||||
return m_d3dInteropDevice;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void CreateDeviceResources() override;
|
||||
|
||||
private:
|
||||
void InitializeUsingHolographicSpace();
|
||||
void OnCameraAdded(
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace const& sender,
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpaceCameraAddedEventArgs const& args);
|
||||
|
||||
void OnCameraRemoved(
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace const& sender,
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpaceCameraRemovedEventArgs const& args);
|
||||
|
||||
void UnregisterHolographicEventHandlers();
|
||||
|
||||
// Direct3D interop objects.
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice m_d3dInteropDevice;
|
||||
|
||||
// The holographic space provides a preferred DXGI adapter ID.
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace m_holographicSpace = nullptr;
|
||||
|
||||
bool m_useLegacyWaitBehavior = false;
|
||||
|
||||
// Back buffer resources, etc. for attached holographic cameras.
|
||||
std::map<UINT32, std::unique_ptr<CameraResources>> m_cameraResources;
|
||||
std::mutex m_cameraResourcesLock;
|
||||
|
||||
winrt::event_token m_cameraAddedToken;
|
||||
winrt::event_token m_cameraRemovedToken;
|
||||
};
|
||||
} // namespace DXHelper
|
||||
|
||||
// Device-based resources for holographic cameras are stored in a std::map. Access this list by providing a
|
||||
// callback to this function, and the std::map will be guarded from add and remove
|
||||
// events until the callback returns. The callback is processed immediately and must
|
||||
// not contain any nested calls to UseHolographicCameraResources.
|
||||
// The callback takes a parameter of type std::map<UINT32, std::unique_ptr<CameraResources>>&
|
||||
// through which the list of cameras will be accessed.
|
||||
template <typename LCallback>
|
||||
void DXHelper::DeviceResourcesUWP::UseHolographicCameraResources(LCallback const& callback)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_cameraResourcesLock);
|
||||
callback(m_cameraResources);
|
||||
}
|
||||
catch (const winrt::hresult_error& err)
|
||||
{
|
||||
switch (err.code())
|
||||
{
|
||||
case DXGI_ERROR_DEVICE_HUNG:
|
||||
case DXGI_ERROR_DEVICE_REMOVED:
|
||||
case DXGI_ERROR_DEVICE_RESET:
|
||||
HandleDeviceLost();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include "IpAddressUpdater.h"
|
||||
|
||||
using namespace winrt::Windows::Networking;
|
||||
using namespace winrt::Windows::Networking::Connectivity;
|
||||
|
||||
IpAddressUpdater::IpAddressUpdater()
|
||||
{
|
||||
|
@ -24,27 +26,50 @@ IpAddressUpdater::IpAddressUpdater()
|
|||
|
||||
IpAddressUpdater::~IpAddressUpdater() = default;
|
||||
|
||||
winrt::hstring IpAddressUpdater::GetIpAddress()
|
||||
winrt::hstring IpAddressUpdater::GetIpAddress(bool ipv6)
|
||||
{
|
||||
std::lock_guard lockGuard(m_lock);
|
||||
return m_ipAddress;
|
||||
return ipv6 ? m_ipAddressIpv6 : m_ipAddressIpv4;
|
||||
}
|
||||
|
||||
void IpAddressUpdater::UpdateIpAddress(winrt::Windows::Foundation::IInspectable sender)
|
||||
{
|
||||
winrt::hstring ipAddress = L"(No Network Connection)";
|
||||
winrt::Windows::Foundation::Collections::IVectorView<winrt::Windows::Networking::HostName> hostnames =
|
||||
winrt::Windows::Networking::Connectivity::NetworkInformation::GetHostNames();
|
||||
winrt::hstring ipAddressIpv4 = L"";
|
||||
winrt::hstring ipAddressIpv6 = L"";
|
||||
winrt::Windows::Foundation::Collections::IVectorView<HostName> hostnames = NetworkInformation::GetHostNames();
|
||||
|
||||
for (winrt::Windows::Networking::HostName hostname : hostnames)
|
||||
{
|
||||
if (hostname.IPInformation() && hostname.IPInformation().NetworkAdapter() && hostname.CanonicalName().size() <= 15) // IPV4 only
|
||||
auto hostNameType = hostname.Type();
|
||||
if (hostNameType != HostNameType::Ipv4 && hostNameType != HostNameType::Ipv6)
|
||||
{
|
||||
ipAddress = hostname.CanonicalName();
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hostname.IPInformation() && hostname.IPInformation().NetworkAdapter())
|
||||
{
|
||||
if (hostNameType == HostNameType::Ipv6 && ipAddressIpv6.empty())
|
||||
{
|
||||
ipAddressIpv6 = hostname.CanonicalName();
|
||||
}
|
||||
else if (hostNameType == HostNameType::Ipv4 && ipAddressIpv4.empty())
|
||||
{
|
||||
ipAddressIpv4 = hostname.CanonicalName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ipAddressIpv6.empty())
|
||||
{
|
||||
ipAddressIpv6 = L"(No Network Connection)";
|
||||
}
|
||||
|
||||
if (ipAddressIpv4.empty())
|
||||
{
|
||||
ipAddressIpv4 = L"(No Network Connection)";
|
||||
}
|
||||
|
||||
std::lock_guard lockGuard(m_lock);
|
||||
m_ipAddress = ipAddress;
|
||||
m_ipAddressIpv6 = ipAddressIpv6;
|
||||
m_ipAddressIpv4 = ipAddressIpv4;
|
||||
};
|
||||
|
|
|
@ -13,21 +13,21 @@
|
|||
|
||||
#include <winrt/Windows.Networking.Connectivity.h>
|
||||
|
||||
|
||||
class IpAddressUpdater
|
||||
{
|
||||
public:
|
||||
IpAddressUpdater();
|
||||
~IpAddressUpdater();
|
||||
|
||||
winrt::hstring GetIpAddress();
|
||||
winrt::hstring GetIpAddress(bool ipv6);
|
||||
|
||||
private:
|
||||
void UpdateIpAddress(winrt::Windows::Foundation::IInspectable sender);
|
||||
|
||||
private:
|
||||
std::mutex m_lock;
|
||||
winrt::hstring m_ipAddress;
|
||||
winrt::hstring m_ipAddressIpv6;
|
||||
winrt::hstring m_ipAddressIpv4;
|
||||
|
||||
winrt::Windows::Networking::Connectivity::NetworkInformation::NetworkStatusChanged_revoker m_networkStatusChangedRevoker;
|
||||
};
|
||||
|
|
|
@ -15,10 +15,8 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
using namespace winrt::Microsoft::Holographic::AppRemoting;
|
||||
|
||||
|
||||
std::wstring PlayerFrameStatisticsHelper::GetStatisticsString() const
|
||||
{
|
||||
float timeSinceLastPresentAvg = 0.0f;
|
||||
|
@ -31,7 +29,6 @@ std::wstring PlayerFrameStatisticsHelper::GetStatisticsString() const
|
|||
float latencyAvg = 0.0f;
|
||||
uint32_t videoFramesDiscarded = 0;
|
||||
|
||||
|
||||
for (const PlayerFrameStatistics& frameStatistics : m_lastWindowFrameStats)
|
||||
{
|
||||
timeSinceLastPresentAvg += frameStatistics.TimeSinceLastPresent;
|
||||
|
@ -69,14 +66,14 @@ std::wstring PlayerFrameStatisticsHelper::GetStatisticsString() const
|
|||
std::wstringstream statisticsStringStream;
|
||||
statisticsStringStream.precision(3);
|
||||
statisticsStringStream << L"Render: " << frameStatsCount << L" fps - " << timeSinceLastPresentAvg * 1000 << L" / "
|
||||
<< timeSinceLastPresentMax * 1000 << L" ms (avg / max)" << std::endl
|
||||
<< timeSinceLastPresentMax * 1000 << L" ms (avg/max)" << std::endl
|
||||
<< L"Video frames: " << videoFramesSkipped << L" / " << videoFramesReused << L" / " << videoFramesReceived
|
||||
<< L" skipped / reused / received" << std::endl
|
||||
<< L" skipped/reused/received" << std::endl
|
||||
<< L"Video frames delta: " << videoFrameMinDelta * 1000 << L" / " << videoFrameMaxDelta * 1000
|
||||
<< L" ms (min / max)" << std::endl
|
||||
<< L" ms (min/max)" << std::endl
|
||||
<< L"Latency: " << latencyAvg * 1000 << L" ms (avg)" << std::endl
|
||||
<< L"Video frames discarded: " << videoFramesDiscarded << L" / " << m_videoFramesDiscardedTotal
|
||||
<< L" frames (last sec / total)" << std::endl;
|
||||
<< L" frames (last sec/total)" << std::endl;
|
||||
|
||||
return statisticsStringStream.str();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
//
|
||||
//*********************************************************
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "PlayerUtil.h"
|
||||
|
||||
#include <codecvt>
|
||||
#include <regex>
|
||||
|
||||
std::wstring PlayerUtil::SplitHostnameAndPortString(const std::wstring& address, uint16_t& port)
|
||||
{
|
||||
static std::basic_regex<wchar_t> addressMatcher(L"(?:(\\[.*\\])|([^:]*))(?:[:](\\d+))?");
|
||||
std::match_results<typename std::wstring::const_iterator> results;
|
||||
if (std::regex_match(address, results, addressMatcher))
|
||||
{
|
||||
if (results[3].matched)
|
||||
{
|
||||
std::wstring portStr = results[3].str();
|
||||
port = static_cast<uint16_t>(std::wcstol(portStr.c_str(), nullptr, 10));
|
||||
}
|
||||
|
||||
return (results[1].matched) ? results[1].str() : results[2].str();
|
||||
}
|
||||
else
|
||||
{
|
||||
return address;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
struct PlayerUtil
|
||||
{
|
||||
static std::wstring SplitHostnameAndPortString(const std::wstring& address, uint16_t& port);
|
||||
};
|
|
@ -12,14 +12,24 @@
|
|||
// Per-pixel color data passed through the pixel shader.
|
||||
struct PixelShaderInput
|
||||
{
|
||||
min16float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0; //Note: we use full precission floats for texture coordinates to avoid artifacts with large textures
|
||||
min16float4 pos : SV_POSITION;
|
||||
float2 uv : TEXCOORD0; // Note: we use full precission floats for texture coordinates to avoid artifacts with large textures
|
||||
};
|
||||
|
||||
Texture2D tex : t0;
|
||||
SamplerState samp : s0;
|
||||
Texture2D tex : t0;
|
||||
SamplerState samp : s0;
|
||||
|
||||
min16float4 main(PixelShaderInput input) : SV_TARGET
|
||||
float4 main(PixelShaderInput input) : SV_TARGET
|
||||
{
|
||||
return (min16float4)tex.Sample(samp, input.uv);
|
||||
float2 offsets[4] = {float2(-0.125, -0.375), float2(0.375, -0.125), float2(-0.375, 0.125), float2(0.125f, 0.375f)};
|
||||
float4 color = float4(0, 0, 0, 0);
|
||||
float2 dtdx = ddx(input.uv);
|
||||
float2 dtdy = ddy(input.uv);
|
||||
|
||||
[unroll]
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
color += 0.25 * tex.Sample(samp, input.uv + offsets[i].x * dtdx + offsets[i].y * dtdy);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012-2019 Microsoft Corp
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies
|
||||
or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2" IgnorableNamespaces="uap mp uap2">
|
||||
<Identity Name="SampleHolographicRemotingPlayer" Publisher="CN=SampleHolographicRemotingPlayer" Version="2.0.14.0" />
|
||||
<Identity Name="SampleHolographicRemotingPlayer" Publisher="CN=SampleHolographicRemotingPlayer" Version="2.1.0.0" />
|
||||
<mp:PhoneIdentity PhoneProductId="b65c9a46-d0b3-4954-829a-6a60bed54d0a" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Properties>
|
||||
<DisplayName>Sample Holographic AppRemoting Player</DisplayName>
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.645
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29806.167
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SamplePlayer", "SamplePlayer.vcxproj", "{B26EEC5F-BBFF-3973-A459-AD3E5A33EF70}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SamplePlayer", "SamplePlayer.vcxproj", "{B848F924-651A-3EC7-8166-E5565290E1FB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM = Debug|ARM
|
||||
Release|ARM = Release|ARM
|
||||
RelWithDebInfo|ARM = RelWithDebInfo|ARM
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
Release|ARM64 = Release|ARM64
|
||||
RelWithDebInfo|ARM64 = RelWithDebInfo|ARM64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B26EEC5F-BBFF-3973-A459-AD3E5A33EF70}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{B26EEC5F-BBFF-3973-A459-AD3E5A33EF70}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{B26EEC5F-BBFF-3973-A459-AD3E5A33EF70}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{B26EEC5F-BBFF-3973-A459-AD3E5A33EF70}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{B26EEC5F-BBFF-3973-A459-AD3E5A33EF70}.Release|ARM.Build.0 = Release|ARM
|
||||
{B26EEC5F-BBFF-3973-A459-AD3E5A33EF70}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{B26EEC5F-BBFF-3973-A459-AD3E5A33EF70}.RelWithDebInfo|ARM.ActiveCfg = RelWithDebInfo|ARM
|
||||
{B26EEC5F-BBFF-3973-A459-AD3E5A33EF70}.RelWithDebInfo|ARM.Build.0 = RelWithDebInfo|ARM
|
||||
{B26EEC5F-BBFF-3973-A459-AD3E5A33EF70}.RelWithDebInfo|ARM.Deploy.0 = RelWithDebInfo|ARM
|
||||
{B848F924-651A-3EC7-8166-E5565290E1FB}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{B848F924-651A-3EC7-8166-E5565290E1FB}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{B848F924-651A-3EC7-8166-E5565290E1FB}.Debug|ARM64.Deploy.0 = Debug|ARM64
|
||||
{B848F924-651A-3EC7-8166-E5565290E1FB}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{B848F924-651A-3EC7-8166-E5565290E1FB}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{B848F924-651A-3EC7-8166-E5565290E1FB}.Release|ARM64.Deploy.0 = Release|ARM64
|
||||
{B848F924-651A-3EC7-8166-E5565290E1FB}.RelWithDebInfo|ARM64.ActiveCfg = RelWithDebInfo|ARM64
|
||||
{B848F924-651A-3EC7-8166-E5565290E1FB}.RelWithDebInfo|ARM64.Build.0 = RelWithDebInfo|ARM64
|
||||
{B848F924-651A-3EC7-8166-E5565290E1FB}.RelWithDebInfo|ARM64.Deploy.0 = RelWithDebInfo|ARM64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="packages\Microsoft.Windows.CppWinRT.2.0.200224.2\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('packages\Microsoft.Windows.CppWinRT.2.0.200224.2\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="RelWithDebInfo|ARM">
|
||||
<ProjectConfiguration Include="RelWithDebInfo|ARM64">
|
||||
<Configuration>RelWithDebInfo</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{B26EEC5F-BBFF-3973-A459-AD3E5A33EF70}</ProjectGuid>
|
||||
<ProjectGuid>{B848F924-651A-3EC7-8166-E5565290E1FB}</ProjectGuid>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
|
@ -24,67 +28,66 @@
|
|||
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<Platform>ARM</Platform>
|
||||
<Platform>ARM64</Platform>
|
||||
<ProjectName>SamplePlayer</ProjectName>
|
||||
<VCProjectUpgraderObjectName>NoUpgrade</VCProjectUpgraderObjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'" Label="Configuration">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="packages\Microsoft.Holographic.Remoting.2.0.14\build\native\Microsoft.Holographic.Remoting.targets" Condition="Exists('packages\Microsoft.Holographic.Remoting.2.0.14\build\native\Microsoft.Holographic.Remoting.targets')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">.\bin\Debug\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">SamplePlayer.dir\Debug\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">SamplePlayer</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">.exe</TargetExt>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</GenerateManifest>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">.\bin\Release\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">SamplePlayer.dir\Release\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">SamplePlayer</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">.exe</TargetExt>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">false</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</GenerateManifest>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">.\bin\RelWithDebInfo\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">SamplePlayer.dir\RelWithDebInfo\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">SamplePlayer</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">.exe</TargetExt>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">true</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">true</GenerateManifest>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">.\bin\Debug\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">SamplePlayer.dir\Debug\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">SamplePlayer</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">.exe</TargetExt>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</GenerateManifest>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">.\bin\Release\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">SamplePlayer.dir\Release\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">SamplePlayer</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">.exe</TargetExt>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</GenerateManifest>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">.\bin\RelWithDebInfo\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">SamplePlayer.dir\RelWithDebInfo\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">SamplePlayer</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">.exe</TargetExt>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">true</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">true</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /await</AdditionalOptions>
|
||||
<AdditionalUsingDirectories>$(VCIDEInstallDir)vcpackages;$(UniversalCRTSdkDir)UnionMetadata</AdditionalUsingDirectories>
|
||||
<AssemblerListingLocation>Debug/</AssemblerListingLocation>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<CompileAsWinRT>false</CompileAsWinRT>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4503;4311;4456;4458;4459;4499</DisableSpecificWarnings>
|
||||
<DisableSpecificWarnings>4503</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<ForcedUsingFiles>;%(ForcedUsingFiles)</ForcedUsingFiles>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
|
@ -98,11 +101,11 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<UseFullPaths>false</UseFullPaths>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;UNICODE;_UNICODE;ALLOW_INSECURE_RANDOM_DEVICE=1;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WINRT;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_ARM;RDBUILD_ARCH_ARM_ARM32;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;UNICODE;_UNICODE;ALLOW_INSECURE_RANDOM_DEVICE=1;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WINRT;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_ARM;RDBUILD_ARCH_ARM_ARM64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;UNICODE;_UNICODE;ALLOW_INSECURE_RANDOM_DEVICE=1;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WINRT;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_ARM;RDBUILD_ARCH_ARM_ARM32;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;UNICODE;_UNICODE;ALLOW_INSECURE_RANDOM_DEVICE=1;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WINRT;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_ARM;RDBUILD_ARCH_ARM_ARM64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
|
@ -116,7 +119,7 @@
|
|||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /machine:ARM</AdditionalOptions>
|
||||
<AdditionalOptions>%(AdditionalOptions) /machine:ARM64</AdditionalOptions>
|
||||
<EnableCOMDATFolding>false</EnableCOMDATFolding>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
|
@ -130,17 +133,17 @@
|
|||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /await</AdditionalOptions>
|
||||
<AdditionalUsingDirectories>$(VCIDEInstallDir)vcpackages;$(UniversalCRTSdkDir)UnionMetadata</AdditionalUsingDirectories>
|
||||
<AssemblerListingLocation>Release/</AssemblerListingLocation>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<CompileAsWinRT>false</CompileAsWinRT>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4503;4311;4456;4458;4459;4499</DisableSpecificWarnings>
|
||||
<DisableSpecificWarnings>4503</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<ForcedUsingFiles>;%(ForcedUsingFiles)</ForcedUsingFiles>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
|
@ -154,11 +157,11 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<UseFullPaths>false</UseFullPaths>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;UNICODE;_UNICODE;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WINRT;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_ARM;RDBUILD_ARCH_ARM_ARM32;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;UNICODE;_UNICODE;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WINRT;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_ARM;RDBUILD_ARCH_ARM_ARM64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;UNICODE;_UNICODE;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WINRT;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_ARM;RDBUILD_ARCH_ARM_ARM32;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;UNICODE;_UNICODE;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WINRT;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_ARM;RDBUILD_ARCH_ARM_ARM64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
|
@ -172,7 +175,7 @@
|
|||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /machine:ARM</AdditionalOptions>
|
||||
<AdditionalOptions>%(AdditionalOptions) /machine:ARM64</AdditionalOptions>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
|
@ -184,16 +187,16 @@
|
|||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /await</AdditionalOptions>
|
||||
<AdditionalUsingDirectories>$(VCIDEInstallDir)vcpackages;$(UniversalCRTSdkDir)UnionMetadata</AdditionalUsingDirectories>
|
||||
<AssemblerListingLocation>RelWithDebInfo/</AssemblerListingLocation>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<CompileAsWinRT>false</CompileAsWinRT>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4503;4311;4456;4458;4459;4499</DisableSpecificWarnings>
|
||||
<DisableSpecificWarnings>4503</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<ForcedUsingFiles>;%(ForcedUsingFiles)</ForcedUsingFiles>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
|
@ -207,11 +210,11 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<UseFullPaths>false</UseFullPaths>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;UNICODE;_UNICODE;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WINRT;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_ARM;RDBUILD_ARCH_ARM_ARM32;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR="RelWithDebInfo";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;UNICODE;_UNICODE;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WINRT;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_ARM;RDBUILD_ARCH_ARM_ARM64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR="RelWithDebInfo";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;UNICODE;_UNICODE;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WINRT;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_ARM;RDBUILD_ARCH_ARM_ARM32;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR=\"RelWithDebInfo\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;UNICODE;_UNICODE;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WINRT;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_ARM;RDBUILD_ARCH_ARM_ARM64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR=\"RelWithDebInfo\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
|
@ -225,7 +228,7 @@
|
|||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /machine:ARM</AdditionalOptions>
|
||||
<AdditionalOptions>%(AdditionalOptions) /machine:ARM64</AdditionalOptions>
|
||||
<EnableCOMDATFolding>false</EnableCOMDATFolding>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
|
@ -246,12 +249,16 @@
|
|||
<ClCompile Include=".\SamplePlayerMain.cpp" />
|
||||
<ClCompile Include="..\common\CameraResources.cpp" />
|
||||
<ClInclude Include="..\common\CameraResources.h" />
|
||||
<ClCompile Include="..\common\DeviceResources.cpp" />
|
||||
<ClInclude Include="..\common\DeviceResources.h" />
|
||||
<ClCompile Include="..\common\DeviceResourcesCommon.cpp" />
|
||||
<ClInclude Include="..\common\DeviceResourcesCommon.h" />
|
||||
<ClCompile Include="..\common\DeviceResourcesUWP.cpp" />
|
||||
<ClInclude Include="..\common\DeviceResourcesUWP.h" />
|
||||
<ClInclude Include="..\common\IpAddressUpdater.h" />
|
||||
<ClCompile Include="..\common\IpAddressUpdater.cpp" />
|
||||
<ClInclude Include="..\common\PlayerFrameStatisticsHelper.h" />
|
||||
<ClCompile Include="..\common\PlayerFrameStatisticsHelper.cpp" />
|
||||
<ClInclude Include="..\common\PlayerUtil.h" />
|
||||
<ClCompile Include="..\common\PlayerUtil.cpp" />
|
||||
<ClCompile Include="..\common\Content\DDSTextureLoader.cpp" />
|
||||
<ClInclude Include="..\common\Content\DDSTextureLoader.h" />
|
||||
<ClInclude Include="..\common\Content\ErrorHelper.h" />
|
||||
|
@ -261,97 +268,101 @@
|
|||
<ClCompile Include="..\common\Content\StatusDisplay.cpp" />
|
||||
<None Include=".\Content\RemotingLogo.dds">
|
||||
<Link>.\%(FileName)%(Extension)</Link>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">true</DeploymentContent>
|
||||
</None>
|
||||
<Image Include=".\Assets\LockScreenLogo.scale-200.png">
|
||||
<Link>Assets\%(FileName)%(Extension)</Link>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">true</DeploymentContent>
|
||||
</Image>
|
||||
<Image Include=".\Assets\SplashScreen.scale-200.png">
|
||||
<Link>Assets\%(FileName)%(Extension)</Link>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">true</DeploymentContent>
|
||||
</Image>
|
||||
<Image Include=".\Assets\Square44x44Logo.scale-200.png">
|
||||
<Link>Assets\%(FileName)%(Extension)</Link>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">true</DeploymentContent>
|
||||
</Image>
|
||||
<Image Include=".\Assets\Square44x44Logo.targetsize-24_altform-unplated.png">
|
||||
<Link>Assets\%(FileName)%(Extension)</Link>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">true</DeploymentContent>
|
||||
</Image>
|
||||
<Image Include=".\Assets\Square150x150Logo.scale-200.png">
|
||||
<Link>Assets\%(FileName)%(Extension)</Link>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">true</DeploymentContent>
|
||||
</Image>
|
||||
<Image Include=".\Assets\StoreLogo.png">
|
||||
<Link>Assets\%(FileName)%(Extension)</Link>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">true</DeploymentContent>
|
||||
</Image>
|
||||
<Image Include=".\Assets\Wide310x150Logo.scale-200.png">
|
||||
<Link>Assets\%(FileName)%(Extension)</Link>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</DeploymentContent>
|
||||
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">true</DeploymentContent>
|
||||
</Image>
|
||||
<AppxManifest Include=".\Package.appxmanifest" />
|
||||
<FXCompile Include="..\common\Shaders\VertexShader.hlsl">
|
||||
<ShaderType>Vertex</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">%(Filename)</VariableName>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">%(Filename)</VariableName>
|
||||
</FXCompile>
|
||||
<FXCompile Include="..\common\Shaders\VPRTVertexShader.hlsl">
|
||||
<ShaderType>Vertex</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">%(Filename)</VariableName>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">%(Filename)</VariableName>
|
||||
</FXCompile>
|
||||
<FXCompile Include="..\common\Shaders\PixelShader.hlsl">
|
||||
<ShaderType>Pixel</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">%(Filename)</VariableName>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">%(Filename)</VariableName>
|
||||
</FXCompile>
|
||||
<FXCompile Include="..\common\Shaders\GeometryShader.hlsl">
|
||||
<ShaderType>Geometry</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM'">%(Filename)</VariableName>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<HeaderFileOutput Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">.\shaders\%(Filename).h</HeaderFileOutput>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">%(Filename)</VariableName>
|
||||
<VariableName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">%(Filename)</VariableName>
|
||||
</FXCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="packages\Microsoft.Windows.CppWinRT.2.0.200224.2\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('packages\Microsoft.Windows.CppWinRT.2.0.200224.2\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="packages\Microsoft.Holographic.Remoting.2.1.0\build\native\Microsoft.Holographic.Remoting.targets" Condition="Exists('packages\Microsoft.Holographic.Remoting.2.1.0\build\native\Microsoft.Holographic.Remoting.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -13,10 +13,14 @@
|
|||
|
||||
#include "SamplePlayerMain.h"
|
||||
|
||||
#include "../common/CameraResources.h"
|
||||
#include "../common/Content/DDSTextureLoader.h"
|
||||
#include "../common/PlayerUtil.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <winrt/Windows.Foundation.Metadata.h>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
using namespace winrt::Microsoft::Holographic::AppRemoting;
|
||||
|
@ -30,7 +34,11 @@ using namespace winrt::Windows::Perception::Spatial;
|
|||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::UI::Input::Spatial;
|
||||
|
||||
|
||||
SamplePlayerMain::SamplePlayerMain()
|
||||
{
|
||||
m_canCommitDirect3D11DepthBuffer = winrt::Windows::Foundation::Metadata::ApiInformation::IsMethodPresent(
|
||||
L"Windows.Graphics.Holographic.HolographicCameraRenderingParameters", L"CommitDirect3D11DepthBuffer");
|
||||
}
|
||||
SamplePlayerMain::~SamplePlayerMain()
|
||||
{
|
||||
Uninitialize();
|
||||
|
@ -127,8 +135,8 @@ HolographicFrame SamplePlayerMain::Update(float deltaTimeInSeconds)
|
|||
HolographicCameraRenderingParameters renderingParameters = holographicFrame.GetRenderingParameters(cameraPose);
|
||||
|
||||
// Set the focus point for image stabilization to the center of the status display.
|
||||
// NOTE: By doing this before the call to PlayerContext::BlitRemoteFrame (in the Render() method),
|
||||
// the focus point can be overriden by the remote side.
|
||||
// NOTE: The focus point set here will be overwritten with the focus point from the remote side by BlitRemoteFrame or
|
||||
// ignored if a depth buffer is commited (see HolographicRemotingPlayerMain::Render for details).
|
||||
renderingParameters.SetFocusPoint(coordinateSystem, m_statusDisplay->GetPosition());
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +155,7 @@ HolographicFrame SamplePlayerMain::Update(float deltaTimeInSeconds)
|
|||
}
|
||||
else
|
||||
{
|
||||
StatusDisplay::Line line = {std::move(statisticsString), StatusDisplay::Small, StatusDisplay::Yellow, 1.0f, true};
|
||||
StatusDisplay::Line line = {std::move(statisticsString), StatusDisplay::Medium, StatusDisplay::Yellow, 1.0f, true};
|
||||
m_statusDisplay->AddLine(line);
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +164,7 @@ HolographicFrame SamplePlayerMain::Update(float deltaTimeInSeconds)
|
|||
{
|
||||
if (m_playerOptions.m_listen)
|
||||
{
|
||||
auto deviceIpNew = m_ipAddressUpdater.GetIpAddress();
|
||||
auto deviceIpNew = m_ipAddressUpdater.GetIpAddress(m_playerOptions.m_ipv6);
|
||||
if (m_deviceIp != deviceIpNew)
|
||||
{
|
||||
m_deviceIp = deviceIpNew;
|
||||
|
@ -209,12 +217,30 @@ void SamplePlayerMain::Render(const HolographicFrame& holographicFrame)
|
|||
deviceContext->ClearRenderTargetView(targets[0], DirectX::Colors::Transparent);
|
||||
deviceContext->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
||||
|
||||
// The view and projection matrices for each holographic camera will change
|
||||
// every frame. This function refreshes the data in the constant buffer for
|
||||
// the holographic camera indicated by cameraPose.
|
||||
if (coordinateSystem)
|
||||
{
|
||||
// The view and projection matrices for each holographic camera will change
|
||||
// every frame. This function refreshes the data in the constant buffer for
|
||||
// the holographic camera indicated by cameraPose.
|
||||
pCameraResources->UpdateViewProjectionBuffer(m_deviceResources, cameraPose, coordinateSystem);
|
||||
|
||||
const bool connected = (m_playerContext.ConnectionState() == ConnectionState::Connected);
|
||||
|
||||
// Reduce the fov of the statistics view.
|
||||
float quadFov = m_statusDisplay->GetDefaultQuadFov();
|
||||
float quadRatio = 1.0f;
|
||||
if (m_playerOptions.m_showStatistics && connected && !m_trackingLost)
|
||||
{
|
||||
quadFov = m_statusDisplay->GetStatisticsFov();
|
||||
quadRatio = m_statusDisplay->GetStatisticsHeightRatio();
|
||||
}
|
||||
// Pass data from the camera resources to the status display.
|
||||
m_statusDisplay->UpdateTextScale(
|
||||
pCameraResources->GetProjectionTransform(),
|
||||
pCameraResources->GetRenderTargetSize().Width,
|
||||
pCameraResources->GetRenderTargetSize().Height,
|
||||
quadFov,
|
||||
quadRatio);
|
||||
}
|
||||
|
||||
// Attach the view/projection constant buffer for this camera to the graphics pipeline.
|
||||
|
@ -223,6 +249,8 @@ void SamplePlayerMain::Render(const HolographicFrame& holographicFrame)
|
|||
// Only render world-locked content when positional tracking is active.
|
||||
if (cameraActive)
|
||||
{
|
||||
bool depthAvailable = false;
|
||||
|
||||
try
|
||||
{
|
||||
if (m_playerContext.ConnectionState() == ConnectionState::Connected)
|
||||
|
@ -230,7 +258,11 @@ void SamplePlayerMain::Render(const HolographicFrame& holographicFrame)
|
|||
// Blit the remote frame into the backbuffer for the HolographicFrame.
|
||||
// NOTE: This overwrites the focus point for the current frame, if the remote application
|
||||
// has specified a focus point during the rendering of the remote frame.
|
||||
m_playerContext.BlitRemoteFrame();
|
||||
if (m_playerContext.BlitRemoteFrame() == BlitResult::Success_Color_Depth)
|
||||
{
|
||||
// In case of Success_Color_Depth a depth buffer has been committed by the remote application.
|
||||
depthAvailable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (winrt::hresult_error err)
|
||||
|
@ -240,8 +272,23 @@ void SamplePlayerMain::Render(const HolographicFrame& holographicFrame)
|
|||
UpdateStatusDisplay();
|
||||
}
|
||||
|
||||
// Draw connection status and/or statistics.
|
||||
m_statusDisplay->Render();
|
||||
// Render local content.
|
||||
{
|
||||
// NOTE: Any local custom content would be rendered here.
|
||||
|
||||
// Draw connection status and/or statistics.
|
||||
m_statusDisplay->Render();
|
||||
}
|
||||
|
||||
// Commit depth buffer if available.
|
||||
// NOTE: CommitDirect3D11DepthBuffer should be the last thing before the frame is presented. By doing so the depth
|
||||
// buffer submitted include remote content and local content.
|
||||
if (m_canCommitDirect3D11DepthBuffer && depthAvailable)
|
||||
{
|
||||
auto interopSurface = pCameraResources->GetDepthStencilTextureInteropObject();
|
||||
HolographicCameraRenderingParameters renderingParameters = holographicFrame.GetRenderingParameters(cameraPose);
|
||||
renderingParameters.CommitDirect3D11DepthBuffer(interopSurface);
|
||||
}
|
||||
}
|
||||
|
||||
atLeastOneCameraRendered = true;
|
||||
|
@ -274,7 +321,7 @@ void SamplePlayerMain::Initialize(const CoreApplicationView& applicationView)
|
|||
m_suspendingEventRevoker = CoreApplication::Suspending(winrt::auto_revoke, {this, &SamplePlayerMain::OnSuspending});
|
||||
m_resumingEventRevoker = CoreApplication::Resuming(winrt::auto_revoke, {this, &SamplePlayerMain::OnResuming});
|
||||
|
||||
m_deviceResources = std::make_shared<DXHelper::DeviceResources>();
|
||||
m_deviceResources = std::make_shared<DXHelper::DeviceResourcesUWP>();
|
||||
m_deviceResources->RegisterDeviceNotify(this);
|
||||
|
||||
m_spatialLocator = SpatialLocator::GetDefault();
|
||||
|
@ -295,6 +342,9 @@ void SamplePlayerMain::Initialize(const CoreApplicationView& applicationView)
|
|||
|
||||
// Set the BlitRemoteFrame timeout to 0.5s
|
||||
m_playerContext.BlitRemoteFrameTimeout(500ms);
|
||||
|
||||
// Projection transform always reflects what has been configured on the remote side.
|
||||
m_playerContext.ProjectionTransformConfig(ProjectionTransformMode::Remote);
|
||||
}
|
||||
|
||||
void SamplePlayerMain::SetWindow(const CoreWindow& window)
|
||||
|
@ -315,7 +365,7 @@ void SamplePlayerMain::SetWindow(const CoreWindow& window)
|
|||
{
|
||||
m_playerContext.OnDataChannelCreated([this](const IDataChannel& dataChannel, uint8_t channelId) {
|
||||
std::lock_guard lock(m_customDataChannelLock);
|
||||
m_customDataChannel = dataChannel;
|
||||
m_customDataChannel = dataChannel.as<IDataChannel2>();
|
||||
|
||||
m_customChannelDataReceivedEventRevoker = m_customDataChannel.OnDataReceived(
|
||||
winrt::auto_revoke, [this](winrt::array_view<const uint8_t> dataView) { OnCustomDataChannelDataReceived(); });
|
||||
|
@ -436,7 +486,7 @@ void SamplePlayerMain::LoadLogoImage()
|
|||
SamplePlayerMain::PlayerOptions SamplePlayerMain::ParseActivationArgs(const IActivatedEventArgs& activationArgs)
|
||||
{
|
||||
std::wstring host = L"";
|
||||
int32_t port = 0;
|
||||
uint16_t port = 0;
|
||||
bool listen = false;
|
||||
bool showStatistics = false;
|
||||
|
||||
|
@ -479,19 +529,7 @@ SamplePlayerMain::PlayerOptions SamplePlayerMain::ParseActivationArgs(const IAct
|
|||
continue;
|
||||
}
|
||||
|
||||
size_t colonPos = arg.find(L':');
|
||||
if (colonPos != std::wstring::npos)
|
||||
{
|
||||
std::wstring portStr = arg.substr(colonPos + 1);
|
||||
|
||||
host = arg.substr(0, colonPos);
|
||||
port = std::wcstol(portStr.c_str(), nullptr, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
host = arg.c_str();
|
||||
port = 0;
|
||||
}
|
||||
host = PlayerUtil::SplitHostnameAndPortString(arg, port);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -558,6 +596,7 @@ SamplePlayerMain::PlayerOptions SamplePlayerMain::ParseActivationArgs(const IAct
|
|||
playerOptions.m_port = port;
|
||||
playerOptions.m_listen = listen;
|
||||
playerOptions.m_showStatistics = showStatistics;
|
||||
playerOptions.m_ipv6 = hostname.front() == L'[';
|
||||
|
||||
return playerOptions;
|
||||
}
|
||||
|
@ -568,12 +607,10 @@ void SamplePlayerMain::UpdateStatusDisplay()
|
|||
|
||||
if (m_trackingLost)
|
||||
{
|
||||
StatusDisplay::Line lines[] = {StatusDisplay::Line{L"Device Tracking Lost", StatusDisplay::LargeBold, StatusDisplay::White, 1.2f},
|
||||
StatusDisplay::Line{L"Ensure your environment is properly lit\r\n"
|
||||
L"and the device's sensors are not covered.",
|
||||
StatusDisplay::Small,
|
||||
StatusDisplay::White,
|
||||
6.0f}};
|
||||
StatusDisplay::Line lines[] = {
|
||||
StatusDisplay::Line{L"Device Tracking Lost", StatusDisplay::LargeBold, StatusDisplay::White, 1.0f},
|
||||
StatusDisplay::Line{L"Ensure your environment is properly lit", StatusDisplay::Small, StatusDisplay::White, 1.0f},
|
||||
StatusDisplay::Line{L"and the device's sensors are not covered.", StatusDisplay::Small, StatusDisplay::White, 12.0f}};
|
||||
m_statusDisplay->SetLines(lines);
|
||||
}
|
||||
else
|
||||
|
@ -581,15 +618,14 @@ void SamplePlayerMain::UpdateStatusDisplay()
|
|||
if (m_playerContext.ConnectionState() != ConnectionState::Connected)
|
||||
{
|
||||
StatusDisplay::Line lines[] = {
|
||||
StatusDisplay::Line{L"Sample Holographic Remoting Player", StatusDisplay::LargeBold, StatusDisplay::White, 1.2f},
|
||||
StatusDisplay::Line{L"This app is a sample companion for Holographic Remoting apps.\r\n"
|
||||
L"Connect from a compatible app to begin.",
|
||||
StatusDisplay::Small,
|
||||
StatusDisplay::White,
|
||||
6.0f},
|
||||
StatusDisplay::Line{m_playerOptions.m_listen ? L"Waiting for connection on" : L"Connecting to",
|
||||
StatusDisplay::Large,
|
||||
StatusDisplay::White}};
|
||||
StatusDisplay::Line{L"Holographic Remoting Player", StatusDisplay::LargeBold, StatusDisplay::White, 1.0f},
|
||||
StatusDisplay::Line{
|
||||
L"This app is a companion for Holographic Remoting apps.", StatusDisplay::Small, StatusDisplay::White, 1.0f},
|
||||
StatusDisplay::Line{L"Connect from a compatible app to begin.", StatusDisplay::Small, StatusDisplay::White, 8.0f},
|
||||
StatusDisplay::Line{
|
||||
m_playerOptions.m_listen ? L"Waiting for connection on" : L"Connecting to",
|
||||
StatusDisplay::Large,
|
||||
StatusDisplay::White}};
|
||||
m_statusDisplay->SetLines(lines);
|
||||
|
||||
std::wostringstream addressLine;
|
||||
|
@ -598,13 +634,15 @@ void SamplePlayerMain::UpdateStatusDisplay()
|
|||
{
|
||||
addressLine << L":" << m_playerOptions.m_port;
|
||||
}
|
||||
m_statusDisplay->AddLine(StatusDisplay::Line{addressLine.str(), StatusDisplay::LargeBold, StatusDisplay::White});
|
||||
}
|
||||
}
|
||||
m_statusDisplay->AddLine(StatusDisplay::Line{addressLine.str(), StatusDisplay::Large, StatusDisplay::White});
|
||||
m_statusDisplay->AddLine(
|
||||
StatusDisplay::Line{L"Get help at: https://aka.ms/holographicremotinghelp", StatusDisplay::Small, StatusDisplay::White});
|
||||
|
||||
if (m_playerOptions.m_showStatistics)
|
||||
{
|
||||
m_statusDisplay->AddLine(StatusDisplay::Line{L"Diagnostics Enabled", StatusDisplay::Small, StatusDisplay::Yellow});
|
||||
if (m_playerOptions.m_showStatistics)
|
||||
{
|
||||
m_statusDisplay->AddLine(StatusDisplay::Line{L"Diagnostics Enabled", StatusDisplay::Small, StatusDisplay::Yellow});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_errorHelper.Apply(m_statusDisplay);
|
||||
|
@ -619,8 +657,25 @@ void SamplePlayerMain::OnCustomDataChannelDataReceived()
|
|||
std::lock_guard customDataChannelLockGuard(m_customDataChannelLock);
|
||||
if (m_customDataChannel)
|
||||
{
|
||||
uint8_t data[] = {1};
|
||||
m_customDataChannel.SendData(data, true);
|
||||
// Get send queue size. The send queue size returns the size of data, that has not been send yet, in bytes. A big number can
|
||||
// indicate that more data is being queued for sending than is actually getting sent. If possible skip sending data in this
|
||||
// case, to help the queue getting smaller again.
|
||||
uint32_t sendQueueSize = m_customDataChannel.SendQueueSize();
|
||||
|
||||
// Only send the packet if the send queue is smaller than 1MiB
|
||||
if (sendQueueSize < 1 * 1024 * 1024)
|
||||
{
|
||||
uint8_t data[] = {1};
|
||||
|
||||
try
|
||||
{
|
||||
m_customDataChannel.SendData(data, true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// SendData might throw if channel is closed, but we did not get or process the async closed event yet.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -751,6 +806,7 @@ void SamplePlayerMain::OnWindowClosed(const CoreWindow& sender, const CoreWindow
|
|||
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
|
||||
{
|
||||
winrt::init_apartment();
|
||||
CoreApplication::Run(SamplePlayerMain());
|
||||
winrt::com_ptr<SamplePlayerMain> main = winrt::make_self<SamplePlayerMain>();
|
||||
CoreApplication::Run(*main);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -15,14 +15,12 @@
|
|||
|
||||
#include "../common/Content/ErrorHelper.h"
|
||||
#include "../common/Content/StatusDisplay.h"
|
||||
#include "../common/DeviceResources.h"
|
||||
#include "../common/DeviceResourcesUWP.h"
|
||||
#include "../common/IpAddressUpdater.h"
|
||||
#include "../common/PlayerFrameStatisticsHelper.h"
|
||||
|
||||
#include <winrt/Microsoft.Holographic.AppRemoting.h>
|
||||
|
||||
|
||||
|
||||
class SamplePlayerMain : public winrt::implements<
|
||||
SamplePlayerMain,
|
||||
winrt::Windows::ApplicationModel::Core::IFrameworkViewSource,
|
||||
|
@ -30,6 +28,7 @@ class SamplePlayerMain : public winrt::implements<
|
|||
public DXHelper::IDeviceNotify
|
||||
{
|
||||
public:
|
||||
SamplePlayerMain();
|
||||
~SamplePlayerMain();
|
||||
|
||||
// Try to (re-)connect to or listen on the hostname/port, that was set during activation of the app.
|
||||
|
@ -67,6 +66,7 @@ private:
|
|||
uint16_t m_port = 0;
|
||||
bool m_listen = true;
|
||||
bool m_showStatistics = false;
|
||||
bool m_ipv6 = false;
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -107,7 +107,7 @@ private:
|
|||
|
||||
private:
|
||||
// Cached pointer to device resources.
|
||||
std::shared_ptr<DXHelper::DeviceResources> m_deviceResources;
|
||||
std::shared_ptr<DXHelper::DeviceResourcesUWP> m_deviceResources;
|
||||
|
||||
// SpatialLocator that is attached to the default HolographicDisplay.
|
||||
winrt::Windows::Perception::Spatial::SpatialLocator m_spatialLocator = nullptr;
|
||||
|
@ -139,9 +139,9 @@ private:
|
|||
|
||||
#ifdef ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE
|
||||
std::mutex m_customDataChannelLock;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IDataChannel m_customDataChannel = nullptr;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IDataChannel::OnDataReceived_revoker m_customChannelDataReceivedEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IDataChannel::OnClosed_revoker m_customChannelClosedEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IDataChannel2 m_customDataChannel = nullptr;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IDataChannel2::OnDataReceived_revoker m_customChannelDataReceivedEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IDataChannel2::OnClosed_revoker m_customChannelClosedEventRevoker;
|
||||
#endif
|
||||
|
||||
// Indicates that tracking has been lost
|
||||
|
@ -151,6 +151,8 @@ private:
|
|||
bool m_windowClosed = false;
|
||||
bool m_windowVisible = true;
|
||||
|
||||
bool m_canCommitDirect3D11DepthBuffer = false;
|
||||
|
||||
// Event registration revokers
|
||||
winrt::Windows::Perception::Spatial::SpatialLocator::LocatabilityChanged_revoker m_locatabilityChangedRevoker;
|
||||
winrt::Windows::ApplicationModel::Core::CoreApplication::Suspending_revoker m_suspendingEventRevoker;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Holographic.Remoting" version="2.0.14" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.200224.2" targetFramework="native" />
|
||||
<package id="Microsoft.Holographic.Remoting" version="2.1.0" targetFramework="native" />
|
||||
</packages>
|
||||
|
|
|
@ -0,0 +1,269 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "CameraResources.h"
|
||||
#include "DeviceResources.h"
|
||||
#include "DirectXHelper.h"
|
||||
|
||||
#include <windows.graphics.directx.direct3d11.interop.h>
|
||||
|
||||
using namespace DirectX;
|
||||
using namespace winrt::Windows::Graphics::Holographic;
|
||||
using namespace winrt::Windows::Perception::Spatial;
|
||||
|
||||
namespace DXHelper
|
||||
{
|
||||
CameraResources::CameraResources(const HolographicCamera& camera)
|
||||
: m_holographicCamera(camera)
|
||||
, m_isStereo(camera.IsStereo())
|
||||
, m_d3dRenderTargetSize(camera.RenderTargetSize())
|
||||
{
|
||||
m_d3dViewport = CD3D11_VIEWPORT(0.f, 0.f, m_d3dRenderTargetSize.Width, m_d3dRenderTargetSize.Height);
|
||||
};
|
||||
|
||||
// Updates resources associated with a holographic camera's swap chain.
|
||||
// The app does not access the swap chain directly, but it does create
|
||||
// resource views for the back buffer.
|
||||
void CameraResources::CreateResourcesForBackBuffer(
|
||||
DeviceResources* pDeviceResources, const HolographicCameraRenderingParameters& cameraParameters)
|
||||
{
|
||||
const auto device = pDeviceResources->GetD3DDevice();
|
||||
|
||||
// Get a DXGI interface for the holographic camera's back buffer.
|
||||
// Holographic cameras do not provide the DXGI swap chain, which is owned
|
||||
// by the system. The Direct3D back buffer resource is provided using WinRT
|
||||
// interop APIs.
|
||||
winrt::com_ptr<ID3D11Resource> resource;
|
||||
{
|
||||
winrt::com_ptr<::IInspectable> inspectable = cameraParameters.Direct3D11BackBuffer().as<::IInspectable>();
|
||||
winrt::com_ptr<Windows::Graphics::DirectX::Direct3D11::IDirect3DDxgiInterfaceAccess> dxgiInterfaceAccess;
|
||||
|
||||
HRESULT hr = inspectable->QueryInterface(__uuidof(dxgiInterfaceAccess), dxgiInterfaceAccess.put_void());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
winrt::throw_hresult(hr);
|
||||
}
|
||||
|
||||
hr = dxgiInterfaceAccess->GetInterface(__uuidof(resource), resource.put_void());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
winrt::throw_hresult(hr);
|
||||
}
|
||||
}
|
||||
|
||||
// Get a Direct3D interface for the holographic camera's back buffer.
|
||||
winrt::com_ptr<ID3D11Texture2D> cameraBackBuffer;
|
||||
resource.as(cameraBackBuffer);
|
||||
|
||||
// Determine if the back buffer has changed. If so, ensure that the render target view
|
||||
// is for the current back buffer.
|
||||
if (m_d3dBackBuffer != cameraBackBuffer)
|
||||
{
|
||||
// This can change every frame as the system moves to the next buffer in the
|
||||
// swap chain. This mode of operation will occur when certain rendering modes
|
||||
// are activated.
|
||||
m_d3dBackBuffer = cameraBackBuffer;
|
||||
|
||||
// Get the DXGI format for the back buffer.
|
||||
// This information can be accessed by the app using CameraResources::GetBackBufferDXGIFormat().
|
||||
D3D11_TEXTURE2D_DESC backBufferDesc;
|
||||
m_d3dBackBuffer->GetDesc(&backBufferDesc);
|
||||
m_dxgiFormat = backBufferDesc.Format;
|
||||
|
||||
D3D11_RENDER_TARGET_VIEW_DESC viewDesc = {};
|
||||
viewDesc.ViewDimension = backBufferDesc.ArraySize > 1 ? D3D11_RTV_DIMENSION_TEXTURE2DARRAY : D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
viewDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
|
||||
if (backBufferDesc.ArraySize > 1)
|
||||
{
|
||||
viewDesc.Texture2DArray.ArraySize = backBufferDesc.ArraySize;
|
||||
}
|
||||
|
||||
// Create a render target view of the back buffer.
|
||||
// Creating this resource is inexpensive, and is better than keeping track of
|
||||
// the back buffers in order to pre-allocate render target views for each one.
|
||||
m_d3dRenderTargetView = nullptr;
|
||||
winrt::check_hresult(device->CreateRenderTargetView(m_d3dBackBuffer.get(), &viewDesc, m_d3dRenderTargetView.put()));
|
||||
|
||||
// Check for render target size changes.
|
||||
winrt::Windows::Foundation::Size currentSize = m_holographicCamera.RenderTargetSize();
|
||||
if (m_d3dRenderTargetSize != currentSize)
|
||||
{
|
||||
// Set render target size.
|
||||
m_d3dRenderTargetSize = currentSize;
|
||||
|
||||
// A new depth stencil view is also needed.
|
||||
m_d3dDepthStencilView = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh depth stencil resources, if needed.
|
||||
if (m_d3dDepthStencilView == nullptr)
|
||||
{
|
||||
// Create a depth stencil view for use with 3D rendering if needed.
|
||||
CD3D11_TEXTURE2D_DESC depthStencilDesc(
|
||||
DXGI_FORMAT_R16_TYPELESS,
|
||||
static_cast<UINT>(m_d3dRenderTargetSize.Width),
|
||||
static_cast<UINT>(m_d3dRenderTargetSize.Height),
|
||||
m_isStereo ? 2 : 1, // Create two textures when rendering in stereo.
|
||||
1, // Use a single mipmap level.
|
||||
D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE);
|
||||
|
||||
winrt::check_hresult(device->CreateTexture2D(&depthStencilDesc, nullptr, m_d3dDepthStencil.put()));
|
||||
|
||||
CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(
|
||||
m_isStereo ? D3D11_DSV_DIMENSION_TEXTURE2DARRAY : D3D11_DSV_DIMENSION_TEXTURE2D);
|
||||
depthStencilViewDesc.Format = DXGI_FORMAT_D16_UNORM;
|
||||
|
||||
winrt::check_hresult(
|
||||
device->CreateDepthStencilView(m_d3dDepthStencil.get(), &depthStencilViewDesc, m_d3dDepthStencilView.put()));
|
||||
}
|
||||
|
||||
// Create the constant buffer, if needed.
|
||||
if (m_viewProjectionConstantBuffer == nullptr)
|
||||
{
|
||||
// Create a constant buffer to store view and projection matrices for the camera.
|
||||
CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(device->CreateBuffer(&constantBufferDesc, nullptr, m_viewProjectionConstantBuffer.put()));
|
||||
}
|
||||
}
|
||||
|
||||
// Releases resources associated with a back buffer.
|
||||
void CameraResources::ReleaseResourcesForBackBuffer(DeviceResources* pDeviceResources)
|
||||
{
|
||||
// Release camera-specific resources.
|
||||
m_d3dBackBuffer = nullptr;
|
||||
m_d3dDepthStencil = nullptr;
|
||||
m_d3dRenderTargetView = nullptr;
|
||||
m_d3dDepthStencilView = nullptr;
|
||||
m_viewProjectionConstantBuffer = nullptr;
|
||||
|
||||
// Ensure system references to the back buffer are released by clearing the render
|
||||
// target from the graphics pipeline state, and then flushing the Direct3D context.
|
||||
pDeviceResources->UseD3DDeviceContext([](auto context) {
|
||||
ID3D11RenderTargetView* nullViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {nullptr};
|
||||
context->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
|
||||
context->Flush();
|
||||
});
|
||||
}
|
||||
|
||||
// Updates the view/projection constant buffer for a holographic camera.
|
||||
void CameraResources::UpdateViewProjectionBuffer(
|
||||
std::shared_ptr<DeviceResources> deviceResources,
|
||||
const HolographicCameraPose& cameraPose,
|
||||
const SpatialCoordinateSystem& coordinateSystem)
|
||||
{
|
||||
// The system changes the viewport on a per-frame basis for system optimizations.
|
||||
m_d3dViewport =
|
||||
CD3D11_VIEWPORT(cameraPose.Viewport().X, cameraPose.Viewport().Y, cameraPose.Viewport().Width, cameraPose.Viewport().Height);
|
||||
|
||||
// The projection transform for each frame is provided by the HolographicCameraPose.
|
||||
auto cameraProjectionTransform = cameraPose.ProjectionTransform();
|
||||
|
||||
// Get a container object with the view and projection matrices for the given
|
||||
// pose in the given coordinate system.
|
||||
auto viewTransformContainer = cameraPose.TryGetViewTransform(coordinateSystem);
|
||||
|
||||
// If TryGetViewTransform returns a null pointer, that means the pose and coordinate
|
||||
// system cannot be understood relative to one another; content cannot be rendered
|
||||
// in this coordinate system for the duration of the current frame.
|
||||
// This usually means that positional tracking is not active for the current frame, in
|
||||
// which case it is possible to use a SpatialLocatorAttachedFrameOfReference to render
|
||||
// content that is not world-locked instead.
|
||||
ViewProjectionConstantBuffer viewProjectionConstantBufferData = {};
|
||||
bool viewTransformAcquired = viewTransformContainer != nullptr;
|
||||
if (viewTransformAcquired)
|
||||
{
|
||||
// Otherwise, the set of view transforms can be retrieved.
|
||||
auto viewCoordinateSystemTransform = viewTransformContainer.Value();
|
||||
|
||||
// Update the view matrices. Holographic cameras (such as Microsoft HoloLens) are
|
||||
// constantly moving relative to the world. The view matrices need to be updated
|
||||
// every frame.
|
||||
XMStoreFloat4x4(
|
||||
&viewProjectionConstantBufferData.viewProjection[0],
|
||||
XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Left) * XMLoadFloat4x4(&cameraProjectionTransform.Left)));
|
||||
XMStoreFloat4x4(
|
||||
&viewProjectionConstantBufferData.viewProjection[1],
|
||||
XMMatrixTranspose(XMLoadFloat4x4(&viewCoordinateSystemTransform.Right) * XMLoadFloat4x4(&cameraProjectionTransform.Right)));
|
||||
}
|
||||
|
||||
// Use the D3D device context to update Direct3D device-based resources.
|
||||
deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
// Loading is asynchronous. Resources must be created before they can be updated.
|
||||
if (context == nullptr || m_viewProjectionConstantBuffer == nullptr || !viewTransformAcquired)
|
||||
{
|
||||
m_framePending = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update the view and projection matrices.
|
||||
context->UpdateSubresource(m_viewProjectionConstantBuffer.get(), 0, nullptr, &viewProjectionConstantBufferData, 0, 0);
|
||||
|
||||
m_framePending = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Gets the view-projection constant buffer for the HolographicCamera and attaches it
|
||||
// to the shader pipeline.
|
||||
bool CameraResources::AttachViewProjectionBuffer(std::shared_ptr<DeviceResources> deviceResources)
|
||||
{
|
||||
// This method uses Direct3D device-based resources.
|
||||
return deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
// Loading is asynchronous. Resources must be created before they can be updated.
|
||||
// Cameras can also be added asynchronously, in which case they must be initialized
|
||||
// before they can be used.
|
||||
if (context == nullptr || m_viewProjectionConstantBuffer == nullptr || m_framePending == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the viewport for this camera.
|
||||
context->RSSetViewports(1, &m_d3dViewport);
|
||||
|
||||
// Send the constant buffer to the vertex shader.
|
||||
ID3D11Buffer* pBuffer = m_viewProjectionConstantBuffer.get();
|
||||
context->VSSetConstantBuffers(1, 1, &pBuffer);
|
||||
|
||||
// The template includes a pass-through geometry shader that is used by
|
||||
// default on systems that don't support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer extension. The shader
|
||||
// will be enabled at run-time on systems that require it.
|
||||
// If your app will also use the geometry shader for other tasks and those
|
||||
// tasks require the view/projection matrix, uncomment the following line
|
||||
// of code to send the constant buffer to the geometry shader as well.
|
||||
/*context->GSSetConstantBuffers(
|
||||
1,
|
||||
1,
|
||||
m_viewProjectionConstantBuffer.GetAddressOf()
|
||||
);*/
|
||||
|
||||
m_framePending = false;
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface CameraResources::GetDepthStencilTextureInteropObject()
|
||||
{
|
||||
// Direct3D interop APIs are used to provide the buffer to the WinRT API.
|
||||
winrt::com_ptr<IDXGIResource1> depthStencilResource;
|
||||
winrt::check_bool(m_d3dDepthStencil.try_as(depthStencilResource));
|
||||
winrt::com_ptr<IDXGISurface2> depthDxgiSurface;
|
||||
winrt::check_hresult(depthStencilResource->CreateSubresourceSurface(0, depthDxgiSurface.put()));
|
||||
winrt::com_ptr<::IInspectable> inspectableSurface;
|
||||
winrt::check_hresult(CreateDirect3D11SurfaceFromDXGISurface(
|
||||
depthDxgiSurface.get(), reinterpret_cast<IInspectable**>(winrt::put_abi(inspectableSurface))));
|
||||
return inspectableSurface.as<winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface>();
|
||||
}
|
||||
} // namespace DXHelper
|
|
@ -1,115 +1,122 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <winrt/Windows.Graphics.Holographic.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
using namespace winrt::Windows::Graphics::Holographic;
|
||||
using namespace winrt::Windows::Perception::Spatial;
|
||||
|
||||
namespace DXHelper
|
||||
{
|
||||
class DeviceResources;
|
||||
|
||||
// Constant buffer used to send the view-projection matrices to the shader pipeline.
|
||||
struct ViewProjectionConstantBuffer
|
||||
{
|
||||
DirectX::XMFLOAT4X4 viewProjection[2];
|
||||
};
|
||||
|
||||
// Assert that the constant buffer remains 16-byte aligned (best practice).
|
||||
static_assert(
|
||||
(sizeof(ViewProjectionConstantBuffer) % (sizeof(float) * 4)) == 0,
|
||||
"ViewProjection constant buffer size must be 16-byte aligned (16 bytes is the length of four floats).");
|
||||
|
||||
// Manages DirectX device resources that are specific to a holographic camera, such as the
|
||||
// back buffer, ViewProjection constant buffer, and viewport.
|
||||
class CameraResources
|
||||
{
|
||||
public:
|
||||
CameraResources(const HolographicCamera& holographicCamera);
|
||||
|
||||
void CreateResourcesForBackBuffer(
|
||||
DXHelper::DeviceResources* pDeviceResources, const HolographicCameraRenderingParameters& cameraParameters);
|
||||
void ReleaseResourcesForBackBuffer(DXHelper::DeviceResources* pDeviceResources);
|
||||
|
||||
void UpdateViewProjectionBuffer(
|
||||
std::shared_ptr<DXHelper::DeviceResources> deviceResources,
|
||||
const HolographicCameraPose& cameraPose,
|
||||
const SpatialCoordinateSystem& coordinateSystem);
|
||||
|
||||
bool AttachViewProjectionBuffer(std::shared_ptr<DXHelper::DeviceResources> deviceResources);
|
||||
|
||||
// Direct3D device resources.
|
||||
ID3D11RenderTargetView* GetBackBufferRenderTargetView() const
|
||||
{
|
||||
return m_d3dRenderTargetView.get();
|
||||
}
|
||||
ID3D11DepthStencilView* GetDepthStencilView() const
|
||||
{
|
||||
return m_d3dDepthStencilView.get();
|
||||
}
|
||||
ID3D11Texture2D* GetBackBufferTexture2D() const
|
||||
{
|
||||
return m_d3dBackBuffer.get();
|
||||
}
|
||||
D3D11_VIEWPORT GetViewport() const
|
||||
{
|
||||
return m_d3dViewport;
|
||||
}
|
||||
DXGI_FORMAT GetBackBufferDXGIFormat() const
|
||||
{
|
||||
return m_dxgiFormat;
|
||||
}
|
||||
|
||||
// Render target properties.
|
||||
winrt::Windows::Foundation::Size GetRenderTargetSize() const
|
||||
{
|
||||
return m_d3dRenderTargetSize;
|
||||
}
|
||||
bool IsRenderingStereoscopic() const
|
||||
{
|
||||
return m_isStereo;
|
||||
}
|
||||
|
||||
// The holographic camera these resources are for.
|
||||
const HolographicCamera& GetHolographicCamera() const
|
||||
{
|
||||
return m_holographicCamera;
|
||||
}
|
||||
|
||||
private:
|
||||
// Direct3D rendering objects. Required for 3D.
|
||||
winrt::com_ptr<ID3D11RenderTargetView> m_d3dRenderTargetView;
|
||||
winrt::com_ptr<ID3D11DepthStencilView> m_d3dDepthStencilView;
|
||||
winrt::com_ptr<ID3D11Texture2D> m_d3dBackBuffer;
|
||||
|
||||
// Device resource to store view and projection matrices.
|
||||
winrt::com_ptr<ID3D11Buffer> m_viewProjectionConstantBuffer;
|
||||
|
||||
// Direct3D rendering properties.
|
||||
DXGI_FORMAT m_dxgiFormat;
|
||||
winrt::Windows::Foundation::Size m_d3dRenderTargetSize;
|
||||
D3D11_VIEWPORT m_d3dViewport;
|
||||
|
||||
// Indicates whether the camera supports stereoscopic rendering.
|
||||
bool m_isStereo = false;
|
||||
|
||||
// Indicates whether this camera has a pending frame.
|
||||
bool m_framePending = false;
|
||||
|
||||
// Pointer to the holographic camera these resources are for.
|
||||
HolographicCamera m_holographicCamera = nullptr;
|
||||
};
|
||||
} // namespace DXHelper
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <winrt/Windows.Graphics.Holographic.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
using namespace winrt::Windows::Graphics::Holographic;
|
||||
using namespace winrt::Windows::Perception::Spatial;
|
||||
|
||||
namespace DXHelper
|
||||
{
|
||||
class DeviceResources;
|
||||
|
||||
// Constant buffer used to send the view-projection matrices to the shader pipeline.
|
||||
struct ViewProjectionConstantBuffer
|
||||
{
|
||||
DirectX::XMFLOAT4X4 viewProjection[2];
|
||||
};
|
||||
|
||||
// Assert that the constant buffer remains 16-byte aligned (best practice).
|
||||
static_assert(
|
||||
(sizeof(ViewProjectionConstantBuffer) % (sizeof(float) * 4)) == 0,
|
||||
"ViewProjection constant buffer size must be 16-byte aligned (16 bytes is the length of four floats).");
|
||||
|
||||
// Manages DirectX device resources that are specific to a holographic camera, such as the
|
||||
// back buffer, ViewProjection constant buffer, and viewport.
|
||||
class CameraResources
|
||||
{
|
||||
public:
|
||||
CameraResources(const HolographicCamera& holographicCamera);
|
||||
|
||||
void CreateResourcesForBackBuffer(
|
||||
DXHelper::DeviceResources* pDeviceResources, const HolographicCameraRenderingParameters& cameraParameters);
|
||||
void ReleaseResourcesForBackBuffer(DXHelper::DeviceResources* pDeviceResources);
|
||||
|
||||
void UpdateViewProjectionBuffer(
|
||||
std::shared_ptr<DXHelper::DeviceResources> deviceResources,
|
||||
const HolographicCameraPose& cameraPose,
|
||||
const SpatialCoordinateSystem& coordinateSystem);
|
||||
|
||||
bool AttachViewProjectionBuffer(std::shared_ptr<DXHelper::DeviceResources> deviceResources);
|
||||
|
||||
// Direct3D device resources.
|
||||
ID3D11RenderTargetView* GetBackBufferRenderTargetView() const
|
||||
{
|
||||
return m_d3dRenderTargetView.get();
|
||||
}
|
||||
ID3D11DepthStencilView* GetDepthStencilView() const
|
||||
{
|
||||
return m_d3dDepthStencilView.get();
|
||||
}
|
||||
ID3D11Texture2D* GetBackBufferTexture2D() const
|
||||
{
|
||||
return m_d3dBackBuffer.get();
|
||||
}
|
||||
ID3D11Texture2D* GetDepthStencilTexture2D() const
|
||||
{
|
||||
return m_d3dDepthStencil.get();
|
||||
}
|
||||
D3D11_VIEWPORT GetViewport() const
|
||||
{
|
||||
return m_d3dViewport;
|
||||
}
|
||||
DXGI_FORMAT GetBackBufferDXGIFormat() const
|
||||
{
|
||||
return m_dxgiFormat;
|
||||
}
|
||||
|
||||
// Render target properties.
|
||||
winrt::Windows::Foundation::Size GetRenderTargetSize() const
|
||||
{
|
||||
return m_d3dRenderTargetSize;
|
||||
}
|
||||
bool IsRenderingStereoscopic() const
|
||||
{
|
||||
return m_isStereo;
|
||||
}
|
||||
|
||||
// The holographic camera these resources are for.
|
||||
const HolographicCamera& GetHolographicCamera() const
|
||||
{
|
||||
return m_holographicCamera;
|
||||
}
|
||||
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface GetDepthStencilTextureInteropObject();
|
||||
|
||||
private:
|
||||
// Direct3D rendering objects. Required for 3D.
|
||||
winrt::com_ptr<ID3D11RenderTargetView> m_d3dRenderTargetView;
|
||||
winrt::com_ptr<ID3D11DepthStencilView> m_d3dDepthStencilView;
|
||||
winrt::com_ptr<ID3D11Texture2D> m_d3dBackBuffer;
|
||||
winrt::com_ptr<ID3D11Texture2D> m_d3dDepthStencil;
|
||||
|
||||
// Device resource to store view and projection matrices.
|
||||
winrt::com_ptr<ID3D11Buffer> m_viewProjectionConstantBuffer;
|
||||
|
||||
// Direct3D rendering properties.
|
||||
DXGI_FORMAT m_dxgiFormat = DXGI_FORMAT_UNKNOWN;
|
||||
winrt::Windows::Foundation::Size m_d3dRenderTargetSize = {};
|
||||
D3D11_VIEWPORT m_d3dViewport = {};
|
||||
|
||||
// Indicates whether the camera supports stereoscopic rendering.
|
||||
bool m_isStereo = false;
|
||||
|
||||
// Indicates whether this camera has a pending frame.
|
||||
bool m_framePending = false;
|
||||
|
||||
// Pointer to the holographic camera these resources are for.
|
||||
HolographicCamera m_holographicCamera = nullptr;
|
||||
};
|
||||
} // namespace DXHelper
|
|
@ -1,37 +1,37 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
static void DebugLog(_In_z_ LPCWSTR format, ...)
|
||||
{
|
||||
wchar_t buffer[1024];
|
||||
LPWSTR bufEnd = nullptr;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
HRESULT hr =
|
||||
StringCchVPrintfExW(buffer, _countof(buffer), &bufEnd, nullptr, STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE, format, args);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (*bufEnd != L'\n')
|
||||
{
|
||||
StringCchCatW(buffer, _countof(buffer), L"\r\n");
|
||||
}
|
||||
|
||||
OutputDebugStringW(buffer);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
static void DebugLog(_In_z_ LPCWSTR format, ...)
|
||||
{
|
||||
wchar_t buffer[1024];
|
||||
LPWSTR bufEnd = nullptr;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
HRESULT hr =
|
||||
StringCchVPrintfExW(buffer, _countof(buffer), &bufEnd, nullptr, STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE, format, args);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (*bufEnd != L'\n')
|
||||
{
|
||||
StringCchCatW(buffer, _countof(buffer), L"\r\n");
|
||||
}
|
||||
|
||||
OutputDebugStringW(buffer);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}
|
|
@ -1,304 +1,305 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "DeviceResources.h"
|
||||
#include "DirectXHelper.h"
|
||||
|
||||
#include <winrt/Windows.Graphics.Display.h>
|
||||
|
||||
using namespace D2D1;
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace winrt::Windows::Graphics::DirectX::Direct3D11;
|
||||
using namespace winrt::Windows::Graphics::Display;
|
||||
using namespace winrt::Windows::Graphics::Holographic;
|
||||
|
||||
// Constructor for DeviceResources.
|
||||
DXHelper::DeviceResources::DeviceResources()
|
||||
{
|
||||
CreateDeviceIndependentResources();
|
||||
}
|
||||
|
||||
DXHelper::DeviceResources::~DeviceResources()
|
||||
{
|
||||
if (m_d3dContext)
|
||||
{
|
||||
m_d3dContext->Flush();
|
||||
m_d3dContext->ClearState();
|
||||
}
|
||||
}
|
||||
|
||||
// Configures resources that don't depend on the Direct3D device.
|
||||
void DXHelper::DeviceResources::CreateDeviceIndependentResources()
|
||||
{
|
||||
// Initialize Direct2D resources.
|
||||
D2D1_FACTORY_OPTIONS options{};
|
||||
|
||||
#if defined(_DEBUG)
|
||||
// If the project is in a debug build, enable Direct2D debugging via SDK Layers.
|
||||
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
|
||||
#endif
|
||||
|
||||
// Initialize the Direct2D Factory.
|
||||
winrt::check_hresult(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory2), &options, m_d2dFactory.put_void()));
|
||||
|
||||
// Initialize the DirectWrite Factory.
|
||||
winrt::check_hresult(
|
||||
DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory2), (::IUnknown**)m_dwriteFactory.put_void()));
|
||||
|
||||
// Initialize the Windows Imaging Component (WIC) Factory.
|
||||
winrt::check_hresult(
|
||||
CoCreateInstance(CLSID_WICImagingFactory2, nullptr, CLSCTX_INPROC_SERVER, __uuidof(m_wicFactory), m_wicFactory.put_void()));
|
||||
}
|
||||
|
||||
void DXHelper::DeviceResources::SetHolographicSpace(HolographicSpace holographicSpace)
|
||||
{
|
||||
// Cache the holographic space. Used to re-initalize during device-lost scenarios.
|
||||
m_holographicSpace = holographicSpace;
|
||||
|
||||
InitializeUsingHolographicSpace();
|
||||
}
|
||||
|
||||
void DXHelper::DeviceResources::InitializeUsingHolographicSpace()
|
||||
{
|
||||
// The holographic space might need to determine which adapter supports
|
||||
// holograms, in which case it will specify a non-zero PrimaryAdapterId.
|
||||
LUID id = {m_holographicSpace.PrimaryAdapterId().LowPart, m_holographicSpace.PrimaryAdapterId().HighPart};
|
||||
|
||||
// When a primary adapter ID is given to the app, the app should find
|
||||
// the corresponding DXGI adapter and use it to create Direct3D devices
|
||||
// and device contexts. Otherwise, there is no restriction on the DXGI
|
||||
// adapter the app can use.
|
||||
if ((id.HighPart != 0) || (id.LowPart != 0))
|
||||
{
|
||||
UINT createFlags = 0;
|
||||
#ifdef DEBUG
|
||||
if (DXHelper::SdkLayersAvailable())
|
||||
{
|
||||
createFlags |= DXGI_CREATE_FACTORY_DEBUG;
|
||||
}
|
||||
#endif
|
||||
// Create the DXGI factory.
|
||||
winrt::com_ptr<IDXGIFactory1> dxgiFactory;
|
||||
winrt::check_hresult(CreateDXGIFactory2(createFlags, __uuidof(dxgiFactory), dxgiFactory.put_void()));
|
||||
winrt::com_ptr<IDXGIFactory4> dxgiFactory4;
|
||||
dxgiFactory.as(dxgiFactory4);
|
||||
|
||||
// Retrieve the adapter specified by the holographic space.
|
||||
winrt::check_hresult(dxgiFactory4->EnumAdapterByLuid(id, __uuidof(m_dxgiAdapter), m_dxgiAdapter.put_void()));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dxgiAdapter = nullptr;
|
||||
}
|
||||
|
||||
CreateDeviceResources();
|
||||
|
||||
m_holographicSpace.SetDirect3D11Device(m_d3dInteropDevice);
|
||||
}
|
||||
|
||||
// Configures the Direct3D device, and stores handles to it and the device context.
|
||||
void DXHelper::DeviceResources::CreateDeviceResources()
|
||||
{
|
||||
// This flag adds support for surfaces with a different color channel ordering
|
||||
// than the API default. It is required for compatibility with Direct2D.
|
||||
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
|
||||
#if defined(_DEBUG)
|
||||
if (DXHelper::SdkLayersAvailable())
|
||||
{
|
||||
// If the project is in a debug build, enable debugging via SDK Layers with this flag.
|
||||
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
}
|
||||
#endif
|
||||
|
||||
// This array defines the set of DirectX hardware feature levels this app will support.
|
||||
// Note the ordering should be preserved.
|
||||
// Note that HoloLens supports feature level 11.1. The HoloLens emulator is also capable
|
||||
// of running on graphics cards starting with feature level 10.0.
|
||||
D3D_FEATURE_LEVEL featureLevels[] = {D3D_FEATURE_LEVEL_12_1,
|
||||
D3D_FEATURE_LEVEL_12_0,
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0};
|
||||
|
||||
// Create the Direct3D 11 API device object and a corresponding context.
|
||||
winrt::com_ptr<ID3D11Device> device;
|
||||
winrt::com_ptr<ID3D11DeviceContext> context;
|
||||
|
||||
const D3D_DRIVER_TYPE driverType = m_dxgiAdapter == nullptr ? D3D_DRIVER_TYPE_HARDWARE : D3D_DRIVER_TYPE_UNKNOWN;
|
||||
const HRESULT hr = D3D11CreateDevice(
|
||||
m_dxgiAdapter.get(), // Either nullptr, or the primary adapter determined by Windows Holographic.
|
||||
driverType, // Create a device using the hardware graphics driver.
|
||||
0, // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE.
|
||||
creationFlags, // Set debug and Direct2D compatibility flags.
|
||||
featureLevels, // List of feature levels this app can support.
|
||||
ARRAYSIZE(featureLevels), // Size of the list above.
|
||||
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
|
||||
device.put(), // Returns the Direct3D device created.
|
||||
&m_d3dFeatureLevel, // Returns feature level of device created.
|
||||
context.put() // Returns the device immediate context.
|
||||
);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// If the initialization fails, fall back to the WARP device.
|
||||
// For more information on WARP, see:
|
||||
// http://go.microsoft.com/fwlink/?LinkId=286690
|
||||
winrt::check_hresult(D3D11CreateDevice(
|
||||
nullptr, // Use the default DXGI adapter for WARP.
|
||||
D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device.
|
||||
0,
|
||||
creationFlags,
|
||||
featureLevels,
|
||||
ARRAYSIZE(featureLevels),
|
||||
D3D11_SDK_VERSION,
|
||||
device.put(),
|
||||
&m_d3dFeatureLevel,
|
||||
context.put()));
|
||||
}
|
||||
|
||||
// Store pointers to the Direct3D device and immediate context.
|
||||
device.as(m_d3dDevice);
|
||||
context.as(m_d3dContext);
|
||||
|
||||
// Acquire the DXGI interface for the Direct3D device.
|
||||
winrt::com_ptr<IDXGIDevice3> dxgiDevice;
|
||||
m_d3dDevice.as(dxgiDevice);
|
||||
|
||||
// Wrap the native device using a WinRT interop object.
|
||||
winrt::com_ptr<::IInspectable> object;
|
||||
winrt::check_hresult(CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.get(), reinterpret_cast<IInspectable**>(winrt::put_abi(object))));
|
||||
m_d3dInteropDevice = object.as<IDirect3DDevice>();
|
||||
|
||||
// Cache the DXGI adapter.
|
||||
// This is for the case of no preferred DXGI adapter, or fallback to WARP.
|
||||
winrt::com_ptr<IDXGIAdapter> dxgiAdapter;
|
||||
dxgiDevice->GetAdapter(dxgiAdapter.put());
|
||||
dxgiAdapter.as(m_dxgiAdapter);
|
||||
|
||||
// Check for device support for the optional feature that allows setting the render target array index from the vertex shader stage.
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS3 options;
|
||||
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &options, sizeof(options));
|
||||
if (options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer)
|
||||
{
|
||||
m_supportsVprt = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Validates the back buffer for each HolographicCamera and recreates
|
||||
// resources for back buffers that have changed.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DXHelper::DeviceResources::EnsureCameraResources(HolographicFrame frame, HolographicFramePrediction prediction)
|
||||
{
|
||||
UseHolographicCameraResources([this, frame, prediction](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
for (HolographicCameraPose const& cameraPose : prediction.CameraPoses())
|
||||
{
|
||||
try
|
||||
{
|
||||
HolographicCameraRenderingParameters renderingParameters = frame.GetRenderingParameters(cameraPose);
|
||||
CameraResources* pCameraResources = cameraResourceMap[cameraPose.HolographicCamera().Id()].get();
|
||||
pCameraResources->CreateResourcesForBackBuffer(this, renderingParameters);
|
||||
}
|
||||
catch (const winrt::hresult_error&)
|
||||
{
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Prepares to allocate resources and adds resource views for a camera.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DXHelper::DeviceResources::AddHolographicCamera(HolographicCamera camera)
|
||||
{
|
||||
UseHolographicCameraResources([this, camera](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
cameraResourceMap[camera.Id()] = std::make_unique<CameraResources>(camera);
|
||||
});
|
||||
}
|
||||
|
||||
// Deallocates resources for a camera and removes the camera from the set.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DXHelper::DeviceResources::RemoveHolographicCamera(HolographicCamera camera)
|
||||
{
|
||||
UseHolographicCameraResources([this, camera](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
CameraResources* pCameraResources = cameraResourceMap[camera.Id()].get();
|
||||
|
||||
if (pCameraResources != nullptr)
|
||||
{
|
||||
pCameraResources->ReleaseResourcesForBackBuffer(this);
|
||||
cameraResourceMap.erase(camera.Id());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Recreate all device resources and set them back to the current state.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DXHelper::DeviceResources::HandleDeviceLost()
|
||||
{
|
||||
if (m_deviceNotify != nullptr)
|
||||
{
|
||||
m_deviceNotify->OnDeviceLost();
|
||||
}
|
||||
|
||||
UseHolographicCameraResources([this](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
for (auto& pair : cameraResourceMap)
|
||||
{
|
||||
CameraResources* pCameraResources = pair.second.get();
|
||||
pCameraResources->ReleaseResourcesForBackBuffer(this);
|
||||
}
|
||||
});
|
||||
|
||||
InitializeUsingHolographicSpace();
|
||||
|
||||
if (m_deviceNotify != nullptr)
|
||||
{
|
||||
m_deviceNotify->OnDeviceRestored();
|
||||
}
|
||||
}
|
||||
|
||||
// Register our DeviceNotify to be informed on device lost and creation.
|
||||
void DXHelper::DeviceResources::RegisterDeviceNotify(DXHelper::IDeviceNotify* deviceNotify)
|
||||
{
|
||||
m_deviceNotify = deviceNotify;
|
||||
}
|
||||
|
||||
// Call this method when the app suspends. It provides a hint to the driver that the app
|
||||
// is entering an idle state and that temporary buffers can be reclaimed for use by other apps.
|
||||
void DXHelper::DeviceResources::Trim()
|
||||
{
|
||||
m_d3dContext->ClearState();
|
||||
|
||||
winrt::com_ptr<IDXGIDevice3> dxgiDevice;
|
||||
m_d3dDevice.as(dxgiDevice);
|
||||
dxgiDevice->Trim();
|
||||
}
|
||||
|
||||
// Present the contents of the swap chain to the screen.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DXHelper::DeviceResources::Present(HolographicFrame frame)
|
||||
{
|
||||
// By default, this API waits for the frame to finish before it returns.
|
||||
// For Holographic Remoting we do not wait but instead wait in SampleHostMain::Update to ensure that CreateNextFrame is called exactly
|
||||
// with a delta of 16.6ms (in case of 60Hz).
|
||||
HolographicFramePresentResult presentResult =
|
||||
frame.PresentUsingCurrentPrediction(HolographicFramePresentWaitBehavior::DoNotWaitForFrameToFinish);
|
||||
|
||||
// The PresentUsingCurrentPrediction API will detect when the graphics device
|
||||
// changes or becomes invalid. When this happens, it is considered a Direct3D
|
||||
// device lost scenario.
|
||||
if (presentResult == HolographicFramePresentResult::DeviceRemoved)
|
||||
{
|
||||
// The Direct3D device, context, and resources should be recreated.
|
||||
HandleDeviceLost();
|
||||
}
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "DeviceResources.h"
|
||||
#include "DirectXHelper.h"
|
||||
|
||||
#include <winrt/Windows.Graphics.Display.h>
|
||||
|
||||
using namespace D2D1;
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace winrt::Windows::Graphics::DirectX::Direct3D11;
|
||||
using namespace winrt::Windows::Graphics::Display;
|
||||
using namespace winrt::Windows::Graphics::Holographic;
|
||||
|
||||
// Constructor for DeviceResources.
|
||||
DXHelper::DeviceResources::DeviceResources()
|
||||
{
|
||||
CreateDeviceIndependentResources();
|
||||
}
|
||||
|
||||
DXHelper::DeviceResources::~DeviceResources()
|
||||
{
|
||||
if (m_d3dContext)
|
||||
{
|
||||
m_d3dContext->Flush();
|
||||
m_d3dContext->ClearState();
|
||||
}
|
||||
}
|
||||
|
||||
// Configures resources that don't depend on the Direct3D device.
|
||||
void DXHelper::DeviceResources::CreateDeviceIndependentResources()
|
||||
{
|
||||
// Initialize Direct2D resources.
|
||||
D2D1_FACTORY_OPTIONS options{};
|
||||
|
||||
#if defined(_DEBUG)
|
||||
// If the project is in a debug build, enable Direct2D debugging via SDK Layers.
|
||||
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
|
||||
#endif
|
||||
|
||||
// Initialize the Direct2D Factory.
|
||||
winrt::check_hresult(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory2), &options, m_d2dFactory.put_void()));
|
||||
|
||||
// Initialize the DirectWrite Factory.
|
||||
winrt::check_hresult(
|
||||
DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory2), (::IUnknown**)m_dwriteFactory.put_void()));
|
||||
|
||||
// Initialize the Windows Imaging Component (WIC) Factory.
|
||||
winrt::check_hresult(
|
||||
CoCreateInstance(CLSID_WICImagingFactory2, nullptr, CLSCTX_INPROC_SERVER, __uuidof(m_wicFactory), m_wicFactory.put_void()));
|
||||
}
|
||||
|
||||
void DXHelper::DeviceResources::SetHolographicSpace(HolographicSpace holographicSpace)
|
||||
{
|
||||
// Cache the holographic space. Used to re-initalize during device-lost scenarios.
|
||||
m_holographicSpace = holographicSpace;
|
||||
|
||||
InitializeUsingHolographicSpace();
|
||||
}
|
||||
|
||||
void DXHelper::DeviceResources::InitializeUsingHolographicSpace()
|
||||
{
|
||||
// The holographic space might need to determine which adapter supports
|
||||
// holograms, in which case it will specify a non-zero PrimaryAdapterId.
|
||||
LUID id = {m_holographicSpace.PrimaryAdapterId().LowPart, m_holographicSpace.PrimaryAdapterId().HighPart};
|
||||
|
||||
// When a primary adapter ID is given to the app, the app should find
|
||||
// the corresponding DXGI adapter and use it to create Direct3D devices
|
||||
// and device contexts. Otherwise, there is no restriction on the DXGI
|
||||
// adapter the app can use.
|
||||
if ((id.HighPart != 0) || (id.LowPart != 0))
|
||||
{
|
||||
UINT createFlags = 0;
|
||||
#ifdef DEBUG
|
||||
if (DXHelper::SdkLayersAvailable())
|
||||
{
|
||||
createFlags |= DXGI_CREATE_FACTORY_DEBUG;
|
||||
}
|
||||
#endif
|
||||
// Create the DXGI factory.
|
||||
winrt::com_ptr<IDXGIFactory1> dxgiFactory;
|
||||
winrt::check_hresult(CreateDXGIFactory2(createFlags, __uuidof(dxgiFactory), dxgiFactory.put_void()));
|
||||
winrt::com_ptr<IDXGIFactory4> dxgiFactory4;
|
||||
dxgiFactory.as(dxgiFactory4);
|
||||
|
||||
// Retrieve the adapter specified by the holographic space.
|
||||
winrt::check_hresult(dxgiFactory4->EnumAdapterByLuid(id, __uuidof(m_dxgiAdapter), m_dxgiAdapter.put_void()));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dxgiAdapter = nullptr;
|
||||
}
|
||||
|
||||
CreateDeviceResources();
|
||||
|
||||
m_holographicSpace.SetDirect3D11Device(m_d3dInteropDevice);
|
||||
}
|
||||
|
||||
// Configures the Direct3D device, and stores handles to it and the device context.
|
||||
void DXHelper::DeviceResources::CreateDeviceResources()
|
||||
{
|
||||
// This flag adds support for surfaces with a different color channel ordering
|
||||
// than the API default. It is required for compatibility with Direct2D.
|
||||
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
|
||||
#if defined(_DEBUG)
|
||||
if (DXHelper::SdkLayersAvailable())
|
||||
{
|
||||
// If the project is in a debug build, enable debugging via SDK Layers with this flag.
|
||||
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
}
|
||||
#endif
|
||||
|
||||
// This array defines the set of DirectX hardware feature levels this app will support.
|
||||
// Note the ordering should be preserved.
|
||||
// Note that HoloLens supports feature level 11.1. The HoloLens emulator is also capable
|
||||
// of running on graphics cards starting with feature level 10.0.
|
||||
D3D_FEATURE_LEVEL featureLevels[] = {
|
||||
D3D_FEATURE_LEVEL_12_1,
|
||||
D3D_FEATURE_LEVEL_12_0,
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0};
|
||||
|
||||
// Create the Direct3D 11 API device object and a corresponding context.
|
||||
winrt::com_ptr<ID3D11Device> device;
|
||||
winrt::com_ptr<ID3D11DeviceContext> context;
|
||||
|
||||
const D3D_DRIVER_TYPE driverType = m_dxgiAdapter == nullptr ? D3D_DRIVER_TYPE_HARDWARE : D3D_DRIVER_TYPE_UNKNOWN;
|
||||
const HRESULT hr = D3D11CreateDevice(
|
||||
m_dxgiAdapter.get(), // Either nullptr, or the primary adapter determined by Windows Holographic.
|
||||
driverType, // Create a device using the hardware graphics driver.
|
||||
0, // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE.
|
||||
creationFlags, // Set debug and Direct2D compatibility flags.
|
||||
featureLevels, // List of feature levels this app can support.
|
||||
ARRAYSIZE(featureLevels), // Size of the list above.
|
||||
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
|
||||
device.put(), // Returns the Direct3D device created.
|
||||
&m_d3dFeatureLevel, // Returns feature level of device created.
|
||||
context.put() // Returns the device immediate context.
|
||||
);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// If the initialization fails, fall back to the WARP device.
|
||||
// For more information on WARP, see:
|
||||
// http://go.microsoft.com/fwlink/?LinkId=286690
|
||||
winrt::check_hresult(D3D11CreateDevice(
|
||||
nullptr, // Use the default DXGI adapter for WARP.
|
||||
D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device.
|
||||
0,
|
||||
creationFlags,
|
||||
featureLevels,
|
||||
ARRAYSIZE(featureLevels),
|
||||
D3D11_SDK_VERSION,
|
||||
device.put(),
|
||||
&m_d3dFeatureLevel,
|
||||
context.put()));
|
||||
}
|
||||
|
||||
// Store pointers to the Direct3D device and immediate context.
|
||||
device.as(m_d3dDevice);
|
||||
context.as(m_d3dContext);
|
||||
|
||||
// Acquire the DXGI interface for the Direct3D device.
|
||||
winrt::com_ptr<IDXGIDevice3> dxgiDevice;
|
||||
m_d3dDevice.as(dxgiDevice);
|
||||
|
||||
// Wrap the native device using a WinRT interop object.
|
||||
winrt::com_ptr<::IInspectable> object;
|
||||
winrt::check_hresult(CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.get(), reinterpret_cast<IInspectable**>(winrt::put_abi(object))));
|
||||
m_d3dInteropDevice = object.as<IDirect3DDevice>();
|
||||
|
||||
// Cache the DXGI adapter.
|
||||
// This is for the case of no preferred DXGI adapter, or fallback to WARP.
|
||||
winrt::com_ptr<IDXGIAdapter> dxgiAdapter;
|
||||
dxgiDevice->GetAdapter(dxgiAdapter.put());
|
||||
dxgiAdapter.as(m_dxgiAdapter);
|
||||
|
||||
// Check for device support for the optional feature that allows setting the render target array index from the vertex shader stage.
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS3 options;
|
||||
m_d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &options, sizeof(options));
|
||||
if (options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer)
|
||||
{
|
||||
m_supportsVprt = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Validates the back buffer for each HolographicCamera and recreates
|
||||
// resources for back buffers that have changed.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DXHelper::DeviceResources::EnsureCameraResources(HolographicFrame frame, HolographicFramePrediction prediction)
|
||||
{
|
||||
UseHolographicCameraResources([this, frame, prediction](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
for (HolographicCameraPose const& cameraPose : prediction.CameraPoses())
|
||||
{
|
||||
try
|
||||
{
|
||||
HolographicCameraRenderingParameters renderingParameters = frame.GetRenderingParameters(cameraPose);
|
||||
CameraResources* pCameraResources = cameraResourceMap[cameraPose.HolographicCamera().Id()].get();
|
||||
pCameraResources->CreateResourcesForBackBuffer(this, renderingParameters);
|
||||
}
|
||||
catch (const winrt::hresult_error&)
|
||||
{
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Prepares to allocate resources and adds resource views for a camera.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DXHelper::DeviceResources::AddHolographicCamera(HolographicCamera camera)
|
||||
{
|
||||
UseHolographicCameraResources([this, camera](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
cameraResourceMap[camera.Id()] = std::make_unique<CameraResources>(camera);
|
||||
});
|
||||
}
|
||||
|
||||
// Deallocates resources for a camera and removes the camera from the set.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DXHelper::DeviceResources::RemoveHolographicCamera(HolographicCamera camera)
|
||||
{
|
||||
UseHolographicCameraResources([this, camera](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
CameraResources* pCameraResources = cameraResourceMap[camera.Id()].get();
|
||||
|
||||
if (pCameraResources != nullptr)
|
||||
{
|
||||
pCameraResources->ReleaseResourcesForBackBuffer(this);
|
||||
cameraResourceMap.erase(camera.Id());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Recreate all device resources and set them back to the current state.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DXHelper::DeviceResources::HandleDeviceLost()
|
||||
{
|
||||
if (m_deviceNotify != nullptr)
|
||||
{
|
||||
m_deviceNotify->OnDeviceLost();
|
||||
}
|
||||
|
||||
UseHolographicCameraResources([this](std::map<UINT32, std::unique_ptr<CameraResources>>& cameraResourceMap) {
|
||||
for (auto& pair : cameraResourceMap)
|
||||
{
|
||||
CameraResources* pCameraResources = pair.second.get();
|
||||
pCameraResources->ReleaseResourcesForBackBuffer(this);
|
||||
}
|
||||
});
|
||||
|
||||
InitializeUsingHolographicSpace();
|
||||
|
||||
if (m_deviceNotify != nullptr)
|
||||
{
|
||||
m_deviceNotify->OnDeviceRestored();
|
||||
}
|
||||
}
|
||||
|
||||
// Register our DeviceNotify to be informed on device lost and creation.
|
||||
void DXHelper::DeviceResources::RegisterDeviceNotify(DXHelper::IDeviceNotify* deviceNotify)
|
||||
{
|
||||
m_deviceNotify = deviceNotify;
|
||||
}
|
||||
|
||||
// Call this method when the app suspends. It provides a hint to the driver that the app
|
||||
// is entering an idle state and that temporary buffers can be reclaimed for use by other apps.
|
||||
void DXHelper::DeviceResources::Trim()
|
||||
{
|
||||
m_d3dContext->ClearState();
|
||||
|
||||
winrt::com_ptr<IDXGIDevice3> dxgiDevice;
|
||||
m_d3dDevice.as(dxgiDevice);
|
||||
dxgiDevice->Trim();
|
||||
}
|
||||
|
||||
// Present the contents of the swap chain to the screen.
|
||||
// Locks the set of holographic camera resources until the function exits.
|
||||
void DXHelper::DeviceResources::Present(HolographicFrame frame)
|
||||
{
|
||||
// By default, this API waits for the frame to finish before it returns.
|
||||
// For Holographic Remoting we do not wait but instead wait in SampleRemoteMain::Update to ensure that CreateNextFrame is called exactly
|
||||
// with a delta of 16.6ms (in case of 60Hz).
|
||||
HolographicFramePresentResult presentResult =
|
||||
frame.PresentUsingCurrentPrediction(HolographicFramePresentWaitBehavior::DoNotWaitForFrameToFinish);
|
||||
|
||||
// The PresentUsingCurrentPrediction API will detect when the graphics device
|
||||
// changes or becomes invalid. When this happens, it is considered a Direct3D
|
||||
// device lost scenario.
|
||||
if (presentResult == HolographicFramePresentResult::DeviceRemoved)
|
||||
{
|
||||
// The Direct3D device, context, and resources should be recreated.
|
||||
HandleDeviceLost();
|
||||
}
|
||||
}
|
|
@ -1,156 +1,157 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CameraResources.h"
|
||||
|
||||
#include <d2d1_2.h>
|
||||
#include <d3d11_4.h>
|
||||
#include <dwrite_2.h>
|
||||
#include <wincodec.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
namespace DXHelper
|
||||
{
|
||||
// Provides an interface for an application that owns DeviceResources to be notified of the device being lost or created.
|
||||
interface IDeviceNotify
|
||||
{
|
||||
virtual void OnDeviceLost() = 0;
|
||||
virtual void OnDeviceRestored() = 0;
|
||||
};
|
||||
|
||||
// Creates and manages a Direct3D device and immediate context, Direct2D device and context (for debug), and the holographic swap chain.
|
||||
class DeviceResources
|
||||
{
|
||||
public:
|
||||
DeviceResources();
|
||||
~DeviceResources();
|
||||
|
||||
// Public methods related to Direct3D devices.
|
||||
void HandleDeviceLost();
|
||||
void RegisterDeviceNotify(IDeviceNotify* deviceNotify);
|
||||
void Trim();
|
||||
void Present(winrt::Windows::Graphics::Holographic::HolographicFrame frame);
|
||||
|
||||
// Public methods related to holographic devices.
|
||||
void SetHolographicSpace(winrt::Windows::Graphics::Holographic::HolographicSpace space);
|
||||
void EnsureCameraResources(
|
||||
winrt::Windows::Graphics::Holographic::HolographicFrame frame,
|
||||
winrt::Windows::Graphics::Holographic::HolographicFramePrediction prediction);
|
||||
|
||||
void AddHolographicCamera(winrt::Windows::Graphics::Holographic::HolographicCamera camera);
|
||||
void RemoveHolographicCamera(winrt::Windows::Graphics::Holographic::HolographicCamera camera);
|
||||
|
||||
// Holographic accessors.
|
||||
template <typename LCallback>
|
||||
void UseHolographicCameraResources(LCallback const& callback);
|
||||
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice GetD3DInteropDevice() const
|
||||
{
|
||||
return m_d3dInteropDevice;
|
||||
}
|
||||
|
||||
// D3D accessors.
|
||||
ID3D11Device4* GetD3DDevice() const
|
||||
{
|
||||
return m_d3dDevice.get();
|
||||
}
|
||||
template <typename F>
|
||||
auto UseD3DDeviceContext(F func) const
|
||||
{
|
||||
std::scoped_lock lock(m_d3dContextMutex);
|
||||
return func(m_d3dContext.get());
|
||||
}
|
||||
D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const
|
||||
{
|
||||
return m_d3dFeatureLevel;
|
||||
}
|
||||
bool GetDeviceSupportsVprt() const
|
||||
{
|
||||
return m_supportsVprt;
|
||||
}
|
||||
|
||||
// DXGI acessors.
|
||||
IDXGIAdapter3* GetDXGIAdapter() const
|
||||
{
|
||||
return m_dxgiAdapter.get();
|
||||
}
|
||||
|
||||
// D2D accessors.
|
||||
ID2D1Factory2* GetD2DFactory() const
|
||||
{
|
||||
return m_d2dFactory.get();
|
||||
}
|
||||
IDWriteFactory2* GetDWriteFactory() const
|
||||
{
|
||||
return m_dwriteFactory.get();
|
||||
}
|
||||
IWICImagingFactory2* GetWicImagingFactory() const
|
||||
{
|
||||
return m_wicFactory.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
void CreateDeviceResources();
|
||||
|
||||
private:
|
||||
// Private methods related to the Direct3D device, and resources based on that device.
|
||||
void CreateDeviceIndependentResources();
|
||||
void InitializeUsingHolographicSpace();
|
||||
|
||||
protected:
|
||||
// Direct3D objects.
|
||||
winrt::com_ptr<ID3D11Device4> m_d3dDevice;
|
||||
mutable std::recursive_mutex m_d3dContextMutex;
|
||||
winrt::com_ptr<ID3D11DeviceContext3> m_d3dContext;
|
||||
winrt::com_ptr<IDXGIAdapter3> m_dxgiAdapter;
|
||||
|
||||
// Direct3D interop objects.
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice m_d3dInteropDevice;
|
||||
|
||||
// Direct2D factories.
|
||||
winrt::com_ptr<ID2D1Factory2> m_d2dFactory;
|
||||
winrt::com_ptr<IDWriteFactory2> m_dwriteFactory;
|
||||
winrt::com_ptr<IWICImagingFactory2> m_wicFactory;
|
||||
|
||||
// The IDeviceNotify can be held directly as it owns the DeviceResources.
|
||||
IDeviceNotify* m_deviceNotify = nullptr;
|
||||
|
||||
// Whether or not the current Direct3D device supports the optional feature
|
||||
// for setting the render target array index from the vertex shader stage.
|
||||
bool m_supportsVprt = false;
|
||||
|
||||
private:
|
||||
// The holographic space provides a preferred DXGI adapter ID.
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace m_holographicSpace = nullptr;
|
||||
|
||||
// Properties of the Direct3D device currently in use.
|
||||
D3D_FEATURE_LEVEL m_d3dFeatureLevel = D3D_FEATURE_LEVEL_10_0;
|
||||
|
||||
// Back buffer resources, etc. for attached holographic cameras.
|
||||
std::map<UINT32, std::unique_ptr<CameraResources>> m_cameraResources;
|
||||
std::mutex m_cameraResourcesLock;
|
||||
};
|
||||
} // namespace DXHelper
|
||||
|
||||
// Device-based resources for holographic cameras are stored in a std::map. Access this list by providing a
|
||||
// callback to this function, and the std::map will be guarded from add and remove
|
||||
// events until the callback returns. The callback is processed immediately and must
|
||||
// not contain any nested calls to UseHolographicCameraResources.
|
||||
// The callback takes a parameter of type std::map<UINT32, std::unique_ptr<DXHelper::CameraResources>>&
|
||||
// through which the list of cameras will be accessed.
|
||||
template <typename LCallback>
|
||||
void DXHelper::DeviceResources::UseHolographicCameraResources(LCallback const& callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_cameraResourcesLock);
|
||||
callback(m_cameraResources);
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CameraResources.h"
|
||||
|
||||
#include <d2d1_2.h>
|
||||
#include <d3d11_4.h>
|
||||
#include <dwrite_2.h>
|
||||
#include <mutex>
|
||||
#include <wincodec.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
namespace DXHelper
|
||||
{
|
||||
// Provides an interface for an application that owns DeviceResources to be notified of the device being lost or created.
|
||||
interface IDeviceNotify
|
||||
{
|
||||
virtual void OnDeviceLost() = 0;
|
||||
virtual void OnDeviceRestored() = 0;
|
||||
};
|
||||
|
||||
// Creates and manages a Direct3D device and immediate context, Direct2D device and context (for debug), and the holographic swap chain.
|
||||
class DeviceResources
|
||||
{
|
||||
public:
|
||||
DeviceResources();
|
||||
~DeviceResources();
|
||||
|
||||
// Public methods related to Direct3D devices.
|
||||
void HandleDeviceLost();
|
||||
void RegisterDeviceNotify(IDeviceNotify* deviceNotify);
|
||||
void Trim();
|
||||
void Present(winrt::Windows::Graphics::Holographic::HolographicFrame frame);
|
||||
|
||||
// Public methods related to holographic devices.
|
||||
void SetHolographicSpace(winrt::Windows::Graphics::Holographic::HolographicSpace space);
|
||||
void EnsureCameraResources(
|
||||
winrt::Windows::Graphics::Holographic::HolographicFrame frame,
|
||||
winrt::Windows::Graphics::Holographic::HolographicFramePrediction prediction);
|
||||
|
||||
void AddHolographicCamera(winrt::Windows::Graphics::Holographic::HolographicCamera camera);
|
||||
void RemoveHolographicCamera(winrt::Windows::Graphics::Holographic::HolographicCamera camera);
|
||||
|
||||
// Holographic accessors.
|
||||
template <typename LCallback>
|
||||
void UseHolographicCameraResources(LCallback const& callback);
|
||||
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice GetD3DInteropDevice() const
|
||||
{
|
||||
return m_d3dInteropDevice;
|
||||
}
|
||||
|
||||
// D3D accessors.
|
||||
ID3D11Device4* GetD3DDevice() const
|
||||
{
|
||||
return m_d3dDevice.get();
|
||||
}
|
||||
template <typename F>
|
||||
auto UseD3DDeviceContext(F func) const
|
||||
{
|
||||
std::scoped_lock lock(m_d3dContextMutex);
|
||||
return func(m_d3dContext.get());
|
||||
}
|
||||
D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const
|
||||
{
|
||||
return m_d3dFeatureLevel;
|
||||
}
|
||||
bool GetDeviceSupportsVprt() const
|
||||
{
|
||||
return m_supportsVprt;
|
||||
}
|
||||
|
||||
// DXGI acessors.
|
||||
IDXGIAdapter3* GetDXGIAdapter() const
|
||||
{
|
||||
return m_dxgiAdapter.get();
|
||||
}
|
||||
|
||||
// D2D accessors.
|
||||
ID2D1Factory2* GetD2DFactory() const
|
||||
{
|
||||
return m_d2dFactory.get();
|
||||
}
|
||||
IDWriteFactory2* GetDWriteFactory() const
|
||||
{
|
||||
return m_dwriteFactory.get();
|
||||
}
|
||||
IWICImagingFactory2* GetWicImagingFactory() const
|
||||
{
|
||||
return m_wicFactory.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
void CreateDeviceResources();
|
||||
|
||||
private:
|
||||
// Private methods related to the Direct3D device, and resources based on that device.
|
||||
void CreateDeviceIndependentResources();
|
||||
void InitializeUsingHolographicSpace();
|
||||
|
||||
protected:
|
||||
// Direct3D objects.
|
||||
winrt::com_ptr<ID3D11Device4> m_d3dDevice;
|
||||
mutable std::recursive_mutex m_d3dContextMutex;
|
||||
winrt::com_ptr<ID3D11DeviceContext3> m_d3dContext;
|
||||
winrt::com_ptr<IDXGIAdapter3> m_dxgiAdapter;
|
||||
|
||||
// Direct3D interop objects.
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice m_d3dInteropDevice;
|
||||
|
||||
// Direct2D factories.
|
||||
winrt::com_ptr<ID2D1Factory2> m_d2dFactory;
|
||||
winrt::com_ptr<IDWriteFactory2> m_dwriteFactory;
|
||||
winrt::com_ptr<IWICImagingFactory2> m_wicFactory;
|
||||
|
||||
// The IDeviceNotify can be held directly as it owns the DeviceResources.
|
||||
IDeviceNotify* m_deviceNotify = nullptr;
|
||||
|
||||
// Whether or not the current Direct3D device supports the optional feature
|
||||
// for setting the render target array index from the vertex shader stage.
|
||||
bool m_supportsVprt = false;
|
||||
|
||||
private:
|
||||
// The holographic space provides a preferred DXGI adapter ID.
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace m_holographicSpace = nullptr;
|
||||
|
||||
// Properties of the Direct3D device currently in use.
|
||||
D3D_FEATURE_LEVEL m_d3dFeatureLevel = D3D_FEATURE_LEVEL_10_0;
|
||||
|
||||
// Back buffer resources, etc. for attached holographic cameras.
|
||||
std::map<UINT32, std::unique_ptr<CameraResources>> m_cameraResources;
|
||||
std::mutex m_cameraResourcesLock;
|
||||
};
|
||||
} // namespace DXHelper
|
||||
|
||||
// Device-based resources for holographic cameras are stored in a std::map. Access this list by providing a
|
||||
// callback to this function, and the std::map will be guarded from add and remove
|
||||
// events until the callback returns. The callback is processed immediately and must
|
||||
// not contain any nested calls to UseHolographicCameraResources.
|
||||
// The callback takes a parameter of type std::map<UINT32, std::unique_ptr<DXHelper::CameraResources>>&
|
||||
// through which the list of cameras will be accessed.
|
||||
template <typename LCallback>
|
||||
void DXHelper::DeviceResources::UseHolographicCameraResources(LCallback const& callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_cameraResourcesLock);
|
||||
callback(m_cameraResources);
|
||||
}
|
|
@ -1,87 +1,89 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wrl.h>
|
||||
|
||||
#include <future>
|
||||
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
|
||||
#include <winrt/Windows.Graphics.DirectX.Direct3D11.h>
|
||||
|
||||
#include <windows.graphics.directx.direct3d11.interop.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <dxgi1_2.h>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace DXHelper
|
||||
{
|
||||
// Function that reads from a binary file asynchronously.
|
||||
inline std::future<std::vector<byte>> ReadDataAsync(const std::wstring_view& filename)
|
||||
{
|
||||
using namespace winrt::Windows::Storage;
|
||||
using namespace winrt::Windows::Storage::Streams;
|
||||
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
|
||||
wchar_t moduleFullyQualifiedFilename[MAX_PATH] = {};
|
||||
uint32_t moduleFileNameLength = GetModuleFileNameW(NULL, moduleFullyQualifiedFilename, _countof(moduleFullyQualifiedFilename));
|
||||
moduleFullyQualifiedFilename[moduleFileNameLength] = L'\0';
|
||||
|
||||
std::filesystem::path modulePath = moduleFullyQualifiedFilename;
|
||||
// winrt::hstring moduleFilename = modulePath.filename().c_str();
|
||||
modulePath.replace_filename(filename);
|
||||
winrt::hstring absoluteFilename = modulePath.c_str();
|
||||
|
||||
IBuffer fileBuffer = co_await PathIO::ReadBufferAsync(absoluteFilename);
|
||||
#else
|
||||
IBuffer fileBuffer = co_await PathIO::ReadBufferAsync(filename);
|
||||
#endif
|
||||
|
||||
std::vector<byte> returnBuffer;
|
||||
returnBuffer.resize(fileBuffer.Length());
|
||||
DataReader::FromBuffer(fileBuffer).ReadBytes(winrt::array_view<uint8_t>(returnBuffer));
|
||||
return returnBuffer;
|
||||
}
|
||||
|
||||
// Converts a length in device-independent pixels (DIPs) to a length in physical pixels.
|
||||
inline float ConvertDipsToPixels(float dips, float dpi)
|
||||
{
|
||||
static const float dipsPerInch = 96.0f;
|
||||
return floorf(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
|
||||
}
|
||||
|
||||
#if defined(_DEBUG)
|
||||
// Check for SDK Layer support.
|
||||
inline bool SdkLayersAvailable()
|
||||
{
|
||||
HRESULT hr = D3D11CreateDevice(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device.
|
||||
0,
|
||||
D3D11_CREATE_DEVICE_DEBUG, // Check for the SDK layers.
|
||||
nullptr, // Any feature level will do.
|
||||
0,
|
||||
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
|
||||
nullptr, // No need to keep the D3D device reference.
|
||||
nullptr, // No need to know the feature level.
|
||||
nullptr // No need to keep the D3D device context reference.
|
||||
);
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
#endif
|
||||
} // namespace DXHelper
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wrl.h>
|
||||
|
||||
#include <future>
|
||||
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
|
||||
#include <winrt/Windows.Graphics.DirectX.Direct3D11.h>
|
||||
|
||||
#include <windows.graphics.directx.direct3d11.interop.h>
|
||||
|
||||
#include <winrt/Windows.Foundation.Collections.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <dxgi1_2.h>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace DXHelper
|
||||
{
|
||||
// Function that reads from a binary file asynchronously.
|
||||
inline std::future<std::vector<byte>> ReadDataAsync(const std::wstring_view& filename)
|
||||
{
|
||||
using namespace winrt::Windows::Storage;
|
||||
using namespace winrt::Windows::Storage::Streams;
|
||||
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
|
||||
wchar_t moduleFullyQualifiedFilename[MAX_PATH] = {};
|
||||
uint32_t moduleFileNameLength = GetModuleFileNameW(NULL, moduleFullyQualifiedFilename, _countof(moduleFullyQualifiedFilename) - 1);
|
||||
moduleFullyQualifiedFilename[moduleFileNameLength] = L'\0';
|
||||
|
||||
std::filesystem::path modulePath = moduleFullyQualifiedFilename;
|
||||
// winrt::hstring moduleFilename = modulePath.filename().c_str();
|
||||
modulePath.replace_filename(filename);
|
||||
winrt::hstring absoluteFilename = modulePath.c_str();
|
||||
|
||||
IBuffer fileBuffer = co_await PathIO::ReadBufferAsync(absoluteFilename);
|
||||
#else
|
||||
IBuffer fileBuffer = co_await PathIO::ReadBufferAsync(filename);
|
||||
#endif
|
||||
|
||||
std::vector<byte> returnBuffer;
|
||||
returnBuffer.resize(fileBuffer.Length());
|
||||
DataReader::FromBuffer(fileBuffer).ReadBytes(winrt::array_view<uint8_t>(returnBuffer));
|
||||
return returnBuffer;
|
||||
}
|
||||
|
||||
// Converts a length in device-independent pixels (DIPs) to a length in physical pixels.
|
||||
inline float ConvertDipsToPixels(float dips, float dpi)
|
||||
{
|
||||
static const float dipsPerInch = 96.0f;
|
||||
return floorf(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
|
||||
}
|
||||
|
||||
#if defined(_DEBUG)
|
||||
// Check for SDK Layer support.
|
||||
inline bool SdkLayersAvailable()
|
||||
{
|
||||
HRESULT hr = D3D11CreateDevice(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device.
|
||||
0,
|
||||
D3D11_CREATE_DEVICE_DEBUG, // Check for the SDK layers.
|
||||
nullptr, // Any feature level will do.
|
||||
0,
|
||||
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
|
||||
nullptr, // No need to keep the D3D device reference.
|
||||
nullptr, // No need to know the feature level.
|
||||
nullptr // No need to keep the D3D device context reference.
|
||||
);
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
#endif
|
||||
} // namespace DXHelper
|
|
@ -1,18 +1,18 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "../pch.h"
|
||||
|
||||
// -- important: preserve order of these two includes (initguid before PerceptionTypes)!
|
||||
#include <initguid.h>
|
||||
|
||||
#include "PerceptionTypes.h"
|
||||
// --
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "../pch.h"
|
||||
|
||||
// -- important: preserve order of these two includes (initguid before PerceptionTypes)!
|
||||
#include <initguid.h>
|
||||
|
||||
#include "PerceptionTypes.h"
|
||||
// --
|
|
@ -1,33 +1,32 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <guiddef.h>
|
||||
|
||||
DEFINE_GUID(SPATIALPROP_QRTrackerObjectId, 0xf2e86326, 0xfbd8, 0x4088, 0xb5, 0xfb, 0xac, 0x61, 0xc, 0x3, 0x99, 0x7f);
|
||||
DEFINE_GUID(SPATIALPROP_QRTracker_TrackingStatus, 0x270f00dc, 0xc0d9, 0x442c, 0x87, 0x25, 0x27, 0xb6, 0xbb, 0xd9, 0x43, 0xd);
|
||||
DEFINE_GUID(SPATIALPROP_QRTracker_QRCodesList, 0x338b32f8, 0x1ce0, 0x4e75, 0x8d, 0xf4, 0x56, 0xd4, 0x2f, 0x73, 0x96, 0x74);
|
||||
DEFINE_GUID(SPATIALPROP_QRCode_PhysicalSize, 0xcfb07ae5, 0x456a, 0x4aaf, 0x9d, 0x6a, 0xa2, 0x9d, 0x3, 0x9b, 0xc0, 0x56);
|
||||
DEFINE_GUID(SPATIALPROP_QRCode_LastSeenTime, 0xb2b08c2d, 0xb531, 0x4f18, 0x87, 0x84, 0x44, 0x84, 0x46, 0x3d, 0x88, 0x53);
|
||||
DEFINE_GUID(SPATIALPROP_QRCode_StreamInfo, 0x609143ea, 0x4ec5, 0x4b0e, 0xba, 0xef, 0x52, 0xa5, 0x5c, 0xfc, 0x23, 0x58);
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct SPATIAL_GRAPH_QR_CODE_STREAM_INFO
|
||||
{
|
||||
UINT32 Version;
|
||||
ULONG StreamSize;
|
||||
|
||||
_Field_size_(StreamSize) BYTE StreamData[ANYSIZE_ARRAY];
|
||||
|
||||
} SPATIAL_GRAPH_QR_CODE_STREAM_INFO, *PSPATIAL_GRAPH_QR_CODE_STREAM_INFO;
|
||||
#pragma pack(pop)
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <guiddef.h>
|
||||
|
||||
DEFINE_GUID(SPATIALPROP_QRTrackerObjectId, 0xf2e86326, 0xfbd8, 0x4088, 0xb5, 0xfb, 0xac, 0x61, 0xc, 0x3, 0x99, 0x7f);
|
||||
DEFINE_GUID(SPATIALPROP_QRTracker_TrackingStatus, 0x270f00dc, 0xc0d9, 0x442c, 0x87, 0x25, 0x27, 0xb6, 0xbb, 0xd9, 0x43, 0xd);
|
||||
DEFINE_GUID(SPATIALPROP_QRTracker_QRCodesList, 0x338b32f8, 0x1ce0, 0x4e75, 0x8d, 0xf4, 0x56, 0xd4, 0x2f, 0x73, 0x96, 0x74);
|
||||
DEFINE_GUID(SPATIALPROP_QRCode_PhysicalSize, 0xcfb07ae5, 0x456a, 0x4aaf, 0x9d, 0x6a, 0xa2, 0x9d, 0x3, 0x9b, 0xc0, 0x56);
|
||||
DEFINE_GUID(SPATIALPROP_QRCode_LastSeenTime, 0xb2b08c2d, 0xb531, 0x4f18, 0x87, 0x84, 0x44, 0x84, 0x46, 0x3d, 0x88, 0x53);
|
||||
DEFINE_GUID(SPATIALPROP_QRCode_StreamInfo, 0x609143ea, 0x4ec5, 0x4b0e, 0xba, 0xef, 0x52, 0xa5, 0x5c, 0xfc, 0x23, 0x58);
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct SPATIAL_GRAPH_QR_CODE_STREAM_INFO
|
||||
{
|
||||
UINT32 Version;
|
||||
ULONG StreamSize;
|
||||
|
||||
_Field_size_(StreamSize) BYTE StreamData[ANYSIZE_ARRAY];
|
||||
|
||||
} SPATIAL_GRAPH_QR_CODE_STREAM_INFO, *PSPATIAL_GRAPH_QR_CODE_STREAM_INFO;
|
||||
#pragma pack(pop)
|
|
@ -1,70 +1,70 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "SampleHostMain.h"
|
||||
#include "Speech.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace
|
||||
{
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> LoadGrammarFileAsync()
|
||||
{
|
||||
const wchar_t* speechGrammarFile = L"SpeechGrammar.xml";
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
wchar_t executablePath[MAX_PATH];
|
||||
|
||||
if (GetModuleFileNameW(NULL, executablePath, ARRAYSIZE(executablePath)) == 0)
|
||||
{
|
||||
winrt::throw_last_error();
|
||||
}
|
||||
std::filesystem::path executableFolder(executablePath);
|
||||
executableFolder.remove_filename();
|
||||
auto rootFolder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(executableFolder.c_str());
|
||||
auto file = co_await rootFolder.GetFileAsync(speechGrammarFile);
|
||||
co_return file;
|
||||
#else
|
||||
auto rootFolder = winrt::Windows::ApplicationModel::Package::Current().InstalledLocation();
|
||||
return rootFolder.GetFileAsync(speechGrammarFile);
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
|
||||
winrt::fire_and_forget Speech::InitializeSpeechAsync(
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech remoteSpeech,
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech::OnRecognizedSpeech_revoker& onRecognizedSpeechRevoker,
|
||||
std::weak_ptr<SampleHostMain> sampleHostMainWeak)
|
||||
{
|
||||
onRecognizedSpeechRevoker = remoteSpeech.OnRecognizedSpeech(
|
||||
winrt::auto_revoke, [sampleHostMainWeak](const winrt::Microsoft::Holographic::AppRemoting::RecognizedSpeech& recognizedSpeech) {
|
||||
if (auto sampleHostMain = sampleHostMainWeak.lock())
|
||||
{
|
||||
sampleHostMain->OnRecognizedSpeech(recognizedSpeech.RecognizedText);
|
||||
}
|
||||
});
|
||||
|
||||
auto grammarFile = co_await LoadGrammarFileAsync();
|
||||
|
||||
std::vector<winrt::hstring> dictionary;
|
||||
dictionary.push_back(L"Red");
|
||||
dictionary.push_back(L"Blue");
|
||||
dictionary.push_back(L"Green");
|
||||
dictionary.push_back(L"Default");
|
||||
dictionary.push_back(L"Aquamarine");
|
||||
|
||||
remoteSpeech.ApplyParameters(L"en-US", grammarFile, dictionary);
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "SampleRemoteMain.h"
|
||||
#include "Speech.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <winrt/Windows.ApplicationModel.h>
|
||||
#include <winrt/Windows.Storage.h>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace
|
||||
{
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> LoadGrammarFileAsync()
|
||||
{
|
||||
const wchar_t* speechGrammarFile = L"SpeechGrammar.xml";
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
wchar_t executablePath[MAX_PATH];
|
||||
|
||||
if (GetModuleFileNameW(NULL, executablePath, ARRAYSIZE(executablePath)) == 0)
|
||||
{
|
||||
winrt::throw_last_error();
|
||||
}
|
||||
std::filesystem::path executableFolder(executablePath);
|
||||
executableFolder.remove_filename();
|
||||
auto rootFolder = co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(executableFolder.c_str());
|
||||
auto file = co_await rootFolder.GetFileAsync(speechGrammarFile);
|
||||
co_return file;
|
||||
#else
|
||||
auto rootFolder = winrt::Windows::ApplicationModel::Package::Current().InstalledLocation();
|
||||
return rootFolder.GetFileAsync(speechGrammarFile);
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
|
||||
winrt::fire_and_forget Speech::InitializeSpeechAsync(
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech remoteSpeech,
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech::OnRecognizedSpeech_revoker& onRecognizedSpeechRevoker,
|
||||
std::weak_ptr<SampleRemoteMain> sampleRemoteMainWeak)
|
||||
{
|
||||
onRecognizedSpeechRevoker = remoteSpeech.OnRecognizedSpeech(
|
||||
winrt::auto_revoke, [sampleRemoteMainWeak](const winrt::Microsoft::Holographic::AppRemoting::RecognizedSpeech& recognizedSpeech) {
|
||||
if (auto sampleRemoteMain = sampleRemoteMainWeak.lock())
|
||||
{
|
||||
sampleRemoteMain->OnRecognizedSpeech(recognizedSpeech.RecognizedText);
|
||||
}
|
||||
});
|
||||
|
||||
auto grammarFile = co_await LoadGrammarFileAsync();
|
||||
|
||||
std::vector<winrt::hstring> dictionary;
|
||||
dictionary.push_back(L"Red");
|
||||
dictionary.push_back(L"Blue");
|
||||
dictionary.push_back(L"Green");
|
||||
dictionary.push_back(L"Default");
|
||||
dictionary.push_back(L"Aquamarine");
|
||||
|
||||
remoteSpeech.ApplyParameters(L"en-US", grammarFile, dictionary);
|
||||
}
|
|
@ -1,28 +1,27 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <winrt/Microsoft.Holographic.AppRemoting.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
|
||||
|
||||
class SampleHostMain;
|
||||
|
||||
namespace Speech
|
||||
{
|
||||
winrt::fire_and_forget InitializeSpeechAsync(
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech remoteSpeech,
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech::OnRecognizedSpeech_revoker& onRecognizedSpeechRevoker,
|
||||
std::weak_ptr<SampleHostMain> sampleHostMainWeak);
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <winrt/Microsoft.Holographic.AppRemoting.h>
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
|
||||
class SampleRemoteMain;
|
||||
|
||||
namespace Speech
|
||||
{
|
||||
winrt::fire_and_forget InitializeSpeechAsync(
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech remoteSpeech,
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech::OnRecognizedSpeech_revoker& onRecognizedSpeechRevoker,
|
||||
std::weak_ptr<SampleRemoteMain> sampleRemoteMainWeak);
|
||||
}
|
|
@ -1,31 +1,31 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
// comparison function to allow for GUID as a hash map key
|
||||
struct GUIDComparer
|
||||
{
|
||||
inline static int compare(const GUID& Left, const GUID& Right)
|
||||
{
|
||||
return memcmp(&Left, &Right, sizeof(GUID));
|
||||
}
|
||||
|
||||
inline static bool equals(const GUID& Left, const GUID& Right)
|
||||
{
|
||||
return memcmp(&Left, &Right, sizeof(GUID)) == 0;
|
||||
}
|
||||
|
||||
bool operator()(const GUID& Left, const GUID& Right) const
|
||||
{
|
||||
return compare(Left, Right) < 0;
|
||||
}
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
// comparison function to allow for GUID as a hash map key
|
||||
struct GUIDComparer
|
||||
{
|
||||
inline static int compare(const GUID& Left, const GUID& Right)
|
||||
{
|
||||
return memcmp(&Left, &Right, sizeof(GUID));
|
||||
}
|
||||
|
||||
inline static bool equals(const GUID& Left, const GUID& Right)
|
||||
{
|
||||
return memcmp(&Left, &Right, sizeof(GUID)) == 0;
|
||||
}
|
||||
|
||||
bool operator()(const GUID& Left, const GUID& Right) const
|
||||
{
|
||||
return compare(Left, Right) < 0;
|
||||
}
|
||||
};
|
|
@ -1,218 +1,211 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "../pch.h"
|
||||
|
||||
#include "../Common/PerceptionTypes.h"
|
||||
#include "../Common/Utils.h"
|
||||
#include "PerceptionDeviceHandler.h"
|
||||
#include "QRCodeTracker.h"
|
||||
|
||||
|
||||
PerceptionRootObject::~PerceptionRootObject()
|
||||
{
|
||||
}
|
||||
|
||||
const GUID& PerceptionRootObject::GetPropertyId() const
|
||||
{
|
||||
return m_typeId;
|
||||
}
|
||||
|
||||
const GUID& PerceptionRootObject::GetObjectId() const
|
||||
{
|
||||
return m_objectId;
|
||||
}
|
||||
|
||||
PerceptionRootObject::PerceptionRootObject(IPerceptionDevice* device, const GUID& typeId, const GUID& objectId)
|
||||
: m_typeId(typeId)
|
||||
, m_objectId(objectId)
|
||||
{
|
||||
m_device.copy_from(device);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PerceptionDeviceHandler::PerceptionDeviceHandler()
|
||||
{
|
||||
}
|
||||
|
||||
PerceptionDeviceHandler::~PerceptionDeviceHandler()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
void PerceptionDeviceHandler::Start()
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
|
||||
if (m_running)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT hr = PerceptionDeviceCreateFactory(IID_PPV_ARGS(m_perceptionDeviceFactory.put()));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_rootObjectChangeHandler = winrt::make_self<RootObjectChangeHandler>(*this);
|
||||
|
||||
std::array<const GUID, 2> rootObjectIds{QRCodeTracker::GetStaticPropertyId()};
|
||||
for (size_t i = 0; i < rootObjectIds.size(); ++i)
|
||||
{
|
||||
winrt::com_ptr<IPerceptionDeviceRootObjectWatcher> watcher;
|
||||
hr = m_perceptionDeviceFactory->CreateRootObjectWatcher(1, &rootObjectIds[i], PerceptionDeviceOptions::None, watcher.put());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
hr = watcher->SetAddedHandler(m_rootObjectChangeHandler.get());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
hr = watcher->SetRemovedHandler(m_rootObjectChangeHandler.get());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_rootObjectWatchers.emplace_back(std::move(watcher));
|
||||
}
|
||||
|
||||
m_running = true;
|
||||
|
||||
for (auto& watcher : m_rootObjectWatchers)
|
||||
{
|
||||
hr = watcher->Start();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PerceptionDeviceHandler::Stop()
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
|
||||
m_running = false;
|
||||
|
||||
for (auto& watcher : m_rootObjectWatchers)
|
||||
{
|
||||
watcher->Stop();
|
||||
}
|
||||
m_rootObjectWatchers.clear();
|
||||
m_rootObjectChangeHandler = nullptr;
|
||||
m_perceptionDeviceFactory = nullptr;
|
||||
}
|
||||
|
||||
HRESULT PerceptionDeviceHandler::HandleRootObjectAdded(IPerceptionDeviceRootObjectAddedEventArgs* args)
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
|
||||
if (!m_running)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
RootObjectKey key{args->GetPropertyId(), args->GetObjectId()};
|
||||
if (m_rootObjects.find(key) != m_rootObjects.end())
|
||||
{
|
||||
return S_FALSE; // Already have that root object; don't add it twice
|
||||
}
|
||||
|
||||
if (GUIDComparer::equals(key.propertyId, QRCodeTracker::GetStaticPropertyId()))
|
||||
{
|
||||
winrt::com_ptr<IPerceptionDevice> device;
|
||||
args->GetDevice(device.put());
|
||||
m_rootObjects.emplace(key, std::make_shared<QRCodeTracker>(device.get(), key.propertyId, key.objectId));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT PerceptionDeviceHandler::HandleRootObjectRemoved(IPerceptionDeviceRootObjectRemovedEventArgs* args)
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
|
||||
if (!m_running)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
RootObjectKey key{args->GetPropertyId(), args->GetObjectId()};
|
||||
auto it = m_rootObjects.find(key);
|
||||
if (it != m_rootObjects.end())
|
||||
{
|
||||
m_rootObjects.erase(key);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PerceptionDeviceHandler::RootObjectChangeHandler::RootObjectChangeHandler(PerceptionDeviceHandler& owner)
|
||||
: m_weakOwner(owner.weak_from_this())
|
||||
{
|
||||
}
|
||||
|
||||
STDMETHODIMP PerceptionDeviceHandler::RootObjectChangeHandler::Invoke(
|
||||
_In_ IPerceptionDeviceRootObjectWatcher* sender, _In_ IPerceptionDeviceRootObjectAddedEventArgs* args)
|
||||
{
|
||||
auto owner{m_weakOwner.lock()};
|
||||
if (owner)
|
||||
{
|
||||
return owner->HandleRootObjectAdded(args);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP PerceptionDeviceHandler::RootObjectChangeHandler::Invoke(
|
||||
_In_ IPerceptionDeviceRootObjectWatcher* sender, _In_ IPerceptionDeviceRootObjectRemovedEventArgs* args)
|
||||
{
|
||||
auto owner{m_weakOwner.lock()};
|
||||
if (owner)
|
||||
{
|
||||
return owner->HandleRootObjectRemoved(args);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool PerceptionDeviceHandler::RootObjectKey::operator<(const RootObjectKey& other) const
|
||||
{
|
||||
const auto typeIdRes = GUIDComparer::compare(propertyId, other.propertyId);
|
||||
if (typeIdRes < 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (typeIdRes > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GUIDComparer::compare(objectId, other.objectId) < 0;
|
||||
}
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "../pch.h"
|
||||
|
||||
#include "../Common/PerceptionTypes.h"
|
||||
#include "../Common/Utils.h"
|
||||
#include "PerceptionDeviceHandler.h"
|
||||
#include "QRCodeTracker.h"
|
||||
|
||||
PerceptionRootObject::~PerceptionRootObject()
|
||||
{
|
||||
}
|
||||
|
||||
const GUID& PerceptionRootObject::GetPropertyId() const
|
||||
{
|
||||
return m_typeId;
|
||||
}
|
||||
|
||||
const GUID& PerceptionRootObject::GetObjectId() const
|
||||
{
|
||||
return m_objectId;
|
||||
}
|
||||
|
||||
PerceptionRootObject::PerceptionRootObject(IPerceptionDevice* device, const GUID& typeId, const GUID& objectId)
|
||||
: m_typeId(typeId)
|
||||
, m_objectId(objectId)
|
||||
{
|
||||
m_device.copy_from(device);
|
||||
}
|
||||
|
||||
PerceptionDeviceHandler::PerceptionDeviceHandler()
|
||||
{
|
||||
}
|
||||
|
||||
PerceptionDeviceHandler::~PerceptionDeviceHandler()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
void PerceptionDeviceHandler::Start()
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
|
||||
if (m_running)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT hr = PerceptionDeviceCreateFactory(IID_PPV_ARGS(m_perceptionDeviceFactory.put()));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_rootObjectChangeHandler = winrt::make_self<RootObjectChangeHandler>(*this);
|
||||
|
||||
std::array<const GUID, 2> rootObjectIds{QRCodeTracker::GetStaticPropertyId()};
|
||||
for (size_t i = 0; i < rootObjectIds.size(); ++i)
|
||||
{
|
||||
winrt::com_ptr<IPerceptionDeviceRootObjectWatcher> watcher;
|
||||
hr = m_perceptionDeviceFactory->CreateRootObjectWatcher(1, &rootObjectIds[i], PerceptionDeviceOptions::None, watcher.put());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
hr = watcher->SetAddedHandler(m_rootObjectChangeHandler.get());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
hr = watcher->SetRemovedHandler(m_rootObjectChangeHandler.get());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_rootObjectWatchers.emplace_back(std::move(watcher));
|
||||
}
|
||||
|
||||
m_running = true;
|
||||
|
||||
for (auto& watcher : m_rootObjectWatchers)
|
||||
{
|
||||
hr = watcher->Start();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PerceptionDeviceHandler::Stop()
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
|
||||
m_running = false;
|
||||
|
||||
for (auto& watcher : m_rootObjectWatchers)
|
||||
{
|
||||
watcher->Stop();
|
||||
}
|
||||
m_rootObjectWatchers.clear();
|
||||
m_rootObjectChangeHandler = nullptr;
|
||||
m_perceptionDeviceFactory = nullptr;
|
||||
}
|
||||
|
||||
HRESULT PerceptionDeviceHandler::HandleRootObjectAdded(IPerceptionDeviceRootObjectAddedEventArgs* args)
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
|
||||
if (!m_running)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
RootObjectKey key{args->GetPropertyId(), args->GetObjectId()};
|
||||
if (m_rootObjects.find(key) != m_rootObjects.end())
|
||||
{
|
||||
return S_FALSE; // Already have that root object; don't add it twice
|
||||
}
|
||||
|
||||
if (GUIDComparer::equals(key.propertyId, QRCodeTracker::GetStaticPropertyId()))
|
||||
{
|
||||
winrt::com_ptr<IPerceptionDevice> device;
|
||||
args->GetDevice(device.put());
|
||||
m_rootObjects.emplace(key, std::make_shared<QRCodeTracker>(device.get(), key.propertyId, key.objectId));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT PerceptionDeviceHandler::HandleRootObjectRemoved(IPerceptionDeviceRootObjectRemovedEventArgs* args)
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
|
||||
if (!m_running)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
RootObjectKey key{args->GetPropertyId(), args->GetObjectId()};
|
||||
auto it = m_rootObjects.find(key);
|
||||
if (it != m_rootObjects.end())
|
||||
{
|
||||
m_rootObjects.erase(key);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
PerceptionDeviceHandler::RootObjectChangeHandler::RootObjectChangeHandler(PerceptionDeviceHandler& owner)
|
||||
: m_weakOwner(owner.weak_from_this())
|
||||
{
|
||||
}
|
||||
|
||||
STDMETHODIMP PerceptionDeviceHandler::RootObjectChangeHandler::Invoke(
|
||||
_In_ IPerceptionDeviceRootObjectWatcher* sender, _In_ IPerceptionDeviceRootObjectAddedEventArgs* args)
|
||||
{
|
||||
auto owner{m_weakOwner.lock()};
|
||||
if (owner)
|
||||
{
|
||||
return owner->HandleRootObjectAdded(args);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP PerceptionDeviceHandler::RootObjectChangeHandler::Invoke(
|
||||
_In_ IPerceptionDeviceRootObjectWatcher* sender, _In_ IPerceptionDeviceRootObjectRemovedEventArgs* args)
|
||||
{
|
||||
auto owner{m_weakOwner.lock()};
|
||||
if (owner)
|
||||
{
|
||||
return owner->HandleRootObjectRemoved(args);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
bool PerceptionDeviceHandler::RootObjectKey::operator<(const RootObjectKey& other) const
|
||||
{
|
||||
const auto typeIdRes = GUIDComparer::compare(propertyId, other.propertyId);
|
||||
if (typeIdRes < 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (typeIdRes > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GUIDComparer::compare(objectId, other.objectId) < 0;
|
||||
}
|
||||
}
|
|
@ -1,121 +1,119 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
#include <PerceptionDevice.h>
|
||||
|
||||
|
||||
// Base class for perception root objects managed by the PerceptionDeviceHandler
|
||||
class PerceptionRootObject
|
||||
{
|
||||
public:
|
||||
virtual ~PerceptionRootObject();
|
||||
|
||||
const GUID& GetPropertyId() const;
|
||||
const GUID& GetObjectId() const;
|
||||
|
||||
protected:
|
||||
PerceptionRootObject(IPerceptionDevice* device, const GUID& typeId, const GUID& objectId);
|
||||
|
||||
protected:
|
||||
winrt::com_ptr<IPerceptionDevice> m_device;
|
||||
GUID m_typeId;
|
||||
GUID m_objectId;
|
||||
};
|
||||
|
||||
// Sample perception device handler. Listens to the availability of perception devices (more accurately:
|
||||
// perception root objects of known types), and retrieves data from these root objects.
|
||||
class PerceptionDeviceHandler : public std::enable_shared_from_this<PerceptionDeviceHandler>
|
||||
{
|
||||
public:
|
||||
PerceptionDeviceHandler();
|
||||
~PerceptionDeviceHandler();
|
||||
|
||||
// Starts monitoring for perception root object changes
|
||||
void Start();
|
||||
|
||||
// Stops monitoring perception root object changes
|
||||
void Stop();
|
||||
|
||||
// Iterates over all perception root objects currently known
|
||||
template <typename Func>
|
||||
void ForEachRootObject(Func& func)
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
for (auto& rootObjectEntry : m_rootObjects)
|
||||
{
|
||||
func(*rootObjectEntry.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
// Iterates over all root objects of a certain type
|
||||
template <typename RootObjectType, typename Func>
|
||||
void ForEachRootObjectOfType(Func& func)
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
for (auto& rootObjectEntry : m_rootObjects)
|
||||
{
|
||||
PerceptionRootObject& rootObject = *rootObjectEntry.second.get();
|
||||
if (GUIDComparer::equals(rootObject.GetPropertyId(), RootObjectType::GetStaticPropertyId()))
|
||||
{
|
||||
func(static_cast<RootObjectType&>(rootObject));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
struct RootObjectChangeHandler
|
||||
: winrt::implements<RootObjectChangeHandler, IPerceptionDeviceRootObjectAddedHandler, IPerceptionDeviceRootObjectRemovedHandler>
|
||||
{
|
||||
RootObjectChangeHandler(PerceptionDeviceHandler& owner);
|
||||
|
||||
IFACEMETHOD(Invoke)
|
||||
(_In_ IPerceptionDeviceRootObjectWatcher* sender, _In_ IPerceptionDeviceRootObjectAddedEventArgs* args) override;
|
||||
IFACEMETHOD(Invoke)
|
||||
(_In_ IPerceptionDeviceRootObjectWatcher* sender, _In_ IPerceptionDeviceRootObjectRemovedEventArgs* args) override;
|
||||
|
||||
private:
|
||||
std::weak_ptr<PerceptionDeviceHandler> m_weakOwner;
|
||||
};
|
||||
friend RootObjectChangeHandler;
|
||||
|
||||
struct RootObjectKey
|
||||
{
|
||||
GUID propertyId;
|
||||
GUID objectId;
|
||||
|
||||
bool operator<(const RootObjectKey& other) const;
|
||||
};
|
||||
|
||||
using RootObjectMap = std::map<RootObjectKey, std::shared_ptr<PerceptionRootObject>>;
|
||||
|
||||
|
||||
private:
|
||||
HRESULT HandleRootObjectAdded(IPerceptionDeviceRootObjectAddedEventArgs* args);
|
||||
HRESULT HandleRootObjectRemoved(IPerceptionDeviceRootObjectRemovedEventArgs* args);
|
||||
|
||||
private:
|
||||
std::recursive_mutex m_stateProtect;
|
||||
|
||||
bool m_running{false};
|
||||
|
||||
winrt::com_ptr<IPerceptionDeviceFactory> m_perceptionDeviceFactory;
|
||||
std::vector<winrt::com_ptr<IPerceptionDeviceRootObjectWatcher>> m_rootObjectWatchers;
|
||||
winrt::com_ptr<RootObjectChangeHandler> m_rootObjectChangeHandler;
|
||||
|
||||
RootObjectMap m_rootObjects;
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
#include <PerceptionDevice.h>
|
||||
|
||||
// Base class for perception root objects managed by the PerceptionDeviceHandler
|
||||
class PerceptionRootObject
|
||||
{
|
||||
public:
|
||||
virtual ~PerceptionRootObject();
|
||||
|
||||
const GUID& GetPropertyId() const;
|
||||
const GUID& GetObjectId() const;
|
||||
|
||||
protected:
|
||||
PerceptionRootObject(IPerceptionDevice* device, const GUID& typeId, const GUID& objectId);
|
||||
|
||||
protected:
|
||||
winrt::com_ptr<IPerceptionDevice> m_device;
|
||||
GUID m_typeId;
|
||||
GUID m_objectId;
|
||||
};
|
||||
|
||||
// Sample perception device handler. Listens to the availability of perception devices (more accurately:
|
||||
// perception root objects of known types), and retrieves data from these root objects.
|
||||
class PerceptionDeviceHandler : public std::enable_shared_from_this<PerceptionDeviceHandler>
|
||||
{
|
||||
public:
|
||||
PerceptionDeviceHandler();
|
||||
~PerceptionDeviceHandler();
|
||||
|
||||
// Starts monitoring for perception root object changes
|
||||
void Start();
|
||||
|
||||
// Stops monitoring perception root object changes
|
||||
void Stop();
|
||||
|
||||
// Iterates over all perception root objects currently known
|
||||
template <typename Func>
|
||||
void ForEachRootObject(Func& func)
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
for (auto& rootObjectEntry : m_rootObjects)
|
||||
{
|
||||
func(*rootObjectEntry.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
// Iterates over all root objects of a certain type
|
||||
template <typename RootObjectType, typename Func>
|
||||
void ForEachRootObjectOfType(Func& func)
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
for (auto& rootObjectEntry : m_rootObjects)
|
||||
{
|
||||
PerceptionRootObject& rootObject = *rootObjectEntry.second.get();
|
||||
if (GUIDComparer::equals(rootObject.GetPropertyId(), RootObjectType::GetStaticPropertyId()))
|
||||
{
|
||||
func(static_cast<RootObjectType&>(rootObject));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct RootObjectChangeHandler
|
||||
: winrt::implements<RootObjectChangeHandler, IPerceptionDeviceRootObjectAddedHandler, IPerceptionDeviceRootObjectRemovedHandler>
|
||||
{
|
||||
RootObjectChangeHandler(PerceptionDeviceHandler& owner);
|
||||
|
||||
IFACEMETHOD(Invoke)
|
||||
(_In_ IPerceptionDeviceRootObjectWatcher* sender, _In_ IPerceptionDeviceRootObjectAddedEventArgs* args) override;
|
||||
IFACEMETHOD(Invoke)
|
||||
(_In_ IPerceptionDeviceRootObjectWatcher* sender, _In_ IPerceptionDeviceRootObjectRemovedEventArgs* args) override;
|
||||
|
||||
private:
|
||||
std::weak_ptr<PerceptionDeviceHandler> m_weakOwner;
|
||||
};
|
||||
friend RootObjectChangeHandler;
|
||||
|
||||
struct RootObjectKey
|
||||
{
|
||||
GUID propertyId;
|
||||
GUID objectId;
|
||||
|
||||
bool operator<(const RootObjectKey& other) const;
|
||||
};
|
||||
|
||||
using RootObjectMap = std::map<RootObjectKey, std::shared_ptr<PerceptionRootObject>>;
|
||||
|
||||
private:
|
||||
HRESULT HandleRootObjectAdded(IPerceptionDeviceRootObjectAddedEventArgs* args);
|
||||
HRESULT HandleRootObjectRemoved(IPerceptionDeviceRootObjectRemovedEventArgs* args);
|
||||
|
||||
private:
|
||||
std::recursive_mutex m_stateProtect;
|
||||
|
||||
bool m_running{false};
|
||||
|
||||
winrt::com_ptr<IPerceptionDeviceFactory> m_perceptionDeviceFactory;
|
||||
std::vector<winrt::com_ptr<IPerceptionDeviceRootObjectWatcher>> m_rootObjectWatchers;
|
||||
winrt::com_ptr<RootObjectChangeHandler> m_rootObjectChangeHandler;
|
||||
|
||||
RootObjectMap m_rootObjects;
|
||||
};
|
|
@ -1,107 +1,108 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "../Common/DirectXHelper.h"
|
||||
#include "../Common/PerceptionTypes.h"
|
||||
#include "PerceptionDeviceHandler.h"
|
||||
#include "QRCodeRenderer.h"
|
||||
#include "QRCodeTracker.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace DirectX;
|
||||
|
||||
void AppendColoredTriangle(
|
||||
winrt::Windows::Foundation::Numerics::float3 p0,
|
||||
winrt::Windows::Foundation::Numerics::float3 p1,
|
||||
winrt::Windows::Foundation::Numerics::float3 p2,
|
||||
winrt::Windows::Foundation::Numerics::float3 color,
|
||||
std::vector<VertexPositionNormalColor>& vertices)
|
||||
{
|
||||
VertexPositionNormalColor vertex;
|
||||
vertex.color = XMFLOAT3(&color.x);
|
||||
vertex.normal = XMFLOAT3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
vertex.pos = XMFLOAT3(&p0.x);
|
||||
vertices.push_back(vertex);
|
||||
vertex.pos = XMFLOAT3(&p1.x);
|
||||
vertices.push_back(vertex);
|
||||
vertex.pos = XMFLOAT3(&p2.x);
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
QRCodeRenderer::QRCodeRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources)
|
||||
: RenderableObject(deviceResources)
|
||||
{
|
||||
}
|
||||
|
||||
void QRCodeRenderer::Update(
|
||||
PerceptionDeviceHandler& perceptionDeviceHandler,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem)
|
||||
{
|
||||
auto processQRCode = [this, renderingCoordinateSystem](QRCode& code) {
|
||||
auto codeCS = code.GetCoordinateSystem();
|
||||
float size = code.GetPhysicalSize();
|
||||
auto codeToRendering = codeCS.TryGetTransformTo(renderingCoordinateSystem);
|
||||
if (!codeToRendering)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto codeToRenderingV = codeToRendering.Value();
|
||||
winrt::Windows::Foundation::Numerics::float3 positions[4] = {
|
||||
{0.0f, 0.0f, 0.0f}, {0.0f, size, 0.0f}, {size, size, 0.0f}, {size, 0.0f, 0.0f}};
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
positions[i] = winrt::Windows::Foundation::Numerics::transform(positions[i], codeToRenderingV);
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Numerics::float3 col{1.0f, 1.0f, 0.0f};
|
||||
AppendColoredTriangle(positions[0], positions[2], positions[1], col, m_vertices);
|
||||
AppendColoredTriangle(positions[0], positions[3], positions[2], col, m_vertices);
|
||||
};
|
||||
|
||||
auto processQRCodeTracker = [this, processQRCode](QRCodeTracker& tracker) { tracker.ForEachQRCode(processQRCode); };
|
||||
|
||||
m_vertices.clear();
|
||||
perceptionDeviceHandler.ForEachRootObjectOfType<QRCodeTracker>(processQRCodeTracker);
|
||||
|
||||
auto modelTransform = winrt::Windows::Foundation::Numerics::float4x4::identity();
|
||||
UpdateModelConstantBuffer(modelTransform);
|
||||
}
|
||||
|
||||
void QRCodeRenderer::Draw(unsigned int numInstances)
|
||||
{
|
||||
if (m_vertices.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const UINT stride = sizeof(m_vertices[0]);
|
||||
const UINT offset = 0;
|
||||
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
|
||||
vertexBufferData.pSysMem = m_vertices.data();
|
||||
const CD3D11_BUFFER_DESC vertexBufferDesc(static_cast<UINT>(m_vertices.size() * stride), D3D11_BIND_VERTEX_BUFFER);
|
||||
winrt::com_ptr<ID3D11Buffer> vertexBuffer;
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&vertexBufferDesc, &vertexBufferData, vertexBuffer.put()));
|
||||
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
ID3D11Buffer* pBuffer = vertexBuffer.get();
|
||||
context->IASetVertexBuffers(0, 1, &pBuffer, &stride, &offset);
|
||||
context->DrawInstanced(static_cast<UINT>(m_vertices.size()), numInstances, offset, 0);
|
||||
});
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "../Common/DirectXHelper.h"
|
||||
#include "../Common/PerceptionTypes.h"
|
||||
#include "PerceptionDeviceHandler.h"
|
||||
#include "QRCodeRenderer.h"
|
||||
#include "QRCodeTracker.h"
|
||||
|
||||
#include <winrt/Windows.Perception.Spatial.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace DirectX;
|
||||
|
||||
void AppendColoredTriangle(
|
||||
winrt::Windows::Foundation::Numerics::float3 p0,
|
||||
winrt::Windows::Foundation::Numerics::float3 p1,
|
||||
winrt::Windows::Foundation::Numerics::float3 p2,
|
||||
winrt::Windows::Foundation::Numerics::float3 color,
|
||||
std::vector<VertexPositionNormalColor>& vertices)
|
||||
{
|
||||
VertexPositionNormalColor vertex;
|
||||
vertex.color = XMFLOAT3(&color.x);
|
||||
vertex.normal = XMFLOAT3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
vertex.pos = XMFLOAT3(&p0.x);
|
||||
vertices.push_back(vertex);
|
||||
vertex.pos = XMFLOAT3(&p1.x);
|
||||
vertices.push_back(vertex);
|
||||
vertex.pos = XMFLOAT3(&p2.x);
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
QRCodeRenderer::QRCodeRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources)
|
||||
: RenderableObject(deviceResources)
|
||||
{
|
||||
}
|
||||
|
||||
void QRCodeRenderer::Update(
|
||||
PerceptionDeviceHandler& perceptionDeviceHandler,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem)
|
||||
{
|
||||
auto processQRCode = [this, renderingCoordinateSystem](QRCode& code) {
|
||||
auto codeCS = code.GetCoordinateSystem();
|
||||
float size = code.GetPhysicalSize();
|
||||
auto codeToRendering = codeCS.TryGetTransformTo(renderingCoordinateSystem);
|
||||
if (!codeToRendering)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto codeToRenderingV = codeToRendering.Value();
|
||||
winrt::Windows::Foundation::Numerics::float3 positions[4] = {
|
||||
{0.0f, 0.0f, 0.0f}, {0.0f, size, 0.0f}, {size, size, 0.0f}, {size, 0.0f, 0.0f}};
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
positions[i] = winrt::Windows::Foundation::Numerics::transform(positions[i], codeToRenderingV);
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Numerics::float3 col{1.0f, 1.0f, 0.0f};
|
||||
AppendColoredTriangle(positions[0], positions[2], positions[1], col, m_vertices);
|
||||
AppendColoredTriangle(positions[0], positions[3], positions[2], col, m_vertices);
|
||||
};
|
||||
|
||||
auto processQRCodeTracker = [this, processQRCode](QRCodeTracker& tracker) { tracker.ForEachQRCode(processQRCode); };
|
||||
|
||||
m_vertices.clear();
|
||||
perceptionDeviceHandler.ForEachRootObjectOfType<QRCodeTracker>(processQRCodeTracker);
|
||||
|
||||
auto modelTransform = winrt::Windows::Foundation::Numerics::float4x4::identity();
|
||||
UpdateModelConstantBuffer(modelTransform);
|
||||
}
|
||||
|
||||
void QRCodeRenderer::Draw(unsigned int numInstances)
|
||||
{
|
||||
if (m_vertices.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const UINT stride = sizeof(m_vertices[0]);
|
||||
const UINT offset = 0;
|
||||
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
|
||||
vertexBufferData.pSysMem = m_vertices.data();
|
||||
const CD3D11_BUFFER_DESC vertexBufferDesc(static_cast<UINT>(m_vertices.size() * stride), D3D11_BIND_VERTEX_BUFFER);
|
||||
winrt::com_ptr<ID3D11Buffer> vertexBuffer;
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&vertexBufferDesc, &vertexBufferData, vertexBuffer.put()));
|
||||
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
ID3D11Buffer* pBuffer = vertexBuffer.get();
|
||||
context->IASetVertexBuffers(0, 1, &pBuffer, &stride, &offset);
|
||||
context->DrawInstanced(static_cast<UINT>(m_vertices.size()), numInstances, offset, 0);
|
||||
});
|
||||
}
|
|
@ -1,35 +1,35 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RenderableObject.h"
|
||||
#include <vector>
|
||||
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
class PerceptionDeviceHandler;
|
||||
|
||||
class QRCodeRenderer : public RenderableObject
|
||||
{
|
||||
public:
|
||||
QRCodeRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources);
|
||||
|
||||
void Update(
|
||||
PerceptionDeviceHandler& perceptionDeviceHandler,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem);
|
||||
|
||||
private:
|
||||
void Draw(unsigned int numInstances) override;
|
||||
|
||||
private:
|
||||
std::vector<VertexPositionNormalColor> m_vertices;
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RenderableObject.h"
|
||||
#include <vector>
|
||||
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
class PerceptionDeviceHandler;
|
||||
|
||||
class QRCodeRenderer : public RenderableObject
|
||||
{
|
||||
public:
|
||||
QRCodeRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources);
|
||||
|
||||
void Update(
|
||||
PerceptionDeviceHandler& perceptionDeviceHandler,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem);
|
||||
|
||||
private:
|
||||
void Draw(unsigned int numInstances) override;
|
||||
|
||||
private:
|
||||
std::vector<VertexPositionNormalColor> m_vertices;
|
||||
};
|
|
@ -1,337 +1,332 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "..\pch.h"
|
||||
|
||||
#include <winrt/Windows.Perception.Spatial.Preview.h>
|
||||
|
||||
#include "QRCodeTracker.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
|
||||
QRCode::QRCode(
|
||||
const GUID& id,
|
||||
PSPATIAL_GRAPH_QR_CODE_STREAM_INFO streamInfo,
|
||||
const winrt::Windows::Perception::Spatial::SpatialCoordinateSystem& coordinateSystem)
|
||||
: m_id(id)
|
||||
, m_streamInfo(streamInfo)
|
||||
, m_coordinateSystem(coordinateSystem)
|
||||
{
|
||||
}
|
||||
|
||||
QRCode::~QRCode()
|
||||
{
|
||||
if (m_streamInfo)
|
||||
{
|
||||
CoTaskMemFree(m_streamInfo);
|
||||
}
|
||||
}
|
||||
|
||||
const GUID& QRCode::GetId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
float QRCode::GetPhysicalSize() const
|
||||
{
|
||||
return m_physicalSizeInMeters;
|
||||
}
|
||||
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem QRCode::GetCoordinateSystem() const
|
||||
{
|
||||
return m_coordinateSystem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QRCodeTracker::QRCodeTracker(IPerceptionDevice* device, const GUID& typeId, const GUID& objectId)
|
||||
: PerceptionRootObject(device, typeId, objectId)
|
||||
{
|
||||
Start();
|
||||
}
|
||||
|
||||
QRCodeTracker::~QRCodeTracker()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
const GUID& QRCodeTracker::GetStaticPropertyId()
|
||||
{
|
||||
return SPATIALPROP_QRTrackerObjectId;
|
||||
}
|
||||
|
||||
void QRCodeTracker::Start()
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
|
||||
if (m_running)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT hr = m_device->CreateObjectSubscription(m_objectId, UINT(1), m_qrTrackerSubscription.put());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
hr = m_device->CreatePropertyListener(GetObjectId(), SPATIALPROP_QRTracker_QRCodesList, m_qrListChangeListener.put());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_propertyChangeHandler = winrt::make_self<PropertyChangeHandler>(*this);
|
||||
hr = m_qrListChangeListener->SetPropertyChangedHandler(m_propertyChangeHandler.get());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
hr = m_qrListChangeListener->Start();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_running = true;
|
||||
}
|
||||
|
||||
void QRCodeTracker::Stop()
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
|
||||
m_running = false;
|
||||
|
||||
if (m_qrListChangeListener)
|
||||
{
|
||||
m_qrListChangeListener->Stop();
|
||||
}
|
||||
|
||||
for (auto& qrByPointer : m_qrCodesByPointer)
|
||||
{
|
||||
QRCode* qrCode = qrByPointer.second.get();
|
||||
if (qrCode->m_propertyChangedListener)
|
||||
{
|
||||
qrCode->m_propertyChangedListener->Stop();
|
||||
qrCode->m_propertyChangedListener = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_propertyChangeHandler)
|
||||
{
|
||||
m_propertyChangeHandler->Dispose();
|
||||
m_propertyChangeHandler = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT QRCodeTracker::HandlePropertyChange(IPerceptionDevicePropertyListener* sender, IPerceptionDevicePropertyChangedEventArgs* args)
|
||||
{
|
||||
// Change event for QR code list?
|
||||
if (sender == m_qrListChangeListener.get())
|
||||
{
|
||||
const GUID* guids = static_cast<const GUID*>(args->GetValue());
|
||||
UINT numGuids = args->GetValueSize() / sizeof(GUID);
|
||||
return HandleQRCodeListChange(guids, numGuids);
|
||||
}
|
||||
|
||||
// Change event for single QR code?
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> stateLock(m_stateProtect);
|
||||
auto byListenerPos = m_qrCodesByListener.find(sender);
|
||||
if (byListenerPos != m_qrCodesByListener.end())
|
||||
{
|
||||
QRCode* qrCode = byListenerPos->second;
|
||||
return UpdateQRCode(*qrCode);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QRCodeTracker::HandleQRCodeListChange(const GUID* guids, UINT numGuids)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> stateLock(m_stateProtect);
|
||||
|
||||
if (!m_running)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
// Duplicate the list of known QR code IDs. We'll remove all entries from it that we see in
|
||||
// the incoming list, and thus will end up with a list of the IDs of all removed QR codes.
|
||||
std::set<GUID, GUIDComparer> codesNotInList;
|
||||
for (auto& kv : m_qrCodesByGUID)
|
||||
{
|
||||
codesNotInList.insert(kv.first);
|
||||
}
|
||||
|
||||
// Check each QR code on the incoming list, and update the local cache
|
||||
// with new codes.
|
||||
for (size_t qrIndex = 0; qrIndex < numGuids; ++qrIndex)
|
||||
{
|
||||
const GUID& qrCodeId = guids[qrIndex];
|
||||
auto it = m_qrCodesByGUID.find(qrCodeId);
|
||||
if (it != m_qrCodesByGUID.end())
|
||||
{
|
||||
// Code is already known.
|
||||
codesNotInList.erase(qrCodeId);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Code is new. Read initial state, and add to collections.
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem coordinateSystem{nullptr};
|
||||
try
|
||||
{
|
||||
coordinateSystem =
|
||||
winrt::Windows::Perception::Spatial::Preview::SpatialGraphInteropPreview::CreateCoordinateSystemForNode(qrCodeId);
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
return ex.to_abi();
|
||||
}
|
||||
|
||||
if (coordinateSystem == nullptr)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
void* streamData{nullptr};
|
||||
UINT streamDataSize{0};
|
||||
HRESULT hr = m_device->ReadVariableSizeProperty(qrCodeId, SPATIALPROP_QRCode_StreamInfo, &streamDataSize, &streamData, nullptr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (streamDataSize == 0)
|
||||
{
|
||||
CoTaskMemFree(streamData);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
auto newCode =
|
||||
std::make_unique<QRCode>(qrCodeId, reinterpret_cast<PSPATIAL_GRAPH_QR_CODE_STREAM_INFO>(streamData), coordinateSystem);
|
||||
QRCode* qrCode = newCode.get();
|
||||
|
||||
m_qrCodesByPointer.emplace(qrCode, std::move(newCode));
|
||||
m_qrCodesByGUID.emplace(qrCodeId, qrCode);
|
||||
|
||||
hr = UpdateQRCode(*qrCode);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = m_device->CreatePropertyListener(qrCodeId, SPATIALPROP_QRCode_LastSeenTime, qrCode->m_propertyChangedListener.put());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (!m_propertyChangeHandler)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
hr = qrCode->m_propertyChangedListener->SetPropertyChangedHandler(
|
||||
m_propertyChangeHandler.as<IPerceptionDevicePropertyChangedHandler>().get());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = qrCode->m_propertyChangedListener->Start();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
m_qrCodesByListener.emplace(qrCode->m_propertyChangedListener.get(), qrCode);
|
||||
}
|
||||
|
||||
// Remove all QR codes that have not been seen in this update
|
||||
for (auto& qrCodeId : codesNotInList)
|
||||
{
|
||||
auto byCodeIdPos = m_qrCodesByGUID.find(qrCodeId);
|
||||
if (byCodeIdPos == m_qrCodesByGUID.end())
|
||||
{
|
||||
// Not found (this should not ever happen)
|
||||
continue;
|
||||
}
|
||||
|
||||
QRCode* qrCode = byCodeIdPos->second;
|
||||
m_qrCodesByGUID.erase(byCodeIdPos);
|
||||
|
||||
if (qrCode->m_propertyChangedListener)
|
||||
{
|
||||
qrCode->m_propertyChangedListener->Stop();
|
||||
qrCode->m_propertyChangedListener = nullptr;
|
||||
|
||||
m_qrCodesByListener.erase(qrCode->m_propertyChangedListener.get());
|
||||
}
|
||||
|
||||
m_qrCodesByPointer.erase(qrCode);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QRCodeTracker::UpdateQRCode(QRCode& qrCode)
|
||||
{
|
||||
float physicalSizeInMeters{0};
|
||||
HRESULT hr =
|
||||
m_device->ReadProperty(qrCode.m_id, SPATIALPROP_QRCode_PhysicalSize, sizeof(physicalSizeInMeters), &physicalSizeInMeters, nullptr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
qrCode.m_physicalSizeInMeters = physicalSizeInMeters;
|
||||
|
||||
LONGLONG lastSeenTime{0};
|
||||
hr = m_device->ReadProperty(qrCode.m_id, SPATIALPROP_QRCode_LastSeenTime, sizeof(lastSeenTime), &lastSeenTime, nullptr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
qrCode.m_lastSeenTime = lastSeenTime;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QRCodeTracker::PropertyChangeHandler::PropertyChangeHandler(QRCodeTracker& owner)
|
||||
: m_owner(&owner)
|
||||
{
|
||||
}
|
||||
|
||||
void QRCodeTracker::PropertyChangeHandler::Dispose()
|
||||
{
|
||||
m_owner = nullptr;
|
||||
}
|
||||
|
||||
STDMETHODIMP QRCodeTracker::PropertyChangeHandler::Invoke(
|
||||
_In_ IPerceptionDevicePropertyListener* sender, _In_ IPerceptionDevicePropertyChangedEventArgs* eventArgs)
|
||||
{
|
||||
auto owner = m_owner;
|
||||
if (owner)
|
||||
{
|
||||
return owner->HandlePropertyChange(sender, eventArgs);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "..\pch.h"
|
||||
|
||||
#include <winrt/Windows.Perception.Spatial.Preview.h>
|
||||
|
||||
#include "QRCodeTracker.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
QRCode::QRCode(
|
||||
const GUID& id,
|
||||
PSPATIAL_GRAPH_QR_CODE_STREAM_INFO streamInfo,
|
||||
const winrt::Windows::Perception::Spatial::SpatialCoordinateSystem& coordinateSystem)
|
||||
: m_id(id)
|
||||
, m_streamInfo(streamInfo)
|
||||
, m_coordinateSystem(coordinateSystem)
|
||||
{
|
||||
}
|
||||
|
||||
QRCode::~QRCode()
|
||||
{
|
||||
if (m_streamInfo)
|
||||
{
|
||||
CoTaskMemFree(m_streamInfo);
|
||||
}
|
||||
}
|
||||
|
||||
const GUID& QRCode::GetId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
float QRCode::GetPhysicalSize() const
|
||||
{
|
||||
return m_physicalSizeInMeters;
|
||||
}
|
||||
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem QRCode::GetCoordinateSystem() const
|
||||
{
|
||||
return m_coordinateSystem;
|
||||
}
|
||||
|
||||
QRCodeTracker::QRCodeTracker(IPerceptionDevice* device, const GUID& typeId, const GUID& objectId)
|
||||
: PerceptionRootObject(device, typeId, objectId)
|
||||
{
|
||||
Start();
|
||||
}
|
||||
|
||||
QRCodeTracker::~QRCodeTracker()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
const GUID& QRCodeTracker::GetStaticPropertyId()
|
||||
{
|
||||
return SPATIALPROP_QRTrackerObjectId;
|
||||
}
|
||||
|
||||
void QRCodeTracker::Start()
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
|
||||
if (m_running)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HRESULT hr = m_device->CreateObjectSubscription(m_objectId, UINT(1), m_qrTrackerSubscription.put());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
hr = m_device->CreatePropertyListener(GetObjectId(), SPATIALPROP_QRTracker_QRCodesList, m_qrListChangeListener.put());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_propertyChangeHandler = winrt::make_self<PropertyChangeHandler>(*this);
|
||||
hr = m_qrListChangeListener->SetPropertyChangedHandler(m_propertyChangeHandler.get());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
hr = m_qrListChangeListener->Start();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_running = true;
|
||||
}
|
||||
|
||||
void QRCodeTracker::Stop()
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
|
||||
m_running = false;
|
||||
|
||||
if (m_qrListChangeListener)
|
||||
{
|
||||
m_qrListChangeListener->Stop();
|
||||
}
|
||||
|
||||
for (auto& qrByPointer : m_qrCodesByPointer)
|
||||
{
|
||||
QRCode* qrCode = qrByPointer.second.get();
|
||||
if (qrCode->m_propertyChangedListener)
|
||||
{
|
||||
qrCode->m_propertyChangedListener->Stop();
|
||||
qrCode->m_propertyChangedListener = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_propertyChangeHandler)
|
||||
{
|
||||
m_propertyChangeHandler->Dispose();
|
||||
m_propertyChangeHandler = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT QRCodeTracker::HandlePropertyChange(IPerceptionDevicePropertyListener* sender, IPerceptionDevicePropertyChangedEventArgs* args)
|
||||
{
|
||||
// Change event for QR code list?
|
||||
if (sender == m_qrListChangeListener.get())
|
||||
{
|
||||
const GUID* guids = static_cast<const GUID*>(args->GetValue());
|
||||
UINT numGuids = args->GetValueSize() / sizeof(GUID);
|
||||
return HandleQRCodeListChange(guids, numGuids);
|
||||
}
|
||||
|
||||
// Change event for single QR code?
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> stateLock(m_stateProtect);
|
||||
auto byListenerPos = m_qrCodesByListener.find(sender);
|
||||
if (byListenerPos != m_qrCodesByListener.end())
|
||||
{
|
||||
QRCode* qrCode = byListenerPos->second;
|
||||
return UpdateQRCode(*qrCode);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QRCodeTracker::HandleQRCodeListChange(const GUID* guids, UINT numGuids)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> stateLock(m_stateProtect);
|
||||
|
||||
if (!m_running)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
// Duplicate the list of known QR code IDs. We'll remove all entries from it that we see in
|
||||
// the incoming list, and thus will end up with a list of the IDs of all removed QR codes.
|
||||
std::set<GUID, GUIDComparer> codesNotInList;
|
||||
for (auto& kv : m_qrCodesByGUID)
|
||||
{
|
||||
codesNotInList.insert(kv.first);
|
||||
}
|
||||
|
||||
// Check each QR code on the incoming list, and update the local cache
|
||||
// with new codes.
|
||||
for (size_t qrIndex = 0; qrIndex < numGuids; ++qrIndex)
|
||||
{
|
||||
const GUID& qrCodeId = guids[qrIndex];
|
||||
auto it = m_qrCodesByGUID.find(qrCodeId);
|
||||
if (it != m_qrCodesByGUID.end())
|
||||
{
|
||||
// Code is already known.
|
||||
codesNotInList.erase(qrCodeId);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Code is new. Read initial state, and add to collections.
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem coordinateSystem{nullptr};
|
||||
try
|
||||
{
|
||||
coordinateSystem =
|
||||
winrt::Windows::Perception::Spatial::Preview::SpatialGraphInteropPreview::CreateCoordinateSystemForNode(qrCodeId);
|
||||
}
|
||||
catch (winrt::hresult_error const& ex)
|
||||
{
|
||||
return ex.to_abi();
|
||||
}
|
||||
|
||||
if (coordinateSystem == nullptr)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
void* streamData{nullptr};
|
||||
UINT streamDataSize{0};
|
||||
HRESULT hr = m_device->ReadVariableSizeProperty(qrCodeId, SPATIALPROP_QRCode_StreamInfo, &streamDataSize, &streamData, nullptr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (streamDataSize == 0)
|
||||
{
|
||||
CoTaskMemFree(streamData);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
auto newCode =
|
||||
std::make_unique<QRCode>(qrCodeId, reinterpret_cast<PSPATIAL_GRAPH_QR_CODE_STREAM_INFO>(streamData), coordinateSystem);
|
||||
QRCode* qrCode = newCode.get();
|
||||
|
||||
m_qrCodesByPointer.emplace(qrCode, std::move(newCode));
|
||||
m_qrCodesByGUID.emplace(qrCodeId, qrCode);
|
||||
|
||||
hr = UpdateQRCode(*qrCode);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = m_device->CreatePropertyListener(qrCodeId, SPATIALPROP_QRCode_LastSeenTime, qrCode->m_propertyChangedListener.put());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (!m_propertyChangeHandler)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
hr = qrCode->m_propertyChangedListener->SetPropertyChangedHandler(
|
||||
m_propertyChangeHandler.as<IPerceptionDevicePropertyChangedHandler>().get());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = qrCode->m_propertyChangedListener->Start();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
m_qrCodesByListener.emplace(qrCode->m_propertyChangedListener.get(), qrCode);
|
||||
}
|
||||
|
||||
// Remove all QR codes that have not been seen in this update
|
||||
for (auto& qrCodeId : codesNotInList)
|
||||
{
|
||||
auto byCodeIdPos = m_qrCodesByGUID.find(qrCodeId);
|
||||
if (byCodeIdPos == m_qrCodesByGUID.end())
|
||||
{
|
||||
// Not found (this should not ever happen)
|
||||
continue;
|
||||
}
|
||||
|
||||
QRCode* qrCode = byCodeIdPos->second;
|
||||
m_qrCodesByGUID.erase(byCodeIdPos);
|
||||
|
||||
if (qrCode->m_propertyChangedListener)
|
||||
{
|
||||
qrCode->m_propertyChangedListener->Stop();
|
||||
qrCode->m_propertyChangedListener = nullptr;
|
||||
|
||||
m_qrCodesByListener.erase(qrCode->m_propertyChangedListener.get());
|
||||
}
|
||||
|
||||
m_qrCodesByPointer.erase(qrCode);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QRCodeTracker::UpdateQRCode(QRCode& qrCode)
|
||||
{
|
||||
float physicalSizeInMeters{0};
|
||||
HRESULT hr =
|
||||
m_device->ReadProperty(qrCode.m_id, SPATIALPROP_QRCode_PhysicalSize, sizeof(physicalSizeInMeters), &physicalSizeInMeters, nullptr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
qrCode.m_physicalSizeInMeters = physicalSizeInMeters;
|
||||
|
||||
LONGLONG lastSeenTime{0};
|
||||
hr = m_device->ReadProperty(qrCode.m_id, SPATIALPROP_QRCode_LastSeenTime, sizeof(lastSeenTime), &lastSeenTime, nullptr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
qrCode.m_lastSeenTime = lastSeenTime;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
QRCodeTracker::PropertyChangeHandler::PropertyChangeHandler(QRCodeTracker& owner)
|
||||
: m_owner(&owner)
|
||||
{
|
||||
}
|
||||
|
||||
void QRCodeTracker::PropertyChangeHandler::Dispose()
|
||||
{
|
||||
m_owner = nullptr;
|
||||
}
|
||||
|
||||
STDMETHODIMP QRCodeTracker::PropertyChangeHandler::Invoke(
|
||||
_In_ IPerceptionDevicePropertyListener* sender, _In_ IPerceptionDevicePropertyChangedEventArgs* eventArgs)
|
||||
{
|
||||
auto owner = m_owner;
|
||||
if (owner)
|
||||
{
|
||||
return owner->HandlePropertyChange(sender, eventArgs);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
|
@ -1,108 +1,108 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Common/PerceptionTypes.h"
|
||||
#include "../Common/Utils.h"
|
||||
#include "PerceptionDeviceHandler.h"
|
||||
|
||||
// Represents a single tracked QR code with position, size and last seen time.
|
||||
class QRCode
|
||||
{
|
||||
public:
|
||||
QRCode(
|
||||
const GUID& id,
|
||||
PSPATIAL_GRAPH_QR_CODE_STREAM_INFO streamInfo,
|
||||
const winrt::Windows::Perception::Spatial::SpatialCoordinateSystem& coordinateSystem);
|
||||
~QRCode();
|
||||
|
||||
const GUID& GetId() const;
|
||||
float GetPhysicalSize() const;
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem GetCoordinateSystem() const;
|
||||
|
||||
private:
|
||||
friend class QRCodeTracker;
|
||||
|
||||
private:
|
||||
GUID m_id;
|
||||
PSPATIAL_GRAPH_QR_CODE_STREAM_INFO m_streamInfo;
|
||||
|
||||
__int64 m_lastSeenTime{0};
|
||||
float m_physicalSizeInMeters{0};
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem m_coordinateSystem{nullptr};
|
||||
winrt::com_ptr<IPerceptionDevicePropertyListener> m_propertyChangedListener;
|
||||
};
|
||||
|
||||
// Manages all active QR codes.
|
||||
// Listens for events from the perception device to add, remove or update QR codes.
|
||||
class QRCodeTracker : public PerceptionRootObject
|
||||
{
|
||||
public:
|
||||
QRCodeTracker(IPerceptionDevice* device, const GUID& typeId, const GUID& objectId);
|
||||
~QRCodeTracker();
|
||||
|
||||
// Helper function to iterate all QR codes in a thread safe manner.
|
||||
template <typename Func>
|
||||
void ForEachQRCode(Func& func)
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
for (auto& qrCodeEntry : m_qrCodesByPointer)
|
||||
{
|
||||
func(*qrCodeEntry.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static const GUID& GetStaticPropertyId();
|
||||
|
||||
private:
|
||||
// Implementation of the IPerceptionDevicePropertyChangedHandler interface.
|
||||
// Events from the perception device are propagated through an instance of this class.
|
||||
struct PropertyChangeHandler : winrt::implements<PropertyChangeHandler, IPerceptionDevicePropertyChangedHandler>
|
||||
{
|
||||
PropertyChangeHandler(QRCodeTracker& owner);
|
||||
|
||||
void Dispose();
|
||||
|
||||
STDMETHOD(Invoke)
|
||||
(_In_ IPerceptionDevicePropertyListener* sender, _In_ IPerceptionDevicePropertyChangedEventArgs* eventArgs) override;
|
||||
|
||||
private:
|
||||
QRCodeTracker* m_owner;
|
||||
};
|
||||
friend PropertyChangeHandler;
|
||||
|
||||
using QRCodesByPointerMap = std::map<const QRCode*, std::unique_ptr<QRCode>>;
|
||||
using QRCodesByGUIDMap = std::map<GUID, QRCode*, GUIDComparer>;
|
||||
using QRCodesByListenerMap = std::map<IPerceptionDevicePropertyListener*, QRCode*>;
|
||||
|
||||
private:
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
HRESULT HandlePropertyChange(IPerceptionDevicePropertyListener* sender, IPerceptionDevicePropertyChangedEventArgs* args);
|
||||
HRESULT HandleQRCodeListChange(const GUID* guids, UINT numGuids);
|
||||
HRESULT UpdateQRCode(QRCode& qrCode);
|
||||
|
||||
private:
|
||||
std::recursive_mutex m_stateProtect;
|
||||
|
||||
bool m_running{false};
|
||||
|
||||
winrt::com_ptr<IPerceptionDeviceObjectSubscription> m_qrTrackerSubscription;
|
||||
winrt::com_ptr<IPerceptionDevicePropertyListener> m_qrListChangeListener;
|
||||
winrt::com_ptr<PropertyChangeHandler> m_propertyChangeHandler;
|
||||
|
||||
QRCodesByPointerMap m_qrCodesByPointer;
|
||||
QRCodesByGUIDMap m_qrCodesByGUID;
|
||||
QRCodesByListenerMap m_qrCodesByListener;
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Common/PerceptionTypes.h"
|
||||
#include "../Common/Utils.h"
|
||||
#include "PerceptionDeviceHandler.h"
|
||||
|
||||
// Represents a single tracked QR code with position, size and last seen time.
|
||||
class QRCode
|
||||
{
|
||||
public:
|
||||
QRCode(
|
||||
const GUID& id,
|
||||
PSPATIAL_GRAPH_QR_CODE_STREAM_INFO streamInfo,
|
||||
const winrt::Windows::Perception::Spatial::SpatialCoordinateSystem& coordinateSystem);
|
||||
~QRCode();
|
||||
|
||||
const GUID& GetId() const;
|
||||
float GetPhysicalSize() const;
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem GetCoordinateSystem() const;
|
||||
|
||||
private:
|
||||
friend class QRCodeTracker;
|
||||
|
||||
private:
|
||||
GUID m_id;
|
||||
PSPATIAL_GRAPH_QR_CODE_STREAM_INFO m_streamInfo;
|
||||
|
||||
__int64 m_lastSeenTime{0};
|
||||
float m_physicalSizeInMeters{0};
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem m_coordinateSystem{nullptr};
|
||||
winrt::com_ptr<IPerceptionDevicePropertyListener> m_propertyChangedListener;
|
||||
};
|
||||
|
||||
// Manages all active QR codes.
|
||||
// Listens for events from the perception device to add, remove or update QR codes.
|
||||
class QRCodeTracker : public PerceptionRootObject
|
||||
{
|
||||
public:
|
||||
QRCodeTracker(IPerceptionDevice* device, const GUID& typeId, const GUID& objectId);
|
||||
~QRCodeTracker();
|
||||
|
||||
// Helper function to iterate all QR codes in a thread safe manner.
|
||||
template <typename Func>
|
||||
void ForEachQRCode(Func& func)
|
||||
{
|
||||
std::lock_guard stateLock(m_stateProtect);
|
||||
for (auto& qrCodeEntry : m_qrCodesByPointer)
|
||||
{
|
||||
func(*qrCodeEntry.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static const GUID& GetStaticPropertyId();
|
||||
|
||||
private:
|
||||
// Implementation of the IPerceptionDevicePropertyChangedHandler interface.
|
||||
// Events from the perception device are propagated through an instance of this class.
|
||||
struct PropertyChangeHandler : winrt::implements<PropertyChangeHandler, IPerceptionDevicePropertyChangedHandler>
|
||||
{
|
||||
PropertyChangeHandler(QRCodeTracker& owner);
|
||||
|
||||
void Dispose();
|
||||
|
||||
STDMETHOD(Invoke)
|
||||
(_In_ IPerceptionDevicePropertyListener* sender, _In_ IPerceptionDevicePropertyChangedEventArgs* eventArgs) override;
|
||||
|
||||
private:
|
||||
QRCodeTracker* m_owner;
|
||||
};
|
||||
friend PropertyChangeHandler;
|
||||
|
||||
using QRCodesByPointerMap = std::map<const QRCode*, std::unique_ptr<QRCode>>;
|
||||
using QRCodesByGUIDMap = std::map<GUID, QRCode*, GUIDComparer>;
|
||||
using QRCodesByListenerMap = std::map<IPerceptionDevicePropertyListener*, QRCode*>;
|
||||
|
||||
private:
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
HRESULT HandlePropertyChange(IPerceptionDevicePropertyListener* sender, IPerceptionDevicePropertyChangedEventArgs* args);
|
||||
HRESULT HandleQRCodeListChange(const GUID* guids, UINT numGuids);
|
||||
HRESULT UpdateQRCode(QRCode& qrCode);
|
||||
|
||||
private:
|
||||
std::recursive_mutex m_stateProtect;
|
||||
|
||||
bool m_running{false};
|
||||
|
||||
winrt::com_ptr<IPerceptionDeviceObjectSubscription> m_qrTrackerSubscription;
|
||||
winrt::com_ptr<IPerceptionDevicePropertyListener> m_qrListChangeListener;
|
||||
winrt::com_ptr<PropertyChangeHandler> m_propertyChangeHandler;
|
||||
|
||||
QRCodesByPointerMap m_qrCodesByPointer;
|
||||
QRCodesByGUIDMap m_qrCodesByGUID;
|
||||
QRCodesByListenerMap m_qrCodesByListener;
|
||||
};
|
|
@ -1,148 +1,147 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "RenderableObject.h"
|
||||
|
||||
#include "../Common/DirectXHelper.h"
|
||||
|
||||
|
||||
RenderableObject::RenderableObject(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources)
|
||||
: m_deviceResources(deviceResources)
|
||||
{
|
||||
CreateDeviceDependentResources();
|
||||
}
|
||||
|
||||
void RenderableObject::UpdateModelConstantBuffer(const winrt::Windows::Foundation::Numerics::float4x4& modelTransform)
|
||||
{
|
||||
winrt::Windows::Foundation::Numerics::float4x4 normalTransform = modelTransform;
|
||||
normalTransform.m41 = normalTransform.m42 = normalTransform.m43 = 0;
|
||||
UpdateModelConstantBuffer(modelTransform, normalTransform);
|
||||
}
|
||||
|
||||
void RenderableObject::UpdateModelConstantBuffer(
|
||||
const winrt::Windows::Foundation::Numerics::float4x4& modelTransform,
|
||||
const winrt::Windows::Foundation::Numerics::float4x4& normalTransform)
|
||||
{
|
||||
if (m_loadingComplete)
|
||||
{
|
||||
m_modelConstantBufferData.model = reinterpret_cast<DirectX::XMFLOAT4X4&>(transpose(modelTransform));
|
||||
m_modelConstantBufferData.normal = reinterpret_cast<DirectX::XMFLOAT4X4&>(transpose(normalTransform));
|
||||
|
||||
// Update the model transform buffer for the hologram.
|
||||
m_deviceResources->UseD3DDeviceContext(
|
||||
[&](auto context) { context->UpdateSubresource(m_modelConstantBuffer.get(), 0, nullptr, &m_modelConstantBufferData, 0, 0); });
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableObject::Render(bool isStereo)
|
||||
{
|
||||
if (!m_loadingComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the D3D device context to update Direct3D device-based resources.
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
context->IASetInputLayout(m_inputLayout.get());
|
||||
context->PSSetShader(m_pixelShader.get(), nullptr, 0);
|
||||
|
||||
// Attach the vertex shader.
|
||||
context->VSSetShader(m_vertexShader.get(), nullptr, 0);
|
||||
|
||||
// Apply the model constant buffer to the vertex shader.
|
||||
ID3D11Buffer* pBuffer = m_modelConstantBuffer.get();
|
||||
context->VSSetConstantBuffers(0, 1, &pBuffer);
|
||||
|
||||
if (!m_usingVprtShaders)
|
||||
{
|
||||
// On devices that do not support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature,
|
||||
// a pass-through geometry shader is used to set the render target
|
||||
// array index.
|
||||
context->GSSetShader(m_geometryShader.get(), nullptr, 0);
|
||||
}
|
||||
|
||||
Draw(isStereo ? 2 : 1);
|
||||
});
|
||||
}
|
||||
|
||||
std::future<void> RenderableObject::CreateDeviceDependentResources()
|
||||
{
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
std::wstring fileNamePrefix = L"";
|
||||
#else
|
||||
std::wstring fileNamePrefix = L"ms-appx:///";
|
||||
#endif
|
||||
|
||||
m_usingVprtShaders = m_deviceResources->GetDeviceSupportsVprt();
|
||||
|
||||
// On devices that do support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature
|
||||
// we can avoid using a pass-through geometry shader to set the render
|
||||
// target array index, thus avoiding any overhead that would be
|
||||
// incurred by setting the geometry shader stage.
|
||||
std::wstring vertexShaderFileName = m_usingVprtShaders ? L"hsa_VprtVertexShader.cso" : L"hsa_VertexShader.cso";
|
||||
|
||||
// Load shaders asynchronously.
|
||||
std::vector<byte> vertexShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + vertexShaderFileName);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateVertexShader(
|
||||
vertexShaderFileData.data(), vertexShaderFileData.size(), nullptr, m_vertexShader.put()));
|
||||
|
||||
constexpr std::array<D3D11_INPUT_ELEMENT_DESC, 3> vertexDesc = {{
|
||||
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
}};
|
||||
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateInputLayout(
|
||||
vertexDesc.data(),
|
||||
static_cast<UINT>(vertexDesc.size()),
|
||||
vertexShaderFileData.data(),
|
||||
static_cast<UINT>(vertexShaderFileData.size()),
|
||||
m_inputLayout.put()));
|
||||
|
||||
std::vector<byte> pixelShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + L"hsa_PixelShader.cso");
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreatePixelShader(
|
||||
pixelShaderFileData.data(), pixelShaderFileData.size(), nullptr, m_pixelShader.put()));
|
||||
|
||||
const ModelConstantBuffer constantBuffer{
|
||||
reinterpret_cast<DirectX::XMFLOAT4X4&>(winrt::Windows::Foundation::Numerics::float4x4::identity()),
|
||||
reinterpret_cast<DirectX::XMFLOAT4X4&>(winrt::Windows::Foundation::Numerics::float4x4::identity()),
|
||||
};
|
||||
|
||||
const CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&constantBufferDesc, nullptr, m_modelConstantBuffer.put()));
|
||||
|
||||
if (!m_usingVprtShaders)
|
||||
{
|
||||
// Load the pass-through geometry shader.
|
||||
std::vector<byte> geometryShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + L"hsa_GeometryShader.cso");
|
||||
|
||||
// After the pass-through geometry shader file is loaded, create the shader.
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateGeometryShader(
|
||||
geometryShaderFileData.data(), geometryShaderFileData.size(), nullptr, m_geometryShader.put()));
|
||||
}
|
||||
|
||||
m_loadingComplete = true;
|
||||
}
|
||||
|
||||
void RenderableObject::ReleaseDeviceDependentResources()
|
||||
{
|
||||
m_loadingComplete = false;
|
||||
m_usingVprtShaders = false;
|
||||
m_vertexShader = nullptr;
|
||||
m_inputLayout = nullptr;
|
||||
m_pixelShader = nullptr;
|
||||
m_geometryShader = nullptr;
|
||||
m_modelConstantBuffer = nullptr;
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "RenderableObject.h"
|
||||
|
||||
#include "../Common/DirectXHelper.h"
|
||||
|
||||
RenderableObject::RenderableObject(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources)
|
||||
: m_deviceResources(deviceResources)
|
||||
{
|
||||
CreateDeviceDependentResources();
|
||||
}
|
||||
|
||||
void RenderableObject::UpdateModelConstantBuffer(const winrt::Windows::Foundation::Numerics::float4x4& modelTransform)
|
||||
{
|
||||
winrt::Windows::Foundation::Numerics::float4x4 normalTransform = modelTransform;
|
||||
normalTransform.m41 = normalTransform.m42 = normalTransform.m43 = 0;
|
||||
UpdateModelConstantBuffer(modelTransform, normalTransform);
|
||||
}
|
||||
|
||||
void RenderableObject::UpdateModelConstantBuffer(
|
||||
const winrt::Windows::Foundation::Numerics::float4x4& modelTransform,
|
||||
const winrt::Windows::Foundation::Numerics::float4x4& normalTransform)
|
||||
{
|
||||
if (m_loadingComplete)
|
||||
{
|
||||
m_modelConstantBufferData.model = reinterpret_cast<DirectX::XMFLOAT4X4&>(transpose(modelTransform));
|
||||
m_modelConstantBufferData.normal = reinterpret_cast<DirectX::XMFLOAT4X4&>(transpose(normalTransform));
|
||||
|
||||
// Update the model transform buffer for the hologram.
|
||||
m_deviceResources->UseD3DDeviceContext(
|
||||
[&](auto context) { context->UpdateSubresource(m_modelConstantBuffer.get(), 0, nullptr, &m_modelConstantBufferData, 0, 0); });
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableObject::Render(bool isStereo)
|
||||
{
|
||||
if (!m_loadingComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the D3D device context to update Direct3D device-based resources.
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
context->IASetInputLayout(m_inputLayout.get());
|
||||
context->PSSetShader(m_pixelShader.get(), nullptr, 0);
|
||||
|
||||
// Attach the vertex shader.
|
||||
context->VSSetShader(m_vertexShader.get(), nullptr, 0);
|
||||
|
||||
// Apply the model constant buffer to the vertex shader.
|
||||
ID3D11Buffer* pBuffer = m_modelConstantBuffer.get();
|
||||
context->VSSetConstantBuffers(0, 1, &pBuffer);
|
||||
|
||||
if (!m_usingVprtShaders)
|
||||
{
|
||||
// On devices that do not support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature,
|
||||
// a pass-through geometry shader is used to set the render target
|
||||
// array index.
|
||||
context->GSSetShader(m_geometryShader.get(), nullptr, 0);
|
||||
}
|
||||
|
||||
Draw(isStereo ? 2 : 1);
|
||||
});
|
||||
}
|
||||
|
||||
std::future<void> RenderableObject::CreateDeviceDependentResources()
|
||||
{
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
std::wstring fileNamePrefix = L"";
|
||||
#else
|
||||
std::wstring fileNamePrefix = L"ms-appx:///";
|
||||
#endif
|
||||
|
||||
m_usingVprtShaders = m_deviceResources->GetDeviceSupportsVprt();
|
||||
|
||||
// On devices that do support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature
|
||||
// we can avoid using a pass-through geometry shader to set the render
|
||||
// target array index, thus avoiding any overhead that would be
|
||||
// incurred by setting the geometry shader stage.
|
||||
std::wstring vertexShaderFileName = m_usingVprtShaders ? L"hsa_VprtVertexShader.cso" : L"hsa_VertexShader.cso";
|
||||
|
||||
// Load shaders asynchronously.
|
||||
std::vector<byte> vertexShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + vertexShaderFileName);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateVertexShader(
|
||||
vertexShaderFileData.data(), vertexShaderFileData.size(), nullptr, m_vertexShader.put()));
|
||||
|
||||
constexpr std::array<D3D11_INPUT_ELEMENT_DESC, 3> vertexDesc = {{
|
||||
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
}};
|
||||
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateInputLayout(
|
||||
vertexDesc.data(),
|
||||
static_cast<UINT>(vertexDesc.size()),
|
||||
vertexShaderFileData.data(),
|
||||
static_cast<UINT>(vertexShaderFileData.size()),
|
||||
m_inputLayout.put()));
|
||||
|
||||
std::vector<byte> pixelShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + L"hsa_PixelShader.cso");
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreatePixelShader(
|
||||
pixelShaderFileData.data(), pixelShaderFileData.size(), nullptr, m_pixelShader.put()));
|
||||
|
||||
const ModelConstantBuffer constantBuffer{
|
||||
reinterpret_cast<DirectX::XMFLOAT4X4&>(winrt::Windows::Foundation::Numerics::float4x4::identity()),
|
||||
reinterpret_cast<DirectX::XMFLOAT4X4&>(winrt::Windows::Foundation::Numerics::float4x4::identity()),
|
||||
};
|
||||
|
||||
const CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&constantBufferDesc, nullptr, m_modelConstantBuffer.put()));
|
||||
|
||||
if (!m_usingVprtShaders)
|
||||
{
|
||||
// Load the pass-through geometry shader.
|
||||
std::vector<byte> geometryShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + L"hsa_GeometryShader.cso");
|
||||
|
||||
// After the pass-through geometry shader file is loaded, create the shader.
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateGeometryShader(
|
||||
geometryShaderFileData.data(), geometryShaderFileData.size(), nullptr, m_geometryShader.put()));
|
||||
}
|
||||
|
||||
m_loadingComplete = true;
|
||||
}
|
||||
|
||||
void RenderableObject::ReleaseDeviceDependentResources()
|
||||
{
|
||||
m_loadingComplete = false;
|
||||
m_usingVprtShaders = false;
|
||||
m_vertexShader = nullptr;
|
||||
m_inputLayout = nullptr;
|
||||
m_pixelShader = nullptr;
|
||||
m_geometryShader = nullptr;
|
||||
m_modelConstantBuffer = nullptr;
|
||||
}
|
|
@ -1,61 +1,61 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "..\Common\DeviceResources.h"
|
||||
#include "ShaderStructures.h"
|
||||
|
||||
#include <future>
|
||||
|
||||
class RenderableObject
|
||||
{
|
||||
public:
|
||||
RenderableObject(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources);
|
||||
virtual ~RenderableObject()
|
||||
{
|
||||
}
|
||||
|
||||
virtual std::future<void> CreateDeviceDependentResources();
|
||||
virtual void ReleaseDeviceDependentResources();
|
||||
|
||||
void Render(bool isStereo);
|
||||
|
||||
protected:
|
||||
void UpdateModelConstantBuffer(const winrt::Windows::Foundation::Numerics::float4x4& modelTransform);
|
||||
void UpdateModelConstantBuffer(
|
||||
const winrt::Windows::Foundation::Numerics::float4x4& modelTransform,
|
||||
const winrt::Windows::Foundation::Numerics::float4x4& normalTransform);
|
||||
|
||||
virtual void Draw(unsigned int numInstances) = 0;
|
||||
|
||||
// Cached pointer to device resources.
|
||||
std::shared_ptr<DXHelper::DeviceResources> m_deviceResources;
|
||||
|
||||
private:
|
||||
// Direct3D resources for geometry.
|
||||
winrt::com_ptr<ID3D11InputLayout> m_inputLayout;
|
||||
winrt::com_ptr<ID3D11VertexShader> m_vertexShader;
|
||||
winrt::com_ptr<ID3D11GeometryShader> m_geometryShader;
|
||||
winrt::com_ptr<ID3D11PixelShader> m_pixelShader;
|
||||
winrt::com_ptr<ID3D11Buffer> m_modelConstantBuffer;
|
||||
|
||||
// System resources for geometry.
|
||||
ModelConstantBuffer m_modelConstantBufferData;
|
||||
uint32_t m_indexCount = 0;
|
||||
|
||||
// Variables used with the rendering loop.
|
||||
bool m_loadingComplete = false;
|
||||
|
||||
// If the current D3D Device supports VPRT, we can avoid using a geometry
|
||||
// shader just to set the render target array index.
|
||||
bool m_usingVprtShaders = false;
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "..\Common\DeviceResources.h"
|
||||
#include "ShaderStructures.h"
|
||||
|
||||
#include <future>
|
||||
|
||||
class RenderableObject
|
||||
{
|
||||
public:
|
||||
RenderableObject(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources);
|
||||
virtual ~RenderableObject()
|
||||
{
|
||||
}
|
||||
|
||||
virtual std::future<void> CreateDeviceDependentResources();
|
||||
virtual void ReleaseDeviceDependentResources();
|
||||
|
||||
void Render(bool isStereo);
|
||||
|
||||
protected:
|
||||
void UpdateModelConstantBuffer(const winrt::Windows::Foundation::Numerics::float4x4& modelTransform);
|
||||
void UpdateModelConstantBuffer(
|
||||
const winrt::Windows::Foundation::Numerics::float4x4& modelTransform,
|
||||
const winrt::Windows::Foundation::Numerics::float4x4& normalTransform);
|
||||
|
||||
virtual void Draw(unsigned int numInstances) = 0;
|
||||
|
||||
// Cached pointer to device resources.
|
||||
std::shared_ptr<DXHelper::DeviceResources> m_deviceResources;
|
||||
|
||||
private:
|
||||
// Direct3D resources for geometry.
|
||||
winrt::com_ptr<ID3D11InputLayout> m_inputLayout;
|
||||
winrt::com_ptr<ID3D11VertexShader> m_vertexShader;
|
||||
winrt::com_ptr<ID3D11GeometryShader> m_geometryShader;
|
||||
winrt::com_ptr<ID3D11PixelShader> m_pixelShader;
|
||||
winrt::com_ptr<ID3D11Buffer> m_modelConstantBuffer;
|
||||
|
||||
// System resources for geometry.
|
||||
ModelConstantBuffer m_modelConstantBufferData;
|
||||
uint32_t m_indexCount = 0;
|
||||
|
||||
// Variables used with the rendering loop.
|
||||
bool m_loadingComplete = false;
|
||||
|
||||
// If the current D3D Device supports VPRT, we can avoid using a geometry
|
||||
// shader just to set the render target array index.
|
||||
bool m_usingVprtShaders = false;
|
||||
};
|
|
@ -1,47 +1,47 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RenderableObject.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <winrt/SceneUnderstanding.h>
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
namespace RemotingHostSample
|
||||
{
|
||||
class SceneUnderstandingRenderer : public RenderableObject
|
||||
{
|
||||
public:
|
||||
SceneUnderstandingRenderer(const std::shared_ptr<DX::DeviceResources>& deviceResources);
|
||||
|
||||
void Update(
|
||||
winrt::SceneUnderstanding::SceneProcessor& sceneProcessor,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem,
|
||||
winrt::Windows::Perception::Spatial::SpatialStationaryFrameOfReference lastUpdateLocation);
|
||||
|
||||
void DebugLogState(
|
||||
winrt::SceneUnderstanding::SceneProcessor& sceneProcessor,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem,
|
||||
winrt::Windows::Perception::Spatial::SpatialStationaryFrameOfReference lastUpdateLocation);
|
||||
|
||||
private:
|
||||
void Draw(unsigned int numInstances) override;
|
||||
|
||||
template <typename Func>
|
||||
void ForEachQuad(winrt::SceneUnderstanding::SceneProcessor& sceneProcessor, Func f);
|
||||
|
||||
private:
|
||||
std::vector<VertexPositionNormalColor> m_vertices;
|
||||
};
|
||||
} // namespace RemotingHostSample
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RenderableObject.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <winrt/SceneUnderstanding.h>
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
namespace RemotingHostSample
|
||||
{
|
||||
class SceneUnderstandingRenderer : public RenderableObject
|
||||
{
|
||||
public:
|
||||
SceneUnderstandingRenderer(const std::shared_ptr<DX::DeviceResources>& deviceResources);
|
||||
|
||||
void Update(
|
||||
winrt::SceneUnderstanding::SceneProcessor& sceneProcessor,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem,
|
||||
winrt::Windows::Perception::Spatial::SpatialStationaryFrameOfReference lastUpdateLocation);
|
||||
|
||||
void DebugLogState(
|
||||
winrt::SceneUnderstanding::SceneProcessor& sceneProcessor,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem,
|
||||
winrt::Windows::Perception::Spatial::SpatialStationaryFrameOfReference lastUpdateLocation);
|
||||
|
||||
private:
|
||||
void Draw(unsigned int numInstances) override;
|
||||
|
||||
template <typename Func>
|
||||
void ForEachQuad(winrt::SceneUnderstanding::SceneProcessor& sceneProcessor, Func f);
|
||||
|
||||
private:
|
||||
std::vector<VertexPositionNormalColor> m_vertices;
|
||||
};
|
||||
} // namespace RemotingHostSample
|
|
@ -1,33 +1,32 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
// Constant buffer used to send hologram position transform to the shader pipeline.
|
||||
struct ModelConstantBuffer
|
||||
{
|
||||
DirectX::XMFLOAT4X4 model;
|
||||
DirectX::XMFLOAT4X4 normal; // Normal transform matrix.
|
||||
};
|
||||
|
||||
// Assert that the constant buffer remains 16-byte aligned (best practice).
|
||||
static_assert(
|
||||
(sizeof(ModelConstantBuffer) % (sizeof(float) * 4)) == 0,
|
||||
"Model constant buffer size must be 16-byte aligned (16 bytes is the length of four floats).");
|
||||
|
||||
|
||||
// Used to send per-vertex data to the vertex shader.
|
||||
struct VertexPositionNormalColor
|
||||
{
|
||||
DirectX::XMFLOAT3 pos;
|
||||
DirectX::XMFLOAT3 normal; // Normal.
|
||||
DirectX::XMFLOAT3 color;
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
// Constant buffer used to send hologram position transform to the shader pipeline.
|
||||
struct ModelConstantBuffer
|
||||
{
|
||||
DirectX::XMFLOAT4X4 model;
|
||||
DirectX::XMFLOAT4X4 normal; // Normal transform matrix.
|
||||
};
|
||||
|
||||
// Assert that the constant buffer remains 16-byte aligned (best practice).
|
||||
static_assert(
|
||||
(sizeof(ModelConstantBuffer) % (sizeof(float) * 4)) == 0,
|
||||
"Model constant buffer size must be 16-byte aligned (16 bytes is the length of four floats).");
|
||||
|
||||
// Used to send per-vertex data to the vertex shader.
|
||||
struct VertexPositionNormalColor
|
||||
{
|
||||
DirectX::XMFLOAT3 pos;
|
||||
DirectX::XMFLOAT3 normal; // Normal.
|
||||
DirectX::XMFLOAT3 color;
|
||||
};
|
|
@ -1,193 +1,190 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "SpatialInputHandler.h"
|
||||
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
|
||||
// Creates and initializes a GestureRecognizer that listens to a Person.
|
||||
SpatialInputHandler::SpatialInputHandler()
|
||||
{
|
||||
// The interaction manager provides an event that informs the app when spatial interactions are detected.
|
||||
m_interactionManager = winrt::Windows::UI::Input::Spatial::SpatialInteractionManager::GetForCurrentView();
|
||||
m_gestureRecognizer = winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer(
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureSettings::Tap |
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureSettings::ManipulationTranslate);
|
||||
|
||||
m_interactionDetectedEventToken =
|
||||
m_interactionManager.InteractionDetected(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionDetectedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionDetectedEventArgs args) {
|
||||
m_gestureRecognizer.CaptureInteraction(args.Interaction());
|
||||
}));
|
||||
|
||||
m_tappedEventToken = m_gestureRecognizer.Tapped(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialTappedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer, winrt::Windows::UI::Input::Spatial::SpatialTappedEventArgs args) {
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
m_tapped = args;
|
||||
}));
|
||||
|
||||
m_manipulationStartedEventToken =
|
||||
m_gestureRecognizer.ManipulationStarted(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationStartedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationStartedEventArgs args) {
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
m_manipulationStarted = args;
|
||||
}));
|
||||
|
||||
m_manipulationUpdatedEventToken =
|
||||
m_gestureRecognizer.ManipulationUpdated(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationUpdatedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationUpdatedEventArgs args) {
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
m_manipulationUpdated = args;
|
||||
}));
|
||||
|
||||
m_manipulationCompletedEventToken =
|
||||
m_gestureRecognizer.ManipulationCompleted(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationCompletedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationCompletedEventArgs) {
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
m_manipulationResult = ManipulationResult::Completed;
|
||||
}));
|
||||
|
||||
m_manipulationCanceledEventToken =
|
||||
m_gestureRecognizer.ManipulationCanceled(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationCanceledEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationCanceledEventArgs) {
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
m_manipulationResult = ManipulationResult::Canceled;
|
||||
}));
|
||||
|
||||
|
||||
|
||||
m_navigationStartedEventToken =
|
||||
m_gestureRecognizer.NavigationStarted(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationStartedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationStartedEventArgs args) {
|
||||
char buf[128];
|
||||
sprintf_s(
|
||||
buf,
|
||||
"NS: %d %d %d\n",
|
||||
static_cast<int>(args.IsNavigatingX()),
|
||||
static_cast<int>(args.IsNavigatingY()),
|
||||
static_cast<int>(args.IsNavigatingZ()));
|
||||
OutputDebugStringA(buf);
|
||||
}));
|
||||
|
||||
m_navigationUpdatedEventToken =
|
||||
m_gestureRecognizer.NavigationUpdated(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationUpdatedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationUpdatedEventArgs args) {
|
||||
winrt::Windows::Foundation::Numerics::float3 offset = args.NormalizedOffset();
|
||||
char buf[128];
|
||||
sprintf_s(buf, "NU: %f %f %f\n", offset.x, offset.y, offset.z);
|
||||
OutputDebugStringA(buf);
|
||||
}));
|
||||
|
||||
m_navigationCompletedEventToken =
|
||||
m_gestureRecognizer.NavigationCompleted(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationCompletedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationCompletedEventArgs args) {
|
||||
winrt::Windows::Foundation::Numerics::float3 offset = args.NormalizedOffset();
|
||||
char buf[128];
|
||||
sprintf_s(buf, "NC: %f %f %f\n", offset.x, offset.y, offset.z);
|
||||
OutputDebugStringA(buf);
|
||||
}));
|
||||
|
||||
m_navigationCanceledEventToken =
|
||||
m_gestureRecognizer.NavigationCanceled(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationCanceledEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationCanceledEventArgs args) {
|
||||
char buf[128];
|
||||
sprintf_s(buf, "N: canceled\n");
|
||||
OutputDebugStringA(buf);
|
||||
}));
|
||||
}
|
||||
|
||||
SpatialInputHandler::~SpatialInputHandler()
|
||||
{
|
||||
// Unregister our handler for the OnSourcePressed event.
|
||||
m_interactionManager.InteractionDetected(m_interactionDetectedEventToken);
|
||||
m_gestureRecognizer.Tapped(m_tappedEventToken);
|
||||
m_gestureRecognizer.ManipulationStarted(m_manipulationStartedEventToken);
|
||||
m_gestureRecognizer.ManipulationUpdated(m_manipulationUpdatedEventToken);
|
||||
m_gestureRecognizer.ManipulationCompleted(m_manipulationCompletedEventToken);
|
||||
m_gestureRecognizer.ManipulationCanceled(m_manipulationCanceledEventToken);
|
||||
}
|
||||
|
||||
// Checks if the user performed an input gesture since the last call to this method.
|
||||
// Allows the main update loop to check for asynchronous changes to the user
|
||||
// input state.
|
||||
winrt::Windows::UI::Input::Spatial::SpatialTappedEventArgs SpatialInputHandler::CheckForTapped()
|
||||
{
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
auto tapped = m_tapped;
|
||||
m_tapped = nullptr;
|
||||
return tapped;
|
||||
}
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationStartedEventArgs SpatialInputHandler::CheckForManipulationStarted()
|
||||
{
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
auto manipulationStarted = m_manipulationStarted;
|
||||
m_manipulationStarted = nullptr;
|
||||
return manipulationStarted;
|
||||
}
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationUpdatedEventArgs SpatialInputHandler::CheckForManipulationUpdated()
|
||||
{
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
auto manipulationUpdated = m_manipulationUpdated;
|
||||
m_manipulationUpdated = nullptr;
|
||||
return manipulationUpdated;
|
||||
}
|
||||
|
||||
SpatialInputHandler::ManipulationResult SpatialInputHandler::CheckForManipulationResult()
|
||||
{
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
auto manipulationResult = m_manipulationResult;
|
||||
m_manipulationResult = ManipulationResult::Unknown;
|
||||
return manipulationResult;
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "SpatialInputHandler.h"
|
||||
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
// Creates and initializes a GestureRecognizer that listens to a Person.
|
||||
SpatialInputHandler::SpatialInputHandler(winrt::Windows::UI::Input::Spatial::SpatialInteractionManager interactionManager)
|
||||
: m_interactionManager(interactionManager)
|
||||
{
|
||||
m_gestureRecognizer = winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer(
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureSettings::Tap |
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureSettings::ManipulationTranslate);
|
||||
|
||||
m_interactionDetectedEventToken =
|
||||
m_interactionManager.InteractionDetected(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionDetectedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionDetectedEventArgs args) {
|
||||
m_gestureRecognizer.CaptureInteraction(args.Interaction());
|
||||
}));
|
||||
|
||||
m_tappedEventToken = m_gestureRecognizer.Tapped(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialTappedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer, winrt::Windows::UI::Input::Spatial::SpatialTappedEventArgs args) {
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
m_tapped = args;
|
||||
}));
|
||||
|
||||
m_manipulationStartedEventToken =
|
||||
m_gestureRecognizer.ManipulationStarted(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationStartedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationStartedEventArgs args) {
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
m_manipulationStarted = args;
|
||||
}));
|
||||
|
||||
m_manipulationUpdatedEventToken =
|
||||
m_gestureRecognizer.ManipulationUpdated(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationUpdatedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationUpdatedEventArgs args) {
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
m_manipulationUpdated = args;
|
||||
}));
|
||||
|
||||
m_manipulationCompletedEventToken =
|
||||
m_gestureRecognizer.ManipulationCompleted(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationCompletedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationCompletedEventArgs) {
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
m_manipulationResult = ManipulationResult::Completed;
|
||||
}));
|
||||
|
||||
m_manipulationCanceledEventToken =
|
||||
m_gestureRecognizer.ManipulationCanceled(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationCanceledEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationCanceledEventArgs) {
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
m_manipulationResult = ManipulationResult::Canceled;
|
||||
}));
|
||||
|
||||
m_navigationStartedEventToken =
|
||||
m_gestureRecognizer.NavigationStarted(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationStartedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationStartedEventArgs args) {
|
||||
char buf[128];
|
||||
sprintf_s(
|
||||
buf,
|
||||
"NS: %d %d %d\n",
|
||||
static_cast<int>(args.IsNavigatingX()),
|
||||
static_cast<int>(args.IsNavigatingY()),
|
||||
static_cast<int>(args.IsNavigatingZ()));
|
||||
OutputDebugStringA(buf);
|
||||
}));
|
||||
|
||||
m_navigationUpdatedEventToken =
|
||||
m_gestureRecognizer.NavigationUpdated(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationUpdatedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationUpdatedEventArgs args) {
|
||||
winrt::Windows::Foundation::Numerics::float3 offset = args.NormalizedOffset();
|
||||
char buf[128];
|
||||
sprintf_s(buf, "NU: %f %f %f\n", offset.x, offset.y, offset.z);
|
||||
OutputDebugStringA(buf);
|
||||
}));
|
||||
|
||||
m_navigationCompletedEventToken =
|
||||
m_gestureRecognizer.NavigationCompleted(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationCompletedEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationCompletedEventArgs args) {
|
||||
winrt::Windows::Foundation::Numerics::float3 offset = args.NormalizedOffset();
|
||||
char buf[128];
|
||||
sprintf_s(buf, "NC: %f %f %f\n", offset.x, offset.y, offset.z);
|
||||
OutputDebugStringA(buf);
|
||||
}));
|
||||
|
||||
m_navigationCanceledEventToken =
|
||||
m_gestureRecognizer.NavigationCanceled(winrt::Windows::Foundation::TypedEventHandler<
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationCanceledEventArgs>(
|
||||
[this](
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialNavigationCanceledEventArgs args) {
|
||||
char buf[128];
|
||||
sprintf_s(buf, "N: canceled\n");
|
||||
OutputDebugStringA(buf);
|
||||
}));
|
||||
}
|
||||
|
||||
SpatialInputHandler::~SpatialInputHandler()
|
||||
{
|
||||
// Unregister our handler for the OnSourcePressed event.
|
||||
m_interactionManager.InteractionDetected(m_interactionDetectedEventToken);
|
||||
m_gestureRecognizer.Tapped(m_tappedEventToken);
|
||||
m_gestureRecognizer.ManipulationStarted(m_manipulationStartedEventToken);
|
||||
m_gestureRecognizer.ManipulationUpdated(m_manipulationUpdatedEventToken);
|
||||
m_gestureRecognizer.ManipulationCompleted(m_manipulationCompletedEventToken);
|
||||
m_gestureRecognizer.ManipulationCanceled(m_manipulationCanceledEventToken);
|
||||
}
|
||||
|
||||
// Checks if the user performed an input gesture since the last call to this method.
|
||||
// Allows the main update loop to check for asynchronous changes to the user
|
||||
// input state.
|
||||
winrt::Windows::UI::Input::Spatial::SpatialTappedEventArgs SpatialInputHandler::CheckForTapped()
|
||||
{
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
auto tapped = m_tapped;
|
||||
m_tapped = nullptr;
|
||||
return tapped;
|
||||
}
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationStartedEventArgs SpatialInputHandler::CheckForManipulationStarted()
|
||||
{
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
auto manipulationStarted = m_manipulationStarted;
|
||||
m_manipulationStarted = nullptr;
|
||||
return manipulationStarted;
|
||||
}
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationUpdatedEventArgs SpatialInputHandler::CheckForManipulationUpdated()
|
||||
{
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
auto manipulationUpdated = m_manipulationUpdated;
|
||||
m_manipulationUpdated = nullptr;
|
||||
return manipulationUpdated;
|
||||
}
|
||||
|
||||
SpatialInputHandler::ManipulationResult SpatialInputHandler::CheckForManipulationResult()
|
||||
{
|
||||
std::lock_guard _lg(m_manipulationStateLock);
|
||||
auto manipulationResult = m_manipulationResult;
|
||||
m_manipulationResult = ManipulationResult::Unknown;
|
||||
return manipulationResult;
|
||||
}
|
|
@ -1,62 +1,62 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
|
||||
// Sample gesture handler.
|
||||
// Hooks up events to recognize a tap gesture, and keeps track of input using a boolean value.
|
||||
class SpatialInputHandler
|
||||
{
|
||||
public:
|
||||
SpatialInputHandler();
|
||||
~SpatialInputHandler();
|
||||
|
||||
enum class ManipulationResult
|
||||
{
|
||||
Unknown = 0,
|
||||
Completed,
|
||||
Canceled,
|
||||
};
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialTappedEventArgs CheckForTapped();
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationStartedEventArgs CheckForManipulationStarted();
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationUpdatedEventArgs CheckForManipulationUpdated();
|
||||
ManipulationResult CheckForManipulationResult();
|
||||
|
||||
private:
|
||||
// API objects used to process gesture input, and generate gesture events.
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager m_interactionManager = nullptr;
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer m_gestureRecognizer = nullptr;
|
||||
|
||||
// Event registration token.
|
||||
winrt::event_token m_interactionDetectedEventToken;
|
||||
winrt::event_token m_tappedEventToken;
|
||||
winrt::event_token m_manipulationStartedEventToken;
|
||||
winrt::event_token m_manipulationUpdatedEventToken;
|
||||
winrt::event_token m_manipulationCompletedEventToken;
|
||||
winrt::event_token m_manipulationCanceledEventToken;
|
||||
|
||||
winrt::event_token m_navigationStartedEventToken;
|
||||
winrt::event_token m_navigationUpdatedEventToken;
|
||||
winrt::event_token m_navigationCompletedEventToken;
|
||||
winrt::event_token m_navigationCanceledEventToken;
|
||||
|
||||
// Used to indicate that a Pressed input event was received this frame.
|
||||
std::recursive_mutex m_manipulationStateLock;
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialTappedEventArgs m_tapped = nullptr;
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationStartedEventArgs m_manipulationStarted = nullptr;
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationUpdatedEventArgs m_manipulationUpdated = nullptr;
|
||||
ManipulationResult m_manipulationResult = ManipulationResult::Unknown;
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
// Sample gesture handler.
|
||||
// Hooks up events to recognize a tap gesture, and keeps track of input using a boolean value.
|
||||
class SpatialInputHandler
|
||||
{
|
||||
public:
|
||||
SpatialInputHandler(winrt::Windows::UI::Input::Spatial::SpatialInteractionManager interactionManager);
|
||||
~SpatialInputHandler();
|
||||
|
||||
enum class ManipulationResult
|
||||
{
|
||||
Unknown = 0,
|
||||
Completed,
|
||||
Canceled,
|
||||
};
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialTappedEventArgs CheckForTapped();
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationStartedEventArgs CheckForManipulationStarted();
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationUpdatedEventArgs CheckForManipulationUpdated();
|
||||
ManipulationResult CheckForManipulationResult();
|
||||
|
||||
private:
|
||||
// API objects used to process gesture input, and generate gesture events.
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager m_interactionManager = nullptr;
|
||||
winrt::Windows::UI::Input::Spatial::SpatialGestureRecognizer m_gestureRecognizer = nullptr;
|
||||
|
||||
// Event registration token.
|
||||
winrt::event_token m_interactionDetectedEventToken;
|
||||
winrt::event_token m_tappedEventToken;
|
||||
winrt::event_token m_manipulationStartedEventToken;
|
||||
winrt::event_token m_manipulationUpdatedEventToken;
|
||||
winrt::event_token m_manipulationCompletedEventToken;
|
||||
winrt::event_token m_manipulationCanceledEventToken;
|
||||
|
||||
winrt::event_token m_navigationStartedEventToken;
|
||||
winrt::event_token m_navigationUpdatedEventToken;
|
||||
winrt::event_token m_navigationCompletedEventToken;
|
||||
winrt::event_token m_navigationCanceledEventToken;
|
||||
|
||||
// Used to indicate that a Pressed input event was received this frame.
|
||||
std::recursive_mutex m_manipulationStateLock;
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialTappedEventArgs m_tapped = nullptr;
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationStartedEventArgs m_manipulationStarted = nullptr;
|
||||
winrt::Windows::UI::Input::Spatial::SpatialManipulationUpdatedEventArgs m_manipulationUpdated = nullptr;
|
||||
ManipulationResult m_manipulationResult = ManipulationResult::Unknown;
|
||||
};
|
|
@ -1,238 +1,268 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "SpatialInputRenderer.h"
|
||||
|
||||
#include <winrt/Windows.Foundation.Numerics.h>
|
||||
#include <winrt/Windows.Perception.People.h>
|
||||
#include <winrt/Windows.Perception.Spatial.h>
|
||||
|
||||
#include "../Common/DirectXHelper.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace DirectX;
|
||||
|
||||
void AppendColoredTriangle(XMFLOAT3 p0, XMFLOAT3 p1, XMFLOAT3 p2, XMFLOAT3 color, std::vector<VertexPositionNormalColor>& vertices)
|
||||
{
|
||||
VertexPositionNormalColor vertex;
|
||||
vertex.color = color;
|
||||
vertex.normal = XMFLOAT3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
vertex.pos = p0;
|
||||
vertices.push_back(vertex);
|
||||
vertex.pos = p1;
|
||||
vertices.push_back(vertex);
|
||||
vertex.pos = p2;
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
SpatialInputRenderer::SpatialInputRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources)
|
||||
: RenderableObject(deviceResources)
|
||||
{
|
||||
m_manager = winrt::Windows::UI::Input::Spatial::SpatialInteractionManager::GetForCurrentView();
|
||||
m_referenceFrame = winrt::Windows::Perception::Spatial::SpatialLocator::GetDefault().CreateAttachedFrameOfReferenceAtCurrentHeading();
|
||||
}
|
||||
|
||||
void SpatialInputRenderer::Update(
|
||||
winrt::Windows::Perception::PerceptionTimestamp timestamp,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem)
|
||||
{
|
||||
m_transforms.clear();
|
||||
m_joints.clear();
|
||||
|
||||
auto headingAdjustment = m_referenceFrame.TryGetRelativeHeadingAtTimestamp(timestamp);
|
||||
if (headingAdjustment)
|
||||
{
|
||||
// keep coordinate systems facing user
|
||||
m_referenceFrame.AdjustHeading(-headingAdjustment.Value());
|
||||
auto coordinateSystem = m_referenceFrame.GetStationaryCoordinateSystemAtTimestamp(timestamp);
|
||||
|
||||
auto spatialPointerPose = winrt::Windows::UI::Input::Spatial::SpatialPointerPose::TryGetAtTimestamp(coordinateSystem, timestamp);
|
||||
if (spatialPointerPose)
|
||||
{
|
||||
if (auto eyesPose = spatialPointerPose.Eyes())
|
||||
{
|
||||
if (auto gaze = eyesPose.Gaze())
|
||||
{
|
||||
auto position = gaze.Value().Origin + gaze.Value().Direction;
|
||||
quaternion orientation = quaternion::identity();
|
||||
m_transforms.emplace_back(QTransform(position, orientation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto states = m_manager.GetDetectedSourcesAtTimestamp(timestamp);
|
||||
|
||||
m_transforms.reserve(states.Size());
|
||||
for (const auto& state : states)
|
||||
{
|
||||
auto location = state.Properties().TryGetLocation(coordinateSystem);
|
||||
if (location)
|
||||
{
|
||||
if (location.Position())
|
||||
{
|
||||
using namespace winrt::Windows::Foundation::Numerics;
|
||||
|
||||
auto position = location.Position().Value();
|
||||
quaternion orientation = quaternion::identity();
|
||||
|
||||
if (location.Orientation())
|
||||
{
|
||||
orientation = location.Orientation().Value();
|
||||
}
|
||||
|
||||
DirectX::XMVECTOR xmPosition = DirectX::XMLoadFloat3(&position);
|
||||
DirectX::XMVECTOR xmOrientation = DirectX::XMLoadQuaternion(&orientation);
|
||||
m_transforms.emplace_back(QTransform(xmPosition, xmOrientation));
|
||||
}
|
||||
|
||||
if (auto sourcePose = location.SourcePointerPose())
|
||||
{
|
||||
m_joints.push_back({sourcePose.Position(), sourcePose.Orientation(), 1.0f, 0.01f});
|
||||
}
|
||||
}
|
||||
|
||||
auto handPose = state.TryGetHandPose();
|
||||
if (handPose)
|
||||
{
|
||||
constexpr const winrt::Windows::Perception::People::HandJointKind jointKinds[] = {
|
||||
winrt::Windows::Perception::People::HandJointKind::Palm,
|
||||
winrt::Windows::Perception::People::HandJointKind::Wrist,
|
||||
winrt::Windows::Perception::People::HandJointKind::ThumbMetacarpal,
|
||||
winrt::Windows::Perception::People::HandJointKind::ThumbProximal,
|
||||
winrt::Windows::Perception::People::HandJointKind::ThumbDistal,
|
||||
winrt::Windows::Perception::People::HandJointKind::ThumbTip,
|
||||
winrt::Windows::Perception::People::HandJointKind::IndexMetacarpal,
|
||||
winrt::Windows::Perception::People::HandJointKind::IndexProximal,
|
||||
winrt::Windows::Perception::People::HandJointKind::IndexIntermediate,
|
||||
winrt::Windows::Perception::People::HandJointKind::IndexDistal,
|
||||
winrt::Windows::Perception::People::HandJointKind::IndexTip,
|
||||
winrt::Windows::Perception::People::HandJointKind::MiddleMetacarpal,
|
||||
winrt::Windows::Perception::People::HandJointKind::MiddleProximal,
|
||||
winrt::Windows::Perception::People::HandJointKind::MiddleIntermediate,
|
||||
winrt::Windows::Perception::People::HandJointKind::MiddleDistal,
|
||||
winrt::Windows::Perception::People::HandJointKind::MiddleTip,
|
||||
winrt::Windows::Perception::People::HandJointKind::RingMetacarpal,
|
||||
winrt::Windows::Perception::People::HandJointKind::RingProximal,
|
||||
winrt::Windows::Perception::People::HandJointKind::RingIntermediate,
|
||||
winrt::Windows::Perception::People::HandJointKind::RingDistal,
|
||||
winrt::Windows::Perception::People::HandJointKind::RingTip,
|
||||
winrt::Windows::Perception::People::HandJointKind::LittleMetacarpal,
|
||||
winrt::Windows::Perception::People::HandJointKind::LittleProximal,
|
||||
winrt::Windows::Perception::People::HandJointKind::LittleIntermediate,
|
||||
winrt::Windows::Perception::People::HandJointKind::LittleDistal,
|
||||
winrt::Windows::Perception::People::HandJointKind::LittleTip};
|
||||
constexpr const size_t jointCount = _countof(jointKinds);
|
||||
winrt::Windows::Perception::People::JointPose jointPoses[jointCount] = {};
|
||||
|
||||
if (handPose.TryGetJoints(coordinateSystem, jointKinds, jointPoses))
|
||||
{
|
||||
for (size_t jointIndex = 0; jointIndex < jointCount; ++jointIndex)
|
||||
{
|
||||
m_joints.push_back({jointPoses[jointIndex].Position,
|
||||
jointPoses[jointIndex].Orientation,
|
||||
jointPoses[jointIndex].Radius * 3,
|
||||
jointPoses[jointIndex].Radius});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto modelTransform = coordinateSystem.TryGetTransformTo(renderingCoordinateSystem);
|
||||
if (modelTransform)
|
||||
{
|
||||
UpdateModelConstantBuffer(modelTransform.Value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpatialInputRenderer::Draw(unsigned int numInstances)
|
||||
{
|
||||
if (!m_transforms.empty())
|
||||
{
|
||||
std::vector<VertexPositionNormalColor> vertices;
|
||||
for (const auto& transform : m_transforms)
|
||||
{
|
||||
DirectX::XMFLOAT3 trianglePositions[3] = {
|
||||
DirectX::XMFLOAT3(0.0f, 0.03f, 0.0f), DirectX::XMFLOAT3(0.01f, 0.0f, 0.0f), DirectX::XMFLOAT3(-0.01f, 0.0f, 0.0f)};
|
||||
|
||||
AppendColoredTriangle(
|
||||
transform.TransformPosition(trianglePositions[0]),
|
||||
transform.TransformPosition(trianglePositions[1]),
|
||||
transform.TransformPosition(trianglePositions[2]),
|
||||
DirectX::XMFLOAT3{0, 0, 1},
|
||||
vertices);
|
||||
}
|
||||
|
||||
for (const auto& joint : m_joints)
|
||||
{
|
||||
auto jointVertices = CalculateJointVisualizationVertices(joint.position, joint.orientation, joint.length, joint.radius);
|
||||
vertices.insert(vertices.end(), jointVertices.begin(), jointVertices.end());
|
||||
}
|
||||
|
||||
const UINT stride = sizeof(vertices[0]);
|
||||
const UINT offset = 0;
|
||||
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
|
||||
vertexBufferData.pSysMem = vertices.data();
|
||||
const CD3D11_BUFFER_DESC vertexBufferDesc(static_cast<UINT>(vertices.size() * stride), D3D11_BIND_VERTEX_BUFFER);
|
||||
winrt::com_ptr<ID3D11Buffer> vertexBuffer;
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&vertexBufferDesc, &vertexBufferData, vertexBuffer.put()));
|
||||
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
ID3D11Buffer* pBuffer = vertexBuffer.get();
|
||||
context->IASetVertexBuffers(0, 1, &pBuffer, &stride, &offset);
|
||||
context->DrawInstanced(static_cast<UINT>(vertices.size()), numInstances, offset, 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<VertexPositionNormalColor> SpatialInputRenderer::CalculateJointVisualizationVertices(
|
||||
float3 jointPosition, quaternion jointOrientation, float jointLength, float jointRadius)
|
||||
{
|
||||
using namespace DirectX;
|
||||
|
||||
constexpr const size_t verticesCount = 2 * 4 * 3;
|
||||
std::vector<VertexPositionNormalColor> vertices;
|
||||
vertices.reserve(verticesCount);
|
||||
|
||||
float centerHeight = std::min<float>(jointRadius, 0.5f * jointLength);
|
||||
float centerXandY = jointRadius / sqrtf(2.0f);
|
||||
|
||||
QTransform jointTransform = QTransform(jointPosition, jointOrientation);
|
||||
|
||||
XMFLOAT3 baseVertexPosition = jointTransform.TransformPosition(XMFLOAT3(0.0f, 0.0f, 0.0f));
|
||||
XMFLOAT3 centerVertexPositions[4] = {
|
||||
jointTransform.TransformPosition(XMFLOAT3(-centerXandY, -centerXandY, -centerHeight)),
|
||||
jointTransform.TransformPosition(XMFLOAT3(-centerXandY, +centerXandY, -centerHeight)),
|
||||
jointTransform.TransformPosition(XMFLOAT3(+centerXandY, +centerXandY, -centerHeight)),
|
||||
jointTransform.TransformPosition(XMFLOAT3(+centerXandY, -centerXandY, -centerHeight)),
|
||||
};
|
||||
XMFLOAT3 topVertexPosition = jointTransform.TransformPosition(XMFLOAT3(0.0f, 0.0f, -jointLength));
|
||||
|
||||
AppendColoredTriangle(baseVertexPosition, centerVertexPositions[0], centerVertexPositions[1], XMFLOAT3(0.0f, 0.0f, 0.4f), vertices);
|
||||
AppendColoredTriangle(baseVertexPosition, centerVertexPositions[1], centerVertexPositions[2], XMFLOAT3(0.0f, 0.4f, 0.0f), vertices);
|
||||
AppendColoredTriangle(baseVertexPosition, centerVertexPositions[2], centerVertexPositions[3], XMFLOAT3(0.4f, 0.0f, 0.0f), vertices);
|
||||
AppendColoredTriangle(baseVertexPosition, centerVertexPositions[3], centerVertexPositions[0], XMFLOAT3(0.4f, 0.4f, 0.0f), vertices);
|
||||
AppendColoredTriangle(topVertexPosition, centerVertexPositions[1], centerVertexPositions[0], XMFLOAT3(0.0f, 0.0f, 0.6f), vertices);
|
||||
AppendColoredTriangle(topVertexPosition, centerVertexPositions[2], centerVertexPositions[1], XMFLOAT3(0.0f, 0.6f, 0.0f), vertices);
|
||||
AppendColoredTriangle(topVertexPosition, centerVertexPositions[3], centerVertexPositions[2], XMFLOAT3(0.6f, 0.0f, 0.0f), vertices);
|
||||
AppendColoredTriangle(topVertexPosition, centerVertexPositions[0], centerVertexPositions[3], XMFLOAT3(0.6f, 0.6f, 0.0f), vertices);
|
||||
|
||||
return vertices;
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "SpatialInputRenderer.h"
|
||||
|
||||
#include <winrt/Windows.Devices.Haptics.h>
|
||||
#include <winrt/Windows.Foundation.Numerics.h>
|
||||
#include <winrt/Windows.Perception.People.h>
|
||||
#include <winrt/Windows.Perception.Spatial.h>
|
||||
|
||||
#include "../Common/DirectXHelper.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include <sstream>
|
||||
#include <winrt/Windows.Devices.Power.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace DirectX;
|
||||
|
||||
void AppendColoredTriangle(XMFLOAT3 p0, XMFLOAT3 p1, XMFLOAT3 p2, XMFLOAT3 color, std::vector<VertexPositionNormalColor>& vertices)
|
||||
{
|
||||
VertexPositionNormalColor vertex;
|
||||
vertex.color = color;
|
||||
vertex.normal = XMFLOAT3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
vertex.pos = p0;
|
||||
vertices.push_back(vertex);
|
||||
vertex.pos = p1;
|
||||
vertices.push_back(vertex);
|
||||
vertex.pos = p2;
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
SpatialInputRenderer::SpatialInputRenderer(
|
||||
const std::shared_ptr<DXHelper::DeviceResources>& deviceResources,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager interactionManager)
|
||||
: RenderableObject(deviceResources)
|
||||
, m_interactionManager(interactionManager)
|
||||
{
|
||||
m_referenceFrame = winrt::Windows::Perception::Spatial::SpatialLocator::GetDefault().CreateAttachedFrameOfReferenceAtCurrentHeading();
|
||||
}
|
||||
|
||||
void SpatialInputRenderer::Update(
|
||||
winrt::Windows::Perception::PerceptionTimestamp timestamp,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem)
|
||||
{
|
||||
m_transforms.clear();
|
||||
m_joints.clear();
|
||||
|
||||
auto headingAdjustment = m_referenceFrame.TryGetRelativeHeadingAtTimestamp(timestamp);
|
||||
if (headingAdjustment)
|
||||
{
|
||||
|
||||
// keep coordinate systems facing user
|
||||
m_referenceFrame.AdjustHeading(-headingAdjustment.Value());
|
||||
auto coordinateSystem = m_referenceFrame.GetStationaryCoordinateSystemAtTimestamp(timestamp);
|
||||
|
||||
auto spatialPointerPose = winrt::Windows::UI::Input::Spatial::SpatialPointerPose::TryGetAtTimestamp(coordinateSystem, timestamp);
|
||||
if (spatialPointerPose)
|
||||
{
|
||||
if (auto eyesPose = spatialPointerPose.Eyes())
|
||||
{
|
||||
if (auto gaze = eyesPose.Gaze())
|
||||
{
|
||||
auto position = gaze.Value().Origin + gaze.Value().Direction;
|
||||
quaternion orientation = quaternion::identity();
|
||||
m_transforms.emplace_back(QTransform(position, orientation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto states = m_interactionManager.GetDetectedSourcesAtTimestamp(timestamp);
|
||||
|
||||
m_transforms.reserve(states.Size());
|
||||
|
||||
for (const auto& state : states)
|
||||
{
|
||||
auto location = state.Properties().TryGetLocation(coordinateSystem);
|
||||
QTransform currentTransform(float3::zero(), quaternion::identity());
|
||||
if (location)
|
||||
{
|
||||
if (location.Position())
|
||||
{
|
||||
using namespace winrt::Windows::Foundation::Numerics;
|
||||
|
||||
auto position = location.Position().Value();
|
||||
quaternion orientation = quaternion::identity();
|
||||
|
||||
if (location.Orientation())
|
||||
{
|
||||
orientation = location.Orientation().Value();
|
||||
}
|
||||
|
||||
DirectX::XMVECTOR xmPosition = DirectX::XMLoadFloat3(&position);
|
||||
DirectX::XMVECTOR xmOrientation = DirectX::XMLoadQuaternion(&orientation);
|
||||
currentTransform = QTransform(xmPosition, xmOrientation);
|
||||
m_transforms.push_back(currentTransform);
|
||||
}
|
||||
|
||||
if (auto sourcePose = location.SourcePointerPose())
|
||||
{
|
||||
m_joints.push_back({sourcePose.Position(), sourcePose.Orientation(), 1.0f, 0.01f});
|
||||
}
|
||||
}
|
||||
|
||||
auto handPose = state.TryGetHandPose();
|
||||
if (handPose)
|
||||
{
|
||||
constexpr const winrt::Windows::Perception::People::HandJointKind jointKinds[] = {
|
||||
winrt::Windows::Perception::People::HandJointKind::Palm,
|
||||
winrt::Windows::Perception::People::HandJointKind::Wrist,
|
||||
winrt::Windows::Perception::People::HandJointKind::ThumbMetacarpal,
|
||||
winrt::Windows::Perception::People::HandJointKind::ThumbProximal,
|
||||
winrt::Windows::Perception::People::HandJointKind::ThumbDistal,
|
||||
winrt::Windows::Perception::People::HandJointKind::ThumbTip,
|
||||
winrt::Windows::Perception::People::HandJointKind::IndexMetacarpal,
|
||||
winrt::Windows::Perception::People::HandJointKind::IndexProximal,
|
||||
winrt::Windows::Perception::People::HandJointKind::IndexIntermediate,
|
||||
winrt::Windows::Perception::People::HandJointKind::IndexDistal,
|
||||
winrt::Windows::Perception::People::HandJointKind::IndexTip,
|
||||
winrt::Windows::Perception::People::HandJointKind::MiddleMetacarpal,
|
||||
winrt::Windows::Perception::People::HandJointKind::MiddleProximal,
|
||||
winrt::Windows::Perception::People::HandJointKind::MiddleIntermediate,
|
||||
winrt::Windows::Perception::People::HandJointKind::MiddleDistal,
|
||||
winrt::Windows::Perception::People::HandJointKind::MiddleTip,
|
||||
winrt::Windows::Perception::People::HandJointKind::RingMetacarpal,
|
||||
winrt::Windows::Perception::People::HandJointKind::RingProximal,
|
||||
winrt::Windows::Perception::People::HandJointKind::RingIntermediate,
|
||||
winrt::Windows::Perception::People::HandJointKind::RingDistal,
|
||||
winrt::Windows::Perception::People::HandJointKind::RingTip,
|
||||
winrt::Windows::Perception::People::HandJointKind::LittleMetacarpal,
|
||||
winrt::Windows::Perception::People::HandJointKind::LittleProximal,
|
||||
winrt::Windows::Perception::People::HandJointKind::LittleIntermediate,
|
||||
winrt::Windows::Perception::People::HandJointKind::LittleDistal,
|
||||
winrt::Windows::Perception::People::HandJointKind::LittleTip};
|
||||
constexpr const size_t jointCount = _countof(jointKinds);
|
||||
winrt::Windows::Perception::People::JointPose jointPoses[jointCount] = {};
|
||||
|
||||
if (handPose.TryGetJoints(coordinateSystem, jointKinds, jointPoses))
|
||||
{
|
||||
for (size_t jointIndex = 0; jointIndex < jointCount; ++jointIndex)
|
||||
{
|
||||
m_joints.push_back(
|
||||
{jointPoses[jointIndex].Position,
|
||||
jointPoses[jointIndex].Orientation,
|
||||
jointPoses[jointIndex].Radius * 3,
|
||||
jointPoses[jointIndex].Radius});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto modelTransform = coordinateSystem.TryGetTransformTo(renderingCoordinateSystem);
|
||||
if (modelTransform)
|
||||
{
|
||||
UpdateModelConstantBuffer(modelTransform.Value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpatialInputRenderer::Draw(unsigned int numInstances)
|
||||
{
|
||||
if (!m_transforms.empty())
|
||||
{
|
||||
std::vector<VertexPositionNormalColor> vertices;
|
||||
for (const auto& transform : m_transforms)
|
||||
{
|
||||
DirectX::XMFLOAT3 trianglePositions[3] = {
|
||||
DirectX::XMFLOAT3(0.0f, 0.03f, 0.0f), DirectX::XMFLOAT3(0.01f, 0.0f, 0.0f), DirectX::XMFLOAT3(-0.01f, 0.0f, 0.0f)};
|
||||
|
||||
AppendColoredTriangle(
|
||||
transform.TransformPosition(trianglePositions[0]),
|
||||
transform.TransformPosition(trianglePositions[1]),
|
||||
transform.TransformPosition(trianglePositions[2]),
|
||||
DirectX::XMFLOAT3{0, 0, 1},
|
||||
vertices);
|
||||
}
|
||||
|
||||
for (const auto& joint : m_joints)
|
||||
{
|
||||
auto jointVertices = CalculateJointVisualizationVertices(joint.position, joint.orientation, joint.length, joint.radius);
|
||||
vertices.insert(vertices.end(), jointVertices.begin(), jointVertices.end());
|
||||
}
|
||||
|
||||
for (const auto& coloredTransform : m_coloredTransforms)
|
||||
{
|
||||
DirectX::XMFLOAT3 quadPositions[4] = {
|
||||
DirectX::XMFLOAT3(-0.01f, 0.0f, -0.01f),
|
||||
DirectX::XMFLOAT3(0.01f, 0.0f, -0.01f),
|
||||
DirectX::XMFLOAT3(0.01f, 0.0f, 0.01f),
|
||||
DirectX::XMFLOAT3(-0.01f, 0.0f, 0.01f)};
|
||||
DirectX::XMFLOAT3 transformedPositions[4];
|
||||
|
||||
for (uint32_t i = 0; i < 4; ++i)
|
||||
{
|
||||
transformedPositions[i] = coloredTransform.m_transform.TransformPosition(quadPositions[i]);
|
||||
}
|
||||
|
||||
AppendColoredTriangle(
|
||||
transformedPositions[0], transformedPositions[1], transformedPositions[2], coloredTransform.m_color, vertices);
|
||||
AppendColoredTriangle(
|
||||
transformedPositions[2], transformedPositions[3], transformedPositions[0], coloredTransform.m_color, vertices);
|
||||
}
|
||||
|
||||
const UINT stride = sizeof(vertices[0]);
|
||||
const UINT offset = 0;
|
||||
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
|
||||
vertexBufferData.pSysMem = vertices.data();
|
||||
const CD3D11_BUFFER_DESC vertexBufferDesc(static_cast<UINT>(vertices.size() * stride), D3D11_BIND_VERTEX_BUFFER);
|
||||
winrt::com_ptr<ID3D11Buffer> vertexBuffer;
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&vertexBufferDesc, &vertexBufferData, vertexBuffer.put()));
|
||||
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
ID3D11Buffer* pBuffer = vertexBuffer.get();
|
||||
context->IASetVertexBuffers(0, 1, &pBuffer, &stride, &offset);
|
||||
context->DrawInstanced(static_cast<UINT>(vertices.size()), numInstances, offset, 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<VertexPositionNormalColor> SpatialInputRenderer::CalculateJointVisualizationVertices(
|
||||
float3 jointPosition, quaternion jointOrientation, float jointLength, float jointRadius)
|
||||
{
|
||||
using namespace DirectX;
|
||||
|
||||
constexpr const size_t verticesCount = 2 * 4 * 3;
|
||||
std::vector<VertexPositionNormalColor> vertices;
|
||||
vertices.reserve(verticesCount);
|
||||
|
||||
float centerHeight = std::min<float>(jointRadius, 0.5f * jointLength);
|
||||
float centerXandY = jointRadius / sqrtf(2.0f);
|
||||
|
||||
QTransform jointTransform = QTransform(jointPosition, jointOrientation);
|
||||
|
||||
XMFLOAT3 baseVertexPosition = jointTransform.TransformPosition(XMFLOAT3(0.0f, 0.0f, 0.0f));
|
||||
XMFLOAT3 centerVertexPositions[4] = {
|
||||
jointTransform.TransformPosition(XMFLOAT3(-centerXandY, -centerXandY, -centerHeight)),
|
||||
jointTransform.TransformPosition(XMFLOAT3(-centerXandY, +centerXandY, -centerHeight)),
|
||||
jointTransform.TransformPosition(XMFLOAT3(+centerXandY, +centerXandY, -centerHeight)),
|
||||
jointTransform.TransformPosition(XMFLOAT3(+centerXandY, -centerXandY, -centerHeight)),
|
||||
};
|
||||
XMFLOAT3 topVertexPosition = jointTransform.TransformPosition(XMFLOAT3(0.0f, 0.0f, -jointLength));
|
||||
|
||||
AppendColoredTriangle(baseVertexPosition, centerVertexPositions[0], centerVertexPositions[1], XMFLOAT3(0.0f, 0.0f, 0.4f), vertices);
|
||||
AppendColoredTriangle(baseVertexPosition, centerVertexPositions[1], centerVertexPositions[2], XMFLOAT3(0.0f, 0.4f, 0.0f), vertices);
|
||||
AppendColoredTriangle(baseVertexPosition, centerVertexPositions[2], centerVertexPositions[3], XMFLOAT3(0.4f, 0.0f, 0.0f), vertices);
|
||||
AppendColoredTriangle(baseVertexPosition, centerVertexPositions[3], centerVertexPositions[0], XMFLOAT3(0.4f, 0.4f, 0.0f), vertices);
|
||||
AppendColoredTriangle(topVertexPosition, centerVertexPositions[1], centerVertexPositions[0], XMFLOAT3(0.0f, 0.0f, 0.6f), vertices);
|
||||
AppendColoredTriangle(topVertexPosition, centerVertexPositions[2], centerVertexPositions[1], XMFLOAT3(0.0f, 0.6f, 0.0f), vertices);
|
||||
AppendColoredTriangle(topVertexPosition, centerVertexPositions[3], centerVertexPositions[2], XMFLOAT3(0.6f, 0.0f, 0.0f), vertices);
|
||||
AppendColoredTriangle(topVertexPosition, centerVertexPositions[0], centerVertexPositions[3], XMFLOAT3(0.6f, 0.6f, 0.0f), vertices);
|
||||
|
||||
return vertices;
|
||||
}
|
|
@ -1,85 +1,110 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
#include "RenderableObject.h"
|
||||
#include <vector>
|
||||
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
using namespace winrt::Windows::Foundation::Numerics;
|
||||
|
||||
struct QTransform
|
||||
{
|
||||
QTransform() = default;
|
||||
QTransform(const DirectX::XMVECTOR& position, const DirectX::XMVECTOR& orientation)
|
||||
: m_position(position)
|
||||
, m_orientation(orientation)
|
||||
{
|
||||
}
|
||||
QTransform(const float3& position, const quaternion& orientation)
|
||||
: m_position(DirectX::XMLoadFloat3(&position))
|
||||
, m_orientation(DirectX::XMLoadQuaternion(&orientation))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DirectX::XMVECTOR TransformNormal(const DirectX::XMVECTOR& normal) const
|
||||
{
|
||||
return DirectX::XMVector3Rotate(normal, m_orientation);
|
||||
}
|
||||
|
||||
DirectX::XMVECTOR TransformPosition(const DirectX::XMVECTOR& position) const
|
||||
{
|
||||
DirectX::XMVECTOR rotated = TransformNormal(position);
|
||||
return DirectX::XMVectorAdd(rotated, m_position);
|
||||
}
|
||||
|
||||
DirectX::XMFLOAT3 TransformPosition(const DirectX::XMFLOAT3& position) const
|
||||
{
|
||||
DirectX::XMFLOAT3 result;
|
||||
XMStoreFloat3(&result, TransformPosition(DirectX::XMLoadFloat3(&position)));
|
||||
return result;
|
||||
}
|
||||
|
||||
DirectX::XMVECTOR m_position;
|
||||
DirectX::XMVECTOR m_orientation;
|
||||
};
|
||||
|
||||
class SpatialInputRenderer : public RenderableObject
|
||||
{
|
||||
public:
|
||||
SpatialInputRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources);
|
||||
|
||||
void Update(
|
||||
winrt::Windows::Perception::PerceptionTimestamp timestamp,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem);
|
||||
|
||||
private:
|
||||
struct Joint
|
||||
{
|
||||
float3 position;
|
||||
quaternion orientation;
|
||||
float length;
|
||||
float radius;
|
||||
};
|
||||
|
||||
private:
|
||||
static std::vector<VertexPositionNormalColor>
|
||||
CalculateJointVisualizationVertices(float3 jointPosition, quaternion jointOrientation, float jointLength, float jointRadius);
|
||||
|
||||
void Draw(unsigned int numInstances) override;
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager m_manager{nullptr};
|
||||
winrt::Windows::Perception::Spatial::SpatialLocatorAttachedFrameOfReference m_referenceFrame{nullptr};
|
||||
std::vector<QTransform> m_transforms;
|
||||
std::vector<Joint> m_joints;
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
#include "RenderableObject.h"
|
||||
#include <vector>
|
||||
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
using namespace winrt::Windows::Foundation::Numerics;
|
||||
|
||||
struct QTransform
|
||||
{
|
||||
QTransform() = default;
|
||||
QTransform(const DirectX::XMVECTOR& position, const DirectX::XMVECTOR& orientation)
|
||||
: m_position(position)
|
||||
, m_orientation(orientation)
|
||||
{
|
||||
}
|
||||
QTransform(const float3& position, const quaternion& orientation)
|
||||
: m_position(DirectX::XMLoadFloat3(&position))
|
||||
, m_orientation(DirectX::XMLoadQuaternion(&orientation))
|
||||
{
|
||||
}
|
||||
|
||||
DirectX::XMVECTOR TransformNormal(const DirectX::XMVECTOR& normal) const
|
||||
{
|
||||
return DirectX::XMVector3Rotate(normal, m_orientation);
|
||||
}
|
||||
|
||||
DirectX::XMVECTOR TransformPosition(const DirectX::XMVECTOR& position) const
|
||||
{
|
||||
DirectX::XMVECTOR rotated = TransformNormal(position);
|
||||
return DirectX::XMVectorAdd(rotated, m_position);
|
||||
}
|
||||
|
||||
DirectX::XMFLOAT3 TransformPosition(const DirectX::XMFLOAT3& position) const
|
||||
{
|
||||
DirectX::XMFLOAT3 result;
|
||||
XMStoreFloat3(&result, TransformPosition(DirectX::XMLoadFloat3(&position)));
|
||||
return result;
|
||||
}
|
||||
|
||||
float3 TransformPosition(const float3& position) const
|
||||
{
|
||||
DirectX::XMFLOAT3 temp;
|
||||
XMStoreFloat3(&temp, TransformPosition(DirectX::XMLoadFloat3(&position)));
|
||||
return float3(temp.x, temp.y, temp.z);
|
||||
}
|
||||
|
||||
DirectX::XMVECTOR m_position;
|
||||
DirectX::XMVECTOR m_orientation;
|
||||
};
|
||||
|
||||
class SpatialInputRenderer : public RenderableObject
|
||||
{
|
||||
public:
|
||||
SpatialInputRenderer(
|
||||
const std::shared_ptr<DXHelper::DeviceResources>& deviceResources,
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager interactionManager);
|
||||
|
||||
void Update(
|
||||
winrt::Windows::Perception::PerceptionTimestamp timestamp,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem);
|
||||
|
||||
private:
|
||||
struct Joint
|
||||
{
|
||||
float3 position;
|
||||
quaternion orientation;
|
||||
float length;
|
||||
float radius;
|
||||
};
|
||||
|
||||
struct ColoredTransform
|
||||
{
|
||||
ColoredTransform(const QTransform& transform, const DirectX::XMFLOAT3& color)
|
||||
: m_transform(transform)
|
||||
, m_color(color)
|
||||
{
|
||||
}
|
||||
ColoredTransform(const float3& position, const quaternion& orientation, const DirectX::XMFLOAT3& colorIn)
|
||||
: m_transform(position, orientation)
|
||||
, m_color(colorIn)
|
||||
{
|
||||
}
|
||||
QTransform m_transform;
|
||||
DirectX::XMFLOAT3 m_color;
|
||||
};
|
||||
|
||||
private:
|
||||
static std::vector<VertexPositionNormalColor>
|
||||
CalculateJointVisualizationVertices(float3 jointPosition, quaternion jointOrientation, float jointLength, float jointRadius);
|
||||
|
||||
void Draw(unsigned int numInstances) override;
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager m_interactionManager{nullptr};
|
||||
winrt::Windows::Perception::Spatial::SpatialLocatorAttachedFrameOfReference m_referenceFrame{nullptr};
|
||||
std::vector<QTransform> m_transforms;
|
||||
std::vector<Joint> m_joints;
|
||||
std::vector<ColoredTransform> m_coloredTransforms;
|
||||
};
|
|
@ -1,395 +1,423 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "SpatialSurfaceMeshRenderer.h"
|
||||
|
||||
#include "Common\DirectXHelper.h"
|
||||
|
||||
using namespace winrt::Windows;
|
||||
using namespace winrt::Windows::Perception::Spatial;
|
||||
using namespace winrt::Windows::Graphics::DirectX;
|
||||
using namespace winrt::Windows::Foundation::Numerics;
|
||||
using namespace Concurrency;
|
||||
|
||||
// for debugging -> remove
|
||||
bool g_freeze = false;
|
||||
bool g_freezeOnFrame = false;
|
||||
|
||||
// Initializes D2D resources used for text rendering.
|
||||
SpatialSurfaceMeshRenderer::SpatialSurfaceMeshRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources)
|
||||
: m_deviceResources(deviceResources)
|
||||
{
|
||||
CreateDeviceDependentResources();
|
||||
}
|
||||
|
||||
SpatialSurfaceMeshRenderer::~SpatialSurfaceMeshRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
std::future<void> SpatialSurfaceMeshRenderer::CreateDeviceDependentResources()
|
||||
{
|
||||
auto asyncAccess = Surfaces::SpatialSurfaceObserver::RequestAccessAsync();
|
||||
asyncAccess.Completed([this](auto handler, auto asyncStatus) {
|
||||
m_surfaceObserver = Surfaces::SpatialSurfaceObserver();
|
||||
|
||||
m_observedSurfaceChangedToken = m_surfaceObserver.ObservedSurfacesChanged(
|
||||
[this](Surfaces::SpatialSurfaceObserver, winrt::Windows::Foundation::IInspectable const& handler) {
|
||||
OnObservedSurfaceChanged();
|
||||
});
|
||||
});
|
||||
|
||||
std::vector<byte> vertexShaderFileData = co_await DXHelper::ReadDataAsync(L"hsa_SRMeshVertexShader.cso");
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateVertexShader(
|
||||
vertexShaderFileData.data(), vertexShaderFileData.size(), nullptr, m_vertexShader.put()));
|
||||
|
||||
constexpr std::array<D3D11_INPUT_ELEMENT_DESC, 1> vertexDesc = {{
|
||||
{"POSITION", 0, DXGI_FORMAT_R16G16B16A16_SNORM, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
}};
|
||||
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateInputLayout(
|
||||
vertexDesc.data(),
|
||||
static_cast<UINT>(vertexDesc.size()),
|
||||
vertexShaderFileData.data(),
|
||||
static_cast<UINT>(vertexShaderFileData.size()),
|
||||
m_inputLayout.put()));
|
||||
|
||||
std::vector<byte> geometryShaderFileData = co_await DXHelper::ReadDataAsync(L"hsa_SRMeshGeometryShader.cso");
|
||||
|
||||
// After the pass-through geometry shader file is loaded, create the shader.
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateGeometryShader(
|
||||
geometryShaderFileData.data(), geometryShaderFileData.size(), nullptr, m_geometryShader.put()));
|
||||
|
||||
std::vector<byte> pixelShaderFileData = co_await DXHelper::ReadDataAsync(L"hsa_SRMeshPixelShader.cso");
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreatePixelShader(
|
||||
pixelShaderFileData.data(), pixelShaderFileData.size(), nullptr, m_pixelShader.put()));
|
||||
|
||||
const CD3D11_BUFFER_DESC constantBufferDesc(sizeof(SRMeshConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&constantBufferDesc, nullptr, m_modelConstantBuffer.put()));
|
||||
|
||||
m_loadingComplete = true;
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshRenderer::ReleaseDeviceDependentResources()
|
||||
{
|
||||
if (m_surfaceObserver)
|
||||
{
|
||||
m_surfaceObserver.ObservedSurfacesChanged(m_observedSurfaceChangedToken);
|
||||
m_surfaceObserver = nullptr;
|
||||
}
|
||||
m_loadingComplete = false;
|
||||
m_inputLayout = nullptr;
|
||||
m_vertexShader = nullptr;
|
||||
m_geometryShader = nullptr;
|
||||
m_pixelShader = nullptr;
|
||||
m_modelConstantBuffer = nullptr;
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshRenderer::OnObservedSurfaceChanged()
|
||||
{
|
||||
if (g_freeze)
|
||||
return;
|
||||
|
||||
m_surfaceChangedCounter++; // just for debugging purposes
|
||||
m_sufaceChanged = true;
|
||||
}
|
||||
|
||||
SpatialSurfaceMeshPart* SpatialSurfaceMeshRenderer::GetOrCreateMeshPart(winrt::guid id)
|
||||
{
|
||||
GUID key = id;
|
||||
auto found = m_meshParts.find(key);
|
||||
if (found == m_meshParts.cend())
|
||||
{
|
||||
m_meshParts[id] = std::make_unique<SpatialSurfaceMeshPart>(this);
|
||||
return m_meshParts[id].get();
|
||||
}
|
||||
|
||||
return found->second.get();
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshRenderer::Update(winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem)
|
||||
{
|
||||
if (m_surfaceObserver == nullptr)
|
||||
return;
|
||||
|
||||
// update bounding volume (every frame)
|
||||
{
|
||||
SpatialBoundingBox axisAlignedBoundingBox = {
|
||||
{-5.0f, -5.0f, -2.5f},
|
||||
{10.0f, 10.0f, 5.f},
|
||||
};
|
||||
|
||||
SpatialBoundingVolume volume = SpatialBoundingVolume::FromBox(renderingCoordinateSystem, axisAlignedBoundingBox);
|
||||
m_surfaceObserver.SetBoundingVolume(volume);
|
||||
}
|
||||
|
||||
|
||||
if (m_sufaceChanged)
|
||||
{
|
||||
// first mark all as not used
|
||||
for (auto& pair : m_meshParts)
|
||||
{
|
||||
pair.second->m_inUse = false;
|
||||
}
|
||||
|
||||
auto mapContainingSurfaceCollection = m_surfaceObserver.GetObservedSurfaces();
|
||||
|
||||
for (auto pair : mapContainingSurfaceCollection)
|
||||
{
|
||||
if (SpatialSurfaceMeshPart* meshPart = GetOrCreateMeshPart(pair.Key()))
|
||||
{
|
||||
meshPart->Update(pair.Value());
|
||||
g_freeze = g_freezeOnFrame;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// purge the ones not used
|
||||
for (MeshPartMap::const_iterator itr = m_meshParts.cbegin(); itr != m_meshParts.cend();)
|
||||
{
|
||||
itr = itr->second->IsInUse() ? std::next(itr) : m_meshParts.erase(itr);
|
||||
}
|
||||
|
||||
m_sufaceChanged = false;
|
||||
}
|
||||
|
||||
// every frame, bring the model matrix to rendering space
|
||||
for (auto& pair : m_meshParts)
|
||||
{
|
||||
pair.second->UpdateModelMatrix(renderingCoordinateSystem);
|
||||
}
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshRenderer::Render(bool isStereo)
|
||||
{
|
||||
if (!m_loadingComplete || m_meshParts.empty())
|
||||
return;
|
||||
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
// Each vertex is one instance of the VertexPositionColorTexture struct.
|
||||
const uint32_t stride = sizeof(SpatialSurfaceMeshPart::Vertex_t);
|
||||
const uint32_t offset = 0;
|
||||
ID3D11Buffer* pBufferToSet;
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
context->IASetInputLayout(m_inputLayout.get());
|
||||
|
||||
// Attach the vertex shader.
|
||||
context->VSSetShader(m_vertexShader.get(), nullptr, 0);
|
||||
// Apply the model constant buffer to the vertex shader.
|
||||
pBufferToSet = m_modelConstantBuffer.get();
|
||||
context->VSSetConstantBuffers(0, 1, &pBufferToSet);
|
||||
|
||||
// geometry shader
|
||||
context->GSSetShader(m_geometryShader.get(), nullptr, 0);
|
||||
|
||||
// pixel shader
|
||||
context->PSSetShader(m_zfillOnly ? nullptr : m_pixelShader.get(), nullptr, 0);
|
||||
|
||||
// Apply the model constant buffer to the pixel shader.
|
||||
pBufferToSet = m_modelConstantBuffer.get();
|
||||
context->PSSetConstantBuffers(0, 1, &pBufferToSet);
|
||||
|
||||
// render each mesh part
|
||||
for (auto& pair : m_meshParts)
|
||||
{
|
||||
SpatialSurfaceMeshPart* part = pair.second.get();
|
||||
if (part->m_indexCount == 0)
|
||||
continue;
|
||||
|
||||
if (part->m_needsUpload)
|
||||
{
|
||||
part->UploadData();
|
||||
}
|
||||
|
||||
// update part specific model matrix
|
||||
context->UpdateSubresource(m_modelConstantBuffer.get(), 0, nullptr, &part->m_constantBufferData, 0, 0);
|
||||
|
||||
ID3D11Buffer* pBufferToSet2 = part->m_vertexBuffer.get();
|
||||
context->IASetVertexBuffers(0, 1, &pBufferToSet2, &stride, &offset);
|
||||
context->IASetIndexBuffer(part->m_indexBuffer.get(), DXGI_FORMAT_R16_UINT, 0);
|
||||
// draw the mesh
|
||||
context->DrawIndexedInstanced(part->m_indexCount, isStereo ? 2 : 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
// set geometry shader back
|
||||
context->GSSetShader(nullptr, nullptr, 0);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SRMeshPart
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SpatialSurfaceMeshPart::SpatialSurfaceMeshPart(SpatialSurfaceMeshRenderer* owner)
|
||||
: m_owner(owner)
|
||||
{
|
||||
auto identity = DirectX::XMMatrixIdentity();
|
||||
m_constantBufferData.modelMatrix = reinterpret_cast<DirectX::XMFLOAT4X4&>(identity);
|
||||
m_vertexScale.x = m_vertexScale.y = m_vertexScale.z = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SpatialSurfaceMeshPart::Update(Surfaces::SpatialSurfaceInfo surfaceInfo)
|
||||
{
|
||||
m_inUse = true;
|
||||
m_updateInProgress = true;
|
||||
double TriangleDensity = 750.0; // from Hydrogen
|
||||
auto asyncOpertation = surfaceInfo.TryComputeLatestMeshAsync(TriangleDensity);
|
||||
asyncOpertation.Completed([this](winrt::Windows::Foundation::IAsyncOperation<Surfaces::SpatialSurfaceMesh> result, auto asyncStatus) {
|
||||
Surfaces::SpatialSurfaceMesh mesh = result.GetResults();
|
||||
UpdateMesh(mesh);
|
||||
m_updateInProgress = false;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SpatialSurfaceMeshPart::UpdateModelMatrix(winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem)
|
||||
{
|
||||
if (m_coordinateSystem == nullptr)
|
||||
return;
|
||||
|
||||
auto modelTransform = m_coordinateSystem.TryGetTransformTo(renderingCoordinateSystem);
|
||||
if (modelTransform)
|
||||
{
|
||||
float4x4 matrixWinRt = transpose(modelTransform.Value());
|
||||
DirectX::XMMATRIX transformMatrix = DirectX::XMLoadFloat4x4(&matrixWinRt);
|
||||
DirectX::XMMATRIX scaleMatrix = DirectX::XMMatrixScaling(m_vertexScale.x, m_vertexScale.y, m_vertexScale.z);
|
||||
DirectX::XMMATRIX result = DirectX::XMMatrixMultiply(transformMatrix, scaleMatrix);
|
||||
DirectX::XMStoreFloat4x4(&m_constantBufferData.modelMatrix, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SpatialSurfaceMeshPart::UpdateMesh(Surfaces::SpatialSurfaceMesh mesh)
|
||||
{
|
||||
m_coordinateSystem = mesh.CoordinateSystem();
|
||||
|
||||
Surfaces::SpatialSurfaceMeshBuffer vertexBuffer = mesh.VertexPositions();
|
||||
Surfaces::SpatialSurfaceMeshBuffer indexBuffer = mesh.TriangleIndices();
|
||||
|
||||
DirectXPixelFormat vertexFormat = vertexBuffer.Format();
|
||||
DirectXPixelFormat indexFormat = indexBuffer.Format();
|
||||
|
||||
assert(vertexFormat == DirectXPixelFormat::R16G16B16A16IntNormalized);
|
||||
assert(indexFormat == DirectXPixelFormat::R16UInt);
|
||||
|
||||
uint32_t vertexCount = vertexBuffer.ElementCount();
|
||||
uint32_t indexCount = indexBuffer.ElementCount();
|
||||
assert((indexCount % 3) == 0);
|
||||
|
||||
if (vertexCount == 0 || indexCount == 0)
|
||||
{
|
||||
m_indexCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// convert vertices:
|
||||
{
|
||||
Vertex_t* dest = MapVertices(vertexCount);
|
||||
winrt::Windows::Storage::Streams::IBuffer vertexData = vertexBuffer.Data();
|
||||
uint8_t* vertexRaw = vertexData.data();
|
||||
int vertexStride = vertexData.Length() / vertexCount;
|
||||
assert(vertexStride == 8); // DirectXPixelFormat::R16G16B16A16IntNormalized
|
||||
winrt::Windows::Foundation::Numerics::float3 positionScale = mesh.VertexPositionScale();
|
||||
m_vertexScale.x = positionScale.x;
|
||||
m_vertexScale.y = positionScale.y;
|
||||
m_vertexScale.z = positionScale.z;
|
||||
memcpy(dest, vertexRaw, vertexCount * sizeof(Vertex_t));
|
||||
UnmapVertices();
|
||||
}
|
||||
|
||||
// convert indices
|
||||
{
|
||||
uint16_t* dest = MapIndices(indexCount);
|
||||
winrt::Windows::Storage::Streams::IBuffer indexData = indexBuffer.Data();
|
||||
uint16_t* source = (uint16_t*)indexData.data();
|
||||
for (uint32_t i = 0; i < indexCount; i++)
|
||||
{
|
||||
assert(source[i] < vertexCount);
|
||||
dest[i] = source[i];
|
||||
}
|
||||
UnmapIndices();
|
||||
}
|
||||
m_needsUpload = true;
|
||||
}
|
||||
|
||||
SpatialSurfaceMeshPart::Vertex_t* SpatialSurfaceMeshPart::MapVertices(uint32_t vertexCount)
|
||||
{
|
||||
m_vertexCount = vertexCount;
|
||||
if (vertexCount > m_vertexData.size())
|
||||
m_vertexData.resize(vertexCount);
|
||||
return &m_vertexData[0];
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshPart::UnmapVertices()
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t* SpatialSurfaceMeshPart::MapIndices(uint32_t indexCount)
|
||||
{
|
||||
m_indexCount = indexCount;
|
||||
if (indexCount > m_indexData.size())
|
||||
m_indexData.resize(indexCount);
|
||||
return &m_indexData[0];
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshPart::UnmapIndices()
|
||||
{
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshPart::UploadData()
|
||||
{
|
||||
if (m_vertexCount > m_allocatedVertexCount)
|
||||
{
|
||||
m_vertexBuffer = nullptr;
|
||||
|
||||
const int alignment = 1024;
|
||||
m_allocatedVertexCount = ((m_vertexCount + alignment - 1) / alignment) * alignment; // align to reasonable size
|
||||
|
||||
const int elementSize = sizeof(Vertex_t);
|
||||
const CD3D11_BUFFER_DESC vertexBufferDesc(
|
||||
m_allocatedVertexCount * elementSize, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||
|
||||
winrt::check_hresult(m_owner->m_deviceResources->GetD3DDevice()->CreateBuffer(&vertexBufferDesc, nullptr, m_vertexBuffer.put()));
|
||||
}
|
||||
|
||||
if (m_indexCount > m_allocatedIndexCount)
|
||||
{
|
||||
m_indexBuffer = nullptr;
|
||||
const int alignment = 3 * 1024;
|
||||
m_allocatedIndexCount = ((m_indexCount + alignment - 1) / alignment) * alignment; // align to reasonable size
|
||||
|
||||
const int elementSize = sizeof(uint16_t);
|
||||
const CD3D11_BUFFER_DESC indexBufferDesc(
|
||||
m_allocatedIndexCount * elementSize, D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||
|
||||
winrt::check_hresult(m_owner->m_deviceResources->GetD3DDevice()->CreateBuffer(&indexBufferDesc, nullptr, m_indexBuffer.put()));
|
||||
}
|
||||
|
||||
// upload data
|
||||
D3D11_MAPPED_SUBRESOURCE resource;
|
||||
|
||||
m_owner->m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
context->Map(m_vertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
|
||||
memcpy(resource.pData, &m_vertexData[0], sizeof(Vertex_t) * m_vertexCount);
|
||||
context->Unmap(m_vertexBuffer.get(), 0);
|
||||
|
||||
context->Map(m_indexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
|
||||
memcpy(resource.pData, &m_indexData[0], sizeof(uint16_t) * m_indexCount);
|
||||
context->Unmap(m_indexBuffer.get(), 0);
|
||||
});
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "SpatialSurfaceMeshRenderer.h"
|
||||
|
||||
#include "Common\DirectXHelper.h"
|
||||
|
||||
using namespace winrt::Windows;
|
||||
using namespace winrt::Windows::Perception::Spatial;
|
||||
using namespace winrt::Windows::Graphics::DirectX;
|
||||
using namespace winrt::Windows::Foundation::Numerics;
|
||||
using namespace Concurrency;
|
||||
|
||||
// for debugging -> remove
|
||||
bool g_freeze = false;
|
||||
bool g_freezeOnFrame = false;
|
||||
|
||||
// Initializes D2D resources used for text rendering.
|
||||
SpatialSurfaceMeshRenderer::SpatialSurfaceMeshRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources)
|
||||
: m_deviceResources(deviceResources)
|
||||
{
|
||||
CreateDeviceDependentResources();
|
||||
|
||||
m_spatialLocator = SpatialLocator::GetDefault();
|
||||
if (m_spatialLocator)
|
||||
{
|
||||
m_spatialLocatorLocabilityChangedEventRevoker =
|
||||
m_spatialLocator.LocatabilityChanged(winrt::auto_revoke, {this, &SpatialSurfaceMeshRenderer::OnLocatibilityChanged});
|
||||
|
||||
m_attachedFrameOfReference = m_spatialLocator.CreateAttachedFrameOfReferenceAtCurrentHeading();
|
||||
}
|
||||
}
|
||||
|
||||
SpatialSurfaceMeshRenderer::~SpatialSurfaceMeshRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
std::future<void> SpatialSurfaceMeshRenderer::CreateDeviceDependentResources()
|
||||
{
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
std::wstring fileNamePrefix = L"";
|
||||
#else
|
||||
std::wstring fileNamePrefix = L"ms-appx:///";
|
||||
#endif
|
||||
|
||||
auto asyncAccess = Surfaces::SpatialSurfaceObserver::RequestAccessAsync();
|
||||
asyncAccess.Completed([this](auto handler, auto asyncStatus) {
|
||||
m_surfaceObserver = Surfaces::SpatialSurfaceObserver();
|
||||
|
||||
m_observedSurfaceChangedToken = m_surfaceObserver.ObservedSurfacesChanged(
|
||||
[this](Surfaces::SpatialSurfaceObserver, winrt::Windows::Foundation::IInspectable const& handler) {
|
||||
OnObservedSurfaceChanged();
|
||||
});
|
||||
});
|
||||
|
||||
std::vector<byte> vertexShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + L"hsa_SRMeshVertexShader.cso");
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateVertexShader(
|
||||
vertexShaderFileData.data(), vertexShaderFileData.size(), nullptr, m_vertexShader.put()));
|
||||
|
||||
constexpr std::array<D3D11_INPUT_ELEMENT_DESC, 1> vertexDesc = {{
|
||||
{"POSITION", 0, DXGI_FORMAT_R16G16B16A16_SNORM, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
}};
|
||||
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateInputLayout(
|
||||
vertexDesc.data(),
|
||||
static_cast<UINT>(vertexDesc.size()),
|
||||
vertexShaderFileData.data(),
|
||||
static_cast<UINT>(vertexShaderFileData.size()),
|
||||
m_inputLayout.put()));
|
||||
|
||||
std::vector<byte> geometryShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + L"hsa_SRMeshGeometryShader.cso");
|
||||
|
||||
// After the pass-through geometry shader file is loaded, create the shader.
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateGeometryShader(
|
||||
geometryShaderFileData.data(), geometryShaderFileData.size(), nullptr, m_geometryShader.put()));
|
||||
|
||||
std::vector<byte> pixelShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + L"hsa_SRMeshPixelShader.cso");
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreatePixelShader(
|
||||
pixelShaderFileData.data(), pixelShaderFileData.size(), nullptr, m_pixelShader.put()));
|
||||
|
||||
const CD3D11_BUFFER_DESC constantBufferDesc(sizeof(SRMeshConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&constantBufferDesc, nullptr, m_modelConstantBuffer.put()));
|
||||
|
||||
m_loadingComplete = true;
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshRenderer::ReleaseDeviceDependentResources()
|
||||
{
|
||||
if (m_surfaceObserver)
|
||||
{
|
||||
m_surfaceObserver.ObservedSurfacesChanged(m_observedSurfaceChangedToken);
|
||||
m_surfaceObserver = nullptr;
|
||||
}
|
||||
m_loadingComplete = false;
|
||||
m_inputLayout = nullptr;
|
||||
m_vertexShader = nullptr;
|
||||
m_geometryShader = nullptr;
|
||||
m_pixelShader = nullptr;
|
||||
m_modelConstantBuffer = nullptr;
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshRenderer::OnObservedSurfaceChanged()
|
||||
{
|
||||
if (g_freeze)
|
||||
return;
|
||||
|
||||
m_surfaceChangedCounter++; // just for debugging purposes
|
||||
m_sufaceChanged = true;
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshRenderer::OnLocatibilityChanged(
|
||||
const SpatialLocator& spatialLocator, const winrt::Windows::Foundation::IInspectable&)
|
||||
{
|
||||
SpatialLocatability locatibility = spatialLocator.Locatability();
|
||||
if (locatibility != SpatialLocatability::PositionalTrackingActive)
|
||||
{
|
||||
m_meshParts.clear();
|
||||
}
|
||||
}
|
||||
|
||||
SpatialSurfaceMeshPart* SpatialSurfaceMeshRenderer::GetOrCreateMeshPart(winrt::guid id)
|
||||
{
|
||||
GUID key = id;
|
||||
auto found = m_meshParts.find(key);
|
||||
if (found == m_meshParts.cend())
|
||||
{
|
||||
m_meshParts[id] = std::make_unique<SpatialSurfaceMeshPart>(this);
|
||||
return m_meshParts[id].get();
|
||||
}
|
||||
|
||||
return found->second.get();
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshRenderer::Update(
|
||||
winrt::Windows::Perception::PerceptionTimestamp timestamp,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem)
|
||||
{
|
||||
if (m_surfaceObserver == nullptr)
|
||||
return;
|
||||
|
||||
// update bounding volume (every frame)
|
||||
{
|
||||
SpatialBoundingBox axisAlignedBoundingBox = {
|
||||
{-5.0f, -5.0f, -2.5f},
|
||||
{10.0f, 10.0f, 5.f},
|
||||
};
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
auto delta = now - m_boundingVolumeUpdateTime;
|
||||
|
||||
if (m_attachedFrameOfReference && delta > 1s)
|
||||
{
|
||||
SpatialCoordinateSystem attachedCoordinateSystem =
|
||||
m_attachedFrameOfReference.GetStationaryCoordinateSystemAtTimestamp(timestamp);
|
||||
SpatialBoundingVolume volume = SpatialBoundingVolume::FromBox(attachedCoordinateSystem, axisAlignedBoundingBox);
|
||||
m_surfaceObserver.SetBoundingVolume(volume);
|
||||
|
||||
m_boundingVolumeUpdateTime = now;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_sufaceChanged)
|
||||
{
|
||||
// first mark all as not used
|
||||
for (auto& pair : m_meshParts)
|
||||
{
|
||||
pair.second->m_inUse = false;
|
||||
}
|
||||
|
||||
auto mapContainingSurfaceCollection = m_surfaceObserver.GetObservedSurfaces();
|
||||
|
||||
for (auto pair : mapContainingSurfaceCollection)
|
||||
{
|
||||
if (SpatialSurfaceMeshPart* meshPart = GetOrCreateMeshPart(pair.Key()))
|
||||
{
|
||||
meshPart->Update(pair.Value());
|
||||
g_freeze = g_freezeOnFrame;
|
||||
}
|
||||
}
|
||||
|
||||
// purge the ones not used
|
||||
for (MeshPartMap::const_iterator itr = m_meshParts.cbegin(); itr != m_meshParts.cend();)
|
||||
{
|
||||
itr = itr->second->IsInUse() ? std::next(itr) : m_meshParts.erase(itr);
|
||||
}
|
||||
|
||||
m_sufaceChanged = false;
|
||||
}
|
||||
|
||||
// every frame, bring the model matrix to rendering space
|
||||
for (auto& pair : m_meshParts)
|
||||
{
|
||||
pair.second->UpdateModelMatrix(renderingCoordinateSystem);
|
||||
}
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshRenderer::Render(bool isStereo)
|
||||
{
|
||||
if (!m_loadingComplete || m_meshParts.empty())
|
||||
return;
|
||||
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
// Each vertex is one instance of the VertexPositionColorTexture struct.
|
||||
const uint32_t stride = sizeof(SpatialSurfaceMeshPart::Vertex_t);
|
||||
const uint32_t offset = 0;
|
||||
ID3D11Buffer* pBufferToSet;
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
context->IASetInputLayout(m_inputLayout.get());
|
||||
|
||||
// Attach the vertex shader.
|
||||
context->VSSetShader(m_vertexShader.get(), nullptr, 0);
|
||||
// Apply the model constant buffer to the vertex shader.
|
||||
pBufferToSet = m_modelConstantBuffer.get();
|
||||
context->VSSetConstantBuffers(0, 1, &pBufferToSet);
|
||||
|
||||
// geometry shader
|
||||
context->GSSetShader(m_geometryShader.get(), nullptr, 0);
|
||||
|
||||
// pixel shader
|
||||
context->PSSetShader(m_zfillOnly ? nullptr : m_pixelShader.get(), nullptr, 0);
|
||||
|
||||
// Apply the model constant buffer to the pixel shader.
|
||||
pBufferToSet = m_modelConstantBuffer.get();
|
||||
context->PSSetConstantBuffers(0, 1, &pBufferToSet);
|
||||
|
||||
// render each mesh part
|
||||
for (auto& pair : m_meshParts)
|
||||
{
|
||||
SpatialSurfaceMeshPart* part = pair.second.get();
|
||||
if (part->m_indexCount == 0)
|
||||
continue;
|
||||
|
||||
if (part->m_needsUpload)
|
||||
{
|
||||
part->UploadData();
|
||||
}
|
||||
|
||||
// update part specific model matrix
|
||||
context->UpdateSubresource(m_modelConstantBuffer.get(), 0, nullptr, &part->m_constantBufferData, 0, 0);
|
||||
|
||||
ID3D11Buffer* pBufferToSet2 = part->m_vertexBuffer.get();
|
||||
context->IASetVertexBuffers(0, 1, &pBufferToSet2, &stride, &offset);
|
||||
context->IASetIndexBuffer(part->m_indexBuffer.get(), DXGI_FORMAT_R16_UINT, 0);
|
||||
// draw the mesh
|
||||
context->DrawIndexedInstanced(part->m_indexCount, isStereo ? 2 : 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
// set geometry shader back
|
||||
context->GSSetShader(nullptr, nullptr, 0);
|
||||
});
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SRMeshPart
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SpatialSurfaceMeshPart::SpatialSurfaceMeshPart(SpatialSurfaceMeshRenderer* owner)
|
||||
: m_owner(owner)
|
||||
{
|
||||
auto identity = DirectX::XMMatrixIdentity();
|
||||
m_constantBufferData.modelMatrix = reinterpret_cast<DirectX::XMFLOAT4X4&>(identity);
|
||||
m_vertexScale.x = m_vertexScale.y = m_vertexScale.z = 1.0f;
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshPart::Update(Surfaces::SpatialSurfaceInfo surfaceInfo)
|
||||
{
|
||||
m_inUse = true;
|
||||
m_updateInProgress = true;
|
||||
double TriangleDensity = 750.0; // from Hydrogen
|
||||
auto asyncOpertation = surfaceInfo.TryComputeLatestMeshAsync(TriangleDensity);
|
||||
asyncOpertation.Completed([this](winrt::Windows::Foundation::IAsyncOperation<Surfaces::SpatialSurfaceMesh> result, auto asyncStatus) {
|
||||
Surfaces::SpatialSurfaceMesh mesh = result.GetResults();
|
||||
UpdateMesh(mesh);
|
||||
m_updateInProgress = false;
|
||||
});
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshPart::UpdateModelMatrix(winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem)
|
||||
{
|
||||
if (m_coordinateSystem == nullptr)
|
||||
return;
|
||||
|
||||
auto modelTransform = m_coordinateSystem.TryGetTransformTo(renderingCoordinateSystem);
|
||||
if (modelTransform)
|
||||
{
|
||||
float4x4 matrixWinRt = transpose(modelTransform.Value());
|
||||
DirectX::XMMATRIX transformMatrix = DirectX::XMLoadFloat4x4(&matrixWinRt);
|
||||
DirectX::XMMATRIX scaleMatrix = DirectX::XMMatrixScaling(m_vertexScale.x, m_vertexScale.y, m_vertexScale.z);
|
||||
DirectX::XMMATRIX result = DirectX::XMMatrixMultiply(transformMatrix, scaleMatrix);
|
||||
DirectX::XMStoreFloat4x4(&m_constantBufferData.modelMatrix, result);
|
||||
}
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshPart::UpdateMesh(Surfaces::SpatialSurfaceMesh mesh)
|
||||
{
|
||||
m_coordinateSystem = mesh.CoordinateSystem();
|
||||
|
||||
Surfaces::SpatialSurfaceMeshBuffer vertexBuffer = mesh.VertexPositions();
|
||||
Surfaces::SpatialSurfaceMeshBuffer indexBuffer = mesh.TriangleIndices();
|
||||
|
||||
DirectXPixelFormat vertexFormat = vertexBuffer.Format();
|
||||
DirectXPixelFormat indexFormat = indexBuffer.Format();
|
||||
|
||||
assert(vertexFormat == DirectXPixelFormat::R16G16B16A16IntNormalized);
|
||||
assert(indexFormat == DirectXPixelFormat::R16UInt);
|
||||
|
||||
uint32_t vertexCount = vertexBuffer.ElementCount();
|
||||
uint32_t indexCount = indexBuffer.ElementCount();
|
||||
assert((indexCount % 3) == 0);
|
||||
|
||||
if (vertexCount == 0 || indexCount == 0)
|
||||
{
|
||||
m_indexCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// convert vertices:
|
||||
{
|
||||
Vertex_t* dest = MapVertices(vertexCount);
|
||||
winrt::Windows::Storage::Streams::IBuffer vertexData = vertexBuffer.Data();
|
||||
uint8_t* vertexRaw = vertexData.data();
|
||||
int vertexStride = vertexData.Length() / vertexCount;
|
||||
assert(vertexStride == 8); // DirectXPixelFormat::R16G16B16A16IntNormalized
|
||||
winrt::Windows::Foundation::Numerics::float3 positionScale = mesh.VertexPositionScale();
|
||||
m_vertexScale.x = positionScale.x;
|
||||
m_vertexScale.y = positionScale.y;
|
||||
m_vertexScale.z = positionScale.z;
|
||||
memcpy(dest, vertexRaw, vertexCount * sizeof(Vertex_t));
|
||||
UnmapVertices();
|
||||
}
|
||||
|
||||
// convert indices
|
||||
{
|
||||
uint16_t* dest = MapIndices(indexCount);
|
||||
winrt::Windows::Storage::Streams::IBuffer indexData = indexBuffer.Data();
|
||||
uint16_t* source = (uint16_t*)indexData.data();
|
||||
for (uint32_t i = 0; i < indexCount; i++)
|
||||
{
|
||||
assert(source[i] < vertexCount);
|
||||
dest[i] = source[i];
|
||||
}
|
||||
UnmapIndices();
|
||||
}
|
||||
m_needsUpload = true;
|
||||
}
|
||||
|
||||
SpatialSurfaceMeshPart::Vertex_t* SpatialSurfaceMeshPart::MapVertices(uint32_t vertexCount)
|
||||
{
|
||||
m_vertexCount = vertexCount;
|
||||
if (vertexCount > m_vertexData.size())
|
||||
m_vertexData.resize(vertexCount);
|
||||
return &m_vertexData[0];
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshPart::UnmapVertices()
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t* SpatialSurfaceMeshPart::MapIndices(uint32_t indexCount)
|
||||
{
|
||||
m_indexCount = indexCount;
|
||||
if (indexCount > m_indexData.size())
|
||||
m_indexData.resize(indexCount);
|
||||
return &m_indexData[0];
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshPart::UnmapIndices()
|
||||
{
|
||||
}
|
||||
|
||||
void SpatialSurfaceMeshPart::UploadData()
|
||||
{
|
||||
if (m_vertexCount > m_allocatedVertexCount)
|
||||
{
|
||||
m_vertexBuffer = nullptr;
|
||||
|
||||
const int alignment = 1024;
|
||||
m_allocatedVertexCount = ((m_vertexCount + alignment - 1) / alignment) * alignment; // align to reasonable size
|
||||
|
||||
const int elementSize = sizeof(Vertex_t);
|
||||
const CD3D11_BUFFER_DESC vertexBufferDesc(
|
||||
m_allocatedVertexCount * elementSize, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||
|
||||
winrt::check_hresult(m_owner->m_deviceResources->GetD3DDevice()->CreateBuffer(&vertexBufferDesc, nullptr, m_vertexBuffer.put()));
|
||||
}
|
||||
|
||||
if (m_indexCount > m_allocatedIndexCount)
|
||||
{
|
||||
m_indexBuffer = nullptr;
|
||||
const int alignment = 3 * 1024;
|
||||
m_allocatedIndexCount = ((m_indexCount + alignment - 1) / alignment) * alignment; // align to reasonable size
|
||||
|
||||
const int elementSize = sizeof(uint16_t);
|
||||
const CD3D11_BUFFER_DESC indexBufferDesc(
|
||||
m_allocatedIndexCount * elementSize, D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
|
||||
|
||||
winrt::check_hresult(m_owner->m_deviceResources->GetD3DDevice()->CreateBuffer(&indexBufferDesc, nullptr, m_indexBuffer.put()));
|
||||
}
|
||||
|
||||
// upload data
|
||||
D3D11_MAPPED_SUBRESOURCE resource;
|
||||
|
||||
m_owner->m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
context->Map(m_vertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
|
||||
memcpy(resource.pData, &m_vertexData[0], sizeof(Vertex_t) * m_vertexCount);
|
||||
context->Unmap(m_vertexBuffer.get(), 0);
|
||||
|
||||
context->Map(m_indexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
|
||||
memcpy(resource.pData, &m_indexData[0], sizeof(uint16_t) * m_indexCount);
|
||||
context->Unmap(m_indexBuffer.get(), 0);
|
||||
});
|
||||
}
|
|
@ -1,130 +1,141 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "..\Common\DeviceResources.h"
|
||||
#include "..\Common\Utils.h"
|
||||
|
||||
#include <winrt/windows.perception.spatial.surfaces.h>
|
||||
|
||||
#include <future>
|
||||
#include <string>
|
||||
|
||||
// forward
|
||||
class SpatialSurfaceMeshRenderer;
|
||||
|
||||
struct SRMeshConstantBuffer
|
||||
{
|
||||
DirectX::XMFLOAT4X4 modelMatrix;
|
||||
};
|
||||
|
||||
// represents a single piece of mesh (SpatialSurfaceMesh)
|
||||
class SpatialSurfaceMeshPart
|
||||
{
|
||||
public:
|
||||
struct Vertex_t
|
||||
{
|
||||
// float pos[4];
|
||||
int16_t pos[4];
|
||||
};
|
||||
SpatialSurfaceMeshPart(SpatialSurfaceMeshRenderer* owner);
|
||||
void Update(winrt::Windows::Perception::Spatial::Surfaces::SpatialSurfaceInfo surfaceInfo);
|
||||
|
||||
void UpdateMesh(winrt::Windows::Perception::Spatial::Surfaces::SpatialSurfaceMesh mesh);
|
||||
|
||||
bool IsInUse() const
|
||||
{
|
||||
return m_inUse || m_updateInProgress;
|
||||
}
|
||||
|
||||
private:
|
||||
Vertex_t* MapVertices(uint32_t vertexCount);
|
||||
void UnmapVertices();
|
||||
uint16_t* MapIndices(uint32_t indexCount);
|
||||
void UnmapIndices();
|
||||
void UploadData();
|
||||
void UpdateModelMatrix(winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem);
|
||||
|
||||
friend class SpatialSurfaceMeshRenderer;
|
||||
SpatialSurfaceMeshRenderer* m_owner;
|
||||
bool m_inUse = true;
|
||||
bool m_needsUpload = false;
|
||||
bool m_updateInProgress = false;
|
||||
|
||||
GUID m_ID;
|
||||
uint32_t m_allocatedVertexCount = 0;
|
||||
uint32_t m_allocatedIndexCount = 0;
|
||||
uint32_t m_vertexCount = 0;
|
||||
uint32_t m_indexCount = 0;
|
||||
winrt::com_ptr<ID3D11Buffer> m_vertexBuffer;
|
||||
winrt::com_ptr<ID3D11Buffer> m_indexBuffer;
|
||||
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem m_coordinateSystem = nullptr;
|
||||
|
||||
// double buffered data:
|
||||
std::vector<Vertex_t> m_vertexData;
|
||||
std::vector<uint16_t> m_indexData;
|
||||
SRMeshConstantBuffer m_constantBufferData;
|
||||
DirectX::XMFLOAT3 m_vertexScale;
|
||||
};
|
||||
|
||||
|
||||
// Renders the SR mesh
|
||||
class SpatialSurfaceMeshRenderer
|
||||
{
|
||||
public:
|
||||
SpatialSurfaceMeshRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources);
|
||||
virtual ~SpatialSurfaceMeshRenderer();
|
||||
|
||||
void Update(winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem);
|
||||
|
||||
void Render(bool isStereo);
|
||||
|
||||
std::future<void> CreateDeviceDependentResources();
|
||||
void ReleaseDeviceDependentResources();
|
||||
|
||||
private:
|
||||
void OnObservedSurfaceChanged();
|
||||
SpatialSurfaceMeshPart* GetOrCreateMeshPart(winrt::guid id);
|
||||
|
||||
private:
|
||||
friend class SpatialSurfaceMeshPart;
|
||||
|
||||
// Cached pointer to device resources.
|
||||
std::shared_ptr<DXHelper::DeviceResources> m_deviceResources;
|
||||
|
||||
// Resources related to mesh rendering.
|
||||
winrt::com_ptr<ID3D11ShaderResourceView> m_shaderResourceView;
|
||||
winrt::com_ptr<ID3D11SamplerState> m_pointSampler;
|
||||
winrt::com_ptr<ID3D11RenderTargetView> m_renderTargetView;
|
||||
|
||||
// observer:
|
||||
int m_surfaceChangedCounter = 0;
|
||||
bool m_sufaceChanged = false;
|
||||
winrt::Windows::Perception::Spatial::Surfaces::SpatialSurfaceObserver m_surfaceObserver = nullptr;
|
||||
winrt::event_token m_observedSurfaceChangedToken;
|
||||
|
||||
// mesh parts
|
||||
using MeshPartMap = std::map<GUID, std::unique_ptr<SpatialSurfaceMeshPart>, GUIDComparer>;
|
||||
MeshPartMap m_meshParts;
|
||||
|
||||
// rendering
|
||||
bool m_zfillOnly = false;
|
||||
bool m_loadingComplete = false;
|
||||
winrt::com_ptr<ID3D11InputLayout> m_inputLayout;
|
||||
|
||||
winrt::com_ptr<ID3D11VertexShader> m_vertexShader;
|
||||
winrt::com_ptr<ID3D11GeometryShader> m_geometryShader;
|
||||
winrt::com_ptr<ID3D11PixelShader> m_pixelShader;
|
||||
|
||||
winrt::com_ptr<ID3D11Buffer> m_modelConstantBuffer;
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "..\Common\DeviceResources.h"
|
||||
#include "..\Common\Utils.h"
|
||||
|
||||
#include <winrt/windows.perception.spatial.surfaces.h>
|
||||
|
||||
#include <future>
|
||||
#include <string>
|
||||
|
||||
// forward
|
||||
class SpatialSurfaceMeshRenderer;
|
||||
|
||||
struct SRMeshConstantBuffer
|
||||
{
|
||||
DirectX::XMFLOAT4X4 modelMatrix;
|
||||
};
|
||||
|
||||
// Assert that the constant buffer remains 16-byte aligned (best practice).
|
||||
static_assert(
|
||||
(sizeof(SRMeshConstantBuffer) % (sizeof(float) * 4)) == 0,
|
||||
"SR mesh constant buffer size must be 16-byte aligned (16 bytes is the length of four floats).");
|
||||
|
||||
// represents a single piece of mesh (SpatialSurfaceMesh)
|
||||
class SpatialSurfaceMeshPart
|
||||
{
|
||||
public:
|
||||
struct Vertex_t
|
||||
{
|
||||
// float pos[4];
|
||||
int16_t pos[4];
|
||||
};
|
||||
SpatialSurfaceMeshPart(SpatialSurfaceMeshRenderer* owner);
|
||||
void Update(winrt::Windows::Perception::Spatial::Surfaces::SpatialSurfaceInfo surfaceInfo);
|
||||
|
||||
void UpdateMesh(winrt::Windows::Perception::Spatial::Surfaces::SpatialSurfaceMesh mesh);
|
||||
|
||||
bool IsInUse() const
|
||||
{
|
||||
return m_inUse || m_updateInProgress;
|
||||
}
|
||||
|
||||
private:
|
||||
Vertex_t* MapVertices(uint32_t vertexCount);
|
||||
void UnmapVertices();
|
||||
uint16_t* MapIndices(uint32_t indexCount);
|
||||
void UnmapIndices();
|
||||
void UploadData();
|
||||
void UpdateModelMatrix(winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem);
|
||||
|
||||
friend class SpatialSurfaceMeshRenderer;
|
||||
SpatialSurfaceMeshRenderer* m_owner;
|
||||
bool m_inUse = true;
|
||||
bool m_needsUpload = false;
|
||||
bool m_updateInProgress = false;
|
||||
|
||||
GUID m_ID;
|
||||
uint32_t m_allocatedVertexCount = 0;
|
||||
uint32_t m_allocatedIndexCount = 0;
|
||||
uint32_t m_vertexCount = 0;
|
||||
uint32_t m_indexCount = 0;
|
||||
winrt::com_ptr<ID3D11Buffer> m_vertexBuffer;
|
||||
winrt::com_ptr<ID3D11Buffer> m_indexBuffer;
|
||||
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem m_coordinateSystem = nullptr;
|
||||
|
||||
// double buffered data:
|
||||
std::vector<Vertex_t> m_vertexData;
|
||||
std::vector<uint16_t> m_indexData;
|
||||
SRMeshConstantBuffer m_constantBufferData;
|
||||
DirectX::XMFLOAT3 m_vertexScale;
|
||||
};
|
||||
|
||||
// Renders the SR mesh
|
||||
class SpatialSurfaceMeshRenderer
|
||||
{
|
||||
public:
|
||||
SpatialSurfaceMeshRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources);
|
||||
virtual ~SpatialSurfaceMeshRenderer();
|
||||
|
||||
void Update(
|
||||
winrt::Windows::Perception::PerceptionTimestamp timestamp,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem);
|
||||
|
||||
void Render(bool isStereo);
|
||||
|
||||
std::future<void> CreateDeviceDependentResources();
|
||||
void ReleaseDeviceDependentResources();
|
||||
|
||||
private:
|
||||
void OnObservedSurfaceChanged();
|
||||
void OnLocatibilityChanged(
|
||||
const winrt::Windows::Perception::Spatial::SpatialLocator& spatialLocator, const winrt::Windows::Foundation::IInspectable&);
|
||||
SpatialSurfaceMeshPart* GetOrCreateMeshPart(winrt::guid id);
|
||||
|
||||
private:
|
||||
friend class SpatialSurfaceMeshPart;
|
||||
|
||||
// Cached pointer to device resources.
|
||||
std::shared_ptr<DXHelper::DeviceResources> m_deviceResources;
|
||||
|
||||
// observer:
|
||||
int m_surfaceChangedCounter = 0;
|
||||
bool m_sufaceChanged = false;
|
||||
winrt::Windows::Perception::Spatial::Surfaces::SpatialSurfaceObserver m_surfaceObserver = nullptr;
|
||||
winrt::event_token m_observedSurfaceChangedToken;
|
||||
|
||||
// mesh parts
|
||||
using MeshPartMap = std::map<GUID, std::unique_ptr<SpatialSurfaceMeshPart>, GUIDComparer>;
|
||||
MeshPartMap m_meshParts;
|
||||
|
||||
// rendering
|
||||
bool m_zfillOnly = false;
|
||||
bool m_loadingComplete = false;
|
||||
winrt::com_ptr<ID3D11InputLayout> m_inputLayout;
|
||||
|
||||
winrt::com_ptr<ID3D11VertexShader> m_vertexShader;
|
||||
winrt::com_ptr<ID3D11GeometryShader> m_geometryShader;
|
||||
winrt::com_ptr<ID3D11PixelShader> m_pixelShader;
|
||||
|
||||
winrt::com_ptr<ID3D11Buffer> m_modelConstantBuffer;
|
||||
|
||||
winrt::Windows::Perception::Spatial::SpatialLocator m_spatialLocator = nullptr;
|
||||
winrt::Windows::Perception::Spatial::SpatialLocator::LocatabilityChanged_revoker m_spatialLocatorLocabilityChangedEventRevoker;
|
||||
|
||||
// A attached frame of reference based on m_spatialLocator.
|
||||
winrt::Windows::Perception::Spatial::SpatialLocatorAttachedFrameOfReference m_attachedFrameOfReference = nullptr;
|
||||
|
||||
std::chrono::time_point<std::chrono::steady_clock> m_boundingVolumeUpdateTime;
|
||||
};
|
|
@ -1,347 +1,353 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "../Common/DirectXHelper.h"
|
||||
#include "SpinningCubeRenderer.h"
|
||||
|
||||
#include <winrt/Windows.Foundation.Numerics.h>
|
||||
#include <winrt/Windows.Perception.People.h>
|
||||
#include <winrt/Windows.Perception.h>
|
||||
|
||||
using namespace DirectX;
|
||||
|
||||
// Loads vertex and pixel shaders from files and instantiates the cube geometry.
|
||||
SpinningCubeRenderer::SpinningCubeRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources)
|
||||
: m_deviceResources(deviceResources)
|
||||
{
|
||||
CreateDeviceDependentResources();
|
||||
}
|
||||
|
||||
// This function uses a SpatialPointerPose to position the world-locked hologram
|
||||
// two meters in front of the user's heading.
|
||||
void SpinningCubeRenderer::PositionHologram(const winrt::Windows::UI::Input::Spatial::SpatialPointerPose& pointerPose)
|
||||
{
|
||||
if (pointerPose != nullptr)
|
||||
{
|
||||
// Try to get the gaze from eyes.
|
||||
winrt::Windows::Perception::People::EyesPose eyesPose = pointerPose.Eyes();
|
||||
if (eyesPose != nullptr)
|
||||
{
|
||||
winrt::Windows::Foundation::IReference<winrt::Windows::Perception::Spatial::SpatialRay> gaze = eyesPose.Gaze();
|
||||
if (gaze != nullptr)
|
||||
{
|
||||
PositionHologram(gaze.Value().Origin, gaze.Value().Direction);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the gaze direction from head.
|
||||
const auto headPosition = pointerPose.Head().Position();
|
||||
const auto headDirection = pointerPose.Head().ForwardDirection();
|
||||
|
||||
PositionHologram(headPosition, headDirection);
|
||||
}
|
||||
}
|
||||
|
||||
void SpinningCubeRenderer::SetColorFilter(DirectX::XMFLOAT4 color)
|
||||
{
|
||||
m_filterColorData = color;
|
||||
}
|
||||
|
||||
// This function uses a point and a vector to position the world-locked hologram
|
||||
// two meters in front of the user's heading.
|
||||
void SpinningCubeRenderer::PositionHologram(
|
||||
winrt::Windows::Foundation::Numerics::float3 headPosition, winrt::Windows::Foundation::Numerics::float3 headDirection)
|
||||
{
|
||||
// The hologram is positioned two meters along the user's gaze direction.
|
||||
static const float distanceFromUser = 2.0f; // meters
|
||||
const auto gazeAtTwoMeters = headPosition + (distanceFromUser * headDirection);
|
||||
|
||||
// This will be used as the translation component of the hologram's
|
||||
// model transform.
|
||||
SetPosition(gazeAtTwoMeters);
|
||||
}
|
||||
|
||||
// Called once per frame. Rotates the cube, and calculates and sets the model matrix
|
||||
// relative to the position transform indicated by hologramPositionTransform.
|
||||
void SpinningCubeRenderer::Update(float totalSeconds)
|
||||
{
|
||||
// Rotate the cube.
|
||||
// Convert degrees to radians, then convert seconds to rotation angle.
|
||||
const float radiansPerSecond = XMConvertToRadians(m_degreesPerSecond);
|
||||
const double relativeRotation = totalSeconds * radiansPerSecond;
|
||||
double totalRotation = m_rotationOffset;
|
||||
switch (m_pauseState)
|
||||
{
|
||||
case PauseState::Unpaused:
|
||||
totalRotation += relativeRotation;
|
||||
break;
|
||||
|
||||
case PauseState::Pausing:
|
||||
m_rotationOffset += relativeRotation;
|
||||
m_pauseState = PauseState::Paused;
|
||||
case PauseState::Paused:
|
||||
totalRotation = m_rotationOffset;
|
||||
break;
|
||||
|
||||
case PauseState::Unpausing:
|
||||
m_rotationOffset -= relativeRotation;
|
||||
m_pauseState = PauseState::Unpaused;
|
||||
break;
|
||||
}
|
||||
const float radians = static_cast<float>(fmod(totalRotation, XM_2PI));
|
||||
const XMMATRIX modelRotation = XMMatrixRotationY(-radians);
|
||||
|
||||
// Position the cube.
|
||||
const XMMATRIX modelTranslation = XMMatrixTranslationFromVector(XMLoadFloat3(&m_position));
|
||||
|
||||
// Multiply to get the transform matrix.
|
||||
// Note that this transform does not enforce a particular coordinate system. The calling
|
||||
// class is responsible for rendering this content in a consistent manner.
|
||||
const XMMATRIX modelTransform = XMMatrixMultiply(modelRotation, modelTranslation);
|
||||
|
||||
// Store the normal transform.
|
||||
XMStoreFloat4x4(&m_modelConstantBufferData.normal, XMMatrixTranspose(modelRotation));
|
||||
|
||||
// The view and projection matrices are provided by the system; they are associated
|
||||
// with holographic cameras, and updated on a per-camera basis.
|
||||
// Here, we provide the model transform for the sample hologram. The model transform
|
||||
// matrix is transposed to prepare it for the shader.
|
||||
XMStoreFloat4x4(&m_modelConstantBufferData.model, XMMatrixTranspose(modelTransform));
|
||||
|
||||
// Loading is asynchronous. Resources must be created before they can be updated.
|
||||
if (!m_loadingComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the D3D device context to update Direct3D device-based resources.
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
// Update the model transform buffer for the hologram.
|
||||
context->UpdateSubresource(m_modelConstantBuffer.get(), 0, nullptr, &m_modelConstantBufferData, 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
// Renders one frame using the vertex and pixel shaders.
|
||||
// On devices that do not support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature,
|
||||
// a pass-through geometry shader is also used to set the render
|
||||
// target array index.
|
||||
void SpinningCubeRenderer::Render(bool isStereo)
|
||||
{
|
||||
// Loading is asynchronous. Resources must be created before drawing can occur.
|
||||
if (!m_loadingComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
ID3D11Buffer* pBufferToSet = nullptr;
|
||||
|
||||
// Each vertex is one instance of the VertexPositionColor struct.
|
||||
const UINT stride = sizeof(VertexPositionNormalColor);
|
||||
const UINT offset = 0;
|
||||
|
||||
pBufferToSet = m_vertexBuffer.get();
|
||||
context->IASetVertexBuffers(0, 1, &pBufferToSet, &stride, &offset);
|
||||
context->IASetIndexBuffer(
|
||||
m_indexBuffer.get(),
|
||||
DXGI_FORMAT_R16_UINT, // Each index is one 16-bit unsigned integer (short).
|
||||
0);
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
context->IASetInputLayout(m_inputLayout.get());
|
||||
|
||||
// Attach the vertex shader.
|
||||
context->VSSetShader(m_vertexShader.get(), nullptr, 0);
|
||||
// Apply the model constant buffer to the vertex shader.
|
||||
pBufferToSet = m_modelConstantBuffer.get();
|
||||
context->VSSetConstantBuffers(0, 1, &pBufferToSet);
|
||||
|
||||
if (!m_usingVprtShaders)
|
||||
{
|
||||
// On devices that do not support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature,
|
||||
// a pass-through geometry shader is used to set the render target
|
||||
// array index.
|
||||
context->GSSetShader(m_geometryShader.get(), nullptr, 0);
|
||||
}
|
||||
|
||||
context->UpdateSubresource(m_filterColorBuffer.get(), 0, nullptr, &m_filterColorData, 0, 0);
|
||||
|
||||
pBufferToSet = m_filterColorBuffer.get();
|
||||
context->PSSetConstantBuffers(2, 1, &pBufferToSet);
|
||||
|
||||
// Attach the pixel shader.
|
||||
context->PSSetShader(m_pixelShader.get(), nullptr, 0);
|
||||
|
||||
// Draw the objects.
|
||||
context->DrawIndexedInstanced(
|
||||
m_indexCount, // Index count per instance.
|
||||
isStereo ? 2 : 1, // Instance count.
|
||||
0, // Start index location.
|
||||
0, // Base vertex location.
|
||||
0 // Start instance location.
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
std::future<void> SpinningCubeRenderer::CreateDeviceDependentResources()
|
||||
{
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
std::wstring fileNamePrefix = L"";
|
||||
#else
|
||||
std::wstring fileNamePrefix = L"ms-appx:///";
|
||||
#endif
|
||||
|
||||
m_usingVprtShaders = m_deviceResources->GetDeviceSupportsVprt();
|
||||
|
||||
// On devices that do support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature
|
||||
// we can avoid using a pass-through geometry shader to set the render
|
||||
// target array index, thus avoiding any overhead that would be
|
||||
// incurred by setting the geometry shader stage.
|
||||
|
||||
std::wstring vertexShaderFileName = m_usingVprtShaders ? L"hsa_VprtVertexShader.cso" : L"hsa_VertexShader.cso";
|
||||
|
||||
std::vector<byte> vertexShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + vertexShaderFileName);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateVertexShader(
|
||||
vertexShaderFileData.data(), vertexShaderFileData.size(), nullptr, m_vertexShader.put()));
|
||||
|
||||
constexpr std::array<D3D11_INPUT_ELEMENT_DESC, 3> vertexDesc = {{
|
||||
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
}};
|
||||
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateInputLayout(
|
||||
vertexDesc.data(),
|
||||
static_cast<UINT>(vertexDesc.size()),
|
||||
vertexShaderFileData.data(),
|
||||
static_cast<UINT>(vertexShaderFileData.size()),
|
||||
m_inputLayout.put()));
|
||||
|
||||
std::vector<byte> pixelShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + L"hsa_PixelShader.cso");
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreatePixelShader(
|
||||
pixelShaderFileData.data(), pixelShaderFileData.size(), nullptr, m_pixelShader.put()));
|
||||
|
||||
const ModelConstantBuffer constantBuffer{
|
||||
reinterpret_cast<DirectX::XMFLOAT4X4&>(winrt::Windows::Foundation::Numerics::float4x4::identity()),
|
||||
reinterpret_cast<DirectX::XMFLOAT4X4&>(winrt::Windows::Foundation::Numerics::float4x4::identity()),
|
||||
};
|
||||
|
||||
const CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&constantBufferDesc, nullptr, m_modelConstantBuffer.put()));
|
||||
|
||||
const CD3D11_BUFFER_DESC filterColorBufferDesc(sizeof(XMFLOAT4), D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&filterColorBufferDesc, nullptr, m_filterColorBuffer.put()));
|
||||
|
||||
if (!m_usingVprtShaders)
|
||||
{
|
||||
// Load the pass-through geometry shader.
|
||||
std::vector<byte> geometryShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + L"hsa_GeometryShader.cso");
|
||||
|
||||
// After the pass-through geometry shader file is loaded, create the shader.
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateGeometryShader(
|
||||
geometryShaderFileData.data(), geometryShaderFileData.size(), nullptr, m_geometryShader.put()));
|
||||
}
|
||||
|
||||
// Load mesh vertices. Each vertex has a position and a color.
|
||||
// Note that the cube size has changed from the default DirectX app
|
||||
// template. Windows Holographic is scaled in meters, so to draw the
|
||||
// cube at a comfortable size we made the cube width 0.2 m (20 cm).
|
||||
static const VertexPositionNormalColor cubeVertices[] = {
|
||||
{XMFLOAT3(-0.1f, -0.1f, -0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f)}, // vertex 0 non-debug
|
||||
{XMFLOAT3(-0.1f, -0.1f, 0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f)},
|
||||
{XMFLOAT3(-0.1f, 0.1f, -0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f)},
|
||||
{XMFLOAT3(-0.1f, 0.1f, 0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 1.0f)},
|
||||
{XMFLOAT3(0.1f, -0.1f, -0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f)},
|
||||
{XMFLOAT3(0.1f, -0.1f, 0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 1.0f)},
|
||||
{XMFLOAT3(0.1f, 0.1f, -0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(1.0f, 1.0f, 0.0f)},
|
||||
{XMFLOAT3(0.1f, 0.1f, 0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(1.0f, 1.0f, 1.0f)},
|
||||
};
|
||||
|
||||
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
|
||||
vertexBufferData.pSysMem = cubeVertices;
|
||||
vertexBufferData.SysMemPitch = 0;
|
||||
vertexBufferData.SysMemSlicePitch = 0;
|
||||
const CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(cubeVertices), D3D11_BIND_VERTEX_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&vertexBufferDesc, &vertexBufferData, m_vertexBuffer.put()));
|
||||
|
||||
// Load mesh indices. Each trio of indices represents
|
||||
// a triangle to be rendered on the screen.
|
||||
// For example: 2,1,0 means that the vertices with indexes
|
||||
// 2, 1, and 0 from the vertex buffer compose the
|
||||
// first triangle of this mesh.
|
||||
// Note that the winding order is clockwise by default.
|
||||
static const unsigned short cubeIndices[] = {
|
||||
2, 1, 0, // -x
|
||||
2, 3, 1,
|
||||
|
||||
6, 4, 5, // +x
|
||||
6, 5, 7,
|
||||
|
||||
0, 1, 5, // -y
|
||||
0, 5, 4,
|
||||
|
||||
2, 6, 7, // +y
|
||||
2, 7, 3,
|
||||
|
||||
0, 4, 6, // -z
|
||||
0, 6, 2,
|
||||
|
||||
1, 3, 7, // +z
|
||||
1, 7, 5,
|
||||
};
|
||||
|
||||
m_indexCount = ARRAYSIZE(cubeIndices);
|
||||
|
||||
D3D11_SUBRESOURCE_DATA indexBufferData = {0};
|
||||
indexBufferData.pSysMem = cubeIndices;
|
||||
indexBufferData.SysMemPitch = 0;
|
||||
indexBufferData.SysMemSlicePitch = 0;
|
||||
const CD3D11_BUFFER_DESC indexBufferDesc(sizeof(cubeIndices), D3D11_BIND_INDEX_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&indexBufferDesc, &indexBufferData, m_indexBuffer.put()));
|
||||
|
||||
// Once the cube is loaded, the object is ready to be rendered.
|
||||
m_loadingComplete = true;
|
||||
}
|
||||
|
||||
void SpinningCubeRenderer::ReleaseDeviceDependentResources()
|
||||
{
|
||||
m_loadingComplete = false;
|
||||
m_usingVprtShaders = false;
|
||||
m_vertexShader = nullptr;
|
||||
m_inputLayout = nullptr;
|
||||
m_pixelShader = nullptr;
|
||||
m_geometryShader = nullptr;
|
||||
m_modelConstantBuffer = nullptr;
|
||||
m_vertexBuffer = nullptr;
|
||||
m_indexBuffer = nullptr;
|
||||
m_filterColorBuffer = nullptr;
|
||||
}
|
||||
|
||||
void SpinningCubeRenderer::CreateWindowSizeDependentResources()
|
||||
{
|
||||
}
|
||||
|
||||
void SpinningCubeRenderer::TogglePauseState()
|
||||
{
|
||||
if (m_pauseState == PauseState::Paused)
|
||||
{
|
||||
m_pauseState = PauseState::Unpausing;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pauseState = PauseState::Pausing;
|
||||
}
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include <Content/SpinningCubeRenderer.h>
|
||||
|
||||
#include <Common/DirectXHelper.h>
|
||||
|
||||
#include <winrt/Windows.Perception.People.h>
|
||||
#include <winrt/Windows.Storage.Streams.h>
|
||||
|
||||
using namespace DirectX;
|
||||
|
||||
// Loads vertex and pixel shaders from files and instantiates the cube geometry.
|
||||
SpinningCubeRenderer::SpinningCubeRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources)
|
||||
: m_deviceResources(deviceResources)
|
||||
{
|
||||
CreateDeviceDependentResources();
|
||||
}
|
||||
|
||||
// This function uses a SpatialPointerPose to position the world-locked hologram
|
||||
// two meters in front of the user's heading.
|
||||
void SpinningCubeRenderer::PositionHologram(const winrt::Windows::UI::Input::Spatial::SpatialPointerPose& pointerPose)
|
||||
{
|
||||
if (pointerPose != nullptr)
|
||||
{
|
||||
// Try to get the gaze from eyes.
|
||||
winrt::Windows::Perception::People::EyesPose eyesPose = pointerPose.Eyes();
|
||||
if (eyesPose != nullptr)
|
||||
{
|
||||
winrt::Windows::Foundation::IReference<winrt::Windows::Perception::Spatial::SpatialRay> gaze = eyesPose.Gaze();
|
||||
if (gaze != nullptr)
|
||||
{
|
||||
PositionHologram(gaze.Value().Origin, gaze.Value().Direction);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the gaze direction from head.
|
||||
const auto headPosition = pointerPose.Head().Position();
|
||||
const auto headDirection = pointerPose.Head().ForwardDirection();
|
||||
|
||||
PositionHologram(headPosition, headDirection);
|
||||
}
|
||||
}
|
||||
|
||||
void SpinningCubeRenderer::SetColorFilter(DirectX::XMFLOAT4 color)
|
||||
{
|
||||
m_filterColorData = color;
|
||||
}
|
||||
|
||||
// This function uses a point and a vector to position the world-locked hologram
|
||||
// two meters in front of the user's heading.
|
||||
void SpinningCubeRenderer::PositionHologram(
|
||||
winrt::Windows::Foundation::Numerics::float3 headPosition, winrt::Windows::Foundation::Numerics::float3 headDirection)
|
||||
{
|
||||
// The hologram is positioned two meters along the user's gaze direction.
|
||||
static const float distanceFromUser = 2.0f; // meters
|
||||
const auto gazeAtTwoMeters = headPosition + (distanceFromUser * headDirection);
|
||||
|
||||
// This will be used as the translation component of the hologram's
|
||||
// model transform.
|
||||
SetPosition(gazeAtTwoMeters);
|
||||
}
|
||||
|
||||
// Called once per frame. Rotates the cube, and calculates and sets the model matrix
|
||||
// relative to the position transform indicated by hologramPositionTransform.
|
||||
void SpinningCubeRenderer::Update(
|
||||
float totalSeconds,
|
||||
winrt::Windows::Perception::PerceptionTimestamp timestamp,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem)
|
||||
{
|
||||
// Rotate the cube.
|
||||
// Convert degrees to radians, then convert seconds to rotation angle.
|
||||
const float radiansPerSecond = XMConvertToRadians(m_degreesPerSecond);
|
||||
const double relativeRotation = totalSeconds * radiansPerSecond;
|
||||
double totalRotation = m_rotationOffset;
|
||||
|
||||
switch (m_pauseState)
|
||||
{
|
||||
case PauseState::Unpaused:
|
||||
totalRotation += relativeRotation;
|
||||
break;
|
||||
|
||||
case PauseState::Pausing:
|
||||
m_rotationOffset += relativeRotation;
|
||||
m_pauseState = PauseState::Paused;
|
||||
case PauseState::Paused:
|
||||
totalRotation = m_rotationOffset;
|
||||
break;
|
||||
|
||||
case PauseState::Unpausing:
|
||||
m_rotationOffset -= relativeRotation;
|
||||
m_pauseState = PauseState::Unpaused;
|
||||
break;
|
||||
}
|
||||
const float radians = static_cast<float>(fmod(totalRotation, XM_2PI));
|
||||
const XMMATRIX modelRotation = XMMatrixRotationY(-radians);
|
||||
|
||||
{
|
||||
// Position the cube.
|
||||
const XMMATRIX modelTranslation = XMMatrixTranslationFromVector(XMLoadFloat3(&m_position));
|
||||
|
||||
// Multiply to get the transform matrix.
|
||||
// Note that this transform does not enforce a particular coordinate system. The calling
|
||||
// class is responsible for rendering this content in a consistent manner.
|
||||
const XMMATRIX modelTransform = XMMatrixMultiply(modelRotation, modelTranslation);
|
||||
|
||||
// Store the normal transform.
|
||||
XMStoreFloat4x4(&m_modelConstantBufferData.normal, XMMatrixTranspose(modelRotation));
|
||||
|
||||
// The view and projection matrices are provided by the system; they are associated
|
||||
// with holographic cameras, and updated on a per-camera basis.
|
||||
// Here, we provide the model transform for the sample hologram. The model transform
|
||||
// matrix is transposed to prepare it for the shader.
|
||||
XMStoreFloat4x4(&m_modelConstantBufferData.model, XMMatrixTranspose(modelTransform));
|
||||
}
|
||||
|
||||
// Loading is asynchronous. Resources must be created before they can be updated.
|
||||
if (!m_loadingComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the D3D device context to update Direct3D device-based resources.
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
// Update the model transform buffer for the hologram.
|
||||
context->UpdateSubresource(m_modelConstantBuffer.get(), 0, nullptr, &(m_modelConstantBufferData), 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
// Renders one frame using the vertex and pixel shaders.
|
||||
// On devices that do not support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature,
|
||||
// a pass-through geometry shader is also used to set the render
|
||||
// target array index.
|
||||
void SpinningCubeRenderer::Render(bool isStereo)
|
||||
{
|
||||
// Loading is asynchronous. Resources must be created before drawing can occur.
|
||||
if (!m_loadingComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_deviceResources->UseD3DDeviceContext([&](auto context) {
|
||||
ID3D11Buffer* pBufferToSet = nullptr;
|
||||
|
||||
// Each vertex is one instance of the VertexPositionColor struct.
|
||||
const UINT stride = sizeof(VertexPositionNormalColor);
|
||||
const UINT offset = 0;
|
||||
|
||||
pBufferToSet = m_vertexBuffer.get();
|
||||
context->IASetVertexBuffers(0, 1, &pBufferToSet, &stride, &offset);
|
||||
context->IASetIndexBuffer(
|
||||
m_indexBuffer.get(),
|
||||
DXGI_FORMAT_R16_UINT, // Each index is one 16-bit unsigned integer (short).
|
||||
0);
|
||||
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
context->IASetInputLayout(m_inputLayout.get());
|
||||
|
||||
// Attach the vertex shader.
|
||||
context->VSSetShader(m_vertexShader.get(), nullptr, 0);
|
||||
// Apply the model constant buffer to the vertex shader.
|
||||
pBufferToSet = m_modelConstantBuffer.get();
|
||||
context->VSSetConstantBuffers(0, 1, &pBufferToSet);
|
||||
|
||||
if (!m_usingVprtShaders)
|
||||
{
|
||||
// On devices that do not support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature,
|
||||
// a pass-through geometry shader is used to set the render target
|
||||
// array index.
|
||||
context->GSSetShader(m_geometryShader.get(), nullptr, 0);
|
||||
}
|
||||
|
||||
context->UpdateSubresource(m_filterColorBuffer.get(), 0, nullptr, &m_filterColorData, 0, 0);
|
||||
|
||||
pBufferToSet = m_filterColorBuffer.get();
|
||||
context->PSSetConstantBuffers(2, 1, &pBufferToSet);
|
||||
|
||||
// Attach the pixel shader.
|
||||
context->PSSetShader(m_pixelShader.get(), nullptr, 0);
|
||||
|
||||
// Draw the objects.
|
||||
context->DrawIndexedInstanced(
|
||||
m_indexCount, // Index count per instance.
|
||||
isStereo ? 2 : 1, // Instance count.
|
||||
0, // Start index location.
|
||||
0, // Base vertex location.
|
||||
0 // Start instance location.
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
std::future<void> SpinningCubeRenderer::CreateDeviceDependentResources()
|
||||
{
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
std::wstring fileNamePrefix = L"";
|
||||
#else
|
||||
std::wstring fileNamePrefix = L"ms-appx:///";
|
||||
#endif
|
||||
|
||||
m_usingVprtShaders = m_deviceResources->GetDeviceSupportsVprt();
|
||||
|
||||
// On devices that do support the D3D11_FEATURE_D3D11_OPTIONS3::
|
||||
// VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature
|
||||
// we can avoid using a pass-through geometry shader to set the render
|
||||
// target array index, thus avoiding any overhead that would be
|
||||
// incurred by setting the geometry shader stage.
|
||||
|
||||
std::wstring vertexShaderFileName = m_usingVprtShaders ? L"hsa_VprtVertexShader.cso" : L"hsa_VertexShader.cso";
|
||||
|
||||
std::vector<byte> vertexShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + vertexShaderFileName);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateVertexShader(
|
||||
vertexShaderFileData.data(), vertexShaderFileData.size(), nullptr, m_vertexShader.put()));
|
||||
|
||||
constexpr std::array<D3D11_INPUT_ELEMENT_DESC, 3> vertexDesc = {{
|
||||
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
}};
|
||||
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateInputLayout(
|
||||
vertexDesc.data(),
|
||||
static_cast<UINT>(vertexDesc.size()),
|
||||
vertexShaderFileData.data(),
|
||||
static_cast<UINT>(vertexShaderFileData.size()),
|
||||
m_inputLayout.put()));
|
||||
|
||||
std::vector<byte> pixelShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + L"hsa_PixelShader.cso");
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreatePixelShader(
|
||||
pixelShaderFileData.data(), pixelShaderFileData.size(), nullptr, m_pixelShader.put()));
|
||||
|
||||
const ModelConstantBuffer constantBuffer{
|
||||
reinterpret_cast<DirectX::XMFLOAT4X4&>(winrt::Windows::Foundation::Numerics::float4x4::identity()),
|
||||
reinterpret_cast<DirectX::XMFLOAT4X4&>(winrt::Windows::Foundation::Numerics::float4x4::identity()),
|
||||
};
|
||||
|
||||
const CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&constantBufferDesc, nullptr, m_modelConstantBuffer.put()));
|
||||
|
||||
const CD3D11_BUFFER_DESC filterColorBufferDesc(sizeof(XMFLOAT4), D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&filterColorBufferDesc, nullptr, m_filterColorBuffer.put()));
|
||||
|
||||
if (!m_usingVprtShaders)
|
||||
{
|
||||
// Load the pass-through geometry shader.
|
||||
std::vector<byte> geometryShaderFileData = co_await DXHelper::ReadDataAsync(fileNamePrefix + L"hsa_GeometryShader.cso");
|
||||
|
||||
// After the pass-through geometry shader file is loaded, create the shader.
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateGeometryShader(
|
||||
geometryShaderFileData.data(), geometryShaderFileData.size(), nullptr, m_geometryShader.put()));
|
||||
}
|
||||
|
||||
// Load mesh vertices. Each vertex has a position and a color.
|
||||
// Note that the cube size has changed from the default DirectX app
|
||||
// template. Windows Holographic is scaled in meters, so to draw the
|
||||
// cube at a comfortable size we made the cube width 0.2 m (20 cm).
|
||||
static const VertexPositionNormalColor cubeVertices[] = {
|
||||
{XMFLOAT3(-0.1f, -0.1f, -0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f)}, // vertex 0 non-debug
|
||||
{XMFLOAT3(-0.1f, -0.1f, 0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(0.0f, 0.0f, 1.0f)},
|
||||
{XMFLOAT3(-0.1f, 0.1f, -0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 0.0f)},
|
||||
{XMFLOAT3(-0.1f, 0.1f, 0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(0.0f, 1.0f, 1.0f)},
|
||||
{XMFLOAT3(0.1f, -0.1f, -0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 0.0f)},
|
||||
{XMFLOAT3(0.1f, -0.1f, 0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(1.0f, 0.0f, 1.0f)},
|
||||
{XMFLOAT3(0.1f, 0.1f, -0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(1.0f, 1.0f, 0.0f)},
|
||||
{XMFLOAT3(0.1f, 0.1f, 0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(1.0f, 1.0f, 1.0f)},
|
||||
};
|
||||
|
||||
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
|
||||
vertexBufferData.pSysMem = cubeVertices;
|
||||
vertexBufferData.SysMemPitch = 0;
|
||||
vertexBufferData.SysMemSlicePitch = 0;
|
||||
const CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(cubeVertices), D3D11_BIND_VERTEX_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&vertexBufferDesc, &vertexBufferData, m_vertexBuffer.put()));
|
||||
|
||||
// Load mesh indices. Each trio of indices represents
|
||||
// a triangle to be rendered on the screen.
|
||||
// For example: 2,1,0 means that the vertices with indexes
|
||||
// 2, 1, and 0 from the vertex buffer compose the
|
||||
// first triangle of this mesh.
|
||||
// Note that the winding order is clockwise by default.
|
||||
static const unsigned short cubeIndices[] = {
|
||||
2, 1, 0, // -x
|
||||
2, 3, 1,
|
||||
|
||||
6, 4, 5, // +x
|
||||
6, 5, 7,
|
||||
|
||||
0, 1, 5, // -y
|
||||
0, 5, 4,
|
||||
|
||||
2, 6, 7, // +y
|
||||
2, 7, 3,
|
||||
|
||||
0, 4, 6, // -z
|
||||
0, 6, 2,
|
||||
|
||||
1, 3, 7, // +z
|
||||
1, 7, 5,
|
||||
};
|
||||
|
||||
m_indexCount = ARRAYSIZE(cubeIndices);
|
||||
|
||||
D3D11_SUBRESOURCE_DATA indexBufferData = {0};
|
||||
indexBufferData.pSysMem = cubeIndices;
|
||||
indexBufferData.SysMemPitch = 0;
|
||||
indexBufferData.SysMemSlicePitch = 0;
|
||||
const CD3D11_BUFFER_DESC indexBufferDesc(sizeof(cubeIndices), D3D11_BIND_INDEX_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(&indexBufferDesc, &indexBufferData, m_indexBuffer.put()));
|
||||
|
||||
// Once everything is loaded, the object is ready to be rendered.
|
||||
m_loadingComplete = true;
|
||||
}
|
||||
|
||||
void SpinningCubeRenderer::ReleaseDeviceDependentResources()
|
||||
{
|
||||
m_loadingComplete = false;
|
||||
m_usingVprtShaders = false;
|
||||
m_vertexShader = nullptr;
|
||||
m_inputLayout = nullptr;
|
||||
m_pixelShader = nullptr;
|
||||
m_geometryShader = nullptr;
|
||||
m_modelConstantBuffer = nullptr;
|
||||
m_vertexBuffer = nullptr;
|
||||
m_indexBuffer = nullptr;
|
||||
m_filterColorBuffer = nullptr;
|
||||
}
|
||||
|
||||
void SpinningCubeRenderer::CreateWindowSizeDependentResources()
|
||||
{
|
||||
}
|
||||
|
||||
void SpinningCubeRenderer::TogglePauseState()
|
||||
{
|
||||
if (m_pauseState == PauseState::Paused)
|
||||
{
|
||||
m_pauseState = PauseState::Unpausing;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pauseState = PauseState::Pausing;
|
||||
}
|
||||
}
|
|
@ -1,93 +1,100 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "..\Common\DeviceResources.h"
|
||||
#include "ShaderStructures.h"
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
// This sample renderer instantiates a basic rendering pipeline.
|
||||
class SpinningCubeRenderer
|
||||
{
|
||||
public:
|
||||
SpinningCubeRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources);
|
||||
void CreateWindowSizeDependentResources();
|
||||
std::future<void> CreateDeviceDependentResources();
|
||||
void ReleaseDeviceDependentResources();
|
||||
void Update(float totalSeconds);
|
||||
void SetColorFilter(DirectX::XMFLOAT4 color);
|
||||
void Render(bool isStereo);
|
||||
|
||||
// Repositions the sample hologram.
|
||||
void PositionHologram(const winrt::Windows::UI::Input::Spatial::SpatialPointerPose& pointerPose);
|
||||
|
||||
// Repositions the sample hologram, using direct measures.
|
||||
void PositionHologram(winrt::Windows::Foundation::Numerics::float3 pos, winrt::Windows::Foundation::Numerics::float3 dir);
|
||||
|
||||
// Property accessors.
|
||||
void SetPosition(winrt::Windows::Foundation::Numerics::float3 pos)
|
||||
{
|
||||
m_position = pos;
|
||||
}
|
||||
const winrt::Windows::Foundation::Numerics::float3& GetPosition()
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
void Pause()
|
||||
{
|
||||
m_pauseState = PauseState::Pausing;
|
||||
}
|
||||
void Unpause()
|
||||
{
|
||||
m_pauseState = PauseState::Unpausing;
|
||||
}
|
||||
void TogglePauseState();
|
||||
|
||||
private:
|
||||
enum class PauseState
|
||||
{
|
||||
Unpaused = 0,
|
||||
Pausing,
|
||||
Paused,
|
||||
Unpausing,
|
||||
};
|
||||
|
||||
// Cached pointer to device resources.
|
||||
std::shared_ptr<DXHelper::DeviceResources> m_deviceResources;
|
||||
|
||||
// Direct3D resources for cube geometry.
|
||||
winrt::com_ptr<ID3D11InputLayout> m_inputLayout;
|
||||
winrt::com_ptr<ID3D11Buffer> m_vertexBuffer;
|
||||
winrt::com_ptr<ID3D11Buffer> m_indexBuffer;
|
||||
winrt::com_ptr<ID3D11VertexShader> m_vertexShader;
|
||||
winrt::com_ptr<ID3D11GeometryShader> m_geometryShader;
|
||||
winrt::com_ptr<ID3D11PixelShader> m_pixelShader;
|
||||
winrt::com_ptr<ID3D11Buffer> m_modelConstantBuffer;
|
||||
winrt::com_ptr<ID3D11Buffer> m_filterColorBuffer;
|
||||
|
||||
// System resources for cube geometry.
|
||||
ModelConstantBuffer m_modelConstantBufferData;
|
||||
uint32_t m_indexCount = 0;
|
||||
DirectX::XMFLOAT4 m_filterColorData = {1, 1, 1, 1};
|
||||
|
||||
// Variables used with the rendering loop.
|
||||
bool m_loadingComplete = false;
|
||||
float m_degreesPerSecond = 180.0f;
|
||||
winrt::Windows::Foundation::Numerics::float3 m_position = {0.0f, 0.0f, -2.0f};
|
||||
PauseState m_pauseState = PauseState::Unpaused;
|
||||
double m_rotationOffset = 0;
|
||||
|
||||
// If the current D3D Device supports VPRT, we can avoid using a geometry
|
||||
// shader just to set the render target array index.
|
||||
bool m_usingVprtShaders = false;
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Common/DeviceResources.h>
|
||||
#include <Content/ShaderStructures.h>
|
||||
|
||||
#include <winrt/Windows.UI.Input.Spatial.h>
|
||||
|
||||
#include <future>
|
||||
|
||||
// This sample renderer instantiates a basic rendering pipeline.
|
||||
class SpinningCubeRenderer
|
||||
{
|
||||
public:
|
||||
SpinningCubeRenderer(const std::shared_ptr<DXHelper::DeviceResources>& deviceResources);
|
||||
|
||||
void CreateWindowSizeDependentResources();
|
||||
std::future<void> CreateDeviceDependentResources();
|
||||
void ReleaseDeviceDependentResources();
|
||||
void Update(
|
||||
float totalSeconds,
|
||||
winrt::Windows::Perception::PerceptionTimestamp timestamp,
|
||||
winrt::Windows::Perception::Spatial::SpatialCoordinateSystem renderingCoordinateSystem);
|
||||
void SetColorFilter(DirectX::XMFLOAT4 color);
|
||||
void Render(bool isStereo);
|
||||
|
||||
// Repositions the sample hologram.
|
||||
void PositionHologram(const winrt::Windows::UI::Input::Spatial::SpatialPointerPose& pointerPose);
|
||||
|
||||
// Repositions the sample hologram, using direct measures.
|
||||
void PositionHologram(winrt::Windows::Foundation::Numerics::float3 pos, winrt::Windows::Foundation::Numerics::float3 dir);
|
||||
|
||||
// Property accessors.
|
||||
void SetPosition(winrt::Windows::Foundation::Numerics::float3 pos)
|
||||
{
|
||||
m_position = pos;
|
||||
}
|
||||
const winrt::Windows::Foundation::Numerics::float3& GetPosition()
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
void Pause()
|
||||
{
|
||||
m_pauseState = PauseState::Pausing;
|
||||
}
|
||||
void Unpause()
|
||||
{
|
||||
m_pauseState = PauseState::Unpausing;
|
||||
}
|
||||
void TogglePauseState();
|
||||
|
||||
private:
|
||||
enum class PauseState
|
||||
{
|
||||
Unpaused = 0,
|
||||
Pausing,
|
||||
Paused,
|
||||
Unpausing,
|
||||
};
|
||||
|
||||
// Cached pointer to device resources.
|
||||
std::shared_ptr<DXHelper::DeviceResources> m_deviceResources;
|
||||
|
||||
// Direct3D resources for cube geometry.
|
||||
winrt::com_ptr<ID3D11InputLayout> m_inputLayout;
|
||||
winrt::com_ptr<ID3D11Buffer> m_vertexBuffer;
|
||||
winrt::com_ptr<ID3D11Buffer> m_indexBuffer;
|
||||
winrt::com_ptr<ID3D11VertexShader> m_vertexShader;
|
||||
winrt::com_ptr<ID3D11GeometryShader> m_geometryShader;
|
||||
winrt::com_ptr<ID3D11PixelShader> m_pixelShader;
|
||||
winrt::com_ptr<ID3D11Buffer> m_modelConstantBuffer;
|
||||
winrt::com_ptr<ID3D11Buffer> m_filterColorBuffer;
|
||||
|
||||
// System resources for cube geometry.
|
||||
ModelConstantBuffer m_modelConstantBufferData;
|
||||
uint32_t m_indexCount = 0;
|
||||
DirectX::XMFLOAT4 m_filterColorData = {1, 1, 1, 1};
|
||||
|
||||
// Variables used with the rendering loop.
|
||||
bool m_loadingComplete = false;
|
||||
float m_degreesPerSecond = 180.0f;
|
||||
winrt::Windows::Foundation::Numerics::float3 m_position = {0.0f, 0.0f, -2.0f};
|
||||
PauseState m_pauseState = PauseState::Unpaused;
|
||||
double m_rotationOffset = 0;
|
||||
|
||||
// If the current D3D Device supports VPRT, we can avoid using a geometry
|
||||
// shader just to set the render target array index.
|
||||
bool m_usingVprtShaders = false;
|
||||
};
|
|
@ -1,44 +1,44 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// Per-vertex data from the vertex shader.
|
||||
struct GeometryShaderInput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint instId : TEXCOORD0;
|
||||
};
|
||||
|
||||
// Per-vertex data passed to the rasterizer.
|
||||
struct GeometryShaderOutput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint idx : TEXCOORD0;
|
||||
uint rtvId : SV_RenderTargetArrayIndex;
|
||||
};
|
||||
|
||||
// This geometry shader is a pass-through that leaves the geometry unmodified
|
||||
// and sets the render target array index.
|
||||
[maxvertexcount(3)]
|
||||
void main(triangle GeometryShaderInput input[3], inout TriangleStream<GeometryShaderOutput> outStream)
|
||||
{
|
||||
GeometryShaderOutput output;
|
||||
[unroll(3)]
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
output.pos = input[i].pos;
|
||||
output.color = input[i].color;
|
||||
output.idx = input[i].instId;
|
||||
output.rtvId = input[i].instId;
|
||||
outStream.Append(output);
|
||||
}
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// Per-vertex data from the vertex shader.
|
||||
struct GeometryShaderInput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint instId : TEXCOORD0;
|
||||
};
|
||||
|
||||
// Per-vertex data passed to the rasterizer.
|
||||
struct GeometryShaderOutput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint idx : TEXCOORD0;
|
||||
uint rtvId : SV_RenderTargetArrayIndex;
|
||||
};
|
||||
|
||||
// This geometry shader is a pass-through that leaves the geometry unmodified
|
||||
// and sets the render target array index.
|
||||
[maxvertexcount(3)]
|
||||
void main(triangle GeometryShaderInput input[3], inout TriangleStream<GeometryShaderOutput> outStream)
|
||||
{
|
||||
GeometryShaderOutput output;
|
||||
[unroll(3)]
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
output.pos = input[i].pos;
|
||||
output.color = input[i].color;
|
||||
output.idx = input[i].instId;
|
||||
output.rtvId = input[i].instId;
|
||||
outStream.Append(output);
|
||||
}
|
||||
}
|
|
@ -1,42 +1,42 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// A constant buffer that stores the model transform.
|
||||
cbuffer ModelConstantBuffer : register(b0)
|
||||
{
|
||||
float4x4 model;
|
||||
float4x4 normal;
|
||||
};
|
||||
|
||||
// A constant buffer that stores each set of view and projection matrices in column-major format.
|
||||
cbuffer ViewProjectionConstantBuffer : register(b1)
|
||||
{
|
||||
float4x4 viewProjection[2];
|
||||
};
|
||||
|
||||
cbuffer ColorFilterConstantBuffer : register(b2)
|
||||
{
|
||||
float4 colorFilter;
|
||||
};
|
||||
|
||||
// Per-pixel color data passed through the pixel shader.
|
||||
struct PixelShaderInput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint idx : TEXCOORD0;
|
||||
};
|
||||
|
||||
// The pixel shader applies Blinn-Phong BRDF shading.
|
||||
min16float4 main(PixelShaderInput input) : SV_TARGET
|
||||
{
|
||||
return min16float4(input.color, 1.f) * min16float4(colorFilter);
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// A constant buffer that stores the model transform.
|
||||
cbuffer ModelConstantBuffer : register(b0)
|
||||
{
|
||||
float4x4 model;
|
||||
float4x4 normal;
|
||||
};
|
||||
|
||||
// A constant buffer that stores each set of view and projection matrices in column-major format.
|
||||
cbuffer ViewProjectionConstantBuffer : register(b1)
|
||||
{
|
||||
float4x4 viewProjection[2];
|
||||
};
|
||||
|
||||
cbuffer ColorFilterConstantBuffer : register(b2)
|
||||
{
|
||||
float4 colorFilter;
|
||||
};
|
||||
|
||||
// Per-pixel color data passed through the pixel shader.
|
||||
struct PixelShaderInput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint idx : TEXCOORD0;
|
||||
};
|
||||
|
||||
// The pixel shader applies Blinn-Phong BRDF shading.
|
||||
min16float4 main(PixelShaderInput input) : SV_TARGET
|
||||
{
|
||||
return min16float4(input.color, 1.f) * min16float4(colorFilter);
|
||||
}
|
|
@ -1,48 +1,48 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// Per-vertex data from the vertex shader.
|
||||
struct GeometryShaderInput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
uint instId : TEXCOORD1;
|
||||
};
|
||||
|
||||
// Per-vertex data passed to the rasterizer.
|
||||
struct GeometryShaderOutput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float3 barycentricCoords : TEXCOORD0;
|
||||
uint rtvId : SV_RenderTargetArrayIndex;
|
||||
};
|
||||
|
||||
// This geometry shader is a pass-through that leaves the geometry unmodified
|
||||
// and sets the render target array index.
|
||||
[maxvertexcount(3)]
|
||||
void main(triangle GeometryShaderInput input[3], inout TriangleStream<GeometryShaderOutput> outStream)
|
||||
{
|
||||
static const float3 barycentricVectors[3] = {
|
||||
float3(1.0f, 0.0f, 0.0f),
|
||||
float3(0.0f, 1.0f, 0.0f),
|
||||
float3(0.0f, 0.0f, 1.0f)
|
||||
};
|
||||
|
||||
GeometryShaderOutput output;
|
||||
[unroll(3)]
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
output.pos = input[i].pos;
|
||||
output.barycentricCoords = barycentricVectors[i];
|
||||
output.rtvId = input[i].instId;
|
||||
|
||||
outStream.Append(output);
|
||||
}
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// Per-vertex data from the vertex shader.
|
||||
struct GeometryShaderInput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
uint instId : TEXCOORD1;
|
||||
};
|
||||
|
||||
// Per-vertex data passed to the rasterizer.
|
||||
struct GeometryShaderOutput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float3 barycentricCoords : TEXCOORD0;
|
||||
uint rtvId : SV_RenderTargetArrayIndex;
|
||||
};
|
||||
|
||||
// This geometry shader is a pass-through that leaves the geometry unmodified
|
||||
// and sets the render target array index.
|
||||
[maxvertexcount(3)]
|
||||
void main(triangle GeometryShaderInput input[3], inout TriangleStream<GeometryShaderOutput> outStream)
|
||||
{
|
||||
static const float3 barycentricVectors[3] = {
|
||||
float3(1.0f, 0.0f, 0.0f),
|
||||
float3(0.0f, 1.0f, 0.0f),
|
||||
float3(0.0f, 0.0f, 1.0f)
|
||||
};
|
||||
|
||||
GeometryShaderOutput output;
|
||||
[unroll(3)]
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
output.pos = input[i].pos;
|
||||
output.barycentricCoords = barycentricVectors[i];
|
||||
output.rtvId = input[i].instId;
|
||||
|
||||
outStream.Append(output);
|
||||
}
|
||||
}
|
|
@ -1,36 +1,36 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// Per-pixel color data passed through the pixel shader.
|
||||
struct PixelShaderInput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float3 barycentricCoords : TEXCOORD0;
|
||||
};
|
||||
|
||||
#define LINE_WIDTH 2.0
|
||||
|
||||
float edgeFactor(float3 coords)
|
||||
{
|
||||
float3 d = fwidth(coords);
|
||||
float3 a3 = smoothstep(0.0, d*LINE_WIDTH, coords);
|
||||
return min(min(a3.x, a3.y), a3.z);
|
||||
}
|
||||
|
||||
// The pixel shader passes through the color data. The color data from
|
||||
// is interpolated and assigned to a pixel at the rasterization step.
|
||||
float4 main(PixelShaderInput input) : SV_TARGET
|
||||
{
|
||||
float lineBrightness = 1.0f - edgeFactor(input.barycentricCoords);
|
||||
float4 result = float4(0.25, 0.25, 0.25, 1.0);
|
||||
result.xyz *= lineBrightness;
|
||||
return result;
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// Per-pixel color data passed through the pixel shader.
|
||||
struct PixelShaderInput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
float3 barycentricCoords : TEXCOORD0;
|
||||
};
|
||||
|
||||
#define LINE_WIDTH 2.0
|
||||
|
||||
float edgeFactor(float3 coords)
|
||||
{
|
||||
float3 d = fwidth(coords);
|
||||
float3 a3 = smoothstep(0.0, d*LINE_WIDTH, coords);
|
||||
return min(min(a3.x, a3.y), a3.z);
|
||||
}
|
||||
|
||||
// The pixel shader passes through the color data. The color data from
|
||||
// is interpolated and assigned to a pixel at the rasterization step.
|
||||
float4 main(PixelShaderInput input) : SV_TARGET
|
||||
{
|
||||
float lineBrightness = 1.0f - edgeFactor(input.barycentricCoords);
|
||||
float4 result = float4(0.25, 0.25, 0.25, 1.0);
|
||||
result.xyz *= lineBrightness;
|
||||
return result;
|
||||
}
|
|
@ -1,64 +1,64 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// A constant buffer that stores the model transform.
|
||||
cbuffer SRMeshConstantBuffer : register(b0)
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
|
||||
// A constant buffer that stores each set of view and projection matrices in column-major format.
|
||||
cbuffer ViewProjectionConstantBuffer : register(b1)
|
||||
{
|
||||
float4x4 viewProjection[2];
|
||||
};
|
||||
|
||||
// Per-vertex data used as input to the vertex shader.
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float4 pos : POSITION;
|
||||
uint instId : SV_InstanceID;
|
||||
};
|
||||
|
||||
// Per-vertex data passed to the geometry shader.
|
||||
// Note that the render target array index will be set by the geometry shader
|
||||
// using the value of viewId.
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
uint viewId : TEXCOORD1; // SV_InstanceID % 2
|
||||
};
|
||||
|
||||
// Simple shader to do vertex processing on the GPU.
|
||||
VertexShaderOutput main(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
float4 pos = float4(input.pos.xyz, 1.0f);
|
||||
|
||||
// Note which view this vertex has been sent to. Used for matrix lookup.
|
||||
// Taking the modulo of the instance ID allows geometry instancing to be used
|
||||
// along with stereo instanced drawing; in that case, two copies of each
|
||||
// instance would be drawn, one for left and one for right.
|
||||
int idx = input.instId % 2;
|
||||
|
||||
// Transform the vertex position into world space.
|
||||
pos = mul(pos, model);
|
||||
|
||||
// Correct for perspective and project the vertex position onto the screen.
|
||||
pos = mul(pos, viewProjection[idx]);
|
||||
output.pos = pos;
|
||||
|
||||
// Set the instance ID. The pass-through geometry shader will set the
|
||||
// render target array index to whatever value is set here.
|
||||
output.viewId = idx;
|
||||
|
||||
return output;
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// A constant buffer that stores the model transform.
|
||||
cbuffer SRMeshConstantBuffer : register(b0)
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
|
||||
// A constant buffer that stores each set of view and projection matrices in column-major format.
|
||||
cbuffer ViewProjectionConstantBuffer : register(b1)
|
||||
{
|
||||
float4x4 viewProjection[2];
|
||||
};
|
||||
|
||||
// Per-vertex data used as input to the vertex shader.
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float4 pos : POSITION;
|
||||
uint instId : SV_InstanceID;
|
||||
};
|
||||
|
||||
// Per-vertex data passed to the geometry shader.
|
||||
// Note that the render target array index will be set by the geometry shader
|
||||
// using the value of viewId.
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
uint viewId : TEXCOORD1; // SV_InstanceID % 2
|
||||
};
|
||||
|
||||
// Simple shader to do vertex processing on the GPU.
|
||||
VertexShaderOutput main(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
float4 pos = float4(input.pos.xyz, 1.0f);
|
||||
|
||||
// Note which view this vertex has been sent to. Used for matrix lookup.
|
||||
// Taking the modulo of the instance ID allows geometry instancing to be used
|
||||
// along with stereo instanced drawing; in that case, two copies of each
|
||||
// instance would be drawn, one for left and one for right.
|
||||
int idx = input.instId % 2;
|
||||
|
||||
// Transform the vertex position into world space.
|
||||
pos = mul(pos, model);
|
||||
|
||||
// Correct for perspective and project the vertex position onto the screen.
|
||||
pos = mul(pos, viewProjection[idx]);
|
||||
output.pos = pos;
|
||||
|
||||
// Set the instance ID. The pass-through geometry shader will set the
|
||||
// render target array index to whatever value is set here.
|
||||
output.viewId = idx;
|
||||
|
||||
return output;
|
||||
}
|
|
@ -1,72 +1,72 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// A constant buffer that stores the model transform.
|
||||
cbuffer ModelConstantBuffer : register(b0)
|
||||
{
|
||||
float4x4 model;
|
||||
float4x4 normal;
|
||||
};
|
||||
|
||||
// A constant buffer that stores each set of view and projection matrices in column-major format.
|
||||
cbuffer ViewProjectionConstantBuffer : register(b1)
|
||||
{
|
||||
float4x4 viewProjection[2];
|
||||
};
|
||||
|
||||
// Per-vertex data used as input to the vertex shader.
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float3 pos : POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint instId : SV_InstanceID;
|
||||
};
|
||||
|
||||
// Per-vertex data passed to the geometry shader.
|
||||
// Note that the render target array index is set here in the vertex shader.
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint idx : TEXCOORD0;
|
||||
uint rtvId : SV_RenderTargetArrayIndex; // SV_InstanceID % 2
|
||||
};
|
||||
|
||||
// Simple shader to do vertex processing on the GPU.
|
||||
VertexShaderOutput main(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
float4 pos = float4(input.pos, 1.0f);
|
||||
|
||||
// Note which view this vertex has been sent to. Used for matrix lookup.
|
||||
// Taking the modulo of the instance ID allows geometry instancing to be used
|
||||
// along with stereo instanced drawing; in that case, two copies of each
|
||||
// instance would be drawn, one for left and one for right.
|
||||
int idx = input.instId % 2;
|
||||
|
||||
// Transform the vertex position into world space.
|
||||
pos = mul(pos, model);
|
||||
|
||||
// Correct for perspective and project the vertex position onto the screen.
|
||||
pos = mul(pos, viewProjection[idx]);
|
||||
|
||||
// Write minimum-precision floating-point data.
|
||||
output.pos = pos;
|
||||
|
||||
// Pass the color through without modification.
|
||||
output.color = input.color;
|
||||
|
||||
// Set the render target array index.
|
||||
output.rtvId = idx;
|
||||
output.idx = idx;
|
||||
|
||||
return output;
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// A constant buffer that stores the model transform.
|
||||
cbuffer ModelConstantBuffer : register(b0)
|
||||
{
|
||||
float4x4 model;
|
||||
float4x4 normal;
|
||||
};
|
||||
|
||||
// A constant buffer that stores each set of view and projection matrices in column-major format.
|
||||
cbuffer ViewProjectionConstantBuffer : register(b1)
|
||||
{
|
||||
float4x4 viewProjection[2];
|
||||
};
|
||||
|
||||
// Per-vertex data used as input to the vertex shader.
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float3 pos : POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint instId : SV_InstanceID;
|
||||
};
|
||||
|
||||
// Per-vertex data passed to the geometry shader.
|
||||
// Note that the render target array index is set here in the vertex shader.
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint idx : TEXCOORD0;
|
||||
uint rtvId : SV_RenderTargetArrayIndex; // SV_InstanceID % 2
|
||||
};
|
||||
|
||||
// Simple shader to do vertex processing on the GPU.
|
||||
VertexShaderOutput main(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
float4 pos = float4(input.pos, 1.0f);
|
||||
|
||||
// Note which view this vertex has been sent to. Used for matrix lookup.
|
||||
// Taking the modulo of the instance ID allows geometry instancing to be used
|
||||
// along with stereo instanced drawing; in that case, two copies of each
|
||||
// instance would be drawn, one for left and one for right.
|
||||
int idx = input.instId % 2;
|
||||
|
||||
// Transform the vertex position into world space.
|
||||
pos = mul(pos, model);
|
||||
|
||||
// Correct for perspective and project the vertex position onto the screen.
|
||||
pos = mul(pos, viewProjection[idx]);
|
||||
|
||||
// Write minimum-precision floating-point data.
|
||||
output.pos = pos;
|
||||
|
||||
// Pass the color through without modification.
|
||||
output.color = input.color;
|
||||
|
||||
// Set the render target array index.
|
||||
output.rtvId = idx;
|
||||
output.idx = idx;
|
||||
|
||||
return output;
|
||||
}
|
|
@ -1,72 +1,72 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// A constant buffer that stores the model transform.
|
||||
cbuffer ModelConstantBuffer : register(b0)
|
||||
{
|
||||
float4x4 model;
|
||||
float4x4 normal;
|
||||
};
|
||||
|
||||
// A constant buffer that stores each set of view and projection matrices in column-major format.
|
||||
cbuffer ViewProjectionConstantBuffer : register(b1)
|
||||
{
|
||||
float4x4 viewProjection[2];
|
||||
};
|
||||
|
||||
// Per-vertex data used as input to the vertex shader.
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float3 pos : POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint instId : SV_InstanceID;
|
||||
};
|
||||
|
||||
// Per-vertex data passed to the geometry shader.
|
||||
// Note that the render target array index will be set by the geometry shader
|
||||
// using the value of viewId.
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint viewId : TEXCOORD0; // SV_InstanceID % 2
|
||||
};
|
||||
|
||||
// Simple shader to do vertex processing on the GPU.
|
||||
VertexShaderOutput main(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
float4 pos = float4(input.pos, 1.0f);
|
||||
|
||||
// Note which view this vertex has been sent to. Used for matrix lookup.
|
||||
// Taking the modulo of the instance ID allows geometry instancing to be used
|
||||
// along with stereo instanced drawing; in that case, two copies of each
|
||||
// instance would be drawn, one for left and one for right.
|
||||
int idx = input.instId % 2;
|
||||
|
||||
// Transform the vertex position into world space.
|
||||
pos = mul(pos, model);
|
||||
|
||||
// Correct for perspective and project the vertex position onto the screen.
|
||||
pos = mul(pos, viewProjection[idx]);
|
||||
|
||||
// Write minimum-precision floating-point data.
|
||||
output.pos = pos;
|
||||
|
||||
// Pass the color through without modification.
|
||||
output.color = input.color;
|
||||
|
||||
// Set the instance ID. The pass-through geometry shader will set the
|
||||
// render target array index to whatever value is set here.
|
||||
output.viewId = idx;
|
||||
|
||||
return output;
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
// A constant buffer that stores the model transform.
|
||||
cbuffer ModelConstantBuffer : register(b0)
|
||||
{
|
||||
float4x4 model;
|
||||
float4x4 normal;
|
||||
};
|
||||
|
||||
// A constant buffer that stores each set of view and projection matrices in column-major format.
|
||||
cbuffer ViewProjectionConstantBuffer : register(b1)
|
||||
{
|
||||
float4x4 viewProjection[2];
|
||||
};
|
||||
|
||||
// Per-vertex data used as input to the vertex shader.
|
||||
struct VertexShaderInput
|
||||
{
|
||||
float3 pos : POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint instId : SV_InstanceID;
|
||||
};
|
||||
|
||||
// Per-vertex data passed to the geometry shader.
|
||||
// Note that the render target array index will be set by the geometry shader
|
||||
// using the value of viewId.
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint viewId : TEXCOORD0; // SV_InstanceID % 2
|
||||
};
|
||||
|
||||
// Simple shader to do vertex processing on the GPU.
|
||||
VertexShaderOutput main(VertexShaderInput input)
|
||||
{
|
||||
VertexShaderOutput output;
|
||||
float4 pos = float4(input.pos, 1.0f);
|
||||
|
||||
// Note which view this vertex has been sent to. Used for matrix lookup.
|
||||
// Taking the modulo of the instance ID allows geometry instancing to be used
|
||||
// along with stereo instanced drawing; in that case, two copies of each
|
||||
// instance would be drawn, one for left and one for right.
|
||||
int idx = input.instId % 2;
|
||||
|
||||
// Transform the vertex position into world space.
|
||||
pos = mul(pos, model);
|
||||
|
||||
// Correct for perspective and project the vertex position onto the screen.
|
||||
pos = mul(pos, viewProjection[idx]);
|
||||
|
||||
// Write minimum-precision floating-point data.
|
||||
output.pos = pos;
|
||||
|
||||
// Pass the color through without modification.
|
||||
output.color = input.color;
|
||||
|
||||
// Set the instance ID. The pass-through geometry shader will set the
|
||||
// render target array index to whatever value is set here.
|
||||
output.viewId = idx;
|
||||
|
||||
return output;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
|
||||
<Identity Name="b0cf2e39-8f6e-4238-b33a-868c9b1122ce" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="2.1.0.0" />
|
||||
<mp:PhoneIdentity PhoneProductId="b0cf2e39-8f6e-4238-b33a-868c9b1122ce" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Properties>
|
||||
<DisplayName>RemotingHostSample</DisplayName>
|
||||
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="SampleRemoteWindowUWPView">
|
||||
<uap:VisualElements DisplayName="RemotingHostSampleUWP" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="RemotingHostSampleUWP" BackgroundColor="transparent">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
|
||||
</uap:DefaultTile>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
<Capability Name="internetClientServer" />
|
||||
<Capability Name="privateNetworkClientServer" />
|
||||
<DeviceCapability Name="microphone" />
|
||||
<DeviceCapability Name="webcam" />
|
||||
</Capabilities>
|
||||
<Extensions>
|
||||
<!--Extension Category="windows.activatableClass.inProcessServer">
|
||||
<InProcessServer>
|
||||
<Path>SceneUnderstanding.dll</Path>
|
||||
<ActivatableClass ActivatableClassId="SceneUnderstanding.Transform" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="SceneUnderstanding.Id" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="SceneUnderstanding.QuadToolkit" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="SceneUnderstanding.SpatialCoordinateSystem" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="SceneUnderstanding.Quad" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="SceneUnderstanding.Toolkit" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="SceneUnderstanding.SpatialComponent" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="SceneUnderstanding.Component" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="SceneUnderstanding.Entity" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="SceneUnderstanding.Mesh" ThreadingModel="both" />
|
||||
<ActivatableClass ActivatableClassId="SceneUnderstanding.SceneProcessor" ThreadingModel="both" />
|
||||
</InProcessServer>
|
||||
</Extension-->
|
||||
</Extensions>
|
||||
</Package>
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29806.167
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleRemote", "SampleRemote.vcxproj", "{D22B424F-B259-356A-8E4C-4937C36E783E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
RelWithDebInfo|x64 = RelWithDebInfo|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D22B424F-B259-356A-8E4C-4937C36E783E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D22B424F-B259-356A-8E4C-4937C36E783E}.Debug|x64.Build.0 = Debug|x64
|
||||
{D22B424F-B259-356A-8E4C-4937C36E783E}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{D22B424F-B259-356A-8E4C-4937C36E783E}.Release|x64.ActiveCfg = Release|x64
|
||||
{D22B424F-B259-356A-8E4C-4937C36E783E}.Release|x64.Build.0 = Release|x64
|
||||
{D22B424F-B259-356A-8E4C-4937C36E783E}.Release|x64.Deploy.0 = Release|x64
|
||||
{D22B424F-B259-356A-8E4C-4937C36E783E}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
|
||||
{D22B424F-B259-356A-8E4C-4937C36E783E}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
|
||||
{D22B424F-B259-356A-8E4C-4937C36E783E}.RelWithDebInfo|x64.Deploy.0 = RelWithDebInfo|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E8A3A1EC-E636-40D6-9E3D-C22347CC8162}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -1,313 +1,320 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="RelWithDebInfo|x64">
|
||||
<Configuration>RelWithDebInfo</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{59F48F16-7CF3-36AB-AE6D-B56A9DA89747}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<Platform>x64</Platform>
|
||||
<ProjectName>HolographicHostSample</ProjectName>
|
||||
<VCProjectUpgraderObjectName>NoUpgrade</VCProjectUpgraderObjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<SpectreMitigation>Spectre</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="packages\Microsoft.Holographic.Remoting.2.0.14\build\native\Microsoft.Holographic.Remoting.targets" Condition="Exists('packages\Microsoft.Holographic.Remoting.2.0.14\build\native\Microsoft.Holographic.Remoting.targets')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">bin\Debug\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">HolographicHostSample.dir\Debug\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">HolographicHostSample</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.exe</TargetExt>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</GenerateManifest>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">bin\Release\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">HolographicHostSample.dir\Release\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">HolographicHostSample</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.exe</TargetExt>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">bin\RelWithDebInfo\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">HolographicHostSample.dir\RelWithDebInfo\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">HolographicHostSample</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">.exe</TargetExt>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">true</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">true</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /await</AdditionalOptions>
|
||||
<AdditionalUsingDirectories>$(VCIDEInstallDir)vcpackages;$(WindowsSDK_UnionMetadataPath)</AdditionalUsingDirectories>
|
||||
<AssemblerListingLocation>Debug/</AssemblerListingLocation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4503</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<UseFullPaths>false</UseFullPaths>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;ALLOW_INSECURE_RANDOM_DEVICE=1;UNICODE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WIN32;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_INTEL;RDBUILD_ARCH_INTEL_X64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;ALLOW_INSECURE_RANDOM_DEVICE=1;UNICODE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WIN32;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_INTEL;RDBUILD_ARCH_INTEL_X64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>
|
||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
||||
</Midl>
|
||||
<Link>
|
||||
<AdditionalDependencies>d2d1.lib;d3d11.lib;dxgi.lib;dwrite.lib;windowscodecs.lib;pathcch.lib;Mswsock.lib;mfreadwrite.lib;Mfplat.lib;mfuuid.lib;ntdll.lib;Secur32.lib;crypt32.lib;secur32.lib;avrt.lib;WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /machine:x64</AdditionalOptions>
|
||||
<EnableCOMDATFolding>false</EnableCOMDATFolding>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<ImportLibrary>lib/Debug/HolographicHostSample.lib</ImportLibrary>
|
||||
<OptimizeReferences>false</OptimizeReferences>
|
||||
<ProgramDataBaseFile>bin/Debug/HolographicHostSample.pdb</ProgramDataBaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /await</AdditionalOptions>
|
||||
<AdditionalUsingDirectories>$(VCIDEInstallDir)vcpackages;$(WindowsSDK_UnionMetadataPath)</AdditionalUsingDirectories>
|
||||
<AssemblerListingLocation>Release/</AssemblerListingLocation>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4503</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<UseFullPaths>false</UseFullPaths>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;UNICODE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WIN32;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_INTEL;RDBUILD_ARCH_INTEL_X64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;UNICODE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WIN32;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_INTEL;RDBUILD_ARCH_INTEL_X64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>
|
||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
||||
</Midl>
|
||||
<Link>
|
||||
<AdditionalDependencies>d2d1.lib;d3d11.lib;dxgi.lib;dwrite.lib;windowscodecs.lib;pathcch.lib;Mswsock.lib;mfreadwrite.lib;Mfplat.lib;mfuuid.lib;ntdll.lib;Secur32.lib;crypt32.lib;secur32.lib;avrt.lib;WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /machine:x64</AdditionalOptions>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<ImportLibrary>lib/Release/HolographicHostSample.lib</ImportLibrary>
|
||||
<ProgramDataBaseFile>bin/Release/HolographicHostSample.pdb</ProgramDataBaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /await</AdditionalOptions>
|
||||
<AdditionalUsingDirectories>$(VCIDEInstallDir)vcpackages;$(WindowsSDK_UnionMetadataPath)</AdditionalUsingDirectories>
|
||||
<AssemblerListingLocation>RelWithDebInfo/</AssemblerListingLocation>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4503</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<UseFullPaths>false</UseFullPaths>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;UNICODE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WIN32;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_INTEL;RDBUILD_ARCH_INTEL_X64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR="RelWithDebInfo";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;UNICODE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WIN32;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_INTEL;RDBUILD_ARCH_INTEL_X64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR=\"RelWithDebInfo\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>
|
||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
||||
</Midl>
|
||||
<Link>
|
||||
<AdditionalDependencies>d2d1.lib;d3d11.lib;dxgi.lib;dwrite.lib;windowscodecs.lib;pathcch.lib;Mswsock.lib;mfreadwrite.lib;Mfplat.lib;mfuuid.lib;ntdll.lib;Secur32.lib;crypt32.lib;secur32.lib;avrt.lib;WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /machine:x64</AdditionalOptions>
|
||||
<EnableCOMDATFolding>false</EnableCOMDATFolding>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<ImportLibrary>lib/RelWithDebInfo/HolographicHostSample.lib</ImportLibrary>
|
||||
<OptimizeReferences>false</OptimizeReferences>
|
||||
<ProgramDataBaseFile>bin/RelWithDebInfo/HolographicHostSample.pdb</ProgramDataBaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include=".\SampleHostMain.cpp" />
|
||||
<ClInclude Include=".\SampleHostMain.h" />
|
||||
<ClInclude Include=".\pch.h" />
|
||||
<ClCompile Include=".\pch.cpp" />
|
||||
<ClCompile Include=".\SampleHostWindowWin32.cpp" />
|
||||
<ClInclude Include=".\SampleHostWindowWin32.h" />
|
||||
<ClCompile Include=".\Common\CameraResources.cpp" />
|
||||
<ClInclude Include=".\Common\CameraResources.h" />
|
||||
<ClInclude Include=".\Common\DbgLog.h" />
|
||||
<ClCompile Include=".\Common\DeviceResources.cpp" />
|
||||
<ClInclude Include=".\Common\DeviceResources.h" />
|
||||
<ClInclude Include=".\Common\DirectXHelper.h" />
|
||||
<ClCompile Include=".\Common\PerceptionTypes.cpp" />
|
||||
<ClInclude Include=".\Common\PerceptionTypes.h" />
|
||||
<ClInclude Include=".\Common\Utils.h" />
|
||||
<ClCompile Include=".\Common\Speech.cpp" />
|
||||
<ClInclude Include=".\Common\Speech.h" />
|
||||
<ClCompile Include=".\Content\PerceptionDeviceHandler.cpp" />
|
||||
<ClInclude Include=".\Content\PerceptionDeviceHandler.h" />
|
||||
<ClCompile Include=".\Content\QRCodeRenderer.cpp" />
|
||||
<ClInclude Include=".\Content\QRCodeRenderer.h" />
|
||||
<ClCompile Include=".\Content\QRCodeTracker.cpp" />
|
||||
<ClInclude Include=".\Content\QRCodeTracker.h" />
|
||||
<ClCompile Include=".\Content\RenderableObject.cpp" />
|
||||
<ClInclude Include=".\Content\RenderableObject.h" />
|
||||
<ClInclude Include=".\Content\ShaderStructures.h" />
|
||||
<ClCompile Include=".\Content\SpatialInputHandler.cpp" />
|
||||
<ClInclude Include=".\Content\SpatialInputHandler.h" />
|
||||
<ClCompile Include=".\Content\SpatialInputRenderer.cpp" />
|
||||
<ClInclude Include=".\Content\SpatialInputRenderer.h" />
|
||||
<ClCompile Include=".\Content\SpinningCubeRenderer.cpp" />
|
||||
<ClInclude Include=".\Content\SpinningCubeRenderer.h" />
|
||||
<ClCompile Include=".\Content\SpatialSurfaceMeshRenderer.cpp" />
|
||||
<ClInclude Include=".\Content\SpatialSurfaceMeshRenderer.h" />
|
||||
<Image Include=".\Assets\LockScreenLogo.scale-200.png" />
|
||||
<Image Include=".\Assets\SplashScreen.scale-200.png" />
|
||||
<Image Include=".\Assets\Square44x44Logo.scale-200.png" />
|
||||
<Image Include=".\Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Image Include=".\Assets\Square150x150Logo.scale-200.png" />
|
||||
<Image Include=".\Assets\StoreLogo.png" />
|
||||
<Image Include=".\Assets\Wide310x150Logo.scale-200.png" />
|
||||
<AppxManifest Include=".\Package.appxmanifest" />
|
||||
<FXCompile Include=".\Content\shaders\hsa_VertexShader.hlsl">
|
||||
<ShaderType>Vertex</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<FXCompile Include=".\Content\shaders\hsa_VPRTVertexShader.hlsl">
|
||||
<ShaderType>Vertex</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<FXCompile Include=".\Content\shaders\hsa_SRMeshVertexShader.hlsl">
|
||||
<ShaderType>Vertex</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<FXCompile Include=".\Content\shaders\hsa_PixelShader.hlsl">
|
||||
<ShaderType>Pixel</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<FXCompile Include=".\Content\shaders\hsa_SRMeshPixelShader.hlsl">
|
||||
<ShaderType>Pixel</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<FXCompile Include=".\Content\shaders\hsa_GeometryShader.hlsl">
|
||||
<ShaderType>Geometry</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<FXCompile Include=".\Content\shaders\hsa_SRMeshGeometryShader.hlsl">
|
||||
<ShaderType>Geometry</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<None Include=".\SpeechGrammar.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="packages\Microsoft.Windows.CppWinRT.2.0.200224.2\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('packages\Microsoft.Windows.CppWinRT.2.0.200224.2\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup>
|
||||
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="RelWithDebInfo|x64">
|
||||
<Configuration>RelWithDebInfo</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{D22B424F-B259-356A-8E4C-4937C36E783E}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<Platform>x64</Platform>
|
||||
<ProjectName>SampleRemote</ProjectName>
|
||||
<VCProjectUpgraderObjectName>NoUpgrade</VCProjectUpgraderObjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<SpectreMitigation>Spectre</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">bin\Debug\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">SampleRemote.dir\Debug\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">SampleRemote</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.exe</TargetExt>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</GenerateManifest>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">bin\Release\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">SampleRemote.dir\Release\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">SampleRemote</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.exe</TargetExt>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">bin\RelWithDebInfo\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">SampleRemote.dir\RelWithDebInfo\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">SampleRemote</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">.exe</TargetExt>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">true</LinkIncremental>
|
||||
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">true</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /await</AdditionalOptions>
|
||||
<AdditionalUsingDirectories>$(VCIDEInstallDir)vcpackages;$(WindowsSDK_UnionMetadataPath)</AdditionalUsingDirectories>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4503</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<UseFullPaths>false</UseFullPaths>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;ALLOW_INSECURE_RANDOM_DEVICE=1;UNICODE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WIN32;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_INTEL;RDBUILD_ARCH_INTEL_X64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;ALLOW_INSECURE_RANDOM_DEVICE=1;UNICODE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WIN32;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_INTEL;RDBUILD_ARCH_INTEL_X64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>
|
||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
||||
</Midl>
|
||||
<Link>
|
||||
<AdditionalDependencies>d2d1.lib;d3d11.lib;dxgi.lib;dwrite.lib;windowscodecs.lib;pathcch.lib;Mswsock.lib;mfreadwrite.lib;Mfplat.lib;mfuuid.lib;ntdll.lib;Secur32.lib;crypt32.lib;secur32.lib;avrt.lib;WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /machine:x64</AdditionalOptions>
|
||||
<EnableCOMDATFolding>false</EnableCOMDATFolding>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<ImportLibrary>lib/Debug/SampleRemote.lib</ImportLibrary>
|
||||
<OptimizeReferences>false</OptimizeReferences>
|
||||
<ProgramDataBaseFile>bin/Debug/SampleRemote.pdb</ProgramDataBaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /await</AdditionalOptions>
|
||||
<AdditionalUsingDirectories>$(VCIDEInstallDir)vcpackages;$(WindowsSDK_UnionMetadataPath)</AdditionalUsingDirectories>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4503</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<UseFullPaths>false</UseFullPaths>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;UNICODE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WIN32;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_INTEL;RDBUILD_ARCH_INTEL_X64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;UNICODE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WIN32;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_INTEL;RDBUILD_ARCH_INTEL_X64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>
|
||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
||||
</Midl>
|
||||
<Link>
|
||||
<AdditionalDependencies>d2d1.lib;d3d11.lib;dxgi.lib;dwrite.lib;windowscodecs.lib;pathcch.lib;Mswsock.lib;mfreadwrite.lib;Mfplat.lib;mfuuid.lib;ntdll.lib;Secur32.lib;crypt32.lib;secur32.lib;avrt.lib;WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /machine:x64</AdditionalOptions>
|
||||
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<ImportLibrary>lib/Release/SampleRemote.lib</ImportLibrary>
|
||||
<ProgramDataBaseFile>bin/Release/SampleRemote.pdb</ProgramDataBaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /await</AdditionalOptions>
|
||||
<AdditionalUsingDirectories>$(VCIDEInstallDir)vcpackages;$(WindowsSDK_UnionMetadataPath)</AdditionalUsingDirectories>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<CompileAsWinRT>true</CompileAsWinRT>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4503</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<UseFullPaths>false</UseFullPaths>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;UNICODE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WIN32;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_INTEL;RDBUILD_ARCH_INTEL_X64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR="RelWithDebInfo";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;ALLOW_INSECURE_RANDOM_DEVICE=1;UNICODE;_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING;RDBUILD_PLATFORM_DEFINED;RDBUILD_PLATFORM_WINDOWS;RDBUILD_PLATFORM_WINDOWS_WIN32;RDBUILD_ARCHITECTURE_DEFINED;RDBUILD_ARCH_INTEL;RDBUILD_ARCH_INTEL_X64;RDBUILD_DEFAULT_CALL=;RDBUILD_FEATURE_OPENSSL=0;_SCL_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN=1;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=0x0A000007;CMAKE_INTDIR=\"RelWithDebInfo\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
<AdditionalIncludeDirectories>.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OutputDirectory>$(ProjectDir)/$(IntDir)</OutputDirectory>
|
||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
||||
</Midl>
|
||||
<Link>
|
||||
<AdditionalDependencies>d2d1.lib;d3d11.lib;dxgi.lib;dwrite.lib;windowscodecs.lib;pathcch.lib;Mswsock.lib;mfreadwrite.lib;Mfplat.lib;mfuuid.lib;ntdll.lib;Secur32.lib;crypt32.lib;secur32.lib;avrt.lib;WindowsApp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>%(AdditionalOptions) /machine:x64</AdditionalOptions>
|
||||
<EnableCOMDATFolding>false</EnableCOMDATFolding>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<ImportLibrary>lib/RelWithDebInfo/SampleRemote.lib</ImportLibrary>
|
||||
<OptimizeReferences>false</OptimizeReferences>
|
||||
<ProgramDataBaseFile>bin/RelWithDebInfo/SampleRemote.pdb</ProgramDataBaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include=".\SampleRemoteMain.cpp" />
|
||||
<ClInclude Include=".\SampleRemoteMain.h" />
|
||||
<ClInclude Include=".\pch.h" />
|
||||
<ClCompile Include=".\pch.cpp" />
|
||||
<ClCompile Include=".\SampleRemoteWindowWin32.cpp" />
|
||||
<ClInclude Include=".\SampleRemoteWindowWin32.h" />
|
||||
<ClCompile Include=".\Common\CameraResources.cpp" />
|
||||
<ClInclude Include=".\Common\CameraResources.h" />
|
||||
<ClInclude Include=".\Common\DbgLog.h" />
|
||||
<ClCompile Include=".\Common\DeviceResources.cpp" />
|
||||
<ClInclude Include=".\Common\DeviceResources.h" />
|
||||
<ClInclude Include=".\Common\DirectXHelper.h" />
|
||||
<ClCompile Include=".\Common\PerceptionTypes.cpp" />
|
||||
<ClInclude Include=".\Common\PerceptionTypes.h" />
|
||||
<ClInclude Include=".\Common\Utils.h" />
|
||||
<ClCompile Include=".\Common\Speech.cpp" />
|
||||
<ClInclude Include=".\Common\Speech.h" />
|
||||
<ClCompile Include=".\Content\PerceptionDeviceHandler.cpp" />
|
||||
<ClInclude Include=".\Content\PerceptionDeviceHandler.h" />
|
||||
<ClCompile Include=".\Content\QRCodeRenderer.cpp" />
|
||||
<ClInclude Include=".\Content\QRCodeRenderer.h" />
|
||||
<ClCompile Include=".\Content\QRCodeTracker.cpp" />
|
||||
<ClInclude Include=".\Content\QRCodeTracker.h" />
|
||||
<ClCompile Include=".\Content\RenderableObject.cpp" />
|
||||
<ClInclude Include=".\Content\RenderableObject.h" />
|
||||
<ClInclude Include=".\Content\ShaderStructures.h" />
|
||||
<ClCompile Include=".\Content\SpatialInputHandler.cpp" />
|
||||
<ClInclude Include=".\Content\SpatialInputHandler.h" />
|
||||
<ClCompile Include=".\Content\SpatialInputRenderer.cpp" />
|
||||
<ClInclude Include=".\Content\SpatialInputRenderer.h" />
|
||||
<ClCompile Include=".\Content\SpinningCubeRenderer.cpp" />
|
||||
<ClInclude Include=".\Content\SpinningCubeRenderer.h" />
|
||||
<ClCompile Include=".\Content\SpatialSurfaceMeshRenderer.cpp" />
|
||||
<ClInclude Include=".\Content\SpatialSurfaceMeshRenderer.h" />
|
||||
<Image Include=".\Assets\LockScreenLogo.scale-200.png" />
|
||||
<Image Include=".\Assets\SplashScreen.scale-200.png" />
|
||||
<Image Include=".\Assets\Square44x44Logo.scale-200.png" />
|
||||
<Image Include=".\Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Image Include=".\Assets\Square150x150Logo.scale-200.png" />
|
||||
<Image Include=".\Assets\StoreLogo.png" />
|
||||
<Image Include=".\Assets\Wide310x150Logo.scale-200.png" />
|
||||
<AppxManifest Include=".\Package.appxmanifest" />
|
||||
<FXCompile Include=".\Content\shaders\hsa_VertexShader.hlsl">
|
||||
<ShaderType>Vertex</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<FXCompile Include=".\Content\shaders\hsa_VPRTVertexShader.hlsl">
|
||||
<ShaderType>Vertex</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<FXCompile Include=".\Content\shaders\hsa_SRMeshVertexShader.hlsl">
|
||||
<ShaderType>Vertex</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<FXCompile Include=".\Content\shaders\hsa_PixelShader.hlsl">
|
||||
<ShaderType>Pixel</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<FXCompile Include=".\Content\shaders\hsa_SRMeshPixelShader.hlsl">
|
||||
<ShaderType>Pixel</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<FXCompile Include=".\Content\shaders\hsa_GeometryShader.hlsl">
|
||||
<ShaderType>Geometry</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<FXCompile Include=".\Content\shaders\hsa_SRMeshGeometryShader.hlsl">
|
||||
<ShaderType>Geometry</ShaderType>
|
||||
<EntryPointName>main</EntryPointName>
|
||||
<ShaderModel>5.0</ShaderModel>
|
||||
</FXCompile>
|
||||
<None Include=".\SpeechGrammar.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="packages\Microsoft.Windows.CppWinRT.2.0.200224.2\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('packages\Microsoft.Windows.CppWinRT.2.0.200224.2\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="packages\Microsoft.Holographic.Remoting.2.1.0\build\native\Microsoft.Holographic.Remoting.targets" Condition="Exists('packages\Microsoft.Holographic.Remoting.2.1.0\build\native\Microsoft.Holographic.Remoting.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -1,211 +1,240 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/DeviceResources.h"
|
||||
|
||||
#include "Content/PerceptionDeviceHandler.h"
|
||||
#include "Content/QRCodeRenderer.h"
|
||||
#include "Content/SpatialInputHandler.h"
|
||||
#include "Content/SpatialInputRenderer.h"
|
||||
#include "Content/SpatialSurfaceMeshRenderer.h"
|
||||
#include "Content/SpinningCubeRenderer.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <winrt/Microsoft.Holographic.AppRemoting.h>
|
||||
|
||||
|
||||
#define INITIAL_WINDOW_WIDTH 1280
|
||||
#define INITIAL_WINDOW_HEIGHT 720
|
||||
|
||||
#define TITLE_TEXT L"Remoting Host Sample"
|
||||
#define TITLE_SEPARATOR L" | "
|
||||
#define TITLE_CONNECT_TEXT L"Press Space To Connect"
|
||||
#define TITLE_DISCONNECT_TEXT L"Press D to Disconnect"
|
||||
#define TITLE_ENABLE_PREVIEW_TEXT L"Preview Disabled (press P to enable)"
|
||||
#define TITLE_DISABLE_PREVIEW_TEXT L"Preview Enabled (press P to disable)"
|
||||
|
||||
|
||||
class SampleHostMain : public std::enable_shared_from_this<SampleHostMain>, public DXHelper::IDeviceNotify
|
||||
{
|
||||
public:
|
||||
struct IWindow
|
||||
{
|
||||
virtual winrt::com_ptr<IDXGISwapChain1>
|
||||
CreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device, const DXGI_SWAP_CHAIN_DESC1* desc) = 0;
|
||||
|
||||
virtual void SetWindowTitle(std::wstring title) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
public:
|
||||
SampleHostMain(std::weak_ptr<IWindow> window);
|
||||
~SampleHostMain();
|
||||
|
||||
// Creates a HolographicFrame and updates the content.
|
||||
winrt::Windows::Graphics::Holographic::HolographicFrame Update();
|
||||
|
||||
// Renders the current frame to each holographic camera and presents it.
|
||||
void Render(winrt::Windows::Graphics::Holographic::HolographicFrame holographicFrame);
|
||||
|
||||
const std::shared_ptr<DXHelper::DeviceResources>& GetDeviceResources()
|
||||
{
|
||||
return m_deviceResources;
|
||||
}
|
||||
|
||||
void SetHostOptions(bool listen, const std::wstring& hostname, uint32_t port);
|
||||
|
||||
// Responds to key presses.
|
||||
void OnKeyPress(char key);
|
||||
|
||||
// Responds to window changing its size.
|
||||
void OnResize(int width, int height);
|
||||
|
||||
// Responds to speech recognition results.
|
||||
void OnRecognizedSpeech(const winrt::hstring& recognizedText);
|
||||
|
||||
// IDeviceNotify methods
|
||||
virtual void OnDeviceLost();
|
||||
virtual void OnDeviceRestored();
|
||||
|
||||
private:
|
||||
// Initializes the RemoteContext and starts connecting or listening to the currently set network address
|
||||
void InitializeRemoteContextAndConnectOrListen();
|
||||
|
||||
// Initializes the HolographicSpace and creates graphics device dependent resources
|
||||
void CreateHolographicSpaceAndDeviceResources();
|
||||
|
||||
// Connects to or listens on the currently set network address
|
||||
void ConnectOrListen();
|
||||
|
||||
// Loads the currently saved position of the spinning cube.
|
||||
void LoadPosition();
|
||||
|
||||
// Saves the position of the spinning cube.
|
||||
void SavePosition();
|
||||
|
||||
|
||||
// Request access for eyes pose data.
|
||||
void RequestEyesPoseAccess();
|
||||
|
||||
// Clears event registration state. Used when changing to a new HolographicSpace
|
||||
// and when tearing down SampleHostMain.
|
||||
void UnregisterHolographicEventHandlers();
|
||||
|
||||
// Shuts down the RemoteContext (which will also disconnect, if currently connected)
|
||||
void ShutdownRemoteContext();
|
||||
|
||||
// Creates a SwapChain for the host window
|
||||
void WindowCreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device);
|
||||
|
||||
// Presents the SwapChain of the host window
|
||||
void WindowPresentSwapChain();
|
||||
|
||||
// Updates the title of the host window
|
||||
void WindowUpdateTitle();
|
||||
|
||||
// Asynchronously creates resources for new holographic cameras.
|
||||
void OnCameraAdded(
|
||||
const winrt::Windows::Graphics::Holographic::HolographicSpace& sender,
|
||||
const winrt::Windows::Graphics::Holographic::HolographicSpaceCameraAddedEventArgs& args);
|
||||
|
||||
// Synchronously releases resources for holographic cameras that are no longer
|
||||
// attached to the system.
|
||||
void OnCameraRemoved(
|
||||
const winrt::Windows::Graphics::Holographic::HolographicSpace& sender,
|
||||
const winrt::Windows::Graphics::Holographic::HolographicSpaceCameraRemovedEventArgs& args);
|
||||
|
||||
// Used to notify the app when the positional tracking state changes.
|
||||
void OnLocatabilityChanged(
|
||||
const winrt::Windows::Perception::Spatial::SpatialLocator& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
|
||||
#ifdef ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE
|
||||
void OnCustomDataChannelDataReceived();
|
||||
void OnCustomDataChannelClosed();
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool m_isInitialized = false;
|
||||
|
||||
std::chrono::high_resolution_clock::time_point m_startTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// RemoteContext used to connect with a Holographic Remoting player and display rendered frames
|
||||
winrt::Microsoft::Holographic::AppRemoting::RemoteContext m_remoteContext = nullptr;
|
||||
|
||||
// Represents the holographic space around the user.
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace m_holographicSpace = nullptr;
|
||||
|
||||
// Cached pointer to device resources.
|
||||
std::shared_ptr<DXHelper::DeviceResources> m_deviceResources;
|
||||
|
||||
// SpatialLocator that is attached to the primary camera.
|
||||
winrt::Windows::Perception::Spatial::SpatialLocator m_locator = nullptr;
|
||||
|
||||
// A reference frame that is positioned in the world.
|
||||
winrt::Windows::Perception::Spatial::SpatialStationaryFrameOfReference m_referenceFrame = nullptr;
|
||||
|
||||
// Renders a colorful holographic cube that's 20 centimeters wide. This sample content
|
||||
// is used to demonstrate world-locked rendering.
|
||||
std::unique_ptr<SpinningCubeRenderer> m_spinningCubeRenderer;
|
||||
|
||||
// Renders the surface observed in the user's surroundings.
|
||||
std::unique_ptr<SpatialSurfaceMeshRenderer> m_spatialSurfaceMeshRenderer;
|
||||
|
||||
// Listens for the Pressed spatial input event.
|
||||
std::shared_ptr<SpatialInputHandler> m_spatialInputHandler;
|
||||
std::unique_ptr<SpatialInputRenderer> m_spatialInputRenderer;
|
||||
|
||||
// Handles perception root objects and their events/updates
|
||||
std::shared_ptr<PerceptionDeviceHandler> m_perceptionDeviceHandler;
|
||||
std::unique_ptr<QRCodeRenderer> m_qrCodeRenderer;
|
||||
|
||||
// Event registration tokens.
|
||||
winrt::event_token m_cameraAddedToken;
|
||||
winrt::event_token m_cameraRemovedToken;
|
||||
winrt::event_token m_locatabilityChangedToken;
|
||||
|
||||
// Event registration revokers
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteContext::OnConnected_revoker m_onConnectedEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteContext::OnDisconnected_revoker m_onDisconnectedEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteContext::OnSendFrame_revoker m_onSendFrameEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteContext::OnDataChannelCreated_revoker m_onDataChannelCreatedEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech::OnRecognizedSpeech_revoker m_onRecognizedSpeechRevoker;
|
||||
|
||||
// Host options
|
||||
std::wstring m_hostname;
|
||||
uint32_t m_port{0};
|
||||
bool m_showPreview = true;
|
||||
bool m_listen{false};
|
||||
|
||||
// Host window related variables
|
||||
std::weak_ptr<IWindow> m_window;
|
||||
int m_width = INITIAL_WINDOW_WIDTH;
|
||||
int m_height = INITIAL_WINDOW_HEIGHT;
|
||||
|
||||
std::chrono::high_resolution_clock::time_point m_windowTitleUpdateTime;
|
||||
uint32_t m_framesPerSecond = 0;
|
||||
|
||||
std::recursive_mutex m_deviceLock;
|
||||
winrt::com_ptr<IDXGISwapChain1> m_swapChain;
|
||||
winrt::com_ptr<ID3D11Texture2D> m_spTexture;
|
||||
|
||||
#ifdef ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE
|
||||
std::recursive_mutex m_customDataChannelLock;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IDataChannel m_customDataChannel = nullptr;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IDataChannel::OnDataReceived_revoker m_customChannelDataReceivedEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IDataChannel::OnClosed_revoker m_customChannelClosedEventRevoker;
|
||||
std::chrono::high_resolution_clock::time_point m_customDataChannelSendTime = std::chrono::high_resolution_clock::now();
|
||||
#endif
|
||||
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Common/DeviceResources.h"
|
||||
|
||||
#include "Content/PerceptionDeviceHandler.h"
|
||||
#include "Content/QRCodeRenderer.h"
|
||||
#include "Content/SpatialInputHandler.h"
|
||||
#include "Content/SpatialInputRenderer.h"
|
||||
#include "Content/SpatialSurfaceMeshRenderer.h"
|
||||
#include "Content/SpinningCubeRenderer.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <winrt/Microsoft.Holographic.AppRemoting.h>
|
||||
|
||||
#define INITIAL_WINDOW_WIDTH 1280
|
||||
#define INITIAL_WINDOW_HEIGHT 720
|
||||
|
||||
#define TITLE_TEXT L"Remoting Host Sample"
|
||||
#define TITLE_SEPARATOR L" | "
|
||||
#define TITLE_CONNECT_TEXT L"Press Space To Connect"
|
||||
#define TITLE_DISCONNECT_TEXT L"Press D to Disconnect"
|
||||
#define TITLE_ENABLE_PREVIEW_TEXT L"Preview Disabled (press P to enable)"
|
||||
#define TITLE_DISABLE_PREVIEW_TEXT L"Preview Enabled (press P to disable)"
|
||||
|
||||
// #define ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE
|
||||
|
||||
class SampleRemoteMain : public std::enable_shared_from_this<SampleRemoteMain>, public DXHelper::IDeviceNotify
|
||||
{
|
||||
public:
|
||||
struct IWindow
|
||||
{
|
||||
virtual winrt::com_ptr<IDXGISwapChain1>
|
||||
CreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device, const DXGI_SWAP_CHAIN_DESC1* desc) = 0;
|
||||
|
||||
virtual winrt::Windows::Graphics::Holographic::HolographicSpace CreateHolographicSpace() = 0;
|
||||
|
||||
virtual winrt::Windows::UI::Input::Spatial::SpatialInteractionManager CreateInteractionManager() = 0;
|
||||
|
||||
virtual void SetWindowTitle(std::wstring title) = 0;
|
||||
};
|
||||
|
||||
public:
|
||||
SampleRemoteMain(std::weak_ptr<IWindow> window);
|
||||
~SampleRemoteMain();
|
||||
|
||||
// Creates a HolographicFrame and updates the content.
|
||||
winrt::Windows::Graphics::Holographic::HolographicFrame Update();
|
||||
|
||||
// Renders the current frame to each holographic camera and presents it.
|
||||
void Render(winrt::Windows::Graphics::Holographic::HolographicFrame holographicFrame);
|
||||
|
||||
const std::shared_ptr<DXHelper::DeviceResources>& GetDeviceResources()
|
||||
{
|
||||
return m_deviceResources;
|
||||
}
|
||||
|
||||
// Initialize SampleRemoteMain for remote rendering targeting a HolographicRemotingPlayer.
|
||||
void
|
||||
ConfigureRemoting(bool listen, const std::wstring& hostname, uint16_t port, uint16_t transportPort = 0, bool ephemeralPort = false);
|
||||
|
||||
// Initialize SampleRemoteMain for local rendering targeting HoloLens or Windows Mixed Reality headsets.
|
||||
void InitializeStandalone();
|
||||
|
||||
// Responds to key presses.
|
||||
void OnKeyPress(char key);
|
||||
|
||||
// Responds to window changing its size.
|
||||
void OnResize(int width, int height);
|
||||
|
||||
// Responds to speech recognition results.
|
||||
void OnRecognizedSpeech(const winrt::hstring& recognizedText);
|
||||
|
||||
// IDeviceNotify methods
|
||||
virtual void OnDeviceLost();
|
||||
virtual void OnDeviceRestored();
|
||||
|
||||
// Initializes the RemoteContext and starts connecting or listening to the currently set network address
|
||||
void InitializeRemoteContextAndConnectOrListen();
|
||||
|
||||
private:
|
||||
// Initializes the HolographicSpace and creates graphics device dependent resources
|
||||
void CreateHolographicSpaceAndDeviceResources();
|
||||
|
||||
// Connects to or listens on the currently set network address
|
||||
void ConnectOrListen();
|
||||
|
||||
// Loads the currently saved position of the spinning cube.
|
||||
void LoadPosition();
|
||||
|
||||
// Saves the position of the spinning cube.
|
||||
void SavePosition();
|
||||
|
||||
// Exports a test anchor via SpatialAnchorExporter.
|
||||
winrt::fire_and_forget ExportPosition();
|
||||
|
||||
// Request access for eyes pose data.
|
||||
void RequestEyesPoseAccess();
|
||||
|
||||
// Create the perception device handler which is required for qr code tracking.
|
||||
winrt::fire_and_forget CreatePerceptionDeviceHandler();
|
||||
|
||||
// Clears event registration state. Used when changing to a new HolographicSpace
|
||||
// and when tearing down SampleRemoteMain.
|
||||
void UnregisterHolographicEventHandlers();
|
||||
|
||||
// Shuts down the RemoteContext (which will also disconnect, if currently connected)
|
||||
void ShutdownRemoteContext();
|
||||
|
||||
// Creates a SwapChain for the host window
|
||||
void WindowCreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device);
|
||||
|
||||
// Presents the SwapChain of the host window
|
||||
void WindowPresentSwapChain();
|
||||
|
||||
// Updates the title of the host window
|
||||
void WindowUpdateTitle();
|
||||
|
||||
// Asynchronously creates resources for new holographic cameras.
|
||||
void OnCameraAdded(
|
||||
const winrt::Windows::Graphics::Holographic::HolographicSpace& sender,
|
||||
const winrt::Windows::Graphics::Holographic::HolographicSpaceCameraAddedEventArgs& args);
|
||||
|
||||
// Synchronously releases resources for holographic cameras that are no longer
|
||||
// attached to the system.
|
||||
void OnCameraRemoved(
|
||||
const winrt::Windows::Graphics::Holographic::HolographicSpace& sender,
|
||||
const winrt::Windows::Graphics::Holographic::HolographicSpaceCameraRemovedEventArgs& args);
|
||||
|
||||
// Used to notify the app when the positional tracking state changes.
|
||||
void OnLocatabilityChanged(
|
||||
const winrt::Windows::Perception::Spatial::SpatialLocator& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
|
||||
void OnDisconnected(winrt::Microsoft::Holographic::AppRemoting::ConnectionFailureReason failureReason);
|
||||
|
||||
#ifdef ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE
|
||||
void OnCustomDataChannelDataReceived();
|
||||
void OnCustomDataChannelClosed();
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool m_isInitialized = false;
|
||||
|
||||
std::chrono::high_resolution_clock::time_point m_startTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// Lock to serialize remote context operations and event handlers
|
||||
std::recursive_mutex m_remoteContextAccess;
|
||||
|
||||
// RemoteContext used to connect with a Holographic Remoting player and display rendered frames
|
||||
winrt::Microsoft::Holographic::AppRemoting::RemoteContext m_remoteContext = nullptr;
|
||||
|
||||
// Whether a disconnect is currently pending.
|
||||
bool m_disconnectPending{false};
|
||||
|
||||
// Represents the holographic space around the user.
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace m_holographicSpace = nullptr;
|
||||
|
||||
// The interaction manager provides an event that informs the app when spatial interactions are detected.
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager m_interactionManager = nullptr;
|
||||
|
||||
// Cached pointer to device resources.
|
||||
std::shared_ptr<DXHelper::DeviceResources> m_deviceResources;
|
||||
|
||||
// SpatialLocator that is attached to the primary camera.
|
||||
winrt::Windows::Perception::Spatial::SpatialLocator m_locator = nullptr;
|
||||
|
||||
// A reference frame that is positioned in the world.
|
||||
winrt::Windows::Perception::Spatial::SpatialStationaryFrameOfReference m_referenceFrame = nullptr;
|
||||
|
||||
// Renders a colorful holographic cube that's 20 centimeters wide. This sample content
|
||||
// is used to demonstrate world-locked rendering.
|
||||
std::unique_ptr<SpinningCubeRenderer> m_spinningCubeRenderer;
|
||||
|
||||
// Renders the surface observed in the user's surroundings.
|
||||
std::unique_ptr<SpatialSurfaceMeshRenderer> m_spatialSurfaceMeshRenderer;
|
||||
|
||||
// Listens for the Pressed spatial input event.
|
||||
std::shared_ptr<SpatialInputHandler> m_spatialInputHandler;
|
||||
std::shared_ptr<SpatialInputRenderer> m_spatialInputRenderer;
|
||||
|
||||
// Handles perception root objects and their events/updates
|
||||
std::shared_ptr<PerceptionDeviceHandler> m_perceptionDeviceHandler;
|
||||
std::unique_ptr<QRCodeRenderer> m_qrCodeRenderer;
|
||||
|
||||
// Event registration tokens.
|
||||
winrt::event_token m_cameraAddedToken;
|
||||
winrt::event_token m_cameraRemovedToken;
|
||||
winrt::event_token m_locatabilityChangedToken;
|
||||
|
||||
// Event registration revokers
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteContext::OnConnected_revoker m_onConnectedEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteContext::OnDisconnected_revoker m_onDisconnectedEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteContext::OnSendFrame_revoker m_onSendFrameEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteContext::OnDataChannelCreated_revoker m_onDataChannelCreatedEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech::OnRecognizedSpeech_revoker m_onRecognizedSpeechRevoker;
|
||||
|
||||
// Host options
|
||||
std::wstring m_hostname;
|
||||
uint16_t m_port{0};
|
||||
uint16_t m_transportPort{0};
|
||||
bool m_ephemeralPort = false;
|
||||
bool m_showPreview = true;
|
||||
bool m_listen{false};
|
||||
|
||||
// Host window related variables
|
||||
std::weak_ptr<IWindow> m_window;
|
||||
int m_width = INITIAL_WINDOW_WIDTH;
|
||||
int m_height = INITIAL_WINDOW_HEIGHT;
|
||||
|
||||
std::chrono::high_resolution_clock::time_point m_windowTitleUpdateTime;
|
||||
uint32_t m_framesPerSecond = 0;
|
||||
|
||||
std::recursive_mutex m_deviceLock;
|
||||
winrt::com_ptr<IDXGISwapChain1> m_swapChain;
|
||||
winrt::com_ptr<ID3D11Texture2D> m_spTexture;
|
||||
|
||||
bool m_canCommitDirect3D11DepthBuffer = false;
|
||||
bool m_commitDirect3D11DepthBuffer = true;
|
||||
|
||||
bool m_isStandalone = false;
|
||||
|
||||
#ifdef ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE
|
||||
std::recursive_mutex m_customDataChannelLock;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IDataChannel2 m_customDataChannel = nullptr;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IDataChannel2::OnDataReceived_revoker m_customChannelDataReceivedEventRevoker;
|
||||
winrt::Microsoft::Holographic::AppRemoting::IDataChannel2::OnClosed_revoker m_customChannelClosedEventRevoker;
|
||||
std::chrono::high_resolution_clock::time_point m_customDataChannelSendTime = std::chrono::high_resolution_clock::now();
|
||||
#endif
|
||||
};
|
|
@ -1,301 +1,323 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "SampleHostWindowUWP.h"
|
||||
|
||||
#include "Common\DbgLog.h"
|
||||
#include "Common\Speech.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
|
||||
#include <HolographicAppRemoting/Streamer.h>
|
||||
|
||||
#include <windows.graphics.directx.direct3d11.interop.h>
|
||||
|
||||
#include <winrt/Windows.ApplicationModel.Activation.h>
|
||||
#include <winrt/Windows.UI.Core.h>
|
||||
#include <winrt/Windows.ui.ViewManagement.h>
|
||||
|
||||
#define INITIAL_WINDOW_WIDTH 1280
|
||||
#define INITIAL_WINDOW_HEIGHT 720
|
||||
|
||||
#define TITLE_SEPARATOR L" | "
|
||||
|
||||
using namespace winrt::Windows::ApplicationModel;
|
||||
using namespace winrt::Windows::ApplicationModel::Activation;
|
||||
using namespace winrt::Windows::ApplicationModel::Core;
|
||||
using namespace winrt::Windows::Graphics::Display;
|
||||
using namespace winrt::Microsoft::Holographic::AppRemoting;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::UI::ViewManagement;
|
||||
|
||||
|
||||
// The main function is only used to initialize our IFrameworkView class.
|
||||
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
|
||||
{
|
||||
winrt::init_apartment();
|
||||
CoreApplication::Run(winrt::make<SampleHostWindowUWPView>());
|
||||
}
|
||||
|
||||
SampleHostWindowUWP::SampleHostWindowUWP()
|
||||
{
|
||||
ApplicationView::PreferredLaunchViewSize(winrt::Windows::Foundation::Size(INITIAL_WINDOW_WIDTH, INITIAL_WINDOW_HEIGHT));
|
||||
}
|
||||
|
||||
// The first method called when the IFrameworkView is being created.
|
||||
void SampleHostWindowUWP::Initialize(const CoreApplicationView& applicationView)
|
||||
{
|
||||
CoreApplication::Suspending({this, &SampleHostWindowUWP::OnSuspending});
|
||||
CoreApplication::Resuming({this, &SampleHostWindowUWP::OnResuming});
|
||||
|
||||
applicationView.Activated({this, &SampleHostWindowUWP::OnViewActivated});
|
||||
|
||||
m_main = std::make_shared<SampleHostMain>(weak_from_this());
|
||||
}
|
||||
|
||||
// Called when the CoreWindow object is created (or re-created).
|
||||
void SampleHostWindowUWP::SetWindow(const CoreWindow& window)
|
||||
{
|
||||
m_window = window;
|
||||
|
||||
window.SizeChanged({this, &SampleHostWindowUWP::OnWindowSizeChanged});
|
||||
window.VisibilityChanged({this, &SampleHostWindowUWP::OnVisibilityChanged});
|
||||
window.Closed({this, &SampleHostWindowUWP::OnWindowClosed});
|
||||
window.KeyDown({this, &SampleHostWindowUWP::OnKeyDown});
|
||||
}
|
||||
|
||||
// Initializes scene resources, or loads a previously saved app state.
|
||||
void SampleHostWindowUWP::Load(const winrt::hstring& entryPoint)
|
||||
{
|
||||
}
|
||||
|
||||
// This method is called after the window becomes active.
|
||||
void SampleHostWindowUWP::Run()
|
||||
{
|
||||
CoreWindow window = CoreWindow::GetForCurrentThread();
|
||||
window.Activate();
|
||||
|
||||
while (!m_windowClosed)
|
||||
{
|
||||
if (m_windowVisible)
|
||||
{
|
||||
CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
|
||||
|
||||
if (m_main)
|
||||
{
|
||||
if (const HolographicFrame& holographicFrame = m_main->Update())
|
||||
{
|
||||
m_main->Render(holographicFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Required for IFrameworkView.
|
||||
// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView
|
||||
// class is torn down while the app is in the foreground.
|
||||
void SampleHostWindowUWP::Uninitialize()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain1>
|
||||
SampleHostWindowUWP::CreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device, const DXGI_SWAP_CHAIN_DESC1* desc)
|
||||
{
|
||||
winrt::com_ptr<IDXGIDevice3> dxgiDevice;
|
||||
device.as(dxgiDevice);
|
||||
|
||||
winrt::com_ptr<IDXGIAdapter> dxgiAdapter;
|
||||
winrt::check_hresult(dxgiDevice->GetAdapter(dxgiAdapter.put()));
|
||||
|
||||
winrt::com_ptr<IDXGIFactory4> dxgiFactory;
|
||||
winrt::check_hresult(dxgiAdapter->GetParent(__uuidof(dxgiFactory), dxgiFactory.put_void()));
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain1> swapChain;
|
||||
winrt::check_hresult(dxgiFactory->CreateSwapChainForCoreWindow(
|
||||
device.get(), static_cast<::IUnknown*>(winrt::get_abi(m_window)), desc, nullptr, swapChain.put()));
|
||||
|
||||
return swapChain;
|
||||
}
|
||||
|
||||
void SampleHostWindowUWP::SetWindowTitle(std::wstring title)
|
||||
{
|
||||
auto dispatcher = winrt::Windows::ApplicationModel::Core::CoreApplication::MainView().CoreWindow().Dispatcher();
|
||||
|
||||
auto doSetWindowTitle = [title]() {
|
||||
try
|
||||
{
|
||||
if (auto view = winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView())
|
||||
{
|
||||
view.Title(winrt::to_hstring(title.c_str()));
|
||||
}
|
||||
}
|
||||
catch (const winrt::hresult_error&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
if (dispatcher.HasThreadAccess())
|
||||
{
|
||||
doSetWindowTitle();
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatcher.RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, doSetWindowTitle);
|
||||
}
|
||||
}
|
||||
|
||||
// Application lifecycle event handlers.
|
||||
|
||||
void SampleHostWindowUWP::OnSuspending(const winrt::Windows::Foundation::IInspectable& sender, const SuspendingEventArgs& args)
|
||||
{
|
||||
}
|
||||
|
||||
void SampleHostWindowUWP::OnResuming(
|
||||
const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args)
|
||||
{
|
||||
// Restore any data or state that was unloaded on suspend. By default, data
|
||||
// and state are persisted when resuming from suspend. Note that this event
|
||||
// does not occur if the app was previously terminated.
|
||||
|
||||
// Insert your code here.
|
||||
}
|
||||
|
||||
// Window event handlers.
|
||||
|
||||
void SampleHostWindowUWP::OnWindowSizeChanged(
|
||||
const winrt::Windows::Foundation::IInspectable& sender, const WindowSizeChangedEventArgs& args)
|
||||
{
|
||||
winrt::Windows::Foundation::Size size = args.Size();
|
||||
m_main->OnResize(static_cast<int>(size.Width + 0.5f), static_cast<int>(size.Height + 0.5f));
|
||||
}
|
||||
|
||||
void SampleHostWindowUWP::OnVisibilityChanged(
|
||||
const winrt::Windows::Foundation::IInspectable& sender, const VisibilityChangedEventArgs& args)
|
||||
{
|
||||
m_windowVisible = args.Visible();
|
||||
}
|
||||
|
||||
void SampleHostWindowUWP::OnWindowClosed(const CoreWindow& window, const CoreWindowEventArgs& args)
|
||||
{
|
||||
m_windowClosed = true;
|
||||
}
|
||||
|
||||
void SampleHostWindowUWP::OnKeyDown(const CoreWindow& window, const KeyEventArgs& args)
|
||||
{
|
||||
int32_t key = static_cast<int32_t>(args.VirtualKey());
|
||||
if (key >= 0 && key <= 0xFF)
|
||||
{
|
||||
m_main->OnKeyPress(static_cast<char>(tolower(key)));
|
||||
}
|
||||
}
|
||||
|
||||
void SampleHostWindowUWP::OnViewActivated(CoreApplicationView const& sender, IActivatedEventArgs const& activationArgs)
|
||||
{
|
||||
using namespace winrt::Windows::ApplicationModel;
|
||||
using namespace Activation;
|
||||
using namespace Core;
|
||||
|
||||
std::wstring host = L"127.0.0.1";
|
||||
int32_t port = 8265;
|
||||
|
||||
if (activationArgs != nullptr)
|
||||
{
|
||||
ActivationKind activationKind = activationArgs.Kind();
|
||||
if (activationKind == Activation::ActivationKind::Launch)
|
||||
{
|
||||
LaunchActivatedEventArgs launchArgs = activationArgs.as<LaunchActivatedEventArgs>();
|
||||
|
||||
std::vector<std::wstring> args;
|
||||
std::wistringstream stream(std::wstring(launchArgs.Arguments()));
|
||||
std::copy(
|
||||
std::istream_iterator<std::wstring, wchar_t>(stream),
|
||||
std::istream_iterator<std::wstring, wchar_t>(),
|
||||
std::back_inserter(args));
|
||||
|
||||
for (const std::wstring& arg : args)
|
||||
{
|
||||
if (arg.size() == 0)
|
||||
continue;
|
||||
|
||||
size_t colonPos = arg.find(L':');
|
||||
if (colonPos != std::wstring::npos)
|
||||
{
|
||||
std::wstring portStr = arg.substr(colonPos + 1);
|
||||
|
||||
host = arg.substr(0, colonPos);
|
||||
port = std::wcstol(portStr.c_str(), nullptr, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
host = arg.c_str();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for invalid port numbers
|
||||
if (port < 0 || port > 65535)
|
||||
{
|
||||
port = 0;
|
||||
}
|
||||
|
||||
m_ipAddress = host;
|
||||
m_port = port;
|
||||
|
||||
m_main->SetHostOptions(false, m_ipAddress, m_port);
|
||||
|
||||
// Run() won't start until the CoreWindow is activated.
|
||||
sender.CoreWindow().Activate();
|
||||
}
|
||||
|
||||
SampleHostWindowUWPView::SampleHostWindowUWPView()
|
||||
{
|
||||
m_window = std::make_shared<SampleHostWindowUWP>();
|
||||
}
|
||||
|
||||
winrt::Windows::ApplicationModel::Core::IFrameworkView SampleHostWindowUWPView::CreateView()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SampleHostWindowUWPView::Initialize(const winrt::Windows::ApplicationModel::Core::CoreApplicationView& applicationView)
|
||||
{
|
||||
m_window->Initialize(applicationView);
|
||||
}
|
||||
|
||||
void SampleHostWindowUWPView::SetWindow(const winrt::Windows::UI::Core::CoreWindow& window)
|
||||
{
|
||||
m_window->SetWindow(window);
|
||||
}
|
||||
|
||||
void SampleHostWindowUWPView::Load(const winrt::hstring& entryPoint)
|
||||
{
|
||||
m_window->Load(entryPoint);
|
||||
}
|
||||
|
||||
void SampleHostWindowUWPView::Run()
|
||||
{
|
||||
m_window->Run();
|
||||
}
|
||||
|
||||
void SampleHostWindowUWPView::Uninitialize()
|
||||
{
|
||||
m_window->Uninitialize();
|
||||
}
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "SampleRemoteWindowUWP.h"
|
||||
|
||||
#include "Common\DbgLog.h"
|
||||
#include "Common\Speech.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
|
||||
#include <HolographicAppRemoting/Streamer.h>
|
||||
|
||||
#include <windows.graphics.directx.direct3d11.interop.h>
|
||||
|
||||
#include <winrt/Windows.ApplicationModel.Activation.h>
|
||||
#include <winrt/Windows.UI.Core.h>
|
||||
#include <winrt/Windows.ui.ViewManagement.h>
|
||||
|
||||
#define INITIAL_WINDOW_WIDTH 1280
|
||||
#define INITIAL_WINDOW_HEIGHT 720
|
||||
|
||||
#define TITLE_SEPARATOR L" | "
|
||||
|
||||
using namespace winrt::Windows::ApplicationModel;
|
||||
using namespace winrt::Windows::ApplicationModel::Activation;
|
||||
using namespace winrt::Windows::ApplicationModel::Core;
|
||||
using namespace winrt::Windows::Graphics::Display;
|
||||
using namespace winrt::Microsoft::Holographic::AppRemoting;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::UI::ViewManagement;
|
||||
|
||||
// The main function is only used to initialize our IFrameworkView class.
|
||||
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
|
||||
{
|
||||
winrt::init_apartment();
|
||||
CoreApplication::Run(winrt::make<SampleRemoteWindowUWPView>());
|
||||
}
|
||||
|
||||
SampleRemoteWindowUWP::SampleRemoteWindowUWP()
|
||||
{
|
||||
ApplicationView::PreferredLaunchViewSize(winrt::Windows::Foundation::Size(INITIAL_WINDOW_WIDTH, INITIAL_WINDOW_HEIGHT));
|
||||
}
|
||||
|
||||
// The first method called when the IFrameworkView is being created.
|
||||
void SampleRemoteWindowUWP::Initialize(const CoreApplicationView& applicationView)
|
||||
{
|
||||
CoreApplication::Suspending({this, &SampleRemoteWindowUWP::OnSuspending});
|
||||
CoreApplication::Resuming({this, &SampleRemoteWindowUWP::OnResuming});
|
||||
|
||||
applicationView.Activated({this, &SampleRemoteWindowUWP::OnViewActivated});
|
||||
|
||||
m_main = std::make_shared<SampleRemoteMain>(weak_from_this());
|
||||
}
|
||||
|
||||
// Called when the CoreWindow object is created (or re-created).
|
||||
void SampleRemoteWindowUWP::SetWindow(const CoreWindow& window)
|
||||
{
|
||||
m_window = window;
|
||||
|
||||
window.SizeChanged({this, &SampleRemoteWindowUWP::OnWindowSizeChanged});
|
||||
window.VisibilityChanged({this, &SampleRemoteWindowUWP::OnVisibilityChanged});
|
||||
window.Closed({this, &SampleRemoteWindowUWP::OnWindowClosed});
|
||||
window.KeyDown({this, &SampleRemoteWindowUWP::OnKeyDown});
|
||||
}
|
||||
|
||||
// Initializes scene resources, or loads a previously saved app state.
|
||||
void SampleRemoteWindowUWP::Load(const winrt::hstring& entryPoint)
|
||||
{
|
||||
}
|
||||
|
||||
// This method is called after the window becomes active.
|
||||
void SampleRemoteWindowUWP::Run()
|
||||
{
|
||||
CoreWindow window = CoreWindow::GetForCurrentThread();
|
||||
window.Activate();
|
||||
|
||||
while (!m_windowClosed)
|
||||
{
|
||||
if (m_windowVisible)
|
||||
{
|
||||
CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
|
||||
|
||||
if (m_main)
|
||||
{
|
||||
if (const HolographicFrame& holographicFrame = m_main->Update())
|
||||
{
|
||||
m_main->Render(holographicFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CoreWindow::GetForCurrentThread().Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Required for IFrameworkView.
|
||||
// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView
|
||||
// class is torn down while the app is in the foreground.
|
||||
void SampleRemoteWindowUWP::Uninitialize()
|
||||
{
|
||||
}
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain1>
|
||||
SampleRemoteWindowUWP::CreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device, const DXGI_SWAP_CHAIN_DESC1* desc)
|
||||
{
|
||||
winrt::com_ptr<IDXGIDevice3> dxgiDevice;
|
||||
device.as(dxgiDevice);
|
||||
|
||||
winrt::com_ptr<IDXGIAdapter> dxgiAdapter;
|
||||
winrt::check_hresult(dxgiDevice->GetAdapter(dxgiAdapter.put()));
|
||||
|
||||
winrt::com_ptr<IDXGIFactory4> dxgiFactory;
|
||||
winrt::check_hresult(dxgiAdapter->GetParent(__uuidof(dxgiFactory), dxgiFactory.put_void()));
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain1> swapChain;
|
||||
winrt::check_hresult(dxgiFactory->CreateSwapChainForCoreWindow(
|
||||
device.get(), static_cast<::IUnknown*>(winrt::get_abi(m_window)), desc, nullptr, swapChain.put()));
|
||||
|
||||
return swapChain;
|
||||
}
|
||||
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace SampleRemoteWindowUWP::CreateHolographicSpace()
|
||||
{
|
||||
return HolographicSpace::CreateForCoreWindow(m_window);
|
||||
}
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager SampleRemoteWindowUWP::CreateInteractionManager()
|
||||
{
|
||||
return winrt::Windows::UI::Input::Spatial::SpatialInteractionManager::GetForCurrentView();
|
||||
}
|
||||
|
||||
void SampleRemoteWindowUWP::SetWindowTitle(std::wstring title)
|
||||
{
|
||||
auto dispatcher = winrt::Windows::ApplicationModel::Core::CoreApplication::MainView().CoreWindow().Dispatcher();
|
||||
|
||||
auto doSetWindowTitle = [title]() {
|
||||
try
|
||||
{
|
||||
if (auto view = winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView())
|
||||
{
|
||||
view.Title(winrt::to_hstring(title.c_str()));
|
||||
}
|
||||
}
|
||||
catch (const winrt::hresult_error&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
if (dispatcher.HasThreadAccess())
|
||||
{
|
||||
doSetWindowTitle();
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatcher.RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, doSetWindowTitle);
|
||||
}
|
||||
}
|
||||
|
||||
// Application lifecycle event handlers.
|
||||
|
||||
void SampleRemoteWindowUWP::OnSuspending(const winrt::Windows::Foundation::IInspectable& sender, const SuspendingEventArgs& args)
|
||||
{
|
||||
}
|
||||
|
||||
void SampleRemoteWindowUWP::OnResuming(
|
||||
const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args)
|
||||
{
|
||||
// Restore any data or state that was unloaded on suspend. By default, data
|
||||
// and state are persisted when resuming from suspend. Note that this event
|
||||
// does not occur if the app was previously terminated.
|
||||
|
||||
// Insert your code here.
|
||||
}
|
||||
|
||||
// Window event handlers.
|
||||
|
||||
void SampleRemoteWindowUWP::OnWindowSizeChanged(
|
||||
const winrt::Windows::Foundation::IInspectable& sender, const WindowSizeChangedEventArgs& args)
|
||||
{
|
||||
winrt::Windows::Foundation::Size size = args.Size();
|
||||
m_main->OnResize(static_cast<int>(size.Width + 0.5f), static_cast<int>(size.Height + 0.5f));
|
||||
}
|
||||
|
||||
void SampleRemoteWindowUWP::OnVisibilityChanged(
|
||||
const winrt::Windows::Foundation::IInspectable& sender, const VisibilityChangedEventArgs& args)
|
||||
{
|
||||
m_windowVisible = args.Visible();
|
||||
}
|
||||
|
||||
void SampleRemoteWindowUWP::OnWindowClosed(const CoreWindow& window, const CoreWindowEventArgs& args)
|
||||
{
|
||||
m_windowClosed = true;
|
||||
}
|
||||
|
||||
void SampleRemoteWindowUWP::OnKeyDown(const CoreWindow& window, const KeyEventArgs& args)
|
||||
{
|
||||
int32_t key = static_cast<int32_t>(args.VirtualKey());
|
||||
if (key >= 0 && key <= 0xFF)
|
||||
{
|
||||
m_main->OnKeyPress(static_cast<char>(tolower(key)));
|
||||
}
|
||||
}
|
||||
|
||||
void SampleRemoteWindowUWP::OnViewActivated(CoreApplicationView const& sender, IActivatedEventArgs const& activationArgs)
|
||||
{
|
||||
using namespace winrt::Windows::ApplicationModel;
|
||||
using namespace Activation;
|
||||
using namespace Core;
|
||||
|
||||
std::wstring host = L"127.0.0.1";
|
||||
int32_t port = 8265;
|
||||
bool isStandalone = false;
|
||||
|
||||
if (activationArgs != nullptr)
|
||||
{
|
||||
ActivationKind activationKind = activationArgs.Kind();
|
||||
if (activationKind == Activation::ActivationKind::Launch)
|
||||
{
|
||||
LaunchActivatedEventArgs launchArgs = activationArgs.as<LaunchActivatedEventArgs>();
|
||||
|
||||
std::vector<std::wstring> args;
|
||||
std::wistringstream stream(std::wstring(launchArgs.Arguments()));
|
||||
std::copy(
|
||||
std::istream_iterator<std::wstring, wchar_t>(stream),
|
||||
std::istream_iterator<std::wstring, wchar_t>(),
|
||||
std::back_inserter(args));
|
||||
|
||||
for (const std::wstring& arg : args)
|
||||
{
|
||||
if (arg.size() == 0)
|
||||
continue;
|
||||
|
||||
if (arg == L"-standalone")
|
||||
{
|
||||
isStandalone = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t colonPos = arg.find(L':');
|
||||
if (colonPos != std::wstring::npos)
|
||||
{
|
||||
std::wstring portStr = arg.substr(colonPos + 1);
|
||||
|
||||
host = arg.substr(0, colonPos);
|
||||
port = std::wcstol(portStr.c_str(), nullptr, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
host = arg.c_str();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isStandalone)
|
||||
{
|
||||
// check for invalid port numbers
|
||||
if (port < 0 || port > 65535)
|
||||
{
|
||||
port = 0;
|
||||
}
|
||||
|
||||
m_ipAddress = host;
|
||||
m_port = port;
|
||||
|
||||
m_main->ConfigureRemoting(false, m_ipAddress, m_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_main->InitializeStandalone();
|
||||
}
|
||||
|
||||
// Run() won't start until the CoreWindow is activated.
|
||||
sender.CoreWindow().Activate();
|
||||
}
|
||||
|
||||
SampleRemoteWindowUWPView::SampleRemoteWindowUWPView()
|
||||
{
|
||||
m_window = std::make_shared<SampleRemoteWindowUWP>();
|
||||
}
|
||||
|
||||
winrt::Windows::ApplicationModel::Core::IFrameworkView SampleRemoteWindowUWPView::CreateView()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SampleRemoteWindowUWPView::Initialize(const winrt::Windows::ApplicationModel::Core::CoreApplicationView& applicationView)
|
||||
{
|
||||
m_window->Initialize(applicationView);
|
||||
}
|
||||
|
||||
void SampleRemoteWindowUWPView::SetWindow(const winrt::Windows::UI::Core::CoreWindow& window)
|
||||
{
|
||||
m_window->SetWindow(window);
|
||||
}
|
||||
|
||||
void SampleRemoteWindowUWPView::Load(const winrt::hstring& entryPoint)
|
||||
{
|
||||
m_window->Load(entryPoint);
|
||||
}
|
||||
|
||||
void SampleRemoteWindowUWPView::Run()
|
||||
{
|
||||
m_window->Run();
|
||||
}
|
||||
|
||||
void SampleRemoteWindowUWPView::Uninitialize()
|
||||
{
|
||||
m_window->Uninitialize();
|
||||
}
|
|
@ -1,89 +1,92 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SampleHostMain.h"
|
||||
|
||||
#include "Common\DeviceResources.h"
|
||||
|
||||
#include <winrt/Microsoft.Holographic.AppRemoting.h>
|
||||
#include <winrt/Windows.ApplicationModel.Core.h>
|
||||
|
||||
|
||||
// Main entry point for our app. Connects the app with the Windows shell and handles application lifecycle events.
|
||||
class SampleHostWindowUWP : public std::enable_shared_from_this<SampleHostWindowUWP>, public SampleHostMain::IWindow
|
||||
{
|
||||
public:
|
||||
SampleHostWindowUWP();
|
||||
|
||||
// IFrameworkView methods
|
||||
virtual void Initialize(const winrt::Windows::ApplicationModel::Core::CoreApplicationView& applicationView);
|
||||
virtual void SetWindow(const winrt::Windows::UI::Core::CoreWindow& window);
|
||||
virtual void Load(const winrt::hstring& entryPoint);
|
||||
virtual void Run();
|
||||
virtual void Uninitialize();
|
||||
|
||||
// SampleHostMain::IWindow methods.
|
||||
virtual winrt::com_ptr<IDXGISwapChain1>
|
||||
CreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device, const DXGI_SWAP_CHAIN_DESC1* desc) override;
|
||||
|
||||
virtual void SetWindowTitle(std::wstring title) override;
|
||||
|
||||
protected:
|
||||
// Application lifecycle event handlers.
|
||||
void OnSuspending(
|
||||
const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::ApplicationModel::SuspendingEventArgs& args);
|
||||
void OnResuming(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
|
||||
// Activation handling
|
||||
void OnViewActivated(
|
||||
winrt::Windows::ApplicationModel::Core::CoreApplicationView const& sender,
|
||||
winrt::Windows::ApplicationModel::Activation::IActivatedEventArgs const& args);
|
||||
|
||||
// Window event handlers.
|
||||
void OnWindowSizeChanged(
|
||||
const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Core::WindowSizeChangedEventArgs& args);
|
||||
void OnVisibilityChanged(
|
||||
const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Core::VisibilityChangedEventArgs& args);
|
||||
void OnWindowClosed(const winrt::Windows::UI::Core::CoreWindow& window, const winrt::Windows::UI::Core::CoreWindowEventArgs& args);
|
||||
void OnKeyDown(const winrt::Windows::UI::Core::CoreWindow& window, const winrt::Windows::UI::Core::KeyEventArgs& args);
|
||||
|
||||
private:
|
||||
winrt::Windows::UI::Core::CoreWindow m_window = nullptr;
|
||||
std::shared_ptr<SampleHostMain> m_main;
|
||||
std::wstring m_ipAddress;
|
||||
int32_t m_port = 8265;
|
||||
bool m_windowClosed = false;
|
||||
bool m_windowVisible = true;
|
||||
};
|
||||
|
||||
class SampleHostWindowUWPView : public winrt::implements<
|
||||
SampleHostWindowUWPView,
|
||||
winrt::Windows::ApplicationModel::Core::IFrameworkViewSource,
|
||||
winrt::Windows::ApplicationModel::Core::IFrameworkView>
|
||||
{
|
||||
public:
|
||||
SampleHostWindowUWPView();
|
||||
|
||||
// IFrameworkViewSource methods.
|
||||
winrt::Windows::ApplicationModel::Core::IFrameworkView CreateView();
|
||||
|
||||
// IFrameworkView methods.
|
||||
virtual void Initialize(const winrt::Windows::ApplicationModel::Core::CoreApplicationView& applicationView);
|
||||
virtual void SetWindow(const winrt::Windows::UI::Core::CoreWindow& window);
|
||||
virtual void Load(const winrt::hstring& entryPoint);
|
||||
virtual void Run();
|
||||
virtual void Uninitialize();
|
||||
|
||||
private:
|
||||
std::shared_ptr<SampleHostWindowUWP> m_window;
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SampleRemoteMain.h"
|
||||
|
||||
#include "Common\DeviceResources.h"
|
||||
|
||||
#include <winrt/Microsoft.Holographic.AppRemoting.h>
|
||||
#include <winrt/Windows.ApplicationModel.Core.h>
|
||||
|
||||
// Main entry point for our app. Connects the app with the Windows shell and handles application lifecycle events.
|
||||
class SampleRemoteWindowUWP : public std::enable_shared_from_this<SampleRemoteWindowUWP>, public SampleRemoteMain::IWindow
|
||||
{
|
||||
public:
|
||||
SampleRemoteWindowUWP();
|
||||
|
||||
// IFrameworkView methods
|
||||
virtual void Initialize(const winrt::Windows::ApplicationModel::Core::CoreApplicationView& applicationView);
|
||||
virtual void SetWindow(const winrt::Windows::UI::Core::CoreWindow& window);
|
||||
virtual void Load(const winrt::hstring& entryPoint);
|
||||
virtual void Run();
|
||||
virtual void Uninitialize();
|
||||
|
||||
// SampleRemoteMain::IWindow methods.
|
||||
virtual winrt::com_ptr<IDXGISwapChain1>
|
||||
CreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device, const DXGI_SWAP_CHAIN_DESC1* desc) override;
|
||||
|
||||
virtual winrt::Windows::Graphics::Holographic::HolographicSpace CreateHolographicSpace() override;
|
||||
|
||||
virtual winrt::Windows::UI::Input::Spatial::SpatialInteractionManager CreateInteractionManager() override;
|
||||
|
||||
virtual void SetWindowTitle(std::wstring title) override;
|
||||
|
||||
protected:
|
||||
// Application lifecycle event handlers.
|
||||
void OnSuspending(
|
||||
const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::ApplicationModel::SuspendingEventArgs& args);
|
||||
void OnResuming(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args);
|
||||
|
||||
// Activation handling
|
||||
void OnViewActivated(
|
||||
winrt::Windows::ApplicationModel::Core::CoreApplicationView const& sender,
|
||||
winrt::Windows::ApplicationModel::Activation::IActivatedEventArgs const& args);
|
||||
|
||||
// Window event handlers.
|
||||
void OnWindowSizeChanged(
|
||||
const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Core::WindowSizeChangedEventArgs& args);
|
||||
void OnVisibilityChanged(
|
||||
const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Core::VisibilityChangedEventArgs& args);
|
||||
void OnWindowClosed(const winrt::Windows::UI::Core::CoreWindow& window, const winrt::Windows::UI::Core::CoreWindowEventArgs& args);
|
||||
void OnKeyDown(const winrt::Windows::UI::Core::CoreWindow& window, const winrt::Windows::UI::Core::KeyEventArgs& args);
|
||||
|
||||
private:
|
||||
winrt::Windows::UI::Core::CoreWindow m_window = nullptr;
|
||||
std::shared_ptr<SampleRemoteMain> m_main;
|
||||
std::wstring m_ipAddress;
|
||||
int32_t m_port = 8265;
|
||||
bool m_windowClosed = false;
|
||||
bool m_windowVisible = true;
|
||||
};
|
||||
|
||||
class SampleRemoteWindowUWPView : public winrt::implements<
|
||||
SampleRemoteWindowUWPView,
|
||||
winrt::Windows::ApplicationModel::Core::IFrameworkViewSource,
|
||||
winrt::Windows::ApplicationModel::Core::IFrameworkView>
|
||||
{
|
||||
public:
|
||||
SampleRemoteWindowUWPView();
|
||||
|
||||
// IFrameworkViewSource methods.
|
||||
winrt::Windows::ApplicationModel::Core::IFrameworkView CreateView();
|
||||
|
||||
// IFrameworkView methods.
|
||||
virtual void Initialize(const winrt::Windows::ApplicationModel::Core::CoreApplicationView& applicationView);
|
||||
virtual void SetWindow(const winrt::Windows::UI::Core::CoreWindow& window);
|
||||
virtual void Load(const winrt::hstring& entryPoint);
|
||||
virtual void Run();
|
||||
virtual void Uninitialize();
|
||||
|
||||
private:
|
||||
std::shared_ptr<SampleRemoteWindowUWP> m_window;
|
||||
};
|
|
@ -0,0 +1,363 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include <windows.graphics.holographic.h>
|
||||
#include <windows.ui.input.spatial.h>
|
||||
|
||||
#include <SampleRemoteWindowWin32.h>
|
||||
|
||||
#include <HolographicAppRemoting/Streamer.h>
|
||||
#include <HolographicSpaceInterop.h>
|
||||
#include <SpatialInteractionManagerInterop.h>
|
||||
|
||||
#include <Common/DbgLog.h>
|
||||
#include <DirectXColors.h>
|
||||
|
||||
#include <codecvt>
|
||||
#include <regex>
|
||||
|
||||
#include <windows.graphics.directx.direct3d11.interop.h>
|
||||
|
||||
#define WINDOWCLASSNAME L"SampleRemoteWindowWin32Class"
|
||||
|
||||
LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static SampleRemoteWindowWin32* s_sampleHostWindow;
|
||||
|
||||
LRESULT result = 0;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
{
|
||||
CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lParam);
|
||||
s_sampleHostWindow = reinterpret_cast<SampleRemoteWindowWin32*>(cs->lpCreateParams);
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect(hWnd, &clientRect);
|
||||
|
||||
s_sampleHostWindow->OnResize(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
|
||||
result = 0;
|
||||
}
|
||||
break;
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
{
|
||||
auto windowPos = reinterpret_cast<WINDOWPOS*>(lParam);
|
||||
if ((windowPos->flags & SWP_NOSIZE) == 0)
|
||||
{
|
||||
RECT clientRect;
|
||||
GetClientRect(hWnd, &clientRect);
|
||||
|
||||
s_sampleHostWindow->OnResize(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
|
||||
}
|
||||
result = 0;
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
s_sampleHostWindow = nullptr;
|
||||
result = 0;
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
{
|
||||
DestroyWindow(hWnd);
|
||||
result = 0;
|
||||
}
|
||||
break;
|
||||
case WM_CHAR:
|
||||
{
|
||||
const int key = tolower(static_cast<int>(wParam));
|
||||
s_sampleHostWindow->OnKeyPress(static_cast<char>(key));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
std::wstring SplitHostnameAndPortString(const std::wstring& address, uint16_t& port)
|
||||
{
|
||||
static std::basic_regex<wchar_t> addressMatcher(L"(?:(\\[.*\\])|([^:]*))(?:[:](\\d+))?");
|
||||
std::match_results<typename std::wstring::const_iterator> results;
|
||||
if (std::regex_match(address, results, addressMatcher))
|
||||
{
|
||||
if (results[3].matched)
|
||||
{
|
||||
std::wstring portStr = results[3].str();
|
||||
port = static_cast<uint16_t>(std::wcstol(portStr.c_str(), nullptr, 10));
|
||||
}
|
||||
|
||||
return (results[1].matched) ? results[1].str() : results[2].str();
|
||||
}
|
||||
else
|
||||
{
|
||||
return address;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void SampleRemoteWindowWin32::Initialize()
|
||||
{
|
||||
m_main = std::make_shared<SampleRemoteMain>(weak_from_this());
|
||||
}
|
||||
|
||||
void SampleRemoteWindowWin32::InitializeHwnd(HWND hWnd)
|
||||
{
|
||||
m_hWnd = hWnd;
|
||||
}
|
||||
|
||||
void SampleRemoteWindowWin32::ConfigureRemoting(
|
||||
bool listen, const std::wstring& hostname, uint16_t port, uint16_t transportPort, bool ephemeralPort)
|
||||
{
|
||||
m_main->ConfigureRemoting(listen, hostname, port, transportPort, ephemeralPort);
|
||||
}
|
||||
|
||||
void SampleRemoteWindowWin32::Connect()
|
||||
{
|
||||
m_main->InitializeRemoteContextAndConnectOrListen();
|
||||
}
|
||||
|
||||
void SampleRemoteWindowWin32::InitializeStandalone()
|
||||
{
|
||||
m_main->InitializeStandalone();
|
||||
}
|
||||
|
||||
void SampleRemoteWindowWin32::Tick()
|
||||
{
|
||||
if (const HolographicFrame& holographicFrame = m_main->Update())
|
||||
{
|
||||
m_main->Render(holographicFrame);
|
||||
}
|
||||
}
|
||||
|
||||
void SampleRemoteWindowWin32::OnKeyPress(char key)
|
||||
{
|
||||
m_main->OnKeyPress(key);
|
||||
}
|
||||
|
||||
void SampleRemoteWindowWin32::OnResize(int width, int height)
|
||||
{
|
||||
m_main->OnResize(width, height);
|
||||
}
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain1>
|
||||
SampleRemoteWindowWin32::CreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device, const DXGI_SWAP_CHAIN_DESC1* desc)
|
||||
{
|
||||
winrt::com_ptr<IDXGIDevice1> dxgiDevice;
|
||||
device.as(dxgiDevice);
|
||||
|
||||
winrt::com_ptr<IDXGIAdapter> dxgiAdapter;
|
||||
winrt::check_hresult(dxgiDevice->GetAdapter(dxgiAdapter.put()));
|
||||
|
||||
winrt::com_ptr<IDXGIFactory2> dxgiFactory;
|
||||
winrt::check_hresult(dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), dxgiFactory.put_void()));
|
||||
|
||||
winrt::check_hresult(dxgiFactory->MakeWindowAssociation(m_hWnd, DXGI_MWA_NO_ALT_ENTER));
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain1> swapChain = nullptr;
|
||||
winrt::check_hresult(dxgiFactory->CreateSwapChainForHwnd(device.get(), m_hWnd, desc, nullptr, nullptr, swapChain.put()));
|
||||
|
||||
return swapChain;
|
||||
}
|
||||
|
||||
void SampleRemoteWindowWin32::SetWindowTitle(std::wstring title)
|
||||
{
|
||||
if (m_hWnd)
|
||||
{
|
||||
if (!SetWindowTextW(m_hWnd, title.c_str()))
|
||||
{
|
||||
winrt::check_hresult(HRESULT_FROM_WIN32(GetLastError()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Graphics::Holographic::HolographicSpace SampleRemoteWindowWin32::CreateHolographicSpace()
|
||||
{
|
||||
// Use WinRT factory to create the holographic space.
|
||||
// See https://docs.microsoft.com/en-us/windows/win32/api/holographicspaceinterop/
|
||||
winrt::com_ptr<IHolographicSpaceInterop> holographicSpaceInterop =
|
||||
winrt::get_activation_factory<HolographicSpace, IHolographicSpaceInterop>();
|
||||
|
||||
winrt::com_ptr<ABI::Windows::Graphics::Holographic::IHolographicSpace> spHolographicSpace;
|
||||
winrt::check_hresult(holographicSpaceInterop->CreateForWindow(
|
||||
m_hWnd, __uuidof(ABI::Windows::Graphics::Holographic::IHolographicSpace), winrt::put_abi(spHolographicSpace)));
|
||||
|
||||
return spHolographicSpace.as<HolographicSpace>();
|
||||
}
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager SampleRemoteWindowWin32::CreateInteractionManager()
|
||||
{
|
||||
using namespace winrt::Windows::UI::Input::Spatial;
|
||||
|
||||
// Use WinRT factory to create the spatial interaction manager.
|
||||
// See https://docs.microsoft.com/en-us/windows/win32/api/spatialinteractionmanagerinterop/
|
||||
winrt::com_ptr<ISpatialInteractionManagerInterop> spatialInteractionManagerInterop =
|
||||
winrt::get_activation_factory<SpatialInteractionManager, ISpatialInteractionManagerInterop>();
|
||||
|
||||
winrt::com_ptr<ABI::Windows::UI::Input::Spatial::ISpatialInteractionManager> spSpatialInteractionManager;
|
||||
winrt::check_hresult(spatialInteractionManagerInterop->GetForWindow(
|
||||
m_hWnd, __uuidof(ABI::Windows::UI::Input::Spatial::ISpatialInteractionManager), winrt::put_abi(spSpatialInteractionManager)));
|
||||
|
||||
return spSpatialInteractionManager.as<SpatialInteractionManager>();
|
||||
}
|
||||
|
||||
int main(Platform::Array<Platform::String ^> ^ args)
|
||||
{
|
||||
winrt::init_apartment();
|
||||
|
||||
bool listen{false};
|
||||
std::wstring host;
|
||||
uint16_t port{0};
|
||||
uint16_t transportPort{0};
|
||||
bool isStandalone = false;
|
||||
bool noUserWait = false;
|
||||
bool useEphemeralPort = false;
|
||||
|
||||
for (unsigned int i = 1; i < args->Length; ++i)
|
||||
{
|
||||
if (args[i]->Length() == 0)
|
||||
continue;
|
||||
|
||||
std::wstring arg = args[i]->Data();
|
||||
if (arg[0] == '-')
|
||||
{
|
||||
std::wstring param = arg.substr(1);
|
||||
std::transform(param.begin(), param.end(), param.begin(), ::tolower);
|
||||
|
||||
if (param == L"listen")
|
||||
{
|
||||
listen = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param == L"standalone")
|
||||
{
|
||||
isStandalone = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param == L"nouserwait")
|
||||
{
|
||||
noUserWait = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param == L"ephemeralport")
|
||||
{
|
||||
useEphemeralPort = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param == L"transportport")
|
||||
{
|
||||
if (args->Length > i + 1)
|
||||
{
|
||||
std::wstring transportPortStr = args[i + 1]->Data();
|
||||
transportPort = std::stoi(transportPortStr);
|
||||
i++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
host = SplitHostnameAndPortString(arg, port);
|
||||
}
|
||||
|
||||
std::shared_ptr<SampleRemoteWindowWin32> sampleHostWindow = std::make_shared<SampleRemoteWindowWin32>();
|
||||
sampleHostWindow->Initialize();
|
||||
|
||||
WNDCLASSEXW wcex = {};
|
||||
wcex.cbSize = sizeof(wcex);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = wndProc;
|
||||
wcex.hInstance = 0;
|
||||
wcex.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wcex.hbrBackground = static_cast<HBRUSH>(GetStockObject(NULL_BRUSH));
|
||||
wcex.lpszClassName = WINDOWCLASSNAME;
|
||||
RegisterClassExW(&wcex);
|
||||
|
||||
RECT rc = {0, 0, INITIAL_WINDOW_WIDTH, INITIAL_WINDOW_HEIGHT};
|
||||
AdjustWindowRectEx(&rc, WS_OVERLAPPEDWINDOW, FALSE, 0);
|
||||
|
||||
std::wstring windowName = TITLE_TEXT;
|
||||
|
||||
HWND hWnd = CreateWindowW(
|
||||
WINDOWCLASSNAME,
|
||||
windowName.c_str(),
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
rc.right - rc.left,
|
||||
rc.bottom - rc.top,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0,
|
||||
sampleHostWindow.get());
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect(hWnd, &clientRect);
|
||||
|
||||
sampleHostWindow->InitializeHwnd(hWnd);
|
||||
|
||||
if (!isStandalone)
|
||||
{
|
||||
sampleHostWindow->ConfigureRemoting(listen, host, port, transportPort, useEphemeralPort);
|
||||
if (noUserWait)
|
||||
{
|
||||
sampleHostWindow->Connect();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sampleHostWindow->InitializeStandalone();
|
||||
}
|
||||
|
||||
ShowWindow(hWnd, SW_SHOWNORMAL);
|
||||
bool quit = false;
|
||||
while (!quit)
|
||||
{
|
||||
MSG msg = {0};
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.message == WM_QUIT)
|
||||
{
|
||||
quit = true;
|
||||
}
|
||||
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
sampleHostWindow->Tick();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Unhandeled exception during tick, exit program
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,41 +1,46 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
//#include <winrt/Windows.Graphics.Holographic.h>
|
||||
|
||||
#include "SampleHostMain.h"
|
||||
|
||||
// #define ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE
|
||||
|
||||
class SampleHostWindowWin32 : public std::enable_shared_from_this<SampleHostWindowWin32>, public SampleHostMain::IWindow
|
||||
{
|
||||
public:
|
||||
void Initialize(bool listen, const std::wstring& host, uint32_t port);
|
||||
|
||||
void InitializeHwnd(HWND hWnd);
|
||||
|
||||
void Tick();
|
||||
|
||||
void OnKeyPress(char key);
|
||||
void OnResize(int width, int height);
|
||||
|
||||
virtual winrt::com_ptr<IDXGISwapChain1>
|
||||
CreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device, const DXGI_SWAP_CHAIN_DESC1* desc) override;
|
||||
|
||||
virtual void SetWindowTitle(std::wstring title) override;
|
||||
|
||||
private:
|
||||
HWND m_hWnd = 0;
|
||||
|
||||
std::shared_ptr<SampleHostMain> m_main;
|
||||
};
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SampleRemoteMain.h>
|
||||
|
||||
class SampleRemoteWindowWin32 : public std::enable_shared_from_this<SampleRemoteWindowWin32>, public SampleRemoteMain::IWindow
|
||||
{
|
||||
public:
|
||||
void Initialize();
|
||||
|
||||
void InitializeHwnd(HWND hWnd);
|
||||
|
||||
void ConfigureRemoting(bool listen, const std::wstring& hostname, uint16_t port, uint16_t transportPort, bool ephemeralPort);
|
||||
void Connect();
|
||||
|
||||
void InitializeStandalone();
|
||||
|
||||
void Tick();
|
||||
|
||||
void OnKeyPress(char key);
|
||||
void OnResize(int width, int height);
|
||||
|
||||
virtual winrt::com_ptr<IDXGISwapChain1>
|
||||
CreateSwapChain(const winrt::com_ptr<ID3D11Device1>& device, const DXGI_SWAP_CHAIN_DESC1* desc) override;
|
||||
|
||||
virtual winrt::Windows::Graphics::Holographic::HolographicSpace CreateHolographicSpace() override;
|
||||
|
||||
virtual winrt::Windows::UI::Input::Spatial::SpatialInteractionManager CreateInteractionManager() override;
|
||||
|
||||
virtual void SetWindowTitle(std::wstring title) override;
|
||||
|
||||
private:
|
||||
HWND m_hWnd = 0;
|
||||
|
||||
std::shared_ptr<SampleRemoteMain> m_main;
|
||||
};
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<grammar xmlns="http://www.w3.org/2001/06/grammar" version="1.0" xml:lang="en-US" root="rootRule">
|
||||
<!-- The first way to load a grammer is by specifying a grammer.xml file according to the https://www.w3.org/TR/speech-grammar/ standard. -->
|
||||
<!-- See https://docs.microsoft.com/en-us/previous-versions/office/developer/speech-technologies/hh361658(v=office.14) for an example -->
|
||||
<rule id="rootRule">
|
||||
<one-of>
|
||||
<item>Load position</item>
|
||||
<item>Save position</item>
|
||||
</one-of>
|
||||
</rule>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<grammar xmlns="http://www.w3.org/2001/06/grammar" version="1.0" xml:lang="en-US" root="rootRule">
|
||||
<!-- The first way to load a grammer is by specifying a grammer.xml file according to the https://www.w3.org/TR/speech-grammar/ standard. -->
|
||||
<!-- See https://docs.microsoft.com/en-us/previous-versions/office/developer/speech-technologies/hh361658(v=office.14) for an example -->
|
||||
<rule id="rootRule">
|
||||
<one-of>
|
||||
<item>Load position</item>
|
||||
<item>Save position</item>
|
||||
</one-of>
|
||||
</rule>
|
||||
</grammar>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.200224.2" targetFramework="native" />
|
||||
<package id="Microsoft.Holographic.Remoting" version="2.1.0" targetFramework="native" />
|
||||
</packages>
|
|
@ -1,12 +1,12 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
|
@ -1,21 +1,21 @@
|
|||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <Unknwn.h>
|
||||
#include <robuffer.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <winrt/base.h>
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <Unknwn.h>
|
||||
#include <robuffer.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <winrt/base.h>
|
До Ширина: | Высота: | Размер: 1.4 KiB После Ширина: | Высота: | Размер: 1.4 KiB |
До Ширина: | Высота: | Размер: 7.5 KiB После Ширина: | Высота: | Размер: 7.5 KiB |
До Ширина: | Высота: | Размер: 2.9 KiB После Ширина: | Высота: | Размер: 2.9 KiB |
До Ширина: | Высота: | Размер: 1.6 KiB После Ширина: | Высота: | Размер: 1.6 KiB |
До Ширина: | Высота: | Размер: 1.2 KiB После Ширина: | Высота: | Размер: 1.2 KiB |