ConstantBufferを定義したヘッダをHLSLとC++共通化する
C++ 側と hlsl 側のcbuffer定義を一致させておくことで多重変更を防ぎます。
また、hlslでは#pragma onceは利用できなかったりするので注意してください。
マクロベースの文字列の1:1置換で対応させます。
用意したヘッダ
#ifndef _HLSL_TYPE_ #define _HLSL_TYPE_ #ifdef TS_FRAMEWORK #define TS_HLSL_CBUFFER struct #define TS_HLSL_TBUFFER struct #define TS_HLSL_FLOAT2 TS::Vector2 #define TS_HLSL_FLOAT3 TS::Vector3 #define TS_HLSL_FLOAT4 TS::Vector4 #define TS_HLSL_MATRIX TS::Matrix4 template<unsigned N = 0> struct ts_cbuffer_register { unsigned RegisterIndex() { return N; } }; #define TS_HLSL_REGISTER_B(register_id) : public ts_cbuffer_register<register_id> #define TS_HLSL_SEMANTICS(semantics_name) #define TS_HLSL_PACKOFFSET(offset_name) #else // hlsl #define TS_HLSL_CBUFFER cbuffer #define TS_HLSL_TBUFFER tbuffer #define TS_HLSL_FLOAT2 float2 #define TS_HLSL_FLOAT3 float3 #define TS_HLSL_FLOAT4 float4 #define TS_HLSL_MATRIX float4x4 #define TS_HLSL_REGISTER_B(register_id) : register(b##register_id) #define TS_HLSL_SEMANTICS(semantics_name) : semantics_name #define TS_HLSL_PACKOFFSET(offset_name) : packoffset(offset_name) #endif #endif
実際の定義
#ifndef _STRUCTURE_RESOURCE #define _STRUCTURE_RESOURCE #include "HlslType.h" TS_HLSL_CBUFFER CameraCbuffer TS_HLSL_REGISTER_B(0) { TS_HLSL_MATRIX u_ViewMatrix; TS_HLSL_MATRIX u_ProjectionMatrix; TS_HLSL_MATRIX u_InvViewMatrix; TS_HLSL_MATRIX u_InvProjectionMatrix; }; TS_HLSL_CBUFFER TransformCBuffer TS_HLSL_REGISTER_B(1) { TS_HLSL_MATRIX u_WorldMatrix; }; #endif <|| 展開されるhlsl コード >|cpp| cbuffer CameraCbuffer : register(b0) { float4x4 u_ViewMatrix; float4x4 u_ProjectionMatrix; float4x4 u_InvViewMatrix; float4x4 u_InvProjectionMatrix; };
展開されるCPPヘッダ
struct CameraCbuffer : public ts_cbuffer_register<0> { TS::Matrix4 u_ViewMatrix; TS::Matrix4 u_ProjectionMatrix; TS::Matrix4 u_InvViewMatrix; TS::Matrix4 u_InvProjectionMatrix; };
C++側ではTS_HLSL_REGISTER_B(0)で継承を利用したレジスタIDの取得を行えるようにしています。
CameraCbuffer cbuffer;
cbuffer.RegisterIndex(); // レジスタのインデックスを取得できる
最近はあまりシェーダを書いていません...。