what will ultimately be a reusable piece of code.
DON'T.
I beg you, stop and rethink your strategy.
Any code that has glBegin/glVertex/etc. in it will be doomed to the compatibility ghetto, limited to 20k vertices while any semi-modern hardware is capable of millions.
I will write article about Pascal beginners being cursed with this glBegin trap and why is it so horrible... Some day.
The first consequence is saying bye-bye to GLES and, correspondingly, to Raspberry Pi 2/3 support.

Here is my horrible code I replaced the glBegin travesty in my project with. It now runs on Raspberry Pi 2 and 3 (I use ANGLE over Direct3d on Windows to develop it because compiling on RPi takes forever):

Code:
  TDumbUniMesh = class (TAbstractMesh)
    //for absolutely dynamic things that get uploaded to the videocard
    //  every frame.
  public
    components: TRenderComponentSet;
    colors: array of TVector4f;
    normals: array of TVector3f;
    texcoords: array of TVector2f;
    vertices: array of TVector3f;
    indices: array of GLushort; //word aka uint16
    matrix: TMatrix4f;

    constructor Create(_components: TRenderComponentSet =
                                     [renc_Vertex, renc_Texcoord, renc_Color]);

    //assumes origin in *upper* left corner (y axis downwards, z axis towards the viewer)
    procedure AddQuad2d(left, top, right, bottom: GLfloat;
      txleft: GLfloat = 0; txtop: GLfloat = 0; txright: GLfloat = 1; txbottom: GLfloat = 1);
    procedure Render; override;
    destructor Destroy;
    procedure Color3f(_r, _g, _b: float);
    procedure Color4f(_r, _g, _b, _a: float);
    procedure Color(c: TVector3f); overload;
    procedure Color(c: TVector4f); overload;
    procedure LineTexCoords(txleft, txtop, txright, txbottom: float);
    procedure AddLine(c: array of const;  width: float); overload;
    procedure AddLineLoop(c: array of const;  width: float); overload;
    procedure AddLine(points: array of TVector2f;  width: float); overload;
    procedure AddLineLoop(points: array of TVector2f;  width: float); overload;

    //specifies opposite corners of a rectangle
    procedure SetLineTexCoords(a, b: TVector2f; _repeat: boolean); overload;

    procedure SetLineGradientTo(c: TVector4f);  // from current color to this
    procedure SetLineTexCoords; // default glyph from | character in the font
  protected
    currentColor: TVector4f;
    lineTC: array[0..3] of TVector2f;
    lineTCrepeat: boolean;
    lineGrad: TVector4f;
    currentNormal: TVector3f;
    maxVertex, maxIndex: integer;
    function ParseAOCToVector2f(var c: array of const): TVector2fArray;
    procedure GenerateLineMesh(points: array of TVector2f; width: float; loop: boolean);
    procedure EnlargeBuffersIfNecessary; // according to maxVertex, maxIndex
  public
    property GetCurrentColor: TVector4f read currentColor;
  end; 


procedure TDumbUniMesh.Render;
var
  i: integer;
  myib: GLuint;
  mymat: TMatrix4f;
  using_shaders: boolean;
  x: TRenderComponentEnum;
begin
  if Length(indices) <= 0 then Exit;
  if maxIndex < High(indices) then maxIndex:= High(indices);
  using_shaders:= Mother^.GAPI.currentProgram.prog > 0;

  case  Mother^.GAPI.Mode of
   {$ifndef glesonly}
    gapi_GL21: begin
    end;
   {$endif glesonly}
    gapi_GLES2: begin
      if not using_shaders then Die(RuEn(
        'Класс %0 не может рисовать, используя GLES2, когда в API матки не указана спецификация текущей программы.',
        'Class %0 cannot render using GLES2 if no current program is specified in mother API.'),
        [AnsiString(Self.ClassName)]);
    end;
  else
    DieUnsupportedGLMode;
  end;

  if using_shaders then begin
    with Mother^.GAPI.currentProgram do begin
      for x in [renc_Matrix, renc_Vertex]
        do if location[x] < 0
          then Die(RuEn(
            'Класс %0 не может рисовать, так как в спецификация текущей программы в API матки не хватает компоненты %1.',
            'Class %0 cannot render because the program specified in the mother API doesn''t have component %1.'),
            [AnsiString(Self.ClassName), GetEnumName(typeinfo(TRenderComponentEnum), ord(x))]);

      for x in TRenderComponentSet do begin
        if x =  renc_Matrix then continue; // it then takes the matrix from the TGAPI singleton
        if (location[x] >= 0) and not (x in components)
          then Die(RuEn(
            'Данный экземпляр %0 не может рисовать, так как текущая программа требует компоненты %1 которой у него нету.',
            'This %0 instance cannot render because the current program requires the %1 component which it does not have.'),
            [AnsiString(Self.ClassName), GetEnumName(typeinfo(TRenderComponentEnum), ord(x))]);
      end;

      CheckGLError;

      glBindBuffer ( GL_ARRAY_BUFFER, 0 );
      glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, 0 );
      CheckGLError;

      glEnableVertexAttribArray( location[renc_Vertex] );
      CheckGLError;

      glVertexAttribPointer( location[renc_Vertex], 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]), @vertices[0]);
      CheckGLError;

      if (renc_Texcoord in components) and (location[renc_Texcoord] >= 0) then begin
        glEnableVertexAttribArray( location[renc_Texcoord] );
        CheckGLError;

        glVertexAttribPointer( location[renc_Texcoord], 2, GL_FLOAT, GL_FALSE, sizeof(texcoords[0]), @texcoords[0]);
        CheckGLError;
      end;

      if (renc_Color in components) and (location[renc_Color] >= 0) then begin
        glEnableVertexAttribArray( location[renc_Color] );
        CheckGLError;

        glVertexAttribPointer( location[renc_Color], 4, GL_FLOAT, GL_FALSE, sizeof(colors[0]), @colors[0]);
        CheckGLError;
      end;

      if (renc_Normal in components) and (location[renc_Normal] >= 0) then begin
        glEnableVertexAttribArray( location[renc_Normal] );
        CheckGLError;

        glVertexAttribPointer( location[renc_Normal], 3, GL_FLOAT, GL_FALSE, sizeof(normals[0]), @normals[0]);
        CheckGLError;
      end;

      if (renc_Matrix in components) then begin
        mymat:= matrix * TGAPI.matrix;
        glUniformMatrix4fv( location[renc_Matrix], 1, GL_FALSE, @mymat);
      end
      else
        glUniformMatrix4fv( location[renc_Matrix], 1, GL_FALSE, @TGAPI.matrix);

      CheckGLError;

      // http://openglbook.com/chapter-3-index-buffer-objects-and-primitive-types.html


      glDrawElements(GL_TRIANGLES, maxIndex + 1, GL_UNSIGNED_SHORT, @indices[0]);
      CheckGLError;

      glDisableVertexAttribArray(location[renc_Vertex]);

      if (renc_Texcoord in components) and (location[renc_Texcoord] >= 0)
        then  glDisableVertexAttribArray(location[renc_Texcoord]);

      if (renc_Color in components) and (location[renc_Color] >= 0)
        then glDisableVertexAttribArray(location[renc_Color]);

      if (renc_Normal in components) and (location[renc_Normal] >= 0)
        then glDisableVertexAttribArray(location[renc_Normal]);
    end
  end
  {$ifndef glesonly}
  else begin
      // FFP compatible
    {
    glBegin(GL_TRIANGLES);
    for i:=0 to maxIndex do begin
      glColor4fv(@colors[indices[i]]);
      glNormal3fv(@normals[indices[i]]);
      glTexCoord3fv(@texcoords[indices[i]]);
      glVertex4fv(@vertices[indices[i]]);
    end;
    glEnd;
    }
   // https://www.opengl.org/wiki/Client-Side_Vertex_Arrays

  //glGetError(); //***TODO this is a hack for an error state provoked somewhere else. Note to self: find and eliminate
    CheckGLError;

    glEnableClientState(GL_VERTEX_ARRAY);
    CheckGLError;
    glVertexPointer(3, GL_FLOAT, 0, @vertices[0]);
    CheckGLError;

    if (renc_Color in components) then begin
      glEnableClientState(GL_COLOR_ARRAY);
      CheckGLError;
      glColorPointer(4, GL_FLOAT, 0, @colors[0]);
    end
    else
      glDisableClientState(GL_COLOR_ARRAY);
    CheckGLError;

    if (renc_Texcoord in components) then begin
      glClientActiveTexture(GL_TEXTURE0);
      CheckGLError;
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
      CheckGLError;
      glTexCoordPointer(2, GL_FLOAT, 0, @texcoords[0]);
    end
    else
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    CheckGLError;

    if (renc_Normal in components) then begin
      glEnableClientState(GL_NORMAL_ARRAY);
      CheckGLError;
      glNormalPointer(GL_FLOAT, 0, @normals[0]);
    end
    else
      glDisableClientState(GL_NORMAL_ARRAY);
    CheckGLError;


    if (renc_Matrix in components) then begin
      glMatrixMode(GL_MODELVIEW);
      glLoadMatrixf(@matrix);
      CheckGLError;
    end;


    glDrawElements(GL_TRIANGLES, maxIndex + 1, GL_UNSIGNED_SHORT, @indices[0]);
    CheckGLError;
  end;
  {$endif}
end; 

destructor TDumbUniMesh.Destroy;
begin
  SetLength(colors, 0);
//  SetLength(normals, 0);
  SetLength(texcoords, 0);
  SetLength(vertices, 0);
  SetLength(indices, 0);
  inherited;
end; 



constructor TDumbUniMesh.Create(_components: TRenderComponentSet);
begin
  components:= _components;
  if not (renc_Vertex in components) then Die(RuEn(
    'Класс %0 не приспособлен к отсутствию компоненты renc_Vertex',
    'Class %0 cannot work without the renc_Vertex component'),
    [AnsiString(Self.ClassName)]);

  if renc_Color in components then begin
    currentColor[0]:= 1;
    currentColor[1]:= 1;
    currentColor[2]:= 1;
    currentColor[3]:= 1;
  end;
  if renc_Normal in components then begin
    currentNormal[0]:= 0;
    currentNormal[1]:= 0;
    currentNormal[2]:= 1;
  end;
  maxIndex:= -1;
  maxVertex:= -1;
  if renc_Matrix in components then begin
    FillChar(matrix, sizeof(matrix), 0);
    matrix[0,0]:= 1;
    matrix[1,1]:= 1;
    matrix[2,2]:= 1;
    matrix[3,3]:= 1;
  end;
end;

procedure TDumbUniMesh.Color3f(_r, _g, _b: float);
begin
  if not (renc_Color in components) then Exit;
  currentColor[0]:= _r;
  currentColor[1]:= _g;
  currentColor[2]:= _b;
  currentColor[3]:= 1.0;
end;

procedure TDumbUniMesh.Color4f(_r, _g, _b, _a: float);
begin
  if not (renc_Color in components) then Exit;
  currentColor[0]:= _r;
  currentColor[1]:= _g;
  currentColor[2]:= _b;
  currentColor[3]:= _a;
end;

procedure TDumbUniMesh.Color(c: TVector3f);
begin
  PVector3f(@currentColor)^:= c;
  currentColor[3]:= 1.0;
end;

procedure TDumbUniMesh.Color(c: TVector4f);
begin
  currentColor:= c;
end;

procedure TDumbUniMesh.LineTexCoords(txleft, txtop, txright, txbottom: float);
begin
  if not (renc_Texcoord in components) then Exit;
  lineTC[0][0]:= txleft;
  lineTC[0][1]:= txtop;
  lineTC[1][0]:= txleft;
  lineTC[1][1]:= txbottom;
  lineTC[2][0]:= txright;
  lineTC[2][1]:= txtop;
  lineTC[3][0]:= txright;
  lineTC[3][1]:= txbottom;
end;


procedure TDumbUniMesh.EnlargeBuffersIfNecessary;
var nv: integer;
begin
  if Length(indices) <= maxIndex + 1
    then
    Setlength(indices, max(16, max(maxIndex, Length(indices) * 2)));

  while Length(vertices) < maxVertex + 1 do begin
    nv:= max(16, max ( maxVertex, Length(vertices) * 2 ));
    if renc_Texcoord in components then SetLength(texcoords, nv);
    if renc_Color in components then SetLength(colors, nv);
    SetLength(vertices, nv);
    if renc_Normal in components then Setlength(normals, nv);
  end;
end;

//reminder: here "top" denotes smaller Y values as my GUI uses y axis downwards
procedure TDumbUniMesh.AddQuad2d(left, top, right, bottom: GLfloat;
                                    txleft, txtop, txright, txbottom: GLfloat);
var
  firstindex, firstvertex, newlength, i: GLint;
begin
  firstindex:= maxIndex + 1; //because are initialized to 0, not -1
  firstvertex:= maxVertex + 1;

  inc (maxIndex, 6);
  inc (maxVertex, 4);

  EnlargeBuffersIfNecessary;

  indices[firstindex + 0]:= firstvertex + 0;
  indices[firstindex + 1]:= firstvertex + 1;
  indices[firstindex + 2]:= firstvertex + 2;
  indices[firstindex + 3]:= firstvertex + 2;
  indices[firstindex + 4]:= firstvertex + 3;
  indices[firstindex + 5]:= firstvertex + 0;

  while Length(vertices) < maxVertex + 6 do begin
    newlength:= max(16, Length(vertices) * 2 );
    if renc_Texcoord in components then SetLength(texcoords, newlength);
    if renc_Color in components then SetLength(colors, newlength);
    SetLength(vertices, newlength);
    if renc_Normal in components then Setlength(normals, newlength);
  end;

  if renc_Normal in components then
    for i:= firstvertex to firstvertex + 3
      do normals[i]:= currentNormal;

  if renc_Color in components then
    for i:= firstvertex to firstvertex + 3
      do colors[i]:= currentColor;

  if renc_Texcoord in components then begin
    texcoords[firstvertex + 0][0]:= txleft;
    texcoords[firstvertex + 0][1]:= txtop;
//    texcoords[firstvertex + 0][2]:= 0;

    texcoords[firstvertex + 1][0]:= txright;
    texcoords[firstvertex + 1][1]:= txtop;
//    texcoords[firstvertex + 1][2]:= 0;

    texcoords[firstvertex + 2][0]:= txright;
    texcoords[firstvertex + 2][1]:= txbottom;
//    texcoords[firstvertex + 2][2]:= 0;

    texcoords[firstvertex + 3][0]:= txleft;
    texcoords[firstvertex + 3][1]:= txbottom;
//    texcoords[firstvertex + 3][2]:= 0;
  end;


  //dat was awful idea, if funny for i:= firstvertex to firstvertex + 3 do vertices[i][3]:= 1.0;

  vertices[firstvertex + 0][0]:= left;
  vertices[firstvertex + 0][1]:= top;
  vertices[firstvertex + 0][2]:= 0;

  vertices[firstvertex + 1][0]:= right;
  vertices[firstvertex + 1][1]:= top;
  vertices[firstvertex + 1][2]:= 0;

  vertices[firstvertex + 2][0]:= right;
  vertices[firstvertex + 2][1]:= bottom;
  vertices[firstvertex + 2][2]:= 0;

  vertices[firstvertex + 3][0]:= left;
  vertices[firstvertex + 3][1]:= bottom;
  vertices[firstvertex + 3][2]:= 0;
end;