Here is a very simple approach that doesn't involve changing mesh data on the fly. Chunk nearby meshes (depending on how many you'd like to store in memory at once); each chunk is a set of hills with a simple flat bottom obscured from the user's view. When the user's window approaches the end of a chunk, generate a new one.
In LibGDX you simply generate a list of points and from that create a new Mesh object. Whichever mesh is within the user's view, you would render with a shader. You could do something simple, like repeat a pattern with GL_REPEAT by giving texcoords to each mesh vertex, or you could use something more advanced like creating the pattern in the shader.