port from perforce

This commit is contained in:
2026-04-18 22:31:51 +02:00
commit 8d0ab5b7cc
8409 changed files with 3972376 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
#include "Stdafx.hpp"
#include "ArcBall.hpp"
ArcBall::ArcBall()
{
Reset();
}
void ArcBall::Reset()
{
m_Down = mt::Quaternion::identity;
m_Now = mt::Quaternion::identity;
m_bDrag = false;
m_fRadius = 1.0f;
}
void ArcBall::SetWindow(float _fWidth, float _fHeight, float _fRadius)
{
m_fWidth = _fWidth;
m_fHeight = _fHeight;
m_fRadius = _fRadius;
}
void ArcBall::OnBegin(float _fX, float _fY)
{
// Only enter the drag state if the click falls inside the click rectangle.
if (_fX >= 0 &&
_fX < m_fWidth &&
_fY >= 0 &&
_fY < m_fHeight)
{
m_bDrag = true;
m_Down = m_Now;
m_DownPoint = ScreenToVector(_fX, _fY);
}
}
void ArcBall::OnMove(float _fX, float _fY)
{
if (m_bDrag)
{
m_CurrentPoint = ScreenToVector(_fX, _fY);
m_Now = mt::Quaternion::FromTo(m_DownPoint, m_CurrentPoint) * m_Down;
}
}
void ArcBall::OnEnd()
{
m_bDrag = false;
}
mt::Matrix ArcBall::GetRotationMatrix()
{
return mt::Matrix::FromQuaternion(m_Now);
}
mt::vec3 ArcBall::ScreenToVector(float _fX, float _fY)
{
// Scale to screen
float x = -(_fX - m_fWidth / 2.0f) / (m_fRadius * m_fWidth / 2.0f);
float y = (_fY - m_fHeight / 2.0f) / (m_fRadius * m_fHeight / 2.0f);
float z = 0.0f;
float fMag = x * x + y * y;
if (fMag > 1.0f)
{
float fScale = 1.0f / sqrtf(fMag);
x *= fScale;
y *= fScale;
}
else
{
z = sqrtf(1.0f - fMag);
}
// Return vector
return mt::vec3(x, y, z);
}

View File

@@ -0,0 +1,32 @@
#pragma once
class ArcBall
{
public:
void Reset();
void SetWindow(float _fWidth, float _fHeight, float _fRadius = 1.0f);
void OnBegin(float _fX, float _fY);
void OnMove(float _fX, float _fY);
void OnEnd();
mt::Matrix GetRotationMatrix();
public:
ArcBall();
private:
mt::vec3 ScreenToVector(float _fX, float _fY);
private:
float m_fWidth; // arc ball's window width
float m_fHeight; // arc ball's window height
float m_fRadius; // arc ball's radius in screen coords
mt::Quaternion m_Down; // Quaternion before button down
mt::Quaternion m_Now; // Composite quaternion for current drag
bool m_bDrag; // Whether user is dragging arc ball
mt::vec3 m_DownPoint; // starting point of rotation arc
mt::vec3 m_CurrentPoint; // current point of rotation arc
};

View File

@@ -0,0 +1,38 @@
#include "Stdafx.hpp"
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly:AssemblyTitleAttribute(L"Interop")];
[assembly:AssemblyDescriptionAttribute(L"")];
[assembly:AssemblyConfigurationAttribute(L"")];
[assembly:AssemblyCompanyAttribute(L"")];
[assembly:AssemblyProductAttribute(L"Interop")];
[assembly:AssemblyCopyrightAttribute(L"Copyright (c) 2016")];
[assembly:AssemblyTrademarkAttribute(L"")];
[assembly:AssemblyCultureAttribute(L"")];
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the value or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly:AssemblyVersionAttribute("1.0.*")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];

View File

@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{306104A5-EEEE-4789-847A-07869D715550}</ProjectGuid>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<Keyword>ManagedCProj</Keyword>
<RootNamespace>Interop</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CLRSupport>true</CLRSupport>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CLRSupport>true</CLRSupport>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)bin\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)obj\$(Configuration)\$(ProjectName)\</IntDir>
<IncludePath>$(SolutionDir)src\Lib;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)lib\$(Configuration)\;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)obj\$(Configuration)\$(ProjectName)\</IntDir>
<IncludePath>$(SolutionDir)src\Lib;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)lib\$(Configuration)\;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>stdafx.hpp</PrecompiledHeaderFile>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Lib.lib;d3d11.lib;DXGI.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>stdafx.hpp</PrecompiledHeaderFile>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Lib.lib;d3d11.lib;DXGI.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ArcBall.hpp" />
<ClInclude Include="Viewer.hpp" />
<ClInclude Include="Stdafx.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ArcBall.cpp" />
<ClCompile Include="AssemblyInfo.cpp" />
<ClCompile Include="Viewer.cpp" />
<ClCompile Include="Stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lib\Lib.vcxproj">
<Project>{fdebd01e-0317-4400-9208-58d7dd7cee44}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<FxCompile Include="MeshVertexShader.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>
</FxCompile>
<FxCompile Include="MeshPixelShader.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
</FxCompile>
<FxCompile Include="SelectionPixelShader.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
</FxCompile>
</ItemGroup>
<ItemGroup>
<Natvis Include="List.natvis">
<SubType>Designer</SubType>
</Natvis>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ArcBall.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Viewer.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Stdafx.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="AssemblyInfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Viewer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ArcBall.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<FxCompile Include="MeshPixelShader.hlsl" />
<FxCompile Include="MeshVertexShader.hlsl" />
<FxCompile Include="SelectionPixelShader.hlsl" />
</ItemGroup>
<ItemGroup>
<Natvis Include="List.natvis" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>true</ShowAllFiles>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="List&lt;*&gt;">
<DisplayString Condition="count == 0">empty</DisplayString>
<DisplayString>{{ size={count} }}</DisplayString>
<Expand>
<ArrayItems>
<Size>count</Size>
<ValuePointer>data</ValuePointer>
</ArrayItems>
<Item Name="[size]" ExcludeView="simple">count</Item>
<Item Name="[capacity]" ExcludeView="simple">capacity</Item>
</Expand>
</Type>
</AutoVisualizer>

View File

@@ -0,0 +1,5 @@
float4 main(in float4 result : SV_POSITION, in float3 normal : NORMAL, in float4 uv : TEXCOORD) : SV_TARGET
{
float l = dot(normal, normalize(float3(1, 0.5, 0.25))) * 0.5 + 0.5;
return float4(l, l, l, 1.0f);
}

View File

@@ -0,0 +1,35 @@
cbuffer cb0 : register (b0)
{
float aspectRatio;
float distanceToCenter;
float dummy2;
float dummy3;
float4x4 modelRotation;
float4 pivot;
}
float4x4 getProjMatrix()
{
float yScale = 2.4142135623730950488016887242097;//cot(fovY/2)
float xScale = yScale / aspectRatio;
float n = 0.1f;
float f = 100.0f;
float4x4 proj =
{
xScale, 0, 0, 0,
0, yScale, 0, 0,
0, 0, f/(f-n), 1,
0, 0, -n*f/(f-n), 0
};
return proj;
}
void main(in float3 pos : POSITION, out float4 result : SV_POSITION, inout float3 normal : NORMAL, inout float4 uv : TEXCOORD)
{
float4 v = float4(pos, 1);
v.xyz -= pivot.xyz;
v = mul(v, modelRotation);
v.z += distanceToCenter;
v = mul(v, getProjMatrix());
result = v;
}

View File

@@ -0,0 +1,6 @@
float4 main(in float4 result : SV_POSITION, in float3 normal : NORMAL, in float4 uv : TEXCOORD) : SV_TARGET
{
int2 wuv = result.xy;
float l = (wuv.x ^ wuv.y) % 4;
return float4(0.25, 0.5, 0.75, l * 0.5f);
}

View File

@@ -0,0 +1,5 @@
// stdafx.cpp : source file that includes just the standard includes
// Interop.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.hpp"

View File

@@ -0,0 +1,8 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#pragma once
#include <mt\mt.h>
#include "ArcBall.hpp"

View File

@@ -0,0 +1,642 @@
#include "Stdafx.hpp"
#include "Viewer.hpp"
#include "../Lib/mt/operators/OpDocument.h"
#include <DXGItype.h>
#include <dxgi1_2.h>
#include <dxgi1_3.h>
#include <DXProgrammableCapture.h>
using namespace System::Linq;
static D3D11_RASTERIZER_DESC rsSolidCullBackDesc =
{
D3D11_FILL_SOLID,
D3D11_CULL_BACK,
FALSE,
0,
0,
0,
TRUE,
FALSE,
FALSE,
FALSE
};
static D3D11_RASTERIZER_DESC rsWireframeCullBackDesc =
{
D3D11_FILL_WIREFRAME,
D3D11_CULL_BACK,
FALSE,
0,
0,
0,
TRUE,
FALSE,
FALSE,
FALSE
};
static D3D11_RASTERIZER_DESC rsSolidCullNoneDesc =
{
D3D11_FILL_SOLID,
D3D11_CULL_NONE,
FALSE,
0,
0,
0,
TRUE,
FALSE,
FALSE,
FALSE
};
static D3D11_RASTERIZER_DESC rsWireframeCullNoneDesc =
{
D3D11_FILL_WIREFRAME,
D3D11_CULL_NONE,
FALSE,
0,
0,
0,
TRUE,
FALSE,
FALSE,
FALSE
};
static D3D11_DEPTH_STENCIL_DESC depthStencilDesc =
{
TRUE,
D3D11_DEPTH_WRITE_MASK_ALL,
D3D11_COMPARISON_LESS_EQUAL,
FALSE,
D3D11_DEFAULT_STENCIL_READ_MASK,
D3D11_DEFAULT_STENCIL_WRITE_MASK,
{
D3D11_STENCIL_OP_KEEP,
D3D11_STENCIL_OP_KEEP,
D3D11_STENCIL_OP_KEEP,
D3D11_COMPARISON_ALWAYS
},
{
D3D11_STENCIL_OP_KEEP,
D3D11_STENCIL_OP_KEEP,
D3D11_STENCIL_OP_KEEP,
D3D11_COMPARISON_ALWAYS
}
};
static D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc =
{
DXGI_FORMAT_D32_FLOAT,
D3D11_DSV_DIMENSION_TEXTURE2DMS,
0
};
static D3D11_RENDER_TARGET_VIEW_DESC backBufferRTVdesc =
{
DXGI_FORMAT_B8G8R8A8_UNORM,
D3D11_RTV_DIMENSION_TEXTURE2DMS,
{ 0 }
};
static D3D11_BLEND_DESC alphaBlendDesc =
{
FALSE,
FALSE,
{
TRUE,
D3D11_BLEND_SRC_ALPHA,
D3D11_BLEND_INV_SRC_ALPHA,
D3D11_BLEND_OP_ADD,
D3D11_BLEND_ZERO,
D3D11_BLEND_ZERO,
D3D11_BLEND_OP_ADD,
0x0F
}
};
static D3D11_VIEWPORT viewPort =
{
0, 0, 0, 0, 0, 1
};
static D3D_FEATURE_LEVEL featureLevel[] = { D3D_FEATURE_LEVEL_11_0 };
static D3D11_INPUT_ELEMENT_DESC inputElementDescs[] =
{
{
"POSITION", 0,
DXGI_FORMAT_R32G32B32_FLOAT,
0,
0, //AlignedByteOffset;
D3D11_INPUT_PER_VERTEX_DATA,
0
},
{
"NORMAL", 0,
DXGI_FORMAT_R32G32B32_FLOAT,
0,
12, //AlignedByteOffset;
D3D11_INPUT_PER_VERTEX_DATA,
0
},
{
"TEXCOORD", 0,
DXGI_FORMAT_R32G32B32A32_FLOAT,
0,
24, //AlignedByteOffset;
D3D11_INPUT_PER_VERTEX_DATA,
0
}
};
static DXGI_SWAP_CHAIN_DESC swapChainDesc =
{
{
0,
0,
{ 60, 1 },
DXGI_FORMAT_B8G8R8A8_UNORM,
DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED,
DXGI_MODE_SCALING_UNSPECIFIED
},
{
8,
(UINT)-1
},
DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT,
1,
0,
TRUE,
DXGI_SWAP_EFFECT_DISCARD,
0
};
static D3D11_BUFFER_DESC constantBufferDesc =
{
(
4 + // float aspectRatio + 3 dummies
(4 * 4) + // float4 modelRotation
4 // pivot
) * sizeof(float),
D3D11_USAGE_DYNAMIC,
D3D11_BIND_CONSTANT_BUFFER,
D3D11_CPU_ACCESS_WRITE,
0,
0
};
#ifdef _DEBUG
#define D3D_DEVICE_FLAGS D3D11_CREATE_DEVICE_DEBUG
#else
#define D3D_DEVICE_FLAGS 0
#endif
#pragma bss_seg(".bss")
ID3D11Device* device = nullptr;
ID3D11DeviceContext* context = nullptr;
IDXGISwapChain* swapChain = nullptr;
ID3D11Texture2D* backBufferTexture = nullptr;
ID3D11Texture2D* depthStencilBuffer = nullptr;
ID3D11InputLayout* inputLayout = nullptr;
ID3D11BlendState* alphaBlendState = nullptr;
ID3D11RenderTargetView* backBufferRTV = nullptr;
ID3D11RasterizerState* rsSolidCullBack = nullptr;
ID3D11RasterizerState* rsWireframeCullBack = nullptr;
ID3D11RasterizerState* rsSolidCullNone = nullptr;
ID3D11RasterizerState* rsWireframeCullNone = nullptr;
ID3D11DepthStencilState* depthStencilState = nullptr;
ID3D11DepthStencilView* depthStencilView = nullptr;
ID3D11VertexShader* vertexShader = nullptr;
ID3D11PixelShader* pixelShader = nullptr;
ID3D11PixelShader* selPixelShader = nullptr;
ID3D11Buffer* vertexBuffer = nullptr;
ID3D11Buffer* indexBuffer = nullptr;
ID3D11Buffer* selIndexBuffer = nullptr;
ID3D11Buffer* constantBuffer = nullptr;
unsigned int indexCount = 0;
unsigned int selIndexCount = 0;
bool drawWireframe = false;
bool backFaceCulling = false;
#pragma code_seg(".code")
IntPtr Interop::Viewer::DevicePtr::get()
{
return IntPtr::IntPtr(device);
}
bool Interop::Viewer::Wireframe::get()
{
return drawWireframe;
}
void Interop::Viewer::Wireframe::set(bool value)
{
drawWireframe = value;
}
bool Interop::Viewer::BackFaceCulling::get()
{
return backFaceCulling;
}
void Interop::Viewer::BackFaceCulling::set(bool value)
{
backFaceCulling = value;
}
Interop::Viewer::Viewer()
{
}
void Interop::Viewer::Init(IntPtr _hWnd, int _iWidth, int _iHeight)
{
m_ArcBall = new ArcBall();
swapChainDesc.OutputWindow = (HWND)_hWnd.ToPointer();
swapChainDesc.BufferDesc.Width = _iWidth;
swapChainDesc.BufferDesc.Height = _iHeight;
D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D_DEVICE_FLAGS, featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, NULL, &context);
swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBufferTexture);
device->CreateRenderTargetView(backBufferTexture, &backBufferRTVdesc, &backBufferRTV);
device->CreateBlendState(&alphaBlendDesc, &alphaBlendState);
device->CreateDepthStencilState(&depthStencilDesc, &depthStencilState);
device->CreateRasterizerState(&rsSolidCullBackDesc, &rsSolidCullBack);
device->CreateRasterizerState(&rsWireframeCullBackDesc, &rsWireframeCullBack);
device->CreateRasterizerState(&rsSolidCullNoneDesc, &rsSolidCullNone);
device->CreateRasterizerState(&rsWireframeCullNoneDesc, &rsWireframeCullNone);
auto vsCode = System::IO::File::ReadAllBytes("MeshVertexShader.cso");
pin_ptr<unsigned char> pVsCode = &vsCode[0];
device->CreateVertexShader(pVsCode, vsCode->Length, NULL, &vertexShader);
device->CreateInputLayout(inputElementDescs, 3, pVsCode, vsCode->Length, &inputLayout);
auto psCode = System::IO::File::ReadAllBytes("MeshPixelShader.cso");
pin_ptr<unsigned char> pPsCode = &psCode[0];
device->CreatePixelShader(pPsCode, psCode->Length, NULL, &pixelShader);
psCode = System::IO::File::ReadAllBytes("SelectionPixelShader.cso");
pPsCode = &psCode[0];
device->CreatePixelShader(pPsCode, psCode->Length, NULL, &selPixelShader);
device->CreateBuffer(&constantBufferDesc, NULL, &constantBuffer);
CreateTextures(_iWidth, _iHeight);
}
template <typename T>
void CreateVertexBuffer(ID3D11Buffer** _vertexBuffer, const List<T>& _data)
{
D3D11_BUFFER_DESC vertexBufferDesc =
{
sizeof(T) * _data.Count(),
D3D11_USAGE_DEFAULT,
D3D11_BIND_VERTEX_BUFFER,
0,
0,
0
};
static D3D11_SUBRESOURCE_DATA vertexData =
{
&_data[0],
sizeof(T),
vertexBufferDesc.ByteWidth
};
device->CreateBuffer(&vertexBufferDesc, &vertexData, _vertexBuffer);
}
void CreateIndexBuffer(ID3D11Buffer** _indexBuffer, const List<unsigned int>& _data)
{
D3D11_BUFFER_DESC indexBufferDesc =
{
sizeof(unsigned int) * _data.Count(),
D3D11_USAGE_DEFAULT,
D3D11_BIND_INDEX_BUFFER,
0,
0,
0
};
D3D11_SUBRESOURCE_DATA indexData =
{
&_data[0],
sizeof(unsigned int),
indexBufferDesc.ByteWidth
};
device->CreateBuffer(&indexBufferDesc, &indexData, _indexBuffer);
}
void Interop::Viewer::LoadDocument(array<System::Byte>^ _data)
{
auto parser = new mt::Parser();
pin_ptr<unsigned char> pData = &_data[0];
auto doc = parser->ParseDocument(pData);
LoadOpMesh(doc->GetMesh(1));
}
void Interop::Viewer::LoadOpMesh(mt::OpMesh* _mesh)
{
m_Mesh = _mesh;
auto vertices = m_Mesh->GetMesh()->GetRawVertices();
auto indicies = m_Mesh->GetMesh()->GetIndices(false);
::CreateVertexBuffer(&vertexBuffer, vertices);
::CreateIndexBuffer(&indexBuffer, indicies);
indexCount = indicies.Count();
auto selIndicies = m_Mesh->GetSelectedFaceIndices();
selIndexCount = selIndicies.Count();
if (selIndexCount)
{
::CreateIndexBuffer(&selIndexBuffer, selIndicies);
}
}
void Interop::Viewer::CreateTextures(int _iWidth, int _iHeight)
{
viewPort.Width = (float)_iWidth;
viewPort.Height = (float)_iHeight;
D3D11_TEXTURE2D_DESC depthStencilBufferDesc =
{
(UINT)_iWidth,
(UINT)_iHeight,
1u,
1u,
DXGI_FORMAT_R32_TYPELESS,
{
8,
(UINT)-1
},
D3D11_USAGE_DEFAULT,
D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE,
0,
0
};
device->CreateTexture2D(&depthStencilBufferDesc, NULL, &depthStencilBuffer);
device->CreateDepthStencilView(depthStencilBuffer, &depthStencilViewDesc, &depthStencilView);
m_ArcBall->SetWindow((float)_iWidth, (float)_iHeight);
UpdateConstantBuffer();
}
void Interop::Viewer::UpdateConstantBuffer()
{
mt::Matrix mat;
if (m_ArcBall != NULL)
mat = m_ArcBall->GetRotationMatrix();
D3D11_MAPPED_SUBRESOURCE mapped;
context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
float* data = (float*)mapped.pData;
int i = 0;
data[i++] = (float)viewPort.Width / (float)viewPort.Height; // aspectRatio;
data[i++] = m_fDistanceToCenter; // distanceToCenter
data[i++] = 0; // unused
data[i++] = 0; // unused
data[i++] = mat.M11; // rotation matrix
data[i++] = mat.M21;
data[i++] = mat.M31;
data[i++] = mat.M41;
data[i++] = mat.M12;
data[i++] = mat.M22;
data[i++] = mat.M32;
data[i++] = mat.M42;
data[i++] = mat.M13;
data[i++] = mat.M23;
data[i++] = mat.M33;
data[i++] = mat.M43;
data[i++] = mat.M14;
data[i++] = mat.M24;
data[i++] = mat.M34;
data[i++] = mat.M44;
data[i++] = m_fPivotX;
data[i++] = m_fPivotY;
data[i++] = m_fPivotZ;
data[i++] = 1; // pivot.w
context->Unmap(constantBuffer, 0);
}
void Interop::Viewer::DisposeTextures()
{
depthStencilBuffer->Release();
depthStencilView->Release();
}
void Interop::Viewer::Resize(int _iWidth, int _iHeight)
{
if (swapChain == nullptr)
return;
DisposeTextures();
backBufferTexture->Release();
backBufferRTV->Release();
swapChain->ResizeBuffers(1, _iWidth, _iHeight, DXGI_FORMAT_B8G8R8A8_UNORM, 0);
swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBufferTexture);
device->CreateRenderTargetView(backBufferTexture, &backBufferRTVdesc, &backBufferRTV);
CreateTextures(_iWidth, _iHeight);
}
void Interop::Viewer::CaptureFrame()
{
m_bCaptureFrame = true;
}
void Interop::Viewer::MouseDown(bool _bLeftButton, int _iX, int _iY)
{
m_bDragging = true;
if (_bLeftButton)
{
m_bLeftDrag = true;
m_ArcBall->OnBegin((float)_iX, (float)_iY);
}
else
{
m_iLastDragX = _iX;
m_iLastDragY = _iY;
m_bLeftDrag = false;
}
}
void Interop::Viewer::Frame(const List<mt::RawVertex>& _vertices)
{
mt::vec3 vmin = mt::vec3(FLT_MAX, FLT_MAX, FLT_MAX);
mt::vec3 vmax = mt::vec3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
for (auto vertex : _vertices)
{
vmin = mt::vec3::Min(vmin, vertex.Position);
vmax = mt::vec3::Max(vmax, vertex.Position);
}
auto center = (vmin + vmax) / 2;
float fMaxDistance = 0.0f;
for (auto vertex : _vertices)
{
fMaxDistance = max(fMaxDistance, mt::vec3::Distance(center, vertex.Position));
}
m_fDistanceToCenter = fMaxDistance * 2.0f;
m_fPivotX = center.x;
m_fPivotY = center.y;
m_fPivotZ = center.z;
UpdateConstantBuffer();
}
void Interop::Viewer::FrameSelection()
{
auto vertices = m_Mesh->GetSelectedFaceVertices();
Frame(vertices);
}
void Interop::Viewer::FrameAll()
{
auto vertices = m_Mesh->GetMesh()->GetRawVertices();
Frame(vertices);
}
void Interop::Viewer::MouseMove(int _iX, int _iY)
{
if (!m_bDragging)
return;
if (m_bLeftDrag)
{
m_ArcBall->OnMove((float)_iX, (float)_iY);
}
else
{
auto iDeltaX = _iX - m_iLastDragX;
auto iDeltaY = m_iLastDragY - _iY;
float fDeltaX = (float)iDeltaX / viewPort.Width;
float fDeltaY = (float)iDeltaY / viewPort.Height;
float mag = fDeltaX + fDeltaY;
if (mag > 0)
{
m_fDistanceToCenter /= 1.0f + mag;
}
else
{
m_fDistanceToCenter *= 1.0f - mag;
}
m_iLastDragX = _iX;
m_iLastDragY = _iY;
}
UpdateConstantBuffer();
}
void Interop::Viewer::MouseUp(int _iX, int _iY)
{
m_bDragging = false;
if (m_bLeftDrag)
{
m_ArcBall->OnEnd();
}
}
void Interop::Viewer::Render()
{
IDXGraphicsAnalysis* pGraphicsAnalysis = nullptr;
if (m_bCaptureFrame)
{
HRESULT getAnalysis = DXGIGetDebugInterface1(0, __uuidof(pGraphicsAnalysis), reinterpret_cast<void**>(&pGraphicsAnalysis));
if (FAILED(getAnalysis))
{
pGraphicsAnalysis = nullptr;
}
if (pGraphicsAnalysis != nullptr)
{
pGraphicsAnalysis->BeginCapture();
m_bCaptureFrame = false;
}
}
static char zero[] = { 0, 0, 0, 0 };
static float color[] = { 0, 0, 1, 1 };
UINT stride = sizeof(mt::RawVertex);
UINT offset = 0;
context->ClearRenderTargetView(backBufferRTV, color);
context->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
context->IASetInputLayout(inputLayout);
context->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);
context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
context->VSSetConstantBuffers(0, 1, &constantBuffer);
context->VSSetShader(vertexShader, NULL, 0);
context->PSSetShader(pixelShader, NULL, 0);
context->RSSetViewports(1, &viewPort);
if (backFaceCulling)
{
context->RSSetState(drawWireframe ? rsWireframeCullBack : rsSolidCullBack);
}
else
{
context->RSSetState(drawWireframe ? rsWireframeCullNone : rsSolidCullNone);
}
context->OMSetBlendState(alphaBlendState, NULL, -1);
context->OMSetDepthStencilState(depthStencilState, 0);
context->OMSetRenderTargets(1, &backBufferRTV, depthStencilView);
context->DrawIndexed(indexCount, 0, 0);
context->RSSetState(backFaceCulling ? rsSolidCullBack : rsSolidCullNone);
context->IASetIndexBuffer(selIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
context->PSSetShader(selPixelShader, NULL, 0);
context->DrawIndexed(selIndexCount, 0, 0);
context->IASetIndexBuffer(NULL, DXGI_FORMAT_R32_UINT, 0);
context->IASetVertexBuffers(0, 1, (ID3D11Buffer* const*)zero, (const UINT*)zero, (const UINT*)zero);
context->OMSetRenderTargets(1, (ID3D11RenderTargetView* const*)zero, NULL);
if (pGraphicsAnalysis != nullptr)
{
pGraphicsAnalysis->EndCapture();
pGraphicsAnalysis->Release();
pGraphicsAnalysis = nullptr;
}
swapChain->Present(1, 0);
}

View File

@@ -0,0 +1,81 @@
// Interop.h
#pragma once
#include <d3d11.h>
using namespace System;
namespace Interop
{
public ref class Viewer
{
public:
static property Viewer^ Instance
{
public:
Viewer^ get()
{
if (s_Instance == nullptr)
{
s_Instance = gcnew Viewer();
}
return s_Instance;
}
}
property IntPtr DevicePtr
{
public:
IntPtr get();
}
property bool Wireframe
{
public:
bool get();
void set(bool _value);
}
property bool BackFaceCulling
{
public:
bool get();
void set(bool _value);
}
void Init(IntPtr _hWnd, int _iWidth, int _iHeight);
void Resize(int _iWidth, int _iHeight);
void MouseDown(bool _bLeftButton, int _iX, int _iY);
void MouseMove(int _iX, int _iY);
void MouseUp(int _iX, int _iY);
void FrameSelection();
void FrameAll();
void Render();
void LoadDocument(array<System::Byte>^ _data);
void LoadOpMesh(mt::OpMesh* _mesh);
void CaptureFrame();
private:
void Frame(const List<mt::RawVertex>& _vertices);
void UpdateConstantBuffer();
void DisposeTextures();
void CreateTextures(int _iWidth, int _iHeight);
Viewer();
mt::OpMesh* m_Mesh;
bool m_bCaptureFrame = false;
bool m_bLeftDrag = false;
bool m_bDragging = false;
int m_iLastDragX = 0;
int m_iLastDragY = 0;
float m_fPivotX = 0.0f;
float m_fPivotY = 0.0f;
float m_fPivotZ = 0.0f;
float m_fDistanceToCenter = 5.0f;
ArcBall* m_ArcBall;
static Viewer^ s_Instance;
};
}