//==============================================================================================================================
bool ShadowMapBuildShader::Render(int indexCount, XMMATRIX world, LightCamera* lightCamera)
{
	cbShadowMapConst cSMB;
	
	//m_pD3DSystem->SetRasterizerState(m_pD3DSystem->RSDepth());

	cSMB.g_World = ZShadeSandboxMath::ZMath::GMathMF(XMMatrixTranspose(world));
	cSMB.g_LightView = lightCamera->LightView4x4();
	cSMB.g_LightProj = lightCamera->LightProj4x4();
	
	// Map matrix constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pShadowMapCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(cbShadowMapConst*)mapped_res.pData = cSMB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pShadowMapCB, 0);
	}
	
	// Set the shadow map constant buffer into the Vertex Shader
	ID3D11Buffer* vs_cbs[1] = { m_pShadowMapCB };
	m_pD3DSystem->GetDeviceContext()->VSSetConstantBuffers(0, 1, vs_cbs);
	
	// Tell the shader what input layout to use
	SetInputLayout("ShadowMapBuildShader");
	
	// Assign the shaders to render the mesh
	SetVertexShader();
	//SetPixelShader();
	
	m_pD3DSystem->GetDeviceContext()->PSSetShader(NULL, NULL, 0);

	//Perform Drawing
	RenderIndex11(indexCount);
	
	return true;
}
//==============================================================================================================================
bool OBJMeshShader::Render
(	int startIndex
,	int indexCount
,	ZShadeSandboxMesh::MeshRenderParameters mrp
,	ZShadeSandboxLighting::ShaderMaterial* material
)
{
	ID3D11ShaderResourceView* diffuseArrayTexture = 0;
	ID3D11ShaderResourceView* diffuseTexture = 0;
	ID3D11ShaderResourceView* ambientTexture = 0;
	ID3D11ShaderResourceView* specularTexture = 0;
	ID3D11ShaderResourceView* emissiveTexture = 0;
	ID3D11ShaderResourceView* normalMapTexture = 0;
	ID3D11ShaderResourceView* blendMapTexture = 0;
	ID3D11ShaderResourceView* detailMapTexture = 0;
	ID3D11ShaderResourceView* alphaMapTexture = 0;
	ID3D11ShaderResourceView* shadowMapTexture = 0;
	ID3D11ShaderResourceView* ssaoTexture = 0;
	ID3D11ShaderResourceView* displacementMapTexture = 0;

	material->GetTextures(
		diffuseArrayTexture,
		diffuseTexture,
		ambientTexture,
		specularTexture,
		emissiveTexture,
		normalMapTexture,
		blendMapTexture,
		detailMapTexture,
		alphaMapTexture,
		shadowMapTexture,
		ssaoTexture,
		displacementMapTexture
	);

	material->BuildMaterialConstantBuffer(m_pShadingCB, mrp.camera->Position(), mrp.clipplane);
	
	mrp.camera->BuildCameraConstantBuffer(m_pD3DSystem, m_pMatrixCB, mrp.world, mrp.reflection);
	
	ZShadeSandboxLighting::LightManager::Instance()->BuildFinalLightBuffers(m_pLightCB, m_pSunCB);

	// Set the shading constant buffer and matrix constant buffer into the Vertex Shader
	ID3D11Buffer* vs_cbs[2] = { m_pShadingCB, m_pMatrixCB };
	m_pD3DSystem->GetDeviceContext()->VSSetConstantBuffers(2, 2, vs_cbs);
	
	// Set the shading constant buffer into the Pixel Shader
	ID3D11Buffer* ps_cbs[3] = { m_pLightCB, m_pSunCB, m_pShadingCB };
	m_pD3DSystem->GetDeviceContext()->PSSetConstantBuffers(0, 3, ps_cbs);
	
	ID3D11ShaderResourceView* ps_srvs[11] = { diffuseArrayTexture, diffuseTexture, ambientTexture, specularTexture, emissiveTexture, normalMapTexture, blendMapTexture, detailMapTexture, alphaMapTexture, shadowMapTexture, ssaoTexture };
	ID3D11SamplerState* ps_samp[1] = { m_pD3DSystem->Linear() };
	
	if (!m_Wireframe)
	{
		m_pD3DSystem->TurnOffCulling();

		// Set the texture into the Pixel Shader
		m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 11, ps_srvs);
		m_pD3DSystem->GetDeviceContext()->PSSetSamplers(0, 1, ps_samp);

		SwitchTo("OBJMeshPS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
	}
	else
	{
		SwitchTo("OBJMeshWireframePS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
	}

	// Tell the shader what input layout to use
	SetInputLayout("OBJMeshShader");
	
	// Assign the shaders to render the mesh
	SetVertexShader();
	SetPixelShader();
	
	//Perform Drawing
	RenderIndex11(startIndex, indexCount);

	// Unbind
	if (!m_Wireframe)
	{
		m_pD3DSystem->TurnOnCulling();

		ps_samp[0] = NULL;
		m_pD3DSystem->GetDeviceContext()->PSSetSamplers(0, 1, ps_samp);

		for (int i = 0; i < 11; i++) ps_srvs[i] = NULL;
		m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 11, ps_srvs);
	}
	
	return true;
}
//==============================================================================================================================
bool MaterialTessellationShader::Render11
(	int indexCount
,	int instanceCount
,	ZShadeSandboxMesh::MeshRenderParameters mrp
,	ZShadeSandboxLighting::ShaderMaterial* material
)
{
	ID3D11ShaderResourceView* diffuseArrayTexture = 0;
	ID3D11ShaderResourceView* diffuseTexture = 0;
	ID3D11ShaderResourceView* ambientTexture = 0;
	ID3D11ShaderResourceView* specularTexture = 0;
	ID3D11ShaderResourceView* emissiveTexture = 0;
	ID3D11ShaderResourceView* normalMapTexture = 0;
	ID3D11ShaderResourceView* blendMapTexture = 0;
	ID3D11ShaderResourceView* detailMapTexture = 0;
	ID3D11ShaderResourceView* alphaMapTexture = 0;
	ID3D11ShaderResourceView* shadowMapTexture = 0;
	ID3D11ShaderResourceView* ssaoTexture = 0;
	ID3D11ShaderResourceView* displacementMapTexture = 0;

	material->GetTextures(
		diffuseArrayTexture,
		diffuseTexture,
		ambientTexture,
		specularTexture,
		emissiveTexture,
		normalMapTexture,
		blendMapTexture,
		detailMapTexture,
		alphaMapTexture,
		shadowMapTexture,
		ssaoTexture,
		displacementMapTexture
	);
	
	material->BuildMaterialTessellationBuffer(m_pTessellationCB, mrp.camera->Position());
	material->BuildMaterialDomainBuffer(m_pDomainCB, mrp.world, mrp.camera, mrp.clipplane, mrp.reflection);
	material->BuildMaterialConstantBuffer(m_pShadingCB, mrp.camera->Position(), mrp.clipplane);
	
	ZShadeSandboxLighting::LightManager::Instance()->BuildFinalLightBuffers(m_pLightCB, m_pSunCB);
	
	ID3D11Buffer* vs_cbs[1] = { m_pShadingCB };
	m_pD3DSystem->GetDeviceContext()->VSSetConstantBuffers(4, 1, vs_cbs);

	// Set the tessellation constant buffer into the Hull Shader
	ID3D11Buffer* hs_cbs[1] = { m_pTessellationCB };
	m_pD3DSystem->GetDeviceContext()->HSSetConstantBuffers(2, 1, hs_cbs);
	
	// Set the matrix constant buffer into the Domain Shader
	ID3D11Buffer* ds_cbs[2] = { m_pDomainCB, m_pShadingCB };
	m_pD3DSystem->GetDeviceContext()->DSSetConstantBuffers(3, 2, ds_cbs);
	
	ID3D11Buffer* ps_cbs[5] = { m_pLightCB, m_pSunCB, m_pTessellationCB, m_pDomainCB, m_pShadingCB };
	m_pD3DSystem->GetDeviceContext()->PSSetConstantBuffers(0, 5, ps_cbs);

	ID3D11ShaderResourceView* ps_srvs[11] = { diffuseArrayTexture, diffuseTexture, ambientTexture, specularTexture, emissiveTexture, normalMapTexture, blendMapTexture, detailMapTexture, alphaMapTexture, shadowMapTexture, ssaoTexture };
	ID3D11SamplerState* ps_samp[2] = { m_pD3DSystem->Point(), m_pD3DSystem->Linear() };

	ID3D11ShaderResourceView* disp_srvs[1] = { displacementMapTexture };

	if (!m_Wireframe)
	{
		// Assign Texture
		
		m_pD3DSystem->GetDeviceContext()->VSSetSamplers(0, 2, ps_samp);
		m_pD3DSystem->GetDeviceContext()->DSSetSamplers(0, 2, ps_samp);
		m_pD3DSystem->GetDeviceContext()->PSSetSamplers(0, 2, ps_samp);
		
		m_pD3DSystem->GetDeviceContext()->VSSetShaderResources(11, 1, disp_srvs);
		m_pD3DSystem->GetDeviceContext()->DSSetShaderResources(11, 1, disp_srvs);
		m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 11, ps_srvs);
		
		switch (mType)
		{
			case ZShadeSandboxLighting::EMaterialTessellationType::Type::eQuad:
				SwitchTo("QuadMaterialTessellationPS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
			break;
			case ZShadeSandboxLighting::EMaterialTessellationType::Type::eTri:
				SwitchTo("TriMaterialTessellationPS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
			break;
		}
	}
	else
	{
		switch (mType)
		{
			case ZShadeSandboxLighting::EMaterialTessellationType::Type::eQuad:
				SwitchTo("QuadMaterialTessellationWireframePS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
			break;
			case ZShadeSandboxLighting::EMaterialTessellationType::Type::eTri:
				SwitchTo("TriMaterialTessellationWireframePS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
			break;
		}
	}
	
	if (mrp.useInstancing)
	{
		SetInputLayout("MaterialTessellationShaderInstance");
		switch (mType)
		{
			case ZShadeSandboxLighting::EMaterialTessellationType::Type::eQuad:
				SwitchTo("QuadMaterialTessellationInstanceVS", ZShadeSandboxShader::EShaderTypes::ST_VERTEX);
			break;
			case ZShadeSandboxLighting::EMaterialTessellationType::Type::eTri:
				SwitchTo("TriMaterialTessellationInstanceVS", ZShadeSandboxShader::EShaderTypes::ST_VERTEX);
			break;
		}
	}
	else
	{
		SetInputLayout("MaterialTessellationShader");
		switch (mType)
		{
			case ZShadeSandboxLighting::EMaterialTessellationType::Type::eQuad:
				SwitchTo("QuadMaterialTessellationVS", ZShadeSandboxShader::EShaderTypes::ST_VERTEX);
			break;
			case ZShadeSandboxLighting::EMaterialTessellationType::Type::eTri:
				SwitchTo("TriMaterialTessellationVS", ZShadeSandboxShader::EShaderTypes::ST_VERTEX);
			break;
		}
	}
	
	SetVertexShader();
	SetHullShader();
	SetDomainShader();
	SetPixelShader();
	
	//Perform Drawing
	if (mrp.useInstancing)
	{
		RenderIndexInstanced11(indexCount, instanceCount);
	}
	else
	{
		RenderIndex11(indexCount);
	}

	// Unbind
	if (!m_Wireframe)
	{
		ps_samp[0] = NULL;
		m_pD3DSystem->GetDeviceContext()->VSSetSamplers(0, 2, ps_samp);
		m_pD3DSystem->GetDeviceContext()->DSSetSamplers(0, 2, ps_samp);
		m_pD3DSystem->GetDeviceContext()->PSSetSamplers(0, 2, ps_samp);
		
		disp_srvs[0] = NULL;
		m_pD3DSystem->GetDeviceContext()->VSSetShaderResources(11, 1, disp_srvs);
		m_pD3DSystem->GetDeviceContext()->DSSetShaderResources(11, 1, disp_srvs);

		for (int i = 0; i < 11; i++) ps_srvs[i] = NULL;
		m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 11, ps_srvs);
	}
	
	// Set Hull, Domain and Geometry Shaders to null in case they are not needed
	m_pD3DSystem->GetDeviceContext()->HSSetShader(NULL, NULL, 0);
	m_pD3DSystem->GetDeviceContext()->DSSetShader(NULL, NULL, 0);
	m_pD3DSystem->GetDeviceContext()->GSSetShader(NULL, NULL, 0);

	return true;
}
//==============================================================================================================================
bool MaterialShader::Render11
(	int indexCount
    ,	int instanceCount
    ,	ZShadeSandboxMesh::MeshRenderParameters mrp
    ,	ZShadeSandboxLighting::ShaderMaterial* material
)
{
    ID3D11ShaderResourceView* diffuseArrayTexture = 0;
    ID3D11ShaderResourceView* diffuseTexture = 0;
    ID3D11ShaderResourceView* ambientTexture = 0;
    ID3D11ShaderResourceView* specularTexture = 0;
    ID3D11ShaderResourceView* emissiveTexture = 0;
    ID3D11ShaderResourceView* normalMapTexture = 0;
    ID3D11ShaderResourceView* blendMapTexture = 0;
    ID3D11ShaderResourceView* detailMapTexture = 0;
    ID3D11ShaderResourceView* alphaMapTexture = 0;
    ID3D11ShaderResourceView* shadowMapTexture = 0;
    ID3D11ShaderResourceView* ssaoTexture = 0;
    ID3D11ShaderResourceView* displacementMapTexture = 0;

    if (material == 0) return false;

    material->GetTextures(
        diffuseArrayTexture,
        diffuseTexture,
        ambientTexture,
        specularTexture,
        emissiveTexture,
        normalMapTexture,
        blendMapTexture,
        detailMapTexture,
        alphaMapTexture,
        shadowMapTexture,
        ssaoTexture,
        displacementMapTexture
    );

    material->fBlendAmount = mrp.blendAmount;

    material->BuildMaterialConstantBuffer(m_pShadingCB, mrp.camera->Position(), mrp.clipplane);

    // Use the default light if there is no light
    if (mrp.light == 0)
    {
        MaterialShader::mDefaultLight->Update();
        mrp.light = MaterialShader::mDefaultLight;
    }

    mrp.camera->BuildCameraConstantBuffer(m_pD3DSystem, m_pMatrixCB, mrp.light, mrp.world, mrp.reflection);

    if (m_pD3DSystem->GetEngineOptions()->m_DimType == DimType::ZSHADE_3D)
        ZShadeSandboxLighting::LightManager::Instance()->BuildFinalLightBuffers(m_pLightCB, m_pSunCB);
    else
    {
        material->bEnableLighting = false;
        material->bHasDetailMapTexture = false;
    }

    ID3D11Buffer* vs_cbs[2] = { m_pShadingCB, m_pMatrixCB };
    m_pD3DSystem->GetDeviceContext()->VSSetConstantBuffers(2, 2, vs_cbs);

    ID3D11Buffer* ps_cbs[3] = { m_pLightCB, m_pSunCB, m_pShadingCB };
    m_pD3DSystem->GetDeviceContext()->PSSetConstantBuffers(0, 3, ps_cbs);

    ID3D11ShaderResourceView* ps_srvs[11] = { diffuseArrayTexture, diffuseTexture, ambientTexture, specularTexture, emissiveTexture, normalMapTexture, blendMapTexture, detailMapTexture, alphaMapTexture, shadowMapTexture, ssaoTexture };
    ID3D11SamplerState* ps_samp[2] = { m_pD3DSystem->Point(), m_pD3DSystem->Linear() };

    ID3D11ShaderResourceView* vs_srvs[1] = { displacementMapTexture };

    if (!m_Wireframe)
    {
        // Assign Texture

        m_pD3DSystem->GetDeviceContext()->VSSetSamplers(0, 2, ps_samp);
        m_pD3DSystem->GetDeviceContext()->PSSetSamplers(0, 2, ps_samp);

        m_pD3DSystem->GetDeviceContext()->VSSetShaderResources(11, 1, vs_srvs);
        m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 11, ps_srvs);

        SwitchTo("MaterialShaderPS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
    }
    else
    {
        SwitchTo("MaterialShaderWireframePS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
    }

    if (mrp.useInstancing)
    {
        SetInputLayout("MaterialShaderInstance");
        SwitchTo("MaterialShaderInstanceVS", ZShadeSandboxShader::EShaderTypes::ST_VERTEX);
    }
    else
    {
        SetInputLayout("MaterialShader");
        SwitchTo("MaterialShaderVS", ZShadeSandboxShader::EShaderTypes::ST_VERTEX);
    }

    SetVertexShader();
    SetPixelShader();

    //Perform Drawing
    if (mrp.useInstancing)
    {
        RenderIndexInstanced11(indexCount, instanceCount);
    }
    else
    {
        RenderIndex11(indexCount);
    }

    // Unbind
    if (!m_Wireframe)
    {
        ps_samp[0] = NULL;
        ps_samp[1] = NULL;
        m_pD3DSystem->GetDeviceContext()->VSSetSamplers(0, 2, ps_samp);
        m_pD3DSystem->GetDeviceContext()->PSSetSamplers(0, 2, ps_samp);

        vs_srvs[0] = NULL;
        m_pD3DSystem->GetDeviceContext()->VSSetShaderResources(11, 1, vs_srvs);

        for (int i = 0; i < 11; i++) ps_srvs[i] = NULL;
        m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 11, ps_srvs);
    }

    return true;
}
//==============================================================================================================================
bool TerrainTessellationQuadShadowShader::Render(int indexCount, LightCamera* lightcamera,
	ZShadeSandboxTerrain::TerrainShadingConst terrainShadingConst, ID3D11ShaderResourceView* heightMapSRV)
{
	cTessellationBuffer cTB;
	cMatrixBuffer cMB;
	cDomainConstBuffer cDCB;
	
	m_pD3DSystem->SetRasterizerState(m_pD3DSystem->RSDepth());
	
	//if (m_UseCustomWorld)
	//	cMB.g_WorldMatrix = ZShadeSandboxMath::ZMath::GMathMF(XMMatrixTranspose(mWorld.Get()));
	//else
	//	cMB.g_WorldMatrix = ZShadeSandboxMath::ZMath::GMathMF(XMMatrixTranspose(XMMatrixIdentity()));
	
	cMB.g_ViewMatrix = lightcamera->LightView4x4();
	cMB.g_ProjMatrix = lightcamera->LightProj4x4();
	cMB.g_ShadowMatrix = lightcamera->ShadowTransform4x4();

	XMMATRIX toTexSpace = XMMatrixScaling(0.5f, -0.5f, 1.0f) * XMMatrixTranslation(0.5f, 0.5f, 0);
	cMB.g_TexSpaceMatrix = ZShadeSandboxMath::ZMath::GMathMF(XMMatrixTranspose(toTexSpace));
	
	cTB.g_EyePosW = terrainShadingConst.g_EyePosW;
	cTB.g_MinDist = terrainShadingConst.g_MinDist;
	cTB.g_MaxDist = terrainShadingConst.g_MaxDist;
	cTB.g_MinTess = terrainShadingConst.g_MinTess;
	cTB.g_MaxTess = terrainShadingConst.g_MaxTess;
	cTB.g_FrustumCull = terrainShadingConst.g_FrustumCull;
	cTB.padding = XMFLOAT2(0, 0);
	cTB.g_TerrSize = terrainShadingConst.g_MapSize;
	cTB.g_TerrScale = terrainShadingConst.g_TerrSize;

	cDCB.g_TexScale = XMFLOAT2(66.0f, 66.0f);
	cDCB.g_HeightScale = terrainShadingConst.g_HeightScale;
	cDCB.g_TerrainZScale = terrainShadingConst.g_TerrSize;
	cDCB.g_ClipPlane = terrainShadingConst.g_ClipPlane;
	cDCB.g_tpadding = XMFLOAT3(0, 0, 0);
	cDCB.g_FarPlane = terrainShadingConst.g_FarPlane;
	
	// Map tessellation constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pTessellationCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(cTessellationBuffer*)mapped_res.pData = cTB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pTessellationCB, 0);
	}
	
	// Map domain shader constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pDomainCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(cDomainConstBuffer*)mapped_res.pData = cDCB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pDomainCB, 0);
	}
	
	// Map matrix constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pMatrixBufferCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(cMatrixBuffer*)mapped_res.pData = cMB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pMatrixBufferCB, 0);
	}
	
	// Set the tessellation constant buffer into the Hull Shader
	ID3D11Buffer* hs_cbs[1] = { m_pTessellationCB };
	m_pD3DSystem->GetDeviceContext()->HSSetConstantBuffers(0, 1, hs_cbs);
	
	// Set the domain and matrix constant buffer into the Domain Shader
	ID3D11Buffer* ds_cbs[2] = { m_pDomainCB, m_pMatrixBufferCB };
	m_pD3DSystem->GetDeviceContext()->DSSetConstantBuffers(0, 2, ds_cbs);
	
	// Set the heightmap texture into the vertex shader
	ID3D11ShaderResourceView* vs_srvs[1] = { heightMapSRV };
	m_pD3DSystem->GetDeviceContext()->VSSetShaderResources(0, 1, vs_srvs);
	
	// Set the heightmap texture into the domain shader
	ID3D11ShaderResourceView* ds_srvs[1] = { heightMapSRV };
	m_pD3DSystem->GetDeviceContext()->DSSetShaderResources(0, 1, ds_srvs);
	
	// Tell the shader what input layout to use
	SetInputLayout("TerrainTessellationQuadShadowShader");
	
	// Assign the shaders to render the mesh
	SetVertexShader();
	SetHullShader();
	SetDomainShader();
	SetPixelShader();

	//m_pD3DSystem->GetDeviceContext()->PSSetShader(NULL, NULL, 0);
	
	//Perform Drawing
	RenderIndex11(indexCount);
	
	return true;
}
//==============================================================================================================================
bool DeferredShader::Render11
(	int indexCount
,	Camera* camera
,	XMMATRIX world
,	XMFLOAT2 specularPowerRange
,	float specularIntensity
,	float specularPower
,	ID3D11ShaderResourceView* texture
)
{
	cbPackBuffer cPB;
	cPB.g_SpecularPowerRange = specularPowerRange;
	cPB.g_SpecularIntensity = specularIntensity;
	cPB.g_SpecularPower = specularPower;
	// Map the pack buffer
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res2;
		m_pD3DSystem->GetDeviceContext()->Map(m_pPackCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res2);
		{
			assert(mapped_res2.pData);
			*(cbPackBuffer*)mapped_res2.pData = cPB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pPackCB, 0);
	}
	
	cbMatrixBuffer cMB;
	cMB.g_matWorld = ZShadeSandboxMath::ZMath::GMathMF(XMMatrixTranspose(world));
	cMB.g_matView = camera->View4x4();
	cMB.g_matProj = camera->Proj4x4();
	// Map the matrix buffer
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res2;
		m_pD3DSystem->GetDeviceContext()->Map(m_pMatrixCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res2);
		{
			assert(mapped_res2.pData);
			*(cbMatrixBuffer*)mapped_res2.pData = cMB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pMatrixCB, 0);
	}
	
	ID3D11Buffer* vs_cbs[1] = { m_pMatrixCB };
	m_pD3DSystem->GetDeviceContext()->VSSetConstantBuffers(1, 1, vs_cbs);
	
	ID3D11Buffer* ps_cbs[1] = { m_pPackCB };
	m_pD3DSystem->GetDeviceContext()->PSSetConstantBuffers(0, 1, ps_cbs);
	
	// Assign Texture
	ID3D11ShaderResourceView* ps_srvs[1] = { texture };
	ID3D11SamplerState* ps_samp[1] = { m_pD3DSystem->Linear() };
	
	if (!m_Wireframe)
	{
		m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 1, ps_srvs);
		m_pD3DSystem->GetDeviceContext()->PSSetSamplers(0, 1, ps_samp);

		SwitchTo("DeferredShaderPS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
	}
	else
	{
		SwitchTo("DeferredShaderWireframePS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
	}

	SetInputLayout("DeferredShader");
	
	SetVertexShader();
	SetPixelShader();
	
	//Perform Drawing
	RenderIndex11(indexCount);

	// Unbind
	if (!m_Wireframe)
	{
		m_pD3DSystem->TurnOnCulling();

		ps_samp[0] = NULL;
		m_pD3DSystem->GetDeviceContext()->PSSetSamplers(0, 1, ps_samp);
		ps_srvs[0] = NULL;
		m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 1, ps_srvs);
	}

	return true;
}
//==============================================================================================================================
bool TriMaterialTessellationShader::Render11(int indexCount, ZShadeSandboxMath::XMMath4 clipplane, Camera* camera, float tessFactor, ZShadeSandboxLighting::ShaderMaterial* material)
{
	int useDiffuseArrayTexture = 0;
	int useDiffuseTexture = 0;
	int useNormalMapTexture = 0;
	int useBlendMapTexture = 0;
	int useDetailMapTexture = 0;
	int useAlphaMapTexture = 0;
	
	ID3D11ShaderResourceView* diffuseArrayTexture = 0;
	ID3D11ShaderResourceView* diffuseTexture = 0;
	ID3D11ShaderResourceView* normalMapTexture = 0;
	ID3D11ShaderResourceView* blendMapTexture = 0;
	ID3D11ShaderResourceView* detailMapTexture = 0;
	ID3D11ShaderResourceView* alphaMapTexture = 0;
	
	for (int i = 0; i < material->TextureCount(); i++)
	{
		switch (material->GetMaterialTextureType(i))
		{
			case ZShadeSandboxLighting::EMaterialTextureType::eDiffuseArray:
				useDiffuseArrayTexture = 1;
				diffuseArrayTexture = material->GetTexture(i)->getTexture11();
			break;
			case ZShadeSandboxLighting::EMaterialTextureType::eDiffuse:
				useDiffuseTexture = 1;
				diffuseTexture = material->GetTexture(i)->getTexture11();
			break;
			case ZShadeSandboxLighting::EMaterialTextureType::eNormal:
				useNormalMapTexture = 1;
				normalMapTexture = material->GetTexture(i)->getTexture11();
			break;
			case ZShadeSandboxLighting::EMaterialTextureType::eBlend:
				useBlendMapTexture = 1;
				blendMapTexture = material->GetTexture(i)->getTexture11();
			break;
			case ZShadeSandboxLighting::EMaterialTextureType::eDetail:
				useDetailMapTexture = 1;
				detailMapTexture = material->GetTexture(i)->getTexture11();
			break;
			case ZShadeSandboxLighting::EMaterialTextureType::eAlpha:
				useAlphaMapTexture = 1;
				alphaMapTexture = material->GetTexture(i)->getTexture11();
			break;
		}
	}
	
	Const_Per_Frame per_frame;
	per_frame.g_EyePosW = camera->Position();
	per_frame.g_ClipPlane = XMFLOAT4(clipplane.x, clipplane.y, clipplane.z, clipplane.w);
	per_frame.g_MaterialDiffuseColor = material->DiffuseColor();
	per_frame.g_MaterialAmbientColor = material->AmbientColor();
	per_frame.g_MaterialSpecularPower = material->SpecularPower();
	per_frame.g_MaterialSpecularIntensity = material->SpecularIntensity();
	per_frame.g_UsingDiffuseArrayTexture = useDiffuseArrayTexture;
	per_frame.g_UsingDiffuseTexture = useDiffuseArrayTexture;
	per_frame.g_UsingNormalMapTexture = useNormalMapTexture;
	per_frame.g_UsingBlendMapTexture = useBlendMapTexture;
	per_frame.g_UsingDetailMapTexture = useDetailMapTexture;
	per_frame.g_UseAlphaMapTexture = useAlphaMapTexture;
	per_frame.g_EnableTransparency = material->EnableTransparency();
	per_frame.g_EnableLighting = material->EnableLighting();
	per_frame.g_DetailBrightness = material->DetailBrightness();
	per_frame.g_AlphaToCoverageValue = material->AlphaToCoverageValue(); // Value that clips pixel during alpha blending
	per_frame.g_FlipTextureH = (bFlipHorizontally == true) ? 1 : 0;
	per_frame.g_FlipTextureV = (bFlipVertically == true) ? 1 : 0;
	per_frame.padding = 0;
	
	Const_Per_Object per_object;
	
	if (m_UseCustomWorld)
	{
		XMFLOAT4X4 world = ZShadeSandboxMath::ZMath::GMathMF(XMMatrixTranspose(mWorld.Get()));
		per_object.g_matWorld = world;
	}
	else
		per_object.g_matWorld = camera->World4x4();

	if (m_UseCustomView)
	{
		per_object.g_matView = mView;
	}
	else
		per_object.g_matView = camera->View4x4();

	if (m_pD3DSystem->GetEngineOptions()->m_DimType == DimType::ZSHADE_2D)
		per_object.g_matProj = camera->Ortho4x4();
	else if (m_pD3DSystem->GetEngineOptions()->m_DimType == DimType::ZSHADE_3D)
		per_object.g_matProj = camera->Proj4x4();

	if (m_UseOrtho)
	{
		per_object.g_matProj = camera->Ortho4x4();
	}
	
	ZShadeSandboxLighting::cbLightBuffer cLB;
	ZShadeSandboxLighting::cbAmbientLightBuffer alb;
	ZShadeSandboxLighting::cbDirectionalLightBuffer dlb;
	ZShadeSandboxLighting::cbSpotLightBuffer slb;
	ZShadeSandboxLighting::cbPointLightBuffer plb;
	ZShadeSandboxLighting::cbCapsuleLightBuffer clb;

	for (int i = 0; i < material->GetLightBuffer()->g_AmbientLightCount; i++)
	{
		alb.g_AmbientColor = material->GetLightBuffer()->g_AmbientLight[i].g_AmbientColor;
		cLB.g_AmbientLight[i] = alb;
	}
	for (int i = 0; i < material->GetLightBuffer()->g_DirectionalLightCount; i++)
	{
		dlb.g_Direction = material->GetLightBuffer()->g_DirectionalLight[i].g_LightDirection;
		dlb.padding = 0;
		dlb.g_Ambient = material->GetLightBuffer()->g_DirectionalLight[i].g_AmbientColor;
		dlb.g_Diffuse = material->GetLightBuffer()->g_DirectionalLight[i].g_DiffuseColor;
		cLB.g_DirectionalLight[i] = dlb;
	}
	for (int i = 0; i < material->GetLightBuffer()->g_SpotLightCount; i++)
	{
		slb.g_AmbientColor = material->GetLightBuffer()->g_SpotLight[i].g_AmbientColor;
		slb.g_DiffuseColor = material->GetLightBuffer()->g_SpotLight[i].g_DiffuseColor;
		slb.g_LightPosition = material->GetLightBuffer()->g_SpotLight[i].g_LightPosition;
		slb.padding = 0;
		slb.g_LightRange = material->GetLightBuffer()->g_SpotLight[i].g_LightRange;
		slb.g_SpotCosOuterCone = material->GetLightBuffer()->g_SpotLight[i].g_SpotCosOuterCone;
		slb.g_SpotInnerConeReciprocal = material->GetLightBuffer()->g_SpotLight[i].g_SpotInnerConeReciprocal;
		slb.g_CosineAngle = material->GetLightBuffer()->g_SpotLight[i].g_CosineAngle;
		cLB.g_SpotLight[i] = slb;
	}
	for (int i = 0; i < material->GetLightBuffer()->g_PointLightCount; i++)
	{
		plb.g_LightPosition = material->GetLightBuffer()->g_PointLight[i].g_LightPosition;
		plb.g_LightRange = material->GetLightBuffer()->g_PointLight[i].g_LightRange;
		plb.g_Attenuation = material->GetLightBuffer()->g_PointLight[i].g_Attenuation;
		plb.padding = 0;
		plb.g_AmbientColor = material->GetLightBuffer()->g_PointLight[i].g_AmbientColor;
		plb.g_DiffuseColor = material->GetLightBuffer()->g_PointLight[i].g_DiffuseColor;
		cLB.g_PointLight[i] = plb;
	}
	for (int i = 0; i < material->GetLightBuffer()->g_CapsuleLightCount; i++)
	{
		clb.g_LightPosition = material->GetLightBuffer()->g_CapsuleLight[i].g_LightPosition;
		clb.g_LightRange = material->GetLightBuffer()->g_CapsuleLight[i].g_LightRange;
		clb.g_LightDirection = material->GetLightBuffer()->g_CapsuleLight[i].g_LightDirection;
		clb.g_DiffuseColor = material->GetLightBuffer()->g_CapsuleLight[i].g_DiffuseColor;
		clb.g_LightLength = material->GetLightBuffer()->g_CapsuleLight[i].g_LightLength;
		clb.g_CapsuleDirectionLength = material->GetLightBuffer()->g_CapsuleLight[i].g_CapsuleDirectionLength;
		clb.g_CapsuleIntensity = material->GetLightBuffer()->g_CapsuleLight[i].g_CapsuleIntensity;
		cLB.g_CapsuleLight[i] = clb;
	}
	cLB.g_AmbientLightCount = material->GetLightBuffer()->g_AmbientLightCount;
	cLB.g_DirectionalLightCount = material->GetLightBuffer()->g_DirectionalLightCount;
	cLB.g_SpotLightCount = material->GetLightBuffer()->g_SpotLightCount;
	cLB.g_PointLightCount = material->GetLightBuffer()->g_PointLightCount;
	cLB.g_CapsuleLightCount = material->GetLightBuffer()->g_CapsuleLightCount;
	cLB.g_AmbientDown = material->GetLightBuffer()->g_AmbientDown;
	cLB.g_AmbientUp = material->GetLightBuffer()->g_AmbientUp;
	cLB.padding = 0;
	
	ZShadeSandboxLighting::cbSunLightBuffer cSLB;
	cSLB.g_SunDir = material->GetSunLightBuffer()->g_SunDir;
	cSLB.g_EnableSun = material->GetSunLightBuffer()->g_EnableSun;
	cSLB.g_SunDiffuseColor = material->GetSunLightBuffer()->g_SunDiffuseColor;
	cSLB.padding = XMFLOAT3(0, 0, 0);
	cSLB.g_SunShineness = material->GetSunLightBuffer()->g_SunShineness;
	
	cTessellationBuffer cTB;
	cTB.g_TessellationFactor = tessFactor;
	cTB.padding = XMFLOAT3(0, 0, 0);
	
	// Map tessellation constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pTessellationCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(cTessellationBuffer*)mapped_res.pData = cTB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pTessellationCB, 0);
	}
	
	// Map the per frame constants
	{
	D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pPerFrameCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(Const_Per_Frame*)mapped_res.pData = per_frame;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pPerFrameCB, 0);
	}
	
	// Map the matrix constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res2;
		m_pD3DSystem->GetDeviceContext()->Map(m_pPerObjectCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res2);
		{
			assert(mapped_res2.pData);
			*(Const_Per_Object*)mapped_res2.pData = per_object;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pPerObjectCB, 0);
	}
	
	// Map light shading constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pLightCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(ZShadeSandboxLighting::cbLightBuffer*)mapped_res.pData = cLB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pLightCB, 0);
	}
	
	// Map sun light shading constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pSunCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(ZShadeSandboxLighting::cbSunLightBuffer*)mapped_res.pData = cSLB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pSunCB, 0);
	}
	
	// Set the tessellation constant buffer into the Hull Shader
	ID3D11Buffer* hs_cbs[1] = { m_pTessellationCB };
	m_pD3DSystem->GetDeviceContext()->HSSetConstantBuffers(0, 1, hs_cbs);
	
	// Set the matrix constant buffer into the Domain Shader
	ID3D11Buffer* ds_cbs[2] = { m_pPerFrameCB, m_pPerObjectCB };
	m_pD3DSystem->GetDeviceContext()->DSSetConstantBuffers(0, 2, ds_cbs);
	
	//ID3D11Buffer* vs_cbs[2] = { m_pPerFrameCB, m_pPerObjectCB };
	//m_pD3DSystem->GetDeviceContext()->VSSetConstantBuffers(0, 2, vs_cbs);
	
	ID3D11Buffer* ps_cbs[3] = { m_pPerFrameCB, m_pLightCB, m_pSunCB };
	m_pD3DSystem->GetDeviceContext()->PSSetConstantBuffers(0, 3, ps_cbs);

	ID3D11ShaderResourceView* ps_srvs[6] = { diffuseArrayTexture, diffuseTexture, normalMapTexture, blendMapTexture, detailMapTexture, alphaMapTexture };
	
	if (!m_Wireframe)
	{
		// Assign Texture
		m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 6, ps_srvs);

		SwitchTo("MaterialTessellationShaderPS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
	}
	else
	{
		SwitchTo("MaterialTessellationShaderWireframePS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
	}
	
	SetVertexShader();
	SetHullShader();
	SetDomainShader();
	SetPixelShader();

	SetInputLayout("TriMaterialTessellationShader");

	//Perform Drawing
	RenderIndex11(indexCount);

	// Unbind
	if (!m_Wireframe)
	{
		for (int i = 0; i < 6; i++) ps_srvs[i] = NULL;
		m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 6, ps_srvs);
	}
	
	// Set Hull, Domain and Geometry Shaders to null in case they are not needed
	m_pD3DSystem->GetDeviceContext()->HSSetShader(NULL, NULL, 0);
	m_pD3DSystem->GetDeviceContext()->DSSetShader(NULL, NULL, 0);
	m_pD3DSystem->GetDeviceContext()->GSSetShader(NULL, NULL, 0);

	return true;
}
//==============================================================================================================================
bool TerrainTessellationQuadSSAOShader::Render(int indexCount, Camera* camera, LightCamera* lightcamera, ZShadeSandboxTerrain::TerrainShadingConst terrainShadingConst, ID3D11ShaderResourceView* heightMapSRV)
{
	cTessellationBuffer cTB;
	cMatrixBuffer cMB;
	cDomainConstBuffer cDCB;
	cShadingConstBuffer cSCB;

	//if (m_UseCustomWorld)
	//	cMB.g_WorldMatrix = ZShadeSandboxMath::ZMath::GMathMF(XMMatrixTranspose(mWorld.Get()));
	//else
	//	cMB.g_WorldMatrix = camera->World4x4();

	cMB.g_ViewMatrix = camera->View4x4();

	cMB.g_ProjMatrix = camera->Proj4x4();

	XMMATRIX toTexSpace = XMMatrixScaling(0.5f, -0.5f, 1.0f) * XMMatrixTranslation(0.5f, 0.5f, 0);
	cMB.g_TexSpaceMatrix = ZShadeSandboxMath::ZMath::GMathMF(XMMatrixTranspose(toTexSpace));

	// Need to create the shadow matrix
	cMB.g_ShadowMatrix = lightcamera->ShadowTransform4x4();

	cTB.g_EyePosW = terrainShadingConst.g_EyePosW;
	cTB.g_MinDist = terrainShadingConst.g_MinDist;
	cTB.g_MaxDist = terrainShadingConst.g_MaxDist;
	cTB.g_MinTess = terrainShadingConst.g_MinTess;
	cTB.g_MaxTess = terrainShadingConst.g_MaxTess;
	cTB.g_FrustumCull = terrainShadingConst.g_FrustumCull;
	cTB.padding = XMFLOAT2(0, 0);
	cTB.g_TerrSize = terrainShadingConst.g_MapSize;
	cTB.g_TerrScale = terrainShadingConst.g_TerrSize;

	cDCB.g_TexScale = XMFLOAT2(66.0f, 66.0f);
	cDCB.g_HeightScale = terrainShadingConst.g_HeightScale;
	cDCB.g_TerrainZScale = terrainShadingConst.g_TerrSize;
	cDCB.g_ClipPlane = terrainShadingConst.g_ClipPlane;
	cDCB.g_tpadding = XMFLOAT3(0, 0, 0);
	cDCB.g_FarPlane = terrainShadingConst.g_FarPlane;

	cSCB.g_EyePosW = terrainShadingConst.g_EyePosW;
	cSCB.g_DetailBrightness = terrainShadingConst.g_DetailBrightness;
	cSCB.g_fogThinning = terrainShadingConst.g_fogThinning;
	cSCB.g_fogAltitude = terrainShadingConst.g_fogAltitude;
	cSCB.g_fogNear = terrainShadingConst.g_fogNear;
	cSCB.g_fogFar = terrainShadingConst.g_fogFar;
	cSCB.g_fogColor = terrainShadingConst.g_fogColor;
	cSCB.g_TextureAmount = terrainShadingConst.g_TextureAmount;
	cSCB.g_TextureWidth = terrainShadingConst.g_TextureWidth;
	cSCB.g_TextureHeight = terrainShadingConst.g_TextureHeight;
	cSCB.g_seaLevel = terrainShadingConst.g_seaLevel;
	cSCB.g_waterBodyColor = terrainShadingConst.g_waterBodyColor;
	//cSCB.g_SunDir = terrainShadingConst.g_SunDir;
	//cSCB.g_EnableSun = terrainShadingConst.g_EnableSun;
	//cSCB.g_SunDiffuseColor = terrainShadingConst.g_SunDiffuseColor;
	cSCB.g_MaterialDiffuseColor = terrainShadingConst.g_MaterialDiffuseColor;
	cSCB.g_MaterialAmbientColor = terrainShadingConst.g_MaterialAmbientColor;
	cSCB.g_TexelCellSpaceU = terrainShadingConst.g_TexelCellSpaceU;
	cSCB.g_TexelCellSpaceV = terrainShadingConst.g_TexelCellSpaceV;
	cSCB.g_MaterialSpecularPower = terrainShadingConst.g_MaterialSpecularPower;
	cSCB.g_MaterialSpecularIntensity = terrainShadingConst.g_MaterialSpecularIntensity;
	cSCB.g_useClippingPlane = terrainShadingConst.g_useClippingPlane;
	cSCB.g_useNormalMap = terrainShadingConst.g_useNormalMap;
	cSCB.g_UseSobelFilter = terrainShadingConst.g_UseSobelFilter;
	cSCB.g_useShadowMap = terrainShadingConst.g_useShadowMap;
	cSCB.tpadding = XMFLOAT3(0, 0, 0);
	cSCB.g_useSSAO = terrainShadingConst.g_useSSAO;
	cSCB.g_ViewMatrix = cMB.g_ViewMatrix;

	ZShadeSandboxLighting::LightManager::Instance()->BuildFinalLightBuffers(m_pLightCB, m_pSunCB);

	// Map tessellation constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pTessellationCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(cTessellationBuffer*)mapped_res.pData = cTB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pTessellationCB, 0);
	}

	// Map domain shader constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pDomainCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(cDomainConstBuffer*)mapped_res.pData = cDCB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pDomainCB, 0);
	}

	// Map matrix constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pMatrixBufferCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(cMatrixBuffer*)mapped_res.pData = cMB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pMatrixBufferCB, 0);
	}

	// Map pixel shading constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pShadingCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(cShadingConstBuffer*)mapped_res.pData = cSCB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pShadingCB, 0);
	}

	// Set the tessellation constant buffer into the Hull ZShadeSandboxShader::Shader
	ID3D11Buffer* hs_cbs[1] = { m_pTessellationCB };
	m_pD3DSystem->GetDeviceContext()->HSSetConstantBuffers(0, 1, hs_cbs);

	// Set the domain constant buffer into the Domain ZShadeSandboxShader::Shader
	// Set the matrix constant buffer into the Domain ZShadeSandboxShader::Shader
	ID3D11Buffer* ds_cbs[2] = { m_pDomainCB, m_pMatrixBufferCB };
	m_pD3DSystem->GetDeviceContext()->DSSetConstantBuffers(0, 2, ds_cbs);

	// Set the shading constant buffer into the Pixel ZShadeSandboxShader::Shader
	ID3D11Buffer* ps_cbs[3] = { m_pShadingCB, m_pLightCB, m_pSunCB };
	m_pD3DSystem->GetDeviceContext()->PSSetConstantBuffers(0, 3, ps_cbs);

	// Set the heightmap texture into the vertex shader
	ID3D11ShaderResourceView* vs_srvs[1] = { heightMapSRV };
	m_pD3DSystem->GetDeviceContext()->VSSetShaderResources(0, 1, vs_srvs);

	// Set the heightmap texture into the domain shader
	ID3D11ShaderResourceView* ds_srvs[1] = { heightMapSRV };
	m_pD3DSystem->GetDeviceContext()->DSSetShaderResources(0, 1, ds_srvs);

	// Set the textures into the Pixel Shader
	ID3D11ShaderResourceView* ps_srvs[1] = { heightMapSRV };
	m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 1, ps_srvs);

	// Tell the shader what input layout to use
	SetInputLayout("TerrainTessellationQuadSSAOShader");

	// Assign the shaders to render the mesh
	SetVertexShader();
	SetHullShader();
	SetDomainShader();
	SetPixelShader();

	//Perform Drawing
	RenderIndex11(indexCount);

	return true;
}
//==============================================================================================================================
bool OBJMeshShader::Render(int startIndex, int indexCount, Camera* camera, XMMATRIX wvp, XMFLOAT4 clipplane, XMFLOAT4 difColor, bool hasTexture,
	ID3D11ShaderResourceView* texture)
{
	cbOBJShadingConst cSC;
	cbMatrixBuffer cMB;
	
	cMB.g_WVPMatrix = ZShadeSandboxMath::ZMath::GMathMF(XMMatrixTranspose(wvp));
	
	//if (m_UseCustomWorld)
	//	cMB.g_WorldMatrix = ZShadeSandboxMath::ZMath::GMathMF(XMMatrixTranspose(mWorld.Get()));
	//else
	//	cMB.g_WorldMatrix = camera->World4x4();
	
	cSC.g_ClipPlane = clipplane;
	cSC.g_DifColor = difColor;
	cSC.padding = XMFLOAT2(0, 0);
	cSC.g_FarPlane = fFarPlane;
	cSC.g_hasTexture = (hasTexture == true) ? 1 : 0;
	
	// Map shading constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pOBJShadingCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(cbOBJShadingConst*)mapped_res.pData = cSC;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pOBJShadingCB, 0);
	}
	
	// Map matrix constants
	{
		D3D11_MAPPED_SUBRESOURCE mapped_res;
		m_pD3DSystem->GetDeviceContext()->Map(m_pMatrixBufferCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_res);
		{
			assert(mapped_res.pData);
			*(cbMatrixBuffer*)mapped_res.pData = cMB;
		}
		m_pD3DSystem->GetDeviceContext()->Unmap(m_pMatrixBufferCB, 0);
	}
	
	// Set the shading constant buffer and matrix constant buffer into the Vertex ZShadeSandboxShader::Shader
	ID3D11Buffer* vs_cbs[2] = { m_pOBJShadingCB, m_pMatrixBufferCB };
	m_pD3DSystem->GetDeviceContext()->VSSetConstantBuffers(0, 2, vs_cbs);
	
	// Set the shading constant buffer into the Pixel Shader
	ID3D11Buffer* ps_cbs[1] = { m_pOBJShadingCB };
	m_pD3DSystem->GetDeviceContext()->PSSetConstantBuffers(0, 1, ps_cbs);
	
	ID3D11ShaderResourceView* ps_srvs[1] = { texture };
	ID3D11SamplerState* ps_samp[1] = { m_pD3DSystem->Linear() };
	
	if (!m_Wireframe)
	{
		m_pD3DSystem->TurnOffCulling();

		// Set the texture into the Pixel Shader
		if (hasTexture)
		{
			m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 1, ps_srvs);
			m_pD3DSystem->GetDeviceContext()->PSSetSamplers(0, 1, ps_samp);
		}

		SwitchTo("OBJMeshPS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
	}
	else
	{
		SwitchTo("OBJMeshWireframePS", ZShadeSandboxShader::EShaderTypes::ST_PIXEL);
	}

	// Tell the shader what input layout to use
	SetInputLayout("OBJMeshShader");
	
	// Assign the shaders to render the mesh
	SetVertexShader();
	SetPixelShader();
	
	//Perform Drawing
	RenderIndex11(startIndex, indexCount);

	if (!m_Wireframe)
	{
		m_pD3DSystem->TurnOnCulling();
	}

	// Unbind
	if (!m_Wireframe && hasTexture)
	{
		ps_samp[0] = NULL;
		m_pD3DSystem->GetDeviceContext()->PSSetSamplers(0, 1, ps_samp);

		ps_srvs[0] = NULL;
		m_pD3DSystem->GetDeviceContext()->PSSetShaderResources(0, 1, ps_srvs);
	}
	
	return true;
}