DX11エフェクトシステム作成 Part2 コンパイラ作成

FXファイルのコンパイラを作成します。ただし一部の仕様のみに対応した簡易コンパイラです。複雑な構文解析は行わないので、文字列によって処理を分岐させる程度のプログラムになります。


コンパイラ

コンパイラといっても内容に従って構造体に値を代入するだけの処理です。シェーダコード自体はD3DCompileを使用し、シェーダバイナリコードを保持します。シェーダの変数については直接扱わず、シェーダバイナリコードを介して操作(ID3D11ShaderReflection)。
FXファイル仕様 Effect Format (Direct3D 11)の一部の仕様に対応。

検証に使用したFXファイル
作成したコンパイルが対応できる書式、これ以外のFXファイル仕様は未対応。

// 構造体定義
struct CBuffScene
{
	matrix mtxProj;
	matrix mtxView;
	matrix mtxWorld;
};
//-------------
struct VS_INPUT
{
	float4 Pos : POSITION;
	float2 Tex : TEXCOORD0;
};
//-------------
struct PS_INPUT
{
	float4 Pos : SV_POSITION;
	float2 Tex : TEXCOORD0;
};

// 定数バッファ
cbuffer CB1 : register( b0 )
{
	CBuffScene Scene;
};


// 変数
Texture2D txDiffuse : register( t0 );

// サンプラーステート
SamplerState samLinear  : register( s0 )
{
	Filter = MIN_MAG_MIP_LINEAR;	// MIN_MAG_MIP_POINT MIN_MAG_POINT_MIP_LINEAR MIN_POINT_MAG_LINEAR_MIP_POINT
									// MIN_POINT_MAG_MIP_LINEAR MIN_LINEAR_MAG_MIP_POINT MIN_LINEAR_MAG_POINT_MIP_LINEAR
									// MIN_MAG_LINEAR_MIP_POINT MIN_MAG_MIP_LINEAR ANISOTROPIC
									// COMPARISON_MIN_MAG_MIP_POINT COMPARISON_MIN_MAG_POINT_MIP_LINEAR
									// COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT COMPARISON_MIN_POINT_MAG_MIP_LINEAR
									// COMPARISON_MIN_LINEAR_MAG_MIP_POINT COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR
									// COMPARISON_MIN_MAG_LINEAR_MIP_POINT COMPARISON_MIN_MAG_MIP_LINEAR
									// COMPARISON_ANISOTROPIC;
	AddressU = CLAMP;				// WRAP MIRROR CLAMP BORDER MIRROR_ONCE
	AddressV = CLAMP;
	AddressW = CLAMP;
	MipLODBias = 0.0;				// float
	MaxAnisotropy = 1;				// uint
	ComparisonFunc = NEVER;			// NEVER LESS EQUAL LESS_EQUAL GREATER NOT_EQUAL GREATER_EQUAL ALWAYS
	BorderColor = float4(1,1,1,1);	// float4
	MinLOD = -99999999.0;			// float
	MaxLOD = 99999999.0;			// float
};

// 関数
//-------------------------
PS_INPUT vsBasic( VS_INPUT input)
{
	PS_INPUT output = (PS_INPUT)0;
	float4 pos = mul( input.Pos, Scene.mtxWorld );
	pos = mul( pos, Scene.mtxView );
	output.Pos = mul( pos, Scene.mtxProj );
	output.Tex = input.Tex;
	return output;
}

//----------------------------
float4 psBasic( PS_INPUT input ) : SV_Target
{
	return txDiffuse.Sample( samLinear, input.Tex);
}

// ステート定義 ※大文字小文字の区別なし

BlendState NoBlend {
	AlphaToCoverageEnable = False;	// bool
	//IndependentBlendEnable = False;//未対応
	BlendEnable[0] = False;	// bool
    SrcBlend[0] = ONE;	// ZERO ONE SRC_COLOR INV_SRC_COLOR SRC_ALPHA INV_SRC_ALPHA DEST_ALPHA INV_DEST_ALPHA DEST_COLOR INV_DEST_COLOR SRC_ALPHA_SAT BLEND_FACTOR INV_BLEND_FACTO SRC1_COLOR INV_SRC1_COLOR SRC1_ALPHA INV_SRC1_ALPHA
	DestBlend[0] = ZERO;// ZERO ONE SRC_COLOR INV_SRC_COLOR SRC_ALPHA INV_SRC_ALPHA DEST_ALPHA INV_DEST_ALPHA DEST_COLOR INV_DEST_COLOR SRC_ALPHA_SAT BLEND_FACTOR INV_BLEND_FACTO SRC1_COLOR INV_SRC1_COLOR SRC1_ALPHA INV_SRC1_ALPHA
    BlendOp[0] = ADD;	// ADD SUBTRACT REV_SUBTRACT MIN MAX
	SrcBlendAlpha[0] = ONE;
	DestBlendAlpha[0] = ZERO;
	BlendOpAlpha[0] = ADD;
	RenderTargetWriteMask[0] = 0xf; //uint8 R=1 G=2 B=4 A=8  
};

DepthStencilState DepthTestOn {
	DepthEnable = True;			// bool
	DepthWriteMask = All;		// Zero All
	DepthFunc = LESS;			// NEVER LESS EQUAL LESS_EQUAL GREATER NOT_EQUAL GREATER_EQUAL ALWAYS
	StencilEnable = False;		// bool	
	StencilReadMask = 255;		// uint8
	StencilWriteMask = 0xff;	// uint8

	FrontFaceStencilFail = KEEP;		// KEEP ZERO REPLACE INCR_SAT DECR_SAT INVERT INCR DECR
	FrontFaceStencilDepthFail = KEEP;	// KEEP ZERO REPLACE INCR_SAT DECR_SAT INVERT INCR DECR
	FrontFaceStencilPass = KEEP;		// KEEP ZERO REPLACE INCR_SAT DECR_SAT INVERT INCR DECR
	FrontFaceStencilFunc = ALWAYS;		// NEVER LESS EQUAL LESS_EQUAL GREATER NOT_EQUAL GREATER_EQUAL ALWAYS	
	BackFaceStencilFail = KEEP;			// KEEP ZERO REPLACE INCR_SAT DECR_SAT INVERT INCR DECR
	BackFaceStencilDepthFail = KEEP;	// KEEP ZERO REPLACE INCR_SAT DECR_SAT INVERT INCR DECR
	BackFaceStencilPass = KEEP;			// KEEP ZERO REPLACE INCR_SAT DECR_SAT INVERT INCR DECR
	BackFaceStencilFunc = ALWAYS;		// NEVER LESS EQUAL LESS_EQUAL GREATER NOT_EQUAL GREATER_EQUAL ALWAYS
};

RasterizerState rsWireframe {
	FillMode = Solid;				// WireFrame Solid
	CullMode = Back;				// None Front Back
	FrontCounterClockwise = False;	// bool;
	DepthBias = 0;					// int
	DepthBiasClamp = 0.0f;			// float
	SlopeScaledDepthBias = 0.0f;	// float
	DepthClipEnable = True;			// bool
	ScissorEnable = False;			// bool
	MultisampleEnable = False;		// bool
	AntialiasedLineEnable = False;	// bool
};


// テクニック
technique11 t0 {

	//パス
	pass p0 {

		// ステート設定
		SetBlendState( NoBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
		SetDepthStencilState( DepthTestOn, 0 );
		SetRasterizerState( rsWireframe );
		
		// シェーダ
		SetVertexShader( CompileShader( vs_5_0, vsBasic() ) );
		SetPixelShader( CompileShader( ps_5_0, psBasic() ) );
		// とりあえずこの書式のみ対応
	}
}
コンパイル結果
結果を保存するコンテナクラスを作成。DirectX11関連のオブジェクトはこの時点では作成しない。単純な構造体に値を書き込みとシェーダバイナリコード作成のみ。

//--------------------------------------------------------
// zgFXコンテナ
class FXContainer
{
public:
	// D3D11ラスタライザステート定義取得
	bool getDesc(Uint32 idx, RasterizerDesc& desc) const;
	
	// D3D11デプスステンシルステート定義取得
	bool getDesc(Uint32 idx, DepthStencilDesc& desc) const;

	// D3D11ブレンドステート定義取得
	bool getDesc(Uint32 idx, BlendDesc& desc) const;

	// D3D11サンプラステート定義取得
	bool getDesc(Uint32 idx, SamplerDesc& desc) const;

	//名前からindex
	Uint32 getRasterizerIdx(const Char* name) const;
	Uint32 getDepthStencilIdx(const Char* name) const;
	Uint32 getBlendIdx(const Char* name) const;
	Uint32 getSamplerIdx(const Char* name) const;

	// 各ステート定義数
	Uint32 getRasterizeNum() const;
	Uint32 getDepthStencilNum() const;
	Uint32 getBlendNum() const;
	Uint32 getSamplerNum() const;

	// テクニックとパス情報取得
	Uint32 getTechNum() const;
	Uint32 getTechIdx(const Char* name) const;
	bool getTech(Uint32 idx, TechniqueDesc& tech) const;
	bool getPass(Uint32 tech_idx, Uint32 pass_idx, PassDesc&) const;

	FXContainer();
	~FXContainer();
}
使用例
コンパイル結果(FXContainer)から取得した構造体を使用してDirectX11のオブジェクトを生成。

	// シェーダコンパイル
	zgfx::FXContainer fx_cntr;
	{
		zgfx::ZGFXCompiler compile;
		if( !compile.CompileFile("data\\shader.fx", fx_cntr) ){
			return E_FAIL;
		}
	}

	// テクニック情報取得
	zgfx::TechniqueDesc fxtech;
	zgfx::PassDesc fxpass;
	UINT tech_idx = fx_cntr.getTechIdx( ZGFXCHAR("t0") );
	if( !fx_cntr.getTech(tech_idx, fxtech) )return E_FAIL;

	// パス情報の取得
	if( !fx_cntr.getPass(tech_idx, 0, fxpass) )return E_FAIL;

	//ステート定義の取得
	zgfx::RasterizerDesc rs_desc;
	zgfx::DepthStencilDesc ds_desc;
	zgfx::BlendDesc bd_desc;
	zgfx::SamplerDesc sp_desc;
	UINT sp_idx = fx_cntr.getSamplerIdx( ZGFXCHAR("samLinear") );
	if( !fx_cntr.getDesc(fxpass.idxRasterizer, rs_desc)
		|| !fx_cntr.getDesc(fxpass.idxDepthStencil, ds_desc)
		|| !fx_cntr.getDesc(fxpass.idxBlend, bd_desc)
		|| !fx_cntr.getDesc(sp_idx, sp_desc)){
		return E_FAIL;
	}

	// 頂点シェーダ作成
	hr = pCtx->pDevice->CreateVertexShader( fxpass.VShader.pCode, fxpass.VShader.sizeCode, NULL, &pObj->pVShader );
	if( FAILED( hr ) ){	
		return hr;
	}
	// ピクセルシェーダ作成
	hr = pCtx->pDevice->CreatePixelShader( fxpass.PShader.pCode, fxpass.PShader.sizeCode, NULL, &pObj->pPShader );
	if( FAILED( hr ) ){
		return hr;
	}

	//ステート設定
	// ラスタライザステート
	hr = pCtx->pDevice->CreateRasterizerState(&rs_desc.Desc, &pObj->pRsState);
	if( FAILED( hr ) ){ return hr; }

	// ブレンドステート
	hr = pCtx->pDevice->CreateBlendState(&bd_desc.Desc, &pObj->pBdState);
	if( FAILED( hr ) ){ return hr; }

	// デプスステンシルステート
	hr = pCtx->pDevice->CreateDepthStencilState(&ds_desc.Desc, &pObj->pDsState);
	if( FAILED( hr ) ){ return hr; }
	
	// サンプラステート
	hr = pCtx->pDevice->CreateSamplerState( &sp_desc.Desc, &pObj->pSampler );
	if( FAILED( hr ) ){
		return hr;
	}
	
	for(int i=0;i<4;++i){pObj->f4BdFactor[i] = fxpass.f4BdFactor.v[i];}
	pObj->bitBdMask = fxpass.bitBdMask;
	pObj->uStencilRef = fxpass.uStencilRef;

サンプルプログラム

エフェクトシステムの作成 Part2 コンパイラ作成

“DX11エフェクトシステムの作成 Part2 コンパイラ作成” をダウンロード dx11Effect1.zip – 573 回のダウンロード – 53 KB

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

認証:数字を入力してください(必須) * Time limit is exhausted. Please reload CAPTCHA.