DirectX11で深度バッファが機能しない

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
toryu

DirectX11で深度バッファが機能しない

#1

投稿記事 by toryu » 8年前

現在、DirectX11でのアプリケーション開発のための簡易ライブラリを制作しています。
しかし、描画はうまくいきますが、深度バッファが全く機能せず困っています。

以下のプログラムは原因究明のためにライブラリのクラス等を全て排除したものです。
深度バッファのテクスチャは作成されており、デバイスコンテキストにも設定されています。
また、ClearDepthStencilView関数も正常に実行されています。
分かることがありましたら、ご教授お願いします。

Main.cpp

コード:

//////////////////////////////////////////////////////////////////////////////
//
//  Main.cpp
//
//////////////////////////////////////////////////////////////////////////////

#include "Include.h"
#include "UTWindow.h"


#include "TestShader_vs.h"
#include "TestShader_ps.h"

/*****  頂点 構造体  *****/
struct Vertex {
	D3DXVECTOR3	pos;
	D3DXVECTOR4	color;
};

/*****  シェーダ入力 構造体*****/
struct ShaderIn {
	D3DXMATRIX	mWVP;
};

UTWindow*				gWindow			=	nullptr;	// ウインドウ

ID3D11Device*			gDevice			=	nullptr;	// デバイス
ID3D11DeviceContext*	gDeviceContext	=	nullptr;	// デバイス コンテキスト

IDXGIAdapter*			gAdapter		=	nullptr;	// アダプタ
IDXGIFactory*			gFactory		=	nullptr;	// ファクトリ
IDXGISwapChain*			gSwapChain		=	nullptr;	// スワップチェイン
DXGI_SWAP_CHAIN_DESC	gSwapChainDesc;					// スワップチェイン情報

ID3D11Texture2D*		gBackBufferTex	=	nullptr;	// バックバッファ
ID3D11RenderTargetView*	gRendetTarget	=	nullptr;	// レンダーターゲット

ID3D11Texture2D*		gDepthBufferTex	=	nullptr;	// 深度バッファ テクスチャ
ID3D11DepthStencilView*	gDepthStencil	=	nullptr;	// 深度バッファ

ID3D11Buffer*			gVertexBufferA	=	nullptr;	// 頂点インデックスA
ID3D11Buffer*			gVertexBufferB	=	nullptr;	// 頂点インデックスB
ID3D11Buffer*			gIndexBuffer	=	nullptr;	// インデックスバッファ

ID3D11VertexShader*		gVertexShader	=	nullptr;	// 頂点シェーダ
ID3D11InputLayout*		gInputLayout	=	nullptr;	// 入力レイアウト
ID3D11PixelShader*		gPixelShader	=	nullptr;	// ピクセルシェーダ

ID3D11Buffer*			gConstantBuffer	=	nullptr;	// 定数バッファ

DWORD					gStartTime		=	0;			// フレーム開始時刻

D3DXVECTOR3				gAPos;							// オブジェクトA 座標
D3DXVECTOR3				gBPos;							// オブジェクトB 座標

HRESULT	Init(HINSTANCE _hInst, int _nCmdshow, UINT _w, UINT _h);	// 初期化
void	Update();										// 更新
void	Draw();											// 描画
void	Release();										// 解放

void	ControlFPS();									// FPS制御

/////////////////////////////////////////////////////////////////////
//
//	WinMain
//	エントリーポイント
//
/////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszCmdParam, int nCmdshow)
{
	int ret = -1;
	HRESULT hr;

	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

	hr = Init(hInst, nCmdshow, 640, 480);
	if (FAILED(hr)) {
		char str[1024];
		sprintf(str, "ERROR : %X", hr);
		DispMessage(str);
		goto RELEASE;
	}

	int res = 0;
	while (1) {
		res = gWindow->MessageProc();
		if (res == -1) { break; }
		else {
			gStartTime = timeGetTime();
			Update();
			Draw();
			ControlFPS();
		}
	}


RELEASE:
	Release();

	return 0;
}

/////////////////////////////////////////////////////////////////////
//
//	Init
//	初期化
//
/////////////////////////////////////////////////////////////////////
HRESULT Init(HINSTANCE _hInst, int _nCmdshow, UINT _w, UINT _h)
{
	BOOL bl;
	HRESULT hr;

	/***************  ウインドウ初期化  ***************/
	gWindow = new UTWindow;
	bl = gWindow->Create(_hInst, _w, _h);
	if (!bl) { return E_FAIL; }


	/***************  ファクトリー作成  ***************/
	hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast< void** >(&gFactory));
	if (FAILED(hr)) { return hr; }


	/***************  ALT+Enterでフルスクリーンを許可する  ***************/
	//hr = gFactory->MakeWindowAssociation(gWindow->GetHandle(), 0);
	//if (FAILED(hr)) { return hr; }


	/***************  アダプター作成  ***************/
	hr = gFactory->EnumAdapters(0, &gAdapter);
	if (FAILED(hr)) { return hr; }


	/***************  デバイスの作成  ***************/
	UINT creationFlags = 0;

#ifdef _DEBUG
	// Direct3Dのデバッグを有効にする
	creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	D3D_FEATURE_LEVEL featureLevels = D3D_FEATURE_LEVEL_11_0;

	// デバイスとでデバイスコンテキストを作成
	hr = D3D11CreateDevice(
		nullptr,
		D3D_DRIVER_TYPE_HARDWARE,
		nullptr,
		creationFlags,
		&featureLevels,
		1,
		D3D11_SDK_VERSION,
		&gDevice,
		nullptr,
		&gDeviceContext);
	if (FAILED(hr)) { return hr; }
	

	/***************  スワップチェインを作成  ***************/
	gSwapChainDesc.BufferDesc.Width = _w;
	gSwapChainDesc.BufferDesc.Height = _h;
	gSwapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
	gSwapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
	gSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	gSwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	gSwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	gSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT;
	gSwapChainDesc.BufferCount = 2;
	gSwapChainDesc.OutputWindow = gWindow->GetHandle();
	gSwapChainDesc.Windowed = TRUE;
	gSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	gSwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

	int startMultisample = 1;
	UINT Quality = 0;
	for (int i = startMultisample; i >= 0; i--)
	{
		// サポートするクォリティレベルの最大値を取得する
		hr = gDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_D24_UNORM_S8_UINT, (UINT)i, &Quality);
		if (FAILED(hr)) { return hr; }

		// 0 以外のときフォーマットとサンプリング数の組み合わせをサポートする
		if (Quality != 0)
		{
			gSwapChainDesc.SampleDesc.Count = i;
			gSwapChainDesc.SampleDesc.Quality = Quality - 1;

			// スワップチェーンを作成する
			hr = gFactory->CreateSwapChain(gDevice, &gSwapChainDesc, &gSwapChain);
			if (SUCCEEDED(hr)) { break; }
			else { return hr; }
		}
	}
	if (gSwapChain == NULL) { return E_FAIL; }


	/***************  レンダーターゲットを作成  ***************/
	hr = gSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&gBackBufferTex);
	if (FAILED(hr)) { return hr; }

	D3D11_TEXTURE2D_DESC tex2DDesc;
	gBackBufferTex->GetDesc(&tex2DDesc);

	D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
	ZeroMemory(&rtvDesc, sizeof(rtvDesc));
	rtvDesc.Format = tex2DDesc.Format;
	rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;

	// レンダーターゲットビュー作成
	hr = gDevice->CreateRenderTargetView(gBackBufferTex, &rtvDesc, &gRendetTarget);
	if (FAILED(hr)) { return hr; }


	/***************  深度バッファを作成  ***************/
	D3D11_TEXTURE2D_DESC dsDesc;
	DXGI_SWAP_CHAIN_DESC chainDesc;
	hr = gSwapChain->GetDesc(&chainDesc);
	if (FAILED(hr)) { return hr; }
	// パラメータ設定
	ZeroMemory(&dsDesc, sizeof(D3D11_TEXTURE2D_DESC));
	dsDesc.Width				=	chainDesc.BufferDesc.Width;   // バックバッファと同じにする。
	dsDesc.Height				=	chainDesc.BufferDesc.Height;  // バックバッファと同じにする。
	dsDesc.MipLevels			=	1;                            // ミップマップを作成しない
	dsDesc.ArraySize			=	1;                            // テクスチャーの配列数
	dsDesc.Format				=	DXGI_FORMAT_R24G8_TYPELESS;   // フォーマット
	dsDesc.SampleDesc.Count		=	chainDesc.SampleDesc.Count;   // バックバッファと同じにする。
	dsDesc.SampleDesc.Quality	=	chainDesc.SampleDesc.Quality; // バックバッファと同じにする。
	dsDesc.Usage				=	D3D11_USAGE_DEFAULT;          // GPU による読み取りおよび書き込みアクセスを必要とするリソース。
	dsDesc.BindFlags			=	D3D11_BIND_DEPTH_STENCIL |    // 深度ステンシルバッファとして作成する
									D3D11_BIND_SHADER_RESOURCE;   // シェーダーリソースビューとして作成する
	dsDesc.CPUAccessFlags		=	0;                            // CPU アクセスが不要。
	dsDesc.MiscFlags			=	0;                            // その他のフラグも設定しない。
	hr = gDevice->CreateTexture2D(&dsDesc, nullptr, &gDepthBufferTex);
	if (FAILED(hr)) { return hr; }

	// 作成するビューの設定
	CD3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
	ZeroMemory(&dsvDesc, sizeof(dsvDesc));

	D3D11_TEXTURE2D_DESC ds2dDesc;
	gDepthBufferTex->GetDesc(&ds2dDesc);
	// テクスチャー作成時に指定したフォーマットと互換性があり、深度ステンシルビューとして指定できるフォーマットを指定する
	switch (ds2dDesc.Format) {
		// 8ビットフォーマットは使用できない?
	case DXGI_FORMAT_R8_TYPELESS:
		dsvDesc.Format = DXGI_FORMAT_R8_UNORM;
		break;
		// 16ビット
	case DXGI_FORMAT_R16_TYPELESS:
		dsvDesc.Format = DXGI_FORMAT_D16_UNORM;
		break;
		// 32ビット
	case DXGI_FORMAT_R32_TYPELESS:
		dsvDesc.Format = DXGI_FORMAT_D32_FLOAT;
		break;
		// 24ビット(Zバッファ) + 8ビット(ステンシルバッファ) 
	case DXGI_FORMAT_R24G8_TYPELESS:
		dsvDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
		break;
	default:
		dsvDesc.Format = ds2dDesc.Format;
		break;
	}

	dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	dsvDesc.Texture2D.MipSlice = 0;

	// デプスステンシルビュー作成
	hr = gDevice->CreateDepthStencilView(gDepthBufferTex, &dsvDesc, &gDepthStencil);
	if (FAILED(hr)) { return hr; }


	/***************  ビューポートを作成  ***************/
	D3D11_VIEWPORT vp;
	vp.Width = (float)_w;
	vp.Height = (float)_h;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	gDeviceContext->RSSetViewports(1, &vp);


	/***************  ビューポートを作成  ***************/
	gDeviceContext->OMSetRenderTargets(1, &gRendetTarget, gDepthStencil);


	/***************  頂点設定  ***************/
	Vertex v[4];
	v[0].pos = { -0.5f, -0.5f, 0 };
	v[0].color = { 1.0f, 1.0f, 1.0f, 1.0f };
	v[1].pos = { -0.5f, 0.5f, 0 };
	v[1].color = { 1.0f, 1.0f, 1.0f, 1.0f };
	v[2].pos = { 0.5f, -0.5f, 0 };
	v[2].color = { 1.0f, 1.0f, 1.0f, 1.0f };
	v[3].pos = { 0.5f, 0.5f, 0 };
	v[3].color = { 1.0f, 1.0f, 1.0f, 1.0f };

	/***************  頂点バッファを作成  ***************/
	D3D11_BUFFER_DESC vBufferDesc;
	vBufferDesc.Usage = D3D11_USAGE_DEFAULT;
	vBufferDesc.ByteWidth = sizeof(Vertex) * 4;
	vBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vBufferDesc.CPUAccessFlags = 0;
	vBufferDesc.MiscFlags = 0;
	vBufferDesc.StructureByteStride = 0;
	D3D11_SUBRESOURCE_DATA vSubResourceData;
	vSubResourceData.pSysMem = v;
	vSubResourceData.SysMemPitch = 0;
	vSubResourceData.SysMemSlicePitch = 0;
	hr = gDevice->CreateBuffer(&vBufferDesc, &vSubResourceData, &gVertexBufferA);
	if (FAILED(hr)) { return hr; }


	v[0].color = { 1.0f, 0.0f, 0.0f, 1.0f };
	v[1].color = { 1.0f, 0.0f, 0.0f, 1.0f };
	v[2].color = { 1.0f, 0.0f, 0.0f, 1.0f };
	v[3].color = { 1.0f, 0.0f, 0.0f, 1.0f };
	hr = gDevice->CreateBuffer(&vBufferDesc, &vSubResourceData, &gVertexBufferB);
	if (FAILED(hr)) { return hr; }

	/***************  インデックス設定  ***************/
	UINT index[4] = { 0,1,2,3 };

	/***************  インデックスバッファを作成  ***************/
	D3D11_BUFFER_DESC iBufferDesc;
	iBufferDesc.Usage = D3D11_USAGE_DEFAULT;
	iBufferDesc.ByteWidth = sizeof(UINT) * 4;
	iBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
	iBufferDesc.CPUAccessFlags = 0;
	iBufferDesc.MiscFlags = 0;
	iBufferDesc.StructureByteStride = 0;
	D3D11_SUBRESOURCE_DATA iSubResourceData;
	iSubResourceData.pSysMem = index;
	iSubResourceData.SysMemPitch = 0;
	iSubResourceData.SysMemSlicePitch = 0;
	hr = gDevice->CreateBuffer(&iBufferDesc, &iSubResourceData, &gIndexBuffer);
	if (FAILED(hr)) { return hr; }

	/***************  頂点、インデックスバッファを設定  ***************/
	gDeviceContext->IASetIndexBuffer(gIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
	gDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);

	/***************  頂点レイアウト  ***************/
	D3D11_INPUT_ELEMENT_DESC inElementDesc[] = {
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 4 * 3, D3D11_INPUT_PER_VERTEX_DATA, 0 }
	};

	/***************  頂点シェーダを作成  ***************/
	hr = gDevice->CreateVertexShader(&g_VS_Main, sizeof(g_VS_Main), nullptr, &gVertexShader);
	if (FAILED(hr)) { return hr; }
	gDeviceContext->VSSetShader(gVertexShader, nullptr, 0);

	/***************  頂点レイアウトを作成  ***************/
	hr = gDevice->CreateInputLayout(inElementDesc, 2, &g_VS_Main, sizeof(g_VS_Main), &gInputLayout);
	if (FAILED(hr)) { return hr; }
	gDeviceContext->IASetInputLayout(gInputLayout);

	/***************  ピクセルシェーダを作成  ***************/
	hr = gDevice->CreatePixelShader(&g_PS_Main, sizeof(g_PS_Main), nullptr, &gPixelShader);
	if (FAILED(hr)) { return hr; }
	gDeviceContext->PSSetShader(gPixelShader, nullptr, 0);

	/***************  定数バッファを作成  ***************/
	D3D11_BUFFER_DESC cb;
	cb.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	cb.ByteWidth = sizeof(ShaderIn);
	cb.StructureByteStride = 0;
	cb.MiscFlags = 0;
	cb.Usage = D3D11_USAGE_DYNAMIC;
	cb.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	hr = gDevice->CreateBuffer(&cb, NULL, &gConstantBuffer);
	if (FAILED(hr)) { return hr; }
	gDeviceContext->VSSetConstantBuffers(0, 1, &gConstantBuffer);

	gDeviceContext->HSSetShader(nullptr, nullptr, 0);
	gDeviceContext->DSSetShader(nullptr, nullptr, 0);
	gDeviceContext->GSSetShader(nullptr, nullptr, 0);


	/***************  デフォルトのラスタライザを設定  ***************/
	ID3D11RasterizerState* rasterState = NULL;
	D3D11_RASTERIZER_DESC rsState;
	rsState.FillMode = D3D11_FILL_SOLID;    // ポリゴン面描画
	rsState.CullMode = D3D11_CULL_NONE;     // 両面描画
	rsState.FrontCounterClockwise = FALSE;   // 反時計回りを表面
	rsState.DepthBias = 0;
	rsState.DepthBiasClamp = 0;
	rsState.SlopeScaledDepthBias = 0;
	rsState.DepthClipEnable = TRUE;
	rsState.ScissorEnable = FALSE;          // シザー矩形無効

	// スワップチェーンのマルチサンプリングの設定にあわせる
	DXGI_SWAP_CHAIN_DESC swapDesc;
	gSwapChain->GetDesc(&swapDesc);
	if (swapDesc.SampleDesc.Count != 1)
		rsState.MultisampleEnable = TRUE;
	else
		rsState.MultisampleEnable = FALSE;

	rsState.AntialiasedLineEnable = FALSE;
	hr = gDevice->CreateRasterizerState(&rsState, &rasterState);
	if (FAILED(hr)) { return hr; }

	gDeviceContext->RSSetState(rasterState);
	SAFE_RELEASE(rasterState);


	/***************  デフォルトの深度ステートを設定  ***************/
	ID3D11DepthStencilState* dsState = nullptr;
	D3D11_DEPTH_STENCIL_DESC dsdesc;
	ZeroMemory(&dsdesc, sizeof(D3D11_DEPTH_STENCIL_DESC));
	dsdesc.DepthEnable = TRUE;
	dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
	dsdesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
	dsdesc.StencilEnable = FALSE;
	gDevice->CreateDepthStencilState(&dsdesc, &dsState);
	gDeviceContext->OMSetDepthStencilState(dsState, 0);
	SAFE_RELEASE(dsState);


	/***************  オブジェクト位置  ***************/
	gAPos.x = -0.3f;
	gAPos.z = 0;
	gBPos.x = 0.3f;
	gBPos.z = 0;

	return S_OK;
}

void Update()
{
	// Z or X + ↑ or ↓ でオブジェクトのZ座標を移動
	if (GetAsyncKeyState('Z')) {
		if (GetAsyncKeyState(VK_UP)) { gAPos.z += 0.1f; }
		else if (GetAsyncKeyState(VK_DOWN)) { gAPos.z -= 0.1f; }
	}
	if (GetAsyncKeyState('X')) {
		if (GetAsyncKeyState(VK_UP)) { gBPos.z += 0.1f; }
		else if (GetAsyncKeyState(VK_DOWN)) { gBPos.z -= 0.1f; }
	}
}

void Draw()
{
	UINT stride = sizeof(Vertex);
	UINT offset = 0;

	// レンダーターゲット、深度バッファをクリア
	float ClearColor[] = { 0.0f, 0.0f, 1.0f, 1.0f };
	gDeviceContext->ClearRenderTargetView(gRendetTarget, ClearColor);
	gDeviceContext->ClearDepthStencilView(gDepthStencil, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

	D3DXMATRIX mW, mV, mP, mWVP;
	ShaderIn shaderIn;
	D3D11_MAPPED_SUBRESOURCE mappedResource;

	// ビュー、射影行列を計算
	D3DXMatrixPerspectiveFovLH(&mP, D3DXToRadian(60), 4.0f / 3.0f, 0, 1000);
	D3DXMatrixLookAtLH(&mV, &D3DXVECTOR3(0, 0, -2.0f), &D3DXVECTOR3(0, 0, 0), &D3DXVECTOR3(0, 1, 0));

	// オブジェクトA
	D3DXMatrixTranslation(&mW, gAPos.x, gAPos.y, gAPos.z);
	mWVP = mW * mV * mP;
	shaderIn.mWVP = mWVP;
	if (SUCCEEDED(gDeviceContext->Map(gConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource)))
	{
		memcpy_s(mappedResource.pData, mappedResource.RowPitch, &shaderIn, sizeof(ShaderIn));
		gDeviceContext->Unmap(gConstantBuffer, 0);
	}
	gDeviceContext->IASetVertexBuffers(0, 1, &gVertexBufferA, &stride, &offset);		// 頂点バッファ設定
	gDeviceContext->DrawIndexed(4, 0, 0);	// 描画

	// オブジェクトB
	D3DXMatrixTranslation(&mW, gBPos.x, gBPos.y, gBPos.z);
	mWVP = mW * mV * mP;
	shaderIn.mWVP = mWVP;
	if (SUCCEEDED(gDeviceContext->Map(gConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource)))
	{
		memcpy_s(mappedResource.pData, mappedResource.RowPitch, &shaderIn, sizeof(ShaderIn));
		gDeviceContext->Unmap(gConstantBuffer, 0);
	}
	gDeviceContext->IASetVertexBuffers(0, 1, &gVertexBufferB, &stride, &offset);		// 頂点バッファ設定
	gDeviceContext->DrawIndexed(4, 0, 0);	// 描画

	gSwapChain->Present(0, 0);
}

/////////////////////////////////////////////////////////////////////
//
//	Release
//	解放
//
/////////////////////////////////////////////////////////////////////
void Release()
{
	SAFE_DELETE(gWindow);
	SAFE_RELEASE(gDevice);
	SAFE_RELEASE(gDeviceContext);
	SAFE_RELEASE(gFactory);
	SAFE_RELEASE(gAdapter);
	SAFE_RELEASE(gSwapChain);

	SAFE_RELEASE(gBackBufferTex);
	SAFE_RELEASE(gRendetTarget);

	SAFE_RELEASE(gDepthBufferTex);
	SAFE_RELEASE(gDepthStencil);

	SAFE_RELEASE(gVertexBufferA);
	SAFE_RELEASE(gVertexBufferB);
	SAFE_RELEASE(gIndexBuffer);

	SAFE_RELEASE(gVertexShader);
	SAFE_RELEASE(gInputLayout);
	SAFE_RELEASE(gPixelShader);

	SAFE_RELEASE(gConstantBuffer);
}

/////////////////////////////////////////////////////////////////////
//
//	ControlFPS
//	FPS制御
//
/////////////////////////////////////////////////////////////////////
void ControlFPS()
{
	DWORD endTime = timeGetTime();
	if (endTime - gStartTime < 16) {
		Sleep(16 - (endTime - gStartTime));
	}
}

UTWindow.h

コード:

//////////////////////////////////////////////////////////////////////////////
//
//  UTWindow.h
//	Windowクラス
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

class UTWindow
{
public:
	UTWindow();
	~UTWindow();

	// ウインドウを作成する
	BOOL	Create(HINSTANCE _hInst, int _w, int _h);

	// メッセージ処理
	int		MessageProc();

	/*****  取得  *****/
	HWND	GetHandle() { return mHwnd; }
	int		GetWidth() { return mWidth; }
	int		GetHeight() { return mHeight; }


private:
	HWND	mHwnd;					// ウインドウ ハンドル
	MSG		mMsg;					// メッセージ
	int		mX, mY;					// 座標
	int		mWidth, mHeight;		// 幅、高さ
	LPCTSTR	mWinTitle;				// タイトル
	HBRUSH	mBackColor;				// 背景色

public:
	// ウインドウプロシージャ
	static LRESULT APIENTRY WndDefFunc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
};

UTWindow.cpp

コード:

//////////////////////////////////////////////////////////////////////////////
//
//  UTWindow.cpp
//
//////////////////////////////////////////////////////////////////////////////


#include <windows.h>
#include "UTWindow.h"


/////////////////////////////////////////////////////////////////////
//
//	UTWindow
//	コンストラクタ
//
/////////////////////////////////////////////////////////////////////
UTWindow::UTWindow()
{
	mX = 0;
	mY = 0;
	mWidth = 0;
	mHeight = 0;
	mWinTitle = "DirectX11 Test";
	mBackColor = (HBRUSH)GetStockObject(WHITE_BRUSH);
}

/////////////////////////////////////////////////////////////////////
//
//	~UTWindow
//	デストラクタ
//
/////////////////////////////////////////////////////////////////////
UTWindow::~UTWindow()
{
}

/////////////////////////////////////////////////////////////////////
//
//	Create
//	ウインドウを作成する
//
//	HINSTANCE _hInst		:	インスタンス
//	int _w					:	幅
//	int _h					:	高さ
//
//	return					:	成功でTRUE、失敗でFALSE
//
/////////////////////////////////////////////////////////////////////
BOOL UTWindow::Create(HINSTANCE _hInst, int _w, int _h)
{
	mWidth = _w;
	mHeight = _h;

	WNDCLASS wc;

	wc.style = CS_DBLCLKS;
	wc.lpfnWndProc = WndDefFunc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = _hInst;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = mBackColor;
	wc.lpszMenuName = NULL;
	wc.lpszClassName = mWinTitle;

	RegisterClass(&wc);

	mHwnd = CreateWindowEx(
		0,
		mWinTitle,
		mWinTitle,
		WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MAXIMIZEBOX,
		mX,
		mY,
		mWidth, mHeight,
		NULL, NULL, _hInst,
		NULL);

	if (!mHwnd)return FALSE;

	ShowWindow(mHwnd, SW_SHOW);
	UpdateWindow(mHwnd);
	SetFocus(mHwnd);

	return TRUE;
}

/////////////////////////////////////////////////////////////////////
//
//	MessageProc
//	メッセージ処理
//
/////////////////////////////////////////////////////////////////////
int UTWindow::MessageProc()
{
	if (PeekMessage(&mMsg, NULL, 0, 0, PM_NOREMOVE))
	{
		if (!GetMessage(&mMsg, NULL, 0, 0)) {
			return -1;
		}

		TranslateMessage(&mMsg);
		DispatchMessage(&mMsg);
		return 1;
	}
	else {
		return 0;
	}
}

/////////////////////////////////////////////////////////////////////
//
//	WndDefFunc
//	ウインドウプロシージャ
//
/////////////////////////////////////////////////////////////////////
LRESULT UTWindow::WndDefFunc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}
Include.h

コード:

#pragma once

#include <windows.h>
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <mmsystem.h>
#include <mmreg.h>

// STL
#include <vector>
#include <algorithm>
#include <string>
#include <functional>

// DirectX11
#include <d3dx11async.h>
#include <d3dcommon.h>
#include <dxgi.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <d3dx11.h>

// DirectX9
#include <d3dx9.h>


// 解放マクロ
#define SAFE_FREE(p)				if(p){free(p);p=NULL;}	
#define SAFE_RELEASE(p)			if(p){p->Release();p=NULL;}	
#define SAFE_DELETE(p)			if(p){delete p;p=NULL;}		
#define SAFE_DELETE_ARRAY(p)		if(p){delete[] p;p=NULL;}	


#define	DispMessage(mes)			MessageBox(NULL, mes, "Message", MB_OK);


#pragma comment(lib, "d3dcompiler.lib")
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "dxguid.lib")

#pragma comment(lib, "Strmiids.lib")
#pragma comment(lib, "winmm.lib")

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectX11で深度バッファが機能しない

#2

投稿記事 by ISLe » 8年前

こちらの環境でビルドできないのであてずっぽうですが
深度バッファテクスチャに対して、Shader Resource Viewを生成する必要があるような気がします。

toryu

Re: DirectX11で深度バッファが機能しない

#3

投稿記事 by toryu » 8年前

深度バッファテクスチャのShaderResourceViewを作成しても深度バッファは機能しませんでした。

検証用プログラムの概要を書き忘れていたので追記します。
2つの四角形ポリゴンを前後させてZ比較が行われているかどうかを検証するものです。
現状はZ座標をどれだけ動かしても前後が入れ替わりません。
シェーダは頂点座標を計算し、色を出力する単純なものです。

TestShader.hlsl

コード:

// ワールド行列 × ビュー × 射影行列
cbuffer cbMatrixWVP : register(b0)
{
	row_major  float4x4 g_matWVP : packoffset(c0);
};

// 頂点シェーダーの入力パラメータ
struct VS_IN
{
	float3 pos   : POSITION;   // 頂点座標
	float4 color : COLOR;      // 頂点カラー
};

// 頂点シェーダーの出力パラメータ
struct VS_OUT
{
	float4 pos   : SV_POSITION;
	float4 color : COLOR0;
};

// 頂点シェーダー
VS_OUT VS_Main(VS_IN In)
{
	VS_OUT Out;

	Out.pos = mul(float4(In.pos, 1), g_matWVP);
	Out.color = In.color;

	return Out;
}

// ピクセルシェーダ
float4 PS_Main(VS_OUT In) : SV_TARGET
{
	return In.color;
}

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectX11で深度バッファが機能しない

#4

投稿記事 by ISLe » 8年前

toryu さんが書きました:2つの四角形ポリゴンを前後させてZ比較が行われているかどうかを検証するものです。
現状はZ座標をどれだけ動かしても前後が入れ替わりません。
それは、Zバッファの機能であって、ステンシルバッファの機能ではないと思うのですが。

深度バッファをステンシルバッファと混同していませんか?

toryu

Re: DirectX11で深度バッファが機能しない

#5

投稿記事 by toryu » 8年前

現在問題になっているのはZバッファが全く機能せず、オブジェクトの前後が入れ替わらないことです。
誤解を生む表現があったなら申し訳ないです。

toryu

Re: DirectX11で深度バッファが機能しない

#6

投稿記事 by toryu » 8年前

検証を続けていた所、問題が解決しました。
D3DXMatrixPerspectiveFovLH関数の4つ目の引数が0になっていたことで、行列演算後Zの値が常に1になってしまうことが原因でした。
深度バッファは正しく生成され、値も書き込まれていました。
ご協力ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る