// Create point to quad geometry shader
HRESULT CFW1GlyphRenderStates::createGlyphShaders() {
	if(m_featureLevel < D3D_FEATURE_LEVEL_10_0)
		return E_FAIL;
	
	// Geometry shader constructing glyphs from point input and texture buffer
	const char gsSimpleStr[] =
	"cbuffer ShaderConstants : register(b0) {\r\n"
	"	float4x4 TransformMatrix : packoffset(c0);\r\n"
	"};\r\n"
	"\r\n"
	"Buffer<float4> tex0 : register(t0);\r\n"
	"\r\n"
	"struct GSIn {\r\n"
	"	float3 PositionIndex : POSITIONINDEX;\r\n"
	"	float4 GlyphColor : GLYPHCOLOR;\r\n"
	"};\r\n"
	"\r\n"
	"struct GSOut {\r\n"
	"	float4 Position : SV_Position;\r\n"
	"	float4 GlyphColor : COLOR;\r\n"
	"	float2 TexCoord : TEXCOORD;\r\n"
	"};\r\n"
	"\r\n"
	"[maxvertexcount(4)]\r\n"
	"void GS(point GSIn Input[1], inout TriangleStream<GSOut> TriStream) {\r\n"
	"	const float2 basePosition = Input[0].PositionIndex.xy;\r\n"
	"	const uint glyphIndex = asuint(Input[0].PositionIndex.z);\r\n"
	"	\r\n"
	"	float4 texCoords = tex0.Load(uint2(glyphIndex*2, 0));\r\n"
	"	float4 offsets = tex0.Load(uint2(glyphIndex*2+1, 0));\r\n"
	"	\r\n"
	"	GSOut Output;\r\n"
	"	Output.GlyphColor = Input[0].GlyphColor;\r\n"
	"	\r\n"
	"	float4 positions = basePosition.xyxy + offsets;\r\n"
	"	\r\n"
	"	Output.Position = mul(TransformMatrix, float4(positions.xy, 0.0f, 1.0f));\r\n"
	"	Output.TexCoord = texCoords.xy;\r\n"
	"	TriStream.Append(Output);\r\n"
	"	\r\n"
	"	Output.Position = mul(TransformMatrix, float4(positions.zy, 0.0f, 1.0f));\r\n"
	"	Output.TexCoord = texCoords.zy;\r\n"
	"	TriStream.Append(Output);\r\n"
	"	\r\n"
	"	Output.Position = mul(TransformMatrix, float4(positions.xw, 0.0f, 1.0f));\r\n"
	"	Output.TexCoord = texCoords.xw;\r\n"
	"	TriStream.Append(Output);\r\n"
	"	\r\n"
	"	Output.Position = mul(TransformMatrix, float4(positions.zw, 0.0f, 1.0f));\r\n"
	"	Output.TexCoord = texCoords.zw;\r\n"
	"	TriStream.Append(Output);\r\n"
	"	\r\n"
	"	TriStream.RestartStrip();\r\n"
	"}\r\n"
	"";
	
	// Geometry shader with rect clipping
	const char gsClipStr[] =
	"cbuffer ShaderConstants : register(b0) {\r\n"
	"	float4x4 TransformMatrix : packoffset(c0);\r\n"
	"	float4 ClipRect : packoffset(c4);\r\n"
	"};\r\n"
	"\r\n"
	"Buffer<float4> tex0 : register(t0);\r\n"
	"\r\n"
	"struct GSIn {\r\n"
	"	float3 PositionIndex : POSITIONINDEX;\r\n"
	"	float4 GlyphColor : GLYPHCOLOR;\r\n"
	"};\r\n"
	"\r\n"
	"struct GSOut {\r\n"
	"	float4 Position : SV_Position;\r\n"
	"	float4 GlyphColor : COLOR;\r\n"
	"	float2 TexCoord : TEXCOORD;\r\n"
	"	float4 ClipDistance : SV_ClipDistance;\r\n"
	"};\r\n"
	"\r\n"
	"[maxvertexcount(4)]\r\n"
	"void GS(point GSIn Input[1], inout TriangleStream<GSOut> TriStream) {\r\n"
	"	const float2 basePosition = Input[0].PositionIndex.xy;\r\n"
	"	const uint glyphIndex = asuint(Input[0].PositionIndex.z);\r\n"
	"	\r\n"
	"	float4 texCoords = tex0.Load(uint2(glyphIndex*2, 0));\r\n"
	"	float4 offsets = tex0.Load(uint2(glyphIndex*2+1, 0));\r\n"
	"	\r\n"
	"	GSOut Output;\r\n"
	"	Output.GlyphColor = Input[0].GlyphColor;\r\n"
	"	\r\n"
	"	float4 positions = basePosition.xyxy + offsets;\r\n"
	"	\r\n"
	"	Output.Position = mul(TransformMatrix, float4(positions.xy, 0.0f, 1.0f));\r\n"
	"	Output.TexCoord = texCoords.xy;\r\n"
	"	Output.ClipDistance = ClipRect + float4(positions.xy, -positions.xy);\r\n"
	"	TriStream.Append(Output);\r\n"
	"	\r\n"
	"	Output.Position = mul(TransformMatrix, float4(positions.zy, 0.0f, 1.0f));\r\n"
	"	Output.TexCoord = texCoords.zy;\r\n"
	"	Output.ClipDistance = ClipRect + float4(positions.zy, -positions.zy);\r\n"
	"	TriStream.Append(Output);\r\n"
	"	\r\n"
	"	Output.Position = mul(TransformMatrix, float4(positions.xw, 0.0f, 1.0f));\r\n"
	"	Output.TexCoord = texCoords.xw;\r\n"
	"	Output.ClipDistance = ClipRect + float4(positions.xw, -positions.xw);\r\n"
	"	TriStream.Append(Output);\r\n"
	"	\r\n"
	"	Output.Position = mul(TransformMatrix, float4(positions.zw, 0.0f, 1.0f));\r\n"
	"	Output.TexCoord = texCoords.zw;\r\n"
	"	Output.ClipDistance = ClipRect + float4(positions.zw, -positions.zw);\r\n"
	"	TriStream.Append(Output);\r\n"
	"	\r\n"
	"	TriStream.RestartStrip();\r\n"
	"}\r\n"
	"";
	
	// Vertex shader
	const char vsEmptyStr[] =
	"struct GSIn {\r\n"
	"	float3 PositionIndex : POSITIONINDEX;\r\n"
	"	float4 GlyphColor : GLYPHCOLOR;\r\n"
	"};\r\n"
	"\r\n"
	"GSIn VS(GSIn Input) {\r\n"
	"	return Input;\r\n"
	"}\r\n"
	"";
	
	// Shader compile profiles
	const char *vs_profile = "vs_4_0";
	const char *gs_profile = "gs_4_0";
	if(m_featureLevel >= D3D_FEATURE_LEVEL_11_0) {
		vs_profile = "vs_5_0";
		gs_profile = "gs_5_0";
	}
	
	// Compile geometry shader
	ID3DBlob *pGSCode;
	
	HRESULT hResult = m_pfnD3DCompile(
		gsSimpleStr,
		sizeof(gsSimpleStr),
		NULL,
		NULL,
		NULL,
		"GS",
		gs_profile,
		D3DCOMPILE_OPTIMIZATION_LEVEL3,
		0,
		&pGSCode,
		NULL
	);
	if(FAILED(hResult)) {
		m_lastError = L"Failed to compile geometry shader";
	}
	else {
		// Create geometry shader
		ID3D11GeometryShader *pGS;
		
		hResult = m_pDevice->CreateGeometryShader(pGSCode->GetBufferPointer(), pGSCode->GetBufferSize(), NULL, &pGS);
		if(FAILED(hResult)) {
			m_lastError = L"Failed to create geometry shader";
		}
		else {
			// Compile clipping geometry shader
			ID3DBlob *pGSClipCode;
			
			hResult = m_pfnD3DCompile(
				gsClipStr,
				sizeof(gsClipStr),
				NULL,
				NULL,
				NULL,
				"GS",
				gs_profile,
				D3DCOMPILE_OPTIMIZATION_LEVEL3,
				0,
				&pGSClipCode,
				NULL
			);
			if(FAILED(hResult)) {
				m_lastError = L"Failed to compile clipping geometry shader";
			}
			else {
				// Create clipping geometry shader
				ID3D11GeometryShader *pGSClip;
				
				hResult = m_pDevice->CreateGeometryShader(
					pGSClipCode->GetBufferPointer(),
					pGSClipCode->GetBufferSize(),
					NULL,
					&pGSClip
				);
				if(FAILED(hResult)) {
					m_lastError = L"Failed to create clipping geometry shader";
				}
				else {
					ID3DBlob *pVSEmptyCode;
					
					// Compile vertex shader
					hResult = m_pfnD3DCompile(
						vsEmptyStr,
						sizeof(vsEmptyStr),
						NULL,
						NULL,
						NULL,
						"VS",
						vs_profile,
						D3DCOMPILE_OPTIMIZATION_LEVEL3,
						0,
						&pVSEmptyCode,
						NULL
					);
					if(FAILED(hResult)) {
						m_lastError = L"Failed to compile empty vertex shader";
					}
					else {
						// Create vertex shader
						ID3D11VertexShader *pVSEmpty;
						
						hResult = m_pDevice->CreateVertexShader(
							pVSEmptyCode->GetBufferPointer(),
							pVSEmptyCode->GetBufferSize(),
							NULL,
							&pVSEmpty
						);
						if(FAILED(hResult)) {
							m_lastError = L"Failed to create empty vertex shader";
						}
						else {
							ID3D11InputLayout *pInputLayout;
							
							// Input layout for geometry shader
							D3D11_INPUT_ELEMENT_DESC inputElements[] = {
								{"POSITIONINDEX", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
								{"GLYPHCOLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}
							};
							
							hResult = m_pDevice->CreateInputLayout(
								inputElements,
								2,
								pVSEmptyCode->GetBufferPointer(),
								pVSEmptyCode->GetBufferSize(),
								&pInputLayout
							);
							if(FAILED(hResult)) {
								m_lastError = L"Failed to create input layout for geometry shader";
							}
							else {
								// Success
								m_pVertexShaderPoint = pVSEmpty;
								m_pGeometryShaderPoint = pGS;
								m_pGeometryShaderClipPoint = pGSClip;
								m_pPointInputLayout = pInputLayout;
								m_hasGeometryShader = true;
								
								hResult = S_OK;
							}
							
							if(FAILED(hResult))
								pVSEmpty->Release();
						}
						
						pVSEmptyCode->Release();
					}
					
					if(FAILED(hResult))
						pGSClip->Release();
				}
				
				pGSClipCode->Release();
			}
			
			if(FAILED(hResult))
				pGS->Release();
		}
		
		pGSCode->Release();
	}
	
	return hResult;
}
//=================================================================================================================
HRESULT ShaderCompiler::Compile(D3D* d3d, BetterString filename, BetterString shaderFuncName, int type, BetterString macroName, bool loadPrecompiledShader)
{
	// Compiling Shaders with D3DCompileFromFile
	//Google: visual studio 2013 hlsl shader compiling
	//http://msdn.microsoft.com/en-us/library/windows/desktop/hh968107(v=vs.85).aspx
	//http://stackoverflow.com/questions/10759300/how-do-i-use-shader-model-5-0-compiled-shaders-in-visual-studio-11
	/*
		Here "PixelShader.cso" is the precompiled hlsl shader generated by Visual Studio 11 from a .hlsl file in the project.
		The compiled .cso file is usually moved to the Projects/ProjectName/Debug folder by default.
		As a result it must be cut and paste into the same directory as your source code before using.
		Mind you this setting can be changed by right-clicking the HLSL file while inside Visual Studio 11 and
		editing the Output Settings. By default its: $(OutDir)%(Filename).cso, change it to: $(Directory)%(Filename).cso
	*/
	
	//Google: creating a cso file in DirectX11.1
	//http://stackoverflow.com/questions/5020204/loading-a-precompiled-hlsl-shader-into-memory-for-use-with-createpixelshader
	
	BetterString base = "..\\Framework\\Shaders\\";
	filename = base + filename;

	unique_ptr<wchar_t> name = filename.ToWideStr();

	HRESULT hr;
	ID3DBlob* blob = nullptr;
	ID3DBlob* errorBlob = nullptr;
	
    UINT flags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    flags |= D3DCOMPILE_DEBUG;
#endif

	ShaderMacros* macros = 0;
	map<string, ShaderMacros*>::iterator it = m_ShaderMacros.find(macroName);
	if (it != m_ShaderMacros.end())
		macros = (*it).second;

	switch (type)
	{
		case EShaderTypes::ST_VERTEX:
		{
			VertexShader* vs = new VertexShader();
			LPCSTR profile = "vs_5_0";
			
			blob = Compile(name.get(), shaderFuncName, profile, flags, errorBlob, macros, loadPrecompiledShader);
			if (blob == nullptr)
			{
				OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename);
				exit(0);
			}
			
			hr = d3d->GetDevice11()->CreateVertexShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &vs->mShader);
			if( FAILED(hr) )
			{
				OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename);
				exit(0);
			}
			
			vs->mBlobData = blob;
			vs->mName = shaderFuncName;
			
#if defined(DEBUG) || defined(PROFILE)
			if ( SUCCEEDED(hr) )
			{
				vs->mShader->SetPrivateData( WKPDID_D3DDebugObjectName, lstrlenA(shaderFuncName), shaderFuncName );
			}
#endif
			//Add the vertex shader to the list of shaders
			m_Shaders.push_back(vs);
		}
		break;
		case EShaderTypes::ST_HULL:
		{
			HullShader* hs = new HullShader();
			LPCSTR profile = "hs_5_0";
			
			blob = Compile(name.get(), shaderFuncName, profile, flags, errorBlob, macros, loadPrecompiledShader);
			if (blob == nullptr)
			{
				OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename);
				exit(0);
			}
			
			hr = d3d->GetDevice11()->CreateHullShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &hs->mShader);
			if (FAILED(hr))
			{
				OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename);
				exit(0);
			}
			
			hs->mBlobData = blob;
			hs->mName = shaderFuncName;
			
#if defined(DEBUG) || defined(PROFILE)
			if (SUCCEEDED(hr))
			{
				hs->mShader->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(shaderFuncName), shaderFuncName);
			}
#endif
			
			//Add the hull shader to the list of shaders
			m_Shaders.push_back(hs);
		}
		break;
		case EShaderTypes::ST_DOMAIN:
		{
			DomainShader* ds = new DomainShader();
			LPCSTR profile = "ds_5_0";
			
			blob = Compile(name.get(), shaderFuncName, profile, flags, errorBlob, macros, loadPrecompiledShader);
			if (blob == nullptr)
			{
				OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename);
				exit(0);
			}
			
			hr = d3d->GetDevice11()->CreateDomainShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &ds->mShader);
			if (FAILED(hr))
			{
				OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename);
				exit(0);
			}
			
			ds->mBlobData = blob;
			ds->mName = shaderFuncName;
			
#if defined(DEBUG) || defined(PROFILE)
			if (SUCCEEDED(hr))
			{
				ds->mShader->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(shaderFuncName), shaderFuncName);
			}
#endif
			
			//Add the domain shader to the list of shaders
			m_Shaders.push_back(ds);
		}
		break;
		case EShaderTypes::ST_PIXEL:
		{
			PixelShader* ps = new PixelShader();
			LPCSTR profile = "ps_5_0";
			
			blob = Compile(name.get(), shaderFuncName, profile, flags, errorBlob, macros, loadPrecompiledShader);
			if (blob == nullptr)
			{
				OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename);
				exit(0);
			}

			hr = d3d->GetDevice11()->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &ps->mShader);
			if (FAILED(hr))
			{
				OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename);
				exit(0);
			}

			ps->mBlobData = blob;
			ps->mName = shaderFuncName;

#if defined(DEBUG) || defined(PROFILE)
			if (SUCCEEDED(hr))
			{
				ps->mShader->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(shaderFuncName), shaderFuncName);
			}
#endif
			
			//Add the pixel shader to the list of shaders
			m_Shaders.push_back(ps);
		}
		break;
		case EShaderTypes::ST_GEOMETRY:
		{
			GeometryShader* gs = new GeometryShader();
			LPCSTR profile = "gs_5_0";
			
			blob = Compile(name.get(), shaderFuncName, profile, flags, errorBlob, macros, loadPrecompiledShader);
			if (blob == nullptr)
			{
				OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename);
				exit(0);
			}

			hr = d3d->GetDevice11()->CreateGeometryShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &gs->mShader);
			if (FAILED(hr))
			{
				OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename);
				exit(0);
			}

			gs->mBlobData = blob;
			gs->mName = shaderFuncName;

#if defined(DEBUG) || defined(PROFILE)
			if (SUCCEEDED(hr))
			{
				gs->mShader->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(shaderFuncName), shaderFuncName);
			}
#endif
			
			//Add the geometry shader to the list of shaders
			m_Shaders.push_back(gs);
		}
		break;
		case EShaderTypes::ST_COMPUTE:
		{
			ComputeShader* cs = new ComputeShader();
			LPCSTR profile = "cs_5_0";
			
			blob = Compile(name.get(), shaderFuncName, profile, flags, errorBlob, macros, loadPrecompiledShader);
			if (blob == nullptr)
			{
				OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename);
				exit(0);
			}

			hr = d3d->GetDevice11()->CreateComputeShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &cs->mShader);
			if (FAILED(hr))
			{
				OutputShaderErrorMessage(errorBlob, NULL, shaderFuncName, filename);
				exit(0);
			}

			cs->mBlobData = blob;
			cs->mName = shaderFuncName;

#if defined(DEBUG) || defined(PROFILE)
			if (SUCCEEDED(hr))
			{
				cs->mShader->SetPrivateData(WKPDID_D3DDebugObjectName, lstrlenA(shaderFuncName), shaderFuncName);
			}
#endif
			
			//Add the compute shader to the list of shaders
			m_Shaders.push_back(cs);
		}
		break;
		default:
		{
			ZShadeMessageCenter::MsgBoxError(NULL, "ShaderCompiler: ZShadeSandboxShader::Shader type not defined !!!");
			exit(0);
		}
		break;
	}
	
	return S_OK;
}
//
// Load unique Content.
//
bool DirectXClass::LoadContent()
{
	HRESULT hr = S_OK;
	
	//
	// Create the shared vertex buffer
	//
	D3D11_BUFFER_DESC sbd;
	ZeroMemory(&sbd, sizeof(D3D11_BUFFER_DESC));

	sbd.Usage = D3D11_USAGE_DEFAULT;
	sbd.ByteWidth = sizeof(TerrainVertex) * TOTAL_GRID_POINTS;
	sbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	sbd.CPUAccessFlags =  0;
	sbd.MiscFlags = 0;

	hr = m_3dDevice->CreateBuffer(&sbd, NULL, &m_VertexBuffer); //Empty buffer, no data
	if (FAILED(hr))
		return false;
	
	//
	// Create the shared index buffer.
	//
	D3D11_BUFFER_DESC indexBufferDesc;
	ZeroMemory(&indexBufferDesc, sizeof(D3D11_BUFFER_DESC));
	
	indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
	indexBufferDesc.ByteWidth = sizeof(int) * NUM_INDICES;
	indexBufferDesc.CPUAccessFlags = 0;
	indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
	
	hr = m_3dDevice->CreateBuffer(&indexBufferDesc, NULL, &m_IndexBuffer); //Empty buffer, no data
	if (FAILED(hr))
		return false;

	//
	// Create Constant buffers
	//
	D3D11_BUFFER_DESC constantBufferDesc;
	ZeroMemory(&constantBufferDesc, sizeof(D3D11_BUFFER_DESC));

	constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	constantBufferDesc.ByteWidth = sizeof(XMMATRIX);
	constantBufferDesc.CPUAccessFlags = 0;
	constantBufferDesc.Usage = D3D11_USAGE_DEFAULT;

	hr = m_3dDevice->CreateBuffer(&constantBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Application]);
	if (FAILED(hr))
		return false;

	hr = m_3dDevice->CreateBuffer(&constantBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Frame]);
	if (FAILED(hr))
		return false;

	hr = m_3dDevice->CreateBuffer(&constantBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Object]);
	if (FAILED(hr))
		return false;

	//
	// Load the compiled vertex shader.
	//
	ID3DBlob* vertexShaderBlob;
#if _DEBUG
	LPCWSTR compiledVertexShaderObject = L"VertexShader_d.cso";
#else
	LPCWSTR compiledVertexShaderObject = L"VertexShader.cso";
#endif

	hr = D3DReadFileToBlob(compiledVertexShaderObject, &vertexShaderBlob);
	if (FAILED(hr))
		return false;

	hr = m_3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &m_VertexShader);
	if (FAILED(hr))
		return false;

	//
	// Create the input layout for the vertex shader.
	//
	D3D11_INPUT_ELEMENT_DESC vertexLayoutDesc[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(TerrainVertex, Position), D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(TerrainVertex, Normal),D3D11_INPUT_PER_VERTEX_DATA, 0 }
	};

	hr = m_3dDevice->CreateInputLayout(vertexLayoutDesc, _countof(vertexLayoutDesc), vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &m_InputLayout);
	if (FAILED(hr))
		return false;

	vertexShaderBlob->Release();

	//
	// Load the compiled pixel shader.
	//
	ID3DBlob* pixelShaderBlob;
#if _DEBUG
	LPCWSTR compiledPixelShaderObject = L"PixelShader_d.cso";
#else
	LPCWSTR compiledPixelShaderObject = L"PixelShader.cso";
#endif

	hr = D3DReadFileToBlob(compiledPixelShaderObject, &pixelShaderBlob);
	if (FAILED(hr))
		return false;

	hr = m_3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &m_PixelShader);
	if (FAILED(hr))
		return false;

	pixelShaderBlob->Release();

	//
	// Setup the projection matrix.
	//
	RECT clientRect;
	GetClientRect(m_windowHandel, &clientRect);

	// Compute the exact client dimensions.
	// This is required for a correct projection matrix.
	float clientWidth = static_cast<float>(clientRect.right - clientRect.left);
	float clientHeight = static_cast<float>(clientRect.bottom - clientRect.top);

	m_ProjectionMatrix = XMMatrixPerspectiveFovLH(XMConvertToRadians(45.0f), clientWidth / clientHeight, 0.1f, 150.0f);
	
	m_3dDeviceContext->UpdateSubresource(g_d3dConstantBuffers[CB_Application], 0, nullptr, &m_ProjectionMatrix, 0, 0);

	return true;
}
// Load and register all the resources needed by the GUI system
//-----------------------------------------------------------------------------
CPUTResult CPUTGuiControllerDX11::RegisterGUIResources(ID3D11DeviceContext *pImmediateContext, cString VertexShaderFilename, cString PixelShaderFilename, cString RenderStateFile, cString DefaultFontFilename, cString ControlAtlasTexture)
{
    if(NULL==pImmediateContext)
    {
        return CPUT_ERROR_INVALID_PARAMETER;
    }
    CPUTResult result;
    HRESULT hr;
    ID3D11Device *pD3dDevice = NULL;
    CPUTOSServices *pServices = NULL;
    CPUTAssetLibraryDX11 *pAssetLibrary = NULL;
    cString ErrorMessage;

    // Get the services/resource pointers we need
    pServices = CPUTOSServices::GetOSServices();
    pImmediateContext->GetDevice(&pD3dDevice);
    pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibraryDX11::GetAssetLibrary();

    // Get the resource directory
    cString ResourceDirectory;
    CPUTGuiControllerDX11::GetController()->GetResourceDirectory(ResourceDirectory);

    // 1. Load the renderstate configuration for the GUI system
    mpGUIRenderStateBlock = (CPUTRenderStateBlockDX11*) pAssetLibrary->GetRenderStateBlock(ResourceDirectory+RenderStateFile); 
    ASSERT(mpGUIRenderStateBlock, _L("Error loading the render state file (.rs) needed for the CPUT GUI system"));
    

    // 2. Store the shader path from AssetLibrary, change it to OUR resource directory
    cString OriginalAssetLibraryDirectory = pAssetLibrary->GetShaderDirectory();
    pAssetLibrary->SetShaderDirectoryName(ResourceDirectory);
    

    // 3. load the shaders for gui drawing
    // Load the GUI Vertex Shader
    cString FullPath, FinalPath;
    FullPath = mResourceDirectory + VertexShaderFilename;
    pServices->ResolveAbsolutePathAndFilename(FullPath, &FinalPath);
    result = pAssetLibrary->GetVertexShader(FinalPath, pD3dDevice, _L("VS"), _L("vs_4_0"), &mpGUIVertexShader, true);
    CPUTSetDebugName( mpGUIVertexShader->GetNativeVertexShader(), _L("GUIVertexShader"));
    if(CPUTFAILED(result))
    {
        ASSERT(CPUTSUCCESS(result), _L("Error loading the vertex shader needed for the CPUT GUI system."));
    }
    ID3DBlob *pVertexShaderBlob = mpGUIVertexShader->GetBlob();

    // Load the GUI Pixel Shader
    FullPath = mResourceDirectory + PixelShaderFilename;
    pServices->ResolveAbsolutePathAndFilename(FullPath, &FinalPath);
    result = pAssetLibrary->GetPixelShader(FinalPath, pD3dDevice, _L("PS"), _L("ps_4_0"), &mpGUIPixelShader, true);
    CPUTSetDebugName( mpGUIPixelShader->GetNativePixelShader(), _L("GUIPixelShader"));
    if(CPUTFAILED(result))
    {
        ASSERT(CPUTSUCCESS(result), _L("Error loading the pixel shader needed for the CPUT GUI system."));
    }

    // Restore the previous shader directory
    pAssetLibrary->SetShaderDirectoryName(OriginalAssetLibraryDirectory);
    

    // 4. Create the vertex layout description for all the GUI controls we'll draw
    // set vertex shader as active so we can configure it
    ID3D11VertexShader *pVertexShader = mpGUIVertexShader->GetNativeVertexShader();
    pImmediateContext->VSSetShader( pVertexShader, NULL, 0 );

    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },		
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = ARRAYSIZE( layout );

    // Create the input layout
    hr = pD3dDevice->CreateInputLayout( layout, numElements, pVertexShaderBlob->GetBufferPointer(), pVertexShaderBlob->GetBufferSize(), &mpVertexLayout );
    ASSERT( SUCCEEDED(hr), _L("Error creating CPUT GUI system input layout" ));
    CPUTSetDebugName( mpVertexLayout, _L("CPUT GUI InputLayout object"));
    

    // 5. create the vertex shader constant buffer pointers
    D3D11_BUFFER_DESC bd;
    ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof(GUIConstantBufferVS);
    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    bd.CPUAccessFlags = 0;
    hr = pD3dDevice->CreateBuffer( &bd, NULL, &mpConstantBufferVS );
    ASSERT( SUCCEEDED(hr), _L("Error creating constant buffer VS" ));
    CPUTSetDebugName( mpConstantBufferVS, _L("GUI ConstantBuffer"));
      
    // Set the texture directory for loading the control texture atlas
    pAssetLibrary->SetTextureDirectoryName(ResourceDirectory);

    // load the control atlas
    mpControlTextureAtlas = (CPUTTextureDX11*) pAssetLibrary->GetTexture(ControlAtlasTexture); 
    if(NULL==mpControlTextureAtlas)
    {
        return CPUT_TEXTURE_LOAD_ERROR;
    }
    mpControlTextureAtlasView = mpControlTextureAtlas->GetShaderResourceView();
    mpControlTextureAtlasView->AddRef();

    // restore the asset library's texture directory    
    pAssetLibrary->SetTextureDirectoryName(OriginalAssetLibraryDirectory);
    

    // 6. Load the font atlas
    // store the existing asset library font directory
    OriginalAssetLibraryDirectory = pAssetLibrary->GetFontDirectory(); 

    // set font directory to the resource directory
    pAssetLibrary->SetFontDirectoryName(ResourceDirectory);
    mpFont = (CPUTFontDX11*) pAssetLibrary->GetFont(DefaultFontFilename); 
    if(NULL==mpFont)
    {
        return CPUT_TEXTURE_LOAD_ERROR;
    }
    mpTextTextureAtlas = mpFont->GetAtlasTexture();
    mpTextTextureAtlas->AddRef();
    mpTextTextureAtlasView = mpFont->GetAtlasTextureResourceView();
    mpTextTextureAtlasView->AddRef();    

    // restore the asset library's font directory    
    pAssetLibrary->SetTextureDirectoryName(OriginalAssetLibraryDirectory);
    
    
    // 7. Set up the DirectX uber-buffers that the controls draw into
    int maxSize = max(CPUT_GUI_BUFFER_STRING_SIZE, CPUT_GUI_BUFFER_SIZE);
    maxSize = max(maxSize, CPUT_GUI_VERTEX_BUFFER_SIZE);    
    maxSize *= sizeof( CPUTGUIVertex );
    char *pZeroedBuffer= new char[maxSize];
    memset(pZeroedBuffer, 0, maxSize);

    // set up buffer description
    ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_VERTEX_BUFFER_SIZE; //mUberBufferIndex;
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    // initialization data (all 0's for now)
    D3D11_SUBRESOURCE_DATA InitData;
    ZeroMemory( &InitData, sizeof(InitData) );
    InitData.pSysMem = mpMirrorBuffer;

    // mpUberBuffer
    SAFE_RELEASE(mpUberBuffer);
    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpUberBuffer );
    ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure"));
    CPUTSetDebugName(mpUberBuffer, _L("CPUT GUI: Control's main vertex buffer"));


    // mpTextUberBuffer
    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_BUFFER_STRING_SIZE;
    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpTextUberBuffer );
    ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure"));
    CPUTSetDebugName(mpTextUberBuffer, _L("CPUT GUI: control text vertex buffer"));


    // mpFocusedControlBuffer
    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_VERTEX_BUFFER_SIZE;
    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpFocusedControlBuffer );
    ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure"));
    CPUTSetDebugName(mpFocusedControlBuffer, _L("CPUT GUI: focused control images vertex buffer"));

    
    // mpFocusedControlTextBuffer
    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_BUFFER_STRING_SIZE; //mFocusedControlTextBufferIndex;
    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpFocusedControlTextBuffer );
    ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure"));
    CPUTSetDebugName(mpFocusedControlTextBuffer, _L("CPUT GUI: focused control text vertex buffer"));

    // mpFPSDirectXBuffer
    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_BUFFER_STRING_SIZE;
    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpFPSDirectXBuffer );
    ASSERT( !FAILED( hr ), _L("CPUT GUI FPS counter buffer creation failure"));
    CPUTSetDebugName(mpFPSDirectXBuffer, _L("CPUT GUI: FPS display text"));
    
    // no longer need the device - release it.
    SAFE_RELEASE(pD3dDevice);
    SAFE_DELETE_ARRAY(pZeroedBuffer);    


    // 8. Register all GUI sub-resources
    // Walk all the controls/fonts and have them register all their required static resources
    // Returning errors if you couldn't find your resources
    result = CPUTText::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    result = CPUTButton::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    result = CPUTCheckbox::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    result = CPUTSlider::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }
    result = CPUTDropdown::RegisterStaticResources();
    if(CPUTFAILED(result))
    {
        return result;
    }

    // create the FPS CPUTText object for drawing FPS
    mpFPSCounter = new CPUTText(_L("FPS:"), ID_CPUT_GUI_FPS_COUNTER, mpFont);
    mpFPSCounter->SetAutoArranged(false);
    mpFPSCounter->SetPosition(0,0);

    // start the timer
    mpFPSTimer->StartTimer();

    // done
    return CPUT_SUCCESS;
}
//--------------------------------------------------------------------------------------
// Create Direct3D device and swap chain
//--------------------------------------------------------------------------------------
HRESULT InitDevice()
{
    HRESULT hr = S_OK;

    RECT rc;
    GetClientRect( g_hWnd, &rc );
    UINT width = rc.right - rc.left;
    UINT height = rc.bottom - rc.top;

    UINT createDeviceFlags = 0;
#ifdef _DEBUG
    createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    D3D_DRIVER_TYPE driverTypes[] =
    {
        D3D_DRIVER_TYPE_HARDWARE,
        D3D_DRIVER_TYPE_WARP,
        D3D_DRIVER_TYPE_REFERENCE,
    };
    UINT numDriverTypes = ARRAYSIZE( driverTypes );

    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
    };
    UINT numFeatureLevels = ARRAYSIZE( featureLevels );

    for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
    {
        g_driverType = driverTypes[driverTypeIndex];
        hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
                                D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );

        if ( hr == E_INVALIDARG )
        {
            // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it
            hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1,
                                    D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
        }

        if( SUCCEEDED( hr ) )
            break;
    }
    if( FAILED( hr ) )
        return hr;

    // Obtain DXGI factory from device (since we used nullptr for pAdapter above)
    IDXGIFactory1* dxgiFactory = nullptr;
    {
        IDXGIDevice* dxgiDevice = nullptr;
        hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) );
        if (SUCCEEDED(hr))
        {
            IDXGIAdapter* adapter = nullptr;
            hr = dxgiDevice->GetAdapter(&adapter);
            if (SUCCEEDED(hr))
            {
                hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) );
                adapter->Release();
            }
            dxgiDevice->Release();
        }
    }
    if (FAILED(hr))
        return hr;

    // Create swap chain
    IDXGIFactory2* dxgiFactory2 = nullptr;
    hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) );
    if ( dxgiFactory2 )
    {
        // DirectX 11.1 or later
        hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) );
        if (SUCCEEDED(hr))
        {
            (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) );
        }

        DXGI_SWAP_CHAIN_DESC1 sd;
        ZeroMemory(&sd, sizeof(sd));
        sd.Width = width;
        sd.Height = height;
        sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.BufferCount = 1;

        hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 );
        if (SUCCEEDED(hr))
        {
            hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) );
        }

        dxgiFactory2->Release();
    }
    else
    {
        // DirectX 11.0 systems
        DXGI_SWAP_CHAIN_DESC sd;
        ZeroMemory(&sd, sizeof(sd));
        sd.BufferCount = 1;
        sd.BufferDesc.Width = width;
        sd.BufferDesc.Height = height;
        sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.BufferDesc.RefreshRate.Numerator = 60;
        sd.BufferDesc.RefreshRate.Denominator = 1;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.OutputWindow = g_hWnd;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.Windowed = TRUE;

        hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain );
    }

    // Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut
    dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER );

    dxgiFactory->Release();

    if (FAILED(hr))
        return hr;

    // Create a render target view
    ID3D11Texture2D* pBackBuffer = nullptr;
    hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &pBackBuffer ) );
    if( FAILED( hr ) )
        return hr;

    hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView );
    pBackBuffer->Release();
    if( FAILED( hr ) )
        return hr;

    g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, nullptr );

    // Setup the viewport
    D3D11_VIEWPORT vp;
    vp.Width = (FLOAT)width;
    vp.Height = (FLOAT)height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = 0;
    vp.TopLeftY = 0;
    g_pImmediateContext->RSSetViewports( 1, &vp );

    // Compile the vertex shader
    ID3DBlob* pVSBlob = nullptr;
    hr = CompileShaderFromFile( L"Tutorial03.fx", "VS", "vs_4_0", &pVSBlob );
    if( FAILED( hr ) )
    {
        MessageBox( nullptr,
                    L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
        return hr;
    }

    // Create the vertex shader
    hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &g_pVertexShader );
    if( FAILED( hr ) )
    {
        pVSBlob->Release();
        return hr;
    }

    // Define the input layout
    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = ARRAYSIZE( layout );

    // Create the input layout
    hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
                                          pVSBlob->GetBufferSize(), &g_pVertexLayout );
    pVSBlob->Release();
    if( FAILED( hr ) )
        return hr;

    // Set the input layout
    g_pImmediateContext->IASetInputLayout( g_pVertexLayout );

    // Compile the pixel shader
    ID3DBlob* pPSBlob = nullptr;
    hr = CompileShaderFromFile( L"Tutorial03.fx", "PS", "ps_4_0", &pPSBlob );
    if( FAILED( hr ) )
    {
        MessageBox( nullptr,
                    L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
        return hr;
    }

    // Create the pixel shader
    hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &g_pPixelShader );
    pPSBlob->Release();
    if( FAILED( hr ) )
        return hr;

    // Create vertex buffer
    SimpleVertex vertices[] =
    {
        XMFLOAT3( 0.0f, 0.5f, 0.5f ),
        XMFLOAT3( 0.5f, -0.5f, 0.5f ),
        XMFLOAT3( -0.5f, -0.5f, 0.5f ),
    };
    D3D11_BUFFER_DESC bd;
    ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( SimpleVertex ) * 3;
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    D3D11_SUBRESOURCE_DATA InitData;
    ZeroMemory( &InitData, sizeof(InitData) );
    InitData.pSysMem = vertices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
    if( FAILED( hr ) )
        return hr;

    // Set vertex buffer
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );

    // Set primitive topology
    g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

    return S_OK;
}
Example #6
0
_Use_decl_annotations_
HRESULT D3DX11CompileEffectFromFile( LPCWSTR pFileName,
                                     const D3D_SHADER_MACRO *pDefines, ID3DInclude *pInclude, UINT HLSLFlags, UINT FXFlags,
                                     ID3D11Device *pDevice, ID3DX11Effect **ppEffect, ID3DBlob **ppErrors )
{
    if ( !pFileName || !pDevice || !ppEffect )
        return E_INVALIDARG;

    if ( FXFlags & D3DCOMPILE_EFFECT_CHILD_EFFECT )
    {
        DPF(0, "Effect pools (i.e. D3DCOMPILE_EFFECT_CHILD_EFFECT) not supported" );
        return E_NOTIMPL;
    }

    ID3DBlob *blob = nullptr;

#if (D3D_COMPILER_VERSION >= 46) && ( !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_APP) )

    HRESULT hr = D3DCompileFromFile( pFileName, pDefines, pInclude, "", "fx_5_0", HLSLFlags, FXFlags, &blob, ppErrors );
    if ( FAILED(hr) )
    {
        DPF(0, "D3DCompileFromFile of fx_5_0 profile failed %08X: %S", hr, pFileName );
        return hr;
    }

#else // D3D_COMPILER_VERSION < 46

    std::unique_ptr<uint8_t[]> fileData;
    uint32_t size;
    HRESULT hr = LoadBinaryFromFile( pFileName, fileData, size );
    if ( FAILED(hr) )
    {
        DPF(0, "Failed to load effect file %08X: %S", hr, pFileName);
        return hr;
    }

    // Create debug object name from input filename
    CHAR strFileA[MAX_PATH];
    int result = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, pFileName, -1, strFileA, MAX_PATH, nullptr, FALSE );
    if ( !result )
    {
        DPF(0, "Failed to load effect file due to WC to MB conversion failure: %S", pFileName);
        return E_FAIL;
    }

    const CHAR* pstrName = strrchr( strFileA, '\\' );
    if (!pstrName)
    {
        pstrName = strFileA;
    }
    else
    {
        pstrName++;
    }

    hr = D3DCompile( fileData.get(), size, pstrName, pDefines, pInclude, "", "fx_5_0", HLSLFlags, FXFlags, &blob, ppErrors );
    if ( FAILED(hr) )
    {
        DPF(0, "D3DCompile of fx_5_0 profile failed: %08X", hr );
        return hr;
    }

#endif // D3D_COMPILER_VERSION

#ifdef _M_X64
    if ( blob->GetBufferSize() > 0xFFFFFFFF )
    {
        SAFE_RELEASE( blob );
        return E_FAIL;
    }
#endif // _M_X64

    hr = S_OK;

    VN( *ppEffect = new CEffect( FXFlags & D3DX11_EFFECT_RUNTIME_VALID_FLAGS ) );
    VH( ((CEffect*)(*ppEffect))->LoadEffect(blob->GetBufferPointer(), static_cast<uint32_t>( blob->GetBufferSize() ) ) );
    SAFE_RELEASE( blob );

#if (D3D_COMPILER_VERSION >= 46) && ( !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_APP) )
    // Create debug object name from input filename
    CHAR strFileA[MAX_PATH];
    int result = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, pFileName, -1, strFileA, MAX_PATH, nullptr, FALSE );
    if ( !result  )
    {
        DPF(0, "Failed to load effect file due to WC to MB conversion failure: %S", pFileName);
        hr = E_FAIL;
        goto lExit;
    }

    const CHAR* pstrName = strrchr( strFileA, '\\' );
    if (!pstrName)
    {
        pstrName = strFileA;
    }
    else
    {
        pstrName++;
    }
#endif

    VH( ((CEffect*)(*ppEffect))->BindToDevice(pDevice, pstrName) );

lExit:
    if (FAILED(hr))
    {
        SAFE_RELEASE(*ppEffect);
    }
    return hr;
}
Example #7
0
//--------------------------------------------------------------------------------------
// Load and compile Effect file (.fx file containing shaders)
//--------------------------------------------------------------------------------------
// An effect file contains a set of "Techniques". A technique is a combination of vertex, geometry and pixel shaders (and some states) used for
// rendering in a particular way. We load the effect file at runtime (it's written in HLSL and has the extension ".fx"). The effect code is compiled
// *at runtime* into low-level GPU language. When rendering a particular model we specify which technique from the effect file that it will use
bool CScene::LoadShaders()
{
	ID3DBlob* pEffectBlob;
	ID3DBlob* pErrors; // This strangely typed variable collects any errors when compiling the effect file
	DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS; // These "flags" are used to set the compiler options

	//compile shaders individually
	HRESULT hr; 
	hr = D3DX11CompileFromFile(
		L"VertexShader.hlsl",
		NULL,
		NULL,
		NULL,
		"fx_5_0",
		dwShaderFlags,
		0,
		NULL,
		&pEffectBlob,
		&pErrors,
		&hr
		);

	if( FAILED( hr ) )
	{
		if( pErrors != 0 )  MessageBox( NULL, CA2CT( reinterpret_cast<char*>(pErrors->GetBufferPointer()) ), L"Error", MB_OK ); // Compiler error: display error message
		else               MessageBox( NULL, L"Error loading Vertex Shader FX file. Ensure your FX file is in the same folder as this executable.", L"Error", MB_OK );  // No error message - probably file not found
		return false;
	}

	hr = mpd3dDevice->CreateVertexShader( pEffectBlob->GetBufferPointer(), pEffectBlob->GetBufferSize(), NULL, &mp_VertexShader[0] );

	if( FAILED( hr ) )
	{
		if( pErrors != 0 )  MessageBox( NULL, CA2CT( reinterpret_cast<char*>(pErrors->GetBufferPointer()) ), L"Error", MB_OK ); // Compiler error: display error message
		else               MessageBox( NULL, L"Error creating Vertex Shader.", L"Error", MB_OK );  // No error message - probably file not found
		return false;
	}

	hr = D3DX11CompileFromFile(
		L"PixelShader.hlsl",
		NULL,
		NULL,
		"main",
		"fx_5_0",
		dwShaderFlags,
		0,
		NULL,
		&pEffectBlob,
		&pErrors,
		&hr
		);

	if( FAILED( hr ) )
	{
		if( pErrors != 0 )  MessageBox( NULL, CA2CT( reinterpret_cast<char*>(pErrors->GetBufferPointer()) ), L"Error", MB_OK ); // Compiler error: display error message
		else               MessageBox( NULL, L"Error loading Pixel Shader FX file. Ensure your FX file is in the same folder as this executable.", L"Error", MB_OK );  // No error message - probably file not found
		return false;
	}

	hr = mpd3dDevice->CreatePixelShader( pEffectBlob->GetBufferPointer(), pEffectBlob->GetBufferSize(), NULL, &mp_PixelShader[0] );


	if( FAILED( hr ) )
	{
		if( pErrors != 0 )  MessageBox( NULL, CA2CT( reinterpret_cast<char*>(pErrors->GetBufferPointer()) ), L"Error", MB_OK ); // Compiler error: display error message
		else               MessageBox( NULL, L"Error Creating Pixel Shader", L"Error", MB_OK );  // No error message - probably file not found
		return false;
	}
	return true;
}
Example #8
0
// Requires the compiled shaders (.cso files)
DXShader::DXShader( string vertexPath, string fragmentPath )
{
	HRESULT result;
	ID3DBlob* shaderCompileErrors;

	// Layout description, must match layout in vertex shader
	const int numLayoutElements = 3;
	const D3D11_INPUT_ELEMENT_DESC vLayout[] =
	{
/*POS*/		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
/*UV*/		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
/*NORMAL*/	{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 }
	};

	// ---- Load Vertex Shader
	ID3DBlob* vsb;
	wstring wVertexPath( vertexPath.begin(), vertexPath.end() );
	ShaderInclude include( File( vertexPath ).GetDirectory() );
	//D3DReadFileToBlob( wVertexPath.c_str(), &vsb );
	result = D3DCompileFromFile( wVertexPath.c_str(),
								NULL,
								&include,
								"main",
								"vs_5_0",
								D3DCOMPILE_ENABLE_STRICTNESS,
								0,
								&vsb,
								&shaderCompileErrors );

	if( FAILED(result) )
	{
		OutputController::PrintMessage( OutputType::Error, "Error compiling vertex shader\n" + vertexPath );
		OutputController::PrintMessage( OutputType::Error, (char*)(shaderCompileErrors->GetBufferPointer()) );
	}
	
	result = AdapterController::Get()->GetDevice().dx->CreateVertexShader( vsb->GetBufferPointer(), 
																vsb->GetBufferSize(),
																NULL,
																&vertexShader );
	if( FAILED(result) )
	{
		OutputController::PrintMessage( OutputType::Error, "Failed to create vertex shader." );
	}

	// Create Input Layout
	result = AdapterController::Get()->GetDevice().dx->CreateInputLayout( vLayout,
																numLayoutElements,//ARRAYSIZE(vertexLayout),
																vsb->GetBufferPointer(),
																vsb->GetBufferSize(),
																&vertexLayout );
	if( FAILED(result) )
	{
		OutputController::PrintMessage( OutputType::Error, "Failed to create input layout." );
	}
	

	// ---- Load Pixel Shader
	ID3DBlob* psb;
	wstring wPixelPath( fragmentPath.begin(), fragmentPath.end() );
	//D3DReadFileToBlob( wPixelPath.c_str(), &psb );
	result = D3DCompileFromFile( wPixelPath.c_str(),
								NULL,
								&include,
								"main",
								"ps_5_0",
								D3DCOMPILE_ENABLE_STRICTNESS,
								0,
								&psb,
								&shaderCompileErrors );

	if( FAILED(result) )
	{
		OutputController::PrintMessage( OutputType::Error, "Error compiling fragment shader\n" + fragmentPath );
		OutputController::PrintMessage( OutputType::Error, (gChar*)(shaderCompileErrors->GetBufferPointer()) );
	}

	result = AdapterController::Get()->GetDevice().dx->CreatePixelShader( psb->GetBufferPointer(),
																psb->GetBufferSize(),
																NULL,
																&pixelShader );
	if( FAILED(result) )
	{
		OutputController::PrintMessage( OutputType::Error, "Failed to create fragment shader." );
	}

	// get constant buffer variables
	ID3D11ShaderReflection* vsReflection = nullptr;
	D3D11Reflect( vsb->GetBufferPointer(), vsb->GetBufferSize(), &vsReflection );
	D3D11_SHADER_BUFFER_DESC vsShaderBufferDesc;
	vsReflection->GetConstantBufferByName( "uniforms" )->GetDesc( &vsShaderBufferDesc );
	vsShaderBufferDesc.Name;
	UINT numVariables = vsShaderBufferDesc.Variables;
	ID3D11ShaderReflectionVariable* var2 = vsReflection->GetConstantBufferByName( "uniforms" )->GetVariableByIndex( 2 );
	
	D3D11_SHADER_VARIABLE_DESC var2Desc;
	var2->GetDesc( &var2Desc );
	var2Desc.Name;
	var2Desc.Size;

	ID3D11ShaderReflectionType* var2Type = var2->GetType();
	var2Type->GetMemberTypeByIndex(0);
	

	

	// ---- Create Sampler State
	D3D11_SAMPLER_DESC samplerDesc;
	samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
	samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.MipLODBias = 0.0f;
	samplerDesc.MaxAnisotropy = 1;
	samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
	samplerDesc.BorderColor[0] = 0;
	samplerDesc.BorderColor[1] = 0;
	samplerDesc.BorderColor[2] = 0;
	samplerDesc.BorderColor[3] = 0;
	samplerDesc.MinLOD = 0;
	samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;

	result = AdapterController::Get()->GetDevice().dx->CreateSamplerState( &samplerDesc, &samplerState );
	if( FAILED(result) )
	{
		OutputController::PrintMessage( OutputType::Error, "Failed to create sampler state." );
	}

	// release unneeded buffers
	ReleaseCOMobjMacro( psb );
	ReleaseCOMobjMacro( vsb );
	ReleaseCOMobjMacro( shaderCompileErrors );

	// TEMPORARY BUFFER TO BE REMOVED FROM C++ SIDE
	auto buf = new ConstBuffer;
	buf->totalSize = 0;
	buf->AddProperty( "modelViewProj", sizeof(Matrix4) );
	buf->AddProperty( "rotationMatrix", sizeof(Matrix4) );
	buf->AddProperty( "ambientLight", AmbientLight::size );
	buf->AddProperty( "dirLight", DirectionalLight::size );

	RegisterConstBuffer( "uniforms", buf );
	delete buf;
}
Example #9
0
	static bool compile(bx::CommandLine& _cmdLine, uint32_t _version, const std::string& _code, bx::WriterI* _writer, bool _firstPass)
	{
		const char* profile = _cmdLine.findOption('p', "profile");
		if (NULL == profile)
		{
			fprintf(stderr, "Error: Shader profile must be specified.\n");
			return false;
		}

		s_compiler = load();

		bool result = false;
		bool debug = _cmdLine.hasArg('\0', "debug");

		uint32_t flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
		flags |= debug ? D3DCOMPILE_DEBUG : 0;
		flags |= _cmdLine.hasArg('\0', "avoid-flow-control") ? D3DCOMPILE_AVOID_FLOW_CONTROL : 0;
		flags |= _cmdLine.hasArg('\0', "no-preshader") ? D3DCOMPILE_NO_PRESHADER : 0;
		flags |= _cmdLine.hasArg('\0', "partial-precision") ? D3DCOMPILE_PARTIAL_PRECISION : 0;
		flags |= _cmdLine.hasArg('\0', "prefer-flow-control") ? D3DCOMPILE_PREFER_FLOW_CONTROL : 0;
		flags |= _cmdLine.hasArg('\0', "backwards-compatibility") ? D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY : 0;

		bool werror = _cmdLine.hasArg('\0', "Werror");

		if (werror)
		{
			flags |= D3DCOMPILE_WARNINGS_ARE_ERRORS;
		}

		uint32_t optimization = 3;
		if (_cmdLine.hasArg(optimization, 'O') )
		{
			optimization = bx::uint32_min(optimization, BX_COUNTOF(s_optimizationLevelD3D11) - 1);
			flags |= s_optimizationLevelD3D11[optimization];
		}
		else
		{
			flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
		}

		BX_TRACE("Profile: %s", profile);
		BX_TRACE("Flags: 0x%08x", flags);

		ID3DBlob* code;
		ID3DBlob* errorMsg;

		// Output preprocessed shader so that HLSL can be debugged via GPA
		// or PIX. Compiling through memory won't embed preprocessed shader
		// file path.
		std::string hlslfp;

		if (debug)
		{
			hlslfp = _cmdLine.findOption('o');
			hlslfp += ".hlsl";
			writeFile(hlslfp.c_str(), _code.c_str(), (int32_t)_code.size() );
		}

		HRESULT hr = D3DCompile(_code.c_str()
			, _code.size()
			, hlslfp.c_str()
			, NULL
			, NULL
			, "main"
			, profile
			, flags
			, 0
			, &code
			, &errorMsg
			);
		if (FAILED(hr)
		|| (werror && NULL != errorMsg) )
		{
			const char* log = (char*)errorMsg->GetBufferPointer();

			int32_t line   = 0;
			int32_t column = 0;
			int32_t start  = 0;
			int32_t end    = INT32_MAX;

			bool found = false
				|| 2 == sscanf(log, "(%u,%u):", &line, &column)
				|| 2 == sscanf(log, " :%u:%u: ", &line, &column)
				;

			if (found
			&&  0 != line)
			{
				start = bx::uint32_imax(1, line - 10);
				end   = start + 20;
			}

			printCode(_code.c_str(), line, start, end, column);
			fprintf(stderr, "Error: D3DCompile failed 0x%08x %s\n", (uint32_t)hr, log);
			errorMsg->Release();
			return false;
		}

		UniformArray uniforms;
		uint8_t numAttrs = 0;
		uint16_t attrs[bgfx::Attrib::Count];
		uint16_t size = 0;

		if (_version == 9)
		{
			if (!getReflectionDataD3D9(code, uniforms) )
			{
				fprintf(stderr, "Error: Unable to get D3D9 reflection data.\n");
				goto error;
			}
		}
		else
		{
			UniformNameList unusedUniforms;
			if (!getReflectionDataD3D11(code, profile[0] == 'v', uniforms, numAttrs, attrs, size, unusedUniforms) )
			{
				fprintf(stderr, "Error: Unable to get D3D11 reflection data.\n");
				goto error;
			}

			if (_firstPass
			&&  unusedUniforms.size() > 0)
			{
				const size_t strLength = strlen("uniform");

				// first time through, we just find unused uniforms and get rid of them
				std::string output;
				LineReader reader(_code.c_str() );
				while (!reader.isEof() )
				{
					std::string line = reader.getLine();
					for (UniformNameList::iterator it = unusedUniforms.begin(), itEnd = unusedUniforms.end(); it != itEnd; ++it)
					{
						size_t index = line.find("uniform ");
						if (index == std::string::npos)
						{
							continue;
						}

						// matching lines like:  uniform u_name;
						// we want to replace "uniform" with "static" so that it's no longer
						// included in the uniform blob that the application must upload
						// we can't just remove them, because unused functions might still reference
						// them and cause a compile error when they're gone
						if (!!bx::findIdentifierMatch(line.c_str(), it->c_str() ) )
						{
							line = line.replace(index, strLength, "static");
							unusedUniforms.erase(it);
							break;
						}
					}

					output += line;
				}

				// recompile with the unused uniforms converted to statics
				return compile(_cmdLine, _version, output.c_str(), _writer, false);
			}
		}

		{
			uint16_t count = (uint16_t)uniforms.size();
			bx::write(_writer, count);

			uint32_t fragmentBit = profile[0] == 'p' ? BGFX_UNIFORM_FRAGMENTBIT : 0;
			for (UniformArray::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
			{
				const Uniform& un = *it;
				uint8_t nameSize = (uint8_t)un.name.size();
				bx::write(_writer, nameSize);
				bx::write(_writer, un.name.c_str(), nameSize);
				uint8_t type = uint8_t(un.type | fragmentBit);
				bx::write(_writer, type);
				bx::write(_writer, un.num);
				bx::write(_writer, un.regIndex);
				bx::write(_writer, un.regCount);

				BX_TRACE("%s, %s, %d, %d, %d"
					, un.name.c_str()
					, getUniformTypeName(un.type)
					, un.num
					, un.regIndex
					, un.regCount
					);
			}
		}

		{
			ID3DBlob* stripped;
			hr = D3DStripShader(code->GetBufferPointer()
				, code->GetBufferSize()
				, D3DCOMPILER_STRIP_REFLECTION_DATA
				| D3DCOMPILER_STRIP_TEST_BLOBS
				, &stripped
				);

			if (SUCCEEDED(hr) )
			{
				code->Release();
				code = stripped;
			}
		}

		{
			uint16_t shaderSize = (uint16_t)code->GetBufferSize();
			bx::write(_writer, shaderSize);
			bx::write(_writer, code->GetBufferPointer(), shaderSize);
			uint8_t nul = 0;
			bx::write(_writer, nul);
		}

		if (_version > 9)
		{
			bx::write(_writer, numAttrs);
			bx::write(_writer, attrs, numAttrs*sizeof(uint16_t) );

			bx::write(_writer, size);
		}

		if (_cmdLine.hasArg('\0', "disasm") )
		{
			ID3DBlob* disasm;
			D3DDisassemble(code->GetBufferPointer()
				, code->GetBufferSize()
				, 0
				, NULL
				, &disasm
				);

			if (NULL != disasm)
			{
				std::string disasmfp = _cmdLine.findOption('o');
				disasmfp += ".disasm";

				writeFile(disasmfp.c_str(), disasm->GetBufferPointer(), (uint32_t)disasm->GetBufferSize() );
				disasm->Release();
			}
		}

		if (NULL != errorMsg)
		{
			errorMsg->Release();
		}

		result = true;

	error:
		code->Release();
		unload();
		return result;
	}
Example #10
0
HRESULT Shader::Init(ID3D11Device* device, ID3D11DeviceContext* deviceContext, char* filename,
		const D3D11_INPUT_ELEMENT_DESC* inputElementDesc, unsigned int numElements)
{
	mImmediateContext = deviceContext;
	mDevice = device;

	HRESULT hr = S_OK;

	ID3DBlob*	pBlobEffect = NULL;
	ID3DBlob*	pBlobErrors = NULL;
	
	DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;

#if defined(DEBUG) || defined(_DEBUG)
	dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif

	hr = D3DX11CompileFromFile(
		filename,
		NULL,
		NULL,
		"",
		"fx_5_0",
		dwShaderFlags,
		NULL,
		NULL,
		&pBlobEffect,
		&pBlobErrors,
		NULL
		);

	char* l_pError = NULL;
	if( FAILED(hr) )
	{
		char msg[20000];
		strcpy_s(msg, sizeof(msg), (char*)pBlobErrors->GetBufferPointer());
		OutputDebugString(msg);
		MessageBox(GetDesktopWindow(), msg, "Effect compilation error", MB_OK | MB_ICONERROR);
		return hr;
	}

	if(FAILED(hr = D3DX11CreateEffectFromMemory(
		pBlobEffect->GetBufferPointer(),
		pBlobEffect->GetBufferSize(),
		dwShaderFlags,
		mDevice,
		&m_pEffect
		)))
	{
		MessageBox(0, "Cannot create effect from memory.", "D3DX11CreateEffectFromMemory error", MB_OK | MB_ICONERROR);
		return hr;
	}


	m_pTechnique = m_pEffect->GetTechniqueByIndex(0);


	if(inputElementDesc)
	{
		D3DX11_PASS_DESC PassDesc;
		m_pTechnique->GetPassByIndex(0)->GetDesc(&PassDesc);
		if(FAILED(hr = mDevice->CreateInputLayout(
			inputElementDesc,
			numElements,
			PassDesc.pIAInputSignature,
			PassDesc.IAInputSignatureSize,
			&m_pInputLayout
			)))
		{
			MessageBox(0, "Cannot create input layout.", "CreateInputLayout error", MB_OK | MB_ICONERROR);
			return hr;
		}
	}

	return hr;
}
Example #11
0
void VertexShader::InitFromFile(std::string inFileName)
{
	assert(FileUtil::FileExists(inFileName.c_str()));

	CleanUp();

	DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
	std::wstring filename = std::wstring(inFileName.begin(), inFileName.end());

#ifdef _DEBUG
	// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
	// Setting this flag improves the shader debugging experience, but still allows 
	// the shaders to be optimized and to run exactly the way they will run in 
	// the release configuration of this program.
	dwShaderFlags |= D3DCOMPILE_DEBUG;

	// Disable optimizations to further improve shader debugging
	dwShaderFlags |= D3DCOMPILE_SKIP_OPTIMIZATION;
#endif

	ID3DBlob* pVSBlob = nullptr;
	ID3DBlob* pErrorBlob = nullptr;

	D3DCall(D3DCompileFromFile(filename.c_str(), nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE, "VS", "vs_5_0", dwShaderFlags, 0, &pVSBlob, &pErrorBlob));
	if (pErrorBlob)
	{
		OutputDebugStringA(reinterpret_cast<const char*>(pErrorBlob->GetBufferPointer()));
		pErrorBlob->Release();
	}
	
	D3DCall(theRenderContext.GetDevice()->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &mHandle));

	// Reflect shader info
	ID3D11ShaderReflection* pVertexShaderReflection = NULL;
	D3DCall(D3DReflect(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&pVertexShaderReflection));
		
	// Get shader info
	D3D11_SHADER_DESC shaderDesc;
	pVertexShaderReflection->GetDesc(&shaderDesc);

	// Read input layout description from shader info
	std::vector<D3D11_INPUT_ELEMENT_DESC> inputLayoutDesc;
	for (int i = 0; i < shaderDesc.InputParameters; i++)
	{
		D3D11_SIGNATURE_PARAMETER_DESC paramDesc;
		pVertexShaderReflection->GetInputParameterDesc(i, &paramDesc);

		// fill out input element desc
		D3D11_INPUT_ELEMENT_DESC elementDesc;
		elementDesc.SemanticName = paramDesc.SemanticName;
		elementDesc.SemanticIndex = paramDesc.SemanticIndex;
		elementDesc.InputSlot = 0;
		if (i == 0)
			elementDesc.AlignedByteOffset = 0;
		else
			elementDesc.AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
		elementDesc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
		elementDesc.InstanceDataStepRate = 0;

		// determine DXGI format
		if (paramDesc.Mask == 1)
		{
			if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32_UINT;
			else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32_SINT;
			else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32_FLOAT;
		}
		else if (paramDesc.Mask <= 3)
		{
			if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32_UINT;
			else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32_SINT;
			else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32_FLOAT;
		}
		else if (paramDesc.Mask <= 7)
		{
			if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_UINT;
			else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_SINT;
			else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT;
		}
		else if (paramDesc.Mask <= 15)
		{
			if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT;
			else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT;
			else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
		}

		//save element desc
		inputLayoutDesc.push_back(elementDesc);
	}

	// Try to create Input Layout
	D3DCall(theRenderContext.GetDevice()->CreateInputLayout(&inputLayoutDesc[0], inputLayoutDesc.size(), pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &mVertexLayout));

	//Free allocation shader reflection memory
	pVertexShaderReflection->Release();
	pVSBlob->Release();
}
Example #12
0
void hwRendererHelperDX::initializeDrawTextureEffect()
{
	if( fDXContext == NULL )
		return;

	// Create the effect
	if( fDrawTextureEffect == NULL )
	{
		const char* simpleShaderCode =	"Texture2D myTexture; \r\n" \

										"SamplerState SamplerLinearWrap \r\n" \
										"{ \r\n" \
										"	Filter = MIN_MAG_MIP_LINEAR; \r\n" \
										"	AddressU = Wrap; \r\n" \
										"	AddressV = Wrap; \r\n" \
										"}; \r\n" \

										"struct APP_TO_VS \r\n" \
										"{ \r\n" \
										"	float3 Pos : POSITION; \r\n" \
										"	float2 TextCoord : TEXTCOORD; \r\n" \
										"}; \r\n" \

										"struct VS_TO_PS \r\n" \
										"{ \r\n" \
										"	float4 Pos : SV_Position; \r\n" \
										"	float2 TextCoord : TEXTCOORD; \r\n" \
										"}; \r\n" \

										"VS_TO_PS BasicVS(APP_TO_VS IN) \r\n" \
										"{ \r\n" \
										"	VS_TO_PS OUT; \r\n" \
										"	OUT.Pos = float4(IN.Pos, 1.0f); \r\n" \
										"	OUT.TextCoord = IN.TextCoord; \r\n" \
										"	return OUT; \r\n" \
										"} \r\n" \

										"float4 BasicPS(VS_TO_PS IN) : SV_Target \r\n" \
										"{ \r\n" \
										"	float4 color = myTexture.Sample(SamplerLinearWrap, IN.TextCoord); \r\n" \
										"	return color; \r\n" \
										"} \r\n" \

										"technique10 simple \r\n" \
										"{ \r\n" \
										"	pass p0 \r\n" \
										"	{ \r\n" \
										"		SetVertexShader( CompileShader( vs_4_0, BasicVS() ) ); \r\n" \
										"		SetGeometryShader( NULL ); \r\n" \
										"		SetPixelShader( CompileShader( ps_4_0, BasicPS() ) ); \r\n" \
										"	} \r\n" \
										"} \r\n";
		const unsigned int simpleShaderLength = (unsigned int)strlen(simpleShaderCode);

		const D3D10_SHADER_MACRO macros[] = { { "DIRECT3D_VERSION", "0xb00" }, { NULL, NULL } };

#ifdef _DEBUG
		const unsigned int flags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#else
		const unsigned int flags = 0;
#endif

		ID3DBlob *shader = NULL;
		ID3DBlob *error = NULL;
#if _MSC_VER >= 1700
		HRESULT hr = D3DCompile((char*)simpleShaderCode, simpleShaderLength, NULL, macros, NULL, "", "fx_5_0", flags, 0, &shader, &error);
#else
		HRESULT hr = D3DX11CompileFromMemory((char*)simpleShaderCode, simpleShaderLength, NULL, macros, NULL, "", "fx_5_0", flags, 0, NULL, &shader, &error, NULL);
#endif
		if( SUCCEEDED( hr ) && shader != NULL )
		{
			hr = D3DX11CreateEffectFromMemory(shader->GetBufferPointer(), shader->GetBufferSize(), 0, fDXDevice, &fDrawTextureEffect);
			if( SUCCEEDED( hr ) && fDrawTextureEffect != NULL )
			{
				ID3DX11EffectVariable* textureVariable = fDrawTextureEffect->GetVariableByName( "myTexture" );
				if( textureVariable != NULL )
				{
					fDrawTextureShaderVariable = textureVariable->AsShaderResource();
				}

				ID3DX11EffectTechnique* technique = fDrawTextureEffect->GetTechniqueByIndex(0);
				if( technique )
				{
					fDrawTexturePass = technique->GetPassByIndex(0);
				}
			}
		}
		else
		{
			MString errorStr( (error && error->GetBufferSize() > 0) ? (char*) error->GetBufferPointer() : (char*) NULL );

			MGlobal::displayWarning( hwApiTextureTestStrings::getString( hwApiTextureTestStrings::kDxErrorEffect, errorStr ) );
		}
		
		if( shader != NULL )
		{
			shader->Release();
		}
	}
	
	// Create the vertex buffers and the input layout
	if( fDrawTextureInputLayout == NULL && fDrawTexturePass != NULL )
	{
		fDrawTextureVertexBuffersCount = 0;

		D3D11_INPUT_ELEMENT_DESC inputDesc[MAX_VERTEX_BUFFERS];

		HRESULT hr;

		// Create the position stream
		{
			const float position[] = {	-1, -1, 0,		// bottom-left
										-1,  1, 0,		// top-left
										 1,  1, 0,		// top-right
										 1, -1, 0 };	// bottom-right

			const D3D11_BUFFER_DESC bufDesc = { sizeof(position), D3D11_USAGE_IMMUTABLE, D3D11_BIND_VERTEX_BUFFER, 0, 0, 0 };
			const D3D11_SUBRESOURCE_DATA bufData = { position, 0, 0 };
			ID3D11Buffer *buffer = NULL;
			hr = fDXDevice->CreateBuffer(&bufDesc, &bufData, &buffer);
			if( SUCCEEDED( hr ) && buffer != NULL )
			{
				inputDesc[fDrawTextureVertexBuffersCount].SemanticName = "POSITION";
				inputDesc[fDrawTextureVertexBuffersCount].SemanticIndex = 0;
				inputDesc[fDrawTextureVertexBuffersCount].Format = DXGI_FORMAT_R32G32B32_FLOAT;
				inputDesc[fDrawTextureVertexBuffersCount].InputSlot = fDrawTextureVertexBuffersCount;
				inputDesc[fDrawTextureVertexBuffersCount].AlignedByteOffset = 0;
				inputDesc[fDrawTextureVertexBuffersCount].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
				inputDesc[fDrawTextureVertexBuffersCount].InstanceDataStepRate = 0;

				fDrawTextureVertexBuffers[fDrawTextureVertexBuffersCount] = buffer;
				fDrawTextureVertexBuffersStrides[fDrawTextureVertexBuffersCount] = 3 * sizeof(float);
				fDrawTextureVertexBuffersOffsets[fDrawTextureVertexBuffersCount] = 0;

				++fDrawTextureVertexBuffersCount;
			}
		}

		// Create the texture coord stream
		if( SUCCEEDED( hr ) )
		{
			const float textCoord[] = {	0, 1,		// bottom-left
										0, 0,		// top-left
										1, 0,		// top-right
										1, 1 };		// bottom-right

			const D3D11_BUFFER_DESC bufDesc = { sizeof(textCoord), D3D11_USAGE_IMMUTABLE, D3D11_BIND_VERTEX_BUFFER, 0, 0, 0 };
			const D3D11_SUBRESOURCE_DATA bufData = { textCoord, 0, 0 };
			ID3D11Buffer *buffer = NULL;
			hr = fDXDevice->CreateBuffer(&bufDesc, &bufData, &buffer);
			if( SUCCEEDED( hr ) && buffer != NULL )
			{
				inputDesc[fDrawTextureVertexBuffersCount].SemanticName = "TEXTCOORD";
				inputDesc[fDrawTextureVertexBuffersCount].SemanticIndex = 0;
				inputDesc[fDrawTextureVertexBuffersCount].Format = DXGI_FORMAT_R32G32_FLOAT;
				inputDesc[fDrawTextureVertexBuffersCount].InputSlot = fDrawTextureVertexBuffersCount;
				inputDesc[fDrawTextureVertexBuffersCount].AlignedByteOffset = 0;
				inputDesc[fDrawTextureVertexBuffersCount].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
				inputDesc[fDrawTextureVertexBuffersCount].InstanceDataStepRate = 0;

				fDrawTextureVertexBuffers[fDrawTextureVertexBuffersCount] = buffer;
				fDrawTextureVertexBuffersStrides[fDrawTextureVertexBuffersCount] = 2 * sizeof(float);
				fDrawTextureVertexBuffersOffsets[fDrawTextureVertexBuffersCount] = 0;

				++fDrawTextureVertexBuffersCount;
			}
		}

		if( SUCCEEDED( hr ) )
		{
			D3DX11_PASS_DESC descPass;
			fDrawTexturePass->GetDesc(&descPass);

			hr = fDXDevice->CreateInputLayout(inputDesc, fDrawTextureVertexBuffersCount, descPass.pIAInputSignature, descPass.IAInputSignatureSize, &fDrawTextureInputLayout);
			if( FAILED( hr ) )
			{
				MGlobal::displayWarning( hwApiTextureTestStrings::getString( hwApiTextureTestStrings::kDxErrorInputLayout ) );
			}
		}
	}
	
	// Create the index buffer
	if( fDrawTextureIndexBuffer == NULL && fDrawTextureVertexBuffersCount > 0  && fDrawTextureInputLayout != NULL )
	{
		const unsigned int indices[] = { 0, 1, 3, 3, 2, 1 };
		fDrawTextureIndexBufferCount = _countof(indices);

		const D3D11_BUFFER_DESC bufDesc = { sizeof(indices), D3D11_USAGE_IMMUTABLE, D3D11_BIND_INDEX_BUFFER, 0, 0, 0 };
		const D3D11_SUBRESOURCE_DATA bufData = { indices, 0, 0 };
		fDXDevice->CreateBuffer(&bufDesc, &bufData, &fDrawTextureIndexBuffer);
	}
}
Example #13
0
void KTRoboDemoRender::Init(Graphics* g) {

	
	HRESULT hr = S_OK;
	ID3DBlob* pblob = 0;
	font = 0;
	p_blendstate = 0;
	p_sampler = 0;
	p_rasterstate = 0;
	try {
		CompileShaderFromFile("resrc/shader/sample.fx", "VSFunc", "vs_4_0", &pblob);
		hr = g->getDevice()->CreateVertexShader(pblob->GetBufferPointer(),
			pblob->GetBufferSize(),
			NULL,
			&vs);
		if (FAILED(hr)) {
			pblob->Release();
			pblob = 0;
			vs = 0;
		}

		// 入力レイアウトの定義
		D3D11_INPUT_ELEMENT_DESC layout[] = {
			{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0},
			{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0},
		};
		
		unsigned int num = sizeof(layout)/ sizeof(layout[0]);
			
		hr = g->getDevice()->CreateInputLayout(
			layout,num,pblob->GetBufferPointer(),
			pblob->GetBufferSize(),
			&p_vertexlayout);
		if (FAILED(hr)) {
			throw new KTROBO::GameError(KTROBO::FATAL_ERROR, "layout make error");;
		}
		if (pblob) {
			pblob->Release();
			pblob = 0;
		}
		 // Set the input layout
		g->getDeviceContext()->IASetInputLayout( p_vertexlayout );

		/*
		
		CompileShaderFromFile("resrc/shader/sample.fx", "GSFunc", "gs_4_0", &pblob);
		hr = g->getDevice()->CreateGeometryShader(pblob->GetBufferPointer(),
			pblob->GetBufferSize(),
			NULL, &gs);
		if (FAILED(hr)) {
			pblob->Release();
			pblob = 0;
			gs = 0;
		}
			if (pblob) {
			pblob->Release();
			pblob = 0;
		}
		*/
		CompileShaderFromFile("resrc/shader/sample.fx", "PSFunc", "ps_4_0", &pblob);
		hr = g->getDevice()->CreatePixelShader(pblob->GetBufferPointer(),
			pblob->GetBufferSize(),
			NULL,&ps);
		if (FAILED(hr)) {
			pblob->Release();
			pblob = 0;
			ps = 0;
		}

		if (pblob) {
			pblob->Release();
			pblob = 0;
		}

		D3D11_BLEND_DESC BlendDesc;
		memset(&BlendDesc, 0, sizeof(BlendDesc));
		BlendDesc.AlphaToCoverageEnable = FALSE;
		BlendDesc.IndependentBlendEnable = FALSE;
		BlendDesc.RenderTarget[0].BlendEnable = FALSE;
		BlendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
		BlendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_DEST_ALPHA;
		BlendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
		BlendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
		BlendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
		BlendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
		BlendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

		HRESULT hr = g->getDevice()->CreateBlendState(&BlendDesc,&p_blendstate);
		if (FAILED(hr)) {
			throw new GameError(KTROBO::FATAL_ERROR, "failed in blend state create");
		}

	} catch (KTROBO::GameError* e) {
		if (pblob) {
			pblob->Release();
			pblob = 0;
		}

		Release();

		
	//	MessageBoxA(NULL,e->getMessage(), "shader compile error", MB_OK);
		throw e;
	}
	float de = 1/(float)4;//512.0/2049;//*512/4096.0f;
	float te = 1.0f/2 * 1  * 2;
	float of = 1.0f/4 * 1  * 2 ;
	float xof = 1.0f/4 * 1  * 2 ;
	// 頂点バッファの作成
	SimpleVertex vertices[] = {

		{XMFLOAT3(0.0f-te-xof,0.0f,0.0f),XMFLOAT2(0.0f,1.0f*de)},
		{XMFLOAT3(0.0f-te-xof,1.0f * te,0.0f),XMFLOAT2(0.0f,0.0f)},
		{XMFLOAT3(1.0f* te-te-xof,0.0f,0.0f),XMFLOAT2(1.0f*de,1.0f*de)},
		{XMFLOAT3(1.0f* te-te-xof,0.0f,0.0f),XMFLOAT2(1.0f*de,1.0f*de)},
		{XMFLOAT3(0.0f-te-xof,1.0f* te,0.0f),XMFLOAT2(0.0f,0.0f)},
		{XMFLOAT3(1.0f*te-te-xof,1.0f*te,0.0f),XMFLOAT2(1.0f*de,0.0f)},


		{XMFLOAT3(0.0f-xof,0.0f,0.0f),XMFLOAT2(0.0f,1.0f*de/2+de/2)},
		{XMFLOAT3(0.0f-xof,1.0f * te/2,0.0f),XMFLOAT2(0.0f,0.0f+de/2)},
		{XMFLOAT3(1.0f* te/2-xof,0.0f,0.0f),XMFLOAT2(1.0f*de/2,1.0f*de/2+de/2)},
		{XMFLOAT3(1.0f* te/2-xof,0.0f,0.0f),XMFLOAT2(1.0f*de/2,1.0f*de/2+de/2)},
		{XMFLOAT3(0.0f-xof,1.0f* te/2,0.0f),XMFLOAT2(0.0f,0.0f+de/2)},
		{XMFLOAT3(1.0f*te/2-xof,1.0f*te/2,0.0f),XMFLOAT2(1.0f*de/2,0.0f+de/2)},

		{XMFLOAT3(0.0f + of-xof ,0.0f,0.0f),XMFLOAT2(0.0f+de/2,1.0f*de/2+de/2)},
		{XMFLOAT3(0.0f+of-xof,1.0f * te/2,0.0f),XMFLOAT2(0.0f+de/2,0.0f+de/2)},
		{XMFLOAT3(1.0f* te/2+of-xof,0.0f,0.0f),XMFLOAT2(1.0f*de/2+de/2,1.0f*de/2+de/2)},
		{XMFLOAT3(1.0f* te/2+of-xof,0.0f,0.0f),XMFLOAT2(1.0f*de/2+de/2,1.0f*de/2+de/2)},
		{XMFLOAT3(0.0f+of-xof,1.0f* te/2,0.0f),XMFLOAT2(0.0f+de/2,0.0f+de/2)},
		{XMFLOAT3(1.0f*te/2+of-xof,1.0f*te/2,0.0f),XMFLOAT2(1.0f*de/2+de/2,0.0f+de/2)},
	
	
		{XMFLOAT3(0.0f-xof,0.0f+of,0.0f),XMFLOAT2(0.0f,1.0f*de/2)},
		{XMFLOAT3(0.0f-xof,1.0f * te/2+of,0.0f),XMFLOAT2(0.0f,0.0f)},
		{XMFLOAT3(1.0f* te/2-xof,0.0f+of,0.0f),XMFLOAT2(1.0f*de/2,1.0f*de/2)},
		{XMFLOAT3(1.0f* te/2-xof,0.0f+of,0.0f),XMFLOAT2(1.0f*de/2,1.0f*de/2)},
		{XMFLOAT3(0.0f-xof,1.0f* te/2+of,0.0f),XMFLOAT2(0.0f,0.0f)},
		{XMFLOAT3(1.0f*te/2-xof,1.0f*te/2+of,0.0f),XMFLOAT2(1.0f*de/2,0.0f)},
	
		{XMFLOAT3(0.0f+of-xof,0.0f+of,0.0f),XMFLOAT2(0.0f+de/2,1.0f*de/2)},
		{XMFLOAT3(0.0f+of-xof,1.0f * te/2+of,0.0f),XMFLOAT2(0.0f+de/2,0.0f)},
		{XMFLOAT3(1.0f* te/2+of-xof,0.0f+of,0.0f),XMFLOAT2(1.0f*de/2+de/2,1.0f*de/2)},
		{XMFLOAT3(1.0f* te/2+of-xof,0.0f+of,0.0f),XMFLOAT2(1.0f*de/2+de/2,1.0f*de/2)},
		{XMFLOAT3(0.0f+of-xof,1.0f* te/2+of,0.0f),XMFLOAT2(0.0f+de/2,0.0f)},
		{XMFLOAT3(1.0f*te/2+of-xof,1.0f*te/2+of,0.0f),XMFLOAT2(1.0f*de/2+de/2,0.0f)},
	};

	D3D11_BUFFER_DESC bd;
	memset(&bd,0,sizeof(bd));
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(SimpleVertex)*30;
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;

	D3D11_SUBRESOURCE_DATA initData;
	memset(&initData, 0, sizeof(initData));
	initData.pSysMem = vertices;

	hr = g->getDevice()->CreateBuffer(&bd, &initData,&p_vertexbuffer);
	if (FAILED(hr)) {
		Release();
		throw new KTROBO::GameError(KTROBO::FATAL_ERROR, "vertex buffer make error");;
		
	}

	unsigned int stride = sizeof(SimpleVertex);
	unsigned int offset = 0;
	
	g->getDeviceContext()->IASetInputLayout(p_vertexlayout);
	g->getDeviceContext()->IASetVertexBuffers( 0, 1, &p_vertexbuffer, &stride, &offset );
	g->getDeviceContext()->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
	
	font = new Font();
	font->Init("resrc/azukiL.ttf","あずきフォントL",g);


	tex_loader = new MyTextureLoader();
	tex_loader->init(g);
	render_target_tex = tex_loader->makeClass(1024,1024);
	msaa_tex = tex_loader->makeClass(1024,1024);


	D3D11_SAMPLER_DESC descS;
	memset(&descS, 0, sizeof(descS));
	descS.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
	descS.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
	descS.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
	descS.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
	descS.BorderColor[0] = 0;
	descS.BorderColor[1] = 0;
	descS.BorderColor[2] = 0;
	descS.BorderColor[3] = 0;
	descS.ComparisonFunc = D3D11_COMPARISON_NEVER;
	descS.MaxAnisotropy = 1;
	descS.MinLOD = 1;
	descS.MaxLOD = D3D11_FLOAT32_MAX;
	hr = g->getDevice()->CreateSamplerState(&descS, &p_sampler);
	if (FAILED(hr)) {
		Release();
		throw new KTROBO::GameError(KTROBO::FATAL_ERROR, "sampler make error");;
		
	}





	D3D11_RASTERIZER_DESC _rasterDesc;
	_rasterDesc.AntialiasedLineEnable = false;//true; // changed to true
	_rasterDesc.CullMode = D3D11_CULL_NONE;
	_rasterDesc.DepthBias = 0;
	_rasterDesc.DepthBiasClamp = 0.0f;
	_rasterDesc.DepthClipEnable = false;
	_rasterDesc.FillMode = D3D11_FILL_SOLID;
	_rasterDesc.FrontCounterClockwise = false;
	_rasterDesc.MultisampleEnable = false;//true; // changed to true
	_rasterDesc.ScissorEnable = false;
	_rasterDesc.SlopeScaledDepthBias = 0.0f;
	hr  = g->getDevice()->CreateRasterizerState( &_rasterDesc, &p_rasterstate );
	if( FAILED( hr ) ) {
		Release();
		throw new KTROBO::GameError(KTROBO::FATAL_ERROR, "raster make error");;
	}
}
// Create pixel shaders
HRESULT CFW1GlyphRenderStates::createPixelShaders() {
	// Pixel shader
	const char psStr[] =
	"SamplerState sampler0 : register(s0);\r\n"
	"Texture2D<float> tex0 : register(t0);\r\n"
	"\r\n"
	"struct PSIn {\r\n"
	"	float4 Position : SV_Position;\r\n"
	"	float4 GlyphColor : COLOR;\r\n"
	"	float2 TexCoord : TEXCOORD;\r\n"
	"};\r\n"
	"\r\n"
	"float4 PS(PSIn Input) : SV_Target {\r\n"
	"	float a = tex0.Sample(sampler0, Input.TexCoord);\r\n"
	"	\r\n"
	"	if(a == 0.0f)\r\n"
	"		discard;\r\n"
	"	\r\n"
	"	return (a * Input.GlyphColor.a) * float4(Input.GlyphColor.rgb, 1.0f);\r\n"
	"}\r\n"
	"";
	
	// Clipping pixel shader
	const char psClipStr[] =
	"SamplerState sampler0 : register(s0);\r\n"
	"Texture2D<float> tex0 : register(t0);\r\n"
	"\r\n"
	"struct PSIn {\r\n"
	"	float4 Position : SV_Position;\r\n"
	"	float4 GlyphColor : COLOR;\r\n"
	"	float2 TexCoord : TEXCOORD;\r\n"
	"	float4 ClipDistance : CLIPDISTANCE;\r\n"
	"};\r\n"
	"\r\n"
	"float4 PS(PSIn Input) : SV_Target {\r\n"
	"	clip(Input.ClipDistance);\r\n"
	"	\r\n"
	"	float a = tex0.Sample(sampler0, Input.TexCoord);\r\n"
	"	\r\n"
	"	if(a == 0.0f)\r\n"
	"		discard;\r\n"
	"	\r\n"
	"	return (a * Input.GlyphColor.a) * float4(Input.GlyphColor.rgb, 1.0f);\r\n"
	"}\r\n"
	"";
	
	// Shader compile profile
	const char *ps_profile = "ps_4_0_level_9_1";
	if(m_featureLevel >= D3D_FEATURE_LEVEL_11_0)
		ps_profile = "ps_5_0";
	else if(m_featureLevel >= D3D_FEATURE_LEVEL_10_0)
		ps_profile = "ps_4_0";
	else if(m_featureLevel >= D3D_FEATURE_LEVEL_9_3)
		ps_profile = "ps_4_0_level_9_3";
	
	// Compile pixel shader
	ID3DBlob *pPSCode;
	
	HRESULT hResult = m_pfnD3DCompile(
		psStr,
		sizeof(psStr),
		NULL,
		NULL,
		NULL,
		"PS",
		ps_profile,
		D3DCOMPILE_OPTIMIZATION_LEVEL3,
		0,
		&pPSCode,
		NULL
	);
	if(FAILED(hResult)) {
		m_lastError = L"Failed to compile pixel shader";
	}
	else {
		// Create pixel shader
		ID3D11PixelShader *pPS;
		
		hResult = m_pDevice->CreatePixelShader(pPSCode->GetBufferPointer(), pPSCode->GetBufferSize(), NULL, &pPS);
		if(FAILED(hResult)) {
			m_lastError = L"Failed to create pixel shader";
		}
		else {
			// Compile clipping pixel shader
			ID3DBlob *pPSClipCode;
			
			HRESULT hResult = m_pfnD3DCompile(
				psClipStr,
				sizeof(psClipStr),
				NULL,
				NULL,
				NULL,
				"PS",
				ps_profile,
				D3DCOMPILE_OPTIMIZATION_LEVEL3,
				0,
				&pPSClipCode,
				NULL
			);
			if(FAILED(hResult)) {
				m_lastError = L"Failed to compile clipping pixel shader";
			}
			else {
				// Create pixel shader
				ID3D11PixelShader *pPSClip;
				
				hResult = m_pDevice->CreatePixelShader(
					pPSClipCode->GetBufferPointer(),
					pPSClipCode->GetBufferSize(),
					NULL, &pPSClip
				);
				if(FAILED(hResult)) {
					m_lastError = L"Failed to create clipping pixel shader";
				}
				else {
					// Success
					m_pPixelShader = pPS;
					m_pPixelShaderClip = pPSClip;
					
					hResult = S_OK;
				}
				
				pPSClipCode->Release();
			}
			
			if(FAILED(hResult))
				pPS->Release();
		}
		
		pPSCode->Release();
	}
	
	return hResult;
}
Example #15
0
int main()
{
    // Create Device
    const D3D_FEATURE_LEVEL lvl[] = { D3D_FEATURE_LEVEL_11_1 };

    UINT createDeviceFlags = 0;
#ifdef _DEBUG
    createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    /* ================================== */
    printf("Creating device...");
    ID3D11Device* device = nullptr;
    HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, lvl, _countof(lvl), D3D11_SDK_VERSION, &device, nullptr, nullptr);
    if (FAILED(hr))
    {
        printf("Failed creating Direct3D 11 device %08X\n", hr);
        return returnDBG(-1);
    }

    /* ================================== */
    printf("Compile Compute Shader...");
    ID3DBlob *csBlob = nullptr;
    hr = CompileComputeShader(L"ComputeShader.hlsl", "main", device, &csBlob);
    if (FAILED(hr))
    {
        device->Release();
        printf("Failed compiling shader %08X\n", hr);
        return returnDBG(-1);
    }

    /* ================================== */
    printf("Create Compute Shader...");
    ID3D11ComputeShader* computeShader = nullptr;
    hr = device->CreateComputeShader(csBlob->GetBufferPointer(), csBlob->GetBufferSize(), nullptr, &computeShader);
            
    /* ================================== */
    printf("Creating buffers and filling them with initial data...");
    for (int i = 0; i < NUM_ELEMENTS; ++i)
    {
        g_vBuf0[i].i = i;
        g_vBuf0[i].f = (float)i;

        g_vBuf1[i].i = i;
        g_vBuf1[i].f = (float)i;
    }

    CreateRawBuffer(g_pDevice, NUM_ELEMENTS * sizeof(BufType), &g_vBuf0[0], &g_pBuf0);
    CreateRawBuffer(g_pDevice, NUM_ELEMENTS * sizeof(BufType), &g_vBuf1[0], &g_pBuf1);
    CreateRawBuffer(g_pDevice, NUM_ELEMENTS * sizeof(BufType), nullptr, &g_pBufResult);

    /* ================================== */
    printf("Running Compute Shader...");
    ID3D11ShaderResourceView* aRViews[2] = { g_pBuf0SRV, g_pBuf1SRV };
    RunComputeShader(g_pContext, g_pCS, 2, aRViews, nullptr, nullptr, 0, g_pBufResultUAV, NUM_ELEMENTS, 1, 1);
    printf("done\n");
    
    
    
    csBlob->Release();

    if (FAILED(hr))
    {
        device->Release();
    }

    printf("Success\n");



    // Clean up
    computeShader->Release();

    device->Release();

    return returnDBG(0);
}
Example #16
0
HRESULT InitDevice()
{
	HRESULT hr = S_OK;

	RECT rc;
	GetClientRect(g_hWnd, &rc);
	UINT width = rc.right - rc.left;
	UINT height = rc.bottom - rc.top;

	UINT createDeviceFlags = 0;
#ifdef _DEBUG
	createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	D3D_DRIVER_TYPE driverTypes[] =
	{
		D3D_DRIVER_TYPE_HARDWARE,
		D3D_DRIVER_TYPE_WARP,
		D3D_DRIVER_TYPE_REFERENCE,
	};
	UINT numDriverTypes = ARRAYSIZE(driverTypes);

	D3D_FEATURE_LEVEL featureLevels[] =
	{
		D3D_FEATURE_LEVEL_11_0,
		D3D_FEATURE_LEVEL_10_1,
		D3D_FEATURE_LEVEL_10_0,
	};
	UINT numFeatureLevels = ARRAYSIZE(featureLevels);

	DXGI_SWAP_CHAIN_DESC sd;
	ZeroMemory(&sd, sizeof(sd));
	sd.BufferCount = 1;
	sd.BufferDesc.Width = width;
	sd.BufferDesc.Height = height;
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow = g_hWnd;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.Windowed = TRUE;
	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

	for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
	{
		g_driverType = driverTypes[driverTypeIndex];
		hr = D3D11CreateDeviceAndSwapChain(NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
			D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext);
		if (SUCCEEDED(hr))
			break;
	}
	if (FAILED(hr))
		return hr;

	// Create a render target view
	ID3D11Texture2D* pBackBuffer = NULL;
	hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
	if (FAILED(hr))
		return hr;

	hr = g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView);
	pBackBuffer->Release();
	if (FAILED(hr))
		return hr;

	// Create depth stencil texture
	D3D11_TEXTURE2D_DESC descDepth;
	ZeroMemory(&descDepth, sizeof(descDepth));
	descDepth.Width = width;
	descDepth.Height = height;
	descDepth.MipLevels = 1;
	descDepth.ArraySize = 1;
	descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	descDepth.SampleDesc.Count = 1;
	descDepth.SampleDesc.Quality = 0;
	descDepth.Usage = D3D11_USAGE_DEFAULT;
	descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	descDepth.CPUAccessFlags = 0;
	descDepth.MiscFlags = 0;
	hr = g_pd3dDevice->CreateTexture2D(&descDepth, NULL, &g_pDepthStencil);
	if (FAILED(hr))
		return hr;

	// Create the depth stencil view
	D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
	ZeroMemory(&descDSV, sizeof(descDSV));
	descDSV.Format = descDepth.Format;
	descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	descDSV.Texture2D.MipSlice = 0;
	hr = g_pd3dDevice->CreateDepthStencilView(g_pDepthStencil, &descDSV, &g_pDepthStencilView);
	if (FAILED(hr))
		return hr;

	g_pImmediateContext->OMSetRenderTargets(1, &g_pRenderTargetView, g_pDepthStencilView);

	// Setup the viewport
	D3D11_VIEWPORT vp;
	vp.Width = (FLOAT)width;
	vp.Height = (FLOAT)height;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	g_pImmediateContext->RSSetViewports(1, &vp);

	// Compile the vertex shader
	ID3DBlob* pVSBlob = NULL;
	hr = CompileShaderFromFile(L"Tutorial05.fx", "VS", "vs_4_0", &pVSBlob);
	if (FAILED(hr))
	{
		MessageBox(NULL,
			L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
		return hr;
	}

	// Create the vertex shader
	hr = g_pd3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader);
	if (FAILED(hr))
	{
		pVSBlob->Release();
		return hr;
	}

	// Define the input layout
	D3D11_INPUT_ELEMENT_DESC layout[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0,  DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "NORMAL", 0,  DXGI_FORMAT_R32G32B32_FLOAT, 0, 36, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TANGENT", 0,  DXGI_FORMAT_R32G32B32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "BINORMAL", 0,  DXGI_FORMAT_R32G32B32_FLOAT, 0, 60, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};
	UINT numElements = ARRAYSIZE(layout);

	// Create the input layout
	hr = g_pd3dDevice->CreateInputLayout(layout, numElements, pVSBlob->GetBufferPointer(),
		pVSBlob->GetBufferSize(), &g_pVertexLayout);
	pVSBlob->Release();
	if (FAILED(hr))
		return hr;

	// Set the input layout
	g_pImmediateContext->IASetInputLayout(g_pVertexLayout);

	// Compile the pixel shader
	ID3DBlob* pPSBlob = NULL;
	hr = CompileShaderFromFile(L"Tutorial05.fx", "PS", "ps_4_0", &pPSBlob);
	if (FAILED(hr))
	{
		MessageBox(NULL,
			L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
		return hr;
	}

	// Create the pixel shader
	hr = g_pd3dDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader);
	pPSBlob->Release();
	if (FAILED(hr))
		return hr;

	// -------------------------------------------------------------
	// JPE: Shaders para WireFrame
	// -------------------------------------------------------------
	// Compile the vertex shader
	ID3DBlob* pVSBlobWF = NULL;
	hr = CompileShaderFromFile(L"Tutorial05.fx", "VS_WF", "vs_4_0", &pVSBlobWF);
	if (FAILED(hr))
	{
		MessageBox(NULL,
			L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
		return hr;
	}

	// Create the vertex shader
	hr = g_pd3dDevice->CreateVertexShader(pVSBlobWF->GetBufferPointer(), pVSBlobWF->GetBufferSize(), NULL, &g_pVertexShaderWF);
	pVSBlobWF->Release();
	if (FAILED(hr))
		return hr;

	// Compile the pixel shader
	ID3DBlob* pPSBlobWF = NULL;
	hr = CompileShaderFromFile(L"Tutorial05.fx", "PS_WF", "ps_4_0", &pPSBlobWF);
	if (FAILED(hr))
	{
		MessageBox(NULL,
			L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
		return hr;
	}

	// Create the pixel shader
	hr = g_pd3dDevice->CreatePixelShader(pPSBlobWF->GetBufferPointer(), pPSBlobWF->GetBufferSize(), NULL, &g_pPixelShaderWF);
	pPSBlobWF->Release();
	if (FAILED(hr))
		return hr;

	// -------------------------------------------------------------

	// JPE: Create vertex buffer and index buffer
	SimpleVertex* vertices;
	WORD* indices;
	if (modelo == ModeloMono)
	{
		LoadFileOFF(&vertices, &indices, &cantVertices, &cantIndices);
	}
	else
	{
		LoadVertices(&vertices, &indices, &cantVertices, &cantIndices);
	}
	CalcularNormales(vertices, indices, cantVertices, cantIndices);

	
	// Crea Buffer para Vertices
    D3D11_BUFFER_DESC bd;
	ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( SimpleVertex ) * cantVertices;
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;
    D3D11_SUBRESOURCE_DATA InitData;
	ZeroMemory( &InitData, sizeof(InitData) );
    InitData.pSysMem = vertices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
    if( FAILED( hr ) )
        return hr;

    // Set vertex buffer
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );

	// Crea Buffer para Indexes
	bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( WORD ) * cantIndices;        // 36 vertices needed for 12 triangles in a triangle list
    bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
	bd.CPUAccessFlags = 0;
    InitData.pSysMem = indices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );
    if( FAILED( hr ) )
        return hr;

    // Set index buffer
    g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );

    // Set primitive topology
    g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

	// Create the constant buffer
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(ConstantBuffer);
	bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	bd.CPUAccessFlags = 0;
    hr = g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pConstantBuffer );
    if( FAILED( hr ) )
        return hr;

	// JPE: Create the constant buffer for PixelShader
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(ConstantBufferPS);
	bd.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	bd.CPUAccessFlags = 0;
	hr = g_pd3dDevice->CreateBuffer(&bd, NULL, &g_pConstantBufferPS);
	if (FAILED(hr))
		return hr;

    // Initialize the world matrix
	g_World1 = XMMatrixIdentity();
	g_World2 = XMMatrixIdentity();

	SetViewMatrix();

    // Initialize the projection matrix
	g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV2, width / (FLOAT)height, 0.01f, 100.0f );

	// JPE: Texturas
	loadTextures(g_pd3dDevice);

	// JPE: Raster state
	///*
	D3D11_RASTERIZER_DESC rasterDesc;

	// Setup the raster description which will determine how and what polygons will be drawn.
	rasterDesc.AntialiasedLineEnable = false;
	rasterDesc.CullMode = D3D11_CULL_BACK;
	rasterDesc.DepthBias = 0;
	rasterDesc.DepthBiasClamp = 0.0f;
	rasterDesc.DepthClipEnable = true;
	rasterDesc.FillMode = D3D11_FILL_SOLID;
	rasterDesc.FrontCounterClockwise = false;
	rasterDesc.MultisampleEnable = false;
	rasterDesc.ScissorEnable = false;
	rasterDesc.SlopeScaledDepthBias = 0.0f;

	// Create the rasterizer state from the description we just filled out.
	hr = g_pd3dDevice->CreateRasterizerState(&rasterDesc, &m_rasterState);
	if (FAILED(hr))
	{
		return hr;
	}

	// Now set the rasterizer state.
	g_pImmediateContext->RSSetState(m_rasterState);
	//*/

	// JPE: Raster state para WireFrame
	// Setup the raster description which will determine how and what polygons will be drawn.
	rasterDesc.AntialiasedLineEnable = false;
	rasterDesc.CullMode = D3D11_CULL_BACK;
	rasterDesc.DepthBias = 0;
	rasterDesc.DepthBiasClamp = 0.0f;
	rasterDesc.DepthClipEnable = true;
	rasterDesc.FillMode = D3D11_FILL_WIREFRAME;
	rasterDesc.FrontCounterClockwise = false;
	rasterDesc.MultisampleEnable = false;
	rasterDesc.ScissorEnable = false;
	rasterDesc.SlopeScaledDepthBias = 0.0f;

	// Create the rasterizer state from the description we just filled out.
	hr = g_pd3dDevice->CreateRasterizerState(&rasterDesc, &m_rasterStateWF);
	if (FAILED(hr))
	{
		return hr;
	}


	// JPE: Parametros default
	if (modelo == ModeloMono)
	{
		bump = false;
		useTexture = false;
		rotate = false;
	}

    return S_OK;
}
Example #17
0
// Loads the specified shader and builds the variable table using
// shader reflection
//
// shaderFile - A "wide string" specifying the compiled shader to load
// 
// Returns true if shader is loaded properly, false otherwise
bool ISimpleShader::LoadShaderFile(LPCWSTR shaderFile)
{
	// Load the shader to a blob and ensure it worked
	ID3DBlob* shaderBlob = 0;
	HRESULT hr = D3DReadFileToBlob(shaderFile, &shaderBlob);
	if (hr != S_OK)
	{
		return false;
	}

	// Create the shader - Calls an overloaded version of this abstract
	// method in the appropriate child class
	shaderValid = CreateShader(shaderBlob);
	if (!shaderValid)
	{
		shaderBlob->Release();
		return false;
	}

	// Set up shader reflection to get information about
	// this shader and its variables,  buffers, etc.
	ID3D11ShaderReflection* refl;
	D3DReflect(
		shaderBlob->GetBufferPointer(),
		shaderBlob->GetBufferSize(),
		IID_ID3D11ShaderReflection,
		(void**)&refl);
	
	// Get the description of the shader
	D3D11_SHADER_DESC shaderDesc;
	refl->GetDesc(&shaderDesc);

	// Create an array of constant buffers
	constantBufferCount = shaderDesc.ConstantBuffers;
	constantBuffers = new SimpleConstantBuffer[constantBufferCount];
	
	// Handle bound resources (like shaders and samplers)
	unsigned int resourceCount = shaderDesc.BoundResources;
	for (unsigned int r = 0; r < resourceCount; r++)
	{
		// Get this resource's description
		D3D11_SHADER_INPUT_BIND_DESC resourceDesc;
		refl->GetResourceBindingDesc(r, &resourceDesc);

		// Check the type
		switch (resourceDesc.Type)
		{
		case D3D_SIT_TEXTURE: // A texture resource
			textureTable.insert(std::pair<std::string, unsigned int>(resourceDesc.Name, resourceDesc.BindPoint));
			break;

		case D3D_SIT_SAMPLER: // A sampler resource
			samplerTable.insert(std::pair<std::string, unsigned int>(resourceDesc.Name, resourceDesc.BindPoint));
			break;
		}
	}

	// Loop through all constant buffers
	for (unsigned int b = 0; b < constantBufferCount; b++)
	{
		// Get this buffer
		ID3D11ShaderReflectionConstantBuffer* cb =
			refl->GetConstantBufferByIndex(b);
		
		// Get the description of this buffer
		D3D11_SHADER_BUFFER_DESC bufferDesc;
		cb->GetDesc(&bufferDesc);

		// Get the description of the resource binding, so
		// we know exactly how it's bound in the shader
		D3D11_SHADER_INPUT_BIND_DESC bindDesc;
		refl->GetResourceBindingDescByName(bufferDesc.Name, &bindDesc);
		
		// Set up the buffer and put its pointer in the table
		constantBuffers[b].BindIndex = bindDesc.BindPoint;
		cbTable.insert(std::pair<std::string, SimpleConstantBuffer*>(bufferDesc.Name, &constantBuffers[b]));

		// Create this constant buffer
		D3D11_BUFFER_DESC newBuffDesc;
		newBuffDesc.Usage = D3D11_USAGE_DEFAULT;
		newBuffDesc.ByteWidth = bufferDesc.Size;
		newBuffDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
		newBuffDesc.CPUAccessFlags = 0;
		newBuffDesc.MiscFlags = 0;
		newBuffDesc.StructureByteStride = 0;
		device->CreateBuffer(&newBuffDesc, 0, &constantBuffers[b].ConstantBuffer);

		// Set up the data buffer for this constant buffer
		constantBuffers[b].LocalDataBuffer = new unsigned char[bufferDesc.Size];
		ZeroMemory(constantBuffers[b].LocalDataBuffer, bufferDesc.Size);

		// Loop through all variables in this buffer
		for (unsigned int v = 0; v < bufferDesc.Variables; v++)
		{
			// Get this variable
			ID3D11ShaderReflectionVariable* var =
				cb->GetVariableByIndex(v);
			
			// Get the description of the variable
			D3D11_SHADER_VARIABLE_DESC varDesc;
			var->GetDesc(&varDesc);

			// Create the variable struct
			SimpleShaderVariable varStruct;
			varStruct.ConstantBufferIndex = b;
			varStruct.ByteOffset = varDesc.StartOffset;
			varStruct.Size = varDesc.Size;
			
			// Get a string version
			std::string varName(varDesc.Name);

			// Add this variable to the table
			varTable.insert(std::pair<std::string, SimpleShaderVariable>(varName, varStruct));
		}
	}

	// All set
	refl->Release();
	shaderBlob->Release();
	return true;
}
Example #18
0
bool Graphics::CreateDefaultShader()
{
	HRESULT r = 0;

	ID3DBlob* vsBuffer = 0;
	ID3DBlob* buffer = 0;

	ID3DBlob* Errors = 0;

	DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG;

	bool b = CompileD3DShader("..\\te010\\DefaultShader.fx", 0, "fx_5_0", &buffer);

	if (!b)
	{
		if (buffer)
		{
			buffer->Release();
		}
		NAIA_FATAL("Unnable to compile default shader");
	}

	r = D3DX11CreateEffectFromMemory(buffer->GetBufferPointer(), buffer->GetBufferSize(), 0 , m_Device, &m_Effect);
	if (FAILED(r))
	{
		NAIA_FATAL("Unnable to create effect");
	}

	m_Technique = m_Effect->GetTechniqueByName("DefaultTechnique");

	if (!m_Technique)
	{
		NAIA_FATAL("Can not find DefaultTechnique in default shader");
	}

	D3D11_INPUT_ELEMENT_DESC defaultLayout[] =
	{
		{"POSITION", 0,  DXGI_FORMAT_R32G32B32_FLOAT,    0,  0,                             D3D11_INPUT_PER_VERTEX_DATA,    0},
		{"NORMAL",   0,  DXGI_FORMAT_R32G32B32_FLOAT,    0,  D3D11_APPEND_ALIGNED_ELEMENT,  D3D11_INPUT_PER_VERTEX_DATA,    0},
		{"COLOR",    0,  DXGI_FORMAT_R32G32B32_FLOAT,    0,  D3D11_APPEND_ALIGNED_ELEMENT,  D3D11_INPUT_PER_VERTEX_DATA,    0},
		{"TEXCOORD", 0,  DXGI_FORMAT_R32G32B32_FLOAT,    0,  D3D11_APPEND_ALIGNED_ELEMENT,  D3D11_INPUT_PER_VERTEX_DATA,    0}
	};

	unsigned int totalLayoutElements = ARRAYSIZE(defaultLayout);

	D3DX11_PASS_DESC descPASS;
	m_Technique->GetPassByIndex(0)->GetDesc(&descPASS);

	r = m_Device->CreateInputLayout(defaultLayout, totalLayoutElements, descPASS.pIAInputSignature, descPASS.IAInputSignatureSize, &m_InputLayout);
	if (FAILED(r))
	{
		NAIA_FATAL("Failed to create input layout");
	}

	m_Context->IASetInputLayout(m_InputLayout);

	Mat4x4 world = Mat4x4::g_Identity;
	SetWorldMatrix(world);

	Mat4x4 view = Mat4x4::g_Identity;
	Vec3 eye(6.0f, 6.0f, 6.0f);
	Vec3 at(0.f,0.f,0.f);
	Vec3 up(0.f,1.0f,0.f);
	D3DXMatrixLookAtLH(&view, &eye, &at, &up);
	SetViewMatrix(view);

	Mat4x4 proj = Mat4x4::g_Identity;
	D3DXMatrixPerspectiveFovLH(&proj, NAIA_PI/2, Application::instance()->m_Width/(float)Application::instance()->m_Height, 0.01f, 100.0f);
	SetProjectionMatrix(proj);

#pragma region Create constant buffers

	D3D11_BUFFER_DESC bd;
	ZeroMemory(&bd, sizeof(bd));
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.ByteWidth = sizeof(CBNeverChanges);
	bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	bd.CPUAccessFlags = 0; 
	r = m_Device->CreateBuffer(&bd, NULL, &m_cbNeverChanges);
	if (FAILED(r))
	{
		NAIA_FATAL("Can not create constant buffer (Never changes)");
	}

	bd.ByteWidth = sizeof(CBChangeOnResize);
	r = m_Device->CreateBuffer(&bd, NULL, &m_cbChangesOnResize);
	if (FAILED(r))
	{
		NAIA_FATAL("Can not create constant buffer (Changes on resize)");
	}

	bd.ByteWidth = sizeof(CBChangesEveryFrame);
	r = m_Device->CreateBuffer(&bd, NULL, &m_cbChangesEveryFrame);
	if (FAILED(r))
	{
		NAIA_FATAL("Can not create constant buffer (Changes every frame)");
	}
#pragma endregion

	CBNeverChanges cbNeverChanges;
	cbNeverChanges.View = view;
	m_Context->UpdateSubresource(m_cbNeverChanges, 0, NULL, &cbNeverChanges, 0, 0);

	CBChangeOnResize cbChangesOnResize;
	cbChangesOnResize.Projection = proj;
	m_Context->UpdateSubresource(m_cbChangesOnResize, 0, NULL, &cbChangesOnResize, 0, 0);

	CBChangesEveryFrame cbChangesEveryFrame;
	cbChangesEveryFrame.World = world;
	m_Context->UpdateSubresource(m_cbChangesEveryFrame, 0, NULL, &cbChangesEveryFrame, 0, 0);

	return true;
}
Example #19
0
	static ID3DBlob* CompileShader(const wchar* path, const char* functionName, const char* profile,
		const D3D_SHADER_MACRO* defines, bool forceOptimization,
		vector<wstring>& filePaths)
	{
		// Make a hash off the expanded shader code
		string shaderCode = GetExpandedShaderCode(path, filePaths);
		wstring cacheName = MakeShaderCacheName(shaderCode, functionName, profile, defines);

		if (FileExists(cacheName.c_str()))
		{
			File cacheFile(cacheName.c_str(), File::OpenRead);

			const size_t shaderSize = cacheFile.Size();
			vector<uint8> compressedShader;
			compressedShader.resize(shaderSize);
			cacheFile.Read(shaderSize, compressedShader.data());

			ID3DBlob* decompressedShader[1] = { nullptr };
			uint32 indices[1] = { 0 };
			DXCall(D3DDecompressShaders(compressedShader.data(), shaderSize, 1, 0,
				indices, 0, decompressedShader, nullptr));

			return decompressedShader[0];
		}

		std::printf("Compiling shader %s %s %s\n", WStringToAnsi(GetFileName(path).c_str()).c_str(),
			profile, MakeDefinesString(defines).c_str());

		// Loop until we succeed, or an exception is thrown
		while (true)
		{
			UINT flags = D3DCOMPILE_WARNINGS_ARE_ERRORS;
#ifdef _DEBUG
			flags |= D3DCOMPILE_DEBUG;
			if(forceOptimization == false)
				flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
#endif

			ID3DBlob* compiledShader;
			ID3DBlobPtr errorMessages;
			HRESULT hr = D3DCompileFromFile(path, defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, functionName,
				profile, flags, 0, &compiledShader, &errorMessages);

			if (FAILED(hr))
			{
				if (errorMessages)
				{
					wchar message[1024] = { 0 };
					char* blobdata = reinterpret_cast<char*>(errorMessages->GetBufferPointer());

					MultiByteToWideChar(CP_ACP, 0, blobdata, static_cast<int>(errorMessages->GetBufferSize()), message, 1024);
					std::wstring fullMessage = L"Error compiling shader file \"";
					fullMessage += path;
					fullMessage += L"\" - ";
					fullMessage += message;

					// Pop up a message box allowing user to retry compilation
					int retVal = MessageBoxW(nullptr, fullMessage.c_str(), L"Shader Compilation Error", MB_RETRYCANCEL);
					if (retVal != IDRETRY)
						throw DXException(hr, fullMessage.c_str());

#if EnableShaderCaching_
					shaderCode = GetExpandedShaderCode(path);
					cacheName = MakeShaderCacheName(shaderCode, functionName, profile, defines);
#endif
				}
				else
				{
					_ASSERT(false);
					throw DXException(hr);
				}
			}
			else
			{
				// Compress the shader
				D3D_SHADER_DATA shaderData;
				shaderData.pBytecode = compiledShader->GetBufferPointer();
				shaderData.BytecodeLength = compiledShader->GetBufferSize();
				ID3DBlobPtr compressedShader;
				DXCall(D3DCompressShaders(1, &shaderData, D3D_COMPRESS_SHADER_KEEP_ALL_PARTS, &compressedShader));

				// Create the cache directory if it doesn't exist
				if (DirectoryExists(baseCacheDir.c_str()) == false)
					Win32Call(CreateDirectory(baseCacheDir.c_str(), nullptr));

				if (DirectoryExists(cacheDir.c_str()) == false)
					Win32Call(CreateDirectory(cacheDir.c_str(), nullptr));

				File cacheFile(cacheName.c_str(), File::OpenWrite);

				// Write the compiled shader to disk
				size_t shaderSize = compressedShader->GetBufferSize();
				cacheFile.Write(shaderSize, compressedShader->GetBufferPointer());

				return compiledShader;
			}
		}
	}
bool ParticleManager::BuildShaders(ID3D11Device* pDevice)
{
#pragma region COMPILE_RENDER_SHADER
	if (!CompileShader(&m_vBlob, "Data/particles.fx", "VS_MAIN", "vs_5_0"))
	{
		return false;
	}

	ID3DBlob* pBlob = 0;

	if (!CompileShader(&pBlob, "Data/particles.fx", "PS_MAIN", "ps_5_0"))
	{
		if (pBlob)
		{
			pBlob->Release();
		}

		return false;
	}
#pragma endregion

#pragma region COMPILE_UPDATE_SHADER

	ID3DBlob* vBlob = 0;

	if (!CompileShader(&vBlob, "Data/particles.fx", "VS_MAIN_SO", "vs_5_0"))
	{
		if (vBlob)
		{
			vBlob->Release();
		}

		return false;
	}

	ID3DBlob* gBlob = 0;

	if (!CompileShader(&gBlob, "Data/particles.fx", "GS_MAIN_SO", "gs_5_0"))
	{
		if (gBlob)
		{
			gBlob->Release();
		}

		return false;
	}

#pragma endregion

#pragma region CREATE_RENDER_SHADER
	
	HRESULT hr = 0;
	hr = pDevice->CreateVertexShader(m_vBlob->GetBufferPointer(), m_vBlob->GetBufferSize(),
		NULL, &m_vShader);
	if (FAILED(hr))
	{
		return false;
	}
	hr = pDevice->CreatePixelShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(),
		NULL, &m_pShader);
	if (FAILED(hr))
	{
		pBlob->Release();
		return false;
	}

	pBlob->Release();

#pragma endregion

	hr = pDevice->CreateVertexShader(vBlob->GetBufferPointer(), vBlob->GetBufferSize(),
		NULL, &m_vUpdate);
	if (FAILED(hr))
	{
		vBlob->Release();
		return false;
	}

	//Stream out decl
	D3D11_SO_DECLARATION_ENTRY dso[] = {
		{ 0, "SV_POSITION", 0, 0, 3, 0 },
		{ 0, "VELOCITY", 0, 0, 3, 0 },
		{ 0, "COLOR", 0, 0, 4, 0 }
	};

	UINT stride = sizeof(Particle);
	UINT elems = sizeof(dso) / sizeof(D3D11_SO_DECLARATION_ENTRY);

	hr = pDevice->CreateGeometryShaderWithStreamOutput(
		gBlob->GetBufferPointer(), gBlob->GetBufferSize(),
		dso, elems, &stride, 1, 0, NULL, &m_gUpdate);
	if (FAILED(hr))
	{
		gBlob->Release();

		return false;
	}

	vBlob->Release();
	gBlob->Release();

	return true;
}
Example #21
0
bool ColorShaderClass::InitializeShader(ID3D11Device* device, HWND hwnd, WCHAR* vsFilename, WCHAR* psFilename)
{
	HRESULT result = S_OK;
	ID3DBlob* vertexShaderBuffer;
	ID3DBlob* pixelShaderBuffer;
	D3D11_INPUT_ELEMENT_DESC polygonLayout[2];
	unsigned int numElements;
	D3D11_BUFFER_DESC matrixBufferDesc;


	// Initialize the pointers this function will use to null.
	vertexShaderBuffer = 0;
	pixelShaderBuffer = 0;

	LPCSTR profile = ( device->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_0 ) ? "vs_5_0" : "vs_4_0";

	// Compile the vertex shader code.
	result = CompileShaderFromFile(vsFilename,"ColorVertexShader",profile,&vertexShaderBuffer);

	if(FAILED(result)){
		MessageBox(hwnd, L"Error compiling vertex shader.", vsFilename, MB_OK);
		return false;
	}

		profile = ( device->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_0 ) ? "ps_5_0" : "ps_4_0";

	// Compile the pixel shader code.
	result = CompileShaderFromFile(psFilename, "ColorPixelShader", profile, &pixelShaderBuffer);

	if(FAILED(result)){
		MessageBox(hwnd, L"Error compiling pixel shader.", psFilename, MB_OK);
		return false;
	}

	// Create the vertex shader from the buffer.
	result = device->CreateVertexShader(vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), NULL, &m_vertexShader);
	if(FAILED(result))
	{
		return false;
	}

	// Create the pixel shader from the buffer.
	result = device->CreatePixelShader(pixelShaderBuffer->GetBufferPointer(), pixelShaderBuffer->GetBufferSize(), NULL, &m_pixelShader);
	if(FAILED(result))
	{
		return false;
	}

	// Create the vertex input layout description.
	// This setup needs to match the VertexType stucture in the ModelClass and in the shader.
	polygonLayout[0].SemanticName = "POSITION";
	polygonLayout[0].SemanticIndex = 0;
	polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	polygonLayout[0].InputSlot = 0;
	polygonLayout[0].AlignedByteOffset = 0;
	polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	polygonLayout[0].InstanceDataStepRate = 0;

	polygonLayout[1].SemanticName = "COLOR";
	polygonLayout[1].SemanticIndex = 0;
	polygonLayout[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	polygonLayout[1].InputSlot = 0;
	polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	polygonLayout[1].InstanceDataStepRate = 0;

	// Get a count of the elements in the layout.
	numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);

	// Create the vertex input layout.
	result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), 
		vertexShaderBuffer->GetBufferSize(), &m_layout);
	if(FAILED(result))
	{
		return false;
	}

	// Release the vertex shader buffer and pixel shader buffer since they are no longer needed.
	vertexShaderBuffer->Release();
	vertexShaderBuffer = 0;

	pixelShaderBuffer->Release();
	pixelShaderBuffer = 0;

	// Setup the description of the dynamic matrix constant buffer that is in the vertex shader.
	matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
	matrixBufferDesc.ByteWidth = sizeof(ConstantBufferType);
	matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	matrixBufferDesc.MiscFlags = 0;
	matrixBufferDesc.StructureByteStride = 0;

	// Create the constant buffer pointer so we can access the vertex shader constant buffer from within this class.
	result = device->CreateBuffer(&matrixBufferDesc, NULL, &m_matrixBuffer);
	if(FAILED(result))
	{
		return false;
	}

	return true;
}
//--------------------------------------------------------------------------------------
// Create Direct3D device and swap chain
//--------------------------------------------------------------------------------------
HRESULT InitDevice()
{
    HRESULT hr = S_OK;

    RECT rc;
    GetClientRect( g_hWnd, &rc );
    UINT width = rc.right - rc.left;
    UINT height = rc.bottom - rc.top;

    UINT createDeviceFlags = 0;
#ifdef _DEBUG
    createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    D3D_DRIVER_TYPE driverTypes[] =
    {
        D3D_DRIVER_TYPE_HARDWARE,
        D3D_DRIVER_TYPE_WARP,
        D3D_DRIVER_TYPE_REFERENCE,
    };
    UINT numDriverTypes = ARRAYSIZE( driverTypes );

    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
    };
    UINT numFeatureLevels = ARRAYSIZE( featureLevels );

    for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
    {
        g_driverType = driverTypes[driverTypeIndex];
        hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
                                D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );

        if ( hr == E_INVALIDARG )
        {
            // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it
            hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1,
                                    D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
        }

        if( SUCCEEDED( hr ) )
            break;
    }
    if( FAILED( hr ) )
        return hr;

    // Obtain DXGI factory from device (since we used nullptr for pAdapter above)
    IDXGIFactory1* dxgiFactory = nullptr;
    {
        IDXGIDevice* dxgiDevice = nullptr;
        hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) );
        if (SUCCEEDED(hr))
        {
            IDXGIAdapter* adapter = nullptr;
            hr = dxgiDevice->GetAdapter(&adapter);
            if (SUCCEEDED(hr))
            {
                hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) );
                adapter->Release();
            }
            dxgiDevice->Release();
        }
    }
    if (FAILED(hr))
        return hr;

    // Create swap chain
    IDXGIFactory2* dxgiFactory2 = nullptr;
    hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) );
    if ( dxgiFactory2 )
    {
        // DirectX 11.1 or later
        hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) );
        if (SUCCEEDED(hr))
        {
            (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) );
        }

        DXGI_SWAP_CHAIN_DESC1 sd;
        ZeroMemory(&sd, sizeof(sd));
        sd.Width = width;
        sd.Height = height;
        sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.BufferCount = 1;

        hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 );
        if (SUCCEEDED(hr))
        {
            hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) );
        }

        dxgiFactory2->Release();
    }
    else
    {
        // DirectX 11.0 systems
        DXGI_SWAP_CHAIN_DESC sd;
        ZeroMemory(&sd, sizeof(sd));
        sd.BufferCount = 1;
        sd.BufferDesc.Width = width;
        sd.BufferDesc.Height = height;
        sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.BufferDesc.RefreshRate.Numerator = 60;
        sd.BufferDesc.RefreshRate.Denominator = 1;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.OutputWindow = g_hWnd;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.Windowed = TRUE;

        hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain );
    }

    // Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut
    dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER );

    dxgiFactory->Release();

    if (FAILED(hr))
        return hr;

    // Create a render target view
    ID3D11Texture2D* pBackBuffer = nullptr;
    hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &pBackBuffer ) );
    if( FAILED( hr ) )
        return hr;

    hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView );
    pBackBuffer->Release();
    if( FAILED( hr ) )
        return hr;

    // Create depth stencil texture
    D3D11_TEXTURE2D_DESC descDepth;
    ZeroMemory( &descDepth, sizeof(descDepth) );
    descDepth.Width = width;
    descDepth.Height = height;
    descDepth.MipLevels = 1;
    descDepth.ArraySize = 1;
    descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    descDepth.SampleDesc.Count = 1;
    descDepth.SampleDesc.Quality = 0;
    descDepth.Usage = D3D11_USAGE_DEFAULT;
    descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    descDepth.CPUAccessFlags = 0;
    descDepth.MiscFlags = 0;
    hr = g_pd3dDevice->CreateTexture2D( &descDepth, nullptr, &g_pDepthStencil );
    if( FAILED( hr ) )
        return hr;

    // Create the depth stencil view
    D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
    ZeroMemory( &descDSV, sizeof(descDSV) );
    descDSV.Format = descDepth.Format;
    descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    descDSV.Texture2D.MipSlice = 0;
    hr = g_pd3dDevice->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView );
    if( FAILED( hr ) )
        return hr;

    g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, g_pDepthStencilView );

    // Setup the viewport
    D3D11_VIEWPORT vp;
    vp.Width = (FLOAT)width;
    vp.Height = (FLOAT)height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = 0;
    vp.TopLeftY = 0;
    g_pImmediateContext->RSSetViewports( 1, &vp );

    // Compile the vertex shader
    ID3DBlob* pVSBlob = nullptr;
    hr = CompileShaderFromFile( L"Tutorial07.fx", "VS", "vs_4_0", &pVSBlob );
    if( FAILED( hr ) )
    {
        MessageBox( nullptr,
                    L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
        return hr;
    }

    // Create the vertex shader
    hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &g_pVertexShader );
    if( FAILED( hr ) )
    {    
        pVSBlob->Release();
        return hr;
    }

    // Define the input layout
    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = ARRAYSIZE( layout );

    // Create the input layout
    hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
                                          pVSBlob->GetBufferSize(), &g_pVertexLayout );
    pVSBlob->Release();
    if( FAILED( hr ) )
        return hr;

    // Set the input layout
    g_pImmediateContext->IASetInputLayout( g_pVertexLayout );

    // Compile the pixel shader
    ID3DBlob* pPSBlob = nullptr;
    hr = CompileShaderFromFile( L"Tutorial07.fx", "PS", "ps_4_0", &pPSBlob );
    if( FAILED( hr ) )
    {
        MessageBox( nullptr,
                    L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
        return hr;
    }

    // Create the pixel shader
    hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &g_pPixelShader );
    pPSBlob->Release();
    if( FAILED( hr ) )
        return hr;

    // Create vertex buffer
    SimpleVertex vertices[] =
    {
        { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
        { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },

        { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) },

        { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
        { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) },

        { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
        { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) },

        { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
        { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
        { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) },

        { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },
        { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) },
        { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) },
        { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) },
    };

    D3D11_BUFFER_DESC bd;
    ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( SimpleVertex ) * 24;
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    D3D11_SUBRESOURCE_DATA InitData;
    ZeroMemory( &InitData, sizeof(InitData) );
    InitData.pSysMem = vertices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
    if( FAILED( hr ) )
        return hr;

    // Set vertex buffer
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );

    // Create index buffer
    // Create vertex buffer
    WORD indices[] =
    {
        3,1,0,
        2,1,3,

        6,4,5,
        7,4,6,

        11,9,8,
        10,9,11,

        14,12,13,
        15,12,14,

        19,17,16,
        18,17,19,

        22,20,21,
        23,20,22
    };

    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( WORD ) * 36;
    bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
    bd.CPUAccessFlags = 0;
    InitData.pSysMem = indices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );
    if( FAILED( hr ) )
        return hr;

    // Set index buffer
    g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );

    // Set primitive topology
    g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

    // Create the constant buffers
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof(CBNeverChanges);
    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    bd.CPUAccessFlags = 0;
    hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pCBNeverChanges );
    if( FAILED( hr ) )
        return hr;
    
    bd.ByteWidth = sizeof(CBChangeOnResize);
    hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pCBChangeOnResize );
    if( FAILED( hr ) )
        return hr;
    
    bd.ByteWidth = sizeof(CBChangesEveryFrame);
    hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pCBChangesEveryFrame );
    if( FAILED( hr ) )
        return hr;

    // Load the Texture
    hr = CreateDDSTextureFromFile( g_pd3dDevice, L"seafloor.dds", nullptr, &g_pTextureRV );
    if( FAILED( hr ) )
        return hr;

    // Create the sample state
    D3D11_SAMPLER_DESC sampDesc;
    ZeroMemory( &sampDesc, sizeof(sampDesc) );
    sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
    sampDesc.MinLOD = 0;
    sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
    hr = g_pd3dDevice->CreateSamplerState( &sampDesc, &g_pSamplerLinear );
    if( FAILED( hr ) )
        return hr;

    // Initialize the world matrices
    g_World = XMMatrixIdentity();

    // Initialize the view matrix
    XMVECTOR Eye = XMVectorSet( 0.0f, 3.0f, -6.0f, 0.0f );
    XMVECTOR At = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
    XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
    g_View = XMMatrixLookAtLH( Eye, At, Up );

    CBNeverChanges cbNeverChanges;
    cbNeverChanges.mView = XMMatrixTranspose( g_View );
    g_pImmediateContext->UpdateSubresource( g_pCBNeverChanges, 0, nullptr, &cbNeverChanges, 0, 0 );

    // Initialize the projection matrix
    g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f );
    
    CBChangeOnResize cbChangesOnResize;
    cbChangesOnResize.mProjection = XMMatrixTranspose( g_Projection );
    g_pImmediateContext->UpdateSubresource( g_pCBChangeOnResize, 0, nullptr, &cbChangesOnResize, 0, 0 );

#ifdef USE_OPENVR
    // OpenVR.
    // Loading the SteamVR Runtime
	  vr::EVRInitError eError = vr::VRInitError_None;
	  openvr_system_ = vr::VR_Init(&eError, vr::VRApplication_Scene);
	  if (eError != vr::VRInitError_None) {
		    openvr_system_ = nullptr;
        ShowMessageBoxAndExit("Unable to init VR runtime: %s", vr::VR_GetVRInitErrorAsEnglishDescription(eError));
	  }
    if (!vr::VRCompositor()) {
        ShowMessageBoxAndExit("Failed to obtain compositor.");
    }
#endif

    return S_OK;
}
Example #23
0
bool LoadContent()
{
	assert(g_d3dDevice);

	D3D11_BUFFER_DESC vertexBufferDesc;
	ZeroMemory(&vertexBufferDesc, sizeof(D3D11_BUFFER_DESC));

	vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vertexBufferDesc.ByteWidth = sizeof(VertexPosColor) * _countof(g_Vertices);
	vertexBufferDesc.CPUAccessFlags = 0;
	vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;

	D3D11_SUBRESOURCE_DATA resourceData;
	ZeroMemory(&resourceData, sizeof(D3D11_SUBRESOURCE_DATA));
	resourceData.pSysMem = g_Vertices;

	HRESULT hResult = g_d3dDevice->CreateBuffer(&vertexBufferDesc, &resourceData, &g_d3dVertexBuffer);
	if (FAILED(hResult))
		return false;

	D3D11_BUFFER_DESC indexBufferDesc;
	ZeroMemory(&indexBufferDesc, sizeof(D3D11_BUFFER_DESC));

	indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
	indexBufferDesc.ByteWidth = sizeof(WORD) * _countof(g_Indicies);
	indexBufferDesc.CPUAccessFlags = 0;
	indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
	resourceData.pSysMem = g_Indicies;

	hResult = g_d3dDevice->CreateBuffer(&indexBufferDesc, &resourceData, &g_d3dIndexBuffer);
	if (FAILED(hResult))
		return false;

	D3D11_BUFFER_DESC constantBufferDesc;
	ZeroMemory(&constantBufferDesc, sizeof(D3D11_BUFFER_DESC));

	constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	constantBufferDesc.ByteWidth = sizeof(XMMATRIX);
	constantBufferDesc.CPUAccessFlags = 0;
	constantBufferDesc.Usage = D3D11_USAGE_DEFAULT;

	hResult = g_d3dDevice->CreateBuffer(&indexBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Application]);
	if (FAILED(hResult))
		return false;

	hResult = g_d3dDevice->CreateBuffer(&indexBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Frame]);
	if (FAILED(hResult))
		return false;

	hResult = g_d3dDevice->CreateBuffer(&indexBufferDesc, nullptr, &g_d3dConstantBuffers[CB_Object]);
	if (FAILED(hResult))
		return false;

#if _DEBUG
	LPCWSTR compiledVertexShaderObject = L"SimpleVertexShader_d.cso";
	LPCWSTR compiledPixelShaderObject = L"SimplePixelShader_d.cso";
#else
	LPCWSTR compiledVertexShaderObject = L"SimpleVertexShader.cso";
	LPCWSTR compiledPixelShaderObject = L"SimplePixelShader.cso";
#endif

	ID3DBlob *vertexShaderBlob;
	hResult = D3DReadFileToBlob(compiledVertexShaderObject, &vertexShaderBlob);
	if (FAILED(hResult))
		return false;

	ID3DBlob *pixelShaderBlob;
	hResult = D3DReadFileToBlob(compiledPixelShaderObject, &pixelShaderBlob);
	if (FAILED(hResult))
		return false;

	hResult = g_d3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &g_d3dVertexShader);
	if (FAILED(hResult))
		return false;

	hResult = g_d3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &g_d3dPixelShader);
	if (FAILED(hResult))
		return false;
}
Example #24
0
bool DXShaderCompiler::CompileShader(const std::string& source_file,
                                     const std::string& entry_point,
                                     const char* target,
                                     ShaderOpt opt_level, bool debug,
                                     const ShaderDefine* defines,
                                     size_t num_defines,
                                     std::vector<uint8_t>& output,
                                     YFileUtils::FileEnv* file_env) {
  std::string work_dir = YFileUtils::FilePath::DirPath(source_file);
  const std::vector<uint8_t>* source_data = GetFileData(source_file, file_env);

  std::vector<D3D_SHADER_MACRO> macros;
  for (size_t i = 0; i < num_defines; ++i) {
    macros.push_back({defines[i].define, defines[i].value});
  }
  macros.push_back({NULL, NULL});

  DXIncludeData include_data(work_dir, file_env);

  UINT flags1 = D3DCOMPILE_WARNINGS_ARE_ERRORS;
  switch (opt_level) {
   case kShaderOpt_None: flags1 |= D3DCOMPILE_SKIP_OPTIMIZATION; break;
   case kShaderOpt_Level0: flags1 |= D3DCOMPILE_OPTIMIZATION_LEVEL0; break;
   case kShaderOpt_Level1: flags1 |= D3DCOMPILE_OPTIMIZATION_LEVEL1; break;
   case kShaderOpt_Level2: flags1 |= D3DCOMPILE_OPTIMIZATION_LEVEL2; break;
   case kShaderOpt_Level3: flags1 |= D3DCOMPILE_OPTIMIZATION_LEVEL3; break;
   default:
     std::cerr << "Invalid Shader Opt: " << opt_level << std::endl;
     return false;
  }

  if (debug) {
    flags1 |= D3DCOMPILE_DEBUG;
  }

  ID3DBlob* code;
  ID3DBlob* error_msgs;

  HRESULT ret = D3DCompile2(
      source_data->data(), // in   LPCVOID pSrcData,
      source_data->size(), // in   SIZE_T SrcDataSize,
      source_file.c_str(), // in   LPCSTR pSourceName,
      macros.data(),       // in   const D3D_SHADER_MACRO *pDefines,
      &include_data,       // in   ID3DInclude *pInclude,
      entry_point.c_str(), // in   LPCSTR pEntrypoint,
      target,              // in   LPCSTR pTarget,
      flags1,              // in   UINT Flags1,
      0,                   // in   UINT Flags2,
      0,                   // in   UINT SecondaryDataFlags,
      NULL,                // in   LPCVOID pSecondaryData,
      0,                   // in   SIZE_T SecondaryDataSize,
      &code,               // out  ID3DBlob **ppCode,
      &error_msgs          // out  ID3DBlob **ppErrorMsgs
      );

  if (FAILED(ret)) {
    std::cerr << "[ERROR] "
              << static_cast<const char*>(error_msgs->GetBufferPointer())
              << std::endl;
    return false;
  }

  size_t code_size = code->GetBufferSize();
  output.resize(code_size);
  memcpy(output.data(), code->GetBufferPointer(), code_size);
  return true;
}
Example #25
0
HRESULT HorseObject::InitShader(ID3D11Device* device)
{
    HRESULT hr = S_OK;

    // alpha blend state
    D3D11_BLEND_DESC blendDesc;
    ZeroMemory(&blendDesc, sizeof(D3D11_BLEND_DESC));
    blendDesc.AlphaToCoverageEnable = FALSE;
    blendDesc.IndependentBlendEnable = FALSE;
    for (int i = 0; i < 8; ++i)
    {
        blendDesc.RenderTarget[i].BlendEnable = TRUE;
        blendDesc.RenderTarget[i].SrcBlend = D3D11_BLEND_SRC_ALPHA;
        blendDesc.RenderTarget[i].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
        blendDesc.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD;
        blendDesc.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_ONE;
        blendDesc.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_ZERO;
        blendDesc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD;
        blendDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
    }
    hr = device->CreateBlendState(&blendDesc, &alphaBlendState);
    if (FAILED(hr))
    {
        return hr;
    }

    // per-frame constant buffer
    D3D11_BUFFER_DESC bufferDesc;
    ZeroMemory(&bufferDesc, sizeof(D3D11_BUFFER_DESC));
    bufferDesc.ByteWidth = sizeof(ConstantBufferPerFrame);
    bufferDesc.Usage = D3D11_USAGE_DEFAULT;
    bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    bufferDesc.CPUAccessFlags = 0;
    hr = device->CreateBuffer(&bufferDesc, nullptr, &constantBufferPerFrame);
    if (FAILED(hr))
    {
        assert(false && "ID3D11Device::CreateBuffer() Failed.");
        return false;
    }

    // matrix palette
    ZeroMemory(&bufferDesc, sizeof(D3D11_BUFFER_DESC));
    bufferDesc.ByteWidth = sizeof(ConstantBufferSkinningMatrix);
    bufferDesc.Usage = D3D11_USAGE_DEFAULT;
    bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    bufferDesc.CPUAccessFlags = 0;
    hr = device->CreateBuffer(&bufferDesc, nullptr, &constantBufferSkinningBone);
    if (FAILED(hr))
    {
        assert(false && "ID3D11Device::CreateBuffer() Failed.");
        return hr;
    }

    // per-object constant buffer
    ZeroMemory(&bufferDesc, sizeof(D3D11_BUFFER_DESC));
    bufferDesc.ByteWidth = sizeof(ConstantBufferPerObj);
    bufferDesc.Usage = D3D11_USAGE_DEFAULT;
    bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    bufferDesc.CPUAccessFlags = 0;
    hr = device->CreateBuffer(&bufferDesc, nullptr, &constantBufferPerObj);
    if (FAILED(hr))
    {
        assert(false && "ID3D11Device::CreateBuffer() Failed.");
        return hr;
    }

    // vertex shader
    ID3DBlob* blob = nullptr;
    hr = CompileShaderFromFile(L"./ssdr.fx", "LambertSkinVS", "vs_5_0", blob);
    if (FAILED(hr))
    {
        if (blob != nullptr)
        {
            blob->Release();
        }
        return hr;
    }
    hr = device->CreateVertexShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &vertexShader);
    if (FAILED(hr))
    {
        assert(false && "CompileShaderFromFile() Failed");
        return false;
    }

    // vertex layout
    UINT numElements = ARRAYSIZE(customVertexLayout);
    hr = device->CreateInputLayout(customVertexLayout, numElements, blob->GetBufferPointer(), blob->GetBufferSize(), &inputLayout);
    if (blob != nullptr)
    {
        blob->Release();
    }
    if (FAILED(hr))
    {
        assert(false && "ID3D11Device::CreateInputLayout() Failed.");
        return false;
    }

    // pixel shader
    hr = CompileShaderFromFile(L"./ssdr.fx", "LambertPS", "ps_5_0", blob);
    if (FAILED(hr))
    {
        if (blob != nullptr)
        {
            blob->Release();
        }
        return hr;
    }
    hr = device->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, &pixelShader);
    if (FAILED(hr))
    {
        assert(false && "ID3D11Device::CreateVertexShader() Failed.");
        if (blob != nullptr)
        {
            blob->Release();
        }
        return hr;
    }
    if (blob != nullptr)
    {
        blob->Release();
    }
    return hr;
}
VOID InitEffects()
{
	ID3DBlob* pErrorBlob;

	// Create the effect
    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Set the D3D10_SHADER_DEBUG flag to embed debug information in the shaders.
    // Setting this flag improves the shader debugging experience, but still allows 
    // the shaders to be optimized and to run exactly the way they will run in 
    // the release configuration of this program.
    dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif

	// Compile the effects file
    HRESULT hr = D3DX10CreateEffectFromFile( 
		L"triangle_shader.fx", 
		NULL, 
		NULL, 
		"fx_4_0", 
		dwShaderFlags, 
		0,
        g_pd3dDevice, 
		NULL, 
		NULL, 
		&g_pEffect, 
		&pErrorBlob, 
		NULL
		);

    // Output the error message if compile failed
	if(FAILED(hr))
    {
        if(pErrorBlob != NULL)
		{
			OutputDebugString((WCHAR*)pErrorBlob->GetBufferPointer());
			pErrorBlob->Release();
		}
    }

	// Release the Blob
	if(pErrorBlob)
		pErrorBlob->Release();

    // Obtain the technique
    g_pTechnique = g_pEffect->GetTechniqueByName("Render");

    // Define the input layout
    D3D10_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = sizeof(layout) / sizeof(layout[0]);

    // Create the input layout
    D3D10_PASS_DESC PassDesc;
    g_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
    hr = g_pd3dDevice->CreateInputLayout(layout, numElements, PassDesc.pIAInputSignature,
                                          PassDesc.IAInputSignatureSize, &g_pVertexLayout);
    if(FAILED(hr))
	{
		MessageBox(NULL, L"Create input layout failed", L"Error", 0);
	}
}
Example #27
0
HRESULT Application::InitShadersAndInputLayout()
{
	HRESULT hr;

    // Compile the vertex shader
    ID3DBlob* pVSBlob = nullptr;
    hr = CompileShaderFromFile(L"DX11 Framework.fx", "VS", "vs_4_0", &pVSBlob);

    if (FAILED(hr))
    {
        MessageBox(nullptr,
                   L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
        return hr;
    }

	// Create the vertex shader
	hr = _pd3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &_pVertexShader);

	if (FAILED(hr))
	{	
		pVSBlob->Release();
        return hr;
	}

	// Compile the pixel shader
	ID3DBlob* pPSBlob = nullptr;
    hr = CompileShaderFromFile(L"DX11 Framework.fx", "PS", "ps_4_0", &pPSBlob);

    if (FAILED(hr))
    {
        MessageBox(nullptr,
                   L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
        return hr;
    }

	// Create the pixel shader
	hr = _pd3dDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &_pPixelShader);
	pPSBlob->Release();

    if (FAILED(hr))
        return hr;
	
    // Define the input layout
    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 },
	};

	UINT numElements = ARRAYSIZE(layout);

    // Create the input layout
	hr = _pd3dDevice->CreateInputLayout(layout, numElements, pVSBlob->GetBufferPointer(),
                                        pVSBlob->GetBufferSize(), &_pVertexLayout);
	pVSBlob->Release();

	if (FAILED(hr))
        return hr;

    // Set the input layout
    _pImmediateContext->IASetInputLayout(_pVertexLayout);

	D3D11_SAMPLER_DESC sampDesc;
	ZeroMemory(&sampDesc, sizeof(sampDesc));
	sampDesc.Filter = D3D11_FILTER_ANISOTROPIC;
	sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
	sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
	sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
	sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
	sampDesc.MinLOD = 0;
	sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
	hr = _pd3dDevice->CreateSamplerState(&sampDesc, &_pSamplerLinear);

	return hr;
}
// プログラマブルシェーダ作成
HRESULT MakeShaders( void )
{
    HRESULT hr;
    ID3DBlob* pVertexShaderBuffer = NULL;
    ID3DBlob* pPixelShaderBuffer = NULL;
    ID3DBlob* pError = NULL;

    DWORD dwShaderFlags = 0;
#ifdef _DEBUG
    dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif
    // コンパイル
    hr = D3DX11CompileFromFile( _T( "Basic_2D.fx" ), NULL, NULL, "VS", "vs_4_0_level_9_1",
								dwShaderFlags, 0, NULL, &pVertexShaderBuffer, &pError, NULL );
    if ( FAILED( hr ) ) {
		MessageBox( NULL, _T( "Can't open Basic_2D.fx" ), _T( "Error" ), MB_OK );
        SAFE_RELEASE( pError );
        return hr;
    }
    hr = D3DX11CompileFromFile( _T( "Basic_2D.fx" ), NULL, NULL, "PS", "ps_4_0_level_9_1",
								dwShaderFlags, 0, NULL, &pPixelShaderBuffer, &pError, NULL );
    if ( FAILED( hr ) ) {
        SAFE_RELEASE( pVertexShaderBuffer );
        SAFE_RELEASE( pError );
        return hr;
    }
    SAFE_RELEASE( pError );
    
    // VertexShader作成
    hr = g_pd3dDevice->CreateVertexShader( pVertexShaderBuffer->GetBufferPointer(),
										   pVertexShaderBuffer->GetBufferSize(),
										   NULL, &g_pVertexShader );
    if ( FAILED( hr ) ) {
        SAFE_RELEASE( pVertexShaderBuffer );
        SAFE_RELEASE( pPixelShaderBuffer );
        return hr;
    }
    // PixelShader作成
    hr = g_pd3dDevice->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer(),
										  pPixelShaderBuffer->GetBufferSize(),
										  NULL, &g_pPixelShader );
    if ( FAILED( hr ) ) {
        SAFE_RELEASE( pVertexShaderBuffer );
        SAFE_RELEASE( pPixelShaderBuffer );
        return hr;
    }

    // 入力バッファの入力形式
    D3D11_INPUT_ELEMENT_DESC layout[] = {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXTURE",  0, DXGI_FORMAT_R32G32_FLOAT,       0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
	UINT numElements = ARRAYSIZE( layout );
	// 入力バッファの入力形式作成
    hr = g_pd3dDevice->CreateInputLayout( layout, numElements,
										  pVertexShaderBuffer->GetBufferPointer(),
										  pVertexShaderBuffer->GetBufferSize(),
										  &g_pInputLayout );
    SAFE_RELEASE( pVertexShaderBuffer );
    SAFE_RELEASE( pPixelShaderBuffer );
    if ( FAILED( hr ) ) {
        return hr;
    }

    // シェーダ定数バッファ作成
    D3D11_BUFFER_DESC bd;
    ZeroMemory( &bd, sizeof( bd ) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( CBNeverChanges );
    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    bd.CPUAccessFlags = 0;
    hr = g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pCBNeverChanges );
    if( FAILED( hr ) )
        return hr;

	// 変換行列
    CBNeverChanges	cbNeverChanges;
	XMMATRIX		mScreen;
    mScreen = XMMatrixIdentity();
	mScreen._11 =  2.0f / g_nClientWidth;
	mScreen._22 = -2.0f / g_nClientHeight;
	mScreen._41 = -1.0f;
	mScreen._42 =  1.0f;
	cbNeverChanges.mView = XMMatrixTranspose( mScreen );
	g_pImmediateContext->UpdateSubresource( g_pCBNeverChanges, 0, NULL, &cbNeverChanges, 0, 0 );

    return S_OK;
}
// Compiles HLSL code into executable binaries
ShaderBlob *Renderer::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, UINT optimizationFlags, bool alternateFlags)
{
    if (!hlsl)
    {
        return NULL;
    }

    HRESULT result = S_OK;
    UINT flags = 0;
    std::string sourceText;
    if (gl::perfActive())
    {
        flags |= D3DCOMPILE_DEBUG;

#ifdef NDEBUG
        flags |= optimizationFlags;
#else
        flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
#endif

        std::string sourcePath = getTempPath();
        sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl);
        writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
    }
    else
    {
        flags |= optimizationFlags;
        sourceText = hlsl;
    }

    // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
    // Try the default flags first and if compilation fails, try some alternatives.
    const static UINT extraFlags[] =
    {
        0,
        D3DCOMPILE_AVOID_FLOW_CONTROL,
        D3DCOMPILE_PREFER_FLOW_CONTROL
    };

    const static char * const extraFlagNames[] =
    {
        "default",
        "avoid flow control",
        "prefer flow control"
    };

    int attempts = alternateFlags ? ArraySize(extraFlags) : 1;
    pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc);
    for (int i = 0; i < attempts; ++i)
    {
        ID3DBlob *errorMessage = NULL;
        ID3DBlob *binary = NULL;

        result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL,
                             "main", profile, flags | extraFlags[i], 0, &binary, &errorMessage);
        if (errorMessage)
        {
            const char *message = (const char*)errorMessage->GetBufferPointer();

            infoLog.appendSanitized(message);
            TRACE("\n%s", hlsl);
            TRACE("\n%s", message);

            errorMessage->Release();
            errorMessage = NULL;
        }

        if (SUCCEEDED(result))
        {
            return (ShaderBlob*)binary;
        }
        else
        {
            if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
            {
                return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*) NULL);
            }

            infoLog.append("Warning: D3D shader compilation failed with ");
            infoLog.append(extraFlagNames[i]);
            infoLog.append(" flags.");
            if (i + 1 < attempts)
            {
                infoLog.append(" Retrying with ");
                infoLog.append(extraFlagNames[i + 1]);
                infoLog.append(".\n");
            }
        }
    }

    return NULL;
}
// Create quad shaders
HRESULT CFW1GlyphRenderStates::createQuadShaders() {
	// Vertex shaders
	const char vsSimpleStr[] =
	"cbuffer ShaderConstants : register(b0) {\r\n"
	"	float4x4 TransformMatrix : packoffset(c0);\r\n"
	"};\r\n"
	"\r\n"
	"struct VSIn {\r\n"
	"	float4 Position : POSITION;\r\n"
	"	float4 GlyphColor : GLYPHCOLOR;\r\n"
	"};\r\n"
	"\r\n"
	"struct VSOut {\r\n"
	"	float4 Position : SV_Position;\r\n"
	"	float4 GlyphColor : COLOR;\r\n"
	"	float2 TexCoord : TEXCOORD;\r\n"
	"};\r\n"
	"\r\n"
	"VSOut VS(VSIn Input) {\r\n"
	"	VSOut Output;\r\n"
	"	\r\n"
	"	Output.Position = mul(TransformMatrix, float4(Input.Position.xy, 0.0f, 1.0f));\r\n"
	"	Output.GlyphColor = Input.GlyphColor;\r\n"
	"	Output.TexCoord = Input.Position.zw;\r\n"
	"	\r\n"
	"	return Output;\r\n"
	"}\r\n"
	"";
	
	const char vsClipStr[] =
	"cbuffer ShaderConstants : register(b0) {\r\n"
	"	float4x4 TransformMatrix : packoffset(c0);\r\n"
	"	float4 ClipRect : packoffset(c4);\r\n"
	"};\r\n"
	"\r\n"
	"struct VSIn {\r\n"
	"	float4 Position : POSITION;\r\n"
	"	float4 GlyphColor : GLYPHCOLOR;\r\n"
	"};\r\n"
	"\r\n"
	"struct VSOut {\r\n"
	"	float4 Position : SV_Position;\r\n"
	"	float4 GlyphColor : COLOR;\r\n"
	"	float2 TexCoord : TEXCOORD;\r\n"
	"	float4 ClipDistance : CLIPDISTANCE;\r\n"
	"};\r\n"
	"\r\n"
	"VSOut VS(VSIn Input) {\r\n"
	"	VSOut Output;\r\n"
	"	\r\n"
	"	Output.Position = mul(TransformMatrix, float4(Input.Position.xy, 0.0f, 1.0f));\r\n"
	"	Output.GlyphColor = Input.GlyphColor;\r\n"
	"	Output.TexCoord = Input.Position.zw;\r\n"
	"	Output.ClipDistance = ClipRect + float4(Input.Position.xy, -Input.Position.xy);\r\n"
	"	\r\n"
	"	return Output;\r\n"
	"}\r\n"
	"";
	
	// Shader compile profile
	const char *vs_profile = "vs_4_0_level_9_1";
	if(m_featureLevel >= D3D_FEATURE_LEVEL_11_0)
		vs_profile = "vs_5_0";
	else if(m_featureLevel >= D3D_FEATURE_LEVEL_10_0)
		vs_profile = "vs_4_0";
	else if(m_featureLevel >= D3D_FEATURE_LEVEL_9_3)
		vs_profile = "vs_4_0_level_9_3";
	
	// Compile vertex shader
	ID3DBlob *pVSCode;
	
	HRESULT hResult = m_pfnD3DCompile(
		vsSimpleStr,
		sizeof(vsSimpleStr),
		NULL,
		NULL,
		NULL,
		"VS",
		vs_profile,
		D3DCOMPILE_OPTIMIZATION_LEVEL3,
		0,
		&pVSCode,
		NULL
	);
	if(FAILED(hResult)) {
		m_lastError = L"Failed to compile vertex shader";
	}
	else {
		// Create vertex shader
		ID3D11VertexShader *pVS;
		
		hResult = m_pDevice->CreateVertexShader(pVSCode->GetBufferPointer(), pVSCode->GetBufferSize(), NULL, &pVS);
		if(FAILED(hResult)) {
			m_lastError = L"Failed to create vertex shader";
		}
		else {
			// Compile clipping vertex shader
			ID3DBlob *pVSClipCode;
			
			hResult = m_pfnD3DCompile(
				vsClipStr,
				sizeof(vsClipStr),
				NULL,
				NULL,
				NULL,
				"VS",
				vs_profile,
				D3DCOMPILE_OPTIMIZATION_LEVEL3,
				0,
				&pVSClipCode,
				NULL
			);
			if(FAILED(hResult)) {
				m_lastError = L"Failed to compile clipping vertex shader";
			}
			else {
				// Create vertex shader
				ID3D11VertexShader *pVSClip;
				
				hResult = m_pDevice->CreateVertexShader(
					pVSClipCode->GetBufferPointer(),
					pVSClipCode->GetBufferSize(),
					NULL,
					&pVSClip
				);
				if(FAILED(hResult)) {
					m_lastError = L"Failed to create clipping vertex shader";
				}
				else {
					// Create input layout
					ID3D11InputLayout *pInputLayout;
					
					// Quad vertex input layout
					D3D11_INPUT_ELEMENT_DESC inputElements[] = {
						{"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
						{"GLYPHCOLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}
					};
					
					hResult = m_pDevice->CreateInputLayout(
						inputElements,
						2,
						pVSCode->GetBufferPointer(),
						pVSCode->GetBufferSize(),
						&pInputLayout
					);
					if(FAILED(hResult)) {
						m_lastError = L"Failed to create input layout";
					}
					else {
						// Success
						m_pVertexShaderQuad = pVS;
						m_pVertexShaderClipQuad = pVSClip;
						m_pQuadInputLayout = pInputLayout;
						
						hResult = S_OK;
					}
					
					if(FAILED(hResult))
						pVSClip->Release();
				}
				
				pVSClipCode->Release();
			}
			
			if(FAILED(hResult))
				pVS->Release();
		}
		
		pVSCode->Release();
	}
	
	return hResult;
}