cw pp.doc

(452 KB) Pobierz
Ćwiczenia 2

Ćwiczenia 6

Post Processing

 

Pobierz projekt z www.twinbottles.com/grk/SimplePP.rar

 

Spróbuj skompilować kod. Jeżeli wyskoczy ci błąd

 

              fatal error C1083: Cannot open include file ‘d3d9.h’: No such file or directory

 

to znaczy, że w środowisku nie są ustawione ścieżki do plików nagłówkowych i bibliotek DirectX.

 

Aby je ustawić wejdź do menu Tools, wybierz Options

 

 

W drzewie opcji w Projects and Solutions wejdź do VC++ Directories

 

 

 

 

 

 

 

 

W combo box Show directories for: wybierz  Include files i dodaj nową ścieżkę klikając na drugi od lewej przycisk z ikoną folderu. W nowym polu wpisz:

 

C:\Program Files\Microsoft DirectX SDK (March 2009)\Include

 

 

 

Podobnie po wybraniu w combo box Library files dodaj nową ścieżke i w polu wpisz

 

C:\Program Files\Microsoft DirectX SDK (March 2009)\Lib\x86

Spróbuj skompilować kod ponownie. Teraz powinno się udać.

 

 

 

Punktem wyjściowym do tych ćwiczeń jest kompletny program z oświetlonym tygrysem. Przetwarzanie obrazu najwydajniej jest implementować w pixel shaderze. Cała scena zamiast do back buffer renderowana jest do tekstury pomocniczej. Następnie do back buffer jest renderowany prostokąt składający się z dwóch trójkątów. Prostokąt ten zajmuje cały ekran i jest poteksturowany tekstura pomocniczą, do której została uprzednio wyrysowana scena. Dzięki temu zabiegowi możemy dowolnie modyfikować teksele sceny.

 

Pierwszym krokiem będzie załadowanie pliku efektu wykorzystywanego przy renderowaniu prostokąta.

 

Ponieważ post processing będzię działał na wyrenderowanym już obrazie, potrzebujemy stworzyć dla niego dodatkowe, niezależne funkcje i zmienne.

 

Potrzebny będzie kod:

 

 

LPDIRECT3DVERTEXDECLARATION9              m_pVertexDeclarationPP ;

LPD3DXCONSTANTTABLE                            m_pVertexConstantsPP;

LPD3DXEFFECT                                          m_pEffectPP;

 

Funkcja initializująca shader ( przykładowa nazwa InitEfectPP () )będzie analogiczna do funkcji initializującej shader tygrysa (zmienią się tylko nazwy zmiennych). Wywołana powinna być na koniec funkcji InitDx( ).

Oczywiście ładowany będzie plik efektu o nazwie PostProcess1.fx a nie Shader.fx. Zmieni się także struktura wierzchołka:

              // Create the shader declaration.

              D3DVERTEXELEMENT9 decl[] =

              {

                            { 0, 0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULTD3DDECLUSAGE_POSITION, 0 },

                            { 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULTD3DDECLUSAGE_TEXCOORD, 0 },

                            D3DDECL_END()

              };

 

Kolejnym krokiem będzie zadeklarowanie struktury wierzchołka i stworzenie tablicy czterech wierzchołków.

 

struct Vert{

 

              D3DXVECTOR4 pos;

              float u1,v1;

 

};

 

 

Vert vertices[4];

 

Wartości w tej tablicy należy ustawić w funkcji InitDX( ) za pomocą następującego kodu:

 

              vertices[0].pos.x=-1.0f;                                         

              vertices[0].pos.y=1.0f;

              vertices[0].pos.z=0;

              vertices[0].pos.w=1.0f;

              vertices[0].u1=0;

              vertices[0].v1=0;

              vertices[1].pos.x=1.0f ;                                         

              vertices[1].pos.y=1.0f;

              vertices[1].pos.z=0;

              vertices[1].pos.w=1.0f;

              vertices[1].u1=1;

              vertices[1].v1=0;

              vertices[2].pos.x=-1.0f;                                         

              vertices[2].pos.y=-1.0f;

              vertices[2].pos.z=0;

              vertices[2].pos.w=1.0f;

              vertices[2].u1=0;

              vertices[2].v1=1;

              vertices[3].pos.x=1.0f ;                                         

              vertices[3].pos.y=-1.0f;

              vertices[3].pos.z=0;

              vertices[3].pos.w=1.0f;

              vertices[3].u1=1;

              vertices[3].v1=1;

 

 

Konieczne będzie także przygotowanie tekstury do której będzie renderowany obraz sceny oraz powierzchni, która będzie służyła za tymczasowy bufor głębokości. Przy renderowaniu sceny do innego bufora niż backbuffer konieczne jest ustawianie własnego Zbufora. Korzystanie z domyślnego bufora głębi podczas renderingu do własnego bufora obrazu jest możliwe tylko na kartach firmy Nvidia, nie jest to jednak zachowanie zgodne ze specyfikacją DX.

 

///   depth

LPDIRECT3DTEXTURE9                            lpTexDepth;

LPD3DXRENDERTOSURFACE                            m_pRenderToDepth;

LPDIRECT3DSURFACE9                            pd3dsSurfaceDepth;

////

 

LPDIRECT3DSURFACE9                             lpBackBufferTmp;

 

LPDIRECT3DTEXTURE9                            lpTexture;

LPD3DXRENDERTOSURFACE                            m_pRenderToSurface;

LPDIRECT3DSURFACE9                            pd3dsSurface;

 

Initializujemy je w nastepujący sposób (w funkcji InitEfectPP):

 

HRESULT  hr = S_OK;// = lpD3DDevice->CreateRenderTarget(   

              D3DDISPLAYMODE mode;

              lpD3DDevice->GetDisplayMode(0,&mode);

 

 

 

              D3DXCreateTexturelpD3DDevice,

                            800,

                            600,

                            1,

                            D3DUSAGE_RENDERTARGET ,

                            mode.Format,

                            D3DPOOL_DEFAULT,

                            &lpTexture

                            );

 

              D3DSURFACE_DESC desc;

              hr = lpTexture->GetSurfaceLevel(0, &pd3dsSurface);

              pd3dsSurface->GetDesc(&desc);

 

              if(FAILED(hr=D3DXCreateRenderToSurface(lpD3DDevice, desc.Width, desc.Height, mode.Format, TRUE, D3DFMT_D16, &m_pRenderToSurface)))

              {

                            return false;

              }

 

 

              lpD3DDevice->CreateDepthStencilSurface(

                            800,

                            600,

                            D3DFMT_D16,

                            D3DMULTISAMPLE_NONE,

                            0,

                            TRUE,

                            &pd3dsSurfaceDepth,

                            NULL  );

 

Warto zwrócić uwagę na fakt, że tekstura która będzie służyła za backbuffer jest tworzona z rozmiarem 800x600 a tekstura, która będzie buforem głębi jest tworzona za pomocą metody ...

Zgłoś jeśli naruszono regulamin