//----------------------------------------------------------------------------
void SEVertexBuffer::BuildCompatibleArray(const SEAttributes& rIAttributes,
    bool bPackARGB, int& rChannels, float*& rCompatible) const
{
    // 注意这里使用unsigned int来存储数据,
    // 从而允许同时存储float和32位ARGB格式的unsigned int数据,
    // 把float指针显示类型转换为unsigned int指针然后取*操作没有任何问题,
    // 但反过来把unsigned int指针显示类型转换为float指针并取*操作,
    // 则取出的数据可能为非法浮点数据,
    // 因此如果使用std::vector<float>将可能存在数据非正常转换的问题
    std::vector<unsigned int> tempCompatible;    
    const unsigned int* puiData;
    float fOne = 1.0f;
    unsigned int* puiOne = (unsigned int*)&fOne;
    int iUnit, iIChannels, iVBChannels;

    for( int i = 0, j; i < m_iVertexCount; i++ )
    {
        // 填充顶点
        if( rIAttributes.HasPosition() )
        {
            iIChannels = rIAttributes.GetPositionChannels();
            iVBChannels = m_Attributes.GetPositionChannels();
            puiData = (unsigned int*)PositionTuple(i);
            if( iVBChannels < iIChannels )
            {
                for( j = 0; j < iVBChannels; j++ )
                {
                    tempCompatible.push_back(*puiData++);
                }
                for( j = iVBChannels; j < iIChannels; j++ )
                {
                    // 将w分量填充为1.0,从而成为齐次空间顶点
                    tempCompatible.push_back(*puiOne);
                }
            }
            else
            {
                for( j = 0; j < iIChannels; j++ )
                {
                    tempCompatible.push_back(*puiData++);
                }
            }
        }

        // 填充法线
        if( rIAttributes.HasNormal() )
        {
            iIChannels = rIAttributes.GetNormalChannels();
            iVBChannels = m_Attributes.GetNormalChannels();
            puiData = (unsigned int*)NormalTuple(i);
            if( iVBChannels < iIChannels )
            {
                for( j = 0; j < iVBChannels; j++ )
                {
                    tempCompatible.push_back(*puiData++);
                }
                for( j = iVBChannels; j < iIChannels; j++ )
                {
                    // 将w分量填充为0.0,从而成为齐次空间向量
                    tempCompatible.push_back(0);
                }
            }
            else
            {
                for( j = 0; j < iIChannels; j++ )
                {
                    tempCompatible.push_back(*puiData++);
                }
            }
        }

        // 填充若干组颜色
        for( iUnit = 0; iUnit < (int)rIAttributes.GetMaxColors(); iUnit++ )
        {
            if( rIAttributes.HasColor(iUnit) )
            {
                unsigned int auiColor[4], uiPackColor, uiValue;
                float fValue;

                iIChannels = rIAttributes.GetColorChannels(iUnit);
                iVBChannels = m_Attributes.GetColorChannels(iUnit);
                puiData = (unsigned int*)ColorTuple(iUnit, i);
                if( iVBChannels < iIChannels )
                {
                    for( j = 0; j < iVBChannels; j++ )
                    {
                        tempCompatible.push_back(*puiData++);
                    }
                    for( j = iVBChannels; j < iIChannels; j++ )
                    {
                        // 将a分量填充为1.0,成为不透明颜色
                        tempCompatible.push_back(*puiOne);
                    }
                    if( bPackARGB )
                    {
                        for( j = iIChannels; j < 4; j++ )
                        {
                            // 将a分量填充为1.0,成为不透明颜色
                            tempCompatible.push_back(*puiOne);
                        }

                        // 从[0.0f, 1.0f]映射到[0,255]
                        for( j = 3; j >= 0; j-- )
                        {
                            uiValue = tempCompatible.back();
                            fValue = *(float*)&uiValue;
                            auiColor[j] = (unsigned int)(255.0f * fValue);
                            tempCompatible.pop_back();
                        }

                        uiPackColor =
                            (auiColor[2]      ) |  // blue
                            (auiColor[1] <<  8) |  // green
                            (auiColor[0] << 16) |  // red
                            (auiColor[3] << 24);   // alpha

                        tempCompatible.push_back(uiPackColor);
                    }
                }
                else
                {
                    for( j = 0; j < iIChannels; j++ )
                    {
                        tempCompatible.push_back(*puiData++);
                    }
                    if( bPackARGB )
                    {
                        for( j = iIChannels; j < 4; j++ )
                        {
                            // 将a分量填充为1.0,成为不透明颜色
                            tempCompatible.push_back(*puiOne);
                        }

                        // 从[0.0f, 1.0f]映射到[0,255]
                        for( j = 3; j >= 0; j-- )
                        {
                            uiValue = tempCompatible.back();
                            fValue = *(float*)&uiValue;
                            auiColor[j] = (unsigned int)(255.0f * fValue);
                            tempCompatible.pop_back();
                        }

                        uiPackColor =
                            (auiColor[2]      ) |  // blue
                            (auiColor[1] <<  8) |  // green
                            (auiColor[0] << 16) |  // red
                            (auiColor[3] << 24);   // alpha

                        tempCompatible.push_back(uiPackColor);
                    }
                }
            }
        }

        // 填充若干组纹理坐标
        for( iUnit = 0; iUnit < (int)rIAttributes.GetMaxTCoords(); iUnit++ )
        {
            if( rIAttributes.HasTCoord(iUnit) )
            {
                iIChannels = rIAttributes.GetTCoordChannels(iUnit);
                iVBChannels = m_Attributes.GetTCoordChannels(iUnit);
                puiData = (unsigned int*)TCoordTuple(iUnit, i);
                if( iVBChannels < iIChannels )
                {
                    for( j = 0; j < iVBChannels; j++ )
                    {
                        tempCompatible.push_back(*puiData++);
                    }
                    for( j = iVBChannels; j < iIChannels; j++ )
                    {
                        // 填充为0,从而高维纹理坐标兼容低维纹理坐标
                        tempCompatible.push_back(0);
                    }
                }
                else
                {
                    for( j = 0; j < iIChannels; j++ )
                    {
                        tempCompatible.push_back(*puiData++);
                    }
                }
            }
        }
    }

    rChannels = (int)tempCompatible.size();
    if( !rCompatible )
    {
        // 调用者有责任释放该内存
        rCompatible = SE_NEW float[rChannels];
    }