1 | #include "dxstdafx.h"
|
---|
2 | #include "media.h"
|
---|
3 | #include ".\cameraeffects.h"
|
---|
4 |
|
---|
5 | CameraEffects::CameraEffects(void)
|
---|
6 | {
|
---|
7 | }
|
---|
8 |
|
---|
9 | CameraEffects::~CameraEffects(void)
|
---|
10 | {
|
---|
11 | }
|
---|
12 |
|
---|
13 | // Loads the selected mesh
|
---|
14 | void 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 |
|
---|
29 | void 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 |
|
---|
64 | void CameraEffects::OnDestroyDevice()
|
---|
65 | {
|
---|
66 | delete mesh;
|
---|
67 | delete lightmesh;
|
---|
68 | SAFE_RELEASE( g_pEffect );
|
---|
69 | SAFE_RELEASE( g_pPostEffect );
|
---|
70 | }
|
---|
71 |
|
---|
72 | void 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 |
|
---|
113 | void 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 |
|
---|
127 | void 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
|
---|
187 | void 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
|
---|
210 | void 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 |
|
---|
290 | void 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 |
|
---|
298 | void 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 | }
|
---|