//-----------------------------------------------------------------------------
CPUTResult CPUTRenderStateBlockOGL::ReadProperties(
    CPUTConfigFile                &file,
    const cString                 &blockName,
    const CPUTRenderStateMapEntry *pMap,
    void                          *pDest
)
{
  //  assert(false);
    CPUTConfigBlock *pProperties = file.GetBlockByName(blockName);
    if( !pProperties )
    {
        // Note: We choose not to assert here.  The nature of the parameter block is that
        // only the values that deviate from default need to be present.  It is very
        // common that blocks will be missing
        return CPUT_ERROR_PARAMETER_BLOCK_NOT_FOUND;
    }

    UINT count = pProperties->ValueCount();
    for( UINT ii=0; ii<count; ii++ )
    {
        // Get the next property
        CPUTConfigEntry *pValue = pProperties->GetValue(ii);
        ASSERT( pValue->IsValid(), _L("Invalid Value: '")+pValue->NameAsString()+_L("'.") );
        ReadValue( pValue, pMap, pDest );
    }
    return CPUT_SUCCESS;
} // CPUTRenderStateBlockOGL::ReadProperties()
//-----------------------------------------------------------------------------
void ReadMacrosFromConfigBlock(
    CPUTConfigBlock   *pMacrosBlock,
    CPUT_SHADER_MACRO  *pShaderMacros,
    CPUT_SHADER_MACRO **pUserSpecifiedMacros,
    int               *pNumUserSpecifiedMacros,
    CPUT_SHADER_MACRO **pFinalShaderMacros
    ){
        *pNumUserSpecifiedMacros = pMacrosBlock->ValueCount();

        // Count the number of macros passed in
        CPUT_SHADER_MACRO *pMacro = (CPUT_SHADER_MACRO*)pShaderMacros;
        int numPassedInMacros = 0;
        if( pMacro )
        {
            while( pMacro->Name )
            {
                ++numPassedInMacros;
                ++pMacro;
            }
        }

        // Allocate an array of macro pointer large enough to contain the passed-in macros plus those specified in the .mtl file.
        *pFinalShaderMacros = new CPUT_SHADER_MACRO[*pNumUserSpecifiedMacros + numPassedInMacros + 1];

        // Copy the passed-in macro pointers to the final array
        int jj;
        for( jj=0; jj<numPassedInMacros; jj++ )
        {
            (*pFinalShaderMacros)[jj] = *(CPUT_SHADER_MACRO*)&pShaderMacros[jj];
        }

        // Create a CPUT_SHADER_MACRO for each of the macros specified in the .mtl file.
        // And, add their pointers to the final array
        *pUserSpecifiedMacros = new CPUT_SHADER_MACRO[*pNumUserSpecifiedMacros];
        for( int kk=0; kk<*pNumUserSpecifiedMacros; kk++, jj++ )
        {
            CPUTConfigEntry *pValue   = pMacrosBlock->GetValue(kk);
            (*pUserSpecifiedMacros)[kk].Name       = ws2s(pValue->NameAsString());
            (*pUserSpecifiedMacros)[kk].Definition = ws2s(pValue->ValueAsString());
            (*pFinalShaderMacros)[jj] = (*pUserSpecifiedMacros)[kk];
        }
        (*pFinalShaderMacros)[jj].Name = NULL;
        (*pFinalShaderMacros)[jj].Definition = NULL;
}