static string GetExpandedShaderCode(const wchar* path, GrowableList<wstring>& filePaths)
{
    for(uint64 i = 0; i < filePaths.Count(); ++i)
        if(filePaths[i] == path)
            return string();

    filePaths.Add(path);

    string fileContents = ReadFileAsString(path);

    // Look for includes
    size_t lineStart = 0;
    while(true)
    {
        size_t lineEnd = fileContents.find('\n', lineStart);
        size_t lineLength = 0;
        if(lineEnd == string::npos)
            lineLength = string::npos;
        else
            lineLength = lineEnd - lineStart;

        string line = fileContents.substr(lineStart, lineLength);
        if(line.find("#include") == 0)
        {
            wstring fullIncludePath;
            size_t startQuote = line.find('\"');
            if(startQuote != -1)
            {
                size_t endQuote = line.find('\"', startQuote + 1);
                string includePath = line.substr(startQuote + 1, endQuote - startQuote - 1);
                fullIncludePath = AnsiToWString(includePath.c_str());
            }
            else
            {
                startQuote = line.find('<');
                if(startQuote == -1)
                    throw Exception(L"Malformed include statement: \"" + AnsiToWString(line.c_str()) + L"\" in file " + path);
                size_t endQuote = line.find('>', startQuote + 1);
                string includePath = line.substr(startQuote + 1, endQuote - startQuote - 1);
                fullIncludePath = SampleFrameworkDir() + L"Shaders\\" + AnsiToWString(includePath.c_str());
            }

            if(FileExists(fullIncludePath.c_str()) == false)
                throw Exception(L"Couldn't find #included file \"" + fullIncludePath + L"\" in file " + path);

            string includeCode = GetExpandedShaderCode(fullIncludePath.c_str(), filePaths);
            fileContents.insert(lineEnd + 1, includeCode);
            lineEnd += includeCode.length();
        }

        if(lineEnd == string::npos)
            break;

        lineStart = lineEnd + 1;
    }

    return fileContents;
}
Esempio n. 2
0
void Model::CreateFromXFile(ID3D11Device* device, LPCWSTR fileName,
    const WCHAR* normalMapSuffix, bool generateNormals,
    bool generateTangentFrame, Mesh::IndexType idxType)
{
    _ASSERT(FileExists(fileName));

    IDirect3DDevice9Ptr d3d9Device = CreateD3D9Device();

    // Load the D3DX mesh
    ID3DXMesh* d3dxMesh = NULL;
    ID3DXBuffer* adjacencyBuffer = NULL;
    ID3DXBuffer* materialsBuffer = NULL;
    DWORD numMaterials = 0;

    UINT options = D3DXMESH_MANAGED;
    if (idxType == Mesh::Index32Bit)
        options |= D3DXMESH_32BIT;
    DXCall(D3DXLoadMeshFromXW(fileName, options, d3d9Device, &adjacencyBuffer,
        &materialsBuffer, NULL, &numMaterials, &d3dxMesh));

    IUnknownReleaser<ID3DXMesh> meshReleaser(d3dxMesh);
    IUnknownReleaser<ID3DXBuffer> adjReleaser(adjacencyBuffer);
    IUnknownReleaser<ID3DXBuffer> matReleaser(materialsBuffer);

    DWORD* initalAdjacency = reinterpret_cast<DWORD*>(adjacencyBuffer->GetBufferPointer());
    D3DXMATERIAL* materials = reinterpret_cast<D3DXMATERIAL*>(materialsBuffer->GetBufferPointer());

    // Get the directory the mesh was loaded from
    wstring fileDirectory = GetDirectoryFromFileName(fileName);

    // Convert materials
    for (UINT i = 0; i < numMaterials; ++i)
    {
        MeshMaterial material;
        D3DXMATERIAL& srcMaterial = materials[i];

        material.AmbientAlbedo = XMFLOAT3(reinterpret_cast<float*>(&srcMaterial.MatD3D.Ambient));
        material.DiffuseAlbedo = XMFLOAT3(reinterpret_cast<float*>(&srcMaterial.MatD3D.Diffuse));
        material.SpecularAlbedo = XMFLOAT3(reinterpret_cast<float*>(&srcMaterial.MatD3D.Specular));
        material.Emissive = XMFLOAT3(reinterpret_cast<float*>(&srcMaterial.MatD3D.Emissive));
        material.SpecularPower = srcMaterial.MatD3D.Power;
        material.Alpha = srcMaterial.MatD3D.Diffuse.a;
        material.DiffuseMapName = AnsiToWString(srcMaterial.pTextureFilename);

        // Add the normal map prefix
        if (normalMapSuffix && material.DiffuseMapName.length() > 0)
        {
            wstring base = GetFileNameWithoutExtension(material.DiffuseMapName.c_str());
            wstring extension = GetFileExtension(material.DiffuseMapName.c_str());
            material.NormalMapName = base + normalMapSuffix + L"." + extension;
        }

        LoadMaterialResources(material, fileDirectory, device);
    }

    // Make a single mesh
    Mesh mesh;
    mesh.CreateFromD3DXMesh(fileDirectory, device, d3d9Device, d3dxMesh, generateNormals, generateTangentFrame, initalAdjacency, idxType);
    meshes.push_back(mesh);
}
    HRESULT Open(D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID* ppData, UINT* pBytes) override
    {
        std::wstring filePath;
        if(IncludeType == D3D_INCLUDE_LOCAL)
            filePath = AnsiToWString(pFileName);
        else if(IncludeType == D3D_INCLUDE_SYSTEM)
            filePath = SampleFrameworkDir() + L"Shaders\\" + AnsiToWString(pFileName);
        else
            return E_FAIL;

        if(FileExists(filePath.c_str()) == false)
            return E_FAIL;
        File file(filePath.c_str(), FileOpenMode::Read);
        *pBytes = UINT(file.Size());
        uint8* data = reinterpret_cast<uint8*>(std::malloc(*pBytes));
        file.Read(*pBytes, data);
        *ppData = data;
        return S_OK;
    }
HRESULT GeometryShaderLoader::GenerateContentHash(const WCHAR* path, GeometryShaderOptions* options, ContentHash* hash)
{
    if (!hash)
    {
        return E_FAIL;
    }

    ContentHash retHash;
    retHash.append(path);

    if (options)
    {
        WCHAR wBuff[1024];
        AnsiToWString(options->EntryPoint, wBuff, 1024);
        retHash.append(wBuff);

        if (options->Defines)
        {
            UINT defineIdx = 0;
            while (options->Defines[defineIdx].Name)
            {
                AnsiToWString(options->Defines[defineIdx].Name, wBuff, 1024);
                retHash.append(wBuff);

                AnsiToWString(options->Defines[defineIdx].Definition, wBuff, 1024);
                retHash.append(wBuff);

                defineIdx++;
            }
        }

        // Not hashing the debug name since it does not affect the content that is loaded
    }

    *hash = retHash;
    return S_OK;
}
HRESULT GeometryShaderLoader::CompileContentFile( ID3D11Device* device, ID3DX11ThreadPump* threadPump, const WCHAR* path, GeometryShaderOptions* options, WCHAR* errorMsg, UINT errorLen, std::ostream* output )
{
    if (!options)
    {
        swprintf_s(errorMsg, errorLen, L"Options cannot be null when loading shaders.");
        return E_FAIL;
    }

    WCHAR logMsg[MAX_LOG_LENGTH];
    if (options->DebugName)
    {
        WCHAR debugNameW[256];
        AnsiToWString(options->DebugName, debugNameW, 256);

        swprintf_s(logMsg, L"Loading - %s (path = %s)", debugNameW, path);
    }
    else
    {
        swprintf_s(logMsg, L"Loading - %s", path);
    }
    LOG_INFO(L"Pixel Shader Loader", logMsg);

    HRESULT hr;

    ID3DBlob* pShaderBlob = NULL;
    hr = CompileShaderFromFile(path, options->EntryPoint, "gs_5_0", options->Defines, threadPump,
        errorMsg, errorLen, &pShaderBlob, NULL);
    if (FAILED(hr))
    {
        // CompileShaderFromFile sets the error message
        SAFE_RELEASE(pShaderBlob);
        return hr;
    }

    UINT size = pShaderBlob->GetBufferSize();
    if (!output->write((const char*)&size, sizeof(UINT)))
    {
        return E_FAIL;
    }

    if (!output->write((const char*)pShaderBlob->GetBufferPointer(), size))
    {
        return E_FAIL;
    }

    return S_OK;
}
Esempio n. 6
0
static string GetExpandedShaderCode(const wchar* path, vector<wstring>& filePaths)
{
    for(uint64 i = 0; i < filePaths.size(); ++i)
        if(filePaths[i] == path)
            throw Exception(L"File \"" + wstring(path) + L" is recursively included");

    filePaths.push_back(path);

    string fileContents = ReadFileAsString(path);
    wstring fileDirectory = GetDirectoryFromFilePath(path);

    // Look for includes
    size_t lineStart = 0;
    size_t lineEnd = std::string::npos;
    while(true)
    {
        size_t lineEnd = fileContents.find('\n', lineStart);
        size_t lineLength = 0;
        if(lineEnd == string::npos)
            lineLength = string::npos;
        else
            lineLength = lineEnd - lineStart;

        string line = fileContents.substr(lineStart, lineLength);
        if(line.find("#include") == 0)
        {
            size_t startQuote = line.find('\"');
            size_t endQuote = line.find('\"', startQuote + 1);
            string includePath = line.substr(startQuote + 1, endQuote - startQuote - 1);
            wstring fullIncludePath = fileDirectory + AnsiToWString(includePath.c_str());
            if(FileExists(fullIncludePath.c_str()) == false)
                throw Exception(L"Couldn't find #included file \"" + fullIncludePath + L"\"");

            string includeCode = GetExpandedShaderCode(fullIncludePath.c_str(), filePaths);
            fileContents.insert(lineEnd + 1, includeCode);
            lineEnd += includeCode.length();
        }

        if(lineEnd == string::npos)
            break;

        lineStart = lineEnd + 1;
    }

    return fileContents;
}
Esempio n. 7
0
void SaveTextureAsEXR(const TextureData<Float4>& texture, const wchar* filePath)
{
    Assert_(texture.Texels.size() > 0);
    Assert_(texture.Width > 0 && texture.Height > 0);
    Assert_(texture.NumSlices == 1);

    const uint64 numTexels = texture.Texels.size();
    std::vector<float> channelDataR;
    std::vector<float> channelDataG;
    std::vector<float> channelDataB;
    channelDataR.resize(numTexels);
    channelDataG.resize(numTexels);
    channelDataB.resize(numTexels);
    for(uint64 i = 0; i < numTexels; ++i)
    {
        channelDataR[i] = texture.Texels[i].x;
        channelDataG[i] = texture.Texels[i].y;
        channelDataB[i] = texture.Texels[i].z;
    }

    float* imageChannels[3] = { channelDataB.data(), channelDataG.data(), channelDataR.data() };
    const char* channelNames[3] = { "B", "G", "R" };

    EXRImage exrImage;
    exrImage.num_channels = 3;
    exrImage.width = texture.Width;
    exrImage.height = texture.Height;
    exrImage.channel_names = channelNames;
    exrImage.images = imageChannels;

    std::string filePathAnsi = WStringToAnsi(filePath);

    const char* errorString = nullptr;
    int returnCode = SaveMultiChannelEXR(&exrImage, filePathAnsi.c_str(), &errorString);
    if(returnCode != 0)
    {
        AssertFail_("%s", errorString);
        throw Exception(AnsiToWString(errorString));
    }
}
Esempio n. 8
0
void Model::CreateFromSDKMeshFile(ID3D11Device* device, LPCWSTR fileName)
{
    _ASSERT(FileExists(fileName));

    // Use the SDKMesh class to load in the data
    SDKMesh sdkMesh;
    sdkMesh.Create(fileName);

    wstring directory = GetDirectoryFromFileName(fileName);

    // Make materials
    UINT numMaterials = sdkMesh.GetNumMaterials();
    for (UINT i = 0; i < numMaterials; ++i)
    {
        MeshMaterial material;
        SDKMESH_MATERIAL* mat = sdkMesh.GetMaterial(i);
        memcpy(&material.AmbientAlbedo, &mat->Ambient, sizeof(D3DXVECTOR4));
        memcpy(&material.DiffuseAlbedo, &mat->Diffuse, sizeof(D3DXVECTOR4));
        memcpy(&material.SpecularAlbedo, &mat->Specular, sizeof(D3DXVECTOR4));
        memcpy(&material.Emissive, &mat->Emissive, sizeof(D3DXVECTOR4));
        material.Alpha = mat->Diffuse.w;
        material.SpecularPower = mat->Power;
        material.DiffuseMapName = AnsiToWString(mat->DiffuseTexture);
        material.NormalMapName = AnsiToWString(mat->NormalTexture);

        LoadMaterialResources(material, directory, device);

        meshMaterials.push_back(material);
    }

    // Make a D3D9 device
    IDirect3DDevice9Ptr d3d9Device = CreateD3D9Device();

    UINT numMeshes = sdkMesh.GetNumMeshes();
    for (UINT meshIdx = 0; meshIdx < numMeshes; ++meshIdx)
    {
        // Figure out the index type
        UINT ops = D3DXMESH_MANAGED;
        UINT indexSize = 2;
        Mesh::IndexType indexType = Mesh::Index16Bit;
        if (sdkMesh.GetIndexType(meshIdx) == IT_32BIT)
        {
            ops |= D3DXMESH_32BIT;
            indexSize = 4;
            indexType = Mesh::Index32Bit;
        }

        // Make a D3DX mesh
        ID3DXMesh* d3dxMesh = NULL;
        UINT numPrims = static_cast<UINT>(sdkMesh.GetNumIndices(meshIdx) / 3);
        UINT numVerts = static_cast<UINT>(sdkMesh.GetNumVertices(meshIdx, 0));
        UINT vbIndex = sdkMesh.GetMesh(meshIdx)->VertexBuffers[0];
        UINT ibIndex = sdkMesh.GetMesh(meshIdx)->IndexBuffer;
        const D3DVERTEXELEMENT9* vbElements = sdkMesh.VBElements(vbIndex);
        DXCall(D3DXCreateMesh(numPrims, numVerts, ops, vbElements, d3d9Device, &d3dxMesh));
        IUnknownReleaser<ID3DXMesh> meshReleaser(d3dxMesh);

        // Copy in vertex data
        BYTE* verts = NULL;
        BYTE* srcVerts = reinterpret_cast<BYTE*>(sdkMesh.GetRawVerticesAt(vbIndex));
        UINT vbStride = sdkMesh.GetVertexStride(meshIdx, 0);
        UINT declStride = D3DXGetDeclVertexSize(vbElements, 0);
        DXCall(d3dxMesh->LockVertexBuffer(0, reinterpret_cast<void**>(&verts)));
        for (UINT vertIdx = 0; vertIdx < numVerts; ++vertIdx)
        {
            memcpy(verts, srcVerts, declStride);
            verts += declStride;
            srcVerts += vbStride;
        }
        DXCall(d3dxMesh->UnlockVertexBuffer());

        // Copy in index data
        void* indices = NULL;
        void* srcIndices = sdkMesh.GetRawIndicesAt(ibIndex);
        DXCall(d3dxMesh->LockIndexBuffer(0, &indices));
        memcpy(indices, srcIndices, numPrims * 3 * indexSize);
        DXCall(d3dxMesh->UnlockIndexBuffer());

        // Set up the attribute table
        DWORD* attributeBuffer = NULL;
        DXCall(d3dxMesh->LockAttributeBuffer(0, &attributeBuffer));

        UINT numSubsets = sdkMesh.GetNumSubsets(meshIdx);
        D3DXATTRIBUTERANGE* attributes = new D3DXATTRIBUTERANGE[numSubsets];
        ArrayDeleter<D3DXATTRIBUTERANGE> attributeDeleter(attributes);
        for (UINT i = 0; i < numSubsets; ++i)
        {
            SDKMESH_SUBSET* subset = sdkMesh.GetSubset(meshIdx, i);
            attributes[i].AttribId = subset->MaterialID;
            attributes[i].FaceStart = static_cast<DWORD>(subset->IndexStart / 3);
            attributes[i].FaceCount = static_cast<DWORD>(subset->IndexCount / 3);
            attributes[i].VertexStart = static_cast<DWORD>(subset->VertexStart);
            // attributes[i].VertexCount = static_cast<DWORD>(subset->VertexCount);
            attributes[i].VertexCount = numVerts;

            for (UINT faceIdx = attributes[i].FaceStart; faceIdx < attributes[i].FaceStart + attributes[i].FaceCount; ++faceIdx)
                attributeBuffer[faceIdx] = subset->MaterialID;
        }

        DXCall(d3dxMesh->UnlockAttributeBuffer());

        d3dxMesh->SetAttributeTable(attributes, numSubsets);

        // Generate initial adjacency
        vector<DWORD> initialAdjacency;
        initialAdjacency.resize(d3dxMesh->GetNumFaces() * 3);
        DXCall(d3dxMesh->GenerateAdjacency(0.0001f, &initialAdjacency[0]));

        // Make the mesh
        Mesh mesh;
        mesh.CreateFromD3DXMesh(directory, device, d3d9Device, d3dxMesh, false, false, &initialAdjacency[0], indexType);
        meshes.push_back(mesh);
    }
}