Here's a working BMP saving variant:

Code:
Procedure ScreenShoot(filen: string);

// 54 bytes bmp header
TBMPheader = packed record
magic               : word;     // BM (word: 19778)
headersize          : longword; // 54
reserved            : longword; // 0
dataofs             : longword; // 54

Size                : longword;
Width               : longword;
Height              : longword;
Planes              : word;     // 1
BitCount            : word;     // 24
Compression         : longword; // 0
SizeImage           : longword; // w * h * 3
XPelsPerMeter       : longword; // 36100
YPelsPerMeter       : longword; // 36100
ClrUsed             : longword; // 0
ClrImportant        : longword; // 0
end;

var
  vport: array[0..3] of integer;
  buffer: pchar;
  bufflen: integer;
  f: Tmemorystream;
  TGAHeader: TTGAHeader;
  BMPheader: TBMPheader;
begin
  glGetIntegerv(GL_VIEWPORT, @vPort);

  bufflen:= (vport[2] * vport[3]) * 3;  // rgb
  getmem(buffer, bufflen);

  glPixelStorei(GL_PACK_ALIGNMENT, 1);

  glReadPixels(0, 0, vport[2], vport[3], GL_BGR_EXT, GL_UNSIGNED_BYTE, buffer);

  fillchar(BMPheader, sizeof(BMPheader), 0);

  BMPheader.magic               := 19778;
  BMPheader.headersize          := 54;
  BMPheader.reserved            := 0;
  BMPheader.dataofs             := 54;
  BMPheader.Size                := 40;
  BMPheader.Width               := vport[2];
  BMPheader.Height              := vport[3];
  BMPheader.Planes              := 1;
  BMPheader.BitCount            := 24;
  BMPheader.SizeImage           := bufflen;
  BMPheader.XPelsPerMeter       := 36100;
  BMPheader.YPelsPerMeter       := 36100;
  BMPheader.ClrUsed             := 0;
  BMPheader.ClrImportant        := 0;

  f:= Tmemorystream.Create;
  f.Write(BMPheader, sizeof(BMPheader));
  f.Write(buffer^, bufflen);
  f.SaveToFile(filen);
  f.free;

  freemem(buffer);

end;