anchor.diff:    //Draw with VBO only if all tiles are on the same texture
     if fUseVBO and TKMResSprites.AllTilesInOneAtlas then
     begin
  +    BindVBOArray(vat_Tile);
       //Bind to tiles texture. All tiles should be places in 1 atlas,
       //so to get TexId we can use any of terrain tile Id (f.e. 1st)
       TRender.BindTexture(GFXData[rxTiles, 1].Tex.ID);
  
positive.code:   KM_CommonClasses, KM_CommonTypes, KM_Defaults, KM_FogOfWar, KM_Pics, KM_ResSprites, KM_Points, KM_Terrain;
  
  type
    TUVRect = array [1 .. 4, 1 .. 2] of Single; // Texture UV coordinates
    TTileVertice = record
      X, Y, Z, UTile, VTile, ULit, UShd, UFow: Single;
    end;
    TFOWVertice = record
      X, Y, Z, UFow: Single;
    end;
  
    //Render terrain without sprites
  
negative.code: end;
  
  
  procedure TRenderTerrain.UpdateVBO(aAnimStep: Integer; aFOW: TKMFogOfWarCommon);
  var
    Fog: PKMByte2Array;
  
    procedure SetTileVertex(aH: Integer; aTX, aTY: Word; aIsBottomRow: Boolean; aUTile, aVTile: Single);
    begin
      with gTerrain do
      begin
        fTilesVtx[aH].X := aTX;
        fTilesVtx[aH].Y := aTY - Land[aTY+1, aTX+1].Height / CELL_HEIGHT_DIV;
        fTilesVtx[aH].Z := aTY - Byte(aIsBottomRow);
        fTilesVtx[aH].UTile := aUTile;
        fTilesVtx[aH].VTile := aVTile;
        fTilesVtx[aH].ULit := Land[aTY+1, aTX+1].Light;
        fTilesVtx[aH].UShd := -Land[aTY+1, aTX+1].Light;
        if Fog <> nil then
          fTilesVtx[aH].UFow := Fog^[aTY, aTX] shr 8 //  shr 8 = / 256
        else
          fTilesVtx[aH].UFow := 255;
      end;
    end;
  
    procedure SetAnimTileVertex(aQ: Integer; aTX, aTY: Word; aIsBottomRow: Boolean; aUAnimTile, aVAnimTile: Single);
    begin
      with gTerrain do
      begin
        fAnimTilesVtx[aQ].X := aTX;
        fAnimTilesVtx[aQ].Y := aTY - Land[aTY+1, aTX+1].Height / CELL_HEIGHT_DIV;
        fAnimTilesVtx[aQ].Z := aTY - Byte(aIsBottomRow);
        fAnimTilesVtx[aQ].UAnim := aUAnimTile;
        fAnimTilesVtx[aQ].VAnim := aVAnimTile;
      end;
    end;
  
    function TryAddAnimTex(var aQ: Integer; aTX, aTY, aTexOffset: Word): Boolean;
    var TexAnimC: TUVRect;
    begin
      Result := False;
      with gTerrain do
        if (aTexOffset + Land[aTY,aTX].Terrain + 1 <= High(GFXData[rxTiles]))
           and (GFXData[rxTiles, aTexOffset + Land[aTY,aTX].Terrain + 1].Tex.ID <> 0)
           and (aFOW.CheckTileRevelation(aTX,aTY) > FOG_OF_WAR_ACT) then
        begin
          TexAnimC := GetTileUV(aTexOffset + Land[aTY,aTX].Terrain, Land[aTY,aTX].Rotation mod 4);
  
          SetAnimTileVertex(aQ,   aTX-1, aTY-1, False, TexAnimC[1][1], TexAnimC[1][2]);
          SetAnimTileVertex(aQ+1, aTX-1, aTY,   True,  TexAnimC[2][1], TexAnimC[2][2]);
          SetAnimTileVertex(aQ+2, aTX,   aTY,   True,  TexAnimC[3][1], TexAnimC[3][2]);
          SetAnimTileVertex(aQ+3, aTX,   aTY-1, False, TexAnimC[4][1], TexAnimC[4][2]);
  
          aQ := aQ + 4;
          Result := True;
        end;
    end;
  
  var
    I,K,H,Q,AnimCnt: Integer;
    SizeX, SizeY: Word;
    tX, tY: Word;
    Row: Integer;
    TexTileC: TUVRect;
    AL: TAnimLayer;
    TexOffsetWater, TexOffsetFalls, TexOffsetSwamp: Word;
  begin
    if not fUseVBO then Exit;
  
    fLastBindVBOArrayType := vat_None;
  
    if aFOW is TKMFogOfWar then
      Fog := @TKMFogOfWar(aFOW).Revelation
  