Skocz do zawartości

[OpenGL + Delphi] Jak zrobić screena?


Demon64

Polecane posty

Otóż chciałbym wzbogacić mój program do 3d o funkcję renderowania sceny do pliku BMP.

Próbowałem już zrobić to podmieniając obiekt, na którym renderowana jest grafika z Formy2 na zmienną bmp: TBitmap;

Ale nie przynosiło to, żadnych efektów, być może coś źle robiłem...

Kolejny sposób jaki próbowałem zastosować to zwykły screen z Formy2 przez kopię Canvasu z Formy2, ale wadą tego

rozwiązania było to, że gdy coś zasłaniało Formę2 to było wrysowane w screena <_<

A może jest jakaś funkcja biblioteczna robiąca screena do pliku?

Oczywiście chcę zrobić tak by przy renderowaniu do pliku można było ustawić wymiary obrazka (Width,Height owej bitmapy).

 

Jeśli to coś pomoże to zamieszczam fragmenty kodu:

 

Zmienne określające obiekt, na którym renderowany jest obraz:

var
   DC: HDC;
   RC: HGLRC;
qnŻ*Ś\"yjYr7^bpp&6VGW&RDf&Ó\"ćDVćv6G&Ev6G&&VvD3ŁvWDD26G&ćFĆR6WGWVf&BD2$3Łvv7&VFT6FWBD2ŚbćBvvśT7W'&VBD2$2FVW76vT&f&ÓćFĆRb33ć6ŚĆŚ6ŚVt6ćRvK6b333b33b33ćf&6Śb33%ŚVćC&6VGW&RDf&Ó\"6WGWVf&BD3D2Ś67@fCETd$DDU45$D\"6ŚS6ŚVbETd$DDU45$D\"&Ś\"7G'VGW'fW'6vW'6ŚGtfĆw3dE5U%ETt\"VĆv[6RgVćś6ŚVtdEE$uDtDr\"'6vćR&Wg&VFććV&ćPdEDT$T%TddU#VF7NćVćRG6ŚćVv'Vf&vćVGSdEEU$t$GśĆ'R$t$46Ć$&G3#CśĆ\"#B&Fw5&VD&G35&VE6gCćR[vćP4w&VV&G34w&VV6gC4&VT&G34&VU6gC4&G346gC467V&G3467V&VD&G3467Vw&VV&G3467V&VT&G3467V&G34FWF&G33#vVĆśnb'Vf&57FVć6&G3ćR[vćP4W'VffW'3ĆW%GSdES\0{?7vć{6ś%&W6W'fVCGtĆW$6łGuf6&ĆT6łćR[vćPGtFvT6łf\"Vf&DćFWŚFVvW#Ś&VvVf&DćFWŁ66UVf&BD2fB6WEVf&BD2Vf&DćFWfBŚVćC

Link do komentarza
Udostępnij na innych stronach

no to załóżmy, że masz wymiary 800x600

to na początek, rezerwujesz pamięć wielkości 800x600x3 w wskaźniku do Byte

metodą glReadPixels(0,0,799,599,GL_RGB,GL_UNSIGNED_BYTE,nasz wskaźnik)

właśnie pobrałeś obraz do pamięci

i zapisujesz te dane (musisz wiedzieć jak wygląda format bmp) do pliku bmp pamiętając aby zamienić bodajże bajty odpowiadające za R i B.

Zwalniasz pamięć na wskaźniku

Edit: Zamiana bajtów to pętla od 0 do Width*Height-1 i zamieniasz wskaznik^[i*3] z wskaznik^[i*3+2] miejscami. Mogłem się walnąć z "^" dawno wskaźników w Delphi nie używałem

Baza tysięcy lotnisk: http://airportsbase.com

Link do komentarza
Udostępnij na innych stronach

no to załóżmy, że masz wymiary 800x600

to na początek, rezerwujesz pamięć wielkości 800x600x3 w wskaźniku do Byte

metodą glReadPixels(0,0,799,599,GL_RGB,GL_UNSIGNED_BYTE,nasz wskaźnik)

właśnie pobrałeś obraz do pamięci

i zapisujesz te dane (musisz wiedzieć jak wygląda format bmp) do pliku bmp pamiętając aby zamienić bodajże bajty odpowiadające za R i B.

Zwalniasz pamięć na wskaźniku

Edit: Zamiana bajtów to pętla od 0 do Width*Height-1 i zamieniasz wskaznik^[i*3] z wskaznik^[i*3+2] miejscami. Mogłem się walnąć z "^" dawno wskaźników w Delphi nie używałem

 

A więc zrobiłem to tak (niestety nie działa):

var 
   GL_obraz: array of array of array of ^Byte;
   i,j: integer;
begin
bmp:=TBitmap.Create;
bmp.Width:=szer.Value;
bmp.Height:=wys.Value;
with bmp.Canvas do begin
    Pen.Color:=0; Brush.Color:=0;
    Rectangle(0,0,bmp.Width,bmp.Height);
    end;
SetLength(GL_obraz,bmp.Width,bmp.Height,3);
glReadPixels(0,0,bmp.Width-1,bmp.Height-1,GL_RGB,GL_UNSIGNED_BYTE,GL_obraz);
for i:=0 to bmp.Width-1 do for j:=0 to bmp.Height-1 do begin
   bmp.Canvas.Pixels[i,j]:=RGB(Byte(@GL_obraz[i,j,0]),Byte(@GL_obraz[i,j,1]),Byte(@GL_obraz[i,j,2]));
   end;
bmp.SaveToFile(nazwa_pliku);
bmp.Free;

 

Problem z pamięcią i tablicami... Program wywala krytyka a czasem się wyłącza <_<

Może spróbuję w ten drugi sposób. Chyba, że macie jakiś pomysł jak to naprawić :huh:

Link do komentarza
Udostępnij na innych stronach

czemu masz array od ^Byte? To raczej array of byte. Ja mówiłem o wskaźniku, ale raczej myslałem, aby na nim GetMem zrobić. więc powinno być bez daszków i bez małp

 

Tak też próbowałem. Kombinowałem różnie i z ^ i @ i bez no i nic, ciągle wywala błędy...

Już nawet robiłem, by czytało do tablicy ^Byte; no i przypisywało dane z takiej tablicy do tablicy Byte; i też nic :(

Force mógłbyś napisać taki kod po swojemu?

Link do komentarza
Udostępnij na innych stronach

  • 2 weeks later...

w Delphi nie mam, w C++ mam z książką gotowy plik co pokazuje ładowanie i zapis bmp. link

 

Nie chodzi tu o ładowanie i zapisywanie pliku BMP, bo to jest proste, ale o skopiowanie obrazu z OpenGL'a, np: do zmiennej TBitmap.

Albo do jakiejś innej tak, abym tylko uzyskał ten obraz, bo już z zapisem to ja sobie poradzę.

Link do komentarza
Udostępnij na innych stronach

Co mi się rzuca w oczy... Po pierwsze takich danych jak bitmapy raczej nie trzyma się w tablicach dynamicznych, bo służą one do czegoś zupełnie innego.

 

Źródła zamieszczone niżej powinny się przydać. Jest to kawalątek kodu wycięty z mojego programu graficznego DaThoX Bitmaps :rolleyes: :

(Co prawda kod ten zapisuje RGB z kanałem alpha do PNG, bo służyło to do zapisywania grafik i fontów do gier 2D, ale łatwo możesz przerobić to na kod zapisujący dane w formacie RGB do bmp.)

 

niezbędne unity to unity z imaginglib

 

uses
 ImagingTypes, Imaging ...
xgzŚ)Ń(AI       yQI        (QI        (Ń((IŃ(Ń(  ąŃ(ąĄŃ((Ą
ą1]((xg{9zyui'
var
 j, k: longint;
 Buf, SecBuf: pointer;
 Pic: TImageData;
 img_width, img_height: integer;
 Pixel, SecPixel: PRGBA;
 TempByte: byte;
J\"'^bppvWDV'VbuvGFuVvBBvWDV6V4'VbuvGFuVvBBv&VEV26ĆVBVvBuVvBuvGFuVvBt$t$tT4tTE%DR'VbVŁ'Vc$u\"F$t 6V5VŁ6V4'Vcć26V5VuvGFuVvBf\"ŁFuVvBF&VvFV26V5VuvGFf\"ŁFuvGFF&VvFV'FRŁV&VCV&VBŁV&VSV&VRŁFV' FS6V5VŁVć2Vć26V5VVćCFV26V
5VuvGFVćCFćRFĆ6fTvUF7G&V2vGFŁuvGF2VvBŁuVvC2f&BŁd#s#26ŚRŁuvGFuVvBC2&G2Ł6V4'Vc2ĆWGFRŁć\0Ś7VŚV'&F7G'VVć6fTvUF7G&Vb33ćrb337G&V2g&VTV'Vbg&VTV6V4'Vb

 

i poproszę jakiś credits jak się przyda ;)

soon Delphi will be only for veterans and finally we all will die at the end…

delphi.dathox.com - nowinki z świata Delphi/Pascala

only programmers and drug dealers call their customers "users"

 

Oto cisza przed burzą, Chwile się dłużą.Z gór schodzi dużo chmur ku podnóżom.Ptaki milaczą, drogi suche jak wiór się kurzą, Ptaki milczą a drogi się kurzą.

Link do komentarza
Udostępnij na innych stronach

Var
 AStream: TFileStream;

 

??

 

 

Próbowałem coś takiego, ale to powoduje błąd ;P

 

Już przerobiłem to całkowicie, wyeliminowałem te ImagingLib, itp.

Udało się zrobić kopię obrazu do zmiennej TBitmap, ale ten sposób nie spełnia moich oczekiwań, bo

nadal są takie błędy podobne jak we wcześniejszych sposobach... Nie ma skalowania, bo rozmiar, który

ustawiam, miał być rozmiarem docelowym, a render nadal ma rozmiar taki jaki jest w okienku podglądowym.

No jedyny plus to to, że nawet zasłonięta część okna jest normalnie renderowana, chyba że wyjdzie się z okienkiem

poza pulpit, wtedy też ucina się obraz... :/

 

Da się utworzyć coś w rodzaju back bufferu, który miałby inny rozmiar niż scena wyświetlana na formie

i przełączenie na czas renderingu na renderowanie do tego back bufferu i robienie renderów z niego?

Jak tak to jak zainicjować coś takiego? Jakiej zmiennej użyć jako miejsce do renderowania grafiki?

Link do komentarza
Udostępnij na innych stronach

  • 5 months later...

Witam, żeby nie zakładać nowego tematu przedstawię swój problem w tym wątku.

Chodzi o przechwytywanie bitmapy z kawałka ekranu i zapis do pamięci, więc mam taki kod:

 

 
               int w = 16, h = 21;
               int bw = 16, bh = 21;
               int bw4=(bw+3)&0xFFFFFFFC;

               BITMAPINFO bi; 
               bi.bmiHeader.biBitCount=24; 
               bi.bmiHeader.biClrImportant=0;
               bi.bmiHeader.biClrUsed=0;
               bi.bmiHeader.biCompression=BI_RGB; 
               bi.bmiHeader.biHeight=bh;
               bi.bmiHeader.biPlanes=1; 
               bi.bmiHeader.biSize=40; 
               bi.bmiHeader.biSizeImage=bw4*bh*3;
               //bi.bmiHeader.biSizeImage=bw*bh*3;
               bi.bmiHeader.biWidth=bw; 
               bi.bmiHeader.biXPelsPerMeter=3780; 
               bi.bmiHeader.biYPelsPerMeter=3780;
               bi.bmiColors[0].rgbBlue=0; 
               bi.bmiColors[0].rgbGreen=0; 
               bi.bmiColors[0].rgbRed=0; 
               bi.bmiColors[0].rgbReserved=0;


               HDC sdc = GetDC(0); 
               BYTE *bits; 
               HBITMAP hbm = CreateDIBSection(sdc,&bi,DIB_RGB_COLORS,(void**)&bits,NULL,0);
               HDC hdc = CreateCompatibleDC(sdc); 
               HGDIOBJ hold = SelectObject(hdc,hbm);
               //StretchBlt(hdc,0,0,bw,bh,sdc,0,0,w,h,SRCCOPY);
               //StretchBlt(hdc,0,0,bw,bh,sdc,BITMAP_WIDTH,BITMAP_HEIGHT,w,h,SRCCOPY);
               BitBlt(hdc,0,0,16,21,sdc,300,500,SRCCOPY);
               SelectObject(hdc,hold); 
               DeleteDC(hdc); 
               ReleaseDC(0,sdc);

 

mój problem polega na tym że nie wiem jak się dostać do danych "pobranej" bitmapy, żeby móc je porównywać z danymi innej bitmapy wczytanej wcześniej z pliku, zdaje się że są one zapisane w zmiennej bits typu BYTE.

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...