Commit af8779e6 authored by chili's avatar chili
Browse files

template typemap vertexlayout

parent d733cb2b
...@@ -23,8 +23,8 @@ AssTest::AssTest( Graphics& gfx,std::mt19937& rng, ...@@ -23,8 +23,8 @@ AssTest::AssTest( Graphics& gfx,std::mt19937& rng,
using hw3dexp::VertexLayout; using hw3dexp::VertexLayout;
hw3dexp::VertexBuffer vbuf( std::move( hw3dexp::VertexBuffer vbuf( std::move(
VertexLayout{} VertexLayout{}
.Append<VertexLayout::Position3D>() .Append( VertexLayout::Position3D )
.Append<VertexLayout::Normal>() .Append( VertexLayout::Normal )
)); ));
Assimp::Importer imp; Assimp::Importer imp;
......
#pragma once #pragma once
#include <vector> #include <vector>
#include <DirectXMath.h>
#include <type_traits> #include <type_traits>
#include "Graphics.h"
namespace hw3dexp namespace hw3dexp
{ {
...@@ -25,7 +25,52 @@ namespace hw3dexp ...@@ -25,7 +25,52 @@ namespace hw3dexp
Float3Color, Float3Color,
Float4Color, Float4Color,
BGRAColor, BGRAColor,
Count,
}; };
template<ElementType> struct Map;
template<> struct Map<Position2D>
{
using SysType = DirectX::XMFLOAT2;
DXGI_FORMAT dxgiFormat = DXGI_FORMAT_R32G32_FLOAT;
const char* semantic = "Position";
};
template<> struct Map<Position3D>
{
using SysType = DirectX::XMFLOAT3;
DXGI_FORMAT dxgiFormat = DXGI_FORMAT_R32G32B32_FLOAT;
const char* semantic = "Position";
};
template<> struct Map<Texture2D>
{
using SysType = DirectX::XMFLOAT2;
DXGI_FORMAT dxgiFormat = DXGI_FORMAT_R32G32_FLOAT;
const char* semantic = "Texcoord";
};
template<> struct Map<Normal>
{
using SysType = DirectX::XMFLOAT3;
DXGI_FORMAT dxgiFormat = DXGI_FORMAT_R32G32B32_FLOAT;
const char* semantic = "Normal";
};
template<> struct Map<Float3Color>
{
using SysType = DirectX::XMFLOAT3;
DXGI_FORMAT dxgiFormat = DXGI_FORMAT_R32G32B32_FLOAT;
const char* semantic = "Color";
};
template<> struct Map<Float4Color>
{
using SysType = DirectX::XMFLOAT4;
DXGI_FORMAT dxgiFormat = DXGI_FORMAT_R32G32B32A32_FLOAT;
const char* semantic = "Color";
};
template<> struct Map<BGRAColor>
{
using SysType = hw3dexp::BGRAColor;
DXGI_FORMAT dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
const char* semantic = "Color";
};
class Element class Element
{ {
public: public:
...@@ -52,19 +97,19 @@ namespace hw3dexp ...@@ -52,19 +97,19 @@ namespace hw3dexp
switch( type ) switch( type )
{ {
case Position2D: case Position2D:
return sizeof( XMFLOAT2 ); return sizeof( Map<Position2D>::SysType );
case Position3D: case Position3D:
return sizeof( XMFLOAT3 ); return sizeof( Map<Position3D>::SysType );
case Texture2D: case Texture2D:
return sizeof( XMFLOAT2 ); return sizeof( Map<Texture2D>::SysType );
case Normal: case Normal:
return sizeof( XMFLOAT3 ); return sizeof( Map<Normal>::SysType );
case Float3Color: case Float3Color:
return sizeof( XMFLOAT3 ); return sizeof( Map<Float3Color>::SysType );
case Float4Color: case Float4Color:
return sizeof( XMFLOAT3 ); return sizeof( Map<Float4Color>::SysType );
case BGRAColor: case BGRAColor:
return sizeof( hw3dexp::BGRAColor ); return sizeof( Map<BGRAColor>::SysType );
} }
assert( "Invalid element type" && false ); assert( "Invalid element type" && false );
return 0u; return 0u;
...@@ -95,10 +140,9 @@ namespace hw3dexp ...@@ -95,10 +140,9 @@ namespace hw3dexp
{ {
return elements[i]; return elements[i];
} }
template<ElementType Type> VertexLayout& Append( ElementType type ) noexcept(!IS_DEBUG)
VertexLayout& Append() noexcept(!IS_DEBUG)
{ {
elements.emplace_back( Type,Size() ); elements.emplace_back( type,Size() );
return *this; return *this;
} }
size_t Size() const noexcept(!IS_DEBUG) size_t Size() const noexcept(!IS_DEBUG)
...@@ -120,71 +164,36 @@ namespace hw3dexp ...@@ -120,71 +164,36 @@ namespace hw3dexp
template<VertexLayout::ElementType Type> template<VertexLayout::ElementType Type>
auto& Attr() noexcept(!IS_DEBUG) auto& Attr() noexcept(!IS_DEBUG)
{ {
using namespace DirectX; auto pAttribute = pData + layout.Resolve<Type>().GetOffset();
const auto& element = layout.Resolve<Type>(); return *reinterpret_cast<typename VertexLayout::Map<Type>::SysType*>(pAttribute);
auto pAttribute = pData + element.GetOffset();
if constexpr( Type == VertexLayout::Position2D )
{
return *reinterpret_cast<XMFLOAT2*>(pAttribute);
}
else if constexpr( Type == VertexLayout::Position3D )
{
return *reinterpret_cast<XMFLOAT3*>(pAttribute);
}
else if constexpr( Type == VertexLayout::Texture2D )
{
return *reinterpret_cast<XMFLOAT2*>(pAttribute);
}
else if constexpr( Type == VertexLayout::Normal )
{
return *reinterpret_cast<XMFLOAT3*>(pAttribute);
}
else if constexpr( Type == VertexLayout::Float3Color )
{
return *reinterpret_cast<XMFLOAT3*>(pAttribute);
}
else if constexpr( Type == VertexLayout::Float4Color )
{
return *reinterpret_cast<XMFLOAT4*>(pAttribute);
}
else if constexpr( Type == VertexLayout::BGRAColor )
{
return *reinterpret_cast<BGRAColor*>(pAttribute);
}
else
{
assert( "Bad element type" && false );
return *reinterpret_cast<char*>(pAttribute);
}
} }
template<typename T> template<typename T>
void SetAttributeByIndex( size_t i,T&& val ) noexcept(!IS_DEBUG) void SetAttributeByIndex( size_t i,T&& val ) noexcept(!IS_DEBUG)
{ {
using namespace DirectX;
const auto& element = layout.ResolveByIndex( i ); const auto& element = layout.ResolveByIndex( i );
auto pAttribute = pData + element.GetOffset(); auto pAttribute = pData + element.GetOffset();
switch( element.GetType() ) switch( element.GetType() )
{ {
case VertexLayout::Position2D: case VertexLayout::Position2D:
SetAttribute<XMFLOAT2>( pAttribute,std::forward<T>( val ) ); SetAttribute<VertexLayout::Position2D>( pAttribute,std::forward<T>( val ) );
break; break;
case VertexLayout::Position3D: case VertexLayout::Position3D:
SetAttribute<XMFLOAT3>( pAttribute,std::forward<T>( val ) ); SetAttribute<VertexLayout::Position3D>( pAttribute,std::forward<T>( val ) );
break; break;
case VertexLayout::Texture2D: case VertexLayout::Texture2D:
SetAttribute<XMFLOAT2>( pAttribute,std::forward<T>( val ) ); SetAttribute<VertexLayout::Texture2D>( pAttribute,std::forward<T>( val ) );
break; break;
case VertexLayout::Normal: case VertexLayout::Normal:
SetAttribute<XMFLOAT3>( pAttribute,std::forward<T>( val ) ); SetAttribute<VertexLayout::Normal>( pAttribute,std::forward<T>( val ) );
break; break;
case VertexLayout::Float3Color: case VertexLayout::Float3Color:
SetAttribute<XMFLOAT3>( pAttribute,std::forward<T>( val ) ); SetAttribute<VertexLayout::Float3Color>( pAttribute,std::forward<T>( val ) );
break; break;
case VertexLayout::Float4Color: case VertexLayout::Float4Color:
SetAttribute<XMFLOAT4>( pAttribute,std::forward<T>( val ) ); SetAttribute<VertexLayout::Float4Color>( pAttribute,std::forward<T>( val ) );
break; break;
case VertexLayout::BGRAColor: case VertexLayout::BGRAColor:
SetAttribute<BGRAColor>( pAttribute,std::forward<T>( val ) ); SetAttribute<VertexLayout::BGRAColor>( pAttribute,std::forward<T>( val ) );
break; break;
default: default:
assert( "Bad element type" && false ); assert( "Bad element type" && false );
...@@ -207,10 +216,11 @@ namespace hw3dexp ...@@ -207,10 +216,11 @@ namespace hw3dexp
SetAttributeByIndex( i + 1,std::forward<Rest>( rest )... ); SetAttributeByIndex( i + 1,std::forward<Rest>( rest )... );
} }
// helper to reduce code duplication in SetAttributeByIndex // helper to reduce code duplication in SetAttributeByIndex
template<typename Dest,typename Src> template<VertexLayout::ElementType DestLayoutType,typename SrcType>
void SetAttribute( char* pAttribute,Src&& val ) noexcept(!IS_DEBUG) void SetAttribute( char* pAttribute,SrcType&& val ) noexcept(!IS_DEBUG)
{ {
if constexpr( std::is_assignable<Dest,Src>::value ) using Dest = typename VertexLayout::Map<DestLayoutType>::SysType;
if constexpr( std::is_assignable<Dest,SrcType>::value )
{ {
*reinterpret_cast<Dest*>(pAttribute) = val; *reinterpret_cast<Dest*>(pAttribute) = val;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment