[760] | 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 | }
|
---|