Pisząc ten artykuł zastanawiałem się czy przypadnie wam do gustu. Mam nadzieję, że tak:). Więc… Na dzisiejszej lekcji zajmiemy się wyświetlaniem bitmap za pomocą DirectDraw(jej:).
Podstawową zmianą będzie użycie DirectDraw4, aby nasz program działał już na komputerach z DirectX6 (o ile ktoś takie jeszcze ma:). Wyświetlenie bitmapy nie jest trudne. Wystarczy zadeklarować odpowiednie zmienne. Ale zanim do tego przystąpimy nauczymy się obsługi klawiatury z WinApi. Zaczynamy od zadeklarowania odpowiedniej zmiennej:
1 2 |
var klawisz : array [1..256] of boolean; |
Tablica ta będzie nas informować które klawisze są aktualnie wciśnięte a które nie:P. Korzystając z tej techniki nie potrzebujemy już DirectInput (hehe… : ] ). To powinno zaspokoić nasze potrzeby. Następnym etapem jest uwzględnienie odpowiednich zdarzeń w WndProc( w poprzednim artykule zwało się to WindowProc). Chodzi mi o zdarzenia już wcześniej wam znane z zakładki Events w Object Inspektorze – KeyUp i KeyDown. Ich odpowiedniki będą wyglądać tak(uważaj na mWParam w poprzednim tutorialu 🙂 nazywał się on WParam) :
1 2 3 4 5 6 7 8 9 10 11 12 13 |
WM_KEYDOWN: // użytkownik nacisnął klawisz? begin klawisz[mWParam] := true; result := 0; exit; end; WM_KEYUP: // użytkownik odcisnął klawisz ;)? begin klawisz[mWParam] := false; result := 0; exit; end; |
To wszystko. Teraz w głównej pętli możemy sobie kontrolować stany klawiszy(true i false). Numer komórki tablicy odpowiada kodowi klawisza który jest zgodny z kodem ASCII(tródno żeby nie był: )Jeśli jakiś klawisz został wciśnięty to informacja o tym trafi do naszej jakże wspaniałej tablicy. Pewnie zapytasz : Czemu opisuje tutaj WinApi?. Ja odpowiem : Ponieważ szanowny pan Nakiel(główny wodzu) nie przewidział działu dla WinApi : ]. Dobra. Teraz czas na zmiany. Nasze programiki będą(są) coraz bardziej obszerne więc należało by je podzelić(skawałkować : ). Stworzymy pewne Unity, których póki co liczba wyniesie 3 :
MDirectDraw.pas – Odpowiada za różne rzeczy związane z DirectDraw(od inicjalizacji po wyświetlanie).
MWinApi.pas – Różne procedury i funkcje powiązane z WinApi(np. WindowProc).
Zmienne.pas – Jak sama nazwa wskazuje będą tam głównie zmienne.
Możesz je sobie ściągnąć(z całą resztą:) u dołu tego artykułu(no bo niby gdzie indziej : ). Czy to koniec??? Na pewno nie!!! Przed nami jeszcze daleka kręta(heh:) droga. Teraz nastał czas na zadeklarowanie nowych zmiennych powiązanych z DirectDraw.
1 2 3 4 5 6 7 8 9 |
var //DirectX kontekst : HDC; // kontekst urządzenia dds_hdc : HDC; // HDC(kontekst) buforu hdcmem : HDC; // kolejny kontekst ;) hbmp : HBITMAP; // bitmapa lpDDSEkran : IDIRECTDRAWSURFACE4;// nasza główna powierzchnia lpDD : IDirectDraw; // obiekt DirectDraw lpDD4 : IDirectDraw4; // obiekt DirectDraw 4 |
Teraz czas na funkcję inicjującą DirectDraw. Tu dużo nam przybyło. Sami zobaczcie:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
function InitDirectDraw( h_Wnd : HWND ) : HRESULT; var ddsd : TDDSURFACEDESC2; begin DirectDrawCreate(nil, lpDD, nil); //Tworzy obiekt DirectDraw który zwie się lpDD lpDD.QueryInterface(IID_IDirectDraw4,lpDD4); //Pobieramy interface DirectDraw4 lpDD4.SetCooperativeLevel(h_Wnd, DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN); lpDD4.SetDisplayMode (width, height, bits, 0, 0); //rozdzielczość ZeroMemory(@ddsd,sizeof(ddsd)); //zerujemy pamięć dla ddsd ddsd.dwSize := sizeof(ddsd); ddsd.dwFlags := DDSD_CAPS; //takie tam bajery które muszą być ;) ddsd.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE; //Odnosi się do naszej głównej powierzchni //ok:) lpDD4.CreateSurface(ddsd,lpDDSEkran, nil); hdcmem := CreateCompatibleDC(0); //"robimy" drugi kontekst hbmp:=LoadImage(hInstance, 'tlo.bmp', IMAGE_BITMAP, 800, 600, LR_LOADFROMFILE); //wczytujemy bitmapę SelectObject(hdcmem, hbmp); //kopiowanie zawartości end; |
A oto procedura wyświetlająca. Umieszczamy ją w głównej pętli.
1 2 3 4 5 6 7 8 |
procedure Render; begin lpDDSEkran.GetDC(kontekst);//Pobieramy kontekst urządzenia, bo zaraz go użyjemy BitBlt(kontekst,0,0,800,600,hdcmem,0,0,SRCCOPY); //Kopiujemy zawartość kontekstu 'hdcmem' do kontekstu 'kontekst' - czyli wyświetlmy obrazek lpDDSEkran.ReleaseDC(kontekst); //Zwalniamy główny kontekst end; |
To wszystko. Wyświetlanie bitmap w DirectDraw nie jest trudne(jak widać:).
Na następnej lekcji omówię buforowanie(żeby nie mrugało : ).
Autor: HNB