Microsoft Visual 2017 Community C++ Direct3D 11.0( SM 5.0 ) DirectXTex texture processing library XMLLite DirectXMath |
■Direct3D11 Percentage Closer Filter | Prev Top Next |
関連ページ:Direct3D11 自作ライブラリ |
Aシェーダー系で使用するソースです。
PercentageCloserFilter_Pass0.hlsl | PercentageCloserFilterのPass0のhlslファイル |
PercentageCloserFilter_Pass1.hlsl | PercentageCloserFilterのPass1のhlslファイル |
PercentageCloserFilter.h | PercentageCloserFilterクラスのヘッダーファイル |
PercentageCloserFilter.cpp | PercentageCloserFilterクラスのソースファイル |
B個別に使用するソースです。
F14Mesh.h | F14メッシュクラスのヘッダーファイル |
F14Mesh.cpp | F14メッシュクラスのソースファイル |
PlaneMesh.h | 地面メッシュクラスのヘッダーファイル |
PlaneMesh.cpp | 地面メッシュクラスのソースファイル |
main.cpp | main関数のソースファイル |
// ************************************************************ // Percentage Closer Filter Pass0 // ************************************************************ // 定数バッファ cbuffer CBuffer : register( b0 ) { column_major float4x4 g_matLightWorldViewProj : packoffset( c0 ); // ライトビューの正射影行列 }; // 頂点シェーダーの入力パラメータ struct VS_IN { float3 pos : POSITION; // 頂点座標 float3 normal : NORMAL; // 法線ベクトル float2 texel : TEXCOORD; // テクセル }; // 頂点シェーダーの出力パラメータ struct VS_OUT_PS_IN { float4 pos : SV_POSITION; }; // 頂点シェーダー VS_OUT_PS_IN PercentageCloserFilter_Pass0_VS_Main( VS_IN In ) { VS_OUT_PS_IN Out; Out.pos = mul( float4( In.pos, 1.0f ), g_matLightWorldViewProj ); return Out; }
---PercentageCloserFilter_Pass1.hlsl---
// ************************************************************ // Percentage Closer Filter Pass1 // ************************************************************ // 定数バッファ cbuffer CBuffer : register( b0 ) { column_major float4x4 g_matCameraWorldViewProj : packoffset( c0 ); // カメラビューの射影行列 column_major float4x4 g_matLightWorldViewProj : packoffset( c4 ); // ライトビューの正射影行列 float4 g_vecLightPos : packoffset( c8 ); // ローカル座標系での平行光源の位置ベクトル float4 g_TexelSize : packoffset( c9 ); // 1テクセルサイズ }; // 頂点シェーダーの入力パラメータ struct VS_IN { float3 pos : POSITION; // 頂点座標 float3 normal : NORMAL; // 法線ベクトル float2 texel : TEXCOORD; // テクセル }; // テクスチャー Texture2D g_DecalMap : register( t0 ); // 深度マップ Texture2D g_DepthMap : register( t5 ); // サンプラーステート SamplerState g_Sampler : register( s0 ); // 比較サンプラステート SamplerComparisonState g_ShadowSampler : register( s5 ); // 頂点シェーダーの出力パラメータ struct VS_OUT_PS_IN { float4 pos : SV_POSITION; float3 normal : NORMAL; float2 texel : TEXCOORD0; float4 posLWVP : TEXCOORD1; }; // 頂点シェーダー VS_OUT_PS_IN PercentageCloserFilter_Pass1_VS_Main( VS_IN In ) { VS_OUT_PS_IN Out; Out.pos = mul( float4( In.pos, 1.0f ), g_matCameraWorldViewProj ); Out.posLWVP = mul( float4( In.pos, 1.0f ), g_matLightWorldViewProj ); Out.normal = In.normal; Out.texel = In.texel; return Out; } // ピクセルシェーダ float4 PercentageCloserFilter_Pass1_PS_Main( VS_OUT_PS_IN In ) : SV_TARGET { float shadowColor; // テクセルを計算 float2 texel = float2( In.posLWVP.x / In.posLWVP.w * 0.5f + 0.5f, In.posLWVP.y / In.posLWVP.w * -0.5f + 0.5f ); // 深度マップの範囲外はとりあえず影なしにする if( texel.x < 0 || texel.x > 1 || texel.y < 0 || texel.y > 1 ) shadowColor = 1.0f; else { float PercentLit = 0; // ライトビュー上でのピクセルの深度値 float depthcompare = In.posLWVP.z / In.posLWVP.w; // バイアス depthcompare -= 0.002f; float cnt = 0; for( int i=-4; i<5; i+=2 ) { for( int j=-4; j<5; j+=2 ) { // ミップマップ0限定で depthcompare >= 深度マップの深度値 の場合、0 PercentLit += g_DepthMap.SampleCmpLevelZero( g_ShadowSampler, float2( texel.x + (float)i * g_TexelSize.x, texel.y + (float)j * g_TexelSize.y ), depthcompare ); cnt++; } } PercentLit = PercentLit / cnt; shadowColor = clamp( PercentLit, 0.3f, 1.0f ); } // ハーフランバート float lambert = dot( g_vecLightPos.xyz, In.normal ); lambert = lambert * 0.5f + 0.5f; // デカールマップ float4 decalmap = g_DecalMap.Sample( g_Sampler, In.texel ); return ( decalmap * min( lambert, shadowColor ) ).bgra; }
---PercentageCloserFilter.h---
#ifndef PERCENTAGE_CLOSER_FILTER_H #define PERCENTAGE_CLOSER_FILTER_H #include "../Common/UCommon.h" #include "../Common/UException.h" #include "../Common/UGraphicsPipeline.h" #include "../Common/UDirect3D11.h" class PercentageCloserFilter { private: // Direct3D用定数バッファ設定用構造体 typedef struct _CBUFFER_PASS0 { XMMATRIX matLightWorldViewProj; }CBUFFER_PASS0; typedef struct _CBUFFER_PASS1 { XMMATRIX matCameraWorldViewProj; XMMATRIX matLightWorldViewProj; XMFLOAT4 vecLightDir; XMFLOAT4 vecTexelSize; }CBUFFER_PASS1; ID3D11DepthStencilView* m_pDSView; ID3D11ShaderResourceView* m_pSRView; ID3D11RenderTargetView* m_pOldRTView; ID3D11DepthStencilView* m_pOldDSView; D3D11_VIEWPORT m_pOldViewport[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; UINT m_ViewportCount; // シェーダー用定数バッファ ID3D11Buffer* m_pConstantBuffers[2]; UGraphicsPipeline* m_pGraphicsPipeline[2]; ID3D11SamplerState* m_pSamplerComparisonState; DWORD m_Width, m_Height; int m_Pass; XMMATRIX m_MatLightViewProj; XMMATRIX m_MatCameraViewProj; XMFLOAT4 m_VecLightPos; public: PercentageCloserFilter(); virtual ~PercentageCloserFilter(); void Invalidate(); void Create( ID3D11Device* pD3DDevice, DWORD Width, DWORD Height ); void BeginPass( ID3D11DeviceContext* pD3DDeviceContext, UINT Pass, XMFLOAT4* pVecLightPos, XMMATRIX* pMatLightProj, XMMATRIX* pMatCameraView, XMMATRIX* pMatCameraProj ); void SetConstantBuffers( ID3D11DeviceContext* pD3DDeviceContext, XMMATRIX* pMatWorld ); void EndPass( ID3D11DeviceContext* pD3DDeviceContext ); inline UINT GetMaxPass(){ return 2; }; inline const ID3D11ShaderResourceView* GetDepthMap(){ return m_pSRView; }; }; #endif
---PercentageCloserFilter.cpp---
#include "../../Header/Shader/PercentageCloserFilter.h" #include "../../HLSL/PercentageCloserFilter_Pass0_VS_Main.h" #include "../../HLSL/PercentageCloserFilter_Pass1_VS_Main.h" #include "../../HLSL/PercentageCloserFilter_Pass1_PS_Main.h" PercentageCloserFilter::PercentageCloserFilter() { m_pDSView = nullptr; m_pSRView = nullptr; for( int i=0; i<_countof( m_pGraphicsPipeline ); i++ ) { m_pGraphicsPipeline[i] = nullptr; m_pConstantBuffers[i] = nullptr; } m_pSamplerComparisonState = nullptr; m_Pass = -1; } PercentageCloserFilter::~PercentageCloserFilter() { SAFE_RELEASE( m_pSamplerComparisonState ); for( int i=0; i<_countof( m_pGraphicsPipeline ); i++ ) { SAFE_DELETE( m_pGraphicsPipeline[i] ); SAFE_RELEASE( m_pConstantBuffers[i] ); } SAFE_RELEASE( m_pSRView ); SAFE_RELEASE( m_pDSView ); } void PercentageCloserFilter::Create( ID3D11Device* pD3DDevice, DWORD Width, DWORD Height ) { m_Width = Width; m_Height = Height; m_Pass = -1; // ******************************************************************************************************* // パス0用のUGraphicsPipelineの作成 // ******************************************************************************************************* m_pGraphicsPipeline[0] = NEW UGraphicsPipeline(); // ラスタライザーステートを作成する m_pGraphicsPipeline[0]->CreateRasterizerState( pD3DDevice, D3D11_CULL_MODE::D3D11_CULL_BACK ); // 深度ステンシルステートを作成する m_pGraphicsPipeline[0]->CreateDepthStencilState( pD3DDevice, TRUE, D3D11_DEPTH_WRITE_MASK::D3D11_DEPTH_WRITE_MASK_ALL ); // ブレンドステートを作成する UGraphicsPipeline::UEBLEND_STATE BlendStateType[1] = { UGraphicsPipeline::UEBLEND_STATE::NONE }; m_pGraphicsPipeline[0]->CreateBlendState( pD3DDevice, BlendStateType, 1 ); D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; // シェーダーを作成する #if defined(DEBUG) || defined(_DEBUG) m_pGraphicsPipeline[0]->CreateVertexShaderFromFile( pD3DDevice, _T("../HLSL/PercentageCloserFilter_Pass0.hlsl"), "PercentageCloserFilter_Pass0_VS_Main", layout, _countof( layout ) ); #else m_pGraphicsPipeline[0]->CreateVertexShaderFromMemory( pD3DDevice, (LPBYTE)g_PercentageCloserFilter_Pass0_VS_Main, sizeof( g_PercentageCloserFilter_Pass0_VS_Main ), layout, _countof( layout ) ); #endif // 深度ステンシルバッファを作成する UMaps::CreateDepthStencilView( pD3DDevice, m_Width, m_Height, &m_pDSView, &m_pSRView ); // 定数バッファを作成する m_pConstantBuffers[0] = m_pGraphicsPipeline[0]->CreateConstantBuffer( pD3DDevice, nullptr, sizeof( PercentageCloserFilter::CBUFFER_PASS0 ), D3D11_CPU_ACCESS_WRITE ); // ******************************************************************************************************* // パス1用のUGraphicsPipelineの作成 // シェーダーと定数バッファ以外はパス0の使いまわし // ******************************************************************************************************* m_pGraphicsPipeline[1] = NEW UGraphicsPipeline(); // シェーダーを作成する #if defined(DEBUG) || defined(_DEBUG) m_pGraphicsPipeline[1]->CreateVertexShaderFromFile( pD3DDevice, _T("../HLSL/PercentageCloserFilter_Pass1.hlsl"), "PercentageCloserFilter_Pass1_VS_Main", layout, _countof( layout ) ); m_pGraphicsPipeline[1]->CreatePixelShaderFromFile( pD3DDevice, _T("../HLSL/PercentageCloserFilter_Pass1.hlsl"), "PercentageCloserFilter_Pass1_PS_Main" ); #else m_pGraphicsPipeline[1]->CreateVertexShaderFromMemory( pD3DDevice, (LPBYTE)g_PercentageCloserFilter_Pass1_VS_Main, sizeof( g_PercentageCloserFilter_Pass1_VS_Main ), layout, _countof( layout ) ); m_pGraphicsPipeline[1]->CreatePixelShaderFromMemory( pD3DDevice, (LPBYTE)g_PercentageCloserFilter_Pass1_PS_Main, sizeof( g_PercentageCloserFilter_Pass1_PS_Main ) ); #endif // 定数バッファを作成する m_pConstantBuffers[1] = m_pGraphicsPipeline[1]->CreateConstantBuffer( pD3DDevice, nullptr, sizeof( PercentageCloserFilter::CBUFFER_PASS1 ), D3D11_CPU_ACCESS_WRITE ); // サンプラーステートを作成する m_pSamplerComparisonState = USamplers::CreateSamplerState(pD3DDevice, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT, D3D11_COMPARISON_LESS); } void PercentageCloserFilter::BeginPass( ID3D11DeviceContext* pD3DDeviceContext, UINT Pass, XMFLOAT4* pVecLightPos, XMMATRIX* pMatLightProj, XMMATRIX* pMatCameraView, XMMATRIX* pMatCameraProj ) { if (m_Pass != -1) { throw(UException(-1, _T("PercentageCloserFilter::BeginPass()はCreate()またはEndPass()実行後に使用してください"))); } m_Pass = (int)Pass; switch( m_Pass ) { case 0: { // 深度ステンシルビューを切り替える。レンダーターゲットビューは使用しない。 pD3DDeviceContext->OMGetRenderTargets( 1, &m_pOldRTView, &m_pOldDSView ); pD3DDeviceContext->OMSetRenderTargets( 0, nullptr, m_pDSView ); pD3DDeviceContext->RSGetViewports( &m_ViewportCount, nullptr ); pD3DDeviceContext->RSGetViewports( &m_ViewportCount, &m_pOldViewport[0] ); // ビューポートを切り替える。 D3D11_VIEWPORT Viewport[1]; Viewport[0].TopLeftX = 0; Viewport[0].TopLeftY = 0; Viewport[0].Width = (FLOAT)m_Width; Viewport[0].Height = (FLOAT)m_Height; Viewport[0].MinDepth = 0.0f; Viewport[0].MaxDepth = 1.0f; pD3DDeviceContext->RSSetViewports( 1, Viewport ); // 深度バッファをクリアする。 pD3DDeviceContext->ClearDepthStencilView( m_pDSView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0 ); m_VecLightPos = *pVecLightPos; // ライトビュー × 射影行列を作成 XMMATRIX matLightView = XMMatrixLookAtLH(XMLoadFloat3((XMFLOAT3*)&m_VecLightPos), XMLoadFloat3(&XMFLOAT3(0, 0, 0)), XMLoadFloat3(&XMFLOAT3(0, 1, 0))); m_MatLightViewProj = matLightView * (*pMatLightProj); m_MatCameraViewProj = XMMatrixIdentity(); } break; case 1: { // 深度マップをシェーダーに設定 pD3DDeviceContext->PSSetShaderResources( 5, 1, &m_pSRView ); pD3DDeviceContext->PSSetSamplers( 5, 1, &m_pSamplerComparisonState ); // ライトビューはPass0と同じにするためここでは設定しない // カメラビュー × 射影行列を作成 m_MatCameraViewProj = (*pMatCameraView) * (*pMatCameraProj); } break; default: throw(UException(-1, _T("PercentageCloserFilter::BeginPass()で無効なPassが指定されました"))); } // 各種ステートを設定する m_pGraphicsPipeline[0]->SetRasterizerState( pD3DDeviceContext ); m_pGraphicsPipeline[0]->SetDepthStencilState( pD3DDeviceContext ); m_pGraphicsPipeline[0]->SetBlendState( pD3DDeviceContext ); // 各種グラフィックパイプラインを設定 m_pGraphicsPipeline[m_Pass]->SetVertexShader( pD3DDeviceContext ); m_pGraphicsPipeline[m_Pass]->SetHullShader( pD3DDeviceContext ); m_pGraphicsPipeline[m_Pass]->SetDomainShader( pD3DDeviceContext ); m_pGraphicsPipeline[m_Pass]->SetGeometryShader( pD3DDeviceContext ); m_pGraphicsPipeline[m_Pass]->SetPixelShader( pD3DDeviceContext ); } void PercentageCloserFilter::SetConstantBuffers( ID3D11DeviceContext* pD3DDeviceContext, XMMATRIX* pMatWorld ) { HRESULT hr = E_FAIL; if (m_Pass == -1) { throw(UException(-1, _T("PercentageCloserFilter::SetConstantBuffers()はBeginPass()実行後に使用してください"))); } switch( m_Pass ) { case 0: { XMMATRIX matLightWorldViewProj; matLightWorldViewProj = (*pMatWorld) * m_MatLightViewProj; matLightWorldViewProj = XMMatrixTranspose( matLightWorldViewProj ); // 定数バッファを作成する D3D11_MAPPED_SUBRESOURCE mappedResource; if( FAILED( hr = pD3DDeviceContext->Map( m_pConstantBuffers[m_Pass], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource ) ) ) throw( UException( -1, _T("PercentageCloserFilter::SetConstantBuffers()でエラーが発生しました。Map()が失敗しました。") ) ); PercentageCloserFilter::CBUFFER_PASS0* cbuffer = (PercentageCloserFilter::CBUFFER_PASS0*)mappedResource.pData; ::CopyMemory( &cbuffer->matLightWorldViewProj, &matLightWorldViewProj, sizeof( XMMATRIX )); pD3DDeviceContext->Unmap( m_pConstantBuffers[m_Pass], 0 ); // 定数バッファを設定 pD3DDeviceContext->VSSetConstantBuffers( 0, 1, &m_pConstantBuffers[m_Pass] ); pD3DDeviceContext->PSSetConstantBuffers( 0, 1, &m_pConstantBuffers[m_Pass] ); } break; case 1: { XMMATRIX matCameraWorldViewProj, matLightWorldViewProj; matCameraWorldViewProj = (*pMatWorld) * m_MatCameraViewProj; matCameraWorldViewProj = XMMatrixTranspose( matCameraWorldViewProj ); matLightWorldViewProj = (*pMatWorld) * m_MatLightViewProj; matLightWorldViewProj = XMMatrixTranspose( matLightWorldViewProj ); // メッシュ基準のローカル座標系上での平行光源の方向ベクトルを計算する XMMATRIX matInv = XMMatrixInverse( nullptr, *pMatWorld ); XMVECTOR v = XMVector4Transform( XMLoadFloat4( &m_VecLightPos ), matInv ); XMVECTOR nv = XMVector3Normalize( v ); XMFLOAT4 localLightPos; XMStoreFloat4( &localLightPos, nv ); XMFLOAT4 texelSize = XMFLOAT4( (float)( 1.0f / m_Width ), (float)( 1.0f / m_Height ), 0, 0 ); // 定数バッファを作成する D3D11_MAPPED_SUBRESOURCE mappedResource; if( FAILED( hr = pD3DDeviceContext->Map( m_pConstantBuffers[m_Pass], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource ) ) ) throw( UException( -1, _T("PercentageCloserFilter::SetConstantBuffers()でエラーが発生しました。Map()が失敗しました。") ) ); PercentageCloserFilter::CBUFFER_PASS1* cbuffer = (PercentageCloserFilter::CBUFFER_PASS1*)mappedResource.pData; ::CopyMemory( &cbuffer->matLightWorldViewProj, &matLightWorldViewProj, sizeof( XMMATRIX )); ::CopyMemory( &cbuffer->matCameraWorldViewProj, &matCameraWorldViewProj, sizeof( XMMATRIX )); ::CopyMemory( &cbuffer->vecLightDir, &localLightPos, sizeof( XMFLOAT4 )); ::CopyMemory( &cbuffer->vecTexelSize, &texelSize, sizeof( XMFLOAT4 )); pD3DDeviceContext->Unmap( m_pConstantBuffers[m_Pass], 0 ); // 定数バッファを設定 pD3DDeviceContext->VSSetConstantBuffers( 0, 1, &m_pConstantBuffers[m_Pass] ); pD3DDeviceContext->PSSetConstantBuffers( 0, 1, &m_pConstantBuffers[m_Pass] ); } break; } } void PercentageCloserFilter::EndPass( ID3D11DeviceContext* pD3DDeviceContext ) { switch( m_Pass ) { case 0: // レンダーターゲットビューと深度ステンシルビューとビューポートを戻す pD3DDeviceContext->OMSetRenderTargets( 1, &m_pOldRTView, m_pOldDSView ); SAFE_RELEASE( m_pOldRTView ); SAFE_RELEASE( m_pOldDSView ); pD3DDeviceContext->RSSetViewports( m_ViewportCount, m_pOldViewport ); break; case 1: ID3D11ShaderResourceView* pNull = nullptr; pD3DDeviceContext->PSSetShaderResources( 5, 1, &pNull ); break; } m_Pass = -1; }
#include "../Header/Common/UCommon.h" #include "../Header/Common/UException.h" #include "../Header/Common/UDirect3D11.h" #include "../Header/Common/UDebugFont.h" #if defined(DEBUG) || defined(_DEBUG) #include "../Header/Common/USRViewRenderer.h" #endif #include "../Header/Shader/PercentageCloserFilter.h" #include "../Header/Mesh/F14Mesh.h" #include "../Header/Mesh/PlaneMesh.h" // アプリケーション名 TCHAR* AppName = _T("Direct3D11 Percentage Closer Filter"); // Direct3D関連の自作クラス UDirect3D11* g_pDirect3D11 = nullptr; PercentageCloserFilter* g_pPercentageCloserFilter = nullptr; F14Mesh* g_pF14Mesh = nullptr; PlaneMesh* g_pPlaneMesh = nullptr; UFPS* g_pFPS = nullptr; #if defined(DEBUG) || defined(_DEBUG) USRViewRenderer* g_pSRViewRenderer = nullptr; #endif DWORD g_Width = 640, g_Height = 480; // カメラビュー行列 XMMATRIX g_MatCameraView = XMMatrixIdentity(); // 射影行列 XMMATRIX g_MatCameraProj = XMMatrixPerspectiveFovLH( XM_PI / 5.0f, (float)g_Width / (float)g_Height, 0.01f, 500.0f ); // 正行列 XMMATRIX g_MatLightOrtho = XMMatrixOrthographicLH( (float)250, (float)250, 1.0f, 800.0f ); // 平行光源の位置ベクトル XMFLOAT4 g_VecLightPos = XMFLOAT4( 300.0f, 200.0f, 300.0f, 0 ); // メモリ解放 void Invalidate() { #if defined(DEBUG) || defined(_DEBUG) SAFE_DELETE( g_pSRViewRenderer ); #endif SAFE_DELETE( g_pFPS ); SAFE_DELETE( g_pPercentageCloserFilter ); SAFE_DELETE( g_pPlaneMesh ); SAFE_DELETE( g_pF14Mesh ); SAFE_DELETE( g_pDirect3D11 ); } // ウィンドウプロシージャ LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, UINT wParam, LONG lParam ) { switch( msg ) { case WM_KEYUP: // アプリ終了 if( wParam == VK_ESCAPE ) ::DestroyWindow( hWnd ); break; case WM_DESTROY: ::PostQuitMessage(0); break; default: return ::DefWindowProc( hWnd, msg, wParam, lParam ); } return 0L; } // Direct3Dの作成 void CreateDirect3D( HINSTANCE hInstance ) { DXGI_MODE_DESC* pModeDescArray = nullptr; __try { DXGI_MODE_DESC ModeDesc; UINT num; // ディスプレイモード一覧の数を取得する g_pDirect3D11->GetDisplayMode( nullptr, &num ); pModeDescArray = NEW DXGI_MODE_DESC[num]; // ディスプレイモード一覧を取得する g_pDirect3D11->GetDisplayMode( pModeDescArray, &num ); bool find = false; for( UINT i=0; i<num; i++ ) { // 適切な解像度のディスプレイモードを検索する if( pModeDescArray[i].Width == g_Width && pModeDescArray[i].Height == g_Height ) { find = true; ::CopyMemory( &ModeDesc, &pModeDescArray[i], sizeof( DXGI_MODE_DESC ) ); break; } } if( find == false ) throw( UException( -1, _T("InitDirect3D()でエラーが発生しました。適切なディスプレイモードの解像度を取得できません。") ) ); // ウィンドウの作成およびDirect3D の作成 g_pDirect3D11->CreateDirect3D11( AppName, hInstance, WndProc, &ModeDesc, TRUE, TRUE ); // FPS描画クラス g_pFPS->CreateMesh( g_pDirect3D11->m_pD3DDevice ); #if defined(DEBUG) || defined(_DEBUG) g_pSRViewRenderer->Create( g_pDirect3D11->m_pD3DDevice, 1.0f - 400.0f / (float)g_Width, 1.0f, 1.0f, 1.0f - 400.0f / (float)g_Height ); #endif } __finally { SAFE_DELETE_ARRAY( pModeDescArray ); } } void CreateGraphicePipeline() { DWORD Width = 1024, Height = 1024; g_pPercentageCloserFilter->Create( g_pDirect3D11->m_pD3DDevice, Width, Height ); } // メッシュを作成する void CreateMesh() { g_pF14Mesh = NEW F14Mesh(); g_pF14Mesh->CreateMesh( g_pDirect3D11->m_pD3DDevice ); g_pPlaneMesh = NEW PlaneMesh(); g_pPlaneMesh->CreateMesh( g_pDirect3D11->m_pD3DDevice ); } void CreateResource( HINSTANCE hInstance ) { // Direct3D 関連自作クラスのインスタンスを作成 // CreateDirect3D()関数内でインスタンスの作成を行うと、C2712 エラーが発生するのでここで行う。 g_pDirect3D11 = NEW UDirect3D11(); g_pPercentageCloserFilter = NEW PercentageCloserFilter(); g_pFPS = NEW UFPS(); #if defined(DEBUG) || defined(_DEBUG) g_pSRViewRenderer = NEW USRViewRenderer(); #endif // Direct3Dの作成 CreateDirect3D( hInstance ); // グラフィックパイプラインリソースの作成 CreateGraphicePipeline(); // リソースの作成 CreateMesh(); } void NextFrame() { // ビュー行列 if( GetKeyState( VK_UP ) & 0x8000 ) g_MatCameraView *= XMMatrixTranslation( 0, 0, -0.1f ); if( GetKeyState( VK_DOWN ) & 0x8000 ) g_MatCameraView *= XMMatrixTranslation( 0, 0, 0.1f ); if( GetKeyState( VK_RIGHT ) & 0x8000 ) g_MatCameraView *= XMMatrixRotationY( -0.002f ); if( GetKeyState( VK_LEFT ) & 0x8000 ) g_MatCameraView *= XMMatrixRotationY( 0.002f ); if( GetKeyState( 'Q' ) & 0x8000 ) g_MatCameraView *= XMMatrixRotationX( 0.002f ); if( GetKeyState( 'A' ) & 0x8000 ) g_MatCameraView *= XMMatrixRotationX( -0.002f ); g_pFPS->NextFrame(); g_pF14Mesh->NextFrame(); g_pPlaneMesh->NextFrame(); } // 描画処理 HRESULT Render() { HRESULT hr = E_FAIL; static float ClearColor[4] = { 0.3f, 0.3f, 1.0f, 1.0f }; // バックバッファをクリアする。 g_pDirect3D11->ClearBackBuffer( ClearColor ); // 深度バッファをクリアする。 g_pDirect3D11->ClearDepthStencilView( D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0 ); for( UINT i=0; i<g_pPercentageCloserFilter->GetMaxPass(); i++ ) { g_pPercentageCloserFilter->BeginPass( g_pDirect3D11->m_pD3DDeviceContext, i, &g_VecLightPos, &g_MatLightOrtho, &g_MatCameraView, &g_MatCameraProj ); for( UINT j=0; j<g_pF14Mesh->GetMaxCount(); j++ ) { // 定数バッファを設定 g_pPercentageCloserFilter->SetConstantBuffers( g_pDirect3D11->m_pD3DDeviceContext, g_pF14Mesh->GetMatWorld(j) ); // レンダリング g_pF14Mesh->Render( g_pDirect3D11->m_pD3DDeviceContext ); } // 定数バッファを設定 g_pPercentageCloserFilter->SetConstantBuffers( g_pDirect3D11->m_pD3DDeviceContext, g_pPlaneMesh->GetMatWorld() ); // レンダリング g_pPlaneMesh->Render( g_pDirect3D11->m_pD3DDeviceContext ); g_pPercentageCloserFilter->EndPass( g_pDirect3D11->m_pD3DDeviceContext ); } #if defined(DEBUG) || defined(_DEBUG) int SrvRGB[] = { 0, 1, 2, 3 }; g_pSRViewRenderer->SetSRView( g_pPercentageCloserFilter->GetDepthMap(), SrvRGB ); g_pSRViewRenderer->Render( g_pDirect3D11->m_pD3DDeviceContext ); #endif g_pFPS->Render( g_pDirect3D11->m_pD3DDeviceContext ); // レンダリングされたイメージをユーザーに表示。 if( FAILED( hr = g_pDirect3D11->Present( 0, 0 ) ) ) throw( UException( hr, _T("IDXGISwapChain::Present()が失敗しました") ) ); return hr; } // メイン関数 int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE, LPTSTR, INT ) { // メモリリーク検出 // _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | CRTDBG_CHECK_ALWAYS_DF ); _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_EVERY_1024_DF ); MSG msg = {0}; try { CreateResource( hInstance ); ::ShowWindow( g_pDirect3D11->m_hWnd, SW_SHOW ); ::UpdateWindow( g_pDirect3D11->m_hWnd ); // メッセージループ do { if( ::PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } else { NextFrame(); Render(); } }while( msg.message != WM_QUIT ); } catch( UException ex ) { ::MessageBox( nullptr, ex.m_pErrorStr, _T("エラー"), MB_OK ); } Invalidate(); ::UnregisterClass( AppName, hInstance ); return msg.wParam; }