void MaterialCompiler::GenerateCode(MaterialGraph * materialGraph)
{
    // Generate pixel shader code
    String pixelShader;
    String vertexShader;
    
    for (uint32 nodeIndex = 0; nodeIndex < materialGraph->GetNodeCount(); ++nodeIndex)
    {
        MaterialGraphNode * node = materialGraph->GetNode(nodeIndex);
        GenerateCodeForNode(node, vertexShader, pixelShader);
    }
    
    //MaterialGraphNode * rootResultNode = materialGraph->GetNodeByName("material");

    FilePath materialPath(materialGraph->GetMaterialPathname().GetDirectory());
    FilePath vertexShaderPath(materialPath + materialGraph->GetVertexShaderFilename());
    FilePath fragmentShaderPath(materialPath + materialGraph->GetPixelShaderFilename());

    String originalVertexShader = FileSystem::Instance()->ReadFileContents(vertexShaderPath);
    String originalFragmentShader = FileSystem::Instance()->ReadFileContents(fragmentShaderPath);
    
    
    File * resultVsh = File::Create(materialCompiledVshName, File::CREATE | File::WRITE);
    resultVsh->WriteString(finalVertexShaderCode, false); // Save without null terminator
    resultVsh->WriteString(originalVertexShader);
    SafeRelease(resultVsh);
    
    File * resultFsh = File::Create(materialCompiledFshName, File::CREATE | File::WRITE);
    resultFsh->WriteString(finalPixelShaderCode, false); // Save without null terminator
    resultFsh->WriteString(originalFragmentShader);
    //resultFsh->Write(fragmentShaderData->GetPtr(), fragmentShaderData->GetSize());
    SafeRelease(resultFsh);
};
static bool EnsureD3D11ResourcesAreCreated()
{
    if (g_D3D11VertexShader)
        return true;

    // D3D11 has to load resources. Wait for Unity to provide the streaming assets path first.
    if (s_UnityStreamingAssetsPath.empty())
        return false;

    D3D11_BUFFER_DESC desc;
    memset (&desc, 0, sizeof(desc));

    // vertex buffer
    desc.Usage = D3D11_USAGE_DEFAULT;
    desc.ByteWidth = 1024;
    desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    g_D3D11Device->CreateBuffer (&desc, NULL, &g_D3D11VB);

    // constant buffer
    desc.Usage = D3D11_USAGE_DEFAULT;
    desc.ByteWidth = 64; // hold 1 matrix
    desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    desc.CPUAccessFlags = 0;
    g_D3D11Device->CreateBuffer (&desc, NULL, &g_D3D11CB);


    HRESULT hr = -1;
    Buffer vertexShader;
    Buffer pixelShader;
    std::string vertexShaderPath(s_UnityStreamingAssetsPath);
    vertexShaderPath += "/Shaders/DX11_9_1/SimpleVertexShader.cso";
    std::string fragmentShaderPath(s_UnityStreamingAssetsPath);
    fragmentShaderPath += "/Shaders/DX11_9_1/SimplePixelShader.cso";
    LoadFileIntoBuffer(vertexShaderPath, vertexShader);
    LoadFileIntoBuffer(fragmentShaderPath, pixelShader);

    if (vertexShader.size() > 0 && pixelShader.size() > 0)
    {
        hr = g_D3D11Device->CreateVertexShader(&vertexShader[0], vertexShader.size(), nullptr, &g_D3D11VertexShader);
        if (FAILED(hr)) DebugLog("Failed to create vertex shader.\n");
        hr = g_D3D11Device->CreatePixelShader(&pixelShader[0], pixelShader.size(), nullptr, &g_D3D11PixelShader);
        if (FAILED(hr)) DebugLog("Failed to create pixel shader.\n");
    }
    else
    {
        DebugLog("Failed to load vertex or pixel shader.\n");
    }
    // input layout
    if (g_D3D11VertexShader && vertexShader.size() > 0)
    {
        g_D3D11Device->CreateInputLayout (s_DX11InputElementDesc, 2, &vertexShader[0], vertexShader.size(), &g_D3D11InputLayout);
    }

    // render states
    D3D11_RASTERIZER_DESC rsdesc;
    memset (&rsdesc, 0, sizeof(rsdesc));
    rsdesc.FillMode = D3D11_FILL_SOLID;
    rsdesc.CullMode = D3D11_CULL_NONE;
    rsdesc.DepthClipEnable = TRUE;
    g_D3D11Device->CreateRasterizerState (&rsdesc, &g_D3D11RasterState);

    D3D11_DEPTH_STENCIL_DESC dsdesc;
    memset (&dsdesc, 0, sizeof(dsdesc));
    dsdesc.DepthEnable = TRUE;
    dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
    dsdesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
    g_D3D11Device->CreateDepthStencilState (&dsdesc, &g_D3D11DepthState);

    D3D11_BLEND_DESC bdesc;
    memset (&bdesc, 0, sizeof(bdesc));
    bdesc.RenderTarget[0].BlendEnable = FALSE;
    bdesc.RenderTarget[0].RenderTargetWriteMask = 0xF;
    g_D3D11Device->CreateBlendState (&bdesc, &g_D3D11BlendState);

    return true;
}