mirror of
https://github.com/servo/servo.git
synced 2025-09-10 06:58:21 +01:00
Add new hololens code (winrt + D3D immersive mode example)
This commit is contained in:
parent
13872eb254
commit
24d2213780
51 changed files with 4691 additions and 27 deletions
31
support/hololens/ServoApp/Content/GeometryShader.hlsl
Normal file
31
support/hololens/ServoApp/Content/GeometryShader.hlsl
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Per-vertex data from the vertex shader.
|
||||
struct GeometryShaderInput
|
||||
{
|
||||
min16float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint instId : TEXCOORD0;
|
||||
};
|
||||
|
||||
// Per-vertex data passed to the rasterizer.
|
||||
struct GeometryShaderOutput
|
||||
{
|
||||
min16float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
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.rtvId = input[i].instId;
|
||||
outStream.Append(output);
|
||||
}
|
||||
}
|
13
support/hololens/ServoApp/Content/PixelShader.hlsl
Normal file
13
support/hololens/ServoApp/Content/PixelShader.hlsl
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Per-pixel color data passed through the pixel shader.
|
||||
struct PixelShaderInput
|
||||
{
|
||||
min16float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
};
|
||||
|
||||
// The pixel shader passes through the color data. The color data from
|
||||
// is interpolated and assigned to a pixel at the rasterization step.
|
||||
min16float4 main(PixelShaderInput input) : SV_TARGET
|
||||
{
|
||||
return min16float4(input.color, 1.0f);
|
||||
}
|
20
support/hololens/ServoApp/Content/ShaderStructures.h
Normal file
20
support/hololens/ServoApp/Content/ShaderStructures.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
namespace Immersive {
|
||||
// Constant buffer used to send hologram position transform to the shader
|
||||
// pipeline.
|
||||
struct ModelConstantBuffer {
|
||||
DirectX::XMFLOAT4X4 model;
|
||||
};
|
||||
|
||||
// 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 VertexPositionColor {
|
||||
DirectX::XMFLOAT3 pos;
|
||||
DirectX::XMFLOAT3 color;
|
||||
};
|
||||
} // namespace Immersive
|
51
support/hololens/ServoApp/Content/SpatialInputHandler.cpp
Normal file
51
support/hololens/ServoApp/Content/SpatialInputHandler.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
#include "pch.h"
|
||||
#include "SpatialInputHandler.h"
|
||||
#include <functional>
|
||||
|
||||
using namespace Immersive;
|
||||
|
||||
using namespace std::placeholders;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Input::Spatial;
|
||||
|
||||
// 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 = SpatialInteractionManager::GetForCurrentView();
|
||||
|
||||
// Bind a handler to the SourcePressed event.
|
||||
m_sourcePressedEventToken = m_interactionManager.SourcePressed(
|
||||
bind(&SpatialInputHandler::OnSourcePressed, this, _1, _2));
|
||||
|
||||
//
|
||||
// TODO: Expand this class to use other gesture-based input events as
|
||||
// applicable to
|
||||
// your app.
|
||||
//
|
||||
}
|
||||
|
||||
SpatialInputHandler::~SpatialInputHandler() {
|
||||
// Unregister our handler for the OnSourcePressed event.
|
||||
m_interactionManager.SourcePressed(m_sourcePressedEventToken);
|
||||
}
|
||||
|
||||
// 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.
|
||||
SpatialInteractionSourceState SpatialInputHandler::CheckForInput() {
|
||||
SpatialInteractionSourceState sourceState = m_sourceState;
|
||||
m_sourceState = nullptr;
|
||||
return sourceState;
|
||||
}
|
||||
|
||||
void SpatialInputHandler::OnSourcePressed(
|
||||
SpatialInteractionManager const &,
|
||||
SpatialInteractionSourceEventArgs const &args) {
|
||||
m_sourceState = args.State();
|
||||
|
||||
//
|
||||
// TODO: In your app or game engine, rewrite this method to queue
|
||||
// input events in your input class or event handler.
|
||||
//
|
||||
}
|
34
support/hololens/ServoApp/Content/SpatialInputHandler.h
Normal file
34
support/hololens/ServoApp/Content/SpatialInputHandler.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
namespace Immersive {
|
||||
// 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();
|
||||
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionSourceState
|
||||
CheckForInput();
|
||||
|
||||
private:
|
||||
// Interaction event handler.
|
||||
void OnSourcePressed(
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager const
|
||||
&sender,
|
||||
winrt::Windows::UI::Input::Spatial::
|
||||
SpatialInteractionSourceEventArgs const &args);
|
||||
|
||||
// API objects used to process gesture input, and generate gesture events.
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionManager
|
||||
m_interactionManager = nullptr;
|
||||
|
||||
// Event registration token.
|
||||
winrt::event_token m_sourcePressedEventToken;
|
||||
|
||||
// Used to indicate that a Pressed input event was received this frame.
|
||||
winrt::Windows::UI::Input::Spatial::SpatialInteractionSourceState
|
||||
m_sourceState = nullptr;
|
||||
};
|
||||
} // namespace Immersive
|
266
support/hololens/ServoApp/Content/SpinningCubeRenderer.cpp
Normal file
266
support/hololens/ServoApp/Content/SpinningCubeRenderer.cpp
Normal file
|
@ -0,0 +1,266 @@
|
|||
#include "pch.h"
|
||||
#include "SpinningCubeRenderer.h"
|
||||
#include "Common/DirectXHelper.h"
|
||||
|
||||
using namespace Immersive;
|
||||
using namespace DirectX;
|
||||
using namespace winrt::Windows::Foundation::Numerics;
|
||||
using namespace winrt::Windows::UI::Input::Spatial;
|
||||
|
||||
// Loads vertex and pixel shaders from files and instantiates the cube geometry.
|
||||
SpinningCubeRenderer::SpinningCubeRenderer(
|
||||
std::shared_ptr<DX::DeviceResources> const &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(
|
||||
SpatialPointerPose const &pointerPose) {
|
||||
if (pointerPose != nullptr) {
|
||||
// Get the gaze direction relative to the given coordinate system.
|
||||
const float3 headPosition = pointerPose.Head().Position();
|
||||
const float3 headDirection = pointerPose.Head().ForwardDirection();
|
||||
|
||||
// The hologram is positioned two meters along the user's gaze direction.
|
||||
constexpr float distanceFromUser = 2.0f; // meters
|
||||
const float3 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(DX::StepTimer const &timer) {
|
||||
// Rotate the cube.
|
||||
// Convert degrees to radians, then convert seconds to rotation angle.
|
||||
const float radiansPerSecond = XMConvertToRadians(m_degreesPerSecond);
|
||||
const double totalRotation = timer.GetTotalSeconds() * radiansPerSecond;
|
||||
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);
|
||||
|
||||
// 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.
|
||||
const auto context = m_deviceResources->GetD3DDeviceContext();
|
||||
|
||||
// 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() {
|
||||
// Loading is asynchronous. Resources must be created before drawing can
|
||||
// occur.
|
||||
if (!m_loadingComplete) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto context = m_deviceResources->GetD3DDeviceContext();
|
||||
|
||||
// Each vertex is one instance of the VertexPositionColor struct.
|
||||
const UINT stride = sizeof(VertexPositionColor);
|
||||
const UINT offset = 0;
|
||||
context->IASetVertexBuffers(0, 1, m_vertexBuffer.GetAddressOf(), &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.
|
||||
context->VSSetConstantBuffers(0, 1, m_modelConstantBuffer.GetAddressOf());
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Attach the pixel shader.
|
||||
context->PSSetShader(m_pixelShader.Get(), nullptr, 0);
|
||||
|
||||
// Draw the objects.
|
||||
context->DrawIndexedInstanced(m_indexCount, // Index count per instance.
|
||||
2, // Instance count.
|
||||
0, // Start index location.
|
||||
0, // Base vertex location.
|
||||
0 // Start instance location.
|
||||
);
|
||||
}
|
||||
|
||||
std::future<void> SpinningCubeRenderer::CreateDeviceDependentResources() {
|
||||
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"ms-appx:///VprtVertexShader.cso"
|
||||
: L"ms-appx:///VertexShader.cso";
|
||||
|
||||
// Shaders will be loaded asynchronously.
|
||||
|
||||
// After the vertex shader file is loaded, create the shader and input layout.
|
||||
std::vector<byte> vertexShaderFileData =
|
||||
co_await DX::ReadDataAsync(vertexShaderFileName);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateVertexShader(
|
||||
vertexShaderFileData.data(), vertexShaderFileData.size(), nullptr,
|
||||
&m_vertexShader));
|
||||
|
||||
constexpr std::array<D3D11_INPUT_ELEMENT_DESC, 2> vertexDesc = {{
|
||||
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12,
|
||||
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));
|
||||
|
||||
// After the pixel shader file is loaded, create the shader and constant
|
||||
// buffer.
|
||||
std::vector<byte> pixelShaderFileData =
|
||||
co_await DX::ReadDataAsync(L"ms-appx:///PixelShader.cso");
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreatePixelShader(
|
||||
pixelShaderFileData.data(), pixelShaderFileData.size(), nullptr,
|
||||
&m_pixelShader));
|
||||
|
||||
const CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelConstantBuffer),
|
||||
D3D11_BIND_CONSTANT_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(
|
||||
&constantBufferDesc, nullptr, &m_modelConstantBuffer));
|
||||
|
||||
if (!m_usingVprtShaders) {
|
||||
// Load the pass-through geometry shader.
|
||||
std::vector<byte> geometryShaderFileData =
|
||||
co_await DX::ReadDataAsync(L"ms-appx:///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));
|
||||
}
|
||||
|
||||
// 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 std::array<VertexPositionColor, 8> cubeVertices = {{
|
||||
{XMFLOAT3(-0.1f, -0.1f, -0.1f), XMFLOAT3(0.0f, 0.0f, 0.0f)},
|
||||
{XMFLOAT3(-0.1f, -0.1f, 0.1f), XMFLOAT3(0.0f, 0.0f, 1.0f)},
|
||||
{XMFLOAT3(-0.1f, 0.1f, -0.1f), XMFLOAT3(0.0f, 1.0f, 0.0f)},
|
||||
{XMFLOAT3(-0.1f, 0.1f, 0.1f), XMFLOAT3(0.0f, 1.0f, 1.0f)},
|
||||
{XMFLOAT3(0.1f, -0.1f, -0.1f), XMFLOAT3(1.0f, 0.0f, 0.0f)},
|
||||
{XMFLOAT3(0.1f, -0.1f, 0.1f), XMFLOAT3(1.0f, 0.0f, 1.0f)},
|
||||
{XMFLOAT3(0.1f, 0.1f, -0.1f), XMFLOAT3(1.0f, 1.0f, 0.0f)},
|
||||
{XMFLOAT3(0.1f, 0.1f, 0.1f), XMFLOAT3(1.0f, 1.0f, 1.0f)},
|
||||
}};
|
||||
|
||||
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
|
||||
vertexBufferData.pSysMem = cubeVertices.data();
|
||||
vertexBufferData.SysMemPitch = 0;
|
||||
vertexBufferData.SysMemSlicePitch = 0;
|
||||
const CD3D11_BUFFER_DESC vertexBufferDesc(
|
||||
sizeof(VertexPositionColor) * static_cast<UINT>(cubeVertices.size()),
|
||||
D3D11_BIND_VERTEX_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(
|
||||
&vertexBufferDesc, &vertexBufferData, &m_vertexBuffer));
|
||||
|
||||
// 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.
|
||||
constexpr std::array<unsigned short, 36> 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 = static_cast<unsigned int>(cubeIndices.size());
|
||||
|
||||
D3D11_SUBRESOURCE_DATA indexBufferData = {0};
|
||||
indexBufferData.pSysMem = cubeIndices.data();
|
||||
indexBufferData.SysMemPitch = 0;
|
||||
indexBufferData.SysMemSlicePitch = 0;
|
||||
CD3D11_BUFFER_DESC indexBufferDesc(sizeof(unsigned short) *
|
||||
static_cast<UINT>(cubeIndices.size()),
|
||||
D3D11_BIND_INDEX_BUFFER);
|
||||
winrt::check_hresult(m_deviceResources->GetD3DDevice()->CreateBuffer(
|
||||
&indexBufferDesc, &indexBufferData, &m_indexBuffer));
|
||||
|
||||
// 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.Reset();
|
||||
m_inputLayout.Reset();
|
||||
m_pixelShader.Reset();
|
||||
m_geometryShader.Reset();
|
||||
m_modelConstantBuffer.Reset();
|
||||
m_vertexBuffer.Reset();
|
||||
m_indexBuffer.Reset();
|
||||
}
|
57
support/hololens/ServoApp/Content/SpinningCubeRenderer.h
Normal file
57
support/hololens/ServoApp/Content/SpinningCubeRenderer.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
#pragma once
|
||||
|
||||
#include "../Common/DeviceResources.h"
|
||||
#include "../Common/StepTimer.h"
|
||||
#include "ShaderStructures.h"
|
||||
|
||||
namespace Immersive {
|
||||
// This sample renderer instantiates a basic rendering pipeline.
|
||||
class SpinningCubeRenderer {
|
||||
public:
|
||||
SpinningCubeRenderer(
|
||||
std::shared_ptr<DX::DeviceResources> const &deviceResources);
|
||||
std::future<void> CreateDeviceDependentResources();
|
||||
void ReleaseDeviceDependentResources();
|
||||
void Update(DX::StepTimer const &timer);
|
||||
void Render();
|
||||
|
||||
// Repositions the sample hologram.
|
||||
void
|
||||
PositionHologram(winrt::Windows::UI::Input::Spatial::SpatialPointerPose const
|
||||
&pointerPose);
|
||||
|
||||
// Property accessors.
|
||||
void SetPosition(winrt::Windows::Foundation::Numerics::float3 const &pos) {
|
||||
m_position = pos;
|
||||
}
|
||||
winrt::Windows::Foundation::Numerics::float3 const &GetPosition() {
|
||||
return m_position;
|
||||
}
|
||||
|
||||
private:
|
||||
// Cached pointer to device resources.
|
||||
std::shared_ptr<DX::DeviceResources> m_deviceResources;
|
||||
|
||||
// Direct3D resources for cube geometry.
|
||||
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;
|
||||
Microsoft::WRL::ComPtr<ID3D11Buffer> m_vertexBuffer;
|
||||
Microsoft::WRL::ComPtr<ID3D11Buffer> m_indexBuffer;
|
||||
Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vertexShader;
|
||||
Microsoft::WRL::ComPtr<ID3D11GeometryShader> m_geometryShader;
|
||||
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pixelShader;
|
||||
Microsoft::WRL::ComPtr<ID3D11Buffer> m_modelConstantBuffer;
|
||||
|
||||
// System resources for cube geometry.
|
||||
ModelConstantBuffer m_modelConstantBufferData;
|
||||
uint32_t m_indexCount = 0;
|
||||
|
||||
// Variables used with the rendering loop.
|
||||
bool m_loadingComplete = false;
|
||||
float m_degreesPerSecond = 45.f;
|
||||
winrt::Windows::Foundation::Numerics::float3 m_position = {0.f, 0.f, -2.f};
|
||||
|
||||
// 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;
|
||||
};
|
||||
} // namespace Immersive
|
11
support/hololens/ServoApp/Content/VPRTVertexShader.hlsl
Normal file
11
support/hololens/ServoApp/Content/VPRTVertexShader.hlsl
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Per-vertex data passed to the geometry shader.
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
min16float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
|
||||
// The render target array index is set here in the vertex shader.
|
||||
uint viewId : SV_RenderTargetArrayIndex;
|
||||
};
|
||||
|
||||
#include "VertexShaderShared.hlsl"
|
11
support/hololens/ServoApp/Content/VertexShader.hlsl
Normal file
11
support/hololens/ServoApp/Content/VertexShader.hlsl
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Per-vertex data passed to the geometry shader.
|
||||
struct VertexShaderOutput
|
||||
{
|
||||
min16float4 pos : SV_POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
|
||||
// The render target array index will be set by the geometry shader.
|
||||
uint viewId : TEXCOORD0;
|
||||
};
|
||||
|
||||
#include "VertexShaderShared.hlsl"
|
47
support/hololens/ServoApp/Content/VertexShaderShared.hlsl
Normal file
47
support/hololens/ServoApp/Content/VertexShaderShared.hlsl
Normal file
|
@ -0,0 +1,47 @@
|
|||
// A constant buffer that stores the model transform.
|
||||
cbuffer ModelConstantBuffer : 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
|
||||
{
|
||||
min16float3 pos : POSITION;
|
||||
min16float3 color : COLOR0;
|
||||
uint instId : SV_InstanceID;
|
||||
};
|
||||
|
||||
// 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]);
|
||||
output.pos = (min16float4)pos;
|
||||
|
||||
// Pass the color through without modification.
|
||||
output.color = input.color;
|
||||
|
||||
// Set the render target array index.
|
||||
output.viewId = idx;
|
||||
|
||||
return output;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue