////////////////////////////////////////////////////////
// filename: CCommonDevice.cpp
// author: Chafumi Touji
// version: 1.0.0
// date: 2020/07/11
////////////////////////////////////////////////////////

#include "defcha3dcore.h"
#include "vs1.h"
#include "vs1_1.h"
#include "vs1_2.h"
#include "vs1_3.h"
#include "vs1_4.h"
#include "vs1_5.h"
#include "vs1_6.h"
#include "vs2.h"
#include "vs3.h"
#include "vs3_1.h"
#include "ps1.h"
#include "ps2.h"
#include "ps3.h"
#include "ps4.h"
#include "ps5.h"
#include "ps6.h"
#include "ps7.h"
#include "ps8.h" //鈴音スクリーンセーバー専用
#include "ps9.h"
#include "ps10.h"
#include "ps11.h" //鈴音表示用
#include "ps12.h" //鈴音表示用
#include "ps13.h" //蝋燭表示用
#include "ps14.h" //パーティクル表示用
#include "ps15.h" //鈴音エフェクト

CCommonDevice::CCommonDevice(){

	m_pDevice = NULL;
	m_pDeviceContext = NULL;
	m_pDXGI = NULL;
	m_pAdapter = NULL;
	m_pFactory = NULL;
	m_pSwapChain = NULL;
	m_pBackBuffer = NULL;
	m_pRenderTargetView = NULL;
	m_pDiffuseTexture = NULL;
	m_pDiffuseRenderTargetView = NULL;
	m_pDiffuseShaderResourceView = NULL;
	m_pDiffuse2Texture = NULL;
	m_pDiffuse2RenderTargetView = NULL;
	m_pDiffuse2ShaderResourceView = NULL;
	m_pToneTexture = NULL;
	m_pToneRenderTargetView = NULL;
	m_pToneShaderResourceView = NULL;
	m_pSkyTexture = NULL;
	m_pSkyRenderTargetView = NULL;
	m_pSkyShaderResourceView = NULL;
	m_pEffectTexture = NULL;
	m_pEffectRenderTargetView = NULL;
	m_pEffectShaderResourceView = NULL;
	m_pGDIRenderTargetView = NULL;
	m_pDepthStencilView = NULL;
	m_pReadOnlyDepthStencilView = NULL;
	m_pDepthBuffer = NULL;
	m_pReadOnlyDepthBuffer = NULL;
	m_pDepthTexture = NULL;
	m_pToneDepthTexture = NULL;
	m_pGDITexture = NULL;
	m_pDepthShaderResourceView = NULL;
	m_pToneDepthShaderResourceView = NULL;
	m_pGDIShaderResourceView = NULL;
	m_pDepthRenderTargetView = NULL;
	m_pToneDepthRenderTargetView = NULL;
	m_pLayout1 = NULL;
	m_pLayout2 = NULL;
	m_pVtxShader1 = NULL;
	m_pVtxShader1_1 = NULL;
	m_pVtxShader1_2 = NULL;
	m_pVtxShader1_3 = NULL;
	m_pVtxShader1_4 = NULL;
	m_pVtxShader1_5 = NULL;
	m_pVtxShader1_6 = NULL;
	m_pVtxShader2 = NULL;
	m_pVtxShader3 = NULL;
	m_pVtxShader3_1 = NULL;
	m_pPxShader1 = NULL;
	m_pPxShader2 = NULL;
	m_pPxShader3 = NULL;
	m_pPxShader4 = NULL;
	m_pPxShader5 = NULL;
	m_pPxShader6 = NULL;
	m_pPxShader7 = NULL;
	m_pPxShader8 = NULL;
	m_pPxShader9 = NULL;
	m_pPxShader10 = NULL;
	m_pPxShader11 = NULL;
	m_pPxShader12 = NULL;
	m_pPxShader13 = NULL;
	m_pPxShader14 = NULL;
	m_pPxShader15 = NULL;
	m_pConstantBuffer1 = NULL;
	m_pSampleState = NULL;
	m_pRasterizeState = NULL;
	m_pBlendState1 = NULL;
	m_pBlendState2 = NULL;
	m_pSurface = NULL;
	VertexBuffer = NULL;

	for (int i = 0; i <= LIGHT_NUM_MAX - 1; i++){
		ShaderLightPos[i] = XMFLOAT4(0, 0, 0, 0);
		ShaderLight[i] = XMFLOAT4(0, 0, 0, 0);
	}

	Eye.x = 0.0f;
	Eye.y = 0.0f;
	Eye.z = 0.0f;
	At.x = 0.0f;
	At.y = 0.0f;
	At.z = 0.0f;
	Move.x = 0.0f;
	Move.y = 0.0f;
	Move.z = 0.0f;
	RotationX = 0.0f;
	RotationY = 0.0f;
	RotationZ = 0.0f;
	Zoom = DEFAULT_ZOOM;
	MSAA_Count = 1;
	MSAA_Quality = 0;

	PrevPoint = XMFLOAT4(0, 0, 0, 0);
	Point = XMFLOAT4(0, 0, 0, 0);
	PathSliceSize = 100;
	PathCount = 0;
	Path_t_Count = 10000;
	CameraRotationZ = 0.0f;
	SightAngle = 60.0f;
}

CCommonDevice::~CCommonDevice(){

	SAFE_RELEASE( m_pDevice );
	SAFE_RELEASE(m_pDeviceContext);
	SAFE_RELEASE(m_pDXGI);
	SAFE_RELEASE(m_pAdapter);
	SAFE_RELEASE(m_pFactory);
	SAFE_RELEASE(m_pSwapChain);
	SAFE_RELEASE(m_pBackBuffer);
	SAFE_RELEASE(m_pDiffuseTexture);
	SAFE_RELEASE(m_pDiffuseRenderTargetView);
	SAFE_RELEASE(m_pDiffuseShaderResourceView);
	SAFE_RELEASE(m_pDiffuse2Texture);
	SAFE_RELEASE(m_pDiffuse2RenderTargetView);
	SAFE_RELEASE(m_pDiffuse2ShaderResourceView);
	SAFE_RELEASE(m_pToneTexture);
	SAFE_RELEASE(m_pToneRenderTargetView);
	SAFE_RELEASE(m_pToneShaderResourceView);
	SAFE_RELEASE(m_pSkyTexture);
	SAFE_RELEASE(m_pSkyRenderTargetView);
	SAFE_RELEASE(m_pSkyShaderResourceView);
	SAFE_RELEASE(m_pEffectTexture);
	SAFE_RELEASE(m_pEffectRenderTargetView);
	SAFE_RELEASE(m_pEffectShaderResourceView);
	SAFE_RELEASE(m_pRenderTargetView);
	SAFE_RELEASE(m_pGDIRenderTargetView);
	SAFE_RELEASE(m_pDepthStencilView);
	SAFE_RELEASE(m_pReadOnlyDepthStencilView);
	SAFE_RELEASE(m_pDepthBuffer);
	SAFE_RELEASE(m_pReadOnlyDepthBuffer);
	SAFE_RELEASE(m_pDepthTexture);
	SAFE_RELEASE(m_pToneDepthTexture);
	SAFE_RELEASE(m_pGDITexture);
	SAFE_RELEASE(m_pDepthShaderResourceView);
	SAFE_RELEASE(m_pToneDepthShaderResourceView);
	SAFE_RELEASE(m_pGDIShaderResourceView);
	SAFE_RELEASE(m_pDepthRenderTargetView);
	SAFE_RELEASE(m_pToneDepthRenderTargetView);
	SAFE_RELEASE(m_pLayout1);
	SAFE_RELEASE(m_pLayout2);
	SAFE_RELEASE(m_pVtxShader1);
	SAFE_RELEASE(m_pVtxShader1_1);
	SAFE_RELEASE(m_pVtxShader1_2);
	SAFE_RELEASE(m_pVtxShader1_3);
	SAFE_RELEASE(m_pVtxShader1_4);
	SAFE_RELEASE(m_pVtxShader1_5);
	SAFE_RELEASE(m_pVtxShader1_6);
	SAFE_RELEASE(m_pVtxShader2);
	SAFE_RELEASE(m_pVtxShader3);
	SAFE_RELEASE(m_pVtxShader3_1);
	SAFE_RELEASE(m_pPxShader1);
	SAFE_RELEASE(m_pPxShader2);
	SAFE_RELEASE(m_pPxShader3);
	SAFE_RELEASE(m_pPxShader4);
	SAFE_RELEASE(m_pPxShader5);
	SAFE_RELEASE(m_pPxShader6);
	SAFE_RELEASE(m_pPxShader7);
	SAFE_RELEASE(m_pPxShader8);
	SAFE_RELEASE(m_pPxShader9);
	SAFE_RELEASE(m_pPxShader10);
	SAFE_RELEASE(m_pPxShader11);
	SAFE_RELEASE(m_pPxShader12);
	SAFE_RELEASE(m_pPxShader13);
	SAFE_RELEASE(m_pPxShader14);
	SAFE_RELEASE(m_pPxShader15);
	SAFE_RELEASE(m_pConstantBuffer1);
	SAFE_RELEASE(m_pSampleState);
	SAFE_RELEASE(m_pRasterizeState);
	SAFE_RELEASE(m_pBlendState1);
	SAFE_RELEASE(m_pBlendState2);
	SAFE_RELEASE(m_pSurface);
	SAFE_RELEASE(VertexBuffer);
}

bool CCommonDevice::CreateDevice( HWND m_hWnd, int width, int height ){

	Width = width;
	Height = height;

	D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &m_pDevice, NULL, &m_pDeviceContext);

	UINT quality = 0;
	UINT count = 1;
	for (int i = 1; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT - 1; i++){
		HRESULT hr = m_pDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_D24_UNORM_S8_UINT, (UINT)i, &quality);
		if (quality > 0 && quality < 32){
			MSAA_Count = i;
			MSAA_Quality = quality - 1;
		}
	}

	//マルチサンプルなし
	MSAA_Count = 1;
	MSAA_Quality = 0;

	//インターフェース取得
	m_pDXGI = NULL;
	m_pDevice->QueryInterface(__uuidof(IDXGIDevice1), (void **)&m_pDXGI);
	
	//アダプター取得
	m_pAdapter = NULL;
	m_pDXGI->GetAdapter(&m_pAdapter);
	
	//ファクトリー取得
	m_pAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&m_pFactory);
	
	DXGI_SWAP_CHAIN_DESC desc;
	desc.BufferDesc.Width = width;
	desc.BufferDesc.Height = height;
	desc.BufferDesc.RefreshRate.Numerator = 0;
	desc.BufferDesc.RefreshRate.Denominator = 1;
	desc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	desc.SampleDesc.Count = MSAA_Count;
	desc.SampleDesc.Quality = MSAA_Quality;
	desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	desc.BufferCount = 1;
	desc.OutputWindow = m_hWnd;
	desc.Windowed = true;
	desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

	m_pFactory->CreateSwapChain(m_pDevice, &desc, &m_pSwapChain);
	m_pSwapChain->SetFullscreenState(true, 0);
	m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)&m_pBackBuffer);	
	m_pDevice->CreateRenderTargetView(m_pBackBuffer, NULL, &m_pRenderTargetView);
	
	////////////////////////////////////////////////////////////////////////

	D3D11_TEXTURE2D_DESC desc_texture_2d;
	ZeroMemory(&desc_texture_2d, sizeof(D3D11_TEXTURE2D_DESC));
	desc_texture_2d.Width = width;
	desc_texture_2d.Height = height;
	desc_texture_2d.MipLevels = 1;
	desc_texture_2d.ArraySize = 1;
	desc_texture_2d.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	desc_texture_2d.SampleDesc.Count = 1;
	desc_texture_2d.SampleDesc.Quality = 0;
	desc_texture_2d.Usage = D3D11_USAGE_DEFAULT;
	desc_texture_2d.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
	desc_texture_2d.CPUAccessFlags = 0;
	desc_texture_2d.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;

	D3D11_SHADER_RESOURCE_VIEW_DESC desc_shader_resource;
	ZeroMemory(&desc_shader_resource, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
	desc_shader_resource.Format = desc_texture_2d.Format;
	desc_shader_resource.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
	desc_shader_resource.Texture2D.MipLevels = desc_texture_2d.MipLevels;
	desc_shader_resource.Texture2D.MostDetailedMip = 0;

	///////////////////////////////////////////////////////////////////////
	// ディフーズテクスチャ作成

	m_pDevice->CreateTexture2D(&desc_texture_2d, NULL, &m_pDiffuseTexture);
	m_pDevice->CreateShaderResourceView(m_pDiffuseTexture, &desc_shader_resource, &m_pDiffuseShaderResourceView);
	m_pDevice->CreateRenderTargetView(m_pDiffuseTexture, NULL, &m_pDiffuseRenderTargetView);
	
	m_pDevice->CreateTexture2D(&desc_texture_2d, NULL, &m_pDiffuse2Texture);
	m_pDevice->CreateShaderResourceView(m_pDiffuse2Texture, &desc_shader_resource, &m_pDiffuse2ShaderResourceView);
	m_pDevice->CreateRenderTargetView(m_pDiffuse2Texture, NULL, &m_pDiffuse2RenderTargetView);

	///////////////////////////////////////////////////////////////////////
	// トーンシェーダ用テクスチャ作成

	m_pDevice->CreateTexture2D(&desc_texture_2d, NULL, &m_pToneTexture);
	m_pDevice->CreateShaderResourceView(m_pToneTexture, &desc_shader_resource, &m_pToneShaderResourceView);
	m_pDevice->CreateRenderTargetView(m_pToneTexture, NULL, &m_pToneRenderTargetView);

	///////////////////////////////////////////////////////////////////////
	// 空用テクスチャ作成

	m_pDevice->CreateTexture2D(&desc_texture_2d, NULL, &m_pSkyTexture);
	m_pDevice->CreateShaderResourceView(m_pSkyTexture, &desc_shader_resource, &m_pSkyShaderResourceView);
	m_pDevice->CreateRenderTargetView(m_pSkyTexture, NULL, &m_pSkyRenderTargetView);

	///////////////////////////////////////////////////////////////////////
	// エフェクトシェーダ用テクスチャ作成

	m_pDevice->CreateTexture2D(&desc_texture_2d, NULL, &m_pEffectTexture);
	m_pDevice->CreateShaderResourceView(m_pEffectTexture, &desc_shader_resource, &m_pEffectShaderResourceView);
	m_pDevice->CreateRenderTargetView(m_pEffectTexture, NULL, &m_pEffectRenderTargetView);

	/*-----------------------------------------------------*/
	//HDC描画用のテクスチャ作成

	desc_texture_2d.Width = ::GetSystemMetrics(SM_CXSCREEN);
	desc_texture_2d.Height = ::GetSystemMetrics(SM_CYSCREEN);;

	m_pDevice->CreateTexture2D(&desc_texture_2d, NULL, &m_pGDITexture);
	m_pDevice->CreateShaderResourceView(m_pGDITexture, &desc_shader_resource, &m_pGDIShaderResourceView);
	m_pDevice->CreateRenderTargetView(m_pGDITexture, NULL, &m_pGDIRenderTargetView);
	m_pGDITexture->QueryInterface(__uuidof(IDXGISurface1), (void **)&m_pSurface);

	///////////////////////////////////////////////////////////////////////
	// 深度バッファ生成

	ZeroMemory(&desc_texture_2d, sizeof(D3D11_TEXTURE2D_DESC));
	desc_texture_2d.Width = width;
	desc_texture_2d.Height = height;
	desc_texture_2d.MipLevels = 1;
	desc_texture_2d.ArraySize = 1;
	desc_texture_2d.Format = DXGI_FORMAT_R32_TYPELESS;
	desc_texture_2d.SampleDesc.Count = 1;
	desc_texture_2d.SampleDesc.Quality = 0;
	desc_texture_2d.Usage = D3D11_USAGE_DEFAULT;
	desc_texture_2d.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
	desc_texture_2d.CPUAccessFlags = 0;
	desc_texture_2d.MiscFlags = 0;

	m_pDevice->CreateTexture2D(&desc_texture_2d, NULL, &m_pDepthBuffer);
	m_pDevice->CreateTexture2D(&desc_texture_2d, NULL, &m_pReadOnlyDepthBuffer);

	D3D11_DEPTH_STENCIL_VIEW_DESC desc_stencil_view;
	ZeroMemory(&desc_stencil_view, sizeof(D3D11_DEPTH_STENCILOP_DESC));
	desc_stencil_view.Format = DXGI_FORMAT_D32_FLOAT;
	desc_stencil_view.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	desc_stencil_view.Texture2D.MipSlice = 0;

	m_pDevice->CreateDepthStencilView(m_pDepthBuffer, &desc_stencil_view, &m_pDepthStencilView);
	m_pDevice->CreateDepthStencilView(m_pReadOnlyDepthBuffer, &desc_stencil_view, &m_pReadOnlyDepthStencilView);

	/*-----------------------------------------------------*/
	//シャドウマップ用の深度テクスチャ生成

	desc_texture_2d.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	desc_texture_2d.SampleDesc.Count = 1;
	desc_texture_2d.SampleDesc.Quality = 0;
	desc_texture_2d.Width = width;
	desc_texture_2d.Height = height;
	desc_texture_2d.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
	m_pDevice->CreateTexture2D(&desc_texture_2d, NULL, &m_pDepthTexture);
	
	ZeroMemory(&desc_shader_resource, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
	desc_shader_resource.Format = desc_texture_2d.Format;
	desc_shader_resource.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
	desc_shader_resource.Texture2D.MipLevels = desc_texture_2d.MipLevels;
	desc_shader_resource.Texture2D.MostDetailedMip = 0;
	m_pDevice->CreateShaderResourceView(m_pDepthTexture, &desc_shader_resource, &m_pDepthShaderResourceView);
	m_pDevice->CreateRenderTargetView(m_pDepthTexture, NULL, &m_pDepthRenderTargetView);
	
	/*-----------------------------------------------------*/
	//トーンシェーダ用の深度テクスチャ生成

	desc_texture_2d.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	desc_texture_2d.SampleDesc.Count = 1;
	desc_texture_2d.SampleDesc.Quality = 0;
	desc_texture_2d.Width = width;
	desc_texture_2d.Height = height;
	desc_texture_2d.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
	m_pDevice->CreateTexture2D(&desc_texture_2d, NULL, &m_pToneDepthTexture);

	ZeroMemory(&desc_shader_resource, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
	desc_shader_resource.Format = desc_texture_2d.Format;
	desc_shader_resource.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
	desc_shader_resource.Texture2D.MipLevels = desc_texture_2d.MipLevels;
	desc_shader_resource.Texture2D.MostDetailedMip = 0;
	m_pDevice->CreateShaderResourceView(m_pToneDepthTexture, &desc_shader_resource, &m_pToneDepthShaderResourceView);
	m_pDevice->CreateRenderTargetView(m_pToneDepthTexture, NULL, &m_pToneDepthRenderTargetView);

	//////////////////////////////////////////////////////////////////
	// ConstantBuffer

	D3D11_BUFFER_DESC desc_buffer;
	m_pConstantBuffer1 = NULL;
	ZeroMemory(&desc_buffer, sizeof(D3D11_BUFFER_DESC));
	desc_buffer.ByteWidth = sizeof(ConstantBuffer1);
	desc_buffer.Usage = D3D11_USAGE_DYNAMIC;
	desc_buffer.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	desc_buffer.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	desc_buffer.MiscFlags = 0;
	desc_buffer.StructureByteStride = sizeof(float);
	m_pDevice->CreateBuffer(&desc_buffer, NULL, &m_pConstantBuffer1);

	////////////////////////////////////////////////////////////////////////////////////////
	// シェーダインプットレイアウト作成

	D3D11_INPUT_ELEMENT_DESC desc_input_element1[] = {

		// texcood 0はテクスチャのUVです。
		// texcood 1〜8はボーンのウェイトが入力されます。WEIGHT_BONE_APPLY_NUMの数だけtexcoordを作る必要があります。(default = 8)

		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 4 * 3, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 4 * 3 + 4 * 3, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 4 * 3 + 4 * 3 + 4 * 4, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 4 * 3 + 4 * 3 + 4 * 4 + 4 * 2, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 4 * 3 + 4 * 3 + 4 * 4 + 4 * 4, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 3, DXGI_FORMAT_R32G32_FLOAT, 0, 4 * 3 + 4 * 3 + 4 * 4 + 4 * 6, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 4, DXGI_FORMAT_R32G32_FLOAT, 0, 4 * 3 + 4 * 3 + 4 * 4 + 4 * 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 5, DXGI_FORMAT_R32G32_FLOAT, 0, 4 * 3 + 4 * 3 + 4 * 4 + 4 * 10, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 6, DXGI_FORMAT_R32G32_FLOAT, 0, 4 * 3 + 4 * 3 + 4 * 4 + 4 * 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 7, DXGI_FORMAT_R32G32_FLOAT, 0, 4 * 3 + 4 * 3 + 4 * 4 + 4 * 14, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 8, DXGI_FORMAT_R32G32_FLOAT, 0, 4 * 3 + 4 * 3 + 4 * 4 + 4 * 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};

	m_pDevice->CreateInputLayout(desc_input_element1, ARRAYSIZE(desc_input_element1), &g_vs_main1, sizeof(g_vs_main1), &m_pLayout1);

	D3D11_INPUT_ELEMENT_DESC desc_input_element2[] = {

		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 4 * 3, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 4 * 3 + 4 * 3, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 4 * 3 + 4 * 3 + 4 * 4, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};

	m_pDevice->CreateInputLayout(desc_input_element2, ARRAYSIZE(desc_input_element2), &g_vs_main1_2, sizeof(g_vs_main1_2), &m_pLayout2);

	///////////////////////////////////////////////////////////////////////////////////////////////////////////
	// vertex shader

	m_pDevice->CreateVertexShader(&g_vs_main1, sizeof(g_vs_main1), NULL, &m_pVtxShader1);
	m_pDevice->CreateVertexShader(&g_vs_main1_1, sizeof(g_vs_main1_1), NULL, &m_pVtxShader1_1);
	m_pDevice->CreateVertexShader(&g_vs_main1_2, sizeof(g_vs_main1_2), NULL, &m_pVtxShader1_2);
	m_pDevice->CreateVertexShader(&g_vs_main1_3, sizeof(g_vs_main1_3), NULL, &m_pVtxShader1_3);
	m_pDevice->CreateVertexShader(&g_vs_main1_4, sizeof(g_vs_main1_4), NULL, &m_pVtxShader1_4);
	m_pDevice->CreateVertexShader(&g_vs_main1_5, sizeof(g_vs_main1_5), NULL, &m_pVtxShader1_5);
	m_pDevice->CreateVertexShader(&g_vs_main1_6, sizeof(g_vs_main1_6), NULL, &m_pVtxShader1_6);
	m_pDevice->CreateVertexShader(&g_vs_main2, sizeof(g_vs_main2), NULL, &m_pVtxShader2);
	m_pDevice->CreateVertexShader(&g_vs_main3, sizeof(g_vs_main3), NULL, &m_pVtxShader3);
	m_pDevice->CreateVertexShader(&g_vs_main3_1, sizeof(g_vs_main3_1), NULL, &m_pVtxShader3_1);

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// pixel shader

	m_pDevice->CreatePixelShader(&g_ps_main1, sizeof(g_ps_main1), NULL, &m_pPxShader1);
	m_pDevice->CreatePixelShader(&g_ps_main2, sizeof(g_ps_main2), NULL, &m_pPxShader2);
	m_pDevice->CreatePixelShader(&g_ps_main3, sizeof(g_ps_main3), NULL, &m_pPxShader3);
	m_pDevice->CreatePixelShader(&g_ps_main4, sizeof(g_ps_main4), NULL, &m_pPxShader4);
	m_pDevice->CreatePixelShader(&g_ps_main5, sizeof(g_ps_main5), NULL, &m_pPxShader5);
	m_pDevice->CreatePixelShader(&g_ps_main6, sizeof(g_ps_main6), NULL, &m_pPxShader6);
	m_pDevice->CreatePixelShader(&g_ps_main7, sizeof(g_ps_main7), NULL, &m_pPxShader7);
	m_pDevice->CreatePixelShader(&g_ps_main8, sizeof(g_ps_main8), NULL, &m_pPxShader8);
	m_pDevice->CreatePixelShader(&g_ps_main9, sizeof(g_ps_main9), NULL, &m_pPxShader9);
	m_pDevice->CreatePixelShader(&g_ps_main10, sizeof(g_ps_main10), NULL, &m_pPxShader10);
	m_pDevice->CreatePixelShader(&g_ps_main11, sizeof(g_ps_main11), NULL, &m_pPxShader11);
	m_pDevice->CreatePixelShader(&g_ps_main12, sizeof(g_ps_main12), NULL, &m_pPxShader12);
	m_pDevice->CreatePixelShader(&g_ps_main13, sizeof(g_ps_main13), NULL, &m_pPxShader13);
	m_pDevice->CreatePixelShader(&g_ps_main14, sizeof(g_ps_main14), NULL, &m_pPxShader14);
	m_pDevice->CreatePixelShader(&g_ps_main15, sizeof(g_ps_main15), NULL, &m_pPxShader15);

	//////////////////////////////////////////////////////////////////////////////////
	// サンプルステート

	D3D11_SAMPLER_DESC sample_desc;
	ZeroMemory(&sample_desc, sizeof(sample_desc));
	sample_desc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
	sample_desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
	sample_desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
	sample_desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
	sample_desc.MaxLOD = D3D11_FLOAT32_MAX;
	sample_desc.MinLOD = 0;
	sample_desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;

	m_pDevice->CreateSamplerState(&sample_desc, &m_pSampleState);

	///////////////////////////////////////////////////////////////////////////////////////////
	//ラスタライズ

	D3D11_RASTERIZER_DESC raster_desc;
	ZeroMemory(&raster_desc, sizeof(raster_desc));
	raster_desc.MultisampleEnable = false;
	raster_desc.ScissorEnable = false;
	raster_desc.AntialiasedLineEnable = true;
	raster_desc.DepthClipEnable = true;
	raster_desc.CullMode = D3D11_CULL_NONE;
	raster_desc.FillMode = D3D11_FILL_SOLID;
	raster_desc.DepthBiasClamp = 0.05f;
	raster_desc.SlopeScaledDepthBias = 0;

	m_pDevice->CreateRasterizerState(&raster_desc, &m_pRasterizeState);

	////////////////////////////////////////////////////////////////////
	// ブレンドステイト

	D3D11_BLEND_DESC desc_blend;
	ZeroMemory(&desc_blend, sizeof(D3D11_BLEND_DESC));
	desc_blend.AlphaToCoverageEnable = true;
	desc_blend.IndependentBlendEnable = false;
	desc_blend.RenderTarget[0].BlendEnable = true;
	desc_blend.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
	desc_blend.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
	desc_blend.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
	desc_blend.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
	desc_blend.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
	desc_blend.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	desc_blend.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
	m_pDevice->CreateBlendState(&desc_blend, &m_pBlendState1); //通常のアルファブレンド

	ZeroMemory(&desc_blend, sizeof(D3D11_BLEND_DESC));
	desc_blend.AlphaToCoverageEnable = false;
	desc_blend.IndependentBlendEnable = false;
	desc_blend.RenderTarget[0].BlendEnable = true;
	desc_blend.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
	desc_blend.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
	desc_blend.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
	desc_blend.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
	desc_blend.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
	desc_blend.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	desc_blend.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
	m_pDevice->CreateBlendState(&desc_blend, &m_pBlendState2); //月明かり用アルファブレンド

	/////////////////////////////////////////////////////////////////////

	CVertex vtx[4];
	SetVertex(&vtx[0], -1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
	SetVertex(&vtx[1], 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0);
	SetVertex(&vtx[2], -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1);
	SetVertex(&vtx[3], 1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1);

	ZeroMemory(&desc_buffer, sizeof(D3D11_BUFFER_DESC));
	desc_buffer.ByteWidth = sizeof(CVertex)* 4;
	desc_buffer.Usage = D3D11_USAGE_DYNAMIC;
	desc_buffer.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	desc_buffer.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	desc_buffer.MiscFlags = 0;
	desc_buffer.StructureByteStride = sizeof(float);

	D3D11_SUBRESOURCE_DATA res_data_buffer;
	res_data_buffer.pSysMem = &vtx[0];
	ID3D11Buffer *vertex_buffer = NULL;
	m_pDevice->CreateBuffer(&desc_buffer, &res_data_buffer, &VertexBuffer);

	return true;
}

bool CCommonDevice::SetViewParam( float screen_width, float screen_height, float aspect ){

	matWorld = XMMatrixIdentity();
	matView = XMMatrixIdentity();
	matProj = XMMatrixIdentity();

	XMVECTOR at = XMVectorSet(At.x, At.y, At.z, 1.0f);
	XMVECTOR eye = XMVectorSet(Eye.x, Eye.y, Eye.z, 1.0f);
	XMVECTOR up = XMVectorSet(0, 0, 1, 0.0f);
	matView = XMMatrixLookAtLH(eye, at, up) * XMMatrixScaling(-1, 1, 1);
	matProj = XMMatrixPerspectiveFovLH(ToRadian(SightAngle), aspect, 0.001, 5000.0);

	ConstantBuffer1 constant_buffer1;

	XMStoreFloat4x4(&constant_buffer1.MatWorld, XMMatrixTranspose(matWorld));
	XMStoreFloat4x4(&constant_buffer1.MatView, XMMatrixTranspose(matView));
	XMStoreFloat4x4(&constant_buffer1.MatProj, XMMatrixTranspose(matProj));
	constant_buffer1.EyePos = XMFLOAT4(Eye.x, Eye.y, Eye.z, 1.0f);

	//シェーダーライトの設定
	for (int i = 0; i <= LIGHT_NUM_MAX - 1; i++){
		constant_buffer1.LightColor[i] = ShaderLight[i];
		constant_buffer1.LightPos[i] = ShaderLightPos[i];
	}

	//コンスタントバッファ設定
	D3D11_MAPPED_SUBRESOURCE resource;
	m_pDeviceContext->Map(m_pConstantBuffer1, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
	memcpy(resource.pData, &constant_buffer1, sizeof(ConstantBuffer1));
	m_pDeviceContext->Unmap(m_pConstantBuffer1, 0);

	m_pDeviceContext->VSSetConstantBuffers(0, 1, &m_pConstantBuffer1);
	m_pDeviceContext->PSSetConstantBuffers(0, 1, &m_pConstantBuffer1);

	return true;
}

///////////////////////////////////////////////////////////////////////////////////

int CCommonDevice::CameraMove(XMFLOAT4 *path1, int num1, int path_slice_size ){

	PathSliceSize = path_slice_size;

	Path_t_Count++;

	if (Path_t_Count >= PathSliceSize){
		Path_t_Count = 0;
		PathCount += 2;
		PathPoint = path1[PathCount];
		ControlPathPoint = path1[PathCount - 1];
		PrevPathPoint = path1[PathCount - 2];
	}

	PrevPoint.x = At.x;
	PrevPoint.y = At.y;
	PrevPoint.z = At.z;
	float rate_t = ((float)Path_t_Count) / ((float)PathSliceSize);
	float pos_x = PathPoint.x * pow(rate_t, 2) + 2.0f * ControlPathPoint.x * rate_t * (1.0f - rate_t) + PrevPathPoint.x * pow(1.0f - rate_t, 2);
	float pos_y = PathPoint.y * pow(rate_t, 2) + 2.0f * ControlPathPoint.y * rate_t * (1.0f - rate_t) + PrevPathPoint.y * pow(1.0f - rate_t, 2);
	float pos_z = PathPoint.z * pow(rate_t, 2) + 2.0f * ControlPathPoint.z * rate_t * (1.0f - rate_t) + PrevPathPoint.z * pow(1.0f - rate_t, 2);
	At.x = pos_x;
	At.y = pos_y;
	At.z = pos_z;
	Eye.x = PrevPoint.x;
	Eye.y = PrevPoint.y;
	Eye.z = PrevPoint.z;

	if (PathCount >= num1)
		return CAMERA_MOVE_REACH_END;

	return CAMERA_MOVE_DONE;
}

int CCommonDevice::CameraMoveSwing(XMFLOAT4 *path1, int num1, int path_slice_size){

	PathSliceSize = path_slice_size;

	float len = 0.0f;
	do{
		Path_t_Count++;

		if (Path_t_Count >= PathSliceSize){
			Path_t_Count = 0;
			PathCount += 2;
			PathPoint = path1[PathCount];
			ControlPathPoint = path1[PathCount - 1];
			PrevPathPoint = path1[PathCount - 2];
		}

		PrevPoint.x = Point.x;
		PrevPoint.y = Point.y;
		PrevPoint.z = Point.z;
		float rate_t = ((float)Path_t_Count) / ((float)PathSliceSize);
		float pos_x = PathPoint.x * pow(rate_t, 2) + 2.0f * ControlPathPoint.x * rate_t * (1.0f - rate_t) + PrevPathPoint.x * pow(1.0f - rate_t, 2);
		float pos_y = PathPoint.y * pow(rate_t, 2) + 2.0f * ControlPathPoint.y * rate_t * (1.0f - rate_t) + PrevPathPoint.y * pow(1.0f - rate_t, 2);
		float pos_z = PathPoint.z * pow(rate_t, 2) + 2.0f * ControlPathPoint.z * rate_t * (1.0f - rate_t) + PrevPathPoint.z * pow(1.0f - rate_t, 2);
		Point.x = pos_x;
		Point.y = pos_y;
		Point.z = pos_z;
		len = sqrt(pow(PrevPoint.x - Point.x, 2.0f) + pow(PrevPoint.y - Point.y, 2.0f) + pow(PrevPoint.z - Point.z, 2.0f));
	} while (len < 0.0001f);

	static float rad = 0.0f;
	rad += 0.02f;
	if (rad > 3.14159265f * 2.0f)
		rad -= 3.14159265f * 2.0f;

	XMVECTOR vec = XMVectorSet(PrevPoint.x - Point.x, PrevPoint.y - Point.y, PrevPoint.z - Point.z, 1.0f);
	float vec_x = XMVectorGetX(vec);
	float vec_y = XMVectorGetY(vec);
	vec.x += sin(rad);
	vec.y += cos(rad);
	vec.z += sin(rad) * cos(rad);
	Eye.x = PrevPoint.x + vec.x * 0.015f;
	Eye.y = PrevPoint.y + vec.y * 0.015f;
	Eye.z = PrevPoint.z + vec.z * 0.015f;
	At.x = Point.x - vec.x * 0.015f;
	At.y = Point.y - vec.y * 0.015f;
	At.z = Point.z - vec.z * 0.015f;
	if (abs(vec_y) < 0.01f){
		if (vec_x > 0.0f)
			CameraRotationZ = 3.14159265f / 2.0f;
		else
			CameraRotationZ = -3.14159265f / 2.0f;
	}
	else{
		CameraRotationZ = -atan(vec_x / vec_y);
	}

	if (PathCount >= num1)
		return CAMERA_MOVE_REACH_END;

	return CAMERA_MOVE_DONE;
}
