source: GTP/trunk/App/Demos/Illum/Standalone/Glow [DirectX]/ToneMap.cpp @ 846

Revision 846, 10.4 KB checked in by szirmay, 19 years ago (diff)
Line 
1#include "dxstdafx.h"
2#include "ToneMap.h"
3
4ToneMap::ToneMap(void)
5{
6}
7
8ToneMap::~ToneMap(void)
9{
10        Gain = 1.0f;
11        Passes = 1.0f;
12}
13
14void ToneMap::SetGain(float gain) {
15        Gain = gain;
16}
17
18void ToneMap::SetPasses(float pass) {
19        Passes = pass;
20}
21
22void ToneMap::SetSource(LPDIRECT3DTEXTURE9 _sourceTexture) {
23        this->sourceTexture = _sourceTexture;
24}
25
26HRESULT ToneMap::Init( IDirect3DDevice9* pd3dDevice, LPDIRECT3DTEXTURE9 sourceTexture, LPDIRECT3DSURFACE9 targetTextureSurface) {
27        this->sourceTexture = sourceTexture;
28        this->myRenderTextureSurface = targetTextureSurface;
29        this->pd3dDevice = pd3dDevice;
30
31        D3DSURFACE_DESC desc;
32
33        sourceTexture->GetLevelDesc(0, &desc);
34
35        int sWidth = desc.Width;
36        int sHeight = desc.Height;
37
38        // Create Luminance Texture
39        HRESULT h = pd3dDevice->CreateTexture(sWidth, sHeight ,0,D3DUSAGE_RENDERTARGET,D3DFMT_G16R16F,D3DPOOL_DEFAULT,&myLuminanceTexture,NULL);
40        myLuminanceTexture->GetSurfaceLevel(0,&myLuminanceTextureSurface);     
41
42        // Create Average Luminance Texture pair
43        pd3dDevice->CreateTexture(sWidth ,sHeight ,0,D3DUSAGE_RENDERTARGET,D3DFMT_G16R16F,D3DPOOL_DEFAULT,&myAverageLuminanceTexture[0],NULL);
44        myAverageLuminanceTexture[0]->GetSurfaceLevel(0,&myAverageLuminanceTextureSurface[0]); 
45
46        pd3dDevice->CreateTexture(sWidth ,sHeight ,0,D3DUSAGE_RENDERTARGET,D3DFMT_G16R16F,D3DPOOL_DEFAULT,&myAverageLuminanceTexture[1],NULL);
47        myAverageLuminanceTexture[1]->GetSurfaceLevel(0,&myAverageLuminanceTextureSurface[1]); 
48
49        // Error Buffer
50        LPD3DXBUFFER errBuff;
51        DWORD effectCompileFlag = 0;
52
53        // Shader options for debuging
54        #ifdef DEBUG_SHADER
55        effectCompileFlag|=D3DXSHADER_DEBUG;
56        effectCompileFlag |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
57        effectCompileFlag |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
58        #endif
59
60        // Create the tone mapping effect from file
61        HRESULT hr = D3DXCreateEffectFromFile(pd3dDevice,L"ToneMap.fx",NULL,NULL,effectCompileFlag,NULL,&myEffect,&errBuff);
62        if(hr!=S_OK){
63                int BufSize = errBuff->GetBufferSize();
64
65                // displaying error message of arbitrary length
66                wchar_t* wbuf = new wchar_t[BufSize];
67                mbstowcs( wbuf, (const char*)errBuff->GetBufferPointer(), BufSize );
68                MessageBox(NULL, wbuf, L".fx Compilation Error", MB_ICONERROR);         // show error message
69
70                delete wbuf;
71                return hr;
72        }
73        SAFE_RELEASE(errBuff);
74       
75        //targetTextureSurface->GetDesc(&desc);
76        int tWidth = desc.Width;
77        int tHeight = desc.Height;
78        V(pd3dDevice->CreateDepthStencilSurface(tWidth,tHeight,D3DFMT_D16,D3DMULTISAMPLE_NONE ,0,true,&rttDepthSurface,NULL));
79        V(pd3dDevice->CreateDepthStencilSurface(tWidth/4,tHeight/4,D3DFMT_D16,D3DMULTISAMPLE_NONE ,0,true,&rttDepthSurface_small,NULL));
80       
81        // Quad rendering declarations
82/*      rttVertices[0] = D3DVERTEX_1(-1,-1,0,1, 0.0f, 2.0f);
83        rttVertices[1] = D3DVERTEX_1(-1,3,0,1, 0.0f, 0.0f);
84        rttVertices[2] = D3DVERTEX_1(3,-1,0,1, 2.0f, 2.0f);
85*/
86        rttVertices[0] = D3DVERTEX_1(-3,1,0,1, -1.0f, 0.0f);
87        rttVertices[1] = D3DVERTEX_1(1,1,0,1, 1.0f, 0.0f);
88        rttVertices[2] = D3DVERTEX_1(1, -3,0,1, 1.0f, 2.0f);
89        //Vertex declaration
90        D3DVERTEXELEMENT9 _texturedecl[]=
91        {
92                {0,0,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,0 },
93                {0,16,D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,0 },
94                D3DDECL_END()
95        };
96        V(pd3dDevice->CreateVertexDeclaration(_texturedecl,&textureDecl));
97        V(pd3dDevice->CreateVertexBuffer(sizeof(D3DVERTEX_1)*3,D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED,&pQuadVB,NULL));
98        void *pData;
99
100        pQuadVB->Lock(0,sizeof(pData),(void**)&pData,0);
101        memcpy(pData,rttVertices,sizeof(D3DVERTEX_1)*3);
102        pQuadVB->Unlock();
103
104    return S_OK;
105}
106
107void ToneMap::Destroy() {
108
109        SAFE_RELEASE(myEffect);
110        SAFE_RELEASE(myLuminanceTexture);
111        SAFE_RELEASE(myLuminanceTextureSurface);
112        SAFE_RELEASE(myAverageLuminanceTexture[0] );
113        SAFE_RELEASE(myAverageLuminanceTextureSurface[0] );
114        SAFE_RELEASE(myAverageLuminanceTexture[1] );
115        SAFE_RELEASE(myAverageLuminanceTextureSurface[1] );
116        SAFE_RELEASE(rttDepthSurface);
117        SAFE_RELEASE(rttDepthSurface_small);
118        SAFE_RELEASE(textureDecl);
119
120        SAFE_RELEASE(myRenderTextureSurface);
121
122        SAFE_RELEASE(pQuadVB);
123}
124
125void ToneMap::Map() {
126        HRESULT hr;
127       
128        D3DXMATRIX modelViewProjMatrix;
129        D3DXMatrixIdentity(&modelViewProjMatrix);
130
131        V( pd3dDevice->GetRenderTarget(0,&backBuffer) );
132        V( pd3dDevice->GetDepthStencilSurface(&backBufferDepthSurface) );
133
134        // Step 1: Calculate the luminance
135        D3DSURFACE_DESC desc;
136        sourceTexture->GetLevelDesc(0,&desc);
137
138        V( pd3dDevice->SetRenderTarget(0,myLuminanceTextureSurface));
139        V( pd3dDevice->SetDepthStencilSurface(rttDepthSurface_small) );
140
141        V( pd3dDevice->SetVertexDeclaration(textureDecl) );
142        V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0) );
143       
144    // Render the scene with the Luminance effect
145    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
146    {
147                UINT numberofPasses=0;
148                D3DXHANDLE techniqueHandle = myEffect->GetTechniqueByName("Luminance");
149                V(myEffect->SetTechnique(techniqueHandle));
150                V(myEffect->SetTexture("SourceTexture",sourceTexture));
151                V(myEffect->SetMatrix("modelViewProjection",&modelViewProjMatrix));
152                V(myEffect->SetFloat("dsWidth", desc.Width));
153                V(myEffect->SetFloat("dsHeight", desc.Height));
154                myEffect->CommitChanges();
155                V(myEffect->Begin(&numberofPasses,0));
156                for(UINT i = 0; i<numberofPasses; i++ )
157                {
158                        V(myEffect->BeginPass(i));
159                       
160                        //Render triangle.
161                        V(pd3dDevice->SetStreamSource(0,pQuadVB,0,sizeof(D3DVERTEX_1)));
162                        V(pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1));
163                       
164                        V(myEffect->EndPass());
165                }
166                V(myEffect->End());
167    }
168
169        // Step 2: Downsampling with Gauss filter
170        //                 Initial pass
171
172        myAverageLuminanceTextureSurface[1]->GetDesc(&desc);
173
174        V( pd3dDevice->SetRenderTarget(0,myAverageLuminanceTextureSurface[1]));
175        V( pd3dDevice->SetDepthStencilSurface(rttDepthSurface) );
176        V( pd3dDevice->SetVertexDeclaration(textureDecl) );
177        V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0) );
178       
179    // Render the scene with DownSample effect
180    {
181                UINT numberofPasses=0;
182                D3DXHANDLE techniqueHandle = myEffect->GetTechniqueByName("Blur_v");
183                V(myEffect->SetTechnique(techniqueHandle));
184                V(myEffect->SetTexture("LuminanceTexture",myLuminanceTexture));
185                V(myEffect->SetMatrix("modelViewProjection",&modelViewProjMatrix));
186                V(myEffect->SetFloat("dsWidth", desc.Width));
187                V(myEffect->SetFloat("dsHeight", desc.Height));
188                myEffect->CommitChanges();
189                V(myEffect->Begin(&numberofPasses,0));
190                for(UINT i = 0; i<numberofPasses; i++ )
191                {
192                        V(myEffect->BeginPass(i));
193                       
194                        //Render triangle.
195                        V(pd3dDevice->SetStreamSource(0,pQuadVB,0,sizeof(D3DVERTEX_1)));
196                        V(pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1));
197
198                        V(myEffect->EndPass());
199                }
200                V(myEffect->End());
201    }
202
203        // Repetitive downsampling pass
204        // Ping-pong between the two buffer
205        for (int ds_pass=0; ds_pass<Passes; ds_pass++) {
206        // buffer1 -> buffer0
207        V( pd3dDevice->SetRenderTarget(0,myAverageLuminanceTextureSurface[0]));
208        V( pd3dDevice->SetDepthStencilSurface(rttDepthSurface) );
209        V( pd3dDevice->SetVertexDeclaration(textureDecl) );
210        V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0) );
211       
212    {
213                UINT numberofPasses=0;
214                D3DXHANDLE techniqueHandle = myEffect->GetTechniqueByName("Blur_h");
215                V(myEffect->SetTechnique(techniqueHandle));
216                V(myEffect->SetTexture("LuminanceTexture",myAverageLuminanceTexture[1]));
217                V(myEffect->SetMatrix("modelViewProjection",&modelViewProjMatrix));
218                V(myEffect->SetFloat("dsWidth", desc.Width));
219                V(myEffect->SetFloat("dsHeight", desc.Height));
220                myEffect->CommitChanges();
221                V(myEffect->Begin(&numberofPasses,0));
222                for(UINT i = 0; i<numberofPasses; i++ )
223                {
224                        V(myEffect->BeginPass(i));
225
226                        V(pd3dDevice->SetStreamSource(0,pQuadVB,0,sizeof(D3DVERTEX_1)));
227                        V(pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1));
228
229                        V(myEffect->EndPass());
230                }
231                V(myEffect->End());
232    }
233
234        // buffer0->buffer1
235        V( pd3dDevice->SetRenderTarget(0,myAverageLuminanceTextureSurface[1]));
236        V( pd3dDevice->SetDepthStencilSurface(rttDepthSurface) );
237        V( pd3dDevice->SetVertexDeclaration(textureDecl) );
238        V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0) );
239       
240    {
241                UINT numberofPasses=0;
242                D3DXHANDLE techniqueHandle = myEffect->GetTechniqueByName("Blur_v");
243                V(myEffect->SetTechnique(techniqueHandle));
244                V(myEffect->SetTexture("LuminanceTexture",myAverageLuminanceTexture[0]));
245                V(myEffect->SetMatrix("modelViewProjection",&modelViewProjMatrix));
246                V(myEffect->SetFloat("dsWidth", desc.Width));
247                V(myEffect->SetFloat("dsHeight", desc.Height));
248                myEffect->CommitChanges();
249                V(myEffect->Begin(&numberofPasses,0));
250                for(UINT i = 0; i<numberofPasses; i++ )
251                {
252                        V(myEffect->BeginPass(i));
253                       
254                        V(pd3dDevice->SetStreamSource(0,pQuadVB,0,sizeof(D3DVERTEX_1)));
255                        V(pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1));
256
257                        V(myEffect->EndPass());
258                }
259                V(myEffect->End());
260    }
261        }
262
263        // Step 3: Final composition
264        V( pd3dDevice->SetRenderTarget(0,backBuffer));
265        V( pd3dDevice->SetDepthStencilSurface(backBufferDepthSurface) );
266        V( pd3dDevice->SetVertexDeclaration(textureDecl) );
267        V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0) );
268
269    {
270                UINT numberofPasses=0;
271                D3DXHANDLE techniqueHandle = myEffect->GetTechniqueByName("FinalTechnique");
272                V(myEffect->SetTechnique(techniqueHandle));
273                V(myEffect->SetTexture("SourceTexture",sourceTexture));
274                V(myEffect->SetTexture("LuminanceTexture",myLuminanceTexture));
275                V(myEffect->SetTexture("AverageLuminanceTexture", myAverageLuminanceTexture[1]));
276                V(myEffect->SetMatrix("modelViewProjection",&modelViewProjMatrix));
277                V(myEffect->SetFloat("Gain", Gain));
278                V(myEffect->SetFloat("dsWidth", desc.Width));
279                V(myEffect->SetFloat("dsHeight", desc.Height));
280                myEffect->CommitChanges();
281                V(myEffect->Begin(&numberofPasses,0));
282                for(UINT i = 0; i<numberofPasses; i++ )
283                {
284                        V(myEffect->BeginPass(i));
285
286                        hr=pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
287                        V(pd3dDevice->SetStreamSource(0,pQuadVB,0,sizeof(D3DVERTEX_1)));
288                        V(pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1));
289
290                        V(myEffect->EndPass());
291                }
292                V(myEffect->End());
293               
294        V( pd3dDevice->EndScene() );
295    }
296
297        SAFE_RELEASE(backBuffer);
298        SAFE_RELEASE(backBufferDepthSurface);
299}
Note: See TracBrowser for help on using the repository browser.