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


◇DirectX11プログラミング -DirectX11でのZバッファはステンシルステート-

三角のポリゴンで立方体を作ると,6面を2つの三角を合わせて四角を作るから,12コでできる
	const int TYOUTEN = 36;	//ポリゴンの頂点数

Vertex3D hVectorData[TYOUTEN] = {
{{ 1.000000, 1.000000,-1.000000},{0.0f,0.0f,0.5f,1.0f},{0.0f,0.0f}},
{{ 1.000000,-1.000000,-1.000000},{0.0f,0.0f,0.5f,1.0f},{1.0f,1.0f}},
{{-1.000000,-1.000000,-1.000000},{0.0f,0.0f,0.5f,1.0f},{0.0f,0.0f}},
{{ 1.000000, 1.000000,-1.000000},{0.0f,0.0f,0.5f,1.0f},{1.0f,1.0f}},
{{-1.000000,-1.000000,-1.000000},{0.0f,0.0f,0.5f,1.0f},{0.0f,0.0f}},
{{-1.000000, 1.000000,-1.000000},{0.0f,0.0f,0.5f,1.0f},{1.0f,1.0f}},

{{ 1.000000, 1.000000, 1.000000},{0.5f,0.0f,0.5f,1.0f},{0.0f,0.0f}},
{{ 1.000000,-1.000000, 1.000000},{0.5f,0.0f,0.5f,1.0f},{1.0f,1.0f}},
{{ 1.000000,-1.000000,-1.000000},{0.5f,0.0f,0.5f,1.0f},{0.0f,0.0f}},
{{ 1.000000, 1.000000, 1.000000},{0.5f,0.0f,0.5f,1.0f},{1.0f,1.0f}},
{{ 1.000000,-1.000000,-1.000000},{0.5f,0.0f,0.5f,1.0f},{0.0f,0.0f}},
{{ 1.000000, 1.000000,-1.000000},{0.5f,0.0f,0.5f,1.0f},{1.0f,1.0f}},

{{-1.000000, 1.000000, 1.000000},{0.0f,0.5f,0.0f,1.0f},{0.0f,0.0f}},
{{-1.000000,-1.000000, 1.000000},{0.0f,0.5f,0.0f,1.0f},{1.0f,1.0f}},
{{ 1.000000,-1.000000, 1.000000},{0.0f,0.5f,0.0f,1.0f},{0.0f,0.0f}},
{{-1.000000, 1.000000, 1.000000},{0.0f,0.5f,0.0f,1.0f},{1.0f,1.0f}},
{{ 1.000000,-1.000000, 1.000000},{0.0f,0.5f,0.0f,1.0f},{0.0f,0.0f}},
{{ 1.000000, 1.000000, 1.000000},{0.0f,0.5f,0.0f,1.0f},{1.0f,1.0f}},

{{-1.000000, 1.000000,-1.000000},{0.5f,0.5f,0.5f,1.0f},{0.0f,0.0f}},
{{-1.000000,-1.000000,-1.000000},{0.5f,0.5f,0.5f,1.0f},{1.0f,1.0f}},
{{-1.000000,-1.000000, 1.000000},{0.5f,0.5f,0.5f,1.0f},{0.0f,0.0f}},
{{-1.000000, 1.000000,-1.000000},{0.5f,0.5f,0.5f,1.0f},{1.0f,1.0f}},
{{-1.000000,-1.000000, 1.000000},{0.5f,0.5f,0.5f,1.0f},{0.0f,0.0f}},
{{-1.000000, 1.000000, 1.000000},{0.5f,0.5f,0.5f,1.0f},{1.0f,1.0f}},

{{ 1.000000, 1.000000, 1.000000},{0.0f,0.5f,0.5f,1.0f},{0.0f,0.0f}},
{{ 1.000000, 1.000000,-1.000000},{0.0f,0.5f,0.5f,1.0f},{1.0f,1.0f}},
{{-1.000000, 1.000000,-1.000000},{0.0f,0.5f,0.5f,1.0f},{0.0f,0.0f}},
{{ 1.000000, 1.000000, 1.000000},{0.0f,0.5f,0.5f,1.0f},{1.0f,1.0f}},
{{-1.000000, 1.000000,-1.000000},{0.0f,0.5f,0.5f,1.0f},{0.0f,0.0f}},
{{-1.000000, 1.000000, 1.000000},{0.0f,0.5f,0.5f,1.0f},{1.0f,1.0f}},

{{ 1.000000,-1.000000,-1.000000},{0.0f,0.0f,0.0f,1.0f},{0.0f,0.0f}},
{{ 1.000000,-1.000000, 1.000000},{0.0f,0.0f,0.0f,1.0f},{1.0f,1.0f}},
{{-1.000000,-1.000000, 1.000000},{0.0f,0.0f,0.0f,1.0f},{0.0f,0.0f}},
{{ 1.000000,-1.000000,-1.000000},{0.0f,0.0f,0.0f,1.0f},{1.0f,1.0f}},
{{-1.000000,-1.000000, 1.000000},{0.0f,0.0f,0.0f,1.0f},{0.0f,0.0f}},
{{-1.000000,-1.000000,-1.000000},{0.0f,0.0f,0.0f,1.0f},{1.0f,1.0f}},
};
プリミティブを三角形いっぱ~いに設定する
	//プリミティブ(ポリゴンの形状)をコンテキストに設定
hpDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

なにがおかしい?
3Dに詳しい同僚が覗き込んで言った「Zバッファがおかしいのでは?」
速攻で理由がわかった。さすがだ(*'-')

本当にそうなのか確認してみる
三角形単位なので,上の配列の改行単位で1面ずつ描画できる
		//描画
hpDeviceContext->Draw(6, 0); //1面
hpDeviceContext->Draw(6, 6); //2面
hpDeviceContext->Draw(6, 6*2); //3面
hpDeviceContext->Draw(6, 6*3); //4面
hpDeviceContext->Draw(6, 6*4); //5面
hpDeviceContext->Draw(6, 6*5); //6面
1面

2面

3面

4面


これで筒状のはずなのですが……
座標的に,一番最初に書いた面が,手前の面になるはず
やはりZバッファが効いておらず,描画順に上書きされている様子

Zバッファをオンにするにはどうすればよいのか?

スイッチオンでZバッファみたいな機能は,DirectX11ではやっぱり削除されていた(ぁ
……が,ステンシルとか言うのを使用すればできるっぽい

デバイスとスワップチェインを生成した直後に追加します(ここに書くのには理由があります)
パラメータが少しでも狂っているとうまく動作しませんでしたので,あえて前に設定して値を引き回す記述にしてあります
	//ステンシル用テクスチャー作成
ID3D11Texture2D* hpTexture2dDepth = NULL;
D3D11_TEXTURE2D_DESC hTexture2dDesc;
hTexture2dDesc.Width = hDXGISwapChainDesc.BufferDesc.Width;
hTexture2dDesc.Height = hDXGISwapChainDesc.BufferDesc.Height;
hTexture2dDesc.MipLevels = 1;
hTexture2dDesc.ArraySize = 1;
hTexture2dDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
hTexture2dDesc.SampleDesc = hDXGISwapChainDesc.SampleDesc;
hTexture2dDesc.Usage = D3D11_USAGE_DEFAULT;
hTexture2dDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
hTexture2dDesc.CPUAccessFlags = 0;
hTexture2dDesc.MiscFlags = 0;
if(FAILED(hpDevice->CreateTexture2D(&hTexture2dDesc, NULL, &hpTexture2dDepth))){
MessageBoxW(hWnd, L"CreateTexture2D", L"Err", MB_ICONSTOP);
goto End;
}

//ステンシルターゲット作成
ID3D11DepthStencilView* hpDepthStencilView = NULL;
D3D11_DEPTH_STENCIL_VIEW_DESC hDepthStencilViewDesc;
hDepthStencilViewDesc.Format = hTexture2dDesc.Format;
hDepthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
hDepthStencilViewDesc.Flags = 0;
if(FAILED(hpDevice->CreateDepthStencilView(hpTexture2dDepth, &hDepthStencilViewDesc, &hpDepthStencilView))){
MessageBoxW(hWnd, L"CreateDepthStencilView", L"Err", MB_ICONSTOP);
goto End;
}
で,これをコンテキストに設定するのですが,実は既に記述している OMSetRenderTargetsの第3引数なのです
	//その描画ターゲットとステンシルターゲットコンテキストに設定
hpDeviceContext->OMSetRenderTargets(1, &hpRenderTargetView, NULL);

	hpDeviceContext->OMSetRenderTargets(1, &hpRenderTargetView, hpDepthStencilView);
それで,これだけでは機能しませんでした(ここでハマった)
描画する際に毎フレーム初期化してやる必要があります
↓こんな風に背景クリアの直後に入れてみました
		//背景クリア
float ClearColor[] = {0.0f, 0.0f, 1.0f, 1.0f};
hpDeviceContext->ClearRenderTargetView(hpRenderTargetView, ClearColor);
hpDeviceContext->ClearDepthStencilView(hpDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
これを実行すると,正しい立方体が描画されるようになりました



TOPプログラマ専用DirectX11開発