///Ends mutation and refreshes display list
void GFXVertexList::EndMutate (int newvertexsize) {
  if (!(changed&CHANGE_MUTABLE)) {
    changed |= CHANGE_CHANGE;
  }
  RenormalizeNormals ();
  RefreshDisplayList();
  if (changed&CHANGE_CHANGE) {
    changed&=(~CHANGE_CHANGE);
  }
  if (newvertexsize) {
    numVertices = newvertexsize;
  }


}
///Ends mutation and refreshes display list
void GFXVertexList::EndMutate( int newvertexsize )
{
    this->UnMap();
    if ( !(changed&CHANGE_MUTABLE) )
        changed |= CHANGE_CHANGE;
    if (newvertexsize) {
        numVertices = newvertexsize;
        //Must keep synchronized - we'll only permit changing vertex count on single-list objects
        if (numlists == 1) *offsets = numVertices;
    }
    if (!vbo_data) {
        RenormalizeNormals();
        RefreshDisplayList();
    } else {
        RefreshDisplayList();
    }
    if (changed&CHANGE_CHANGE)
        changed &= (~CHANGE_CHANGE);
}
void GFXVertexList::Init( enum POLYTYPE *poly,
                          int numVertices,
                          const GFXVertex *vertices,
                          const GFXColorVertex *colors,
                          int numlists,
                          int *offsets,
                          bool Mutable,
                          unsigned int *indices )
{
    vbo_data = 0;
    
    int stride = 0;
    
    changed  = HAS_COLOR*( (colors != NULL) ? 1 : 0 );
    if (numlists > 0) {
        mode = new POLYTYPE[numlists];
        unique_mode = true;
        POLYTYPE umode = *poly;
        for (int pol = 0; pol < numlists; pol++) {
            mode[pol] = poly[pol];             //PolyLookup (poly[pol]);
            if ( unique_mode && (poly[pol] != umode) ) unique_mode = false;
        }
    } else {
        mode = NULL;
        unique_mode = false;
    }
    this->numlists    = numlists;
    this->numVertices = numVertices;
    if (numVertices) {
        if (vertices) {
            if (!GFX_BUFFER_MAP_UNMAP) {
                data.vertices = (GFXVertex*) malloc( sizeof (GFXVertex)*numVertices );
                memcpy( data.vertices, vertices, sizeof (GFXVertex)*numVertices );
            } else {
                data.vertices = const_cast< GFXVertex* > (vertices);                  //will *not* modify
            }
        } else if (colors) {
            if (!GFX_BUFFER_MAP_UNMAP) {
                data.colors = (GFXColorVertex*) malloc( sizeof (GFXColorVertex)*numVertices );
                memcpy( data.colors, colors, sizeof (GFXColorVertex)*numVertices );
            } else {
                data.colors = const_cast< GFXColorVertex* > (colors);
            }
        }
    } else {
        data.vertices = NULL;
        data.colors   = NULL;
    }
    this->offsets = new int[numlists];
    memcpy( this->offsets, offsets, sizeof (int)*numlists );
    int i;
    unsigned int numindices = 0;
    for (i = 0; i < numlists; i++)
        numindices += offsets[i];
    display_list = 0;
    if (Mutable)
        changed |= CHANGE_MUTABLE;
    else
        changed |= CHANGE_CHANGE;
    if (indices) {
        stride = INDEX_BYTE;
        if (numVertices > 255)
            stride = INDEX_SHORT;
        if (numVertices > 65535)
            stride = INDEX_INT;
                
        index.b = (unsigned char*) malloc( stride*numindices );
        switch (stride)
        {
        case INDEX_BYTE:
            VSFileSystem::vs_dprintf(3, "Optimized vertex list - using 8-bit indices\n");
            for (unsigned int i = 0; i < numindices; i++)
                index.b[i] = indices[i];
            break;
        case INDEX_SHORT:
            VSFileSystem::vs_dprintf(3, "Optimized vertex list - using 16-bit indices\n");
            for (unsigned int i = 0; i < numindices; i++)
                index.s[i] = indices[i];
            break;
        case INDEX_INT:
            VSFileSystem::vs_dprintf(2, "Optimized vertex list - using 32-bit indices\n");
            for (unsigned int i = 0; i < numindices; i++)
                index.i[i] = indices[i];
            break;
        }
    } else {
        index.b = NULL;
    }
    changed |= stride;
    RenormalizeNormals();
    RefreshDisplayList();
    if (GFX_BUFFER_MAP_UNMAP) {
        if (!vbo_data) {
            //backstore required
            if (numVertices) {
                if (vertices) {
                    data.vertices = (GFXVertex*) malloc( sizeof (GFXVertex)*numVertices );
                    memcpy( data.vertices, vertices, sizeof (GFXVertex)*numVertices );
                } else if (colors) {
                    data.colors = (GFXColorVertex*) malloc( sizeof (GFXColorVertex)*numVertices );
                    memcpy( data.colors, colors, sizeof (GFXColorVertex)*numVertices );
                }
            }
        } else {
            if (index.b)
                free( index.b );
            index.b = NULL;
            data.vertices = NULL;
            data.colors = NULL;
        }
    }
    if (Mutable)
        changed |= CHANGE_MUTABLE;          //for display lists
    else
        changed &= (~CHANGE_CHANGE);
}