DirectX w VB cz.2 Witam ponownie. Można by tak rzec. W drugiej części artykułu o Direct X pojawi się Direct Draw. W poprzedniej części zasady działania jego były dokładnie wytłumaczone, teraz przejdziemy do praktyki.
Na początek należy sprawdzić, czy mamy zainstalowaną wersję 7 Direct'a X, ponieważ taką to wersją się tutaj będę posługiwał. Jeśli jej nie ma, to koniecznie należy ją zainstalować! Dalej - wchodzimy do VB, tworzymy nowy projekt, wchodzimy do menu Project i kilkamy na podmenu References. Z pozycji zamieszczonych tam w liście wybieramy dodatkowo 'Direct X for Visual Basic Type Libary', czyli plik 'dx7vb.dll', który powinien znajdować się w katalogu systemowym, czyli najczęściej C:\WINDOWS\SYSTEM\. Biblioteka ta będzie pośredniczyć między naszym programem zrobionym w VB, a właściwymi bibliotekami DirectX. Wyglądać to będzie tak: nasza aplikacjia -> dx7vb.dll - > biblioteki DirectX - > sterowniki podzespołów - > urządzenie/pamięć urządzenia Pisząc aplikację używającą DirectX w VC++ w cyklu pośrednictwa nie uczestniczy 'dx7vb.dll', dlatego także pośrednictwo te zachodzi szybciej i pozwala na dużo więcej.
Naturalny Direct Draw Aplikacja VB używająca DDraw w jego naturalnej postaci będzie musiała: - zadeklarować zmienne obiektowe DX - ustawić zmienne obiektowe DX - wyświetlić obiekty, w razie potrzeby powtórzyć tą czynność - usunąć dane ze zmiennych obiektowych A w praktyce jest kształtuje się to w następujący sposób: - utworzenie obiektów - zmiana ich atrybutów - initializacja DX - wyświetlanie - deinitializacja DX Zaczynamy pierwszą aplikację! Przygotowawszy projekt w w/w sposób, do General'a formy w Declarations wklejamy:
Dim DX As New DirectX7 'zmienna obiektowa DirectX Dim DD As DirectDraw7 'zmienna obiektowa Direct Draw, zostanie zainitializowana przez DX
Dim ddsFront As DirectDrawSurface7 'zmienna obiektowa powierzchni ekranu - Primary Surface Dim ddsBack As DirectDrawSurface7 'zmienna obiektowa powierzchni tylniego bufora - Back Buffer
Dim Background As DirectDrawSurface7 'zmienna obiektowa naszej pierwszej powierzchni - tła
Dim ddsd1 As DDSURFACEDESC2 'zmienna obiektowa "podkładu", związana potem z ddsFront Dim ddsd2 As DDSURFACEDESC2 'zmienna obiektowa "podkładu", związana potem z Background. ddsback będzie powiązany z inną zmienną, później
Dim inicjacja As Boolean 'zmienna określająca czy DDraw został zainitializowany Dim is_run As Boolean 'zmienna określająca czy wyświetlanie ma trwać
Private Declare Function ShowCursor Lib "user32" (ByVal bShow As Long) As Long 'pomocnicza funkcja API do ukrywania kursora
Dla tych, mających styczność z VC++, na pewno przypomina to udrękę z deklarowaniem wszystkiego i "ręcznym" ustawianiem. Tak, tak, to niestety właśnie to... Tworzymy sobie rysuneczek, np. w Paint, o wymiarach 640x480 i zapisujemy go np. na dysku C:\ pod nazwą 'bkg.bmp'. Następnie robimy Sub o nazwie InitDD:
Sub InitDD() On Error GoTo MErr ' jeśli wystąpi błąd, musimy mieć zabezpieczenie, bo inaczej komputer przestanie odpowiadać Set DD = DX.DirectDrawCreate("") ' tworzymy DD - Direct Draw z DX- DirectX Me.Show ' pokazujemy naszą formę :-) Call DD.SetCooperativeLevel(Me.hWnd, DDSCL_FULLSCREEN Or DDSCL_EXCLUSIVE) ' ustalamy parametry współpracy DD.SetDisplayMode 640, 480, 24, 0, DDSDM_DEFAULT 'ustalamy atrybuty wyświetlania, tu 640x480 i 24 bit koloru
ddsd1.lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT ' ustalamy atrybuty powierzchni Primary Surface ddsd1.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_FLIP Or DDSCAPS_COMPLEX ddsd1.lBackBufferCount = 1 Set ddsFront = DD.CreateSurface(ddsd1) 'nadajemy powierzchni Primary Surface te atrybuty
Dim caps As DDSCAPS2 'ustalamy atrybuty Back Buffer'a caps.lCaps = DDSCAPS_BACKBUFFER Set ddsBack = ddsFront.GetAttachedSurface(caps) ' nadajemy mu te atrybuty
Call LoadSurfaces 'przechodzimy do sub'a, gdzie ładujemy powierzchnie inne niż Primary i Back
inicjacja = True ' ustalamy, że zainicjowaliśmy DD is_run = True ' obraz ma być wyświetlany ShowCursor False ' ukrywamy kursor Do While is_run = True 'jeżeli obraz ma być wyświeltany to BLT 'przechodzimy do sub'a BLT DoEvents Loop MErr: 'jeżeli wystąpił błąd, to ratuj się kto może! If Err Then DDUnload ' przechodzimy do sub'a deinicjacji DD MsgBox "Błąd(" & Err & ": " & Error(Err) 'wyświetlamy jaki to błąd End If End Sub
Dalej tworzymy sub Load Surfaces:
Sub LoadSurfaces() On Error GoTo MErr ' zabezpieczamy się przed błędem Set Background = Nothing ' resetujemy zmienną ddsd2.lFlags = DDSD_CAPS Or DDSD_HEIGHT Or DDSD_WIDTH 'ustalamy jej atrybuty ddsd2.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN ddsd2.lWidth = 640 ddsd2.lHeight = 480 Set Background = DD.CreateSurfaceFromFile("c:\bkg.bmp", ddsd2) 'ładujemy obrazek bmp MErr: ' i znowu na wypadek błędu wszystko wyładowujemy i czyścimy pamięć If Err Then DDUnload MsgBox "Błąd(" & Err & ": " & Error(Err) End If End Sub
Robimy sub'a który będzie wyświetlał już wszystko:
Sub BLT() On Error GoTo MErr If inicjacja = False Then Exit Sub Dim RBackGround As RECT
RBackGround.Bottom = ddsd2.lHeight ' przekładamy atrybuty RECT RBackGround.Right = ddsd2.lWidth Call ddsBack.BltFast(0, 0, Background, RBackGround, DDBLTFAST_WAIT) 'wklejamy obraz do Back Buffera(ddsback) ddsFront.Flip Nothing, DDFLIP_WAIT 'przeżucamy obraz z back buffera do Primary Surface MErr: 'jeśli wystąpi błąd to wiadomo co robić... If Err Then DDUnload MsgBox "Błąd(" & Err & ": " & Error(Err) End If End Sub
A teraz sub wyładowujący DD:
Sub DDUnload() Call DD.RestoreDisplayMode 'przywracamy tryb wyświetlania Call DD.SetCooperativeLevel(Me.hWnd, DDSCL_NORMAL) ShowCursor True 'pokazujemy kursor End 'zamykamy program End Sub
Jeszcze w Form_Click damy wywołanie DDUnload, by po kliknięciu myszką program wyłączył się
Private Sub Form_Click() DDUnload End Sub
A w Form_Load:
Private Sub Form_Load() Call InitDD End Sub
I to wszystko. Twój pierwszy program z Direct Draw gotowy! Analogicznie postępując dodajemy dalsze powierzchnie. Aplikację tą należy skompilować bo praca w trybie projektowania może wywołać efekty uboczne. Radzę kilkakrotnie przejrzeć kod tej aplikacji i spróbować go dogłębnie zrozumieć, poprzestawiać jakieś atrybuty i zobaczyć co się stanie, ale uwaga - jak już wspominałem program może zrobić nam kawał i zatrzymać się, powodując, że komputer nie będzie odpowiadał...
W następnej części: - omówienie Engine BioHazard - przykładowy program na jego podstawie