I made a small test application with my GLEngine. Using Vertex arrays, display lists and raw rendering using glBegin-glEnd. Take this code for tutorial or such as it's heavily commented. Vertex arrays method made my windowed 1024x768 mode render over 20000 triangles by over 114fps whereas other 2 methods remained at ~94fps. Surprisingly displaylist did not beat pre-defined raw rendering.
Screenshot: http://i10.tinypic.com/6euqii1.jpg

GLEngine is available at http://www.freewebs.com/loknar
but it hasn't been updated on the web for maybe long time, something i wish to do hopefully soon. Maybe it can run this demo however.
edit: I did update the website with new version

[pascal]unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, GLEngine, dglOpenGL, TLibUnit, TLib3D;

type
TForm1 = class(TForm)
GLEngine1: TGLEngine;
GLTimer1: TGLTimer;
procedure FormCreate(Sender: TObject);
procedure GLTimer1Timer(Sender: TObject; Lag: Single);
procedure GLEngine1Initialize(Sender: TObject);
procedure GLEngine1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
list,vObj,cObj: cardinal;
vArray,cArray: array[0..4319] of P3f; // 38*60*2 vertices
vCount,mode: integer;
public
procedure vaSphereVertex(ax,ay: single);
procedure SphereVertex(ax,ay: single);
end;

var Form1: TForm1;

implementation

{$R *.dfm}

function BUFFER_OFFSET(i: cardinal): Pointer;
var ptr: pointer absolute i;
begin
result:=ptr;
end;

procedure TForm1.SphereVertex(ax,ay: single);
var z: single;
begin
// Raw rendering for vertex
z:=abs(cos(ay));
glColor3f(sin(ax)*0.5+0.5, sin(ay)*0.5+0.5, cos(ax)*0.5+0.5);
glVertex3f(cos(ax)*z,sin(ay),sin(ax)*z);
end;

procedure TForm1.vaSphereVertex(ax,ay: single);
var z: single;
begin
// Adding vertex to the vertex array
z:=abs(cos(ay));
vArray[vCount].x:=cos(ax)*z;
vArray[vCount].y:=sin(ay);
vArray[vCount].z:=sin(ax)*z;
cArray[vCount].x:=sin(ax)*0.5+0.5;
cArray[vCount].y:=sin(ay)*0.5+0.5;
cArray[vCount].z:=cos(ax)*0.5+0.5;
inc(vCount);
end;

procedure TForm1.GLTimer1Timer(Sender: TObject; Lag: Single);
var i,j,n: integer; s: string;
begin
GLEngine1.ClearScreen; // Clear screen

// Set view
glLoadIdentity;
glTranslatef(0,0,-4);
glRotatef(gettickcount/30,1,0,0);
glRotatef(gettickcount/17,0,1,0);

// Render same sphere in 20 different positions
for n:=1 to 20 do begin
glTranslatef(sin(n*0.37)*0.16,cos(n*0.37)*0.16,0);

// Rotate colors
for i:=0 to vCount-1 do
cArray[i].x:=0.5+0.1*sin((i div 240)*integer(GetTickCount)/10*toRad);

if mode in [0,3] then begin
// Render vertex array OR vertex buffer object
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glDrawArrays(GL_TRIANGLE_STRIP,0,vCount); // Render

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

end else if mode=1 then begin
// Render displaylist
glCallList(list);

end else if mode=2 then begin
// Raw rendering
glBegin(GL_TRIANGLE_STRIP);
for j:=0 to vCount-1 do begin
glColor3fv(@cArray[j]); glVertex3fv(@vArray[j]);
end;
glEnd;
end;

end; // for

GLEngine1.Flip; // Flip screen

// Show current mode in caption
if mode=0 then s:='VertexArray'
else if mode=1 then s:='DisplayList'
else if mode=2 then s:='BeginEnd'
else s:='VertexBufferObject';
caption:=s+format(' - FPS: %d',[GLTimer1.FPS]); // Show fps
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
GLEngine1.Align:=alClient; // Stretch GLEngine to form
end;

procedure TForm1.GLEngine1Initialize(Sender: TObject);
var i,j: integer;
begin
// Generate displaylist
list:=glGenLists(1);
glNewList(list,GL_COMPILE);
glBegin(GL_TRIANGLE_STRIP);
for j:=-18 to 17 do
for i:=0 to 59 do begin
// Make lower and upper triangle-strip vertex for displaylist
SphereVertex(i*6*toRad,j*5*toRad);
SphereVertex(i*6*toRad,(j+1)*5*toRad);

// Make lower and upper triangle-strip vertex for vertex array
vaSphereVertex(i*6*toRad,j*5*toRad);
vaSphereVertex(i*6*toRad,(j+1)*5*toRad);
end;
glEnd;
glEndList;

// Set vertex and color arrays
glVertexPointer(3,GL_FLOAT,0,@vArray);
glColorPointer(3,GL_FLOAT,0,@cArray);

// Create Vertex Buffer Object
glGenBuffersARB(1, @vObj); // Make VBO list for vertices
// Bind and load vertex data
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vObj);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, vCount*sizeof(single)*3,
@vArray, GL_STATIC_DRAW_ARB);

glGenBuffersARB(1, @cObj); // Make VBO list for colors
// Bind and load color data
glBindBufferARB(GL_ARRAY_BUFFER_ARB, cObj);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, vCount*sizeof(single)*3,
@cArray, GL_STATIC_DRAW_ARB);
end;

procedure TForm1.GLEngine1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
mode:=(mode+1) mod 4;
if mode=0 then begin
// Reset vertex and color pointers when coming back
// to VertexArray mode (else the VBO data would be used)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glVertexPointer(3, GL_FLOAT, 0, @vArray);
glColorPointer(3, GL_FLOAT, 0, @cArray);
end else if mode=3 then begin
// Set vertex and color pointers to VBO
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vObj);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
glBindBufferARB(GL_ARRAY_BUFFER_ARB, cObj);
glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
end;
end;

end.[/pascal]

Fixed typos. Lastly added VBO.