void MeshRenderer::LoadShaders()
{
    // Load the mesh shaders
    meshDepthVS = CompileVSFromFile(device, L"DepthOnly.hlsl", "VS", "vs_5_0");
    meshVS = CompileVSFromFile(device, L"Mesh.hlsl", "VS", "vs_5_0");
    meshPS = CompilePSFromFile(device, L"Mesh.hlsl", "PS", "ps_5_0");

    fullScreenVS = CompileVSFromFile(device, L"EVSMConvert.hlsl", "FullScreenVS");

    CompileOptions opts;
    opts.Add("MSAASamples_", ShadowMSAASamples);
    evsmConvertPS = CompilePSFromFile(device, L"EVSMConvert.hlsl", "ConvertToEVSM", "ps_5_0", opts);

    opts.Reset();
    opts.Add("Horizontal_", 1);
    opts.Add("Vertical_", 0);
    opts.Add("SampleRadius_", SampleRadius);
    evsmBlurH = CompilePSFromFile(device, L"EVSMConvert.hlsl", "BlurEVSM", "ps_5_0", opts);

    opts.Reset();
    opts.Add("Horizontal_", 0);
    opts.Add("Vertical_", 1);
    opts.Add("SampleRadius_", SampleRadius);
    evsmBlurV = CompilePSFromFile(device, L"EVSMConvert.hlsl", "BlurEVSM", "ps_5_0", opts);

    opts.Reset();
    opts.Add("MSAA_", 0);
    depthReductionInitialCS[0] = CompileCSFromFile(device, L"DepthReduction.hlsl", "DepthReductionInitialCS", "cs_5_0", opts);

    opts.Reset();
    opts.Add("MSAA_", 1);
    depthReductionInitialCS[1] = CompileCSFromFile(device, L"DepthReduction.hlsl", "DepthReductionInitialCS", "cs_5_0", opts);

    depthReductionCS = CompileCSFromFile(device, L"DepthReduction.hlsl", "DepthReductionCS");
}
Example #2
0
void MeshRenderer::GenVSRecursive(ID3D11Device *device, int depth, bool32 *descStates, CompileOptions *opts, 
	const wchar *path, const char *entryName, const char **shaderDescs, int numDescs, std::unordered_map<uint32, VertexShaderPtr> &out)
{
	if (depth == numDescs)
	{
		if (RenderShaderProgress(_curShaderNum++, _totalShaderNum) == false)
			return;

		opts->Reset();
		for (int i = 0; i < numDescs; i++)
		{
			opts->Add(shaderDescs[i], descStates[i]);
		}

		uint32 bits = boolArrToUint32(descStates, numDescs);
		VertexShaderPtr ptr = CompileVSFromFile(device, path, entryName, "vs_5_0", *opts);
		out.insert(std::make_pair(bits, ptr));
	}
	else
	{
		for (int i = 0; i < 2; i++)
		{
			descStates[numDescs - 1 - depth] = i;
			GenVSRecursive(device, depth + 1, descStates, opts, path, entryName, shaderDescs, numDescs, out);
		}
	}
}
void PostProcessorBase::Initialize(ID3D11Device* device)
{
    this->device = device;

    // Create resources for the full-screen quad

    // Load the shaders
    std::wstring quadPath = SampleFrameworkDir() + L"Shaders\\Quad.hlsl";
    quadVS = CompileVSFromFile(device, quadPath.c_str(), "QuadVS");

    // Create the input layout
    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };

    DXCall(device->CreateInputLayout(layout, 2, quadVS->ByteCode->GetBufferPointer(),
                                     quadVS->ByteCode->GetBufferSize(), &quadInputLayout));

    // Create and initialize the vertex and index buffers
    QuadVertex verts[4] =
    {
        { XMFLOAT4(1, 1, 1, 1), XMFLOAT2(1, 0) },
        { XMFLOAT4(1, -1, 1, 1), XMFLOAT2(1, 1) },
        { XMFLOAT4(-1, -1, 1, 1), XMFLOAT2(0, 1) },
        { XMFLOAT4(-1, 1, 1, 1), XMFLOAT2(0, 0) }
    };

    D3D11_BUFFER_DESC desc;
    desc.Usage = D3D11_USAGE_IMMUTABLE;
    desc.ByteWidth = sizeof(verts);
    desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    desc.CPUAccessFlags = 0;
    desc.MiscFlags = 0;
    D3D11_SUBRESOURCE_DATA initData;
    initData.pSysMem = verts;
    initData.SysMemPitch = 0;
    initData.SysMemSlicePitch = 0;
    DXCall(device->CreateBuffer(&desc, &initData, &quadVB));

    unsigned short indices[6] = { 0, 1, 2, 2, 3, 0 };

    desc.Usage = D3D11_USAGE_IMMUTABLE;
    desc.ByteWidth = sizeof(indices);
    desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
    desc.CPUAccessFlags = 0;
    initData.pSysMem = indices;
    DXCall(device->CreateBuffer(&desc, &initData, &quadIB));

    // Create the constant buffer
    desc.Usage = D3D11_USAGE_DYNAMIC;
    desc.ByteWidth = CBSize(sizeof(PSConstants));
    desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    DXCall(device->CreateBuffer(&desc, nullptr, &psConstants));

    // Create a depth-stencil state
    D3D11_DEPTH_STENCIL_DESC dsDesc;
    dsDesc.DepthEnable = false;
    dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
    dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
    dsDesc.StencilEnable = false;
    dsDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
    dsDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
    dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
    dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
    dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
    dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    dsDesc.BackFace = dsDesc.FrontFace;
    DXCall(device->CreateDepthStencilState(&dsDesc, &dsState));

    // Create a blend state
    D3D11_BLEND_DESC blendDesc;
    blendDesc.AlphaToCoverageEnable = false;
    blendDesc.IndependentBlendEnable = false;
    for (uint32 i = 0; i < 8; ++i)
    {
        blendDesc.RenderTarget[i].BlendEnable = false;
        blendDesc.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD;
        blendDesc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD;
        blendDesc.RenderTarget[i].DestBlend = D3D11_BLEND_ONE;
        blendDesc.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_ONE;
        blendDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
        blendDesc.RenderTarget[i].SrcBlend = D3D11_BLEND_ONE;
        blendDesc.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_ONE;
    }
    DXCall(device->CreateBlendState(&blendDesc, &blendState));

    // Create a rasterizer state
    D3D11_RASTERIZER_DESC rastDesc;
    rastDesc.AntialiasedLineEnable = false;
    rastDesc.CullMode = D3D11_CULL_NONE;
    rastDesc.DepthBias = 0;
    rastDesc.DepthBiasClamp = 0.0f;
    rastDesc.DepthClipEnable = true;
    rastDesc.FillMode = D3D11_FILL_SOLID;
    rastDesc.FrontCounterClockwise = false;
    rastDesc.MultisampleEnable = true;
    rastDesc.ScissorEnable = false;
    rastDesc.SlopeScaledDepthBias = 0;
    DXCall(device->CreateRasterizerState(&rastDesc, &rastState));

    // Create sampler states
    D3D11_SAMPLER_DESC sampDesc;
    sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
    sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
    sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.BorderColor[0] = 0;
    sampDesc.BorderColor[1] = 0;
    sampDesc.BorderColor[2] = 0;
    sampDesc.BorderColor[3] = 0;
    sampDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
    sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    sampDesc.MaxAnisotropy = 1;
    sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
    sampDesc.MinLOD = 0;
    sampDesc.MipLODBias = 0;
    DXCall(device->CreateSamplerState(&sampDesc, &linearSamplerState));

    sampDesc.AddressU = sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    DXCall(device->CreateSamplerState(&sampDesc, &linearWrapSamplerState));

    sampDesc.AddressU = sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
    DXCall(device->CreateSamplerState(&sampDesc, &linearBorderSamplerState));

    sampDesc.AddressU = sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
    sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
    DXCall(device->CreateSamplerState(&sampDesc, &pointSamplerState));

    sampDesc.AddressU = sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
    DXCall(device->CreateSamplerState(&sampDesc, &pointBorderSamplerState));
}
void SpriteRenderer::Initialize(ID3D11Device* device)
{
    this->device = device;

    // Load the shaders
    vertexShader = CompileVSFromFile(device, L"SampleFramework11\\Shaders\\Sprite.hlsl", "SpriteVS", "vs_4_0");
    vertexShaderInstanced = CompileVSFromFile(device, L"SampleFramework11\\Shaders\\Sprite.hlsl", "SpriteInstancedVS", "vs_4_0");
    pixelShader = CompilePSFromFile(device, L"SampleFramework11\\Shaders\\Sprite.hlsl", "SpritePS", "ps_4_0");

    // Define the input layouts
    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
    };

    DXCall(device->CreateInputLayout(layout, 2, vertexShader->ByteCode->GetBufferPointer(),
                                     vertexShader->ByteCode->GetBufferSize(), &inputLayout));

    D3D11_INPUT_ELEMENT_DESC layoutInstanced[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TRANSFORM", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
        { "TRANSFORM", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
        { "TRANSFORM", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 32, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
        { "TRANSFORM", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 48, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 64, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
        { "SOURCERECT", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 80, D3D11_INPUT_PER_INSTANCE_DATA, 1 }
    };

    DXCall(device->CreateInputLayout(layoutInstanced, 8, vertexShaderInstanced->ByteCode->GetBufferPointer(),
                                     vertexShaderInstanced->ByteCode->GetBufferSize(), &inputLayoutInstanced));

    // Create the vertex buffer
    SpriteVertex verts[] =
    {
        { Float2(0.0f, 0.0f), Float2(0.0f, 0.0f) },
        { Float2(1.0f, 0.0f), Float2(1.0f, 0.0f) },
        { Float2(1.0f, 1.0f), Float2(1.0f, 1.0f) },
        { Float2(0.0f, 1.0f), Float2(0.0f, 1.0f) }
    };

    D3D11_BUFFER_DESC desc;
    desc.Usage = D3D11_USAGE_IMMUTABLE;
    desc.ByteWidth = sizeof(SpriteVertex) * 4;
    desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    desc.CPUAccessFlags = 0;
    desc.MiscFlags = 0;

    D3D11_SUBRESOURCE_DATA initData;
    initData.pSysMem = verts;
    initData.SysMemPitch = 0;
    initData.SysMemSlicePitch = 0;
    DXCall(device->CreateBuffer(&desc, &initData, &vertexBuffer));

    // Create the instance data buffer
    desc.Usage = D3D11_USAGE_DYNAMIC;
    desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    desc.ByteWidth = sizeof(SpriteDrawData) * MaxBatchSize;
    DXCall(device->CreateBuffer(&desc, nullptr, &instanceDataBuffer));

    // Create the index buffer
    uint16 indices[] = { 0, 1, 2, 3, 0, 2 };
    desc.Usage = D3D11_USAGE_IMMUTABLE;
    desc.ByteWidth = sizeof(uint16) * 6;
    desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
    desc.CPUAccessFlags = 0;
    initData.pSysMem = indices;
    DXCall(device->CreateBuffer(&desc, &initData, &indexBuffer));

    // Create our constant buffers
    desc.Usage = D3D11_USAGE_DYNAMIC;
    desc.ByteWidth = CBSize(sizeof(VSPerBatchCB));
    desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    DXCall(device->CreateBuffer(&desc, nullptr, &vsPerBatchCB));

    desc.ByteWidth = CBSize(sizeof(SpriteDrawData));
    DXCall(device->CreateBuffer(&desc, nullptr, &vsPerInstanceCB));

    // Create our states
    D3D11_RASTERIZER_DESC rastDesc;
    rastDesc.AntialiasedLineEnable = false;
    rastDesc.CullMode = D3D11_CULL_NONE;
    rastDesc.DepthBias = 0;
    rastDesc.DepthBiasClamp = 1.0f;
    rastDesc.DepthClipEnable = false;
    rastDesc.FillMode = D3D11_FILL_SOLID;
    rastDesc.FrontCounterClockwise = false;
    rastDesc.MultisampleEnable = true;
    rastDesc.ScissorEnable = false;
    rastDesc.SlopeScaledDepthBias = 0;
    DXCall(device->CreateRasterizerState(&rastDesc, &rastState));

    D3D11_BLEND_DESC blendDesc;
    blendDesc.AlphaToCoverageEnable = false;
    blendDesc.IndependentBlendEnable = false;
    for(UINT i = 0; i < 8; ++i)
    {
        blendDesc.RenderTarget[i].BlendEnable = true;
        blendDesc.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD;
        blendDesc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD;
        blendDesc.RenderTarget[i].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
        blendDesc.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_ONE;
        blendDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
        blendDesc.RenderTarget[i].SrcBlend = D3D11_BLEND_ONE;
        blendDesc.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_ONE;
    }
    DXCall(device->CreateBlendState(&blendDesc, &alphaBlendState));

    D3D11_DEPTH_STENCIL_DESC dsDesc;
    dsDesc.DepthEnable = false;
    dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
    dsDesc.DepthFunc = D3D11_COMPARISON_LESS;
    dsDesc.StencilEnable = false;
    dsDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
    dsDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
    dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
    dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
    dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
    dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    dsDesc.BackFace = dsDesc.FrontFace;
    DXCall(device->CreateDepthStencilState(&dsDesc, &dsState));

    // linear filtering
    D3D11_SAMPLER_DESC sampDesc;
    sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.BorderColor[0] = 0;
    sampDesc.BorderColor[1] = 0;
    sampDesc.BorderColor[2] = 0;
    sampDesc.BorderColor[3] = 0;
    sampDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
    sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    sampDesc.MaxAnisotropy = 1;
    sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
    sampDesc.MinLOD = 0;
    sampDesc.MipLODBias = 0;
    DXCall(device->CreateSamplerState(&sampDesc, &linearSamplerState));

    // point filtering
    sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
    DXCall(device->CreateSamplerState(&sampDesc, &pointSamplerState));

    initialized = true;
}
Example #5
0
void MeshRenderer::LoadShaders()
{
	_totalShaderNum = (int)pow(2, 5) + (int)pow(2, 8) + 8;

    CompileOptions opts;

	// Mesh.hlsl
	const char *vsDescs[] = { "UseNormalMapping_", "UseAlbedoMap_", "UseMetallicMap_", "UseRoughnessMap_", "UseEmissiveMap_" };
	const char *psDescs[] = { "UseNormalMapping_", "UseAlbedoMap_", "UseMetallicMap_", "UseRoughnessMap_", "UseEmissiveMap_", "CreateCubemap_", "CentroidSampling_", "IsGBuffer_" };
	GenVSShaderPermutations(_device, L"Mesh.hlsl", "VS", vsDescs, _countof(vsDescs), _meshVertexShaders);
	GenPSShaderPermutations(_device, L"Mesh.hlsl", "PS", psDescs, _countof(psDescs), _meshPixelShaders);

	// DepthOnly.hlsl
	_meshDepthVS = CompileVSFromFile(_device, L"DepthOnly.hlsl", "VS", "vs_5_0");
	if (RenderShaderProgress(_curShaderNum++, _totalShaderNum) == false)
		return;

	// EVSMConvert.hlsl
    _fullScreenVS = CompileVSFromFile(_device, L"EVSMConvert.hlsl", "FullScreenVS");
	if (RenderShaderProgress(_curShaderNum++, _totalShaderNum) == false)
		return;

    opts.Reset();
    opts.Add("MSAASamples_", ShadowMSAASamples);
    _evsmConvertPS = CompilePSFromFile(_device, L"EVSMConvert.hlsl", "ConvertToEVSM", "ps_5_0", opts);
	if (RenderShaderProgress(_curShaderNum++, _totalShaderNum) == false)
		return;

    opts.Reset();
    opts.Add("Horizontal_", 1);
    opts.Add("Vertical_", 0);
    opts.Add("SampleRadius_", SampleRadius);
    _evsmBlurH = CompilePSFromFile(_device, L"EVSMConvert.hlsl", "BlurEVSM", "ps_5_0", opts);
	if (RenderShaderProgress(_curShaderNum++, _totalShaderNum) == false)
		return;

    opts.Reset();
    opts.Add("Horizontal_", 0);
    opts.Add("Vertical_", 1);
    opts.Add("SampleRadius_", SampleRadius);
    _evsmBlurV = CompilePSFromFile(_device, L"EVSMConvert.hlsl", "BlurEVSM", "ps_5_0", opts);
	if (RenderShaderProgress(_curShaderNum++, _totalShaderNum) == false)
		return;

	// DepthReduction.hlsl
    opts.Reset();
    opts.Add("MSAA_", 0);
    _depthReductionInitialCS[0] = CompileCSFromFile(_device, L"DepthReduction.hlsl", "DepthReductionInitialCS", "cs_5_0", opts);
	if (RenderShaderProgress(_curShaderNum++, _totalShaderNum) == false)
		return;

    opts.Reset();
    opts.Add("MSAA_", 1);
    _depthReductionInitialCS[1] = CompileCSFromFile(_device, L"DepthReduction.hlsl", "DepthReductionInitialCS", "cs_5_0", opts);
	if (RenderShaderProgress(_curShaderNum++, _totalShaderNum) == false)
		return;

    _depthReductionCS = CompileCSFromFile(_device, L"DepthReduction.hlsl", "DepthReductionCS");
	if (RenderShaderProgress(_curShaderNum++, _totalShaderNum) == false)
		return;
}
Example #6
0
void Skybox::Initialize(ID3D11Device* device)
{
    // Load the shaders
    ID3D10BlobPtr byteCode;
    vertexShader.Attach(CompileVSFromFile(device, L"SampleFramework11\\Shaders\\Skybox.hlsl", "SkyboxVS", "vs_4_0", NULL, NULL, &byteCode));
    pixelShader.Attach(CompilePSFromFile(device, L"SampleFramework11\\Shaders\\Skybox.hlsl", "SkyboxPS"));

    // Create the input layout
    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };

    DXCall(device->CreateInputLayout(layout, 1, byteCode->GetBufferPointer(), byteCode->GetBufferSize(), &inputLayout));

    // Create and initialize the vertex and index buffers
    XMFLOAT3 verts[NumVertices] =
    {
        XMFLOAT3(-1, 1, 1),
        XMFLOAT3(1, 1, 1),
        XMFLOAT3(1, -1, 1),
        XMFLOAT3(-1, -1, 1),
        XMFLOAT3(1, 1, -1),
        XMFLOAT3(-1, 1, -1),
        XMFLOAT3(-1, -1, -1),
        XMFLOAT3(1, -1,- 1),
    };

    D3D11_BUFFER_DESC desc;
    desc.Usage = D3D11_USAGE_IMMUTABLE;
    desc.ByteWidth = sizeof(verts);
    desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    desc.CPUAccessFlags = 0;
    desc.MiscFlags = 0;
    D3D11_SUBRESOURCE_DATA initData;
    initData.pSysMem = verts;
    initData.SysMemPitch = 0;
    initData.SysMemSlicePitch = 0;
    DXCall(device->CreateBuffer(&desc, &initData, &vertexBuffer));

    unsigned short indices[NumIndices] =
    {
        0, 1, 2, 2, 3, 0,   // Front
        1, 4, 7, 7, 2, 1,   // Right
        4, 5, 6, 6, 7, 4,   // Back
        5, 0, 3, 3, 6, 5,   // Left
        5, 4, 1, 1, 0, 5,   // Top
        3, 2, 7, 7, 6, 3    // Bottom
    };

    desc.Usage = D3D11_USAGE_IMMUTABLE;
    desc.ByteWidth = sizeof(indices);
    desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
    desc.CPUAccessFlags = 0;
    initData.pSysMem = indices;
    DXCall(device->CreateBuffer(&desc, &initData, &indexBuffer));

    // Create the constant buffer
    desc.Usage = D3D11_USAGE_DYNAMIC;
    desc.ByteWidth = CBSize(sizeof(VSConstants));
    desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    DXCall(device->CreateBuffer(&desc, NULL, &constantBuffer));

    // Create a depth-stencil state
    D3D11_DEPTH_STENCIL_DESC dsDesc;
    dsDesc.DepthEnable = true;
    dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
    dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
    dsDesc.StencilEnable = false;
    dsDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
    dsDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
    dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
    dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
    dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
    dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    dsDesc.BackFace = dsDesc.FrontFace;
    DXCall(device->CreateDepthStencilState(&dsDesc, &dsState));

    // Create a blend state
    D3D11_BLEND_DESC blendDesc;
    blendDesc.AlphaToCoverageEnable = false;
    blendDesc.IndependentBlendEnable = false;
    for (UINT i = 0; i < 8; ++i)
    {
        blendDesc.RenderTarget[i].BlendEnable = false;
        blendDesc.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD;
        blendDesc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD;
        blendDesc.RenderTarget[i].DestBlend = D3D11_BLEND_ONE;
        blendDesc.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_ONE;
        blendDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
        blendDesc.RenderTarget[i].SrcBlend = D3D11_BLEND_ONE;
        blendDesc.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_ONE;
    }
    DXCall(device->CreateBlendState(&blendDesc, &blendState));

    // Create a rasterizer state
    D3D11_RASTERIZER_DESC rastDesc;
    rastDesc.AntialiasedLineEnable = FALSE;
    rastDesc.CullMode = D3D11_CULL_NONE;
    rastDesc.DepthBias = 0;
    rastDesc.DepthBiasClamp = 0.0f;
    rastDesc.DepthClipEnable = TRUE;
    rastDesc.FillMode = D3D11_FILL_SOLID;
    rastDesc.FrontCounterClockwise = false;
    rastDesc.MultisampleEnable = true;
    rastDesc.ScissorEnable = false;
    rastDesc.SlopeScaledDepthBias = 0;
    DXCall(device->CreateRasterizerState(&rastDesc, &rastState));

    D3D11_SAMPLER_DESC sampDesc;
    sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.BorderColor[0] = 0;
    sampDesc.BorderColor[1] = 0;
    sampDesc.BorderColor[2] = 0;
    sampDesc.BorderColor[3] = 0;
    sampDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
    sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    sampDesc.MaxAnisotropy = 1;
    sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
    sampDesc.MinLOD = 0;
    sampDesc.MipLODBias = 0;
    DXCall(device->CreateSamplerState(&sampDesc, &samplerState));
}