// Retrieve specified pixel shader
//-----------------------------------------------------------------------------
CPUTResult CPUTAssetLibraryDX11::GetPixelShader(
    const cString        &name,
    ID3D11Device         *pD3dDevice,
    const cString        &shaderMain,
    const cString        &shaderProfile,
    CPUTPixelShaderDX11 **ppPixelShader,
    bool                  nameIsFullPathAndFilename
)
{
    CPUTResult result = CPUT_SUCCESS;
    cString finalName;
    if( name.at(0) == '$' )
    {
        finalName = name;
    } else
    {
        // Resolve name to absolute path
        CPUTOSServices *pServices = CPUTOSServices::GetOSServices();
        pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (mShaderDirectoryName + name), &finalName);
    }

    // see if the shader is already in the library
    void *pShader = FindPixelShader(finalName + shaderMain + shaderProfile, true);
    if(NULL!=pShader)
    {
        *ppPixelShader = (CPUTPixelShaderDX11*) pShader;
        (*ppPixelShader)->AddRef();
        return result;
    }
    *ppPixelShader = CPUTPixelShaderDX11::CreatePixelShader( finalName, pD3dDevice, shaderMain, shaderProfile );

    return result;
}
//==============================================================================
PixelShader * CGraphicsMgr::FindPixelShaderRaii (const std::wstring & name) {

    PixelShader * result = FindPixelShader(name);
    
    if (!result) {
        m_pixelShaders.push_back(PixelShader());
        result = &m_pixelShaders.back();
    }
    
    return result;

}
//-----------------------------------------------------------------------------
CPUTResult CPUTAssetLibraryDX11::CreateComputeShaderFromMemory(
    const cString          &name,
    ID3D11Device           *pD3dDevice,
    const cString          &shaderMain,
    const cString          &shaderProfile,
    CPUTComputeShaderDX11 **ppShader,
    char                   *pShaderSource
)
{
    CPUTResult result = CPUT_SUCCESS;
    void *pShader = FindPixelShader(name + shaderMain + shaderProfile, true);
    ASSERT( NULL == pShader, _L("Shader already exists.") );
    *ppShader = CPUTComputeShaderDX11::CreateComputeShaderFromMemory( name, pD3dDevice, shaderMain, shaderProfile, pShaderSource);
    return result;
}
// Retrieve specified pixel shader
// TODO: Delegate creation to asset (AssetLibrary shouldn't know the nitty-gritty details of how to create an asset)
//-----------------------------------------------------------------------------
CPUTResult CPUTAssetLibraryOGLES::GetPixelShader(
    const cString        &name,
    const cString        &shaderMain,
    const cString        &shaderProfile,
    CPUTPixelShaderOGLES **ppPixelShader,
    bool                  nameIsFullPathAndFilename
)
{
    CPUTResult result = CPUT_SUCCESS;
    
    // Resolve name to absolute path before searching
    cString absolutePathAndFilename;
    CPUTOSServices* pServices = CPUTOSServices::GetOSServices();
    pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (m_ShaderDirectoryName + name), &absolutePathAndFilename);

    // see if the shader is already in the library
    void *pShader = FindPixelShader(absolutePathAndFilename);
    if(NULL!=pShader)
    {
        *ppPixelShader = (CPUTPixelShaderOGLES*) pShader;
        (*ppPixelShader)->AddRef();
        return result;
    }

    // load the pixel shader as null-terminated char* string
    void* pShaderString=NULL;
    result = LoadShaderFileString(absolutePathAndFilename, &pShaderString);
    ASSERT( CPUTSUCCESS(result), _L("Error loading pixel shader: ")+name );

    // compile the pixel/fragment shader
    GLuint NewPixelShaderID = CompileShader(GL_FRAGMENT_SHADER, pShaderString);
    ASSERT( (0!=NewPixelShaderID), _L("Error compiling pixel shader: "+name) );

    // delete the shader's string now that it's no longer needed
    delete [] pShaderString;
    
    // store this new shader
    CPUTPixelShaderOGLES *pNewCPUTPixelShader = new CPUTPixelShaderOGLES( NewPixelShaderID );

    // add shader to library
    AddPixelShader(absolutePathAndFilename, pNewCPUTPixelShader);
    
    // return the shader 
    *ppPixelShader = pNewCPUTPixelShader;

    return result;
}
CPUTResult CPUTAssetLibraryOGL::GetPixelShader(
    const std::vector<cString>  &fileNames,
    const cString               &shaderMain,
    const cString               &shaderProfile,
    CPUTShaderOGL          **ppPixelShader,
    bool                        nameIsFullPathAndFilename,
    CPUT_SHADER_MACRO           *pShaderMacros
)
{
    CPUTResult result = CPUT_SUCCESS;
    std::vector<cString> finalNames;
    cString libName;
    for(UINT i=0; i<fileNames.size(); i++)   
    {   
        cString name = fileNames[i];
        cString finalName;
        if( fileNames[i].at(0) == '%' )
        {
            // Consider moving slashes to some sub variable dependent from OS,
            // or even MACRO would be better in such situation.
            finalName = mSystemDirectoryName + _L("Shader/") + name.substr(1);  // TODO: Instead of having the Shader/ directory hardcoded here it could be set like the normal material directory. But then there would need to be a bunch new variables like SetSystemMaterialDirectory
        } else if( fileNames[i].at(0) == '$' )
        {
            finalName = fileNames[i];
        } else
        {
            CPUTFileSystem::ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (mShaderDirectoryName + name), &finalName );
        }
        libName += finalName;
        finalNames.push_back(finalName);
    }
    // see if the shader is already in the library
    void *pShader = FindPixelShader(libName + shaderMain + shaderProfile, true);
    if(NULL!=pShader)
    {
        *ppPixelShader = (CPUTShaderOGL*)pShader;
        (*ppPixelShader)->AddRef();
        return result;
    }
    *ppPixelShader = CPUTShaderOGL::CreateShaderFromFiles( finalNames, GL_FRAGMENT_SHADER, CPUT_OGL::GLSL_VERSION, CPUT_OGL::DEFAULT_MACROS, pShaderMacros);

    return result;
}