Holographic Remoting version 2.1.0 (#6)

* version 2.1.0

* updated .gitignore file

Co-authored-by: Florian Bagar <flbagar@microsoft.com>
This commit is contained in:
FlorianBagarMicrosoft 2020-03-11 14:28:05 +01:00 коммит произвёл GitHub
Родитель d6ff35e13a
Коммит 012a50e416
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
152 изменённых файлов: 16857 добавлений и 15177 удалений

3
.gitignore поставляемый
Просмотреть файл

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

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 7.5 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичные данные
hostsampleapp/uwp/Assets/StoreLogo.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 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;
}

20
player/sample/LICENSE Normal file
Просмотреть файл

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

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше