Example #1
0
// Render - render this model (only)
//-----------------------------------------------------------------------------
void CPUTModelDX11::RenderShadow(CPUTRenderParameters &renderParams)
{
    CPUTRenderParametersDX *pParams = (CPUTRenderParametersDX*)&renderParams;
    CPUTCamera             *pCamera = pParams->mpCamera;

#ifdef SUPPORT_DRAWING_BOUNDING_BOXES 
    if( renderParams.mShowBoundingBoxes && (!pCamera || pCamera->mFrustum.IsVisible( mBoundingBoxCenterWorldSpace, mBoundingBoxHalfWorldSpace )))
    {
        DrawBoundingBox( renderParams );
    }
#endif
    if( !renderParams.mDrawModels ) { return; }

    // TODO: add world-space bounding box to model so we don't need to do that work every frame
    if( !pParams->mRenderOnlyVisibleModels || !pCamera || pCamera->mFrustum.IsVisible( mBoundingBoxCenterWorldSpace, mBoundingBoxHalfWorldSpace ) )
    {
        // Update the model's render states only once (and then iterate over materials)
        UpdateShaderConstants(renderParams);

        CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)(mpShadowCastMaterial);
        pMaterial->SetRenderStates(renderParams);

        // loop over all meshes in this model and draw them
        for(UINT ii=0; ii<mMeshCount; ii++)
        {
            ((CPUTMeshDX11*)mpMesh[ii])->DrawShadow(renderParams, this);
        }
    }
}
//-----------------------------------------------------------------------------
CPUTMaterial *CPUTMaterialDX11::CloneMaterial(const cString &fileName, const CPUTModel *pModel, int meshIndex)
{
    CPUTMaterialDX11 *pMaterial = new CPUTMaterialDX11();

    // TODO: move texture to base class.  All APIs have textures.
    pMaterial->mpPixelShader    = mpPixelShader;    if(mpPixelShader)    mpPixelShader->AddRef();   
    pMaterial->mpComputeShader  = mpComputeShader;  if(mpComputeShader)  mpComputeShader->AddRef();
    pMaterial->mpVertexShader   = mpVertexShader;   if(mpVertexShader)   mpVertexShader->AddRef();
    pMaterial->mpGeometryShader = mpGeometryShader; if(mpGeometryShader) mpGeometryShader->AddRef();
    pMaterial->mpHullShader     = mpHullShader;     if(mpHullShader)     mpHullShader->AddRef();
    pMaterial->mpDomainShader   = mpDomainShader;   if(mpDomainShader)   mpDomainShader->AddRef();

    mPixelShaderParameters.CloneShaderParameters(    &pMaterial->mPixelShaderParameters );
    mComputeShaderParameters.CloneShaderParameters(  &pMaterial->mComputeShaderParameters );
    mVertexShaderParameters.CloneShaderParameters(   &pMaterial->mVertexShaderParameters );
    mGeometryShaderParameters.CloneShaderParameters( &pMaterial->mGeometryShaderParameters );
    mHullShaderParameters.CloneShaderParameters(     &pMaterial->mHullShaderParameters );
    mDomainShaderParameters.CloneShaderParameters(   &pMaterial->mDomainShaderParameters );

    pMaterial->mpShaderParametersList[0] =  &pMaterial->mPixelShaderParameters,
    pMaterial->mpShaderParametersList[1] =  &pMaterial->mComputeShaderParameters,
    pMaterial->mpShaderParametersList[2] =  &pMaterial->mVertexShaderParameters,
    pMaterial->mpShaderParametersList[3] =  &pMaterial->mGeometryShaderParameters,
    pMaterial->mpShaderParametersList[4] =  &pMaterial->mHullShaderParameters,
    pMaterial->mpShaderParametersList[5] =  &pMaterial->mDomainShaderParameters,
    pMaterial->mpShaderParametersList[6] =  NULL;

    pMaterial->mpRenderStateBlock = mpRenderStateBlock; if( mpRenderStateBlock ) mpRenderStateBlock->AddRef();

    pMaterial->mMaterialName      = mMaterialName + ptoc(pModel) + itoc(meshIndex);
    pMaterial->mMaterialNameHash  = CPUTComputeHash(pMaterial->mMaterialName);
    pMaterial->mConfigBlock       = mConfigBlock;
    pMaterial->mBufferCount       = mBufferCount;

    // For each of the shader stages, bind shaders and buffers
    for( CPUTShaderParameters **pCur = pMaterial->mpShaderParametersList; *pCur; pCur++ ) // Bind textures and buffersfor each shader stage
    {
        pMaterial->BindTextures(        **pCur, pModel, meshIndex );
        pMaterial->BindBuffers(         **pCur, pModel, meshIndex );
        pMaterial->BindUAVs(            **pCur, pModel, meshIndex );
        pMaterial->BindConstantBuffers( **pCur, pModel, meshIndex );
    }
    // Append this clone to our clone list
    if( mpMaterialNextClone )
    {
        // Already have a list, so add to the end of it.
        ((CPUTMaterialDX11*)mpMaterialLastClone)->mpMaterialNextClone = pMaterial;
    } else
    {
        // No list yet, so start it with this material.
        mpMaterialNextClone = pMaterial;
        mpMaterialLastClone = pMaterial;
    }
    pMaterial->mpModel    = pModel;
    pMaterial->mMeshIndex = meshIndex;
    return pMaterial;
}
Example #3
0
//-----------------------------------------------------------------------------
void CPUTModelDX11::DrawBoundingBox(CPUTRenderParameters &renderParams)
{
    CPUTRenderParametersDX *pParams = (CPUTRenderParametersDX*)&renderParams;

    UpdateShaderConstants(renderParams);
    CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)mpBoundingBoxMaterial;

    pMaterial->SetRenderStates(renderParams);
    ((CPUTMeshDX11*)mpBoundingBoxMesh)->Draw(renderParams, this);
}
//-----------------------------------------------------------------------------
void CPUTModelDX11::DrawBoundingBox(CPUTRenderParameters &renderParams)
{
    UpdateShaderConstants(renderParams);

    UINT index  = mpSubMaterialCount[0] + CPUT_MATERIAL_INDEX_BOUNDING_BOX;
    CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)(mpMaterial[0][index]);
    pMaterial->SetRenderStates(renderParams);

    ((CPUTMeshDX11*)mpBoundingBoxMesh)->Draw(renderParams, mpInputLayout[0][index]);
}
// Render this model. Render only this model, not its children or siblings.
//-----------------------------------------------------------------------------
void CPUTModelDX11::Render(CPUTRenderParameters &renderParams, int materialIndex)
{
    CPUTRenderParametersDX *pParams = (CPUTRenderParametersDX*)&renderParams;
    CPUTCamera             *pCamera = pParams->mpCamera;

    // TODO: Move bboxDirty to member and set only when model moves.
    bool bboxDirty = true;
    if( bboxDirty )
    {
        UpdateBoundsWorldSpace();
    }

#ifdef SUPPORT_DRAWING_BOUNDING_BOXES 
    if( renderParams.mShowBoundingBoxes && (!pCamera || pCamera->mFrustum.IsVisible( mBoundingBoxCenterWorldSpace, mBoundingBoxHalfWorldSpace )))
    {
        DrawBoundingBox( renderParams );
    }
#endif
    if( !renderParams.mDrawModels ) { return; }

    if( !pParams->mRenderOnlyVisibleModels || !pCamera || pCamera->mFrustum.IsVisible( mBoundingBoxCenterWorldSpace, mBoundingBoxHalfWorldSpace ) )
    {
        // Update the model's constant buffer.
        // Note that the materials reference this, so we need to do it only once for all of the model's meshes.
        UpdateShaderConstants(renderParams);

        // loop over all meshes in this model and draw them
        for(UINT ii=0; ii<mMeshCount; ii++)
        {
            UINT finalMaterialIndex = GetMaterialIndex(ii, materialIndex);
            ASSERT( finalMaterialIndex < mpSubMaterialCount[ii], _L("material index out of range."));
            CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)(mpMaterial[ii][finalMaterialIndex]);
            pMaterial->SetRenderStates(renderParams);

            ((CPUTMeshDX11*)mpMesh[ii])->Draw(renderParams, mpInputLayout[ii][finalMaterialIndex]);
        }
    }
}
Example #6
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;
}
// 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;
}