VertexBufferState::VertexBufferState( const GLEWContext* glewContext ) 
        : _pmvMatrix( Matrix4f::IDENTITY )
        , _glewContext( glewContext )
        , _renderMode( RENDER_MODE_DISPLAY_LIST )
        , _useColors( false )
        , _useFrustumCulling( true )
{
    _range[0] = 0.f;
    _range[1] = 1.f;
    resetRegion();
    PLYLIBASSERT( glewContext );
} 
/*  Finish partial setup - sort, reindex and merge into global data.  */
void VertexBufferLeaf::setupTree( VertexData& data, const Index start,
                                  const Index length, const Axis axis,
                                  const size_t /*depth*/,
                                  VertexBufferData& globalData )
{
    data.sort( start, length, axis );
    _vertexStart = globalData.vertices.size();
    _vertexLength = 0;
    _indexStart = globalData.indices.size();
    _indexLength = 0;

    const bool hasColors = !data.colors.empty();

    // stores the new indices (relative to _start)
    std::map< Index, ShortIndex > newIndex;

    for( Index t = 0; t < length; ++t )
    {
        for( Index v = 0; v < 3; ++v )
        {
            Index i = data.triangles[start + t][v];
            if( newIndex.find( i ) == newIndex.end() )
            {
                newIndex[i] = _vertexLength++;
                // assert number of vertices does not exceed SmallIndex range
                PLYLIBASSERT( _vertexLength );
                globalData.vertices.push_back( data.vertices[i] );
                if( hasColors )
                    globalData.colors.push_back( data.colors[i] );
                globalData.normals.push_back( data.normals[i] );
            }
            globalData.indices.push_back( newIndex[i] );
            ++_indexLength;
        }
    }

#ifndef NDEBUG
    PLYLIBINFO << "setupTree" << "( " << _indexStart << ", " << _indexLength
             << "; start " << _vertexStart << ", " << _vertexLength
             << " vertices)." << std::endl;
#endif
}