Nanashi-softプログラマ専用DirectX11開発


◇DirectX11プログラミング -テクスチャーデータを複数持つには?-

次にテクスチャーデータを2つ持つ方法を考えます
実は,メソッド自体にそういう機能があります

PSSetShaderResources時の第1引数で,識別できます
例えば,1枚目を,
				hpDeviceContext->PSSetShaderResources(0, 1, hpShaderResourceViews1);
2枚目を,
				hpDeviceContext->PSSetShaderResources(1, 1, hpShaderResourceViews2);
のようにセットしておくのです

そうしておいて,ピクセルシェーダーのHLSLにて,
1枚目受け取り,
SamplerState samLinear : register(s0);
2枚目受け取り,
SamplerState samLinear : register(s1);
のようにして受け取って処理します

……が,この方法だと,テクスチャー毎にピクセルシェーダーHLSLを組む必要がありますよね?
そもそも受け取る時のグローバル定数(?)に代入する値(レジスタ)が異なるわけですから
もちろんインプットレイアウトにテクスチャー識別番号を追加して分岐させても良いですけれどね


うちのシステムでは別のアプローチを取ります
前に実験した,テクスチャーを生成したポインタを保持する方法を発展させます

現状のテクスチャーデータは,このようなプログラムになっています
	//テクスチャー読み込み
D3DX11_IMAGE_LOAD_INFO LoadInfo;
LoadInfo.Width = 0;
LoadInfo.Height = 0;
LoadInfo.Depth = 0;
LoadInfo.FirstMipLevel = 0;
LoadInfo.MipLevels = D3DX11_DEFAULT,
LoadInfo.Usage = D3D11_USAGE_DEFAULT;
LoadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE;
LoadInfo.CpuAccessFlags = 0;
LoadInfo.MiscFlags = 0;
LoadInfo.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
LoadInfo.Filter = D3DX11_FILTER_TRIANGLE;
LoadInfo.MipFilter = D3DX11_FILTER_TRIANGLE;
LoadInfo.pSrcInfo = NULL;

ID3D11ShaderResourceView* hpShaderResourceView = NULL;
if(FAILED(D3DX11CreateShaderResourceViewFromFile(hpDevice, TEXT("eye2.png"), &LoadInfo, NULL, &hpShaderResourceView, NULL))){
MessageBoxW(hWnd, L"D3DX11CreateShaderResourceViewFromFile", L"Err", MB_ICONSTOP);
goto End;
}
ID3D11ShaderResourceView* hpShaderResourceViews[] = { hpShaderResourceView };
//テクスチャー1をコンテキストに設定
hpDeviceContext->PSSetShaderResources(0, 1, hpShaderResourceViews);
○処理の流れ
mainクラス

pmdクラスでモデルデータロード

D3DX11CreateShaderResourceViewFromFileでテクスチャーデータを生成

modeldataクラスにID3D11ShaderResourceViewポインターをセット

描画時にPSSetShaderResourcesで使用するテクスチャーデータをスイッチ

初期化で,テクスチャーデータを生成して,
	#define MODELDATA_MAX 2
ID3D11ShaderResourceView *texSRV[MAX_TEXTURE];
~略~
for(int mdcnt=0; mdcnt < MODELDATA_MAX; mdcnt++){
~略~
//テクスチャーファイルを読み込み
D3DX11_IMAGE_LOAD_INFO LoadInfo;
LoadInfo.Width = 0;
LoadInfo.Height = 0;
LoadInfo.Depth = 0;
LoadInfo.FirstMipLevel = 0;
LoadInfo.MipLevels = D3DX11_DEFAULT,
LoadInfo.Usage = D3D11_USAGE_DEFAULT;
LoadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE;
LoadInfo.CpuAccessFlags = 0;
LoadInfo.MiscFlags = 0;
LoadInfo.Format = DXGI_FORMAT_R32G32B32_FLOAT;
LoadInfo.Filter = D3DX11_FILTER_TRIANGLE;
LoadInfo.MipFilter = D3DX11_FILTER_TRIANGLE;
LoadInfo.pSrcInfo = NULL;

ID3D11ShaderResourceView* hpShaderResourceView = NULL;

LPCSTR file;
char w[MATERIAL_FILENAME_MAX];
memcpy(w, &texture_file[i*MATERIAL_FILENAME_MAX], MATERIAL_FILENAME_MAX);
file = w;
if(FAILED(D3DX11CreateShaderResourceViewFromFile(hpDevice, file, &LoadInfo, NULL, &hpShaderResourceView, NULL))){
MessageBoxW(hWnd, L"D3DX11CreateShaderResourceViewFromFile", L"Err", MB_ICONSTOP);
goto End;
}
texSRV[mdcnt] = hpShaderResourceView;
}
~略~
}
メインループで,それをセットして描画する
	for(int mdcnt=0; mdcnt < MODELDATA_MAX; mdcnt++){
~略~
//テクスチャー切り替え
ID3D11ShaderResourceView* hpShaderResourceViews[] = { texSRV[mdcnt], 0) };
hpDeviceContext->PSSetShaderResources(0, 1, hpShaderResourceViews);
~略~
//インデックス描画
hpDeviceContext->DrawIndexed(INDEXSU[mdcnt], 0, 0);
}
テクスチャーを生成したデータのポインタであるID3D11ShaderResourceView*を保管しておけば描画可能です


TOPプログラマ専用DirectX11開発

メイナの実験場~小生意気な感じにしてみました~メイナの実験場~ナース服大好き+~メイナの実験場~裸マント文乃ちゃん~