Jump to content

[Delphi] TBitMap i adres danych glTexImage2D


sybic

Recommended Posts

Proszę niech mnie ktoś oświeci. Jaki jest adres do danych w TbitMap?

Zawsze mi się wydawało, że bmp.scanline[0] jednak jeśli ten adres przekazuje do procedury gdzie następuje ładowanie textury glTexImage2D to coś nie chcę działać

 

 

 
Var 
Bmp:=Tbitmap;
P:pointer;
begin
Bmp:=Tbitmap.Create;
Bmp.width:=2048;
Bmp.height:=1024;

// tu procedury na bitmapie

p:=bmp.scanline[0]; // teraz adres 

glTexImage2D(GL_TEXTURE_2D, 0, 3, 2048, 1024, 0, GL_BGR, GL_UNSIGNED_BYTE, p)   // brak efektów 

 

Jeśli zapisuje tą bitmapę do pliku bmp.SaveToFile('xx.bmp'); a potem ją odczytuje przekazując adres od BITMAPFILEHEADER. BfOffBits to działa, ale takie rozwiązanie jest nie do przyjęcia...

Link to comment
Share on other sites

neee to nie tak :) Scanline nie wskazuje na poczatek danych, ogolnie sa tam zmiany w alignowaniu danych dla kolejnych lini. Jak doturlam sie do chaty to dam ci klaske ktora wczyta bitmape i poda adres na poczatek danych. Chyba ze wczesniej wygooglasz.

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link to comment
Share on other sites

Mowisz, masz. Ta wersja wspiera tylko bitmapy 24b inne jakos mnie nie kręcą ;)

 

unit TLib;

interface
uses Windows, Classes, SysUtils, Graphics;

type
  TBmpHeader = Packed Record
     bfType1         : Byte;
     bfType2         : Byte;
     bfSize          : LongInt;
     bfReserved1     : Word;
     bfReserved2     : Word;
     bfOffBits       : LongInt;
     biSize          : LongInt;
     biWidth         : LongInt;
     biHeight        : LongInt;
     biPlanes        : Word;
     biBitCount      : Word;
     biCompression   : LongInt;
     biSizeImage     : LongInt;
     biXPelsPerMeter : LongInt;
     biYPelsPerMeter : LongInt;
     biClrUsed       : LongInt;
     biClrImportant  : LongInt;
  End;

  PFastColor = ^TFastColor;
  TFastColor = packed record
     blue, green, red: byte;
  end;

  TFastBitmap = class
     public
        Header:    TBmpHeader;
        Data:      array of TFastColor;

        constructor    Create(const w, h: integer);overload;
        constructor    Create(const stream: TStream);overload;
        destructor     Destroy;override;
        procedure      ToBitmap(const bitmap: Tbitmap);
        procedure      SaveToStream(stream: TStream);
     private
        procedure      LoadFromStream(const stream: TStream);
        procedure      FlipData;
  end;

implementation

{ TFastBitmap }

constructor TFastBitmap.Create(const w, h: integer);
begin
  header.biWidth := w;
  header.biHeight := h;
  SetLength(Data, w*h);
end;

constructor TFastBitmap.Create(const stream: TStream);
begin
  LoadFromStream(stream);
end;

destructor TFastBitmap.Destroy;
begin
  Data := nil;
 inherited;
end;

procedure TFastBitmap.FlipData;
var
  wsk1, wsk2: PFastColor;
  i, i2: integer;
  tmp: array of byte;
begin
  //rotacja
  wsk1 := @data[0];
  wsk2 := @data[Header.biwidth * (Header.biheight-1) ];
  i := Header.biwidth;
  i2 := i * 3;
  SetLength(tmp, i2);
  while Integer(wsk1) < Integer(wsk2) do begin
     Move(wsk1^, tmp[0], i2);
     Move(wsk2^, wsk1^, i2);
     Move(tmp[0], wsk2^,i2);
     inc(wsk1,i);
     Dec(wsk2,i);
  end;
  tmp := nil;
end;

procedure TFastBitmap.LoadFromStream(const stream: TStream);
begin
  Stream.Read(Header, sizeOf(Header));
  SetLength(Data, header.biWidth * Header.biHeight);
  Stream.Read(Data[0], Length(data) * SizeOf(TFastColor));
  FlipData;
end;

procedure TFastBitmap.SaveToStream(stream: TStream);
begin
  with Header do begin
     bfType1 := $42;
     bfType2 := $4d;
     bfSize := SizeOf(Header) + 3 * biWidth * biHeight;
     bfReserved1 := 0;
     bfReserved2 := 0;
     bfOffBits := 54;
     biSize := 40;
     biPlanes := 1;
     biBitCount := 24;
     biCompression := 0;
     biSizeImage := 3 * biWidth * biHeight;
     biXPelsPerMeter := 1;
     biYPelsPerMeter := 1;
     biClrUsed       := 0;
     biClrImportant  := 0;
  end;
  stream.Write(Header, sizeOf(Header));
  FlipData;
  try
     Stream.Write(Data[0], Length(data) * SizeOf(TFastColor));
  finally
     FlipData;
  end;
end;

procedure TFastBitmap.ToBitmap(const bitmap: Tbitmap);
var
  y, x: integer;
  wsk1, wsk2: PFastColor;
begin
  bitmap.Width := Header.biWidth;
  bitmap.Height := Header.biHeight;
  bitmap.PixelFormat:=pf24bit;
  wsk2 := @Data[Header.biWidth * (Header.biHeight - 1)];
  x := Header.biWidth * SizeOf(TFastColor);
  for y := bitmap.Height -1 downto 0 do begin
     wsk1 := Bitmap.ScanLine[y];
     Move(wsk2^, wsk1^, x);
     Dec(Wsk2, bitmap.Width);
  end;
end;

 

 

Aa i jeszcze jedna ważna rzecz, cytat z wiki abys sie nie zdziwil momentami:

Należy zwrócić uwagę, że (poniekąd ze względów historycznych) w wierszu danych pliku BMP jest zawsze zapisana wielokrotność 4 bajtów. Jeśli wiersz danych ma długość (w bajtach) inną, niż podzielna przez 4, to dopisuje się bajty o wartości 0, tak aby w danym wierszu ilość bajtów była wielokrotnością 4.

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...