procedure LoadTextureFromStream(Stream: TStream; var Texture: GLuint);
var
FileHeader: BITMAPFILEHEADER;
InfoHeader: BITMAPINFOHEADER;
Palette: array of RGBQUAD;
BitmapLength: LongWord;
PaletteLength: LongWord;
Width, Height : Integer;
pData : Pointer;
p,j,ExpandBMP,Rmask,Gmask,Bmask : Integer;
Format : Word;
begin
Stream.Position := 0;
Stream.ReadBuffer(FileHeader, SizeOf(FileHeader)); // FileHeader
Stream.ReadBuffer(InfoHeader, SizeOf(InfoHeader)); // InfoHeader
PaletteLength := InfoHeader.biClrUsed;
case InfoHeader.biBitCount of
1,4:
begin
ExpandBMP := InfoHeader.biBitCount;
InfoHeader.biBitCount := 8;
end;
else
ExpandBMP := 0;
end;
case InfoHeader.biCompression of
0: // BI_RGB
begin
case InfoHeader.biBitCount of
15,16: begin Rmask := $7c00; GMask := $03e0; BMask := $001f; end;
// assuming big endian
24: begin Rmask := $ff; GMask := $ff00; Bmask := $ff0000; end;
32: begin Rmask := $ff0000; Gmask := $ff00; Bmask := $ff; end;
end;
end;
1, // BI_RLE8
2: // BI_RLE4
raise EInvalidGraphic.create('Compressed Bitmaps not handled');
3: // BI_BitFields
begin
case InfoHeader.biBitCount of
15,16,32: begin
Stream.ReadBuffer(Rmask,sizeof(Rmask));
Stream.ReadBuffer(Gmask,sizeof(Gmask));
Stream.ReadBuffer(Bmask,sizeof(Bmask));
end;
end;
end;
end;
if (InfoHeader.biBitCount=24) then
Format := GL_RGB
else
Format := GL_RGBA;
SetLength(Palette, PaletteLength);
Stream.ReadBuffer(Palette, PaletteLength); // Palette
Width := InfoHeader.biWidth;
Height := InfoHeader.biHeight;
BitmapLength := InfoHeader.biSizeImage;
if BitmapLength = 0 then
BitmapLength := Width * Height * InfoHeader.biBitCount Div 8;
GetMem(pData, BitmapLength);
try
Stream.ReadBuffer(pData^, BitmapLength); // Bitmap Data
// Bitmaps are stored BGR and not RGB, so swap the R and B bytes.
if (Rmask<>$ff0000) then
SwapRGB(pData, Width*Height);
if (InfoHeader.biBitCount=32) then
begin
SwapRGBA(pData,Width*Height);
end;
Texture :=CreateTexture(Width, Height, format, pData);
finally
FreeMem(pData);
end;
end;