Nareszcie coś na ekranie!

Hej! Jak zwykle omijamy wstęp, gdyż ta lekcja będzie naprawdę ważna i ciężka. ;)

Dzisiaj narysujemy coś w naszym nowostworzonym okienku. Co więcej, narysujemy owo coś (trójkąt, konkretnie. A jak! ;) ) z użyciem naszej karty grafiki. :) Jak już mówiłem, nasz trójkąt składać się będzie z trzech wierzchołków. Teraz pozostaje jedynie problem – jak przekazać je karcie? Spójrzmy na listing.

   1:  

   2: struct OurVertex

   3: {

   4:     float x, y, z; // pozycja

   5:     float rhw; // komponent rhw

   6:     D3DCOLOR color; // kolor

   7: };

   8:  

   9: const DWORD OURVERT_FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE;

  10:  

  11: IDirect3DVertexBuffer9* pVB;

  12:  

  13: int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

  14: {

  15:     // Init Direct3D

  16:  

  17:     OurVertex verts[] =

  18:     {

  19:         { 200.0f, 500.0f, 0.5f, 1.0f, 0xffff0000,},

  20:         { 400.0f, 100.0f, 0.5f, 1.0f, 0xff00ff00,},

  21:         { 600.0f, 500.0f, 0.5f, 1.0f, 0xff0000ff},

  22:     };

  23:  

  24:     pDev->CreateVertexBuffer(sizeof(verts),

  25:         D3DUSAGE_DYNAMIC, OURVERT_FVF, D3DPOOL_DEFAULT, &pVB, 0);

  26:  

  27:     void* data;

  28:  

  29:     pVB->Lock(0, 3*sizeof(OurVertex), &data, D3DLOCK_DISCARD);

  30:  

  31:     memcpy(data, (void*)verts, sizeof(verts));

  32:  

  33:     pVB->Unlock();

  34:  

  35:     MSG msg;

  36:     while(1)

  37:     {

  38:         if (PeekMessage(&msg, 0, 0U, 0U, PM_REMOVE))

  39:         {

  40:             TranslateMessage(&msg);

  41:             DispatchMessage(&msg);

  42:         }

  43:         else

  44:         {

  45:             pDev->Clear(0, 0, D3DCLEAR_TARGET, 0xff000000, 1, 0);

  46:             pDev->BeginScene();

  47:             

  48:             pDev->SetFVF(OURVERT_FVF);

  49:             pDev->SetStreamSource(0, pVB, 0, sizeof(OurVertex));

  50:             pDev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

  51:  

  52:             pDev->EndScene();

  53:             pDev->Present(0, 0, 0, 0);

  54:         }

  55:     }

  56:     pVB->Release();

  57:     pDev->Release();

  58:     pD3D->Release();

  59: }

Od początku widzimy masę nowych rzeczy. Mamy więc strukturę OurVertex, która będzie przechowywać dane o naszych wierzchołku. Mamy oczywiście pozycję (jako wektor trójwymiarowy), komponent koloru (w formacie DWORD – 0xAARRGGBB). Tak na prawdę tajemniczy jest element wierzchołka o nazwie rhw. Faktycznie należy on do pozycji, jednak postanowiłem go oddzielić, gdyż o nim powiemy sobie dokładniej podczas lekcji o macierzach, gdzie przy okazji omówimy jeszcze dalszą cześć potoku. Narazie po prostu radośnie ustawimy ten komponent na 1. :)

Kolejnym rzucającym się w oczy elementem jest OURVERT_FVF. Jest to deklaracja czegoś takiego jak Flexible Vertex Format. Jest to narzędzie, które pozwala powiedzieć karcie o formacie wierzchołka jaki jej przekazujemy. Innymi słowy, jest to jakby opis wierzchołka. Tutaj ustawiamy właśnie pozycję (D3DFVF_XYZRHW) oraz kolor (D3DFVF_DIFFUSE – światła rozproszonego).

Następnie widać deklaracje obiektu Vertex Buffer. W przeciwieństwie do OpenGL-a, tutaj nie mamy do dyspozycji (a właść. mamy, ale jest to rzadko używane) narzędzia typu glVertex. Musimy pakować wszystkie nasze wierzchołki do takiego bufora; jest to praktycznie jedyne jego zadanie – służyć jako kontener wierzchołków.

Po inicjalizacji podstawowych interface`ów D3D, zabieramy się za wypełnianie naszego Vertex Buffera. Na początku tworzymy sobie tablice trzech wierzchołków. Mamy więc pozycję (w pikselach na ekranie), komponent rhw, który nie jest nam narazie potrzebny, oraz kolor w formacie 0xAARRGGBB.

Widzimy wykorzystanie naszego urządzenia renderującego. Używamy go do utworzenia bufora wierzchołków. Powinniśmy się przyzwyczaić do takich konstrukcji, bo jak mówiłem pDev będzie się często powtarzał. :) Omówmy co ważniejsze argumenty tej funkcji. Mamy oczywiście rozmiar naszych wierzchołków, flagę oznaczającą sposób w jaki będzie używany bufor. D3DUSAGE_DYNAMIC został tutaj użyty trochę na wyrost, bo nasz bufor jest statyczny, tym niemniej – nada się. ;) Mamy także nasz FVF oraz ciekawa sprawa – flaga D3DPOOL_DEFAULT. Mówi ona o sposobie zarządzania zasobami przez Direct3D. Tutaj akurat wykorzystujemy sposób „domyślny” – sterownik sam zdecyduje w którym miejscu w pamięci umieścić dany zasób. Z tym poolem wiąże się jeszcze jeden ból – odzyskiwanie zasobów przy resecie urządzenia. Ale o tym później.

Następnie tworzymy sobie tymczasową zmienną, która reprezentować będzie dane w buforze wierzchołków. Blokowanie VB jest proste. Podajemy offset (przesunięcie) od początku, wielkość na jaką blokujemy, podajemy adres do wskaźnika na nasze przyszłe dane oraz flagę D3DLOCK_DISCARD – oznaczającą, że ewentualną poprzednią zawartość bufora nadpisujemy. Prostym memcpy wypełniamy VB. Funkcja odblokowująca nie przyjmuje żadnych parametrów.

Następnym nowym fragmentem kodu jest sam rendering. Jest on stosunkowo prosty. Mówimy karcie z jakiego będziemy korzystać FVF (SetFVF), z jakiego będziemy korzystać bufora wierzchołków: SetStreamSource – przyjmuje numer strumienia wierzchołków, których może być więcej niż jeden, wskaźnik na nasz VB, przesunięcie (offset) oraz stride – „szerokość” danych. W tym przypadku jeden wierzchołek.

Ostatnim nowym wywołaniem jest pDev->DrawPrimitive. Jest to wywołanie już bezpośrednio powodujące rendering. Pierwszy parametr mówi sterownikowi co właściwie będziemy renderować – u nas będzie to D3DPT_TRIANGLELIST – czyli lista trójkątów. Jest to najczęściej używany typ prymitywów. Drugi parametr oznacza offset, trzeci zaś – ile trójkątów renderujemy.

Do tej lekcji załączony jest pełny kod źródłowy oraz .exe.

image

Reklamy

Jedna odpowiedź to “Nareszcie coś na ekranie!”

  1. Dlaczego jak uruchamiam ten program (z linka do pliku źródłowego) to wywala mi raport o błędach?

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj / Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj / Zmień )

Zdjęcie na Google+

Komentujesz korzystając z konta Google+. Wyloguj / Zmień )

Connecting to %s

 
%d blogerów lubi to: