----------------------------------------------- -------- DirectX in Delphi (cz 1) -------- -------- Copyright by Sulek [r] -------- -------- sulek@shnet.pl -------- -------- http://coders.shnet.pl/klub/ -------- -------- ^ wiecej artykulow ^ -------- ----------------------------------------------- Dokument powstal: 01 08 2000 r Ten artykuł traktowac bedzie o tworzeniu aplikacji w Delphi z wykorzystaniem DirectX. Uzyjemy do tego pakietu DelphiX. Komponenty potrebne do pisania w Delphi pod DirectX Potrzebne tez bedzie Delphi (3 i >).*** Po co ten artykul ***
Napisalem ten text, aby zapelnic luke w dokumantacji doteyczacej zastosowan DirectX pod Delphi. Znalazlem doslownie 1 tutorial w sieci do DelphiX i to wcale nie najlepszy... Dlatego mam zamiar napisac szereg tutoriali, w ktorych bede opisywal jak stworzyc prosta gre z uzyciem Delphi i DelphiX. Architektura DirectX wyglada tak: (dosyc stary screen)![]()
i ustawmy w Object Inspektorze:
= Align na alClient (plotno DXDraw zajmnie cala forme)
= AutoInitialize na True (DXDraw zostanie zainicjowny od razu po starcie aplikacji)
= Display na 640x480x8 (rozdzielczosc + glebia kolorow)
= w Options doFullScreen na True (pelny ekran)
= zmieniamy name na DXDraw
Po uruchomieniu aplikacji powinnismy zobaczyc czarny ekran i kursor myszki.
Efekt nadzwyczaj nieciekawy, ale jesli Ty tez to widzisz to znaczy, ze wszystko gra.
Teraz wyjdz z aplikacji (Alt+F4).
Na pewno Twoj entuzjazm dawno juz minal i pewnie chcialbys zobaczyc cos innego niz
tylko czarny ekran.
No to wyswietlimy text Hello DirectX !
Przede wszystkim dodamy nowy modul DXClass i zamienimy
TMainForm = class(TForm)
naTMainForm = class(TDXForm)
Jest to zalecane, gdyz jak podaje autom pakietu bez tego moga wystepowac rozne dziwne bledy. Zmienimy tez AutoInitialize na False komponentu DXDraw. Nasz text bedzie pojawial sie od razu po uruchomieniu aplikacji, wiec uzyjemy do tego zdarzenia onCreate dla MainForm. Tworzymy obsluge zdarzenia onCreate dla MainForm i piszemy:procedure TMainForm.FormCreate(Sender: TObject); begin // inicjujemy DXDraw DXDraw.Initialize; // Sprawdzamy czy mozemy rysowac if DXDraw.CanDraw then begin // jesli mozna rysowac with DXDraw.Surface.Canvas do begin // zmieniamy parametry czcionki Brush.Style:= bsClear; Font.Color:= clGreen; Font.Size:= 12; // piszemy text w punkcjie P(10, 10) TextOut(10, 10, 'Hello DirectX'); end; // wyswietlenie Surface na ekranie DXDraw.Surface.Canvas.Release; DXDraw.Flip; end else begin // jesli inicjacja sie nie powiodla MessageBox(Handle, 'DXError', 'Blad inicjacjiDirectX', 0); Close; end; end;
Ta prosta procedura incjuje DXDraw i rysuje na ekranie napis Hello DirectX. Kod zawiera wiele komentarzy wiec nie trzeba go dodatkowo tlumaczyc. Nalezy jednak wspomniec o sposobie w jaki DirectX wyswietla dane na ekranie. Kiedy rusyjemy na DXDraw.Surface.Canvas to nie odwolujemy sie odpowiednio do katy graficznej. Zapisyjemy dane na tzw. wirtualnym ekranie a dopiero poprzez Release i Flip przesylamy je na ekran. Musimy jeszcze zamknac DXDraw kiedy konczymy aplikacje. Podpinamy sie wiec do zdarzenia onClose dla MainForm i piszemy.procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); begin DXDraw.Finalize; end;
Kod zrodlowy do przykladu 1 (3,72 KB)procedure TMainForm.FormCreate(Sender: TObject); begin // inicjijemy DXDraw DXDraw.Initialize; // Sprawdzamy czy mozemy rysowac if not DXDraw.CanDraw then begin // jesli inicjacja sie nie powiodla MessageBox(Handle, 'DXError', 'Blad inicjacjiDirectX', 0); Close; end; end;
Musimy obsluzyc zdarzenie onMouseMove dla komponentu DXDraw:procedure TMainForm.DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin with DXDraw.Surface.Canvas do begin Pen.Color:= clRed; // kolor piora Pen.Width:= 5; // szerokosc piora LineTo(X, Y); // Narysowanie linii end; // wyrzucenia Surface na ekran DXDraw.Surface.Canvas.Release; DXDraw.Flip; end;
Po uruchomieniu programu zobaczymy, ze jesli poruszymy myszka rysowana jest linia. Mozna oczywiscie to rozbudowac. Np jesli chcemy rysowac tylko gdy nacisniety jest lewy przycisk myszy musimy: - stworzyc zmienna globalna MB: TMouseButton - przypisac jej wartosc mbMiddle podczas tworzenia formy (onCreate - MainForm) - Obsluzyc zdarzenie onMouseDown dla DXDraw (klawisz myszy nacisniety):procedure TMainForm.DXDrawMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin MB:= Button; end;
- Obsluzyc zdarzenie onMouseUp dla DXDraw (kalwisz myszy puszczony):procedure TMainForm.DXDrawMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin MB:= mbMiddle; end;
- zanim narysujemy linie musimy sprawdzic, czy lewy klawisz myszy jest nacisniety:if MB = mbLeft then begin // rysujemy linie end;
Kod zrodlowy do przykladu 2 (3,84 KB)
na forme, zmieniamy jego nazwe na DXInput.
Upewnij sie ze wartosc DXInput Keyboard.Enabled = true
Mamy teraz komponent odpowiedzialny za odczyt stanu kalwiatury. Jednak jak pewnie
zauwazyles nie ma to zdarzen. Trzeba wiec stworzyc procdure, ktora bedzie sprawdzac co pare
sekund stan klawiatury.
Swietnie nadaje sie do tego komponent TDXTimer
(rowniez z pakietu DelphiX).
Przeciegamy go na forme i ustalamy Name na DXTimer, Enabled na false i Interval na 100.
Interval decyduje co ile czasu bedzie wywolywana procedura onTimer, ktora wlasnie deraz zdefiniujemy.
Czyli po prostu tworzymy procedure obslugi zdarzenia onTimer dla komponentu TDXTimer.
W tej procedurze piszemy:
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer); begin DXTimer.Enabled:= False; // wylaczamy Timera na czas trwania procedury // odczytujemy stan klawiatury DXInput.Update; // sprawdzanie klawiszy if DXInput.Keyboard.Keys[VK_NUMPAD0] then Ekran.SetColor(DXDraw, clBlack) // zdefiniowalem sobie obiekt, ale Ty mozesz zmieniac kolory jak przedtem else if DXInput.Keyboard.Keys[VK_NUMPAD1] then Ekran.SetColor(DXDraw, clWhite) // itd. az do 9 DXTimer.Enabled:= True;
Musimy jeszcze dodac DXTimer:= True po zainicjowaniu DXDraw i program powinien dzialac, a my mozemy zmieniac kolor piora. Rozbudowalem troche ten program, tak ze mozna zmieniac szerokosc piora strzalkami, czyscic ekran spacja, ukrywac/pokazywac kursor enterem. Stworzylem takze obiekt Ekran. Zrodla rozbudowanego przykladu 3 (6 KB) Zrodla + EXE rozbudowanego przykladu 3 (187 KB)