source: GTP/trunk/App/Games/Jungle_Rumble/src/ParticleRenderer.cpp @ 1378

Revision 1378, 14.8 KB checked in by giegl, 18 years ago (diff)

GTPD - Jungle Rumble - integrate into GTP SVN structure

Line 
1#include "dxstdafx.h"
2#include ".\ParticleRenderer.h"
3#include "GameManager.h"
4#include "SharedResourceTexture.h"
5
6ParticleRenderer::ParticleRenderer(void) : Renderer()
7{
8        this->setRenderPriority(50);
9        this->rendererType |= Renderer::RENDERER_PARTICLE;
10        this->singleParticle = false;
11}
12
13ParticleRenderer::~ParticleRenderer(void)
14{
15        SAFE_RELEASE( depthTexture );
16}
17
18void ParticleRenderer::init()
19{
20        HRESULT hr;
21        this->device = DXUTGetD3DDevice();
22
23        this->ParticleEffect = this->myScene->manager->getEffect(GameManager::EFFECT_DEPTHIMP);
24        if(!this->ParticleEffect) {
25                this->ParticleEffect = this->myScene->manager->loadEffect(GameManager::EFFECT_DEPTHIMP, L"shaders/depthImp.obj");
26        }
27
28        //Create DepthTexture
29        this->sr = (SharedResourceTexture*) this->myScene->getSharedResource(Scene::SR_TEXTURE_VIEWDEPTH);
30        if(!this->sr) {
31                this->sr = (SharedResourceTexture*) this->myScene->createSharedResource(Scene::SR_TEXTURE_VIEWDEPTH);
32        }
33        this->depthTexture = this->sr->getTexture();
34       
35        V( this->ParticleEffect->SetTexture("g_txDepthBuffer", this->depthTexture) );
36        nearPlane = this->myScene->getActiveCamera()->getNearClipping();
37        farPlane = this->myScene->getActiveCamera()->getFarClipping();
38        V(this->ParticleEffect->SetFloat("NearPlaneDistance", nearPlane));
39        V(this->ParticleEffect->SetFloat("FarPlaneMinusNearPlane", farPlane - nearPlane));
40        V( this->ParticleEffect->CommitChanges() );
41       
42        this->depthTexture->GetSurfaceLevel(0, &depthSurface);
43}
44
45void ParticleRenderer::render()
46{
47        if(this->singleParticle) {
48                this->renderSingleParticle();
49                return;
50        }
51        HRESULT hr;
52        SPTR<Node> node = this->myNode.lock();
53        Node* particleGroup = node.get();
54        std::list<SPTR<Node> >::iterator it;
55        std::list<SPTR<Node> >* childList;
56        std::vector<Sprite* > sortedList;
57       
58        childList = particleGroup->getChildren();
59        if(childList->size()!=0) {
60                LPD3DXMESH quad = this->myScene->getQuadMesh();
61                V( this->ParticleEffect->SetMatrix("g_mView", &this->myScene->getViewMatrix()) );
62                switch(this->myScene->getActivePassId()) {
63                        case Scene::PASS_NORMAL:
64                                //Render Particles
65                                this->device->SetTransform(D3DTS_PROJECTION, &this->myScene->getProjectionMatrix());
66                               
67                                UINT cPass;
68                                V( this->ParticleEffect->SetTechnique("DepthImposter") );
69                                V( this->ParticleEffect->SetMatrix("g_mProj", &this->myScene->getProjectionMatrix()) );
70                                V( this->ParticleEffect->SetBool("useDepthImposter", this->myScene->useDepthImposter) );
71                                V( this->ParticleEffect->CommitChanges() );
72
73                                //Sort Sprites by Depth
74                                for(it=childList->begin();it!=childList->end();it++) {
75                                        sortedList.push_back((Sprite*) (*it).get());
76                                }
77                                this->cameraPos = this->myScene->getActiveCamera()->getAbsolutePosition();
78                                spriteSortFunction ssf(this->cameraPos);
79                                std::sort(sortedList.begin(), sortedList.end(), ssf);
80
81                                this->device->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW);
82                                this->device->SetRenderState( D3DRS_LIGHTING, FALSE );
83                                this->device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
84                                this->device->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_FALSE); 
85                                this->device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
86                                this->device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
87                                this->device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
88                                this->device->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
89                                this->device->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
90                                this->device->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
91                               
92
93                                for(UINT i=0; i<sortedList.size();i++) {
94                                        Sprite *obj = sortedList.at(i);
95                                        //ReciprokeParticleSize setzen
96                                        if(obj!=NULL && !obj->firstRendering) {
97                                                float d = obj->getMinDim();
98                                                V( this->ParticleEffect->SetFloat("ParticleSize", d/(farPlane-nearPlane)) );
99                                                V( this->ParticleEffect->SetFloat("ReciprocalParticleSize", 1/(d/(farPlane-nearPlane))) );
100
101                                                //World Matrix setzen
102                                                D3DXMATRIX viewMat;
103                                                D3DXMATRIX projMat;
104                                                D3DXMATRIX viewProjMat;
105                                                viewMat = this->myScene->getViewMatrix();
106                                                projMat = this->myScene->getProjectionMatrix();
107                                                D3DXMatrixMultiply(&viewProjMat, &viewMat, &projMat);
108                                                V( this->ParticleEffect->SetMatrix("g_mViewProjection", &viewProjMat) );
109                                                V( this->ParticleEffect->SetMatrix("g_mView", &this->myScene->getViewMatrix()) );
110
111                                                float pPos[3];
112                                                Vector absPos = obj->getAbsolutePosition();
113                                                pPos[0] = absPos.x;
114                                                pPos[1] = absPos.y;
115                                                pPos[2] = absPos.z;
116                                                V( this->ParticleEffect->SetTexture("g_txCurrentTexture", obj->texture) );
117                                                V( this->ParticleEffect->SetFloatArray("argb", obj->currentValues, 4) );
118                                                V( this->ParticleEffect->SetFloatArray("hWidthHeight", &obj->currentValues[Sprite::KF_HWIDTH], 2) );
119                                                V( this->ParticleEffect->SetFloatArray("ParticlePos", pPos, 3) );
120                                               
121                                                //Animation stuff
122                                                V( this->ParticleEffect->SetBool("animatedSprite", obj->animatedSprite) );
123                                                if(obj->animatedSprite) {
124                                                        V( this->ParticleEffect->SetFloat("invNbRows", obj->invRows) );
125                                                        V( this->ParticleEffect->SetFloat("invNbColumns", obj->invColumns) );
126                                                        V( this->ParticleEffect->SetInt("nbFrame", obj->activeFrame) );
127                                                        V( this->ParticleEffect->SetInt("nbColumns", obj->nbColumns) );
128                                                        V( this->ParticleEffect->SetInt("nbRows", obj->nbRows) );
129                                                }
130
131                                                V( this->ParticleEffect->CommitChanges() );
132
133                                       
134                                                // bilinear texture filtering:
135                                                V( this->device->BeginScene() );
136                                                V( this->ParticleEffect->Begin( &cPass, 0 ) );
137                                                V( this->ParticleEffect->BeginPass( 0 ) );
138                                                quad->DrawSubset(0);
139                                                V( this->ParticleEffect->EndPass() );
140                                                V( this->ParticleEffect->End() );
141                                                V( this->device->EndScene() );
142                                        } else if(obj->firstRendering) {
143                                                obj->firstRendering = false;
144                                        }
145                                }
146                                //deactivate textures
147                                this->device->SetTexture(0, 0);
148                               
149                                this->device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
150                                this->device->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_TRUE);
151                                this->device->SetTransform(D3DTS_PROJECTION, &this->myScene->getIdentityMatrix());
152                                break;
153                }
154        }
155}
156
157void ParticleRenderer::OnLostDevice( void* pUserContext )
158{
159        HRESULT hr;
160        this->myScene->manager->printToConsole(" OnLostDevice ParticleRenderer");
161        SAFE_RELEASE( depthTexture );
162        V( this->ParticleEffect->OnLostDevice() );
163}
164
165void ParticleRenderer::OnDestroyDevice( void* pUserContext )
166{
167        this->myScene->manager->printToConsole(" OnDestroyDevice ParticleRenderer");
168        this->myScene->manager->releaseEffect(this->ParticleEffect);
169        this->ParticleEffect = NULL;
170        this->sr = NULL;
171}
172
173HRESULT ParticleRenderer::OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
174{
175        this->device = pd3dDevice;
176        this->ParticleEffect = this->myScene->manager->getEffect(GameManager::EFFECT_DEPTHIMP);
177        if(!this->ParticleEffect) {
178                this->ParticleEffect = this->myScene->manager->loadEffect(GameManager::EFFECT_DEPTHIMP, L"shaders/depthImp.obj");
179        }
180
181        //Create DepthTexture
182        this->sr = (SharedResourceTexture*) this->myScene->getSharedResource(Scene::SR_TEXTURE_VIEWDEPTH);
183        if(!this->sr) {
184                this->sr = (SharedResourceTexture*) this->myScene->createSharedResource(Scene::SR_TEXTURE_VIEWDEPTH);
185        }
186        this->depthTexture = this->sr->getTexture();
187        return S_OK;
188}
189
190bool ParticleRenderer::isLowerThan(Renderer* renderer)
191{
192        //Der ParticleRenderer sollte die Sprites intern richtig aufzeichnen
193        return this->getRenderPriority()<renderer->getRenderPriority();
194}
195
196bool ParticleRenderer::needsExtraPass() {
197        SPTR<Node> node = this->myNode.lock();
198        ParticleGroup* particleGroup = (ParticleGroup*) node.get();
199        if(particleGroup->getChildren()->size()!=0) {
200                return true;
201        }
202        for(UINT i=0; i<particleGroup->emitterList.size();i++) {
203                if(particleGroup->emitterList.at(i)->isEmitting()) {
204                        return true;
205                }
206        }
207        return false;
208}
209
210bool ParticleRenderer::needHeatHazePass()
211{
212        SPTR<Node> node = this->myNode.lock();
213        ParticleGroup* particleGroup = (ParticleGroup*) node.get();
214        if(particleGroup->getUseHeatHaze()) {
215                return this->needsExtraPass();
216        }
217        return false;
218}
219
220void ParticleRenderer::renderHeatHaze() {
221        SPTR<Node> node = this->myNode.lock();
222        Node* particleGroup = node.get();
223        std::list<SPTR<Node> >::iterator it;
224        std::list<SPTR<Node> >* childList;
225        std::vector<Sprite* > sortedList;
226       
227        childList = particleGroup->getChildren();
228        if(childList->size()!=0) {
229                HRESULT hr;
230                LPD3DXMESH quad = this->myScene->getQuadMesh();
231                //Render Particles
232                this->device->SetTransform(D3DTS_PROJECTION, &this->myScene->getProjectionMatrix());
233
234                UINT cPass;
235                V( this->ParticleEffect->SetTechnique("HeatHaze") );
236                V( this->ParticleEffect->SetMatrix("g_mProj", &this->myScene->getProjectionMatrix()) );
237                V( this->ParticleEffect->SetBool("useDepthImposter", this->myScene->useDepthImposter) );
238                V( this->ParticleEffect->CommitChanges() );
239
240                //Sort Sprites by Depth
241                for(it=childList->begin();it!=childList->end();it++) {
242                        sortedList.push_back((Sprite*) (*it).get());
243                }
244                this->cameraPos = this->myScene->getActiveCamera()->getAbsolutePosition();
245                spriteSortFunction ssf(this->cameraPos);
246                std::sort(sortedList.begin(), sortedList.end(), ssf);           
247
248                for(UINT i=0; i<sortedList.size();i++) {
249                        Sprite *obj = sortedList.at(i);
250                        //ReciprokeParticleSize setzen
251                        float d = obj->getMinDim();
252                        V( this->ParticleEffect->SetFloat("ParticleSize", d/(farPlane-nearPlane)) );
253                        V( this->ParticleEffect->SetFloat("ReciprocalParticleSize", 1/(d/(farPlane-nearPlane))) );
254
255                        D3DXMATRIX viewMat;
256                        D3DXMATRIX projMat;
257                        D3DXMATRIX viewProjMat;
258                        viewMat = this->myScene->getViewMatrix();
259                        projMat = this->myScene->getProjectionMatrix();
260                        D3DXMatrixMultiply(&viewProjMat, &viewMat, &projMat);
261                        V( this->ParticleEffect->SetMatrix("g_mViewProjection", &viewProjMat) );
262                        V( this->ParticleEffect->SetMatrix("g_mView", &this->myScene->getViewMatrix()) );
263                       
264                        if(obj!=NULL) {
265                                // bilinear texture filtering:
266                                V( this->device->BeginScene() );
267                                V( this->ParticleEffect->Begin( &cPass, 0 ) );
268                                V( this->ParticleEffect->BeginPass( 0 ) );
269                                float pPos[3];
270                                Vector absPos = obj->getAbsolutePosition();
271                                pPos[0] = absPos.x;
272                                pPos[1] = absPos.y;
273                                pPos[2] = absPos.z;
274                                V( this->ParticleEffect->SetTexture("g_txCurrentTexture", obj->texture) );
275                                V( this->ParticleEffect->SetFloatArray("argb", obj->currentValues, 4) );
276                                V( this->ParticleEffect->SetFloatArray("hWidthHeight", &obj->currentValues[Sprite::KF_HWIDTH], 2) );
277                                V( this->ParticleEffect->SetFloatArray("ParticlePos", pPos, 3) );
278                                V( this->ParticleEffect->CommitChanges() );
279                                quad->DrawSubset(0);
280                                V( this->ParticleEffect->EndPass() );
281                                V( this->ParticleEffect->End() );
282                                V( this->device->EndScene() );
283                        }
284                }
285                //deactivate textures
286                this->device->SetTexture(0, 0);
287               
288               
289                this->device->SetTransform(D3DTS_PROJECTION, &this->myScene->getIdentityMatrix());
290        }
291}
292
293void ParticleRenderer::setRenderSingleParticle(bool _singleParticle)
294{
295        this->singleParticle = _singleParticle;
296}
297
298void ParticleRenderer::renderSingleParticle()
299{
300        HRESULT hr;
301        SPTR<Node> node = this->myNode.lock();
302        Sprite* obj = (Sprite*) node.get();
303       
304        LPD3DXMESH quad = this->myScene->getQuadMesh();
305        V( this->ParticleEffect->SetMatrix("g_mView", &this->myScene->getViewMatrix()) );
306        switch(this->myScene->getActivePassId()) {
307                case Scene::PASS_NORMAL:
308                        //Render Particles
309                        this->device->SetTransform(D3DTS_PROJECTION, &this->myScene->getProjectionMatrix());
310                       
311                        UINT cPass;
312                        V( this->ParticleEffect->SetTechnique("DepthImposter") );
313                        V( this->ParticleEffect->SetMatrix("g_mProj", &this->myScene->getProjectionMatrix()) );
314                        V( this->ParticleEffect->SetBool("useDepthImposter", this->myScene->useDepthImposter) );
315                        V( this->ParticleEffect->CommitChanges() );
316
317                        this->device->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW);
318                        this->device->SetRenderState( D3DRS_LIGHTING, FALSE );
319                        this->device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
320                        this->device->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_FALSE); 
321                        this->device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
322                        this->device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
323                        this->device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
324                        this->device->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
325                        this->device->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
326                        this->device->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
327                       
328                        //ReciprokeParticleSize setzen
329                        if(obj!=NULL && !obj->firstRendering) {
330                                float d = obj->getMinDim();
331                                V( this->ParticleEffect->SetFloat("ParticleSize", d/(farPlane-nearPlane)) );
332                                V( this->ParticleEffect->SetFloat("ReciprocalParticleSize", 1/(d/(farPlane-nearPlane))) );
333
334                                //World Matrix setzen
335                                D3DXMATRIX viewMat;
336                                D3DXMATRIX projMat;
337                                D3DXMATRIX viewProjMat;
338                                viewMat = this->myScene->getViewMatrix();
339                                projMat = this->myScene->getProjectionMatrix();
340                                D3DXMatrixMultiply(&viewProjMat, &viewMat, &projMat);
341                                V( this->ParticleEffect->SetMatrix("g_mViewProjection", &viewProjMat) );
342                                V( this->ParticleEffect->SetMatrix("g_mView", &this->myScene->getViewMatrix()) );
343
344                                float pPos[3];
345                                Vector absPos = obj->getAbsolutePosition();
346                                pPos[0] = absPos.x;
347                                pPos[1] = absPos.y;
348                                pPos[2] = absPos.z;
349                                V( this->ParticleEffect->SetTexture("g_txCurrentTexture", obj->texture) );
350                                V( this->ParticleEffect->SetFloatArray("argb", obj->currentValues, 4) );
351                                V( this->ParticleEffect->SetFloatArray("hWidthHeight", &obj->currentValues[Sprite::KF_HWIDTH], 2) );
352                                V( this->ParticleEffect->SetFloatArray("ParticlePos", pPos, 3) );
353                               
354                                //Animation stuff
355                                V( this->ParticleEffect->SetBool("animatedSprite", obj->animatedSprite) );
356                                if(obj->animatedSprite) {
357                                        V( this->ParticleEffect->SetFloat("invNbRows", obj->invRows) );
358                                        V( this->ParticleEffect->SetFloat("invNbColumns", obj->invColumns) );
359                                        V( this->ParticleEffect->SetInt("nbFrame", obj->activeFrame) );
360                                        V( this->ParticleEffect->SetInt("nbColumns", obj->nbColumns) );
361                                        V( this->ParticleEffect->SetInt("nbRows", obj->nbRows) );
362                                }
363
364                                V( this->ParticleEffect->CommitChanges() );
365                       
366                                // bilinear texture filtering:
367                                V( this->device->BeginScene() );
368                                V( this->ParticleEffect->Begin( &cPass, 0 ) );
369                                V( this->ParticleEffect->BeginPass( 0 ) );
370                                quad->DrawSubset(0);
371                                V( this->ParticleEffect->EndPass() );
372                                V( this->ParticleEffect->End() );
373                                V( this->device->EndScene() );
374                        } else if(obj->firstRendering) {
375                                obj->firstRendering = false;
376                        }
377                       
378                        this->device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
379                        this->device->SetRenderState(D3DRS_ZWRITEENABLE, D3DZB_TRUE);
380                        this->device->SetTransform(D3DTS_PROJECTION, &this->myScene->getIdentityMatrix());
381                        break;
382        }
383}
Note: See TracBrowser for help on using the repository browser.