Microsoft Visual 2017 Community C++ Direct3D 11.0( SM 5.0 ) DirectXTex texture processing library XMLLite DirectXMath |
■Direct3D11 Colored Stochastic Shadow Maps | Prev Top Next |
関連ページ:Direct3D11 自作ライブラリ |
できはなよくないのですが、一応完成したのでアップしておきます。
概要について簡単に説明すると、ぶっちゃけ色がついた投影シャドウマップです。
これは、普通に実装しようとすれば、RGB成分を持つカラーマップ( 透明度マップ )と深度マップを使用すると思います。
今回のネタはこのカラーマップと深度マップを一個のマップにまとめてメモリ使用量を低減しようというものです。
ではどうやってまとめるかというと、ノイズマップを使用して遮蔽率を確立的に計算していくわけですが、
メッシュのアルファチャンネルを変更しつつ、サンプルを動かしたほうがわかりやすいかもですので、説明はここまでとします。すいません。
アルゴリズムは以下の流れになります。
1.不透明メッシュの深度値を取得。
2.1をRGBカラー・深度マップにコピー。
3.ブレンドステートで深度テストを行う設定にして、半透明メッシュのカラーと深度値を取得。このときノイズマップを使用して深度値の更新を制御する。
4.3のカラー・深度マップをPCFを使用してぼかして、カラー( 場合によっては影 )をメッシュに適用する。
といった感じになります。
ブレンドステートで深度テストを行う方法については、UGraphicsPipeline.cppを参照してください。
Aシェーダー系で使用するソースです。
ColoredStochasticShadowMaps_Pass0.hlsl | 不透明メッシュの深度マップを生成するシェーダーソース |
ColoredStochasticShadowMaps_Pass1.hlsl | 半透明メッシュのカラーおよび深度マップを生成するシェーダーソース |
ColoredStochasticShadowMaps_Pass2.hlsl | シャドウを適用するためのシェーダーソース |
ColoredStochasticShadowMaps.h | ColoredStochasticShadowMapsクラスのヘッダーファイル |
ColoredStochasticShadowMaps.cpp | ColoredStochasticShadowMapsクラスのソースファイル |
B個別に使用するソースです。
WallMesh.h | 壁メッシュクラスのヘッダーファイル |
WallMesh.cpp | 壁メッシュクラスのソースファイル |
PlaneMesh.h | 地面メッシュクラスのヘッダーファイル |
PlaneMesh.cpp | 地面メッシュクラスのソースファイル |
main.cpp | main関数のソースファイル |
// ************************************************************ // Colored Stochastic Shadow Maps ポリゴンの深度値 // ************************************************************ // 定数バッファ 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 ColoredStochasticShadowMaps_Pass0_VS_Main( VS_IN In ) { VS_OUT_PS_IN Out; Out.pos = mul( float4( In.pos, 1.0f ), g_matLightWorldViewProj ); return Out; }
---ColoredStochasticShadowMaps_Pass1.hlsl---
// ************************************************************ // Colored Stochastic Shadow Maps カラーマップの作成 // ************************************************************ // 定数バッファ cbuffer CBuffer : register( b0 ) { column_major float4x4 g_matLightWorldViewProj : packoffset( c0 ); // ライトビューのワールドビュー射影行列 }; // テクスチャー Texture2Dg_GlassMap : register( t0 ); Texture2D g_NoiseMap : register( t1 ); // サンプラーステート SamplerState g_GlassSampler : register( s0 ); SamplerState g_NoiseSampler : register( s1 ); // 頂点シェーダーの入力パラメータ struct VS_IN { float3 pos : POSITION; // 頂点座標 float3 normal : NORMAL; // 法線ベクトル float2 texel : TEXCOORD; // テクセル }; // 頂点シェーダーの出力パラメータ struct VS_OUT_PS_IN { float4 pos : SV_POSITION; float2 texel : TEXCOORD0; float4 posWVP : TEXCOORD1; }; // 頂点シェーダー VS_OUT_PS_IN ColoredStochasticShadowMaps_Pass1_VS_Main( VS_IN In ) { VS_OUT_PS_IN Out; Out.pos = mul( float4( In.pos, 1.0f ), g_matLightWorldViewProj ); Out.texel = In.texel; Out.posWVP = Out.pos; return Out; } // ピクセルシェーダ float4 ColoredStochasticShadowMaps_Pass1_PS_Main( VS_OUT_PS_IN In ) : SV_TARGET { float4 Out; float4 col = g_GlassMap.Sample( g_GlassSampler, In.texel ); float2 texel = float2( In.posWVP.x / In.posWVP.w * 0.5f + 0.5f, In.posWVP.y / In.posWVP.w * -0.5f + 0.5f ); float noise = g_NoiseMap.Sample( g_NoiseSampler, texel ).r; float3 rgb; float z = In.posWVP.z / In.posWVP.w; for( uint i=0; i<3; i++ ) { // 色はカラーマップを適用するとき、積算合成するため反転する。 // アルファチャンネルが0のときはrgb[i]が常に1になるため、深度バッファへの書き込みが行われない。つまり透明になる。 // アルファチャンネルが1のときはnoiseが常に0になるため、深度マップの最前面で書き込まれる。 float p = ( 1.0f - col[i] ) * col.a; // p が大きいほど、手前側の深度値がで書込まれやすくなる if( noise * ( 1.0f - col.a ) <= p ) rgb[i] = z; // 書込みしない else rgb[i] = 1; } return float4( rgb, 0 ); }
---ColoredStochasticShadowMaps_Pass2.hlsl---
// ************************************************************ // Colored Stochastic Shadow Maps カラーマップをレンダリング // ************************************************************ // 定数バッファ cbuffer CBuffer : register( b0 ) { column_major float4x4 g_matLightWorldViewProj : packoffset( c0 ); // ライトビューのワールドビュー射影行列 column_major float4x4 g_matCameraWorldViewProj : packoffset( c4 ); // カメラビューのワールドビュー射影行列 }; // テクスチャー Texture2D g_DecalMap : register( t0 ); // カラー深度マップ Texture2D g_ColorAndDepthMap : register( t1 ); // サンプラーステート SamplerState g_SamplerDecalMap : register( s0 ); // サンプラーステート SamplerState g_SamplerColorAndDepthMap : register( s1 ); // 頂点シェーダーの入力パラメータ struct VS_IN { float3 pos : POSITION; // 頂点座標 float3 normal : NORMAL; // 法線ベクトル float2 texel : TEXCOORD; // テクセル }; // 頂点シェーダーの出力パラメータ struct VS_OUT_PS_IN { float4 pos : SV_POSITION; float3 normal : NORMAL; float2 texel : TEXCOORD0; float4 posLWVP : TEXCOORD1; }; // 頂点シェーダー VS_OUT_PS_IN ColoredStochasticShadowMaps_Pass2_VS_Main( VS_IN In ) { VS_OUT_PS_IN Out; Out.pos = mul( float4( In.pos, 1.0f ), g_matCameraWorldViewProj ); Out.normal = In.normal; Out.texel = In.texel; Out.posLWVP = mul( float4( In.pos, 1.0f ), g_matLightWorldViewProj ); return Out; } // ピクセルシェーダ float4 ColoredStochasticShadowMaps_Pass2_PS_Main( VS_OUT_PS_IN In ) : SV_TARGET { float4 Out; float4 col = g_DecalMap.Sample( g_SamplerDecalMap, In.texel ); 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.0f && texel.x <= 1.0f && texel.y >= 0.0f && texel.y <= 1.0f ) { // ライトビュー上でのピクセルの深度値 float depth = In.posLWVP.z / In.posLWVP.w - 0.0085f; float4 depthmap; // RGBループ for( int i=0; i<3; i++ ) { float PercentLit = 0; float cnt = 0; // PCF( R16G16B16A16_FLOATフォーマットの場合、SampleCmpLevelZero()は使えないっぽい ) for( int x=-4; x<5; x+=2 ) { for( int y=-4; y<5; y+=2 ) { depthmap = g_ColorAndDepthMap.Sample( g_SamplerColorAndDepthMap, texel, int2( x, y ) ); // 深度マップの深度値のほうが奥にあるときは影を落とさない if( depthmap[i] > depth ) PercentLit++; cnt++; } } // 平均値を計算する col[i] *= ( PercentLit / cnt ); } } return col.bgra; }
#ifndef COLORED_STOCHASTIC_SHADOW_MAPS_H #define COLORED_STOCHASTIC_SHADOW_MAPS_H #include "../Common/UCommon.h" #include "../Common/UException.h" #include "../Common/UGraphicsPipeline.h" #include "../Common/UDirect3D11.h" #include "../Common/USRViewRenderer.h" class ColoredStochasticShadowMaps { private: // Direct3D用定数バッファ設定用構造体 // 不透明メッシュの深度値を出力 typedef struct _CBUFFER_PASS0 { XMMATRIX matLightWorldViewProj; }CBUFFER_PASS0; // 半透明メッシュのカラーマップおよび深度マップ作成 typedef struct _CBUFFER_PASS1 { XMMATRIX matLightWorldViewProj; }CBUFFER_PASS1; // カメラビューからレンダリング typedef struct _CBUFFER_PASS2 { XMMATRIX matLightWorldViewProj; XMMATRIX matCameraWorldViewProj; }CBUFFER_PASS2; // 不透明メッシュの深度マップ ID3D11DepthStencilView* m_pDSViewOfOpacityDepthMap; ID3D11ShaderResourceView* m_pSRViewOfOpacityDepthMap; // 半透明カラーマップおよび深度マップ ID3D11RenderTargetView* m_pRTViewOfTranslucentColorAndDepthMap; ID3D11ShaderResourceView* m_pSRViewOfTranslucentColorAndDepthMap; // サンプラーステート ID3D11SamplerState* m_pSamplerStateOfColorAndDepthMap; // ノイズマップ ID3D11ShaderResourceView* m_pSRViewOfTNoiseMap; // サンプラーステート ID3D11SamplerState* m_pSamplerStateOfNoiseMap; // レンダーターゲットと深度ステンシルとビューポートのバックアップ ID3D11RenderTargetView* m_pOldRTView[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; ID3D11DepthStencilView* m_pOldDSView; D3D11_VIEWPORT m_pOldViewport[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; UINT m_ViewportCount; // シェーダー用定数バッファ ID3D11Buffer* m_pConstantBuffers[3]; UGraphicsPipeline* m_pGraphicsPipeline[3]; // 深度マップの色をカラーマップにコピーするときにクラス。フォーマットが異なるので、CopyResource()とか使えない。 USRViewRenderer* m_pSRViewRenderer; DWORD m_Width, m_Height; int m_Pass; XMMATRIX m_MatLightView; XMMATRIX m_MatLightProj; XMMATRIX m_MatCameraView; XMMATRIX m_MatCameraProj; XMFLOAT4 m_VecLightPos; public: ColoredStochasticShadowMaps(); virtual ~ColoredStochasticShadowMaps(); 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* GetOpacityDepthMap(){ return m_pSRViewOfOpacityDepthMap; }; inline const ID3D11ShaderResourceView* GetTranslucentColorMap(){ return m_pSRViewOfTranslucentColorAndDepthMap; }; inline const ID3D11ShaderResourceView* GetNoiseMap(){ return m_pSRViewOfTNoiseMap; }; }; #endif
---ColoredStochasticShadowMaps.cpp---
#include "../../Header/Shader/ColoredStochasticShadowMaps.h" #include "../../HLSL/ColoredStochasticShadowMaps_Pass0_VS_Main.h" #include "../../HLSL/ColoredStochasticShadowMaps_Pass1_VS_Main.h" #include "../../HLSL/ColoredStochasticShadowMaps_Pass1_PS_Main.h" #include "../../HLSL/ColoredStochasticShadowMaps_Pass2_VS_Main.h" #include "../../HLSL/ColoredStochasticShadowMaps_Pass2_PS_Main.h" ColoredStochasticShadowMaps::ColoredStochasticShadowMaps() { m_pDSViewOfOpacityDepthMap = nullptr; m_pSRViewOfOpacityDepthMap = nullptr; m_pRTViewOfTranslucentColorAndDepthMap = nullptr; m_pSRViewOfTranslucentColorAndDepthMap = nullptr; m_pSRViewOfTNoiseMap = nullptr; for( int i=0; i<_countof( m_pGraphicsPipeline ); i++ ) { m_pGraphicsPipeline[i] = nullptr; m_pConstantBuffers[i] = nullptr; } m_pSRViewRenderer = nullptr; m_pSamplerStateOfNoiseMap = nullptr; m_pSamplerStateOfColorAndDepthMap = nullptr; m_Pass = -1; } ColoredStochasticShadowMaps::~ColoredStochasticShadowMaps() { SAFE_RELEASE( m_pSamplerStateOfColorAndDepthMap ); SAFE_RELEASE( m_pSamplerStateOfNoiseMap ); SAFE_DELETE( m_pSRViewRenderer ); for( int i=0; i<_countof( m_pGraphicsPipeline ); i++ ) { SAFE_DELETE( m_pGraphicsPipeline[i] ); SAFE_RELEASE( m_pConstantBuffers[i] ); } SAFE_RELEASE( m_pSRViewOfTNoiseMap ); SAFE_RELEASE( m_pSRViewOfTranslucentColorAndDepthMap ); SAFE_RELEASE( m_pRTViewOfTranslucentColorAndDepthMap ); SAFE_RELEASE( m_pSRViewOfOpacityDepthMap ); SAFE_RELEASE( m_pDSViewOfOpacityDepthMap ); } void ColoredStochasticShadowMaps::Create( ID3D11Device* pD3DDevice, DWORD Width, DWORD Height ) { m_Width = Width; m_Height = Height; m_Pass = -1; // ******************************************************************************************************* // 不透明メッシュの深度マップ作成 // ******************************************************************************************************* 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/ColoredStochasticShadowMaps_Pass0.hlsl"), "ColoredStochasticShadowMaps_Pass0_VS_Main", layout, _countof( layout ) ); #else m_pGraphicsPipeline[0]->CreateVertexShaderFromMemory( pD3DDevice, (LPBYTE)g_ColoredStochasticShadowMaps_Pass0_VS_Main, sizeof( g_ColoredStochasticShadowMaps_Pass0_VS_Main ), layout, _countof( layout ) ); #endif // 深度ステンシルバッファを作成する UMaps::CreateDepthStencilView( pD3DDevice, m_Width, m_Height, &m_pDSViewOfOpacityDepthMap, &m_pSRViewOfOpacityDepthMap ); // 定数バッファを作成する m_pConstantBuffers[0] = m_pGraphicsPipeline[0]->CreateConstantBuffer( pD3DDevice, nullptr, sizeof( ColoredStochasticShadowMaps::CBUFFER_PASS0 ), D3D11_CPU_ACCESS_WRITE ); // 深度マップコピー用クラス m_pSRViewRenderer = NEW USRViewRenderer(); m_pSRViewRenderer->Create( pD3DDevice, -1, 1, 1, -1 ); // ******************************************************************************************************* // 半透明メッシュのカラーおよび深度マップ作成 // ******************************************************************************************************* m_pGraphicsPipeline[1] = NEW UGraphicsPipeline(); // ラスタライザーステートを作成する m_pGraphicsPipeline[1]->CreateRasterizerState( pD3DDevice, D3D11_CULL_MODE::D3D11_CULL_BACK ); // 深度ステンシルステートを作成する( 深度バッファへの書き込みを行わない ) m_pGraphicsPipeline[1]->CreateDepthStencilState( pD3DDevice, TRUE, D3D11_DEPTH_WRITE_MASK::D3D11_DEPTH_WRITE_MASK_ZERO ); // ブレンドステートを作成する BlendStateType[0] = UGraphicsPipeline::UEBLEND_STATE::DEPTH_TEST; m_pGraphicsPipeline[1]->CreateBlendState( pD3DDevice, BlendStateType, 1 ); // シェーダーを作成する #if defined(DEBUG) || defined(_DEBUG) m_pGraphicsPipeline[1]->CreateVertexShaderFromFile( pD3DDevice, _T("../HLSL/ColoredStochasticShadowMaps_Pass1.hlsl"), "ColoredStochasticShadowMaps_Pass1_VS_Main", layout, _countof( layout ) ); m_pGraphicsPipeline[1]->CreatePixelShaderFromFile( pD3DDevice, _T("../HLSL/ColoredStochasticShadowMaps_Pass1.hlsl"), "ColoredStochasticShadowMaps_Pass1_PS_Main" ); #else m_pGraphicsPipeline[1]->CreateVertexShaderFromMemory( pD3DDevice, (LPBYTE)g_ColoredStochasticShadowMaps_Pass1_VS_Main, sizeof( g_ColoredStochasticShadowMaps_Pass1_VS_Main ), layout, _countof( layout ) ); m_pGraphicsPipeline[1]->CreatePixelShaderFromMemory( pD3DDevice, (LPBYTE)g_ColoredStochasticShadowMaps_Pass1_PS_Main, sizeof( g_ColoredStochasticShadowMaps_Pass1_PS_Main ) ); #endif // カラーマップ UMaps::CreateRenderTargetView( pD3DDevice, DXGI_FORMAT_R16G16B16A16_FLOAT, m_Width, m_Height, &m_pRTViewOfTranslucentColorAndDepthMap, &m_pSRViewOfTranslucentColorAndDepthMap ); // ノイズマップを作成する UMaps::CreateSRViewOfNoiseMap( pD3DDevice, m_Width, m_Height, DXGI_FORMAT_R32_FLOAT, &m_pSRViewOfTNoiseMap ); // 定数バッファを作成する m_pConstantBuffers[1] = m_pGraphicsPipeline[1]->CreateConstantBuffer( pD3DDevice, nullptr, sizeof( ColoredStochasticShadowMaps::CBUFFER_PASS1 ), D3D11_CPU_ACCESS_WRITE ); // サンプラーステートを作成する m_pSamplerStateOfNoiseMap = USamplers::CreateSamplerState( pD3DDevice, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT ); // ******************************************************************************************************* // カメラビューでレンダリング // ******************************************************************************************************* m_pGraphicsPipeline[2] = NEW UGraphicsPipeline(); // ラスタライザーステートを作成する m_pGraphicsPipeline[2]->CreateRasterizerState( pD3DDevice, D3D11_CULL_MODE::D3D11_CULL_BACK ); // 深度ステンシルステートを作成する m_pGraphicsPipeline[2]->CreateDepthStencilState( pD3DDevice, TRUE, D3D11_DEPTH_WRITE_MASK::D3D11_DEPTH_WRITE_MASK_ALL ); // ブレンドステートを作成する BlendStateType[0] = UGraphicsPipeline::UEBLEND_STATE::ALIGNMENT; m_pGraphicsPipeline[2]->CreateBlendState( pD3DDevice, BlendStateType, 1 ); // シェーダーを作成する #if defined(DEBUG) || defined(_DEBUG) m_pGraphicsPipeline[2]->CreateVertexShaderFromFile( pD3DDevice, _T("../HLSL/ColoredStochasticShadowMaps_Pass2.hlsl"), "ColoredStochasticShadowMaps_Pass2_VS_Main", layout, _countof( layout ) ); m_pGraphicsPipeline[2]->CreatePixelShaderFromFile( pD3DDevice, _T("../HLSL/ColoredStochasticShadowMaps_Pass2.hlsl"), "ColoredStochasticShadowMaps_Pass2_PS_Main" ); #else m_pGraphicsPipeline[2]->CreateVertexShaderFromMemory( pD3DDevice, (LPBYTE)g_ColoredStochasticShadowMaps_Pass2_VS_Main, sizeof( g_ColoredStochasticShadowMaps_Pass2_VS_Main ), layout, _countof( layout ) ); m_pGraphicsPipeline[2]->CreatePixelShaderFromMemory( pD3DDevice, (LPBYTE)g_ColoredStochasticShadowMaps_Pass2_PS_Main, sizeof( g_ColoredStochasticShadowMaps_Pass2_PS_Main ) ); #endif // 定数バッファを作成する m_pConstantBuffers[2] = m_pGraphicsPipeline[2]->CreateConstantBuffer( pD3DDevice, nullptr, sizeof( ColoredStochasticShadowMaps::CBUFFER_PASS2 ), D3D11_CPU_ACCESS_WRITE ); // サンプラーステートを作成する m_pSamplerStateOfNoiseMap = USamplers::CreateSamplerState( pD3DDevice, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT ); } void ColoredStochasticShadowMaps::BeginPass( ID3D11DeviceContext* pD3DDeviceContext, UINT Pass, XMFLOAT4* pVecLightPos, XMMATRIX* pMatLightProj, XMMATRIX* pMatCameraView, XMMATRIX* pMatCameraProj ) { if (m_Pass != -1) { throw(UException(-1, _T("ColoredStochasticShadowMaps::BeginPass()はCreate()またはEndPass()実行後に使用してください"))); } m_Pass = (int)Pass; switch( m_Pass ) { case 0: { pD3DDeviceContext->OMGetRenderTargets( _countof( m_pOldRTView ), m_pOldRTView, &m_pOldDSView ); // 不透明メッシュの深度値を出力 pD3DDeviceContext->OMSetRenderTargets( 0, nullptr, m_pDSViewOfOpacityDepthMap ); 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_pDSViewOfOpacityDepthMap, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0 ); m_VecLightPos = *pVecLightPos; m_MatLightView = XMMatrixLookAtLH(XMLoadFloat3((XMFLOAT3*)&m_VecLightPos), XMLoadFloat3(&XMFLOAT3(0, 0, 0)), XMLoadFloat3(&XMFLOAT3(0, 1, 0))); m_MatLightProj = (*pMatLightProj); m_MatCameraView = XMMatrixIdentity(); m_MatCameraProj = XMMatrixIdentity(); } break; case 1: { pD3DDeviceContext->OMGetRenderTargets( _countof( m_pOldRTView ), m_pOldRTView, &m_pOldDSView ); // カラーマップに出力 pD3DDeviceContext->OMSetRenderTargets( 1, &m_pRTViewOfTranslucentColorAndDepthMap, m_pDSViewOfOpacityDepthMap ); 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->PSSetShaderResources( 1, 1, &m_pSRViewOfTNoiseMap ); pD3DDeviceContext->PSSetSamplers( 1, 1, &m_pSamplerStateOfNoiseMap ); } break; case 2: { pD3DDeviceContext->PSSetShaderResources( 1, 1, &m_pSRViewOfTranslucentColorAndDepthMap ); pD3DDeviceContext->PSSetSamplers( 1, 1, &m_pSamplerStateOfColorAndDepthMap ); m_MatCameraView = (*pMatCameraView); m_MatCameraProj = (*pMatCameraProj); } break; default: throw(UException(-1, _T("ColoredStochasticShadowMaps::BeginPass()で無効なPassが指定されました"))); } // 各種ステートを設定する m_pGraphicsPipeline[m_Pass]->SetRasterizerState( pD3DDeviceContext ); m_pGraphicsPipeline[m_Pass]->SetDepthStencilState( pD3DDeviceContext ); m_pGraphicsPipeline[m_Pass]->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 ColoredStochasticShadowMaps::SetConstantBuffers( ID3D11DeviceContext* pD3DDeviceContext, XMMATRIX* pMatWorld ) { HRESULT hr = E_FAIL; // ライトビューのビュー行列を作成 XMMATRIX matLView = XMMatrixLookAtLH( XMLoadFloat3( (XMFLOAT3*)&m_VecLightPos ), XMLoadFloat3( &XMFLOAT3( 0, 0, 0 ) ), XMLoadFloat3( &XMFLOAT3( 0, 1, 0 ) ) ); // ライトビューのワールド行列とビュー行列と射影行列 XMMATRIX matLightWorldViewProj = XMMatrixTranspose( *pMatWorld * matLView * m_MatLightProj ); switch( m_Pass ) { case 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("ColoredStochasticShadowMaps::SetConstantBuffers()でエラーが発生しました。Map()が失敗しました。") ) ); ColoredStochasticShadowMaps::CBUFFER_PASS0* cbuffer = (ColoredStochasticShadowMaps::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] ); } break; case 1: { // 定数バッファをロックする D3D11_MAPPED_SUBRESOURCE mappedResource; if( FAILED( hr = pD3DDeviceContext->Map( m_pConstantBuffers[m_Pass], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource ) ) ) throw( UException( -1, _T("ColoredStochasticShadowMaps::SetConstantBuffers()でエラーが発生しました。Map()が失敗しました。") ) ); ColoredStochasticShadowMaps::CBUFFER_PASS1* cbuffer = (ColoredStochasticShadowMaps::CBUFFER_PASS1*)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 2: { // カメラビュー XMMATRIX matCameraWorldViewProj = XMMatrixTranspose( *pMatWorld * m_MatCameraView * m_MatCameraProj ); // 定数バッファをロックする D3D11_MAPPED_SUBRESOURCE mappedResource; if( FAILED( hr = pD3DDeviceContext->Map( m_pConstantBuffers[m_Pass], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource ) ) ) throw( UException( -1, _T("ColoredStochasticShadowMaps::SetConstantBuffers()でエラーが発生しました。Map()が失敗しました。") ) ); ColoredStochasticShadowMaps::CBUFFER_PASS2* cbuffer = (ColoredStochasticShadowMaps::CBUFFER_PASS2*)mappedResource.pData; ::CopyMemory( &cbuffer->matLightWorldViewProj, &matLightWorldViewProj, sizeof( XMMATRIX ) ); ::CopyMemory( &cbuffer->matCameraWorldViewProj, &matCameraWorldViewProj, 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; } } void ColoredStochasticShadowMaps::EndPass( ID3D11DeviceContext* pD3DDeviceContext ) { switch( m_Pass ) { case 0: { // 深度値が格納されているR成分をコピーする pD3DDeviceContext->OMSetRenderTargets( 1, &m_pRTViewOfTranslucentColorAndDepthMap, nullptr ); int SrcRGB[4] = { 0, 0, 0, 0 }; m_pSRViewRenderer->SetSRView( m_pSRViewOfOpacityDepthMap, SrcRGB ); m_pSRViewRenderer->Render( pD3DDeviceContext ); // レンダーターゲットビューと深度ステンシルビューとビューポートを戻す pD3DDeviceContext->OMSetRenderTargets( _countof( m_pOldRTView ), m_pOldRTView, m_pOldDSView ); for( UINT i=0; i<_countof( m_pOldRTView ); i++ ) SAFE_RELEASE( m_pOldRTView[i] ); SAFE_RELEASE( m_pOldDSView ); pD3DDeviceContext->RSSetViewports( m_ViewportCount, m_pOldViewport ); } break; case 1: { // レンダーターゲットビューと深度ステンシルビューとビューポートを戻す pD3DDeviceContext->OMSetRenderTargets( _countof( m_pOldRTView ), m_pOldRTView, m_pOldDSView ); for( UINT i=0; i<_countof( m_pOldRTView ); i++ ) SAFE_RELEASE( m_pOldRTView[i] ); SAFE_RELEASE( m_pOldDSView ); pD3DDeviceContext->RSSetViewports( m_ViewportCount, m_pOldViewport ); ID3D11ShaderResourceView* pSRViewNull[] = { nullptr, nullptr }; pD3DDeviceContext->PSSetShaderResources( 0, _countof( pSRViewNull ), pSRViewNull ); } break; case 2: { } break; } m_Pass = -1; }
#ifndef WALLMESH_H #define WALLMESH_H #include "../Common/UCommon.h" #include "../Common/UDirect3D11.h" #include "../Common/UException.h" #include "../Common/UD3DMeshDataCreater.h" class WallMesh { private: // 頂点バッファ ID3D11Buffer* m_pVertexBuffer; // インデックスバッファ ID3D11Buffer* m_pIndexBuffer; // シェーダーリソースビュー ID3D11ShaderResourceView* m_pSRView; // サンプラーステート ID3D11SamplerState* m_pSamplerState; XMMATRIX m_MatWorld[2]; ULONG m_VertexCount; ULONG m_IndexCount; public: WallMesh(); virtual ~WallMesh(); void Invalidate(); void CreateMesh( ID3D11Device* pD3DDevice ); void NextFrame(); inline UINT GetMaxMeshCount(){ return _countof( m_MatWorld ); }; inline XMMATRIX* GetMatWorld( UINT index ){ return &m_MatWorld[index]; }; void Render( ID3D11DeviceContext* pD3DDeviceContext ); }; #endif
#include "../../Header/Mesh/WallMesh.h" WallMesh::WallMesh() { m_pVertexBuffer = nullptr; m_pIndexBuffer = nullptr; m_pSRView = nullptr; m_pSamplerState = nullptr; m_VertexCount = 0; m_IndexCount = 0; } WallMesh::~WallMesh() { Invalidate(); } void WallMesh::Invalidate() { m_IndexCount = 0; m_VertexCount = 0; SAFE_RELEASE( m_pSamplerState ); SAFE_RELEASE( m_pSRView ); SAFE_RELEASE( m_pIndexBuffer ); SAFE_RELEASE( m_pVertexBuffer ); } void WallMesh::CreateMesh( ID3D11Device* pD3DDevice ) { UD3DMeshDataCreater::VERTEX vertex[] = { XMFLOAT3(1.0f, 1.0f, 1.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(0.0f, 0.0f), // 0 XMFLOAT3(-1.0f, 1.0f, 1.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 0.0f), // 1 XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(0.0f, 1.0f), // 2 XMFLOAT3(-1.0f, -1.0f, 1.0f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 1.0f), // 3 XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT2(0.0f, 0.0f), // 4 XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT2(1.0f, 0.0f), // 5 XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT2(0.0f, 1.0f), // 6 XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT2(1.0f, 1.0f), // 7 }; m_VertexCount = _countof( vertex ); // 頂点バッファを作成する m_pVertexBuffer = UBuffers::CreateVertexBuffer( pD3DDevice, vertex, sizeof( vertex ), 0 ); UINT Indexes[] = { 1, 0, 3, 0, 2, 3, // 奥面 4, 5, 6, 5, 7, 6, // 手前面 0, 4, 2, 4, 6, 2, // 右面 5, 1, 7, 1, 3, 7, // 左面 0, 1, 4, 1, 5, 4, // 上面 3, 2, 7, 2, 6, 7 // 下面 }; m_IndexCount = _countof( Indexes ); // インデックスバッファを作成する m_pIndexBuffer = UBuffers::CreateIndexBuffer( pD3DDevice, Indexes, sizeof( Indexes ), 0 ); // サンプラーステートを作成する m_pSamplerState = USamplers::CreateSamplerState( pD3DDevice, D3D11_TEXTURE_ADDRESS_WRAP ); // テクスチャーを作成する UMaps::CreateSRViewFromDDSFile( pD3DDevice, _T("../Resource/Glass.dds"), &m_pSRView ); } void WallMesh::NextFrame() { XMMATRIX matScaling, matRotationZ, matTranslate; matScaling = XMMatrixScaling( 70, 50, 2 ); matRotationZ = XMMatrixRotationZ( 0.0f ); matTranslate = XMMatrixTranslation( 0.0f, 25.0f, 50.0f ); m_MatWorld[0] = matRotationZ * matScaling * matTranslate; matRotationZ = XMMatrixRotationZ( XM_PI / 2 ); matTranslate = XMMatrixTranslation( 0.0f, 25.0f, -50.0f ); m_MatWorld[1] = matRotationZ * matScaling * matTranslate; } void WallMesh::Render( ID3D11DeviceContext* pD3DDeviceContext ) { // 頂点バッファ設定 UINT stride = sizeof( UD3DMeshDataCreater::VERTEX ); UINT offset = 0; pD3DDeviceContext->IASetVertexBuffers( 0, 1, &m_pVertexBuffer, &stride, &offset ); // インデックスバッファを設定 pD3DDeviceContext->IASetIndexBuffer( m_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 ); // プリミティブ タイプおよびデータの順序に関する情報を設定 pD3DDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); // ピクセルシェーダーのサンプラーステートを設定する pD3DDeviceContext->PSSetSamplers( 0, 1, &m_pSamplerState ); // デカールマップを設定する pD3DDeviceContext->PSSetShaderResources( 0, 1, &m_pSRView ); // 描画 pD3DDeviceContext->DrawIndexed( m_IndexCount, 0, 0 ); }
#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/ColoredStochasticShadowMaps.h" #include "../Header/Mesh/PlaneMesh.h" #include "../Header/Mesh/WallMesh.h" // アプリケーション名 TCHAR* AppName = _T("Direct3D11 Colored Stochastic Shadow Maps"); // Direct3D関連の自作クラス UDirect3D11* g_pDirect3D11 = nullptr; ColoredStochasticShadowMaps* g_pColoredStochasticShadowMaps = nullptr; PlaneMesh* g_pPlaneMesh = nullptr; WallMesh* g_pWallMesh = nullptr; UFPS* g_pFPS = nullptr; #if defined(DEBUG) || defined(_DEBUG) USRViewRenderer* g_pSRViewRenderer = nullptr; #endif DWORD g_Width = 640, g_Height = 480; float g_LZFar = 950.0f, g_LZNear = 10.0f; // カメラビュー行列 XMMATRIX g_MatCameraView = XMMatrixIdentity(); // カメラービュー射影行列 XMMATRIX g_MatCameraProj = XMMatrixPerspectiveFovLH( XM_PI / 5.0f, (float)g_Width / (float)g_Height, 10.0f, 1000.0f ); // ライトビューは距離計算が正しくできるように正射影行列にする XMMATRIX g_MatLightProj = XMMatrixOrthographicLH( 300.0f, 300.0f, g_LZNear, g_LZFar ); // 平行光源の位置ベクトル XMFLOAT4 g_VecLightPos = XMFLOAT4( 130.0f, 100.0f, -170.0f, 0 ); // メモリ解放 void Invalidate() { #if defined(DEBUG) || defined(_DEBUG) SAFE_DELETE( g_pSRViewRenderer ); #endif SAFE_DELETE( g_pFPS ); SAFE_DELETE( g_pColoredStochasticShadowMaps ); SAFE_DELETE( g_pPlaneMesh ); SAFE_DELETE( g_pWallMesh ); 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 = 512, Height = 512; g_pColoredStochasticShadowMaps->Create( g_pDirect3D11->m_pD3DDevice, Width, Height ); } // メッシュを作成する void CreateMesh() { g_pPlaneMesh = NEW PlaneMesh(); g_pPlaneMesh->CreateMesh( g_pDirect3D11->m_pD3DDevice ); g_pWallMesh = NEW WallMesh(); g_pWallMesh->CreateMesh( g_pDirect3D11->m_pD3DDevice ); } void CreateResource( HINSTANCE hInstance ) { // Direct3D 関連自作クラスのインスタンスを作成 // CreateDirect3D()関数内でインスタンスの作成を行うと、C2712 エラーが発生するのでここで行う。 g_pDirect3D11 = NEW UDirect3D11(); g_pColoredStochasticShadowMaps = NEW ColoredStochasticShadowMaps(); 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.5f ); if( GetKeyState( VK_DOWN ) & 0x8000 ) g_MatCameraView *= XMMatrixTranslation( 0, 0, 0.5f ); if( GetKeyState( VK_RIGHT ) & 0x8000 ) g_MatCameraView *= XMMatrixRotationY( -0.004f ); if( GetKeyState( VK_LEFT ) & 0x8000 ) g_MatCameraView *= XMMatrixRotationY( 0.004f ); if( GetKeyState( 'Q' ) & 0x8000 ) g_MatCameraView *= XMMatrixRotationX( 0.004f ); if( GetKeyState( 'A' ) & 0x8000 ) g_MatCameraView *= XMMatrixRotationX( -0.004f ); g_pFPS->NextFrame(); g_pPlaneMesh->NextFrame(); g_pWallMesh->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 ); g_pColoredStochasticShadowMaps->BeginPass( g_pDirect3D11->m_pD3DDeviceContext, 0, &g_VecLightPos, &g_MatLightProj, &g_MatCameraView, &g_MatCameraProj ); g_pColoredStochasticShadowMaps->SetConstantBuffers( g_pDirect3D11->m_pD3DDeviceContext, g_pPlaneMesh->GetMatWorld() ); g_pPlaneMesh->Render( g_pDirect3D11->m_pD3DDeviceContext ); g_pColoredStochasticShadowMaps->EndPass( g_pDirect3D11->m_pD3DDeviceContext ); g_pColoredStochasticShadowMaps->BeginPass( g_pDirect3D11->m_pD3DDeviceContext, 1, &g_VecLightPos, &g_MatLightProj, &g_MatCameraView, &g_MatCameraProj ); for( UINT i=0; i<g_pWallMesh->GetMaxMeshCount(); i++ ) { g_pColoredStochasticShadowMaps->SetConstantBuffers( g_pDirect3D11->m_pD3DDeviceContext, g_pWallMesh->GetMatWorld(i) ); g_pWallMesh->Render( g_pDirect3D11->m_pD3DDeviceContext ); } g_pColoredStochasticShadowMaps->EndPass( g_pDirect3D11->m_pD3DDeviceContext ); g_pColoredStochasticShadowMaps->BeginPass( g_pDirect3D11->m_pD3DDeviceContext, 2, &g_VecLightPos, &g_MatLightProj, &g_MatCameraView, &g_MatCameraProj ); g_pColoredStochasticShadowMaps->SetConstantBuffers( g_pDirect3D11->m_pD3DDeviceContext, g_pPlaneMesh->GetMatWorld() ); g_pPlaneMesh->Render( g_pDirect3D11->m_pD3DDeviceContext ); for( UINT i=0; i<g_pWallMesh->GetMaxMeshCount(); i++ ) { g_pColoredStochasticShadowMaps->SetConstantBuffers( g_pDirect3D11->m_pD3DDeviceContext, g_pWallMesh->GetMatWorld(i) ); g_pWallMesh->Render( g_pDirect3D11->m_pD3DDeviceContext ); } g_pColoredStochasticShadowMaps->EndPass( g_pDirect3D11->m_pD3DDeviceContext ); #if defined(DEBUG) || defined(_DEBUG) int SrcRGB[4] = { 0, 1, 2, 3 }; g_pSRViewRenderer->SetSRView( g_pColoredStochasticShadowMaps->GetTranslucentColorMap(), SrcRGB ); 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; }