anchor.diff:    //They all run at different speeds so we can't adjoin them in one layer
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   
  -  //Each new layer inflicts 10% fps drop
  -  for AL := Low(TAnimLayer) to High(TAnimLayer) do
  -  begin
  -    case AL of
  -      alWater: TexOffset := 300 * (aAnimStep mod 8 + 1);       // 300..2400
  -      alFalls: TexOffset := 300 * (aAnimStep mod 5 + 1 + 8);   // 2700..3900
  -      alSwamp: TexOffset := 300 * ((aAnimStep mod 24) div 8 + 1 + 8 + 5); // 4200..4800
  -      else     TexOffset := 0;
  -    end;
  -
  -    with gTerrain do
  -    for I := fClipRect.Top to fClipRect.Bottom do
  -    for K := fClipRect.Left to fClipRect.Right do
  -    if (TexOffset + Land[I,K].Terrain + 1 <= High(GFXData[rxTiles]))
  -    and (GFXData[rxTiles, TexOffset + Land[I,K].Terrain + 1].Tex.ID <> 0)
  -    and (aFOW.CheckTileRevelation(K,I) > FOG_OF_WAR_ACT) then //No animation in FOW
  +  if fUseVBO and TKMResSprites.AllTilesInOneAtlas then
  +  begin
  +    if Length(fAnimTilesVtx) = 0 then Exit; //There is no animation on map
  +    BindVBOArray(vat_AnimTile);
  +    //Bind to tiles texture. All tiles should be placed 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);
  +
  +    //Setup vertex and UV layout and offsets
  +    glEnableClientState(GL_VERTEX_ARRAY);
  +    glVertexPointer(3, GL_FLOAT, SizeOf(TAnimTileVertice), Pointer(0));
  +    glClientActiveTexture(GL_TEXTURE0);
  +    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  +    glTexCoordPointer(2, GL_FLOAT, SizeOf(TAnimTileVertice), Pointer(12));
  +
  +    //Here and above OGL requests Pointer, but in fact it's just a number (offset within Array)
  +    glDrawElements(GL_TRIANGLES, Length(fAnimTilesInd), GL_UNSIGNED_INT, Pointer(0));
  +
  +    glDisableClientState(GL_VERTEX_ARRAY);
  +    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  +  end else begin
  +    //Each new layer inflicts 10% fps drop
  +    for AL := Low(TAnimLayer) to High(TAnimLayer) do
       begin
  -      TRender.BindTexture(GFXData[rxTiles, TexOffset + Land[I,K].Terrain + 1].Tex.ID);
  -      TexC := GetTileUV(TexOffset + Land[I,K].Terrain, Land[I,K].Rotation);
  -
  -      glBegin(GL_TRIANGLE_FAN);
  -        glColor4f(1,1,1,1);
  -        if RENDER_3D then
  -        begin
  -          glTexCoord2fv(@TexC[1]); glVertex3f(K-1,I-1,-Land[I,K].Height/CELL_HEIGHT_DIV);
  -          glTexCoord2fv(@TexC[2]); glVertex3f(K-1,I  ,-Land[I+1,K].Height/CELL_HEIGHT_DIV);
  -          glTexCoord2fv(@TexC[3]); glVertex3f(K  ,I  ,-Land[I+1,K+1].Height/CELL_HEIGHT_DIV);
  -          glTexCoord2fv(@TexC[4]); glVertex3f(K  ,I-1,-Land[I,K+1].Height/CELL_HEIGHT_DIV);
  -        end
  -        else
  -        begin
  -          glTexCoord2fv(@TexC[1]); glVertex3f(K-1,I-1-Land[I,K].Height/CELL_HEIGHT_DIV, I-1);
  -          glTexCoord2fv(@TexC[2]); glVertex3f(K-1,I  -Land[I+1,K].Height/CELL_HEIGHT_DIV, I-1);
  -          glTexCoord2fv(@TexC[3]); glVertex3f(K  ,I  -Land[I+1,K+1].Height/CELL_HEIGHT_DIV, I-1);
  -          glTexCoord2fv(@TexC[4]); glVertex3f(K  ,I-1-Land[I,K+1].Height/CELL_HEIGHT_DIV, I-1);
  -        end;
  -      glEnd;
  +      case AL of
  +        alWater: TexOffset := 300 * (aAnimStep mod 8 + 1);       // 300..2400
  +        alFalls: TexOffset := 300 * (aAnimStep mod 5 + 1 + 8);   // 2700..3900
  +        alSwamp: TexOffset := 300 * ((aAnimStep mod 24) div 8 + 1 + 8 + 5); // 4200..4800
  +        else     TexOffset := 0;
  +      end;
  +
  +      with gTerrain do
  +      for I := fClipRect.Top to fClipRect.Bottom do
  +      for K := fClipRect.Left to fClipRect.Right do
  +      if (TexOffset + Land[I,K].Terrain + 1 <= High(GFXData[rxTiles]))
  +      and (GFXData[rxTiles, TexOffset + Land[I,K].Terrain + 1].Tex.ID <> 0)
  +      and (aFOW.CheckTileRevelation(K,I) > FOG_OF_WAR_ACT) then //No animation in FOW
  +      begin
  +        TRender.BindTexture(GFXData[rxTiles, TexOffset + Land[I,K].Terrain + 1].Tex.ID);
  +        TexC := GetTileUV(TexOffset + Land[I,K].Terrain, Land[I,K].Rotation);
  +
  +        glBegin(GL_TRIANGLE_FAN);
  +          glColor4f(1,1,1,1);
  +          if RENDER_3D then
  +          begin
  +            glTexCoord2fv(@TexC[1]); glVertex3f(K-1,I-1,-Land[I,K].Height/CELL_HEIGHT_DIV);
  +            glTexCoord2fv(@TexC[2]); glVertex3f(K-1,I  ,-Land[I+1,K].Height/CELL_HEIGHT_DIV);
  +            glTexCoord2fv(@TexC[3]); glVertex3f(K  ,I  ,-Land[I+1,K+1].Height/CELL_HEIGHT_DIV);
  +            glTexCoord2fv(@TexC[4]); glVertex3f(K  ,I-1,-Land[I,K+1].Height/CELL_HEIGHT_DIV);
  +          end
  +          else
  +          begin
  +            glTexCoord2fv(@TexC[1]); glVertex3f(K-1,I-1-Land[I,K].Height/CELL_HEIGHT_DIV, I-1);
  +            glTexCoord2fv(@TexC[2]); glVertex3f(K-1,I  -Land[I+1,K].Height/CELL_HEIGHT_DIV, I-1);
  +            glTexCoord2fv(@TexC[3]); glVertex3f(K  ,I  -Land[I+1,K+1].Height/CELL_HEIGHT_DIV, I-1);
  +            glTexCoord2fv(@TexC[4]); glVertex3f(K  ,I-1-Land[I,K+1].Height/CELL_HEIGHT_DIV, I-1);
  +          end;
  +        glEnd;
  +      end;
       end;
     end;
   end;
  
positive.code:   pData[3] := $00000000;
    fTextB := TRender.GenTexture(4, 1, @pData[0], tf_RGBA8);
  
    fUseVBO := VBOSupported;
  
    if fUseVBO then
    begin
      glGenBuffers(1, @fVtxShd);
      glGenBuffers(1, @fIndShd);
    end;
  end;
  
  
  destructor TRenderTerrain.Destroy;
  begin
    fUseVBO := VBOSupported; //Could have been set to false if 3D rendering is enabled, so reset it
    if fUseVBO then
    begin
      //Since RenderTerrain is created fresh everytime fGame is created, we should clear
      //the buffers to avoid memory leaks.
      glDeleteBuffers(1, @fVtxShd);
      glDeleteBuffers(1, @fIndShd);
    end;
    inherited;
  end;
  
negative.code: 
    if fUseVBO then
    begin
      BindVBOArray(vat_Tile);
      //Setup vertex and UV layout and offsets
      glEnableClientState(GL_VERTEX_ARRAY);
      glVertexPointer(3, GL_FLOAT, SizeOf(TTileVertice), Pointer(0));
  