[ Pobierz całość w formacie PDF ]
.Uruchamianie Direct3D z poziomu aplikacji C++ oraz wychodzenie z niejGame Design PL - Uruchamianie Direct3D z poziomu aplikacji C++ oraz wychodzenie z niejAutor:Data: 26 Sierpień 2001WSTĘPRelease(); p = NULL; }To makro jest bardzo pomocne przy usuwaniu wszelkiego rodzaju obiektów Direct3D, od tekstury do obiektu głównego.Wracamy do pliku d3dFrameWork.cpp.Napiszemy teraz funkcję kończącą pracę środowiska 3D.void ExitD3D( void ){//ustawiamy flagę braku gotowości Direct3D do pracyg_bD3DReady = FALSE;// usuwamy obiekty// używamy do tego celu makra SAFE_RELEASE// najpierw urządzenie renderujące (kolejność jest bardzo ważna)SAFE_RELEASE(g_pD3DDevice);// potem obiekt głównySAFE_RELEASE(g_pD3D);}Funkcja kończąca pracę Direct3D jest prosta jak konstrukcja cepa J.Po prostu usuwamy wszystkie obiekty.Trzeba tu pamiętac tylko o kolejności.Najpierw usuwamy tekstury, VertexBufory, IndexBufory (co to jest, dowiesz się w artykule a renderingu).Dopiero potem mozemy usunąć urządzenie renderujące, a na samym końcu obiekt główny.Niezachowanie tej kolejności moze doprowadzić do nieprzewidzianych efektów, łącznie z załamaniem się systemu.To tyle, jeżeli chodzi o inicjację i niszczenie Direct3D.Napiszemy jeszcze szkielet funkcji renderującej, który w chwili obecnej będzie czyscił ekran na niebiesko.Dzięki temu będziemy wiedziec, ze inicjacja Direct3D przebiegła pomyślnie.Funkcja Render ma następującą postać:HRESULT Render(){//czyścimy scenęg_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,150), 1.0f, 0 );// rozpoczynamy scenę (wywołanie tej funkcji jest potrzebne tylko w wypadku, gdy coś// rzeczywiście renderujemy, ale nic nie szkodzi, gdy się tu znajdzieg_pD3DDevice->BeginScene();// kończymy scenę.Ta funkcja musi być zawsze wywoływana, gdy użyliśmy BeginScene()g_pD3DDevice->EndScene();// wyświetlamy scenęg_pD3DDevice->Present( NULL, NULL, NULL, NULL );// zwracamy wartość 0 - operacja udanareturn S_OK;}W funkcji tej wywołujemy cztery metody interfejsu urządzenia renderującego.Pierwsza z nich jest odpowiedzialna za czyszczenie sceny, tu akurat kolorem niebieskim ( w makrze D3DCOLOR_XRGB( a, r, g, b) wpisujemy : a - niużywane, r - składowa czerwona,g - składowa zielona, b - składowa niebieska.Można dowolnie mieszać barwy.Nie zalecam jednak stosowania koloru czarnego w fazie budowy i testowania aplikacji, ponieważ na czarnym tle nie widać ewentualnych nieoświetlonych albo nieoteksturowanych obiektów.Czas na funkcję, która kiedyś zostałaby nazwana główną pętlą gry.Jest to funkcja OnIdle(), w której wywołujemy funkcję renderującą (na razie - później znajdą się tam wszystkie funkcje czytające klawisze i tworzące transformacje).Jej postać jest też bardzo prosta:HRESULT OnIdle ( void ){// jeżeli Direct3D jest gotowy do pracy, renderujemyif(g_pD3DReady)return Render();// zwracamy kod błędu - Direct3D nie jest gotowyreturn E_FAIL;}Tej funkcji nie trzeba chyba tłumaczyć.Pozostaje jeszcze problem jej wywołania.Tu musimy wrócic do głównego pliku aplikacji i zamienić pętlę komunikatów na mniej wwięcej taką:// tu inicjujemy Direct3DInitD3D( );hAccelTable = LoadAccelerators(hInstance, (LPCTSTR) IDC_PRZYKLADDIRECT3D);GetMessage(&msg, g_hWndMain, 0, 0);while( msg.message != WM_QUIT ){if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ){if(!TranslateAccelerator(g_hWndMain, hAccelTable, &msg)){TranslateMessage( &msg );DispatchMessage( &msg );}}else// tu własnie wywołujemy OnIdle()OnIdle();}// dotrzemy tu wtedy, gdy aplikacja ma zakończyć.Jest to więc dobre miejsce na usunięcie//obiektów Direct3DExitD3D();return msg.wParam;Nie zapomnij dopisać w głównym pliku.cpp aplikacji#include "d3dframework.h"Niektórzy twierdzą, że taka postać pętli komunikatowej jest zła, ponieważ komunikaty mogą być gubione.Nic bardziej mylnego! W systemie Windows żaden kominikat nie może zostać zgubiony.Musi być obsłużony w ten czy inny sposób, inaczej nie wyjdzie z pętli komunikatów.Postać petli komunikatowej, taka jak wyżej, pozwala na optymalne wykorzystanie czasu procesora.Można wzorem niektórych umieścić wywołanie OnIdle() w odpowiedzi na komunikat WM_PAIN, jednak nie jest to najlepszy pomysł, ponieważ system zużyje dużo czasu procesora rozpaczliwie próbując odmalować okienko.I to koniec inicjacji Direct3D.W chwili obecnej posiadamy aplikację uruchamiającą Direct3D w trybie okienkowym.Możemy jeszcze dorobić przełączanie się pomiędzy trybami okienko - Fullscreen.Jest to proste.Wystarczy, że dodasz w głównym pliku zewnętrzną zmienną globalną:extern BOOL g_bD3DFullscreen;W tablicy akceleratorów zaś dodasz skrót klawiszowy, pod którym chcesz mieć przełączanie trybów (najczęściej jest to Alt-Enter), a następnie w funkcji komunikatowej okna wpiszesz odpowiedź na komunikat, który zdefiniowałeś w akceleratorze (i/lub w Menu).Sama reakcja powinna wyglądać mniej więcej tak:case ID_CHANGEMODE: // komunikat z akceleratora- mamy zmienić tryb// Niszczymy stare obiekty Direct3DExitD3D();// ustawiamy flagę g_bFullScreen na przeciwnąg_bD3DFullscreen = !g_bD3DFullscreen;// musimy wydać polecenie odrysowania okienka//(ćwiczenie - spróbuj to zakomentarzować i nie wpadaj w// panikę po uruchomieniu i zmianie trybu - Alt - F4 nadal działa)// robimy to na przykład tak:ShowWindow( g_hWndMain, SW_MINIMIZE );ShowWindow( g_hWndMain, SW_RESTORE );// uruchamiamy D3D jeszcze razInitD3D();// gotowebreak;I to już naprawdę wszystko w tym artykule.W następnych będziemy powoli uczyć się nowych rzeczy i dodawać coraz to nowe funkcje aż do czasu, kiedy stworzenie renderera dla pełnej trójwymiarowej gry nie bedzie stanowiło żadnego problemu.Życzę powodzenia !Wiktoryn "Wiku" ŻerebeckiWiku34@poczta.onet.pl(c) 2001 by Game Design PL - http://www.warsztat.px.pl
[ Pobierz całość w formacie PDF ]