W tym artykule zajmiemy się buforowaniem. Buforujemy po to żeby nam ekran nie mrugał. Nie będę się wdawać w szczegóły.
Ważne, że działa : P i tyle; ). Więc tradycyjnie zaczniemy od zdefiniowania nowych zmiennych.
1 2 3 4 5 |
var lpDDSBufor : IDIRECTDRAWSURFACE4;//bufor dds_hdc : HDC;//HDC buforu x, y : integer//położenie obrazka hgdi : HGDIOBJ; |
Teraz zajmiemy się obsługą klawiatury. Kod ten powinniśmy umieścić w głównej pętli naszego programu. Odpowiada on za sterowanie naszym obrazkiem.
1 2 3 4 5 6 |
//klawisze if (klawisz[VK_ESCAPE] = true) then done := true; if (klawisz[VK_LEFT] = true) and (x > 1) then dec(x,2); if (klawisz[VK_RIGHT] = true) and (x < 799-100) then inc(x,2); if (klawisz[VK_UP] = true) and (y > 1) then dec(y,2); if (klawisz[VK_DOWN] = true) and (y < 599-100) then inc(y,2); |
To tyle jeśli chodzi o sterowanie. Procedura inicjująca także różni się znacząco. Koło nowych rzeczy umieściłem niestosowny komentarz : ).
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 |
function InitDirectDraw( h_Wnd : HWND ) : HRESULT; var ddsd : TDDSURFACEDESC2; begin DirectDrawCreate(nil, lpDD, nil); lpDD.QueryInterface(IID_IDirectDraw4,lpDD4); lpDD4.SetCooperativeLevel(h_Wnd, DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN); lpDD4.SetDisplayMode (width, height, bits, 0, 0); ZeroMemory(@ddsd,sizeof(ddsd)); ddsd.dwSize := sizeof(ddsd); //dodajemy do flagi bufor(informujemy o wykorzystaniu buforu) ddsd.dwFlags := DDSD_CAPS or DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE or DDSCAPS_FLIP or DDSCAPS_COMPLEX; ddsd.dwBackBufferCount := 1; //powierzchnia posiada jeden bufor //ok:) lpDD4.CreateSurface(ddsd,lpDDSEkran, nil); //takie tam ;) ddsd.ddsCaps.dwCaps := DDSCAPS_BACKBUFFER; lpDDSEkran.GetAttachedSurface(ddsd.ddsCaps, lpDDSBufor); //to poniżej jest chyba zrozumiałe hdcmem := CreateCompatibleDC(0); hbmp:=LoadImage(hInstance, 'buzia.bmp', IMAGE_BITMAP, 100, 100, LR_LOADFROMFILE); hgdi:=SelectObject(hdcmem, hbmp); end; |
Ufffffff…… W następnej lekcji wszystko będzie jeszcze bardziej pokręcone, więc się nie martw : ]. Inicjalizacje DirectDraw nie jest taka trudna. Te funkcje render są trochę oszukane ale dowiesz się o tym w następnej lekcji. Teraz zajmijmy się naszą jakże oszukaną 😛 funkcją Render(czy tam procedurą; ).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
procedure Render; var r : TRect; begin hgdi:=SelectObject(hdcmem, hbmp); r.Left := 0; r.Top := 0; r.Right := 800; r.Bottom := 600; lpDDSBufor.GetDC(dds_hdc); FillRect(dds_hdc,r,2); //rysujemy kwadrat BitBlt(dds_hdc,x,y,100,100,hdcmem,0,0,SRCCOPY); lpDDSBufor.ReleaseDC(dds_hdc); SelectObject(hdcmem,hgdi); end; |
Jak widać wyświetlenie kwadratu nie jest trudne, jak i samo buforowanie. Ów kwadrat rysujemy aby wyczyścić ekran. A…. Byłbym zapomniał po procedurze render która oczywiście znajduje się w głównej pętli umieszczamy coś takiego :
1 |
lpDDSEkran.Flip(nil,DDFLIP_WAIT); |
Te procedura wyświetla nam na ekranie Scenę(zresztą sama nazwa Flip wskazuje na to). Bez tego istotnego elementu ujrzymy czarny ekran, i nici z naszej pracy, he, he ; ). Na następnej lekcji żeby narobić wam smaczku powiem, że zajmiemy się rysowaniem bitmap z parametrem transparent, czyli z przezroczystością.
Autor: HNB