3
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

DXライブラリで2Dピクセルシェーダーする

久しぶりに使おうとしたら大いにハマったので自分用メモ
※DirectX9記述
※DXライブラリ Ver3.21 時点

サンプルHLSL

画面全体にモザイクをかけるだけ
PS_INPUT、OUTPUTの記述を省略した最小限のソース

sampler sampler0 : register( s0 ) ;

float   mosLv;      //  モザイク強さ 0.0に近いほど荒い
float   alpha;      //  輝度:0.0~1.0

float4 main( float2 uv : TEXCOORD0 ) : COLOR0
{
    float   size1   = mosLv * 100;
    float2  uv1     = floor( uv * size1 + 0.5f ) / size1;   //  0.5fで中心揃えになる、端の部分が半分になるイメージ

    float4  texc    = tex2D( sampler0, uv1 );
    texc.a          = alpha;

    return texc;
}

DXライブラリについてくるツール(ShaderCompiler.exe)でコンパイルする
コマンドでPS2_0かPS3_0を指定

ShaderCompiler.exe /Tps_2_0 HLSLファイルのパス

拡張子.psoのシェーダーファイルが生成される。

C++側

DxLib_Init()の前にDirectX9を使う宣言!
いつの間にかデフォルトでDX11を使うようになってたので注意
これをしないと何も描画されなくて延々と泣くことになる。

SetUseDirect3DVersion( DX_DIRECT3D_9EX );

シェーダーファイル読み込み
コンパイルで生成された、拡張子.psoのファイルを使用する。
※生のHLSLを読んでも何も起こらないので注意

int psHandle = LoadPixelShader( "Mosaic.pso" );

ポリゴンの頂点定義(インデックス式)
楽したいのでラムダ式記述。

std::array< VERTEX2DSHADER, 4 > vertex;
std::array< unsigned short, 6 > vertexIndex;

auto Settings = []( VERTEX2DSHADER &vtx, float x, float y, float u, float v )
{
    vtx.pos = VGet( x, y, 0.0f ) ;
    vtx.u   = u;
    vtx.v   = v;
    vtx.su  = u;
    vtx.sv  = v;
    vtx.rhw = 1.0f ;
    vtx.dif = GetColorU8( 255,255,255,255 ) ;
    vtx.spc = GetColorU8(   0,  0,  0,  0 ) ;
};

Settings( vertex[ 0 ], 100.0f,  100.0f, 0.0f, 0.0f );
Settings( vertex[ 1 ], 600.0f,  100.0f, 1.0f, 0.0f );
Settings( vertex[ 2 ], 100.0f,  600.0f, 0.0f, 1.0f );
Settings( vertex[ 3 ], 600.0f,  600.0f, 1.0f, 1.0f );

vertexIndex = { 0, 1, 2, 1, 2, 3 };

使用するテクスチャをセット
LoadGraphで読み込んだ画像やMakeScreenしたスクリーンなど

SetUseTextureToShader( 0, imgHandle ) ;

さっき読み込んだシェーダーファイルのハンドルをセット
HLSLで記述したパラメータもここで調整

SetUsePixelShader( psHandle );
SetPSConstSF( GetConstIndexToShader( "alpha", psHandle ), 1.0f );
SetPSConstSF( GetConstIndexToShader( "mosLv", psHandle ), 0.5f );

描画
アドレスモードはお好みで

SetTextureAddressMode( DX_TEXADDRESS_CLAMP );
DrawPolygonIndexed2DToShader( vertex.data(), 4, vertexIndex.data(), 2 );

まとめ

これでもうハマらない。
DXライブラリのバージョンアップで仕様が変わりませんように・・・

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
3
Help us understand the problem. What are the problem?