source: GTP/branches/IllumWPdeliver2008dec/IlluminationWP/demos/Standalone/DepthOfField [DirectX]/CameraEffects.cpp @ 3255

Revision 3255, 10.4 KB checked in by szirmay, 15 years ago (diff)
Line 
1#include "dxstdafx.h"
2#include "media.h"
3#include ".\cameraeffects.h"
4
5CameraEffects::CameraEffects(void)
6{
7}
8
9CameraEffects::~CameraEffects(void)
10{
11}
12
13// Loads the selected mesh
14void CameraEffects::changeMesh(int meshid)
15{
16        if(meshid!=currentmesh)
17        {
18                switch (meshid)
19                {
20                        case 1: mesh->Load(pixelMESH0);break;
21                        case 2: mesh->Load(pixelMESH1);break;
22                        default: return;
23                }
24                currentmesh=meshid;
25                mesh->computeTangent();
26        }
27}
28
29void CameraEffects::OnCreateDevice( IDirect3DDevice9* pd3dDevice)
30{
31        this->pd3dDevice = pd3dDevice;         
32        mesh = new Mesh(pixelMESH0, 1, D3DXVECTOR3(0,0,0));
33        mesh->computeTangent();
34        // loading light sphere model
35        lightmesh = new Mesh(L"Media\\Objects\\light.x", 1, D3DXVECTOR3(0,0,0));
36       
37        ID3DXBuffer* errBuff = NULL;
38        // loading simple rendering shaders
39        if( FAILED(D3DXCreateEffectFromFile( pd3dDevice, L"shaders/BumpMapping.fx", NULL, NULL, NULL,
40                NULL, &g_pEffect, &errBuff )))
41        {
42                int BufSize = errBuff->GetBufferSize();
43                // displaying error message of arbitrary length
44                wchar_t* wbuf = new wchar_t[BufSize];
45                mbstowcs( wbuf, (const char*)errBuff->GetBufferPointer(), BufSize );
46                MessageBox(NULL, wbuf, L".fx Compilation Error", MB_ICONERROR);         // show error message
47                delete wbuf;
48                exit(-1);
49        }
50        // loading Depth Of Field shaders
51        if( FAILED(D3DXCreateEffectFromFile( pd3dDevice, L"shaders/CameraEffects.fx", NULL, NULL, NULL,
52                NULL, &g_pPostEffect, &errBuff )))
53        {
54                int BufSize = errBuff->GetBufferSize();
55                // displaying error message of arbitrary length
56                wchar_t* wbuf = new wchar_t[BufSize];
57                mbstowcs( wbuf, (const char*)errBuff->GetBufferPointer(), BufSize );
58                MessageBox(NULL, wbuf, L".fx Compilation Error", MB_ICONERROR);         // show error message
59                delete wbuf;
60                exit(-1);
61        }
62}
63
64void CameraEffects::OnDestroyDevice()
65{
66        delete mesh;
67        delete lightmesh;
68        SAFE_RELEASE( g_pEffect );
69        SAFE_RELEASE( g_pPostEffect );
70}
71
72void CameraEffects::OnResetDevice(D3DSURFACE_DESC* pBackBufferDesc)
73{
74        m_ScreenWidth = pBackBufferDesc->Width;
75        m_ScreenHeight = pBackBufferDesc->Height;
76
77        if( g_pEffect )
78        g_pEffect->OnResetDevice();
79       
80        // loading color texture
81        D3DXCreateTextureFromFile( pd3dDevice, COLOR_TEXTURE_PATH, &ColorTexture );
82        // loading height map and converting to (RGB - normal, A - height) format without mipmap creation
83        CreateBumpMap(false);
84        // Create full-screen texture for post-process effects (RGB)
85        FrameBufferTexture = new CDXTexture();
86        if (!FrameBufferTexture->InitTex(pd3dDevice, "framebuffer", m_ScreenWidth, m_ScreenHeight, D3DFMT_A8R8G8B8, false))
87        {
88                MessageBox(NULL, L"FrameBufferTexture creation failed!",L"", MB_OK);
89        }
90        // create full-screen texture for post-process effects (blurriness, depth)
91        FrameBufferDepthTexture = new CDXTexture();
92        if (!FrameBufferDepthTexture->InitTex(pd3dDevice, "framebufferdepth", m_ScreenWidth, m_ScreenHeight, D3DFMT_G16R16F, false))
93        {
94                MessageBox(NULL, L"FrameBufferDepthTexture creation failed!",L"", MB_OK);
95        }
96
97        // create vertex buffer for full-screen quad
98        pd3dDevice->CreateVertexBuffer(sizeof(float) * 18, D3DUSAGE_WRITEONLY, D3DFVF_XYZ, D3DPOOL_DEFAULT, &FullScreenQuad, 0);
99        float* snipet;
100        FullScreenQuad->Lock(0, 0, (void**)&snipet, D3DLOCK_DISCARD);
101        int index = 0;
102        snipet[index++] = -1; snipet[index++] = -1; snipet[index++] = 0;
103        snipet[index++] =  1; snipet[index++] =  1; snipet[index++] = 0; 
104        snipet[index++] =  1; snipet[index++] = -1; snipet[index++] = 0; 
105
106        snipet[index++] = -1; snipet[index++] = -1; snipet[index++] = 0; 
107        snipet[index++] = -1; snipet[index++] =  1; snipet[index++] = 0; 
108        snipet[index++] =  1; snipet[index++] =  1; snipet[index++] = 0; 
109
110        FullScreenQuad->Unlock();
111}
112
113void CameraEffects::OnLostDevice()
114{
115        if( g_pEffect )
116        g_pEffect->OnLostDevice();
117        if( g_pPostEffect )
118        g_pPostEffect->OnLostDevice();
119
120        SAFE_RELEASE(DisplacementTexture);
121        SAFE_RELEASE(ColorTexture);
122        SAFE_RELEASE(FullScreenQuad);
123        delete FrameBufferTexture;
124        delete FrameBufferDepthTexture;
125}
126
127void CameraEffects::CreateBumpMap(bool createMipMaps)
128{
129        D3DXIMAGE_INFO info;
130       
131        // height field is loaded into temporal texture
132        LPDIRECT3DTEXTURE9 heightTex;
133        D3DXCreateTextureFromFileEx(
134                pd3dDevice,
135                DISPLACEMENT_TEXTURE_PATH,
136                D3DX_DEFAULT, D3DX_DEFAULT,
137                createMipMaps ? D3DX_DEFAULT : 1,  // mipmap levels
138                0,
139                D3DFMT_A8R8G8B8,
140                D3DPOOL_MANAGED,
141                D3DX_DEFAULT,
142                D3DX_DEFAULT,
143                NULL,
144                &info,
145                NULL,
146                &heightTex);
147
148        // texture creation
149        V(D3DXCreateTexture(pd3dDevice, info.Width, info.Height, createMipMaps ? D3DX_DEFAULT : 1, 0, D3DFMT_Q8W8V8U8, D3DPOOL_MANAGED, &DisplacementTexture));
150
151        // normal map számítás
152        V(D3DXComputeNormalMap(DisplacementTexture, heightTex, NULL, 0, D3DX_CHANNEL_RED, 5.0f));
153
154        D3DLOCKED_RECT rect1, rect2;
155        V(heightTex->LockRect(0, &rect2, 0, D3DLOCK_READONLY));
156        //
157        // copy height map to DisplacementTexture's alpha channel
158        // mipmap levels too, biased to [-128, +127]
159        //
160        int level = 0;
161        while (createMipMaps ? (pow(2, level) <= info.Height) : (level == 0)) {
162                V(DisplacementTexture->LockRect(level, &rect1, 0, 0));
163                char* target = (char*)rect1.pBits;
164                unsigned char* source = (unsigned char*)rect2.pBits;
165                int mul = (int)pow(2, level);
166                for (unsigned int i = 0; i < info.Height / mul; i++) {
167                        for (unsigned int j = 0; j < info.Width / mul; j++) {
168                                int index1 = i * rect1.Pitch / 4 + j;
169                               
170                                int index2a = i * mul * rect2.Pitch / 4 +  j * mul;
171                                int index2b = (i*mul+mul/2) * rect2.Pitch / 4+ j*mul;
172                                int index2c = i*mul * rect2.Pitch / 4+ j*mul + mul/2;
173                                int index2d = (i*mul+mul/2) * rect2.Pitch / 4 + j*mul + mul/2;
174                               
175                                target[index1 * 4 + 3] =(char)((source[4*index2a]+source[4*index2b]+source[4*index2c]+source[4*index2d]) / 8.0f);
176                        }
177                }
178                DisplacementTexture->UnlockRect(level);
179                level++;
180        }
181        heightTex->UnlockRect(0);
182        heightTex->Release();
183}
184
185
186// prepares the depth of field filter kernel array
187void CameraEffects::SetupFilterKernel()
188{
189        FLOAT dx = 1.0f / (FLOAT)m_ScreenWidth;
190        FLOAT dy = 1.0f / (FLOAT)m_ScreenHeight;
191
192        D3DXVECTOR4 v[12];
193        v[0]  = D3DXVECTOR4(-0.326212f * dx, -0.405805f * dy, 0.0f, 0.0f);
194        v[1]  = D3DXVECTOR4(-0.840144f * dx, -0.07358f * dy, 0.0f, 0.0f);
195        v[2]  = D3DXVECTOR4(-0.695914f * dx, 0.457137f * dy, 0.0f, 0.0f);
196        v[3]  = D3DXVECTOR4(-0.203345f * dx, 0.620716f * dy, 0.0f, 0.0f);
197        v[4]  = D3DXVECTOR4(0.96234f * dx, -0.194983f * dy, 0.0f, 0.0f);
198        v[5]  = D3DXVECTOR4(0.473434f * dx, -0.480026f * dy, 0.0f, 0.0f);
199        v[6]  = D3DXVECTOR4(0.519456f * dx, 0.767022f * dy, 0.0f, 0.0f);
200        v[7]  = D3DXVECTOR4(0.185461f * dx, -0.893124f * dy, 0.0f, 0.0f);
201        v[8]  = D3DXVECTOR4(0.507431f * dx, 0.064425f * dy, 0.0f, 0.0f);
202        v[9]  = D3DXVECTOR4(0.89642f * dx, 0.412458f * dy, 0.0f, 0.0f);
203        v[10] = D3DXVECTOR4(-0.32194f * dx, -0.932615f * dy, 0.0f, 0.0f);
204        v[11] = D3DXVECTOR4(-0.791559f * dx, -0.597705f * dy, 0.0f, 0.0f);
205
206        g_pPostEffect->SetVectorArray("filterTaps", v, 12);
207}
208
209// rendering
210void CameraEffects::OnFrameRender( D3DXMATRIXA16& mView, D3DXMATRIXA16& mProj )
211{               
212        // setting the full screen-textures as render targets 0 and 1
213        FrameBufferTexture->StartRender(true, 0);
214        FrameBufferDepthTexture->StartRender(false, 1);
215        // clear screen
216        D3DCOLOR backgroundColor = D3DCOLOR_ARGB(0, 66, 75, 121);
217        V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, backgroundColor, 1.0f, 0) );
218
219        // setting up matrices
220        D3DXMATRIXA16 mWorld;
221        D3DXMatrixTranslation(&mWorld,LightPos->x,LightPos->y,LightPos->z);
222        pd3dDevice->SetTransform( D3DTS_PROJECTION, &mProj );   
223        pd3dDevice->SetTransform( D3DTS_WORLD, &mWorld );       
224        pd3dDevice->SetTransform( D3DTS_VIEW, &mView );
225        // draw light source
226        lightmesh->Draw();
227        D3DXMATRIX Trans, Rot;
228        D3DXMatrixTranslation(&Trans, 0, 0, -27);
229        D3DXMatrixRotationY(&Rot,  3.1415792);
230        D3DXMatrixMultiply(&mWorld, &Trans, &Rot);
231        SetWorldViewProj(mWorld,mView,mProj);
232
233        // LightPos and CameraPos is needed in Model Space in shader
234        D3DXVECTOR4 mEye, mLight, wEye, wLight;
235        wEye = D3DXVECTOR4(camera->GetEyePt()->x,camera->GetEyePt()->y,camera->GetEyePt()->z, 1.0f);
236        wLight=D3DXVECTOR4(LightPos->x, LightPos->y, LightPos->z, 1.0f);
237        D3DXVec4Transform(&mEye, &wEye, &m_InvWorld);
238        D3DXVec4Transform(&mLight, &wLight, &m_InvWorld);
239
240        // setting shader parameters
241        D3DSURFACE_DESC desc;
242        DisplacementTexture->GetLevelDesc(0,&desc);
243        g_pEffect->SetTexture("BumpMap", DisplacementTexture);
244        g_pEffect->SetTexture("ColorMap", ColorTexture);
245        g_pEffect->SetFloat("focalDist", params->Get(fFocalDistance));
246        g_pEffect->SetFloat("focalRange", 0.1f);
247
248        float lp[] = {mLight.x, mLight.y, mLight.z};
249        g_pEffect->SetFloatArray("mLightPos", lp, 3);
250        float cp[] = {mEye.x, mEye.y, mEye.z};
251        g_pEffect->SetFloatArray("mCameraPos", cp, 3);
252
253        g_pEffect->CommitChanges();
254        g_pEffect->SetTechnique("BumpMapping");
255        UINT p;
256        g_pEffect->Begin(&p, 0 );
257        g_pEffect->BeginPass( 0 );     
258               
259        mesh->Draw();
260       
261        g_pEffect->EndPass();
262        g_pEffect->End();
263
264
265        FrameBufferTexture->EndRender();
266        FrameBufferDepthTexture->EndRender();
267
268        // doing DoF post-processing
269        pd3dDevice->SetStreamSource(0, FullScreenQuad, 0, sizeof(float) * 3);
270        pd3dDevice->SetFVF(D3DFVF_XYZ);
271
272        g_pPostEffect->SetTexture("ColorMap", FrameBufferTexture->m_Tex);
273        g_pPostEffect->SetTexture("DepthMap", FrameBufferDepthTexture->m_Tex);
274       
275        SetupFilterKernel();
276       
277        g_pPostEffect->CommitChanges();
278
279        g_pPostEffect->SetTechnique("DepthOfField");
280
281        g_pPostEffect->Begin(&p, 0 );
282        g_pPostEffect->BeginPass( 0 ); 
283        // drawing full-screen quad
284        pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
285
286        g_pPostEffect->EndPass();
287        g_pPostEffect->End();
288}
289
290void CameraEffects::addUiParams(Parameters& p)
291{
292        params=&p;
293        p.Add( fFocalDistance, "Focal Distance", 100, convertToZeroTo30 );
294        //p.Add( fDisplacementScale, "Scale", 100, convertToMinusOne_One );
295
296}
297
298void CameraEffects::SetWorldViewProj(D3DXMATRIXA16& mWorld, D3DXMATRIXA16& mView, D3DXMATRIXA16& mProj )
299{
300        D3DXMatrixInverse(&m_InvWorld,0,&mWorld); // inverse matrix
301        D3DXMATRIXA16 mWorldView = mWorld * mView;
302        D3DXMATRIXA16 mWorldViewProjection = mWorldView * mProj;
303
304        D3DXMATRIXA16 mWorldViewI, mWorldViewIT;
305        D3DXMatrixInverse(&mWorldViewI, NULL, &mWorldView);
306        D3DXMatrixTranspose(&mWorldViewIT, &mWorldViewI);
307
308        V( g_pEffect->SetMatrix( "WorldView", &mWorldView ) );
309        V( g_pEffect->SetMatrix( "WorldViewIT", &mWorldViewIT ) );
310        V( g_pEffect->SetMatrix( "WorldViewProj", &mWorldViewProjection ) );
311        V( g_pEffect->CommitChanges() );
312}
Note: See TracBrowser for help on using the repository browser.