//--------------------------------------------------------------------------------------
CPUTPixelShaderDX11 *CPUTPixelShaderDX11::CreatePixelShaderFromMemory(
    const cString      &name,
    ID3D11Device       *pD3dDevice,
    const cString      &shaderMain,
    const cString      &shaderProfile,
    const char         *pShaderSource
)
{
    ID3DBlob           *pCompiledBlob = NULL;
    ID3D11PixelShader  *pNewPixelShader = NULL;

    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();
    CPUTResult result = pAssetLibrary->CompileShaderFromMemory(pShaderSource, shaderMain, shaderProfile, &pCompiledBlob);
    ASSERT( CPUTSUCCESS(result), _L("Error compiling pixel shader:\n\n") );

    // Create the pixel shader
    // TODO: Move to pixel shader class
    HRESULT hr = pD3dDevice->CreatePixelShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewPixelShader );
    ASSERT( SUCCEEDED(result), _L("Error compiling pixel shader:\n\n") );
    // cString DebugName = _L("CPUTAssetLibraryDX11::GetPixelShader ")+name;
    // CPUTSetDebugName(pNewPixelShader, DebugName);

    CPUTPixelShaderDX11 *pNewCPUTPixelShader = new CPUTPixelShaderDX11( pNewPixelShader, pCompiledBlob );

    // add shader to library
    pAssetLibrary->AddPixelShader(name + shaderMain + shaderProfile, pNewCPUTPixelShader);
    // pNewCPUTPixelShader->Release(); // We've added it to the library, so release our reference

    // return the shader (and blob)
    return pNewCPUTPixelShader;
}
CPUTComputeShaderDX11 *CPUTComputeShaderDX11::Create(
    const std::string     &name,
    const std::string     &shaderMain,
    const std::string     &shaderProfile,
    CPUT_SHADER_MACRO *pShaderMacros
)
{
    ID3DBlob            *pCompiledBlob = NULL;
    ID3D11ComputeShader *pNewComputeShader = NULL;

    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();
    CPUTResult result = pAssetLibrary->CompileShaderFromFile(name, shaderMain, shaderProfile, &pCompiledBlob, pShaderMacros);
    ASSERT( CPUTSUCCESS(result), "Error compiling compute shader:\n\n" );
    UNREFERENCED_PARAMETER(result);

    // Create the compute shader
    ID3D11Device      *pD3dDevice = CPUT_DX11::GetDevice();
    HRESULT hr = pD3dDevice->CreateComputeShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewComputeShader );
    ASSERT( SUCCEEDED(hr), "Error creating compute shader:\n\n" );
    UNREFERENCED_PARAMETER(hr);
    // std::string DebugName = "CPUTAssetLibraryDX11::GetComputeShader "+name;
    // CPUTSetDebugName(pNewComputeShader, DebugName);

    CPUTComputeShaderDX11 *pNewCPUTComputeShader = new CPUTComputeShaderDX11( pNewComputeShader, pCompiledBlob );

    // add shader to library
    pAssetLibrary->AddComputeShader(name, "", shaderMain + shaderProfile, pNewCPUTComputeShader);

    // return the shader
    return pNewCPUTComputeShader;
}
//--------------------------------------------------------------------------------------
CPUTGeometryShaderDX11 *CPUTGeometryShaderDX11::CreateFromMemory(
    const std::string     &name,
    const std::string     &shaderMain,
    const std::string     &shaderProfile,
    const char        *pShaderSource,
    CPUT_SHADER_MACRO *pShaderMacros
)
{
    ID3DBlob             *pCompiledBlob = NULL;
    ID3D11GeometryShader *pNewGeometryShader = NULL;

    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();
    CPUTResult result = pAssetLibrary->CompileShaderFromMemory(pShaderSource, shaderMain, shaderProfile, &pCompiledBlob, pShaderMacros );
    ASSERT( CPUTSUCCESS(result), "Error creating Geometry shader:\n\n" );
    UNREFERENCED_PARAMETER(result);

    // Create the Geometry shader
    ID3D11Device      *pD3dDevice = CPUT_DX11::GetDevice();
    HRESULT hr = pD3dDevice->CreateGeometryShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewGeometryShader );
    ASSERT( SUCCEEDED(hr), "Error creating Geometry shader:\n\n" );
    UNREFERENCED_PARAMETER(hr);
    // std::string DebugName = "CPUTAssetLibraryDX11::GetGeometryShader "+name;
    // CPUTSetDebugName(pNewGeometryShader, DebugName);

    CPUTGeometryShaderDX11 *pNewCPUTGeometryShader = new CPUTGeometryShaderDX11( pNewGeometryShader, pCompiledBlob );

    // add shader to library
    pAssetLibrary->AddGeometryShader(name, "", shaderMain + shaderProfile, pNewCPUTGeometryShader);
    // pNewCPUTGeometryShader->Release(); // We've added it to the library, so release our reference

    // return the shader (and blob)
    return pNewCPUTGeometryShader;
}
CPUTComputeShaderDX11 *CPUTComputeShaderDX11::CreateComputeShader(
    const cString  &name,
    ID3D11Device   *pD3dDevice,
    const cString  &shaderMain,
    const cString  &shaderProfile
)
{
    ID3DBlob            *pCompiledBlob = NULL;
    ID3D11ComputeShader *pNewComputeShader = NULL;

    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();
    CPUTResult result = pAssetLibrary->CompileShaderFromFile(name, shaderMain, shaderProfile, &pCompiledBlob);
    ASSERT( CPUTSUCCESS(result), _L("Error compiling compute shader:\n\n") );

    // Create the compute shader
    // TODO: Move to compute shader class
    HRESULT hr = pD3dDevice->CreateComputeShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewComputeShader );
    ASSERT( SUCCEEDED(result), _L("Error compiling compute shader:\n\n") );
    // cString DebugName = _L("CPUTAssetLibraryDX11::GetComputeShader ")+name;
    // CPUTSetDebugName(pNewComputeShader, DebugName);

    CPUTComputeShaderDX11 *pNewCPUTComputeShader = new CPUTComputeShaderDX11( pNewComputeShader, pCompiledBlob );

    // add shader to library
    pAssetLibrary->AddComputeShader(name + shaderMain + shaderProfile, pNewCPUTComputeShader);

    // return the shader
    return pNewCPUTComputeShader;
}
//-----------------------------------------------------------------------------
void CPUTMaterialDX11::BindTextures( CPUTShaderParameters &params, const CPUTModel *pModel, int meshIndex )
{
    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();

    for(params.mTextureCount=0; params.mTextureCount < params.mTextureParameterCount; params.mTextureCount++)
    {
        cString textureName;
        UINT textureCount = params.mTextureCount;
        cString tagName = params.mpTextureParameterName[textureCount];
        CPUTConfigEntry *pValue = mConfigBlock.GetValueByName(tagName);
        if( !pValue->IsValid() )
        {
            // We didn't find our property in the file.  Is it in the global config block?
            pValue = mGlobalProperties.GetValueByName(tagName);
        }
        ASSERT( pValue->IsValid(), L"Can't find texture '" + tagName + L"'." ); //  TODO: fix message
        textureName = pValue->ValueAsString();
        // If the texture name not specified.  Load default.dds instead
        if( 0 == textureName.length() ) { textureName = _L("default.dds"); }

        UINT bindPoint = params.mpTextureParameterBindPoint[textureCount]; 
        ASSERT( bindPoint < CPUT_MATERIAL_MAX_TEXTURE_SLOTS, _L("Texture bind point out of range.") );

        if( textureName[0] == '@' )
        {
            // This is a per-mesh value.  Add to per-mesh list.
            textureName += ptoc(pModel) + itoc(meshIndex);
        } else if( textureName[0] == '#' )
        {
            // This is a per-mesh value.  Add to per-mesh list.
            textureName += ptoc(pModel);
        }

        // Get the sRGB flag (default to true)
        cString SRGBName = tagName+_L("sRGB");
        CPUTConfigEntry *pSRGBValue = mConfigBlock.GetValueByName(SRGBName);
        bool loadAsSRGB = pSRGBValue->IsValid() ?  loadAsSRGB = pSRGBValue->ValueAsBool() : true;

        if( !mpTexture[textureCount] )
        {
            mpTexture[textureCount] = pAssetLibrary->GetTexture( textureName, false, loadAsSRGB );
            ASSERT( mpTexture[textureCount], _L("Failed getting texture ") + textureName);
        }

        // The shader file (e.g. .fx) can specify the texture bind point (e.g., t0).  Those specifications 
        // might not be contiguous, and there might be gaps (bind points without assigned textures)
        // TODO: Warn about missing bind points?
        params.mppBindViews[bindPoint] = ((CPUTTextureDX11*)mpTexture[textureCount])->GetShaderResourceView();
		params.mppBindViews[bindPoint]->AddRef();
    }
}
//-----------------------------------------------------------------------------
void CPUTMaterialDX11::BindConstantBuffers( CPUTShaderParameters &params, const CPUTModel *pModel, int meshIndex )
{
    CPUTConfigEntry *pValue;
    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();
    for(params.mConstantBufferCount=0; params.mConstantBufferCount < params.mConstantBufferParameterCount; params.mConstantBufferCount++)
    {
        cString constantBufferName;
        UINT constantBufferCount = params.mConstantBufferCount;

        cString tagName = params.mpConstantBufferParameterName[constantBufferCount];
        {
            pValue = mConfigBlock.GetValueByName(tagName);
            if( !pValue->IsValid() )
            {
                // We didn't find our property in the file.  Is it in the global config block?
                pValue = mGlobalProperties.GetValueByName(tagName);
            }
            ASSERT( pValue->IsValid(), L"Can't find constant buffer '" + tagName + L"'." ); //  TODO: fix message
            constantBufferName = pValue->ValueAsString();
        }
        UINT bindPoint = params.mpConstantBufferParameterBindPoint[constantBufferCount];
        ASSERT( bindPoint < CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS, _L("Constant buffer bind point out of range.") );

        const CPUTModel *pWhichModel = NULL;
        int              whichMesh   = -1;
        if( constantBufferName[0] == '@' )
        {
            pWhichModel = pModel;
            whichMesh   = meshIndex;
        } else if( constantBufferName[0] == '#' )
        {
            pWhichModel = pModel;
        }
        if( !mpConstantBuffer[constantBufferCount] )
        {
            if( pWhichModel )
            {
                mpConstantBuffer[constantBufferCount] = pAssetLibrary->GetConstantBuffer( constantBufferName, pWhichModel, whichMesh );
            } else
            {
                mpConstantBuffer[constantBufferCount] = pAssetLibrary->GetConstantBuffer( constantBufferName );
            }
            ASSERT( mpConstantBuffer[constantBufferCount], _L("Failed getting constant buffer ") + constantBufferName);
        }

        // If has constant buffer, then add to mppBindConstantBuffer
        params.mppBindConstantBuffers[bindPoint]   = ((CPUTBufferDX11*)mpConstantBuffer[constantBufferCount])->GetNativeBuffer();
        if( params.mppBindConstantBuffers[bindPoint] )  { params.mppBindConstantBuffers[bindPoint]->AddRef();}
    }
}
//-----------------------------------------------------------------------------
void CPUTMaterialDX11::BindUAVs( CPUTShaderParameters &params, const CPUTModel *pModel, int meshIndex )
{
    CPUTConfigEntry *pValue;
    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();
    memset( params.mppBindUAVs, 0, sizeof(params.mppBindUAVs) );
    for(params.mUAVCount=0; params.mUAVCount < params.mUAVParameterCount; params.mUAVCount++)
    {
        cString uavName;
        UINT uavCount = params.mUAVCount;

        cString tagName = params.mpUAVParameterName[uavCount];
        {
            pValue = mConfigBlock.GetValueByName(tagName);
            if( !pValue->IsValid() )
            {
                // We didn't find our property in the file.  Is it in the global config block?
                pValue = mGlobalProperties.GetValueByName(tagName);
            }
            ASSERT( pValue->IsValid(), L"Can't find UAV '" + tagName + L"'." ); //  TODO: fix message
            uavName = pValue->ValueAsString();
        }
        UINT bindPoint = params.mpUAVParameterBindPoint[uavCount];
        ASSERT( bindPoint < CPUT_MATERIAL_MAX_UAV_SLOTS, _L("UAV bind point out of range.") );

        const CPUTModel *pWhichModel = NULL;
        int              whichMesh   = -1;
        if( uavName[0] == '@' )
        {
            pWhichModel = pModel;
            whichMesh   = meshIndex;
        } else if( uavName[0] == '#' )
        {
            pWhichModel = pModel;
        }
        if( !mpUAV[uavCount] )
        {
            mpUAV[uavCount] = pAssetLibrary->GetBuffer( uavName, pWhichModel, whichMesh );
            ASSERT( mpUAV[uavCount], _L("Failed getting UAV ") + uavName);
        }
        // If has UAV, then add to mppBindUAV
        params.mppBindUAVs[bindPoint]   = ((CPUTBufferDX11*)mpUAV[uavCount])->GetUnorderedAccessView();
        if( params.mppBindUAVs[bindPoint] )  { params.mppBindUAVs[bindPoint]->AddRef();}
    }
}
Example #8
0
//-----------------------------------------------------------------------------
void CPUTModelDX11::CreateModelConstantBuffer()
{
    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();

    // Create the model constant buffer.
    HRESULT hr;
    D3D11_BUFFER_DESC bd = {0};
    bd.ByteWidth = sizeof(CPUTModelConstantBuffer);
    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    bd.Usage = D3D11_USAGE_DYNAMIC;
    bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    hr = (CPUT_DX11::GetDevice())->CreateBuffer( &bd, NULL, &mpModelConstantBuffer );
    ASSERT( !FAILED( hr ), _L("Error creating constant buffer.") );
    CPUTSetDebugName( mpModelConstantBuffer, _L("Model Constant buffer") );
    cString name = _L("$cbPerModelValues");
    CPUTBufferDX11 *pBuffer = new CPUTBufferDX11(name, mpModelConstantBuffer);
    pAssetLibrary->AddConstantBuffer( name, pBuffer );
    pBuffer->Release(); // We're done with it.  We added it to the library.  Release our reference.
}
//-----------------------------------------------------------------------------
CPUTAssetSet *CPUTAssetSetDX11::CreateAssetSet( const cString &name, const cString &absolutePathAndFilename )
{
    CPUTAssetLibraryDX11 *pAssetLibrary = ((CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary());

    // Create the root node.
    CPUTNullNode *pRootNode = new CPUTNullNode();
    pRootNode->SetName(_L("_CPUTAssetSetRootNode_"));

    // Create the asset set, set its root, and load it
    CPUTAssetSet   *pNewAssetSet = new CPUTAssetSetDX11();
    pNewAssetSet->SetRoot( pRootNode );
    pAssetLibrary->AddNullNode( name + _L("_Root"), pRootNode );

    CPUTResult result = pNewAssetSet->LoadAssetSet(absolutePathAndFilename);
    if( CPUTSUCCESS(result) )
    {
        pAssetLibrary->AddAssetSet(name, pNewAssetSet);
        return pNewAssetSet;
    }
    ASSERT( CPUTSUCCESS(result), _L("Error loading AssetSet\n'")+absolutePathAndFilename+_L("'"));
    pNewAssetSet->Release();
    return NULL;
}
Example #10
0
// incoming resize event to be handled and translated
//-----------------------------------------------------------------------------
void CPUT_DX11::ResizeWindow(UINT width, UINT height)
{
    HRESULT hr;
    CPUTResult result;
    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibraryDX11::GetAssetLibrary();

    // TODO: Making the back and depth buffers into CPUTRenderTargets should simplify this (CPUTRenderTarget* manages RTV, SRV, UAV, etc.)
    if( mpBackBuffer )         ((CPUTBufferDX11*)mpBackBuffer)->ReleaseBuffer();
    if( mpDepthBuffer )        ((CPUTBufferDX11*)mpDepthBuffer)->ReleaseBuffer();
    if( mpBackBufferTexture )  ((CPUTTextureDX11*)mpBackBufferTexture)->ReleaseTexture();
    if( mpDepthBufferTexture ) ((CPUTTextureDX11*)mpDepthBufferTexture)->ReleaseTexture();

    // Make sure we don't have any buffers bound.
    mpContext->ClearState();
    Present();
    mpContext->Flush();

    SAFE_RELEASE(mpBackBufferRTV);
    SAFE_RELEASE(mpBackBufferSRV);
    SAFE_RELEASE(mpBackBufferUAV);
    SAFE_RELEASE(mpDepthStencilSRV);

    CPUT::ResizeWindow( width, height );

    // Call the sample's clean up code if present.
    ReleaseSwapChain();

    // handle the internals of a resize
    int windowWidth, windowHeight;
    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();
    pServices->GetClientDimensions( &windowWidth, &windowHeight);

    // resize the swap chain
    hr = mpSwapChain->ResizeBuffers(mSwapChainBufferCount, windowWidth, windowHeight, mSwapChainFormat, 0);
    ASSERT( SUCCEEDED(hr), _L("Error resizing swap chain") );

    // re-create the render-target view
    ID3D11Texture2D *pSwapChainBuffer = NULL;
    hr = mpSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), (LPVOID*) (&pSwapChainBuffer));
    ASSERT(SUCCEEDED(hr), _L(""));
    hr = mpD3dDevice->CreateRenderTargetView( pSwapChainBuffer, NULL, &mpBackBufferRTV);
    ASSERT(SUCCEEDED(hr), _L(""));
    hr = mpD3dDevice->CreateShaderResourceView( pSwapChainBuffer, NULL, &mpBackBufferSRV);
    ASSERT(SUCCEEDED(hr), _L(""));
#ifdef CREATE_SWAP_CHAIN_UAV
    // Not every DXGI format supports UAV.  So, create UAV only if sample chooses to do so.
    hr = mpD3dDevice->CreateUnorderedAccessView( pSwapChainBuffer, NULL, &mpBackBufferUAV);
    ASSERT(SUCCEEDED(hr), _L(""));
#endif
    // Add the back buffer to the asset library.  Create CPUTBuffer and a CPUTTexture forms and add them.
    if( mpBackBuffer )
    {
        ((CPUTBufferDX11*)mpBackBuffer)->SetBufferAndViews( NULL, mpBackBufferSRV, mpBackBufferUAV );
    }
    else
    {
        cString backBufferName = _L("$BackBuffer"); 
        mpBackBuffer  = new CPUTBufferDX11( backBufferName,  NULL, mpBackBufferUAV );
        pAssetLibrary->AddBuffer( backBufferName, mpBackBuffer );
    }
    if( mpBackBufferTexture )
    {
        ((CPUTTextureDX11*)mpBackBufferTexture)->SetTextureAndShaderResourceView( NULL, mpBackBufferSRV );
    }
    else
    {
        cString backBufferName = _L("$BackBuffer"); 
        mpBackBufferTexture  = new CPUTTextureDX11( backBufferName, NULL, mpBackBufferSRV );
        pAssetLibrary->AddTexture( backBufferName, mpBackBufferTexture );
    }

    // release the old depth buffer objects
    // release the temporary swap chain buffer
    SAFE_RELEASE(pSwapChainBuffer);
    SAFE_RELEASE(mpDepthStencilBuffer);
    SAFE_RELEASE(mpDepthStencilState);
    SAFE_RELEASE(mpDepthStencilView);

    result = CreateAndBindDepthBuffer(windowWidth, windowHeight);
    if(CPUTFAILED(result))
    {
        // depth buffer creation error
        ASSERT(0,_L(""));
    }

    if( mpDepthBuffer )
    {
        ((CPUTBufferDX11*)mpDepthBuffer)->SetBufferAndViews( NULL, mpDepthStencilSRV, NULL );
    }
    else
    {
        cString depthBufferName = _L("$DepthBuffer"); 
        mpDepthBuffer  = new CPUTBufferDX11( depthBufferName, NULL, mpDepthStencilSRV );
        pAssetLibrary->AddBuffer( depthBufferName, mpDepthBuffer );
    }
    if( mpDepthBufferTexture )
    {
        ((CPUTTextureDX11*)mpDepthBufferTexture)->SetTextureAndShaderResourceView( NULL, mpDepthStencilSRV );
    }
    else
    {
        cString DepthBufferName = _L("$DepthBuffer"); 
        mpDepthBufferTexture  = new CPUTTextureDX11( DepthBufferName, NULL, mpDepthStencilSRV );
        pAssetLibrary->AddTexture( DepthBufferName, mpDepthBufferTexture );
    }

    // Release our extra reference to each view.
    // if(mpBackBufferSRV)   mpBackBufferSRV->Release();
    // if(mpBackBufferUAV)   mpBackBufferUAV->Release();
    // if(mpDepthStencilSRV) mpDepthStencilSRV->Release();;

    // set the viewport
    D3D11_VIEWPORT vp;
    vp.Width = (FLOAT) windowWidth;
    vp.Height = (FLOAT)windowHeight;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = 0;
    vp.TopLeftY = 0;
    mpContext->RSSetViewports( 1, &vp );

    // trigger the GUI manager to resize
    CPUTGuiControllerDX11::GetController()->Resize();
}
//-----------------------------------------------------------------------------
CPUTResult CPUTAssetSetDX11::LoadAssetSet(cString name)
{
    CPUTResult result = CPUT_SUCCESS;

    // if not found, load the set file
    CPUTConfigFile ConfigFile;
    result = ConfigFile.LoadFile(name);
#if 1
    if( !CPUTSUCCESS(result) )
    {
        return result;
    }
    // ASSERT( CPUTSUCCESS(result), _L("Failed loading set file '") + name + _L("'.") );

    mAssetCount = ConfigFile.BlockCount() + 1; // Add one for the implied root node
    // mAssetCount = min(2, mAssetCount); // Add one for the implied root node
    mppAssetList = new CPUTRenderNode*[mAssetCount];
    mppAssetList[0] = mpRootNode;
    mpRootNode->AddRef();

    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();
    for(UINT ii=0; ii<mAssetCount-1; ii++) // Note: -1 because we added one for the root node (we don't load it)
    {
        CPUTConfigBlock *pBlock = ConfigFile.GetBlock(ii);
        int assetIndex = pBlock->GetNameValue();
        cString nodeType = pBlock->GetValueByName(_L("type"))->ValueAsString();
        CPUTRenderNode *pParentNode = NULL;

        // TODO: use Get*() instead of Load*() ?

        cString name = pBlock->GetValueByName(_L("name"))->ValueAsString();

        int parentIndex;
        CPUTRenderNode *pNode;
        if(0==nodeType.compare(_L("null")))
        {
            pNode  = pNode = new CPUTNullNode();
            result = ((CPUTNullNode*)pNode)->LoadNullNode(pBlock, &parentIndex);
            pParentNode = mppAssetList[parentIndex+1];
            cString &parentPrefix = pParentNode->GetPrefix();
            pNode->SetPrefix( parentPrefix + _L(".") + name );
            pAssetLibrary->AddNullNode(parentPrefix + name, (CPUTNullNode*)pNode);
            // Add this null's name to our prefix
            // Append this null's name to our parent's prefix
            pNode->SetParent( pParentNode );
            pParentNode->AddChild( pNode );
        }
        else if(0==nodeType.compare(_L("model")))
        {
            CPUTConfigEntry *pValue = pBlock->GetValueByName( _L("instance") );
            CPUTModelDX11 *pModel = new CPUTModelDX11();
            if( pValue == &CPUTConfigEntry::sNullConfigValue )
            {
                // Not found.  So, not an instance.
                pModel->LoadModel(pBlock, &parentIndex, NULL);
            }
            else
            {
                int instance = pValue->ValueAsInt();
                pModel->LoadModel(pBlock, &parentIndex, (CPUTModel*)mppAssetList[instance+1]);
            }
            pParentNode = mppAssetList[parentIndex+1];
            pModel->SetParent( pParentNode );
            pParentNode->AddChild( pModel );
            cString &parentPrefix = pParentNode->GetPrefix();
            pModel->SetPrefix( parentPrefix );
            pAssetLibrary->AddModel(parentPrefix + name, pModel);

            pModel->UpdateBoundsWorldSpace();

#ifdef SUPPORT_DRAWING_BOUNDING_BOXES
            // Create a mesh for rendering the bounding box
            // TODO: There is definitely a better way to do this.  But, want to see the bounding boxes!
            pModel->CreateBoundingBoxMesh();
#endif
            pNode = pModel;
        }
        else if(0==nodeType.compare(_L("light")))
        {
            pNode = new CPUTLight();
            ((CPUTLight*)pNode)->LoadLight(pBlock, &parentIndex);
            pParentNode = mppAssetList[parentIndex+1]; // +1 because we added a root node to the start
            pNode->SetParent( pParentNode );
            pParentNode->AddChild( pNode );
            cString &parentPrefix = pParentNode->GetPrefix();
            pNode->SetPrefix( parentPrefix );
            pAssetLibrary->AddLight(parentPrefix + name, (CPUTLight*)pNode);
        }
        else if(0==nodeType.compare(_L("camera")))
        {
            pNode = new CPUTCamera();
            ((CPUTCamera*)pNode)->LoadCamera(pBlock, &parentIndex);
            pParentNode = mppAssetList[parentIndex+1]; // +1 because we added a root node to the start
            pNode->SetParent( pParentNode );
            pParentNode->AddChild( pNode );
            cString &parentPrefix = pParentNode->GetPrefix();
            pNode->SetPrefix( parentPrefix );
            pAssetLibrary->AddCamera(parentPrefix + name, (CPUTCamera*)pNode);
            if( !mpFirstCamera ) { mpFirstCamera = (CPUTCamera*)pNode; mpFirstCamera->AddRef();}
            ++mCameraCount;
        }
        else
        {
            ASSERT(0,_L("Unsupported node type '") + nodeType + _L("'."));
        }

        // Add the node to our asset list (i.e., the linear list, not the hierarchical)
        mppAssetList[ii+1] = pNode;
        // Don't AddRef.Creating it set the refcount to 1.  We add it to the list, and then we're done with it.
        // Net effect is 0 (+1 to add to list, and -1 because we're done with it)
        // pNode->AddRef();
    }
#endif
    HEAPCHECK
	return result;
}
//-----------------------------------------------------------------------------
CPUTResult CPUTMaterialDX11::LoadMaterial(const cString &fileName, const CPUTModel *pModel, int meshIndex)
{
    CPUTResult result = CPUT_SUCCESS;

    mMaterialName = fileName;
    mMaterialNameHash = CPUTComputeHash( mMaterialName );

    // Open/parse the file
    CPUTConfigFile file;
    result = file.LoadFile(fileName);
    if(CPUTFAILED(result))
    {
        return result;
    }

    // Make a local copy of all the parameters
    mConfigBlock = *file.GetBlock(0);

    // get necessary device and AssetLibrary pointers
    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();
    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();

    // TODO:  The following code is very repetitive.  Consider generalizing so we can call a function instead.
    // see if there are any pixel/vertex/geo shaders to load
    CPUTConfigEntry *pValue, *pEntryPointName, *pProfileName;
    pValue   = mConfigBlock.GetValueByName(_L("VertexShaderFile"));
    if( pValue->IsValid() )
    {
        pEntryPointName = mConfigBlock.GetValueByName(_L("VertexShaderMain"));
        pProfileName    = mConfigBlock.GetValueByName(_L("VertexShaderProfile"));
        pAssetLibrary->GetVertexShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpVertexShader );
        ReadShaderSamplersAndTextures( mpVertexShader->GetBlob(), &mVertexShaderParameters );
    }

    // load and store the pixel shader if it was specified
    pValue  = mConfigBlock.GetValueByName(_L("PixelShaderFile"));
    if( pValue->IsValid() )
    {
        pEntryPointName = mConfigBlock.GetValueByName(_L("PixelShaderMain"));
        pProfileName    = mConfigBlock.GetValueByName(_L("PixelShaderProfile"));
        pAssetLibrary->GetPixelShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpPixelShader);
        ReadShaderSamplersAndTextures( mpPixelShader->GetBlob(), &mPixelShaderParameters );
    }

    // load and store the compute shader if it was specified
    pValue = mConfigBlock.GetValueByName(_L("ComputeShaderFile"));
    if( pValue->IsValid() )
    {
        pEntryPointName = mConfigBlock.GetValueByName(_L("ComputeShaderMain"));
        pProfileName = mConfigBlock.GetValueByName(_L("ComputeShaderProfile"));
        pAssetLibrary->GetComputeShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpComputeShader);
        ReadShaderSamplersAndTextures( mpComputeShader->GetBlob(), &mComputeShaderParameters );
    }

    // load and store the geometry shader if it was specified
    pValue = mConfigBlock.GetValueByName(_L("GeometryShaderFile"));
    if( pValue->IsValid() )
    {
        pEntryPointName = mConfigBlock.GetValueByName(_L("GeometryShaderMain"));
        pProfileName = mConfigBlock.GetValueByName(_L("GeometryShaderProfile"));
        pAssetLibrary->GetGeometryShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpGeometryShader);
        ReadShaderSamplersAndTextures( mpGeometryShader->GetBlob(), &mGeometryShaderParameters );
    }

    // load and store the hull shader if it was specified
    pValue = mConfigBlock.GetValueByName(_L("HullShaderFile"));
    if( pValue->IsValid() )
    {
        pEntryPointName = mConfigBlock.GetValueByName(_L("HullShaderMain"));
        pProfileName = mConfigBlock.GetValueByName(_L("HullShaderProfile"));
        pAssetLibrary->GetHullShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpHullShader);
        ReadShaderSamplersAndTextures( mpHullShader->GetBlob(), &mHullShaderParameters );
    }

    // load and store the domain shader if it was specified
    pValue = mConfigBlock.GetValueByName(_L("DomainShaderFile"));
    if( pValue->IsValid() )
    {
        pEntryPointName = mConfigBlock.GetValueByName(_L("DomainShaderMain"));
        pProfileName = mConfigBlock.GetValueByName(_L("DomainShaderProfile"));
        pAssetLibrary->GetDomainShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpDomainShader);
        ReadShaderSamplersAndTextures( mpDomainShader->GetBlob(), &mDomainShaderParameters );
    }

    // load and store the render state file if it was specified
    pValue = mConfigBlock.GetValueByName(_L("RenderStateFile"));
    if( pValue->IsValid() )
    {
        mpRenderStateBlock = pAssetLibrary->GetRenderStateBlock(pValue->ValueAsString());
    }

    // For each of the shader stages, bind shaders and buffers
    for( CPUTShaderParameters **pCur = mpShaderParametersList; *pCur; pCur++ ) // Bind textures and buffersfor each shader stage
    {
        BindTextures(        **pCur, pModel, meshIndex );
        BindBuffers(         **pCur, pModel, meshIndex );
        BindUAVs(            **pCur, pModel, meshIndex );
        BindConstantBuffers( **pCur, pModel, meshIndex );
    }

    return result;
}
// 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;
}
Example #14
0
//-----------------------------------------------------------------------------
CPUTResult CPUTModelDX11::LoadModel(CPUTConfigBlock *pBlock, int *pParentID, CPUTModel *pMasterModel)
{
    CPUTResult result = CPUT_SUCCESS;
    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();

    cString modelSuffix = ptoc(this);

    // set the model's name
    mName = pBlock->GetValueByName(_L("name"))->ValueAsString();
    mName = mName + _L(".mdl");

    // resolve the full path name
    cString modelLocation;
    cString resolvedPathAndFile;
    modelLocation = ((CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary())->GetModelDirectory();
    modelLocation = modelLocation+mName;
    CPUTOSServices::GetOSServices()->ResolveAbsolutePathAndFilename(modelLocation, &resolvedPathAndFile);    

    // Get the parent ID.  Note: the caller will use this to set the parent.
    *pParentID = pBlock->GetValueByName(_L("parent"))->ValueAsInt();

    LoadParentMatrixFromParameterBlock( pBlock );

    // Get the bounding box information
    float3 center(0.0f), half(0.0f);
    pBlock->GetValueByName(_L("BoundingBoxCenter"))->ValueAsFloatArray(center.f, 3);
    pBlock->GetValueByName(_L("BoundingBoxHalf"))->ValueAsFloatArray(half.f, 3);
    mBoundingBoxCenterObjectSpace = center;
    mBoundingBoxHalfObjectSpace   = half;

    mMeshCount = pBlock->GetValueByName(_L("meshcount"))->ValueAsInt();
    mpMesh     = new CPUTMesh*[mMeshCount];
    mpMaterial = new CPUTMaterial*[mMeshCount];
    memset( mpMaterial, 0, mMeshCount * sizeof(CPUTMaterial*) );
    
    cString materialName;
    char pNumber[4];
    cString materialValueName;

    CPUTModelDX11 *pMasterModelDX = (CPUTModelDX11*)pMasterModel;

    for(UINT ii=0; ii<mMeshCount; ii++)
    {
        if(pMasterModelDX)
        {
            // Reference the master model's mesh.  Don't create a new one.
            mpMesh[ii] = pMasterModelDX->mpMesh[ii];
            mpMesh[ii]->AddRef();
        }
        else
        {
            mpMesh[ii] = new CPUTMeshDX11();
        }
    }
    if( !pMasterModelDX )
    {
        // Not a clone/instance.  So, load the model's binary payload (i.e., vertex and index buffers)
        // TODO: Change to use GetModel()
        result = LoadModelPayload(resolvedPathAndFile);
        ASSERT( CPUTSUCCESS(result), _L("Failed loading model") );
    }
    
#if 0
    cString assetSetDirectoryName = pAssetLibrary->GetAssetSetDirectoryName();
    cString modelDirectory        = pAssetLibrary->GetModelDirectory();
    cString materialDirectory     = pAssetLibrary->GetMaterialDirectory();
    cString textureDirectory      = pAssetLibrary->GetTextureDirectory();
    cString shaderDirectory       = pAssetLibrary->GetShaderDirectory();
    cString fontDirectory         = pAssetLibrary->GetFontDirectory();
    cString up2MediaDirName       = assetSetDirectoryName + _L("..\\..\\");
    pAssetLibrary->SetMediaDirectoryName( up2MediaDirName );
    mpShadowCastMaterial = pAssetLibrary->GetMaterial( _L("shadowCast"), false, this, -2 ); // -2 signifies shadow material.  TODO: find a clearer way (e.g., enum?)
    pAssetLibrary->SetAssetSetDirectoryName( assetSetDirectoryName );
    pAssetLibrary->SetModelDirectoryName( modelDirectory ); 
    pAssetLibrary->SetMaterialDirectoryName( materialDirectory );
    pAssetLibrary->SetTextureDirectoryName( textureDirectory );
    pAssetLibrary->SetShaderDirectoryName( shaderDirectory );
    pAssetLibrary->SetFontDirectoryName( fontDirectory );
#endif
    for(UINT ii=0; ii<mMeshCount; ii++)
    {
        // get the right material number ('material0', 'material1', 'material2', etc)
        materialValueName = _L("material");
        _itoa_s(ii, pNumber, 4, 10);
        materialValueName.append(s2ws(pNumber));
        materialName = pBlock->GetValueByName(materialValueName)->ValueAsString();

        // Get/load material for this mesh
        CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)pAssetLibrary->GetMaterial(materialName, false, this, ii);
        ASSERT( pMaterial, _L("Couldn't find material.") );

        // set the material on this mesh
        // TODO: Model owns the materials.  That allows different models to share meshes (aka instancing) that have different materials
        SetMaterial(ii, pMaterial);

        // Release the extra refcount we're holding from the GetMaterial operation earlier
        // now the asset library, and this model have the only refcounts on that material
        pMaterial->Release();

        // Create two ID3D11InputLayout objects, one for each material.
        mpMesh[ii]->BindVertexShaderLayout( mpMaterial[ii], mpShadowCastMaterial);
        // mpShadowCastMaterial->Release()
    }
    return result;
}
Example #15
0
// Load the set file definition of this object
// 1. Parse the block of name/parent/transform info for model block
// 2. Load the model's binary payload (i.e., the meshes)
// 3. Assert the # of meshes matches # of materials
// 4. Load each mesh's material
//-----------------------------------------------------------------------------
CPUTResult CPUTModelDX11::LoadModel(CPUTConfigBlock *pBlock, int *pParentID, CPUTModel *pMasterModel, int numSystemMaterials, cString *pSystemMaterialNames)
{
    CPUTResult result = CPUT_SUCCESS;
    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();

    cString modelSuffix = ptoc(this);

    // set the model's name
    mName = pBlock->GetValueByName(_L("name"))->ValueAsString();
    mName = mName + _L(".mdl");

    // resolve the full path name
    cString modelLocation;
    cString resolvedPathAndFile;
    modelLocation = ((CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary())->GetModelDirectoryName();
    modelLocation = modelLocation+mName;
    CPUTOSServices::GetOSServices()->ResolveAbsolutePathAndFilename(modelLocation, &resolvedPathAndFile);	

    // Get the parent ID.  Note: the caller will use this to set the parent.
    *pParentID = pBlock->GetValueByName(_L("parent"))->ValueAsInt();

    LoadParentMatrixFromParameterBlock( pBlock );

    // Get the bounding box information
    float3 center(0.0f), half(0.0f);
    pBlock->GetValueByName(_L("BoundingBoxCenter"))->ValueAsFloatArray(center.f, 3);
    pBlock->GetValueByName(_L("BoundingBoxHalf"))->ValueAsFloatArray(half.f, 3);
    mBoundingBoxCenterObjectSpace = center;
    mBoundingBoxHalfObjectSpace   = half;

    mMeshCount = pBlock->GetValueByName(_L("meshcount"))->ValueAsInt();
    mpMesh     = new CPUTMesh*[mMeshCount];
    mpSubMaterialCount = new UINT[mMeshCount];
    mpMaterial = new CPUTMaterial**[mMeshCount];
    memset( mpMaterial, 0, mMeshCount * sizeof(CPUTMaterial*) );
    mpInputLayout = new ID3D11InputLayout**[mMeshCount];
    memset( mpInputLayout, 0, mMeshCount * sizeof(ID3D11InputLayout**) );
    
    cString materialName;
    char pNumber[4];
    cString materialValueName;

    CPUTModelDX11 *pMasterModelDX = (CPUTModelDX11*)pMasterModel;

    for(UINT ii=0; ii<mMeshCount; ii++)
    {
        if(pMasterModelDX)
        {
            // Reference the master model's mesh.  Don't create a new one.
            mpMesh[ii] = pMasterModelDX->mpMesh[ii];
            mpMesh[ii]->AddRef();
        }
        else
        {
            mpMesh[ii] = new CPUTMeshDX11();
        }
    }
    if( !pMasterModelDX )
    {
        // Not a clone/instance.  So, load the model's binary payload (i.e., vertex and index buffers)
        // TODO: Change to use GetModel()
        result = LoadModelPayload(resolvedPathAndFile);
        ASSERT( CPUTSUCCESS(result), _L("Failed loading model") );
    }

    for(UINT ii=0; ii<mMeshCount; ii++)
    {
        // get the right material number ('material0', 'material1', 'material2', etc)
        materialValueName = _L("material");
        _itoa_s(ii, pNumber, 4, 10);
        materialValueName.append(s2ws(pNumber));
        materialName = pBlock->GetValueByName(materialValueName)->ValueAsString();

        // Get/load material for this mesh
        cString meshSuffix  = itoc(ii);
#if GENERATE_BILLBOARD_TEXTURES
        cString *pFinalSystemNames = new cString[numSystemMaterials+2];
        pFinalSystemNames[1] = materialName + _L("Color");
        pFinalSystemNames[0] = materialName + _L("ColorNormal");
        int finalNumSystemMaterials = 2;
#else
        UINT totalNameCount = numSystemMaterials + NUM_GLOBAL_SYSTEM_MATERIALS;
        cString *pFinalSystemNames = new cString[totalNameCount];

        // Copy "global" system materials to caller-supplied list
        for( int jj=0; jj<numSystemMaterials; jj++ )
        {
            pFinalSystemNames[jj] = pSystemMaterialNames[jj];
        }
        pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_SHADOW_CAST]                 = _L("..\\..\\Material\\ShadowCast");
        pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_AMBIENT_SHADOW_CAST]         = _L("..\\..\\Material\\AmbientShadowCast");
        pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_HEIGHT_FIELD]                = _L("..\\..\\Material\\HeightField");
        pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_BOUNDING_BOX]                = _L("..\\..\\Material\\BoundingBox");
        pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_TERRAIN_LIGHT_MAP]           = _L("..\\..\\Material\\TerrainLightMap");
        pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_TERRAIN_AND_TREES_LIGHT_MAP] = _L("..\\..\\Material\\TerrainAndTreesLightMap");

        int finalNumSystemMaterials = numSystemMaterials + NUM_GLOBAL_SYSTEM_MATERIALS;
#endif
        CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)pAssetLibrary->GetMaterial(materialName, false, modelSuffix, meshSuffix, NULL, finalNumSystemMaterials, pFinalSystemNames);
        ASSERT( pMaterial, _L("Couldn't find material.") );

        delete []pFinalSystemNames;

        mpSubMaterialCount[ii] = pMaterial->GetSubMaterialCount();
        HEAPCHECK;
        SetSubMaterials(ii, pMaterial->GetSubMaterials());
        HEAPCHECK;

        // Release the extra refcount we're holding from the GetMaterial operation earlier
        // now the asset library, and this model have the only refcounts on that material
        pMaterial->Release();
    }

    return result;
}