
Un « vertex traits » sert à décrire un format de sommet une seule fois, en C++, et à laisser le compilateur en déduire le reste. Sans lui, le même vertex est décrit à trois endroits qui doivent rester synchronisés à la main.
Prenons un sommet classique avec position, normale et coordonnées de texture :
Il existe trois définitions d’une structure élémentaire GPU. Dans le programme :|
1 2 3 4 5 6 |
struct VertexPNT { DirectX::XMFLOAT3 position; DirectX::XMFLOAT3 normal; DirectX::XMFLOAT2 uv; }; |
|
1 2 3 4 5 6 |
const D3D11_INPUT_ELEMENT_DESC layout[] = { { "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 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; |
|
1 2 3 4 5 6 |
struct VSInput { float3 position : POSITION; float3 normal : NORMAL; float2 uv : TEXCOORD0; }; |
Rappel : c’est quoi, un trait ? Un trait est une structure template qui associe des informations à un type, sans modifier ce type. On interroge le trait avec le type en paramètre, et il répond à la compilation.
Première version : spécialiser à la main
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include <array> #include <cstddef> // offsetof #include <d3d11.h> #include <DirectXMath.h> // Template primaire : volontairement non défini. // Utiliser un type non décrit = erreur de compilation. template <typename TVertex> struct VertexTraits; struct VertexPNT { DirectX::XMFLOAT3 position; DirectX::XMFLOAT3 normal; DirectX::XMFLOAT2 uv; }; template <> struct VertexTraits<VertexPNT> { static constexpr UINT Stride = sizeof(VertexPNT); static constexpr std::array<D3D11_INPUT_ELEMENT_DESC, 3> Layout = {{ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(VertexPNT, position), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(VertexPNT, normal), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(VertexPNT, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, }}; }; |























